From ac262e7c9c78644503ad4ffb2d3086d30e7aa589 Mon Sep 17 00:00:00 2001 From: lendihop Date: Wed, 20 May 2026 14:23:04 +0200 Subject: [PATCH 01/20] TW-2254: update react native to 0.85 --- Gemfile | 1 + android/app/build.gradle | 4 +- android/gradle/wrapper/gradle-wrapper.jar | Bin 45457 -> 46175 bytes .../gradle/wrapper/gradle-wrapper.properties | 2 +- android/gradlew | 3 - android/gradlew.bat | 3 +- jest.config.js | 2 +- package.json | 27 +- yarn.lock | 970 ++++++++++-------- 9 files changed, 564 insertions(+), 448 deletions(-) diff --git a/Gemfile b/Gemfile index 6a4c5f171..51515233e 100644 --- a/Gemfile +++ b/Gemfile @@ -14,3 +14,4 @@ gem 'bigdecimal' gem 'logger' gem 'benchmark' gem 'mutex_m' +gem 'nkf' diff --git a/android/app/build.gradle b/android/app/build.gradle index e397a1404..407f44bf9 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -24,9 +24,9 @@ react { /* Variants */ // The list of variants to that are debuggable. For those we're going to - // skip the bundling of the JS bundle and the assets. By default is just 'debug'. + // skip the bundling of the JS bundle and the assets. Default is "debug", "debugOptimized". // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. - // debuggableVariants = ["liteDebug", "prodDebug"] + // debuggableVariants = ["liteDebug", "liteDebugOptimized", "prodDebug", "prodDebugOptimized"] /* Bundling */ // A list containing the node command and its flags. Default is just 'node'. diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar index 8bdaf60c75ab801e22807dde59e12a8735a34077..61285a659d17295f1de7c53e24fdf13ad755c379 100644 GIT binary patch delta 36855 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%0Aonjyf`q#Bg+;H(_UceX22V^ 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" + "node": ">= 22.11.0" } } diff --git a/yarn.lock b/yarn.lock index ab181cb2c..b266bed09 100644 --- a/yarn.lock +++ b/yarn.lock @@ -138,7 +138,7 @@ tslib "^2.3.0" zen-observable-ts "^1.2.5" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.24.7", "@babel/code-frame@^7.27.1": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be" integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== @@ -147,6 +147,15 @@ js-tokens "^4.0.0" picocolors "^1.1.1" +"@babel/code-frame@^7.28.6", "@babel/code-frame@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.0.tgz#7cd7a59f15b3cc0dcd803038f7792712a7d0b15c" + integrity sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw== + dependencies: + "@babel/helper-validator-identifier" "^7.28.5" + js-tokens "^4.0.0" + picocolors "^1.1.1" + "@babel/code-frame@~7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" @@ -189,7 +198,7 @@ eslint-visitor-keys "^2.1.0" semver "^6.3.1" -"@babel/generator@^7.25.0", "@babel/generator@^7.28.5", "@babel/generator@^7.7.2": +"@babel/generator@^7.28.5", "@babel/generator@^7.7.2": version "7.28.5" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.5.tgz#712722d5e50f44d07bc7ac9fe84438742dd61298" integrity sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ== @@ -200,6 +209,17 @@ "@jridgewell/trace-mapping" "^0.3.28" jsesc "^3.0.2" +"@babel/generator@^7.29.0", "@babel/generator@^7.29.1": + version "7.29.1" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.1.tgz#d09876290111abbb00ef962a7b83a5307fba0d50" + integrity sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw== + dependencies: + "@babel/parser" "^7.29.0" + "@babel/types" "^7.29.0" + "@jridgewell/gen-mapping" "^0.3.12" + "@jridgewell/trace-mapping" "^0.3.28" + jsesc "^3.0.2" + "@babel/helper-annotate-as-pure@^7.27.1", "@babel/helper-annotate-as-pure@^7.27.3": version "7.27.3" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz#f31fd86b915fc4daf1f3ac6976c59be7084ed9c5" @@ -231,6 +251,19 @@ "@babel/traverse" "^7.28.5" semver "^6.3.1" +"@babel/helper-create-class-features-plugin@^7.28.6": + version "7.29.3" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.3.tgz#67328947d956f06fc7b48def269bf0489155fd42" + integrity sha512-RpLYy2sb51oNLjuu1iD3bwBqCBWUzjO0ocp+iaCP/lJtb2CPLcnC2Fftw+4sAzaMELGeWTgExSKADbdo0GFVzA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.27.3" + "@babel/helper-member-expression-to-functions" "^7.28.5" + "@babel/helper-optimise-call-expression" "^7.27.1" + "@babel/helper-replace-supers" "^7.28.6" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + "@babel/traverse" "^7.29.0" + semver "^6.3.1" + "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.27.1": version "7.28.5" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz#7c1ddd64b2065c7f78034b25b43346a7e19ed997" @@ -293,6 +326,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz#ddb2f876534ff8013e6c2b299bf4d39b3c51d44c" integrity sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw== +"@babel/helper-plugin-utils@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz#6f13ea251b68c8532e985fd532f28741a8af9ac8" + integrity sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug== + "@babel/helper-remap-async-to-generator@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz#4601d5c7ce2eb2aea58328d43725523fcd362ce6" @@ -311,6 +349,15 @@ "@babel/helper-optimise-call-expression" "^7.27.1" "@babel/traverse" "^7.27.1" +"@babel/helper-replace-supers@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz#94aa9a1d7423a00aead3f204f78834ce7d53fe44" + integrity sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.28.5" + "@babel/helper-optimise-call-expression" "^7.27.1" + "@babel/traverse" "^7.28.6" + "@babel/helper-skip-transparent-expression-wrappers@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz#62bb91b3abba8c7f1fec0252d9dbea11b3ee7a56" @@ -361,13 +408,20 @@ js-tokens "^4.0.0" picocolors "^1.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.24.4", "@babel/parser@^7.25.3", "@babel/parser@^7.27.2", "@babel/parser@^7.28.5": +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.24.4", "@babel/parser@^7.27.2", "@babel/parser@^7.28.5": version "7.28.5" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.5.tgz#0b0225ee90362f030efd644e8034c99468893b08" integrity sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ== dependencies: "@babel/types" "^7.28.5" +"@babel/parser@^7.28.6", "@babel/parser@^7.29.0": + version "7.29.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.3.tgz#116f70a77958307fceac27747573032f8a62f88e" + integrity sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA== + dependencies: + "@babel/types" "^7.29.0" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.28.5": version "7.28.5" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz#fbde57974707bbfa0376d34d425ff4fa6c732421" @@ -566,6 +620,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" +"@babel/plugin-syntax-typescript@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz#c7b2ddf1d0a811145b1de800d1abd146af92e3a2" + integrity sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A== + dependencies: + "@babel/helper-plugin-utils" "^7.28.6" + "@babel/plugin-syntax-unicode-sets-regex@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" @@ -574,7 +635,7 @@ "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-arrow-functions@7.27.1", "@babel/plugin-transform-arrow-functions@^7.24.7", "@babel/plugin-transform-arrow-functions@^7.27.1": +"@babel/plugin-transform-arrow-functions@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz#6e2061067ba3ab0266d834a9f94811196f2aba9a" integrity sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA== @@ -613,7 +674,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-class-properties@7.27.1", "@babel/plugin-transform-class-properties@^7.25.4", "@babel/plugin-transform-class-properties@^7.27.1": +"@babel/plugin-transform-class-properties@^7.25.4", "@babel/plugin-transform-class-properties@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz#dd40a6a370dfd49d32362ae206ddaf2bb082a925" integrity sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA== @@ -629,7 +690,7 @@ "@babel/helper-create-class-features-plugin" "^7.28.3" "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-classes@7.28.4", "@babel/plugin-transform-classes@^7.25.4", "@babel/plugin-transform-classes@^7.28.4": +"@babel/plugin-transform-classes@^7.25.4", "@babel/plugin-transform-classes@^7.28.4": version "7.28.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz#75d66175486788c56728a73424d67cbc7473495c" integrity sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA== @@ -641,7 +702,7 @@ "@babel/helper-replace-supers" "^7.27.1" "@babel/traverse" "^7.28.4" -"@babel/plugin-transform-computed-properties@^7.24.7", "@babel/plugin-transform-computed-properties@^7.27.1": +"@babel/plugin-transform-computed-properties@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz#81662e78bf5e734a97982c2b7f0a793288ef3caa" integrity sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw== @@ -725,7 +786,7 @@ "@babel/helper-plugin-utils" "^7.27.1" "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" -"@babel/plugin-transform-function-name@^7.25.1", "@babel/plugin-transform-function-name@^7.27.1": +"@babel/plugin-transform-function-name@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz#4d0bf307720e4dce6d7c30fcb1fd6ca77bdeb3a7" integrity sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ== @@ -741,14 +802,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-literals@^7.25.2", "@babel/plugin-transform-literals@^7.27.1": +"@babel/plugin-transform-literals@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz#baaefa4d10a1d4206f9dcdda50d7d5827bb70b24" integrity sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA== dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-logical-assignment-operators@^7.24.7", "@babel/plugin-transform-logical-assignment-operators@^7.28.5": +"@babel/plugin-transform-logical-assignment-operators@^7.28.5": version "7.28.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz#d028fd6db8c081dee4abebc812c2325e24a85b0e" integrity sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA== @@ -811,21 +872,21 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-nullish-coalescing-operator@7.27.1", "@babel/plugin-transform-nullish-coalescing-operator@^7.24.7", "@babel/plugin-transform-nullish-coalescing-operator@^7.27.1": +"@babel/plugin-transform-nullish-coalescing-operator@^7.24.7", "@babel/plugin-transform-nullish-coalescing-operator@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz#4f9d3153bf6782d73dd42785a9d22d03197bc91d" integrity sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA== dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-numeric-separator@^7.24.7", "@babel/plugin-transform-numeric-separator@^7.27.1": +"@babel/plugin-transform-numeric-separator@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz#614e0b15cc800e5997dadd9bd6ea524ed6c819c6" integrity sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw== dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-object-rest-spread@^7.24.7", "@babel/plugin-transform-object-rest-spread@^7.28.4": +"@babel/plugin-transform-object-rest-spread@^7.28.4": version "7.28.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz#9ee1ceca80b3e6c4bac9247b2149e36958f7f98d" integrity sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew== @@ -851,14 +912,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-optional-chaining@7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz#874ce3c4f06b7780592e946026eb76a32830454f" - integrity sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" - "@babel/plugin-transform-optional-chaining@^7.24.8", "@babel/plugin-transform-optional-chaining@^7.27.1", "@babel/plugin-transform-optional-chaining@^7.28.5": version "7.28.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz#8238c785f9d5c1c515a90bf196efb50d075a4b26" @@ -867,7 +920,7 @@ "@babel/helper-plugin-utils" "^7.27.1" "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" -"@babel/plugin-transform-parameters@^7.24.7", "@babel/plugin-transform-parameters@^7.27.7": +"@babel/plugin-transform-parameters@^7.27.7": version "7.27.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz#1fd2febb7c74e7d21cf3b05f7aebc907940af53a" integrity sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg== @@ -964,14 +1017,14 @@ babel-plugin-polyfill-regenerator "^0.6.5" semver "^6.3.1" -"@babel/plugin-transform-shorthand-properties@7.27.1", "@babel/plugin-transform-shorthand-properties@^7.24.7", "@babel/plugin-transform-shorthand-properties@^7.27.1": +"@babel/plugin-transform-shorthand-properties@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz#532abdacdec87bfee1e0ef8e2fcdee543fe32b90" integrity sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ== dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-spread@^7.24.7", "@babel/plugin-transform-spread@^7.27.1": +"@babel/plugin-transform-spread@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz#1a264d5fc12750918f50e3fe3e24e437178abb08" integrity sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q== @@ -979,14 +1032,14 @@ "@babel/helper-plugin-utils" "^7.27.1" "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" -"@babel/plugin-transform-sticky-regex@^7.24.7", "@babel/plugin-transform-sticky-regex@^7.27.1": +"@babel/plugin-transform-sticky-regex@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz#18984935d9d2296843a491d78a014939f7dcd280" integrity sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g== dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-template-literals@7.27.1", "@babel/plugin-transform-template-literals@^7.27.1": +"@babel/plugin-transform-template-literals@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz#1a0eb35d8bb3e6efc06c9fd40eb0bcef548328b8" integrity sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg== @@ -1000,7 +1053,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-typescript@^7.25.2", "@babel/plugin-transform-typescript@^7.27.1": +"@babel/plugin-transform-typescript@^7.25.2": version "7.28.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz#441c5f9a4a1315039516c6c612fc66d5f4594e72" integrity sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA== @@ -1011,6 +1064,17 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" "@babel/plugin-syntax-typescript" "^7.27.1" +"@babel/plugin-transform-typescript@^7.28.5": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.6.tgz#1e93d96da8adbefdfdade1d4956f73afa201a158" + integrity sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.27.3" + "@babel/helper-create-class-features-plugin" "^7.28.6" + "@babel/helper-plugin-utils" "^7.28.6" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + "@babel/plugin-syntax-typescript" "^7.28.6" + "@babel/plugin-transform-unicode-escapes@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz#3e3143f8438aef842de28816ece58780190cf806" @@ -1026,7 +1090,7 @@ "@babel/helper-create-regexp-features-plugin" "^7.27.1" "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-unicode-regex@7.27.1", "@babel/plugin-transform-unicode-regex@^7.24.7", "@babel/plugin-transform-unicode-regex@^7.27.1": +"@babel/plugin-transform-unicode-regex@^7.24.7", "@babel/plugin-transform-unicode-regex@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz#25948f5c395db15f609028e370667ed8bae9af97" integrity sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw== @@ -1127,16 +1191,16 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/preset-typescript@7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.27.1.tgz#190742a6428d282306648a55b0529b561484f912" - integrity sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ== +"@babel/preset-typescript@^7.27.1": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz#540359efa3028236958466342967522fd8f2a60c" + integrity sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/helper-validator-option" "^7.27.1" "@babel/plugin-syntax-jsx" "^7.27.1" "@babel/plugin-transform-modules-commonjs" "^7.27.1" - "@babel/plugin-transform-typescript" "^7.27.1" + "@babel/plugin-transform-typescript" "^7.28.5" "@babel/runtime@7.28.4", "@babel/runtime@^7.25.0": version "7.28.4" @@ -1148,7 +1212,7 @@ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.6.tgz#d267a43cb1836dc4d182cce93ae75ba954ef6d2b" integrity sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA== -"@babel/template@^7.25.0", "@babel/template@^7.27.1", "@babel/template@^7.27.2", "@babel/template@^7.3.3": +"@babel/template@^7.27.1", "@babel/template@^7.27.2", "@babel/template@^7.3.3": version "7.27.2" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.2.tgz#fa78ceed3c4e7b63ebf6cb39e5852fca45f6809d" integrity sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw== @@ -1157,7 +1221,16 @@ "@babel/parser" "^7.27.2" "@babel/types" "^7.27.1" -"@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3": +"@babel/template@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.28.6.tgz#0e7e56ecedb78aeef66ce7972b082fce76a23e57" + integrity sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ== + dependencies: + "@babel/code-frame" "^7.28.6" + "@babel/parser" "^7.28.6" + "@babel/types" "^7.28.6" + +"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.0", "@babel/traverse@^7.28.3", "@babel/traverse@^7.28.4", "@babel/traverse@^7.28.5": version "7.28.5" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.5.tgz#450cab9135d21a7a2ca9d2d35aa05c20e68c360b" integrity sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ== @@ -1170,20 +1243,20 @@ "@babel/types" "^7.28.5" debug "^4.3.1" -"@babel/traverse@^7.25.3", "@babel/traverse@^7.27.1", "@babel/traverse@^7.28.0", "@babel/traverse@^7.28.3", "@babel/traverse@^7.28.4", "@babel/traverse@^7.28.5": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.5.tgz#450cab9135d21a7a2ca9d2d35aa05c20e68c360b" - integrity sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ== +"@babel/traverse@^7.28.6", "@babel/traverse@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.0.tgz#f323d05001440253eead3c9c858adbe00b90310a" + integrity sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA== dependencies: - "@babel/code-frame" "^7.27.1" - "@babel/generator" "^7.28.5" + "@babel/code-frame" "^7.29.0" + "@babel/generator" "^7.29.0" "@babel/helper-globals" "^7.28.0" - "@babel/parser" "^7.28.5" - "@babel/template" "^7.27.2" - "@babel/types" "^7.28.5" + "@babel/parser" "^7.29.0" + "@babel/template" "^7.28.6" + "@babel/types" "^7.29.0" debug "^4.3.1" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.21.3", "@babel/types@^7.25.2", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2", "@babel/types@^7.28.4", "@babel/types@^7.28.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4": +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.21.3", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2", "@babel/types@^7.28.4", "@babel/types@^7.28.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4": version "7.28.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.5.tgz#10fc405f60897c35f07e85493c932c7b5ca0592b" integrity sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA== @@ -1191,6 +1264,14 @@ "@babel/helper-string-parser" "^7.27.1" "@babel/helper-validator-identifier" "^7.28.5" +"@babel/types@^7.28.6", "@babel/types@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.0.tgz#9f5b1e838c446e72cf3cd4b918152b8c605e37c7" + integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.28.5" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -2425,25 +2506,25 @@ resolved "https://registry.yarnpkg.com/@react-native-community/blur/-/blur-4.4.1.tgz#72cbc0be5a84022c33091683ec6888925ebcca6e" integrity sha512-XBSsRiYxE/MOEln2ayunShfJtWztHwUxLFcSL20o+HNNRnuUDv+GXkF6FmM2zE8ZUfrnhQ/zeTqvnuDPGw6O8A== -"@react-native-community/cli-clean@20.0.0": - version "20.0.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-20.0.0.tgz#e685f5404195ded69c81d1394e8c5eb332b780bc" - integrity sha512-YmdNRcT+Dp8lC7CfxSDIfPMbVPEXVFzBH62VZNbYGxjyakqAvoQUFTYPgM2AyFusAr4wDFbDOsEv88gCDwR3ig== +"@react-native-community/cli-clean@20.1.0": + version "20.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-20.1.0.tgz#c60a8f909c4269cabb785b47e43af4f8cd3fef3b" + integrity sha512-77L4DifWfxAT8ByHnkypge7GBMYpbJAjBGV+toowt5FQSGaTBDcBHCX+FFqFRukD5fH6i8sZ41Gtw+nbfCTTIA== dependencies: - "@react-native-community/cli-tools" "20.0.0" - chalk "^4.1.2" + "@react-native-community/cli-tools" "20.1.0" execa "^5.0.0" fast-glob "^3.3.2" + picocolors "^1.1.1" -"@react-native-community/cli-config-android@20.0.0": - version "20.0.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-config-android/-/cli-config-android-20.0.0.tgz#756bd8f2d5c47023964551612cc48a1fecc9a7e4" - integrity sha512-asv60qYCnL1v0QFWcG9r1zckeFlKG+14GGNyPXY72Eea7RX5Cxdx8Pb6fIPKroWH1HEWjYH9KKHksMSnf9FMKw== +"@react-native-community/cli-config-android@20.1.0": + version "20.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-config-android/-/cli-config-android-20.1.0.tgz#238be46bf2674506c8e920aa28284939234fc07c" + integrity sha512-3A01ZDyFeCALzzPcwP/fleHoP3sGNq1UX7FzxkTrOFX8RRL9ntXNXQd27E56VU4BBxGAjAJT4Utw8pcOjJceIA== dependencies: - "@react-native-community/cli-tools" "20.0.0" - chalk "^4.1.2" + "@react-native-community/cli-tools" "20.1.0" fast-glob "^3.3.2" fast-xml-parser "^4.4.1" + picocolors "^1.1.1" "@react-native-community/cli-config-android@^18.0.0": version "18.0.1" @@ -2455,15 +2536,15 @@ fast-glob "^3.3.2" fast-xml-parser "^4.4.1" -"@react-native-community/cli-config-apple@20.0.0": - version "20.0.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-config-apple/-/cli-config-apple-20.0.0.tgz#eaef1db689a4f205cf665306c04e4d717c5d7d46" - integrity sha512-PS1gNOdpeQ6w7dVu1zi++E+ix2D0ZkGC2SQP6Y/Qp002wG4se56esLXItYiiLrJkhH21P28fXdmYvTEkjSm9/Q== +"@react-native-community/cli-config-apple@20.1.0": + version "20.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-config-apple/-/cli-config-apple-20.1.0.tgz#02ee5c553c4b8a061039ca43eb9a99c2f7daf893" + integrity sha512-n6JVs8Q3yxRbtZQOy05ofeb1kGtspGN3SgwPmuaqvURF9fsuS7c4/9up2Kp9C+1D2J1remPJXiZLNGOcJvfpOA== dependencies: - "@react-native-community/cli-tools" "20.0.0" - chalk "^4.1.2" + "@react-native-community/cli-tools" "20.1.0" execa "^5.0.0" fast-glob "^3.3.2" + picocolors "^1.1.1" "@react-native-community/cli-config-apple@^18.0.0": version "18.0.1" @@ -2475,74 +2556,74 @@ execa "^5.0.0" fast-glob "^3.3.2" -"@react-native-community/cli-config@20.0.0": - version "20.0.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-config/-/cli-config-20.0.0.tgz#890e3cdb7779f936bd50f2fe2601f0fdd917b3e6" - integrity sha512-5Ky9ceYuDqG62VIIpbOmkg8Lybj2fUjf/5wK4UO107uRqejBgNgKsbGnIZgEhREcaSEOkujWrroJ9gweueLfBg== +"@react-native-community/cli-config@20.1.0": + version "20.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-config/-/cli-config-20.1.0.tgz#97f58866af4cd34d2604e3c4c120e5bf03187083" + integrity sha512-1x9rhLLR/dKKb92Lb5O0l0EmUG08FHf+ZVyVEf9M+tX+p5QIm52MRiy43R0UAZ2jJnFApxRk+N3sxoYK4Dtnag== dependencies: - "@react-native-community/cli-tools" "20.0.0" - chalk "^4.1.2" + "@react-native-community/cli-tools" "20.1.0" cosmiconfig "^9.0.0" deepmerge "^4.3.0" fast-glob "^3.3.2" joi "^17.2.1" + picocolors "^1.1.1" -"@react-native-community/cli-doctor@20.0.0": - version "20.0.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-20.0.0.tgz#4d19108dafffc4727654dc4fc17f8f170519f130" - integrity sha512-cPHspi59+Fy41FDVxt62ZWoicCZ1o34k8LAl64NVSY0lwPl+CEi78jipXJhtfkVqSTetloA8zexa/vSAcJy57Q== +"@react-native-community/cli-doctor@20.1.0": + version "20.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-20.1.0.tgz#03e2b2702b9f44b2d6d9535d265345ade7349134" + integrity sha512-QfJF1GVjA4PBrIT3SJ0vFFIu0km1vwOmLDlOYVqfojajZJ+Dnvl0f94GN1il/jT7fITAxom///XH3/URvi7YTQ== dependencies: - "@react-native-community/cli-config" "20.0.0" - "@react-native-community/cli-platform-android" "20.0.0" - "@react-native-community/cli-platform-apple" "20.0.0" - "@react-native-community/cli-platform-ios" "20.0.0" - "@react-native-community/cli-tools" "20.0.0" - chalk "^4.1.2" + "@react-native-community/cli-config" "20.1.0" + "@react-native-community/cli-platform-android" "20.1.0" + "@react-native-community/cli-platform-apple" "20.1.0" + "@react-native-community/cli-platform-ios" "20.1.0" + "@react-native-community/cli-tools" "20.1.0" command-exists "^1.2.8" deepmerge "^4.3.0" envinfo "^7.13.0" execa "^5.0.0" node-stream-zip "^1.9.1" ora "^5.4.1" + picocolors "^1.1.1" semver "^7.5.2" wcwidth "^1.0.1" yaml "^2.2.1" -"@react-native-community/cli-platform-android@20.0.0": - version "20.0.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-20.0.0.tgz#f2f6c666e8c878abf39bde1f3281198ba6e3d5b3" - integrity sha512-th3ji1GRcV6ACelgC0wJtt9daDZ+63/52KTwL39xXGoqczFjml4qERK90/ppcXU0Ilgq55ANF8Pr+UotQ2AB/A== +"@react-native-community/cli-platform-android@20.1.0": + version "20.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-20.1.0.tgz#d221a7ad0dcea320410a7ed918bf2811fd68d9fa" + integrity sha512-TeHPDThOwDppQRpndm9kCdRCBI8AMy3HSIQ+iy7VYQXL5BtZ5LfmGdusoj7nVN/ZGn0Lc6Gwts5qowyupXdeKg== dependencies: - "@react-native-community/cli-config-android" "20.0.0" - "@react-native-community/cli-tools" "20.0.0" - chalk "^4.1.2" + "@react-native-community/cli-config-android" "20.1.0" + "@react-native-community/cli-tools" "20.1.0" execa "^5.0.0" logkitty "^0.7.1" + picocolors "^1.1.1" -"@react-native-community/cli-platform-apple@20.0.0": - version "20.0.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-apple/-/cli-platform-apple-20.0.0.tgz#976f535278b6671703fce5dc91833cedd45a1040" - integrity sha512-rZZCnAjUHN1XBgiWTAMwEKpbVTO4IHBSecdd1VxJFeTZ7WjmstqA6L/HXcnueBgxrzTCRqvkRIyEQXxC1OfhGw== +"@react-native-community/cli-platform-apple@20.1.0": + version "20.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-apple/-/cli-platform-apple-20.1.0.tgz#40e5dce8cba6cfc5a970f4bac2b62d3b25908da6" + integrity sha512-0ih1hrYezSM2cuOlVnwBEFtMwtd8YgpTLmZauDJCv50rIumtkI1cQoOgLoS4tbPCj9U/Vn2a9BFH0DLFOOIacg== dependencies: - "@react-native-community/cli-config-apple" "20.0.0" - "@react-native-community/cli-tools" "20.0.0" - chalk "^4.1.2" + "@react-native-community/cli-config-apple" "20.1.0" + "@react-native-community/cli-tools" "20.1.0" execa "^5.0.0" fast-xml-parser "^4.4.1" + picocolors "^1.1.1" -"@react-native-community/cli-platform-ios@20.0.0": - version "20.0.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-20.0.0.tgz#382c1781c352ef5d4c8a6357e552a2e51a722f75" - integrity sha512-Z35M+4gUJgtS4WqgpKU9/XYur70nmj3Q65c9USyTq6v/7YJ4VmBkmhC9BticPs6wuQ9Jcv0NyVCY0Wmh6kMMYw== +"@react-native-community/cli-platform-ios@20.1.0": + version "20.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-20.1.0.tgz#6388b4453bb2bac7c46ded0546d0e43167107b0c" + integrity sha512-XN7Da9z4WsJxtqVtEzY8q2bv22OsvzaFP5zy5+phMWNoJlU4lf7IvBSxqGYMpQ9XhYP7arDw5vmW4W34s06rnA== dependencies: - "@react-native-community/cli-platform-apple" "20.0.0" + "@react-native-community/cli-platform-apple" "20.1.0" -"@react-native-community/cli-server-api@20.0.0": - version "20.0.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-20.0.0.tgz#67399e213341449f1785476a35753c58bae8a260" - integrity sha512-Ves21bXtjUK3tQbtqw/NdzpMW1vR2HvYCkUQ/MXKrJcPjgJnXQpSnTqHXz6ZdBlMbbwLJXOhSPiYzxb5/v4CDg== +"@react-native-community/cli-server-api@20.1.0": + version "20.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-20.1.0.tgz#048d25afcd6e6532530cdea4f31d9b2becb9c9f4" + integrity sha512-Tb415Oh8syXNT2zOzLzFkBXznzGaqKCiaichxKzGCDKg6JGHp3jSuCmcTcaPeYC7oc32n/S3Psw7798r4Q/7lA== dependencies: - "@react-native-community/cli-tools" "20.0.0" + "@react-native-community/cli-tools" "20.1.0" body-parser "^1.20.3" compression "^1.7.1" connect "^3.6.5" @@ -2569,47 +2650,47 @@ prompts "^2.4.2" semver "^7.5.2" -"@react-native-community/cli-tools@20.0.0": - version "20.0.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-20.0.0.tgz#a20a80e58da07dd0cc02c897e8dada21bd289bea" - integrity sha512-akSZGxr1IajJ8n0YCwQoA3DI0HttJ0WB7M3nVpb0lOM+rJpsBN7WG5Ft+8ozb6HyIPX+O+lLeYazxn5VNG/Xhw== +"@react-native-community/cli-tools@20.1.0": + version "20.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-20.1.0.tgz#0046f2ad4826b663c1b9ce5663b6b91830fb51b9" + integrity sha512-/YmzHGOkY6Bgrv4OaA1L8rFqsBlQd1EB2/ipAoKPiieV0EcB5PUamUSuNeFU3sBZZTYQCUENwX4wgOHgFUlDnQ== dependencies: "@vscode/sudo-prompt" "^9.0.0" appdirsjs "^1.2.4" - chalk "^4.1.2" execa "^5.0.0" find-up "^5.0.0" launch-editor "^2.9.1" mime "^2.4.1" ora "^5.4.1" + picocolors "^1.1.1" prompts "^2.4.2" semver "^7.5.2" -"@react-native-community/cli-types@20.0.0": - version "20.0.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-20.0.0.tgz#f38988d21538a0537757782e3e44f088e6715708" - integrity sha512-7J4hzGWOPTBV1d30Pf2NidV+bfCWpjfCOiGO3HUhz1fH4MvBM0FbbBmE9LE5NnMz7M8XSRSi68ZGYQXgLBB2Qw== +"@react-native-community/cli-types@20.1.0": + version "20.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-20.1.0.tgz#00fe43c59e1e79e0a453e83ce4dd50b5494c1f88" + integrity sha512-D0kDspcwgbVXyNjwicT7Bb1JgXjijTw1JJd+qxyF/a9+sHv7TU4IchV+gN38QegeXqVyM4Ym7YZIvXMFBmyJqA== dependencies: joi "^17.2.1" -"@react-native-community/cli@20.0.0": - version "20.0.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-20.0.0.tgz#a9155bd63e0cf45aafb4cc49c390ceb3bde64c74" - integrity sha512-/cMnGl5V1rqnbElY1Fvga1vfw0d3bnqiJLx2+2oh7l9ulnXfVRWb5tU2kgBqiMxuDOKA+DQoifC9q/tvkj5K2w== - dependencies: - "@react-native-community/cli-clean" "20.0.0" - "@react-native-community/cli-config" "20.0.0" - "@react-native-community/cli-doctor" "20.0.0" - "@react-native-community/cli-server-api" "20.0.0" - "@react-native-community/cli-tools" "20.0.0" - "@react-native-community/cli-types" "20.0.0" - chalk "^4.1.2" +"@react-native-community/cli@20.1.0": + version "20.1.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-20.1.0.tgz#d4b9a1bcbbd4ad6b1462acb3af474c87b5de793c" + integrity sha512-441WsVtRe4nGJ9OzA+QMU1+22lA6Q2hRWqqIMKD0wjEMLqcSfOZyu2UL9a/yRpL/dRpyUsU4n7AxqKfTKO/Csg== + dependencies: + "@react-native-community/cli-clean" "20.1.0" + "@react-native-community/cli-config" "20.1.0" + "@react-native-community/cli-doctor" "20.1.0" + "@react-native-community/cli-server-api" "20.1.0" + "@react-native-community/cli-tools" "20.1.0" + "@react-native-community/cli-types" "20.1.0" commander "^9.4.1" deepmerge "^4.3.0" execa "^5.0.0" find-up "^5.0.0" fs-extra "^8.1.0" graceful-fs "^4.1.3" + picocolors "^1.1.1" prompts "^2.4.2" semver "^7.5.2" @@ -2655,23 +2736,23 @@ resolved "https://registry.yarnpkg.com/@react-native-masked-view/masked-view/-/masked-view-0.3.2.tgz#7064533a573e3539ec912f59c1f457371bf49dd9" integrity sha512-XwuQoW7/GEgWRMovOQtX3A4PrXhyaZm0lVUiY8qJDvdngjLms9Cpdck6SmGAUNqQwcj2EadHC1HwL0bEyoa/SQ== -"@react-native/assets-registry@0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.83.1.tgz#d210065b8d7939660f845fba3c6d9e5aa5998d13" - integrity sha512-AT7/T6UwQqO39bt/4UL5EXvidmrddXrt0yJa7ENXndAv+8yBzMsZn6fyiax6+ERMt9GLzAECikv3lj22cn2wJA== +"@react-native/assets-registry@0.85.3": + version "0.85.3" + resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.85.3.tgz#e28da0d296120b9677c3cb9f4ebc92b636ac987e" + integrity sha512-u9ZiYP23vA2IFtdFQFmetzSmk6SM0xgKIoiOsr1hXNHjHaLhOm+/Ph1ud57wX6+Dbwdzx8coJgnzSKL3W21PCg== -"@react-native/babel-plugin-codegen@0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.83.1.tgz#56418c0eeab55800a8fa35333598e71495b9053f" - integrity sha512-VPj8O3pG1ESjZho9WVKxqiuryrotAECPHGF5mx46zLUYNTWR5u9OMUXYk7LeLy+JLWdGEZ2Gn3KoXeFZbuqE+g== +"@react-native/babel-plugin-codegen@0.85.3": + version "0.85.3" + resolved "https://registry.yarnpkg.com/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.85.3.tgz#85584812e08e04b0b8f443ee732f787017eaf254" + integrity sha512-Wc94zGfeFG8Njf9SHMPfYZP04kjigkOps6F1TYTvd7ZVXuGxqseCDgxc50LWcOhOCLypI9n3oVVqz81C3p44ZA== dependencies: - "@babel/traverse" "^7.25.3" - "@react-native/codegen" "0.83.1" + "@babel/traverse" "^7.29.0" + "@react-native/codegen" "0.85.3" -"@react-native/babel-preset@0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.83.1.tgz#a8bc9e7548a8f400ce6fb97c7e76a8ae80aa015c" - integrity sha512-xI+tbsD4fXcI6PVU4sauRCh0a5fuLQC849SINmU2J5wP8kzKu4Ye0YkGjUW3mfGrjaZcjkWmF6s33jpyd3gdTw== +"@react-native/babel-preset@0.85.3": + version "0.85.3" + resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.85.3.tgz#b4e226c9b996e38cee51bdc1055d4a2ba24a733b" + integrity sha512-fD7fxEhkJB/aF57tWoXjaAWpklfrExYZS3k6aXPP3BQ77DZY7gvf/b7dbirwjID6NVnP1JDRJyTuPBGr0K/vlw== dependencies: "@babel/core" "^7.25.2" "@babel/plugin-proposal-export-default-from" "^7.24.7" @@ -2679,27 +2760,19 @@ "@babel/plugin-syntax-export-default-from" "^7.24.7" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-transform-arrow-functions" "^7.24.7" "@babel/plugin-transform-async-generator-functions" "^7.25.4" "@babel/plugin-transform-async-to-generator" "^7.24.7" "@babel/plugin-transform-block-scoping" "^7.25.0" "@babel/plugin-transform-class-properties" "^7.25.4" "@babel/plugin-transform-classes" "^7.25.4" - "@babel/plugin-transform-computed-properties" "^7.24.7" "@babel/plugin-transform-destructuring" "^7.24.8" "@babel/plugin-transform-flow-strip-types" "^7.25.2" "@babel/plugin-transform-for-of" "^7.24.7" - "@babel/plugin-transform-function-name" "^7.25.1" - "@babel/plugin-transform-literals" "^7.25.2" - "@babel/plugin-transform-logical-assignment-operators" "^7.24.7" "@babel/plugin-transform-modules-commonjs" "^7.24.8" "@babel/plugin-transform-named-capturing-groups-regex" "^7.24.7" "@babel/plugin-transform-nullish-coalescing-operator" "^7.24.7" - "@babel/plugin-transform-numeric-separator" "^7.24.7" - "@babel/plugin-transform-object-rest-spread" "^7.24.7" "@babel/plugin-transform-optional-catch-binding" "^7.24.7" "@babel/plugin-transform-optional-chaining" "^7.24.8" - "@babel/plugin-transform-parameters" "^7.24.7" "@babel/plugin-transform-private-methods" "^7.24.7" "@babel/plugin-transform-private-property-in-object" "^7.24.7" "@babel/plugin-transform-react-display-name" "^7.24.7" @@ -2708,66 +2781,63 @@ "@babel/plugin-transform-react-jsx-source" "^7.24.7" "@babel/plugin-transform-regenerator" "^7.24.7" "@babel/plugin-transform-runtime" "^7.24.7" - "@babel/plugin-transform-shorthand-properties" "^7.24.7" - "@babel/plugin-transform-spread" "^7.24.7" - "@babel/plugin-transform-sticky-regex" "^7.24.7" "@babel/plugin-transform-typescript" "^7.25.2" "@babel/plugin-transform-unicode-regex" "^7.24.7" - "@babel/template" "^7.25.0" - "@react-native/babel-plugin-codegen" "0.83.1" - babel-plugin-syntax-hermes-parser "0.32.0" + "@react-native/babel-plugin-codegen" "0.85.3" + babel-plugin-syntax-hermes-parser "0.33.3" babel-plugin-transform-flow-enums "^0.0.2" react-refresh "^0.14.0" -"@react-native/codegen@0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.83.1.tgz#cd502b801b23b0cf2da079c0e482ccb145c944d3" - integrity sha512-FpRxenonwH+c2a5X5DZMKUD7sCudHxB3eSQPgV9R+uxd28QWslyAWrpnJM/Az96AEksHnymDzEmzq2HLX5nb+g== +"@react-native/codegen@0.85.3": + version "0.85.3" + resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.85.3.tgz#3168a42d240b66d1597f8e292ce71171fabb3b1c" + integrity sha512-/JkS1lGLyzBWP1FbgDwaqEf7qShIC6pUC1M0a/YMAd/v4iqR24MRkQWe7jkYvcBQ2LpEhs5NGE9InhxSv21zCA== dependencies: "@babel/core" "^7.25.2" - "@babel/parser" "^7.25.3" - glob "^7.1.1" - hermes-parser "0.32.0" + "@babel/parser" "^7.29.0" + hermes-parser "0.33.3" invariant "^2.2.4" nullthrows "^1.1.1" + tinyglobby "^0.2.15" yargs "^17.6.2" -"@react-native/community-cli-plugin@0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@react-native/community-cli-plugin/-/community-cli-plugin-0.83.1.tgz#5bbb419069b70baf5c3a908651cde432535d743d" - integrity sha512-FqR1ftydr08PYlRbrDF06eRiiiGOK/hNmz5husv19sK6iN5nHj1SMaCIVjkH/a5vryxEddyFhU6PzO/uf4kOHg== +"@react-native/community-cli-plugin@0.85.3": + version "0.85.3" + resolved "https://registry.yarnpkg.com/@react-native/community-cli-plugin/-/community-cli-plugin-0.85.3.tgz#bc9008fe823bca059ab330861253e9be57f8cc46" + integrity sha512-fs85dmbIqNmtzEixDb0g+q6R3Vt4H9eAt8/inIZdDKfjN76+sUJA2r1nxODQ76bU23MrIbz8sI7KFBPaWk/zQw== dependencies: - "@react-native/dev-middleware" "0.83.1" + "@react-native/dev-middleware" "0.85.3" debug "^4.4.0" invariant "^2.2.4" - metro "^0.83.3" - metro-config "^0.83.3" - metro-core "^0.83.3" + metro "^0.84.3" + metro-config "^0.84.3" + metro-core "^0.84.3" semver "^7.1.3" -"@react-native/debugger-frontend@0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@react-native/debugger-frontend/-/debugger-frontend-0.83.1.tgz#bd46dfdb6753d8521181b07ab7a5e48a2849d791" - integrity sha512-01Rn3goubFvPjHXONooLmsW0FLxJDKIUJNOlOS0cPtmmTIx9YIjxhe/DxwHXGk7OnULd7yl3aYy7WlBsEd5Xmg== +"@react-native/debugger-frontend@0.85.3": + version "0.85.3" + resolved "https://registry.yarnpkg.com/@react-native/debugger-frontend/-/debugger-frontend-0.85.3.tgz#c8c66a5bb766b22466ffb0adaf0f0074bd38b482" + integrity sha512-uAu7rM5o/Np1zgp6fi5zM1sP1aB8DcS7DdOLcj/TkSutOAjkMqqd2lWt1/+3S7qXexRHVK5XcP+o3VXo4L/V0A== -"@react-native/debugger-shell@0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@react-native/debugger-shell/-/debugger-shell-0.83.1.tgz#81ae1edee83f9e68bde1739f18e368614317ee22" - integrity sha512-d+0w446Hxth5OP/cBHSSxOEpbj13p2zToUy6e5e3tTERNJ8ueGlW7iGwGTrSymNDgXXFjErX+dY4P4/3WokPIQ== +"@react-native/debugger-shell@0.85.3": + version "0.85.3" + resolved "https://registry.yarnpkg.com/@react-native/debugger-shell/-/debugger-shell-0.85.3.tgz#ad755fc280942c240cd833916ddcf89a86a34b1f" + integrity sha512-/jRAaT9boiCttIcEwS02WPwYkUihqsjSaK/TMtHz05vT6uMgac9PaQt5kzBQLIABv5aEIa5gtrMmKVz49MjkjQ== dependencies: cross-spawn "^7.0.6" + debug "^4.4.0" fb-dotslash "0.5.8" -"@react-native/dev-middleware@0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.83.1.tgz#78c5efed072e6d31c3927cc93e957a6f39d6485c" - integrity sha512-QJaSfNRzj3Lp7MmlCRgSBlt1XZ38xaBNXypXAp/3H3OdFifnTZOeYOpFmcpjcXYnDqkxetuwZg8VL65SQhB8dg== +"@react-native/dev-middleware@0.85.3": + version "0.85.3" + resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.85.3.tgz#a5818ea674b0bbead230555697748b215ef3fc3a" + integrity sha512-JYzBiT4A8w+KQt+dOD5v+ti+tDrGoPnsSTuApq3Ls4RB5sfWbDlYMyz3dbc8qBIHz9tv0sQ5+eOu6Xwqzr5AQA== dependencies: "@isaacs/ttlcache" "^1.4.1" - "@react-native/debugger-frontend" "0.83.1" - "@react-native/debugger-shell" "0.83.1" + "@react-native/debugger-frontend" "0.85.3" + "@react-native/debugger-shell" "0.85.3" chrome-launcher "^0.15.2" - chromium-edge-launcher "^0.2.0" + chromium-edge-launcher "^0.3.0" connect "^3.6.5" debug "^4.4.0" invariant "^2.2.4" @@ -2776,73 +2846,84 @@ serve-static "^1.16.2" ws "^7.5.10" -"@react-native/eslint-config@0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@react-native/eslint-config/-/eslint-config-0.83.1.tgz#42d811b2cda253e4b3d8ccce6c49ac0f0263313e" - integrity sha512-fo3DmFywzkpVZgIji9vR93kN7sSAY122ZIB7VcudgKlmD/YFxJ5Yi+ZNiWYl6aprLexxOWjROgHXNP0B0XaAng== +"@react-native/eslint-config@0.85.3": + version "0.85.3" + resolved "https://registry.yarnpkg.com/@react-native/eslint-config/-/eslint-config-0.85.3.tgz#15b832a7bfd00ff7a9267860167ae678fe46cd2b" + integrity sha512-CvE+1H4be7eZXpadoBDnz7B3ooK2Tl/tvbW2+odrsR22Afs2Q4m9fJtKD8lD8/LCufttsT5pnGIhP/ugO6x/mw== dependencies: "@babel/core" "^7.25.2" "@babel/eslint-parser" "^7.25.1" - "@react-native/eslint-plugin" "0.83.1" + "@react-native/eslint-plugin" "0.85.3" "@typescript-eslint/eslint-plugin" "^8.36.0" "@typescript-eslint/parser" "^8.36.0" eslint-config-prettier "^8.5.0" eslint-plugin-eslint-comments "^3.2.0" eslint-plugin-ft-flow "^2.0.1" eslint-plugin-jest "^29.0.1" - eslint-plugin-react "^7.30.1" + eslint-plugin-react "^7.37.5" eslint-plugin-react-hooks "^7.0.1" - eslint-plugin-react-native "^4.0.0" + eslint-plugin-react-native "^5.0.0" -"@react-native/eslint-plugin@0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@react-native/eslint-plugin/-/eslint-plugin-0.83.1.tgz#da5fd6be5b0b458c8d8cf3e8f67cc6415b87216d" - integrity sha512-nKd/FONY8aIIjtjEqI2ScvgJYeblBgdnwseRHlIC+Nm3f3tuOifUrHFtWBJznlrKFJcme31Tl7qiryE2SruLYw== +"@react-native/eslint-plugin@0.85.3": + version "0.85.3" + resolved "https://registry.yarnpkg.com/@react-native/eslint-plugin/-/eslint-plugin-0.85.3.tgz#4b63f8c84173c0c7651f89832e947b0077e7b403" + integrity sha512-xUt6BZkIEPxNpsHsZc/FsjsyslrCW5NrGZDFIayyxQxg0zwwd0nXWFZ0qDfCeA75qYYTnboOwIuDIqykzJp61Q== -"@react-native/gradle-plugin@0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.83.1.tgz#52615a9fc2e875f4afd8dca8c165ffb98709a65c" - integrity sha512-6ESDnwevp1CdvvxHNgXluil5OkqbjkJAkVy7SlpFsMGmVhrSxNAgD09SSRxMNdKsnLtzIvMsFCzyHLsU/S4PtQ== +"@react-native/gradle-plugin@0.85.3": + version "0.85.3" + resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.85.3.tgz#79f94aa38bc68be9b331cfd197de5bb53109465a" + integrity sha512-39dY2j50Q1pntejzwt3XL7vwXtrj8jcIfHq6E+gyu3jzYxZJVvMkMutQ39vSg6zinIQOX36oQDhidXUbCXzgoA== -"@react-native/js-polyfills@0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.83.1.tgz#2544b07c8b39cdbd7fea7a37ecfbd79354b297be" - integrity sha512-qgPpdWn/c5laA+3WoJ6Fak8uOm7CG50nBsLlPsF8kbT7rUHIVB9WaP6+GPsoKV/H15koW7jKuLRoNVT7c3Ht3w== +"@react-native/jest-preset@0.85.3": + version "0.85.3" + resolved "https://registry.yarnpkg.com/@react-native/jest-preset/-/jest-preset-0.85.3.tgz#e7ce02f0fdf2b51d06097598f24a3e4f234478bb" + integrity sha512-ALPSrM0q2fU+5AXcOXzDKx7rxVKPMvygAZfsTWLdrGRVWIqf/HEfM0R8euQqIKUqmEuQ1TxMWN+px3h6gc4vow== + dependencies: + "@jest/create-cache-key-function" "^29.7.0" + "@react-native/js-polyfills" "0.85.3" + babel-jest "^29.7.0" + jest-environment-node "^29.7.0" + regenerator-runtime "^0.13.2" -"@react-native/metro-babel-transformer@0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.83.1.tgz#cf2697ca0773a3d1b9e99a85556c2c7142df8023" - integrity sha512-fqt6DHWX1GBGDKa5WJOjDtPPy2M9lkYVLn59fBeFQ0GXhBRzNbUh8JzWWI/Q2CLDZ2tgKCcwaiXJ1OHWVd2BCQ== +"@react-native/js-polyfills@0.85.3": + version "0.85.3" + resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.85.3.tgz#f3eef60ee619f51f78f8db7489abc192e685508f" + integrity sha512-U2+aMshIXf1uFn77tpBb/xhHWB9vkVrMpt7kkucAugF8hJKYTDGB587X7WwelHduK2KBfhl4giSv0rzZGoef9A== + +"@react-native/metro-babel-transformer@0.85.3": + version "0.85.3" + resolved "https://registry.yarnpkg.com/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.85.3.tgz#c97cde6699b52e099c35c9ace00d25a6b790a0ca" + integrity sha512-omuKq+r7jM4XvCMIlNMPP7Up3SyB8o5EAdZtF7YXniKyq7UOMBqhYHFqgsdOXr0lT+3ADf7VCJG3sb82jlBrrQ== dependencies: "@babel/core" "^7.25.2" - "@react-native/babel-preset" "0.83.1" - hermes-parser "0.32.0" + "@react-native/babel-preset" "0.85.3" + hermes-parser "0.33.3" nullthrows "^1.1.1" -"@react-native/metro-config@0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@react-native/metro-config/-/metro-config-0.83.1.tgz#7cec0e82cfd5b556093b7f3fbc0e54ced4d1cf69" - integrity sha512-1rjYZf62fCm6QAinHmRAKnJxIypX0VF/zBPd0qWvWABMZugrS0eACuIbk9Wk0StBod4yL8KnwEJyg77ak8xYzQ== +"@react-native/metro-config@0.85.3": + version "0.85.3" + resolved "https://registry.yarnpkg.com/@react-native/metro-config/-/metro-config-0.85.3.tgz#0c1fe49b4a579366501d5b776f94a4d371cbbb0d" + integrity sha512-sVo6HepUmCcpdfozEf91lA0FjpLNNZYu/Zi9FiYiAQTK8pzATXDVTqhvdxpFrQn435p5eUTSbllvbH/KN+bnyA== dependencies: - "@react-native/js-polyfills" "0.83.1" - "@react-native/metro-babel-transformer" "0.83.1" - metro-config "^0.83.3" - metro-runtime "^0.83.3" + "@react-native/js-polyfills" "0.85.3" + "@react-native/metro-babel-transformer" "0.85.3" + metro-config "^0.84.3" + metro-runtime "^0.84.3" -"@react-native/normalize-colors@0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.83.1.tgz#f33f6abf9f3fd9d20f211e669657346e0563f5d1" - integrity sha512-84feABbmeWo1kg81726UOlMKAhcQyFXYz2SjRKYkS78QmfhVDhJ2o/ps1VjhFfBz0i/scDwT1XNv9GwmRIghkg== +"@react-native/normalize-colors@0.85.3": + version "0.85.3" + resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.85.3.tgz#681f4be6c0a57b5bcf16b993b3bc96e5a45bf3a2" + integrity sha512-hj0PScZEhIbcOvQV5yMKX3ha4XEIOy/SVE1Rrpp0beW0dpNLOgSC7KDxGewmDnIHK9YdQUXGY9eMEfShUMIaZw== -"@react-native/typescript-config@0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@react-native/typescript-config/-/typescript-config-0.83.1.tgz#16d2291be94511df53c3f932aefd2cc36ece99ee" - integrity sha512-y83qd7fmlZG+EJoOyKEmAXifdjN1csNhcfpyxDvgaIUNO/pw2ws3MV/wp+ERQ8F6JIuAu1zcfyCy1/pEA7tC9g== +"@react-native/typescript-config@0.85.3": + version "0.85.3" + resolved "https://registry.yarnpkg.com/@react-native/typescript-config/-/typescript-config-0.85.3.tgz#d2d4f0a4ee9a07d3336c5c3e35bedc9cb5a2e569" + integrity sha512-F2Ign3lv/99R5HMDiaQE6NpRdopn87VuXgfHABSk0iwzouLFk1fcwaMkJUmjhnxrQagsUwxOWp4WTPwEvRRazQ== -"@react-native/virtualized-lists@0.83.1": - version "0.83.1" - resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.83.1.tgz#97e66c6c7d32112cf8da0ddbb29361913a9a8820" - integrity sha512-MdmoAbQUTOdicCocm5XAFDJWsswxk7hxa6ALnm6Y88p01HFML0W593hAn6qOt9q6IM1KbAcebtH6oOd4gcQy8w== +"@react-native/virtualized-lists@0.85.3": + version "0.85.3" + resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.85.3.tgz#0fe478a10505d7fd3cfd39de26b6673a1fd0e091" + integrity sha512-dsCjI//OIPEUJMyNHp4l7zNLVjCx7bcaRUceOCkU+IB17hkbtbGWvi7HjGFSzy7FJGmS/MOlcfpb72xXiy1Oig== dependencies: invariant "^2.2.4" nullthrows "^1.1.1" @@ -4464,7 +4545,15 @@ abort-controller@^3.0.0: dependencies: event-target-shim "^5.0.0" -accepts@^1.3.7, accepts@~1.3.8: +accepts@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-2.0.0.tgz#bbcf4ba5075467f3f2131eab3cffc73c2f5d7895" + integrity sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng== + dependencies: + mime-types "^3.0.0" + negotiator "^1.0.0" + +accepts@~1.3.8: version "1.3.8" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== @@ -4825,12 +4914,12 @@ babel-plugin-polyfill-regenerator@^0.6.5: dependencies: "@babel/helper-define-polyfill-provider" "^0.6.5" -babel-plugin-syntax-hermes-parser@0.32.0: - version "0.32.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.32.0.tgz#06f7452bf91adf6cafd7c98e7467404d4eb65cec" - integrity sha512-m5HthL++AbyeEA2FcdwOLfVFvWYECOBObLHNqdR8ceY4TsEdn4LdX2oTvbB2QJSSElE2AWA/b2MXZ/PF/CqLZg== +babel-plugin-syntax-hermes-parser@0.33.3: + version "0.33.3" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.33.3.tgz#07602f8163cc7e63c4ec17d47467f2a3c5db70e9" + integrity sha512-/Z9xYdaJ1lC0pT9do6TqCqhOSLfZ5Ot8D5za1p+feEfWYupCOfGbhhEXN9r2ZgJtDNUNRw/Z+T2CvAGKBqtqWA== dependencies: - hermes-parser "0.32.0" + hermes-parser "0.33.3" babel-plugin-transform-flow-enums@^0.0.2: version "0.0.2" @@ -5310,17 +5399,16 @@ chrome-launcher@^0.15.2: is-wsl "^2.2.0" lighthouse-logger "^1.0.0" -chromium-edge-launcher@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/chromium-edge-launcher/-/chromium-edge-launcher-0.2.0.tgz#0c378f28c99aefc360705fa155de0113997f62fc" - integrity sha512-JfJjUnq25y9yg4FABRRVPmBGWPZZi+AQXT4mxupb67766/0UlhG8PAZCz6xzEMXTbW3CsSoE8PcCWA49n35mKg== +chromium-edge-launcher@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/chromium-edge-launcher/-/chromium-edge-launcher-0.3.0.tgz#34d5ca8142fc059ea2b4482bdcb184393a399ffe" + integrity sha512-p03azHlGjtyRvFEee3cyvtsRYdniSkwjkzmM/KmVnqT5d7QkkwpJBhis/zCLMYdQMVJ5tt140TBNqqrZPaWeFA== dependencies: "@types/node" "*" escape-string-regexp "^4.0.0" is-wsl "^2.2.0" lighthouse-logger "^1.0.0" mkdirp "^1.0.4" - rimraf "^3.0.2" ci-info@^2.0.0: version "2.0.0" @@ -5528,7 +5616,7 @@ content-type@~1.0.5: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== -convert-source-map@2.0.0, convert-source-map@^2.0.0: +convert-source-map@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== @@ -6440,14 +6528,14 @@ eslint-plugin-react-native-globals@^0.1.1: resolved "https://registry.yarnpkg.com/eslint-plugin-react-native-globals/-/eslint-plugin-react-native-globals-0.1.2.tgz#ee1348bc2ceb912303ce6bdbd22e2f045ea86ea2" integrity sha512-9aEPf1JEpiTjcFAmmyw8eiIXmcNZOqaZyHO77wgm0/dWfT/oxC1SrIq8ET38pMxHYrcB6Uew+TzUVsBeczF88g== -eslint-plugin-react-native@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-native/-/eslint-plugin-react-native-4.1.0.tgz#5343acd3b2246bc1b857ac38be708f070d18809f" - integrity sha512-QLo7rzTBOl43FvVqDdq5Ql9IoElIuTdjrz9SKAXCvULvBoRZ44JGSkx9z4999ZusCsb4rK3gjS8gOGyeYqZv2Q== +eslint-plugin-react-native@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-native/-/eslint-plugin-react-native-5.0.0.tgz#2ee990ba4967c557183b31121578547fb5c02d5d" + integrity sha512-VyWlyCC/7FC/aONibOwLkzmyKg4j9oI8fzrk9WYNs4I8/m436JuOTAFwLvEn1CVvc7La4cPfbCyspP4OYpP52Q== dependencies: eslint-plugin-react-native-globals "^0.1.1" -eslint-plugin-react@^7.30.1: +eslint-plugin-react@^7.37.5: version "7.37.5" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz#2975511472bdda1b272b34d779335c9b0e877065" integrity sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA== @@ -7126,7 +7214,7 @@ glob@^10.4.2: package-json-from-dist "^1.0.0" path-scurry "^1.11.1" -glob@^7.1.1, glob@^7.1.3, glob@^7.1.4: +glob@^7.1.3, glob@^7.1.4: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -7292,27 +7380,39 @@ he@1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -hermes-compiler@0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/hermes-compiler/-/hermes-compiler-0.14.0.tgz#ec0ec83132ab5954e7bd2c74e6331752742f188f" - integrity sha512-clxa193o+GYYwykWVFfpHduCATz8fR5jvU7ngXpfKHj+E9hr9vjLNtdLSEe8MUbObvVexV3wcyxQ00xTPIrB1Q== +hermes-compiler@250829098.0.10: + version "250829098.0.10" + resolved "https://registry.yarnpkg.com/hermes-compiler/-/hermes-compiler-250829098.0.10.tgz#b31cae9a2517ee361c73966f76a556a1029af52b" + integrity sha512-TcRlZ0/TlyfJqquRFAWoyElVNnkdYRi/sEp4/Qy8/GYxjg8j2cS9D4MjuaQ+qimkmLN7AmO+44IznRf06mAr0w== hermes-estree@0.25.1: version "0.25.1" resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.25.1.tgz#6aeec17d1983b4eabf69721f3aa3eb705b17f480" integrity sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw== -hermes-estree@0.32.0: - version "0.32.0" - resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.32.0.tgz#bb7da6613ab8e67e334a1854ea1e209f487d307b" - integrity sha512-KWn3BqnlDOl97Xe1Yviur6NbgIZ+IP+UVSpshlZWkq+EtoHg6/cwiDj/osP9PCEgFE15KBm1O55JRwbMEm5ejQ== +hermes-estree@0.33.3: + version "0.33.3" + resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.33.3.tgz#6d6b593d4b471119772c82bdb0212dfadabb6f17" + integrity sha512-6kzYZHCk8Fy1Uc+t3HGYyJn3OL4aeqKLTyina4UFtWl8I0kSL7OmKThaiX+Uh2f8nGw3mo4Ifxg0M5Zk3/Oeqg== + +hermes-estree@0.35.0: + version "0.35.0" + resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.35.0.tgz#767cce0b14a68b4bc06cd5db7efe889f6188c565" + integrity sha512-xVx5Opwy8Oo1I5yGpVRhCvWL/iV3M+ylksSKVNlxxD90cpDpR/AR1jLYqK8HWihm065a6UI3HeyAmYzwS8NOOg== + +hermes-parser@0.33.3: + version "0.33.3" + resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.33.3.tgz#da50ababb7a5ab636d339e7b2f6e3848e217e09d" + integrity sha512-Yg3HgaG4CqgyowtYjX/FsnPAuZdHOqSMtnbpylbptsQ9nwwSKsy6uRWcGO5RK0EqiX12q8HvDWKgeAVajRO5DA== + dependencies: + hermes-estree "0.33.3" -hermes-parser@0.32.0: - version "0.32.0" - resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.32.0.tgz#7916984ef6fdce62e7415d354cf35392061cd303" - integrity sha512-g4nBOWFpuiTqjR3LZdRxKUkij9iyveWeuks7INEsMX741f3r9xxrOe8TeQfUxtda0eXmiIFiMQzoeSQEno33Hw== +hermes-parser@0.35.0: + version "0.35.0" + resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.35.0.tgz#7625ec2f34ab897c2a17a7bea9788d136d5fd8c9" + integrity sha512-9JLjeHxBx8T4CAsydZR49PNZUaix+WpQJwu9p2010lu+7Kwl6D/7wYFFJxoz+aXkaaClp9Zfg6W6/zVlSJORaA== dependencies: - hermes-estree "0.32.0" + hermes-estree "0.35.0" hermes-parser@^0.25.1: version "0.25.1" @@ -8625,60 +8725,61 @@ merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -metro-babel-transformer@0.83.3: - version "0.83.3" - resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.83.3.tgz#d8c134615530c9ee61364526d44ca4bb0c5343ea" - integrity sha512-1vxlvj2yY24ES1O5RsSIvg4a4WeL7PFXgKOHvXTXiW0deLvQr28ExXj6LjwCCDZ4YZLhq6HddLpZnX4dEdSq5g== +metro-babel-transformer@0.84.4: + version "0.84.4" + resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.84.4.tgz#2d7de9bd4e5998c8c0530fe05eef714d7c10f9cf" + integrity sha512-rvCfz8snl9h20VcvpOHxZuHP1SlAkv4HXbzw7nyyVwu6Eqo5PRerbakQ9XmUCOsRy70spJ37O+G1TK8oMzo48g== dependencies: "@babel/core" "^7.25.2" flow-enums-runtime "^0.0.6" - hermes-parser "0.32.0" + hermes-parser "0.35.0" + metro-cache-key "0.84.4" nullthrows "^1.1.1" -metro-cache-key@0.83.3: - version "0.83.3" - resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.83.3.tgz#ae6c5d4eb1ad8d06a92bf7294ca730a8d880b573" - integrity sha512-59ZO049jKzSmvBmG/B5bZ6/dztP0ilp0o988nc6dpaDsU05Cl1c/lRf+yx8m9WW/JVgbmfO5MziBU559XjI5Zw== +metro-cache-key@0.84.4: + version "0.84.4" + resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.84.4.tgz#52059d32da68ef2e06d5a3d4770defdc6d8bad77" + integrity sha512-wVO79aGrkYImpnaVS4+d5RrRBRPX31QtvKB3wKGBuiNSznduZTQHzsrJZRroFJSwnygrzdsGUtDQPuqqFjFdvw== dependencies: flow-enums-runtime "^0.0.6" -metro-cache@0.83.3: - version "0.83.3" - resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.83.3.tgz#f1245cc48570c47d8944495e61d67f0228f10172" - integrity sha512-3jo65X515mQJvKqK3vWRblxDEcgY55Sk3w4xa6LlfEXgQ9g1WgMh9m4qVZVwgcHoLy0a2HENTPCCX4Pk6s8c8Q== +metro-cache@0.84.4: + version "0.84.4" + resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.84.4.tgz#026476edb629a84650efd7b4245bbc600b3b0eb7" + integrity sha512-gpcFQdSLUwUCk71saKoE64jLFbx2nwTfVCcPSULMNT8QYq0p1eZZE29Jvd0HtT/UlhC3ZOutLxJME5xqD2JUZg== dependencies: exponential-backoff "^3.1.1" flow-enums-runtime "^0.0.6" https-proxy-agent "^7.0.5" - metro-core "0.83.3" + metro-core "0.84.4" -metro-config@0.83.3, metro-config@^0.83.3: - version "0.83.3" - resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.83.3.tgz#a30e7a69b5cf8c4ac4c4b68b1b4c33649ae129a2" - integrity sha512-mTel7ipT0yNjKILIan04bkJkuCzUUkm2SeEaTads8VfEecCh+ltXchdq6DovXJqzQAXuR2P9cxZB47Lg4klriA== +metro-config@0.84.4, metro-config@^0.84.3: + version "0.84.4" + resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.84.4.tgz#456190b984a4ce16eb10448a3c726880cec895e9" + integrity sha512-PMotGDjXcXLWo2TMRH+VR99phFNgYTwqh4OoieIKK3yTJa1Jmkl+fZJxDO0jfBvNF+WESHciHvpNuBtXaF3B0Q== dependencies: connect "^3.6.5" flow-enums-runtime "^0.0.6" jest-validate "^29.7.0" - metro "0.83.3" - metro-cache "0.83.3" - metro-core "0.83.3" - metro-runtime "0.83.3" + metro "0.84.4" + metro-cache "0.84.4" + metro-core "0.84.4" + metro-runtime "0.84.4" yaml "^2.6.1" -metro-core@0.83.3, metro-core@^0.83.3: - version "0.83.3" - resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.83.3.tgz#007e93f7d1983777da8988dfb103ad897c9835b8" - integrity sha512-M+X59lm7oBmJZamc96usuF1kusd5YimqG/q97g4Ac7slnJ3YiGglW5CsOlicTR5EWf8MQFxxjDoB6ytTqRe8Hw== +metro-core@0.84.4, metro-core@^0.84.3: + version "0.84.4" + resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.84.4.tgz#e4afffab9bd2e9b304c89c59322344d59911c31b" + integrity sha512-HONpWC5LGXZn3ffkd4Hu6AIrfE7j4Z0g0wMo/goV24WOB3lhuFZ40KgvaDiSw8iyQHloMYay5N/wPX+z8oN/PQ== dependencies: flow-enums-runtime "^0.0.6" lodash.throttle "^4.1.1" - metro-resolver "0.83.3" + metro-resolver "0.84.4" -metro-file-map@0.83.3: - version "0.83.3" - resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.83.3.tgz#3d79fbb1d379ab178dd895ce54cb5ecb183d74a2" - integrity sha512-jg5AcyE0Q9Xbbu/4NAwwZkmQn7doJCKGW0SLeSJmzNB9Z24jBe0AL2PHNMy4eu0JiKtNWHz9IiONGZWq7hjVTA== +metro-file-map@0.84.4: + version "0.84.4" + resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.84.4.tgz#00df08834ee4d34a8c15e33419fdff5a76a34870" + integrity sha512-KSVDi/u60hKPx++NLu3MTIvyjzNoJnFAF8PQFxaj1jiSka/wjw+Ua6sNuJ0TDHQv+7AAoFQxeMgaRAe8Yic5wQ== dependencies: debug "^4.4.0" fb-watchman "^2.0.0" @@ -8690,127 +8791,125 @@ metro-file-map@0.83.3: nullthrows "^1.1.1" walker "^1.0.7" -metro-minify-terser@0.83.3: - version "0.83.3" - resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.83.3.tgz#c1c70929c86b14c8bf03e6321b4f9310bc8dbe87" - integrity sha512-O2BmfWj6FSfzBLrNCXt/rr2VYZdX5i6444QJU0fFoc7Ljg+Q+iqebwE3K0eTvkI6TRjELsXk1cjU+fXwAR4OjQ== +metro-minify-terser@0.84.4: + version "0.84.4" + resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.84.4.tgz#e904d63f085d1af33587ff6daf5010243d19eec9" + integrity sha512-5qpbaVOMC7CPitIpuewzVeGw7E+C3ykbv2mqTjQLl85Z3annSVGlSCTcsZjqXZzjupfK4Ztj3dDc4kc44NZwtQ== dependencies: flow-enums-runtime "^0.0.6" terser "^5.15.0" -metro-resolver@0.83.3: - version "0.83.3" - resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.83.3.tgz#06207bdddc280b9335722a8c992aeec017413942" - integrity sha512-0js+zwI5flFxb1ktmR///bxHYg7OLpRpWZlBBruYG8OKYxeMP7SV0xQ/o/hUelrEMdK4LJzqVtHAhBm25LVfAQ== +metro-resolver@0.84.4: + version "0.84.4" + resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.84.4.tgz#88181301abb9b476072e8263f7b3b918d493931a" + integrity sha512-1qLgbxQ5ZGhhutuPot1Yp348ofDsATL2WkrHF65TobqTT9K3P9qJXw38bomk7ncp5B7OYMfWwtyBZo1lCV792A== dependencies: flow-enums-runtime "^0.0.6" -metro-runtime@0.83.3, metro-runtime@^0.83.3: - version "0.83.3" - resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.83.3.tgz#ff504df5d93f38b1af396715b327e589ba8d184d" - integrity sha512-JHCJb9ebr9rfJ+LcssFYA2x1qPYuSD/bbePupIGhpMrsla7RCwC/VL3yJ9cSU+nUhU4c9Ixxy8tBta+JbDeZWw== +metro-runtime@0.84.4, metro-runtime@^0.84.3: + version "0.84.4" + resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.84.4.tgz#8c10a488d19a49d64bcc775039032b61cceb26a6" + integrity sha512-Jibypds4g7AhzdRKY+kDoj51s5EXMwgyp5ddtlreDAsWefMdOx+agWqgm0H2XSZ/ueanHHVM89fnf5OJnlxa8Q== dependencies: "@babel/runtime" "^7.25.0" flow-enums-runtime "^0.0.6" -metro-source-map@0.83.3, metro-source-map@^0.83.3: - version "0.83.3" - resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.83.3.tgz#04bb464f7928ea48bcdfd18912c8607cf317c898" - integrity sha512-xkC3qwUBh2psVZgVavo8+r2C9Igkk3DibiOXSAht1aYRRcztEZNFtAMtfSB7sdO2iFMx2Mlyu++cBxz/fhdzQg== +metro-source-map@0.84.4, metro-source-map@^0.84.3: + version "0.84.4" + resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.84.4.tgz#e16e7c2dce22d8aea527f459ba88f5a2827ba32a" + integrity sha512-jbWkPxIesVuo1IWkvezmMJld6iu8nD62GsrZiV6jP37AOdbo4OBq1FJ+qkOg8sV05wAHB//jAbziuW0SlJfW4g== dependencies: - "@babel/traverse" "^7.25.3" - "@babel/traverse--for-generate-function-map" "npm:@babel/traverse@^7.25.3" - "@babel/types" "^7.25.2" + "@babel/traverse" "^7.29.0" + "@babel/types" "^7.29.0" flow-enums-runtime "^0.0.6" invariant "^2.2.4" - metro-symbolicate "0.83.3" + metro-symbolicate "0.84.4" nullthrows "^1.1.1" - ob1 "0.83.3" + ob1 "0.84.4" source-map "^0.5.6" vlq "^1.0.0" -metro-symbolicate@0.83.3: - version "0.83.3" - resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.83.3.tgz#67af03950f0dfe19a7c059e3983e39a31e95d03a" - integrity sha512-F/YChgKd6KbFK3eUR5HdUsfBqVsanf5lNTwFd4Ca7uuxnHgBC3kR/Hba/RGkenR3pZaGNp5Bu9ZqqP52Wyhomw== +metro-symbolicate@0.84.4: + version "0.84.4" + resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.84.4.tgz#0d5a9fd2f15b5c079050051d8bd1f88726d6e0d2" + integrity sha512-OnfpacxUqGPZQ27t8qK9mFa7uqHIlVWeqRqkCbvMvreEBiamEeOn8krKtcwgP5M4cYDPwuSmCTopHMVthqG4zA== dependencies: flow-enums-runtime "^0.0.6" invariant "^2.2.4" - metro-source-map "0.83.3" + metro-source-map "0.84.4" nullthrows "^1.1.1" source-map "^0.5.6" vlq "^1.0.0" -metro-transform-plugins@0.83.3: - version "0.83.3" - resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.83.3.tgz#2c59ba841e269363cf3acb13138cb992f0c75013" - integrity sha512-eRGoKJU6jmqOakBMH5kUB7VitEWiNrDzBHpYbkBXW7C5fUGeOd2CyqrosEzbMK5VMiZYyOcNFEphvxk3OXey2A== +metro-transform-plugins@0.84.4: + version "0.84.4" + resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.84.4.tgz#b5a4e4329b1ee0261fb21f8910df7eefd02e685d" + integrity sha512-kehr6HbAecqD0/a3xLXobELdPaAmRAl8bel0qagPF4vhZtux93nS8S4eq2kgKt6J2GnQpVjSoW1PXdst04mwow== dependencies: "@babel/core" "^7.25.2" - "@babel/generator" "^7.25.0" - "@babel/template" "^7.25.0" - "@babel/traverse" "^7.25.3" + "@babel/generator" "^7.29.1" + "@babel/template" "^7.28.6" + "@babel/traverse" "^7.29.0" flow-enums-runtime "^0.0.6" nullthrows "^1.1.1" -metro-transform-worker@0.83.3: - version "0.83.3" - resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.83.3.tgz#ca6ae4a02b0f61b33299e6e56bacaba32dcd607f" - integrity sha512-Ztekew9t/gOIMZX1tvJOgX7KlSLL5kWykl0Iwu2cL2vKMKVALRl1hysyhUw0vjpAvLFx+Kfq9VLjnHIkW32fPA== +metro-transform-worker@0.84.4: + version "0.84.4" + resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.84.4.tgz#2a66d65d147f7aa7d13c8620e65474095f46b441" + integrity sha512-W1IYMvvXTu4MxYr7d9h7CeG2vpIr3bmLLIavkPY4O1ilzDrvS8z/NEe6y+pC44Ff7raMXQgYSfdqDUwN/i39gg== dependencies: "@babel/core" "^7.25.2" - "@babel/generator" "^7.25.0" - "@babel/parser" "^7.25.3" - "@babel/types" "^7.25.2" + "@babel/generator" "^7.29.1" + "@babel/parser" "^7.29.0" + "@babel/types" "^7.29.0" flow-enums-runtime "^0.0.6" - metro "0.83.3" - metro-babel-transformer "0.83.3" - metro-cache "0.83.3" - metro-cache-key "0.83.3" - metro-minify-terser "0.83.3" - metro-source-map "0.83.3" - metro-transform-plugins "0.83.3" + metro "0.84.4" + metro-babel-transformer "0.84.4" + metro-cache "0.84.4" + metro-cache-key "0.84.4" + metro-minify-terser "0.84.4" + metro-source-map "0.84.4" + metro-transform-plugins "0.84.4" nullthrows "^1.1.1" -metro@0.83.3, metro@^0.83.3: - version "0.83.3" - resolved "https://registry.yarnpkg.com/metro/-/metro-0.83.3.tgz#1e7e04c15519af746f8932c7f9c553d92c39e922" - integrity sha512-+rP+/GieOzkt97hSJ0MrPOuAH/jpaS21ZDvL9DJ35QYRDlQcwzcvUlGUf79AnQxq/2NPiS/AULhhM4TKutIt8Q== +metro@0.84.4, metro@^0.84.3: + version "0.84.4" + resolved "https://registry.yarnpkg.com/metro/-/metro-0.84.4.tgz#dfcf92b3bcadce7cafaf1a1fa231b6490dfae78c" + integrity sha512-8ETTubqfD6ornDy2zYDvRcKnVDOXdFJsjetYDBsY4oAsb6NJkiwFR+FaMESyGppFmQUyBQA4H4sFGxzcQSGtFA== dependencies: - "@babel/code-frame" "^7.24.7" + "@babel/code-frame" "^7.29.0" "@babel/core" "^7.25.2" - "@babel/generator" "^7.25.0" - "@babel/parser" "^7.25.3" - "@babel/template" "^7.25.0" - "@babel/traverse" "^7.25.3" - "@babel/types" "^7.25.2" - accepts "^1.3.7" - chalk "^4.0.0" + "@babel/generator" "^7.29.1" + "@babel/parser" "^7.29.0" + "@babel/template" "^7.28.6" + "@babel/traverse" "^7.29.0" + "@babel/types" "^7.29.0" + accepts "^2.0.0" ci-info "^2.0.0" connect "^3.6.5" debug "^4.4.0" error-stack-parser "^2.0.6" flow-enums-runtime "^0.0.6" graceful-fs "^4.2.4" - hermes-parser "0.32.0" + hermes-parser "0.35.0" image-size "^1.0.2" invariant "^2.2.4" jest-worker "^29.7.0" jsc-safe-url "^0.2.2" lodash.throttle "^4.1.1" - metro-babel-transformer "0.83.3" - metro-cache "0.83.3" - metro-cache-key "0.83.3" - metro-config "0.83.3" - metro-core "0.83.3" - metro-file-map "0.83.3" - metro-resolver "0.83.3" - metro-runtime "0.83.3" - metro-source-map "0.83.3" - metro-symbolicate "0.83.3" - metro-transform-plugins "0.83.3" - metro-transform-worker "0.83.3" - mime-types "^2.1.27" + metro-babel-transformer "0.84.4" + metro-cache "0.84.4" + metro-cache-key "0.84.4" + metro-config "0.84.4" + metro-core "0.84.4" + metro-file-map "0.84.4" + metro-resolver "0.84.4" + metro-runtime "0.84.4" + metro-source-map "0.84.4" + metro-symbolicate "0.84.4" + metro-transform-plugins "0.84.4" + metro-transform-worker "0.84.4" + mime-types "^3.0.1" nullthrows "^1.1.1" serialize-error "^2.1.0" source-map "^0.5.6" @@ -8839,18 +8938,25 @@ mime-db@1.52.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -"mime-db@>= 1.43.0 < 2": +"mime-db@>= 1.43.0 < 2", mime-db@^1.54.0: version "1.54.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.54.0.tgz#cddb3ee4f9c64530dff640236661d42cb6a314f5" integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== -mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.35, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.12, mime-types@^2.1.35, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" +mime-types@^3.0.0, mime-types@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-3.0.2.tgz#39002d4182575d5af036ffa118100f2524b2e2ab" + integrity sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A== + dependencies: + mime-db "^1.54.0" + mime@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" @@ -8972,6 +9078,11 @@ negotiator@0.6.3: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== +negotiator@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-1.0.0.tgz#b6c91bb47172d69f93cfd7c357bbb529019b5f6a" + integrity sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg== + negotiator@~0.6.4: version "0.6.4" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.4.tgz#777948e2452651c570b712dd01c23e262713fff7" @@ -9117,10 +9228,10 @@ nullthrows@^1.1.1: resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1" integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw== -ob1@0.83.3: - version "0.83.3" - resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.83.3.tgz#2208e20c9070e9beff3ad067f2db458fa6b07014" - integrity sha512-egUxXCDwoWG06NGCS5s5AdcpnumHKJlfd3HH06P3m9TEMwwScfcY35wpQxbm9oHof+dM/lVH9Rfyu1elTVelSA== +ob1@0.84.4: + version "0.84.4" + resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.84.4.tgz#ec645debf5fbd8511dc1f00bf454e232fba02a9b" + integrity sha512-eJXMpz4aQHXF/YBB9ddqZDIS+ooO91hObo9FoW/xBkr54/zCwYYCDqT/O54vNo8kOkWs5Ou/y28NgdrV0edQNA== dependencies: flow-enums-runtime "^0.0.6" @@ -9871,11 +9982,16 @@ react-is@^18.0.0, react-is@^18.3.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== -react-is@^19.1.0, react-is@^19.2.0: +react-is@^19.1.0: version "19.2.3" resolved "https://registry.yarnpkg.com/react-is/-/react-is-19.2.3.tgz#eec2feb69c7fb31f77d0b5c08c10ae1c88886b29" integrity sha512-qJNJfu81ByyabuG7hPFEbXqNcWSU3+eVus+KJs+0ncpGfMyYdvSmxiJxbWR65lYi1I+/0HBcliO029gc4F+PnA== +react-is@^19.2.3: + version "19.2.6" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-19.2.6.tgz#aeee6159b159eb7f520d672cffcc69e7052d288f" + integrity sha512-XjBR15BhXuylgWGuslhDKqlSayuqvqBX91BP8pauG8kd1zY8kotkNWbXksTCNRarse4kuGbe2kIY05ARtwNIvw== + react-native-android-open-settings@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/react-native-android-open-settings/-/react-native-android-open-settings-1.3.0.tgz#c6257f3c88ada62945fffe887933a2a828adf45d" @@ -9983,11 +10099,16 @@ react-native-haptic-feedback@^2.3.3: resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-2.3.3.tgz#88b6876e91399a69bd1b551fe1681b2f3dc1214e" integrity sha512-svS4D5PxfNv8o68m9ahWfwje5NqukM3qLS48+WTdhbDkNUkOhP9rDfDSRHzlhk4zq+ISjyw95EhLeh8NkKX5vQ== -react-native-is-edge-to-edge@1.2.1, react-native-is-edge-to-edge@^1.2.1: +react-native-is-edge-to-edge@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.2.1.tgz#64e10851abd9d176cbf2b40562f751622bde3358" integrity sha512-FLbPWl/MyYQWz+KwqOZsSyj2JmLKglHatd3xLZWskXOpRaio4LfEDEz8E/A6uD8QoTHW6Aobw1jbEwK7KMgR7Q== +react-native-is-edge-to-edge@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.3.1.tgz#feb9a6a8faf0874298947edd556e5af22044e139" + integrity sha512-NIXU/iT5+ORyCc7p0z2nnlkouYKX425vuU1OEm6bMMtWWR9yvb+Xg5AZmImTKoF9abxCPqrKC3rOZsKzUYgYZA== + react-native-keychain@^10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/react-native-keychain/-/react-native-keychain-10.0.0.tgz#1de6f54d27b2376deaac4d51883c066f53b7be7b" @@ -10028,13 +10149,13 @@ react-native-reanimated-carousel@^4.0.3: resolved "https://registry.yarnpkg.com/react-native-reanimated-carousel/-/react-native-reanimated-carousel-4.0.3.tgz#975f4ff3f5da5bb3790fe60850a46ad8119612bc" integrity sha512-YZXlvZNghR5shFcI9hTA7h7bEhh97pfUSLZvLBAshpbkuYwJDKmQXejO/199T6hqGq0wCRwR0CWf2P4Vs6A4Fw== -react-native-reanimated@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-4.2.1.tgz#fbdee721bff0946a6e5ae67c8c38c37ca4a0a057" - integrity sha512-/NcHnZMyOvsD/wYXug/YqSKw90P9edN0kEPL5lP4PFf1aQ4F1V7MKe/E0tvfkXKIajy3Qocp5EiEnlcrK/+BZg== +react-native-reanimated@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-4.3.1.tgz#dd390567f27a9245ae431d4992d9787a597ec914" + integrity sha512-KhGsS0YkCA+gusgyzlf9hnqzVPIR398KTpqXyqq/+yYJJPAvyEEPKcxlB0xtOOXSMrR2A9uRKVARVQhZwrOh+Q== dependencies: - react-native-is-edge-to-edge "1.2.1" - semver "7.7.3" + react-native-is-edge-to-edge "^1.3.1" + semver "^7.7.3" react-native-restart@^0.0.27: version "0.0.27" @@ -10147,51 +10268,47 @@ react-native-webview@^13.16.0: escape-string-regexp "^4.0.0" invariant "2.2.4" -react-native-worklets@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/react-native-worklets/-/react-native-worklets-0.7.1.tgz#263da5216b0b5342b9f1b36e0ab897c5ca5c863b" - integrity sha512-KNsvR48ULg73QhTlmwPbdJLPsWcyBotrGPsrDRDswb5FYpQaJEThUKc2ncXE4UM5dn/ewLoQHjSjLaKUVPxPhA== - dependencies: - "@babel/plugin-transform-arrow-functions" "7.27.1" - "@babel/plugin-transform-class-properties" "7.27.1" - "@babel/plugin-transform-classes" "7.28.4" - "@babel/plugin-transform-nullish-coalescing-operator" "7.27.1" - "@babel/plugin-transform-optional-chaining" "7.27.1" - "@babel/plugin-transform-shorthand-properties" "7.27.1" - "@babel/plugin-transform-template-literals" "7.27.1" - "@babel/plugin-transform-unicode-regex" "7.27.1" - "@babel/preset-typescript" "7.27.1" - convert-source-map "2.0.0" - semver "7.7.3" - -react-native@0.83.1: - version "0.83.1" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.83.1.tgz#2c163cd055baa40166553487bada1eb7b9de154f" - integrity sha512-mL1q5HPq5cWseVhWRLl+Fwvi5z1UO+3vGOpjr+sHFwcUletPRZ5Kv+d0tUfqHmvi73/53NjlQqX1Pyn4GguUfA== +react-native-worklets@^0.8.2: + version "0.8.3" + resolved "https://registry.yarnpkg.com/react-native-worklets/-/react-native-worklets-0.8.3.tgz#87014dbe148f76a8ffd623953d3614a54aa880e8" + integrity sha512-oCBJROyLU7yG/1R8s0INMflygTH71bx+5XcYkH0CM938TlhSoVbiunE1WVW5FZa51vwYqfLie/IXMX2s1Kh3eg== dependencies: - "@jest/create-cache-key-function" "^29.7.0" - "@react-native/assets-registry" "0.83.1" - "@react-native/codegen" "0.83.1" - "@react-native/community-cli-plugin" "0.83.1" - "@react-native/gradle-plugin" "0.83.1" - "@react-native/js-polyfills" "0.83.1" - "@react-native/normalize-colors" "0.83.1" - "@react-native/virtualized-lists" "0.83.1" + "@babel/plugin-transform-arrow-functions" "^7.27.1" + "@babel/plugin-transform-class-properties" "^7.27.1" + "@babel/plugin-transform-classes" "^7.28.4" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.27.1" + "@babel/plugin-transform-optional-chaining" "^7.27.1" + "@babel/plugin-transform-shorthand-properties" "^7.27.1" + "@babel/plugin-transform-template-literals" "^7.27.1" + "@babel/plugin-transform-unicode-regex" "^7.27.1" + "@babel/preset-typescript" "^7.27.1" + convert-source-map "^2.0.0" + semver "^7.7.3" + +react-native@0.85.3: + version "0.85.3" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.85.3.tgz#4a3d25c63a2fd320ffb093e20269cf47d585d483" + integrity sha512-HN/fGC+3nZVcDNcw7gfbM/DuqZAvI9Mz+/SxuhODaua4JY0BPzhfTzWXRyTR4mRgMHmShTPpH2PYMTxvZrsdZA== + dependencies: + "@react-native/assets-registry" "0.85.3" + "@react-native/codegen" "0.85.3" + "@react-native/community-cli-plugin" "0.85.3" + "@react-native/gradle-plugin" "0.85.3" + "@react-native/js-polyfills" "0.85.3" + "@react-native/normalize-colors" "0.85.3" + "@react-native/virtualized-lists" "0.85.3" abort-controller "^3.0.0" anser "^1.4.9" ansi-regex "^5.0.0" - babel-jest "^29.7.0" - babel-plugin-syntax-hermes-parser "0.32.0" + babel-plugin-syntax-hermes-parser "0.33.3" base64-js "^1.5.1" commander "^12.0.0" flow-enums-runtime "^0.0.6" - glob "^7.1.1" - hermes-compiler "0.14.0" + hermes-compiler "250829098.0.10" invariant "^2.2.4" - jest-environment-node "^29.7.0" memoize-one "^5.0.0" - metro-runtime "^0.83.3" - metro-source-map "^0.83.3" + metro-runtime "^0.84.3" + metro-source-map "^0.84.3" nullthrows "^1.1.1" pretty-format "^29.7.0" promise "^8.3.0" @@ -10201,6 +10318,7 @@ react-native@0.83.1: scheduler "0.27.0" semver "^7.1.3" stacktrace-parser "^0.1.10" + tinyglobby "^0.2.15" whatwg-fetch "^3.0.0" ws "^7.5.10" yargs "^17.6.2" @@ -10222,18 +10340,18 @@ react-refresh@^0.14.0: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.2.tgz#3833da01ce32da470f1f936b9d477da5c7028bf9" integrity sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA== -react-test-renderer@19.2.0: - version "19.2.0" - resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-19.2.0.tgz#5c9782b4a4ba0630a77d7ce092779fdf9ccde209" - integrity sha512-zLCFMHFE9vy/w3AxO0zNxy6aAupnCuLSVOJYDe/Tp+ayGI1f2PLQsFVPANSD42gdSbmYx5oN+1VWDhcXtq7hAQ== +react-test-renderer@19.2.3: + version "19.2.3" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-19.2.3.tgz#d20f5193867c98b2df9e13b4e72bb83f311f6a43" + integrity sha512-TMR1LnSFiWZMJkCgNf5ATSvAheTT2NvKIwiVwdBPHxjBI7n/JbWd4gaZ16DVd9foAXdvDz+sB5yxZTwMjPRxpw== dependencies: - react-is "^19.2.0" + react-is "^19.2.3" scheduler "^0.27.0" -react@19.2.0: - version "19.2.0" - resolved "https://registry.yarnpkg.com/react/-/react-19.2.0.tgz#d33dd1721698f4376ae57a54098cb47fc75d93a5" - integrity sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ== +react@19.2.3: + version "19.2.3" + resolved "https://registry.yarnpkg.com/react/-/react-19.2.3.tgz#d83e5e8e7a258cf6b4fe28640515f99b87cd19b8" + integrity sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA== readable-stream@^2.2.9, readable-stream@^2.3.6, readable-stream@^2.3.8: version "2.3.8" @@ -10549,16 +10667,16 @@ scheduler@0.27.0, scheduler@^0.27.0: resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.27.0.tgz#0c4ef82d67d1e5c1e359e8fc76d3a87f045fe5bd" integrity sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q== -semver@7.7.3, semver@^7.1.3, semver@^7.3.5, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4, semver@^7.7.1, semver@^7.7.3: - version "7.7.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.3.tgz#4b5f4143d007633a8dc671cd0a6ef9147b8bb946" - integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== - semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== +semver@^7.1.3, semver@^7.3.5, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4, semver@^7.7.1, semver@^7.7.3: + version "7.7.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.3.tgz#4b5f4143d007633a8dc671cd0a6ef9147b8bb946" + integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== + send@~0.19.1: version "0.19.2" resolved "https://registry.yarnpkg.com/send/-/send-0.19.2.tgz#59bc0da1b4ea7ad42736fd642b1c4294e114ff29" From 61c85c19e6c3388f7a38ddc605a0856890020aa8 Mon Sep 17 00:00:00 2001 From: lendihop Date: Wed, 20 May 2026 16:16:29 +0200 Subject: [PATCH 02/20] TW-2254: rm deprecated api usage --- AGENTS.md | 2 +- CLAUDE.md | 2 +- ios/Podfile | 12 + ios/Podfile.lock | 967 ++++++++++-------- ios/TempleWallet.xcodeproj/project.pbxproj | 42 +- package.json | 8 +- src/components/button/button.styles.ts | 2 +- .../react-native-image-progress/index.js | 2 +- .../segmented-control.styles.ts | 4 +- .../kolo-card-widget-modal.styles.ts | 2 +- .../backup-your-wallet-overlay.styles.ts | 2 +- .../on-ramp-overlay/on-ramp-overlay.styles.ts | 2 +- yarn.lock | 475 +++++---- 13 files changed, 830 insertions(+), 692 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 4dd8ba110..48048430b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ This repository is the Temple Wallet mobile app codebase. Temple Wallet is an open-source wallet for Tezos blockchain, focusing on security and seamless UX. -Tech stack: React Native CLI 0.83.1, React v19, TypeScript, Redux Toolkit, RxJS with Redux Observable +Tech stack: React Native CLI 0.85, React v19.2, TypeScript, Redux Toolkit, RxJS with Redux Observable Optimize for clarity, polish, and performance in every change. diff --git a/CLAUDE.md b/CLAUDE.md index 7ed847c0e..35c517e6f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1 +1 @@ -# Read AGENTS.md file to work Effectively In This Repo +Read AGENTS.md file diff --git a/ios/Podfile b/ios/Podfile index cd56c2d83..4e283db86 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,3 +1,7 @@ +# Build React Native third-party dependencies from source, +# so native pods can depend on RCT-Folly directly. +ENV['RCT_USE_RN_DEP'] = '0' + # Resolve react_native_pods.rb with node to allow for hoisting def node_require(script) # Resolve script with node to allow for hoisting @@ -65,6 +69,14 @@ target 'TempleWallet' do # :ccache_enabled => true ) + # Static-framework pods can import React's non-modular + # headers when building with Xcode explicit modules. + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES'] = 'YES' + end + end + # Patch to fix fastlane artifact upload. # See: https://github.com/mapbox/mapbox-maps-ios/issues/2233#issuecomment-2345562101 diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 5edc0880e..d1806fafb 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -12,45 +12,45 @@ PODS: - boost (1.84.0) - DoubleConversion (1.1.6) - fast_float (8.0.0) - - FBLazyVector (0.83.1) - - Firebase/AppCheck (12.8.0): + - FBLazyVector (0.85.3) + - Firebase/AppCheck (12.10.0): - Firebase/CoreOnly - - FirebaseAppCheck (~> 12.8.0) - - Firebase/CoreOnly (12.8.0): - - FirebaseCore (~> 12.8.0) - - Firebase/Messaging (12.8.0): + - FirebaseAppCheck (~> 12.10.0) + - Firebase/CoreOnly (12.10.0): + - FirebaseCore (~> 12.10.0) + - Firebase/Messaging (12.10.0): - Firebase/CoreOnly - - FirebaseMessaging (~> 12.8.0) - - FirebaseAppCheck (12.8.0): + - FirebaseMessaging (~> 12.10.0) + - FirebaseAppCheck (12.10.0): - AppCheckCore (~> 11.0) - - FirebaseAppCheckInterop (~> 12.8.0) - - FirebaseCore (~> 12.8.0) + - FirebaseAppCheckInterop (~> 12.10.0) + - FirebaseCore (~> 12.10.0) - GoogleUtilities/Environment (~> 8.1) - GoogleUtilities/UserDefaults (~> 8.1) - - FirebaseAppCheckInterop (12.8.0) - - FirebaseCore (12.8.0): - - FirebaseCoreInternal (~> 12.8.0) + - FirebaseAppCheckInterop (12.10.0) + - FirebaseCore (12.10.0): + - FirebaseCoreInternal (~> 12.10.0) - GoogleUtilities/Environment (~> 8.1) - GoogleUtilities/Logger (~> 8.1) - - FirebaseCoreExtension (12.8.0): - - FirebaseCore (~> 12.8.0) - - FirebaseCoreInternal (12.8.0): + - FirebaseCoreExtension (12.10.0): + - FirebaseCore (~> 12.10.0) + - FirebaseCoreInternal (12.10.0): - "GoogleUtilities/NSData+zlib (~> 8.1)" - - FirebaseInstallations (12.8.0): - - FirebaseCore (~> 12.8.0) + - FirebaseInstallations (12.10.0): + - FirebaseCore (~> 12.10.0) - GoogleUtilities/Environment (~> 8.1) - GoogleUtilities/UserDefaults (~> 8.1) - PromisesObjC (~> 2.4) - - FirebaseMessaging (12.8.0): - - FirebaseCore (~> 12.8.0) - - FirebaseInstallations (~> 12.8.0) + - FirebaseMessaging (12.10.0): + - FirebaseCore (~> 12.10.0) + - FirebaseInstallations (~> 12.10.0) - GoogleDataTransport (~> 10.1) - GoogleUtilities/AppDelegateSwizzler (~> 8.1) - GoogleUtilities/Environment (~> 8.1) - GoogleUtilities/Reachability (~> 8.1) - GoogleUtilities/UserDefaults (~> 8.1) - nanopb (~> 3.30910.0) - - fmt (11.0.2) + - fmt (12.1.0) - glog (0.3.5) - GoogleDataTransport (10.1.0): - nanopb (~> 3.30910.0) @@ -88,9 +88,9 @@ PODS: - AppAuth/Core (~> 2.0) - GTMSessionFetcher/Core (< 4.0, >= 3.3) - GTMSessionFetcher/Core (3.5.0) - - hermes-engine (0.14.0): - - hermes-engine/Pre-built (= 0.14.0) - - hermes-engine/Pre-built (0.14.0) + - hermes-engine (250829098.0.10): + - hermes-engine/Pre-built (= 250829098.0.10) + - hermes-engine/Pre-built (250829098.0.10) - libavif/core (0.11.1) - libavif/libdav1d (0.11.1): - libavif/core @@ -118,46 +118,46 @@ PODS: - boost - DoubleConversion - fast_float (= 8.0.0) - - fmt (= 11.0.2) + - fmt (= 12.1.0) - glog - RCT-Folly/Default (= 2024.11.18.00) - RCT-Folly/Default (2024.11.18.00): - boost - DoubleConversion - fast_float (= 8.0.0) - - fmt (= 11.0.2) + - fmt (= 12.1.0) - glog - RCT-Folly/Fabric (2024.11.18.00): - boost - DoubleConversion - fast_float (= 8.0.0) - - fmt (= 11.0.2) + - fmt (= 12.1.0) - glog - - RCTDeprecation (0.83.1) - - RCTRequired (0.83.1) - - RCTSwiftUI (0.83.1) - - RCTSwiftUIWrapper (0.83.1): + - RCTDeprecation (0.85.3) + - RCTRequired (0.85.3) + - RCTSwiftUI (0.85.3) + - RCTSwiftUIWrapper (0.85.3): - RCTSwiftUI - - RCTTypeSafety (0.83.1): - - FBLazyVector (= 0.83.1) - - RCTRequired (= 0.83.1) - - React-Core (= 0.83.1) - - React (0.83.1): - - React-Core (= 0.83.1) - - React-Core/DevSupport (= 0.83.1) - - React-Core/RCTWebSocket (= 0.83.1) - - React-RCTActionSheet (= 0.83.1) - - React-RCTAnimation (= 0.83.1) - - React-RCTBlob (= 0.83.1) - - React-RCTImage (= 0.83.1) - - React-RCTLinking (= 0.83.1) - - React-RCTNetwork (= 0.83.1) - - React-RCTSettings (= 0.83.1) - - React-RCTText (= 0.83.1) - - React-RCTVibration (= 0.83.1) - - React-callinvoker (0.83.1) + - RCTTypeSafety (0.85.3): + - FBLazyVector (= 0.85.3) + - RCTRequired (= 0.85.3) + - React-Core (= 0.85.3) + - React (0.85.3): + - React-Core (= 0.85.3) + - React-Core/DevSupport (= 0.85.3) + - React-Core/RCTWebSocket (= 0.85.3) + - React-RCTActionSheet (= 0.85.3) + - React-RCTAnimation (= 0.85.3) + - React-RCTBlob (= 0.85.3) + - React-RCTImage (= 0.85.3) + - React-RCTLinking (= 0.85.3) + - React-RCTNetwork (= 0.85.3) + - React-RCTSettings (= 0.85.3) + - React-RCTText (= 0.85.3) + - React-RCTVibration (= 0.85.3) + - React-callinvoker (0.85.3) - React-Codegen (0.1.0) - - React-Core (0.83.1): + - React-Core (0.85.3): - boost - DoubleConversion - fast_float @@ -167,7 +167,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTDeprecation - - React-Core/Default (= 0.83.1) + - React-Core/Default (= 0.85.3) - React-cxxreact - React-featureflags - React-hermes @@ -182,7 +182,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/CoreModulesHeaders (0.83.1): + - React-Core/CoreModulesHeaders (0.85.3): - boost - DoubleConversion - fast_float @@ -207,7 +207,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/Default (0.83.1): + - React-Core/Default (0.85.3): - boost - DoubleConversion - fast_float @@ -231,7 +231,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/DevSupport (0.83.1): + - React-Core/DevSupport (0.85.3): - boost - DoubleConversion - fast_float @@ -241,8 +241,8 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTDeprecation - - React-Core/Default (= 0.83.1) - - React-Core/RCTWebSocket (= 0.83.1) + - React-Core/Default (= 0.85.3) + - React-Core/RCTWebSocket (= 0.85.3) - React-cxxreact - React-featureflags - React-hermes @@ -257,7 +257,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/RCTActionSheetHeaders (0.83.1): + - React-Core/RCTActionSheetHeaders (0.85.3): - boost - DoubleConversion - fast_float @@ -282,7 +282,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/RCTAnimationHeaders (0.83.1): + - React-Core/RCTAnimationHeaders (0.85.3): - boost - DoubleConversion - fast_float @@ -307,7 +307,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/RCTBlobHeaders (0.83.1): + - React-Core/RCTBlobHeaders (0.85.3): - boost - DoubleConversion - fast_float @@ -332,7 +332,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/RCTImageHeaders (0.83.1): + - React-Core/RCTImageHeaders (0.85.3): - boost - DoubleConversion - fast_float @@ -357,7 +357,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/RCTLinkingHeaders (0.83.1): + - React-Core/RCTLinkingHeaders (0.85.3): - boost - DoubleConversion - fast_float @@ -382,7 +382,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/RCTNetworkHeaders (0.83.1): + - React-Core/RCTNetworkHeaders (0.85.3): - boost - DoubleConversion - fast_float @@ -407,7 +407,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/RCTSettingsHeaders (0.83.1): + - React-Core/RCTSettingsHeaders (0.85.3): - boost - DoubleConversion - fast_float @@ -432,7 +432,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/RCTTextHeaders (0.83.1): + - React-Core/RCTTextHeaders (0.85.3): - boost - DoubleConversion - fast_float @@ -457,7 +457,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/RCTVibrationHeaders (0.83.1): + - React-Core/RCTVibrationHeaders (0.85.3): - boost - DoubleConversion - fast_float @@ -482,7 +482,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-Core/RCTWebSocket (0.83.1): + - React-Core/RCTWebSocket (0.85.3): - boost - DoubleConversion - fast_float @@ -492,7 +492,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - RCTDeprecation - - React-Core/Default (= 0.83.1) + - React-Core/Default (= 0.85.3) - React-cxxreact - React-featureflags - React-hermes @@ -507,7 +507,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-CoreModules (0.83.1): + - React-CoreModules (0.85.3): - boost - DoubleConversion - fast_float @@ -515,22 +515,23 @@ PODS: - glog - RCT-Folly - RCT-Folly/Fabric - - RCTTypeSafety (= 0.83.1) - - React-Core/CoreModulesHeaders (= 0.83.1) + - RCTTypeSafety (= 0.85.3) + - React-Core/CoreModulesHeaders (= 0.85.3) - React-debug - - React-jsi (= 0.83.1) + - React-featureflags + - React-jsi (= 0.85.3) - React-jsinspector - React-jsinspectorcdp - React-jsinspectortracing - React-NativeModulesApple - React-RCTBlob - React-RCTFBReactNativeSpec - - React-RCTImage (= 0.83.1) + - React-RCTImage (= 0.85.3) - React-runtimeexecutor - React-utils - ReactCommon - SocketRocket - - React-cxxreact (0.83.1): + - React-cxxreact (0.85.3): - boost - DoubleConversion - fast_float @@ -539,20 +540,22 @@ PODS: - hermes-engine - RCT-Folly - RCT-Folly/Fabric - - React-callinvoker (= 0.83.1) - - React-debug (= 0.83.1) - - React-jsi (= 0.83.1) + - React-callinvoker (= 0.85.3) + - React-debug (= 0.85.3) + - React-jsi (= 0.85.3) - React-jsinspector - React-jsinspectorcdp - React-jsinspectortracing - - React-logger (= 0.83.1) - - React-perflogger (= 0.83.1) + - React-logger (= 0.85.3) + - React-perflogger (= 0.85.3) - React-runtimeexecutor - - React-timing (= 0.83.1) + - React-timing (= 0.85.3) - React-utils - SocketRocket - - React-debug (0.83.1) - - React-defaultsnativemodule (0.83.1): + - React-debug (0.85.3): + - React-debug/redbox (= 0.85.3) + - React-debug/redbox (0.85.3) + - React-defaultsnativemodule (0.85.3): - boost - DoubleConversion - fast_float @@ -562,6 +565,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - React-domnativemodule + - React-Fabric/animated - React-featureflags - React-featureflagsnativemodule - React-idlecallbacksnativemodule @@ -569,11 +573,12 @@ PODS: - React-jsi - React-jsiexecutor - React-microtasksnativemodule + - React-mutationobservernativemodule - React-RCTFBReactNativeSpec - React-webperformancenativemodule - SocketRocket - Yoga - - React-domnativemodule (0.83.1): + - React-domnativemodule (0.85.3): - boost - DoubleConversion - fast_float @@ -593,7 +598,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-Fabric (0.83.1): + - React-Fabric (0.85.3): - boost - DoubleConversion - fast_float @@ -607,25 +612,24 @@ PODS: - React-Core - React-cxxreact - React-debug - - React-Fabric/animated (= 0.83.1) - - React-Fabric/animationbackend (= 0.83.1) - - React-Fabric/animations (= 0.83.1) - - React-Fabric/attributedstring (= 0.83.1) - - React-Fabric/bridging (= 0.83.1) - - React-Fabric/componentregistry (= 0.83.1) - - React-Fabric/componentregistrynative (= 0.83.1) - - React-Fabric/components (= 0.83.1) - - React-Fabric/consistency (= 0.83.1) - - React-Fabric/core (= 0.83.1) - - React-Fabric/dom (= 0.83.1) - - React-Fabric/imagemanager (= 0.83.1) - - React-Fabric/leakchecker (= 0.83.1) - - React-Fabric/mounting (= 0.83.1) - - React-Fabric/observers (= 0.83.1) - - React-Fabric/scheduler (= 0.83.1) - - React-Fabric/telemetry (= 0.83.1) - - React-Fabric/templateprocessor (= 0.83.1) - - React-Fabric/uimanager (= 0.83.1) + - React-Fabric/animated (= 0.85.3) + - React-Fabric/animationbackend (= 0.85.3) + - React-Fabric/animations (= 0.85.3) + - React-Fabric/attributedstring (= 0.85.3) + - React-Fabric/bridging (= 0.85.3) + - React-Fabric/componentregistry (= 0.85.3) + - React-Fabric/componentregistrynative (= 0.85.3) + - React-Fabric/components (= 0.85.3) + - React-Fabric/consistency (= 0.85.3) + - React-Fabric/core (= 0.85.3) + - React-Fabric/dom (= 0.85.3) + - React-Fabric/imagemanager (= 0.85.3) + - React-Fabric/leakchecker (= 0.85.3) + - React-Fabric/mounting (= 0.85.3) + - React-Fabric/observers (= 0.85.3) + - React-Fabric/scheduler (= 0.85.3) + - React-Fabric/telemetry (= 0.85.3) + - React-Fabric/uimanager (= 0.85.3) - React-featureflags - React-graphics - React-jsi @@ -637,7 +641,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/animated (0.83.1): + - React-Fabric/animated (0.85.3): - boost - DoubleConversion - fast_float @@ -651,6 +655,7 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-Fabric/animationbackend - React-featureflags - React-graphics - React-jsi @@ -662,7 +667,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/animationbackend (0.83.1): + - React-Fabric/animationbackend (0.85.3): - boost - DoubleConversion - fast_float @@ -687,7 +692,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/animations (0.83.1): + - React-Fabric/animations (0.85.3): - boost - DoubleConversion - fast_float @@ -712,7 +717,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/attributedstring (0.83.1): + - React-Fabric/attributedstring (0.85.3): - boost - DoubleConversion - fast_float @@ -737,7 +742,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/bridging (0.83.1): + - React-Fabric/bridging (0.85.3): - boost - DoubleConversion - fast_float @@ -762,7 +767,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/componentregistry (0.83.1): + - React-Fabric/componentregistry (0.85.3): - boost - DoubleConversion - fast_float @@ -787,7 +792,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/componentregistrynative (0.83.1): + - React-Fabric/componentregistrynative (0.85.3): - boost - DoubleConversion - fast_float @@ -812,7 +817,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/components (0.83.1): + - React-Fabric/components (0.85.3): - boost - DoubleConversion - fast_float @@ -826,10 +831,10 @@ PODS: - React-Core - React-cxxreact - React-debug - - React-Fabric/components/legacyviewmanagerinterop (= 0.83.1) - - React-Fabric/components/root (= 0.83.1) - - React-Fabric/components/scrollview (= 0.83.1) - - React-Fabric/components/view (= 0.83.1) + - React-Fabric/components/legacyviewmanagerinterop (= 0.85.3) + - React-Fabric/components/root (= 0.85.3) + - React-Fabric/components/scrollview (= 0.85.3) + - React-Fabric/components/view (= 0.85.3) - React-featureflags - React-graphics - React-jsi @@ -841,7 +846,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/components/legacyviewmanagerinterop (0.83.1): + - React-Fabric/components/legacyviewmanagerinterop (0.85.3): - boost - DoubleConversion - fast_float @@ -866,7 +871,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/components/root (0.83.1): + - React-Fabric/components/root (0.85.3): - boost - DoubleConversion - fast_float @@ -891,7 +896,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/components/scrollview (0.83.1): + - React-Fabric/components/scrollview (0.85.3): - boost - DoubleConversion - fast_float @@ -916,7 +921,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/components/view (0.83.1): + - React-Fabric/components/view (0.85.3): - boost - DoubleConversion - fast_float @@ -943,7 +948,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-Fabric/consistency (0.83.1): + - React-Fabric/consistency (0.85.3): - boost - DoubleConversion - fast_float @@ -968,7 +973,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/core (0.83.1): + - React-Fabric/core (0.85.3): - boost - DoubleConversion - fast_float @@ -993,7 +998,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/dom (0.83.1): + - React-Fabric/dom (0.85.3): - boost - DoubleConversion - fast_float @@ -1018,7 +1023,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/imagemanager (0.83.1): + - React-Fabric/imagemanager (0.85.3): - boost - DoubleConversion - fast_float @@ -1043,7 +1048,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/leakchecker (0.83.1): + - React-Fabric/leakchecker (0.85.3): - boost - DoubleConversion - fast_float @@ -1068,7 +1073,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/mounting (0.83.1): + - React-Fabric/mounting (0.85.3): - boost - DoubleConversion - fast_float @@ -1093,7 +1098,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/observers (0.83.1): + - React-Fabric/observers (0.85.3): - boost - DoubleConversion - fast_float @@ -1107,8 +1112,9 @@ PODS: - React-Core - React-cxxreact - React-debug - - React-Fabric/observers/events (= 0.83.1) - - React-Fabric/observers/intersection (= 0.83.1) + - React-Fabric/observers/events (= 0.85.3) + - React-Fabric/observers/intersection (= 0.85.3) + - React-Fabric/observers/mutation (= 0.85.3) - React-featureflags - React-graphics - React-jsi @@ -1120,7 +1126,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/observers/events (0.83.1): + - React-Fabric/observers/events (0.85.3): - boost - DoubleConversion - fast_float @@ -1145,7 +1151,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/observers/intersection (0.83.1): + - React-Fabric/observers/intersection (0.85.3): - boost - DoubleConversion - fast_float @@ -1170,7 +1176,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/scheduler (0.83.1): + - React-Fabric/observers/mutation (0.85.3): - boost - DoubleConversion - fast_float @@ -1184,21 +1190,18 @@ PODS: - React-Core - React-cxxreact - React-debug - - React-Fabric/observers/events - React-featureflags - React-graphics - React-jsi - React-jsiexecutor - React-logger - - React-performancecdpmetrics - - React-performancetimeline - React-rendererdebug - React-runtimeexecutor - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/telemetry (0.83.1): + - React-Fabric/scheduler (0.85.3): - boost - DoubleConversion - fast_float @@ -1212,18 +1215,22 @@ PODS: - React-Core - React-cxxreact - React-debug + - React-Fabric/animationbackend + - React-Fabric/observers/events - React-featureflags - React-graphics - React-jsi - React-jsiexecutor - React-logger + - React-performancecdpmetrics + - React-performancetimeline - React-rendererdebug - React-runtimeexecutor - React-runtimescheduler - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/templateprocessor (0.83.1): + - React-Fabric/telemetry (0.85.3): - boost - DoubleConversion - fast_float @@ -1248,7 +1255,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/uimanager (0.83.1): + - React-Fabric/uimanager (0.85.3): - boost - DoubleConversion - fast_float @@ -1262,7 +1269,7 @@ PODS: - React-Core - React-cxxreact - React-debug - - React-Fabric/uimanager/consistency (= 0.83.1) + - React-Fabric/uimanager/consistency (= 0.85.3) - React-featureflags - React-graphics - React-jsi @@ -1275,7 +1282,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-Fabric/uimanager/consistency (0.83.1): + - React-Fabric/uimanager/consistency (0.85.3): - boost - DoubleConversion - fast_float @@ -1301,7 +1308,7 @@ PODS: - React-utils - ReactCommon/turbomodule/core - SocketRocket - - React-FabricComponents (0.83.1): + - React-FabricComponents (0.85.3): - boost - DoubleConversion - fast_float @@ -1316,8 +1323,8 @@ PODS: - React-cxxreact - React-debug - React-Fabric - - React-FabricComponents/components (= 0.83.1) - - React-FabricComponents/textlayoutmanager (= 0.83.1) + - React-FabricComponents/components (= 0.85.3) + - React-FabricComponents/textlayoutmanager (= 0.85.3) - React-featureflags - React-graphics - React-jsi @@ -1330,7 +1337,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components (0.83.1): + - React-FabricComponents/components (0.85.3): - boost - DoubleConversion - fast_float @@ -1345,18 +1352,17 @@ PODS: - React-cxxreact - React-debug - React-Fabric - - React-FabricComponents/components/inputaccessory (= 0.83.1) - - React-FabricComponents/components/iostextinput (= 0.83.1) - - React-FabricComponents/components/modal (= 0.83.1) - - React-FabricComponents/components/rncore (= 0.83.1) - - React-FabricComponents/components/safeareaview (= 0.83.1) - - React-FabricComponents/components/scrollview (= 0.83.1) - - React-FabricComponents/components/switch (= 0.83.1) - - React-FabricComponents/components/text (= 0.83.1) - - React-FabricComponents/components/textinput (= 0.83.1) - - React-FabricComponents/components/unimplementedview (= 0.83.1) - - React-FabricComponents/components/virtualview (= 0.83.1) - - React-FabricComponents/components/virtualviewexperimental (= 0.83.1) + - React-FabricComponents/components/inputaccessory (= 0.85.3) + - React-FabricComponents/components/iostextinput (= 0.85.3) + - React-FabricComponents/components/modal (= 0.85.3) + - React-FabricComponents/components/rncore (= 0.85.3) + - React-FabricComponents/components/safeareaview (= 0.85.3) + - React-FabricComponents/components/scrollview (= 0.85.3) + - React-FabricComponents/components/switch (= 0.85.3) + - React-FabricComponents/components/text (= 0.85.3) + - React-FabricComponents/components/textinput (= 0.85.3) + - React-FabricComponents/components/unimplementedview (= 0.85.3) + - React-FabricComponents/components/virtualview (= 0.85.3) - React-featureflags - React-graphics - React-jsi @@ -1369,7 +1375,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/inputaccessory (0.83.1): + - React-FabricComponents/components/inputaccessory (0.85.3): - boost - DoubleConversion - fast_float @@ -1396,7 +1402,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/iostextinput (0.83.1): + - React-FabricComponents/components/iostextinput (0.85.3): - boost - DoubleConversion - fast_float @@ -1423,7 +1429,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/modal (0.83.1): + - React-FabricComponents/components/modal (0.85.3): - boost - DoubleConversion - fast_float @@ -1450,7 +1456,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/rncore (0.83.1): + - React-FabricComponents/components/rncore (0.85.3): - boost - DoubleConversion - fast_float @@ -1477,7 +1483,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/safeareaview (0.83.1): + - React-FabricComponents/components/safeareaview (0.85.3): - boost - DoubleConversion - fast_float @@ -1504,7 +1510,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/scrollview (0.83.1): + - React-FabricComponents/components/scrollview (0.85.3): - boost - DoubleConversion - fast_float @@ -1531,7 +1537,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/switch (0.83.1): + - React-FabricComponents/components/switch (0.85.3): - boost - DoubleConversion - fast_float @@ -1558,7 +1564,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/text (0.83.1): + - React-FabricComponents/components/text (0.85.3): - boost - DoubleConversion - fast_float @@ -1585,7 +1591,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/textinput (0.83.1): + - React-FabricComponents/components/textinput (0.85.3): - boost - DoubleConversion - fast_float @@ -1612,7 +1618,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/unimplementedview (0.83.1): + - React-FabricComponents/components/unimplementedview (0.85.3): - boost - DoubleConversion - fast_float @@ -1639,7 +1645,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/virtualview (0.83.1): + - React-FabricComponents/components/virtualview (0.85.3): - boost - DoubleConversion - fast_float @@ -1666,7 +1672,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/components/virtualviewexperimental (0.83.1): + - React-FabricComponents/textlayoutmanager (0.85.3): - boost - DoubleConversion - fast_float @@ -1693,7 +1699,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-FabricComponents/textlayoutmanager (0.83.1): + - React-FabricImage (0.85.3): - boost - DoubleConversion - fast_float @@ -1702,48 +1708,21 @@ PODS: - hermes-engine - RCT-Folly - RCT-Folly/Fabric - - RCTRequired - - RCTTypeSafety - - React-Core - - React-cxxreact - - React-debug - - React-Fabric - - React-featureflags - - React-graphics - - React-jsi - - React-jsiexecutor - - React-logger - - React-RCTFBReactNativeSpec - - React-rendererdebug - - React-runtimescheduler - - React-utils - - ReactCommon/turbomodule/core - - SocketRocket - - Yoga - - React-FabricImage (0.83.1): - - boost - - DoubleConversion - - fast_float - - fmt - - glog - - hermes-engine - - RCT-Folly - - RCT-Folly/Fabric - - RCTRequired (= 0.83.1) - - RCTTypeSafety (= 0.83.1) + - RCTRequired (= 0.85.3) + - RCTTypeSafety (= 0.85.3) - React-Fabric - React-featureflags - React-graphics - React-ImageManager - React-jsi - - React-jsiexecutor (= 0.83.1) + - React-jsiexecutor (= 0.85.3) - React-logger - React-rendererdebug - React-utils - ReactCommon - SocketRocket - Yoga - - React-featureflags (0.83.1): + - React-featureflags (0.85.3): - boost - DoubleConversion - fast_float @@ -1752,7 +1731,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - SocketRocket - - React-featureflagsnativemodule (0.83.1): + - React-featureflagsnativemodule (0.85.3): - boost - DoubleConversion - fast_float @@ -1767,7 +1746,7 @@ PODS: - React-RCTFBReactNativeSpec - ReactCommon/turbomodule/core - SocketRocket - - React-graphics (0.83.1): + - React-graphics (0.85.3): - boost - DoubleConversion - fast_float @@ -1776,11 +1755,12 @@ PODS: - hermes-engine - RCT-Folly - RCT-Folly/Fabric + - React-featureflags - React-jsi - React-jsiexecutor - React-utils - SocketRocket - - React-hermes (0.83.1): + - React-hermes (0.85.3): - boost - DoubleConversion - fast_float @@ -1789,17 +1769,18 @@ PODS: - hermes-engine - RCT-Folly - RCT-Folly/Fabric - - React-cxxreact (= 0.83.1) + - React-cxxreact (= 0.85.3) - React-jsi - - React-jsiexecutor (= 0.83.1) + - React-jsiexecutor (= 0.85.3) - React-jsinspector - React-jsinspectorcdp - React-jsinspectortracing + - React-jsitooling - React-oscompat - - React-perflogger (= 0.83.1) + - React-perflogger (= 0.85.3) - React-runtimeexecutor - SocketRocket - - React-idlecallbacksnativemodule (0.83.1): + - React-idlecallbacksnativemodule (0.85.3): - boost - DoubleConversion - fast_float @@ -1815,7 +1796,7 @@ PODS: - React-runtimescheduler - ReactCommon/turbomodule/core - SocketRocket - - React-ImageManager (0.83.1): + - React-ImageManager (0.85.3): - boost - DoubleConversion - fast_float @@ -1830,7 +1811,7 @@ PODS: - React-rendererdebug - React-utils - SocketRocket - - React-intersectionobservernativemodule (0.83.1): + - React-intersectionobservernativemodule (0.85.3): - boost - DoubleConversion - fast_float @@ -1851,7 +1832,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-jserrorhandler (0.83.1): + - React-jserrorhandler (0.85.3): - boost - DoubleConversion - fast_float @@ -1866,7 +1847,7 @@ PODS: - React-jsi - ReactCommon/turbomodule/bridging - SocketRocket - - React-jsi (0.83.1): + - React-jsi (0.85.3): - boost - DoubleConversion - fast_float @@ -1876,7 +1857,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - SocketRocket - - React-jsiexecutor (0.83.1): + - React-jsiexecutor (0.85.3): - boost - DoubleConversion - fast_float @@ -1887,15 +1868,17 @@ PODS: - RCT-Folly/Fabric - React-cxxreact - React-debug + - React-jserrorhandler - React-jsi - React-jsinspector - React-jsinspectorcdp - React-jsinspectortracing + - React-jsitooling - React-perflogger - React-runtimeexecutor - React-utils - SocketRocket - - React-jsinspector (0.83.1): + - React-jsinspector (0.85.3): - boost - DoubleConversion - fast_float @@ -1910,11 +1893,11 @@ PODS: - React-jsinspectornetwork - React-jsinspectortracing - React-oscompat - - React-perflogger (= 0.83.1) + - React-perflogger (= 0.85.3) - React-runtimeexecutor - React-utils - SocketRocket - - React-jsinspectorcdp (0.83.1): + - React-jsinspectorcdp (0.85.3): - boost - DoubleConversion - fast_float @@ -1923,7 +1906,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - SocketRocket - - React-jsinspectornetwork (0.83.1): + - React-jsinspectornetwork (0.85.3): - boost - DoubleConversion - fast_float @@ -1933,7 +1916,7 @@ PODS: - RCT-Folly/Fabric - React-jsinspectorcdp - SocketRocket - - React-jsinspectortracing (0.83.1): + - React-jsinspectortracing (0.85.3): - boost - DoubleConversion - fast_float @@ -1946,27 +1929,29 @@ PODS: - React-jsinspectornetwork - React-oscompat - React-timing + - React-utils - SocketRocket - - React-jsitooling (0.83.1): + - React-jsitooling (0.85.3): - boost - DoubleConversion - fast_float - fmt - glog + - hermes-engine - RCT-Folly - RCT-Folly/Fabric - - React-cxxreact (= 0.83.1) + - React-cxxreact (= 0.85.3) - React-debug - - React-jsi (= 0.83.1) + - React-jsi (= 0.85.3) - React-jsinspector - React-jsinspectorcdp - React-jsinspectortracing - React-runtimeexecutor - React-utils - SocketRocket - - React-jsitracing (0.83.1): + - React-jsitracing (0.85.3): - React-jsi - - React-logger (0.83.1): + - React-logger (0.85.3): - boost - DoubleConversion - fast_float @@ -1975,7 +1960,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - SocketRocket - - React-Mapbuffer (0.83.1): + - React-Mapbuffer (0.85.3): - boost - DoubleConversion - fast_float @@ -1985,7 +1970,7 @@ PODS: - RCT-Folly/Fabric - React-debug - SocketRocket - - React-microtasksnativemodule (0.83.1): + - React-microtasksnativemodule (0.85.3): - boost - DoubleConversion - fast_float @@ -1999,6 +1984,27 @@ PODS: - React-RCTFBReactNativeSpec - ReactCommon/turbomodule/core - SocketRocket + - React-mutationobservernativemodule (0.85.3): + - boost + - DoubleConversion + - fast_float + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - React-cxxreact + - React-Fabric + - React-Fabric/bridging + - React-Fabric/observers/mutation + - React-featureflags + - React-jsi + - React-jsiexecutor + - React-RCTFBReactNativeSpec + - React-runtimeexecutor + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga - react-native-biometrics (3.0.1): - React-Core - react-native-blur (4.4.1): @@ -2385,7 +2391,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - React-NativeModulesApple (0.83.1): + - React-NativeModulesApple (0.85.3): - boost - DoubleConversion - fast_float @@ -2406,7 +2412,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - SocketRocket - - React-networking (0.83.1): + - React-networking (0.85.3): - boost - DoubleConversion - fast_float @@ -2414,14 +2420,13 @@ PODS: - glog - RCT-Folly - RCT-Folly/Fabric - - React-featureflags - React-jsinspectornetwork - React-jsinspectortracing - React-performancetimeline - React-timing - SocketRocket - - React-oscompat (0.83.1) - - React-perflogger (0.83.1): + - React-oscompat (0.85.3) + - React-perflogger (0.85.3): - boost - DoubleConversion - fast_float @@ -2430,7 +2435,7 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - SocketRocket - - React-performancecdpmetrics (0.83.1): + - React-performancecdpmetrics (0.85.3): - boost - DoubleConversion - fast_float @@ -2444,7 +2449,7 @@ PODS: - React-runtimeexecutor - React-timing - SocketRocket - - React-performancetimeline (0.83.1): + - React-performancetimeline (0.85.3): - boost - DoubleConversion - fast_float @@ -2453,13 +2458,14 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - React-featureflags + - React-jsinspector - React-jsinspectortracing - React-perflogger - React-timing - SocketRocket - - React-RCTActionSheet (0.83.1): - - React-Core/RCTActionSheetHeaders (= 0.83.1) - - React-RCTAnimation (0.83.1): + - React-RCTActionSheet (0.85.3): + - React-Core/RCTActionSheetHeaders (= 0.85.3) + - React-RCTAnimation (0.85.3): - boost - DoubleConversion - fast_float @@ -2469,13 +2475,14 @@ PODS: - RCT-Folly/Fabric - RCTTypeSafety - React-Core/RCTAnimationHeaders + - React-debug - React-featureflags - React-jsi - React-NativeModulesApple - React-RCTFBReactNativeSpec - ReactCommon - SocketRocket - - React-RCTAppDelegate (0.83.1): + - React-RCTAppDelegate (0.85.3): - boost - DoubleConversion - fast_float @@ -2509,7 +2516,7 @@ PODS: - React-utils - ReactCommon - SocketRocket - - React-RCTBlob (0.83.1): + - React-RCTBlob (0.85.3): - boost - DoubleConversion - fast_float @@ -2528,7 +2535,7 @@ PODS: - React-RCTNetwork - ReactCommon - SocketRocket - - React-RCTFabric (0.83.1): + - React-RCTFabric (0.85.3): - boost - DoubleConversion - fast_float @@ -2565,7 +2572,7 @@ PODS: - React-utils - SocketRocket - Yoga - - React-RCTFBReactNativeSpec (0.83.1): + - React-RCTFBReactNativeSpec (0.85.3): - boost - DoubleConversion - fast_float @@ -2579,10 +2586,10 @@ PODS: - React-Core - React-jsi - React-NativeModulesApple - - React-RCTFBReactNativeSpec/components (= 0.83.1) + - React-RCTFBReactNativeSpec/components (= 0.85.3) - ReactCommon - SocketRocket - - React-RCTFBReactNativeSpec/components (0.83.1): + - React-RCTFBReactNativeSpec/components (0.85.3): - boost - DoubleConversion - fast_float @@ -2605,7 +2612,7 @@ PODS: - ReactCommon - SocketRocket - Yoga - - React-RCTImage (0.83.1): + - React-RCTImage (0.85.3): - boost - DoubleConversion - fast_float @@ -2621,14 +2628,14 @@ PODS: - React-RCTNetwork - ReactCommon - SocketRocket - - React-RCTLinking (0.83.1): - - React-Core/RCTLinkingHeaders (= 0.83.1) - - React-jsi (= 0.83.1) + - React-RCTLinking (0.85.3): + - React-Core/RCTLinkingHeaders (= 0.85.3) + - React-jsi (= 0.85.3) - React-NativeModulesApple - React-RCTFBReactNativeSpec - ReactCommon - - ReactCommon/turbomodule/core (= 0.83.1) - - React-RCTNetwork (0.83.1): + - ReactCommon/turbomodule/core (= 0.85.3) + - React-RCTNetwork (0.85.3): - boost - DoubleConversion - fast_float @@ -2648,7 +2655,7 @@ PODS: - React-RCTFBReactNativeSpec - ReactCommon - SocketRocket - - React-RCTRuntime (0.83.1): + - React-RCTRuntime (0.85.3): - boost - DoubleConversion - fast_float @@ -2670,7 +2677,7 @@ PODS: - React-RuntimeHermes - React-utils - SocketRocket - - React-RCTSettings (0.83.1): + - React-RCTSettings (0.85.3): - boost - DoubleConversion - fast_float @@ -2685,10 +2692,10 @@ PODS: - React-RCTFBReactNativeSpec - ReactCommon - SocketRocket - - React-RCTText (0.83.1): - - React-Core/RCTTextHeaders (= 0.83.1) + - React-RCTText (0.85.3): + - React-Core/RCTTextHeaders (= 0.85.3) - Yoga - - React-RCTVibration (0.83.1): + - React-RCTVibration (0.85.3): - boost - DoubleConversion - fast_float @@ -2702,11 +2709,11 @@ PODS: - React-RCTFBReactNativeSpec - ReactCommon - SocketRocket - - React-rendererconsistency (0.83.1) - - React-renderercss (0.83.1): + - React-rendererconsistency (0.85.3) + - React-renderercss (0.85.3): - React-debug - React-utils - - React-rendererdebug (0.83.1): + - React-rendererdebug (0.85.3): - boost - DoubleConversion - fast_float @@ -2716,7 +2723,7 @@ PODS: - RCT-Folly/Fabric - React-debug - SocketRocket - - React-RuntimeApple (0.83.1): + - React-RuntimeApple (0.85.3): - boost - DoubleConversion - fast_float @@ -2745,7 +2752,7 @@ PODS: - React-runtimescheduler - React-utils - SocketRocket - - React-RuntimeCore (0.83.1): + - React-RuntimeCore (0.85.3): - boost - DoubleConversion - fast_float @@ -2767,7 +2774,7 @@ PODS: - React-runtimescheduler - React-utils - SocketRocket - - React-runtimeexecutor (0.83.1): + - React-runtimeexecutor (0.85.3): - boost - DoubleConversion - fast_float @@ -2777,10 +2784,10 @@ PODS: - RCT-Folly/Fabric - React-debug - React-featureflags - - React-jsi (= 0.83.1) + - React-jsi (= 0.85.3) - React-utils - SocketRocket - - React-RuntimeHermes (0.83.1): + - React-RuntimeHermes (0.85.3): - boost - DoubleConversion - fast_float @@ -2801,7 +2808,7 @@ PODS: - React-runtimeexecutor - React-utils - SocketRocket - - React-runtimescheduler (0.83.1): + - React-runtimescheduler (0.85.3): - boost - DoubleConversion - fast_float @@ -2823,9 +2830,9 @@ PODS: - React-timing - React-utils - SocketRocket - - React-timing (0.83.1): + - React-timing (0.85.3): - React-debug - - React-utils (0.83.1): + - React-utils (0.85.3): - boost - DoubleConversion - fast_float @@ -2835,9 +2842,9 @@ PODS: - RCT-Folly - RCT-Folly/Fabric - React-debug - - React-jsi (= 0.83.1) + - React-jsi (= 0.85.3) - SocketRocket - - React-webperformancenativemodule (0.83.1): + - React-webperformancenativemodule (0.85.3): - boost - DoubleConversion - fast_float @@ -2854,9 +2861,9 @@ PODS: - React-runtimeexecutor - ReactCommon/turbomodule/core - SocketRocket - - ReactAppDependencyProvider (0.83.1): + - ReactAppDependencyProvider (0.85.3): - ReactCodegen - - ReactCodegen (0.83.1): + - ReactCodegen (0.85.3): - boost - DoubleConversion - fast_float @@ -2882,7 +2889,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - SocketRocket - - ReactCommon (0.83.1): + - ReactCommon (0.85.3): - boost - DoubleConversion - fast_float @@ -2890,9 +2897,9 @@ PODS: - glog - RCT-Folly - RCT-Folly/Fabric - - ReactCommon/turbomodule (= 0.83.1) + - ReactCommon/turbomodule (= 0.85.3) - SocketRocket - - ReactCommon/turbomodule (0.83.1): + - ReactCommon/turbomodule (0.85.3): - boost - DoubleConversion - fast_float @@ -2901,15 +2908,15 @@ PODS: - hermes-engine - RCT-Folly - RCT-Folly/Fabric - - React-callinvoker (= 0.83.1) - - React-cxxreact (= 0.83.1) - - React-jsi (= 0.83.1) - - React-logger (= 0.83.1) - - React-perflogger (= 0.83.1) - - ReactCommon/turbomodule/bridging (= 0.83.1) - - ReactCommon/turbomodule/core (= 0.83.1) + - React-callinvoker (= 0.85.3) + - React-cxxreact (= 0.85.3) + - React-jsi (= 0.85.3) + - React-logger (= 0.85.3) + - React-perflogger (= 0.85.3) + - ReactCommon/turbomodule/bridging (= 0.85.3) + - ReactCommon/turbomodule/core (= 0.85.3) - SocketRocket - - ReactCommon/turbomodule/bridging (0.83.1): + - ReactCommon/turbomodule/bridging (0.85.3): - boost - DoubleConversion - fast_float @@ -2918,13 +2925,13 @@ PODS: - hermes-engine - RCT-Folly - RCT-Folly/Fabric - - React-callinvoker (= 0.83.1) - - React-cxxreact (= 0.83.1) - - React-jsi (= 0.83.1) - - React-logger (= 0.83.1) - - React-perflogger (= 0.83.1) + - React-callinvoker (= 0.85.3) + - React-cxxreact (= 0.85.3) + - React-jsi (= 0.85.3) + - React-logger (= 0.85.3) + - React-perflogger (= 0.85.3) - SocketRocket - - ReactCommon/turbomodule/core (0.83.1): + - ReactCommon/turbomodule/core (0.85.3): - boost - DoubleConversion - fast_float @@ -2933,14 +2940,14 @@ PODS: - hermes-engine - RCT-Folly - RCT-Folly/Fabric - - React-callinvoker (= 0.83.1) - - React-cxxreact (= 0.83.1) - - React-debug (= 0.83.1) - - React-featureflags (= 0.83.1) - - React-jsi (= 0.83.1) - - React-logger (= 0.83.1) - - React-perflogger (= 0.83.1) - - React-utils (= 0.83.1) + - React-callinvoker (= 0.85.3) + - React-cxxreact (= 0.85.3) + - React-debug (= 0.85.3) + - React-featureflags (= 0.85.3) + - React-jsi (= 0.85.3) + - React-logger (= 0.85.3) + - React-perflogger (= 0.85.3) + - React-utils (= 0.85.3) - SocketRocket - ReactNativeExceptionHandler (2.10.10): - React-Core @@ -3100,18 +3107,96 @@ PODS: - SDWebImageWebPCoder (~> 0.14) - SocketRocket - Yoga - - RNFBApp (23.8.2): - - Firebase/CoreOnly (= 12.8.0) + - RNFBApp (24.0.0): + - boost + - DoubleConversion + - fast_float + - Firebase/CoreOnly (= 12.10.0) + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety - React-Core - - RNFBAppCheck (23.8.2): - - Firebase/AppCheck (= 12.8.0) + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - SocketRocket + - Yoga + - RNFBAppCheck (24.0.0): + - boost + - DoubleConversion + - fast_float + - Firebase/AppCheck (= 12.10.0) + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core - RNFBApp - - RNFBMessaging (23.8.2): - - Firebase/Messaging (= 12.8.0) + - SocketRocket + - Yoga + - RNFBMessaging (24.0.0): + - boost + - DoubleConversion + - fast_float + - Firebase/Messaging (= 12.10.0) - FirebaseCoreExtension + - fmt + - glog + - hermes-engine + - RCT-Folly + - RCT-Folly/Fabric + - RCTRequired + - RCTTypeSafety - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core - RNFBApp + - SocketRocket + - Yoga - RNFS (2.20.0): - React-Core - RNGestureHandler (2.30.0): @@ -3263,7 +3348,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - RNReanimated (4.2.1): + - RNReanimated (4.3.1): - boost - DoubleConversion - fast_float @@ -3290,11 +3375,12 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNReanimated/reanimated (= 4.2.1) + - RNReanimated/apple (= 4.3.1) + - RNReanimated/common (= 4.3.1) - RNWorklets - SocketRocket - Yoga - - RNReanimated/reanimated (4.2.1): + - RNReanimated/apple (4.3.1): - boost - DoubleConversion - fast_float @@ -3321,11 +3407,10 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNReanimated/reanimated/apple (= 4.2.1) - RNWorklets - SocketRocket - Yoga - - RNReanimated/reanimated/apple (4.2.1): + - RNReanimated/common (4.3.1): - boost - DoubleConversion - fast_float @@ -3448,7 +3533,7 @@ PODS: - Yoga - RNSha256 (1.4.10): - React-Core - - RNSVG (15.15.1): + - RNSVG (15.15.5): - boost - DoubleConversion - fast_float @@ -3474,10 +3559,10 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNSVG/common (= 15.15.1) + - RNSVG/common (= 15.15.5) - SocketRocket - Yoga - - RNSVG/common (15.15.1): + - RNSVG/common (15.15.5): - boost - DoubleConversion - fast_float @@ -3505,7 +3590,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - RNWorklets (0.7.1): + - RNWorklets (0.8.3): - boost - DoubleConversion - fast_float @@ -3532,10 +3617,11 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNWorklets/worklets (= 0.7.1) + - RNWorklets/apple (= 0.8.3) + - RNWorklets/common (= 0.8.3) - SocketRocket - Yoga - - RNWorklets/worklets (0.7.1): + - RNWorklets/apple (0.8.3): - boost - DoubleConversion - fast_float @@ -3562,10 +3648,9 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNWorklets/worklets/apple (= 0.7.1) - SocketRocket - Yoga - - RNWorklets/worklets/apple (0.7.1): + - RNWorklets/common (0.8.3): - boost - DoubleConversion - fast_float @@ -3594,9 +3679,9 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - SDWebImage (5.21.5): - - SDWebImage/Core (= 5.21.5) - - SDWebImage/Core (5.21.5) + - SDWebImage (5.21.7): + - SDWebImage/Core (= 5.21.7) + - SDWebImage/Core (5.21.7) - SDWebImageAVIFCoder (0.11.1): - libavif/core (>= 0.11.0) - SDWebImage (~> 5.10) @@ -3660,6 +3745,7 @@ DEPENDENCIES: - React-logger (from `../node_modules/react-native/ReactCommon/logger`) - React-Mapbuffer (from `../node_modules/react-native/ReactCommon`) - React-microtasksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`) + - React-mutationobservernativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/mutationobserver`) - react-native-biometrics (from `../node_modules/react-native-biometrics`) - "react-native-blur (from `../node_modules/@react-native-community/blur`)" - react-native-cloud-fs (from `../node_modules/react-native-cloud-fs`) @@ -3783,7 +3869,7 @@ EXTERNAL SOURCES: :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" hermes-engine: :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" - :tag: hermes-v0.14.0 + :tag: hermes-v250829098.0.10 RCT-Folly: :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" RCTDeprecation: @@ -3856,6 +3942,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon" React-microtasksnativemodule: :path: "../node_modules/react-native/ReactCommon/react/nativemodule/microtasks" + React-mutationobservernativemodule: + :path: "../node_modules/react-native/ReactCommon/react/nativemodule/mutationobserver" react-native-biometrics: :path: "../node_modules/react-native-biometrics" react-native-blur: @@ -4015,148 +4103,149 @@ SPEC CHECKSUMS: boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90 DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb fast_float: b32c788ed9c6a8c584d114d0047beda9664e7cc6 - FBLazyVector: 309703e71d3f2f1ed7dc7889d58309c9d77a95a4 - Firebase: 9a58fdbc9d8655ed7b79a19cf9690bb007d3d46d - FirebaseAppCheck: 11da425929a45c677d537adfff3520ccd57c1690 - FirebaseAppCheckInterop: ba3dc604a89815379e61ec2365101608d365cf7d - FirebaseCore: 0dbad74bda10b8fb9ca34ad8f375fb9dd3ebef7c - FirebaseCoreExtension: 6605938d51f765d8b18bfcafd2085276a252bee2 - FirebaseCoreInternal: fe5fa466aeb314787093a7dce9f0beeaad5a2a21 - FirebaseInstallations: 6a14ab3d694ebd9f839c48d330da5547e9ca9dc0 - FirebaseMessaging: 7f42cfd10ec64181db4e01b305a613791c8e782c - fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd - glog: 5683914934d5b6e4240e497e0f4a3b42d1854183 + FBLazyVector: 473b935415b82ae4f7f9aa9d5b3378491143ccbf + Firebase: 99f203d3a114c6ba591f3b32263a9626e450af65 + FirebaseAppCheck: 3cd5112c60c3b04e6207e41a864b6c3cb06f73ad + FirebaseAppCheckInterop: 2480ab50a070a6bc02e26e62733874361f017a11 + FirebaseCore: f4428e22415ea3b3eca652c2098413dabf2a23a9 + FirebaseCoreExtension: 3473a6ec16a91aee29fb75994a86c0220d2cddf3 + FirebaseCoreInternal: e7bbaeb00ab73011298f35ed223aa7371e212948 + FirebaseInstallations: 047343aa91fd6a1ebfa3eb374ddecf36a8aaddfd + FirebaseMessaging: ed18fb50634e6e85b5d3e77e628c21e2c928cc53 + fmt: 530618a01105dae0fa3a2f27c81ae11fa8f67eac + glog: e56ede4028c4b7418e6b1195a36b1656bb35e225 GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 GoogleSignIn: fcee2257188d5eda57a5e2b6a715550ffff9206d GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 GTMAppAuth: 217a876b249c3c585a54fd6f73e6b58c4f5c4238 GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 - hermes-engine: 14aa635b6bd5805973f70fb9acddb60e03442a22 + hermes-engine: d966b1de293ca04584eccd89d1de4c7c45e1aebe libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7 libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8 nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 - RCT-Folly: 59ec0ac1f2f39672a0c6e6cecdd39383b764646f - RCTDeprecation: a41bbdd9af30bf2e5715796b313e44ec43eefff1 - RCTRequired: 7be34aabb0b77c3cefe644528df0fa0afad4e4d0 - RCTSwiftUI: a6c7271c39098bf00dbdad8f8ed997a59bbfbe44 - RCTSwiftUIWrapper: 5ec163e8fde163d3fba714a992b50a266e1ece37 - RCTTypeSafety: 27927d0ca04e419ed9467578b3e6297e37210b5c - React: 4bc1f928568ad4bcfd147260f907b4ea5873a03b - React-callinvoker: 87f8728235a0dc62e9dc19b3851c829d9347d015 + RCT-Folly: 36c4f904fb6cd0219dcb76b94e9502d2a72fab0b + RCTDeprecation: 225e022b85a206cf0883a909c4a114159783363c + RCTRequired: 827a95c181af0886a11e21bc66c084088cf87839 + RCTSwiftUI: 7babb07156ae0a8e5ea97f77e43959ddaca2c6f2 + RCTSwiftUIWrapper: 30f2e591ca57d625a244acd866fa169fd4859273 + RCTTypeSafety: 47f936a87875e1a08ccf1ffe34e8bf29f1d85567 + React: e2dc35338068bbd299c66f043ae0d7f25de8499e + React-callinvoker: d3163d80425735b095cff517da3b8631691fd734 React-Codegen: 4b8b4817cea7a54b83851d4c1f91f79aa73de30a - React-Core: 19e0183e28d7a6613ecacebd7525fe6650efa3b6 - React-CoreModules: 73cc86f2a0ff84b93d6325073ad2e4874d21ad40 - React-cxxreact: 4bf734645c77c9b86e2f3e933e0411cf2f14d1ba - React-debug: b2c9f60a9b7a81cefd737cb61e31c2bc39fdfe17 - React-defaultsnativemodule: d5577e030a746840c77d791f06382a5fd7c2b789 - React-domnativemodule: cec896810e9856a07ae62682b2c4e699307f9f35 - React-Fabric: ea457167d2bb9b8ceb31fd0882393ab08d32f0b8 - React-FabricComponents: aa8cf0b3409a81222786fb6e2e45069f44e060ca - React-FabricImage: 7629c06d41d6dea01d152ce0077b15147169f48f - React-featureflags: 7f1e45dd4148aabba7b42b2d588fb45d432c0a6d - React-featureflagsnativemodule: cb1c09c4e3e4873f101bbdd9be2fa0f7906ec5ab - React-graphics: 163d15b019d7ff23032a1a8d2b37f5afdd561bbb - React-hermes: ec50b9fcea2c3bfdd42f8cec845eac3f35888572 - React-idlecallbacksnativemodule: 1a358f7d16b9ff916a646ba184cded54f74439b8 - React-ImageManager: 958477b5f4acc67f864111c55de84bcdbd1d6592 - React-intersectionobservernativemodule: 189460858d6105bc44ded7fb02d19cd887f25bc6 - React-jserrorhandler: 291eddd4e3dc80927c306e039ecbeb4dc515eb6f - React-jsi: 3216c876cd4c571a57909e22d77c8fd9530aa067 - React-jsiexecutor: 475563c0042841a85930a455d3199f6b1483a5fe - React-jsinspector: 856aff364b569a4cd861605656de41d34c3cd92d - React-jsinspectorcdp: f34715c4c392e75f217bd5453aa8ff5bc394c111 - React-jsinspectornetwork: 8a02d4d189476b1a92d6c49014fa83973b6fc24d - React-jsinspectortracing: 9a97753c772fbce4f2ed8d4fb684e507d7e49a5a - React-jsitooling: 6fda3ff1bfed7525e7be2f5ca152b6d2d378e4a8 - React-jsitracing: a2dd6d6df9d017d5be176d5e71e09f8ce6f99594 - React-logger: 6ac901f5c7f7321d2be1a40b203bccc2e23411e3 - React-Mapbuffer: 9d33f0f79b6b5705d08d89d8fb9709d1ee655c81 - React-microtasksnativemodule: 1a5a9488d2a05c74ea276c2012df632d8221d169 - react-native-biometrics: 352e5a794bfffc46a0c86725ea7dc62deb085bdc - react-native-blur: 981b2ec64b3084ecf98812333f2a8c6e83643a1e - react-native-cloud-fs: cd21282c5cecaf285225e447dd7f3cf2f9015496 - react-native-config: 81fd713bbbc6fbe39588c975edf5485d0e15adf8 - react-native-document-picker: ca09736423f98ee844aec0ecf76c280103ef05cd - react-native-get-random-values: 4c1e8378eb5a30b2ac9aa6e28da7c3a987350e8a - react-native-netinfo: f0a9899081c185db1de5bb2fdc1c88c202a059ac - react-native-orientation-locker: 5819fd23ca89cbac0d736fb4314745f62716d517 - react-native-restart: 7595693413fe3ca15893702f2c8306c62a708162 - react-native-safe-area-context: fea29ae0275beaa22f72d0a8be1eb0ab09c3feae - react-native-sapling: 36b28bc90d96e6ccc754c515d0dd3ba99049a094 - react-native-slider: f44eb4f327db65c7c0519cc91aefb7b0d50f1615 - react-native-themis: 52e1ff00dbd17ca8ddec02c6e071259602f4b5c7 - react-native-video: f9758cda5b9dd6fd378389002f28f3f19017a406 - react-native-webview: 5887b6094417c75a9bee446261f89c32adf6b602 - React-NativeModulesApple: dfce21d2c4b7eab44db0af861fcb8998d0b8ad16 - React-networking: 26355121d0bf86d974dff5a3cc11f8aeb9f28a22 - React-oscompat: 80166b66da22e7af7fad94474e9997bd52d4c8c6 - React-perflogger: 63c90e0d8c24df87ffa14dad01aeafc352847dd0 - React-performancecdpmetrics: 5b0a0eb369b5fcb18109fba91bdd5ac2a2360753 - React-performancetimeline: 9a45658d92ce7b30d41fa557bbe9fa7c399f301b - React-RCTActionSheet: 3bd5f5db9f983cf38d51bb9a7a198e2ebea94821 - React-RCTAnimation: 346865a809fa5132f6c594c8b376c6cf46b44e88 - React-RCTAppDelegate: b2d1e0d3663c987f49f45094883b9e36fcbf0181 - React-RCTBlob: 74759ebb7ff9077d19f60c301782c1f8c3eb2813 - React-RCTFabric: 7a352dc4db7da5334b36d0074d3e44a112d4d168 - React-RCTFBReactNativeSpec: f74fabd086f4a302a9883086ad1398a4408aecd4 - React-RCTImage: 60763f56e8a5e45d861d7c4777e428bb820ec52a - React-RCTLinking: 52aee78b0b3163167c7fcf58f80a42943c03a056 - React-RCTNetwork: f5e1e8ae5eff6982efff6289b06ec0a76d0a6ac2 - React-RCTRuntime: b1c69249aab7cf0ff2b9cf7bd7d1cdc23c60c89f - React-RCTSettings: 298bb40d3412bf32e0b4f0797e48416b0b7278a1 - React-RCTText: dfb74800e27d792d1188fa975a3b9807c3362e3e - React-RCTVibration: ffe5fd4f50a835e353a3b6869eb005dab11eea44 - React-rendererconsistency: ac8a9e9ee3eb299458cc848944133ff4be46cc41 - React-renderercss: 25ff740b0da15dab6ba505c702c86bfbe9cd764e - React-rendererdebug: 48afb7a15ed4f2a87760e63abdc70bb92f4165d0 - React-RuntimeApple: bcc8fbdce32bc7100294bf9a4b741da233d38de2 - React-RuntimeCore: 632c35fbe0980a390719470a9f6d2f1ba9dc3bd0 - React-runtimeexecutor: 8151aae90978856b75f3c5079c428c00f795ffa6 - React-RuntimeHermes: 1269317d3d7d899f27aa3c03a04d7ce017171837 - React-runtimescheduler: 752209b337a93cd3a25ecea691308f6b801706cf - React-timing: 73729fab687aa4876d45707e9f7ddc9446effab1 - React-utils: a60c501ec701ca062f3c5367ce766c4e5bfc363a - React-webperformancenativemodule: 7ec95df9690d9cc96e31f3282facecd39a3914a6 - ReactAppDependencyProvider: bfb12ead469222b022a2024f32aba47ce50de512 - ReactCodegen: 0e88072391201f99a9ce48e9ad27310d63b336ae - ReactCommon: 136c3863bf14312a58944f674691f2c5874deafb - ReactNativeExceptionHandler: b11ff67c78802b2f62eed0e10e75cb1ef7947c60 - RNBootSplash: d8407c268d5159ea026dc741ec867ebbe4708f25 - RNCAsyncStorage: 8857fb173af29664cb90897903902dc8533e36cc - RNCClipboard: 4eea71d801c880175c12f6ab14332ca86fed935f - RNCMaskedView: 8bfc13a356455b15d56114738f4d2a804769c1bf - RNDeviceInfo: 53f9c84e28e854a308d3e548e25ef120b4615531 - RNExitApp: a804a6de055a698e2f6c11e8fce146c5c8ce3ead - RNFastImage: 94681302bfbe8076b0163450183ae2121b45e525 - RNFBApp: 76f7bc724c9b60f1439ca60b256eed17b14a6ddb - RNFBAppCheck: 52bbfdd0396db9fe16e5734a36734e9edb3535ee - RNFBMessaging: a39a75dc6e4f3d1433eaffefe131a400380602a3 - RNFS: 4ac0f0ea233904cb798630b3c077808c06931688 - RNGestureHandler: 1f7ac76fa9d6ffedfdde38ce781442ffadac8880 - RNGoogleSignin: 9c5c73089b78fd865f9a6758fc05ef7da7bd2be2 - RNKeychain: d0bdaca4688ae123909b137de08491f49a6cf6b1 - RNNotifee: 4a6ee5c7deaf00e005050052d73ee6315dff7ec9 - RNPermissions: d5c31fdf7f0368d8740f2d3aefe212ed007e6cca - RNQuickAction: 6d404a869dc872cde841ad3147416a670d13fa93 - RNReactNativeHapticFeedback: 43c09eb41d8321be2e1375cb87ae734e58f677b0 - RNReanimated: 0a23a0a9721f450580f0fdf04b9ae928cd22915a - RNScreens: c73f6bcfc19e209736c4e069f62b0f274535214b - RNScrypt: 95fdef077b482e9fdf8a761120cb69d129ef4016 - RNSentry: f3c0498f67c1a7ff86155b66b74318cdfcaeb693 - RNSha256: e1bc64e9e50b293d5282bb4caa1b2043931f1c9d - RNSVG: 5bd1e478698eb9e5cc8f926157333ac814468064 - RNWorklets: b94f5c1b61a985c309dcc0092aacf41515cc39d6 - SDWebImage: e9c98383c7572d713c1a0d7dd2783b10599b9838 + React-Core: 821522bb86acc8bbe37698e87a6862a1f0504b05 + React-CoreModules: f732869c77b076b962a4e3ee5becd704a87d2817 + React-cxxreact: 84b7c9400c1c84bde649d06755b9c64b48114904 + React-debug: f6293d03b643d4bcc487c7da7c745a75fd48ad7d + React-defaultsnativemodule: c412503114bae304c667d832bf838619f82e6937 + React-domnativemodule: c4fd125653b3753879e75adf5aa7c8438d9a9142 + React-Fabric: c6bfb98333f99e6c81916ffa4705326e1716745c + React-FabricComponents: 8b869a560a7db0b208ae33550f0aa6f9ce446b27 + React-FabricImage: e78a213d6a359c9927de1eb4f81444c5bc65cf7a + React-featureflags: bb7e30ca0fe9a8421e094536a25650c6ce9e5212 + React-featureflagsnativemodule: 1a09ad358e71d6d69b1d7a4b54fd93a0f8acd5cf + React-graphics: 268f4c2718610747287d32d25287d8b50d303e7e + React-hermes: c14b3df7089e74ebe956636598734f6996985641 + React-idlecallbacksnativemodule: dfd9165a261c4b5c7cb4ed741642bce63fdbea7c + React-ImageManager: 3fdbb547b886755b08eb4cc20c3087292adb4d1d + React-intersectionobservernativemodule: cd85dd1826f19f2473d83f100e18c5f5860c515e + React-jserrorhandler: ee2d3ffb79eabd6663a908fd5a5cab8ff9d2363d + React-jsi: d2616066314453f8059b4e2f5f7967b926ba5bf6 + React-jsiexecutor: f9c7fba6062530924ae402fd72789dd7479002dd + React-jsinspector: 34e269fd0bf776dabaa62678b25c0be73670c31a + React-jsinspectorcdp: 98fd3b1d42052813788a1a06a3cbbf84c2f4a5e9 + React-jsinspectornetwork: b3f3af03024340c1403a79dc4cc65fa9e13a7bec + React-jsinspectortracing: 2c8b432316abf2b089f6e6c108b7ddd82e3d335d + React-jsitooling: 22410dec7b0df633e0635b7607971175bca736ea + React-jsitracing: cb1c2483e0263022c88359a8438cf44711197342 + React-logger: 65c987d6465d254c08c9eb0fb6145be6eb8ca9ba + React-Mapbuffer: 9c9e5f0871d36f59b5b3421b6121596a6a74e67b + React-microtasksnativemodule: c8315d5f4ae7188f30cbfa499d8ec2e9281b97b1 + React-mutationobservernativemodule: 9bb7f57044059bcaf28e0287154942acd9b9b6dc + react-native-biometrics: 43ed5b828646a7862dbc7945556446be00798e7d + react-native-blur: b83ffbc5380d8bd2f06804b4b0e848be3507e65c + react-native-cloud-fs: 1f838a872b0204376514f5df175ccbbd342f496f + react-native-config: 916e53e7333d5b2bcb7ee9882f5605143b4fc4c5 + react-native-document-picker: 910f7b853dc56664285752289d477a48537f0178 + react-native-get-random-values: 9ef342c6e33fa57ac82f73e9270d5d651a48071a + react-native-netinfo: cec9c4e86083cb5b6aba0e0711f563e2fbbff187 + react-native-orientation-locker: cc6f357b289a2e0dd2210fea0c52cb8e0727fdaa + react-native-restart: 0bc732f4461709022a742bb29bcccf6bbc5b4863 + react-native-safe-area-context: 0a3b034bb63a5b684dd2f5fffd3c90ef6ed41ee8 + react-native-sapling: dcefd6adbe3dc7717a8336f7a9719c046b35ddab + react-native-slider: 05e7080478df08489251c2a6739a0d5628b7c198 + react-native-themis: b681fd9654ec2b55b9fb81d086159d974f752d6c + react-native-video: 624deff94be379ffaba289bed13fc0917f01abcb + react-native-webview: cdce419e8022d0ef6f07db21890631258e7a9e6e + React-NativeModulesApple: 67c09c715a8763a07a8a241a3019661ffc3f71d6 + React-networking: 72b8973a280b6a54e46930717e6c15f7c389d76e + React-oscompat: 563c536fc2d9cece1f54442fa2a3d9f68a9621e3 + React-perflogger: 69b12c83ec90d61e9fc8055bdce33f3fed9978b3 + React-performancecdpmetrics: dc08b5f87fa0c9c43915bfcd58b8124d2d07c8f9 + React-performancetimeline: 773a4631cf1a12499d25e5afe356c0d4934cb509 + React-RCTActionSheet: ea8200cac284d410090bd780baf729903912e4e6 + React-RCTAnimation: 2612fabae23447a1afa7ac7405fbb4d0f6fa52b0 + React-RCTAppDelegate: cf9ecbc46ee5d6aa9f06c60d8395aa13495d1368 + React-RCTBlob: 7b4d7420a6d46327eeeeacdbd54a392253517772 + React-RCTFabric: bcd85c8a26c49635e8056af7bdb480969244ae9d + React-RCTFBReactNativeSpec: 68368860f257ac2ec24a8584b933a9b10dd5dc4a + React-RCTImage: 9424c680b0866903ff65a9a093641f3d1e6ce85d + React-RCTLinking: c5dd340d5fee2fa01fee28750ae4211449fd3904 + React-RCTNetwork: 3fe661f94974cfba5126800d834f98e4608b2d68 + React-RCTRuntime: 1d8ae939d193598ff7de5043196cdc1b90135b71 + React-RCTSettings: 1ba76e945f541c1c246618d2775caea0c6a76e26 + React-RCTText: 1d7a4f263266efbd5fa5335a107fbd00ff94ba9e + React-RCTVibration: 0de7b5cc470892e4a65358ae7853f117fe5c2173 + React-rendererconsistency: e90b9e1bab21c3fabbaa220c3fab820ee81c59d9 + React-renderercss: 41759ec6208f3afe6f7cd0205d4358a983f7ac6d + React-rendererdebug: 0ddb9d40c7e40d47b03e7ef76b8ea02157ccf83c + React-RuntimeApple: 345c69430aba5a1f958962e7ea03d2bd88f017d0 + React-RuntimeCore: 189d7e79c2c57cc292973c9a21b595b5ab32f5ee + React-runtimeexecutor: 07bf5c4b99250eeb87d11c6a7525b2e23c4d9335 + React-RuntimeHermes: 7ab04f8717cb8cb4a95788d822e1d52c17b59f7c + React-runtimescheduler: 3a5dfc9754d01a25573a7814e204ce2285d10290 + React-timing: 52725a5eac08312f63ddf2fcedb11887249e62dc + React-utils: 13434fd45de041d5170cdb0a8e7fa593d9c3dc13 + React-webperformancenativemodule: 7c40fad73f558c60f3101e4b3fed0a3e66f7a312 + ReactAppDependencyProvider: 25c9c516839be2c5e3d3344f95dc7da5f7e63fc2 + ReactCodegen: 3a96f3289dc44bc80ba172d16419c058874afa20 + ReactCommon: f7748c97e657e7be0df505a5fc51c4ace9791a32 + ReactNativeExceptionHandler: a23922ca00122b050ae9412f960061791c232c47 + RNBootSplash: 7fcc9a58ae343aeb1a1dd49f9030832fe432c544 + RNCAsyncStorage: fd44f4b03e007e642e98df6726737bc66e9ba609 + RNCClipboard: e560338bf6cc4656a09ff90610b62ddc0dbdad65 + RNCMaskedView: d707a83784c67099b54b37d056ababb2767ce15e + RNDeviceInfo: 36d7f232bfe7c9b5c494cb7793230424ed32c388 + RNExitApp: a2fd7923ab37b9166704fdc488622a48dcd372a2 + RNFastImage: 674d5912e174468a60971d2ba9efc7bb43d116fa + RNFBApp: 59a5f1280d8c7d48ed5cb658682ed12904bca65e + RNFBAppCheck: 5a1a36ca7f428d174930bd6ecfdfcd8579cc0296 + RNFBMessaging: 296600da7f02e92bb6631c11ef5e19bc1b89a54d + RNFS: 89de7d7f4c0f6bafa05343c578f61118c8282ed8 + RNGestureHandler: 420e50a05cdec7de12a3c8ce2bde368130cfa9cc + RNGoogleSignin: c1de96d92d6dd4335fa8e0f0ed4312a9d34e4ecb + RNKeychain: 76d042fc1dfba47f3945920bc82e0bce9ad1ff55 + RNNotifee: 5e3b271e8ea7456a36eec994085543c9adca9168 + RNPermissions: 0dbae39cf157f6c699f1454bbdcc25a0977eca83 + RNQuickAction: c2c8f379e614428be0babe4d53a575739667744d + RNReactNativeHapticFeedback: 5f1542065f0b24c9252bd8cf3e83bc9c548182e4 + RNReanimated: 920c33f677549b725b3e4a571fa8eeda790703d0 + RNScreens: d6413aeb1878cdafd3c721e2c5218faf5d5d3b13 + RNScrypt: 3e8612600c93aaa3bfa7849b6d1a4ab61613e2af + RNSentry: 0cb5c73bdb064318193d5b658774bd34f83107cf + RNSha256: 4d35f112e967f58273d625a19376f4eafc72bd5c + RNSVG: 0b9792eb17fbbc8e6d186581cb2cf712998dcc2a + RNWorklets: 8598e72b87947ae2f8428a541440851eb50579c3 + SDWebImage: e9fc87c1aab89a8ab1bbd74eba378c6f53be8abf SDWebImageAVIFCoder: afe194a084e851f70228e4be35ef651df0fc5c57 SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c SDWebImageWebPCoder: 0e06e365080397465cc73a7a9b472d8a3bd0f377 Sentry: d587a8fe91ca13503ecd69a1905f3e8a0fcf61be SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 - VisionCamera: 68d40255fa8866e815cbbb063730102d3da276fd - Yoga: 33b53536a0500d039f2cd78caf1d5d68712d3af7 + VisionCamera: b51af005669c6642dd1b4fca434eda4c1778de87 + Yoga: 9d8e8094a2bed6a175d9e6001a0546d5dae663ee -PODFILE CHECKSUM: 6c9f36f7a741b08836b8fe7eeb4d59447eddae08 +PODFILE CHECKSUM: 37909e0c8f2a781d24747230d0c5d3554596f0ed COCOAPODS: 1.16.2 diff --git a/ios/TempleWallet.xcodeproj/project.pbxproj b/ios/TempleWallet.xcodeproj/project.pbxproj index 6e71d6462..c033187ca 100644 --- a/ios/TempleWallet.xcodeproj/project.pbxproj +++ b/ios/TempleWallet.xcodeproj/project.pbxproj @@ -823,6 +823,20 @@ "${PODS_CONFIGURATION_BUILD_DIR}/React-NativeModulesApple/React_NativeModulesApple.framework/Headers", "${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers", "${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios", + "${PODS_CONFIGURATION_BUILD_DIR}/React-featureflags/React_featureflags.framework/Headers", + "${PODS_CONFIGURATION_BUILD_DIR}/React-renderercss/React_renderercss.framework/Headers", + "${PODS_ROOT}/ReactCommon", + "${PODS_ROOT}/ReactCommon/react/nativemodule/core", + "${PODS_ROOT}/React-runtimeexecutor", + "${PODS_ROOT}/React-runtimeexecutor/platform/ios", + "${PODS_ROOT}/ReactCommon-Samples", + "${PODS_ROOT}/ReactCommon-Samples/platform/ios", + "${PODS_ROOT}/React-Fabric/react/renderer/components/view/platform/cxx", + "${PODS_ROOT}/React-NativeModulesApple", + "${PODS_ROOT}/React-graphics", + "${PODS_ROOT}/React-graphics/react/renderer/graphics/platform/ios", + "${PODS_ROOT}/React-featureflags", + "${PODS_ROOT}/React-renderercss", ); IPHONEOS_DEPLOYMENT_TARGET = 15.1; LD_RUNPATH_SEARCH_PATHS = ( @@ -836,7 +850,10 @@ ); MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; - OTHER_CFLAGS = "$(inherited)"; + OTHER_CFLAGS = ( + "$(inherited)", + "-DRCT_REMOVE_LEGACY_ARCH=1", + ); OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "-DFOLLY_NO_CONFIG", @@ -844,10 +861,12 @@ "-DFOLLY_USE_LIBCPP=1", "-DFOLLY_CFG_NO_COROUTINES=1", "-DFOLLY_HAVE_CLOCK_GETTIME=1", + "-DRCT_REMOVE_LEGACY_ARCH=1", ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG"; + SWIFT_ENABLE_EXPLICIT_MODULES = NO; USE_HERMES = true; }; name = Debug; @@ -906,6 +925,20 @@ "${PODS_CONFIGURATION_BUILD_DIR}/React-NativeModulesApple/React_NativeModulesApple.framework/Headers", "${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers", "${PODS_CONFIGURATION_BUILD_DIR}/React-graphics/React_graphics.framework/Headers/react/renderer/graphics/platform/ios", + "${PODS_CONFIGURATION_BUILD_DIR}/React-featureflags/React_featureflags.framework/Headers", + "${PODS_CONFIGURATION_BUILD_DIR}/React-renderercss/React_renderercss.framework/Headers", + "${PODS_ROOT}/ReactCommon", + "${PODS_ROOT}/ReactCommon/react/nativemodule/core", + "${PODS_ROOT}/React-runtimeexecutor", + "${PODS_ROOT}/React-runtimeexecutor/platform/ios", + "${PODS_ROOT}/ReactCommon-Samples", + "${PODS_ROOT}/ReactCommon-Samples/platform/ios", + "${PODS_ROOT}/React-Fabric/react/renderer/components/view/platform/cxx", + "${PODS_ROOT}/React-NativeModulesApple", + "${PODS_ROOT}/React-graphics", + "${PODS_ROOT}/React-graphics/react/renderer/graphics/platform/ios", + "${PODS_ROOT}/React-featureflags", + "${PODS_ROOT}/React-renderercss", ); IPHONEOS_DEPLOYMENT_TARGET = 15.1; LD_RUNPATH_SEARCH_PATHS = ( @@ -918,7 +951,10 @@ "\"$(inherited)\"", ); MTL_ENABLE_DEBUG_INFO = NO; - OTHER_CFLAGS = "$(inherited)"; + OTHER_CFLAGS = ( + "$(inherited)", + "-DRCT_REMOVE_LEGACY_ARCH=1", + ); OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", "-DFOLLY_NO_CONFIG", @@ -926,9 +962,11 @@ "-DFOLLY_USE_LIBCPP=1", "-DFOLLY_CFG_NO_COROUTINES=1", "-DFOLLY_HAVE_CLOCK_GETTIME=1", + "-DRCT_REMOVE_LEGACY_ARCH=1", ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; + SWIFT_ENABLE_EXPLICIT_MODULES = NO; USE_HERMES = true; VALIDATE_PRODUCT = YES; }; diff --git a/package.json b/package.json index 8c876af59..dff23aea5 100644 --- a/package.json +++ b/package.json @@ -40,9 +40,9 @@ "@react-native-community/netinfo": "^11.4.1", "@react-native-community/slider": "^5.1.1", "@react-native-documents/picker": "^12.0.0", - "@react-native-firebase/app": "^23.8.2", - "@react-native-firebase/app-check": "^23.8.2", - "@react-native-firebase/messaging": "^23.8.2", + "@react-native-firebase/app": "^24.0.0", + "@react-native-firebase/app-check": "^24.0.0", + "@react-native-firebase/messaging": "^24.0.0", "@react-native-google-signin/google-signin": "^16.1.1", "@react-native-masked-view/masked-view": "^0.3.2", "@react-navigation/native": "^7.1.27", @@ -106,7 +106,7 @@ "react-native-screens": "^4.19.0", "react-native-scrypt": "madfish-solutions/react-native-scrypt#120e21ee291ed6bbb51acd251e09f9efeedba3c2", "react-native-sha256": "^1.4.10", - "react-native-svg": "^15.15.1", + "react-native-svg": "^15.15.5", "react-native-swipe-list-view": "^3.2.9", "react-native-themis": "^0.15.6", "react-native-toast-message": "^2.3.3", diff --git a/src/components/button/button.styles.ts b/src/components/button/button.styles.ts index 9c6293adf..989582084 100644 --- a/src/components/button/button.styles.ts +++ b/src/components/button/button.styles.ts @@ -10,7 +10,7 @@ export const ButtonStyles = StyleSheet.create({ justifyContent: 'center' }, loader: { - ...StyleSheet.absoluteFillObject, + ...StyleSheet.absoluteFill, justifyContent: 'center' } }); diff --git a/src/components/image/react-native-image-progress/index.js b/src/components/image/react-native-image-progress/index.js index 2aa0ee29a..ff2de28c0 100644 --- a/src/components/image/react-native-image-progress/index.js +++ b/src/components/image/react-native-image-progress/index.js @@ -6,7 +6,7 @@ import { ActivityIndicator, Image, StyleSheet, View } from 'react-native'; const styles = StyleSheet.create({ centered: { - ...StyleSheet.absoluteFillObject, + ...StyleSheet.absoluteFill, alignItems: 'center', justifyContent: 'center' } diff --git a/src/components/segmented-control/segmented-control.styles.ts b/src/components/segmented-control/segmented-control.styles.ts index c1b840612..ec1f70689 100644 --- a/src/components/segmented-control/segmented-control.styles.ts +++ b/src/components/segmented-control/segmented-control.styles.ts @@ -16,7 +16,7 @@ export const useSegmentedControlStyles = createUseStyles(({ colors }) => ({ padding: formatSize(2) }, tile: { - ...StyleSheet.absoluteFillObject, + ...StyleSheet.absoluteFill, ...generateShadow(1, black), zIndex: 1, margin: tileMargin, @@ -24,7 +24,7 @@ export const useSegmentedControlStyles = createUseStyles(({ colors }) => ({ backgroundColor: colors.navigation }, contentContainer: { - ...StyleSheet.absoluteFillObject, + ...StyleSheet.absoluteFill, ...generateShadow(2, transparent), zIndex: 2, flexDirection: 'row', diff --git a/src/modals/kolo-card/kolo-card-widget-modal.styles.ts b/src/modals/kolo-card/kolo-card-widget-modal.styles.ts index 4c88d74d7..4053eca01 100644 --- a/src/modals/kolo-card/kolo-card-widget-modal.styles.ts +++ b/src/modals/kolo-card/kolo-card-widget-modal.styles.ts @@ -20,7 +20,7 @@ export const useKoloCardWidgetModalStyles = createUseStylesMemoized(({ colors }) backgroundColor: colors.pageBG }, loaderContainer: { - ...StyleSheet.absoluteFillObject, + ...StyleSheet.absoluteFill, justifyContent: 'center', alignItems: 'center', zIndex: 1 diff --git a/src/screens/wallet/backup-your-wallet-overlay/backup-your-wallet-overlay.styles.ts b/src/screens/wallet/backup-your-wallet-overlay/backup-your-wallet-overlay.styles.ts index 5a70fd9a2..afe2a94d8 100644 --- a/src/screens/wallet/backup-your-wallet-overlay/backup-your-wallet-overlay.styles.ts +++ b/src/screens/wallet/backup-your-wallet-overlay/backup-your-wallet-overlay.styles.ts @@ -5,7 +5,7 @@ import { formatSize, formatTextSize } from 'src/styles/format-size'; export const useBackupYourWalletOverlayStyles = createUseStyles(({ colors }) => ({ backdrop: { - ...StyleSheet.absoluteFillObject, + ...StyleSheet.absoluteFill, backgroundColor: colors.black16, flexDirection: 'column', justifyContent: 'flex-end' diff --git a/src/screens/wallet/on-ramp-overlay/on-ramp-overlay.styles.ts b/src/screens/wallet/on-ramp-overlay/on-ramp-overlay.styles.ts index 674905ac9..6ccc51db7 100644 --- a/src/screens/wallet/on-ramp-overlay/on-ramp-overlay.styles.ts +++ b/src/screens/wallet/on-ramp-overlay/on-ramp-overlay.styles.ts @@ -49,7 +49,7 @@ export const useOnRampOverlayStyles = createUseStyles(({ colors, typography }) = color: colors.peach }, loaderContainer: { - ...StyleSheet.absoluteFillObject, + ...StyleSheet.absoluteFill, justifyContent: 'center' } })); diff --git a/yarn.lock b/yarn.lock index b266bed09..f716fc5a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1491,26 +1491,26 @@ resolved "https://registry.yarnpkg.com/@expo/sdk-runtime-versions/-/sdk-runtime-versions-1.0.0.tgz#d7ebd21b19f1c6b0395e50d78da4416941c57f7c" integrity sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ== -"@firebase/ai@2.6.1": - version "2.6.1" - resolved "https://registry.yarnpkg.com/@firebase/ai/-/ai-2.6.1.tgz#c59d09e6dfbc6fe2d3347859b05f84d8b52d8bf7" - integrity sha512-qJd9bpABqsanFnwdbjZEDbKKr1jRtuUZ+cHyNBLWsxobH4pd73QncvuO3XlMq4eKBLlg1f5jNdFpJ3G3ABu2Tg== +"@firebase/ai@2.9.0": + version "2.9.0" + resolved "https://registry.yarnpkg.com/@firebase/ai/-/ai-2.9.0.tgz#9e6f3546eb688e31488f3e081702773300d609f1" + integrity sha512-NPvBBuvdGo9x3esnABAucFYmqbBmXvyTMimBq2PCuLZbdANZoHzGlx7vfzbwNDaEtCBq4RGGNMliLIv6bZ+PtA== dependencies: "@firebase/app-check-interop-types" "0.3.3" - "@firebase/component" "0.7.0" + "@firebase/component" "0.7.1" "@firebase/logger" "0.5.0" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" tslib "^2.1.0" -"@firebase/analytics-compat@0.2.25": - version "0.2.25" - resolved "https://registry.yarnpkg.com/@firebase/analytics-compat/-/analytics-compat-0.2.25.tgz#1f48bb6237bed7d6a3cf8136957aa5ceb245507b" - integrity sha512-fdzoaG0BEKbqksRDhmf4JoyZf16Wosrl0Y7tbZtJyVDOOwziE0vrFjmZuTdviL0yhak+Nco6rMsUUbkbD+qb6Q== +"@firebase/analytics-compat@0.2.26": + version "0.2.26" + resolved "https://registry.yarnpkg.com/@firebase/analytics-compat/-/analytics-compat-0.2.26.tgz#2ec74dc4d41d075d38fab7670c33464803214f2f" + integrity sha512-0j2ruLOoVSwwcXAF53AMoniJKnkwiTjGVfic5LDzqiRkR13vb5j6TXMeix787zbLeQtN/m1883Yv1TxI0gItbA== dependencies: - "@firebase/analytics" "0.10.19" + "@firebase/analytics" "0.10.20" "@firebase/analytics-types" "0.8.3" - "@firebase/component" "0.7.0" - "@firebase/util" "1.13.0" + "@firebase/component" "0.7.1" + "@firebase/util" "1.14.0" tslib "^2.1.0" "@firebase/analytics-types@0.8.3": @@ -1518,27 +1518,27 @@ resolved "https://registry.yarnpkg.com/@firebase/analytics-types/-/analytics-types-0.8.3.tgz#d08cd39a6209693ca2039ba7a81570dfa6c1518f" integrity sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg== -"@firebase/analytics@0.10.19": - version "0.10.19" - resolved "https://registry.yarnpkg.com/@firebase/analytics/-/analytics-0.10.19.tgz#6bddeb9db287fa2367066855b12ec514e2914697" - integrity sha512-3wU676fh60gaiVYQEEXsbGS4HbF2XsiBphyvvqDbtC1U4/dO4coshbYktcCHq+HFaGIK07iHOh4pME0hEq1fcg== +"@firebase/analytics@0.10.20": + version "0.10.20" + resolved "https://registry.yarnpkg.com/@firebase/analytics/-/analytics-0.10.20.tgz#ec3aaacaa157b979b6e2c12ac5a30e6484b19ddf" + integrity sha512-adGTNVUWH5q66tI/OQuKLSN6mamPpfYhj0radlH2xt+3eL6NFPtXoOs+ulvs+UsmK27vNFx5FjRDfWk+TyduHg== dependencies: - "@firebase/component" "0.7.0" - "@firebase/installations" "0.6.19" + "@firebase/component" "0.7.1" + "@firebase/installations" "0.6.20" "@firebase/logger" "0.5.0" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" tslib "^2.1.0" -"@firebase/app-check-compat@0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@firebase/app-check-compat/-/app-check-compat-0.4.0.tgz#94ac0cf9f66cab1d81a7b14e0c151dcc2684bc95" - integrity sha512-UfK2Q8RJNjYM/8MFORltZRG9lJj11k0nW84rrffiKvcJxLf1jf6IEjCIkCamykHE73C6BwqhVfhIBs69GXQV0g== +"@firebase/app-check-compat@0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@firebase/app-check-compat/-/app-check-compat-0.4.1.tgz#2ff3f4b28fd4ee136e7ee12b99edac8cdc8cbbb1" + integrity sha512-yjSvSl5B1u4CirnxhzirN1uiTRCRfx+/qtfbyeyI+8Cx8Cw1RWAIO/OqytPSVwLYbJJ1vEC3EHfxazRaMoWKaA== dependencies: - "@firebase/app-check" "0.11.0" + "@firebase/app-check" "0.11.1" "@firebase/app-check-types" "0.5.3" - "@firebase/component" "0.7.0" + "@firebase/component" "0.7.1" "@firebase/logger" "0.5.0" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" tslib "^2.1.0" "@firebase/app-check-interop-types@0.3.3": @@ -1551,25 +1551,25 @@ resolved "https://registry.yarnpkg.com/@firebase/app-check-types/-/app-check-types-0.5.3.tgz#38ba954acf4bffe451581a32fffa20337f11d8e5" integrity sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng== -"@firebase/app-check@0.11.0": - version "0.11.0" - resolved "https://registry.yarnpkg.com/@firebase/app-check/-/app-check-0.11.0.tgz#a7e1d1e3f5ae36eabed1455db937114fe869ce8f" - integrity sha512-XAvALQayUMBJo58U/rxW02IhsesaxxfWVmVkauZvGEz3vOAjMEQnzFlyblqkc2iAaO82uJ2ZVyZv9XzPfxjJ6w== +"@firebase/app-check@0.11.1": + version "0.11.1" + resolved "https://registry.yarnpkg.com/@firebase/app-check/-/app-check-0.11.1.tgz#f327a2190b405eb566a93cd5c7eb8ebe7556032b" + integrity sha512-gmKfwQ2k8aUQlOyRshc+fOQLq0OwUmibIZvpuY1RDNu2ho0aTMlwxOuEiJeYOs7AxzhSx7gnXPFNsXCFbnvXUQ== dependencies: - "@firebase/component" "0.7.0" + "@firebase/component" "0.7.1" "@firebase/logger" "0.5.0" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" tslib "^2.1.0" -"@firebase/app-compat@0.5.6": - version "0.5.6" - resolved "https://registry.yarnpkg.com/@firebase/app-compat/-/app-compat-0.5.6.tgz#a94d67fce839f2bf23c9b2d8f2f4099a68e94c27" - integrity sha512-YYGARbutghQY4zZUWMYia0ib0Y/rb52y72/N0z3vglRHL7ii/AaK9SA7S/dzScVOlCdnbHXz+sc5Dq+r8fwFAg== +"@firebase/app-compat@0.5.9": + version "0.5.9" + resolved "https://registry.yarnpkg.com/@firebase/app-compat/-/app-compat-0.5.9.tgz#464efce323951283c6812893d251dddee15d61da" + integrity sha512-e5LzqjO69/N2z7XcJeuMzIp4wWnW696dQeaHAUpQvGk89gIWHAIvG6W+mA3UotGW6jBoqdppEJ9DnuwbcBByug== dependencies: - "@firebase/app" "0.14.6" - "@firebase/component" "0.7.0" + "@firebase/app" "0.14.9" + "@firebase/component" "0.7.1" "@firebase/logger" "0.5.0" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" tslib "^2.1.0" "@firebase/app-types@0.9.3": @@ -1577,26 +1577,26 @@ resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.9.3.tgz#8408219eae9b1fb74f86c24e7150a148460414ad" integrity sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw== -"@firebase/app@0.14.6": - version "0.14.6" - resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.14.6.tgz#bf3333bfb104240320d54beab4c2fc1f10bae9e0" - integrity sha512-4uyt8BOrBsSq6i4yiOV/gG6BnnrvTeyymlNcaN/dKvyU1GoolxAafvIvaNP1RCGPlNab3OuE4MKUQuv2lH+PLQ== +"@firebase/app@0.14.9": + version "0.14.9" + resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.14.9.tgz#b7f740904deee2889a3d6115736b16fdbdc853c7" + integrity sha512-3gtUX0e584MYkKBQMgSECMvE1Dwzg+eONefDQ0wxVSe5YMBsZwdN5pL7UapwWBlV8+i8QCztF9TP947tEjZAGA== dependencies: - "@firebase/component" "0.7.0" + "@firebase/component" "0.7.1" "@firebase/logger" "0.5.0" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" idb "7.1.1" tslib "^2.1.0" -"@firebase/auth-compat@0.6.2": - version "0.6.2" - resolved "https://registry.yarnpkg.com/@firebase/auth-compat/-/auth-compat-0.6.2.tgz#12469442cb896558eb0a5f4077790576a9402473" - integrity sha512-8UhCzF6pav9bw/eXA8Zy1QAKssPRYEYXaWagie1ewLTwHkXv6bKp/j6/IwzSYQP67sy/BMFXIFaCCsoXzFLr7A== +"@firebase/auth-compat@0.6.3": + version "0.6.3" + resolved "https://registry.yarnpkg.com/@firebase/auth-compat/-/auth-compat-0.6.3.tgz#8e085d98bd133081e7e7d37b7fb421b876694847" + integrity sha512-nHOkupcYuGVxI1AJJ/OBhLPaRokbP14Gq4nkkoVvf1yvuREEWqdnrYB/CdsSnPxHMAnn5wJIKngxBF9jNX7s/Q== dependencies: - "@firebase/auth" "1.12.0" + "@firebase/auth" "1.12.1" "@firebase/auth-types" "0.13.0" - "@firebase/component" "0.7.0" - "@firebase/util" "1.13.0" + "@firebase/component" "0.7.1" + "@firebase/util" "1.14.0" tslib "^2.1.0" "@firebase/auth-interop-types@0.2.4": @@ -1609,77 +1609,77 @@ resolved "https://registry.yarnpkg.com/@firebase/auth-types/-/auth-types-0.13.0.tgz#ae6e0015e3bd4bfe18edd0942b48a0a118a098d9" integrity sha512-S/PuIjni0AQRLF+l9ck0YpsMOdE8GO2KU6ubmBB7P+7TJUCQDa3R1dlgYm9UzGbbePMZsp0xzB93f2b/CgxMOg== -"@firebase/auth@1.12.0": - version "1.12.0" - resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-1.12.0.tgz#192923495c22891a4e56021b949dfb8b87ed9f42" - integrity sha512-zkvLpsrxynWHk07qGrUDfCSqKf4AvfZGEqJ7mVCtYGjNNDbGE71k0Yn84rg8QEZu4hQw1BC0qDEHzpNVBcSVmA== +"@firebase/auth@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-1.12.1.tgz#5eb1c3bf99dfbe7025578a5f1439cc073a4183f0" + integrity sha512-nXKj7d5bMBlnq6XpcQQpmnSVwEeHBkoVbY/+Wk0P1ebLSICoH4XPtvKOFlXKfIHmcS84mLQ99fk3njlDGKSDtw== dependencies: - "@firebase/component" "0.7.0" + "@firebase/component" "0.7.1" "@firebase/logger" "0.5.0" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" tslib "^2.1.0" -"@firebase/component@0.7.0": - version "0.7.0" - resolved "https://registry.yarnpkg.com/@firebase/component/-/component-0.7.0.tgz#3736644fdb6d3572dceae7fdc1c35a8bd3819adc" - integrity sha512-wR9En2A+WESUHexjmRHkqtaVH94WLNKt6rmeqZhSLBybg4Wyf0Umk04SZsS6sBq4102ZsDBFwoqMqJYj2IoDSg== +"@firebase/component@0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@firebase/component/-/component-0.7.1.tgz#f16376146d77034ac5055834de25405e6c011491" + integrity sha512-mFzsm7CLHR60o08S23iLUY8m/i6kLpOK87wdEFPLhdlCahaxKmWOwSVGiWoENYSmFJJoDhrR3gKSCxz7ENdIww== dependencies: - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" tslib "^2.1.0" -"@firebase/data-connect@0.3.12": - version "0.3.12" - resolved "https://registry.yarnpkg.com/@firebase/data-connect/-/data-connect-0.3.12.tgz#611e684fb6940855f37da5f3126bd9449f070ece" - integrity sha512-baPddcoNLj/+vYo+HSJidJUdr5W4OkhT109c5qhR8T1dJoZcyJpkv/dFpYlw/VJ3dV66vI8GHQFrmAZw/xUS4g== +"@firebase/data-connect@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@firebase/data-connect/-/data-connect-0.4.0.tgz#957d2e0ee602d7120b4c5dbcb8494f911b8a2e47" + integrity sha512-vLXM6WHNIR3VtEeYNUb/5GTsUOyl3Of4iWNZHBe1i9f88sYFnxybJNWVBjvJ7flhCyF8UdxGpzWcUnv6F5vGfg== dependencies: "@firebase/auth-interop-types" "0.2.4" - "@firebase/component" "0.7.0" + "@firebase/component" "0.7.1" "@firebase/logger" "0.5.0" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" tslib "^2.1.0" -"@firebase/database-compat@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@firebase/database-compat/-/database-compat-2.1.0.tgz#c64488d741c6da2ed8dcf02f2e433089dae2f590" - integrity sha512-8nYc43RqxScsePVd1qe1xxvWNf0OBnbwHxmXJ7MHSuuTVYFO3eLyLW3PiCKJ9fHnmIz4p4LbieXwz+qtr9PZDg== +"@firebase/database-compat@2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@firebase/database-compat/-/database-compat-2.1.1.tgz#8ab656d2f6b53d1645b86fa846295db4734b9ac5" + integrity sha512-heAEVZ9Z8c8PnBUcmGh91JHX0cXcVa1yESW/xkLuwaX7idRFyLiN8sl73KXpR8ZArGoPXVQDanBnk6SQiekRCQ== dependencies: - "@firebase/component" "0.7.0" - "@firebase/database" "1.1.0" - "@firebase/database-types" "1.0.16" + "@firebase/component" "0.7.1" + "@firebase/database" "1.1.1" + "@firebase/database-types" "1.0.17" "@firebase/logger" "0.5.0" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" tslib "^2.1.0" -"@firebase/database-types@1.0.16": - version "1.0.16" - resolved "https://registry.yarnpkg.com/@firebase/database-types/-/database-types-1.0.16.tgz#262f54b8dbebbc46259757b3ba384224fb2ede48" - integrity sha512-xkQLQfU5De7+SPhEGAXFBnDryUWhhlFXelEg2YeZOQMCdoe7dL64DDAd77SQsR+6uoXIZY5MB4y/inCs4GTfcw== +"@firebase/database-types@1.0.17": + version "1.0.17" + resolved "https://registry.yarnpkg.com/@firebase/database-types/-/database-types-1.0.17.tgz#6b7a14d81655e9ee5e87c26dc853c24d9737e4fe" + integrity sha512-4eWaM5fW3qEIHjGzfi3cf0Jpqi1xQsAdT6rSDE1RZPrWu8oGjgrq6ybMjobtyHQFgwGCykBm4YM89qDzc+uG/w== dependencies: "@firebase/app-types" "0.9.3" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" -"@firebase/database@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@firebase/database/-/database-1.1.0.tgz#bdf60f1605079a87ceb2b5e30d90846e0bde294b" - integrity sha512-gM6MJFae3pTyNLoc9VcJNuaUDej0ctdjn3cVtILo3D5lpp0dmUHHLFN/pUKe7ImyeB1KAvRlEYxvIHNF04Filg== +"@firebase/database@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@firebase/database/-/database-1.1.1.tgz#591610b5087ffc25cc56486ad03749b09c887759" + integrity sha512-LwIXe8+mVHY5LBPulWECOOIEXDiatyECp/BOlu0gOhe+WOcKjWHROaCbLlkFTgHMY7RHr5MOxkLP/tltWAH3dA== dependencies: "@firebase/app-check-interop-types" "0.3.3" "@firebase/auth-interop-types" "0.2.4" - "@firebase/component" "0.7.0" + "@firebase/component" "0.7.1" "@firebase/logger" "0.5.0" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" faye-websocket "0.11.4" tslib "^2.1.0" -"@firebase/firestore-compat@0.4.3": - version "0.4.3" - resolved "https://registry.yarnpkg.com/@firebase/firestore-compat/-/firestore-compat-0.4.3.tgz#49244c1a49383d95e0360506a9c65abcf9e7ccfb" - integrity sha512-1ylF/njF68Pmb6p0erP0U78XQv1w77Wap4bUmqZ7ZVkmN1oMgplyu0TyirWtCBoKFRV2+SUZfWXvIij/z39LYg== +"@firebase/firestore-compat@0.4.6": + version "0.4.6" + resolved "https://registry.yarnpkg.com/@firebase/firestore-compat/-/firestore-compat-0.4.6.tgz#30a20be30a72e80b0cfa32d5d693564daff6911a" + integrity sha512-NgVyR4hHHN2FvSNQOtbgBOuVsEdD/in30d9FKbEvvITiAChrBN2nBstmhfjI4EOTnHaP8zigwvkNYFI9yKGAkQ== dependencies: - "@firebase/component" "0.7.0" - "@firebase/firestore" "4.9.3" + "@firebase/component" "0.7.1" + "@firebase/firestore" "4.12.0" "@firebase/firestore-types" "3.0.3" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" tslib "^2.1.0" "@firebase/firestore-types@3.0.3": @@ -1687,28 +1687,28 @@ resolved "https://registry.yarnpkg.com/@firebase/firestore-types/-/firestore-types-3.0.3.tgz#7d0c3dd8850c0193d8f5ee0cc8f11961407742c1" integrity sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q== -"@firebase/firestore@4.9.3": - version "4.9.3" - resolved "https://registry.yarnpkg.com/@firebase/firestore/-/firestore-4.9.3.tgz#38199b490847767800651641b7caef7d2bfdfce5" - integrity sha512-RVuvhcQzs1sD5Osr2naQS71H0bQMbSnib16uOWAKk3GaKb/WBPyCYSr2Ry7MqlxDP/YhwknUxECL07lw9Rq1nA== +"@firebase/firestore@4.12.0": + version "4.12.0" + resolved "https://registry.yarnpkg.com/@firebase/firestore/-/firestore-4.12.0.tgz#3321155f66d70c749924c635bb1f0deb92254df3" + integrity sha512-PM47OyiiAAoAMB8kkq4Je14mTciaRoAPDd3ng3Ckqz9i2TX9D9LfxIRcNzP/OxzNV4uBKRq6lXoOggkJBQR3Gw== dependencies: - "@firebase/component" "0.7.0" + "@firebase/component" "0.7.1" "@firebase/logger" "0.5.0" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" "@firebase/webchannel-wrapper" "1.0.5" "@grpc/grpc-js" "~1.9.0" "@grpc/proto-loader" "^0.7.8" tslib "^2.1.0" -"@firebase/functions-compat@0.4.1": - version "0.4.1" - resolved "https://registry.yarnpkg.com/@firebase/functions-compat/-/functions-compat-0.4.1.tgz#b253b761845f0c82bbdf76ef59975978ed84eb65" - integrity sha512-AxxUBXKuPrWaVNQ8o1cG1GaCAtXT8a0eaTDfqgS5VsRYLAR0ALcfqDLwo/QyijZj1w8Qf8n3Qrfy/+Im245hOQ== +"@firebase/functions-compat@0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@firebase/functions-compat/-/functions-compat-0.4.2.tgz#5788b9d33a700164eefd0b4e455de87cd62d635c" + integrity sha512-YNxgnezvZDkqxqXa6cT7/oTeD4WXbxgIP7qZp4LFnathQv5o2omM6EoIhXiT9Ie5AoQDcIhG9Y3/dj+DFJGaGQ== dependencies: - "@firebase/component" "0.7.0" - "@firebase/functions" "0.13.1" + "@firebase/component" "0.7.1" + "@firebase/functions" "0.13.2" "@firebase/functions-types" "0.6.3" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" tslib "^2.1.0" "@firebase/functions-types@0.6.3": @@ -1716,27 +1716,27 @@ resolved "https://registry.yarnpkg.com/@firebase/functions-types/-/functions-types-0.6.3.tgz#f5faf770248b13f45d256f614230da6a11bfb654" integrity sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg== -"@firebase/functions@0.13.1": - version "0.13.1" - resolved "https://registry.yarnpkg.com/@firebase/functions/-/functions-0.13.1.tgz#472e8456568689154b87a494ee8c10ee2e610d94" - integrity sha512-sUeWSb0rw5T+6wuV2o9XNmh9yHxjFI9zVGFnjFi+n7drTEWpl7ZTz1nROgGrSu472r+LAaj+2YaSicD4R8wfbw== +"@firebase/functions@0.13.2": + version "0.13.2" + resolved "https://registry.yarnpkg.com/@firebase/functions/-/functions-0.13.2.tgz#2e7936898afcdfa391e564e39049e0e908282420" + integrity sha512-tHduUD+DeokM3NB1QbHCvEMoL16e8Z8JSkmuVA4ROoJKPxHn8ibnecHPO2e3nVCJR1D9OjuKvxz4gksfq92/ZQ== dependencies: "@firebase/app-check-interop-types" "0.3.3" "@firebase/auth-interop-types" "0.2.4" - "@firebase/component" "0.7.0" + "@firebase/component" "0.7.1" "@firebase/messaging-interop-types" "0.2.3" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" tslib "^2.1.0" -"@firebase/installations-compat@0.2.19": - version "0.2.19" - resolved "https://registry.yarnpkg.com/@firebase/installations-compat/-/installations-compat-0.2.19.tgz#4bc57c8c57d241eeca95900ff3033d6ec3dbcc7c" - integrity sha512-khfzIY3EI5LePePo7vT19/VEIH1E3iYsHknI/6ek9T8QCozAZshWT9CjlwOzZrKvTHMeNcbpo/VSOSIWDSjWdQ== +"@firebase/installations-compat@0.2.20": + version "0.2.20" + resolved "https://registry.yarnpkg.com/@firebase/installations-compat/-/installations-compat-0.2.20.tgz#f17bcd7623f1283937ac3192c3293dd68037fcdc" + integrity sha512-9C9pL/DIEGucmoPj8PlZTnztbX3nhNj5RTYVpUM7wQq/UlHywaYv99969JU/WHLvi9ptzIogXYS9d1eZ6XFe9g== dependencies: - "@firebase/component" "0.7.0" - "@firebase/installations" "0.6.19" + "@firebase/component" "0.7.1" + "@firebase/installations" "0.6.20" "@firebase/installations-types" "0.5.3" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" tslib "^2.1.0" "@firebase/installations-types@0.5.3": @@ -1744,13 +1744,13 @@ resolved "https://registry.yarnpkg.com/@firebase/installations-types/-/installations-types-0.5.3.tgz#cac8a14dd49f09174da9df8ae453f9b359c3ef2f" integrity sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA== -"@firebase/installations@0.6.19": - version "0.6.19" - resolved "https://registry.yarnpkg.com/@firebase/installations/-/installations-0.6.19.tgz#93c569321f6fb399f4f1a197efc0053ce6452c7c" - integrity sha512-nGDmiwKLI1lerhwfwSHvMR9RZuIH5/8E3kgUWnVRqqL7kGVSktjLTWEMva7oh5yxQ3zXfIlIwJwMcaM5bK5j8Q== +"@firebase/installations@0.6.20": + version "0.6.20" + resolved "https://registry.yarnpkg.com/@firebase/installations/-/installations-0.6.20.tgz#a019da0e71d5a0bb59b58e43a8edef0153368b94" + integrity sha512-LOzvR7XHPbhS0YB5ANXhqXB5qZlntPpwU/4KFwhSNpXNsGk/sBQ9g5hepi0y0/MfenJLe2v7t644iGOOElQaHQ== dependencies: - "@firebase/component" "0.7.0" - "@firebase/util" "1.13.0" + "@firebase/component" "0.7.1" + "@firebase/util" "1.14.0" idb "7.1.1" tslib "^2.1.0" @@ -1761,14 +1761,14 @@ dependencies: tslib "^2.1.0" -"@firebase/messaging-compat@0.2.23": - version "0.2.23" - resolved "https://registry.yarnpkg.com/@firebase/messaging-compat/-/messaging-compat-0.2.23.tgz#2ca6b36ea238fae4dff53bf85442c4a2af516224" - integrity sha512-SN857v/kBUvlQ9X/UjAqBoQ2FEaL1ZozpnmL1ByTe57iXkmnVVFm9KqAsTfmf+OEwWI4kJJe9NObtN/w22lUgg== +"@firebase/messaging-compat@0.2.24": + version "0.2.24" + resolved "https://registry.yarnpkg.com/@firebase/messaging-compat/-/messaging-compat-0.2.24.tgz#9ea9bf0d88d605c382dd416e231203310da7b867" + integrity sha512-wXH8FrKbJvFuFe6v98TBhAtvgknxKIZtGM/wCVsfpOGmaAE80bD8tBxztl+uochjnFb9plihkd6mC4y7sZXSpA== dependencies: - "@firebase/component" "0.7.0" - "@firebase/messaging" "0.12.23" - "@firebase/util" "1.13.0" + "@firebase/component" "0.7.1" + "@firebase/messaging" "0.12.24" + "@firebase/util" "1.14.0" tslib "^2.1.0" "@firebase/messaging-interop-types@0.2.3": @@ -1776,28 +1776,28 @@ resolved "https://registry.yarnpkg.com/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz#e647c9cd1beecfe6a6e82018a6eec37555e4da3e" integrity sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q== -"@firebase/messaging@0.12.23": - version "0.12.23" - resolved "https://registry.yarnpkg.com/@firebase/messaging/-/messaging-0.12.23.tgz#71f932a521ac39d9f036175672e37897531010eb" - integrity sha512-cfuzv47XxqW4HH/OcR5rM+AlQd1xL/VhuaeW/wzMW1LFrsFcTn0GND/hak1vkQc2th8UisBcrkVcQAnOnKwYxg== +"@firebase/messaging@0.12.24": + version "0.12.24" + resolved "https://registry.yarnpkg.com/@firebase/messaging/-/messaging-0.12.24.tgz#ac586f68a038d8595ee8cbaea2a4b60e1886029a" + integrity sha512-UtKoubegAhHyehcB7iQjvQ8OVITThPbbWk3g2/2ze42PrQr6oe6OmCElYQkBrE5RDCeMTNucXejbdulrQ2XwVg== dependencies: - "@firebase/component" "0.7.0" - "@firebase/installations" "0.6.19" + "@firebase/component" "0.7.1" + "@firebase/installations" "0.6.20" "@firebase/messaging-interop-types" "0.2.3" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" idb "7.1.1" tslib "^2.1.0" -"@firebase/performance-compat@0.2.22": - version "0.2.22" - resolved "https://registry.yarnpkg.com/@firebase/performance-compat/-/performance-compat-0.2.22.tgz#1c24ea360b03cfef831bdf379b4fc7080f412741" - integrity sha512-xLKxaSAl/FVi10wDX/CHIYEUP13jXUjinL+UaNXT9ByIvxII5Ne5150mx6IgM8G6Q3V+sPiw9C8/kygkyHUVxg== +"@firebase/performance-compat@0.2.23": + version "0.2.23" + resolved "https://registry.yarnpkg.com/@firebase/performance-compat/-/performance-compat-0.2.23.tgz#e4e440878c5be1e11e01d5fe28e5e1fe73d36857" + integrity sha512-c7qOAGBUAOpIuUlHu1axWcrCVtIYKPMhH0lMnoCDWnPwn1HcPuPUBVTWETbC7UWw71RMJF8DpirfWXzMWJQfgA== dependencies: - "@firebase/component" "0.7.0" + "@firebase/component" "0.7.1" "@firebase/logger" "0.5.0" - "@firebase/performance" "0.7.9" + "@firebase/performance" "0.7.10" "@firebase/performance-types" "0.2.3" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" tslib "^2.1.0" "@firebase/performance-types@0.2.3": @@ -1805,28 +1805,28 @@ resolved "https://registry.yarnpkg.com/@firebase/performance-types/-/performance-types-0.2.3.tgz#5ce64e90fa20ab5561f8b62a305010cf9fab86fb" integrity sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ== -"@firebase/performance@0.7.9": - version "0.7.9" - resolved "https://registry.yarnpkg.com/@firebase/performance/-/performance-0.7.9.tgz#7e3a072b1542f0df3f502684a38a0516b0d72cab" - integrity sha512-UzybENl1EdM2I1sjYm74xGt/0JzRnU/0VmfMAKo2LSpHJzaj77FCLZXmYQ4oOuE+Pxtt8Wy2BVJEENiZkaZAzQ== +"@firebase/performance@0.7.10": + version "0.7.10" + resolved "https://registry.yarnpkg.com/@firebase/performance/-/performance-0.7.10.tgz#a282de63f064477a62cf0379c3374f3cc693ffa4" + integrity sha512-8nRFld+Ntzp5cLKzZuG9g+kBaSn8Ks9dmn87UQGNFDygbmR6ebd8WawauEXiJjMj1n70ypkvAOdE+lzeyfXtGA== dependencies: - "@firebase/component" "0.7.0" - "@firebase/installations" "0.6.19" + "@firebase/component" "0.7.1" + "@firebase/installations" "0.6.20" "@firebase/logger" "0.5.0" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" tslib "^2.1.0" web-vitals "^4.2.4" -"@firebase/remote-config-compat@0.2.20": - version "0.2.20" - resolved "https://registry.yarnpkg.com/@firebase/remote-config-compat/-/remote-config-compat-0.2.20.tgz#4bca09b1361867d0c882411970486ee06622e071" - integrity sha512-P/ULS9vU35EL9maG7xp66uljkZgcPMQOxLj3Zx2F289baTKSInE6+YIkgHEi1TwHoddC/AFePXPpshPlEFkbgg== +"@firebase/remote-config-compat@0.2.22": + version "0.2.22" + resolved "https://registry.yarnpkg.com/@firebase/remote-config-compat/-/remote-config-compat-0.2.22.tgz#5d34d4e856c8a9010e77be5fc2dc183657ade58c" + integrity sha512-uW/eNKKtRBot2gnCC5mnoy5Voo2wMzZuQ7dwqqGHU176fO9zFgMwKiRzk+aaC99NLrFk1KOmr0ZVheD+zdJmjQ== dependencies: - "@firebase/component" "0.7.0" + "@firebase/component" "0.7.1" "@firebase/logger" "0.5.0" - "@firebase/remote-config" "0.7.0" + "@firebase/remote-config" "0.8.1" "@firebase/remote-config-types" "0.5.0" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" tslib "^2.1.0" "@firebase/remote-config-types@0.5.0": @@ -1834,26 +1834,26 @@ resolved "https://registry.yarnpkg.com/@firebase/remote-config-types/-/remote-config-types-0.5.0.tgz#f0f503b32edda3384f5252f9900cd9613adbb99c" integrity sha512-vI3bqLoF14L/GchtgayMiFpZJF+Ao3uR8WCde0XpYNkSokDpAKca2DxvcfeZv7lZUqkUwQPL2wD83d3vQ4vvrg== -"@firebase/remote-config@0.7.0": - version "0.7.0" - resolved "https://registry.yarnpkg.com/@firebase/remote-config/-/remote-config-0.7.0.tgz#0e5e5879a7a9121c9da55606be8fa40ff70ddae1" - integrity sha512-dX95X6WlW7QlgNd7aaGdjAIZUiQkgWgNS+aKNu4Wv92H1T8Ue/NDUjZHd9xb8fHxLXIHNZeco9/qbZzr500MjQ== +"@firebase/remote-config@0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@firebase/remote-config/-/remote-config-0.8.1.tgz#47309f3e623d358652878935ac90c880b97ef118" + integrity sha512-L86TReBnPiiJOWd7k9iaiE9f7rHtMpjAoYN0fH2ey2ZRzsOChHV0s5sYf1+IIUYzplzsE46pjlmAUNkRRKwHSQ== dependencies: - "@firebase/component" "0.7.0" - "@firebase/installations" "0.6.19" + "@firebase/component" "0.7.1" + "@firebase/installations" "0.6.20" "@firebase/logger" "0.5.0" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" tslib "^2.1.0" -"@firebase/storage-compat@0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@firebase/storage-compat/-/storage-compat-0.4.0.tgz#a09bd33c262123e7e3ed0cd590b4c6e2ce4a8902" - integrity sha512-vDzhgGczr1OfcOy285YAPur5pWDEvD67w4thyeCUh6Ys0izN9fNYtA1MJERmNBfqjqu0lg0FM5GLbw0Il21M+g== +"@firebase/storage-compat@0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@firebase/storage-compat/-/storage-compat-0.4.1.tgz#94c105a416f949fd1552ced075d2df613e761faa" + integrity sha512-bgl3FHHfXAmBgzIK/Fps6Xyv2HiAQlSTov07CBL+RGGhrC5YIk4lruS8JVIC+UkujRdYvnf8cpQFGn2RCilJ/A== dependencies: - "@firebase/component" "0.7.0" - "@firebase/storage" "0.14.0" + "@firebase/component" "0.7.1" + "@firebase/storage" "0.14.1" "@firebase/storage-types" "0.8.3" - "@firebase/util" "1.13.0" + "@firebase/util" "1.14.0" tslib "^2.1.0" "@firebase/storage-types@0.8.3": @@ -1861,19 +1861,19 @@ resolved "https://registry.yarnpkg.com/@firebase/storage-types/-/storage-types-0.8.3.tgz#2531ef593a3452fc12c59117195d6485c6632d3d" integrity sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg== -"@firebase/storage@0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@firebase/storage/-/storage-0.14.0.tgz#01acb97d413ada7c91de860fb260623468baa25d" - integrity sha512-xWWbb15o6/pWEw8H01UQ1dC5U3rf8QTAzOChYyCpafV6Xki7KVp3Yaw2nSklUwHEziSWE9KoZJS7iYeyqWnYFA== +"@firebase/storage@0.14.1": + version "0.14.1" + resolved "https://registry.yarnpkg.com/@firebase/storage/-/storage-0.14.1.tgz#2cdc6523bac9fd85bdd369c77e02a785866d4c02" + integrity sha512-uIpYgBBsv1vIET+5xV20XT7wwqV+H4GFp6PBzfmLUcEgguS4SWNFof56Z3uOC2lNDh0KDda1UflYq2VwD9Nefw== dependencies: - "@firebase/component" "0.7.0" - "@firebase/util" "1.13.0" + "@firebase/component" "0.7.1" + "@firebase/util" "1.14.0" tslib "^2.1.0" -"@firebase/util@1.13.0": - version "1.13.0" - resolved "https://registry.yarnpkg.com/@firebase/util/-/util-1.13.0.tgz#2e9e7569722a1e3fc86b1b4076d5cbfbfa7265d6" - integrity sha512-0AZUyYUfpMNcztR5l09izHwXkZpghLgCUaAGjtMwXnCg3bj4ml5VgiwqOMOxJ+Nw4qN/zJAaOQBcJ7KGkWStqQ== +"@firebase/util@1.14.0": + version "1.14.0" + resolved "https://registry.yarnpkg.com/@firebase/util/-/util-1.14.0.tgz#e0a5998fc30a065fe5cba8bd7546ae8f095f3d3e" + integrity sha512-/gnejm7MKkVIXnSJGpc9L2CvvvzJvtDPeAEq5jAwgVlf/PeNxot+THx/bpD20wQ8uL5sz0xqgXy1nisOYMU+mw== dependencies: tslib "^2.1.0" @@ -2709,22 +2709,22 @@ resolved "https://registry.yarnpkg.com/@react-native-documents/picker/-/picker-12.0.0.tgz#fbb88a9434da1fb0035a5196fd02259ff67596f9" integrity sha512-7kdUaF0Kin3F6OBixHTGY7mMHG7JAejbnAWUQltC8v2xmkPN+CMli3i4sm62ZIEhYzf3QX+fCe/3kFBcr+Vb6g== -"@react-native-firebase/app-check@^23.8.2": - version "23.8.2" - resolved "https://registry.yarnpkg.com/@react-native-firebase/app-check/-/app-check-23.8.2.tgz#87b19efa2fe9d9692db948af7cfa677ad33da649" - integrity sha512-E79/RJhVG2VdEDDHigXxJzaNEvokeNVjlg4dT/ZQwHdzUU524GQ4CaqYWX47MCBLxL1+NP0TvR0Auavxpy+ypA== +"@react-native-firebase/app-check@^24.0.0": + version "24.0.0" + resolved "https://registry.yarnpkg.com/@react-native-firebase/app-check/-/app-check-24.0.0.tgz#8fbe1b1292963cefbbbe356abb7d1e3fa2ae0d44" + integrity sha512-HdHqeuKyKxantqLpJYlMJCcUBsOdC4Mb6tOEuUGVo1A0vWiCqSK3NK0Jo25S/Q9fG8dHAq8bwMZjRripFYz3UA== -"@react-native-firebase/app@^23.8.2": - version "23.8.2" - resolved "https://registry.yarnpkg.com/@react-native-firebase/app/-/app-23.8.2.tgz#0fbc2d603eb0b51dd2c3b8a22bd8bdced4027b90" - integrity sha512-L1RbO7tQwjO7t3+1HWz9z4zxLKbDJ2ErOu43HCfPOXv10aJT/14E3F1pCmGAeG7oqImCH0pK3X+NaFfcnUAjPA== +"@react-native-firebase/app@^24.0.0": + version "24.0.0" + resolved "https://registry.yarnpkg.com/@react-native-firebase/app/-/app-24.0.0.tgz#b9400ac3c13617811b0375d1335d24edeec986bf" + integrity sha512-rLWNd8/4FjKYV7PeDR9uiT5vwYWdJ7dJ1yiIIaZ/eL+Y56Ij2iXbqRCUu4zWkvu/ZrJfaGOyT12Vhy1SLy0NMg== dependencies: - firebase "12.7.0" + firebase "12.10.0" -"@react-native-firebase/messaging@^23.8.2": - version "23.8.2" - resolved "https://registry.yarnpkg.com/@react-native-firebase/messaging/-/messaging-23.8.2.tgz#aa9afdbaae2096b5e0f78444a319181e5e5745f8" - integrity sha512-FHDAwN1hLqeDPkEjrwwUw+svNavuY17/C4HwQepkZAp6q2bLm3RqSmBniiqlk3PRLKNUWrLlvn6MHX2yiAwH9Q== +"@react-native-firebase/messaging@^24.0.0": + version "24.0.0" + resolved "https://registry.yarnpkg.com/@react-native-firebase/messaging/-/messaging-24.0.0.tgz#185cd1d9f343fd6a2f077de05def34977fe63103" + integrity sha512-rODaV83e8mR+Y9EPDblfSpy4rM+alriiq5306RyzPryhsyu+guj4fhGwZpESWwhmk9fKjsnshv++aFA50xFjhg== "@react-native-google-signin/google-signin@^16.1.1": version "16.1.1" @@ -6932,39 +6932,39 @@ find-up@^5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" -firebase@12.7.0: - version "12.7.0" - resolved "https://registry.yarnpkg.com/firebase/-/firebase-12.7.0.tgz#fa975abb784a2cdb2ff581c3890e84c49aaa9118" - integrity sha512-ZBZg9jFo8uH4Emd7caOqtalKJfDGHnHQSrCPiqRAdTFQd0wL3ERilUBfhnhBLnlernugkN/o7nJa0p+sE71Izg== - dependencies: - "@firebase/ai" "2.6.1" - "@firebase/analytics" "0.10.19" - "@firebase/analytics-compat" "0.2.25" - "@firebase/app" "0.14.6" - "@firebase/app-check" "0.11.0" - "@firebase/app-check-compat" "0.4.0" - "@firebase/app-compat" "0.5.6" +firebase@12.10.0: + version "12.10.0" + resolved "https://registry.yarnpkg.com/firebase/-/firebase-12.10.0.tgz#2c000e889e8b423ce37399b6a0497cadfba890fe" + integrity sha512-tAjHnEirksqWpa+NKDUSUMjulOnsTcsPC1X1rQ+gwPtjlhJS572na91CwaBXQJHXharIrfj7sw/okDkXOsphjA== + dependencies: + "@firebase/ai" "2.9.0" + "@firebase/analytics" "0.10.20" + "@firebase/analytics-compat" "0.2.26" + "@firebase/app" "0.14.9" + "@firebase/app-check" "0.11.1" + "@firebase/app-check-compat" "0.4.1" + "@firebase/app-compat" "0.5.9" "@firebase/app-types" "0.9.3" - "@firebase/auth" "1.12.0" - "@firebase/auth-compat" "0.6.2" - "@firebase/data-connect" "0.3.12" - "@firebase/database" "1.1.0" - "@firebase/database-compat" "2.1.0" - "@firebase/firestore" "4.9.3" - "@firebase/firestore-compat" "0.4.3" - "@firebase/functions" "0.13.1" - "@firebase/functions-compat" "0.4.1" - "@firebase/installations" "0.6.19" - "@firebase/installations-compat" "0.2.19" - "@firebase/messaging" "0.12.23" - "@firebase/messaging-compat" "0.2.23" - "@firebase/performance" "0.7.9" - "@firebase/performance-compat" "0.2.22" - "@firebase/remote-config" "0.7.0" - "@firebase/remote-config-compat" "0.2.20" - "@firebase/storage" "0.14.0" - "@firebase/storage-compat" "0.4.0" - "@firebase/util" "1.13.0" + "@firebase/auth" "1.12.1" + "@firebase/auth-compat" "0.6.3" + "@firebase/data-connect" "0.4.0" + "@firebase/database" "1.1.1" + "@firebase/database-compat" "2.1.1" + "@firebase/firestore" "4.12.0" + "@firebase/firestore-compat" "0.4.6" + "@firebase/functions" "0.13.2" + "@firebase/functions-compat" "0.4.2" + "@firebase/installations" "0.6.20" + "@firebase/installations-compat" "0.2.20" + "@firebase/messaging" "0.12.24" + "@firebase/messaging-compat" "0.2.24" + "@firebase/performance" "0.7.10" + "@firebase/performance-compat" "0.2.23" + "@firebase/remote-config" "0.8.1" + "@firebase/remote-config-compat" "0.2.22" + "@firebase/storage" "0.14.1" + "@firebase/storage-compat" "0.4.1" + "@firebase/util" "1.14.0" first-match@~0.0.1: version "0.0.1" @@ -10210,14 +10210,13 @@ react-native-svg-transformer@^1.5.2: "@svgr/plugin-svgo" "^8.1.0" path-dirname "^1.0.2" -react-native-svg@^15.15.1: - version "15.15.1" - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-15.15.1.tgz#0b08716f5c389ef8550a73492c985c7b23849d65" - integrity sha512-ZUD1xwc3Hwo4cOmOLumjJVoc7lEf9oQFlHnLmgccLC19fNm6LVEdtB+Cnip6gEi0PG3wfvVzskViEtrySQP8Fw== +react-native-svg@^15.15.5: + version "15.15.5" + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-15.15.5.tgz#822805c14481b8ec16d5fbac1e3ce2b27a5509d7" + integrity sha512-L4go5jA+GWutdJ/JucuN20cjAbMg1HmMtAP+wZ+3JLCf6Jd0bhXQHxciRP/AQm/FlrIEZwkMcHNZP+FXAiic0w== dependencies: css-select "^5.1.0" css-tree "^1.1.3" - warn-once "0.1.1" react-native-swipe-list-view@^3.2.9: version "3.2.9" @@ -11871,7 +11870,7 @@ walker@^1.0.7, walker@^1.0.8: dependencies: makeerror "1.0.12" -warn-once@0.1.1, warn-once@^0.1.0: +warn-once@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/warn-once/-/warn-once-0.1.1.tgz#952088f4fb56896e73fd4e6a3767272a3fccce43" integrity sha512-VkQZJbO8zVImzYFteBXvBOZEl1qL175WH8VmZcxF2fZAoudNhNDvHi+doCaAEdU2l2vtcIwa2zn0QK5+I1HQ3Q== From 2cfa583c95729c99ddea5ece477c73afeacfa7dc Mon Sep 17 00:00:00 2001 From: lendihop Date: Wed, 20 May 2026 16:23:37 +0200 Subject: [PATCH 03/20] TW-2254: fix tests --- src/mocks/tezos.mock.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mocks/tezos.mock.ts b/src/mocks/tezos.mock.ts index e102a2aa4..7fcc5a94f 100644 --- a/src/mocks/tezos.mock.ts +++ b/src/mocks/tezos.mock.ts @@ -186,8 +186,8 @@ const mockTezosToolkit = { jest.mock('@taquito/taquito', () => ({ ...jest.requireActual('@taquito/taquito'), - TezosToolkit: () => mockTezosToolkit, - MichelCodecPacker: () => ({}), - CompositeForger: () => ({}), - RpcForger: () => ({}) + TezosToolkit: jest.fn(() => mockTezosToolkit), + MichelCodecPacker: jest.fn(() => ({})), + CompositeForger: jest.fn(() => ({})), + RpcForger: jest.fn(() => ({})) })); From 111e1ad77f298927d389db9e322fc316451c1775 Mon Sep 17 00:00:00 2001 From: lendihop Date: Wed, 20 May 2026 17:06:22 +0200 Subject: [PATCH 04/20] TW-2254: fix android build --- postinstall.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/postinstall.sh b/postinstall.sh index 466833eb2..5e217e386 100755 --- a/postinstall.sh +++ b/postinstall.sh @@ -1,9 +1,17 @@ -if [ "$(expr substr $(uname -s) 1 5)" != "Linux" ]; then +if [ "$(uname -s)" != "Linux" ]; then sed_mac_arg=true fi find node_modules -type f -name 'build.gradle' -exec sed -i ${sed_mac_arg:+""} 's/jcenter()/mavenCentral()/g' {} + +# https://github.com/facebook/react-native/issues/56287 +# Gradle 9 removed JvmVendorSpec.IBM_SEMERU. React Native 0.85.3 ships Foojay +# resolver 0.5.0, which still references it and crashes during Android builds. +rn_gradle_plugin_settings="node_modules/@react-native/gradle-plugin/settings.gradle.kts" +if [ -f "$rn_gradle_plugin_settings" ]; then + sed -i ${sed_mac_arg:+""} 's/org.gradle.toolchains.foojay-resolver-convention").version("0.5.0")/org.gradle.toolchains.foojay-resolver-convention").version("1.0.0")/' "$rn_gradle_plugin_settings" +fi + search_string="compile 'com.facebook.react:react-native:+'" replace_string="implementation 'com.facebook.react:react-native:+'" sed -i ${sed_mac_arg:+""} "s/$search_string/$replace_string/" node_modules/react-native-scrypt/android/build.gradle From b4933d7791c1517b63546b87839a58b1c59c862a Mon Sep 17 00:00:00 2001 From: lendihop Date: Wed, 20 May 2026 17:38:10 +0200 Subject: [PATCH 05/20] TW-2254: fix audit --- audit-deps.mjs | 8 -- package.json | 11 +-- yarn.lock | 204 +++++++++++++++++++++++++++---------------------- 3 files changed, 119 insertions(+), 104 deletions(-) diff --git a/audit-deps.mjs b/audit-deps.mjs index 5f21e2cc4..1d6a8de1b 100644 --- a/audit-deps.mjs +++ b/audit-deps.mjs @@ -4,14 +4,6 @@ exec('yarn audit --level high', (error, stdout) => { if (error) { console.log(stdout); - if ( - (stdout.includes('Axios is vulnerable to DoS attack through lack of data size') || - stdout.includes('minimatch')) && - !stdout.includes('Critical') - ) { - return; - } - if (stdout.includes('High') || stdout.includes('Critical')) { throw new Error('Audit failed'); } diff --git a/package.json b/package.json index dff23aea5..a41eaa30f 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "@types/async-retry": "^1.4.9", "@types/redux-logger": "^3.0.13", "async-retry": "^1.3.3", - "axios": "^1.13.5", + "axios": "1.15.2", "bignumber.js": "^9.3.1", "bip39": "^3.1.0", "buffer": "^6.0.3", @@ -74,7 +74,7 @@ "ed25519-hd-key": "^1.3.0", "formik": "^2.2.9", "graphql": "^16.6.0", - "lodash-es": "^4.17.21", + "lodash-es": "^4.18.1", "memoizee": "^0.4.15", "node-forge": "^1.3.2", "pbkdf2": "^3.1.5", @@ -174,11 +174,12 @@ "@airgap/beacon-dapp": "link:./node_modules/.cache/null", "@airgap/beacon-ui": "link:./node_modules/.cache/null", "@airgap/beacon-transport-postmessage": "link:./node_modules/.cache/null", - "axios": "^1.13.5", + "axios": "1.15.2", "node-libs-react-native/react-native-randombytes": "madfish-solutions/react-native-randombytes#cf4f237e0affbef3f23d444478bd271b28936ac0", - "fast-xml-parser": "5.3.7", + "fast-xml-parser": "5.5.6", "underscore": "^1.13.8", - "@noble/curves": "1.9.7" + "@noble/curves": "1.9.7", + "eslint-plugin-jsx-expressions/@typescript-eslint/utils/@typescript-eslint/typescript-estree/minimatch": "^9.0.7" }, "engines": { "node": ">= 22.11.0" diff --git a/yarn.lock b/yarn.lock index f716fc5a0..2410b2d84 100644 --- a/yarn.lock +++ b/yarn.lock @@ -305,6 +305,14 @@ "@babel/traverse" "^7.27.1" "@babel/types" "^7.27.1" +"@babel/helper-module-imports@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz#60632cbd6ffb70b22823187201116762a03e2d5c" + integrity sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw== + dependencies: + "@babel/traverse" "^7.28.6" + "@babel/types" "^7.28.6" + "@babel/helper-module-transforms@^7.27.1", "@babel/helper-module-transforms@^7.28.3": version "7.28.3" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz#a2b37d3da3b2344fe085dab234426f2b9a2fa5f6" @@ -314,6 +322,15 @@ "@babel/helper-validator-identifier" "^7.27.1" "@babel/traverse" "^7.28.3" +"@babel/helper-module-transforms@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz#9312d9d9e56edc35aeb6e95c25d4106b50b9eb1e" + integrity sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA== + dependencies: + "@babel/helper-module-imports" "^7.28.6" + "@babel/helper-validator-identifier" "^7.28.5" + "@babel/traverse" "^7.28.6" + "@babel/helper-optimise-call-expression@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz#c65221b61a643f3e62705e5dd2b5f115e35f9200" @@ -840,14 +857,14 @@ "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-modules-systemjs@^7.28.5": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz#7439e592a92d7670dfcb95d0cbc04bd3e64801d2" - integrity sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew== + version "7.29.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.4.tgz#f621105da99919c15cf4bde6fcc7346ef95e7b20" + integrity sha512-N7QmZ0xRZfjHOfZeQLJjwgX2zS9pdGHSVl/cjSGlo4dXMqvurfxXDMKY4RqEKzPozV78VMcd0lxyG13mlbKc4w== dependencies: - "@babel/helper-module-transforms" "^7.28.3" - "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-module-transforms" "^7.28.6" + "@babel/helper-plugin-utils" "^7.28.6" "@babel/helper-validator-identifier" "^7.28.5" - "@babel/traverse" "^7.28.5" + "@babel/traverse" "^7.29.0" "@babel/plugin-transform-modules-umd@^7.27.1": version "7.27.1" @@ -2446,33 +2463,32 @@ resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== -"@protobufjs/codegen@^2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" - integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== +"@protobufjs/codegen@^2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.5.tgz#d9315ad7cf3f30aac70bda3c068443dc6f143659" + integrity sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g== "@protobufjs/eventemitter@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== -"@protobufjs/fetch@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" - integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== +"@protobufjs/fetch@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.1.tgz#4d6fc00c8fb64016a5c81b469d549046350f1065" + integrity sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw== dependencies: "@protobufjs/aspromise" "^1.1.1" - "@protobufjs/inquire" "^1.1.0" "@protobufjs/float@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== -"@protobufjs/inquire@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" - integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== +"@protobufjs/inquire@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.2.tgz#ae64fbc014ff44c8bfad03dd4c93cd2d6a4c82db" + integrity sha512-pa0vFRuws4wkvaXKK1uXZMAwAX4/t8ANaJo45iw/oQHNQ9q5xUzwgFmVJGXiga2BeN+zpX7Vf9vmsiIa2J+MUw== "@protobufjs/path@^1.1.2": version "1.1.2" @@ -2484,10 +2500,10 @@ resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== -"@protobufjs/utf8@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" - integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== +"@protobufjs/utf8@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.1.tgz#eaee5900122c110a3dbcb728c0597014a2621774" + integrity sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg== "@react-native-async-storage/async-storage@^2.2.0": version "2.2.0" @@ -3776,11 +3792,6 @@ bignumber.js "^9.1.2" node-cache "^5.1.2" -"@trysound/sax@0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" - integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== - "@tybys/wasm-util@^0.10.0", "@tybys/wasm-util@^0.10.1": version "0.10.1" resolved "https://registry.yarnpkg.com/@tybys/wasm-util/-/wasm-util-0.10.1.tgz#ecddd3205cf1e2d5274649ff0eedd2991ed7f414" @@ -4534,9 +4545,9 @@ tslib "^2.3.0" "@xmldom/xmldom@^0.8.8": - version "0.8.12" - resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.12.tgz#cf488a5435fa06c7374ad1449c69cea0f823624b" - integrity sha512-9k/gHF6n/pAi/9tqr3m3aqkuiNosYTurLLUtc7xQ9sxB/wm7WPygCv8GYa6mS0fLJEHhqMC1ATYhz++U/lRHqg== + version "0.8.13" + resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.13.tgz#00d1dd940b218dff2e49309d410d8bb212159225" + integrity sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw== abort-controller@^3.0.0: version "3.0.0" @@ -4842,10 +4853,10 @@ available-typed-arrays@^1.0.7: dependencies: possible-typed-array-names "^1.0.0" -axios@^0.30.0, axios@^1.11.0, axios@^1.13.5, axios@^1.8.4: - version "1.15.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.15.0.tgz#0fcee91ef03d386514474904b27863b2c683bf4f" - integrity sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q== +axios@1.15.2, axios@^0.30.0, axios@^1.11.0, axios@^1.8.4: + version "1.15.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.15.2.tgz#eb8fb6d30349abace6ade5b4cb4d9e8a0dc23e5b" + integrity sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A== dependencies: follow-redirects "^1.15.11" form-data "^4.0.5" @@ -5127,13 +5138,6 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -brace-expansion@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.2.tgz#54fc53237a613d854c7bd37463aad17df87214e7" - integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ== - dependencies: - balanced-match "^1.0.0" - brace-expansion@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.3.tgz#0493338bdd58e319b1039c67cf7ee439892c01d9" @@ -5621,10 +5625,10 @@ convert-source-map@^2.0.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== -cookie-es@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/cookie-es/-/cookie-es-1.2.2.tgz#18ceef9eb513cac1cb6c14bcbf8bdb2679b34821" - integrity sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg== +cookie-es@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cookie-es/-/cookie-es-1.2.3.tgz#06ca3c5f5f3531684a2059666a361173f74a89c8" + integrity sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw== core-js-compat@^3.43.0: version "3.47.0" @@ -5944,7 +5948,7 @@ define-properties@^1.1.3, define-properties@^1.2.1: has-property-descriptors "^1.0.0" object-keys "^1.1.1" -defu@^6.1.4: +defu@^6.1.6: version "6.1.7" resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.7.tgz#72543567c8e9f97ff13ce402b6dbe09ac5ae4d23" integrity sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ== @@ -6839,11 +6843,21 @@ fast-text-encoding@^1.0.6: resolved "https://registry.yarnpkg.com/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz#0aa25f7f638222e3396d72bf936afcf1d42d6867" integrity sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w== -fast-xml-parser@5.3.7, fast-xml-parser@^4.4.1: - version "5.3.7" - resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-5.3.7.tgz#81694e71ff0e568cbb6befade342f2a7e58aa1d9" - integrity sha512-JzVLro9NQv92pOM/jTCR6mHlJh2FGwtomH8ZQjhFj/R29P2Fnj38OgPJVtcvYw6SuKClhgYuwUZf5b3rd8u2mA== +fast-xml-builder@^1.1.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz#abd2363145a7625d9789ad96da375fabe3cff28c" + integrity sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q== + dependencies: + path-expression-matcher "^1.5.0" + xml-naming "^0.1.0" + +fast-xml-parser@5.5.6, fast-xml-parser@^4.4.1: + version "5.5.6" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-5.5.6.tgz#6fc61f5ae06a55a1f058abd6a4f4b5d3e9972cd0" + integrity sha512-3+fdZyBRVg29n4rXP0joHthhcHdPUHaIC16cuyyd1iLsuaO6Vea36MPrxgAzbZna8lhvZeRL8Bc9GP56/J9xEw== dependencies: + fast-xml-builder "^1.1.4" + path-expression-matcher "^1.1.3" strnum "^2.1.2" fastq@^1.6.0: @@ -6981,9 +6995,9 @@ flat-cache@^3.0.4: rimraf "^3.0.2" flatted@^3.2.9: - version "3.3.3" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.3.tgz#67c8fad95454a7c7abebf74bb78ee74a44023358" - integrity sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg== + version "3.4.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.4.2.tgz#f5c23c107f0f37de8dbdf24f13722b3b98d52726" + integrity sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA== flow-enums-runtime@^0.0.6: version "0.0.6" @@ -7295,13 +7309,13 @@ graphql@^16.6.0: integrity sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ== h3@^1.15.4: - version "1.15.5" - resolved "https://registry.yarnpkg.com/h3/-/h3-1.15.5.tgz#e2f28d4a66a249973bb050eaddb06b9ab55506f8" - integrity sha512-xEyq3rSl+dhGX2Lm0+eFQIAzlDN6Fs0EcC4f7BNUmzaRX/PTzeuM+Tr2lHB8FoXggsQIeXLj8EDVgs5ywxyxmg== + version "1.15.11" + resolved "https://registry.yarnpkg.com/h3/-/h3-1.15.11.tgz#831179fc6b4bc06de8ad1077e7a5c7d63b796577" + integrity sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg== dependencies: - cookie-es "^1.2.2" + cookie-es "^1.2.3" crossws "^0.3.5" - defu "^6.1.4" + defu "^6.1.6" destr "^2.0.5" iron-webcrypto "^1.2.1" node-mock-http "^1.0.4" @@ -8541,10 +8555,10 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -lodash-es@^4.17.21: - version "4.17.22" - resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.22.tgz#eb7d123ec2470d69b911abe34f85cb694849b346" - integrity sha512-XEawp1t0gxSi9x01glktRZ5HDy0HXqrM0x5pXQM98EaI0NxO6jVM7omDOxsuEo5UIASAnm2bRp1Jt/e0a2XU8Q== +lodash-es@^4.17.21, lodash-es@^4.18.1: + version "4.18.1" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.18.1.tgz#b962eeb80d9d983a900bf342961fb7418ca10b1d" + integrity sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A== lodash.camelcase@^4.3.0: version "4.3.0" @@ -8577,9 +8591,9 @@ lodash.throttle@^4.1.1: integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ== lodash@^4.16.4, lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + version "4.18.1" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.18.1.tgz#ff2b66c1f6326d59513de2407bf881439812771c" + integrity sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q== log-symbols@^4.1.0: version "4.1.0" @@ -8598,7 +8612,7 @@ logkitty@^0.7.1: dayjs "^1.8.15" yargs "^15.1.0" -long@^5.0.0: +long@^5.0.0, long@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/long/-/long-5.3.2.tgz#1d84463095999262d7d7b7f8bfd4a8cc55167f83" integrity sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA== @@ -8992,12 +9006,12 @@ minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== -minimatch@9.0.3: - version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== +minimatch@9.0.3, minimatch@^9.0.4, minimatch@^9.0.5, minimatch@^9.0.7: + version "9.0.9" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.9.tgz#9b0cb9fcb78087f6fd7eababe2511c4d3d60574e" + integrity sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg== dependencies: - brace-expansion "^2.0.1" + brace-expansion "^2.0.2" minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.5" @@ -9006,13 +9020,6 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -minimatch@^9.0.4, minimatch@^9.0.5: - version "9.0.9" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.9.tgz#9b0cb9fcb78087f6fd7eababe2511c4d3d60574e" - integrity sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg== - dependencies: - brace-expansion "^2.0.2" - minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6, minimist@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" @@ -9556,6 +9563,11 @@ path-exists@^4.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== +path-expression-matcher@^1.1.3, path-expression-matcher@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz#3b98545dc88ffebb593e2d8458d0929da9275f4a" + integrity sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ== + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -9780,22 +9792,22 @@ property-expr@^2.0.4: integrity sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA== protobufjs@^7.2.5: - version "7.5.5" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.5.5.tgz#b7089ca4410374c75150baf277353ef76db69f96" - integrity sha512-3wY1AxV+VBNW8Yypfd1yQY9pXnqTAN+KwQxL8iYm3/BjKYMNg4i0owhEe26PWDOMaIrzeeF98Lqd5NGz4omiIg== + version "7.6.0" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.6.0.tgz#61e42285beec2708a9c84d7abbb5f22e2ddc54d4" + integrity sha512-LtESOsMPTZgyYtwxhvdgdjGL0HmXEaRA/hVD6sol4zA60hVXXXP/SGmxnqDbgGE8gy7pYex7cym+5vYPcmaXBQ== dependencies: "@protobufjs/aspromise" "^1.1.2" "@protobufjs/base64" "^1.1.2" - "@protobufjs/codegen" "^2.0.4" + "@protobufjs/codegen" "^2.0.5" "@protobufjs/eventemitter" "^1.1.0" - "@protobufjs/fetch" "^1.1.0" + "@protobufjs/fetch" "^1.1.1" "@protobufjs/float" "^1.0.2" - "@protobufjs/inquire" "^1.1.0" + "@protobufjs/inquire" "^1.1.2" "@protobufjs/path" "^1.1.2" "@protobufjs/pool" "^1.1.0" - "@protobufjs/utf8" "^1.1.0" + "@protobufjs/utf8" "^1.1.1" "@types/node" ">=13.7.0" - long "^5.0.0" + long "^5.3.2" proxy-from-env@^1.1.0: version "1.1.0" @@ -10661,6 +10673,11 @@ sax@>=0.6.0: resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.3.tgz#fcebae3b756cdc8428321805f4b70f16ec0ab5db" integrity sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ== +sax@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.6.0.tgz#da59637629307b97e7c4cb28e080a7bc38560d5b" + integrity sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA== + scheduler@0.27.0, scheduler@^0.27.0: version "0.27.0" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.27.0.tgz#0c4ef82d67d1e5c1e359e8fc76d3a87f045fe5bd" @@ -11268,17 +11285,17 @@ svg-parser@^2.0.4: integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== svgo@^3.0.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-3.3.2.tgz#ad58002652dffbb5986fc9716afe52d869ecbda8" - integrity sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw== + version "3.3.3" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-3.3.3.tgz#8246aee0b08791fde3b0ed22b5661b471fadf58e" + integrity sha512-+wn7I4p7YgJhHs38k2TNjy1vCfPIfLIJWR5MnCStsN8WuuTcBnRKcMHQLMM2ijxGZmDoZwNv8ipl5aTTen62ng== dependencies: - "@trysound/sax" "0.2.0" commander "^7.2.0" css-select "^5.1.0" css-tree "^2.3.1" css-what "^6.1.0" csso "^5.0.5" picocolors "^1.0.0" + sax "^1.5.0" swr@^2.2.4: version "2.3.8" @@ -12092,6 +12109,11 @@ xml-formatter@^3.6.5: dependencies: xml-parser-xo "^4.1.5" +xml-naming@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/xml-naming/-/xml-naming-0.1.0.tgz#8ab7106c5b8d23caa2fabac1cadf17136379fbd8" + integrity sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw== + xml-parser-xo@^4.1.5: version "4.1.5" resolved "https://registry.yarnpkg.com/xml-parser-xo/-/xml-parser-xo-4.1.5.tgz#c3326af56219a406f1e20741a2826655fcb3b607" From 037099ecce64d01e32684f4f4bb0b64ea264d009 Mon Sep 17 00:00:00 2001 From: lendihop Date: Wed, 20 May 2026 17:45:58 +0200 Subject: [PATCH 06/20] TW-2254: bump version --- android/app/build.gradle | 2 +- ios/TempleWallet/Debug-Info.plist | 2 +- ios/TempleWallet/Info.plist | 2 +- package.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 407f44bf9..00017d222 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -99,7 +99,7 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1460 - versionName "1.55" + versionName "2.00" missingDimensionStrategy 'react-native-camera', 'general' } diff --git a/ios/TempleWallet/Debug-Info.plist b/ios/TempleWallet/Debug-Info.plist index 27baac113..17214c39d 100644 --- a/ios/TempleWallet/Debug-Info.plist +++ b/ios/TempleWallet/Debug-Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.55 + 2.00 CFBundleSignature ???? CFBundleURLTypes diff --git a/ios/TempleWallet/Info.plist b/ios/TempleWallet/Info.plist index f18286d80..a43664977 100644 --- a/ios/TempleWallet/Info.plist +++ b/ios/TempleWallet/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.55 + 2.00 CFBundleSignature ???? CFBundleURLTypes diff --git a/package.json b/package.json index a41eaa30f..9605a764b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "temple-wallet", - "version": "1.55", + "version": "2.00", "private": true, "scripts": { "postinstall": "bash postinstall.sh", From e100b67beeaa71311b098013e753cc724ee7ee2d Mon Sep 17 00:00:00 2001 From: lendihop Date: Wed, 20 May 2026 17:52:27 +0200 Subject: [PATCH 07/20] TW-2254: update workflows --- .github/workflows/apk-build.yml | 2 +- .github/workflows/fastlane-build.yml | 2 +- .github/workflows/repository-setup/action.yml | 6 +++--- .github/workflows/testapp-build.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/apk-build.yml b/.github/workflows/apk-build.yml index 9e65b1bcd..d88da2cb3 100644 --- a/.github/workflows/apk-build.yml +++ b/.github/workflows/apk-build.yml @@ -7,7 +7,7 @@ on: inputs: version: description: Version - default: "1.53" + default: "2.00" required: true build-number: description: Build number diff --git a/.github/workflows/fastlane-build.yml b/.github/workflows/fastlane-build.yml index ce0238177..929b148de 100644 --- a/.github/workflows/fastlane-build.yml +++ b/.github/workflows/fastlane-build.yml @@ -109,7 +109,7 @@ jobs: - name: Setup Xcode uses: maxim-lobanov/setup-xcode@v1 with: - xcode-version: "26.2" + xcode-version: "26.5" - name: Install iOS Gemfile dependencies run: cd ios && bundle install diff --git a/.github/workflows/repository-setup/action.yml b/.github/workflows/repository-setup/action.yml index 7615e5a8b..fe951b79d 100644 --- a/.github/workflows/repository-setup/action.yml +++ b/.github/workflows/repository-setup/action.yml @@ -1,14 +1,14 @@ name: Repository setup -description: Setups Node 18.x & installs dependencies +description: Setups Node 22.x & installs dependencies runs: using: 'composite' steps: - - name: Setup Node 20.x + - name: Setup Node 22.x uses: actions/setup-node@v4 with: - node-version: '20.x' + node-version: '22.x' - name: Get branch name uses: EthanSK/git-branch-name-action@v1 diff --git a/.github/workflows/testapp-build.yml b/.github/workflows/testapp-build.yml index f2f41c460..327dc5319 100644 --- a/.github/workflows/testapp-build.yml +++ b/.github/workflows/testapp-build.yml @@ -7,7 +7,7 @@ on: inputs: version: description: Version - default: "1.53" + default: "2.00" required: true build-number: description: Build number @@ -115,7 +115,7 @@ jobs: - name: Setup Xcode uses: maxim-lobanov/setup-xcode@v1 with: - xcode-version: "26.2" + xcode-version: "26.5" - name: Install Pods if: ${{ github.event.inputs.ios == 'true' }} From 38e107098685c34b8fd055f281d478d197c86aed Mon Sep 17 00:00:00 2001 From: lendihop Date: Thu, 21 May 2026 15:45:35 +0200 Subject: [PATCH 08/20] TW-2254: update some more packages --- package.json | 9 +-- yarn.lock | 161 +++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 128 insertions(+), 42 deletions(-) diff --git a/package.json b/package.json index 9605a764b..5cec50cfc 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "@apollo/client": "^3.7.1", "@d11/react-native-fast-image": "^8.13.0", "@dicebear/bottts": "^9.3.0", - "@dicebear/core": "^9.3.0", + "@dicebear/core": "^9.4.2", "@gorhom/bottom-sheet": "^5", "@gorhom/portal": "^1.0.14", "@jitsu/sdk-js": "madfish-solutions/jitsu-js#87c49de334f5747952f7beda573b95ceb5d86903", @@ -45,11 +45,11 @@ "@react-native-firebase/messaging": "^24.0.0", "@react-native-google-signin/google-signin": "^16.1.1", "@react-native-masked-view/masked-view": "^0.3.2", - "@react-navigation/native": "^7.1.27", - "@react-navigation/stack": "^7.6.14", + "@react-navigation/native": "^7.2.4", + "@react-navigation/stack": "^7.9.2", "@reduxjs/toolkit": "^1.8.5", "@sentry/react-native": "^7.8.0", - "@shopify/flash-list": "^2.2.0", + "@shopify/flash-list": "^2.3.1", "@taquito/local-forging": "^24.2.0", "@taquito/rpc": "^24.2.0", "@taquito/signer": "^24.2.0", @@ -128,6 +128,7 @@ "ts-action": "^11.0.0", "ts-action-operators": "^9.1.2", "typedarray-to-buffer": "^4.0.0", + "viem": "^2.50.4", "yup": "^0.32.11" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 2410b2d84..5d1881430 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@adraffy/ens-normalize@^1.11.0": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.11.1.tgz#6c2d657d4b2dfb37f8ea811dcb3e60843d4ac24a" + integrity sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ== + "@airgap/beacon-blockchain-substrate@4.6.4": version "4.6.4" resolved "https://registry.yarnpkg.com/@airgap/beacon-blockchain-substrate/-/beacon-blockchain-substrate-4.6.4.tgz#2f91763192e77cba1bb214abf37e93bf731765f8" @@ -1304,12 +1309,12 @@ resolved "https://registry.yarnpkg.com/@dicebear/bottts/-/bottts-9.3.0.tgz#8a86e03868825d2f6fab800f858ec8d992143fef" integrity sha512-Qk5SThcva58LRfM385WmaKGeaIlKExqTBnf3bOcWsCV9kuiVZTxl+h0li636wlYdfC4AX20xugmCgKSKS5egIw== -"@dicebear/core@^9.3.0": - version "9.3.0" - resolved "https://registry.yarnpkg.com/@dicebear/core/-/core-9.3.0.tgz#cab55104f70f9fd73cb660d64006db3282cd21c6" - integrity sha512-ZzIKk9Xaiee5rYAEDvSfD5qyCQddiHeg/u0dwehXgxAL+FpZgr2qlEq2Ea4hkJHv0lCulZzKTL5hkLexaUHU1w== +"@dicebear/core@^9.4.2": + version "9.4.2" + resolved "https://registry.yarnpkg.com/@dicebear/core/-/core-9.4.2.tgz#8c15c7ef20e598228240a0fbfb173fe34d01f0bb" + integrity sha512-MF0042+Z3s8PGZKZLySfhft28bUa3B1iq0e5NSjCvY8gfMi5aIH/iRJGRJa1N9Jz1BNkxYb4yvJ/N9KO8Z6Y+w== dependencies: - "@types/json-schema" "^7.0.11" + "@types/json-schema" "^7.0.15" "@egjs/hammerjs@^2.0.17": version "2.0.17" @@ -1900,9 +1905,9 @@ integrity sha512-+uGNN7rkfn41HLO0vekTFhTxk61eKa8mTpRGLO0QSqlQdKvIoGAvLp3ppdVIWbTGYJWM6Kp0iN+PjMIOcnVqTw== "@gorhom/bottom-sheet@^5": - version "5.2.8" - resolved "https://registry.yarnpkg.com/@gorhom/bottom-sheet/-/bottom-sheet-5.2.8.tgz#25e49122c30ffe83d3813b3bcf3dec39f3359aeb" - integrity sha512-+N27SMpbBxXZQ/IA2nlEV6RGxL/qSFHKfdFKcygvW+HqPG5jVNb1OqehLQsGfBP+Up42i0gW5ppI+DhpB7UCzA== + version "5.2.14" + resolved "https://registry.yarnpkg.com/@gorhom/bottom-sheet/-/bottom-sheet-5.2.14.tgz#2b74ad9293b0ad40518487c6dcd151cadd5b3de3" + integrity sha512-uLQFlDjp9z+jrOFcMSEldPqL5JdaXL3vXOh+juhwoNvXgTsEorJLjHTugXu+YccAG/0KJnShzKCrb71MHBsvJg== dependencies: "@gorhom/portal" "1.0.14" invariant "^2.2.4" @@ -2293,7 +2298,12 @@ resolved "https://registry.yarnpkg.com/@noble/ciphers/-/ciphers-1.2.1.tgz#3812b72c057a28b44ff0ad4aff5ca846e5b9cdc9" integrity sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA== -"@noble/curves@1.8.0", "@noble/curves@1.8.1", "@noble/curves@1.9.7", "@noble/curves@^1.9.7": +"@noble/ciphers@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@noble/ciphers/-/ciphers-1.3.0.tgz#f64b8ff886c240e644e5573c097f86e5b43676dc" + integrity sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw== + +"@noble/curves@1.8.0", "@noble/curves@1.8.1", "@noble/curves@1.9.1", "@noble/curves@1.9.7", "@noble/curves@^1.9.7", "@noble/curves@~1.9.0": version "1.9.7" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.9.7.tgz#79d04b4758a43e4bca2cbdc62e7771352fa6b951" integrity sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw== @@ -2310,7 +2320,7 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.7.1.tgz#5738f6d765710921e7a751e00c20ae091ed8db0f" integrity sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ== -"@noble/hashes@1.8.0", "@noble/hashes@^1.2.0": +"@noble/hashes@1.8.0", "@noble/hashes@^1.2.0", "@noble/hashes@^1.8.0", "@noble/hashes@~1.8.0": version "1.8.0" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.8.0.tgz#cee43d801fcef9644b11b8194857695acd5f815a" integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A== @@ -2944,12 +2954,12 @@ invariant "^2.2.4" nullthrows "^1.1.1" -"@react-navigation/core@^7.13.7": - version "7.13.7" - resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-7.13.7.tgz#1263903a703b5f183a08c22dfc5c3735ac4ef91c" - integrity sha512-k2ABo3250vq1ovOh/iVwXS6Hwr5PVRGXoPh/ewVFOOuEKTvOx9i//OBzt8EF+HokBxS2HBRlR2b+aCOmscRqBw== +"@react-navigation/core@^7.17.4": + version "7.17.4" + resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-7.17.4.tgz#704f650d0be01f5a1bfd2f17c96825ee27ab6bb2" + integrity sha512-Rv9E2oNNQEkPGpmu9q+vJwGJRSQR6LBg5L+Yo1QHjtwGbHUbjkIKOdYymDZoZYgNzX2OD4rAIlfuzbDKa3cCeA== dependencies: - "@react-navigation/routers" "^7.5.3" + "@react-navigation/routers" "^7.5.5" escape-string-regexp "^4.0.0" fast-deep-equal "^3.1.3" nanoid "^3.3.11" @@ -2958,39 +2968,39 @@ use-latest-callback "^0.2.4" use-sync-external-store "^1.5.0" -"@react-navigation/elements@^2.9.4": - version "2.9.4" - resolved "https://registry.yarnpkg.com/@react-navigation/elements/-/elements-2.9.4.tgz#72101e7cf74e6952a303ffd3a69aab5e9ba178a8" - integrity sha512-TMFh+QzwesEuSaKpvZk4BFC5105t5gJs9eq+jG7jtfdlMKyrcFwheu2/dy1zfrW4WYbVcoMxhzFqCU4mKwI4fw== +"@react-navigation/elements@^2.9.18": + version "2.9.18" + resolved "https://registry.yarnpkg.com/@react-navigation/elements/-/elements-2.9.18.tgz#6197631c44dde42c63b623df4f4d3276611aa1b2" + integrity sha512-mKEvDr6CkCVYZSb8W9WubNseihL+1c8M7ktZJCTCbMk8rQgdQfkdRNwpSUQKspdGpUHCb9cyzvaiuzl1NtjVgw== dependencies: color "^4.2.3" use-latest-callback "^0.2.4" use-sync-external-store "^1.5.0" -"@react-navigation/native@^7.1.27": - version "7.1.27" - resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-7.1.27.tgz#5be53e9fac9f6173d229b334fe41c2208684bac2" - integrity sha512-kW7LGP/RrisktpGyizTKw6HwSeQJdXnAN9L8GyQJcJAlgL9YtfEg6yEyD5n9RWH90CL8G0cRyUhphKIAFf4lVw== +"@react-navigation/native@^7.2.4": + version "7.2.4" + resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-7.2.4.tgz#3e44077d2ae1b7a6ba8e376b49e1fce6272dbec1" + integrity sha512-eWC2D3JjhYLId2fVTZhhCiUpWIaPhO9XyEb7Wq8ElmOHyIODlbOzgZ0rKia02OIsDKr9BzZl2sK1dL70yMxDaw== dependencies: - "@react-navigation/core" "^7.13.7" + "@react-navigation/core" "^7.17.4" escape-string-regexp "^4.0.0" fast-deep-equal "^3.1.3" nanoid "^3.3.11" use-latest-callback "^0.2.4" -"@react-navigation/routers@^7.5.3": - version "7.5.3" - resolved "https://registry.yarnpkg.com/@react-navigation/routers/-/routers-7.5.3.tgz#8002930ef5f62351be2475d0dffde3ffaee174d7" - integrity sha512-1tJHg4KKRJuQ1/EvJxatrMef3NZXEPzwUIUZ3n1yJ2t7Q97siwRtbynRpQG9/69ebbtiZ8W3ScOZF/OmhvM4Rg== +"@react-navigation/routers@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@react-navigation/routers/-/routers-7.5.5.tgz#04358f1997cc31aa702d01719af274dc123d6025" + integrity sha512-9/hhMte12Kgu+pMnLfA4EWJ0OQmIEAMVMX06FPH2yGkEQSQ3JhhCN/GkcRikzQhtEi97VYYQA15umptBUShcOQ== dependencies: nanoid "^3.3.11" -"@react-navigation/stack@^7.6.14": - version "7.6.14" - resolved "https://registry.yarnpkg.com/@react-navigation/stack/-/stack-7.6.14.tgz#0bb92d36ea306222f6e8e613ce26e694f3f1bdd7" - integrity sha512-JsNHn4pivZjIjYsUZn6f018AsvwmKZSPNSyVzXd4IhbjrF5hOZApNp1R7pFnQgBiET76Z06qKwBeCwVcW0Xoig== +"@react-navigation/stack@^7.9.2": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@react-navigation/stack/-/stack-7.9.2.tgz#d04bfce909d937a665e8265def986f3af4dd7d95" + integrity sha512-zrUpd1TMUa8X2WqEmrBo2tW7EYmPD/vUXchXF2SSM7pnKQILPbhaB6+724ANnBIyMKBgskxaAly7oX+I16X7ww== dependencies: - "@react-navigation/elements" "^2.9.4" + "@react-navigation/elements" "^2.9.18" color "^4.2.3" use-latest-callback "^0.2.4" @@ -3009,6 +3019,28 @@ resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8" integrity sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g== +"@scure/base@~1.2.5": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.2.6.tgz#ca917184b8231394dd8847509c67a0be522e59f6" + integrity sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg== + +"@scure/bip32@1.7.0", "@scure/bip32@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.7.0.tgz#b8683bab172369f988f1589640e53c4606984219" + integrity sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw== + dependencies: + "@noble/curves" "~1.9.0" + "@noble/hashes" "~1.8.0" + "@scure/base" "~1.2.5" + +"@scure/bip39@1.6.0", "@scure/bip39@^1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.6.0.tgz#475970ace440d7be87a6086cbee77cb8f1a684f9" + integrity sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A== + dependencies: + "@noble/hashes" "~1.8.0" + "@scure/base" "~1.2.5" + "@sentry-internal/browser-utils@10.38.0": version "10.38.0" resolved "https://registry.yarnpkg.com/@sentry-internal/browser-utils/-/browser-utils-10.38.0.tgz#576780062808bd3bae21476393f50caf9acbe12f" @@ -3147,10 +3179,10 @@ dependencies: "@sentry/core" "10.38.0" -"@shopify/flash-list@^2.2.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@shopify/flash-list/-/flash-list-2.3.0.tgz#ded45604a38bc0edd49f27e356e1c761bef4018f" - integrity sha512-DR7VuN8KJHTYj9zv1/IhpqrMBMQyeeW/DCWCbVQAAkWhHrc6ylIbXOY+qK93CuHABV+dNHXK/3V6p4wCSW/+wA== +"@shopify/flash-list@^2.3.1": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@shopify/flash-list/-/flash-list-2.3.1.tgz#d4f90b1471a741a97c07d9aadbfaf200e92c86f7" + integrity sha512-7oktg2NQR7KAODjFoDaWe8/OBzyYbdTE3zQTrUBMxjIbxHTHN7UXRX1hX3DHk8KvtkgQdRfZOV8Gjj2l4fGrXw== "@sideway/address@^4.1.5": version "4.1.5" @@ -3924,7 +3956,7 @@ expect "^29.0.0" pretty-format "^29.0.0" -"@types/json-schema@^7.0.11", "@types/json-schema@^7.0.12": +"@types/json-schema@^7.0.12", "@types/json-schema@^7.0.15": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -4549,6 +4581,16 @@ resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.13.tgz#00d1dd940b218dff2e49309d410d8bb212159225" integrity sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw== +abitype@1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.2.3.tgz#bec3e09dea97d99ef6c719140bee663a329ad1f4" + integrity sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg== + +abitype@^1.2.3: + version "1.2.4" + resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.2.4.tgz#8aab72949bcad4107031862ae998e5bd20eec76e" + integrity sha512-dpKH+N27vRjarMVTFFkeY445VTKftzGWpL0FiT7xmVmzQRKazZexzC5uHG0f6XKsVLAuUlndnbGau6lRejClxg== + abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -6709,6 +6751,11 @@ event-target-shim@^5.0.0: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== +eventemitter3@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== + eventemitter3@^4.0.4: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" @@ -7896,6 +7943,11 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== +isows@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/isows/-/isows-1.0.7.tgz#1c06400b7eed216fbba3bcbd68f12490fc342915" + integrity sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg== + istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" @@ -9426,6 +9478,20 @@ own-keys@^1.0.1: object-keys "^1.1.1" safe-push-apply "^1.0.0" +ox@0.14.22: + version "0.14.22" + resolved "https://registry.yarnpkg.com/ox/-/ox-0.14.22.tgz#ec4bbb5cfbdb8fbd03ec23cfe0732263a7c14697" + integrity sha512-nb5msL8qWbPglhIfZbGJAfw3cqiJjFMiWmACt7kgyWtLib12tcctbHufMT9Hb0Lr6Pt4k9I3dbpueTpbhvbqvA== + dependencies: + "@adraffy/ens-normalize" "^1.11.0" + "@noble/ciphers" "^1.3.0" + "@noble/curves" "1.9.1" + "@noble/hashes" "^1.8.0" + "@scure/bip32" "^1.7.0" + "@scure/bip39" "^1.6.0" + abitype "^1.2.3" + eventemitter3 "5.0.1" + oxc-resolver@^11.15.0: version "11.16.3" resolved "https://registry.yarnpkg.com/oxc-resolver/-/oxc-resolver-11.16.3.tgz#79b538ac74438f8f28eaff423b465080e821ac07" @@ -11870,6 +11936,20 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== +viem@^2.50.4: + version "2.50.4" + resolved "https://registry.yarnpkg.com/viem/-/viem-2.50.4.tgz#2fe61b1667c924234f31a1aa181957ac07adb1ee" + integrity sha512-rf98F4s3Vlb+uJZEKfay3IbBw3CNCbVtx5Y3UIljlO2tSX420g/J0WQSYsjzBSasUFgxgsXabji14O9kGbiqgg== + dependencies: + "@noble/curves" "1.9.1" + "@noble/hashes" "1.8.0" + "@scure/bip32" "1.7.0" + "@scure/bip39" "1.6.0" + abitype "1.2.3" + isows "1.0.7" + ox "0.14.22" + ws "8.20.1" + vlq@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/vlq/-/vlq-1.0.1.tgz#c003f6e7c0b4c1edd623fd6ee50bbc0d6a1de468" @@ -12082,6 +12162,11 @@ write-file-atomic@^4.0.2: imurmurhash "^0.1.4" signal-exit "^3.0.7" +ws@8.20.1: + version "8.20.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.20.1.tgz#91a9ae2b312ccf98e0a85ec499b48cef45ab0ddb" + integrity sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w== + ws@^6.2.3: version "6.2.3" resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.3.tgz#ccc96e4add5fd6fedbc491903075c85c5a11d9ee" From 5da4e9c070eb643373634fe06b52a42be080adaf Mon Sep 17 00:00:00 2001 From: lendihop Date: Mon, 25 May 2026 17:48:51 +0200 Subject: [PATCH 09/20] TW-2254: fix knip --- package.json | 1 - yarn.lock | 89 ++-------------------------------------------------- 2 files changed, 2 insertions(+), 88 deletions(-) diff --git a/package.json b/package.json index 5cec50cfc..ff1ca1e6b 100644 --- a/package.json +++ b/package.json @@ -128,7 +128,6 @@ "ts-action": "^11.0.0", "ts-action-operators": "^9.1.2", "typedarray-to-buffer": "^4.0.0", - "viem": "^2.50.4", "yup": "^0.32.11" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 5d1881430..8f0de1ad1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,11 +2,6 @@ # yarn lockfile v1 -"@adraffy/ens-normalize@^1.11.0": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.11.1.tgz#6c2d657d4b2dfb37f8ea811dcb3e60843d4ac24a" - integrity sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ== - "@airgap/beacon-blockchain-substrate@4.6.4": version "4.6.4" resolved "https://registry.yarnpkg.com/@airgap/beacon-blockchain-substrate/-/beacon-blockchain-substrate-4.6.4.tgz#2f91763192e77cba1bb214abf37e93bf731765f8" @@ -2298,12 +2293,7 @@ resolved "https://registry.yarnpkg.com/@noble/ciphers/-/ciphers-1.2.1.tgz#3812b72c057a28b44ff0ad4aff5ca846e5b9cdc9" integrity sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA== -"@noble/ciphers@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@noble/ciphers/-/ciphers-1.3.0.tgz#f64b8ff886c240e644e5573c097f86e5b43676dc" - integrity sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw== - -"@noble/curves@1.8.0", "@noble/curves@1.8.1", "@noble/curves@1.9.1", "@noble/curves@1.9.7", "@noble/curves@^1.9.7", "@noble/curves@~1.9.0": +"@noble/curves@1.8.0", "@noble/curves@1.8.1", "@noble/curves@1.9.7", "@noble/curves@^1.9.7": version "1.9.7" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.9.7.tgz#79d04b4758a43e4bca2cbdc62e7771352fa6b951" integrity sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw== @@ -2320,7 +2310,7 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.7.1.tgz#5738f6d765710921e7a751e00c20ae091ed8db0f" integrity sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ== -"@noble/hashes@1.8.0", "@noble/hashes@^1.2.0", "@noble/hashes@^1.8.0", "@noble/hashes@~1.8.0": +"@noble/hashes@1.8.0", "@noble/hashes@^1.2.0": version "1.8.0" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.8.0.tgz#cee43d801fcef9644b11b8194857695acd5f815a" integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A== @@ -3019,28 +3009,6 @@ resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8" integrity sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g== -"@scure/base@~1.2.5": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.2.6.tgz#ca917184b8231394dd8847509c67a0be522e59f6" - integrity sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg== - -"@scure/bip32@1.7.0", "@scure/bip32@^1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.7.0.tgz#b8683bab172369f988f1589640e53c4606984219" - integrity sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw== - dependencies: - "@noble/curves" "~1.9.0" - "@noble/hashes" "~1.8.0" - "@scure/base" "~1.2.5" - -"@scure/bip39@1.6.0", "@scure/bip39@^1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.6.0.tgz#475970ace440d7be87a6086cbee77cb8f1a684f9" - integrity sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A== - dependencies: - "@noble/hashes" "~1.8.0" - "@scure/base" "~1.2.5" - "@sentry-internal/browser-utils@10.38.0": version "10.38.0" resolved "https://registry.yarnpkg.com/@sentry-internal/browser-utils/-/browser-utils-10.38.0.tgz#576780062808bd3bae21476393f50caf9acbe12f" @@ -4581,16 +4549,6 @@ resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.13.tgz#00d1dd940b218dff2e49309d410d8bb212159225" integrity sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw== -abitype@1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.2.3.tgz#bec3e09dea97d99ef6c719140bee663a329ad1f4" - integrity sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg== - -abitype@^1.2.3: - version "1.2.4" - resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.2.4.tgz#8aab72949bcad4107031862ae998e5bd20eec76e" - integrity sha512-dpKH+N27vRjarMVTFFkeY445VTKftzGWpL0FiT7xmVmzQRKazZexzC5uHG0f6XKsVLAuUlndnbGau6lRejClxg== - abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -6751,11 +6709,6 @@ event-target-shim@^5.0.0: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== -eventemitter3@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" - integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== - eventemitter3@^4.0.4: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" @@ -7943,11 +7896,6 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -isows@1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/isows/-/isows-1.0.7.tgz#1c06400b7eed216fbba3bcbd68f12490fc342915" - integrity sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg== - istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" @@ -9478,20 +9426,6 @@ own-keys@^1.0.1: object-keys "^1.1.1" safe-push-apply "^1.0.0" -ox@0.14.22: - version "0.14.22" - resolved "https://registry.yarnpkg.com/ox/-/ox-0.14.22.tgz#ec4bbb5cfbdb8fbd03ec23cfe0732263a7c14697" - integrity sha512-nb5msL8qWbPglhIfZbGJAfw3cqiJjFMiWmACt7kgyWtLib12tcctbHufMT9Hb0Lr6Pt4k9I3dbpueTpbhvbqvA== - dependencies: - "@adraffy/ens-normalize" "^1.11.0" - "@noble/ciphers" "^1.3.0" - "@noble/curves" "1.9.1" - "@noble/hashes" "^1.8.0" - "@scure/bip32" "^1.7.0" - "@scure/bip39" "^1.6.0" - abitype "^1.2.3" - eventemitter3 "5.0.1" - oxc-resolver@^11.15.0: version "11.16.3" resolved "https://registry.yarnpkg.com/oxc-resolver/-/oxc-resolver-11.16.3.tgz#79b538ac74438f8f28eaff423b465080e821ac07" @@ -11936,20 +11870,6 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== -viem@^2.50.4: - version "2.50.4" - resolved "https://registry.yarnpkg.com/viem/-/viem-2.50.4.tgz#2fe61b1667c924234f31a1aa181957ac07adb1ee" - integrity sha512-rf98F4s3Vlb+uJZEKfay3IbBw3CNCbVtx5Y3UIljlO2tSX420g/J0WQSYsjzBSasUFgxgsXabji14O9kGbiqgg== - dependencies: - "@noble/curves" "1.9.1" - "@noble/hashes" "1.8.0" - "@scure/bip32" "1.7.0" - "@scure/bip39" "1.6.0" - abitype "1.2.3" - isows "1.0.7" - ox "0.14.22" - ws "8.20.1" - vlq@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/vlq/-/vlq-1.0.1.tgz#c003f6e7c0b4c1edd623fd6ee50bbc0d6a1de468" @@ -12162,11 +12082,6 @@ write-file-atomic@^4.0.2: imurmurhash "^0.1.4" signal-exit "^3.0.7" -ws@8.20.1: - version "8.20.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.20.1.tgz#91a9ae2b312ccf98e0a85ec499b48cef45ab0ddb" - integrity sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w== - ws@^6.2.3: version "6.2.3" resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.3.tgz#ccc96e4add5fd6fedbc491903075c85c5a11d9ee" From 4c92d07abddf0f7a502c1cd6fa8d6b606b5ab9f2 Mon Sep 17 00:00:00 2001 From: lendihop Date: Mon, 25 May 2026 21:01:06 +0200 Subject: [PATCH 10/20] TW-2254: fix linter --- .eslintrc.json | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index da3453235..ffde2c429 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -15,6 +15,7 @@ ], "plugins": ["@typescript-eslint", "import", "no-type-assertion", "jest", "jsx-expressions"], "settings": { + "import/ignore": ["node_modules/react-native/"], "import/resolver": { "typescript": {} } diff --git a/package.json b/package.json index ff1ca1e6b..13e7a3190 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "ios": "react-native run-ios", "ios:pods": "cd ios && pod install", "ios:test-flight": "cd ios && bundle exec fastlane beta", - "lint": "eslint .", + "lint": "eslint --quiet src", "lint:format": "prettier \"src/**/*\" --write --ignore-unknown", "start": "react-native start", "test": "jest", From 05872e0ae14f07cbbddc67721e3e2eeba2d995ad Mon Sep 17 00:00:00 2001 From: lendihop Date: Fri, 29 May 2026 19:23:02 +0200 Subject: [PATCH 11/20] TW-2254: fix audit --- package.json | 4 ++-- yarn.lock | 21 +++++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 13e7a3190..a1db1c032 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "@types/async-retry": "^1.4.9", "@types/redux-logger": "^3.0.13", "async-retry": "^1.3.3", - "axios": "1.15.2", + "axios": "1.16.1", "bignumber.js": "^9.3.1", "bip39": "^3.1.0", "buffer": "^6.0.3", @@ -174,7 +174,7 @@ "@airgap/beacon-dapp": "link:./node_modules/.cache/null", "@airgap/beacon-ui": "link:./node_modules/.cache/null", "@airgap/beacon-transport-postmessage": "link:./node_modules/.cache/null", - "axios": "1.15.2", + "axios": "1.16.1", "node-libs-react-native/react-native-randombytes": "madfish-solutions/react-native-randombytes#cf4f237e0affbef3f23d444478bd271b28936ac0", "fast-xml-parser": "5.5.6", "underscore": "^1.13.8", diff --git a/yarn.lock b/yarn.lock index 8f0de1ad1..640185b9b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4853,13 +4853,14 @@ available-typed-arrays@^1.0.7: dependencies: possible-typed-array-names "^1.0.0" -axios@1.15.2, axios@^0.30.0, axios@^1.11.0, axios@^1.8.4: - version "1.15.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.15.2.tgz#eb8fb6d30349abace6ade5b4cb4d9e8a0dc23e5b" - integrity sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A== +axios@1.16.1, axios@^0.30.0, axios@^1.11.0, axios@^1.8.4: + version "1.16.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.16.1.tgz#517e29291d19d6e8cf919ff264f4fe157261ba12" + integrity sha512-caYkukvroVPO8KrzuJEb50Hm07KwfBZPEC3VeFHTsqWHvKTsy54hjJz9BS/cdaypROE2rH6xvm9mHX4fgWkr3A== dependencies: - follow-redirects "^1.15.11" + follow-redirects "^1.16.0" form-data "^4.0.5" + https-proxy-agent "^5.0.1" proxy-from-env "^2.1.0" b4a@^1.6.4: @@ -7004,10 +7005,10 @@ flow-enums-runtime@^0.0.6: resolved "https://registry.yarnpkg.com/flow-enums-runtime/-/flow-enums-runtime-0.0.6.tgz#5bb0cd1b0a3e471330f4d109039b7eba5cb3e787" integrity sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw== -follow-redirects@^1.15.11: - version "1.15.11" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.11.tgz#777d73d72a92f8ec4d2e410eb47352a56b8e8340" - integrity sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ== +follow-redirects@^1.16.0: + version "1.16.0" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.16.0.tgz#28474a159d3b9d11ef62050a14ed60e4df6d61bc" + integrity sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw== for-each@^0.3.3, for-each@^0.3.5: version "0.3.5" @@ -7477,7 +7478,7 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg== -https-proxy-agent@^5.0.0: +https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== From 118f3af8d11913af85d6a25193df0a6f199beca5 Mon Sep 17 00:00:00 2001 From: lendihop Date: Tue, 2 Jun 2026 12:53:38 +0200 Subject: [PATCH 12/20] TW-2254: adjust lockfile --- package.json | 2 +- yarn.lock | 1664 +++++++++++++++++++++++++++----------------------- 2 files changed, 911 insertions(+), 755 deletions(-) diff --git a/package.json b/package.json index 9cfa56a35..02347107a 100644 --- a/package.json +++ b/package.json @@ -180,7 +180,7 @@ "fast-xml-parser": "5.5.6", "underscore": "^1.13.8", "@noble/curves": "1.9.7", - "eslint-plugin-jsx-expressions/@typescript-eslint/utils/@typescript-eslint/typescript-estree/minimatch": "^9.0.7" + "@typescript-eslint/typescript-estree/minimatch": "^9.0.7" }, "engines": { "node": ">= 22.11.0" diff --git a/yarn.lock b/yarn.lock index 9a906a6c1..220295b02 100644 --- a/yarn.lock +++ b/yarn.lock @@ -170,7 +170,7 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.24.7, @babel/code-frame@npm:^7.27.1": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.27.1": version: 7.27.1 resolution: "@babel/code-frame@npm:7.27.1" dependencies: @@ -181,7 +181,7 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.29.7": +"@babel/code-frame@npm:^7.29.0, @babel/code-frame@npm:^7.29.7": version: 7.29.7 resolution: "@babel/code-frame@npm:7.29.7" dependencies: @@ -245,7 +245,7 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.25.0, @babel/generator@npm:^7.28.5, @babel/generator@npm:^7.7.2": +"@babel/generator@npm:^7.28.5, @babel/generator@npm:^7.7.2": version: 7.28.5 resolution: "@babel/generator@npm:7.28.5" dependencies: @@ -258,7 +258,7 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.29.7": +"@babel/generator@npm:^7.29.1, @babel/generator@npm:^7.29.7": version: 7.29.7 resolution: "@babel/generator@npm:7.29.7" dependencies: @@ -280,6 +280,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-annotate-as-pure@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-annotate-as-pure@npm:7.29.7" + dependencies: + "@babel/types": "npm:^7.29.7" + checksum: 10c0/c56536b52d17632d89d49db2063ed6102f0e3bbadf6a0ccb74e6599d6a77173b644c7fe8c3ef17c7a162709d55b75ee5145ef6db917d16ba7f375fbffcf2e942 + languageName: node + linkType: hard + "@babel/helper-compilation-targets@npm:^7.27.1, @babel/helper-compilation-targets@npm:^7.27.2": version: 7.27.2 resolution: "@babel/helper-compilation-targets@npm:7.27.2" @@ -310,6 +319,23 @@ __metadata: languageName: node linkType: hard +"@babel/helper-create-class-features-plugin@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-create-class-features-plugin@npm:7.29.7" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.29.7" + "@babel/helper-member-expression-to-functions": "npm:^7.29.7" + "@babel/helper-optimise-call-expression": "npm:^7.29.7" + "@babel/helper-replace-supers": "npm:^7.29.7" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.29.7" + "@babel/traverse": "npm:^7.29.7" + semver: "npm:^6.3.1" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/75f34905b5e708b473f1e9b33e07b2fcc8f4c60676df8bc74541bb91c77f387c32a948dd04d5071e469ba454d72d0a872e3ace40fbb1d1e7aaa8569efcf09ed4 + languageName: node + linkType: hard + "@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.27.1": version: 7.28.5 resolution: "@babel/helper-create-regexp-features-plugin@npm:7.28.5" @@ -362,6 +388,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-member-expression-to-functions@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-member-expression-to-functions@npm:7.29.7" + dependencies: + "@babel/traverse": "npm:^7.29.7" + "@babel/types": "npm:^7.29.7" + checksum: 10c0/eef7940ce0797208854a5af1049a98fee9abbffb5c619640c69ff5a555f8e3552295bb18756490b02bc6af7df8c1babcb83f12203aac2deb9dfecfc78846e12d + languageName: node + linkType: hard + "@babel/helper-module-imports@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-module-imports@npm:7.27.1" @@ -417,6 +453,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-optimise-call-expression@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-optimise-call-expression@npm:7.29.7" + dependencies: + "@babel/types": "npm:^7.29.7" + checksum: 10c0/fd0244b9bfbb487db02d59aa2703c6991d654ea5f3f39d912682842bdca2e87b5ae8643b0ce8069bf5fbee39d1aa9db7abefeb5e6ba1aa650dca12777cf5b7e2 + languageName: node + linkType: hard + "@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.27.1, @babel/helper-plugin-utils@npm:^7.8.0": version: 7.27.1 resolution: "@babel/helper-plugin-utils@npm:7.27.1" @@ -457,6 +502,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-replace-supers@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-replace-supers@npm:7.29.7" + dependencies: + "@babel/helper-member-expression-to-functions": "npm:^7.29.7" + "@babel/helper-optimise-call-expression": "npm:^7.29.7" + "@babel/traverse": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/1c7ae37797f226e965ab85f6affa53d25a10c169c604a4daeb36f9df09e673471e6522f631c13761cf9fbafeca2ea14c241dea8d723a51039d561beb01d86ac4 + languageName: node + linkType: hard + "@babel/helper-skip-transparent-expression-wrappers@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.27.1" @@ -467,6 +525,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-skip-transparent-expression-wrappers@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.29.7" + dependencies: + "@babel/traverse": "npm:^7.29.7" + "@babel/types": "npm:^7.29.7" + checksum: 10c0/8c59493621487fc491f27adfc200af82a6aca3b9a5511e4e6050f8716593b4b243472cb56c8d2016e828b7ae12d605a819205aa8600ca08ee291dcd58d65c832 + languageName: node + linkType: hard + "@babel/helper-string-parser@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-string-parser@npm:7.27.1" @@ -502,6 +570,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-option@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-validator-option@npm:7.29.7" + checksum: 10c0/d2a06c6d0ac40ba4a2f219fc2cab249c7a94bacdb2686273b7f9598571c908809b48468ff588915a346e6cc7296f60b581023d1d498b747fed06f779d335c2cc + languageName: node + linkType: hard + "@babel/helper-wrap-function@npm:^7.27.1": version: 7.28.3 resolution: "@babel/helper-wrap-function@npm:7.28.3" @@ -535,7 +610,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.24.4, @babel/parser@npm:^7.25.3, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.5": +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.24.4, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.5": version: 7.28.5 resolution: "@babel/parser@npm:7.28.5" dependencies: @@ -546,7 +621,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.29.7": +"@babel/parser@npm:^7.29.0, @babel/parser@npm:^7.29.7": version: 7.29.7 resolution: "@babel/parser@npm:7.29.7" dependencies: @@ -768,6 +843,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-jsx@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/plugin-syntax-jsx@npm:7.29.7" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/1736000de183538ba8eef34520105508860e48b0c763254ba9158af5e814ed8bbceeedbb4281fbda33de787ae5b3870e92f60c6ae7131e7d322e451d57387896 + languageName: node + linkType: hard + "@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4": version: 7.10.4 resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" @@ -867,6 +953,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-typescript@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/plugin-syntax-typescript@npm:7.29.7" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/c49883b0327e8683b770dc823205af5c697da216e590dcf5bf53f3f031e7e381de450b164f8f99853f0837a3de5cb793298e2be6697a0f6e452bb9dd34b5165e + languageName: node + linkType: hard + "@babel/plugin-syntax-unicode-sets-regex@npm:^7.18.6": version: 7.18.6 resolution: "@babel/plugin-syntax-unicode-sets-regex@npm:7.18.6" @@ -879,7 +976,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-arrow-functions@npm:7.27.1, @babel/plugin-transform-arrow-functions@npm:^7.24.7, @babel/plugin-transform-arrow-functions@npm:^7.27.1": +"@babel/plugin-transform-arrow-functions@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-arrow-functions@npm:7.27.1" dependencies: @@ -938,7 +1035,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-class-properties@npm:7.27.1, @babel/plugin-transform-class-properties@npm:^7.25.4, @babel/plugin-transform-class-properties@npm:^7.27.1": +"@babel/plugin-transform-class-properties@npm:^7.25.4, @babel/plugin-transform-class-properties@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-class-properties@npm:7.27.1" dependencies: @@ -962,7 +1059,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-classes@npm:7.28.4, @babel/plugin-transform-classes@npm:^7.25.4, @babel/plugin-transform-classes@npm:^7.28.4": +"@babel/plugin-transform-classes@npm:^7.25.4, @babel/plugin-transform-classes@npm:^7.28.4": version: 7.28.4 resolution: "@babel/plugin-transform-classes@npm:7.28.4" dependencies: @@ -978,7 +1075,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-computed-properties@npm:^7.24.7, @babel/plugin-transform-computed-properties@npm:^7.27.1": +"@babel/plugin-transform-computed-properties@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-computed-properties@npm:7.27.1" dependencies: @@ -1106,7 +1203,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-function-name@npm:^7.25.1, @babel/plugin-transform-function-name@npm:^7.27.1": +"@babel/plugin-transform-function-name@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-function-name@npm:7.27.1" dependencies: @@ -1130,7 +1227,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-literals@npm:^7.25.2, @babel/plugin-transform-literals@npm:^7.27.1": +"@babel/plugin-transform-literals@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-literals@npm:7.27.1" dependencies: @@ -1141,7 +1238,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-logical-assignment-operators@npm:^7.24.7, @babel/plugin-transform-logical-assignment-operators@npm:^7.28.5": +"@babel/plugin-transform-logical-assignment-operators@npm:^7.28.5": version: 7.28.5 resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.28.5" dependencies: @@ -1187,6 +1284,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-modules-commonjs@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.29.7" + dependencies: + "@babel/helper-module-transforms": "npm:^7.29.7" + "@babel/helper-plugin-utils": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/9791cb524438b2a8ba6cb8715788fa1e202fbecd4e76b3ccab0af0819fd69212b40ae30d72ac377012f7149889f7792ed8bf91e97bbe9113ca9641f8ad3bf332 + languageName: node + linkType: hard + "@babel/plugin-transform-modules-systemjs@npm:^7.28.5": version: 7.29.7 resolution: "@babel/plugin-transform-modules-systemjs@npm:7.29.7" @@ -1236,7 +1345,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-nullish-coalescing-operator@npm:7.27.1, @babel/plugin-transform-nullish-coalescing-operator@npm:^7.24.7, @babel/plugin-transform-nullish-coalescing-operator@npm:^7.27.1": +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.24.7, @babel/plugin-transform-nullish-coalescing-operator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.27.1" dependencies: @@ -1247,7 +1356,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-numeric-separator@npm:^7.24.7, @babel/plugin-transform-numeric-separator@npm:^7.27.1": +"@babel/plugin-transform-numeric-separator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-numeric-separator@npm:7.27.1" dependencies: @@ -1258,7 +1367,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-object-rest-spread@npm:^7.24.7, @babel/plugin-transform-object-rest-spread@npm:^7.28.4": +"@babel/plugin-transform-object-rest-spread@npm:^7.28.4": version: 7.28.4 resolution: "@babel/plugin-transform-object-rest-spread@npm:7.28.4" dependencies: @@ -1296,18 +1405,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-optional-chaining@npm:7.27.1": - version: 7.27.1 - resolution: "@babel/plugin-transform-optional-chaining@npm:7.27.1" - dependencies: - "@babel/helper-plugin-utils": "npm:^7.27.1" - "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 10c0/5b18ff5124e503f0a25d6b195be7351a028b3992d6f2a91fb4037e2a2c386400d66bc1df8f6df0a94c708524f318729e81a95c41906e5a7919a06a43e573a525 - languageName: node - linkType: hard - "@babel/plugin-transform-optional-chaining@npm:^7.24.8, @babel/plugin-transform-optional-chaining@npm:^7.27.1, @babel/plugin-transform-optional-chaining@npm:^7.28.5": version: 7.28.5 resolution: "@babel/plugin-transform-optional-chaining@npm:7.28.5" @@ -1320,7 +1417,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-parameters@npm:^7.24.7, @babel/plugin-transform-parameters@npm:^7.27.7": +"@babel/plugin-transform-parameters@npm:^7.27.7": version: 7.27.7 resolution: "@babel/plugin-transform-parameters@npm:7.27.7" dependencies: @@ -1465,7 +1562,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-shorthand-properties@npm:7.27.1, @babel/plugin-transform-shorthand-properties@npm:^7.24.7, @babel/plugin-transform-shorthand-properties@npm:^7.27.1": +"@babel/plugin-transform-shorthand-properties@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-shorthand-properties@npm:7.27.1" dependencies: @@ -1476,7 +1573,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-spread@npm:^7.24.7, @babel/plugin-transform-spread@npm:^7.27.1": +"@babel/plugin-transform-spread@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-spread@npm:7.27.1" dependencies: @@ -1488,7 +1585,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-sticky-regex@npm:^7.24.7, @babel/plugin-transform-sticky-regex@npm:^7.27.1": +"@babel/plugin-transform-sticky-regex@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-sticky-regex@npm:7.27.1" dependencies: @@ -1499,7 +1596,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-template-literals@npm:7.27.1, @babel/plugin-transform-template-literals@npm:^7.27.1": +"@babel/plugin-transform-template-literals@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-template-literals@npm:7.27.1" dependencies: @@ -1521,7 +1618,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-typescript@npm:^7.25.2, @babel/plugin-transform-typescript@npm:^7.27.1": +"@babel/plugin-transform-typescript@npm:^7.25.2": version: 7.28.5 resolution: "@babel/plugin-transform-typescript@npm:7.28.5" dependencies: @@ -1536,6 +1633,21 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-typescript@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/plugin-transform-typescript@npm:7.29.7" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.29.7" + "@babel/helper-create-class-features-plugin": "npm:^7.29.7" + "@babel/helper-plugin-utils": "npm:^7.29.7" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.29.7" + "@babel/plugin-syntax-typescript": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/8bf6a89c6827af6f11d4b189f1f97a64b8d754cc4caa5cbae16a6a8b113294d7f310dd40efd82e87ebcff2a1c683584b872d6d8960abe88d48f441d42f94c4d1 + languageName: node + linkType: hard + "@babel/plugin-transform-unicode-escapes@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-unicode-escapes@npm:7.27.1" @@ -1559,7 +1671,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-unicode-regex@npm:7.27.1, @babel/plugin-transform-unicode-regex@npm:^7.24.7, @babel/plugin-transform-unicode-regex@npm:^7.27.1": +"@babel/plugin-transform-unicode-regex@npm:^7.24.7, @babel/plugin-transform-unicode-regex@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-unicode-regex@npm:7.27.1" dependencies: @@ -1676,18 +1788,18 @@ __metadata: languageName: node linkType: hard -"@babel/preset-typescript@npm:7.27.1": - version: 7.27.1 - resolution: "@babel/preset-typescript@npm:7.27.1" +"@babel/preset-typescript@npm:^7.27.1": + version: 7.29.7 + resolution: "@babel/preset-typescript@npm:7.29.7" dependencies: - "@babel/helper-plugin-utils": "npm:^7.27.1" - "@babel/helper-validator-option": "npm:^7.27.1" - "@babel/plugin-syntax-jsx": "npm:^7.27.1" - "@babel/plugin-transform-modules-commonjs": "npm:^7.27.1" - "@babel/plugin-transform-typescript": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.29.7" + "@babel/helper-validator-option": "npm:^7.29.7" + "@babel/plugin-syntax-jsx": "npm:^7.29.7" + "@babel/plugin-transform-modules-commonjs": "npm:^7.29.7" + "@babel/plugin-transform-typescript": "npm:^7.29.7" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 10c0/cba6ca793d915f8aff9fe2f13b0dfbf5fd3f2e9a17f17478ec9878e9af0d206dcfe93154b9fd353727f16c1dca7c7a3ceb4943f8d28b216235f106bc0fbbcaa3 + checksum: 10c0/40746a23a7ab46c0beb1c02d69883d9ffbe3043685cb3ae5363644391376b9261189fdad317191349e322c2c9bc550b031daa42470a1f8987362e4c56e492194 languageName: node linkType: hard @@ -1705,7 +1817,7 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.25.0, @babel/template@npm:^7.27.1, @babel/template@npm:^7.27.2, @babel/template@npm:^7.3.3": +"@babel/template@npm:^7.27.1, @babel/template@npm:^7.27.2, @babel/template@npm:^7.3.3": version: 7.27.2 resolution: "@babel/template@npm:7.27.2" dependencies: @@ -1716,7 +1828,7 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.29.7": +"@babel/template@npm:^7.28.6, @babel/template@npm:^7.29.7": version: 7.29.7 resolution: "@babel/template@npm:7.29.7" dependencies: @@ -1727,7 +1839,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3, @babel/traverse@npm:^7.25.3, @babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.28.0, @babel/traverse@npm:^7.28.3, @babel/traverse@npm:^7.28.4, @babel/traverse@npm:^7.28.5": +"@babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.28.0, @babel/traverse@npm:^7.28.3, @babel/traverse@npm:^7.28.4, @babel/traverse@npm:^7.28.5": version: 7.28.5 resolution: "@babel/traverse@npm:7.28.5" dependencies: @@ -1742,7 +1854,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.29.7": +"@babel/traverse@npm:^7.29.0, @babel/traverse@npm:^7.29.7": version: 7.29.7 resolution: "@babel/traverse@npm:7.29.7" dependencies: @@ -1757,7 +1869,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.25.2, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.28.5, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.28.5, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": version: 7.28.5 resolution: "@babel/types@npm:7.28.5" dependencies: @@ -1767,7 +1879,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.29.7": +"@babel/types@npm:^7.29.0, @babel/types@npm:^7.29.7": version: 7.29.7 resolution: "@babel/types@npm:7.29.7" dependencies: @@ -1803,12 +1915,12 @@ __metadata: languageName: node linkType: hard -"@dicebear/core@npm:^9.3.0": - version: 9.3.0 - resolution: "@dicebear/core@npm:9.3.0" +"@dicebear/core@npm:^9.4.2": + version: 9.4.2 + resolution: "@dicebear/core@npm:9.4.2" dependencies: - "@types/json-schema": "npm:^7.0.11" - checksum: 10c0/76c9d9efc5d0e973aca66c72c65a03f9c312d4dcfcde2ada20c889c06d9386d879dd36c1f1fbf00cc4381af904b856641449ffa2c615ecd8ee6e538de7ab6767 + "@types/json-schema": "npm:^7.0.15" + checksum: 10c0/ca5aa4fcdb91988601fdde56a476a439465c835ce8789b9666205f6e841e5cf0524e545a8fdce5e40be95b88920c4873e892d1e24e34a5d6a4f9dd6b1e43c4fc languageName: node linkType: hard @@ -2057,34 +2169,34 @@ __metadata: languageName: node linkType: hard -"@firebase/ai@npm:2.6.1": - version: 2.6.1 - resolution: "@firebase/ai@npm:2.6.1" +"@firebase/ai@npm:2.9.0": + version: 2.9.0 + resolution: "@firebase/ai@npm:2.9.0" dependencies: "@firebase/app-check-interop-types": "npm:0.3.3" - "@firebase/component": "npm:0.7.0" + "@firebase/component": "npm:0.7.1" "@firebase/logger": "npm:0.5.0" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app": 0.x "@firebase/app-types": 0.x - checksum: 10c0/c9e6d0a4acb9ddbb8d809566de8806b27677e02ee7e7455cc09235bc84639e21ad1499d43025007cebb3b2231fe78067c93a8b5b1a8f2dac905f43284a8944b5 + checksum: 10c0/ff5296c4aa822c70078bfd5b3d724cc088639b026dcc964291c214b06ee4fdd1696f3e4515d06a4664f189009abe89ed7aa9da9a7944950ea0a2ae952f0efad7 languageName: node linkType: hard -"@firebase/analytics-compat@npm:0.2.25": - version: 0.2.25 - resolution: "@firebase/analytics-compat@npm:0.2.25" +"@firebase/analytics-compat@npm:0.2.26": + version: 0.2.26 + resolution: "@firebase/analytics-compat@npm:0.2.26" dependencies: - "@firebase/analytics": "npm:0.10.19" + "@firebase/analytics": "npm:0.10.20" "@firebase/analytics-types": "npm:0.8.3" - "@firebase/component": "npm:0.7.0" - "@firebase/util": "npm:1.13.0" + "@firebase/component": "npm:0.7.1" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app-compat": 0.x - checksum: 10c0/5cc2719caee5371516fe3a4ce628926b75a1f8ec563e4b994a9f18762037725e48f3a4313218b13bd5418cea29e7fb1109d99557863de2ac4c731e0b8cf78024 + checksum: 10c0/d42b984f504ddc2166dc6b2efa6388fb413bc78ddc270eaaf81e7e517391b87b5a0db631f9d6176f04e305b02145323a25939fb4ebb12e22cb42cd73558f4781 languageName: node linkType: hard @@ -2095,34 +2207,34 @@ __metadata: languageName: node linkType: hard -"@firebase/analytics@npm:0.10.19": - version: 0.10.19 - resolution: "@firebase/analytics@npm:0.10.19" +"@firebase/analytics@npm:0.10.20": + version: 0.10.20 + resolution: "@firebase/analytics@npm:0.10.20" dependencies: - "@firebase/component": "npm:0.7.0" - "@firebase/installations": "npm:0.6.19" + "@firebase/component": "npm:0.7.1" + "@firebase/installations": "npm:0.6.20" "@firebase/logger": "npm:0.5.0" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app": 0.x - checksum: 10c0/9af9b74ad285df0b3fa04abf4653dfed436e698193f28b50bf309948b1288de21d91114fab94d7ae29a3c9950d6cbebd7355a5a752a2e936d9375fa71f26728f + checksum: 10c0/6b5d7b0c47ec7825f1ba114e7ba6adc7c4a0cf6eac64695d861272b8d69bda6e9d12a8018e9d889ced4c8e28ce799e96b4e49303ff13f005dd52d112a9f9c0f2 languageName: node linkType: hard -"@firebase/app-check-compat@npm:0.4.0": - version: 0.4.0 - resolution: "@firebase/app-check-compat@npm:0.4.0" +"@firebase/app-check-compat@npm:0.4.1": + version: 0.4.1 + resolution: "@firebase/app-check-compat@npm:0.4.1" dependencies: - "@firebase/app-check": "npm:0.11.0" + "@firebase/app-check": "npm:0.11.1" "@firebase/app-check-types": "npm:0.5.3" - "@firebase/component": "npm:0.7.0" + "@firebase/component": "npm:0.7.1" "@firebase/logger": "npm:0.5.0" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app-compat": 0.x - checksum: 10c0/3e171cf352faa647162a866b02b12408165a584a30899cccc1bf2c75c972332c7238d75317b71457269451acf5a30f8b1d87b441e0b32ae09dcb6f3dcec41a6f + checksum: 10c0/dd2bcd76d48dc90f3d09c2d87dab409042a5361a210a299337b28180d4c1d89c260071fd396d53a2034e7fdf5d2cd2a8af9b451de2a28999b8df41891c168794 languageName: node linkType: hard @@ -2140,30 +2252,30 @@ __metadata: languageName: node linkType: hard -"@firebase/app-check@npm:0.11.0": - version: 0.11.0 - resolution: "@firebase/app-check@npm:0.11.0" +"@firebase/app-check@npm:0.11.1": + version: 0.11.1 + resolution: "@firebase/app-check@npm:0.11.1" dependencies: - "@firebase/component": "npm:0.7.0" + "@firebase/component": "npm:0.7.1" "@firebase/logger": "npm:0.5.0" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app": 0.x - checksum: 10c0/3229c02c2496d8bca9893f4dcc67fd3e97d833ca84a86de38768f3e46cde183415201683ed7d73672c720f0047e960e5855ca9dfbc4aba358b40348fa1b72833 + checksum: 10c0/6e8ecccb387e5653fce963f69092a63b0bc6eb71bd0aa3f827d7afe235c248e1784873884736e43ff65199f3f3af5714b1e123d4b6b2b90e3e96da5db6d83f7e languageName: node linkType: hard -"@firebase/app-compat@npm:0.5.6": - version: 0.5.6 - resolution: "@firebase/app-compat@npm:0.5.6" +"@firebase/app-compat@npm:0.5.9": + version: 0.5.9 + resolution: "@firebase/app-compat@npm:0.5.9" dependencies: - "@firebase/app": "npm:0.14.6" - "@firebase/component": "npm:0.7.0" + "@firebase/app": "npm:0.14.9" + "@firebase/component": "npm:0.7.1" "@firebase/logger": "npm:0.5.0" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" - checksum: 10c0/cb21a6b61de63a48ed75bf2abd6863d19c46b44841cd5cc65eddf6a33b1986748d215c05bb080a6805cf1b70fe7295740b3dc64fbc355de57d49ead190a7372b + checksum: 10c0/69a015f010a3468caf8aee1e9ef9cefa233f57fd683443f231ec39e73096ef50f14834b6fcdffd1a4702aaafce5309e0ac26d1317f4cf8c5c290bbd5c914a05a languageName: node linkType: hard @@ -2174,31 +2286,31 @@ __metadata: languageName: node linkType: hard -"@firebase/app@npm:0.14.6": - version: 0.14.6 - resolution: "@firebase/app@npm:0.14.6" +"@firebase/app@npm:0.14.9": + version: 0.14.9 + resolution: "@firebase/app@npm:0.14.9" dependencies: - "@firebase/component": "npm:0.7.0" + "@firebase/component": "npm:0.7.1" "@firebase/logger": "npm:0.5.0" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" idb: "npm:7.1.1" tslib: "npm:^2.1.0" - checksum: 10c0/bc79488a20ec065929a7de8c39560c507b80e85bc892a784b1a3ba44e4f57c203b27755c6b2cb1699f13ac1f7fca7ecc7bad3de1673d4788c1f7063037ced9f9 + checksum: 10c0/302f257538bda95349141ec99ea40373dc0f84abbfcbd3a8becd5c32f491c047028fb78ebbd418d88e188f2d191c376d5f9adbdc8ce8a42ad27bbe7f52b606f2 languageName: node linkType: hard -"@firebase/auth-compat@npm:0.6.2": - version: 0.6.2 - resolution: "@firebase/auth-compat@npm:0.6.2" +"@firebase/auth-compat@npm:0.6.3": + version: 0.6.3 + resolution: "@firebase/auth-compat@npm:0.6.3" dependencies: - "@firebase/auth": "npm:1.12.0" + "@firebase/auth": "npm:1.12.1" "@firebase/auth-types": "npm:0.13.0" - "@firebase/component": "npm:0.7.0" - "@firebase/util": "npm:1.13.0" + "@firebase/component": "npm:0.7.1" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app-compat": 0.x - checksum: 10c0/8eb06d4d45ef072ca196ed64b102ff8e546285c0c011e6f4b3cf0a7ddb0f66623cfff1e3bec49e26e94d40714240788e9d4eee59de2c8f9756d49828e53ec036 + checksum: 10c0/9d7fd68ce36f1ad39817c1947892bcd0550b3c54c7e415410916348f681ef240dbcc57ce9c4dda0249ff37d27662f0e0d0fbdf7c7e43fd4465fbe1f8f0cd5981 languageName: node linkType: hard @@ -2219,13 +2331,13 @@ __metadata: languageName: node linkType: hard -"@firebase/auth@npm:1.12.0": - version: 1.12.0 - resolution: "@firebase/auth@npm:1.12.0" +"@firebase/auth@npm:1.12.1": + version: 1.12.1 + resolution: "@firebase/auth@npm:1.12.1" dependencies: - "@firebase/component": "npm:0.7.0" + "@firebase/component": "npm:0.7.1" "@firebase/logger": "npm:0.5.0" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app": 0.x @@ -2233,86 +2345,86 @@ __metadata: peerDependenciesMeta: "@react-native-async-storage/async-storage": optional: true - checksum: 10c0/b3d87027bdba7ebad8d8d8c3e23f483d1936ad13b5356ecd6940a18a531805fa9f5f46348faae446e2971171f29223427c9287f58632d39392fc34003ddd792b + checksum: 10c0/66ad73b5bcb6245f1225a3b1315f117273fae7d2185501e0459d3f2e6cdee9edcfa57c33bdbaaa5c541b94a524905815f93c2f698ae0fb5461334e55af49691d languageName: node linkType: hard -"@firebase/component@npm:0.7.0": - version: 0.7.0 - resolution: "@firebase/component@npm:0.7.0" +"@firebase/component@npm:0.7.1": + version: 0.7.1 + resolution: "@firebase/component@npm:0.7.1" dependencies: - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" - checksum: 10c0/10e78f51a0c6764dbfe3863eda05b8d6e8ec431430bec165891b0b9c0eca06faf7851c5ec6a6b669f3e0cfab5d997a6f0510b1920c0424e83162a53812220e1a + checksum: 10c0/11c1d23793cd4f47a2fde13f65a38b9aaf9a7b4aa3013992219ab86320360e51f790ddf5d4a5fcfd94d5d967bbff47fff44c3d141d1615dc27a8829dc4bcca6d languageName: node linkType: hard -"@firebase/data-connect@npm:0.3.12": - version: 0.3.12 - resolution: "@firebase/data-connect@npm:0.3.12" +"@firebase/data-connect@npm:0.4.0": + version: 0.4.0 + resolution: "@firebase/data-connect@npm:0.4.0" dependencies: "@firebase/auth-interop-types": "npm:0.2.4" - "@firebase/component": "npm:0.7.0" + "@firebase/component": "npm:0.7.1" "@firebase/logger": "npm:0.5.0" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app": 0.x - checksum: 10c0/f1134585d5e571286ed285d4385b1e6930b3efd385cbd28eacb170a8fcf6ff9427b5583d8e9343d4a06783a2c99e05411cb2a402394336b6a7ac9c98c6618269 + checksum: 10c0/1127770cdc1b773c3421486df09be5e08da052b3e6b6a006991ed316231ad6534759012c39d8d1366019cba7137b18e13158a47932c15eadfe9fd39e0ef6b538 languageName: node linkType: hard -"@firebase/database-compat@npm:2.1.0": - version: 2.1.0 - resolution: "@firebase/database-compat@npm:2.1.0" +"@firebase/database-compat@npm:2.1.1": + version: 2.1.1 + resolution: "@firebase/database-compat@npm:2.1.1" dependencies: - "@firebase/component": "npm:0.7.0" - "@firebase/database": "npm:1.1.0" - "@firebase/database-types": "npm:1.0.16" + "@firebase/component": "npm:0.7.1" + "@firebase/database": "npm:1.1.1" + "@firebase/database-types": "npm:1.0.17" "@firebase/logger": "npm:0.5.0" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" - checksum: 10c0/f9b29c27b08915ba3310efafb5dee4fb024a9f20c66560740d1a9a8569a72a2479163a353c6ae0559f5fcab165518348f749a7bb07a5c22e446bc93826f34b8a + checksum: 10c0/d2189ae030f8af47a2bc196754df13b0f857e5eb70e445ed631dc00028e58f238418ab1562dca1476b36e45fc943f80c7ef2acaba2373ceaeed74c598c05a570 languageName: node linkType: hard -"@firebase/database-types@npm:1.0.16": - version: 1.0.16 - resolution: "@firebase/database-types@npm:1.0.16" +"@firebase/database-types@npm:1.0.17": + version: 1.0.17 + resolution: "@firebase/database-types@npm:1.0.17" dependencies: "@firebase/app-types": "npm:0.9.3" - "@firebase/util": "npm:1.13.0" - checksum: 10c0/d67356cb4edfe01df33bb23a42c365746fa65eeb156ead03de1f5b1bb630266ec7dd46787a0f4ae3e86b23375b47ddcef255b508aae7c7a9343800dbcc0b5c50 + "@firebase/util": "npm:1.14.0" + checksum: 10c0/7091ecf96215d0908328f26bc79bcdc7dd662de20cc31d24bf84575fd98ccfb30b584a17ee1c6069e444a4965af1cb4bc8f9681de3f6f7d1af242fa276068501 languageName: node linkType: hard -"@firebase/database@npm:1.1.0": - version: 1.1.0 - resolution: "@firebase/database@npm:1.1.0" +"@firebase/database@npm:1.1.1": + version: 1.1.1 + resolution: "@firebase/database@npm:1.1.1" dependencies: "@firebase/app-check-interop-types": "npm:0.3.3" "@firebase/auth-interop-types": "npm:0.2.4" - "@firebase/component": "npm:0.7.0" + "@firebase/component": "npm:0.7.1" "@firebase/logger": "npm:0.5.0" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" faye-websocket: "npm:0.11.4" tslib: "npm:^2.1.0" - checksum: 10c0/1c7b1fb310b9f2ddab2dec652b2686b614b9adaae360a7e336eda905c18a6f38c89e17d90ff251f4189576108ef1ee7832b70e492dfcc0c8d580b7f606dc9b14 + checksum: 10c0/0ab7bd849173590cbc34f92eeb3fc4ce8849aac60b8ef64fd8347682e3506eacb470cf20512b377e0a94defc6f9cb172d88c30f31b5a3b27a29e6702c3db33f9 languageName: node linkType: hard -"@firebase/firestore-compat@npm:0.4.3": - version: 0.4.3 - resolution: "@firebase/firestore-compat@npm:0.4.3" +"@firebase/firestore-compat@npm:0.4.6": + version: 0.4.6 + resolution: "@firebase/firestore-compat@npm:0.4.6" dependencies: - "@firebase/component": "npm:0.7.0" - "@firebase/firestore": "npm:4.9.3" + "@firebase/component": "npm:0.7.1" + "@firebase/firestore": "npm:4.12.0" "@firebase/firestore-types": "npm:3.0.3" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app-compat": 0.x - checksum: 10c0/20216e86e1217fe42b29d5ffe030919d5a411088ccbcd59c61693a70e8282d400cc2ebf0f118a30c8d96693e398b89c619d5840a17692f95c1aa70e535034d83 + checksum: 10c0/705421d9ecef16c1e5554ef1dfcc63459c94cab7ebb1b0cfa7d4c7e033251861dc4da2c51f48f107fb8a3745a0d65d08053be3258d202e37de2ef03ef5889901 languageName: node linkType: hard @@ -2326,35 +2438,35 @@ __metadata: languageName: node linkType: hard -"@firebase/firestore@npm:4.9.3": - version: 4.9.3 - resolution: "@firebase/firestore@npm:4.9.3" +"@firebase/firestore@npm:4.12.0": + version: 4.12.0 + resolution: "@firebase/firestore@npm:4.12.0" dependencies: - "@firebase/component": "npm:0.7.0" + "@firebase/component": "npm:0.7.1" "@firebase/logger": "npm:0.5.0" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" "@firebase/webchannel-wrapper": "npm:1.0.5" "@grpc/grpc-js": "npm:~1.9.0" "@grpc/proto-loader": "npm:^0.7.8" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app": 0.x - checksum: 10c0/f5502fa6f8bdc3d8033ddc4157c2f29c00eae35ee1912c54bf66dc236a71a223ae349c7132878ff9e6c58f0488d02f58ec151bcf5750071efb010a456fac8c11 + checksum: 10c0/884bbea381d7f75c6d88fc4e260557ec5d643b5d847d98440efd51e60b4be95b2b44d5100d5af3c059e21f7dfd6a20923468e8a403413288339350a2e982801f languageName: node linkType: hard -"@firebase/functions-compat@npm:0.4.1": - version: 0.4.1 - resolution: "@firebase/functions-compat@npm:0.4.1" +"@firebase/functions-compat@npm:0.4.2": + version: 0.4.2 + resolution: "@firebase/functions-compat@npm:0.4.2" dependencies: - "@firebase/component": "npm:0.7.0" - "@firebase/functions": "npm:0.13.1" + "@firebase/component": "npm:0.7.1" + "@firebase/functions": "npm:0.13.2" "@firebase/functions-types": "npm:0.6.3" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app-compat": 0.x - checksum: 10c0/3ad638e7e29e5a795ee4009787c442f8e319782780499de4e31889d931db8e7822559e0fb46b899f0306bcb740ef687c2144609c6b3ca62760d24697f7cf330b + checksum: 10c0/b705fa0729f1ebc2bbdb137388a68f1633fee21d9392eb85393d30ec2a069539adb332f1ade25cbf0284258bb4e832e8b964801af180c75187536ada05de8191 languageName: node linkType: hard @@ -2365,34 +2477,34 @@ __metadata: languageName: node linkType: hard -"@firebase/functions@npm:0.13.1": - version: 0.13.1 - resolution: "@firebase/functions@npm:0.13.1" +"@firebase/functions@npm:0.13.2": + version: 0.13.2 + resolution: "@firebase/functions@npm:0.13.2" dependencies: "@firebase/app-check-interop-types": "npm:0.3.3" "@firebase/auth-interop-types": "npm:0.2.4" - "@firebase/component": "npm:0.7.0" + "@firebase/component": "npm:0.7.1" "@firebase/messaging-interop-types": "npm:0.2.3" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app": 0.x - checksum: 10c0/cf2436708142c1b6aee5808dd76cbc7ed66b1448e806f3c1b8793f24b9bfc6963039eaf1fe84c3d1e0d121cee95d23e646dee4f92fe1d94f9ee73973b12c36dc + checksum: 10c0/86214a08a5b67e2763f79af3220376c93f90609b235c2b4dacf7ac53336f39980b095568702ef9b9395e75895ced2f90183204026ed312148b6c7e3de6e37329 languageName: node linkType: hard -"@firebase/installations-compat@npm:0.2.19": - version: 0.2.19 - resolution: "@firebase/installations-compat@npm:0.2.19" +"@firebase/installations-compat@npm:0.2.20": + version: 0.2.20 + resolution: "@firebase/installations-compat@npm:0.2.20" dependencies: - "@firebase/component": "npm:0.7.0" - "@firebase/installations": "npm:0.6.19" + "@firebase/component": "npm:0.7.1" + "@firebase/installations": "npm:0.6.20" "@firebase/installations-types": "npm:0.5.3" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app-compat": 0.x - checksum: 10c0/666dee235b73defe2a0c34a00be1e8f91612fc33c9ba5b3c1a21a076afc891d274b94cd094da37bfb1809a3971df2dead88345aaf78504bf788326847b8f4d3b + checksum: 10c0/ad17808fbe43fc9848dea97701e8997c7b604b7bad7e9536204d0ab5192d5a5fdfd7f9fda6aae4ba919a8043d6528e3a2f39bac598326c9f5527190f8dc22a0d languageName: node linkType: hard @@ -2405,17 +2517,17 @@ __metadata: languageName: node linkType: hard -"@firebase/installations@npm:0.6.19": - version: 0.6.19 - resolution: "@firebase/installations@npm:0.6.19" +"@firebase/installations@npm:0.6.20": + version: 0.6.20 + resolution: "@firebase/installations@npm:0.6.20" dependencies: - "@firebase/component": "npm:0.7.0" - "@firebase/util": "npm:1.13.0" + "@firebase/component": "npm:0.7.1" + "@firebase/util": "npm:1.14.0" idb: "npm:7.1.1" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app": 0.x - checksum: 10c0/c0fe4cf11f4ae9e3d6dcb59db1e559ed691b57d9f61c5ddd3ca36d4f4ce8d7d7fc6c97437f83cc0b612a0a19050dbde9e53085044318cd889ee1ef0fa09410b1 + checksum: 10c0/36be74ba311dadef726002af2eee557f1bb3fca12d8c6c3f8b07fb57ca294b87f3fa75765fb698195b4cc3abc70e6810ce523195d10c5a01ce52e4c855fe93c1 languageName: node linkType: hard @@ -2428,17 +2540,17 @@ __metadata: languageName: node linkType: hard -"@firebase/messaging-compat@npm:0.2.23": - version: 0.2.23 - resolution: "@firebase/messaging-compat@npm:0.2.23" +"@firebase/messaging-compat@npm:0.2.24": + version: 0.2.24 + resolution: "@firebase/messaging-compat@npm:0.2.24" dependencies: - "@firebase/component": "npm:0.7.0" - "@firebase/messaging": "npm:0.12.23" - "@firebase/util": "npm:1.13.0" + "@firebase/component": "npm:0.7.1" + "@firebase/messaging": "npm:0.12.24" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app-compat": 0.x - checksum: 10c0/f52c46cea3c14faca185a8605ca03bd741e70bba1c1277f849170756549e0abca00cf0c1ae22c4ce3ec83b72d6a9438cee8ef5cfef57156b76be55308844d602 + checksum: 10c0/9148a0710e275d6950bd07228b458f1a8226ed46b42ec73535157c515efb8d30f1bdd0369f3d0953e08c05f6348c1f4ff3e8b581c85958c6828be5f2a8df779e languageName: node linkType: hard @@ -2449,35 +2561,35 @@ __metadata: languageName: node linkType: hard -"@firebase/messaging@npm:0.12.23": - version: 0.12.23 - resolution: "@firebase/messaging@npm:0.12.23" +"@firebase/messaging@npm:0.12.24": + version: 0.12.24 + resolution: "@firebase/messaging@npm:0.12.24" dependencies: - "@firebase/component": "npm:0.7.0" - "@firebase/installations": "npm:0.6.19" + "@firebase/component": "npm:0.7.1" + "@firebase/installations": "npm:0.6.20" "@firebase/messaging-interop-types": "npm:0.2.3" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" idb: "npm:7.1.1" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app": 0.x - checksum: 10c0/6c0ca7bc41149261420ac4385921d421656be8a388be5caa0bfb28ba16093aa8e7df30707ab0e5ddeadc2778e81beb2e945d72a2908248b2a1ae7c2bd6711592 + checksum: 10c0/e993f42ca65a57d26ffc3c26df68704bd98bc7e07781d1ae4ab3af3af0b8165724df5ba9813f5f001a8aafa1088166732114436b08007643650015af0e78bd56 languageName: node linkType: hard -"@firebase/performance-compat@npm:0.2.22": - version: 0.2.22 - resolution: "@firebase/performance-compat@npm:0.2.22" +"@firebase/performance-compat@npm:0.2.23": + version: 0.2.23 + resolution: "@firebase/performance-compat@npm:0.2.23" dependencies: - "@firebase/component": "npm:0.7.0" + "@firebase/component": "npm:0.7.1" "@firebase/logger": "npm:0.5.0" - "@firebase/performance": "npm:0.7.9" + "@firebase/performance": "npm:0.7.10" "@firebase/performance-types": "npm:0.2.3" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app-compat": 0.x - checksum: 10c0/259f73da8cd8a70a0ccc77230ebdedbe98e62d5a01d888d3b155997a70bcd218a4fb373b6a81773cf599b17ec1e8edfcc9e6fef0f9778d4744d15d58207453c1 + checksum: 10c0/7d1d01555ecf59d38e2615e1d55afd98f1c5d46136f0c49be60c224a5c6f88d8a3459d24bce76bb2a052ae30dea481e71b3b5a2c70e2c03860d1fbfa2b3aaf57 languageName: node linkType: hard @@ -2488,35 +2600,35 @@ __metadata: languageName: node linkType: hard -"@firebase/performance@npm:0.7.9": - version: 0.7.9 - resolution: "@firebase/performance@npm:0.7.9" +"@firebase/performance@npm:0.7.10": + version: 0.7.10 + resolution: "@firebase/performance@npm:0.7.10" dependencies: - "@firebase/component": "npm:0.7.0" - "@firebase/installations": "npm:0.6.19" + "@firebase/component": "npm:0.7.1" + "@firebase/installations": "npm:0.6.20" "@firebase/logger": "npm:0.5.0" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" web-vitals: "npm:^4.2.4" peerDependencies: "@firebase/app": 0.x - checksum: 10c0/921905e23657a7537569f85291290bce3e95ddbc067618f83fa98050b014da2fd8af7b63ab10f6f35ffd53ede8262ce9224bcfe7e06d071060977b8a5cb52b5b + checksum: 10c0/bafde698b129d21fa6f13aa8ac0318efe2a0827936449f91f11af41b1a77cd9ff3a16e061843c7a7ffd202aaf323f1350208ad10418f4d47aca6ee46da543a39 languageName: node linkType: hard -"@firebase/remote-config-compat@npm:0.2.20": - version: 0.2.20 - resolution: "@firebase/remote-config-compat@npm:0.2.20" +"@firebase/remote-config-compat@npm:0.2.22": + version: 0.2.22 + resolution: "@firebase/remote-config-compat@npm:0.2.22" dependencies: - "@firebase/component": "npm:0.7.0" + "@firebase/component": "npm:0.7.1" "@firebase/logger": "npm:0.5.0" - "@firebase/remote-config": "npm:0.7.0" + "@firebase/remote-config": "npm:0.8.1" "@firebase/remote-config-types": "npm:0.5.0" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app-compat": 0.x - checksum: 10c0/1fbd20e9274df8e6ecc2498fa1562c506ffb29e920402f8cccbfa10535664d56fa8f4d4acc13a01b09ed3cc94c77cad38d14c6c2f4b223ac8e7ad98d56215164 + checksum: 10c0/d0f515de4cb3cffaa4a05d1912423681a37f87ea9e8b9acd0d6b165a3f9fa42c6783395a3498f40ac8376a64d4ec9d5c05cafe542a03bce6a8c4295264959e38 languageName: node linkType: hard @@ -2527,33 +2639,33 @@ __metadata: languageName: node linkType: hard -"@firebase/remote-config@npm:0.7.0": - version: 0.7.0 - resolution: "@firebase/remote-config@npm:0.7.0" +"@firebase/remote-config@npm:0.8.1": + version: 0.8.1 + resolution: "@firebase/remote-config@npm:0.8.1" dependencies: - "@firebase/component": "npm:0.7.0" - "@firebase/installations": "npm:0.6.19" + "@firebase/component": "npm:0.7.1" + "@firebase/installations": "npm:0.6.20" "@firebase/logger": "npm:0.5.0" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app": 0.x - checksum: 10c0/840904660b671969d9bb72cea0af77aaef46491711d76a0dea2a637c512c3f7b65dfc1fa4635c202f14de9da47108cccc94e8fcf7a1a25e380a8e2e448a0c70d + checksum: 10c0/3bef37daacb5798b253ea199185efb2a1362a3bfb3346208e456a372d85ca9a5d637d30ed51f4b3081b6dd96c9e92d20042a0285c6629f19d0dc1c0c9c8272e4 languageName: node linkType: hard -"@firebase/storage-compat@npm:0.4.0": - version: 0.4.0 - resolution: "@firebase/storage-compat@npm:0.4.0" +"@firebase/storage-compat@npm:0.4.1": + version: 0.4.1 + resolution: "@firebase/storage-compat@npm:0.4.1" dependencies: - "@firebase/component": "npm:0.7.0" - "@firebase/storage": "npm:0.14.0" + "@firebase/component": "npm:0.7.1" + "@firebase/storage": "npm:0.14.1" "@firebase/storage-types": "npm:0.8.3" - "@firebase/util": "npm:1.13.0" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app-compat": 0.x - checksum: 10c0/16e868afdfd67c89919e69a4d2916899f6807e03a33b5bf03a563942ee35a7858929df846d6be8d3d712ea4482683a31dbf9c48979352d3ef87962f7e1dc3705 + checksum: 10c0/538ab3f9c0bf71349fb46206fd786bbae3464e33d2c73a171650496eb32b0b45649a010d31ba0c6874a7482c7e498909e911bee106c8d8284ca9fddd15f15f19 languageName: node linkType: hard @@ -2567,25 +2679,25 @@ __metadata: languageName: node linkType: hard -"@firebase/storage@npm:0.14.0": - version: 0.14.0 - resolution: "@firebase/storage@npm:0.14.0" +"@firebase/storage@npm:0.14.1": + version: 0.14.1 + resolution: "@firebase/storage@npm:0.14.1" dependencies: - "@firebase/component": "npm:0.7.0" - "@firebase/util": "npm:1.13.0" + "@firebase/component": "npm:0.7.1" + "@firebase/util": "npm:1.14.0" tslib: "npm:^2.1.0" peerDependencies: "@firebase/app": 0.x - checksum: 10c0/7a210db11c698dfeff57bdf8c883d0d595a8ddef25eadd144d7501747d1f0e429c073beb9d1e871e5bad8e6dc1eda10f3fb2288290349e6058b5bad7e042e7f1 + checksum: 10c0/87fe89253ffb4380593675c17be6f5e9731fe2c7a140519e0b128f6b51839265ec09943d892c3735ed7c26f40684e0781d0b22070aebab300c52619ca8db1231 languageName: node linkType: hard -"@firebase/util@npm:1.13.0": - version: 1.13.0 - resolution: "@firebase/util@npm:1.13.0" +"@firebase/util@npm:1.14.0": + version: 1.14.0 + resolution: "@firebase/util@npm:1.14.0" dependencies: tslib: "npm:^2.1.0" - checksum: 10c0/2e0c19dffdf69a1d1f8d786de551268d6af804de857eb195f4af50b732fe9e696cb73c52abc5f0bc98b34527225fb97a81ec380e89bd47a1d8448fc66536845c + checksum: 10c0/58eabfc145d6a6924fdafb801ef883cf84b364c05b9822648bdff6a34f18338ef075c21724df9d15dce37000ad493367e6a59aaf59a9ce1efc01427fb1584997 languageName: node linkType: hard @@ -3447,27 +3559,27 @@ __metadata: languageName: node linkType: hard -"@react-native-community/cli-clean@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-clean@npm:20.0.0" +"@react-native-community/cli-clean@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-clean@npm:20.1.0" dependencies: - "@react-native-community/cli-tools": "npm:20.0.0" - chalk: "npm:^4.1.2" + "@react-native-community/cli-tools": "npm:20.1.0" execa: "npm:^5.0.0" fast-glob: "npm:^3.3.2" - checksum: 10c0/cd65907bf2bff82abe8a6616802cf1f756340983e9154a93e771710059ccbf863e45046d2568a6bcb85ef1b4e51b883866ce6371950ec27309a6d1e3fc10cbf4 + picocolors: "npm:^1.1.1" + checksum: 10c0/5d7fce73545154035e55801e9596b634c85bbe7bb04861f3d0787f2a9588b7b6f927709bfce4e45a8d62da03e5a92789281e07dafd29e2db86ca52ca3e5ad49c languageName: node linkType: hard -"@react-native-community/cli-config-android@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-config-android@npm:20.0.0" +"@react-native-community/cli-config-android@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-config-android@npm:20.1.0" dependencies: - "@react-native-community/cli-tools": "npm:20.0.0" - chalk: "npm:^4.1.2" + "@react-native-community/cli-tools": "npm:20.1.0" fast-glob: "npm:^3.3.2" fast-xml-parser: "npm:^4.4.1" - checksum: 10c0/79298ecde495e0587585e8d67431e9543ac83392a06e5c8fb736853d199f0aae014858b1d3db81ce3decf58c2172c95c78eeb27e0f2be2b8a5ad43b96331d0ce + picocolors: "npm:^1.1.1" + checksum: 10c0/66e95adf2fb9750a12592a146b034ab4b8ea15aa41efb5d497d6be2f08029a59a0be2450e97de0bf59aa6b66778b3af0bbd693a42b7e7f9f60c9d9b5f966aadc languageName: node linkType: hard @@ -3483,15 +3595,15 @@ __metadata: languageName: node linkType: hard -"@react-native-community/cli-config-apple@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-config-apple@npm:20.0.0" +"@react-native-community/cli-config-apple@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-config-apple@npm:20.1.0" dependencies: - "@react-native-community/cli-tools": "npm:20.0.0" - chalk: "npm:^4.1.2" + "@react-native-community/cli-tools": "npm:20.1.0" execa: "npm:^5.0.0" fast-glob: "npm:^3.3.2" - checksum: 10c0/1b11e1dde776ccc3244eb3029eb49239120a89a12ed84bd4957e4e7b81bba4b332ed04a2fb081fd9a9711be65d1a85cf429247fa2daa4010ba4b42b5bf273c2f + picocolors: "npm:^1.1.1" + checksum: 10c0/2c7b7116594c7b0035ef7e41e0219fcff664c3883471460ae48f19dd88ec9a26dd5b4bd60e33c054603b3a10efd78570490bc84599ad987e4ffb274b05512351 languageName: node linkType: hard @@ -3507,83 +3619,83 @@ __metadata: languageName: node linkType: hard -"@react-native-community/cli-config@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-config@npm:20.0.0" +"@react-native-community/cli-config@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-config@npm:20.1.0" dependencies: - "@react-native-community/cli-tools": "npm:20.0.0" - chalk: "npm:^4.1.2" + "@react-native-community/cli-tools": "npm:20.1.0" cosmiconfig: "npm:^9.0.0" deepmerge: "npm:^4.3.0" fast-glob: "npm:^3.3.2" joi: "npm:^17.2.1" - checksum: 10c0/766364c0c1d0f551a98b86317b74e7942521a05111f6c7e2898341c0413c6a55ae91d184bd549109edd61f02065662ada142788dba1090db200cbec00fdfeede + picocolors: "npm:^1.1.1" + checksum: 10c0/e3d863ffc5d18aa7b7406908c1360de7ea7a1bab32897e34d0afe184f4682bb5d110d4db0c6ba2c35c4f1330ca4a281b8fc3548e53a2978b8b07ca3beca5765c languageName: node linkType: hard -"@react-native-community/cli-doctor@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-doctor@npm:20.0.0" +"@react-native-community/cli-doctor@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-doctor@npm:20.1.0" dependencies: - "@react-native-community/cli-config": "npm:20.0.0" - "@react-native-community/cli-platform-android": "npm:20.0.0" - "@react-native-community/cli-platform-apple": "npm:20.0.0" - "@react-native-community/cli-platform-ios": "npm:20.0.0" - "@react-native-community/cli-tools": "npm:20.0.0" - chalk: "npm:^4.1.2" + "@react-native-community/cli-config": "npm:20.1.0" + "@react-native-community/cli-platform-android": "npm:20.1.0" + "@react-native-community/cli-platform-apple": "npm:20.1.0" + "@react-native-community/cli-platform-ios": "npm:20.1.0" + "@react-native-community/cli-tools": "npm:20.1.0" command-exists: "npm:^1.2.8" deepmerge: "npm:^4.3.0" envinfo: "npm:^7.13.0" execa: "npm:^5.0.0" node-stream-zip: "npm:^1.9.1" ora: "npm:^5.4.1" + picocolors: "npm:^1.1.1" semver: "npm:^7.5.2" wcwidth: "npm:^1.0.1" yaml: "npm:^2.2.1" - checksum: 10c0/843a7e8e5969154ed171616c3c556389d7debc30035bb6a9d6392876d22ef84d390d02673032bb8c8ac164380a97fe9f62971476aacb06ba3a3b849358e4cb99 + checksum: 10c0/79762f3e789fe98f21c6f500f6c65df399508979f05174272652a9422295f4dace099e87575776bf209b533a6667070fc355c5b510e14a8a61b31a9a8af7b3be languageName: node linkType: hard -"@react-native-community/cli-platform-android@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-platform-android@npm:20.0.0" +"@react-native-community/cli-platform-android@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-platform-android@npm:20.1.0" dependencies: - "@react-native-community/cli-config-android": "npm:20.0.0" - "@react-native-community/cli-tools": "npm:20.0.0" - chalk: "npm:^4.1.2" + "@react-native-community/cli-config-android": "npm:20.1.0" + "@react-native-community/cli-tools": "npm:20.1.0" execa: "npm:^5.0.0" logkitty: "npm:^0.7.1" - checksum: 10c0/9c17cbc0661698dd8154286ce893205b91a9f71cb8af8505641fb82ab99217116300fe0dfb8b5e6e9270cf3917c0fb227d45f90322ad7e624d9c65aacf086012 + picocolors: "npm:^1.1.1" + checksum: 10c0/8b44178a78245085824c3fda9d6753d03cd817772fdde82b1d4f1a89f177f10339822401c0b8ef17e8353f3168c3971ae4cfb0a158cef03c22e55f5dff66179b languageName: node linkType: hard -"@react-native-community/cli-platform-apple@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-platform-apple@npm:20.0.0" +"@react-native-community/cli-platform-apple@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-platform-apple@npm:20.1.0" dependencies: - "@react-native-community/cli-config-apple": "npm:20.0.0" - "@react-native-community/cli-tools": "npm:20.0.0" - chalk: "npm:^4.1.2" + "@react-native-community/cli-config-apple": "npm:20.1.0" + "@react-native-community/cli-tools": "npm:20.1.0" execa: "npm:^5.0.0" fast-xml-parser: "npm:^4.4.1" - checksum: 10c0/a6b2296d6291853f59d3c68302676fea54d68fa6626c14727b7db63280761714785fd70a75d7ae036644a7ea5ebd8211235c64d4dec5297565d734a1c5a3b6c9 + picocolors: "npm:^1.1.1" + checksum: 10c0/2218e172bf13c0bb027f7f2a036a0515f8fe023d98fc65d22d0dab601036c5b461b1af7a5d826df2dd3e86a3894f9531d43e8861746a071ee22c0b33b8e47c29 languageName: node linkType: hard -"@react-native-community/cli-platform-ios@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-platform-ios@npm:20.0.0" +"@react-native-community/cli-platform-ios@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-platform-ios@npm:20.1.0" dependencies: - "@react-native-community/cli-platform-apple": "npm:20.0.0" - checksum: 10c0/6eb77946cb3392cc548007723b790796360651e62422095da2bbc8a20b7c8e79d9fc32c0155ba669a10c556e6e7327964d59e5755c64f6099708701e4acf8fd3 + "@react-native-community/cli-platform-apple": "npm:20.1.0" + checksum: 10c0/f5eef9dfbe3dad7dc69f4b3a37ebee9d124f3a649071e0275624f88468a7f506b622646dcbd61ba0435cc35e705badfc287690d6b7c3867c0a86c9a45d4f463e languageName: node linkType: hard -"@react-native-community/cli-server-api@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-server-api@npm:20.0.0" +"@react-native-community/cli-server-api@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-server-api@npm:20.1.0" dependencies: - "@react-native-community/cli-tools": "npm:20.0.0" + "@react-native-community/cli-tools": "npm:20.1.0" body-parser: "npm:^1.20.3" compression: "npm:^1.7.1" connect: "npm:^3.6.5" @@ -3593,7 +3705,7 @@ __metadata: pretty-format: "npm:^29.7.0" serve-static: "npm:^1.13.1" ws: "npm:^6.2.3" - checksum: 10c0/105099a3b667978880144eb4e1ca1725c57f1fe6bb6f8d09b189f021ecc1ad70f8e865667ef1d921fb85f1bea8d1da766d713672dfde80d6d2cdde47e800d5a8 + checksum: 10c0/d83c9bbff36fb84201478ed8efc17c80f1474cb0346a2577eee7299407e9e34892c213e2316062a2c59d47ebfe9f0c8215b82cd1abb05c85fe7702a94a52cdf5 languageName: node linkType: hard @@ -3615,55 +3727,55 @@ __metadata: languageName: node linkType: hard -"@react-native-community/cli-tools@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-tools@npm:20.0.0" +"@react-native-community/cli-tools@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-tools@npm:20.1.0" dependencies: "@vscode/sudo-prompt": "npm:^9.0.0" appdirsjs: "npm:^1.2.4" - chalk: "npm:^4.1.2" execa: "npm:^5.0.0" find-up: "npm:^5.0.0" launch-editor: "npm:^2.9.1" mime: "npm:^2.4.1" ora: "npm:^5.4.1" + picocolors: "npm:^1.1.1" prompts: "npm:^2.4.2" semver: "npm:^7.5.2" - checksum: 10c0/3a379558f2673de68d872d740754e242d9dd84dd0a837f94910936faad632f35fc9b61dd9d256e635391815da7a4cbc42c3ca918371d60fb4d5a3b4acea6bffd + checksum: 10c0/993f5dfbc1ae6301e616269896b2e5ecc29888cc8a12325881148b546b07d45572bd065e392ceaad32f86067e31b0eabedbe71fac3b1b820cd489ab86e56094d languageName: node linkType: hard -"@react-native-community/cli-types@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli-types@npm:20.0.0" +"@react-native-community/cli-types@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli-types@npm:20.1.0" dependencies: joi: "npm:^17.2.1" - checksum: 10c0/328f623579b3b8e797d833aeb76fad86a75f9da84b45da1d9ffe4c6429a57cd3440d401d3448d15c2b44b69137459033522e3dff87767f887772d8f6055dccc9 + checksum: 10c0/247deebf26b435c0cbabfb7dd7de09a4e79c544ee72a2ef2817268108f7c085dab4d54c7fbc8111ad89360e13227f2041c5eac208971c251da332e4d33311a7b languageName: node linkType: hard -"@react-native-community/cli@npm:20.0.0": - version: 20.0.0 - resolution: "@react-native-community/cli@npm:20.0.0" +"@react-native-community/cli@npm:20.1.0": + version: 20.1.0 + resolution: "@react-native-community/cli@npm:20.1.0" dependencies: - "@react-native-community/cli-clean": "npm:20.0.0" - "@react-native-community/cli-config": "npm:20.0.0" - "@react-native-community/cli-doctor": "npm:20.0.0" - "@react-native-community/cli-server-api": "npm:20.0.0" - "@react-native-community/cli-tools": "npm:20.0.0" - "@react-native-community/cli-types": "npm:20.0.0" - chalk: "npm:^4.1.2" + "@react-native-community/cli-clean": "npm:20.1.0" + "@react-native-community/cli-config": "npm:20.1.0" + "@react-native-community/cli-doctor": "npm:20.1.0" + "@react-native-community/cli-server-api": "npm:20.1.0" + "@react-native-community/cli-tools": "npm:20.1.0" + "@react-native-community/cli-types": "npm:20.1.0" commander: "npm:^9.4.1" deepmerge: "npm:^4.3.0" execa: "npm:^5.0.0" find-up: "npm:^5.0.0" fs-extra: "npm:^8.1.0" graceful-fs: "npm:^4.1.3" + picocolors: "npm:^1.1.1" prompts: "npm:^2.4.2" semver: "npm:^7.5.2" bin: rnc-cli: build/bin.js - checksum: 10c0/ccdbc8ba1f678274772237941993e68143707240762194842fa756fc7d53bcee9114e0b7d3eefaa750ccba41189909fbd7ceaa3a99f5ae781ccf2e98c5ff10b6 + checksum: 10c0/f3fa43fc8c170ba291ae81e796f4ac35956e143bf1094f15f91061b93835ed0665749ca11da91df7fbfcdd96ee32fc16da6cab60adef1a21022195aa1947bd5d languageName: node linkType: hard @@ -3693,24 +3805,24 @@ __metadata: languageName: node linkType: hard -"@react-native-firebase/app-check@npm:^23.8.2": - version: 23.8.2 - resolution: "@react-native-firebase/app-check@npm:23.8.2" +"@react-native-firebase/app-check@npm:^24.0.0": + version: 24.0.0 + resolution: "@react-native-firebase/app-check@npm:24.0.0" peerDependencies: - "@react-native-firebase/app": 23.8.2 + "@react-native-firebase/app": 24.0.0 expo: ">=47.0.0" peerDependenciesMeta: expo: optional: true - checksum: 10c0/8dff04cff1c0b59a054f3350e18867bebf2914b264892810baaddc4e293099202fff0bf74862b201f419d273960488bfe7d39f4d6ba6023ac545191ac2284b70 + checksum: 10c0/58ad9d3fcc98975ff322731768da81c09ab1d4f293a9890f45e47ab4e2882920eb41c73c42a442816725acff963bf135f28dd27b8518cd48ff04398d978ee677 languageName: node linkType: hard -"@react-native-firebase/app@npm:^23.8.2": - version: 23.8.2 - resolution: "@react-native-firebase/app@npm:23.8.2" +"@react-native-firebase/app@npm:^24.0.0": + version: 24.0.0 + resolution: "@react-native-firebase/app@npm:24.0.0" dependencies: - firebase: "npm:12.7.0" + firebase: "npm:12.10.0" peerDependencies: expo: ">=47.0.0" react: "*" @@ -3718,20 +3830,20 @@ __metadata: peerDependenciesMeta: expo: optional: true - checksum: 10c0/b3ed9842184943eae8f9ff7935f09fe76c794466e750b26a91b662c022d2f9989c2dca51848c5501d4bdaadbab50246441d010dae9f7691c1a873668a97a2804 + checksum: 10c0/7019b99bda3f9b033bc6e619b8b37206a900ae64c662837971f31356a291b4e8eeb4f9e5a41dba70b33627425824d43620ec44a194daab01368b5932b3b9f7ae languageName: node linkType: hard -"@react-native-firebase/messaging@npm:^23.8.2": - version: 23.8.2 - resolution: "@react-native-firebase/messaging@npm:23.8.2" +"@react-native-firebase/messaging@npm:^24.0.0": + version: 24.0.0 + resolution: "@react-native-firebase/messaging@npm:24.0.0" peerDependencies: - "@react-native-firebase/app": 23.8.2 + "@react-native-firebase/app": 24.0.0 expo: ">=47.0.0" peerDependenciesMeta: expo: optional: true - checksum: 10c0/e413a484ac5dae303f1b7dbda17288286fc9b3a1245a9f06688f9642c928f3afa04eeb6b19e04a0ec80286b9539508f8d0c9a7779cdbd7308f7fcae224a45812 + checksum: 10c0/5be8b1e50d4f04ff6ead57503c506537c034e7e19c1e4515003eed535c5e8d54a976302fed459bffb62e6413640225bd2c28982c4083e9216c7bda7f768f0336 languageName: node linkType: hard @@ -3759,26 +3871,26 @@ __metadata: languageName: node linkType: hard -"@react-native/assets-registry@npm:0.83.1": - version: 0.83.1 - resolution: "@react-native/assets-registry@npm:0.83.1" - checksum: 10c0/284ec022bc91fdc8f2dc14d92cb52247ad42b076fb12997cd089d0ea594f628425fb631d3abcf91a97bbe4f28e84ce5bcecd44ea0db86a51f821602ef54dc73c +"@react-native/assets-registry@npm:0.85.3": + version: 0.85.3 + resolution: "@react-native/assets-registry@npm:0.85.3" + checksum: 10c0/c926848dae180940c19a68df42783900474a010944fc2f31f1b9a61ec722e6b4ead76943a560df5679d64d4784e7e945fd9f6d60f25555fdd1eb59c4326b8c29 languageName: node linkType: hard -"@react-native/babel-plugin-codegen@npm:0.83.1": - version: 0.83.1 - resolution: "@react-native/babel-plugin-codegen@npm:0.83.1" +"@react-native/babel-plugin-codegen@npm:0.85.3": + version: 0.85.3 + resolution: "@react-native/babel-plugin-codegen@npm:0.85.3" dependencies: - "@babel/traverse": "npm:^7.25.3" - "@react-native/codegen": "npm:0.83.1" - checksum: 10c0/fa08bf71cf4f4f70d8a0167ad8f91b47e270ab2879e745d63ce599406f9bb92b38100b9e0cea42dff8f8f17a5ea64826921f73f04535b4f09b77e53376cc043d + "@babel/traverse": "npm:^7.29.0" + "@react-native/codegen": "npm:0.85.3" + checksum: 10c0/59f61f5d783ac0a820a84ff45b7700b3c290de32e313e55171fe3bf0234d9836422bc239832d2650f893dc409a63772a50664f9487a8e6f86bc0c3bc88eb7ecd languageName: node linkType: hard -"@react-native/babel-preset@npm:0.83.1": - version: 0.83.1 - resolution: "@react-native/babel-preset@npm:0.83.1" +"@react-native/babel-preset@npm:0.85.3": + version: 0.85.3 + resolution: "@react-native/babel-preset@npm:0.85.3" dependencies: "@babel/core": "npm:^7.25.2" "@babel/plugin-proposal-export-default-from": "npm:^7.24.7" @@ -3786,27 +3898,19 @@ __metadata: "@babel/plugin-syntax-export-default-from": "npm:^7.24.7" "@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3" "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3" - "@babel/plugin-transform-arrow-functions": "npm:^7.24.7" "@babel/plugin-transform-async-generator-functions": "npm:^7.25.4" "@babel/plugin-transform-async-to-generator": "npm:^7.24.7" "@babel/plugin-transform-block-scoping": "npm:^7.25.0" "@babel/plugin-transform-class-properties": "npm:^7.25.4" "@babel/plugin-transform-classes": "npm:^7.25.4" - "@babel/plugin-transform-computed-properties": "npm:^7.24.7" "@babel/plugin-transform-destructuring": "npm:^7.24.8" "@babel/plugin-transform-flow-strip-types": "npm:^7.25.2" "@babel/plugin-transform-for-of": "npm:^7.24.7" - "@babel/plugin-transform-function-name": "npm:^7.25.1" - "@babel/plugin-transform-literals": "npm:^7.25.2" - "@babel/plugin-transform-logical-assignment-operators": "npm:^7.24.7" "@babel/plugin-transform-modules-commonjs": "npm:^7.24.8" "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.24.7" "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.24.7" - "@babel/plugin-transform-numeric-separator": "npm:^7.24.7" - "@babel/plugin-transform-object-rest-spread": "npm:^7.24.7" "@babel/plugin-transform-optional-catch-binding": "npm:^7.24.7" "@babel/plugin-transform-optional-chaining": "npm:^7.24.8" - "@babel/plugin-transform-parameters": "npm:^7.24.7" "@babel/plugin-transform-private-methods": "npm:^7.24.7" "@babel/plugin-transform-private-property-in-object": "npm:^7.24.7" "@babel/plugin-transform-react-display-name": "npm:^7.24.7" @@ -3815,88 +3919,85 @@ __metadata: "@babel/plugin-transform-react-jsx-source": "npm:^7.24.7" "@babel/plugin-transform-regenerator": "npm:^7.24.7" "@babel/plugin-transform-runtime": "npm:^7.24.7" - "@babel/plugin-transform-shorthand-properties": "npm:^7.24.7" - "@babel/plugin-transform-spread": "npm:^7.24.7" - "@babel/plugin-transform-sticky-regex": "npm:^7.24.7" "@babel/plugin-transform-typescript": "npm:^7.25.2" "@babel/plugin-transform-unicode-regex": "npm:^7.24.7" - "@babel/template": "npm:^7.25.0" - "@react-native/babel-plugin-codegen": "npm:0.83.1" - babel-plugin-syntax-hermes-parser: "npm:0.32.0" + "@react-native/babel-plugin-codegen": "npm:0.85.3" + babel-plugin-syntax-hermes-parser: "npm:0.33.3" babel-plugin-transform-flow-enums: "npm:^0.0.2" react-refresh: "npm:^0.14.0" peerDependencies: "@babel/core": "*" - checksum: 10c0/6662b4b427c7c95eae069e1395e92a2cd618926e22c515bb9f088ac1dde1c9c1ee707334658be68db4da5fd2e17a5d8735f9dbe455e5b454e73cca846e44050a + checksum: 10c0/88b1ea1d0fcebf5df9b2eb6e48eb2c8c18c92fda64d54c91b95a6974348d6f2c2cc72777ac479586fee27b24ce7caccd9d6460394a3adb2a8a0915d36d6da14b languageName: node linkType: hard -"@react-native/codegen@npm:0.83.1": - version: 0.83.1 - resolution: "@react-native/codegen@npm:0.83.1" +"@react-native/codegen@npm:0.85.3": + version: 0.85.3 + resolution: "@react-native/codegen@npm:0.85.3" dependencies: "@babel/core": "npm:^7.25.2" - "@babel/parser": "npm:^7.25.3" - glob: "npm:^7.1.1" - hermes-parser: "npm:0.32.0" + "@babel/parser": "npm:^7.29.0" + hermes-parser: "npm:0.33.3" invariant: "npm:^2.2.4" nullthrows: "npm:^1.1.1" + tinyglobby: "npm:^0.2.15" yargs: "npm:^17.6.2" peerDependencies: "@babel/core": "*" - checksum: 10c0/8c9846ff210adc38fdc87dee3a1eff62d6e29781e3aea678069e73b27c50710c5ee38083cc4168c631118f0f4c98bd5343825e270b44a189845b358e86e1395b + checksum: 10c0/3d6e08564c3436fcbd450c279b6755768ddfa47a534455c3077c222d5aa0a77270682afe933aa8d84bcd952b1a43107d25220d17c83f4f003fd338846a33ea4c languageName: node linkType: hard -"@react-native/community-cli-plugin@npm:0.83.1": - version: 0.83.1 - resolution: "@react-native/community-cli-plugin@npm:0.83.1" +"@react-native/community-cli-plugin@npm:0.85.3": + version: 0.85.3 + resolution: "@react-native/community-cli-plugin@npm:0.85.3" dependencies: - "@react-native/dev-middleware": "npm:0.83.1" + "@react-native/dev-middleware": "npm:0.85.3" debug: "npm:^4.4.0" invariant: "npm:^2.2.4" - metro: "npm:^0.83.3" - metro-config: "npm:^0.83.3" - metro-core: "npm:^0.83.3" + metro: "npm:^0.84.3" + metro-config: "npm:^0.84.3" + metro-core: "npm:^0.84.3" semver: "npm:^7.1.3" peerDependencies: "@react-native-community/cli": "*" - "@react-native/metro-config": "*" + "@react-native/metro-config": 0.85.3 peerDependenciesMeta: "@react-native-community/cli": optional: true "@react-native/metro-config": optional: true - checksum: 10c0/9c39e186769322ab74b1f777b488452b4f891fc6a3e716155bedf6dd30e3dbd5153c07f8d0cde20407885bc3d308572b595e3f2bf7e718653731089012cd91e8 + checksum: 10c0/23d09b4b7e7324efb563f96e7d6fe672bd6c6e2e2a81e60cb60ef017765e43790a1ed0b56d2960d73780730fe3f13b2a4c53cf88b93a2c44da61bbcd16af8e78 languageName: node linkType: hard -"@react-native/debugger-frontend@npm:0.83.1": - version: 0.83.1 - resolution: "@react-native/debugger-frontend@npm:0.83.1" - checksum: 10c0/83a2a7a56b7cbe47771dd84ff99478ba76a4fe50a24b5c356dbceeb20a589c35334d6d321dea7bf34a04185857112bdbbb93c5edbe3512c20ef1ba1ecb4cf8b6 +"@react-native/debugger-frontend@npm:0.85.3": + version: 0.85.3 + resolution: "@react-native/debugger-frontend@npm:0.85.3" + checksum: 10c0/4e52fc9f10051d0d1ae225ff5c1d0fbcf5e5cc2fdfa13f5985b8578352a3196bd0ad6c7714f62901496be7f231e593308964a469f26575680f558f48e6161a2e languageName: node linkType: hard -"@react-native/debugger-shell@npm:0.83.1": - version: 0.83.1 - resolution: "@react-native/debugger-shell@npm:0.83.1" +"@react-native/debugger-shell@npm:0.85.3": + version: 0.85.3 + resolution: "@react-native/debugger-shell@npm:0.85.3" dependencies: cross-spawn: "npm:^7.0.6" + debug: "npm:^4.4.0" fb-dotslash: "npm:0.5.8" - checksum: 10c0/a98b870f1741f476dade84cb770a090e30a82712caef7589b9a5ffc7b5fde18acb270950c57dc03301c2fe091bbe9edc5b2ebfe699d7e07ba8df4a7ccbf4863e + checksum: 10c0/2782929d1352c323cc33289fb2b08a8d05b4df5b59af7d588958729f59db966ffd6d73e2df86a66b240f005e23f796829b56978f4a0152a6837e67fd0fae1dd0 languageName: node linkType: hard -"@react-native/dev-middleware@npm:0.83.1": - version: 0.83.1 - resolution: "@react-native/dev-middleware@npm:0.83.1" +"@react-native/dev-middleware@npm:0.85.3": + version: 0.85.3 + resolution: "@react-native/dev-middleware@npm:0.85.3" dependencies: "@isaacs/ttlcache": "npm:^1.4.1" - "@react-native/debugger-frontend": "npm:0.83.1" - "@react-native/debugger-shell": "npm:0.83.1" + "@react-native/debugger-frontend": "npm:0.85.3" + "@react-native/debugger-shell": "npm:0.85.3" chrome-launcher: "npm:^0.15.2" - chromium-edge-launcher: "npm:^0.2.0" + chromium-edge-launcher: "npm:^0.3.0" connect: "npm:^3.6.5" debug: "npm:^4.4.0" invariant: "npm:^2.2.4" @@ -3904,116 +4005,131 @@ __metadata: open: "npm:^7.0.3" serve-static: "npm:^1.16.2" ws: "npm:^7.5.10" - checksum: 10c0/b9697e8729a74daf21338e2f3b69c1a542a9023cffe7b045537e2bd66d55397544b47b6980120207bf4dac5add986bcb0aed9a41608f74df3f9210d1f5d9f604 + checksum: 10c0/6adb5e0ecf933f1936eaf993bc39dd8afd4b20e1f1f6525f2c1428fb9000855a764fa93a4043a1bb1678ec827d9c5fca2d6082a928c3dac49f51ea882d991011 languageName: node linkType: hard -"@react-native/eslint-config@npm:0.83.1": - version: 0.83.1 - resolution: "@react-native/eslint-config@npm:0.83.1" +"@react-native/eslint-config@npm:0.85.3": + version: 0.85.3 + resolution: "@react-native/eslint-config@npm:0.85.3" dependencies: "@babel/core": "npm:^7.25.2" "@babel/eslint-parser": "npm:^7.25.1" - "@react-native/eslint-plugin": "npm:0.83.1" + "@react-native/eslint-plugin": "npm:0.85.3" "@typescript-eslint/eslint-plugin": "npm:^8.36.0" "@typescript-eslint/parser": "npm:^8.36.0" eslint-config-prettier: "npm:^8.5.0" eslint-plugin-eslint-comments: "npm:^3.2.0" eslint-plugin-ft-flow: "npm:^2.0.1" eslint-plugin-jest: "npm:^29.0.1" - eslint-plugin-react: "npm:^7.30.1" + eslint-plugin-react: "npm:^7.37.5" eslint-plugin-react-hooks: "npm:^7.0.1" - eslint-plugin-react-native: "npm:^4.0.0" + eslint-plugin-react-native: "npm:^5.0.0" peerDependencies: - eslint: ">=8" + eslint: ^8.0.0 || ^9.0.0 prettier: ">=2" - checksum: 10c0/c6df159a86abd073e4093a1b32f5c410cb698d4f4b9996256c0027acd986007985a79fc44a85ff2752bbcdea3a1131b84dcdeccc9a1b8dac8b06487e1590e9a0 + checksum: 10c0/d33ca9019c156750efb696e8c068a83800ecc8dedff7effc24778ee35b45099f1d5533cd91acd4d2e3aeb252628a9f8bb8b5c3b1e55489ae5795b4f374d5d05d languageName: node linkType: hard -"@react-native/eslint-plugin@npm:0.83.1": - version: 0.83.1 - resolution: "@react-native/eslint-plugin@npm:0.83.1" - checksum: 10c0/11ed1b8162d0a31ba854d41e2e9009418cf4a2a85188c542f2491316b2718808e53f788529d79f0a143d5a17d8b6f92c074303b9490ca44f546d7f344b0e925c +"@react-native/eslint-plugin@npm:0.85.3": + version: 0.85.3 + resolution: "@react-native/eslint-plugin@npm:0.85.3" + checksum: 10c0/c5dd55b55f2f331b75f686dac03a01c72699f04bfa9502c6b482bdbdfd7b7b7d20d69bd4066f7623d96a2552cac8f3e36a53fe8e4d4abde9c9292b861f84a1ee languageName: node linkType: hard -"@react-native/gradle-plugin@npm:0.83.1": - version: 0.83.1 - resolution: "@react-native/gradle-plugin@npm:0.83.1" - checksum: 10c0/3f55ea53fbb3ac1892c2d442a6649e779290e49667d887f613dd28b7d6d2dd73b33b5dbbe03bcfa1f730bf151dd05b9770631f6c66177162483a75ebb1a85c36 +"@react-native/gradle-plugin@npm:0.85.3": + version: 0.85.3 + resolution: "@react-native/gradle-plugin@npm:0.85.3" + checksum: 10c0/a5a57a0f0783cc31f3daec9e092c32774e72dbae334e9a3eaa86a4ff55f6563069003213d72efc2666e2381b73c653a2f8a4af42c8efd5a974eb848233984a2c languageName: node linkType: hard -"@react-native/js-polyfills@npm:0.83.1": - version: 0.83.1 - resolution: "@react-native/js-polyfills@npm:0.83.1" - checksum: 10c0/f79a6ccf0ba7206bbb0d0653c3a0da8d8bb9c064cf2614c04b69204a4b36f047bd4d00f835114f0f7f0bf37c0c9c388eea6baedbf2eeec1fbc7cdbbb76d12e7d +"@react-native/jest-preset@npm:0.85.3": + version: 0.85.3 + resolution: "@react-native/jest-preset@npm:0.85.3" + dependencies: + "@jest/create-cache-key-function": "npm:^29.7.0" + "@react-native/js-polyfills": "npm:0.85.3" + babel-jest: "npm:^29.7.0" + jest-environment-node: "npm:^29.7.0" + regenerator-runtime: "npm:^0.13.2" + peerDependencies: + react: ^19.2.3 + checksum: 10c0/7c18a87432978d8e05bb66401d6591a99e1aaf575a206afd0a120611359c8addf7259ecf9f1ccb162fd2bd23412eaf8d7791168718bbe180e397a219806a302f languageName: node linkType: hard -"@react-native/metro-babel-transformer@npm:0.83.1": - version: 0.83.1 - resolution: "@react-native/metro-babel-transformer@npm:0.83.1" +"@react-native/js-polyfills@npm:0.85.3": + version: 0.85.3 + resolution: "@react-native/js-polyfills@npm:0.85.3" + checksum: 10c0/67c4ed8234cbeb6d5250b06901f352ddd5348f9aad88aac8a06dc884f42e0da22ff2e1ca8e06c7d03e1e659486bdb9d7682f34858ebf9398d7ae199ce02b3749 + languageName: node + linkType: hard + +"@react-native/metro-babel-transformer@npm:0.85.3": + version: 0.85.3 + resolution: "@react-native/metro-babel-transformer@npm:0.85.3" dependencies: "@babel/core": "npm:^7.25.2" - "@react-native/babel-preset": "npm:0.83.1" - hermes-parser: "npm:0.32.0" + "@react-native/babel-preset": "npm:0.85.3" + hermes-parser: "npm:0.33.3" nullthrows: "npm:^1.1.1" peerDependencies: "@babel/core": "*" - checksum: 10c0/be9c900d6c303202839cdb9009349e389b8850eda0805080428d1ed9a95113c653a653639ffb9e1bbeba047196359f3fe1c1afe9e0e0e308d13850570ef7184a + checksum: 10c0/e3e976b05d7cd7256eaed024ca4f50c29f2cd34df887566017ae14d5d918de1bfaeecfc9b6b83098ebcf7fd3b6b55bca344ee9e17c5ff8aa612d944f9704ec9f languageName: node linkType: hard -"@react-native/metro-config@npm:0.83.1": - version: 0.83.1 - resolution: "@react-native/metro-config@npm:0.83.1" +"@react-native/metro-config@npm:0.85.3": + version: 0.85.3 + resolution: "@react-native/metro-config@npm:0.85.3" dependencies: - "@react-native/js-polyfills": "npm:0.83.1" - "@react-native/metro-babel-transformer": "npm:0.83.1" - metro-config: "npm:^0.83.3" - metro-runtime: "npm:^0.83.3" - checksum: 10c0/5aa6d30a96a04ec21c8fe6640843014a6a45659b7013b690843f42ede7b7ba340bd452bca80b5a430d3eb3d62fdcb6ab6fd83447782da1b50e1dd3c04f994d2d + "@react-native/js-polyfills": "npm:0.85.3" + "@react-native/metro-babel-transformer": "npm:0.85.3" + metro-config: "npm:^0.84.3" + metro-runtime: "npm:^0.84.3" + checksum: 10c0/3f405497efa36050d8db85d4c2a019ec178489eea6e35213097f314fc76ff83209858da0a72373b5e1c00d82321fb97d5cb46e506ac79369a291783a94a65608 languageName: node linkType: hard -"@react-native/normalize-colors@npm:0.83.1": - version: 0.83.1 - resolution: "@react-native/normalize-colors@npm:0.83.1" - checksum: 10c0/e1bb0b1b6d098513dd493b1ea926a8db57e96132be75525c8d03008453a48a2f09a12d8b059ef49fcb6ae05f0decc1a9120825ea5c845a4aeedd6e4b1596d75b +"@react-native/normalize-colors@npm:0.85.3": + version: 0.85.3 + resolution: "@react-native/normalize-colors@npm:0.85.3" + checksum: 10c0/343cdbe79e51b0f62e13fcf8620d9c72d7d956d18e9b1b04380a231cff1ec43ff2c54f1ed7a9b975bc23ed4879b96520a7c88aa1c8c7f17a99c32ef8073cf341 languageName: node linkType: hard -"@react-native/typescript-config@npm:0.83.1": - version: 0.83.1 - resolution: "@react-native/typescript-config@npm:0.83.1" - checksum: 10c0/d630758fa5e081d39a6c665068576574cfad08d7d0971a4de25a95bd9e3547ab28aa8e57543ba741569c4c9adf37587e80ac1ef2971cc1e6d2bbfd0c326edb1a +"@react-native/typescript-config@npm:0.85.3": + version: 0.85.3 + resolution: "@react-native/typescript-config@npm:0.85.3" + checksum: 10c0/6adf0fd9ae9d93b57fde6490e8a1531abc1bd46ebfc278fbaf4afa485280a61780bbbd0f188754faab65f705f0c107bd772278955866b354c8116bc2aa16cce5 languageName: node linkType: hard -"@react-native/virtualized-lists@npm:0.83.1": - version: 0.83.1 - resolution: "@react-native/virtualized-lists@npm:0.83.1" +"@react-native/virtualized-lists@npm:0.85.3": + version: 0.85.3 + resolution: "@react-native/virtualized-lists@npm:0.85.3" dependencies: invariant: "npm:^2.2.4" nullthrows: "npm:^1.1.1" peerDependencies: "@types/react": ^19.2.0 react: "*" - react-native: "*" + react-native: 0.85.3 peerDependenciesMeta: "@types/react": optional: true - checksum: 10c0/722a2939dc056fda700935026d6d2d6ac26ddc98a06370d96e3d97d254bda321e4c5ec3ccca64e97f119d9a56eb707ffb35100ae377431e69427550c68ee4709 + checksum: 10c0/ff3425a27c90f3d51292533c330338cfb285d1a230129abed315e7ea07be55e62ab395f7b167c0fe5b20385f67f587a8ea17440e6ab18661846cc8a1936f8fdb languageName: node linkType: hard -"@react-navigation/core@npm:^7.13.7": - version: 7.13.7 - resolution: "@react-navigation/core@npm:7.13.7" +"@react-navigation/core@npm:^7.17.5": + version: 7.17.5 + resolution: "@react-navigation/core@npm:7.17.5" dependencies: - "@react-navigation/routers": "npm:^7.5.3" + "@react-navigation/routers": "npm:^7.5.5" escape-string-regexp: "npm:^4.0.0" fast-deep-equal: "npm:^3.1.3" nanoid: "npm:^3.3.11" @@ -4023,35 +4139,35 @@ __metadata: use-sync-external-store: "npm:^1.5.0" peerDependencies: react: ">= 18.2.0" - checksum: 10c0/6d33e97a4fb72ffbb5fd135afb418b8d3411abbdbe7ce0fde026fcb0bc0ce7c96e8995a24c77314d6e5e4b689ba3b0311805cb619eedbafc2011aca5e26591fa + checksum: 10c0/537c719cebc476bae70330bb870938c0d3763341da428e5ed4aedcfa6b5fc730babf6b89d38337925188597611abe11ce07734a0a3257624d4b01aec0aa1a3da languageName: node linkType: hard -"@react-navigation/elements@npm:^2.9.4": - version: 2.9.4 - resolution: "@react-navigation/elements@npm:2.9.4" +"@react-navigation/elements@npm:^2.9.19": + version: 2.9.19 + resolution: "@react-navigation/elements@npm:2.9.19" dependencies: color: "npm:^4.2.3" use-latest-callback: "npm:^0.2.4" use-sync-external-store: "npm:^1.5.0" peerDependencies: "@react-native-masked-view/masked-view": ">= 0.2.0" - "@react-navigation/native": ^7.1.27 + "@react-navigation/native": ^7.2.5 react: ">= 18.2.0" react-native: "*" react-native-safe-area-context: ">= 4.0.0" peerDependenciesMeta: "@react-native-masked-view/masked-view": optional: true - checksum: 10c0/822d8cbf079520e943c05b37fbcd48b7f574db421b764fa6c6200dc77223720da83fa7361d7c42e15104883e13d1a5349dd2bc2de2538f7f05502dd79101e38f + checksum: 10c0/8743a20a19de8538346f5376ab21f0fb58f843f39bee70c973c5bd5ee2d2f46ff5aa91284d287602de76c02e704fe6cf6c410aa8936121f8c8891bfe97dc35cb languageName: node linkType: hard -"@react-navigation/native@npm:^7.1.27": - version: 7.1.27 - resolution: "@react-navigation/native@npm:7.1.27" +"@react-navigation/native@npm:^7.2.4": + version: 7.2.5 + resolution: "@react-navigation/native@npm:7.2.5" dependencies: - "@react-navigation/core": "npm:^7.13.7" + "@react-navigation/core": "npm:^7.17.5" escape-string-regexp: "npm:^4.0.0" fast-deep-equal: "npm:^3.1.3" nanoid: "npm:^3.3.11" @@ -4059,34 +4175,34 @@ __metadata: peerDependencies: react: ">= 18.2.0" react-native: "*" - checksum: 10c0/57ce15c61fe7c966b881704d3b31daa047333093f9484c4e4118ccc6878a20ec72d9a8884c6a79a7fce8b53d51481289871e6eb03a9ec27f14e8eb2aa0d96c37 + checksum: 10c0/ae5f6eb27923bb3b4dd292fc6017046d060f4434e04eaab6b952acba381e3225326eee89c1467363e3c3b0010e612c252f46df8e231c7ceb842c455b62e391ba languageName: node linkType: hard -"@react-navigation/routers@npm:^7.5.3": - version: 7.5.3 - resolution: "@react-navigation/routers@npm:7.5.3" +"@react-navigation/routers@npm:^7.5.5": + version: 7.5.5 + resolution: "@react-navigation/routers@npm:7.5.5" dependencies: nanoid: "npm:^3.3.11" - checksum: 10c0/85f6cb9ac71e0492845aa87637c7c745d85aa15e4ad7e71a8d910080f5d5a469dd348f59ffaaed8c488cb92708fae56350a0bfc7bc5750c65e12da1f0d4eca70 + checksum: 10c0/d555029547e9de2b846fcd6e4cc15989335492c8b2c03bf92df1558278f2871a700a57b2ece4950958fd6531d39e9eb8b896fcfc40c8163c01f39d4dda9fb34a languageName: node linkType: hard -"@react-navigation/stack@npm:^7.6.14": - version: 7.6.14 - resolution: "@react-navigation/stack@npm:7.6.14" +"@react-navigation/stack@npm:^7.9.2": + version: 7.9.3 + resolution: "@react-navigation/stack@npm:7.9.3" dependencies: - "@react-navigation/elements": "npm:^2.9.4" + "@react-navigation/elements": "npm:^2.9.19" color: "npm:^4.2.3" use-latest-callback: "npm:^0.2.4" peerDependencies: - "@react-navigation/native": ^7.1.27 + "@react-navigation/native": ^7.2.5 react: ">= 18.2.0" react-native: "*" react-native-gesture-handler: ">= 2.0.0" react-native-safe-area-context: ">= 4.0.0" react-native-screens: ">= 4.0.0" - checksum: 10c0/8b54a80cd73f44db14e0edd6103722124733b5ca0617b44ea5767c857d4aadc101558d4349956d1ba447926dc224ff72043b95fed7152c139ce6f2f902cc5668 + checksum: 10c0/566ae69335af8aea363bcfe704d49fe7c6dfd3d01fd431b443a8bd53c53a8bcf9288fb8d7d4b1333db6e73f5c6be10aaf5e066f48642e7ff61b373df4907cb67 languageName: node linkType: hard @@ -4322,14 +4438,14 @@ __metadata: languageName: node linkType: hard -"@shopify/flash-list@npm:^2.2.0": - version: 2.3.0 - resolution: "@shopify/flash-list@npm:2.3.0" +"@shopify/flash-list@npm:^2.3.1": + version: 2.3.1 + resolution: "@shopify/flash-list@npm:2.3.1" peerDependencies: "@babel/runtime": "*" react: "*" react-native: "*" - checksum: 10c0/549fbecd447f3b34a07e37387891105a6b087b673d008c04611b91693d8e37db802a40a1cf7029a8b28d9cf97cefd3676901deab90c38cbf3efa8debc2422cd6 + checksum: 10c0/abe921b93aeb6bf35efb4cd16163ca0126eec1513a40f1b88e370eb646e8bece5daa245e889300aa7ace2a4a81a9ffbd765c1ce2c3f2346611e94cc66c97c6e3 languageName: node linkType: hard @@ -5353,7 +5469,7 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:^7.0.11, @types/json-schema@npm:^7.0.12": +"@types/json-schema@npm:^7.0.12, @types/json-schema@npm:^7.0.15": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db @@ -6191,7 +6307,17 @@ __metadata: languageName: node linkType: hard -"accepts@npm:^1.3.7, accepts@npm:~1.3.8": +"accepts@npm:^2.0.0": + version: 2.0.0 + resolution: "accepts@npm:2.0.0" + dependencies: + mime-types: "npm:^3.0.0" + negotiator: "npm:^1.0.0" + checksum: 10c0/98374742097e140891546076215f90c32644feacf652db48412329de4c2a529178a81aa500fbb13dd3e6cbf6e68d829037b123ac037fc9a08bcec4b87b358eef + languageName: node + linkType: hard + +"accepts@npm:~1.3.8": version: 1.3.8 resolution: "accepts@npm:1.3.8" dependencies: @@ -6666,12 +6792,12 @@ __metadata: languageName: node linkType: hard -"babel-plugin-syntax-hermes-parser@npm:0.32.0": - version: 0.32.0 - resolution: "babel-plugin-syntax-hermes-parser@npm:0.32.0" +"babel-plugin-syntax-hermes-parser@npm:0.33.3": + version: 0.33.3 + resolution: "babel-plugin-syntax-hermes-parser@npm:0.33.3" dependencies: - hermes-parser: "npm:0.32.0" - checksum: 10c0/2e5aad897d4abd643d33329814ed7adb301047890a8a4325ef140da86e377a1127f1ce6af4064526e5cb603c16d3d3e15784998df4095f1385e7f4e8ca53f03e + hermes-parser: "npm:0.33.3" + checksum: 10c0/61d9f0014b249247e6d5809b638cec4770769a077d3509b8ad575f62c814b28bdd78157dfddf94b040696497c3b78e69cc14793b0b5c15f893c11dc225cc0e3e languageName: node linkType: hard @@ -6963,15 +7089,6 @@ __metadata: languageName: node linkType: hard -"brace-expansion@npm:^2.0.1": - version: 2.0.2 - resolution: "brace-expansion@npm:2.0.2" - dependencies: - balanced-match: "npm:^1.0.0" - checksum: 10c0/6d117a4c793488af86b83172deb6af143e94c17bc53b0b3cec259733923b4ca84679d506ac261f4ba3c7ed37c46018e2ff442f9ce453af8643ecd64f4a54e6cf - languageName: node - linkType: hard - "brace-expansion@npm:^2.0.2": version: 2.0.3 resolution: "brace-expansion@npm:2.0.3" @@ -7318,17 +7435,16 @@ __metadata: languageName: node linkType: hard -"chromium-edge-launcher@npm:^0.2.0": - version: 0.2.0 - resolution: "chromium-edge-launcher@npm:0.2.0" +"chromium-edge-launcher@npm:^0.3.0": + version: 0.3.0 + resolution: "chromium-edge-launcher@npm:0.3.0" dependencies: "@types/node": "npm:*" escape-string-regexp: "npm:^4.0.0" is-wsl: "npm:^2.2.0" lighthouse-logger: "npm:^1.0.0" mkdirp: "npm:^1.0.4" - rimraf: "npm:^3.0.2" - checksum: 10c0/880972816dd9b95c0eb77d1f707569667a8cce7cc29fe9c8d199c47fdfbe4971e9da3e5a29f61c4ecec29437ac7cebbbb5afc30bec96306579d1121e7340606a + checksum: 10c0/ad04a75bf53ebed0b7adc5bd133587369b0c2e55c92fe460eb6ccec5efe03c161a7466756173969867a2acbe02dd40449186bd74671dd892520492283d4ff43d languageName: node linkType: hard @@ -7604,7 +7720,7 @@ __metadata: languageName: node linkType: hard -"convert-source-map@npm:2.0.0, convert-source-map@npm:^2.0.0": +"convert-source-map@npm:^2.0.0": version: 2.0.0 resolution: "convert-source-map@npm:2.0.0" checksum: 10c0/8f2f7a27a1a011cc6cc88cc4da2d7d0cfa5ee0369508baae3d98c260bb3ac520691464e5bbe4ae7cdf09860c1d69ecc6f70c63c6e7c7f7e3f18ec08484dc7d9b @@ -8833,18 +8949,18 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-react-native@npm:^4.0.0": - version: 4.1.0 - resolution: "eslint-plugin-react-native@npm:4.1.0" +"eslint-plugin-react-native@npm:^5.0.0": + version: 5.0.0 + resolution: "eslint-plugin-react-native@npm:5.0.0" dependencies: eslint-plugin-react-native-globals: "npm:^0.1.1" peerDependencies: - eslint: ^3.17.0 || ^4 || ^5 || ^6 || ^7 || ^8 - checksum: 10c0/9aedccde6227b78bad7c243844aca0860fca2dccd635e91e745bcd617c1e7fb889fa212917cf7b56860335a147fc7c8dc339d1976330ec4f896fe9156b35b162 + eslint: ^3.17.0 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + checksum: 10c0/c7c927bc743abf0cb367cc64fea5b28b28ea0c58be2990cab858a050b4855e89d90513afa44d73012c9fd670810ad0da2ac72e3e4bdfedf0ce0cbb65e901af7f languageName: node linkType: hard -"eslint-plugin-react@npm:^7.30.1": +"eslint-plugin-react@npm:^7.37.5": version: 7.37.5 resolution: "eslint-plugin-react@npm:7.37.5" dependencies: @@ -9374,39 +9490,39 @@ __metadata: languageName: node linkType: hard -"firebase@npm:12.7.0": - version: 12.7.0 - resolution: "firebase@npm:12.7.0" +"firebase@npm:12.10.0": + version: 12.10.0 + resolution: "firebase@npm:12.10.0" dependencies: - "@firebase/ai": "npm:2.6.1" - "@firebase/analytics": "npm:0.10.19" - "@firebase/analytics-compat": "npm:0.2.25" - "@firebase/app": "npm:0.14.6" - "@firebase/app-check": "npm:0.11.0" - "@firebase/app-check-compat": "npm:0.4.0" - "@firebase/app-compat": "npm:0.5.6" + "@firebase/ai": "npm:2.9.0" + "@firebase/analytics": "npm:0.10.20" + "@firebase/analytics-compat": "npm:0.2.26" + "@firebase/app": "npm:0.14.9" + "@firebase/app-check": "npm:0.11.1" + "@firebase/app-check-compat": "npm:0.4.1" + "@firebase/app-compat": "npm:0.5.9" "@firebase/app-types": "npm:0.9.3" - "@firebase/auth": "npm:1.12.0" - "@firebase/auth-compat": "npm:0.6.2" - "@firebase/data-connect": "npm:0.3.12" - "@firebase/database": "npm:1.1.0" - "@firebase/database-compat": "npm:2.1.0" - "@firebase/firestore": "npm:4.9.3" - "@firebase/firestore-compat": "npm:0.4.3" - "@firebase/functions": "npm:0.13.1" - "@firebase/functions-compat": "npm:0.4.1" - "@firebase/installations": "npm:0.6.19" - "@firebase/installations-compat": "npm:0.2.19" - "@firebase/messaging": "npm:0.12.23" - "@firebase/messaging-compat": "npm:0.2.23" - "@firebase/performance": "npm:0.7.9" - "@firebase/performance-compat": "npm:0.2.22" - "@firebase/remote-config": "npm:0.7.0" - "@firebase/remote-config-compat": "npm:0.2.20" - "@firebase/storage": "npm:0.14.0" - "@firebase/storage-compat": "npm:0.4.0" - "@firebase/util": "npm:1.13.0" - checksum: 10c0/1b23fd061bc7e7e4d5ac993fecd9f76622e7343bb1f7be367963014f1ea485f3deb3e4aa5bc3d198a8313339cf2a51adb8a5d4e9696fa9ed7c7752252438f132 + "@firebase/auth": "npm:1.12.1" + "@firebase/auth-compat": "npm:0.6.3" + "@firebase/data-connect": "npm:0.4.0" + "@firebase/database": "npm:1.1.1" + "@firebase/database-compat": "npm:2.1.1" + "@firebase/firestore": "npm:4.12.0" + "@firebase/firestore-compat": "npm:0.4.6" + "@firebase/functions": "npm:0.13.2" + "@firebase/functions-compat": "npm:0.4.2" + "@firebase/installations": "npm:0.6.20" + "@firebase/installations-compat": "npm:0.2.20" + "@firebase/messaging": "npm:0.12.24" + "@firebase/messaging-compat": "npm:0.2.24" + "@firebase/performance": "npm:0.7.10" + "@firebase/performance-compat": "npm:0.2.23" + "@firebase/remote-config": "npm:0.8.1" + "@firebase/remote-config-compat": "npm:0.2.22" + "@firebase/storage": "npm:0.14.1" + "@firebase/storage-compat": "npm:0.4.1" + "@firebase/util": "npm:1.14.0" + checksum: 10c0/d5dec2e47056cf554a8de46985aba91b5a0a6f08c87c5cda9a38c6b34a14d19f3b7995ff7817baec0d0d0bd1e6b4fe393df3783aec0d19c2b3b899a66994bba8 languageName: node linkType: hard @@ -9747,7 +9863,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^7.1.1, glob@npm:^7.1.3, glob@npm:^7.1.4": +"glob@npm:^7.1.3, glob@npm:^7.1.4": version: 7.2.3 resolution: "glob@npm:7.2.3" dependencies: @@ -9965,10 +10081,10 @@ __metadata: languageName: node linkType: hard -"hermes-compiler@npm:0.14.0": - version: 0.14.0 - resolution: "hermes-compiler@npm:0.14.0" - checksum: 10c0/672036528448e8af5895c9d8c5dfd6012b76e92a5a187caf3143925e358bfc81b993a0cd50bbae7518c01fe6dc4fdc882e25cd623219a4d33f56d5f7abe6918b +"hermes-compiler@npm:250829098.0.10": + version: 250829098.0.10 + resolution: "hermes-compiler@npm:250829098.0.10" + checksum: 10c0/ccf02f842dc0257deb45cf508dd9183b163fbb1db3b37aca25943cc4667193722dece99c7fba94d89666560b74210873ab139d741def1863bd440ff515113b27 languageName: node linkType: hard @@ -9979,19 +10095,35 @@ __metadata: languageName: node linkType: hard -"hermes-estree@npm:0.32.0": - version: 0.32.0 - resolution: "hermes-estree@npm:0.32.0" - checksum: 10c0/3b67d1fe44336240ef7f9c40ecbf363279ba263d51efe120570c3862cc109e652fc09aebddfe6b73d0f0246610bee130e4064c359f1f4cbf002bdb1d99717ef2 +"hermes-estree@npm:0.33.3": + version: 0.33.3 + resolution: "hermes-estree@npm:0.33.3" + checksum: 10c0/4e04e767a706a93c59d64ef3f114075aeb93b08433655d4f11d310f0785c2a74d5b5041b80bc34d22630dece54865dd93a53fde160d48b8369cfef10dbd0520b + languageName: node + linkType: hard + +"hermes-estree@npm:0.35.0": + version: 0.35.0 + resolution: "hermes-estree@npm:0.35.0" + checksum: 10c0/a88c9dc63b8b3679b1aeb43e72e977597096c1bd7d59978c952f1d6df6d1a517c4a817c70b1b701854996b485adfa66c2fc7f80871029a7f0c04306f6717b59a languageName: node linkType: hard -"hermes-parser@npm:0.32.0": - version: 0.32.0 - resolution: "hermes-parser@npm:0.32.0" +"hermes-parser@npm:0.33.3": + version: 0.33.3 + resolution: "hermes-parser@npm:0.33.3" dependencies: - hermes-estree: "npm:0.32.0" - checksum: 10c0/5902d2c5d347c0629fba07a47eaad5569590ac69bc8bfb2e454e08d2dfbe1ebd989d88518dca2cba64061689b5eac5960ae6bd15a4a66600bbf377498a3234b7 + hermes-estree: "npm:0.33.3" + checksum: 10c0/f7d69de54c77321d8481e37a323bbac01d180ec982275ef8925ceaaf7e501fc3062593e84cf5da50852f36daffb34d0f5d6cbbef079fd0125a7b91c1fe84f225 + languageName: node + linkType: hard + +"hermes-parser@npm:0.35.0": + version: 0.35.0 + resolution: "hermes-parser@npm:0.35.0" + dependencies: + hermes-estree: "npm:0.35.0" + checksum: 10c0/49d98093a2094758db5b536627c6cf5146b140f66e63143acf471c62f1d3fd8bd6ae10a33f2372f72e3653deda5d4615c6dae89d01248849440916209901fc4a languageName: node linkType: hard @@ -11717,69 +11849,70 @@ __metadata: languageName: node linkType: hard -"metro-babel-transformer@npm:0.83.3": - version: 0.83.3 - resolution: "metro-babel-transformer@npm:0.83.3" +"metro-babel-transformer@npm:0.84.4": + version: 0.84.4 + resolution: "metro-babel-transformer@npm:0.84.4" dependencies: "@babel/core": "npm:^7.25.2" flow-enums-runtime: "npm:^0.0.6" - hermes-parser: "npm:0.32.0" + hermes-parser: "npm:0.35.0" + metro-cache-key: "npm:0.84.4" nullthrows: "npm:^1.1.1" - checksum: 10c0/b0107f86cdc9ef9419d669b5b3dac22e35b02c67c480563a63d98f5fb50953587938769efc854bfc09c225557790cd6488dbe3fed6f05c2b3f322cfb2e5ff577 + checksum: 10c0/d1ac996666334bc1cfe9d399cbf4cd747b675f6f8f758c2317eebcc52bd76046ed864ddb7b270efeb8cf337940a61fb03912e5c859b7cbc54687c2f5c41a9d2a languageName: node linkType: hard -"metro-cache-key@npm:0.83.3": - version: 0.83.3 - resolution: "metro-cache-key@npm:0.83.3" +"metro-cache-key@npm:0.84.4": + version: 0.84.4 + resolution: "metro-cache-key@npm:0.84.4" dependencies: flow-enums-runtime: "npm:^0.0.6" - checksum: 10c0/403a2ca5b5bbb31a979effaa31fba0c47e2eb3830428c39c99db58aa0739a6fcc386f5a56c91495c53a4569065f0bda29e3038e9c41ca17af443971395f257dc + checksum: 10c0/a82ab6367f11886d960cc8fa1f3aa54f6529fe30c16059c141c3e789084c50838fdd7e1a5528534cd9c11a74c63aa5c6a7461dbfa50e8c449b6141eaf2fd05e0 languageName: node linkType: hard -"metro-cache@npm:0.83.3": - version: 0.83.3 - resolution: "metro-cache@npm:0.83.3" +"metro-cache@npm:0.84.4": + version: 0.84.4 + resolution: "metro-cache@npm:0.84.4" dependencies: exponential-backoff: "npm:^3.1.1" flow-enums-runtime: "npm:^0.0.6" https-proxy-agent: "npm:^7.0.5" - metro-core: "npm:0.83.3" - checksum: 10c0/608e85d819092c0b472c9adabb5de58e88355739de71833230626c1af7f3ce5dd1dca9f1ff3a836d995201f717315fd769c4c646a818c1f490ea2ec29417e32a + metro-core: "npm:0.84.4" + checksum: 10c0/3bf7f3a1f85b4f1af05f4b2c71c78e56fd3262d967ee43f02e9ff6820254063af33a70b6549e3dc5e993a6a0b9df92e9279632ad9a8b1cde2577342f93df45eb languageName: node linkType: hard -"metro-config@npm:0.83.3, metro-config@npm:^0.83.3": - version: 0.83.3 - resolution: "metro-config@npm:0.83.3" +"metro-config@npm:0.84.4, metro-config@npm:^0.84.3": + version: 0.84.4 + resolution: "metro-config@npm:0.84.4" dependencies: connect: "npm:^3.6.5" flow-enums-runtime: "npm:^0.0.6" jest-validate: "npm:^29.7.0" - metro: "npm:0.83.3" - metro-cache: "npm:0.83.3" - metro-core: "npm:0.83.3" - metro-runtime: "npm:0.83.3" + metro: "npm:0.84.4" + metro-cache: "npm:0.84.4" + metro-core: "npm:0.84.4" + metro-runtime: "npm:0.84.4" yaml: "npm:^2.6.1" - checksum: 10c0/c53e4a061cfc776a65cdb5055c0be840055f9741dae25e7d407835988618b15f1407270dbd957c7333d01e9c79eccbf8e6bcb76421b2145bd134b53df459a033 + checksum: 10c0/f8aaf7d8cff9b486353b62f4746b0a70f99749bd4061f5ae847524aaedcd9c5a34bf176cbbe12fb33e771e8ed3c1496654b2578fa5ba8b9e4f856f0589744d98 languageName: node linkType: hard -"metro-core@npm:0.83.3, metro-core@npm:^0.83.3": - version: 0.83.3 - resolution: "metro-core@npm:0.83.3" +"metro-core@npm:0.84.4, metro-core@npm:^0.84.3": + version: 0.84.4 + resolution: "metro-core@npm:0.84.4" dependencies: flow-enums-runtime: "npm:^0.0.6" lodash.throttle: "npm:^4.1.1" - metro-resolver: "npm:0.83.3" - checksum: 10c0/d44c1f117c4b27f18abd27110e9536abf3105733e8fccaa522bd0e008248cce0260130517840c4914d7ce5df498f39ecfd43b6046a0f0b1c0f8ada7de38e52c4 + metro-resolver: "npm:0.84.4" + checksum: 10c0/19d859de16b5e082c9c31bed981c579a4e6d31a626c7829b725df9ae0ffb755d0ef7809ba9f8adf22d3921f5ffdd931ed77b21b95ca2ea17895f0c99b3cab831 languageName: node linkType: hard -"metro-file-map@npm:0.83.3": - version: 0.83.3 - resolution: "metro-file-map@npm:0.83.3" +"metro-file-map@npm:0.84.4": + version: 0.84.4 + resolution: "metro-file-map@npm:0.84.4" dependencies: debug: "npm:^4.4.0" fb-watchman: "npm:^2.0.0" @@ -11790,146 +11923,144 @@ __metadata: micromatch: "npm:^4.0.4" nullthrows: "npm:^1.1.1" walker: "npm:^1.0.7" - checksum: 10c0/4bf9c0fcdb5a5c08851f7370d6427fb68a770f156c4eabbddf20bd3583fb25ae428507eaeb8dc525e792db41d048620209750f33735055863abc909cbb6ef71a + checksum: 10c0/09ca829570d1d6dc5beb0534da8a7f2bfcae5415b0974fd5f58b4a05da95dbafdd47f7dc8dedeb11b6562ee9a92c4d918466d02a05cda6e1eaf2c400cbbe6fb4 languageName: node linkType: hard -"metro-minify-terser@npm:0.83.3": - version: 0.83.3 - resolution: "metro-minify-terser@npm:0.83.3" +"metro-minify-terser@npm:0.84.4": + version: 0.84.4 + resolution: "metro-minify-terser@npm:0.84.4" dependencies: flow-enums-runtime: "npm:^0.0.6" terser: "npm:^5.15.0" - checksum: 10c0/9158e3199c0ea647776a7ed5c68ec1bb493f5347ac979f1ca75020cf1c39f907bd29983d60f8cb24dca17053d6b5c35f140c6d720fad0bd0fa9728e8c51e95c6 + checksum: 10c0/c9b36c2adb8254c38bdedad9da8bf2b7fae7f45cbd883e590430a5fc9cad808af24dd08a9420925e15733dab886528ad553e3eeb3faffc53d3ad80e7e03e5f6d languageName: node linkType: hard -"metro-resolver@npm:0.83.3": - version: 0.83.3 - resolution: "metro-resolver@npm:0.83.3" +"metro-resolver@npm:0.84.4": + version: 0.84.4 + resolution: "metro-resolver@npm:0.84.4" dependencies: flow-enums-runtime: "npm:^0.0.6" - checksum: 10c0/1d6c030a00b987fbee38e5c632219b2be602e38c9aa9628bb4b591f646e64130d08adb8dcb35076c5c8cc151135557b655f3dee514c0df9f26d3416629eb006b + checksum: 10c0/468334270598222e15cbee32af51a3b5e1f4fa6869794955b95d1134b28a58594e8e3879e841ccf00bbb5cd86c689a4481714d6c6a464931987d5333d2c55f80 languageName: node linkType: hard -"metro-runtime@npm:0.83.3, metro-runtime@npm:^0.83.3": - version: 0.83.3 - resolution: "metro-runtime@npm:0.83.3" +"metro-runtime@npm:0.84.4, metro-runtime@npm:^0.84.3": + version: 0.84.4 + resolution: "metro-runtime@npm:0.84.4" dependencies: "@babel/runtime": "npm:^7.25.0" flow-enums-runtime: "npm:^0.0.6" - checksum: 10c0/1d788483b6c2f13e0ea9ff4564996154754d3de84f683812ac848053eaea9243144adee3e8ffe90789e6c253f7402211d72b1b5ebf09e6c23841bc956a680253 + checksum: 10c0/e2b2e819027940c6bbd081e5650238d52b6c6d78561cd486b8c10cd1e7fce0213c66fa7f885e37ad5377fcd5726b1c9e473fba6de13938cdf2c966e82968c05f languageName: node linkType: hard -"metro-source-map@npm:0.83.3, metro-source-map@npm:^0.83.3": - version: 0.83.3 - resolution: "metro-source-map@npm:0.83.3" +"metro-source-map@npm:0.84.4, metro-source-map@npm:^0.84.3": + version: 0.84.4 + resolution: "metro-source-map@npm:0.84.4" dependencies: - "@babel/traverse": "npm:^7.25.3" - "@babel/traverse--for-generate-function-map": "npm:@babel/traverse@^7.25.3" - "@babel/types": "npm:^7.25.2" + "@babel/traverse": "npm:^7.29.0" + "@babel/types": "npm:^7.29.0" flow-enums-runtime: "npm:^0.0.6" invariant: "npm:^2.2.4" - metro-symbolicate: "npm:0.83.3" + metro-symbolicate: "npm:0.84.4" nullthrows: "npm:^1.1.1" - ob1: "npm:0.83.3" + ob1: "npm:0.84.4" source-map: "npm:^0.5.6" vlq: "npm:^1.0.0" - checksum: 10c0/47e984bde1f8f06348298771f44b5803657c9cfa387df8ff36a359cc72ae3bc0e9c4ea6141345609b183ac8c63dcc997000d3626006e388c24779abb57c6f82c + checksum: 10c0/39df4524022e07aa4b4d09dd874a9509eb9e2e1e491e80a35099020347ab6be2407851b026452296aad314b0eb7ecf14f9b6bab96bd7c31d47d8b1eb30279aaf languageName: node linkType: hard -"metro-symbolicate@npm:0.83.3": - version: 0.83.3 - resolution: "metro-symbolicate@npm:0.83.3" +"metro-symbolicate@npm:0.84.4": + version: 0.84.4 + resolution: "metro-symbolicate@npm:0.84.4" dependencies: flow-enums-runtime: "npm:^0.0.6" invariant: "npm:^2.2.4" - metro-source-map: "npm:0.83.3" + metro-source-map: "npm:0.84.4" nullthrows: "npm:^1.1.1" source-map: "npm:^0.5.6" vlq: "npm:^1.0.0" bin: metro-symbolicate: src/index.js - checksum: 10c0/bd3d234c7581466a9a78f952caa25816666753f6b560fe41502727b3e59931ac65225c9909635dc7c25d4dfaf392631366ef3ec5fa8490413385d60f8d900112 + checksum: 10c0/416a9ef694150a8ec708187743b74ab67e0b4fec39c64610b3771b584830117670a62acb9aa824f84a44efbb1cfec07aaf943d1aaf349d977eecf7c72bd8c0bf languageName: node linkType: hard -"metro-transform-plugins@npm:0.83.3": - version: 0.83.3 - resolution: "metro-transform-plugins@npm:0.83.3" +"metro-transform-plugins@npm:0.84.4": + version: 0.84.4 + resolution: "metro-transform-plugins@npm:0.84.4" dependencies: "@babel/core": "npm:^7.25.2" - "@babel/generator": "npm:^7.25.0" - "@babel/template": "npm:^7.25.0" - "@babel/traverse": "npm:^7.25.3" + "@babel/generator": "npm:^7.29.1" + "@babel/template": "npm:^7.28.6" + "@babel/traverse": "npm:^7.29.0" flow-enums-runtime: "npm:^0.0.6" nullthrows: "npm:^1.1.1" - checksum: 10c0/df3c6db6a69d4888e1b6aad40d48ffec0c3c3faa38e89c07633432fc107ef12c47d55598904c91aadfe0751c5bcb7ec191f8a5ee70c18d253201150fc617ca37 + checksum: 10c0/7edb0c0d3655e9f5f5fb8bd8221ec297394b8730c959a3245ea81e50da8177ad7782f21696201a0dcb922281efd919e9548d5b819d8338e52d4b130f06333123 languageName: node linkType: hard -"metro-transform-worker@npm:0.83.3": - version: 0.83.3 - resolution: "metro-transform-worker@npm:0.83.3" +"metro-transform-worker@npm:0.84.4": + version: 0.84.4 + resolution: "metro-transform-worker@npm:0.84.4" dependencies: "@babel/core": "npm:^7.25.2" - "@babel/generator": "npm:^7.25.0" - "@babel/parser": "npm:^7.25.3" - "@babel/types": "npm:^7.25.2" + "@babel/generator": "npm:^7.29.1" + "@babel/parser": "npm:^7.29.0" + "@babel/types": "npm:^7.29.0" flow-enums-runtime: "npm:^0.0.6" - metro: "npm:0.83.3" - metro-babel-transformer: "npm:0.83.3" - metro-cache: "npm:0.83.3" - metro-cache-key: "npm:0.83.3" - metro-minify-terser: "npm:0.83.3" - metro-source-map: "npm:0.83.3" - metro-transform-plugins: "npm:0.83.3" + metro: "npm:0.84.4" + metro-babel-transformer: "npm:0.84.4" + metro-cache: "npm:0.84.4" + metro-cache-key: "npm:0.84.4" + metro-minify-terser: "npm:0.84.4" + metro-source-map: "npm:0.84.4" + metro-transform-plugins: "npm:0.84.4" nullthrows: "npm:^1.1.1" - checksum: 10c0/bea0cbcc7d13cd2b97a2159257b3a53b9ecfb15da18ace82ae05bf2d0ac7cc1806c0bd77ed3b8f4c82c9532773fb99f3938e4b1480e2673f5eda69575ee1d7ef + checksum: 10c0/95924f9bcaf6df931bba2783f440d8fab29909bdde8cecdcc3bc7603e7de71e51728a34288f045694b616c94216d1fc683493b8a470e074c9c8a7f220aa9f9b5 languageName: node linkType: hard -"metro@npm:0.83.3, metro@npm:^0.83.3": - version: 0.83.3 - resolution: "metro@npm:0.83.3" +"metro@npm:0.84.4, metro@npm:^0.84.3": + version: 0.84.4 + resolution: "metro@npm:0.84.4" dependencies: - "@babel/code-frame": "npm:^7.24.7" + "@babel/code-frame": "npm:^7.29.0" "@babel/core": "npm:^7.25.2" - "@babel/generator": "npm:^7.25.0" - "@babel/parser": "npm:^7.25.3" - "@babel/template": "npm:^7.25.0" - "@babel/traverse": "npm:^7.25.3" - "@babel/types": "npm:^7.25.2" - accepts: "npm:^1.3.7" - chalk: "npm:^4.0.0" + "@babel/generator": "npm:^7.29.1" + "@babel/parser": "npm:^7.29.0" + "@babel/template": "npm:^7.28.6" + "@babel/traverse": "npm:^7.29.0" + "@babel/types": "npm:^7.29.0" + accepts: "npm:^2.0.0" ci-info: "npm:^2.0.0" connect: "npm:^3.6.5" debug: "npm:^4.4.0" error-stack-parser: "npm:^2.0.6" flow-enums-runtime: "npm:^0.0.6" graceful-fs: "npm:^4.2.4" - hermes-parser: "npm:0.32.0" + hermes-parser: "npm:0.35.0" image-size: "npm:^1.0.2" invariant: "npm:^2.2.4" jest-worker: "npm:^29.7.0" jsc-safe-url: "npm:^0.2.2" lodash.throttle: "npm:^4.1.1" - metro-babel-transformer: "npm:0.83.3" - metro-cache: "npm:0.83.3" - metro-cache-key: "npm:0.83.3" - metro-config: "npm:0.83.3" - metro-core: "npm:0.83.3" - metro-file-map: "npm:0.83.3" - metro-resolver: "npm:0.83.3" - metro-runtime: "npm:0.83.3" - metro-source-map: "npm:0.83.3" - metro-symbolicate: "npm:0.83.3" - metro-transform-plugins: "npm:0.83.3" - metro-transform-worker: "npm:0.83.3" - mime-types: "npm:^2.1.27" + metro-babel-transformer: "npm:0.84.4" + metro-cache: "npm:0.84.4" + metro-cache-key: "npm:0.84.4" + metro-config: "npm:0.84.4" + metro-core: "npm:0.84.4" + metro-file-map: "npm:0.84.4" + metro-resolver: "npm:0.84.4" + metro-runtime: "npm:0.84.4" + metro-source-map: "npm:0.84.4" + metro-symbolicate: "npm:0.84.4" + metro-transform-plugins: "npm:0.84.4" + metro-transform-worker: "npm:0.84.4" + mime-types: "npm:^3.0.1" nullthrows: "npm:^1.1.1" serialize-error: "npm:^2.1.0" source-map: "npm:^0.5.6" @@ -11938,7 +12069,7 @@ __metadata: yargs: "npm:^17.6.2" bin: metro: src/cli.js - checksum: 10c0/9513c05725c3984ce3b72896c4f7d019ad4fd024a1231b8b84c5c655a0563fc7f26725f28c20c5d3511e3825d64fec3a1e68621f6a6af34d785c5e714ed7da89 + checksum: 10c0/ff92915119db29cd855274f3789d391cba83c50cb92e22d1e9b8c729e7f6d39495e32540a22ca4c6591eea6a847ade49fcfa5faab01b2300227e3f1fc7df359c languageName: node linkType: hard @@ -11971,14 +12102,14 @@ __metadata: languageName: node linkType: hard -"mime-db@npm:>= 1.43.0 < 2": +"mime-db@npm:>= 1.43.0 < 2, mime-db@npm:^1.54.0": version: 1.54.0 resolution: "mime-db@npm:1.54.0" checksum: 10c0/8d907917bc2a90fa2df842cdf5dfeaf509adc15fe0531e07bb2f6ab15992416479015828d6a74200041c492e42cce3ebf78e5ce714388a0a538ea9c53eece284 languageName: node linkType: hard -"mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:^2.1.35, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": +"mime-types@npm:^2.1.12, mime-types@npm:^2.1.35, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -11987,6 +12118,15 @@ __metadata: languageName: node linkType: hard +"mime-types@npm:^3.0.0, mime-types@npm:^3.0.1": + version: 3.0.2 + resolution: "mime-types@npm:3.0.2" + dependencies: + mime-db: "npm:^1.54.0" + checksum: 10c0/35a0dd1035d14d185664f346efcdb72e93ef7a9b6e9ae808bd1f6358227010267fab52657b37562c80fc888ff76becb2b2938deb5e730818b7983bf8bd359767 + languageName: node + linkType: hard + "mime@npm:1.6.0": version: 1.6.0 resolution: "mime@npm:1.6.0" @@ -12040,15 +12180,6 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:9.0.3": - version: 9.0.3 - resolution: "minimatch@npm:9.0.3" - dependencies: - brace-expansion: "npm:^2.0.1" - checksum: 10c0/85f407dcd38ac3e180f425e86553911d101455ca3ad5544d6a7cec16286657e4f8a9aa6695803025c55e31e35a91a2252b5dc8e7d527211278b8b65b4dbd5eac - languageName: node - linkType: hard - "minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.5 resolution: "minimatch@npm:3.1.5" @@ -12058,7 +12189,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^9.0.4, minimatch@npm:^9.0.5": +"minimatch@npm:^9.0.4, minimatch@npm:^9.0.7": version: 9.0.9 resolution: "minimatch@npm:9.0.9" dependencies: @@ -12180,6 +12311,13 @@ __metadata: languageName: node linkType: hard +"negotiator@npm:^1.0.0": + version: 1.0.0 + resolution: "negotiator@npm:1.0.0" + checksum: 10c0/4c559dd52669ea48e1914f9d634227c561221dd54734070791f999c52ed0ff36e437b2e07d5c1f6e32909fc625fe46491c16e4a8f0572567d4dd15c3a4fda04b + languageName: node + linkType: hard + "negotiator@npm:~0.6.4": version: 0.6.4 resolution: "negotiator@npm:0.6.4" @@ -12405,12 +12543,12 @@ __metadata: languageName: node linkType: hard -"ob1@npm:0.83.3": - version: 0.83.3 - resolution: "ob1@npm:0.83.3" +"ob1@npm:0.84.4": + version: 0.84.4 + resolution: "ob1@npm:0.84.4" dependencies: flow-enums-runtime: "npm:^0.0.6" - checksum: 10c0/9231315de39cf0612a01e283c7d7ef31d16618e598de96e44ae1ab3007629296ce1a3d5d02ef60ff22d9fefe33050358c10e7fcba8278861157b89befe13cb3d + checksum: 10c0/8bf3a3bdc2b27f1b1b60569c31ff2d9d829025f9a1ce7388b5e810242e48672c8d6b24e5972d6e30aef4d84f6894d12b13d0c6c418460d031da1972b96920bba languageName: node linkType: hard @@ -13436,13 +13574,20 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^19.1.0, react-is@npm:^19.2.0": +"react-is@npm:^19.1.0": version: 19.2.3 resolution: "react-is@npm:19.2.3" checksum: 10c0/2b54c422c21b8dbd68a435a1cce21ecd5b6f06f48659531f7d53dd7368365da5a67e946f352fb2010d11ca40658aa67bec90995f0f1ec5556c0f71dbffe54994 languageName: node linkType: hard +"react-is@npm:^19.2.3": + version: 19.2.6 + resolution: "react-is@npm:19.2.6" + checksum: 10c0/263177f370fc156b279d22570dd6e922a0ad641a4a426a4cb70284b8003b00ef532d59f2beca1d22a1ca0b37f85f9077d7733ca5d344ebecd2942e9bc2a2a3c0 + languageName: node + linkType: hard + "react-native-android-open-settings@npm:^1.3.0": version: 1.3.0 resolution: "react-native-android-open-settings@npm:1.3.0" @@ -13619,7 +13764,7 @@ __metadata: languageName: node linkType: hard -"react-native-is-edge-to-edge@npm:1.2.1, react-native-is-edge-to-edge@npm:^1.2.1": +"react-native-is-edge-to-edge@npm:^1.2.1": version: 1.2.1 resolution: "react-native-is-edge-to-edge@npm:1.2.1" peerDependencies: @@ -13629,6 +13774,16 @@ __metadata: languageName: node linkType: hard +"react-native-is-edge-to-edge@npm:^1.3.1": + version: 1.3.1 + resolution: "react-native-is-edge-to-edge@npm:1.3.1" + peerDependencies: + react: "*" + react-native: "*" + checksum: 10c0/28cebd5f1f3632864ff5e342278721d1e5e38627ae73859a8814012116ef15c629fee7137a6c9c97bb05d94bbe639b0b47e69b36fc2735ab53ed31570140663f + languageName: node + linkType: hard + "react-native-keychain@npm:^10.0.0": version: 10.0.0 resolution: "react-native-keychain@npm:10.0.0" @@ -13709,17 +13864,17 @@ __metadata: languageName: node linkType: hard -"react-native-reanimated@npm:^4.2.1": - version: 4.2.1 - resolution: "react-native-reanimated@npm:4.2.1" +"react-native-reanimated@npm:^4.3.1": + version: 4.4.0 + resolution: "react-native-reanimated@npm:4.4.0" dependencies: - react-native-is-edge-to-edge: "npm:1.2.1" - semver: "npm:7.7.3" + react-native-is-edge-to-edge: "npm:^1.3.1" + semver: "npm:^7.7.3" peerDependencies: react: "*" - react-native: "*" - react-native-worklets: ">=0.7.0" - checksum: 10c0/1458fb634d374125931c5815b2b0941e12b1a880ba12b4ff6bba12b6c101e0ce1f5c32a2226034ae762558e38077ae112d8498eb2c8af6bd967524c7e7f87c6b + react-native: 0.83 - 0.86 + react-native-worklets: 0.9.x + checksum: 10c0/6a7ac5b9349d1313f16c2ac514993cf5b113c8e76a2463636112673daf648aaa902d601fff7358bf87fff0dcc707e956b600e5ff9d5fc64e7d703726933df608 languageName: node linkType: hard @@ -13809,17 +13964,16 @@ __metadata: languageName: node linkType: hard -"react-native-svg@npm:^15.15.1": - version: 15.15.1 - resolution: "react-native-svg@npm:15.15.1" +"react-native-svg@npm:^15.15.5": + version: 15.15.5 + resolution: "react-native-svg@npm:15.15.5" dependencies: css-select: "npm:^5.1.0" css-tree: "npm:^1.1.3" - warn-once: "npm:0.1.1" peerDependencies: react: "*" react-native: "*" - checksum: 10c0/9e047e8afdd5121296a3402c5c37363b9b37fbddc41f7b0b49b923ac4d2898954c8b57a6784a625321236987e494ee54f594e22f9de815f807e03a3433d7fefd + checksum: 10c0/34b71b6c83d7235efbc4263abaffcbad780375f9e0fca95786e4f1a543a2b6d07e90c7df426f708e85be68331c412066cdc639f4a6ce82bed42bc728050d9402 languageName: node linkType: hard @@ -13923,56 +14077,53 @@ __metadata: languageName: node linkType: hard -"react-native-worklets@npm:^0.7.1": - version: 0.7.1 - resolution: "react-native-worklets@npm:0.7.1" - dependencies: - "@babel/plugin-transform-arrow-functions": "npm:7.27.1" - "@babel/plugin-transform-class-properties": "npm:7.27.1" - "@babel/plugin-transform-classes": "npm:7.28.4" - "@babel/plugin-transform-nullish-coalescing-operator": "npm:7.27.1" - "@babel/plugin-transform-optional-chaining": "npm:7.27.1" - "@babel/plugin-transform-shorthand-properties": "npm:7.27.1" - "@babel/plugin-transform-template-literals": "npm:7.27.1" - "@babel/plugin-transform-unicode-regex": "npm:7.27.1" - "@babel/preset-typescript": "npm:7.27.1" - convert-source-map: "npm:2.0.0" - semver: "npm:7.7.3" +"react-native-worklets@npm:^0.8.2": + version: 0.8.3 + resolution: "react-native-worklets@npm:0.8.3" + dependencies: + "@babel/plugin-transform-arrow-functions": "npm:^7.27.1" + "@babel/plugin-transform-class-properties": "npm:^7.27.1" + "@babel/plugin-transform-classes": "npm:^7.28.4" + "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.27.1" + "@babel/plugin-transform-optional-chaining": "npm:^7.27.1" + "@babel/plugin-transform-shorthand-properties": "npm:^7.27.1" + "@babel/plugin-transform-template-literals": "npm:^7.27.1" + "@babel/plugin-transform-unicode-regex": "npm:^7.27.1" + "@babel/preset-typescript": "npm:^7.27.1" + convert-source-map: "npm:^2.0.0" + semver: "npm:^7.7.3" peerDependencies: "@babel/core": "*" + "@react-native/metro-config": "*" react: "*" - react-native: "*" - checksum: 10c0/6965ff3cef7981e10585e15c222fb78f12c54807fcd6f7f9fccdd4dea2bd59d234797fe26a9f47d5c5ba6609f653b807d67f2d03e513e179a25ba28c3ad413ff + react-native: 0.81 - 0.85 + checksum: 10c0/9ceb8ff1f1569165be3318c958087ed95d7b89e5e7308b733dc3f8e328d48c2acc7bc7369449b004b1824ed96e14a15a279d2dbee0105d7d62a55001045484ba languageName: node linkType: hard -"react-native@npm:0.83.1": - version: 0.83.1 - resolution: "react-native@npm:0.83.1" +"react-native@npm:0.85.3": + version: 0.85.3 + resolution: "react-native@npm:0.85.3" dependencies: - "@jest/create-cache-key-function": "npm:^29.7.0" - "@react-native/assets-registry": "npm:0.83.1" - "@react-native/codegen": "npm:0.83.1" - "@react-native/community-cli-plugin": "npm:0.83.1" - "@react-native/gradle-plugin": "npm:0.83.1" - "@react-native/js-polyfills": "npm:0.83.1" - "@react-native/normalize-colors": "npm:0.83.1" - "@react-native/virtualized-lists": "npm:0.83.1" + "@react-native/assets-registry": "npm:0.85.3" + "@react-native/codegen": "npm:0.85.3" + "@react-native/community-cli-plugin": "npm:0.85.3" + "@react-native/gradle-plugin": "npm:0.85.3" + "@react-native/js-polyfills": "npm:0.85.3" + "@react-native/normalize-colors": "npm:0.85.3" + "@react-native/virtualized-lists": "npm:0.85.3" abort-controller: "npm:^3.0.0" anser: "npm:^1.4.9" ansi-regex: "npm:^5.0.0" - babel-jest: "npm:^29.7.0" - babel-plugin-syntax-hermes-parser: "npm:0.32.0" + babel-plugin-syntax-hermes-parser: "npm:0.33.3" base64-js: "npm:^1.5.1" commander: "npm:^12.0.0" flow-enums-runtime: "npm:^0.0.6" - glob: "npm:^7.1.1" - hermes-compiler: "npm:0.14.0" + hermes-compiler: "npm:250829098.0.10" invariant: "npm:^2.2.4" - jest-environment-node: "npm:^29.7.0" memoize-one: "npm:^5.0.0" - metro-runtime: "npm:^0.83.3" - metro-source-map: "npm:^0.83.3" + metro-runtime: "npm:^0.84.3" + metro-source-map: "npm:^0.84.3" nullthrows: "npm:^1.1.1" pretty-format: "npm:^29.7.0" promise: "npm:^8.3.0" @@ -13982,18 +14133,22 @@ __metadata: scheduler: "npm:0.27.0" semver: "npm:^7.1.3" stacktrace-parser: "npm:^0.1.10" + tinyglobby: "npm:^0.2.15" whatwg-fetch: "npm:^3.0.0" ws: "npm:^7.5.10" yargs: "npm:^17.6.2" peerDependencies: + "@react-native/jest-preset": 0.85.3 "@types/react": ^19.1.1 - react: ^19.2.0 + react: ^19.2.3 peerDependenciesMeta: + "@react-native/jest-preset": + optional: true "@types/react": optional: true bin: react-native: cli.js - checksum: 10c0/3a2202ea6e69c1f612b71d31a664eeda2b79811e560aab280c2fa5738d5e285c52d3b6d1820bb1652dd0d78f5ac0f7f183535b5585e29f8cc8298723aa834999 + checksum: 10c0/365bd8ea2de1a707b753e249f17d9f18d993fd80edf76d4316e133ab6d10d51b9ed6912b952fa2173f56a3b8fbef34f179b686907e7d7c06b6e605fbf1dce895 languageName: node linkType: hard @@ -14036,22 +14191,22 @@ __metadata: languageName: node linkType: hard -"react-test-renderer@npm:19.2.0": - version: 19.2.0 - resolution: "react-test-renderer@npm:19.2.0" +"react-test-renderer@npm:19.2.3": + version: 19.2.3 + resolution: "react-test-renderer@npm:19.2.3" dependencies: - react-is: "npm:^19.2.0" + react-is: "npm:^19.2.3" scheduler: "npm:^0.27.0" peerDependencies: - react: ^19.2.0 - checksum: 10c0/cc116b908489316f06881bf7392c5fad4b5f66be42d2f04788f4179a19e86674d54f1006b33fe9eba28bde6edb4cb38764ab75b416f28d02e0182c5552c97551 + react: ^19.2.3 + checksum: 10c0/842b82239dbddbc536083a6260c3e1b0507c02a3400bd05879fc19160468fd0f8ab79fec5dceffa6113b131835cc7621212f8415b46ea5156ab66bbfd7e24297 languageName: node linkType: hard -"react@npm:19.2.0": - version: 19.2.0 - resolution: "react@npm:19.2.0" - checksum: 10c0/1b6d64eacb9324725bfe1e7860cb7a6b8a34bc89a482920765ebff5c10578eb487e6b46b2f0df263bd27a25edbdae2c45e5ea5d81ae61404301c1a7192c38330 +"react@npm:19.2.3": + version: 19.2.3 + resolution: "react@npm:19.2.3" + checksum: 10c0/094220b3ba3a76c1b668f972ace1dd15509b157aead1b40391d1c8e657e720c201d9719537375eff08f5e0514748c0319063392a6f000e31303aafc4471f1436 languageName: node linkType: hard @@ -14516,21 +14671,21 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.7.3, semver@npm:^7.1.3, semver@npm:^7.3.5, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.7.1, semver@npm:^7.7.3": - version: 7.7.3 - resolution: "semver@npm:7.7.3" +"semver@npm:^6.3.0, semver@npm:^6.3.1": + version: 6.3.1 + resolution: "semver@npm:6.3.1" bin: semver: bin/semver.js - checksum: 10c0/4afe5c986567db82f44c8c6faef8fe9df2a9b1d98098fc1721f57c696c4c21cebd572f297fc21002f81889492345b8470473bc6f4aff5fb032a6ea59ea2bc45e + checksum: 10c0/e3d79b609071caa78bcb6ce2ad81c7966a46a7431d9d58b8800cfa9cb6a63699b3899a0e4bcce36167a284578212d9ae6942b6929ba4aa5015c079a67751d42d languageName: node linkType: hard -"semver@npm:^6.3.0, semver@npm:^6.3.1": - version: 6.3.1 - resolution: "semver@npm:6.3.1" +"semver@npm:^7.1.3, semver@npm:^7.3.5, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.7.1, semver@npm:^7.7.3": + version: 7.7.3 + resolution: "semver@npm:7.7.3" bin: semver: bin/semver.js - checksum: 10c0/e3d79b609071caa78bcb6ce2ad81c7966a46a7431d9d58b8800cfa9cb6a63699b3899a0e4bcce36167a284578212d9ae6942b6929ba4aa5015c079a67751d42d + checksum: 10c0/4afe5c986567db82f44c8c6faef8fe9df2a9b1d98098fc1721f57c696c4c21cebd572f297fc21002f81889492345b8470473bc6f4aff5fb032a6ea59ea2bc45e languageName: node linkType: hard @@ -15396,7 +15551,7 @@ __metadata: "@babel/runtime": "npm:^7.25.0" "@d11/react-native-fast-image": "npm:^8.13.0" "@dicebear/bottts": "npm:^9.3.0" - "@dicebear/core": "npm:^9.3.0" + "@dicebear/core": "npm:^9.4.2" "@gorhom/bottom-sheet": "npm:^5" "@gorhom/portal": "npm:^1.0.14" "@jitsu/sdk-js": "madfish-solutions/jitsu-js#87c49de334f5747952f7beda573b95ceb5d86903" @@ -15404,26 +15559,27 @@ __metadata: "@react-native-async-storage/async-storage": "npm:^2.2.0" "@react-native-clipboard/clipboard": "npm:^1.16.3" "@react-native-community/blur": "npm:^4.4.1" - "@react-native-community/cli": "npm:20.0.0" - "@react-native-community/cli-platform-android": "npm:20.0.0" - "@react-native-community/cli-platform-ios": "npm:20.0.0" + "@react-native-community/cli": "npm:20.1.0" + "@react-native-community/cli-platform-android": "npm:20.1.0" + "@react-native-community/cli-platform-ios": "npm:20.1.0" "@react-native-community/netinfo": "npm:^11.4.1" "@react-native-community/slider": "npm:^5.1.1" "@react-native-documents/picker": "npm:^12.0.0" - "@react-native-firebase/app": "npm:^23.8.2" - "@react-native-firebase/app-check": "npm:^23.8.2" - "@react-native-firebase/messaging": "npm:^23.8.2" + "@react-native-firebase/app": "npm:^24.0.0" + "@react-native-firebase/app-check": "npm:^24.0.0" + "@react-native-firebase/messaging": "npm:^24.0.0" "@react-native-google-signin/google-signin": "npm:^16.1.1" "@react-native-masked-view/masked-view": "npm:^0.3.2" - "@react-native/babel-preset": "npm:0.83.1" - "@react-native/eslint-config": "npm:0.83.1" - "@react-native/metro-config": "npm:0.83.1" - "@react-native/typescript-config": "npm:0.83.1" - "@react-navigation/native": "npm:^7.1.27" - "@react-navigation/stack": "npm:^7.6.14" + "@react-native/babel-preset": "npm:0.85.3" + "@react-native/eslint-config": "npm:0.85.3" + "@react-native/jest-preset": "npm:0.85.3" + "@react-native/metro-config": "npm:0.85.3" + "@react-native/typescript-config": "npm:0.85.3" + "@react-navigation/native": "npm:^7.2.4" + "@react-navigation/stack": "npm:^7.9.2" "@reduxjs/toolkit": "npm:^1.8.5" "@sentry/react-native": "npm:^7.8.0" - "@shopify/flash-list": "npm:^2.2.0" + "@shopify/flash-list": "npm:^2.3.1" "@taquito/local-forging": "npm:^24.2.0" "@taquito/rpc": "npm:^24.2.0" "@taquito/signer": "npm:^24.2.0" @@ -15477,8 +15633,8 @@ __metadata: pbkdf2: "npm:^3.1.5" prettier: "npm:2.8.8" qs: "npm:^6.14.1" - react: "npm:19.2.0" - react-native: "npm:0.83.1" + react: "npm:19.2.3" + react-native: "npm:0.85.3" react-native-android-open-settings: "npm:^1.3.0" react-native-biometrics: "npm:^3.0.1" react-native-bootsplash: "npm:^6.3.11" @@ -15496,7 +15652,7 @@ __metadata: react-native-permissions: "npm:^5.4.4" react-native-qrcode-svg: "npm:^6.3.21" react-native-quick-actions: "npm:^0.3.13" - react-native-reanimated: "npm:^4.2.1" + react-native-reanimated: "npm:^4.3.1" react-native-reanimated-carousel: "npm:^4.0.3" react-native-restart: "npm:^0.0.27" react-native-safe-area-context: "npm:^5.5.2" @@ -15504,7 +15660,7 @@ __metadata: react-native-screens: "npm:^4.19.0" react-native-scrypt: "madfish-solutions/react-native-scrypt#120e21ee291ed6bbb51acd251e09f9efeedba3c2" react-native-sha256: "npm:^1.4.10" - react-native-svg: "npm:^15.15.1" + react-native-svg: "npm:^15.15.5" react-native-svg-transformer: "npm:^1.5.2" react-native-swipe-list-view: "npm:^3.2.9" react-native-themis: "npm:^0.15.6" @@ -15514,9 +15670,9 @@ __metadata: react-native-video-controls: "npm:^2.8.1" react-native-vision-camera: "npm:^4.7.3" react-native-webview: "npm:^13.16.0" - react-native-worklets: "npm:^0.7.1" + react-native-worklets: "npm:^0.8.2" react-redux: "npm:^8.0.4" - react-test-renderer: "npm:19.2.0" + react-test-renderer: "npm:19.2.3" redux: "npm:^5.0.1" redux-logger: "npm:^3.0.6" redux-observable: "npm:^2.0.0" @@ -16370,7 +16526,7 @@ __metadata: languageName: node linkType: hard -"warn-once@npm:0.1.1, warn-once@npm:^0.1.0": +"warn-once@npm:^0.1.0": version: 0.1.1 resolution: "warn-once@npm:0.1.1" checksum: 10c0/f531e7b2382124f51e6d8f97b8c865246db8ab6ff4e53257a2d274e0f02b97d7201eb35db481843dc155815e154ad7afb53b01c4d4db15fb5aa073562496aff7 From ad4c8498ab58655a2be93cfeca96d5576891ad48 Mon Sep 17 00:00:00 2001 From: lendihop Date: Tue, 2 Jun 2026 15:39:32 +0200 Subject: [PATCH 13/20] TW-2254: update packages --- ios/Podfile | 1 + ios/Podfile.lock | 30 +++++------ package.json | 6 +-- yarn.lock | 127 ++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 123 insertions(+), 41 deletions(-) diff --git a/ios/Podfile b/ios/Podfile index 4e283db86..9dd6f46e1 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,6 +1,7 @@ # Build React Native third-party dependencies from source, # so native pods can depend on RCT-Folly directly. ENV['RCT_USE_RN_DEP'] = '0' +ENV['RCT_USE_PREBUILT_RNCORE'] = '0' # Resolve react_native_pods.rb with node to allow for hoisting def node_require(script) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index d1806fafb..3164fa881 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -3199,7 +3199,7 @@ PODS: - Yoga - RNFS (2.20.0): - React-Core - - RNGestureHandler (2.30.0): + - RNGestureHandler (2.31.2): - boost - DoubleConversion - fast_float @@ -3348,7 +3348,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - RNReanimated (4.3.1): + - RNReanimated (4.4.0): - boost - DoubleConversion - fast_float @@ -3375,12 +3375,12 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNReanimated/apple (= 4.3.1) - - RNReanimated/common (= 4.3.1) + - RNReanimated/apple (= 4.4.0) + - RNReanimated/common (= 4.4.0) - RNWorklets - SocketRocket - Yoga - - RNReanimated/apple (4.3.1): + - RNReanimated/apple (4.4.0): - boost - DoubleConversion - fast_float @@ -3410,7 +3410,7 @@ PODS: - RNWorklets - SocketRocket - Yoga - - RNReanimated/common (4.3.1): + - RNReanimated/common (4.4.0): - boost - DoubleConversion - fast_float @@ -3590,7 +3590,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - RNWorklets (0.8.3): + - RNWorklets (0.9.1): - boost - DoubleConversion - fast_float @@ -3617,11 +3617,11 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNWorklets/apple (= 0.8.3) - - RNWorklets/common (= 0.8.3) + - RNWorklets/apple (= 0.9.1) + - RNWorklets/common (= 0.9.1) - SocketRocket - Yoga - - RNWorklets/apple (0.8.3): + - RNWorklets/apple (0.9.1): - boost - DoubleConversion - fast_float @@ -3650,7 +3650,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - RNWorklets/common (0.8.3): + - RNWorklets/common (0.9.1): - boost - DoubleConversion - fast_float @@ -4223,20 +4223,20 @@ SPEC CHECKSUMS: RNFBAppCheck: 5a1a36ca7f428d174930bd6ecfdfcd8579cc0296 RNFBMessaging: 296600da7f02e92bb6631c11ef5e19bc1b89a54d RNFS: 89de7d7f4c0f6bafa05343c578f61118c8282ed8 - RNGestureHandler: 420e50a05cdec7de12a3c8ce2bde368130cfa9cc + RNGestureHandler: 35e1f5f04f5b224777890a3e93c6208072c2057b RNGoogleSignin: c1de96d92d6dd4335fa8e0f0ed4312a9d34e4ecb RNKeychain: 76d042fc1dfba47f3945920bc82e0bce9ad1ff55 RNNotifee: 5e3b271e8ea7456a36eec994085543c9adca9168 RNPermissions: 0dbae39cf157f6c699f1454bbdcc25a0977eca83 RNQuickAction: c2c8f379e614428be0babe4d53a575739667744d RNReactNativeHapticFeedback: 5f1542065f0b24c9252bd8cf3e83bc9c548182e4 - RNReanimated: 920c33f677549b725b3e4a571fa8eeda790703d0 + RNReanimated: 4405484a956444df1df51a49493ca2824a281226 RNScreens: d6413aeb1878cdafd3c721e2c5218faf5d5d3b13 RNScrypt: 3e8612600c93aaa3bfa7849b6d1a4ab61613e2af RNSentry: 0cb5c73bdb064318193d5b658774bd34f83107cf RNSha256: 4d35f112e967f58273d625a19376f4eafc72bd5c RNSVG: 0b9792eb17fbbc8e6d186581cb2cf712998dcc2a - RNWorklets: 8598e72b87947ae2f8428a541440851eb50579c3 + RNWorklets: dd22aad568254990d6f3dc4655d54364c5a3eb3a SDWebImage: e9fc87c1aab89a8ab1bbd74eba378c6f53be8abf SDWebImageAVIFCoder: afe194a084e851f70228e4be35ef651df0fc5c57 SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c @@ -4246,6 +4246,6 @@ SPEC CHECKSUMS: VisionCamera: b51af005669c6642dd1b4fca434eda4c1778de87 Yoga: 9d8e8094a2bed6a175d9e6001a0546d5dae663ee -PODFILE CHECKSUM: 37909e0c8f2a781d24747230d0c5d3554596f0ed +PODFILE CHECKSUM: a1b45771ff02f9813c28a409db7c90feec8bef1d COCOAPODS: 1.16.2 diff --git a/package.json b/package.json index 02347107a..9d695e592 100644 --- a/package.json +++ b/package.json @@ -92,14 +92,14 @@ "react-native-exception-handler": "^2.10.10", "react-native-exit-app": "^2.0.0", "react-native-fs": "^2.20.0", - "react-native-gesture-handler": "^2.30.0", + "react-native-gesture-handler": "^2.31.2", "react-native-haptic-feedback": "^2.3.3", "react-native-keychain": "^10.0.0", "react-native-orientation-locker": "^1.7.0", "react-native-permissions": "^5.4.4", "react-native-qrcode-svg": "^6.3.21", "react-native-quick-actions": "^0.3.13", - "react-native-reanimated": "^4.3.1", + "react-native-reanimated": "^4.4.0", "react-native-reanimated-carousel": "^4.0.3", "react-native-restart": "^0.0.27", "react-native-safe-area-context": "^5.5.2", @@ -116,7 +116,7 @@ "react-native-video-controls": "^2.8.1", "react-native-vision-camera": "^4.7.3", "react-native-webview": "^13.16.0", - "react-native-worklets": "^0.8.2", + "react-native-worklets": "^0.9.1", "react-redux": "^8.0.4", "redux": "^5.0.1", "redux-logger": "^3.0.6", diff --git a/yarn.lock b/yarn.lock index 220295b02..ee8603739 100644 --- a/yarn.lock +++ b/yarn.lock @@ -208,6 +208,13 @@ __metadata: languageName: node linkType: hard +"@babel/compat-data@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/compat-data@npm:7.29.7" + checksum: 10c0/47913f05e08a45a1c9df38c02b4b49e391005085b489432647a1abe112e5d9c75e3be8ea5972b7f6da4ec5d1339922ceb9ea02b8a25d4ed1cb8636e5261f344e + languageName: node + linkType: hard + "@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.21.3, @babel/core@npm:^7.23.9, @babel/core@npm:^7.24.4, @babel/core@npm:^7.25.2": version: 7.28.5 resolution: "@babel/core@npm:7.28.5" @@ -302,6 +309,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-compilation-targets@npm:^7.29.7": + version: 7.29.7 + resolution: "@babel/helper-compilation-targets@npm:7.29.7" + dependencies: + "@babel/compat-data": "npm:^7.29.7" + "@babel/helper-validator-option": "npm:^7.29.7" + browserslist: "npm:^4.24.0" + lru-cache: "npm:^5.1.1" + semver: "npm:^6.3.1" + checksum: 10c0/4c15fd4c69a0a7047799a28a88460c19cede0a0ee8af994ea169114986f4af48b92c7393a4a3fee0456c11a656eece3448a6ed06354453d6c27cccf17195453b + languageName: node + linkType: hard + "@babel/helper-create-class-features-plugin@npm:^7.27.1, @babel/helper-create-class-features-plugin@npm:^7.28.3, @babel/helper-create-class-features-plugin@npm:^7.28.5": version: 7.28.5 resolution: "@babel/helper-create-class-features-plugin@npm:7.28.5" @@ -1047,6 +1067,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-class-properties@npm:^7.28.6": + version: 7.29.7 + resolution: "@babel/plugin-transform-class-properties@npm:7.29.7" + dependencies: + "@babel/helper-create-class-features-plugin": "npm:^7.29.7" + "@babel/helper-plugin-utils": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/c370700423439aa9f0c1f8c4b97f2ef7c2dc46a1b04ec3b10e83e6bae5e4e2159f56d8e4376c9d669b3cf827650cc3740170a36e3924e3e9970d27fd85f4e48a + languageName: node + linkType: hard + "@babel/plugin-transform-class-static-block@npm:^7.28.3": version: 7.28.3 resolution: "@babel/plugin-transform-class-static-block@npm:7.28.3" @@ -1075,6 +1107,22 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-classes@npm:^7.28.6": + version: 7.29.7 + resolution: "@babel/plugin-transform-classes@npm:7.29.7" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.29.7" + "@babel/helper-compilation-targets": "npm:^7.29.7" + "@babel/helper-globals": "npm:^7.29.7" + "@babel/helper-plugin-utils": "npm:^7.29.7" + "@babel/helper-replace-supers": "npm:^7.29.7" + "@babel/traverse": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/53a55bc5348d82ca744dbfcfedf33ab79877e609a5308f43976de8c240bd09cee195a535bf54a01b28d7080eebe759735b1c6cf39f252eef469eefc1d838d2a2 + languageName: node + linkType: hard + "@babel/plugin-transform-computed-properties@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-computed-properties@npm:7.27.1" @@ -1356,6 +1404,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.28.6": + version: 7.29.7 + resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.29.7" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/b0c186fe38bc66830e1be76f06fabbae8a655d3896a841ba5ffa12d6c40bb9c8a6ecd38a7e2196034b1d7470653109b1ceac1ef5e46a5fdc9291d14afa56e0d0 + languageName: node + linkType: hard + "@babel/plugin-transform-numeric-separator@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-transform-numeric-separator@npm:7.27.1" @@ -1417,6 +1476,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-optional-chaining@npm:^7.28.6": + version: 7.29.7 + resolution: "@babel/plugin-transform-optional-chaining@npm:7.29.7" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.29.7" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.29.7" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/71feacf9a7083030f4c69bf4e91db75f2fceae28e58c58b63db040006d908e15bc1e85a464f24ad659f17702e91a64eabbff9f1dd555ba33d78bb1af8a1d697a + languageName: node + linkType: hard + "@babel/plugin-transform-parameters@npm:^7.27.7": version: 7.27.7 resolution: "@babel/plugin-transform-parameters@npm:7.27.7" @@ -1788,7 +1859,7 @@ __metadata: languageName: node linkType: hard -"@babel/preset-typescript@npm:^7.27.1": +"@babel/preset-typescript@npm:^7.28.5": version: 7.29.7 resolution: "@babel/preset-typescript@npm:7.29.7" dependencies: @@ -2709,8 +2780,8 @@ __metadata: linkType: hard "@gorhom/bottom-sheet@npm:^5": - version: 5.2.8 - resolution: "@gorhom/bottom-sheet@npm:5.2.8" + version: 5.2.14 + resolution: "@gorhom/bottom-sheet@npm:5.2.14" dependencies: "@gorhom/portal": "npm:1.0.14" invariant: "npm:^2.2.4" @@ -2726,7 +2797,7 @@ __metadata: optional: true "@types/react-native": optional: true - checksum: 10c0/9bb71a375cdcaec650e8c84ab5e3e42f55b3ae19d9e08cf90688cf72706588d211f3aeef28b857a37e9e411efa8fdf038429c90a8855167c7ab3dce5c595dfca + checksum: 10c0/744c718aaa4e66989043378932ea31d8ff510cff289b5561115530ff49218af080d28dbe409191b33ab7d87b1cfab4e7c16cfb0015cf2b6917b26c61f033bc05 languageName: node linkType: hard @@ -13741,17 +13812,18 @@ __metadata: languageName: node linkType: hard -"react-native-gesture-handler@npm:^2.30.0": - version: 2.30.0 - resolution: "react-native-gesture-handler@npm:2.30.0" +"react-native-gesture-handler@npm:^2.31.2": + version: 2.31.2 + resolution: "react-native-gesture-handler@npm:2.31.2" dependencies: "@egjs/hammerjs": "npm:^2.0.17" + "@types/react-test-renderer": "npm:^19.1.0" hoist-non-react-statics: "npm:^3.3.0" invariant: "npm:^2.2.4" peerDependencies: react: "*" react-native: "*" - checksum: 10c0/26b94b0f97433fc6fb5b1c196ef29fce4f5a66c77fabb1bc33db91099357fbd44a5220783fcbb91d42700bcd578f2fd114314029d9e0d4674878767d9b7f5df6 + checksum: 10c0/a312bb684b5de5376078e407a08a17fddef51a11ea09dd12236b3a971b18a68496f3d8c13391cdfefcc5af776fd90936066aaf20a7cfe2849d8c47c223643dd2 languageName: node linkType: hard @@ -13864,7 +13936,7 @@ __metadata: languageName: node linkType: hard -"react-native-reanimated@npm:^4.3.1": +"react-native-reanimated@npm:^4.4.0": version: 4.4.0 resolution: "react-native-reanimated@npm:4.4.0" dependencies: @@ -14077,27 +14149,27 @@ __metadata: languageName: node linkType: hard -"react-native-worklets@npm:^0.8.2": - version: 0.8.3 - resolution: "react-native-worklets@npm:0.8.3" +"react-native-worklets@npm:^0.9.1": + version: 0.9.1 + resolution: "react-native-worklets@npm:0.9.1" dependencies: "@babel/plugin-transform-arrow-functions": "npm:^7.27.1" - "@babel/plugin-transform-class-properties": "npm:^7.27.1" - "@babel/plugin-transform-classes": "npm:^7.28.4" - "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.27.1" - "@babel/plugin-transform-optional-chaining": "npm:^7.27.1" + "@babel/plugin-transform-class-properties": "npm:^7.28.6" + "@babel/plugin-transform-classes": "npm:^7.28.6" + "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.28.6" + "@babel/plugin-transform-optional-chaining": "npm:^7.28.6" "@babel/plugin-transform-shorthand-properties": "npm:^7.27.1" "@babel/plugin-transform-template-literals": "npm:^7.27.1" "@babel/plugin-transform-unicode-regex": "npm:^7.27.1" - "@babel/preset-typescript": "npm:^7.27.1" + "@babel/preset-typescript": "npm:^7.28.5" convert-source-map: "npm:^2.0.0" - semver: "npm:^7.7.3" + semver: "npm:^7.7.4" peerDependencies: "@babel/core": "*" "@react-native/metro-config": "*" react: "*" - react-native: 0.81 - 0.85 - checksum: 10c0/9ceb8ff1f1569165be3318c958087ed95d7b89e5e7308b733dc3f8e328d48c2acc7bc7369449b004b1824ed96e14a15a279d2dbee0105d7d62a55001045484ba + react-native: 0.83 - 0.86 + checksum: 10c0/a3612d9c2b3613c789dc0b15ffe4e200681b8e64a715029748d29fb4176930765f1afb9fa4d625c02a2c136f3c331ab488e28fbb75e28295fa15edd4000195f3 languageName: node linkType: hard @@ -14689,6 +14761,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.7.4": + version: 7.8.1 + resolution: "semver@npm:7.8.1" + bin: + semver: bin/semver.js + checksum: 10c0/92d6871d6347e1f99d0ba396a70f2545ccf2a032cda3d378fa0699edf7506b5c6d266aed55c8b88e72bd91a30d2351e4f39db479375374430fcdc4b58f4e3c1a + languageName: node + linkType: hard + "send@npm:~0.19.1": version: 0.19.2 resolution: "send@npm:0.19.2" @@ -15645,14 +15726,14 @@ __metadata: react-native-exception-handler: "npm:^2.10.10" react-native-exit-app: "npm:^2.0.0" react-native-fs: "npm:^2.20.0" - react-native-gesture-handler: "npm:^2.30.0" + react-native-gesture-handler: "npm:^2.31.2" react-native-haptic-feedback: "npm:^2.3.3" react-native-keychain: "npm:^10.0.0" react-native-orientation-locker: "npm:^1.7.0" react-native-permissions: "npm:^5.4.4" react-native-qrcode-svg: "npm:^6.3.21" react-native-quick-actions: "npm:^0.3.13" - react-native-reanimated: "npm:^4.3.1" + react-native-reanimated: "npm:^4.4.0" react-native-reanimated-carousel: "npm:^4.0.3" react-native-restart: "npm:^0.0.27" react-native-safe-area-context: "npm:^5.5.2" @@ -15670,7 +15751,7 @@ __metadata: react-native-video-controls: "npm:^2.8.1" react-native-vision-camera: "npm:^4.7.3" react-native-webview: "npm:^13.16.0" - react-native-worklets: "npm:^0.8.2" + react-native-worklets: "npm:^0.9.1" react-redux: "npm:^8.0.4" react-test-renderer: "npm:19.2.3" redux: "npm:^5.0.1" From a3f2e132752e6c7a830fdbbe281ac0ba0312fb51 Mon Sep 17 00:00:00 2001 From: lendihop Date: Tue, 2 Jun 2026 19:03:26 +0200 Subject: [PATCH 14/20] TW-2254: adjust bottomSheet layout --- src/components/bottom-sheet/bottom-sheet.tsx | 35 ++++++++++++-------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/components/bottom-sheet/bottom-sheet.tsx b/src/components/bottom-sheet/bottom-sheet.tsx index 71f6cc840..d30bbf708 100644 --- a/src/components/bottom-sheet/bottom-sheet.tsx +++ b/src/components/bottom-sheet/bottom-sheet.tsx @@ -5,13 +5,14 @@ import GorhomBottomSheet, { TouchableOpacity } from '@gorhom/bottom-sheet'; import { Portal } from '@gorhom/portal'; -import React, { PropsWithChildren, useCallback, useEffect, useRef, useState } from 'react'; -import { BackHandler, Keyboard, Text, View } from 'react-native'; +import React, { PropsWithChildren, useCallback, useEffect, useState } from 'react'; +import { BackHandler, Keyboard, Text, useWindowDimensions, View } from 'react-native'; import { useOrientationChange } from 'react-native-orientation-locker'; +import { useSharedValue } from 'react-native-reanimated'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { TouchableWithAnalytics } from 'src/components/touchable-with-analytics'; -import { emptyComponent, emptyFn } from 'src/config/general'; +import { emptyFn } from 'src/config/general'; import { useAppLock } from 'src/shelter/app-lock/app-lock'; import { formatSize } from 'src/styles/format-size'; import { isDefined } from 'src/utils/is-defined'; @@ -50,22 +51,29 @@ export const BottomSheet: FCWithChildren = ({ const insets = useSafeAreaInsets(); const [isOpened, setIsOpened] = useState(false); - const wasAnimatedRef = useRef(false); - const handleAnimate = useCallback(() => { - wasAnimatedRef.current = true; - }, []); + const { height } = useWindowDimensions(); + const bottomInset = insets.bottom + formatSize(8); + const containerLayoutState = useSharedValue({ + height: height - bottomInset, + offset: { + top: 0, + right: 0, + bottom: bottomInset, + left: 0 + } + }); const renderBackdropComponent = useCallback( (props: PropsWithChildren) => ( ), - [styles.backdrop, isInitiallyOpen] + [styles.backdrop] ); const handleChange = (index: number) => { @@ -102,15 +110,16 @@ export const BottomSheet: FCWithChildren = ({ {!isLocked && ( From 9e1d585e0688a6198cdddb4f952fd6a01ee73236 Mon Sep 17 00:00:00 2001 From: lendihop Date: Tue, 2 Jun 2026 19:26:25 +0200 Subject: [PATCH 15/20] TW-2254: patch react-native-orientation-locker to not cause crush on debug app reload --- postinstall.sh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/postinstall.sh b/postinstall.sh index 5e217e386..47b8bedb0 100755 --- a/postinstall.sh +++ b/postinstall.sh @@ -24,3 +24,12 @@ if [ -f "$rnexitapp_h" ]; then sed -i ${sed_mac_arg:+""} 's|#import |#import "RNExitAppSpec/RNExitAppSpec.h"|' "$rnexitapp_h" sed -i ${sed_mac_arg:+""} 's|#import |#import "RNExitAppSpec/RNExitAppSpec.h"|' "$rnexitapp_h" fi + +# Fix react-native-orientation-locker iOS reload redbox on RN 0.85. +# The native module manually mutates RCTEventEmitter listener accounting during +# init/dealloc, which can remove listeners after React Native already reset them. +orientation_locker_m="node_modules/react-native-orientation-locker/iOS/RCTOrientation/Orientation.m" +if [ -f "$orientation_locker_m" ]; then + sed -i ${sed_mac_arg:+""} '/\[self addListener:@"orientationDidChange"\];/d' "$orientation_locker_m" + sed -i ${sed_mac_arg:+""} '/\[self removeListeners:1\];/d' "$orientation_locker_m" +fi From b30a06541d2a3d87eececa34d5462705a9ce9743 Mon Sep 17 00:00:00 2001 From: lendihop Date: Sat, 13 Jun 2026 00:17:09 +0200 Subject: [PATCH 16/20] TW-2254: update macos --- .github/workflows/fastlane-build.yml | 2 +- .github/workflows/testapp-build.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/fastlane-build.yml b/.github/workflows/fastlane-build.yml index 929b148de..1fb1039d6 100644 --- a/.github/workflows/fastlane-build.yml +++ b/.github/workflows/fastlane-build.yml @@ -16,7 +16,7 @@ on: jobs: fastlane-build: name: Create new iOS & Android builds and upload them via Fastlane - runs-on: macos-15 + runs-on: macos-26 environment: fastlane steps: - name: Clone repository diff --git a/.github/workflows/testapp-build.yml b/.github/workflows/testapp-build.yml index 327dc5319..bcafb29de 100644 --- a/.github/workflows/testapp-build.yml +++ b/.github/workflows/testapp-build.yml @@ -26,7 +26,7 @@ on: jobs: testapp-build: name: Create new iOS / Android builds and upload them via TestApp - runs-on: macos-15 + runs-on: macos-26 environment: testapp steps: - name: Clone repository From 91093df9fc9145348aae2f134b037f50a5b1ba24 Mon Sep 17 00:00:00 2001 From: Danyl Mishyn <35381314+lendihop@users.noreply.github.com> Date: Wed, 17 Jun 2026 19:31:05 +0200 Subject: [PATCH 17/20] TW-2254: EVM accounts derivation (#1211) --- AGENTS.md | 9 +- package.json | 1 + src/apis/youves/index.ts | 4 +- src/apis/youves/utils.ts | 26 +- src/app/app.tsx | 5 +- .../account-dropdown-base.tsx | 111 ++++-- .../account-dropdown-item.interface.ts | 7 +- .../account-dropdown-item.styles.ts | 60 ++- .../account-dropdown-item.tsx | 95 +++-- .../account-dropdown/account-equality-fn.ts | 6 +- .../account-form-dropdown.tsx | 8 +- .../account-form-section-dropdown.tsx | 40 -- .../current-account-dropdown.tsx | 35 +- .../use-activity-group-info.hook.ts | 4 +- .../bottom-sheet-action-button.styles.ts | 3 + .../bottom-sheet-action-button.tsx | 9 +- .../use-bottom-sheet-controller.ts | 13 +- .../contact-dropdown/contact-equality-fn.ts | 6 + .../contact-form-section-dropdown.tsx | 47 +++ src/components/copy-address-popup/index.tsx | 109 +++++ src/components/copy-address-popup/styles.ts | 59 +++ src/components/dropdown/dropdown.tsx | 50 ++- src/components/dropdown/section-dropdown.tsx | 8 +- src/components/error-boundary/content.tsx | 8 +- src/components/error-boundary/errors.ts | 18 + src/components/error-boundary/index.tsx | 8 +- .../header-card-action-buttons.tsx | 10 +- src/components/icon/assets/copy.svg | 3 +- .../icon/assets/tokens/etherlink.svg | 7 + src/components/icon/icon-name.enum.ts | 1 + src/components/icon/icon-name.map.ts | 2 + src/components/promotion-item/index.tsx | 4 +- src/components/robot-icon/robot-icon.tsx | 7 +- src/components/robot-icon/robot-icon.utils.ts | 9 + src/components/sorter/sorter.tsx | 2 +- src/components/styled-radio-group/index.tsx | 2 +- src/config/wallet.const.ts | 1 + src/declarations.d.ts | 2 + src/enums/account-type.enum.ts | 10 +- src/enums/temple-chain-kind.enum.ts | 4 + src/form/form-radio-buttons-group.tsx | 32 -- src/form/form-section-dropdown.tsx | 2 +- src/form/validation/derivation-path.spec.ts | 19 + src/form/validation/derivation-path.ts | 23 ++ src/hooks/main-hooks/index.ts | 4 +- ...ration-request-action-payload.interface.ts | 4 +- ...ration-request-action-payload.interface.ts | 5 +- .../use-request-confirmation.hook.ts | 3 +- src/hooks/use-chain-id.hook.ts | 7 +- src/hooks/use-contract-activity.ts | 24 +- .../use-fake-refresh-control-props.hook.ts | 4 +- src/hooks/use-filtered-account-list.hook.ts | 20 +- src/hooks/use-filtered-receivers-list.hook.ts | 31 +- src/hooks/use-internal-ads-analytics.hook.ts | 6 +- src/hooks/use-load-on-each-block.hook.ts | 8 +- src/hooks/use-read-only-tezos-toolkit.hook.ts | 24 +- src/hooks/use-swap.hook.ts | 14 +- src/interfaces/account.interface.mock.ts | 50 ++- src/interfaces/account.interface.ts | 51 --- src/interfaces/account.interfaces.ts | 39 ++ src/interfaces/contact.interface.ts | 4 + src/layouts/reveal-seed-phrase/index.tsx | 11 +- src/mocks/account-credentials.mock.ts | 2 +- src/mocks/react-redux.mock.ts | 2 +- .../choose-account-import-type/index.tsx | 13 +- .../choose-wallet-import-type/index.tsx | 10 - .../collectible-modal/collectible-modal.tsx | 26 +- .../operation-request-confirmation.tsx | 23 +- .../permission-request-confirmation.form.tsx | 4 +- .../permission-request-confirmation.tsx | 29 +- .../sign-payload-request-confirmation.tsx | 10 +- .../internal-operations-confirmation.tsx | 62 +-- .../hooks/use-estimations.hook.ts | 9 +- .../operations-confirmation.tsx | 14 +- .../rebalance-after-preview.tsx | 14 +- .../sapling-send-preview.tsx | 12 +- .../add-contact-modal/add-contact-modal.tsx | 12 +- .../edit-contact-modal/edit-contact-modal.tsx | 10 +- .../utils/handle-contact-submission.util.ts | 18 +- .../contact-modals/validation-schema.ts | 15 +- .../import-account-keystore-file.form.ts | 30 ++ .../import-account-keystore-file.selectors.ts | 6 + .../import-account-keystore-file.styles.ts | 7 + .../import-account-keystore-file.tsx} | 106 ++--- .../import-account-private-key.form.tsx | 10 +- .../import-account-private-key.tsx | 39 +- ...port-account-seed-derivation-path.form.tsx | 35 -- .../import-account-seed.form.tsx | 19 +- .../import-account-seed.selectors.ts | 2 +- .../import-account-seed.tsx | 66 ++- .../import-wallet-from-keystore-file.form.ts | 30 -- ...import-wallet-from-keystore-file.styles.ts | 20 - src/modals/import-wallet/import-wallet.tsx | 13 +- .../manage-earn-opportunity-modal/index.tsx | 16 +- .../stake-form/use-stake-formik.ts | 16 +- .../withdraw-form/use-withdraw-formik.ts | 26 +- .../rebalance-modal/rebalance-modal.tsx | 14 +- src/modals/receive-modal/receive-modal.tsx | 157 +++++--- .../reveal-private-key-modal.form.tsx | 4 +- .../reveal-private-key-modal.tsx | 56 ++- .../reveal-private-key-view.tsx | 8 +- .../reveal-seed-phrase-form-content.tsx | 31 +- .../reveal-seed-phrase-modal.form.tsx | 10 +- .../reveal-seed-phrase-modal.tsx | 14 +- .../select-baker-modal/select-baker-modal.tsx | 19 +- src/modals/send-modal/send-modal.form.tsx | 6 +- src/modals/send-modal/send-modal.tsx | 19 +- src/navigator/enums/modals.enum.ts | 19 +- src/screens/backup/backup.tsx | 4 +- .../use-buy-with-credit-card-formik.hook.ts | 17 +- .../steps/initial-step/initial-step.tsx | 12 +- .../collectibles-home/collectibles-home.tsx | 20 +- src/screens/collection/index.tsx | 16 +- .../contacts/contact-item/contact-item.tsx | 10 +- src/screens/contacts/contacts.tsx | 6 +- .../create-new-wallet.form.tsx | 2 +- .../import-watch-only-debug.tsx | 16 +- .../baker-rewards-list/baker-rewards-list.tsx | 4 +- src/screens/earn/index.tsx | 19 +- .../manage-account-item.tsx | 47 ++- .../manage-hd-accounts/manage-hd-accounts.tsx | 18 +- .../manage-imported-accounts.tsx | 8 +- src/screens/settings/settings.selectors.ts | 1 + src/screens/settings/settings.tsx | 24 +- src/screens/swap/swap-form/swap-form.tsx | 36 +- .../tezos-token-screen/tezos-token-screen.tsx | 36 +- src/screens/token-screen/token-screen.tsx | 22 +- .../on-ramp-overlay/on-ramp-overlay.tsx | 21 +- src/screens/wallet/token-list/token-list.tsx | 4 +- src/screens/wallet/wallet.tsx | 23 +- src/shelter/app-lock/app-lock.tsx | 18 +- src/shelter/evm-accounts-migration/gate.tsx | 115 ++++++ src/shelter/evm-accounts-migration/index.ts | 46 +++ src/shelter/evm-accounts-migration/styles.ts | 34 ++ .../reveal-secret-key-params.interface.ts | 2 +- src/shelter/shelter.mock.ts | 18 +- src/shelter/shelter.spec.ts | 282 +++++++++++-- src/shelter/shelter.ts | 376 +++++++++++++----- src/shelter/use-shelter.hook.spec.ts | 207 ++++++++-- src/shelter/use-shelter.hook.ts | 93 +++-- src/shelter/utils/common.utils.ts | 18 + ...reate-account-import-subscriptions.util.ts | 288 ++++++++++++++ .../create-hd-account-subscription.util.ts | 38 +- ...create-import-account-subscription.util.ts | 95 ----- ...ble-biometry-password-subscription.util.ts | 4 +- .../utils/import-wallet-subscription.util.ts | 12 +- .../utils/reveal-secrets-subscription.util.ts | 9 +- src/store/baking/baking-epics.ts | 17 +- src/store/collectons/collections-selectors.ts | 6 +- .../contact-book/contact-book-actions.ts | 13 +- src/store/contact-book/contact-book-epics.ts | 8 +- .../contact-book/contact-book-reducers.ts | 6 +- .../contact-book/contact-book-selectors.ts | 2 +- .../contact-book/contact-book-state.mock.ts | 4 +- src/store/contact-book/contact-book-state.ts | 4 +- src/store/farms/selectors.ts | 32 +- src/store/index.ts | 2 + src/store/migrations.ts | 131 +++++- src/store/migrations.types.ts | 62 +++ src/store/root-state.reducers.ts | 2 +- src/store/sapling/sapling-epics.ts | 79 ++-- src/store/sapling/sapling-selectors.ts | 15 +- src/store/savings/epics.ts | 2 +- src/store/savings/selectors.ts | 32 +- src/store/savings/utils.ts | 4 +- src/store/wallet/wallet-actions.ts | 25 +- src/store/wallet/wallet-epics.ts | 78 ++-- src/store/wallet/wallet-reducers.ts | 77 ++-- src/store/wallet/wallet-selectors.ts | 91 +++-- src/store/wallet/wallet-state.mock.ts | 4 +- src/store/wallet/wallet-state.ts | 22 +- src/store/wallet/wallet-state.utils.ts | 14 +- src/types/read-only-signer-payload.ts | 3 - src/types/tezos-read-only-signer-payload.ts | 7 + src/utils/account.utils.spec.ts | 24 ++ src/utils/account.utils.ts | 64 +++ .../get-selected-account-from-wallet.util.ts | 4 + src/utils/keys.util.ts | 42 -- src/utils/keys.utils.spec.ts | 116 +++++- src/utils/keys.utils.ts | 202 ++++++++++ src/utils/rpc/tezos-toolkit.utils.ts | 10 +- src/utils/sapling/address-utils.ts | 11 - ...ts => tezos-read-only.signer.util.spec.ts} | 7 +- ...util.ts => tezos-read-only.signer.util.ts} | 15 +- src/utils/token-balance.utils.ts | 8 +- src/utils/token-operations.util.ts | 38 +- src/utils/transfer-params.spec.ts | 4 +- src/utils/transfer-params.utils.ts | 16 +- src/utils/wallet-account-state.utils.ts | 12 +- src/utils/wallet.utils.ts | 56 +-- yarn.lock | 148 ++++++- 191 files changed, 4023 insertions(+), 1798 deletions(-) delete mode 100644 src/components/account-dropdown/account-form-section-dropdown.tsx create mode 100644 src/components/contact-dropdown/contact-equality-fn.ts create mode 100644 src/components/contact-dropdown/contact-form-section-dropdown.tsx create mode 100644 src/components/copy-address-popup/index.tsx create mode 100644 src/components/copy-address-popup/styles.ts create mode 100644 src/components/error-boundary/errors.ts create mode 100644 src/components/icon/assets/tokens/etherlink.svg create mode 100644 src/components/robot-icon/robot-icon.utils.ts create mode 100644 src/config/wallet.const.ts create mode 100644 src/enums/temple-chain-kind.enum.ts delete mode 100644 src/form/form-radio-buttons-group.tsx create mode 100644 src/form/validation/derivation-path.spec.ts create mode 100644 src/form/validation/derivation-path.ts delete mode 100644 src/interfaces/account.interface.ts create mode 100644 src/interfaces/account.interfaces.ts create mode 100644 src/interfaces/contact.interface.ts create mode 100644 src/modals/import-account/import-account-keystore-file/import-account-keystore-file.form.ts create mode 100644 src/modals/import-account/import-account-keystore-file/import-account-keystore-file.selectors.ts create mode 100644 src/modals/import-account/import-account-keystore-file/import-account-keystore-file.styles.ts rename src/modals/{import-wallet/import-wallet-from-keystore-file-form/import-wallet-from-keystore-file.tsx => import-account/import-account-keystore-file/import-account-keystore-file.tsx} (51%) delete mode 100644 src/modals/import-account/import-account-seed/import-account-seed-derivation-path.form.tsx delete mode 100644 src/modals/import-wallet/import-wallet-from-keystore-file-form/import-wallet-from-keystore-file.form.ts delete mode 100644 src/modals/import-wallet/import-wallet-from-keystore-file-form/import-wallet-from-keystore-file.styles.ts create mode 100644 src/shelter/evm-accounts-migration/gate.tsx create mode 100644 src/shelter/evm-accounts-migration/index.ts create mode 100644 src/shelter/evm-accounts-migration/styles.ts create mode 100644 src/shelter/utils/common.utils.ts create mode 100644 src/shelter/utils/create-account-import-subscriptions.util.ts delete mode 100644 src/shelter/utils/create-import-account-subscription.util.ts create mode 100644 src/store/migrations.types.ts delete mode 100644 src/types/read-only-signer-payload.ts create mode 100644 src/types/tezos-read-only-signer-payload.ts create mode 100644 src/utils/account.utils.spec.ts create mode 100644 src/utils/account.utils.ts create mode 100644 src/utils/get-selected-account-from-wallet.util.ts delete mode 100644 src/utils/keys.util.ts create mode 100644 src/utils/keys.utils.ts rename src/utils/{read-only.signer.util.spec.ts => tezos-read-only.signer.util.spec.ts} (78%) rename src/utils/{read-only.signer.util.ts => tezos-read-only.signer.util.ts} (72%) diff --git a/AGENTS.md b/AGENTS.md index 48048430b..3f4ac30ef 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,18 +1,11 @@ # AGENTS.md – Working Effectively In This Repo -This repository is the Temple Wallet mobile app codebase. Temple Wallet is an open-source wallet for Tezos blockchain, focusing on security and seamless UX. +This repository is the Temple Wallet mobile app codebase. Temple Wallet is an open-source wallet for Tezos blockchain (in transition to support EVM-compatible blockchains), focusing on security and seamless UX. Tech stack: React Native CLI 0.85, React v19.2, TypeScript, Redux Toolkit, RxJS with Redux Observable Optimize for clarity, polish, and performance in every change. -## Core Tenets (Do Not Violate) -1. Polish is a feature. Visual and interaction quality matter as much as correctness. -2. Performance is a feature. Avoid UI hitches, excessive main-thread work, and unnecessary re-rendering. -3. Stay aligned with the existing architecture. Prefer small, targeted improvements over new abstractions. -4. Do not quietly change security-sensitive behavior. Call it out. -5. When instructions are unclear or conflicting, ask for clarification. - ## Commands - `yarn start`: Start Metro server - `yarn android`: Create a debug build for Android and run it on an Android device or simulator diff --git a/package.json b/package.json index 9d695e592..8c640a704 100644 --- a/package.json +++ b/package.json @@ -129,6 +129,7 @@ "ts-action": "^11.0.0", "ts-action-operators": "^9.1.2", "typedarray-to-buffer": "^4.0.0", + "viem": "^2.51.0", "yup": "^0.32.11" }, "devDependencies": { diff --git a/src/apis/youves/index.ts b/src/apis/youves/index.ts index bb459e63e..77cf0d5d4 100644 --- a/src/apis/youves/index.ts +++ b/src/apis/youves/index.ts @@ -3,7 +3,7 @@ import { BigNumber } from 'bignumber.js'; import { catchError, firstValueFrom, forkJoin, from, map, Observable, of } from 'rxjs'; import { EarnOpportunityTypeEnum } from 'src/enums/earn-opportunity-type.enum'; -import { AccountInterface } from 'src/interfaces/account.interface'; +import { Account } from 'src/interfaces/account.interfaces'; import { SavingsItem } from 'src/interfaces/earn-opportunity/savings-item.interface'; import { UserStakeValueInterface } from 'src/interfaces/user-stake-value.interface'; import { ExchangeRateRecord } from 'src/store/currency/currency-state'; @@ -90,7 +90,7 @@ export const getYouvesSavingsItems$ = (tokenUsdExchangeRates: ExchangeRateRecord ).pipe(map(items => items.filter(isDefined))); export const getUserStake = async ( - account: AccountInterface, + account: Account, stakingOrSavingId: string, type: EarnOpportunityTypeEnum, rpcUrl: string diff --git a/src/apis/youves/utils.ts b/src/apis/youves/utils.ts index 364303551..df1bd4286 100644 --- a/src/apis/youves/utils.ts +++ b/src/apis/youves/utils.ts @@ -14,7 +14,8 @@ import { import memoize from 'memoizee'; import { EarnOpportunityTokenStandardEnum } from 'src/enums/earn-opportunity-token-standard.enum'; -import { AccountInterface } from 'src/interfaces/account.interface'; +import { Account } from 'src/interfaces/account.interfaces'; +import { getAccountForTezos } from 'src/utils/account.utils'; import { createReadOnlyTezosToolkit } from 'src/utils/rpc/tezos-toolkit.utils'; import { INDEXER_CONFIG, YOUVES_TOKENS_ICONS } from './constants'; @@ -53,20 +54,23 @@ class MemoryStorage implements Storage { } } -const getCreateEngineCacheKey = (rpcUrl: string, token: AssetDefinition, account?: AccountInterface) => - [rpcUrl, token.id, account?.publicKey].join('_'); +const getCreateEngineCacheKey = (rpcUrl: string, token: AssetDefinition, account?: Account) => + [rpcUrl, token.id, account?.id].join('_'); export const createEngineMemoized = memoize( - (rpcUrl: string, token: AssetDefinition, account?: AccountInterface) => - createEngine({ - tezos: createReadOnlyTezosToolkit(rpcUrl, account), + (rpcUrl: string, token: AssetDefinition, account?: Account) => { + const tezosAccount = account ? getAccountForTezos(account) : null; + + return createEngine({ + tezos: createReadOnlyTezosToolkit(rpcUrl, tezosAccount), contracts: token, storage: new MemoryStorage(), indexerConfig: INDEXER_CONFIG, tokens: mainnetTokens, activeCollateral: contracts.mainnet[0].collateralOptions[0], networkConstants: mainnetNetworkConstants - }), + }); + }, { normalizer: ([rpcUrl, token, account]) => getCreateEngineCacheKey(rpcUrl, token, account) } @@ -75,16 +79,16 @@ export const createEngineMemoized = memoize( const getCreateUnifiedSavingsCacheKey = ( rpcUrl: string, { SAVINGS_V3_POOL_ADDRESS, token }: AssetDefinition, - account: AccountInterface -) => [rpcUrl, SAVINGS_V3_POOL_ADDRESS, token.id, account.publicKey].join('_'); + account: Account +) => [rpcUrl, SAVINGS_V3_POOL_ADDRESS, token.id, account.id].join('_'); export const createUnifiedSavings = memoize( - (rpcUrl: string, assetDefinition: AssetDefinition, account: AccountInterface) => + (rpcUrl: string, assetDefinition: AssetDefinition, account: Account) => new UnifiedSavings( assetDefinition.SAVINGS_V3_POOL_ADDRESS, assetDefinition.token, assetDefinition.token, - createReadOnlyTezosToolkit(rpcUrl, account), + createReadOnlyTezosToolkit(rpcUrl, getAccountForTezos(account)), INDEXER_CONFIG, mainnetNetworkConstants ), diff --git a/src/app/app.tsx b/src/app/app.tsx index 74545a39e..731c52f12 100644 --- a/src/app/app.tsx +++ b/src/app/app.tsx @@ -14,6 +14,7 @@ import { HideBalanceProvider } from 'src/hooks/hide-balance/hide-balance.provide import { HideBootsplashProvider } from 'src/hooks/use-hide-bootsplash'; import { RootStackScreen } from 'src/navigator/root-stack'; import { AppLockContextProvider } from 'src/shelter/app-lock/app-lock'; +import { EvmAccountsMigrationGate } from 'src/shelter/evm-accounts-migration/gate'; import { persistor, store } from 'src/store'; import { TypographyProvider } from 'src/styles/typography.context'; import { ToastProvider } from 'src/toast/toast-provider'; @@ -36,7 +37,9 @@ const NoSentryApp = () => ( - + + + diff --git a/src/components/account-dropdown/account-dropdown-base.tsx b/src/components/account-dropdown/account-dropdown-base.tsx index ee3c268ce..02b7f2842 100644 --- a/src/components/account-dropdown/account-dropdown-base.tsx +++ b/src/components/account-dropdown/account-dropdown-base.tsx @@ -1,16 +1,18 @@ -import React, { memo } from 'react'; +import React, { memo, useCallback, useMemo, useRef } from 'react'; +import { CopyAddressPopup, CopyAddressPopupController } from 'src/components/copy-address-popup'; +import { AccountTypeEnum } from 'src/enums/account-type.enum'; import { useCallbackIfOnline } from 'src/hooks/use-callback-if-online'; -import { AccountBaseInterface } from 'src/interfaces/account.interface'; +import { Account } from 'src/interfaces/account.interfaces'; import { TestIdProps } from 'src/interfaces/test-id.props'; import { ModalsEnum } from 'src/navigator/enums/modals.enum'; import { ScreensEnum } from 'src/navigator/enums/screens.enum'; import { useNavigateToModal, useNavigateToScreen } from 'src/navigator/hooks/use-navigation.hook'; import { WalletSelectors } from 'src/screens/wallet/wallet.selectors'; import { useShelter } from 'src/shelter/use-shelter.hook'; +import { formatSize } from 'src/styles/format-size'; import { AnalyticsEventCategory } from 'src/utils/analytics/analytics-event.enum'; import { useAnalytics } from 'src/utils/analytics/use-analytics.hook'; -import { copyStringToClipboard } from 'src/utils/clipboard.utils'; import { isDefined } from 'src/utils/is-defined'; import { BottomSheetActionButton } from '../bottom-sheet/bottom-sheet-action-button/bottom-sheet-action-button'; @@ -18,31 +20,32 @@ import { Dropdown, DropdownActionButtonsComponent, DropdownValueBaseProps } from import { accountEqualityFn } from './account-equality-fn'; -const ActionButtons: DropdownActionButtonsComponent = ({ onPress }) => { +const ActionButtons: DropdownActionButtonsComponent = ({ closeDropdown }) => { const navigateToModal = useNavigateToModal(); const navigateToScreen = useNavigateToScreen(); const { trackEvent } = useAnalytics(); const { createHdAccount } = useShelter(); const handleCreateNewAccountButtonPress = () => { - createHdAccount(); - onPress(); trackEvent(WalletSelectors.createNewAccountButton, AnalyticsEventCategory.ButtonPress); - }; - - const handleManageAccountsButtonPress = () => { - navigateToScreen({ screen: ScreensEnum.ManageAccounts }); - onPress(); + closeDropdown(); + createHdAccount(); }; const handleImportAccountButtonPress = () => { navigateToModal(ModalsEnum.ChooseAccountImportType); - onPress(); + closeDropdown(); + }; + + const handleManageAccountsButtonPress = () => { + closeDropdown(); + setTimeout(() => navigateToScreen({ screen: ScreensEnum.ManageAccounts }), 100); }; return ( <> @@ -55,7 +58,39 @@ const ActionButtons: DropdownActionButtonsComponent = ({ onPress }) => { ); }; -type Props = DropdownValueBaseProps & TestIdProps; +export type AccountDropdownValueComponent = SyncFC< + { value: Account; disabled?: boolean; isCollectibleScreen?: boolean } & TestIdProps +>; + +type Props = Omit, 'value' | 'renderValue' | 'onValueChange'> & { + value: Account; + renderValue: AccountDropdownValueComponent; + onValueChange: SyncFn; +} & TestIdProps; + +const getAccountSectionTitle = (account: Account) => { + switch (account.type) { + case AccountTypeEnum.HD: + return 'Created'; + case AccountTypeEnum.IMPORTED_CHAIN: + case AccountTypeEnum.IMPORTED_MULTICHAIN: + return 'Imported'; + case AccountTypeEnum.WATCH_ONLY_DEBUG: + return 'Watch Only'; + } +}; + +const getAccountSectionWeight = (account: Account) => { + switch (account.type) { + case AccountTypeEnum.HD: + return 0; + case AccountTypeEnum.IMPORTED_CHAIN: + case AccountTypeEnum.IMPORTED_MULTICHAIN: + return 1; + case AccountTypeEnum.WATCH_ONLY_DEBUG: + return 2; + } +}; export const AccountDropdownBase = memo( ({ @@ -68,23 +103,43 @@ export const AccountDropdownBase = memo( testIDProperties, isCollectibleScreen }) => { - const onLongPressHandler = () => isDefined(value) && copyStringToClipboard(value.publicKeyHash); + const copyAddressPopupRef = useRef(null); + + const groupedList = useMemo( + () => + [...list].sort((accountA, accountB) => getAccountSectionWeight(accountA) - getAccountSectionWeight(accountB)), + [list] + ); + + const onLongPressHandler = useCallback(() => { + copyAddressPopupRef.current?.open(); + }, []); return ( - + <> + renderValue({ ...props, value })} + renderListItem={renderAccountListItem} + getListItemSectionTitle={getAccountSectionTitle} + renderActionButtons={ActionButtons} + onValueChange={value => { + if (isDefined(value)) { + onValueChange(value); + } + }} + onLongPress={onLongPressHandler} + isCollectibleScreen={isCollectibleScreen} + /> + + + ); } ); diff --git a/src/components/account-dropdown/account-dropdown-item/account-dropdown-item.interface.ts b/src/components/account-dropdown/account-dropdown-item/account-dropdown-item.interface.ts index 45be72141..84d187431 100644 --- a/src/components/account-dropdown/account-dropdown-item/account-dropdown-item.interface.ts +++ b/src/components/account-dropdown/account-dropdown-item/account-dropdown-item.interface.ts @@ -1,9 +1,8 @@ -import { AccountBaseInterface } from 'src/interfaces/account.interface'; - -import { IconNameEnum } from '../../icon/icon-name.enum'; +import { IconNameEnum } from 'src/components/icon/icon-name.enum'; +import { Account } from 'src/interfaces/account.interfaces.ts'; export interface AccountDropdownItemProps { - account?: AccountBaseInterface; + account: Account; showFullData?: boolean; actionIconName?: IconNameEnum; isPublicKeyHashTextDisabled?: boolean; diff --git a/src/components/account-dropdown/account-dropdown-item/account-dropdown-item.styles.ts b/src/components/account-dropdown/account-dropdown-item/account-dropdown-item.styles.ts index 9574c95a9..afd0a9106 100644 --- a/src/components/account-dropdown/account-dropdown-item/account-dropdown-item.styles.ts +++ b/src/components/account-dropdown/account-dropdown-item/account-dropdown-item.styles.ts @@ -3,32 +3,44 @@ import { formatSize } from 'src/styles/format-size'; export const useAccountDropdownItemStyles = createUseStylesMemoized(({ colors, typography }) => ({ root: { - flexDirection: 'row' + flexDirection: 'row', + alignItems: 'center' }, - rootModal: { - margin: formatSize(8) + listItemHeader: { + flexDirection: 'row', + alignItems: 'center' }, - infoContainer: { - flexGrow: 1, - flexShrink: 1, + listItemHeaderInfo: { + flex: 1, + flexDirection: 'row', + alignItems: 'center', justifyContent: 'space-between', marginLeft: formatSize(10) }, - smallInfoContainer: { + infoContainer: { flexGrow: 1, flexShrink: 1, - justifyContent: 'center', - marginLeft: formatSize(4) + justifyContent: 'space-between', + marginLeft: formatSize(10) }, upperContainer: { flexDirection: 'row', alignItems: 'center' }, upperContainerFullData: { - justifyContent: 'space-between' + justifyContent: 'space-between', + minHeight: formatSize(40) }, name: { - ...typography.tagline13Tag, + ...typography.body17Semibold, + flexShrink: 1, + marginRight: formatSize(10), + color: colors.black + }, + listItemName: { + ...typography.body15Semibold, + flexShrink: 1, + marginRight: formatSize(10), color: colors.black }, lowerContainer: { @@ -37,9 +49,33 @@ export const useAccountDropdownItemStyles = createUseStylesMemoized(({ colors, t alignItems: 'center' }, balanceText: { - ...typography.numbersRegular13, + ...typography.numbersRegular15, color: colors.black }, + listItemBalanceText: { + ...typography.numbersRegular15, + flexShrink: 0, + color: colors.black + }, + addressesContainer: { + flexDirection: 'row', + flexWrap: 'nowrap', + alignItems: 'center', + gap: formatSize(12), + marginTop: formatSize(16), + marginLeft: formatSize(2) + }, + addressChip: { + flexDirection: 'row', + alignItems: 'center', + maxWidth: formatSize(100) + }, + addressText: { + ...typography.caption13Regular, + flexShrink: 1, + marginLeft: formatSize(4), + color: colors.blue + }, accountNameMargin: { marginLeft: formatSize(10) }, diff --git a/src/components/account-dropdown/account-dropdown-item/account-dropdown-item.tsx b/src/components/account-dropdown/account-dropdown-item/account-dropdown-item.tsx index 09c916de2..1c31a4a8e 100644 --- a/src/components/account-dropdown/account-dropdown-item/account-dropdown-item.tsx +++ b/src/components/account-dropdown/account-dropdown-item/account-dropdown-item.tsx @@ -8,13 +8,15 @@ import { HideBalance } from 'src/components/hide-balance/hide-balance'; import { Icon } from 'src/components/icon/icon'; import { IconNameEnum } from 'src/components/icon/icon-name.enum'; import { RobotIcon } from 'src/components/robot-icon/robot-icon'; +import { getSeedFromAccount } from 'src/components/robot-icon/robot-icon.utils.ts'; import { TruncatedText } from 'src/components/truncated-text'; -import { WalletAddress } from 'src/components/wallet-address/wallet-address'; import { useNetworkInfo } from 'src/hooks/use-network-info.hook'; -import { AccountBaseInterface, emptyAccountBase } from 'src/interfaces/account.interface'; +import { Account } from 'src/interfaces/account.interfaces.ts'; import { useAllCollectiblesDetailsSelector } from 'src/store/collectibles/collectibles-selectors'; import { useContactsSelector } from 'src/store/contact-book/contact-book-selectors'; +import { useSaplingAddressForAccount } from 'src/store/sapling/sapling-selectors.ts'; import { formatSize } from 'src/styles/format-size'; +import { getAccountAddressForEvm, getAccountAddressForTezos } from 'src/utils/account.utils'; import { useCurrentAccountCollectiblesWithPositiveBalance } from 'src/utils/assets/hooks'; import { conditionalStyle } from 'src/utils/conditional-style'; import { formatNumber } from 'src/utils/format-price'; @@ -24,26 +26,24 @@ import { useTezosTokenOfKnownAccount } from 'src/utils/wallet.utils'; import { AccountDropdownItemProps } from './account-dropdown-item.interface'; import { - useAccountDropdownItemStyles, - useAccountDropdownItemCollectiblesInfoStyles + useAccountDropdownItemCollectiblesInfoStyles, + useAccountDropdownItemStyles } from './account-dropdown-item.styles'; const COLLECTIBLES_ROBOT_ICON_SIZE = 76; export const AccountDropdownItem = memo( - ({ - account = emptyAccountBase, - showFullData = true, - actionIconName, - isPublicKeyHashTextDisabled, - isCollectibleScreen = false - }) => { + ({ account, showFullData = true, actionIconName, isCollectibleScreen = false }) => { const styles = useAccountDropdownItemStyles(); - const tezos = useTezosTokenOfKnownAccount(account.publicKeyHash); + + const tezos = useTezosTokenOfKnownAccount(account.id); return ( - + ( ]} > {account.name} - {isDefined(actionIconName) && } + {isDefined(actionIconName) && } - {isCollectibleScreen ? ( - - ) : ( - - )} + {isCollectibleScreen && } {showFullData && !isCollectibleScreen && ( @@ -77,10 +69,60 @@ export const AccountDropdownItem = memo( } ); -export const renderAccountListItem: DropdownListItemComponent = ({ item, isSelected }) => ( - +export const AccountDropdownTriggerItem = memo(props => ); + +const AccountDropdownListItem = memo>(({ account }) => { + const styles = useAccountDropdownItemStyles(); + const saplingAddress = useSaplingAddressForAccount(account); + + const tezosAddress = getAccountAddressForTezos(account); + const evmAddress = getAccountAddressForEvm(account); + + const tezos = useTezosTokenOfKnownAccount(account.id); + + return ( + <> + + + + {account.name} + + + + + + + + {isDefined(tezosAddress) && } + {isDefined(saplingAddress) && ( + + )} + {isDefined(evmAddress) && } + + + ); +}); + +export const renderAccountListItem: DropdownListItemComponent = ({ item }) => ( + ); +interface AccountAddressChipProps { + address: string; + iconName: IconNameEnum; +} + +const AccountAddressChip = memo(({ address, iconName }) => { + const styles = useAccountDropdownItemStyles(); + + return ( + + + {truncateAddress(address)} + + ); +}); + const CollectiblesInfo = memo(() => { const styles = useAccountDropdownItemCollectiblesInfoStyles(); @@ -130,3 +172,6 @@ const CollectiblesInfo = memo(() => { ); }); + +const truncateAddress = (address: string) => + address.length > 10 ? `${address.slice(0, 3)}...${address.slice(-4)}` : address; diff --git a/src/components/account-dropdown/account-equality-fn.ts b/src/components/account-dropdown/account-equality-fn.ts index e8e41c030..e4c59ae36 100644 --- a/src/components/account-dropdown/account-equality-fn.ts +++ b/src/components/account-dropdown/account-equality-fn.ts @@ -1,7 +1,5 @@ -import { AccountBaseInterface } from 'src/interfaces/account.interface'; -import { isDefined } from 'src/utils/is-defined'; +import { Account } from 'src/interfaces/account.interfaces'; import { DropdownEqualityFn } from '../dropdown/dropdown'; -export const accountEqualityFn: DropdownEqualityFn = (item, value) => - isDefined(value) && item.publicKeyHash === value.publicKeyHash; +export const accountEqualityFn: DropdownEqualityFn = (item, value) => item.id === value?.id; diff --git a/src/components/account-dropdown/account-form-dropdown.tsx b/src/components/account-dropdown/account-form-dropdown.tsx index 8687c85fc..fbea6ab01 100644 --- a/src/components/account-dropdown/account-form-dropdown.tsx +++ b/src/components/account-dropdown/account-form-dropdown.tsx @@ -1,7 +1,7 @@ import React, { FC } from 'react'; import { FormDropdown } from 'src/form/form-dropdown'; -import { AccountBaseInterface } from 'src/interfaces/account.interface'; +import { Account } from 'src/interfaces/account.interfaces.ts'; import { TestIdProps } from 'src/interfaces/test-id.props'; import { DropdownValueComponent } from '../dropdown/dropdown'; @@ -13,12 +13,12 @@ import { accountEqualityFn } from './account-equality-fn'; interface Props extends TestIdProps { name: string; - list: AccountBaseInterface[]; + list: Account[]; } -const renderAccountValue: DropdownValueComponent = ({ value }) => ( +const renderAccountValue: DropdownValueComponent = ({ value }) => ( - + {value && } ); diff --git a/src/components/account-dropdown/account-form-section-dropdown.tsx b/src/components/account-dropdown/account-form-section-dropdown.tsx deleted file mode 100644 index b5d7c6011..000000000 --- a/src/components/account-dropdown/account-form-section-dropdown.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import React, { FC } from 'react'; - -import { FormSectionDropdown } from 'src/form/form-section-dropdown'; -import { AccountBaseInterface } from 'src/interfaces/account.interface'; -import { SectionDropdownDataInterface } from 'src/interfaces/section-dropdown-data.interface'; -import { TestIdProps } from 'src/interfaces/test-id.props'; - -import { DropdownValueComponent } from '../dropdown/dropdown'; -import { DropdownItemContainer } from '../dropdown/dropdown-item-container/dropdown-item-container'; -import { IconNameEnum } from '../icon/icon-name.enum'; - -import { AccountDropdownItem, renderAccountListItem } from './account-dropdown-item/account-dropdown-item'; -import { accountEqualityFn } from './account-equality-fn'; - -interface Props extends TestIdProps { - name: string; - list: Array>; - setSearchValue: SyncFn; -} - -const renderAccountValue: DropdownValueComponent = ({ value }) => ( - - - -); - -export const AccountFormSectionDropdown: FC = ({ name, list, setSearchValue, testID, testIDProperties }) => ( - -); diff --git a/src/components/account-dropdown/current-account-dropdown.tsx b/src/components/account-dropdown/current-account-dropdown.tsx index 655aa61a8..439c7954c 100644 --- a/src/components/account-dropdown/current-account-dropdown.tsx +++ b/src/components/account-dropdown/current-account-dropdown.tsx @@ -1,42 +1,35 @@ import React, { memo, useCallback } from 'react'; import { View } from 'react-native'; -import { useDispatch } from 'react-redux'; -import { isAndroid } from 'src/config/system'; -import { AccountBaseInterface } from 'src/interfaces/account.interface'; +import { Account } from 'src/interfaces/account.interfaces.ts'; import { TestIdProps } from 'src/interfaces/test-id.props'; -import { setSelectedAccountAction } from 'src/store/wallet/wallet-actions'; -import { useSelectedAccountSelector, useVisibleAccountsListSelector } from 'src/store/wallet/wallet-selectors'; +import { dispatch } from 'src/store'; +import { setSelectedAccountIdAction } from 'src/store/wallet/wallet-actions'; +import { useAccount, useAllVisibleAccounts } from 'src/store/wallet/wallet-selectors'; -import { DropdownValueComponent, DropdownValueProps } from '../dropdown/dropdown'; +import { DropdownValueProps } from '../dropdown/dropdown'; import { IconNameEnum } from '../icon/icon-name.enum'; -import { AccountDropdownBase } from './account-dropdown-base'; -import { AccountDropdownItem, renderAccountListItem } from './account-dropdown-item/account-dropdown-item'; +import { AccountDropdownBase, AccountDropdownValueComponent } from './account-dropdown-base'; +import { AccountDropdownTriggerItem, renderAccountListItem } from './account-dropdown-item/account-dropdown-item'; import { CurrentAccountDropdownStyles } from './current-account-dropdown.styles'; -const renderAccountValue: DropdownValueComponent = ({ value, isCollectibleScreen }) => ( - ( + ); -type Props = Omit, 'list' | 'value' | 'onValueChange'> & TestIdProps; +type Props = Omit, 'list' | 'value' | 'onValueChange'> & TestIdProps; export const CurrentAccountDropdown = memo(({ testID, testIDProperties, isCollectibleScreen }) => { - const selectedAccount = useSelectedAccountSelector(); - const visibleAccounts = useVisibleAccountsListSelector(); + const selectedAccount = useAccount(); + const visibleAccounts = useAllVisibleAccounts(); - const dispatch = useDispatch(); - - const onValueChange = useCallback( - (value: AccountBaseInterface | undefined) => dispatch(setSelectedAccountAction(value?.publicKeyHash)), - [] - ); + const onValueChange = useCallback((value: Account) => dispatch(setSelectedAccountIdAction(value.id)), []); return ( diff --git a/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts b/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts index 990020f76..d2f0ccfab 100644 --- a/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts +++ b/src/components/activity-groups-list/activity-group-item/activity-group-type/use-activity-group-info.hook.ts @@ -5,7 +5,7 @@ import { IconNameEnum } from 'src/components/icon/icon-name.enum'; import { SAPLING_CONTRACT_ADDRESS } from 'src/config/sapling'; import { ActivityTypeEnum } from 'src/enums/activity-type.enum'; import { ActivityGroup, emptyActivity } from 'src/interfaces/activity.interface'; -import { useCurrentAccountPkhSelector } from 'src/store/wallet/wallet-selectors'; +import { useAccountAddressForTezos } from 'src/store/wallet/wallet-selectors'; import { useColors } from 'src/styles/use-colors'; import { isString } from 'src/utils/is-string'; import { ZERO } from 'src/utils/number.util'; @@ -21,7 +21,7 @@ const isSaplingOperation = (group: ActivityGroup): boolean => export const useActivityGroupInfo = (group: ActivityGroup) => { const colors = useColors(); - const publicKeyHash = useCurrentAccountPkhSelector(); + const publicKeyHash = useAccountAddressForTezos(); return useMemo<[IconNameEnum, string, string]>(() => { if (isSaplingOperation(group)) { diff --git a/src/components/bottom-sheet/bottom-sheet-action-button/bottom-sheet-action-button.styles.ts b/src/components/bottom-sheet/bottom-sheet-action-button/bottom-sheet-action-button.styles.ts index 130b09bc3..910183e3c 100644 --- a/src/components/bottom-sheet/bottom-sheet-action-button/bottom-sheet-action-button.styles.ts +++ b/src/components/bottom-sheet/bottom-sheet-action-button/bottom-sheet-action-button.styles.ts @@ -10,6 +10,9 @@ export const useBottomSheetActionButtonStyles = createUseStyles(({ colors, typog borderColor: colors.lines, borderBottomWidth: formatSize(1) }, + topBorder: { + borderTopWidth: formatSize(1) + }, title: { ...typography.body17Regular, color: colors.orange diff --git a/src/components/bottom-sheet/bottom-sheet-action-button/bottom-sheet-action-button.tsx b/src/components/bottom-sheet/bottom-sheet-action-button/bottom-sheet-action-button.tsx index 1e750e766..41dfb819d 100644 --- a/src/components/bottom-sheet/bottom-sheet-action-button/bottom-sheet-action-button.tsx +++ b/src/components/bottom-sheet/bottom-sheet-action-button/bottom-sheet-action-button.tsx @@ -16,6 +16,7 @@ interface Props extends Pick; iconLeftName?: IconNameEnum; + showTopBorder?: boolean; } export const BottomSheetActionButton: FC = ({ @@ -24,6 +25,7 @@ export const BottomSheetActionButton: FC = ({ style, titleStyle, iconLeftName, + showTopBorder = false, onPress, testID }) => { @@ -32,7 +34,12 @@ export const BottomSheetActionButton: FC = ({ return ( diff --git a/src/components/bottom-sheet/use-bottom-sheet-controller.ts b/src/components/bottom-sheet/use-bottom-sheet-controller.ts index de2e359f0..d8ea88cbc 100644 --- a/src/components/bottom-sheet/use-bottom-sheet-controller.ts +++ b/src/components/bottom-sheet/use-bottom-sheet-controller.ts @@ -1,12 +1,15 @@ import BottomSheet from '@gorhom/bottom-sheet'; import { Ref, useMemo, useRef } from 'react'; +import { WithSpringConfig, WithTimingConfig } from 'react-native-reanimated'; import { isDefined } from 'src/utils/is-defined'; +type BottomSheetCallback = (config?: WithSpringConfig | WithTimingConfig) => void; + interface BottomSheetController { ref: Ref; - open: EmptyFn; - close: EmptyFn; + open: BottomSheetCallback; + close: BottomSheetCallback; } export interface BottomSheetControllerProps { @@ -16,8 +19,8 @@ export interface BottomSheetControllerProps { export const useBottomSheetController = (): BottomSheetController => { const ref = useRef(null); - const open = () => void (isDefined(ref.current) && ref.current.expand()); - const close = () => void (isDefined(ref.current) && ref.current.close()); + const open: BottomSheetCallback = config => void (isDefined(ref.current) && ref.current.expand(config)); + const close: BottomSheetCallback = config => void (isDefined(ref.current) && ref.current.close(config)); - return useMemo(() => ({ ref, open, close }), []); + return useMemo(() => ({ ref, open, close }), []); }; diff --git a/src/components/contact-dropdown/contact-equality-fn.ts b/src/components/contact-dropdown/contact-equality-fn.ts new file mode 100644 index 000000000..e350c0b06 --- /dev/null +++ b/src/components/contact-dropdown/contact-equality-fn.ts @@ -0,0 +1,6 @@ +import { Contact } from 'src/interfaces/contact.interface.ts'; + +import { DropdownEqualityFn } from '../dropdown/dropdown'; + +export const contactEqualityFn: DropdownEqualityFn = (item, value) => + item.name === value?.name && item.address === value?.address; diff --git a/src/components/contact-dropdown/contact-form-section-dropdown.tsx b/src/components/contact-dropdown/contact-form-section-dropdown.tsx new file mode 100644 index 000000000..c45d55112 --- /dev/null +++ b/src/components/contact-dropdown/contact-form-section-dropdown.tsx @@ -0,0 +1,47 @@ +import React, { FC } from 'react'; +import { Text } from 'react-native'; + +import { FormSectionDropdown } from 'src/form/form-section-dropdown'; +import { Contact } from 'src/interfaces/contact.interface.ts'; +import { SectionDropdownDataInterface } from 'src/interfaces/section-dropdown-data.interface'; +import { TestIdProps } from 'src/interfaces/test-id.props'; + +import { DropdownListItemComponent, DropdownValueComponent } from '../dropdown/dropdown'; +import { DropdownItemContainer } from '../dropdown/dropdown-item-container/dropdown-item-container'; + +import { contactEqualityFn } from './contact-equality-fn.ts'; + +interface Props extends TestIdProps { + name: string; + list: Array>; + setSearchValue: SyncFn; +} + +const renderContactValue: DropdownValueComponent = ({ value }) => ( + + {value?.name} + {value?.address} + +); + +const renderContactListItem: DropdownListItemComponent = ({ item }) => ( + + {item.name} + {item.address} + +); + +export const ContactFormSectionDropdown: FC = ({ name, list, setSearchValue, testID, testIDProperties }) => ( + +); diff --git a/src/components/copy-address-popup/index.tsx b/src/components/copy-address-popup/index.tsx new file mode 100644 index 000000000..86fbf4d51 --- /dev/null +++ b/src/components/copy-address-popup/index.tsx @@ -0,0 +1,109 @@ +import React, { memo, Ref, useCallback, useImperativeHandle, useMemo, useState } from 'react'; +import { Modal, Text, TouchableWithoutFeedback, View } from 'react-native'; + +import { Icon } from 'src/components/icon/icon'; +import { IconNameEnum } from 'src/components/icon/icon-name.enum'; +import { SafeTouchableOpacity } from 'src/components/safe-touchable-opacity'; +import { TruncatedText } from 'src/components/truncated-text'; +import { Account } from 'src/interfaces/account.interfaces'; +import { useSaplingAddressForAccount } from 'src/store/sapling/sapling-selectors.ts'; +import { formatSize } from 'src/styles/format-size'; +import { getAccountAddressForEvm, getAccountAddressForTezos } from 'src/utils/account.utils'; +import { copyStringToClipboard } from 'src/utils/clipboard.utils'; +import { isDefined } from 'src/utils/is-defined'; +import { isTruthy } from 'src/utils/is-truthy.ts'; + +import { useCopyAddressPopupStyles } from './styles'; + +export interface CopyAddressPopupController { + open: EmptyFn; + close: EmptyFn; +} + +interface CopyAddressOption { + label: string; + address: string; + iconName: IconNameEnum; +} + +interface Props { + controlRef: Ref; + account: Account; +} + +export const CopyAddressPopup = memo(({ controlRef, account }) => { + const [isVisible, setIsVisible] = useState(false); + + const styles = useCopyAddressPopupStyles(); + const saplingAddress = useSaplingAddressForAccount(account); + + const options = useMemo(() => { + const tezosAddress = getAccountAddressForTezos(account); + const evmAddress = getAccountAddressForEvm(account); + + return [ + isDefined(tezosAddress) && { + label: 'Tezos', + address: tezosAddress, + iconName: IconNameEnum.TezToken + }, + isDefined(saplingAddress) && { + label: 'Shielded', + address: saplingAddress, + iconName: IconNameEnum.TezShieldedToken + }, + isDefined(evmAddress) && { + label: 'Etherlink', + address: evmAddress, + iconName: IconNameEnum.EtherlinkToken + } + ].filter(isTruthy); + }, [account, saplingAddress]); + + const onClose = useCallback(() => setIsVisible(false), []); + + useImperativeHandle( + controlRef, + () => ({ + open: () => setIsVisible(true), + close: onClose + }), + [onClose] + ); + + const handleOptionPress = (address: string) => { + copyStringToClipboard(address); + onClose(); + }; + + return ( + + + + + + Copy address + + {options.map(({ label, address, iconName }) => ( + + handleOptionPress(address)}> + + {label} + + {address} + + + + + + + + + ))} + + + + + + ); +}); diff --git a/src/components/copy-address-popup/styles.ts b/src/components/copy-address-popup/styles.ts new file mode 100644 index 000000000..5f376f057 --- /dev/null +++ b/src/components/copy-address-popup/styles.ts @@ -0,0 +1,59 @@ +import { createUseStylesMemoized } from 'src/styles/create-use-styles'; +import { formatSize } from 'src/styles/format-size'; + +export const useCopyAddressPopupStyles = createUseStylesMemoized(({ colors, typography }) => ({ + backdrop: { + flex: 1 + }, + container: { + position: 'absolute', + top: formatSize(115), + left: formatSize(16), + width: formatSize(207), + borderRadius: formatSize(12), + backgroundColor: colors.pageBG, + borderWidth: formatSize(1), + borderColor: colors.lines, + overflow: 'hidden' + }, + title: { + ...typography.caption13Regular, + backgroundColor: colors.cardBG, + paddingVertical: formatSize(13), + textAlign: 'center', + color: colors.gray1 + }, + option: { + paddingHorizontal: formatSize(16), + paddingVertical: formatSize(8), + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + borderTopWidth: formatSize(1), + borderColor: colors.lines + }, + optionInfo: { + flex: 1, + marginRight: formatSize(16) + }, + optionLabel: { + ...typography.body15Semibold, + color: colors.black, + marginBottom: formatSize(8) + }, + optionAddress: { + ...typography.caption13Regular, + width: formatSize(80), + color: colors.blue + }, + iconContainer: { + width: formatSize(24), + height: formatSize(24), + borderRadius: formatSize(100), + borderWidth: formatSize(1), + borderColor: colors.gray4, + alignItems: 'center', + justifyContent: 'center', + backgroundColor: colors.cardBG + } +})); diff --git a/src/components/dropdown/dropdown.tsx b/src/components/dropdown/dropdown.tsx index bdcde37a8..f649f8e34 100644 --- a/src/components/dropdown/dropdown.tsx +++ b/src/components/dropdown/dropdown.tsx @@ -1,5 +1,5 @@ import React, { memo, useCallback, useMemo, useRef } from 'react'; -import { FlatListProps, ListRenderItemInfo, StyleProp, View, ViewStyle, ActivityIndicator } from 'react-native'; +import { FlatListProps, ListRenderItemInfo, StyleProp, Text, View, ViewStyle, ActivityIndicator } from 'react-native'; import { FlatList } from 'react-native-gesture-handler'; import { emptyComponent } from 'src/config/general'; @@ -34,6 +34,7 @@ export interface DropdownProps extends Pick, 'keyExtractor'> equalityFn: DropdownEqualityFn; renderValue: DropdownValueComponent; renderListItem: DropdownListItemComponent; + getListItemSectionTitle?: (item: T) => string | undefined; renderActionButtons?: DropdownActionButtonsComponent; onLongPress?: EmptyFn; } @@ -65,7 +66,7 @@ export type DropdownListItemComponent = SyncFC<{ }>; export type DropdownActionButtonsComponent = SyncFC<{ - onPress: EmptyFn; + closeDropdown: EmptyFn; }>; const DropdownComponent = ({ @@ -83,6 +84,7 @@ const DropdownComponent = ({ equalityFn, renderValue, renderListItem, + getListItemSectionTitle, renderActionButtons = emptyComponent, keyExtractor, onValueChange, @@ -101,6 +103,10 @@ const DropdownComponent = ({ const renderItem = useCallback( ({ item, index }: ListRenderItemInfo) => { const isSelected = equalityFn(item, value); + const sectionTitle = getListItemSectionTitle?.(item); + const previousItem = index > 0 ? list[index - 1] : undefined; + const previousSectionTitle = previousItem ? getListItemSectionTitle?.(previousItem) : undefined; + const shouldRenderSectionTitle = isDefined(sectionTitle) && sectionTitle !== previousSectionTitle; const handlePress = () => { onValueChange(item); @@ -108,20 +114,34 @@ const DropdownComponent = ({ }; return ( - - - {renderListItem({ item, isSelected })} - - + <> + {shouldRenderSectionTitle && {sectionTitle}} + + + {renderListItem({ item, isSelected })} + + + ); }, - [equalityFn, value, onValueChange, dropdownBottomSheetController.close, renderListItem, itemTestIDPropertiesFn] + [ + equalityFn, + value, + getListItemSectionTitle, + list, + onValueChange, + dropdownBottomSheetController.close, + itemTestIDPropertiesFn, + styles.sectionHeaderText, + itemContainerStyle, + renderListItem + ] ); const scroll = useCallback(() => { @@ -182,7 +202,7 @@ const DropdownComponent = ({ {renderActionButtons({ - onPress: () => dropdownBottomSheetController.close() + closeDropdown: () => dropdownBottomSheetController.close({ duration: 100 }) })} diff --git a/src/components/dropdown/section-dropdown.tsx b/src/components/dropdown/section-dropdown.tsx index bc954edd4..e5dbee9b5 100644 --- a/src/components/dropdown/section-dropdown.tsx +++ b/src/components/dropdown/section-dropdown.tsx @@ -33,17 +33,17 @@ export interface SectionDropdownProps extends TestIdProps, Pick { - value?: T; + value: T; itemHeight?: number; list: Array>; disabled?: boolean; - onValueChange: SyncFn; + onValueChange: SyncFn; } -type DropdownEqualityFn = (item: T, value?: T) => boolean; +type DropdownEqualityFn = (item: T, value: T) => boolean; type DropdownValueComponent = SyncFC<{ - value?: T; + value: T; disabled?: boolean; }>; diff --git a/src/components/error-boundary/content.tsx b/src/components/error-boundary/content.tsx index cacd16d1d..615172227 100644 --- a/src/components/error-boundary/content.tsx +++ b/src/components/error-boundary/content.tsx @@ -29,6 +29,7 @@ import { Icon } from '../icon/icon'; import { IconNameEnum } from '../icon/icon-name.enum'; import { useErrorBoundaryContentStyles } from './content.styles'; +import { BoundaryError } from './errors'; interface ErrorBoundaryContentProps { error: Error; @@ -43,6 +44,7 @@ export const ErrorBoundaryContent = memo( const errorMessage = isString(whileMessage) ? `Oops! Something unexpected happened while ${whileMessage}.` : 'Oops! Something unexpected happened.'; + const isBoundaryError = error instanceof BoundaryError; const styles = useErrorBoundaryContentStyles(); const colors = useColors(); @@ -71,8 +73,10 @@ export const ErrorBoundaryContent = memo( color={colors.destructive} style={styles.icon} /> - {errorMessage} Even our app wasn't ready for that move. - {error.message ?? 'No error message'} + + {isBoundaryError ? error.message : `${errorMessage} Even our app wasn't ready for that move.`} + + {!isBoundaryError && {error.message ?? 'No error message'}} {isDefined(error.stack) && ( diff --git a/src/components/error-boundary/errors.ts b/src/components/error-boundary/errors.ts new file mode 100644 index 000000000..bc950ffd4 --- /dev/null +++ b/src/components/error-boundary/errors.ts @@ -0,0 +1,18 @@ +import { StacksEnum } from 'src/navigator/enums/stacks.enum'; +import { globalNavigationRef } from 'src/navigator/global-nav-ref'; + +export class BoundaryError extends Error { + constructor(public readonly message: string, public readonly beforeTryAgain: EmptyFn) { + super(message); + + Object.setPrototypeOf(this, BoundaryError.prototype); + } +} + +export class DeadEndBoundaryError extends BoundaryError { + constructor() { + super('🚧 🛠️ 🔜 🏗️', () => globalNavigationRef.current?.resetRoot({ routes: [{ name: StacksEnum.MainStack }] })); + + Object.setPrototypeOf(this, DeadEndBoundaryError.prototype); + } +} diff --git a/src/components/error-boundary/index.tsx b/src/components/error-boundary/index.tsx index e5e5629fb..5b62f199d 100644 --- a/src/components/error-boundary/index.tsx +++ b/src/components/error-boundary/index.tsx @@ -6,13 +6,9 @@ import { store } from 'src/store'; import { sendErrorAnalyticsEvent } from 'src/utils/analytics/analytics.util'; import { ErrorBoundaryContent } from './content'; +import { BoundaryError } from './errors'; -// TODO: export when it becomes necessary -class BoundaryError extends Error { - constructor(public readonly message: string, public readonly beforeTryAgain: EmptyFn) { - super(message); - } -} +export { DeadEndBoundaryError } from './errors'; type Props = PropsWithChildren<{ Fallback?: FC; diff --git a/src/components/header-card-action-buttons/header-card-action-buttons.tsx b/src/components/header-card-action-buttons/header-card-action-buttons.tsx index 30e7e1b72..3b7f1f0c6 100644 --- a/src/components/header-card-action-buttons/header-card-action-buttons.tsx +++ b/src/components/header-card-action-buttons/header-card-action-buttons.tsx @@ -16,9 +16,11 @@ import { WalletSelectors } from 'src/screens/wallet/wallet.selectors'; import { useAppLock } from 'src/shelter/app-lock/app-lock'; import { setOnRampOverlayStateAction } from 'src/store/settings/settings-actions'; import { useIsShowLoaderSelector } from 'src/store/settings/settings-selectors'; +import { useAccount } from 'src/store/wallet/wallet-selectors'; import { formatSize } from 'src/styles/format-size'; import { showErrorToast } from 'src/toast/toast.utils'; import { emptyToken, TokenInterface } from 'src/token/interfaces/token.interface'; +import { getAccountAddressForTezos } from 'src/utils/account.utils'; import { isDefined } from 'src/utils/is-defined'; import { openUrl } from 'src/utils/linking'; import { useTezosTokenOfCurrentAccount } from 'src/utils/wallet.utils'; @@ -45,19 +47,21 @@ export const HeaderCardActionButtons: FC = ({ token, onSendPress }) => { const { isLocked } = useAppLock(); const atBootsplash = useAtBootsplash(); const canUseOnRamp = useCanUseOnRamp(); + const selectedAccount = useAccount(); const { metadata, isTezosNode, isTezosMainnet } = useNetworkInfo(); const tezosToken = useTezosTokenOfCurrentAccount(); const { balance } = useTotalBalance(); const styles = useHeaderCardActionButtonsStyles(); const defaultStyleConfig = useButtonMediumStyleConfig(); const isLoaderBeingShown = useIsShowLoaderSelector(); + const canUseTezos = Boolean(getAccountAddressForTezos(selectedAccount)); const isTezBalanceTooLow = isDefined(token.address) && token.address === tezosToken.address && tezosToken.balance === emptyToken.balance; const errorMessage = isTezBalanceTooLow ? `You need to have ${metadata.symbol} to pay gas fee` : 'Balance is zero'; const emptyBalance = token.balance === emptyToken.balance || tezosToken.balance === emptyToken.balance; - const disabledSendButton = emptyBalance && LIMIT_FIN_FEATURES; + const disabledSendButton = !canUseTezos || (emptyBalance && LIMIT_FIN_FEATURES); const actionButtonStylesOverrides = useMemo( () => ({ @@ -141,6 +145,7 @@ export const HeaderCardActionButtons: FC = ({ token, onSendPress }) => { <> (isTezosNode ? navigateToScreen({ screen: ScreensEnum.Buy }) : openUrl(CHAINBITS_URL))} @@ -154,7 +159,7 @@ export const HeaderCardActionButtons: FC = ({ token, onSendPress }) => { navigateToScreen({ screen: ScreensEnum.Earn })} @@ -169,6 +174,7 @@ export const HeaderCardActionButtons: FC = ({ token, onSendPress }) => { - - + diff --git a/src/components/icon/assets/tokens/etherlink.svg b/src/components/icon/assets/tokens/etherlink.svg new file mode 100644 index 000000000..29db914f0 --- /dev/null +++ b/src/components/icon/assets/tokens/etherlink.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/components/icon/icon-name.enum.ts b/src/components/icon/icon-name.enum.ts index 5d568efd8..038ae0b43 100644 --- a/src/components/icon/icon-name.enum.ts +++ b/src/components/icon/icon-name.enum.ts @@ -58,6 +58,7 @@ export enum IconNameEnum { Close = 'Close', TezToken = 'TezToken', TezShieldedToken = 'TezShieldedToken', + EtherlinkToken = 'EtherlinkToken', FilmToken = 'FilmToken', TzBtcToken = 'TzBtcToken', NoNameToken = 'NoNameToken', diff --git a/src/components/icon/icon-name.map.ts b/src/components/icon/icon-name.map.ts index 1ec78a75c..d48451f97 100644 --- a/src/components/icon/icon-name.map.ts +++ b/src/components/icon/icon-name.map.ts @@ -158,6 +158,7 @@ import TempleLogoWithTextIcon from './assets/temple-logo-with-text.svg'; import TempleLogoIcon from './assets/temple-logo.svg'; import TerminalIcon from './assets/terminal.svg'; import TezWalletIcon from './assets/tez-wallet.svg'; +import EtherlinkTokenIcon from './assets/tokens/etherlink.svg'; import FilmTokenIcon from './assets/tokens/film.svg'; import NoNameTokenIcon from './assets/tokens/no-name.svg'; import SwapTokenPlaceholderIcon from './assets/tokens/swap-token-placeholder.svg'; @@ -246,6 +247,7 @@ export const iconNameMap: Record> = { [IconNameEnum.Close]: CloseIcon, [IconNameEnum.TezToken]: TezTokenIcon, [IconNameEnum.TezShieldedToken]: TezShieldedTokenIcon, + [IconNameEnum.EtherlinkToken]: EtherlinkTokenIcon, [IconNameEnum.FilmToken]: FilmTokenIcon, [IconNameEnum.TzBtcToken]: TzBtcTokenIcon, [IconNameEnum.InfoFilled]: InfoFilledIcon, diff --git a/src/components/promotion-item/index.tsx b/src/components/promotion-item/index.tsx index 9e3cf315f..9cb0989b2 100644 --- a/src/components/promotion-item/index.tsx +++ b/src/components/promotion-item/index.tsx @@ -13,7 +13,7 @@ import { PromotionVariantEnum } from 'src/enums/promotion-variant.enum'; import { useAdTemporaryHiding } from 'src/hooks/use-ad-temporary-hiding.hook'; import { useAuthorisedInterval } from 'src/hooks/use-authed-interval'; import { useIsPartnersPromoEnabledSelector } from 'src/store/partners-promotion/partners-promotion-selectors'; -import { useCurrentAccountPkhSelector } from 'src/store/wallet/wallet-selectors'; +import { useAccountAddressForTezos } from 'src/store/wallet/wallet-selectors'; import { MS_IN_SECOND, SECONDS_IN_MINUTE } from 'src/utils/date.utils'; import { usePromotionItemStyles } from './styles'; @@ -46,7 +46,7 @@ export const PromotionItem: FCWithRef = ({ onImpression, onLayout }) => { - const accountPkh = useCurrentAccountPkhSelector(); + const accountPkh = useAccountAddressForTezos(); const isImageAd = variant === PromotionVariantEnum.Image; const styles = usePromotionItemStyles(); diff --git a/src/components/robot-icon/robot-icon.tsx b/src/components/robot-icon/robot-icon.tsx index 39b5e71d5..3fecc9069 100644 --- a/src/components/robot-icon/robot-icon.tsx +++ b/src/components/robot-icon/robot-icon.tsx @@ -12,9 +12,10 @@ import { useRobotIconStyles } from './robot-icon.styles'; interface Props { seed: string; size?: number; + padding?: number; } -export const RobotIcon: FC = ({ seed, size = formatSize(44) }) => { +export const RobotIcon: FC = ({ seed, size = formatSize(40), padding = formatSize(8) }) => { const styles = useRobotIconStyles(); const xml = useMemo( @@ -22,12 +23,12 @@ export const RobotIcon: FC = ({ seed, size = formatSize(44) }) => { createAvatar(bottts, { seed, size, - scale: fractionToPercentage((size - formatSize(8)) / size).toNumber(), + scale: fractionToPercentage((size - padding) / size).toNumber(), clip: false }) .toString() .replace('undefined', ''), - [seed, size] + [seed, size, padding] ); return ( diff --git a/src/components/robot-icon/robot-icon.utils.ts b/src/components/robot-icon/robot-icon.utils.ts new file mode 100644 index 000000000..edda4837b --- /dev/null +++ b/src/components/robot-icon/robot-icon.utils.ts @@ -0,0 +1,9 @@ +import { Account } from 'src/interfaces/account.interfaces.ts'; +import { getAccountAddressForEvm, getAccountAddressForTezos } from 'src/utils/account.utils.ts'; + +export const getSeedFromAccount = (account: Account) => { + const tezosAddress = getAccountAddressForTezos(account); + const evmAddress = getAccountAddressForEvm(account); + + return tezosAddress ?? evmAddress ?? ''; +}; diff --git a/src/components/sorter/sorter.tsx b/src/components/sorter/sorter.tsx index 286427769..5ff714ab7 100644 --- a/src/components/sorter/sorter.tsx +++ b/src/components/sorter/sorter.tsx @@ -44,7 +44,7 @@ export const Sorter = ({ Sort by revealSelectBottomSheetController.open()} testID={testID} > {sortFieldsLabels[sortValue]} diff --git a/src/components/styled-radio-group/index.tsx b/src/components/styled-radio-group/index.tsx index 5d0ea7351..40b074c06 100644 --- a/src/components/styled-radio-group/index.tsx +++ b/src/components/styled-radio-group/index.tsx @@ -7,7 +7,7 @@ import { useColors } from 'src/styles/use-colors'; import { RadioItemInterface, RadioGroup } from './radio-group'; import { useStyledRadioButtonsGroupStyles } from './styles'; -export interface StyledRadioGroupProps { +interface StyledRadioGroupProps { items: RadioItemInterface[]; } diff --git a/src/config/wallet.const.ts b/src/config/wallet.const.ts new file mode 100644 index 000000000..a1ff3da8d --- /dev/null +++ b/src/config/wallet.const.ts @@ -0,0 +1 @@ +export const EVM_ADDRESS_PLACEHOLDER = '0x'; diff --git a/src/declarations.d.ts b/src/declarations.d.ts index d972d48b2..d9f8d01b2 100644 --- a/src/declarations.d.ts +++ b/src/declarations.d.ts @@ -4,6 +4,8 @@ type EmptyFn = () => void; type SyncFn = (arg: T) => R; type AsyncFn = (arg: T) => Promise; +type HexString = `0x${string}`; + type StringRecord = Record; declare module '*.svg' { diff --git a/src/enums/account-type.enum.ts b/src/enums/account-type.enum.ts index e601891ca..0fdb495c3 100644 --- a/src/enums/account-type.enum.ts +++ b/src/enums/account-type.enum.ts @@ -1,10 +1,6 @@ export enum AccountTypeEnum { - HD_ACCOUNT = 'HD', - IMPORTED_ACCOUNT = 'IMPORTED', + HD = 'HD', + IMPORTED_CHAIN = 'IMPORTED_CHAIN', + IMPORTED_MULTICHAIN = 'IMPORTED_MULTICHAIN', WATCH_ONLY_DEBUG = 'WATCH_ONLY_DEBUG' } - -export enum ImportAccountDerivationEnum { - DEFAULT = 'DEFAULT', - CUSTOM_PATH = 'CUSTOM_PATH' -} diff --git a/src/enums/temple-chain-kind.enum.ts b/src/enums/temple-chain-kind.enum.ts new file mode 100644 index 000000000..3d773c840 --- /dev/null +++ b/src/enums/temple-chain-kind.enum.ts @@ -0,0 +1,4 @@ +export enum TempleChainKind { + Tezos = 'tezos', + EVM = 'evm' +} diff --git a/src/form/form-radio-buttons-group.tsx b/src/form/form-radio-buttons-group.tsx deleted file mode 100644 index 30ad308a8..000000000 --- a/src/form/form-radio-buttons-group.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { useField } from 'formik'; -import React, { useCallback } from 'react'; - -import { StyledRadioGroupProps, StyledRadioGroup } from 'src/components/styled-radio-group'; - -import { emptyFn } from '../config/general'; - -import { ErrorMessage } from './error-message/error-message'; - -interface Props extends StyledRadioGroupProps { - name: string; - onChange?: (value: T) => void; -} - -export const FormRadioButtonsGroup = ({ name, items, onChange = emptyFn }: Props) => { - const [field, meta, helpers] = useField(name); - - const handleChange = useCallback( - (value: T) => { - helpers.setValue(value); - onChange(value); - }, - [helpers, onChange] - ); - - return ( - <> - items={items} value={field.value} onChange={handleChange} /> - - - ); -}; diff --git a/src/form/form-section-dropdown.tsx b/src/form/form-section-dropdown.tsx index 318fbacaa..46951f990 100644 --- a/src/form/form-section-dropdown.tsx +++ b/src/form/form-section-dropdown.tsx @@ -23,7 +23,7 @@ export const FormSectionDropdown = ({ testID, testIDProperties }: Props) => { - const [field, meta, helpers] = useField(name); + const [field, meta, helpers] = useField(name); return ( <> diff --git a/src/form/validation/derivation-path.spec.ts b/src/form/validation/derivation-path.spec.ts new file mode 100644 index 000000000..d58b9b480 --- /dev/null +++ b/src/form/validation/derivation-path.spec.ts @@ -0,0 +1,19 @@ +import { derivationPathValidation } from './derivation-path'; + +describe('derivationPathValidation', () => { + it('should allow empty derivation path', async () => { + await expect(derivationPathValidation.isValid('')).resolves.toEqual(true); + }); + + it('should validate custom EVM, Tezos, and arbitrary coin type paths', async () => { + await expect(derivationPathValidation.isValid("m/44'/60'/0'/0/1")).resolves.toEqual(true); + await expect(derivationPathValidation.isValid("m/44'/1729'/0'/0'")).resolves.toEqual(true); + await expect(derivationPathValidation.isValid("m/44'/999'/0'/0'")).resolves.toEqual(true); + }); + + it('should reject syntactically invalid derivation paths', async () => { + await expect(derivationPathValidation.isValid("44'/60'/0'/0/0")).resolves.toEqual(false); + await expect(derivationPathValidation.isValid("m-44'/60'/0'/0/0")).resolves.toEqual(false); + await expect(derivationPathValidation.isValid("m/44'/coin'/0'/0/0")).resolves.toEqual(false); + }); +}); diff --git a/src/form/validation/derivation-path.ts b/src/form/validation/derivation-path.ts new file mode 100644 index 000000000..ef1361041 --- /dev/null +++ b/src/form/validation/derivation-path.ts @@ -0,0 +1,23 @@ +import { string } from 'yup'; + +import { isTruthy } from 'src/utils/is-truthy.ts'; + +export const derivationPathValidation = string().test('validateDerivationPath', 'Invalid path', path => { + const p = path ?? ''; + + if (p.length === 0) return true; + if (!p.startsWith('m')) { + return false; + } + if (p.length > 1 && p[1] !== '/') { + return false; + } + + const parts = p.replace('m', '').split('/').filter(isTruthy); + + return parts.every(itemPart => { + const pNum = +(itemPart.includes("'") ? itemPart.replace("'", '') : itemPart); + + return Number.isSafeInteger(pNum) && pNum >= 0; + }); +}); diff --git a/src/hooks/main-hooks/index.ts b/src/hooks/main-hooks/index.ts index 20d3d6738..b82a7131a 100644 --- a/src/hooks/main-hooks/index.ts +++ b/src/hooks/main-hooks/index.ts @@ -21,7 +21,7 @@ import { loadTokensApyActions } from 'src/store/d-apps/d-apps-actions'; import { loadNotificationsAction } from 'src/store/notifications/notifications-actions'; import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { loadTezosBalanceActions, loadAssetsBalancesActions } from 'src/store/wallet/wallet-actions'; -import { useCurrentAccountPkhSelector } from 'src/store/wallet/wallet-selectors'; +import { useAccountAddressForTezos } from 'src/store/wallet/wallet-selectors'; import { shouldMoveToSoftwareInV1 } from 'src/utils/keychain.utils'; import { useMetadataLoading } from './use-metadata-loading'; @@ -30,7 +30,7 @@ import { useNotificationRedirection } from './use-notification-redirection'; export const useMainHooks = (isLocked: boolean, isAuthorised: boolean) => { const dispatch = useDispatch(); - const selectedAccountPkh = useCurrentAccountPkhSelector(); + const selectedAccountPkh = useAccountAddressForTezos(); const selectedRpcUrl = useSelectedRpcUrlSelector(); const exchangeRates = useUsdToTokenRates(); const navigateToScreen = useNavigateToScreen(); diff --git a/src/hooks/request-confirmation/approve-internal-operation-request-action-payload.interface.ts b/src/hooks/request-confirmation/approve-internal-operation-request-action-payload.interface.ts index 1cc4ec05a..250aca326 100644 --- a/src/hooks/request-confirmation/approve-internal-operation-request-action-payload.interface.ts +++ b/src/hooks/request-confirmation/approve-internal-operation-request-action-payload.interface.ts @@ -1,9 +1,9 @@ import { ParamsWithKind } from '@taquito/taquito'; -import { ReadOnlySignerPayload } from 'src/types/read-only-signer-payload'; +import { TezosReadOnlySignerPayload } from 'src/types/tezos-read-only-signer-payload'; export interface ApproveInternalOperationRequestActionPayloadInterface { rpcUrl: string; - sender: ReadOnlySignerPayload; + sender: TezosReadOnlySignerPayload; opParams: ParamsWithKind[]; } diff --git a/src/hooks/request-confirmation/approve-operation-request-action-payload.interface.ts b/src/hooks/request-confirmation/approve-operation-request-action-payload.interface.ts index 37056196c..f1bc7edbf 100644 --- a/src/hooks/request-confirmation/approve-operation-request-action-payload.interface.ts +++ b/src/hooks/request-confirmation/approve-operation-request-action-payload.interface.ts @@ -1,11 +1,12 @@ import { OperationRequestOutput } from '@airgap/beacon-sdk'; import { ParamsWithKind } from '@taquito/taquito'; -import { ReadOnlySignerPayload } from 'src/types/read-only-signer-payload'; +import { TempleChainKind } from 'src/enums/temple-chain-kind.enum.ts'; +import { AccountForChain } from 'src/utils/account.utils.ts'; export interface ApproveOperationRequestActionPayloadInterface { rpcUrl: string; - sender: ReadOnlySignerPayload; + sender: AccountForChain; opParams: ParamsWithKind[]; message: OperationRequestOutput; } diff --git a/src/hooks/request-confirmation/use-request-confirmation.hook.ts b/src/hooks/request-confirmation/use-request-confirmation.hook.ts index a8fa1d91b..812f09ee2 100644 --- a/src/hooks/request-confirmation/use-request-confirmation.hook.ts +++ b/src/hooks/request-confirmation/use-request-confirmation.hook.ts @@ -1,9 +1,9 @@ import { useEffect, useMemo, useRef, useState } from 'react'; -import { useDispatch } from 'react-redux'; import { EMPTY, ObservableInput, of, Subject } from 'rxjs'; import { catchError, switchMap, tap } from 'rxjs/operators'; import { Action } from 'src/interfaces/action.interface'; +import { dispatch } from 'src/store'; import { showErrorToast } from 'src/toast/toast.utils'; import { useAnalytics } from 'src/utils/analytics/use-analytics.hook'; import { AnalyticsError } from 'src/utils/error-analytics-data.utils'; @@ -12,7 +12,6 @@ export const useRequestConfirmation = >( project: (value: T, index: number) => O ) => { const { trackErrorEvent } = useAnalytics(); - const dispatch = useDispatch(); const isConfirmed = useRef(false); const [isLoading, setIsLoading] = useState(false); diff --git a/src/hooks/use-chain-id.hook.ts b/src/hooks/use-chain-id.hook.ts index 2397fab42..c066b9306 100644 --- a/src/hooks/use-chain-id.hook.ts +++ b/src/hooks/use-chain-id.hook.ts @@ -3,8 +3,8 @@ import { noop } from 'lodash-es'; import { useEffect, useState } from 'react'; import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; -import { READ_ONLY_SIGNER_PUBLIC_KEY, READ_ONLY_SIGNER_PUBLIC_KEY_HASH } from 'src/utils/env.utils'; import { createReadOnlyTezosToolkit } from 'src/utils/rpc/tezos-toolkit.utils'; +import { tezosReadOnlySignerAccount } from 'src/utils/tezos-read-only.signer.util.ts'; /** @deprecated // Flawed logic. Manifests in a wrong initial value */ export const useChainId = () => { @@ -12,10 +12,7 @@ export const useChainId = () => { const rpcUrl = useSelectedRpcUrlSelector(); useEffect(() => { - const tezos = createReadOnlyTezosToolkit(rpcUrl, { - publicKey: READ_ONLY_SIGNER_PUBLIC_KEY, - publicKeyHash: READ_ONLY_SIGNER_PUBLIC_KEY_HASH - }); + const tezos = createReadOnlyTezosToolkit(rpcUrl, tezosReadOnlySignerAccount); tezos.rpc.getChainId().then(setChainId).catch(noop); }, [rpcUrl]); diff --git a/src/hooks/use-contract-activity.ts b/src/hooks/use-contract-activity.ts index 67005cb52..2d909d5e2 100644 --- a/src/hooks/use-contract-activity.ts +++ b/src/hooks/use-contract-activity.ts @@ -1,13 +1,14 @@ import { uniq } from 'lodash-es'; import { useCallback, useEffect, useRef, useState } from 'react'; -import { ActivityGroup } from '../interfaces/activity.interface'; -import { UseActivityInterface } from '../interfaces/use-activity.interface'; -import { useSelectedRpcUrlSelector } from '../store/settings/settings-selectors'; -import { useSelectedAccountSelector } from '../store/wallet/wallet-selectors'; -import { useAnalytics } from '../utils/analytics/use-analytics.hook'; -import { isDefined } from '../utils/is-defined'; -import { loadActivity } from '../utils/token-operations.util'; +import { ActivityGroup } from 'src/interfaces/activity.interface'; +import { UseActivityInterface } from 'src/interfaces/use-activity.interface'; +import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; +import { useAccount } from 'src/store/wallet/wallet-selectors'; +import { getAccountAddressForTezos } from 'src/utils/account.utils'; +import { useAnalytics } from 'src/utils/analytics/use-analytics.hook'; +import { isDefined } from 'src/utils/is-defined'; +import { loadActivity } from 'src/utils/token-operations.util'; interface ContractActivityState { activities: Array; @@ -16,9 +17,10 @@ interface ContractActivityState { } export const useContractActivity = (tokenSlug?: string): UseActivityInterface => { - const selectedAccount = useSelectedAccountSelector(); + const selectedAccount = useAccount(); const selectedRpcUrl = useSelectedRpcUrlSelector(); const { trackErrorEvent } = useAnalytics(); + const selectedTezosAddress = getAccountAddressForTezos(selectedAccount); const lastActivityRef = useRef(''); @@ -36,7 +38,7 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => fetchedActivities = await loadActivity(selectedRpcUrl, selectedAccount, tokenSlug); } catch (error) { console.error(error); - trackErrorEvent('InitialLoadContractActivityError', error, [selectedAccount.publicKeyHash], { + trackErrorEvent('InitialLoadContractActivityError', error, selectedTezosAddress ? [selectedTezosAddress] : [], { tokenSlug, selectedRpcUrl, refresh @@ -63,7 +65,7 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => }); } }, - [selectedRpcUrl, selectedAccount, tokenSlug, trackErrorEvent] + [selectedRpcUrl, selectedAccount, selectedTezosAddress, tokenSlug, trackErrorEvent] ); useEffect(() => { @@ -93,7 +95,7 @@ export const useContractActivity = (tokenSlug?: string): UseActivityInterface => } } catch (error) { console.error(error); - trackErrorEvent('HandleUpdateContractActivityError', error, [selectedAccount.publicKeyHash], { + trackErrorEvent('HandleUpdateContractActivityError', error, selectedTezosAddress ? [selectedTezosAddress] : [], { tokenSlug, selectedRpcUrl, lastItem diff --git a/src/hooks/use-fake-refresh-control-props.hook.ts b/src/hooks/use-fake-refresh-control-props.hook.ts index d217a7706..6d6a1f599 100644 --- a/src/hooks/use-fake-refresh-control-props.hook.ts +++ b/src/hooks/use-fake-refresh-control-props.hook.ts @@ -2,7 +2,7 @@ import { useCallback, useContext, useEffect, useMemo, useState } from 'react'; import { RefreshControlProps } from 'react-native'; import { CurrentRouteNameContext } from 'src/navigator/current-route-name.context'; -import { useCurrentAccountPkhSelector } from 'src/store/wallet/wallet-selectors'; +import { useAccountAddressForTezos } from 'src/store/wallet/wallet-selectors'; import { useActiveTimer } from './use-active-timer.hook'; @@ -13,7 +13,7 @@ export const useFakeRefreshControlProps = (): RefreshControlProps => { const [isRefreshing, setRefreshing] = useState(false); const { activeTimer, clearActiveTimer } = useActiveTimer(); const currentRouteName = useContext(CurrentRouteNameContext); - const publicKeyHash = useCurrentAccountPkhSelector(); + const publicKeyHash = useAccountAddressForTezos(); const handleRefresh = useCallback(() => { clearActiveTimer(); diff --git a/src/hooks/use-filtered-account-list.hook.ts b/src/hooks/use-filtered-account-list.hook.ts index 1f7524181..bacc22feb 100644 --- a/src/hooks/use-filtered-account-list.hook.ts +++ b/src/hooks/use-filtered-account-list.hook.ts @@ -1,26 +1,30 @@ import { debounce } from 'lodash-es'; import { useEffect, useState } from 'react'; -import { AccountInterface } from '../interfaces/account.interface'; -import { isString } from '../utils/is-string'; +import { Account } from 'src/interfaces/account.interfaces'; +import { getAccountAddressForEvm, getAccountAddressForTezos } from 'src/utils/account.utils.ts'; +import { isString } from 'src/utils/is-string'; -export const useFilteredAccountList = (accountList: AccountInterface[]) => { +export const useFilteredAccountList = (accountList: Account[]) => { const [searchValue, setSearchValue] = useState(); - const [filteredAccountList, setFilteredAccountList] = useState(accountList); + const [filteredAccountList, setFilteredAccountList] = useState(accountList); useEffect(() => { - const result: AccountInterface[] = []; + const result: Account[] = []; if (isString(searchValue)) { const lowerCaseSearchValue = searchValue.toLowerCase(); for (const account of accountList) { - const { name, publicKey, publicKeyHash } = account; + const { name } = account; + const tezosAddress = getAccountAddressForTezos(account); + const evmAddress = getAccountAddressForEvm(account); + if ( name.toLowerCase().includes(lowerCaseSearchValue) || - publicKey.toLowerCase().includes(lowerCaseSearchValue) || - publicKeyHash.toLowerCase().includes(lowerCaseSearchValue) + tezosAddress?.toLowerCase().includes(lowerCaseSearchValue) || + evmAddress?.toLowerCase().includes(lowerCaseSearchValue) ) { result.push(account); } diff --git a/src/hooks/use-filtered-receivers-list.hook.ts b/src/hooks/use-filtered-receivers-list.hook.ts index c84f8c080..a73fd8c29 100644 --- a/src/hooks/use-filtered-receivers-list.hook.ts +++ b/src/hooks/use-filtered-receivers-list.hook.ts @@ -1,34 +1,41 @@ import { useMemo, useState } from 'react'; -import { AccountBaseInterface } from 'src/interfaces/account.interface'; +import { Contact } from 'src/interfaces/contact.interface'; import { SectionDropdownDataInterface } from 'src/interfaces/section-dropdown-data.interface'; import { useContactsSelector } from 'src/store/contact-book/contact-book-selectors'; -import { useCurrentAccountPkhSelector, useVisibleAccountsListSelector } from 'src/store/wallet/wallet-selectors'; +import { useAccountAddressForTezos, useAllVisibleAccounts } from 'src/store/wallet/wallet-selectors'; +import { getAccountAddressForTezos } from 'src/utils/account.utils'; +import { isDefined } from 'src/utils/is-defined'; export const useFilteredReceiversList = () => { const contacts = useContactsSelector(); - const accountPkh = useCurrentAccountPkhSelector(); + const tezosAddress = useAccountAddressForTezos(); - const allVisibleAccounts = useVisibleAccountsListSelector(); + const allVisibleAccounts = useAllVisibleAccounts(); const myVisibleAccounts = useMemo( () => allVisibleAccounts - .filter(({ publicKeyHash }) => publicKeyHash !== accountPkh) - .map(({ name, publicKeyHash }) => ({ name, publicKeyHash })), - [allVisibleAccounts, accountPkh] + .map(account => { + const address = getAccountAddressForTezos(account); + + return address ? { name: account.name, address } : undefined; + }) + .filter(isDefined) + .filter(({ address }) => address !== tezosAddress), + [allVisibleAccounts, tezosAddress] ); const [searchValue, setSearchValue] = useState(''); const filteredReceiversList = useMemo(() => { - const result: Array> = []; + const result: Array> = []; const searchValueLowerCase = searchValue.toLowerCase(); const filteredAccounts = myVisibleAccounts.filter( - ({ name, publicKeyHash }) => - name.toLowerCase().includes(searchValueLowerCase) || publicKeyHash.toLowerCase().includes(searchValueLowerCase) + ({ name, address }) => + name.toLowerCase().includes(searchValueLowerCase) || address.toLowerCase().includes(searchValueLowerCase) ); if (filteredAccounts.length > 0) { @@ -36,8 +43,8 @@ export const useFilteredReceiversList = () => { } const filteredContacts = contacts.filter( - ({ name, publicKeyHash }) => - name.toLowerCase().includes(searchValueLowerCase) || publicKeyHash.toLowerCase().includes(searchValueLowerCase) + ({ name, address }) => + name.toLowerCase().includes(searchValueLowerCase) || address.toLowerCase().includes(searchValueLowerCase) ); if (filteredContacts.length > 0) { diff --git a/src/hooks/use-internal-ads-analytics.hook.ts b/src/hooks/use-internal-ads-analytics.hook.ts index c4a3d05e5..b960cf16f 100644 --- a/src/hooks/use-internal-ads-analytics.hook.ts +++ b/src/hooks/use-internal-ads-analytics.hook.ts @@ -3,7 +3,7 @@ import { useCallback, useEffect, useRef, useState } from 'react'; import { PromotionProviderEnum } from 'src/enums/promotion-provider.enum'; import { PromotionVariantEnum } from 'src/enums/promotion-variant.enum'; -import { useCurrentAccountPkhSelector } from 'src/store/wallet/wallet-selectors'; +import { useAccountAddressForTezos } from 'src/store/wallet/wallet-selectors'; import { AnalyticsEventCategory } from 'src/utils/analytics/analytics-event.enum'; import { useAnalytics } from 'src/utils/analytics/use-analytics.hook'; import { isDefined } from 'src/utils/is-defined'; @@ -23,7 +23,7 @@ export const useInternalAdsAnalytics = ( initialAdAreaIsVisible = false, seenTimeout: number ) => { - const accountPkh = useCurrentAccountPkhSelector(); + const accountPkh = useAccountAddressForTezos(); const isFocused = useIsFocused(); const { trackEvent } = useAnalytics(); const [adAreaIsVisible, setAdAreaIsVisible] = useState(initialAdAreaIsVisible); @@ -83,7 +83,7 @@ export const useInternalAdsAnalyticsWithImpressionCallback = ( variant = PromotionVariantEnum.Image, initialAdAreaIsVisible = false ) => { - const accountPkh = useCurrentAccountPkhSelector(); + const accountPkh = useAccountAddressForTezos(); const isFocused = useIsFocused(); const { trackEvent } = useAnalytics(); const [loadedPromotionProvider, setLoadedPromotionProvider] = useState(); diff --git a/src/hooks/use-load-on-each-block.hook.ts b/src/hooks/use-load-on-each-block.hook.ts index 7af7e26ce..4d2f609b2 100644 --- a/src/hooks/use-load-on-each-block.hook.ts +++ b/src/hooks/use-load-on-each-block.hook.ts @@ -2,7 +2,7 @@ import { PayloadAction } from '@reduxjs/toolkit'; import { useEffect, useRef } from 'react'; import { useDispatch } from 'react-redux'; -import { useCurrentAccountPkhSelector } from 'src/store/wallet/wallet-selectors'; +import { useAccountAddressForTezos } from 'src/store/wallet/wallet-selectors'; import { useBlockLevel } from './use-block-level.hook'; @@ -12,10 +12,14 @@ export const useLoadOnEachBlock = ( ) => { const blockLevel = useBlockLevel(); const prevBlockLevelRef = useRef(-1); - const currentAccountPkh = useCurrentAccountPkhSelector(); + const currentAccountPkh = useAccountAddressForTezos(); const dispatch = useDispatch(); useEffect(() => { + if (!currentAccountPkh) { + return; + } + if (!isLoading && prevBlockLevelRef.current !== blockLevel) { dispatch(actionFactory(currentAccountPkh)); prevBlockLevelRef.current = blockLevel; diff --git a/src/hooks/use-read-only-tezos-toolkit.hook.ts b/src/hooks/use-read-only-tezos-toolkit.hook.ts index 03eaa8a60..991df53e8 100644 --- a/src/hooks/use-read-only-tezos-toolkit.hook.ts +++ b/src/hooks/use-read-only-tezos-toolkit.hook.ts @@ -1,27 +1,17 @@ import { useMemo } from 'react'; -import { AccountInterface } from 'src/interfaces/account.interface'; import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; -import { useRawCurrentAccountSelector } from 'src/store/wallet/wallet-selectors'; +import { useAccount } from 'src/store/wallet/wallet-selectors'; +import { TezosReadOnlySignerPayload } from 'src/types/tezos-read-only-signer-payload'; +import { getAccountForTezos } from 'src/utils/account.utils.ts'; import { createReadOnlyTezosToolkit } from 'src/utils/rpc/tezos-toolkit.utils'; -export const useReadOnlyTezosToolkit = (sender?: AccountInterface) => { - const defaultSender = useRawCurrentAccountSelector(); +export const useReadOnlyTezosToolkit = (sender?: TezosReadOnlySignerPayload) => { + const account = useAccount(); const selectedRpcUrl = useSelectedRpcUrlSelector(); - let publicKeyHash = ''; - let publicKey = ''; - - if (sender) { - publicKeyHash = sender.publicKeyHash; - publicKey = sender.publicKey; - } else if (defaultSender) { - publicKeyHash = defaultSender.publicKeyHash; - publicKey = defaultSender.publicKey; - } - return useMemo( - () => createReadOnlyTezosToolkit(selectedRpcUrl, { publicKey, publicKeyHash }), - [selectedRpcUrl, publicKey, publicKeyHash] + () => createReadOnlyTezosToolkit(selectedRpcUrl, sender ?? getAccountForTezos(account)), + [account, selectedRpcUrl, sender] ); }; diff --git a/src/hooks/use-swap.hook.ts b/src/hooks/use-swap.hook.ts index c6dd9e7ba..ac69ae614 100644 --- a/src/hooks/use-swap.hook.ts +++ b/src/hooks/use-swap.hook.ts @@ -1,14 +1,20 @@ import BigNumber from 'bignumber.js'; import { useCallback } from 'react'; +import { DeadEndBoundaryError } from 'src/components/error-boundary'; import { Route3SwapHops, Route3LiquidityBakingHops, Route3Token } from 'src/interfaces/route3.interface'; -import { useCurrentAccountPkhSelector } from 'src/store/wallet/wallet-selectors'; +import { useAccountAddressForTezos } from 'src/store/wallet/wallet-selectors'; import { getSwapTransferParams } from 'src/utils/swap.utils'; import { useReadOnlyTezosToolkit } from './use-read-only-tezos-toolkit.hook'; export const useSwap = () => { - const publicKeyHash = useCurrentAccountPkhSelector(); + const tezosAddress = useAccountAddressForTezos(); + + if (!tezosAddress) { + throw new DeadEndBoundaryError(); + } + const tezos = useReadOnlyTezosToolkit(); return useCallback( @@ -28,8 +34,8 @@ export const useSwap = () => { slippageRatio, hops, tezos, - publicKeyHash + tezosAddress ), - [tezos, publicKeyHash] + [tezos, tezosAddress] ); }; diff --git a/src/interfaces/account.interface.mock.ts b/src/interfaces/account.interface.mock.ts index bd4e26dd5..57d99e9d5 100644 --- a/src/interfaces/account.interface.mock.ts +++ b/src/interfaces/account.interface.mock.ts @@ -1,23 +1,51 @@ import { AccountTypeEnum } from '../enums/account-type.enum'; +import { TempleChainKind } from '../enums/temple-chain-kind.enum'; import { mockAccountCredentials } from '../mocks/account-credentials.mock'; -import { AccountInterface, AccountBaseInterface } from './account.interface'; +import { HDAccount, ImportedChainAccount } from './account.interfaces'; +import { Contact } from './contact.interface'; -export const mockAccountBase: AccountBaseInterface = { +export const mockContact: Contact = { name: 'MockContact', - publicKeyHash: mockAccountCredentials.publicKeyHash + address: mockAccountCredentials.publicKeyHash }; -export const mockHdAccount: AccountInterface = { +export const mockHdAccount: HDAccount = { + id: mockAccountCredentials.publicKeyHash, name: 'Mock HD Account', - type: AccountTypeEnum.HD_ACCOUNT, - publicKey: mockAccountCredentials.publicKey, - publicKeyHash: mockAccountCredentials.publicKeyHash + type: AccountTypeEnum.HD, + tezosAddress: mockAccountCredentials.publicKeyHash, + tezosPublicKey: mockAccountCredentials.publicKey, + evmAddress: '0xfDc237eff648793c9F3B976c702493f0EE056489', + evmPublicKey: 'f648793c9F3B976c702493f0EE05648976c702493f76c702493f76c702493f76c702493f', + hdIndex: 0 }; -export const mockNewHdAccount: AccountInterface = { +export const mockNewHdAccount: HDAccount = { + id: 'tz1NewMockPublicKeyHash', name: 'Mock New HD Account', - type: AccountTypeEnum.HD_ACCOUNT, - publicKey: 'edpkNewMockPublicKey', - publicKeyHash: 'tz1NewMockPublicKeyHash' + type: AccountTypeEnum.HD, + tezosAddress: 'tz1NewMockPublicKeyHash', + tezosPublicKey: 'tz2NewMockPublicKey', + evmAddress: '0x1111111111111111111111111111111111111111', + evmPublicKey: '1111111111111111111111111111111111111111111111111111111111111111111111111', + hdIndex: 1 +}; + +export const mockTezosImportedAccount: ImportedChainAccount = { + id: 'tz1ImportedMockPublicKeyHash', + name: 'Mock Tezos Imported Account', + type: AccountTypeEnum.IMPORTED_CHAIN, + chain: TempleChainKind.Tezos, + address: 'tz1ImportedMockPublicKeyHash', + publicKey: 'tz2NewMockPublicKey' +}; + +export const mockEvmImportedAccount: ImportedChainAccount = { + id: '0x2222222222222222222222222222222222222222', + name: 'Mock EVM Imported Account', + type: AccountTypeEnum.IMPORTED_CHAIN, + chain: TempleChainKind.EVM, + address: '0x2222222222222222222222222222222222222222', + publicKey: '0x33333333333333333333333333333333333333' }; diff --git a/src/interfaces/account.interface.ts b/src/interfaces/account.interface.ts deleted file mode 100644 index 04ee853f7..000000000 --- a/src/interfaces/account.interface.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { EMPTY_PUBLIC_KEY_HASH } from '../config/system'; -import { AccountTypeEnum } from '../enums/account-type.enum'; -import { LoadableEntityState } from '../store/types'; -import { AccountTokenInterface } from '../token/interfaces/account-token.interface'; - -import { ActivityGroup } from './activity.interface'; - -export interface AccountBaseInterface { - name: string; - publicKeyHash: string; -} - -export interface AccountInterface extends AccountBaseInterface { - type: AccountTypeEnum; - publicKey: string; - - /** @deprecated */ - isVisible?: boolean; - /** @deprecated */ - tezosBalance?: string; - /** @deprecated */ - tokensList?: AccountTokenInterface[]; - /** @deprecated */ - removedTokensList?: string[]; - /** @deprecated */ - activityGroups?: LoadableEntityState; - /** @deprecated */ - pendingActivities?: ActivityGroup[]; -} - -/** @deprecated // BAD PRACTICE */ -export const initialAccount: AccountInterface = { - name: '', - type: AccountTypeEnum.HD_ACCOUNT, - publicKey: '', - publicKeyHash: EMPTY_PUBLIC_KEY_HASH -}; - -/** @deprecated // BAD PRACTICE */ -export const emptyAccount: AccountInterface = { - name: '', - type: AccountTypeEnum.HD_ACCOUNT, - publicKey: '', - publicKeyHash: EMPTY_PUBLIC_KEY_HASH -}; - -/** @deprecated // BAD PRACTICE */ -export const emptyAccountBase: AccountBaseInterface = { - name: '', - publicKeyHash: EMPTY_PUBLIC_KEY_HASH -}; diff --git a/src/interfaces/account.interfaces.ts b/src/interfaces/account.interfaces.ts new file mode 100644 index 000000000..986a8d98d --- /dev/null +++ b/src/interfaces/account.interfaces.ts @@ -0,0 +1,39 @@ +import { AccountTypeEnum } from 'src/enums/account-type.enum'; +import { TempleChainKind } from 'src/enums/temple-chain-kind.enum'; + +interface BaseAccount { + id: string; + name: string; +} + +interface MultichainAccount extends BaseAccount { + tezosAddress: string; + tezosPublicKey: string; + evmAddress: HexString; + evmPublicKey: string; +} + +export interface HDAccount extends MultichainAccount { + type: AccountTypeEnum.HD; + hdIndex: number; +} + +export interface ImportedMultichainAccount extends MultichainAccount { + type: AccountTypeEnum.IMPORTED_MULTICHAIN; +} + +interface ChainAccount extends BaseAccount { + chain: TempleChainKind; + address: string; + publicKey: string; +} + +export interface ImportedChainAccount extends ChainAccount { + type: AccountTypeEnum.IMPORTED_CHAIN; +} + +export interface WatchOnlyDebugAccount extends ChainAccount { + type: AccountTypeEnum.WATCH_ONLY_DEBUG; +} + +export type Account = HDAccount | ImportedMultichainAccount | ImportedChainAccount | WatchOnlyDebugAccount; diff --git a/src/interfaces/contact.interface.ts b/src/interfaces/contact.interface.ts new file mode 100644 index 000000000..19379c4e1 --- /dev/null +++ b/src/interfaces/contact.interface.ts @@ -0,0 +1,4 @@ +export interface Contact { + name: string; + address: string; +} diff --git a/src/layouts/reveal-seed-phrase/index.tsx b/src/layouts/reveal-seed-phrase/index.tsx index 6caa74baa..61b5259ca 100644 --- a/src/layouts/reveal-seed-phrase/index.tsx +++ b/src/layouts/reveal-seed-phrase/index.tsx @@ -5,6 +5,7 @@ import { Text, View } from 'react-native'; import { ButtonLargePrimary } from 'src/components/button/button-large/button-large-primary/button-large-primary'; import { CheckboxLabel } from 'src/components/checkbox-description/checkbox-label'; import { Divider } from 'src/components/divider/divider'; +import { DeadEndBoundaryError } from 'src/components/error-boundary'; import { HeaderButton } from 'src/components/header/header-button/header-button'; import { HeaderProgress } from 'src/components/header/header-progress/header-progress'; import { HeaderTitle } from 'src/components/header/header-title/header-title'; @@ -16,7 +17,7 @@ import { NewSeedPhraseAttention } from 'src/components/new-seed-phrase-attention import { ScreenContainer } from 'src/components/screen-container/screen-container'; import { FormCheckbox } from 'src/form/form-checkbox'; import { RevealSeedPhraseView } from 'src/modals/reveal-seed-phrase-modal/reveal-seed-phrase-form-content/reveal-seed-phrase-view/reveal-seed-phrase-view'; -import { useCurrentAccountPkhSelector } from 'src/store/wallet/wallet-selectors'; +import { useAccountAddressForTezos } from 'src/store/wallet/wallet-selectors'; import { formatSize } from 'src/styles/format-size'; import { @@ -43,7 +44,11 @@ export const RevealSeedPhrase: FC = ({ headerTitleText = 'Manual backup' }) => { const styles = useCreateNewWalletStyles(); - const accountPkh = useCurrentAccountPkhSelector(); + const tezosAddress = useAccountAddressForTezos(); + + if (!tezosAddress) { + throw new DeadEndBoundaryError(); + } useNavigationSetOptions( { @@ -70,7 +75,7 @@ export const RevealSeedPhrase: FC = ({ description="If you ever switch between browsers or devices, you will need this seed phrase to access your accounts." /> diff --git a/src/mocks/account-credentials.mock.ts b/src/mocks/account-credentials.mock.ts index e328af10a..f9a3cefd0 100644 --- a/src/mocks/account-credentials.mock.ts +++ b/src/mocks/account-credentials.mock.ts @@ -10,7 +10,7 @@ export const mockAccountCredentials = { export const mockHDAccountCredentials = { mockAccountIndex: 77, - privateKey: 'edsk4PnmkH1gzBCAWKAagyBG83JeTKRKRZrRejbjunyhdcAqgPiHsL', + privateKey: 'edsk4GNNuhSc34VFizCN1qTRJipwBe7ok7pCLpZDrJubFaVhZiDz5A', seedPhrase: mockAccountCredentials.seedPhrase, publicKey: mockAccountCredentials.publicKey, publicKeyHash: mockAccountCredentials.publicKeyHash diff --git a/src/mocks/react-redux.mock.ts b/src/mocks/react-redux.mock.ts index e59bbfbdc..f62cdf860 100644 --- a/src/mocks/react-redux.mock.ts +++ b/src/mocks/react-redux.mock.ts @@ -1,6 +1,6 @@ import { mockRootState } from '../store/root-state.mock'; -export const mockUseDispatch = jest.fn(); +const mockUseDispatch = jest.fn(); jest.mock('react-redux', () => ({ ...jest.requireActual('react-redux'), diff --git a/src/modals/choose-account-import-type/index.tsx b/src/modals/choose-account-import-type/index.tsx index fb512a17d..f1314f58d 100644 --- a/src/modals/choose-account-import-type/index.tsx +++ b/src/modals/choose-account-import-type/index.tsx @@ -14,6 +14,7 @@ import { useNavigation } from 'src/navigator/hooks/use-navigation.hook'; import { formatSize } from 'src/styles/format-size'; import { usePageAnalytic } from 'src/utils/analytics/use-analytics.hook'; +import { ImportAccountKeystoreFile } from '../import-account/import-account-keystore-file/import-account-keystore-file'; import { ImportAccountPrivateKey } from '../import-account/import-account-private-key/import-account-private-key'; import { ImportAccountSeed } from '../import-account/import-account-seed/import-account-seed'; @@ -21,7 +22,8 @@ import { useChooseAccountImportTypeStyles } from './styles'; enum ImportType { SeedPhrase = 'SeedPhrase', - PrivateKey = 'PrivateKey' + PrivateKey = 'PrivateKey', + KeystoreFile = 'KeystoreFile' } export const ChooseAccountImportType = memo(() => { @@ -40,6 +42,12 @@ export const ChooseAccountImportType = memo(() => { description: 'Use your private key of the account you\n' + 'want to import', iconName: IconNameEnum.Key, onPress: () => setSelectedImportType(ImportType.PrivateKey) + }, + { + title: 'Keystore File', + description: 'Import your account from an encrypted\n' + 'keystore file (.tez)', + iconName: IconNameEnum.FileUpload, + onPress: () => setSelectedImportType(ImportType.KeystoreFile) } ], [] @@ -54,6 +62,9 @@ export const ChooseAccountImportType = memo(() => { case ImportType.PrivateKey: return ; + case ImportType.KeystoreFile: + return ; + default: return ; } diff --git a/src/modals/choose-wallet-import-type/index.tsx b/src/modals/choose-wallet-import-type/index.tsx index 8f0b94514..7f9acb077 100644 --- a/src/modals/choose-wallet-import-type/index.tsx +++ b/src/modals/choose-wallet-import-type/index.tsx @@ -21,7 +21,6 @@ import { useChooseWalletImportTypeStyles } from './styles'; enum ImportType { SeedPhrase = 'SeedPhrase', - KeystoreFile = 'KeystoreFile', Sync = 'Sync' } @@ -41,12 +40,6 @@ export const ChooseWalletImportType = memo(() => { description: 'Synchronize your mobile and extension\n' + 'Temple Wallet', iconName: IconNameEnum.Sync, onPress: () => setSelectedImportType(ImportType.Sync) - }, - { - title: 'Keystore File', - description: 'Import your wallet from an encrypted\n' + 'keystore file (.tez)', - iconName: IconNameEnum.FileUpload, - onPress: () => setSelectedImportType(ImportType.KeystoreFile) } ], [] @@ -58,9 +51,6 @@ export const ChooseWalletImportType = memo(() => { case ImportType.SeedPhrase: return ; - case ImportType.KeystoreFile: - return ; - case ImportType.Sync: return ; diff --git a/src/modals/collectible-modal/collectible-modal.tsx b/src/modals/collectible-modal/collectible-modal.tsx index 5be138b77..c36acd2e3 100644 --- a/src/modals/collectible-modal/collectible-modal.tsx +++ b/src/modals/collectible-modal/collectible-modal.tsx @@ -3,11 +3,11 @@ import BigNumber from 'bignumber.js'; import React, { memo, useMemo, useState } from 'react'; import { Dimensions, Text, TouchableOpacity, View, Image } from 'react-native'; import { SvgUri, SvgXml } from 'react-native-svg'; -import { useDispatch } from 'react-redux'; import { objktCurrencies } from 'src/apis/objkt/constants'; import { ButtonLargePrimary } from 'src/components/button/button-large/button-large-primary/button-large-primary'; import { Divider } from 'src/components/divider/divider'; +import { DeadEndBoundaryError } from 'src/components/error-boundary'; import { Icon } from 'src/components/icon/icon'; import { IconNameEnum } from 'src/components/icon/icon-name.enum'; import { LinkWithIcon } from 'src/components/link-with-icon/link-with-icon'; @@ -24,6 +24,7 @@ import { ConfirmationTypeEnum } from 'src/interfaces/confirm-payload/confirmatio import { ModalButtonsFloatingContainer } from 'src/layouts/modal-buttons-floating-container'; import { ModalsEnum } from 'src/navigator/enums/modals.enum'; import { useModalParams, useNavigateToModal } from 'src/navigator/hooks/use-navigation.hook'; +import { dispatch } from 'src/store'; import { loadCollectiblesDetailsActions } from 'src/store/collectibles/collectibles-actions'; import { useCollectibleDetailsLoadingSelector, @@ -31,7 +32,7 @@ import { } from 'src/store/collectibles/collectibles-selectors'; import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { useAssetMetadataSelector } from 'src/store/tokens-metadata/tokens-metadata-selectors'; -import { useAssetBalanceSelector, useCurrentAccountPkhSelector } from 'src/store/wallet/wallet-selectors'; +import { useAssetBalanceSelector, useAccountAddressForTezos } from 'src/store/wallet/wallet-selectors'; import { formatSize } from 'src/styles/format-size'; import { usePageAnalytic } from 'src/utils/analytics/use-analytics.hook'; import { conditionalStyle } from 'src/utils/conditional-style'; @@ -66,7 +67,12 @@ export const CollectibleModal = memo(() => { const navigateToModal = useNavigateToModal(); const [address, id] = fromTokenSlug(slug); - const accountPkh = useCurrentAccountPkhSelector(); + const tezosAddress = useAccountAddressForTezos(); + + if (!tezosAddress) { + throw new DeadEndBoundaryError(); + } + const selectedRpc = useSelectedRpcUrlSelector(); const { width } = Dimensions.get('window'); @@ -74,8 +80,6 @@ export const CollectibleModal = memo(() => { usePageAnalytic(ModalsEnum.CollectibleModal); - const dispatch = useDispatch(); - const styles = useCollectibleModalStyles(); const [scrollEnabled, setScrollEnabled] = useState(true); @@ -130,7 +134,7 @@ export const CollectibleModal = memo(() => { return { title: `Buy for ${formatNumber(priceToDisplay)} ${purchaseCurrency.symbol}`, onPress: () => - void buildBuyCollectibleParams(createTezosToolkit(selectedRpc), accountPkh, listing, purchaseCurrency).then( + void buildBuyCollectibleParams(createTezosToolkit(selectedRpc), tezosAddress, listing, purchaseCurrency).then( opParams => navigateToModal(ModalsEnum.Confirmation, { type: ConfirmationTypeEnum.InternalOperations, @@ -138,7 +142,15 @@ export const CollectibleModal = memo(() => { }) ) }; - }, [isAccountHolder, areDetailsLoading, metadata, details?.listingsActive, accountPkh, selectedRpc, navigateToModal]); + }, [ + isAccountHolder, + areDetailsLoading, + metadata, + details?.listingsActive, + tezosAddress, + selectedRpc, + navigateToModal + ]); const name = metadata?.name ?? details?.name; let artifactUri: string | undefined; diff --git a/src/modals/confirmation-modal/d-app-operations-confirmation/operation-request-confirmation/operation-request-confirmation.tsx b/src/modals/confirmation-modal/d-app-operations-confirmation/operation-request-confirmation/operation-request-confirmation.tsx index bb7a029f3..a3ee11995 100644 --- a/src/modals/confirmation-modal/d-app-operations-confirmation/operation-request-confirmation/operation-request-confirmation.tsx +++ b/src/modals/confirmation-modal/d-app-operations-confirmation/operation-request-confirmation/operation-request-confirmation.tsx @@ -5,14 +5,15 @@ import { mapTo, switchMap } from 'rxjs/operators'; import { BeaconHandler } from 'src/beacon/beacon-handler'; import { Divider } from 'src/components/divider/divider'; +import { DeadEndBoundaryError } from 'src/components/error-boundary'; import { ApproveOperationRequestActionPayloadInterface } from 'src/hooks/request-confirmation/approve-operation-request-action-payload.interface'; import { useDappRequestConfirmation } from 'src/hooks/request-confirmation/use-dapp-request-confirmation.hook'; -import { emptyAccount } from 'src/interfaces/account.interface'; import { navigateBackAction } from 'src/store/root-state.actions'; import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { waitForOperationCompletionAction } from 'src/store/wallet/wallet-actions'; -import { useAccountsListSelector } from 'src/store/wallet/wallet-selectors'; +import { useAllAccounts } from 'src/store/wallet/wallet-selectors'; import { showSuccessToast } from 'src/toast/toast.utils'; +import { getAccountAddressForTezos, getAccountForTezos } from 'src/utils/account.utils'; import { useAnalytics } from 'src/utils/analytics/use-analytics.hook'; import { mapBeaconToTaquitoParams } from 'src/utils/beacon.utils'; import { sendTransaction$ } from 'src/utils/wallet.utils'; @@ -30,7 +31,7 @@ const approveOperationRequest = ({ opParams, message }: ApproveOperationRequestActionPayloadInterface) => - sendTransaction$(rpcUrl, sender.publicKeyHash, opParams).pipe( + sendTransaction$(rpcUrl, sender.address, opParams).pipe( switchMap(({ hash }) => from( BeaconHandler.respond({ @@ -52,28 +53,34 @@ const approveOperationRequest = ({ ); export const OperationRequestConfirmation: FC = ({ message }) => { - const accounts = useAccountsListSelector(); + const accounts = useAllAccounts(); const rpcUrl = useSelectedRpcUrlSelector(); const { trackErrorEvent } = useAnalytics(); const { confirmRequest, isLoading } = useDappRequestConfirmation(message, approveOperationRequest); const sender = useMemo( - () => accounts.find(({ publicKeyHash }) => publicKeyHash === message.sourceAddress) ?? emptyAccount, + () => accounts.find(account => getAccountAddressForTezos(account) === message.sourceAddress)!, [accounts, message.sourceAddress] ); + const tezosAccount = getAccountForTezos(sender); + + if (!tezosAccount) { + throw new DeadEndBoundaryError(); + } + const opParams = useMemo(() => message.operationDetails.map(mapBeaconToTaquitoParams), [message]); const handleEstimationError = useCallback( (error: unknown) => { - trackErrorEvent('DAppOperationsConfirmationEstimateError', error, [sender.publicKeyHash], { + trackErrorEvent('DAppOperationsConfirmationEstimateError', error, [message.sourceAddress], { opParams, rpcUrl, appMetadata: message.appMetadata }); }, - [trackErrorEvent, sender.publicKeyHash, opParams, rpcUrl, message.appMetadata] + [trackErrorEvent, message.sourceAddress, message.appMetadata, opParams, rpcUrl] ); return ( @@ -81,7 +88,7 @@ export const OperationRequestConfirmation: FC = ({ message }) => { sender={sender} opParams={opParams} isLoading={isLoading} - onSubmit={newOpParams => confirmRequest({ rpcUrl, sender, opParams: newOpParams, message })} + onSubmit={newOpParams => confirmRequest({ rpcUrl, sender: tezosAccount, opParams: newOpParams, message })} onEstimationError={handleEstimationError} > diff --git a/src/modals/confirmation-modal/d-app-operations-confirmation/permission-request-confirmation/permission-request-confirmation.form.tsx b/src/modals/confirmation-modal/d-app-operations-confirmation/permission-request-confirmation/permission-request-confirmation.form.tsx index e0ccee691..ccc460c84 100644 --- a/src/modals/confirmation-modal/d-app-operations-confirmation/permission-request-confirmation/permission-request-confirmation.form.tsx +++ b/src/modals/confirmation-modal/d-app-operations-confirmation/permission-request-confirmation/permission-request-confirmation.form.tsx @@ -1,9 +1,9 @@ import { object, SchemaOf } from 'yup'; -import { AccountInterface } from 'src/interfaces/account.interface'; +import { Account } from 'src/interfaces/account.interfaces'; export interface PermissionRequestConfirmationFormValues { - approver: AccountInterface; + approver: Account; } export const permissionRequestConfirmationModalValidationSchema: SchemaOf = diff --git a/src/modals/confirmation-modal/d-app-operations-confirmation/permission-request-confirmation/permission-request-confirmation.tsx b/src/modals/confirmation-modal/d-app-operations-confirmation/permission-request-confirmation/permission-request-confirmation.tsx index d721cf4a9..d837382e8 100644 --- a/src/modals/confirmation-modal/d-app-operations-confirmation/permission-request-confirmation/permission-request-confirmation.tsx +++ b/src/modals/confirmation-modal/d-app-operations-confirmation/permission-request-confirmation/permission-request-confirmation.tsx @@ -19,10 +19,11 @@ import { useDappRequestConfirmation } from 'src/hooks/request-confirmation/use-d import { ModalButtonsFloatingContainer } from 'src/layouts/modal-buttons-floating-container'; import { useNavigation } from 'src/navigator/hooks/use-navigation.hook'; import { navigateBackAction } from 'src/store/root-state.actions'; -import { setSelectedAccountAction } from 'src/store/wallet/wallet-actions'; -import { useAccountsListSelector, useSelectedAccountSelector } from 'src/store/wallet/wallet-selectors'; +import { setSelectedAccountIdAction } from 'src/store/wallet/wallet-actions'; +import { useAllAccounts, useAccount } from 'src/store/wallet/wallet-selectors'; import { formatSize } from 'src/styles/format-size'; import { showSuccessToast } from 'src/toast/toast.utils'; +import { getAccountAddressForTezos, getAccountPublicKeyForTezos } from 'src/utils/account.utils'; import { AppMetadataConnectionView } from './app-metadata-connection-view/app-metadata-connection-view'; import { @@ -56,23 +57,31 @@ const approvePermissionRequest = ({ message, publicKey }: ApprovePermissionReque export const PermissionRequestConfirmation: FC = ({ message }) => { const dispatch = useDispatch(); const { goBack } = useNavigation(); - const accounts = useAccountsListSelector(); - const selectedAccount = useSelectedAccountSelector(); + const accounts = useAllAccounts(); + const selectedAccount = useAccount(); + const tezosAccounts = useMemo(() => accounts.filter(account => getAccountAddressForTezos(account)), [accounts]); const { confirmRequest, isLoading } = useDappRequestConfirmation(message, approvePermissionRequest); const formInitialValues = useMemo( - () => ({ approver: selectedAccount }), - [selectedAccount] + () => ({ approver: getAccountAddressForTezos(selectedAccount) ? selectedAccount : tezosAccounts[0] }), + [selectedAccount, tezosAccounts] ); const onSubmit = ({ approver }: PermissionRequestConfirmationFormValues) => { - if (approver.publicKeyHash !== selectedAccount.publicKeyHash) { - dispatch(setSelectedAccountAction(approver.publicKeyHash)); + if (approver.id !== selectedAccount.id) { + dispatch(setSelectedAccountIdAction(approver.id)); } + + const publicKey = getAccountPublicKeyForTezos(approver); + + if (!publicKey) { + return; + } + confirmRequest({ message, - publicKey: approver.publicKey + publicKey }); }; @@ -90,7 +99,7 @@ export const PermissionRequestConfirmation: FC = ({ message }) => { ); }; diff --git a/src/modals/select-baker-modal/select-baker-modal.tsx b/src/modals/select-baker-modal/select-baker-modal.tsx index 7f7625fbe..7922496ec 100644 --- a/src/modals/select-baker-modal/select-baker-modal.tsx +++ b/src/modals/select-baker-modal/select-baker-modal.tsx @@ -15,10 +15,9 @@ import { Label } from 'src/components/label/label'; import { ModalStatusBar } from 'src/components/modal-status-bar/modal-status-bar'; import { SearchInput } from 'src/components/search-input/search-input'; import { Sorter } from 'src/components/sorter/sorter'; +import { LIMIT_FIN_FEATURES } from 'src/config/system'; import { BakersSortFieldEnum } from 'src/enums/bakers-sort-field.enum'; import { OnRampOverlayState } from 'src/enums/on-ramp-overlay-state.enum'; -import { useCanUseOnRamp } from 'src/hooks/use-can-use-on-ramp.hook'; -import { useNetworkInfo } from 'src/hooks/use-network-info.hook'; import { useOnRampContinueOverlay } from 'src/hooks/use-on-ramp-continue-overlay.hook'; import { ConfirmationTypeEnum } from 'src/interfaces/confirm-payload/confirmation-type.enum'; import { ModalButtonsFloatingContainer } from 'src/layouts/modal-buttons-floating-container'; @@ -38,7 +37,7 @@ import { EVERSTAKE_BAKER_ADDRESS, HELP_UKRAINE_BAKER_ADDRESS, TEMPLE_BAKER_ADDRE import { isValidAddress } from 'src/utils/tezos.util'; import { BakerListItem } from './baker-list-item/baker-list-item'; -import { DISCLAIMER_MESSAGE, TEZ_LABEL, DCP_LABEL, TEZ_DESCRIPTION, DCP_DESCRIPTION } from './constants'; +import { DISCLAIMER_MESSAGE, TEZ_LABEL, TEZ_DESCRIPTION } from './constants'; import { SelectBakerModalSelectors } from './select-baker-modal.selectors'; import { useSelectBakerModalStyles } from './select-baker-modal.styles'; @@ -64,15 +63,9 @@ export const SelectBakerModal = memo(() => { const navigateToModal = useNavigateToModal(); const styles = useSelectBakerModalStyles(); const currentBaker = useSelectedBakerSelector(); - const { isTezosNode, isDcpNode } = useNetworkInfo(); - const canUseOnRamp = useCanUseOnRamp(); const tezosBalance = useCurrentAccountTezosBalance(); const dispatch = useDispatch(); const { isOpened: onRampOverlayIsOpened, onClose: onOnRampOverlayClose } = useOnRampContinueOverlay(); - const bakerNameByNode = isDcpNode ? 'Producer' : 'Baker'; - - const searchPlaceholder = `Search ${bakerNameByNode}`; - const unknownBakerName = `Unknown ${bakerNameByNode}`; const { trackEvent } = useAnalytics(); @@ -109,9 +102,9 @@ export const SelectBakerModal = memo(() => { if (currentBaker?.address === selectedBaker.address) { showErrorToast({ title: 'Re-delegation is not possible', - description: `Already delegated funds to this ${isDcpNode ? 'producer' : 'baker'}.` + description: `Already delegated funds to this baker.` }); - } else if (new BigNumber(tezosBalance).isZero() && canUseOnRamp) { + } else if (new BigNumber(tezosBalance).isZero() && !LIMIT_FIN_FEATURES) { dispatch(setOnRampOverlayStateAction(OnRampOverlayState.Continue)); } else { navigateToModal(ModalsEnum.Confirmation, { @@ -120,7 +113,7 @@ export const SelectBakerModal = memo(() => { ...(isTempleBakerSelected && { testID: 'TEMPLE_BAKER_DELEGATION' }), ...(isEverstakeBakerSelected && { testID: 'EVERSTAKE_BAKER_DELEGATION' }), ...(isHelpUkraineBakerSelected && { testID: 'HELP_UKRAINE_BAKER_DELEGATION' }), - ...(Boolean(selectedBaker.isUnknownBaker) && !isDcpNode && { disclaimerMessage: DISCLAIMER_MESSAGE }) + ...(Boolean(selectedBaker.isUnknownBaker) && { disclaimerMessage: DISCLAIMER_MESSAGE }) }); } } @@ -166,10 +159,7 @@ export const SelectBakerModal = memo(() => { const isValidBakerAddress = isDefined(selectedBaker) && !isValidAddress(selectedBaker.address); - const unknownBaker = useMemo( - () => buildUnknownBaker(searchValue ?? '', unknownBakerName), - [unknownBakerName, searchValue] - ); + const unknownBaker = useMemo(() => buildUnknownBaker(searchValue ?? '', 'Unknown Baker'), [searchValue]); const ListEmptyComponent = useMemo( () => @@ -180,7 +170,7 @@ export const SelectBakerModal = memo(() => { selected={searchValue === selectedBaker?.address} /> ) : undefined, - [unknownBakerName, searchValue, tezosAddress, selectedBaker?.address] + [searchValue, tezosAddress, selectedBaker?.address] ); const renderItem: ListRenderItem = useCallback( @@ -201,59 +191,41 @@ export const SelectBakerModal = memo(() => { - {isValidBakerAddress && Not a valid address} {searchValue === tezosAddress && You can not delegate to yourself} - {isTezosNode && ( - - The higher the better - - - - )} - - - {isTezosNode && ( - - )} - - {isDcpNode && isValidAddress(searchValue ?? '') && searchValue?.toLowerCase() !== tezosAddress.toLowerCase() && ( - - - + The higher the better + + - )} + + + - + { const tokens = useCurrentAccountTokens(true); const collectibles = useCurrentAccountCollectibles(true); const tezosToken = useTezosTokenOfCurrentAccount(); - const canUseOnRamp = useCanUseOnRamp(); const tezosBalance = useCurrentAccountTezosBalance(); const tezosAddress = useAccountAddressForTezos(); const { isOpened: onRampOverlayIsOpened, onClose: onOnRampOverlayClose } = useOnRampContinueOverlay(); @@ -100,8 +99,8 @@ export const SendModal: FC = () => { const { filteredAssetsList, setSearchValue } = useFilteredAssetsList(assets, true, true, leadingAssets); const { filteredReceiversList, handleSearchValueChange } = useFilteredReceiversList(); - const selectedRpcUrl = useSelectedRpcUrlSelector(); - const resolver = useMemo(() => tezosDomainsResolver(selectedRpcUrl), [selectedRpcUrl]); + // TODO: Add preferredRpcUrl when choosing RPC node becomes available + const resolver = useMemo(() => tezosDomainsResolver(), []); const isTransferDisabled = filteredReceiversList.length === 0; const recipient = filteredReceiversList[0]?.data[0]; @@ -202,7 +201,11 @@ export const SendModal: FC = () => { // Regular flow !transferBetweenOwnAccounts && dispatch(addContactCandidateAddressAction(receiverPublicKeyHash)); - if (getTokenSlug(asset) === TEZ_TOKEN_SLUG && (amount?.isGreaterThan(tezosBalance) ?? false) && canUseOnRamp) { + if ( + getTokenSlug(asset) === TEZ_TOKEN_SLUG && + (amount?.isGreaterThan(tezosBalance) ?? false) && + !LIMIT_FIN_FEATURES + ) { dispatch(setOnRampOverlayStateAction(OnRampOverlayState.Continue)); } else if (isDefined(amount)) { dispatch( @@ -214,7 +217,7 @@ export const SendModal: FC = () => { ); } }, - [dispatch, tezosBalance, canUseOnRamp, resolver, tezosAddress] + [dispatch, tezosBalance, resolver, tezosAddress] ); const formik = useFormik({ diff --git a/src/navigator/enums/screens.enum.ts b/src/navigator/enums/screens.enum.ts index e9a7d6d22..0e485f25d 100644 --- a/src/navigator/enums/screens.enum.ts +++ b/src/navigator/enums/screens.enum.ts @@ -1,5 +1,6 @@ import { ObjktCollectionType } from 'src/apis/objkt/types'; import { TokenInterface } from 'src/token/interfaces/token.interface'; +import { ChainId } from 'src/types/networks'; import { EncryptedBackupObject } from 'src/utils/cloud-backup'; import { ModalsEnum } from './modals.enum'; @@ -52,7 +53,8 @@ export enum ScreensEnum { DAppsSettings = 'DAppsSettings', FiatSettings = 'FiatSettings', SecureSettings = 'SecureSettings', - NodeSettings = 'NodeSettings', + Networks = 'Networks', + NetworkSettings = 'NetworkSettings', Backup = 'Backup', ManualBackup = 'ManualBackup', CloudBackup = 'CloudBackup', @@ -111,7 +113,8 @@ export type ScreensParamList = { [ScreensEnum.DAppsSettings]: undefined; [ScreensEnum.FiatSettings]: undefined; [ScreensEnum.SecureSettings]: undefined; - [ScreensEnum.NodeSettings]: undefined; + [ScreensEnum.Networks]: undefined; + [ScreensEnum.NetworkSettings]: { chainId: ChainId }; [ScreensEnum.Backup]: undefined; [ScreensEnum.ManualBackup]: undefined; [ScreensEnum.CloudBackup]: undefined; diff --git a/src/navigator/enums/stacks.enum.ts b/src/navigator/enums/stacks.enum.ts index 59de4b7fd..0a0ab806e 100644 --- a/src/navigator/enums/stacks.enum.ts +++ b/src/navigator/enums/stacks.enum.ts @@ -42,7 +42,8 @@ export type MainStackParams = | MainStackParamsPart | MainStackParamsPart | MainStackParamsPart - | MainStackParamsPart + | MainStackParamsPart + | MainStackParamsPart | MainStackParamsPart | MainStackParamsPart | MainStackParamsPart diff --git a/src/navigator/main-stack.tsx b/src/navigator/main-stack.tsx index 6e80f47d8..2ea2263bb 100644 --- a/src/navigator/main-stack.tsx +++ b/src/navigator/main-stack.tsx @@ -1,6 +1,7 @@ import { PortalProvider } from '@gorhom/portal'; +import type { RouteProp } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; -import React, { memo, useMemo } from 'react'; +import React, { memo, useCallback, useMemo } from 'react'; import { exolixScreenOptions } from 'src/components/header/exolix-screen-options'; import { generateScreenOptions } from 'src/components/header/generate-screen-options.util'; @@ -12,7 +13,8 @@ import { emptyFn } from 'src/config/general'; import { transparent } from 'src/config/styles'; import { LIMIT_FIN_FEATURES } from 'src/config/system'; import { useMainHooks } from 'src/hooks/main-hooks'; -import { useNetworkInfo } from 'src/hooks/use-network-info.hook'; +import { useEvmChains } from 'src/hooks/use-evm-chains.hook'; +import { useTezosChains } from 'src/hooks/use-tezos-chains.hook'; import { SecurityUpdate } from 'src/modals/security-update'; import { About } from 'src/screens/about/about'; import { Activity } from 'src/screens/activity/activity'; @@ -37,7 +39,8 @@ import { ManageAccounts } from 'src/screens/manage-accounts/manage-accounts'; import { ManageAssets } from 'src/screens/manage-assets/manage-assets'; import { ManualBackup } from 'src/screens/manual-backup/manual-backup'; import { Market } from 'src/screens/market/market'; -import { NodeSettings } from 'src/screens/node-settings/node-settings'; +import { NetworkSettings } from 'src/screens/network-settings'; +import { Networks } from 'src/screens/networks'; import { Notifications } from 'src/screens/notifications/notifications'; import { NotificationsItem } from 'src/screens/notifications-item/notifications-item'; import { NotificationsSettings } from 'src/screens/notifications-settings/notifications-settings'; @@ -55,6 +58,7 @@ import { Welcome } from 'src/screens/welcome/welcome'; import { useAppLock } from 'src/shelter/app-lock/app-lock'; import { useIsAuthorisedSelector } from 'src/store/wallet/wallet-selectors'; import { useColors } from 'src/styles/use-colors'; +import { TEZ_TOKEN_METADATA } from 'src/token/data/tokens-metadata'; import { emptyTokenMetadata } from 'src/token/interfaces/token-metadata.interface'; import { cloudTitle } from 'src/utils/cloud-backup'; @@ -70,6 +74,8 @@ export const MainStackScreen = memo(() => { const styleScreenOptions = useStackNavigatorStyleOptions(); const colors = useColors(); + const tezosChains = useTezosChains(); + const evmChains = useEvmChains(); const tokenScreenHeaderStyle = useMemo( () => ({ @@ -80,14 +86,25 @@ export const MainStackScreen = memo(() => { [colors] ); - const { metadata } = useNetworkInfo(); - useMainHooks(isLocked, isAuthorised); const shouldShowUnauthorizedScreens = !isAuthorised; const shouldShowAuthorizedScreens = isAuthorised && !isLocked; const shouldShowBlankScreen = isAuthorised && isLocked; + const getNetworkSettingsScreenOptions = useCallback( + ({ route }: { route: RouteProp }) => { + const { chainId } = route.params; + const chain = + typeof chainId === 'string' + ? tezosChains.find(chain => chain.chainId === chainId) + : evmChains.find(chain => chain.chainId === chainId); + + return generateScreenOptions(); + }, + [tezosChains, evmChains] + ); + return ( @@ -126,7 +143,7 @@ export const MainStackScreen = memo(() => { name={ScreensEnum.TezosTokenScreen} component={TezosTokenScreen} options={generateScreenOptions( - , + , null, true, tokenScreenHeaderStyle @@ -270,9 +287,14 @@ export const MainStackScreen = memo(() => { options={generateScreenOptions()} /> )} + name={ScreensEnum.Networks} + component={Networks} + options={generateScreenOptions()} + /> + (({ currentRouteName }) => { const styles = useSideBarStyles(); - const { isDcpNode } = useNetworkInfo(); - const swapScreenParams = useSwapScreenParams(currentRouteName); const isStackFocusedMemo = useCallback( @@ -70,7 +67,6 @@ export const SideBar = memo(({ currentRouteName }) => { routeName={ScreensEnum.SwapScreen} swapScreenParams={swapScreenParams} focused={isStackFocusedMemo(swapStackScreens)} - disabled={isDcpNode} disabledOnPress={handleDisabledPress} /> )} @@ -79,7 +75,6 @@ export const SideBar = memo(({ currentRouteName }) => { iconName={IconNameEnum.DApps} routeName={ScreensEnum.DApps} focused={isStackFocusedMemo(dAppsStackScreens)} - disabled={isDcpNode} disabledOnPress={handleDisabledPress} /> (({ currentRouteName }) => { const styles = useTabBarStyles(); - const { isDcpNode } = useNetworkInfo(); - const swapScreenParams = useSwapScreenParams(currentRouteName); const isStackFocusedMemo = useCallback( @@ -70,7 +67,6 @@ export const TabBar = memo(({ currentRouteName }) => { routeName={ScreensEnum.SwapScreen} swapScreenParams={swapScreenParams} focused={isStackFocusedMemo(swapStackScreens)} - disabled={isDcpNode} disabledOnPress={handleDisabledPress} /> )} @@ -80,7 +76,6 @@ export const TabBar = memo(({ currentRouteName }) => { iconWidth={formatSize(32)} routeName={ScreensEnum.DApps} focused={isStackFocusedMemo(dAppsStackScreens)} - disabled={isDcpNode} disabledOnPress={handleDisabledPress} /> { const { isLocked } = useAppLock(); const isShowLoader = useIsShowLoaderSelector(); const isAuthorised = useIsAuthorisedSelector(); - const { isDcpNode } = useNetworkInfo(); useRootHooks(); @@ -125,7 +123,7 @@ export const RootStackScreen = () => { { - const { metadata } = useNetworkInfo(); const styles = useBuyStyles(); const navigateToScreen = useNavigateToScreen(); @@ -48,7 +47,7 @@ export const Buy = () => { diff --git a/src/screens/cloud-backup/form.ts b/src/screens/cloud-backup/form.ts index 1bf93ab83..20b89091b 100644 --- a/src/screens/cloud-backup/form.ts +++ b/src/screens/cloud-backup/form.ts @@ -3,9 +3,9 @@ import { useDispatch } from 'react-redux'; import { firstValueFrom } from 'rxjs'; import { object, SchemaOf } from 'yup'; +import { LIMIT_FIN_FEATURES } from 'src/config/system'; import { OnRampOverlayState } from 'src/enums/on-ramp-overlay-state.enum'; import { passwordValidation } from 'src/form/validation/password'; -import { useCanUseOnRamp } from 'src/hooks/use-can-use-on-ramp.hook'; import { ScreensEnum } from 'src/navigator/enums/screens.enum'; import { useNavigateToScreen, useNavigation } from 'src/navigator/hooks/use-navigation.hook'; import { Shelter } from 'src/shelter/shelter'; @@ -47,7 +47,6 @@ export const useHandleSubmit = () => { const dispatch = useDispatch(); const { trackCloudError, trackCloudSuccess } = useCloudAnalytics(); const { trackEvent } = useAnalytics(); - const canUseOnRamp = useCanUseOnRamp(); const proceedWithSaving = useCallback( async (password: string, replacing = false) => { @@ -60,7 +59,7 @@ export const useHandleSubmit = () => { dispatch(hideLoaderAction()); dispatch(madeCloudBackupAction()); - canUseOnRamp && dispatch(setOnRampOverlayStateAction(OnRampOverlayState.Start)); + !LIMIT_FIN_FEATURES && dispatch(setOnRampOverlayStateAction(OnRampOverlayState.Start)); showSuccessToast({ description: 'Your wallet has been backed up successfully!' }); goBack(); @@ -73,7 +72,7 @@ export const useHandleSubmit = () => { trackCloudError(error); } }, - [canUseOnRamp, dispatch, goBack, trackCloudError, trackCloudSuccess] + [dispatch, goBack, trackCloudError, trackCloudSuccess] ); const submit: (password: string) => Promise = useCallback( diff --git a/src/screens/collection/components/collectible-item.tsx b/src/screens/collection/components/collectible-item.tsx index b6d4d7ed2..bbdb313c5 100644 --- a/src/screens/collection/components/collectible-item.tsx +++ b/src/screens/collection/components/collectible-item.tsx @@ -19,7 +19,6 @@ import { useShareNFT } from 'src/hooks/use-share-nft.hook'; import { ConfirmationTypeEnum } from 'src/interfaces/confirm-payload/confirmation-type.enum'; import { ModalsEnum } from 'src/navigator/enums/modals.enum'; import { useNavigateToModal } from 'src/navigator/hooks/use-navigation.hook'; -import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { formatSize } from 'src/styles/format-size'; import { CollectionItemInterface } from 'src/token/interfaces/collectible-interfaces.interface'; import { getTokenSlug } from 'src/token/utils/token.utils'; @@ -44,7 +43,6 @@ export const CollectibleItem = memo(({ item, collectionContract, accountP const styles = useCollectibleItemStyles(); const navigateToModal = useNavigateToModal(); - const selectedRpc = useSelectedRpcUrlSelector(); const lastPrice = useMemo(() => { const lastDeal = item.lastDeal; @@ -116,7 +114,7 @@ export const CollectibleItem = memo(({ item, collectionContract, accountP title: `Sell for ${priceToDisplay} ${currency.symbol}`, onPress: () => void buildSellCollectibleParams( - createTezosToolkit(selectedRpc), + createTezosToolkit(), accountPkh, collectionContract, item.id, @@ -129,15 +127,7 @@ export const CollectibleItem = memo(({ item, collectionContract, accountP }) ) }; - }, [ - accountPkh, - selectedRpc, - isAccountHolder, - collectionContract, - item.id, - extraDetails?.offers_active, - navigateToModal - ]); + }, [accountPkh, isAccountHolder, collectionContract, item.id, extraDetails?.offers_active, navigateToModal]); const secondButton = useMemo(() => { if (LIMIT_NFT_FEATURES) { @@ -194,24 +184,14 @@ export const CollectibleItem = memo(({ item, collectionContract, accountP return { title: `Buy for ${priceToDisplay} ${purchaseCurrency.symbol}`, onPress: () => - void buildBuyCollectibleParams(createTezosToolkit(selectedRpc), accountPkh, listing, purchaseCurrency).then( - opParams => - navigateToModal(ModalsEnum.Confirmation, { - type: ConfirmationTypeEnum.InternalOperations, - opParams - }) + void buildBuyCollectibleParams(createTezosToolkit(), accountPkh, listing, purchaseCurrency).then(opParams => + navigateToModal(ModalsEnum.Confirmation, { + type: ConfirmationTypeEnum.InternalOperations, + opParams + }) ) }; - }, [ - accountPkh, - selectedRpc, - isAccountHolder, - collectionContract, - item.id, - item.holders, - item.listingsActive, - navigateToModal - ]); + }, [accountPkh, isAccountHolder, collectionContract, item.id, item.holders, item.listingsActive, navigateToModal]); const handleShare = useShareNFT(slug, item.thumbnailUri, item.name, item.description); diff --git a/src/screens/debug/debug.tsx b/src/screens/debug/debug.tsx index 63e04481b..4b02c2316 100644 --- a/src/screens/debug/debug.tsx +++ b/src/screens/debug/debug.tsx @@ -9,7 +9,9 @@ import { formatSize } from 'src/styles/format-size'; import { usePageAnalytic } from 'src/utils/analytics/use-analytics.hook'; import { AsyncStorageDetails } from './async-storage-details'; +import { EtherlinkFallbackDemo } from './etherlink-fallback-demo'; import { ImportWatchOnlyDebug } from './import-watch-only-debug/import-watch-only-debug'; +import { TezosFallbackDemo } from './tezos-fallback-demo'; export const Debug: FC = () => { const [shouldThrowRenderError, setShouldThrowRenderError] = useState(false); @@ -37,6 +39,10 @@ export const Debug: FC = () => { /> {shouldThrowRenderError && } + + + + ); diff --git a/src/screens/debug/etherlink-fallback-demo.tsx b/src/screens/debug/etherlink-fallback-demo.tsx new file mode 100644 index 000000000..390b35b2d --- /dev/null +++ b/src/screens/debug/etherlink-fallback-demo.tsx @@ -0,0 +1,58 @@ +import { useCallback } from 'react'; +import { WatchBlocksReturnType } from 'viem'; + +import { useEtherlinkPublicClient } from 'src/hooks/use-etherlink-public-client.hook'; + +import { FallbackDemo, FallbackDemoProps } from './fallback-demo'; + +interface SubscriptionArtifacts { + unwatch: WatchBlocksReturnType | undefined; + retryTimeoutId: NodeJS.Timeout | undefined; +} + +export const EtherlinkFallbackDemo = () => { + const client = useEtherlinkPublicClient(); + + const createSubscription = useCallback['createSubscription']>( + (setMessages, _setUsedRpcUrl) => { + let unwatch: WatchBlocksReturnType | undefined; + let retryTimeoutId: NodeJS.Timeout | undefined; + + const subscribe = () => { + unwatch = client.watchBlocks({ + onBlock: block => { + setMessages(prev => prev.concat(`Block received, level ${block.number.toString()}, hash ${block.hash}`)); + }, + onError: error => { + setMessages(prev => prev.concat(`Error: ${error.message}`)); + clearTimeout(retryTimeoutId); + unwatch?.(); + retryTimeoutId = setTimeout(() => subscribe(), 5000); + } + }); + }; + + subscribe(); + + return { unwatch, retryTimeoutId }; + }, + [client] + ); + + const destroySubscription = useCallback['destroySubscription']>( + ({ unwatch, retryTimeoutId }) => { + unwatch?.(); + clearTimeout(retryTimeoutId); + }, + [] + ); + + return ( + + ); +}; diff --git a/src/screens/debug/fallback-demo.tsx b/src/screens/debug/fallback-demo.tsx new file mode 100644 index 000000000..5b9e6c3a7 --- /dev/null +++ b/src/screens/debug/fallback-demo.tsx @@ -0,0 +1,72 @@ +import { identity } from 'lodash-es'; +import { useCallback, useEffect, useRef, useState } from 'react'; +import { ListRenderItemInfo, ScrollView, Text, View } from 'react-native'; +import { FlatList } from 'react-native-gesture-handler'; + +import { DEFAULT_BORDER_WIDTH } from 'src/config/styles'; +import { createUseStylesMemoized } from 'src/styles/create-use-styles'; +import { formatSize } from 'src/styles/format-size'; + +export interface FallbackDemoProps { + networkName: string; + createSubscription: ( + setMessages: React.Dispatch>, + setUsedRpcUrl: React.Dispatch> + ) => S; + destroySubscription: SyncFn; + initialRpcUrl: string | (() => string); +} + +export const FallbackDemo = ({ + networkName, + createSubscription, + destroySubscription, + initialRpcUrl +}: FallbackDemoProps) => { + const [messages, setMessages] = useState([]); + const [usedRpcUrl, setUsedRpcUrl] = useState(initialRpcUrl); + const styles = useStyles(); + const scrollViewRef = useRef(null); + + const renderMessageItem = useCallback( + (info: ListRenderItemInfo) => {info.item}, + [styles] + ); + + useEffect(() => { + const updateMessages: typeof setMessages = input => { + setMessages(input); + scrollViewRef.current?.scrollToEnd(); + }; + + const subscription = createSubscription(updateMessages, setUsedRpcUrl); + + return () => destroySubscription(subscription); + }, [createSubscription, destroySubscription]); + + return ( + + + Used {networkName} RPC URL: {usedRpcUrl} + + Messages: + + + + + ); +}; + +const useStyles = createUseStylesMemoized(({ colors, typography }) => ({ + messagesContainer: { + padding: formatSize(8), + gap: formatSize(4), + borderColor: colors.lines, + borderWidth: DEFAULT_BORDER_WIDTH, + height: formatSize(300) + }, + messageText: { + ...typography.numbersRegular13, + color: colors.black + } +})); diff --git a/src/screens/debug/tezos-fallback-demo.tsx b/src/screens/debug/tezos-fallback-demo.tsx new file mode 100644 index 000000000..8aec683ad --- /dev/null +++ b/src/screens/debug/tezos-fallback-demo.tsx @@ -0,0 +1,61 @@ +import { BlockResponse } from '@taquito/rpc'; +import { Subscription } from '@taquito/taquito'; +import { useCallback } from 'react'; + +import { useReadOnlyTezosToolkit } from 'src/hooks/use-read-only-tezos-toolkit.hook'; + +import { FallbackDemo, FallbackDemoProps } from './fallback-demo'; + +interface SubscriptionArtifacts { + sub: Subscription | undefined; + retryTimeoutId: NodeJS.Timeout | undefined; +} + +export const TezosFallbackDemo = () => { + const tezos = useReadOnlyTezosToolkit(); + + const initialRpcUrl = useCallback(() => tezos.rpc.getRpcUrl(), [tezos]); + + const createSubscription = useCallback['createSubscription']>( + (setMessages, setUsedRpcUrl) => { + let sub: Subscription | undefined; + let retryTimeoutId: NodeJS.Timeout | undefined; + + const subscribe = () => { + sub = tezos.stream.subscribeBlock('head'); + sub.on('data', block => { + setMessages(prev => prev.concat(`Block received, level ${block.header.level}, hash ${block.hash}`)); + setUsedRpcUrl(tezos.rpc.getRpcUrl()); + }); + sub.on('error', error => { + setMessages(prev => prev.concat(`Error: ${error.message}`)); + clearTimeout(retryTimeoutId); + sub?.close(); + retryTimeoutId = setTimeout(() => subscribe(), 5000); + }); + }; + + subscribe(); + + return { sub, retryTimeoutId }; + }, + [tezos] + ); + + const destroySubscription = useCallback['destroySubscription']>( + ({ sub, retryTimeoutId }) => { + sub?.close(); + clearTimeout(retryTimeoutId); + }, + [] + ); + + return ( + + ); +}; diff --git a/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-reward-item/baker-reward-item-details/details/endorsements.tsx b/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-reward-item/baker-reward-item-details/details/endorsements.tsx index 020520df8..54ffb5aba 100644 --- a/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-reward-item/baker-reward-item-details/details/endorsements.tsx +++ b/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-reward-item/baker-reward-item-details/details/endorsements.tsx @@ -5,8 +5,8 @@ import { Text, View } from 'react-native'; import { Divider } from 'src/components/divider/divider'; import { Icon } from 'src/components/icon/icon'; import { IconNameEnum } from 'src/components/icon/icon-name.enum'; -import { useNetworkInfo } from 'src/hooks/use-network-info.hook'; import { formatSize } from 'src/styles/format-size'; +import { TEZ_TOKEN_SYMBOL } from 'src/token/data/tokens-metadata'; import { BakingHistoryEntry } from '../../../interfaces/baking-history-entry'; import { useBakerRewardItemStyles } from '../../baker-reward-item.styles'; @@ -16,7 +16,6 @@ export const Endorsements: FC { const styles = useBakerRewardItemStyles(); - const { metadata } = useNetworkInfo(); return ( <> @@ -37,7 +36,7 @@ export const Endorsements: FC +{attestationRewards.decimalPlaces(2, BigNumber.ROUND_FLOOR).toString() + ' '} - {metadata.symbol} + {TEZ_TOKEN_SYMBOL} {' '} for {attestations.toString()} slots diff --git a/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-reward-item/baker-reward-item-details/details/missed-endorsements.tsx b/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-reward-item/baker-reward-item-details/details/missed-endorsements.tsx index f1a7200be..699d069b8 100644 --- a/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-reward-item/baker-reward-item-details/details/missed-endorsements.tsx +++ b/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-reward-item/baker-reward-item-details/details/missed-endorsements.tsx @@ -5,8 +5,8 @@ import { Text, View } from 'react-native'; import { Divider } from 'src/components/divider/divider'; import { Icon } from 'src/components/icon/icon'; import { IconNameEnum } from 'src/components/icon/icon-name.enum'; -import { useNetworkInfo } from 'src/hooks/use-network-info.hook'; import { formatSize } from 'src/styles/format-size'; +import { TEZ_TOKEN_SYMBOL } from 'src/token/data/tokens-metadata'; import { BakingHistoryEntry } from '../../../interfaces/baking-history-entry'; import { useBakerRewardItemStyles } from '../../baker-reward-item.styles'; @@ -16,7 +16,6 @@ export const MissedEndorsements: FC { const styles = useBakerRewardItemStyles(); - const { metadata } = useNetworkInfo(); return ( <> @@ -37,7 +36,7 @@ export const MissedEndorsements: FC -{missedAttestationRewards.decimalPlaces(2, BigNumber.ROUND_FLOOR).toString() + ' '} - {metadata.symbol} + {TEZ_TOKEN_SYMBOL} {' '} for {missedAttestations.toString()} slots diff --git a/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-reward-item/baker-reward-item-details/details/missed-own-blocks.tsx b/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-reward-item/baker-reward-item-details/details/missed-own-blocks.tsx index d07f7676d..326ce28f4 100644 --- a/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-reward-item/baker-reward-item-details/details/missed-own-blocks.tsx +++ b/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-reward-item/baker-reward-item-details/details/missed-own-blocks.tsx @@ -5,8 +5,8 @@ import { Text, View } from 'react-native'; import { Divider } from 'src/components/divider/divider'; import { Icon } from 'src/components/icon/icon'; import { IconNameEnum } from 'src/components/icon/icon-name.enum'; -import { useNetworkInfo } from 'src/hooks/use-network-info.hook'; import { formatSize } from 'src/styles/format-size'; +import { TEZ_TOKEN_SYMBOL } from 'src/token/data/tokens-metadata'; import { BakingHistoryEntry } from '../../../interfaces/baking-history-entry'; import { useBakerRewardItemStyles } from '../../baker-reward-item.styles'; @@ -15,7 +15,6 @@ export const MissedOwnBlocks: FC< Pick > = ({ missedBlockFees, missedBlockRewards, missedBlocks }) => { const styles = useBakerRewardItemStyles(); - const { metadata } = useNetworkInfo(); return ( <> @@ -36,7 +35,7 @@ export const MissedOwnBlocks: FC< -{missedBlockRewards.decimalPlaces(2, BigNumber.ROUND_FLOOR).toString() + ' '} - {metadata.symbol} + {TEZ_TOKEN_SYMBOL} {' '} for {missedBlocks.toString()} blocks @@ -45,7 +44,7 @@ export const MissedOwnBlocks: FC< -{missedBlockFees.decimalPlaces(2, BigNumber.ROUND_FLOOR).toString() + ' '} - {metadata.symbol} + {TEZ_TOKEN_SYMBOL} fees diff --git a/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-reward-item/baker-reward-item-details/details/own-blocks.tsx b/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-reward-item/baker-reward-item-details/details/own-blocks.tsx index b1d6b142f..84e85ec4f 100644 --- a/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-reward-item/baker-reward-item-details/details/own-blocks.tsx +++ b/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-reward-item/baker-reward-item-details/details/own-blocks.tsx @@ -5,8 +5,8 @@ import { Text, View } from 'react-native'; import { Divider } from 'src/components/divider/divider'; import { Icon } from 'src/components/icon/icon'; import { IconNameEnum } from 'src/components/icon/icon-name.enum'; -import { useNetworkInfo } from 'src/hooks/use-network-info.hook'; import { formatSize } from 'src/styles/format-size'; +import { TEZ_TOKEN_SYMBOL } from 'src/token/data/tokens-metadata'; import { BakingHistoryEntry } from '../../../interfaces/baking-history-entry'; import { useBakerRewardItemStyles } from '../../baker-reward-item.styles'; @@ -17,7 +17,6 @@ export const OwnBlocks: FC { const styles = useBakerRewardItemStyles(); - const { metadata } = useNetworkInfo(); return ( <> @@ -38,7 +37,7 @@ export const OwnBlocks: FC +{blockRewards.decimalPlaces(2, BigNumber.ROUND_FLOOR).toString() + ' '} - {metadata.symbol} + {TEZ_TOKEN_SYMBOL} {' '} for {blocks.toString()} blocks @@ -47,7 +46,7 @@ export const OwnBlocks: FC +{blockFees.decimalPlaces(2, BigNumber.ROUND_FLOOR).toString() + ' '} - {metadata.symbol} + {TEZ_TOKEN_SYMBOL} fees diff --git a/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-reward-item/baker-reward-item.tsx b/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-reward-item/baker-reward-item.tsx index 34e23df36..4eb11d06a 100644 --- a/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-reward-item/baker-reward-item.tsx +++ b/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-reward-item/baker-reward-item.tsx @@ -10,9 +10,8 @@ import { Icon } from 'src/components/icon/icon'; import { IconNameEnum } from 'src/components/icon/icon-name.enum'; import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; import { SafeTouchableOpacity } from 'src/components/safe-touchable-opacity'; -import { useNetworkInfo } from 'src/hooks/use-network-info.hook'; -import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { formatSize } from 'src/styles/format-size'; +import { TEZ_TOKEN_SYMBOL } from 'src/token/data/tokens-metadata'; import { isString } from 'src/utils/is-string'; import { isTruthy } from 'src/utils/is-truthy'; import { tzktUrl } from 'src/utils/linking'; @@ -45,12 +44,8 @@ export const BakerRewardItem: FC<{ item: BakingHistoryEntry }> = ({ item }) => { const styles = useBakerRewardItemStyles(); - const selectedRpcUrl = useSelectedRpcUrlSelector(); - const [isDetailsOpen, setIsDetailsOpen] = useState(false); - const { metadata, isDcpNode } = useNetworkInfo(); - const luckPercentage = luck.times(100); const efficiencyPercentage = efficiency.multipliedBy(100); @@ -97,20 +92,20 @@ export const BakerRewardItem: FC<{ item: BakingHistoryEntry }> = ({ item }) => { - + Delegated: {delegated.lt(1) ? '<1' : delegated.decimalPlaces(0, BigNumber.ROUND_FLOOR).toString()} - {` ${metadata.symbol} `} + {` ${TEZ_TOKEN_SYMBOL} `} {status === CycleStatus.UNLOCKED && ( Rewards & Luck: - {`${totalRewards.toString()} ${metadata.symbol} `} + {`${totalRewards.toString()} ${TEZ_TOKEN_SYMBOL} `} ({luckPercentage.gt(0) ? '+' : ''} {luckPercentage.decimalPlaces(0).toString()}%) @@ -119,18 +114,18 @@ export const BakerRewardItem: FC<{ item: BakingHistoryEntry }> = ({ item }) => { )} - {isDcpNode ? 'Producer' : 'Baker'} fee: + Baker fee: {isTruthy(feeStr) ? feeStr : '--'}% {' '} - ({bakerFee.toString()} {metadata.symbol}) + ({bakerFee.toString()} {TEZ_TOKEN_SYMBOL}) Expected payout: - {`${expectedPayout} ${metadata.symbol}`} + {`${expectedPayout} ${TEZ_TOKEN_SYMBOL}`} {status === CycleStatus.UNLOCKED && ( diff --git a/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-rewards-list.tsx b/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-rewards-list.tsx index 5d2e4fb3e..05d9f59c3 100644 --- a/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-rewards-list.tsx +++ b/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/baker-rewards-list.tsx @@ -6,7 +6,6 @@ import useSWR from 'swr'; import { DataPlaceholder } from 'src/components/data-placeholder/data-placeholder'; import { useSelectedBakerSelector } from 'src/store/baking/baking-selectors'; -import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { useAccountAddressForTezos } from 'src/store/wallet/wallet-selectors'; import { showErrorToast } from 'src/toast/toast.utils'; import { useAnalytics } from 'src/utils/analytics/use-analytics.hook'; @@ -55,32 +54,25 @@ const getCycleValue = ( export const BakerRewardsList = memo(() => { const selectedBaker = useSelectedBakerSelector(); - const selectedRpcUrl = useSelectedRpcUrlSelector(); const accountPkh = useAccountAddressForTezos(); const { trackErrorEvent } = useAnalytics(); const styles = useBakerRewardsListStyles(); const getBakingHistory = useCallback( - async ([, accountPkh, , selectedRpcUrl]: [string, string, string | nullish, string]) => { + async ([, accountPkh]: [string, string, string | nullish]) => { const fetchedValues: Record = {}; try { - const rewards = await getDelegatorRewards(selectedRpcUrl, { address: accountPkh, limit: 30 }).then( - res => res || [] - ); + const rewards = await getDelegatorRewards({ address: accountPkh, limit: 30 }).then(res => res || []); fetchedValues.rewards = rewards; - const [newestCycle] = await getCycles(selectedRpcUrl, undefined, 1); + const [newestCycle] = await getCycles(undefined, 1); fetchedValues.newestCycle = newestCycle; const [cycles, protocol] = rewards.length === 0 - ? await Promise.all([getCycles(selectedRpcUrl), getProtocol(selectedRpcUrl)]) + ? await Promise.all([getCycles(), getProtocol()]) : await Promise.all([ - getCycles( - selectedRpcUrl, - newestCycle.index - rewards[0].cycle, - rewards[0].cycle - rewards.at(-1)!.cycle + 1 - ), - getProtocolByCycle(selectedRpcUrl, rewards[0].cycle) + getCycles(newestCycle.index - rewards[0].cycle, rewards[0].cycle - rewards.at(-1)!.cycle + 1), + getProtocolByCycle(rewards[0].cycle) ]); fetchedValues.cycles = cycles; fetchedValues.protocol = protocol; @@ -88,7 +80,7 @@ export const BakerRewardsList = memo(() => { fetchedValues.bakersAddresses = bakersAddresses; const setParamsOperationsValues = await Promise.all( bakersAddresses.map(address => - fetchSetDelegateParametersOperations(selectedRpcUrl, { sender: address, 'sort.desc': 'level' }) + fetchSetDelegateParametersOperations({ sender: address, 'sort.desc': 'level' }) ) ); fetchedValues.setParamsOperations = setParamsOperationsValues; @@ -105,10 +97,7 @@ export const BakerRewardsList = memo(() => { stories: Object.fromEntries(bakersAddresses.map((address, i) => [address, storiesValues[i]])) }; } catch (error) { - trackErrorEvent('BakerRewardsListGetBakingHistoryError', error, [accountPkh], { - fetchedValues, - selectedRpcUrl - }); + trackErrorEvent('BakerRewardsListGetBakingHistoryError', error, [accountPkh], { fetchedValues }); showErrorToast({ description: 'Failed to load rewards history' }); return undefined; @@ -118,7 +107,7 @@ export const BakerRewardsList = memo(() => { ); const { data: bakingHistoryInput, isLoading } = useSWR( - ['baking-history', accountPkh, selectedBaker?.address, selectedRpcUrl], + ['baking-history', accountPkh, selectedBaker?.address], getBakingHistory, { suspense: true, errorRetryCount: 2 } ); diff --git a/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/utils/tzkt.ts b/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/utils/tzkt.ts index 7f977f765..78b464de4 100644 --- a/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/utils/tzkt.ts +++ b/src/screens/delegation-screen/selected-baker-screen/baker-rewards-list/utils/tzkt.ts @@ -1,4 +1,4 @@ -import { getTzktApi } from 'src/api.service'; +import { tzktApi } from 'src/api.service'; import { TzktCycle } from 'src/interfaces/tzkt/cycle.interface'; import { TzktProtocol } from 'src/interfaces/tzkt/protocol.interface'; @@ -11,11 +11,8 @@ import { TzktSetDelegateParamsOperation } from '../interfaces/tzkt'; -export const getDelegatorRewards = ( - selectedRpcUrl: string, - { address, cycle = {}, sort, quote, ...restParams }: TzktGetRewardsParams -) => - getTzktApi(selectedRpcUrl) +export const getDelegatorRewards = ({ address, cycle = {}, sort, quote, ...restParams }: TzktGetRewardsParams) => + tzktApi .get(`/rewards/delegators/${address}`, { params: { ...allInt32ParameterKeys.reduce( @@ -32,25 +29,13 @@ export const getDelegatorRewards = ( }) .then(x => x.data); -export const getCycles = (selectedRpcUrl: string, offset?: number, limit?: number) => - getTzktApi(selectedRpcUrl) - .get('/cycles', { params: { offset, limit } }) - .then(x => x.data); +export const getCycles = (offset?: number, limit?: number) => + tzktApi.get('/cycles', { params: { offset, limit } }).then(x => x.data); -export const getProtocol = (selectedRpcUrl: string) => - getTzktApi(selectedRpcUrl) - .get('/protocols/current') - .then(x => x.data); +export const getProtocol = () => tzktApi.get('/protocols/current').then(x => x.data); -export const getProtocolByCycle = (selectedRpcUrl: string, cycle: number) => - getTzktApi(selectedRpcUrl) - .get(`/protocols/cycles/${cycle}`) - .then(x => x.data); +export const getProtocolByCycle = (cycle: number) => + tzktApi.get(`/protocols/cycles/${cycle}`).then(x => x.data); -export const fetchSetDelegateParametersOperations = ( - selectedRpcUrl: string, - params: GetOperationsBaseParams & OperationSortParams -) => - getTzktApi(selectedRpcUrl) - .get('/operations/set_delegate_parameters', { params }) - .then(x => x.data); +export const fetchSetDelegateParametersOperations = (params: GetOperationsBaseParams & OperationSortParams) => + tzktApi.get('/operations/set_delegate_parameters', { params }).then(x => x.data); diff --git a/src/screens/delegation-screen/selected-baker-screen/selected-baker-screen.tsx b/src/screens/delegation-screen/selected-baker-screen/selected-baker-screen.tsx index 654d41036..098e70285 100644 --- a/src/screens/delegation-screen/selected-baker-screen/selected-baker-screen.tsx +++ b/src/screens/delegation-screen/selected-baker-screen/selected-baker-screen.tsx @@ -9,10 +9,10 @@ import { ExternalLinkButton } from 'src/components/icon/external-link-button/ext import { Icon } from 'src/components/icon/icon'; import { IconNameEnum } from 'src/components/icon/icon-name.enum'; import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; -import { useNetworkInfo } from 'src/hooks/use-network-info.hook'; -import { useIsInAppBrowserEnabledSelector, useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; +import { useIsInAppBrowserEnabledSelector } from 'src/store/settings/settings-selectors'; import { formatSize } from 'src/styles/format-size'; import { useColors } from 'src/styles/use-colors'; +import { TEZ_TOKEN_SYMBOL } from 'src/token/data/tokens-metadata'; import { isDefined } from 'src/utils/is-defined'; import { isTruthy } from 'src/utils/is-truthy'; import { openUrl, tzktUrl, useOpenUrlInAppBrowser } from 'src/utils/linking'; @@ -34,10 +34,6 @@ export const SelectedBakerScreen: FC = ({ baker, onRedelegatePress }) => const styles = useSelectedBakerScreenStyles(); const colors = useColors(); - const { metadata, isDcpNode } = useNetworkInfo(); - const selectedRpcUrl = useSelectedRpcUrlSelector(); - const bakerName = isDcpNode ? 'Current Producer' : baker.name; - const openUrlInAppBrowser = useOpenUrlInAppBrowser(); const isInAppBrowserEnabled = useIsInAppBrowserEnabledSelector(); @@ -59,14 +55,14 @@ export const SelectedBakerScreen: FC = ({ baker, onRedelegatePress }) => - {bakerName} + {baker.name} @@ -84,56 +80,52 @@ export const SelectedBakerScreen: FC = ({ baker, onRedelegatePress }) => - {!isDcpNode && ( - - - Delegated: - {isDefined(stakingBalance) ? kFormatter(stakingBalance) : '--'} - - - - Space: - - {isDefined(freeSpace) ? kFormatter(freeSpace) : '--'} {metadata.symbol} - - - - - Baker fee: - {isTruthy(feeStr) ? feeStr : '--'}% - - - - Min Balance: - {isDefined(minBalance) ? `${minBalance} TEZ` : '--'} - + + + Delegated: + {isDefined(stakingBalance) ? kFormatter(stakingBalance) : '--'} - )} + + + Space: + + {isDefined(freeSpace) ? kFormatter(freeSpace) : '--'} {TEZ_TOKEN_SYMBOL} + + + + + Baker fee: + {isTruthy(feeStr) ? feeStr : '--'}% + + + + Min Balance: + {isDefined(minBalance) ? `${minBalance} TEZ` : '--'} + + - {!isDcpNode && ( - - - - - - - - - - Stake TEZ - - - Earn interest up to 17.5% APY - - + + + + + - - + + + + Stake TEZ + + + Earn interest up to 17.5% APY + - - )} + + + + + diff --git a/src/screens/farming/farm-item.tsx b/src/screens/farming/farm-item.tsx index f2d7d159c..ce129c800 100644 --- a/src/screens/farming/farm-item.tsx +++ b/src/screens/farming/farm-item.tsx @@ -88,11 +88,7 @@ export const FarmItem: FC = ({ farm, lastStakeRecord }) => { } } catch (e) { trackErrorEvent('FarmHarvestAssetsError', e, [], { - harvestAssetsInput: { - rpcUrl: tezos.rpc.getRpcUrl(), - contractAddress, - lastStakeId - } + harvestAssetsInput: { contractAddress, lastStakeId } }); } }, [ diff --git a/src/screens/manage-assets/manage-assets-item/manage-assets-item.tsx b/src/screens/manage-assets/manage-assets-item/manage-assets-item.tsx index e143d0cb1..d50f14b70 100644 --- a/src/screens/manage-assets/manage-assets-item/manage-assets-item.tsx +++ b/src/screens/manage-assets/manage-assets-item/manage-assets-item.tsx @@ -8,8 +8,6 @@ import { TouchableIcon } from 'src/components/icon/touchable-icon/touchable-icon import { Switch } from 'src/components/switch/switch'; import { TokenContainer } from 'src/components/token-container/token-container'; import { VisibilityEnum } from 'src/enums/visibility.enum'; -import { useNetworkInfo } from 'src/hooks/use-network-info.hook'; -import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { removeTokenAction, toggleTokenVisibilityAction } from 'src/store/wallet/wallet-actions'; import { formatSize } from 'src/styles/format-size'; import { TokenInterface } from 'src/token/interfaces/token.interface'; @@ -23,10 +21,6 @@ export const ManageAssetsItem: FC = ({ asset }) => { const dispatch = useDispatch(); const slug = getTokenSlug(asset); - const selectedRpcUrl = useSelectedRpcUrlSelector(); - - const { isTezosNode } = useNetworkInfo(); - const handleTrashIconPress = () => Alert.alert('Delete asset?', 'You can add this asset again in the same menu in the "Add asset" section.', [ { @@ -42,11 +36,11 @@ export const ManageAssetsItem: FC = ({ asset }) => { return ( - {isTezosNode && } + dispatch(toggleTokenVisibilityAction({ slug, selectedRpcUrl }))} + onChange={() => dispatch(toggleTokenVisibilityAction({ slug }))} /> ); diff --git a/src/screens/manage-assets/manage-collectibles/manage-collectibles.tsx b/src/screens/manage-assets/manage-collectibles/manage-collectibles.tsx index 8b731b002..08acadfd7 100644 --- a/src/screens/manage-assets/manage-collectibles/manage-collectibles.tsx +++ b/src/screens/manage-assets/manage-collectibles/manage-collectibles.tsx @@ -5,7 +5,6 @@ import { Text } from 'react-native'; import { DataPlaceholder } from 'src/components/data-placeholder/data-placeholder'; import { SearchInput } from 'src/components/search-input/search-input'; import { useFilteredAssetsList } from 'src/hooks/use-filtered-assets-list.hook'; -import { useNetworkInfo } from 'src/hooks/use-network-info.hook'; import { TokenInterface } from 'src/token/interfaces/token.interface'; import { getTokenSlug } from 'src/token/utils/token.utils'; import { useCurrentAccountCollectibles } from 'src/utils/assets/hooks'; @@ -21,8 +20,6 @@ const ListEmptyComponent = - Show{isTezosNode && ', remove'} and hide collectibles. + Show, remove, and hide collectibles. - Show{isTezosNode && ', remove'} and hide tokens at your home screen. + Show, remove, and hide tokens at your home screen. = ({ onGoBackPress }) => { const styles = useVerifySeedPhraseStyles(); const navigateToScreen = useNavigateToScreen(); const { revealSeedPhrase } = useShelter(); - const canUseOnRamp = useCanUseOnRamp(); const [words, setWords] = useState([]); @@ -115,7 +114,7 @@ export const VerifySeedPhrase: FC = ({ onGoBackPress }) => { dispatch(madeManualBackupAction()); showSuccessToast({ description: 'You have successfully verified seed phrase!' }); - canUseOnRamp && dispatch(setOnRampOverlayStateAction(OnRampOverlayState.Start)); + !LIMIT_FIN_FEATURES && dispatch(setOnRampOverlayStateAction(OnRampOverlayState.Start)); }; return ( diff --git a/src/screens/market/tezos-info/tezos-info.tsx b/src/screens/market/tezos-info/tezos-info.tsx index 939f4a780..2e8584945 100644 --- a/src/screens/market/tezos-info/tezos-info.tsx +++ b/src/screens/market/tezos-info/tezos-info.tsx @@ -5,10 +5,10 @@ import { IconNameEnum } from 'src/components/icon/icon-name.enum'; import { TouchableIcon } from 'src/components/icon/touchable-icon/touchable-icon'; import { TokenIcon } from 'src/components/token-icon/token-icon'; import { TruncatedText } from 'src/components/truncated-text'; -import { useNetworkInfo } from 'src/hooks/use-network-info.hook'; import { useTezosMarketTokenSelector } from 'src/store/market/market-selectors'; import { formatSize } from 'src/styles/format-size'; import { useColors } from 'src/styles/use-colors'; +import { TEZ_TOKEN_METADATA } from 'src/token/data/tokens-metadata'; import { formatPrice, formatPriceChange, formatRegularValue, getPriceChangeColor } from 'src/utils/market.utils'; import { MarketSelectors } from '../market.selectors'; @@ -18,7 +18,6 @@ import { useTezosInfoStyles } from './tezos-info.styles'; export const TezosInfo = () => { const styles = useTezosInfoStyles(); - const { metadata: tezosMetadata } = useNetworkInfo(); const marketTezos = useTezosMarketTokenSelector(); const colors = useColors(); @@ -38,10 +37,10 @@ export const TezosInfo = () => { - + - {tezosMetadata.symbol} + {TEZ_TOKEN_METADATA.symbol} {marketTezos?.name} diff --git a/src/screens/network-settings/index.tsx b/src/screens/network-settings/index.tsx new file mode 100644 index 000000000..520cc3e2f --- /dev/null +++ b/src/screens/network-settings/index.tsx @@ -0,0 +1,61 @@ +import React from 'react'; +import { StyleSheet } from 'react-native'; + +import { ScreenContainer } from 'src/components/screen-container/screen-container'; +import { TempleChainKind } from 'src/enums/temple-chain-kind.enum'; +import { useEvmChain } from 'src/hooks/use-evm-chains.hook'; +import { useTezosChain } from 'src/hooks/use-tezos-chains.hook'; +import { ScreensEnum } from 'src/navigator/enums/screens.enum'; +import { useScreenParams } from 'src/navigator/hooks/use-navigation.hook'; +import { formatSize } from 'src/styles/format-size'; +import { ChainId, ChainOfKind } from 'src/types/networks'; +import { usePageAnalytic } from 'src/utils/analytics/use-analytics.hook'; + +import { NetworkSettingsLayout } from './network-settings-layout'; + +export const NetworkSettings = () => { + const { chainId } = useScreenParams(); + + usePageAnalytic(ScreensEnum.NetworkSettings); + + return ( + + {typeof chainId === 'number' ? ( + + ) : ( + + )} + + ); +}; + +const NetworkSettingsContentHOC = ( + useChain: (chainId: ChainId) => ChainOfKind | undefined +) => { + const NetworkSettings = (props: { chainId: ChainId }) => { + const chain = useChain(props.chainId); + + if (!chain) { + return null; + } + + return ( + + ); + }; + + return NetworkSettings; +}; + +const EvmNetworkSettingsContent = NetworkSettingsContentHOC(useEvmChain); +const TezosNetworkSettingsContent = NetworkSettingsContentHOC(useTezosChain); +const styles = StyleSheet.create({ + container: { + paddingTop: formatSize(16) + } +}); diff --git a/src/screens/network-settings/network-settings-layout/index.tsx b/src/screens/network-settings/network-settings-layout/index.tsx new file mode 100644 index 000000000..408cf8a72 --- /dev/null +++ b/src/screens/network-settings/network-settings-layout/index.tsx @@ -0,0 +1,76 @@ +import { memo, useMemo } from 'react'; +import { Text, View } from 'react-native'; + +import { BlockExplorer, RpcBase } from 'src/types/networks'; + +import { useNetworkSettingsLayoutStyles } from './styles'; + +interface OptionProps { + id: string; + title: string; + description: string; +} + +interface NetworkSettingsLayoutProps { + activeRpcEndpointId: string; + rpcEndpoints: RpcBase[]; + activeBlockExplorerId: string; + blockExplorers: BlockExplorer[]; +} + +export const NetworkSettingsLayout = memo( + ({ activeRpcEndpointId, rpcEndpoints, activeBlockExplorerId, blockExplorers }) => { + const styles = useNetworkSettingsLayoutStyles(); + + const rpcEndpointItems = useMemo( + () => + rpcEndpoints.map(({ id, name, description, rpcBaseURL }) => ({ + id, + title: name, + description: description || rpcBaseURL + })), + [rpcEndpoints] + ); + + const blockExplorerItems = useMemo( + () => blockExplorers.map(({ id, name, url }) => ({ id, title: name, description: url })), + [blockExplorers] + ); + + return ( + + + + + ); + } +); + +interface LayoutSectionProps { + title: string; + items: OptionProps[]; + activeItemId: string; +} + +const LayoutSection = memo(({ title, items, activeItemId }) => { + const styles = useNetworkSettingsLayoutStyles(); + + return ( + + {title} + {items.map(({ id, title, description }) => ( + + + {title} + {description} + + {id === activeItemId && ( + + Active + + )} + + ))} + + ); +}); diff --git a/src/screens/network-settings/network-settings-layout/styles.ts b/src/screens/network-settings/network-settings-layout/styles.ts new file mode 100644 index 000000000..ffccf41b3 --- /dev/null +++ b/src/screens/network-settings/network-settings-layout/styles.ts @@ -0,0 +1,54 @@ +import { StyleSheet } from 'react-native'; + +import { black } from 'src/config/styles'; +import { createUseStylesMemoized } from 'src/styles/create-use-styles'; +import { formatSize, formatTextSize } from 'src/styles/format-size'; +import { generateShadow } from 'src/styles/generate-shadow'; +import { hexa } from 'src/utils/style.util'; + +export const useNetworkSettingsLayoutStyles = createUseStylesMemoized(({ colors, typography }) => ({ + container: { + gap: formatSize(24) + }, + section: { + gap: formatSize(8) + }, + sectionTitle: { + ...typography.body15Semibold, + color: colors.black + }, + optionContainer: { + ...generateShadow(1, black), + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + gap: formatSize(4), + padding: formatSize(16), + borderRadius: formatSize(10), + backgroundColor: colors.cardBG + }, + optionTitle: { + ...typography.caption13Semibold, + color: colors.black, + lineHeight: formatTextSize(18) + }, + optionDescription: { + ...typography.caption11Regular, + color: colors.gray1, + lineHeight: formatTextSize(13) + }, + activeLabel: { + borderWidth: StyleSheet.hairlineWidth * 2, + borderColor: colors.adding, + backgroundColor: hexa(colors.adding, 0.1), + paddingHorizontal: formatSize(8), + borderRadius: formatSize(4), + height: formatSize(19), + justifyContent: 'center', + alignItems: 'center' + }, + activeLabelText: { + ...typography.tagline11TagUppercase, + color: colors.adding + } +})); diff --git a/src/screens/networks/all-networks-options/index.tsx b/src/screens/networks/all-networks-options/index.tsx new file mode 100644 index 000000000..78d7877bd --- /dev/null +++ b/src/screens/networks/all-networks-options/index.tsx @@ -0,0 +1,77 @@ +import { memo, useCallback } from 'react'; +import { StyleProp, Text, View, ViewStyle } from 'react-native'; + +import { Icon } from 'src/components/icon/icon'; +import { IconNameEnum } from 'src/components/icon/icon-name.enum'; +import { TouchableWithAnalytics } from 'src/components/touchable-with-analytics'; +import { TempleChainKind } from 'src/enums/temple-chain-kind.enum'; +import { useEvmChains } from 'src/hooks/use-evm-chains.hook'; +import { useTezosChains } from 'src/hooks/use-tezos-chains.hook'; +import { formatSize } from 'src/styles/format-size'; +import { ChainId, ChainOfKind } from 'src/types/networks'; + +import { NetworksSelectors } from '../selectors'; + +import { useAllNetworksOptionsStyles } from './styles'; + +interface AllNetworksOptionsProps { + onSelect: SyncFn; +} + +export const AllNetworksOptions = memo(({ onSelect }) => { + const styles = useAllNetworksOptionsStyles(); + + const evmChains = useEvmChains(); + const tezosChains = useTezosChains(); + + return ( + + {tezosChains.map(chain => ( + + ))} + {evmChains.map(chain => ( + + ))} + + ); +}); + +interface AllNetworksOptionProps { + chain: ChainOfKind; + onClick: SyncFn>; +} + +const AllNetworksOptionHOC = ( + NetworkIcon: React.ComponentType<{ chainId: ChainId; size: number; style: StyleProp }> +) => { + const AllNetworksOption = memo>(({ chain, onClick }) => { + const styles = useAllNetworksOptionsStyles(); + const { name, chainId } = chain; + + const handlePress = useCallback(() => onClick(chainId), [chainId, onClick]); + + return ( + + + {name} + + + ); + }); + + return AllNetworksOption; +}; + +const TezosNetworkOption = AllNetworksOptionHOC(({ size, style }) => ( + +)); + +// TODO: Add icons for other EVM chains +const EvmNetworkOption = AllNetworksOptionHOC(({ size, style }) => ( + +)); diff --git a/src/screens/networks/all-networks-options/styles.ts b/src/screens/networks/all-networks-options/styles.ts new file mode 100644 index 000000000..be9d3d53c --- /dev/null +++ b/src/screens/networks/all-networks-options/styles.ts @@ -0,0 +1,28 @@ +import { black } from 'src/config/styles'; +import { createUseStylesMemoized } from 'src/styles/create-use-styles'; +import { formatSize } from 'src/styles/format-size'; +import { generateShadow } from 'src/styles/generate-shadow'; + +export const useAllNetworksOptionsStyles = createUseStylesMemoized(({ colors, typography }) => ({ + container: { + gap: formatSize(8) + }, + option: { + ...generateShadow(1, black), + backgroundColor: colors.cardBG, + padding: formatSize(12), + paddingRight: formatSize(16), + flexDirection: 'row', + alignItems: 'center', + gap: formatSize(4), + borderRadius: formatSize(10) + }, + optionIcon: { + margin: formatSize(5) + }, + optionName: { + ...typography.body15Semibold, + color: colors.black, + flex: 1 + } +})); diff --git a/src/screens/networks/index.tsx b/src/screens/networks/index.tsx new file mode 100644 index 000000000..2b45deaea --- /dev/null +++ b/src/screens/networks/index.tsx @@ -0,0 +1,34 @@ +import React, { useCallback } from 'react'; +import { StyleSheet } from 'react-native'; + +import { ScreenContainer } from 'src/components/screen-container/screen-container'; +import { ScreensEnum } from 'src/navigator/enums/screens.enum'; +import { useNavigateToScreen } from 'src/navigator/hooks/use-navigation.hook'; +import { formatSize } from 'src/styles/format-size'; +import { ChainId } from 'src/types/networks'; +import { usePageAnalytic } from 'src/utils/analytics/use-analytics.hook'; + +import { AllNetworksOptions } from './all-networks-options'; + +export const Networks = () => { + const navigateToScreen = useNavigateToScreen(); + + usePageAnalytic(ScreensEnum.Networks); + + const handleNetworkSelect = useCallback( + (chainId: ChainId) => navigateToScreen({ screen: ScreensEnum.NetworkSettings, params: { chainId } }), + [navigateToScreen] + ); + + return ( + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + paddingTop: formatSize(16) + } +}); diff --git a/src/screens/networks/selectors.ts b/src/screens/networks/selectors.ts new file mode 100644 index 000000000..1d7a57f7c --- /dev/null +++ b/src/screens/networks/selectors.ts @@ -0,0 +1,3 @@ +export enum NetworksSelectors { + networkOption = 'Networks/Network Option' +} diff --git a/src/screens/node-settings/node-settings.selectors.ts b/src/screens/node-settings/node-settings.selectors.ts deleted file mode 100644 index 5bb8f9222..000000000 --- a/src/screens/node-settings/node-settings.selectors.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum NodeSettingsSelectors { - addNodeButton = 'Settings Default node (RPC)/Add Node "+" Button', - nodeRadioButton = 'Settings Default node (RPC)/Node Radio Button' -} diff --git a/src/screens/node-settings/node-settings.tsx b/src/screens/node-settings/node-settings.tsx deleted file mode 100644 index aa8dabb52..000000000 --- a/src/screens/node-settings/node-settings.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React, { useMemo } from 'react'; -import { useDispatch } from 'react-redux'; - -import { generateScreenOptions } from 'src/components/header/generate-screen-options.util'; -import { HeaderButton } from 'src/components/header/header-button/header-button'; -import { HeaderTitle } from 'src/components/header/header-title/header-title'; -import { useNavigationSetOptions } from 'src/components/header/use-navigation-set-options.hook'; -import { IconNameEnum } from 'src/components/icon/icon-name.enum'; -import { ScreenContainer } from 'src/components/screen-container/screen-container'; -import { StyledRadioGroup } from 'src/components/styled-radio-group'; -import { ModalsEnum } from 'src/navigator/enums/modals.enum'; -import { ScreensEnum } from 'src/navigator/enums/screens.enum'; -import { useNavigateToModal } from 'src/navigator/hooks/use-navigation.hook'; -import { setSelectedRpcUrl } from 'src/store/settings/settings-actions'; -import { useRpcListSelector, useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; -import { usePageAnalytic } from 'src/utils/analytics/use-analytics.hook'; -import { isDcpNode } from 'src/utils/network.utils'; -import { TEMPLE_RPC } from 'src/utils/rpc/rpc-list'; - -import { NodeSettingsSelectors } from './node-settings.selectors'; - -export const NodeSettings = () => { - const dispatch = useDispatch(); - const navigateToModal = useNavigateToModal(); - - const rpcList = useRpcListSelector(); - const selectedRpcUrl = useSelectedRpcUrlSelector(); - - const radioItems = useMemo( - () => - rpcList.map(rpc => ({ - label: rpc.name, - value: rpc.url, - buttons: [ - { - key: 'edit', - iconName: IconNameEnum.Edit, - disabled: rpc.url === TEMPLE_RPC.url || isDcpNode(rpc.url) ? true : undefined, - onPress: () => void navigateToModal(ModalsEnum.EditCustomRpc, { url: rpc.url }) - } - ], - disabledMessage: isDcpNode(rpc.url) ? 'The T4L3NT Mainnet RPC is temporarily unavailable.' : undefined - })), - [rpcList] - ); - - usePageAnalytic(ScreensEnum.NodeSettings); - - useNavigationSetOptions( - generateScreenOptions( - , - navigateToModal(ModalsEnum.AddCustomRpc)} - testID={NodeSettingsSelectors.addNodeButton} - /> - ), - [] - ); - - const handleChange = (newRpcUrl: string) => dispatch(setSelectedRpcUrl(newRpcUrl)); - - return ( - - - - ); -}; diff --git a/src/screens/scan-qr-code/scan-qr-code.tsx b/src/screens/scan-qr-code/scan-qr-code.tsx index 25ca911b2..c440e1f05 100644 --- a/src/screens/scan-qr-code/scan-qr-code.tsx +++ b/src/screens/scan-qr-code/scan-qr-code.tsx @@ -13,7 +13,6 @@ import { import { beaconDeepLinkHandler } from 'src/beacon/use-beacon-handler.hook'; import { useNavigationSetOptions } from 'src/components/header/use-navigation-set-options.hook'; import { isIOS } from 'src/config/system'; -import { useNetworkInfo } from 'src/hooks/use-network-info.hook'; import { useSuggestedHeaderHeight } from 'src/hooks/use-suggested-header-height.hook'; import { ConfirmationTypeEnum } from 'src/interfaces/confirm-payload/confirmation-type.enum'; import { ModalsEnum } from 'src/navigator/enums/modals.enum'; @@ -22,6 +21,7 @@ import { useNavigateToModal, useNavigation } from 'src/navigator/hooks/use-navig import { useIsAuthorisedSelector } from 'src/store/wallet/wallet-selectors'; import { formatSize } from 'src/styles/format-size'; import { showErrorToast } from 'src/toast/toast.utils'; +import { TEZ_TOKEN_METADATA } from 'src/token/data/tokens-metadata'; import { AnalyticsEventCategory } from 'src/utils/analytics/analytics-event.enum'; import { useAnalytics, usePageAnalytic } from 'src/utils/analytics/use-analytics.hook'; import { isBeaconPayload } from 'src/utils/beacon.utils'; @@ -67,8 +67,6 @@ const CameraView = () => { const { trackEvent } = useAnalytics(); const { top: topInset } = useSafeAreaInsets(); - const { metadata } = useNetworkInfo(); - usePageAnalytic(ScreensEnum.ScanQrCode); const handleRead = useCallback( @@ -85,10 +83,10 @@ const CameraView = () => { if (isAuthorised) { if (isValidAddress(data)) { if (Number(tezosToken.balance) > 0) { - navigateToModal(ModalsEnum.Send, { token: metadata, receiverPublicKeyHash: data }); + navigateToModal(ModalsEnum.Send, { token: TEZ_TOKEN_METADATA, receiverPublicKeyHash: data }); } else { trackEvent(ScanQrCodeAnalyticsEvents.SCAN_QR_CODE_ZERO_BALANCE, AnalyticsEventCategory.General); - showErrorToast({ description: `You need to have ${metadata.symbol} to pay gas fee` }); + showErrorToast({ description: `You need to have ${TEZ_TOKEN_METADATA.symbol} to pay gas fee` }); } } else if (isBeaconPayload(data)) { let dataWasIgnored = true; @@ -127,7 +125,7 @@ const CameraView = () => { } } }, - [goBack, navigateToModal, trackEvent, tezosToken, metadata, isAuthorised] + [goBack, navigateToModal, trackEvent, tezosToken, isAuthorised] ); const headerHeight = useSuggestedHeaderHeight(false); diff --git a/src/screens/settings/settings.selectors.ts b/src/screens/settings/settings.selectors.ts index 2a335b1c1..8e98064c3 100644 --- a/src/screens/settings/settings.selectors.ts +++ b/src/screens/settings/settings.selectors.ts @@ -7,7 +7,7 @@ export enum SettingsSelectors { secureButton = 'Settings/Secure Button', notificationsButton = 'Settings/Notifications Button', authorizedDAppsButton = 'Settings/Authorized DApps Button', - defaultNodeRPCButton = 'Settings/Default node (RPC) Button', + networksButton = 'Settings/Networks Button', aboutButton = 'Settings/About Button', shareTempleWalletButton = 'Settings/Share Temple Wallet Button', shareSuccess = 'Settings/Success sharing Temple Wallet', diff --git a/src/screens/settings/settings.tsx b/src/screens/settings/settings.tsx index 468d94fcf..f2c84a44d 100644 --- a/src/screens/settings/settings.tsx +++ b/src/screens/settings/settings.tsx @@ -216,10 +216,10 @@ export const Settings = () => { navigateToScreen({ screen: ScreensEnum.NodeSettings })} - testID={SettingsSelectors.defaultNodeRPCButton} + onPress={() => navigateToScreen({ screen: ScreensEnum.Networks })} + testID={SettingsSelectors.networksButton} > - + diff --git a/src/screens/swap/swap-form/swap-form.tsx b/src/screens/swap/swap-form/swap-form.tsx index 7ca86b57c..597e13a9f 100644 --- a/src/screens/swap/swap-form/swap-form.tsx +++ b/src/screens/swap/swap-form/swap-form.tsx @@ -24,10 +24,10 @@ import { SWAP_THRESHOLD_TO_GET_CASHBACK, TEMPLE_TOKEN } from 'src/config/swap'; +import { LIMIT_FIN_FEATURES } from 'src/config/system'; import { OnRampOverlayState } from 'src/enums/on-ramp-overlay-state.enum'; import { FormAssetAmountInput } from 'src/form/form-asset-amount-input/form-asset-amount-input'; import { useBlockLevel } from 'src/hooks/use-block-level.hook'; -import { useCanUseOnRamp } from 'src/hooks/use-can-use-on-ramp.hook'; import { TokensInputsEnum, useFilteredSwapTokensList } from 'src/hooks/use-filtered-swap-tokens.hook'; import { useOnRampContinueOverlay } from 'src/hooks/use-on-ramp-continue-overlay.hook'; import { useReadOnlyTezosToolkit } from 'src/hooks/use-read-only-tezos-toolkit.hook'; @@ -104,7 +104,6 @@ export const SwapForm: FC = ({ inputToken, outputToken }) => { const { isLoading: isMetadataLoading, data: tokensMetadataData } = useSwapTokensMetadataSelector(); const isLoading = isMetadataLoading && tokensMetadataData.length === 0; const usdExchangeRates = useUsdToTokenRates(); - const canUseOnRamp = useCanUseOnRamp(); const { isOpened: onRampOverlayIsOpened, onClose: onOnRampOverlayClose } = useOnRampContinueOverlay(); const swapParams = useSwapParamsSelector(); @@ -160,7 +159,7 @@ export const SwapForm: FC = ({ inputToken, outputToken }) => { return; } - if (inputAssetSlug === TEZ_TOKEN_SLUG && inputAssets.amount.isGreaterThan(tezosBalance) && canUseOnRamp) { + if (inputAssetSlug === TEZ_TOKEN_SLUG && inputAssets.amount.isGreaterThan(tezosBalance) && !LIMIT_FIN_FEATURES) { dispatch(setOnRampOverlayStateAction(OnRampOverlayState.Continue)); return; @@ -219,8 +218,7 @@ export const SwapForm: FC = ({ inputToken, outputToken }) => { toSymbol: TEMPLE_TOKEN.symbol, toTokenDecimals: TEMPLE_TOKEN.decimals, amount: mutezToTz(routingFeeFromInputAtomic, fromRoute3Token.decimals).toFixed(), - dexesLimit: CASHBACK_SWAP_MAX_DEXES, - rpcUrl: tezos.rpc.getRpcUrl() + dexesLimit: CASHBACK_SWAP_MAX_DEXES }); fetchedData.swapToTempleParams = swapToTempleParams; @@ -270,8 +268,7 @@ export const SwapForm: FC = ({ inputToken, outputToken }) => { toSymbol: TEMPLE_TOKEN.symbol, toTokenDecimals: TEMPLE_TOKEN.decimals, amount: mutezToTz(routingFeeFromOutputAtomic, toRoute3Token.decimals).toFixed(), - dexesLimit: CASHBACK_SWAP_MAX_DEXES, - rpcUrl: tezos.rpc.getRpcUrl() + dexesLimit: CASHBACK_SWAP_MAX_DEXES }); fetchedData.swapToTempleParams = swapToTempleParams; @@ -435,12 +432,11 @@ export const SwapForm: FC = ({ inputToken, outputToken }) => { toSymbol: getRoute3TokenSymbol(output.asset), toTokenDecimals: output.asset.decimals, amount: mutezToTz(amount, input.asset.decimals).toFixed(), - dexesLimit: mainSwapMaxDexes, - rpcUrl: tezos.rpc.getRpcUrl() + dexesLimit: mainSwapMaxDexes }) ); }, - [getSwapWithFeeParams, tezos.rpc] + [getSwapWithFeeParams] ); useEffect(() => { diff --git a/src/screens/tezos-token-screen/private-tezos-token-history/private-activity-item.tsx b/src/screens/tezos-token-screen/private-tezos-token-history/private-activity-item.tsx index 0a4833a70..004d3f6c5 100644 --- a/src/screens/tezos-token-screen/private-tezos-token-history/private-activity-item.tsx +++ b/src/screens/tezos-token-screen/private-tezos-token-history/private-activity-item.tsx @@ -13,7 +13,7 @@ import { SaplingTransactionHistoryItem } from 'src/interfaces/sapling-service.in import { useAssetExchangeRate } from 'src/store/settings/settings-selectors'; import { formatSize } from 'src/styles/format-size'; import { useColors } from 'src/styles/use-colors'; -import { TEZ_TOKEN_METADATA, TEZ_TOKEN_SLUG } from 'src/token/data/tokens-metadata'; +import { TEZ_TOKEN_DECIMALS, TEZ_TOKEN_SLUG } from 'src/token/data/tokens-metadata'; import { conditionalStyle } from 'src/utils/conditional-style'; import { formatAssetAmount } from 'src/utils/number.util'; import { mutezToTz } from 'src/utils/tezos.util'; @@ -33,7 +33,7 @@ export const PrivateActivityItem = ({ transaction }: Props) => { const iconName = isIncoming ? IconNameEnum.ArrowDown : IconNameEnum.ArrowUp; const iconColor = isIncoming ? colors.adding : colors.destructive; - const amountTez = mutezToTz(new BigNumber(transaction.value), TEZ_TOKEN_METADATA.decimals); + const amountTez = mutezToTz(new BigNumber(transaction.value), TEZ_TOKEN_DECIMALS); const formattedAmount = formatAssetAmount(amountTez); const dollarAmount = useMemo(() => { diff --git a/src/screens/tezos-token-screen/tezos-token-screen.tsx b/src/screens/tezos-token-screen/tezos-token-screen.tsx index 09a6b8def..fbf4ad7b5 100644 --- a/src/screens/tezos-token-screen/tezos-token-screen.tsx +++ b/src/screens/tezos-token-screen/tezos-token-screen.tsx @@ -36,7 +36,7 @@ import { useAssetExchangeRate } from 'src/store/settings/settings-selectors'; import { useAccountAddressForTezos } from 'src/store/wallet/wallet-selectors'; import { formatSize } from 'src/styles/format-size'; import { useColors } from 'src/styles/use-colors'; -import { TEZ_TOKEN_METADATA, TEZ_TOKEN_SLUG, TEZ_SHIELDED_TOKEN_METADATA } from 'src/token/data/tokens-metadata'; +import { TEZ_TOKEN_SLUG, TEZ_SHIELDED_TOKEN_METADATA, TEZ_TOKEN_DECIMALS } from 'src/token/data/tokens-metadata'; import type { TokenInterface } from 'src/token/interfaces/token.interface'; import { usePageAnalytic } from 'src/utils/analytics/use-analytics.hook'; import { mutezToTz } from 'src/utils/tezos.util'; @@ -83,11 +83,11 @@ export const TezosTokenScreen = () => { return ''; } - return mutezToTz(new BigNumber(tezosToken.balance), TEZ_TOKEN_METADATA.decimals).toFormat(); + return mutezToTz(new BigNumber(tezosToken.balance), TEZ_TOKEN_DECIMALS).toFormat(); }, [tezosToken.balance]); const formattedShieldedBalance = useMemo( - () => mutezToTz(new BigNumber(shieldedBalanceMutez), TEZ_TOKEN_METADATA.decimals).toFormat(), + () => mutezToTz(new BigNumber(shieldedBalanceMutez), TEZ_TOKEN_DECIMALS).toFormat(), [shieldedBalanceMutez] ); diff --git a/src/screens/token-info/token-info.tsx b/src/screens/token-info/token-info.tsx index d37f146df..3bb5af840 100644 --- a/src/screens/token-info/token-info.tsx +++ b/src/screens/token-info/token-info.tsx @@ -5,10 +5,10 @@ import { Divider } from 'src/components/divider/divider'; import { Label } from 'src/components/label/label'; import { ScreenContainer } from 'src/components/screen-container/screen-container'; import { StyledTextInput } from 'src/components/styled-text-input/styled-text-input'; -import { useTokenType } from 'src/hooks/use-token-type'; -import { TokenTypeEnum } from 'src/interfaces/token-type.enum'; +import { useTokenStandard } from 'src/hooks/use-token-standard'; import { ScreensEnum } from 'src/navigator/enums/screens.enum'; import { useScreenParams } from 'src/navigator/hooks/use-navigation.hook'; +import { TokenStandardsEnum } from 'src/token/interfaces/token-metadata.interface'; import { copyStringToClipboard } from 'src/utils/clipboard.utils'; import { isDefined } from 'src/utils/is-defined'; @@ -18,7 +18,7 @@ export const TokenInfo = () => { const { token } = useScreenParams(); const styles = useTokenInfoStyles(); - const { tokenType, loading } = useTokenType(token.address); + const { tokenStandard, loading } = useTokenStandard(token.address); const symbol = token.symbol; const isTezos = token.address === ''; @@ -37,7 +37,7 @@ export const TokenInfo = () => { - {isDefined(token.id) && !loading && tokenType === TokenTypeEnum.FA_2 && ( + {isDefined(token.id) && !loading && tokenStandard === TokenStandardsEnum.Fa2 && ( <> )} diff --git a/src/token/data/token-methods-assertions.ts b/src/token/data/token-methods-assertions.ts index a9b91e5d1..0b0eec4ea 100644 --- a/src/token/data/token-methods-assertions.ts +++ b/src/token/data/token-methods-assertions.ts @@ -2,9 +2,9 @@ import { TokenSchema } from '@taquito/michelson-encoder'; import { isEqual } from 'lodash-es'; import { ContractType } from 'src/interfaces/contract.type'; -import { TokenTypeEnum } from 'src/interfaces/token-type.enum'; import { assert } from 'src/utils/assert.utils'; +import { TokenStandardsEnum } from '../interfaces/token-metadata.interface'; import { TokenMethodsAssertionInterface } from '../interfaces/token-methods-assertion.interface'; const extractArgsTypes = (schema: TokenSchema): string[] => { @@ -62,7 +62,7 @@ const FA_2_TOKEN_METHODS_ASSERTIONS: TokenMethodsAssertionInterface[] = [ } ]; -export const TokenMethodsAssertionsMap: Record = { - [TokenTypeEnum.FA_1_2]: FA_1_2_TOKEN_METHODS_ASSERTIONS, - [TokenTypeEnum.FA_2]: FA_2_TOKEN_METHODS_ASSERTIONS +export const TokenMethodsAssertionsMap: Record = { + [TokenStandardsEnum.Fa12]: FA_1_2_TOKEN_METHODS_ASSERTIONS, + [TokenStandardsEnum.Fa2]: FA_2_TOKEN_METHODS_ASSERTIONS }; diff --git a/src/token/data/tokens-metadata.ts b/src/token/data/tokens-metadata.ts index f3b6754e9..9f221d77e 100644 --- a/src/token/data/tokens-metadata.ts +++ b/src/token/data/tokens-metadata.ts @@ -32,6 +32,9 @@ export const TEZ_TOKEN_METADATA: TokenMetadataInterface = { iconName: IconNameEnum.TezToken }; +export const TEZ_TOKEN_SYMBOL = TEZ_TOKEN_METADATA.symbol; +export const TEZ_TOKEN_DECIMALS = TEZ_TOKEN_METADATA.decimals; + export const TEZ_SHIELDED_TOKEN_SLUG = 'shielded_tez_0'; /** Shielded TEZ shares the same exchange rate as public TEZ */ @@ -46,14 +49,6 @@ export const TEZ_SHIELDED_TOKEN_METADATA: TokenMetadataInterface = { iconName: IconNameEnum.TezShieldedToken }; -export const FILM_TOKEN_METADATA: TokenMetadataInterface = { - ...emptyTokenMetadata, - name: 'FILM', - symbol: 'FILM', - decimals: 6, - iconName: IconNameEnum.FilmToken -}; - export const TZBTC_TOKEN_METADATA: TokenMetadataInterface = { id: 0, address: 'KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn', diff --git a/src/token/interfaces/token-metadata.interface.ts b/src/token/interfaces/token-metadata.interface.ts index 43f65a64a..9df4dab8e 100644 --- a/src/token/interfaces/token-metadata.interface.ts +++ b/src/token/interfaces/token-metadata.interface.ts @@ -25,3 +25,39 @@ export const emptyTokenMetadata: TokenMetadataInterface = { decimals: 0, standard: TokenStandardsEnum.Fa12 }; + +enum EvmAssetStandardEnum { + NATIVE = 'native', + ERC20 = 'erc20', + ERC721 = 'erc721', + ERC1155 = 'erc1155' +} + +export const EVM_TOKEN_SLUG = 'eth'; + +interface EvmAssetMetadataBase { + address: typeof EVM_TOKEN_SLUG | HexString; + standard?: EvmAssetStandardEnum; + /** contract name (for nft contract refers to collection name) */ + name?: string; + /** contract symbol (for nft contract refers to collection symbol) */ + symbol?: string; + /** contract decimals (could be available only for ERC20 tokens and native currency) */ + decimals?: number; + /** A fallback for icon URL */ + iconURL?: string; +} + +export interface EvmNativeTokenMetadata + extends RequiredBy> { + standard: EvmAssetStandardEnum.NATIVE; + address: typeof EVM_TOKEN_SLUG; +} + +export const DEFAULT_EVM_CURRENCY: EvmNativeTokenMetadata = { + address: EVM_TOKEN_SLUG, + standard: EvmAssetStandardEnum.NATIVE, + name: 'Ethereum', + symbol: 'ETH', + decimals: 18 +}; diff --git a/src/token/utils/token.utils.ts b/src/token/utils/token.utils.ts index 7bc5626b6..ea46eda1f 100644 --- a/src/token/utils/token.utils.ts +++ b/src/token/utils/token.utils.ts @@ -1,9 +1,9 @@ import { ContractType } from 'src/interfaces/contract.type'; -import { TokenTypeEnum } from 'src/interfaces/token-type.enum'; import { isString } from 'src/utils/is-string'; import { TokenMethodsAssertionsMap } from '../data/token-methods-assertions'; import { TEZ_TOKEN_SLUG } from '../data/tokens-metadata'; +import { TokenStandardsEnum } from '../interfaces/token-metadata.interface'; export const getTokenSlug = ({ address, id }: T) => toTokenSlug(address, id); @@ -11,7 +11,7 @@ export const getTokenSlug = isString(address) ? `${address}_${id ?? 0}` : TEZ_TOKEN_SLUG; -const assertTokenContractType = (contract: ContractType, tokenType: TokenTypeEnum) => { +const assertTokenContractType = (contract: ContractType, tokenType: TokenStandardsEnum) => { try { for (const assertion of TokenMethodsAssertionsMap[tokenType]) { const { name, assertionFn } = assertion; @@ -30,7 +30,8 @@ const assertTokenContractType = (contract: ContractType, tokenType: TokenTypeEnu }; export const isValidTokenContract = (contract: ContractType) => - assertTokenContractType(contract, TokenTypeEnum.FA_1_2) || assertTokenContractType(contract, TokenTypeEnum.FA_2); + assertTokenContractType(contract, TokenStandardsEnum.Fa12) || + assertTokenContractType(contract, TokenStandardsEnum.Fa2); -export const getTokenType = (tokenContract: ContractType) => - assertTokenContractType(tokenContract, TokenTypeEnum.FA_2) ? TokenTypeEnum.FA_2 : TokenTypeEnum.FA_1_2; +export const getTokenStandard = (tokenContract: ContractType) => + assertTokenContractType(tokenContract, TokenStandardsEnum.Fa2) ? TokenStandardsEnum.Fa2 : TokenStandardsEnum.Fa12; diff --git a/src/types/networks.ts b/src/types/networks.ts new file mode 100644 index 000000000..2cd9f7009 --- /dev/null +++ b/src/types/networks.ts @@ -0,0 +1,149 @@ +import { ChainIds } from '@taquito/taquito'; + +import { TempleChainKind } from '../enums/temple-chain-kind.enum'; +import { TEZ_TOKEN_SYMBOL } from '../token/data/tokens-metadata'; +import { DEFAULT_EVM_CURRENCY, EvmNativeTokenMetadata } from '../token/interfaces/token-metadata.interface'; +import { ETHERLINK_MAINNET_CHAIN_ID, FALLBACK_EVM_RPCS_LIST, TEMPLE_RPC } from '../utils/rpc/rpc-list'; + +export interface EvmNetworkEssentials { + rpcBaseURL: string; + chainId: number; +} + +export interface RpcBase { + chain: TempleChainKind; + id: string; + rpcBaseURL: string; + chainId: string | number; + name: string; + description?: string; + /** Means: hardcoded, never stored */ + default?: boolean; +} + +export interface TezosRpc extends RpcBase { + chain: TempleChainKind.Tezos; + chainId: string; +} + +export interface EvmRpc extends RpcBase { + chain: TempleChainKind.EVM; + chainId: number; +} + +interface BasicEvmChain { + kind: TempleChainKind.EVM; + chainId: number; +} + +interface BasicTezosChain { + kind: TempleChainKind.Tezos; + chainId: string; +} + +export interface BlockExplorer { + name: string; + url: string; + id: string; + default: boolean; +} + +interface ChainSpecsBase { + activeRpcId?: string; + activeBlockExplorerId?: string; + disabled?: boolean; + disabledAutomatically?: boolean; + name: string; + default: boolean; +} + +interface TezosChainSpecs extends ChainSpecsBase { + currencySymbol?: string; +} + +export interface EvmChainSpecs extends ChainSpecsBase { + chainId: number; + currency?: EvmNativeTokenMetadata; +} + +interface ChainBase { + activeBlockExplorer: BlockExplorer; + name: string; + disabled?: boolean; + disabledAutomatically?: boolean; + allBlockExplorers: BlockExplorer[]; + default: boolean; +} + +export interface TezosChain extends BasicTezosChain, ChainBase { + allRpcs: TezosRpc[]; + activeRpc: TezosRpc; + currencySymbol?: string; +} + +export interface EvmChain extends BasicEvmChain, ChainBase { + currency: EvmNativeTokenMetadata; + allRpcs: EvmRpc[]; + activeRpc: EvmRpc; +} + +export const DEFAULT_TEZOS_RPCS: TezosRpc[] = [ + { + id: 'tezos-default', + name: 'Tezos', + chain: TempleChainKind.Tezos, + chainId: ChainIds.MAINNET, + rpcBaseURL: TEMPLE_RPC.url, + description: 'Default', + default: true + } +]; + +export const DEFAULT_TEZOS_BLOCK_EXPLORERS: BlockExplorer[] = [ + { name: 'TzKT', url: 'https://tzkt.io', id: 'tzkt-mainnet', default: true } +]; + +export const DEFAULT_MAINNET_TEZOS_CHAIN_SPECS: TezosChainSpecs = { + name: 'Tezos', + currencySymbol: TEZ_TOKEN_SYMBOL, + activeRpcId: 'tezos-default', + activeBlockExplorerId: 'tzkt-mainnet', + default: true +}; + +export const DEFAULT_EVM_BLOCK_EXPLORERS: Record = { + [ETHERLINK_MAINNET_CHAIN_ID]: [ + { name: 'Etherlink explorer', url: 'https://explorer.etherlink.com', id: 'etherlink-mainnet', default: true } + ] +}; + +export const DEFAULT_RPC_INDEX = 0; + +export const DEFAULT_EVM_RPCS: Record = { + [ETHERLINK_MAINNET_CHAIN_ID]: [ + { + id: 'etherlink', + name: 'Etherlink', + chain: TempleChainKind.EVM, + chainId: ETHERLINK_MAINNET_CHAIN_ID, + rpcBaseURL: FALLBACK_EVM_RPCS_LIST[ETHERLINK_MAINNET_CHAIN_ID][DEFAULT_RPC_INDEX], + description: 'Default RPC', + default: true + } + ] +}; + +export const DEFAULT_EVM_CHAINS_SPECS: EvmChainSpecs[] = [ + { + name: 'Etherlink', + chainId: ETHERLINK_MAINNET_CHAIN_ID, + currency: { ...DEFAULT_EVM_CURRENCY, name: 'Tezos', symbol: 'XTZ' }, + activeRpcId: 'etherlink', + activeBlockExplorerId: 'etherlink-mainnet', + default: true + } +]; + +export type ChainOfKind = T extends TempleChainKind.Tezos ? TezosChain : EvmChain; + +export type ChainId = ChainOfKind['chainId']; diff --git a/src/utils/dns.utils.ts b/src/utils/dns.utils.ts index 86edf5725..efeaae5f8 100644 --- a/src/utils/dns.utils.ts +++ b/src/utils/dns.utils.ts @@ -5,8 +5,9 @@ import memoizee from 'memoizee'; import { createReadOnlyTezosToolkit } from './rpc/tezos-toolkit.utils'; export const tezosDomainsResolver = memoizee( - (rpcUrl: string) => - new TaquitoTezosDomainsClient({ network: 'mainnet', tezos: createReadOnlyTezosToolkit(rpcUrl) }).resolver + (preferredRpcUrl?: string) => + new TaquitoTezosDomainsClient({ network: 'mainnet', tezos: createReadOnlyTezosToolkit(undefined, preferredRpcUrl) }) + .resolver ); export const isTezosDomainNameValid = (domain: string) => diff --git a/src/utils/linking/index.ts b/src/utils/linking/index.ts index ecdc48614..12eef3328 100644 --- a/src/utils/linking/index.ts +++ b/src/utils/linking/index.ts @@ -4,8 +4,6 @@ import { Linking } from 'react-native'; import { ModalsEnum } from 'src/navigator/enums/modals.enum'; import { useNavigateToModal } from 'src/navigator/hooks/use-navigation.hook'; -import { isDcpNode } from '../network.utils'; - export const openUrl = (url: string) => { Linking.canOpenURL(url) .then(() => Linking.openURL(url)) @@ -18,5 +16,4 @@ export const useOpenUrlInAppBrowser = () => { return useCallback((uri: string) => void navigateToModal(ModalsEnum.InAppBrowser, { uri }), [navigateToModal]); }; -export const tzktUrl = (rpcUrl: string, address: string) => - isDcpNode(rpcUrl) ? `https://explorer.tlnt.net/${address}` : `https://tzkt.io/${address}`; +export const tzktUrl = (addressOrTxHash: string) => `https://tzkt.io/${addressOrTxHash}`; diff --git a/src/utils/linking/tests.spec.ts b/src/utils/linking/tests.spec.ts index 7a258face..fab778879 100644 --- a/src/utils/linking/tests.spec.ts +++ b/src/utils/linking/tests.spec.ts @@ -1,23 +1,14 @@ import { mockLinking } from '../../mocks/react-native.mock'; -import { DCP_RPC } from '../rpc/rpc-list'; import { openUrl, tzktUrl } from './index'; describe('tzktUrl', () => { it('should return tzkt link with passed non-empty address path', () => { - expect(tzktUrl('https://mainnet-node.madfish.solutions', 'test')).toEqual('https://tzkt.io/test'); + expect(tzktUrl('test')).toEqual('https://tzkt.io/test'); }); it('should return tzkt link with passed empty address path', () => { - expect(tzktUrl('https://mainnet-node.madfish.solutions', '')).toEqual('https://tzkt.io/'); - }); - - it('should return DPC tzkt link with passed non-empty address path (DPC rpcUrl)', () => { - expect(tzktUrl(DCP_RPC.url, 'test')).toEqual('https://explorer.tlnt.net/test'); - }); - - it('should return DPC tzkt link with passed empty address path (DPC rpcUrl)', () => { - expect(tzktUrl(DCP_RPC.url, '')).toEqual('https://explorer.tlnt.net/'); + expect(tzktUrl('')).toEqual('https://tzkt.io/'); }); }); diff --git a/src/utils/network.utils.ts b/src/utils/network.utils.ts deleted file mode 100644 index 5a951ccaf..000000000 --- a/src/utils/network.utils.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { showErrorToast } from '../toast/toast.utils'; -import { FILM_TOKEN_METADATA, TEZ_TOKEN_METADATA } from '../token/data/tokens-metadata'; - -import { DCP_RPC } from './rpc/rpc-list'; - -const DCP_NODE_RPC_URL = new URL(DCP_RPC.url).href; - -export const isDcpNode = (selectedRpcUrl: string) => { - try { - return new URL(selectedRpcUrl).href === DCP_NODE_RPC_URL; - } catch { - showErrorToast({ description: 'App loading failed due to RPC URL. Verify the URL and try again.' }); - - return false; - } -}; - -export const getNetworkGasTokenMetadata = (selectedRpcUrl: string) => - isDcpNode(selectedRpcUrl) ? FILM_TOKEN_METADATA : TEZ_TOKEN_METADATA; diff --git a/src/utils/route3.util.ts b/src/utils/route3.util.ts index 7cc2cc36c..a6d51716c 100644 --- a/src/utils/route3.util.ts +++ b/src/utils/route3.util.ts @@ -22,7 +22,7 @@ import { } from 'src/token/data/three-route-tokens'; import { SIRS_TOKEN_METADATA, - TEZ_TOKEN_METADATA, + TEZ_TOKEN_SYMBOL, TEZ_TOKEN_SLUG, TZBTC_TOKEN_METADATA } from 'src/token/data/tokens-metadata'; @@ -49,7 +49,7 @@ const parser = (origJSON: string): ReturnType<(typeof JSON)['parse']> => { function getRoute3ParametrizedUrlPart(params: Route3SwapParamsRequest): string; function getRoute3ParametrizedUrlPart(params: Route3LbSwapParamsRequest): string; function getRoute3ParametrizedUrlPart(params: Route3SwapParamsRequest | Route3LbSwapParamsRequest) { - const { fromSymbol, toSymbol, amount, toTokenDecimals, rpcUrl, ...queryParams } = params; + const { fromSymbol, toSymbol, amount, toTokenDecimals, ...queryParams } = params; const searchParams = new URLSearchParams( transform( queryParams, @@ -141,10 +141,10 @@ const correctOutput = (tree: T, newOutput: BigNumber, export const fetchRoute3LiquidityBakingParams = async ( params: Route3LbSwapParamsRequest ): Promise => { - const { rpcUrl, toSymbol, toTokenDecimals } = params; + const { toSymbol, toTokenDecimals } = params; if (params.fromSymbol === THREE_ROUTE_SIRS_TOKEN.symbol) { - const { tokenPool, xtzPool, lqtTotal } = await getLbStorage(params.rpcUrl); + const { tokenPool, xtzPool, lqtTotal } = await getLbStorage(); const sirsAtomicAmount = tzToMutez(new BigNumber(params.amount), THREE_ROUTE_SIRS_TOKEN.decimals); const tzbtcAtomicAmount = sirsAtomicAmount .times(tokenPool) @@ -174,7 +174,6 @@ export const fetchRoute3LiquidityBakingParams = async ( toSymbol: toSymbol, amount: xtzInAmount, toTokenDecimals, - rpcUrl, dexesLimit: params.xtzDexesLimit, showTree: true }), @@ -195,7 +194,6 @@ export const fetchRoute3LiquidityBakingParams = async ( toSymbol: toSymbol, amount: tzbtcInAmount, toTokenDecimals, - rpcUrl, dexesLimit: params.tzbtcDexesLimit, showTree: true }) @@ -275,7 +273,7 @@ export const fetchRoute3Dexes$ = () => from(route3Api.get>('/dexes')).pipe(map(response => response.data)); const route3TokenSymbols = { - [TEZ_TOKEN_METADATA.symbol]: THREE_ROUTE_XTZ_TOKEN.symbol, + [TEZ_TOKEN_SYMBOL]: THREE_ROUTE_XTZ_TOKEN.symbol, [TZBTC_TOKEN_METADATA.symbol]: THREE_ROUTE_TZBTC_TOKEN.symbol, [SIRS_TOKEN_METADATA.symbol]: THREE_ROUTE_SIRS_TOKEN.symbol }; diff --git a/src/utils/rpc/evm-client.utils.ts b/src/utils/rpc/evm-client.utils.ts new file mode 100644 index 000000000..49f7f6407 --- /dev/null +++ b/src/utils/rpc/evm-client.utils.ts @@ -0,0 +1,70 @@ +import { uniq } from 'lodash-es'; +import memoizee from 'memoizee'; +import { + Chain, + createPublicClient, + extractChain, + fallback, + http, + HttpTransportConfig, + PublicClient, + Transport +} from 'viem'; +import * as ViemChains from 'viem/chains'; + +import { DEFAULT_EVM_CURRENCY } from 'src/token/interfaces/token-metadata.interface'; +import { DEFAULT_RPC_INDEX, EvmNetworkEssentials } from 'src/types/networks'; + +import { isDefined } from '../is-defined'; + +import { FALLBACK_EVM_RPCS_LIST } from './rpc-list'; + +type ChainPublicClient = PublicClient>; + +const DEFAULT_TRANSPORT_CONFIG: HttpTransportConfig = { + /** Defaults to 3 */ + retryCount: 1, + /** Defaults to 150 */ + retryDelay: 300 +}; + +const getViemTransportForNetwork = (network: EvmNetworkEssentials): Transport => { + const fallbacks = FALLBACK_EVM_RPCS_LIST[network.chainId]; + const shouldApplyFallbacks = isDefined(fallbacks) && network.rpcBaseURL === fallbacks[DEFAULT_RPC_INDEX]; + + if (!shouldApplyFallbacks) return http(network.rpcBaseURL, DEFAULT_TRANSPORT_CONFIG); + + return fallback( + uniq([network.rpcBaseURL].concat(fallbacks)).map(url => http(url, { retryCount: 0 })), + { retryCount: 0 } + ); +}; + +const getViemChainByChainId = (chainId: number): Chain | undefined => + extractChain({ chains: getViemChainsList(), id: chainId }); + +const getViemChainsList = memoizee(() => Object.values(ViemChains) as Chain[]); + +const getCustomViemChain = (network: EvmNetworkEssentials) => ({ + id: network.chainId, + rpcUrls: { + default: { + http: [network.rpcBaseURL] + } + }, + name: '', + nativeCurrency: DEFAULT_EVM_CURRENCY +}); + +export const getViemPublicClient = memoizee( + (network: EvmNetworkEssentials): ChainPublicClient => { + const viemChain = getViemChainByChainId(network.chainId); + + return createPublicClient({ + chain: viemChain ?? getCustomViemChain(network), + transport: getViemTransportForNetwork(network), + batch: { multicall: { batchSize: 64, wait: 20 } } + }); + }, + { normalizer: ([network]) => `${network.chainId}_${network.rpcBaseURL}`, max: 10 } +); diff --git a/src/utils/rpc/fallback-rpc.ts b/src/utils/rpc/fallback-rpc.ts index c2d1a33f7..aa12361e9 100644 --- a/src/utils/rpc/fallback-rpc.ts +++ b/src/utils/rpc/fallback-rpc.ts @@ -11,12 +11,13 @@ import { RPCSimulateOperationParam } from '@taquito/rpc'; import { TezosOperationError } from '@taquito/taquito'; +import { uniq } from 'lodash-es'; import memoize from 'memoizee'; import { isDefined } from '../is-defined'; import { FastRpcClient, getFastRpcClient } from './fast-rpc'; -import { FALLBACK_RPC_LIST, TEMPLE_RPC } from './rpc-list'; +import { FALLBACK_TEZOS_RPC_LIST, TEMPLE_RPC } from './rpc-list'; /** * A lightweight fallback client that sequentially tries multiple FastRpcClient instances @@ -258,10 +259,6 @@ function isNonRetryableTezosError(error: unknown): boolean { return false; } -export const getFallbackRpcClient = memoize((rpc: string) => { - if (rpc === TEMPLE_RPC.url) { - return new FallbackRpcClient([rpc, ...FALLBACK_RPC_LIST]); - } - - return getFastRpcClient(rpc); -}); +export const getFallbackRpcClient = memoize( + (preferredRpcUrl = TEMPLE_RPC.url) => new FallbackRpcClient(uniq([preferredRpcUrl].concat(FALLBACK_TEZOS_RPC_LIST))) +); diff --git a/src/utils/rpc/rpc-list.ts b/src/utils/rpc/rpc-list.ts index 3fa614f5c..bedb6dfd3 100644 --- a/src/utils/rpc/rpc-list.ts +++ b/src/utils/rpc/rpc-list.ts @@ -1,5 +1,8 @@ import { RpcInterface } from 'src/interfaces/rpc.interface'; +export const ETHERLINK_MAINNET_CHAIN_ID = 42793; + +/** @deprecated: Not going to support Talentnet */ export const DCP_RPC: RpcInterface = { name: 'T4L3NT Mainnet', url: 'https://rpc.decentralized.pictures' @@ -26,14 +29,18 @@ export const RpcList: RpcInterface[] = [ { name: 'ECAD Labs Mainnet', url: 'https://mainnet.api.tez.ie' - }, - DCP_RPC + } ]; -export const FALLBACK_RPC_LIST = [ +export const FALLBACK_TEZOS_RPC_LIST = [ + TEMPLE_RPC.url, 'https://mainnet.smartpy.io', 'https://mainnet.api.tez.ie', 'https://rpc.tzkt.io/mainnet', 'https://rpc.tzbeta.net', 'https://mainnet.tezos.ecadinfra.com' ]; + +export const FALLBACK_EVM_RPCS_LIST: Record = { + [ETHERLINK_MAINNET_CHAIN_ID]: ['https://node.mainnet.etherlink.com', 'https://rpc.ankr.com/etherlink_mainnet'] +}; diff --git a/src/utils/rpc/tezos-toolkit.utils.ts b/src/utils/rpc/tezos-toolkit.utils.ts index 3dca20882..6f6832e1a 100644 --- a/src/utils/rpc/tezos-toolkit.utils.ts +++ b/src/utils/rpc/tezos-toolkit.utils.ts @@ -20,7 +20,7 @@ import { getFallbackRpcClient } from './fallback-rpc'; const michelEncoder = new MichelCodecPacker(); -export const createTezosToolkit = (rpcUrl: string) => { +export const createTezosToolkit = (preferredRpcUrl?: string) => { const metadataProvider = new MetadataProvider( new Map([ ['http', new HttpHandler()], @@ -29,7 +29,7 @@ export const createTezosToolkit = (rpcUrl: string) => { ['ipfs', new IpfsHttpHandler('ipfs.filebase.io')] ]) ); - const tezosToolkit = new TezosToolkit(getFallbackRpcClient(rpcUrl)); + const tezosToolkit = new TezosToolkit(getFallbackRpcClient(preferredRpcUrl)); tezosToolkit.setPackerProvider(michelEncoder); tezosToolkit.setForgerProvider(new CompositeForger([tezosToolkit.getFactory(RpcForger)(), localForger])); tezosToolkit.addExtension(new Tzip16Module(metadataProvider)); @@ -39,13 +39,13 @@ export const createTezosToolkit = (rpcUrl: string) => { }; export const createReadOnlyTezosToolkit = memoize( - (rpcUrl: string, sender?: TezosReadOnlySignerPayload | null) => { - const readOnlyTezosToolkit = createTezosToolkit(rpcUrl); + (sender?: TezosReadOnlySignerPayload | null, preferredRpcUrl?: string) => { + const readOnlyTezosToolkit = createTezosToolkit(preferredRpcUrl); if (isDefined(sender)) { readOnlyTezosToolkit.setSignerProvider(new TezosReadOnlySigner(sender.address, sender.publicKey)); } return readOnlyTezosToolkit; }, - { normalizer: ([rpcUrl, sender]) => `${rpcUrl}_${sender?.address}`, max: 10 } + { normalizer: ([sender, preferredRpcUrl]) => `${sender?.address ?? ''}_${preferredRpcUrl ?? ''}`, max: 10 } ); diff --git a/src/utils/style.util.spec.ts b/src/utils/style.util.spec.ts index 109d6374b..a000ae610 100644 --- a/src/utils/style.util.spec.ts +++ b/src/utils/style.util.spec.ts @@ -1,5 +1,7 @@ import { hexa } from './style.util'; it('hexa should add opacity to the hex color', () => { - expect(hexa('#aabbcc', 0.1)).toEqual('#aabbcc10'); + expect(hexa('#aabbcc', 0.1)).toEqual('#aabbcc1a'); + expect(hexa('#aabbcc', 0.5)).toEqual('#aabbcc80'); + expect(hexa('#aabbcc', 1)).toEqual('#aabbccff'); }); diff --git a/src/utils/style.util.ts b/src/utils/style.util.ts index 1d44c4bb9..9d6289dd5 100644 --- a/src/utils/style.util.ts +++ b/src/utils/style.util.ts @@ -1 +1,5 @@ -export const hexa = (hex: string, alpha: number) => hex + alpha * 100; +export const hexa = (hex: string, alpha: number) => + hex + + Math.round(alpha * 255) + .toString(16) + .padStart(2, '0'); diff --git a/src/utils/swap.utils.ts b/src/utils/swap.utils.ts index 477087f0f..58b04b21e 100644 --- a/src/utils/swap.utils.ts +++ b/src/utils/swap.utils.ts @@ -34,14 +34,11 @@ import { tzToMutez } from './tezos.util'; import { getTransferParams$ } from './transfer-params.utils'; import { getTransferPermissions } from './transfer-permissions.util'; -export const getLbStorage = async (tezosOrRpc: string | TezosToolkit) => { - const tezos = typeof tezosOrRpc === 'string' ? createReadOnlyTezosToolkit(tezosOrRpc) : tezosOrRpc; - - return getContractStorage<{ tokenPool: BigNumber; xtzPool: BigNumber; lqtTotal: BigNumber }>( - tezos, +export const getLbStorage = () => + getContractStorage<{ tokenPool: BigNumber; xtzPool: BigNumber; lqtTotal: BigNumber }>( + createReadOnlyTezosToolkit(), LIQUIDITY_BAKING_DEX_ADDRESS ); -}; const mapToRoute3ExecuteHops = (hops: Route3Hop[]): Record => { const result: Record = {}; @@ -262,7 +259,7 @@ export const getSwapTransferParams = async ( tzbtcAddLiqInput ); // Prevent extra TEZ spending - const { xtzPool, lqtTotal } = await getLbStorage(tezos); + const { xtzPool, lqtTotal } = await getLbStorage(); const xtzAddLiqInput = BigNumber.min( xtzSwapMinOut, xtzPool diff --git a/src/utils/tezos.util.spec.ts b/src/utils/tezos.util.spec.ts index dfc45bdc1..03cbddae1 100644 --- a/src/utils/tezos.util.spec.ts +++ b/src/utils/tezos.util.spec.ts @@ -1,6 +1,6 @@ import { BigNumber } from 'bignumber.js'; -import { FILM_TOKEN_METADATA, TEZ_TOKEN_METADATA } from '../token/data/tokens-metadata'; +import { TEZ_TOKEN_DECIMALS } from '../token/data/tokens-metadata'; import { isKTAddress, isValidAddress, mutezToTz, tzToMutez, isCollectible } from './tezos.util'; @@ -33,10 +33,7 @@ describe('mutezToTz', () => { expect(mutezToTz(mockNaNBigNumber, 10).toNumber()).toEqual(NaN); }); it('should correctly map TEZ value', () => { - expect(mutezToTz(mockMutezValue, TEZ_TOKEN_METADATA.decimals).toNumber()).toEqual(0.1); - }); - it('should correctly map FILM value', () => { - expect(mutezToTz(mockMutezValue, FILM_TOKEN_METADATA.decimals).toNumber()).toEqual(0.1); + expect(mutezToTz(mockMutezValue, TEZ_TOKEN_DECIMALS).toNumber()).toEqual(0.1); }); it('should correctly map fiat value', () => { expect(mutezToTz(mockMutezValue, 2).toNumber()).toEqual(1000); @@ -48,10 +45,7 @@ describe('tzToMutez', () => { expect(tzToMutez(mockNaNBigNumber, 10).toNumber()).toEqual(NaN); }); it('should correctly map TEZ value', () => { - expect(tzToMutez(mockTzValue, TEZ_TOKEN_METADATA.decimals).toNumber()).toEqual(100000); - }); - it('should correctly map FILM value', () => { - expect(tzToMutez(mockTzValue, FILM_TOKEN_METADATA.decimals).toNumber()).toEqual(100000); + expect(tzToMutez(mockTzValue, TEZ_TOKEN_DECIMALS).toNumber()).toEqual(100000); }); it('should correctly map fiat value', () => { expect(tzToMutez(mockTzValue, 2).toNumber()).toEqual(10); diff --git a/src/utils/token-balance.utils.ts b/src/utils/token-balance.utils.ts index d5d005e3b..097718864 100644 --- a/src/utils/token-balance.utils.ts +++ b/src/utils/token-balance.utils.ts @@ -2,10 +2,10 @@ import BigNumber from 'bignumber.js'; import { from, of } from 'rxjs'; import { catchError, map, switchMap } from 'rxjs/operators'; -import { getTzktApi } from 'src/api.service'; +import { tzktApi } from 'src/api.service'; import { ContractType } from 'src/interfaces/contract.type'; -import { TokenTypeEnum } from 'src/interfaces/token-type.enum'; -import { getTokenType, toTokenSlug } from 'src/token/utils/token.utils'; +import { TokenStandardsEnum } from 'src/token/interfaces/token-metadata.interface'; +import { getTokenStandard, toTokenSlug } from 'src/token/utils/token.utils'; import { sendErrorAnalyticsEvent } from './analytics/analytics.util'; import { UserAnalyticsCredentials } from './error-analytics-data.utils'; @@ -18,11 +18,11 @@ const TEZOS_DOMAINS_NAME_REGISTRY_ADDRESS = 'KT1GBZmSxmnKJXGMdMLbugPfLyUPmuLSMwK /** TZKT API max items limit */ const LIMIT = 10000; -export const fetchAllAssetsBalancesFromTzkt = async (selectedRpcUrl: string, account: string) => { +export const fetchAllAssetsBalancesFromTzkt = async (account: string) => { const balances: StringRecord = {}; await (async function recourse(offset: number) { - const { data } = await fetchAssetsBalancesFromTzktOnce(selectedRpcUrl, account, offset); + const { data } = await fetchAssetsBalancesFromTzktOnce(account, offset); for (const [address, tokenId, balance] of data) { const slug = toTokenSlug(address, tokenId); @@ -39,8 +39,8 @@ export const fetchAllAssetsBalancesFromTzkt = async (selectedRpcUrl: string, acc type AssetBalance = [address: string, tokenId: string, balance: string]; -const fetchAssetsBalancesFromTzktOnce = (selectedRpcUrl: string, account: string, offset = 0) => - getTzktApi(selectedRpcUrl).get('/tokens/balances', { +const fetchAssetsBalancesFromTzktOnce = (account: string, offset = 0) => + tzktApi.get('/tokens/balances', { params: { account, 'token.contract.ne': TEZOS_DOMAINS_NAME_REGISTRY_ADDRESS, @@ -50,13 +50,13 @@ const fetchAssetsBalancesFromTzktOnce = (selectedRpcUrl: string, account: string } }); -export const loadTezosBalance$ = (rpcUrl: string, publicKeyHash: string) => - from(createReadOnlyTezosToolkit(rpcUrl, tezosReadOnlySignerAccount).tz.getBalance(publicKeyHash)).pipe( +export const loadTezosBalance$ = (publicKeyHash: string) => + from(createReadOnlyTezosToolkit(tezosReadOnlySignerAccount).tz.getBalance(publicKeyHash)).pipe( map(balance => balance.toFixed()) ); -export const loadTezosBalances$ = (rpcUrl: string, publicKeyHashes: string[]) => { - const tezos = createReadOnlyTezosToolkit(rpcUrl, tezosReadOnlySignerAccount); +export const loadTezosBalances$ = (publicKeyHashes: string[]) => { + const tezos = createReadOnlyTezosToolkit(tezosReadOnlySignerAccount); return from(Promise.allSettled(publicKeyHashes.map(publicKeyHash => tezos.tz.getBalance(publicKeyHash)))).pipe( map(results => @@ -86,7 +86,7 @@ export const getBalance = async ( owner: string, tokenId?: number | string | undefined ): Promise => { - if (getTokenType(contract) === TokenTypeEnum.FA_2) { + if (getTokenStandard(contract) === TokenStandardsEnum.Fa2) { return (await contract.views.balance_of([{ owner, token_id: tokenId }]).read())[0].balance; } else { return await contract.views.getBalance(owner).read(); @@ -94,12 +94,11 @@ export const getBalance = async ( }; export const loadAssetBalance$ = ( - rpcUrl: string, publicKeyHash: string, assetSlug: string, { isAnalyticsEnabled, userId, ABTestingCategory }: UserAnalyticsCredentials ) => { - const tezos = createReadOnlyTezosToolkit(rpcUrl, tezosReadOnlySignerAccount); + const tezos = createReadOnlyTezosToolkit(tezosReadOnlySignerAccount); const [assetAddress, assetId = '0'] = assetSlug.split('_'); const cachedRecord = cachedResults[`${publicKeyHash}_${assetSlug}`]; @@ -126,7 +125,7 @@ export const loadAssetBalance$ = ( error, [publicKeyHash], { userId, ABTestingCategory }, - { rpcUrl, assetSlug } + { assetSlug } ); } diff --git a/src/utils/token-metadata.utils.ts b/src/utils/token-metadata.utils.ts index ab59961b3..a961adcf3 100644 --- a/src/utils/token-metadata.utils.ts +++ b/src/utils/token-metadata.utils.ts @@ -6,9 +6,8 @@ import { forkJoin, from, Observable, of } from 'rxjs'; import { map } from 'rxjs/operators'; import { scamlistApi, tezosMetadataApi, whitelistApi } from 'src/api.service'; -import { useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; import { useTokensMetadataSelector } from 'src/store/tokens-metadata/tokens-metadata-selectors'; -import { OVERRIDEN_MAINNET_TOKENS_METADATA, TEZ_TOKEN_SLUG } from 'src/token/data/tokens-metadata'; +import { OVERRIDEN_MAINNET_TOKENS_METADATA, TEZ_TOKEN_METADATA, TEZ_TOKEN_SLUG } from 'src/token/data/tokens-metadata'; import { TokenMetadataInterface, TokenStandardsEnum } from 'src/token/interfaces/token-metadata.interface'; import type { TokenInterface } from 'src/token/interfaces/token.interface'; import { getTokenSlug } from 'src/token/utils/token.utils'; @@ -16,7 +15,6 @@ import { getTokenSlug } from 'src/token/utils/token.utils'; import { getDollarValue } from './balance.utils'; import { isDefined } from './is-defined'; import { isTruthy } from './is-truthy'; -import { getNetworkGasTokenMetadata, isDcpNode } from './network.utils'; export interface TokenMetadataResponse { decimals: number; @@ -93,21 +91,18 @@ export const transformWhitelistToTokenMetadata = (token: WhitelistTokensItem): T export const useTokenMetadataGetter = () => { const tokensMetadata = useTokensMetadataSelector(); - const selectedRpcUrl = useSelectedRpcUrlSelector(); return useCallback( (slug: string): TokenMetadataInterface | undefined => - slug === TEZ_TOKEN_SLUG ? getNetworkGasTokenMetadata(selectedRpcUrl) : tokensMetadata[slug], - [tokensMetadata, selectedRpcUrl] + slug === TEZ_TOKEN_SLUG ? TEZ_TOKEN_METADATA : tokensMetadata[slug], + [tokensMetadata] ); }; -export const loadWhitelist$ = (selectedRpc: string) => - isDcpNode(selectedRpc) - ? from([]) - : from(whitelistApi.get('tokens/quipuswap.whitelist.json')).pipe( - map(({ data }) => data.tokens?.filter(x => x.contractAddress !== 'tez') ?? []) - ); +export const loadWhitelist$ = () => + from(whitelistApi.get('tokens/quipuswap.whitelist.json')).pipe( + map(({ data }) => data.tokens?.filter(x => x.contractAddress !== 'tez') ?? []) + ); export const loadScamlist$ = () => from(scamlistApi.get('tokens/scamlist.json')).pipe(map(({ data }) => data.slugs)); diff --git a/src/utils/token-operations.util.ts b/src/utils/token-operations.util.ts index 07ba5b3f0..05078163c 100644 --- a/src/utils/token-operations.util.ts +++ b/src/utils/token-operations.util.ts @@ -1,7 +1,7 @@ import { uniq } from 'lodash-es'; import { stringify } from 'qs'; -import { getTzktApi } from '../api.service'; +import { tzktApi } from '../api.service'; import { OPERATION_LIMIT } from '../config/general'; import { ActivityTypeEnum } from '../enums/activity-type.enum'; import { Account } from '../interfaces/account.interfaces'; @@ -12,10 +12,10 @@ import { OperationInterface, OperationLiquidityBakingInterface } from '../interfaces/operation.interface'; -import { TokenTypeEnum } from '../interfaces/token-type.enum'; import { LIQUIDITY_BAKING_DEX_ADDRESS } from '../token/data/token-slugs'; import { TEZ_TOKEN_SLUG } from '../token/data/tokens-metadata'; -import { getTokenType } from '../token/utils/token.utils'; +import { TokenStandardsEnum } from '../token/interfaces/token-metadata.interface'; +import { getTokenStandard } from '../token/utils/token.utils'; import { getAccountAddressForTezos, getAccountForTezos } from './account.utils'; import { isDefined } from './is-defined'; @@ -23,17 +23,11 @@ import { mapOperationsToActivities } from './operation.utils'; import { createReadOnlyTezosToolkit } from './rpc/tezos-toolkit.utils'; import { sleep } from './timeouts.util'; -const getOperationGroupByHash = (selectedRpcUrl: string, hash: string) => - getTzktApi(selectedRpcUrl).get>(`operations/${hash}`); +const getOperationGroupByHash = (hash: string) => tzktApi.get>(`operations/${hash}`); // LIQUIDITY BAKING ACTIVITY -const getContractOperations = ( - selectedRpcUrl: string, - account: string, - contractAddress: string, - lastLevel?: number -) => - getTzktApi(selectedRpcUrl) +const getContractOperations = (account: string, contractAddress: string, lastLevel?: number) => + tzktApi .get>('/operations/transactions', { params: { target: contractAddress, @@ -48,14 +42,8 @@ const getContractOperations = ( const paramsSerializer = (params: Record) => stringify(params); -const getTokenFa2Operations = ( - selectedRpcUrl: string, - account: string, - contractAddress: string, - tokenId = '0', - lastLevel?: number -) => - getTzktApi(selectedRpcUrl) +const getTokenFa2Operations = (account: string, contractAddress: string, tokenId = '0', lastLevel?: number) => + tzktApi .get>('operations/transactions', { paramsSerializer, params: { @@ -69,8 +57,8 @@ const getTokenFa2Operations = ( }) .then(x => x.data); -const getTokenFa12Operations = (selectedRpcUrl: string, account: string, contractAddress: string, lastLevel?: number) => - getTzktApi(selectedRpcUrl) +const getTokenFa12Operations = (account: string, contractAddress: string, lastLevel?: number) => + tzktApi .get>('operations/transactions', { paramsSerializer, params: { @@ -84,8 +72,8 @@ const getTokenFa12Operations = (selectedRpcUrl: string, account: string, contrac }) .then(x => x.data); -const getTezosOperations = (selectedRpcUrl: string, account: string, lastLevel?: number) => - getTzktApi(selectedRpcUrl) +const getTezosOperations = (account: string, lastLevel?: number) => + tzktApi .get>('operations/transactions', { params: { 'anyof.sender.target.initiator': account, @@ -97,8 +85,8 @@ const getTezosOperations = (selectedRpcUrl: string, account: string, lastLevel?: }) .then(x => x.data); -const getAccountOperations = (selectedRpcUrl: string, account: string, lastId?: number) => - getTzktApi(selectedRpcUrl) +const getAccountOperations = (account: string, lastId?: number) => + tzktApi .get>('accounts/activity', { params: { addresses: account, @@ -110,8 +98,8 @@ const getAccountOperations = (selectedRpcUrl: string, account: string, lastId?: }) .then(x => x.data); -const getFa12IncomingOperations = (selectedRpcUrl: string, account: string, lowerId: number, upperId?: number) => - getTzktApi(selectedRpcUrl) +const getFa12IncomingOperations = (account: string, lowerId: number, upperId?: number) => + tzktApi .get>('operations/transactions', { params: { 'sender.ne': account, @@ -125,8 +113,8 @@ const getFa12IncomingOperations = (selectedRpcUrl: string, account: string, lowe }) .then(x => x.data); -const getFa2IncomingOperations = (selectedRpcUrl: string, account: string, lowerId: number, upperId?: number) => - getTzktApi(selectedRpcUrl) +const getFa2IncomingOperations = (account: string, lowerId: number, upperId?: number) => + tzktApi .get>('operations/transactions', { params: { 'sender.ne': account, @@ -140,12 +128,8 @@ const getFa2IncomingOperations = (selectedRpcUrl: string, account: string, lower }) .then(x => x.data); -const getAllOperations = async ( - selectedRpcUrl: string, - publicKeyHash: string, - upperId?: number -): Promise => { - const operations = await getAccountOperations(selectedRpcUrl, publicKeyHash, upperId); +const getAllOperations = async (publicKeyHash: string, upperId?: number): Promise => { + const operations = await getAccountOperations(publicKeyHash, upperId); if (operations.length === 0) { return []; } @@ -155,8 +139,8 @@ const getAllOperations = async ( } const lowerId = localLastItem.id; const [operationsFa12, operationsFa2] = await Promise.all([ - getFa12IncomingOperations(selectedRpcUrl, publicKeyHash, lowerId, upperId), - getFa2IncomingOperations(selectedRpcUrl, publicKeyHash, lowerId, upperId) + getFa12IncomingOperations(publicKeyHash, lowerId, upperId), + getFa2IncomingOperations(publicKeyHash, lowerId, upperId) ]); return operations @@ -165,12 +149,7 @@ const getAllOperations = async ( .sort((b, a) => a.id - b.id); }; -const loadOperations = async ( - selectedRpcUrl: string, - selectedAccount: Account, - tokenSlug?: string, - lastItem?: ActivityInterface -) => { +const loadOperations = async (selectedAccount: Account, tokenSlug?: string, lastItem?: ActivityInterface) => { const [contractAddress, tokenId] = (tokenSlug ?? '').split('_'); const selectedTezosAddress = getAccountAddressForTezos(selectedAccount); @@ -180,36 +159,34 @@ const loadOperations = async ( if (isDefined(tokenSlug)) { if (tokenSlug === TEZ_TOKEN_SLUG) { - return getTezosOperations(selectedRpcUrl, selectedTezosAddress, lastItem?.level); + return getTezosOperations(selectedTezosAddress, lastItem?.level); } if (contractAddress === LIQUIDITY_BAKING_DEX_ADDRESS) { return getContractOperations( - selectedRpcUrl, selectedTezosAddress, contractAddress, lastItem?.level ); } - const tezos = createReadOnlyTezosToolkit(selectedRpcUrl, getAccountForTezos(selectedAccount)); + const tezos = createReadOnlyTezosToolkit(getAccountForTezos(selectedAccount)); const contract = await tezos.contract.at(contractAddress); - const tokenType = getTokenType(contract); + const tokenType = getTokenStandard(contract); - if (tokenType === TokenTypeEnum.FA_1_2) { - return getTokenFa12Operations(selectedRpcUrl, selectedTezosAddress, contractAddress, lastItem?.level); + if (tokenType === TokenStandardsEnum.Fa12) { + return getTokenFa12Operations(selectedTezosAddress, contractAddress, lastItem?.level); } - if (tokenType === TokenTypeEnum.FA_2) { - return getTokenFa2Operations(selectedRpcUrl, selectedTezosAddress, contractAddress, tokenId, lastItem?.level); + if (tokenType === TokenStandardsEnum.Fa2) { + return getTokenFa2Operations(selectedTezosAddress, contractAddress, tokenId, lastItem?.level); } } - return getAllOperations(selectedRpcUrl, selectedTezosAddress, lastItem?.id); + return getAllOperations(selectedTezosAddress, lastItem?.id); }; export const loadActivity = async ( - selectedRpcUrl: string, /** @deprecated // Wanna pass PKH only */ selectedAccount: Account, tokenSlug?: string, @@ -221,14 +198,14 @@ export const loadActivity = async ( return []; } - const operationsHashes = await loadOperations(selectedRpcUrl, selectedAccount, tokenSlug, lastItem) + const operationsHashes = await loadOperations(selectedAccount, tokenSlug, lastItem) .then(operations => operations.map(operation => operation.hash)) .then(newHashes => uniq(newHashes.filter(x => x !== lastItem?.hash))); const operationGroups = []; for (const opHash of operationsHashes) { - const { data } = await getOperationGroupByHash(selectedRpcUrl, opHash); + const { data } = await getOperationGroupByHash(opHash); operationGroups.push(data); await sleep(100); } diff --git a/src/utils/transfer-params.spec.ts b/src/utils/transfer-params.spec.ts index f2dfe9f3e..045cf149f 100644 --- a/src/utils/transfer-params.spec.ts +++ b/src/utils/transfer-params.spec.ts @@ -2,14 +2,12 @@ import { BigNumber } from 'bignumber.js'; import { mockHdAccount } from '../interfaces/account.interface.mock'; import { mockFA1_2Contract, mockFA2Contract, mockToolkitMethods } from '../mocks/tezos.mock'; -import { FILM_TOKEN_METADATA, TEZ_TOKEN_METADATA } from '../token/data/tokens-metadata'; +import { TEZ_TOKEN_METADATA } from '../token/data/tokens-metadata'; import { mockFA1_2TokenMetadata, mockFA2TokenMetadata } from '../token/interfaces/token-metadata.interface.mock'; import { rxJsTestingHelper } from './testing.utils'; import { getTransferParams$ } from './transfer-params.utils'; -const mockRpcUrl = 'https://rpc-url.mock/mainnet'; - describe('getTransferParams$', () => { beforeEach(() => { mockFA1_2Contract.methodsObject.transfer.mockReset(); @@ -21,23 +19,7 @@ describe('getTransferParams$', () => { getTransferParams$( TEZ_TOKEN_METADATA, - mockRpcUrl, - mockHdAccount, - 'receiverPublicKeyHash', - mockInputAmount - ).subscribe( - rxJsTestingHelper(params => { - expect(params).toEqual({ amount: mockInputAmount.toNumber(), to: 'receiverPublicKeyHash', mutez: true }); - }, done) - ); - }); - - it('should create params for transferring FILM', done => { - const mockInputAmount = new BigNumber(0.005); - - getTransferParams$( - FILM_TOKEN_METADATA, - mockRpcUrl, + undefined, mockHdAccount, 'receiverPublicKeyHash', mockInputAmount @@ -56,7 +38,7 @@ describe('getTransferParams$', () => { getTransferParams$( mockFA1_2TokenMetadata, - mockRpcUrl, + undefined, mockHdAccount, 'receiverPublicKeyHash', mockInputAmount @@ -79,7 +61,7 @@ describe('getTransferParams$', () => { getTransferParams$( mockFA2TokenMetadata, - mockRpcUrl, + undefined, mockHdAccount, 'receiverPublicKeyHash', mockInputAmount diff --git a/src/utils/transfer-params.utils.ts b/src/utils/transfer-params.utils.ts index c980546bc..a3f189af2 100644 --- a/src/utils/transfer-params.utils.ts +++ b/src/utils/transfer-params.utils.ts @@ -5,9 +5,8 @@ import { from, Observable, of } from 'rxjs'; import { map } from 'rxjs/operators'; import { Account } from '../interfaces/account.interfaces'; -import { TokenTypeEnum } from '../interfaces/token-type.enum'; -import { TokenMetadataInterface } from '../token/interfaces/token-metadata.interface'; -import { getTokenType } from '../token/utils/token.utils'; +import { TokenMetadataInterface, TokenStandardsEnum } from '../token/interfaces/token-metadata.interface'; +import { getTokenStandard } from '../token/utils/token.utils'; import { getAccountAddressForTezos, getAccountForTezos } from './account.utils'; import { isString } from './is-string'; @@ -16,30 +15,14 @@ import { throwError$ } from './rxjs.utils'; export function getTransferParams$( asset: Pick, - tezos: TezosToolkit, - senderPkh: string, - receiverPublicKeyHash: string, - amount: BigNumber -): Observable; -export function getTransferParams$( - asset: Pick, - rpcUrl: string, - sender: Account, - receiverPublicKeyHash: string, - amount: BigNumber -): Observable; -export function getTransferParams$( - asset: Pick, - rpcUrlOrTezos: string | TezosToolkit, + tezosFromArgs: TezosToolkit | undefined, sender: Account | string, receiverPublicKeyHash: string, amount: BigNumber ): Observable { const { id, address } = asset; const tezos = - typeof rpcUrlOrTezos === 'string' - ? createReadOnlyTezosToolkit(rpcUrlOrTezos, getAccountForTezos(sender as Account)) - : rpcUrlOrTezos; + tezosFromArgs ?? createReadOnlyTezosToolkit(typeof sender === 'string' ? undefined : getAccountForTezos(sender)); const senderPkh = typeof sender === 'string' ? sender : getAccountAddressForTezos(sender); if (!senderPkh) { @@ -49,7 +32,7 @@ export function getTransferParams$( return isString(address) ? from(tezos.contract.at(address)).pipe( map(contract => - getTokenType(contract) === TokenTypeEnum.FA_2 + getTokenStandard(contract) === TokenStandardsEnum.Fa2 ? { to: contract.address, amount: 0, diff --git a/src/utils/wallet.utils.ts b/src/utils/wallet.utils.ts index 38bd187e9..7dd2731f9 100644 --- a/src/utils/wallet.utils.ts +++ b/src/utils/wallet.utils.ts @@ -8,18 +8,17 @@ import { VisibilityEnum } from 'src/enums/visibility.enum'; import { Account } from 'src/interfaces/account.interfaces'; import { Shelter } from 'src/shelter/shelter'; import { ExchangeRateRecord } from 'src/store/currency/currency-state'; -import { useAssetExchangeRate, useSelectedRpcUrlSelector } from 'src/store/settings/settings-selectors'; +import { useAssetExchangeRate } from 'src/store/settings/settings-selectors'; import type { RootState } from 'src/store/types'; import { useCurrentAccountTezosBalance, useTezosBalanceOfKnownAccountSelector } from 'src/store/wallet/wallet-selectors'; -import { TEZ_TOKEN_SLUG } from 'src/token/data/tokens-metadata'; +import { TEZ_TOKEN_METADATA, TEZ_TOKEN_SLUG } from 'src/token/data/tokens-metadata'; import { TokenInterface } from 'src/token/interfaces/token.interface'; import { AnalyticsError } from './error-analytics-data.utils'; import { getSelectedAccountFromWallet } from './get-selected-account-from-wallet.util.ts'; -import { getNetworkGasTokenMetadata } from './network.utils'; import { createTezosToolkit } from './rpc/tezos-toolkit.utils'; export const withAccount = @@ -45,11 +44,6 @@ export const withOnRampOverlayState = withLatestFrom(state$, (value, { settings }): [T, OnRampOverlayState] => [value, settings.onRampOverlayState]) ); -export const withSelectedRpcUrl = - (state$: Observable) => - (observable$: Observable) => - observable$.pipe(withLatestFrom(state$, (value, { settings }): [T, string] => [value, settings.selectedRpcUrl])); - export const withUsdToTokenRates = (state$: Observable) => (observable$: Observable) => @@ -57,17 +51,16 @@ export const withUsdToTokenRates = withLatestFrom(state$, (value, { currency }): [T, ExchangeRateRecord] => [value, currency.usdToTokenRates.data]) ); -export const sendTransaction$ = (rpcUrl: string, senderPkh: string, opParams: ParamsWithKind[]) => +export const sendTransaction$ = (senderPkh: string, opParams: ParamsWithKind[]) => Shelter.getTezosSigner$(senderPkh).pipe( switchMap(signer => { - const tezos = createTezosToolkit(rpcUrl); + const tezos = createTezosToolkit(); tezos.setSignerProvider(signer); return tezos.contract.batch(opParams).send(); }), catchError(err => { - const makeAnalyticsError = (message?: string) => - new AnalyticsError(err, [senderPkh], { rpcUrl, opParams }, message); + const makeAnalyticsError = (message?: string) => new AnalyticsError(err, [senderPkh], { opParams }, message); try { const errorBody = JSON.parse(err.body); @@ -85,18 +78,16 @@ export const sendTransaction$ = (rpcUrl: string, senderPkh: string, opParams: Pa ); export const useTezosToken = (balance: string) => { - const selectedRpcUrl = useSelectedRpcUrlSelector(); - const metadata = getNetworkGasTokenMetadata(selectedRpcUrl); const exchangeRate = useAssetExchangeRate(TEZ_TOKEN_SLUG); return useMemo( () => ({ visibility: VisibilityEnum.Visible, - ...metadata, + ...TEZ_TOKEN_METADATA, balance, exchangeRate }), - [metadata, balance, exchangeRate] + [balance, exchangeRate] ); }; diff --git a/yarn.lock b/yarn.lock index 3ad7ea406..79b1e273e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2830,12 +2830,12 @@ __metadata: linkType: hard "@grpc/grpc-js@npm:~1.9.0": - version: 1.9.15 - resolution: "@grpc/grpc-js@npm:1.9.15" + version: 1.9.16 + resolution: "@grpc/grpc-js@npm:1.9.16" dependencies: "@grpc/proto-loader": "npm:^0.7.8" "@types/node": "npm:>=12.12.47" - checksum: 10c0/5bd40e1b886df238f8ffe4cab694ceb51250f94ede7da6f94233b4d9a2526a4e525aafbc8f319850c2d8126c189232be458991768877b2af441f0234fb4b4292 + checksum: 10c0/dfe2b1a670d650489fe82bb7afc1c0336313b0cde4a102623a1331267cbdeb1bde9409143fb1432db074bc1845b38d96b82a4277bdd99929aa8322cf97d305aa languageName: node linkType: hard @@ -9738,28 +9738,28 @@ __metadata: linkType: hard "form-data@npm:^3.0.0": - version: 3.0.4 - resolution: "form-data@npm:3.0.4" + version: 3.0.5 + resolution: "form-data@npm:3.0.5" dependencies: asynckit: "npm:^0.4.0" combined-stream: "npm:^1.0.8" es-set-tostringtag: "npm:^2.1.0" - hasown: "npm:^2.0.2" + hasown: "npm:^2.0.4" mime-types: "npm:^2.1.35" - checksum: 10c0/2451043b3e931653ce9690ba051b0bf1b5855a63029279bd7bdf8d02e4b5b42f4582b23ed3637df27a0d21bac2013c37d165ec9486e1af2470c13114aee83acc + checksum: 10c0/899fdb1ee507f5d44159314a53d05d0c41cbf58f92f99b2dd258dd23a5d2d08d069046523b5f12f38f1870ea4f2338266dc0628ea7c8e9b440a4a31d9b88b4d5 languageName: node linkType: hard "form-data@npm:^4.0.5": - version: 4.0.5 - resolution: "form-data@npm:4.0.5" + version: 4.0.6 + resolution: "form-data@npm:4.0.6" dependencies: asynckit: "npm:^0.4.0" combined-stream: "npm:^1.0.8" es-set-tostringtag: "npm:^2.1.0" - hasown: "npm:^2.0.2" - mime-types: "npm:^2.1.12" - checksum: 10c0/dd6b767ee0bbd6d84039db12a0fa5a2028160ffbfaba1800695713b46ae974a5f6e08b3356c3195137f8530dcd9dfcb5d5ae1eeff53d0db1e5aad863b619ce3b + hasown: "npm:^2.0.4" + mime-types: "npm:^2.1.35" + checksum: 10c0/43947a77bf0ff45c6ceed789778982d47a3f3e720a74b71721174ebf3310a5f1a8be1d6b38a3ee3688e8a18a2c4273073ec0844cd37efda3eaf46d41c9c318ff languageName: node linkType: hard @@ -10222,6 +10222,15 @@ __metadata: languageName: node linkType: hard +"hasown@npm:^2.0.4": + version: 2.0.4 + resolution: "hasown@npm:2.0.4" + dependencies: + function-bind: "npm:^1.1.2" + checksum: 10c0/2d8de939e270b70618f8cebb69746620db10617dbb495bc66ddad326955ea24d3ca4af133aff3eb7c1853e0218f867bc2b050ec26fe02e3aea58f880ffc5e506 + languageName: node + linkType: hard + "he@npm:1.2.0": version: 1.2.0 resolution: "he@npm:1.2.0" @@ -12268,7 +12277,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^2.1.12, mime-types@npm:^2.1.35, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": +"mime-types@npm:^2.1.35, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -15024,9 +15033,9 @@ __metadata: linkType: hard "shell-quote@npm:^1.6.1, shell-quote@npm:^1.8.3": - version: 1.8.3 - resolution: "shell-quote@npm:1.8.3" - checksum: 10c0/bee87c34e1e986cfb4c30846b8e6327d18874f10b535699866f368ade11ea4ee45433d97bf5eada22c4320c27df79c3a6a7eb1bf3ecfc47f2c997d9e5e2672fd + version: 1.8.4 + resolution: "shell-quote@npm:1.8.4" + checksum: 10c0/86c93678bc394cb81f5ddcdc87df9c95d279ef9652775cd1cd1eed361404169a8d8cbaacaeed232ab09919e36ee1e5363863570390d78571f8c22b7f6312fb40 languageName: node linkType: hard @@ -16379,9 +16388,9 @@ __metadata: linkType: hard "undici@npm:^6.25.0": - version: 6.26.0 - resolution: "undici@npm:6.26.0" - checksum: 10c0/cf2b4caf58c33d6582970991290cc7a6486d6e738845f25dcdd16952d708ec844815c6d30362919764fcaf30f719891289341f1ada496f003ce2700310453a47 + version: 6.27.0 + resolution: "undici@npm:6.27.0" + checksum: 10c0/f88c3dae3957dbf9d93cb481440aced317bd3c4941b5914fea5efba516d51138988cdb5c76006f0bb1337e41d56c3443351055d492e73af2428521c37ba2a76f languageName: node linkType: hard @@ -16985,9 +16994,9 @@ __metadata: languageName: node linkType: hard -"ws@npm:8.20.1": - version: 8.20.1 - resolution: "ws@npm:8.20.1" +"ws@npm:8.21.0": + version: 8.21.0 + resolution: "ws@npm:8.21.0" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ">=5.0.2" @@ -16996,22 +17005,22 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 10c0/ce162433218399cdedeb76fd33363d4d86a7d910058d4e3c679dce08cea65d6da6b39f11baa4d7808d024cf46ed88f6a05c17611621aaad8fc5e62edacc30c5d + checksum: 10c0/ef4a243476283fc49bc7550966c4af4aa0eef56273837211e700de3b664e08604a760cdddcb5ba43c049140e74ccfec5b0ee0bb439e08c2adf9138902fdde5f9 languageName: node linkType: hard "ws@npm:^6.2.3": - version: 6.2.3 - resolution: "ws@npm:6.2.3" + version: 6.2.4 + resolution: "ws@npm:6.2.4" dependencies: async-limiter: "npm:~1.0.0" - checksum: 10c0/56a35b9799993cea7ce2260197e7879f21bbbb194a967f31acbbda6f7f46ecda4365951966fb062044c95197e19fb2f053be6f65c172435455186835f494de41 + checksum: 10c0/5c2b9474164f9cb68c7776a1d10b0461c186f3a69bffb1028fca33eba5ab7206a09173fb0b311d6c5a81c8cf148406f8deb0b7d899542ab8ca67407d99717dad languageName: node linkType: hard "ws@npm:^7, ws@npm:^7.5.1, ws@npm:^7.5.10": - version: 7.5.10 - resolution: "ws@npm:7.5.10" + version: 7.5.11 + resolution: "ws@npm:7.5.11" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ^5.0.2 @@ -17020,7 +17029,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 10c0/bd7d5f4aaf04fae7960c23dcb6c6375d525e00f795dd20b9385902bd008c40a94d3db3ce97d878acc7573df852056ca546328b27b39f47609f80fb22a0a9b61d + checksum: 10c0/7972670b676fb1ccba73b0899ca3c2e04e8c2075629c2614cced7f556536f96a672bbf4619fc5a06c8b8720bb839a47ca88c69c95dc14c9c61a99fbecba1c866 languageName: node linkType: hard From 3a50223caf153623ddd483edce9c709247b11345 Mon Sep 17 00:00:00 2001 From: Inokentii Mazhara Date: Thu, 16 Jul 2026 15:55:56 +0300 Subject: [PATCH 19/20] TW-2275 Redesign 'Receive' page (#1223) --- .../account-dropdown-item.tsx | 13 +- .../bottom-sheet/bottom-sheet.styles.ts | 26 +- src/components/bottom-sheet/bottom-sheet.tsx | 55 +++- .../use-bottom-sheet-controller.ts | 2 +- src/components/copy-address-popup/index.tsx | 19 +- .../crypto-logo/assets/etherlink.svg | 7 + .../crypto-logo/assets/placeholder.svg | 9 + .../crypto-logo/assets/shielded-tezos.svg | 4 + src/components/crypto-logo/assets/tezos.svg | 4 + src/components/crypto-logo/index.tsx | 37 +++ src/components/crypto-logo/logo-name.enum.ts | 6 + src/components/crypto-logo/logo-name.map.ts | 15 + .../header/exolix-screen-options.tsx | 4 +- .../header-back-button/header-back-button.tsx | 4 +- .../header/header-button/header-button.tsx | 32 ++- .../header-close-button.tsx | 16 +- .../header/header-close-button/styles.ts | 9 + .../icon-v2/assets/alarm-triangle.svg | 3 + src/components/icon-v2/assets/arrow-left.svg | 3 + .../icon-v2/assets/chevron-right.svg | 3 + src/components/icon-v2/assets/copy.svg | 3 + src/components/icon-v2/assets/info.svg | 3 + src/components/icon-v2/assets/plus-big.svg | 3 + src/components/icon-v2/assets/qr.svg | 3 + src/components/icon-v2/assets/x-big.svg | 3 + src/components/icon-v2/icon-name.enum.ts | 10 + src/components/icon-v2/icon-name.map.ts | 23 ++ src/components/icon-v2/index.tsx | 78 ++++++ src/components/icon/assets/alert-shield.svg | 3 - src/components/icon/assets/arrow-left.svg | 4 - src/components/icon/assets/book-open.svg | 4 - src/components/icon/assets/chart-icon.svg | 5 - src/components/icon/assets/exolix.svg | 10 - src/components/icon/assets/hummer.svg | 9 - src/components/icon/assets/info.svg | 5 - src/components/icon/assets/lb-dapp-icon.svg | 4 - src/components/icon/assets/lb-token-icon.svg | 10 - src/components/icon/assets/minus-icon.svg | 3 - src/components/icon/assets/plus-circle.svg | 5 - src/components/icon/assets/plus-icon.svg | 4 - src/components/icon/assets/ramp.svg | 6 - src/components/icon/assets/refresh-icon.svg | 3 - src/components/icon/assets/search.svg | 4 - src/components/icon/assets/socials/github.svg | 3 - .../icon/assets/socials/website.svg | 3 - src/components/icon/assets/soon-badge.svg | 4 - .../assets/swap-route-item-background.svg | 3 - .../icon/assets/swap-settings-new.svg | 3 - src/components/icon/assets/tag.svg | 4 - src/components/icon/assets/terminal.svg | 4 - .../icon/assets/tokens/etherlink.svg | 7 - src/components/icon/assets/tokens/film.svg | 1 - src/components/icon/assets/ukraine.svg | 1 - src/components/icon/assets/x-search.svg | 3 - src/components/icon/icon-name.enum.ts | 27 +- src/components/icon/icon-name.map.ts | 52 ---- src/components/icon/icon.tsx | 1 + src/components/touchable-icon-v2/index.tsx | 43 +++ src/components/touchable-icon-v2/styles.ts | 8 + src/layouts/reveal-seed-phrase/index.tsx | 4 +- .../receive-modal/address-card/index.tsx | 74 +++++ .../receive-modal/address-card/styles.ts | 58 ++++ .../receive-modal/network-icon/index.tsx | 21 ++ .../receive-modal/network-icon/styles.ts | 14 + .../receive-modal/qr-bottom-sheet/index.tsx | 44 +++ .../receive-modal/qr-bottom-sheet/styles.ts | 36 +++ .../receive-modal/receive-modal.selectors.ts | 3 +- .../receive-modal/receive-modal.styles.ts | 102 +------ src/modals/receive-modal/receive-modal.tsx | 257 +++--------------- src/modals/receive-modal/types.ts | 9 + src/screens/contacts/contacts.tsx | 4 +- .../manage-accounts/manage-accounts.tsx | 4 +- src/screens/manage-assets/manage-assets.tsx | 4 +- .../verify-seed-phrase/verify-seed-phrase.tsx | 4 +- .../networks/all-networks-options/index.tsx | 14 +- .../tezos-token-screen/tezos-token-screen.tsx | 3 +- src/screens/token-screen/token-screen.tsx | 4 +- .../backup-your-wallet-overlay.tsx | 10 +- .../on-ramp-overlay/on-ramp-overlay.tsx | 112 ++++---- 79 files changed, 796 insertions(+), 628 deletions(-) create mode 100644 src/components/crypto-logo/assets/etherlink.svg create mode 100644 src/components/crypto-logo/assets/placeholder.svg create mode 100644 src/components/crypto-logo/assets/shielded-tezos.svg create mode 100644 src/components/crypto-logo/assets/tezos.svg create mode 100644 src/components/crypto-logo/index.tsx create mode 100644 src/components/crypto-logo/logo-name.enum.ts create mode 100644 src/components/crypto-logo/logo-name.map.ts create mode 100644 src/components/header/header-close-button/styles.ts create mode 100644 src/components/icon-v2/assets/alarm-triangle.svg create mode 100644 src/components/icon-v2/assets/arrow-left.svg create mode 100644 src/components/icon-v2/assets/chevron-right.svg create mode 100644 src/components/icon-v2/assets/copy.svg create mode 100644 src/components/icon-v2/assets/info.svg create mode 100644 src/components/icon-v2/assets/plus-big.svg create mode 100644 src/components/icon-v2/assets/qr.svg create mode 100644 src/components/icon-v2/assets/x-big.svg create mode 100644 src/components/icon-v2/icon-name.enum.ts create mode 100644 src/components/icon-v2/icon-name.map.ts create mode 100644 src/components/icon-v2/index.tsx delete mode 100644 src/components/icon/assets/alert-shield.svg delete mode 100644 src/components/icon/assets/arrow-left.svg delete mode 100644 src/components/icon/assets/book-open.svg delete mode 100644 src/components/icon/assets/chart-icon.svg delete mode 100644 src/components/icon/assets/exolix.svg delete mode 100644 src/components/icon/assets/hummer.svg delete mode 100644 src/components/icon/assets/info.svg delete mode 100644 src/components/icon/assets/lb-dapp-icon.svg delete mode 100644 src/components/icon/assets/lb-token-icon.svg delete mode 100644 src/components/icon/assets/minus-icon.svg delete mode 100644 src/components/icon/assets/plus-circle.svg delete mode 100644 src/components/icon/assets/plus-icon.svg delete mode 100644 src/components/icon/assets/ramp.svg delete mode 100644 src/components/icon/assets/refresh-icon.svg delete mode 100644 src/components/icon/assets/search.svg delete mode 100644 src/components/icon/assets/socials/github.svg delete mode 100644 src/components/icon/assets/socials/website.svg delete mode 100644 src/components/icon/assets/soon-badge.svg delete mode 100644 src/components/icon/assets/swap-route-item-background.svg delete mode 100644 src/components/icon/assets/swap-settings-new.svg delete mode 100644 src/components/icon/assets/tag.svg delete mode 100644 src/components/icon/assets/terminal.svg delete mode 100644 src/components/icon/assets/tokens/etherlink.svg delete mode 100644 src/components/icon/assets/tokens/film.svg delete mode 100644 src/components/icon/assets/ukraine.svg delete mode 100644 src/components/icon/assets/x-search.svg create mode 100644 src/components/touchable-icon-v2/index.tsx create mode 100644 src/components/touchable-icon-v2/styles.ts create mode 100644 src/modals/receive-modal/address-card/index.tsx create mode 100644 src/modals/receive-modal/address-card/styles.ts create mode 100644 src/modals/receive-modal/network-icon/index.tsx create mode 100644 src/modals/receive-modal/network-icon/styles.ts create mode 100644 src/modals/receive-modal/qr-bottom-sheet/index.tsx create mode 100644 src/modals/receive-modal/qr-bottom-sheet/styles.ts create mode 100644 src/modals/receive-modal/types.ts diff --git a/src/components/account-dropdown/account-dropdown-item/account-dropdown-item.tsx b/src/components/account-dropdown/account-dropdown-item/account-dropdown-item.tsx index 9da7dff4c..22e188508 100644 --- a/src/components/account-dropdown/account-dropdown-item/account-dropdown-item.tsx +++ b/src/components/account-dropdown/account-dropdown-item/account-dropdown-item.tsx @@ -3,10 +3,11 @@ import React, { memo, useMemo } from 'react'; import { Text, View } from 'react-native'; import { AssetValueText } from 'src/components/asset-value-text/asset-value-text'; +import { CryptoLogo } from 'src/components/crypto-logo'; +import { CryptoLogoNameEnum } from 'src/components/crypto-logo/logo-name.enum'; import { DropdownListItemComponent } from 'src/components/dropdown/dropdown'; import { HideBalance } from 'src/components/hide-balance/hide-balance'; import { Icon } from 'src/components/icon/icon'; -import { IconNameEnum } from 'src/components/icon/icon-name.enum'; import { RobotIcon } from 'src/components/robot-icon/robot-icon'; import { getSeedFromAccount } from 'src/components/robot-icon/robot-icon.utils.ts'; import { TruncatedText } from 'src/components/truncated-text'; @@ -93,11 +94,11 @@ const AccountDropdownListItem = memo>( - {isDefined(tezosAddress) && } + {isDefined(tezosAddress) && } {isDefined(saplingAddress) && ( - + )} - {isDefined(evmAddress) && } + {isDefined(evmAddress) && } ); @@ -109,7 +110,7 @@ export const renderAccountListItem: DropdownListItemComponent = ({ item interface AccountAddressChipProps { address: string; - iconName: IconNameEnum; + iconName: CryptoLogoNameEnum; } const AccountAddressChip = memo(({ address, iconName }) => { @@ -117,7 +118,7 @@ const AccountAddressChip = memo(({ address, iconName }) return ( - + {truncateAddress(address)} ); diff --git a/src/components/bottom-sheet/bottom-sheet.styles.ts b/src/components/bottom-sheet/bottom-sheet.styles.ts index ab144218a..43ebbe483 100644 --- a/src/components/bottom-sheet/bottom-sheet.styles.ts +++ b/src/components/bottom-sheet/bottom-sheet.styles.ts @@ -12,12 +12,30 @@ export const useDropdownBottomSheetStyles = createUseStyles(({ colors, typograph overflow: 'hidden' }, headerContainer: { - justifyContent: 'center', alignItems: 'center', - paddingVertical: formatSize(16), - paddingHorizontal: formatSize(12), + paddingVertical: formatSize(12), + paddingHorizontal: formatSize(16), borderBottomColor: colors.lines, - borderBottomWidth: formatSize(1) + borderBottomWidth: formatSize(1), + flexDirection: 'row' + }, + headerTextsContainer: { + flex: 1, + alignItems: 'center', + flexDirection: 'column' + }, + headerLeftSide: { + flex: 1 + }, + headerRightSide: { + flex: 1, + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'flex-end' + }, + closeButton: { + backgroundColor: colors.peach10, + borderRadius: formatSize(100) }, title: { ...typography.body17Semibold, diff --git a/src/components/bottom-sheet/bottom-sheet.tsx b/src/components/bottom-sheet/bottom-sheet.tsx index d30bbf708..4c8832355 100644 --- a/src/components/bottom-sheet/bottom-sheet.tsx +++ b/src/components/bottom-sheet/bottom-sheet.tsx @@ -6,7 +6,7 @@ import GorhomBottomSheet, { } from '@gorhom/bottom-sheet'; import { Portal } from '@gorhom/portal'; import React, { PropsWithChildren, useCallback, useEffect, useState } from 'react'; -import { BackHandler, Keyboard, Text, useWindowDimensions, View } from 'react-native'; +import { BackHandler, Keyboard, StyleProp, Text, useWindowDimensions, View, ViewStyle } from 'react-native'; import { useOrientationChange } from 'react-native-orientation-locker'; import { useSharedValue } from 'react-native-reanimated'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; @@ -17,6 +17,9 @@ import { useAppLock } from 'src/shelter/app-lock/app-lock'; import { formatSize } from 'src/styles/format-size'; import { isDefined } from 'src/utils/is-defined'; +import { IconNameV2Enum } from '../icon-v2/icon-name.enum'; +import { TouchableIconV2 } from '../touchable-icon-v2'; + import { useDropdownBottomSheetStyles } from './bottom-sheet.styles'; import { BottomSheetControllerProps } from './use-bottom-sheet-controller'; @@ -26,9 +29,12 @@ interface Props extends BottomSheetControllerProps { cancelButtonText?: string; onCancelButtonPress?: EmptyFn; cancelButtonTestID?: string; + showCancelButton?: boolean; + showCloseButton?: boolean; onClose?: EmptyFn; contentHeight: number; isInitiallyOpen?: boolean; + rootStyle?: StyleProp; } export const BottomSheet: FCWithChildren = ({ @@ -41,7 +47,10 @@ export const BottomSheet: FCWithChildren = ({ onClose = emptyFn, contentHeight, controller, - children + children, + showCancelButton = true, + showCloseButton = false, + rootStyle }) => { // hack that prevents rendering of GorhomBottomSheet component for locked app state, // as it loads heavy Reanimated 2 modules and application do not respond on gestures @@ -68,7 +77,7 @@ export const BottomSheet: FCWithChildren = ({ @@ -90,6 +99,9 @@ export const BottomSheet: FCWithChildren = ({ onClose(); } }; + const handleClosePress = () => { + controller.close(); + }; useEffect(() => { if (isOpened) { @@ -123,24 +135,39 @@ export const BottomSheet: FCWithChildren = ({ onChange={handleChange} onClose={handleClose} > - + {(isDefined(title) || isDefined(description)) && ( - {isDefined(title) && {title}} - {isDefined(description) && {description}} + {showCloseButton && } + + {isDefined(title) && {title}} + {isDefined(description) && {description}} + + {showCloseButton && ( + + + + )} )} {children} - - {cancelButtonText} - + {showCancelButton && ( + + {cancelButtonText} + + )} )} diff --git a/src/components/bottom-sheet/use-bottom-sheet-controller.ts b/src/components/bottom-sheet/use-bottom-sheet-controller.ts index d8ea88cbc..4cedbcd95 100644 --- a/src/components/bottom-sheet/use-bottom-sheet-controller.ts +++ b/src/components/bottom-sheet/use-bottom-sheet-controller.ts @@ -6,7 +6,7 @@ import { isDefined } from 'src/utils/is-defined'; type BottomSheetCallback = (config?: WithSpringConfig | WithTimingConfig) => void; -interface BottomSheetController { +export interface BottomSheetController { ref: Ref; open: BottomSheetCallback; close: BottomSheetCallback; diff --git a/src/components/copy-address-popup/index.tsx b/src/components/copy-address-popup/index.tsx index 86fbf4d51..d4c78fb63 100644 --- a/src/components/copy-address-popup/index.tsx +++ b/src/components/copy-address-popup/index.tsx @@ -1,10 +1,6 @@ import React, { memo, Ref, useCallback, useImperativeHandle, useMemo, useState } from 'react'; import { Modal, Text, TouchableWithoutFeedback, View } from 'react-native'; -import { Icon } from 'src/components/icon/icon'; -import { IconNameEnum } from 'src/components/icon/icon-name.enum'; -import { SafeTouchableOpacity } from 'src/components/safe-touchable-opacity'; -import { TruncatedText } from 'src/components/truncated-text'; import { Account } from 'src/interfaces/account.interfaces'; import { useSaplingAddressForAccount } from 'src/store/sapling/sapling-selectors.ts'; import { formatSize } from 'src/styles/format-size'; @@ -13,6 +9,11 @@ import { copyStringToClipboard } from 'src/utils/clipboard.utils'; import { isDefined } from 'src/utils/is-defined'; import { isTruthy } from 'src/utils/is-truthy.ts'; +import { CryptoLogo } from '../crypto-logo'; +import { CryptoLogoNameEnum } from '../crypto-logo/logo-name.enum'; +import { SafeTouchableOpacity } from '../safe-touchable-opacity'; +import { TruncatedText } from '../truncated-text'; + import { useCopyAddressPopupStyles } from './styles'; export interface CopyAddressPopupController { @@ -23,7 +24,7 @@ export interface CopyAddressPopupController { interface CopyAddressOption { label: string; address: string; - iconName: IconNameEnum; + iconName: CryptoLogoNameEnum; } interface Props { @@ -45,17 +46,17 @@ export const CopyAddressPopup = memo(({ controlRef, account }) => { isDefined(tezosAddress) && { label: 'Tezos', address: tezosAddress, - iconName: IconNameEnum.TezToken + iconName: CryptoLogoNameEnum.Tezos }, isDefined(saplingAddress) && { label: 'Shielded', address: saplingAddress, - iconName: IconNameEnum.TezShieldedToken + iconName: CryptoLogoNameEnum.ShieldedTezos }, isDefined(evmAddress) && { label: 'Etherlink', address: evmAddress, - iconName: IconNameEnum.EtherlinkToken + iconName: CryptoLogoNameEnum.Etherlink } ].filter(isTruthy); }, [account, saplingAddress]); @@ -95,7 +96,7 @@ export const CopyAddressPopup = memo(({ controlRef, account }) => { - + diff --git a/src/components/crypto-logo/assets/etherlink.svg b/src/components/crypto-logo/assets/etherlink.svg new file mode 100644 index 000000000..0d185360c --- /dev/null +++ b/src/components/crypto-logo/assets/etherlink.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/components/crypto-logo/assets/placeholder.svg b/src/components/crypto-logo/assets/placeholder.svg new file mode 100644 index 000000000..95d400c0b --- /dev/null +++ b/src/components/crypto-logo/assets/placeholder.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/components/crypto-logo/assets/shielded-tezos.svg b/src/components/crypto-logo/assets/shielded-tezos.svg new file mode 100644 index 000000000..88f182a44 --- /dev/null +++ b/src/components/crypto-logo/assets/shielded-tezos.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/components/crypto-logo/assets/tezos.svg b/src/components/crypto-logo/assets/tezos.svg new file mode 100644 index 000000000..6cc7b7226 --- /dev/null +++ b/src/components/crypto-logo/assets/tezos.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/components/crypto-logo/index.tsx b/src/components/crypto-logo/index.tsx new file mode 100644 index 000000000..31229d4fb --- /dev/null +++ b/src/components/crypto-logo/index.tsx @@ -0,0 +1,37 @@ +import { FC, useMemo } from 'react'; +import { SvgProps } from 'react-native-svg'; + +import { TestIdProps } from 'src/interfaces/test-id.props'; +import { formatSize } from 'src/styles/format-size'; + +import { CryptoLogoNameEnum } from './logo-name.enum'; +import { CryptoLogoNameMap } from './logo-name.map'; + +interface CryptoLogoProps extends TestIdProps, Omit { + name: CryptoLogoNameEnum; + size?: number; + internalSize?: number; +} + +const defaultInternalSizeByRatioIcons = new Set([ + CryptoLogoNameEnum.Etherlink, + CryptoLogoNameEnum.ShieldedTezos, + CryptoLogoNameEnum.Tezos +]); + +export const CryptoLogo: FC = ({ + name, + size = formatSize(24), + internalSize = defaultInternalSizeByRatioIcons.has(name) ? (size * 10) / 12 : size - formatSize(4), + style: styleFromProps, + ...restProps +}) => { + const Svg = CryptoLogoNameMap[name]; + + const style = useMemo( + () => [{ margin: (size - internalSize) / 2 }, styleFromProps], + [styleFromProps, internalSize, size] + ); + + return ; +}; diff --git a/src/components/crypto-logo/logo-name.enum.ts b/src/components/crypto-logo/logo-name.enum.ts new file mode 100644 index 000000000..bdd4bcfa7 --- /dev/null +++ b/src/components/crypto-logo/logo-name.enum.ts @@ -0,0 +1,6 @@ +export enum CryptoLogoNameEnum { + Etherlink = 'etherlink', + Placeholder = 'placeholder', + Tezos = 'tezos', + ShieldedTezos = 'shielded-tezos' +} diff --git a/src/components/crypto-logo/logo-name.map.ts b/src/components/crypto-logo/logo-name.map.ts new file mode 100644 index 000000000..829083270 --- /dev/null +++ b/src/components/crypto-logo/logo-name.map.ts @@ -0,0 +1,15 @@ +import { FC } from 'react'; +import { SvgProps } from 'react-native-svg'; + +import EtherlinkLogo from './assets/etherlink.svg'; +import PlaceholderLogo from './assets/placeholder.svg'; +import ShieldedTezosLogo from './assets/shielded-tezos.svg'; +import TezosLogo from './assets/tezos.svg'; +import { CryptoLogoNameEnum } from './logo-name.enum'; + +export const CryptoLogoNameMap: Record> = { + [CryptoLogoNameEnum.Etherlink]: EtherlinkLogo, + [CryptoLogoNameEnum.Placeholder]: PlaceholderLogo, + [CryptoLogoNameEnum.Tezos]: TezosLogo, + [CryptoLogoNameEnum.ShieldedTezos]: ShieldedTezosLogo +}; diff --git a/src/components/header/exolix-screen-options.tsx b/src/components/header/exolix-screen-options.tsx index 9a2e19be6..9bd2121a1 100644 --- a/src/components/header/exolix-screen-options.tsx +++ b/src/components/header/exolix-screen-options.tsx @@ -4,7 +4,7 @@ import React, { FC, useMemo } from 'react'; import { useNavigation } from 'src/navigator/hooks/use-navigation.hook'; import { useExolixStep } from 'src/store/exolix/exolix-selectors'; -import { IconNameEnum } from '../icon/icon-name.enum'; +import { IconNameV2Enum } from '../icon-v2/icon-name.enum'; import { HeaderButton } from './header-button/header-button'; import { HeaderProgress } from './header-progress/header-progress'; @@ -17,7 +17,7 @@ const BackButton: FC = () => { goBack(); }; - return ; + return ; }; export const exolixScreenOptions = (): StackNavigationOptions => ({ diff --git a/src/components/header/header-back-button/header-back-button.tsx b/src/components/header/header-back-button/header-back-button.tsx index 1acf7a797..0b18080be 100644 --- a/src/components/header/header-back-button/header-back-button.tsx +++ b/src/components/header/header-back-button/header-back-button.tsx @@ -1,12 +1,12 @@ import React, { FC } from 'react'; +import { IconNameV2Enum } from 'src/components/icon-v2/icon-name.enum'; import { useNavigation } from 'src/navigator/hooks/use-navigation.hook'; -import { IconNameEnum } from '../../icon/icon-name.enum'; import { HeaderButton } from '../header-button/header-button'; export const HeaderBackButton: FC = () => { const { goBack } = useNavigation(); - return ; + return ; }; diff --git a/src/components/header/header-button/header-button.tsx b/src/components/header/header-button/header-button.tsx index fe33543d0..f3ce541a6 100644 --- a/src/components/header/header-button/header-button.tsx +++ b/src/components/header/header-button/header-button.tsx @@ -1,18 +1,38 @@ import React, { FC } from 'react'; +import { IconV2Props } from 'src/components/icon-v2'; +import { IconNameV2Enum } from 'src/components/icon-v2/icon-name.enum'; +import { TouchableIconV2 } from 'src/components/touchable-icon-v2'; import { TestIdProps } from 'src/interfaces/test-id.props'; - -import { IconNameEnum } from '../../icon/icon-name.enum'; -import { TouchableIcon } from '../../icon/touchable-icon/touchable-icon'; +import { formatSize } from 'src/styles/format-size'; import { HeaderButtonStyles } from './header-button.styles'; interface Props extends TestIdProps { - iconName: IconNameEnum; + iconName: IconNameV2Enum; onPress: EmptyFn; color?: string; + style?: IconV2Props['style']; + iconSize?: IconV2Props['size']; + size?: number; } -export const HeaderButton: FC = ({ iconName, color, onPress, testID }) => ( - +export const HeaderButton: FC = ({ + iconName, + color, + onPress, + testID, + style, + iconSize = 24, + size = formatSize(24) +}) => ( + ); diff --git a/src/components/header/header-close-button/header-close-button.tsx b/src/components/header/header-close-button/header-close-button.tsx index 362062ccc..49ad219d5 100644 --- a/src/components/header/header-close-button/header-close-button.tsx +++ b/src/components/header/header-close-button/header-close-button.tsx @@ -1,12 +1,24 @@ import React, { FC } from 'react'; +import { IconNameV2Enum } from 'src/components/icon-v2/icon-name.enum'; import { useNavigation } from 'src/navigator/hooks/use-navigation.hook'; +import { formatSize } from 'src/styles/format-size'; -import { IconNameEnum } from '../../icon/icon-name.enum'; import { HeaderButton } from '../header-button/header-button'; +import { useHeaderCloseButtonStyles } from './styles'; + export const HeaderCloseButton: FC = () => { const { goBack } = useNavigation(); + const styles = useHeaderCloseButtonStyles(); - return ; + return ( + + ); }; diff --git a/src/components/header/header-close-button/styles.ts b/src/components/header/header-close-button/styles.ts new file mode 100644 index 000000000..250ede5ab --- /dev/null +++ b/src/components/header/header-close-button/styles.ts @@ -0,0 +1,9 @@ +import { createUseStylesMemoized } from 'src/styles/create-use-styles'; +import { formatSize } from 'src/styles/format-size'; + +export const useHeaderCloseButtonStyles = createUseStylesMemoized(({ colors }) => ({ + icon: { + backgroundColor: colors.peach10, + borderRadius: formatSize(100) + } +})); diff --git a/src/components/icon-v2/assets/alarm-triangle.svg b/src/components/icon-v2/assets/alarm-triangle.svg new file mode 100644 index 000000000..7bbdf2362 --- /dev/null +++ b/src/components/icon-v2/assets/alarm-triangle.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/icon-v2/assets/arrow-left.svg b/src/components/icon-v2/assets/arrow-left.svg new file mode 100644 index 000000000..0c53bb2b0 --- /dev/null +++ b/src/components/icon-v2/assets/arrow-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/icon-v2/assets/chevron-right.svg b/src/components/icon-v2/assets/chevron-right.svg new file mode 100644 index 000000000..cf0bb70aa --- /dev/null +++ b/src/components/icon-v2/assets/chevron-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/icon-v2/assets/copy.svg b/src/components/icon-v2/assets/copy.svg new file mode 100644 index 000000000..5d7ac74fd --- /dev/null +++ b/src/components/icon-v2/assets/copy.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/icon-v2/assets/info.svg b/src/components/icon-v2/assets/info.svg new file mode 100644 index 000000000..dbc163be0 --- /dev/null +++ b/src/components/icon-v2/assets/info.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/icon-v2/assets/plus-big.svg b/src/components/icon-v2/assets/plus-big.svg new file mode 100644 index 000000000..a10f6a88c --- /dev/null +++ b/src/components/icon-v2/assets/plus-big.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/icon-v2/assets/qr.svg b/src/components/icon-v2/assets/qr.svg new file mode 100644 index 000000000..6e4cb2fe3 --- /dev/null +++ b/src/components/icon-v2/assets/qr.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/icon-v2/assets/x-big.svg b/src/components/icon-v2/assets/x-big.svg new file mode 100644 index 000000000..e4d2287e1 --- /dev/null +++ b/src/components/icon-v2/assets/x-big.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/icon-v2/icon-name.enum.ts b/src/components/icon-v2/icon-name.enum.ts new file mode 100644 index 000000000..ccf442a18 --- /dev/null +++ b/src/components/icon-v2/icon-name.enum.ts @@ -0,0 +1,10 @@ +export enum IconNameV2Enum { + Copy = 'Copy', + Qr = 'Qr', + XBig = 'XBig', + AlarmTriangle = 'AlarmTriangle', + Info = 'Info', + ArrowLeft = 'ArrowLeft', + PlusBig = 'PlusBig', + ChevronRight = 'ChevronRight' +} diff --git a/src/components/icon-v2/icon-name.map.ts b/src/components/icon-v2/icon-name.map.ts new file mode 100644 index 000000000..b6d68eb88 --- /dev/null +++ b/src/components/icon-v2/icon-name.map.ts @@ -0,0 +1,23 @@ +import { FC } from 'react'; +import { SvgProps } from 'react-native-svg'; + +import AlarmTriangleIcon from './assets/alarm-triangle.svg'; +import ArrowLeftIcon from './assets/arrow-left.svg'; +import ChevronRightIcon from './assets/chevron-right.svg'; +import CopyIcon from './assets/copy.svg'; +import InfoIcon from './assets/info.svg'; +import PlusBigIcon from './assets/plus-big.svg'; +import QrIcon from './assets/qr.svg'; +import XBigIcon from './assets/x-big.svg'; +import { IconNameV2Enum } from './icon-name.enum'; + +export const IconNameV2Map: Record> = { + [IconNameV2Enum.Copy]: CopyIcon, + [IconNameV2Enum.Qr]: QrIcon, + [IconNameV2Enum.XBig]: XBigIcon, + [IconNameV2Enum.AlarmTriangle]: AlarmTriangleIcon, + [IconNameV2Enum.Info]: InfoIcon, + [IconNameV2Enum.ArrowLeft]: ArrowLeftIcon, + [IconNameV2Enum.PlusBig]: PlusBigIcon, + [IconNameV2Enum.ChevronRight]: ChevronRightIcon +}; diff --git a/src/components/icon-v2/index.tsx b/src/components/icon-v2/index.tsx new file mode 100644 index 000000000..693b3fd34 --- /dev/null +++ b/src/components/icon-v2/index.tsx @@ -0,0 +1,78 @@ +import { FC, useMemo } from 'react'; +import { StyleSheet, View } from 'react-native'; +import { SvgProps } from 'react-native-svg'; + +import { TestIdProps } from 'src/interfaces/test-id.props'; +import { formatSize } from 'src/styles/format-size'; +import { useColors } from 'src/styles/use-colors'; + +import { IconNameV2Enum } from './icon-name.enum'; +import { IconNameV2Map } from './icon-name.map'; + +type IconSize = 12 | 16 | 24 | 32; + +export interface IconV2Props extends TestIdProps, Omit { + name: IconNameV2Enum; + size?: IconSize; +} + +const regularPaddingSizes: Record = { + 12: 1, + 16: 1, + 24: 4, + 32: 1 +}; + +const irregularPaddingByIconName: Partial>>> = { + // TODO: Apply the same for other single arrow icons + [IconNameV2Enum.ArrowLeft]: { + 24: 4.742 + }, + // TODO: Apply the same for other single chevron icons + [IconNameV2Enum.ChevronRight]: { + 16: 2, + 24: 5.219 + }, + [IconNameV2Enum.Copy]: { + 24: 3.458 + } +}; + +const getPadding = (size: IconSize, name: IconNameV2Enum) => + irregularPaddingByIconName[name]?.[size] ?? regularPaddingSizes[size]; + +const makeSizeWrapperStyles = (size: IconSize) => ({ + width: formatSize(size), + height: formatSize(size) +}); + +const sizeWrapperStyles = StyleSheet.create({ + wrapper: { + justifyContent: 'center', + alignItems: 'center' + }, + 12: makeSizeWrapperStyles(12), + 16: makeSizeWrapperStyles(16), + 24: makeSizeWrapperStyles(24), + 32: makeSizeWrapperStyles(32) +}); + +const DEFAULT_SIZE = 16 as const; + +export const IconV2: FC = ({ name, size = DEFAULT_SIZE, color, style, testID }) => { + const { peach } = useColors(); + const Svg = IconNameV2Map[name]; + + const internalSize = useMemo(() => { + const padding = getPadding(size, name); + const defaultSizePadding = getPadding(DEFAULT_SIZE, name); + + return ((size - 2 * padding) * formatSize(DEFAULT_SIZE)) / (DEFAULT_SIZE - 2 * defaultSizePadding); + }, [size, name]); + + return ( + + + + ); +}; diff --git a/src/components/icon/assets/alert-shield.svg b/src/components/icon/assets/alert-shield.svg deleted file mode 100644 index fbffe02b5..000000000 --- a/src/components/icon/assets/alert-shield.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/components/icon/assets/arrow-left.svg b/src/components/icon/assets/arrow-left.svg deleted file mode 100644 index 3cacc71ee..000000000 --- a/src/components/icon/assets/arrow-left.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/components/icon/assets/book-open.svg b/src/components/icon/assets/book-open.svg deleted file mode 100644 index 2b95a6123..000000000 --- a/src/components/icon/assets/book-open.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/components/icon/assets/chart-icon.svg b/src/components/icon/assets/chart-icon.svg deleted file mode 100644 index 19196ae37..000000000 --- a/src/components/icon/assets/chart-icon.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/components/icon/assets/exolix.svg b/src/components/icon/assets/exolix.svg deleted file mode 100644 index 2cb0ab971..000000000 --- a/src/components/icon/assets/exolix.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/src/components/icon/assets/hummer.svg b/src/components/icon/assets/hummer.svg deleted file mode 100644 index 1efaabc81..000000000 --- a/src/components/icon/assets/hummer.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/src/components/icon/assets/info.svg b/src/components/icon/assets/info.svg deleted file mode 100644 index ff3b5769b..000000000 --- a/src/components/icon/assets/info.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/components/icon/assets/lb-dapp-icon.svg b/src/components/icon/assets/lb-dapp-icon.svg deleted file mode 100644 index 5f333936b..000000000 --- a/src/components/icon/assets/lb-dapp-icon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/components/icon/assets/lb-token-icon.svg b/src/components/icon/assets/lb-token-icon.svg deleted file mode 100644 index ab6e7603a..000000000 --- a/src/components/icon/assets/lb-token-icon.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/src/components/icon/assets/minus-icon.svg b/src/components/icon/assets/minus-icon.svg deleted file mode 100644 index f3a9d4c9f..000000000 --- a/src/components/icon/assets/minus-icon.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/components/icon/assets/plus-circle.svg b/src/components/icon/assets/plus-circle.svg deleted file mode 100644 index f964cd27a..000000000 --- a/src/components/icon/assets/plus-circle.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/components/icon/assets/plus-icon.svg b/src/components/icon/assets/plus-icon.svg deleted file mode 100644 index 2d8aaf19d..000000000 --- a/src/components/icon/assets/plus-icon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/components/icon/assets/ramp.svg b/src/components/icon/assets/ramp.svg deleted file mode 100644 index f3d554f23..000000000 --- a/src/components/icon/assets/ramp.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/components/icon/assets/refresh-icon.svg b/src/components/icon/assets/refresh-icon.svg deleted file mode 100644 index f2686c427..000000000 --- a/src/components/icon/assets/refresh-icon.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/components/icon/assets/search.svg b/src/components/icon/assets/search.svg deleted file mode 100644 index 0fec8a9d9..000000000 --- a/src/components/icon/assets/search.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/components/icon/assets/socials/github.svg b/src/components/icon/assets/socials/github.svg deleted file mode 100644 index 2601996a8..000000000 --- a/src/components/icon/assets/socials/github.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/components/icon/assets/socials/website.svg b/src/components/icon/assets/socials/website.svg deleted file mode 100644 index fe6087f2f..000000000 --- a/src/components/icon/assets/socials/website.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/components/icon/assets/soon-badge.svg b/src/components/icon/assets/soon-badge.svg deleted file mode 100644 index 871ff90fe..000000000 --- a/src/components/icon/assets/soon-badge.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/components/icon/assets/swap-route-item-background.svg b/src/components/icon/assets/swap-route-item-background.svg deleted file mode 100644 index 645d69bb8..000000000 --- a/src/components/icon/assets/swap-route-item-background.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/components/icon/assets/swap-settings-new.svg b/src/components/icon/assets/swap-settings-new.svg deleted file mode 100644 index 667bc797f..000000000 --- a/src/components/icon/assets/swap-settings-new.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/components/icon/assets/tag.svg b/src/components/icon/assets/tag.svg deleted file mode 100644 index f06ce8f1c..000000000 --- a/src/components/icon/assets/tag.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/components/icon/assets/terminal.svg b/src/components/icon/assets/terminal.svg deleted file mode 100644 index 48ab6ba3a..000000000 --- a/src/components/icon/assets/terminal.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/components/icon/assets/tokens/etherlink.svg b/src/components/icon/assets/tokens/etherlink.svg deleted file mode 100644 index 29db914f0..000000000 --- a/src/components/icon/assets/tokens/etherlink.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/components/icon/assets/tokens/film.svg b/src/components/icon/assets/tokens/film.svg deleted file mode 100644 index 4d876937b..000000000 --- a/src/components/icon/assets/tokens/film.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/components/icon/assets/ukraine.svg b/src/components/icon/assets/ukraine.svg deleted file mode 100644 index 7a1013437..000000000 --- a/src/components/icon/assets/ukraine.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/components/icon/assets/x-search.svg b/src/components/icon/assets/x-search.svg deleted file mode 100644 index 69b2ac201..000000000 --- a/src/components/icon/assets/x-search.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/components/icon/icon-name.enum.ts b/src/components/icon/icon-name.enum.ts index 038ae0b43..0dc91698d 100644 --- a/src/components/icon/icon-name.enum.ts +++ b/src/components/icon/icon-name.enum.ts @@ -1,9 +1,9 @@ +/** @deprecated Extend and use IconNameV2Enum or CryptoLogoNameEnum */ export enum IconNameEnum { Audio = 'Audio', ArrowUp = 'ArrowUp', ArrowDown = 'ArrowDown', ArrowRight = 'ArrowRight', - ArrowLeft = 'ArrowLeft', Action = 'Action', Bell = 'Bell', Burn = 'Burn', @@ -13,8 +13,6 @@ export enum IconNameEnum { CycleStatusInProgress = 'CycleStatusInProgress', CycleStatusUnlocked = 'CycleStatusUnlocked', CycleStatusFuture = 'CycleStatusFuture', - BookOpen = 'BookOpen', - Terminal = 'Terminal', Download = 'Download', Diez = 'Diez', FaceId = 'FaceId', @@ -29,7 +27,6 @@ export enum IconNameEnum { InvertedCheckboxOn = 'InvertedCheckboxOn', PlusSquare = 'PlusSquare', HelpCircle = 'HelpCircle', - PlusCircle = 'PlusCircle', InputXCircle = 'InputXCircle', X = 'X', XBold = 'XBold', @@ -39,14 +36,12 @@ export enum IconNameEnum { SwapArrow = 'SwapArrow', SwapInfo = 'SwapInfo', SwapSettings = 'SwapSettings', - SwapSettingsNew = 'SwapSettingsNew', Swap = 'Swap', EyeClosedBold = 'EyeClosedBold', EyeOpenBold = 'EyeOpenBold', TezWallet = 'TezWallet', Settings = 'Settings', DApps = 'DApps', - SoonBadge = 'SoonBadge', Spicy = 'Spicy', WTez = 'WTez', OXtz = 'OXtz', @@ -58,8 +53,6 @@ export enum IconNameEnum { Close = 'Close', TezToken = 'TezToken', TezShieldedToken = 'TezShieldedToken', - EtherlinkToken = 'EtherlinkToken', - FilmToken = 'FilmToken', TzBtcToken = 'TzBtcToken', NoNameToken = 'NoNameToken', InfoFilled = 'InfoFilled', @@ -68,14 +61,11 @@ export enum IconNameEnum { Share = 'Share', Copy = 'Copy', CopyBold = 'CopyBold', - Tag = 'Tag', QrScanner = 'QrScanner', QrScannerBold = 'QrScannerBold', TriangleDown = 'TriangleDown', MoonPay = 'MoonPay', - Exolix = 'Exolix', Utorg = 'Utorg', - Ramp = 'Ramp', Check = 'Check', CheckCircle = 'CheckCircle', Lock = 'Lock', @@ -86,7 +76,6 @@ export enum IconNameEnum { AlertTriangle = 'AlertTriangle', AlertCircle = 'AlertCircle', Clock = 'Clock', - Info = 'Info', InfoAlt = 'InfoAlt', ChevronRight = 'ChevronRight', ChevronUp = 'ChevronUp', @@ -104,9 +93,7 @@ export enum IconNameEnum { ExternalLink = 'ExternalLink', ExternalLinkTag = 'ExternalLinkTag', IosSearch = 'IosSearch', - Search = 'Search', SearchNew = 'SearchNew', - XSearch = 'XSearch', Alert = 'Alert', AlertMonochrome = 'AlertMonochrome', Edit = 'Edit', @@ -121,18 +108,9 @@ export enum IconNameEnum { Delegate3 = 'Delegate3', Delegate4 = 'Delegate4', Link = 'Link', - Shield = 'Shield', Success = 'Success', - Hummer = 'Hummer', - LbDappIcon = 'LbDappIcon', - LbTokenIcon = 'LbTokenIcon', - RefreshIcon = 'RefreshIcon', RetryIcon = 'RetryIcon', - ChartIcon = 'ChartIcon', - MinusIcon = 'MinusIcon', - PlusIcon = 'PlusIcon', PlusIconOrange = 'PlusIconOrange', - UkraineIcon = 'UkraineIcon', Update = 'Update', OwnBlocks = 'OwnBlocks', MissedOwnBlocks = 'MissedOwnBlocks', @@ -146,11 +124,8 @@ export enum IconNameEnum { BuyWithCrypto = 'BuyWithCrypto', CreditCard = 'CreditCard', Favourite = 'Favourite', - Github = 'Github', - Website = 'Website', NFTCollection = 'NFTCollection', NFT = 'NFT', - SwapRouteItemBackground = 'SwapRouteItemBackground', GoogleDrive = 'GoogleDrive', BlurEyeBlack = 'BlurEyeBlack', BlurEyeWhite = 'BlurEyeWhite', diff --git a/src/components/icon/icon-name.map.ts b/src/components/icon/icon-name.map.ts index d48451f97..a04c5df6f 100644 --- a/src/components/icon/icon-name.map.ts +++ b/src/components/icon/icon-name.map.ts @@ -4,11 +4,9 @@ import { SvgProps } from 'react-native-svg'; import ActionIcon from './assets/action.svg'; import AlertCircleIcon from './assets/alert-circle.svg'; import AlertMonochromeIcon from './assets/alert-monochrome.svg'; -import ShieldIcon from './assets/alert-shield.svg'; import AlertTriangleIcon from './assets/alert-triangle.svg'; import AlertIcon from './assets/alert.svg'; import ArrowDownIcon from './assets/arrow-down.svg'; -import ArrowLeftIcon from './assets/arrow-left.svg'; import ArrowRightIcon from './assets/arrow-right.svg'; import ArrowUpIcon from './assets/arrow-up.svg'; import AudioIcon from './assets/audio.svg'; @@ -17,12 +15,10 @@ import BlurDark from './assets/blur-dark.svg'; import BlurEyeBlack from './assets/blur-eye-black.svg'; import BlurEyeWhite from './assets/blur-eye-white.svg'; import BlurLight from './assets/blur-light.svg'; -import BookOpenIcon from './assets/book-open.svg'; import BrokenImage from './assets/broken-image.svg'; import BurnIcon from './assets/burn.svg'; import BuyWithCryptoIcon from './assets/buy-with-crypto.svg'; import BuyIcon from './assets/buy.svg'; -import ChartIcon from './assets/chart-icon.svg'; import CheckCircleIcon from './assets/check-circle.svg'; import CheckIcon from './assets/check.svg'; import CheckboxOffIcon from './assets/checkbox-off.svg'; @@ -61,7 +57,6 @@ import EarnIcon from './assets/earn.svg'; import EditNewIcon from './assets/edit-new.svg'; import EditIcon from './assets/edit.svg'; import EndorsementsIcon from './assets/endorsements.svg'; -import ExolixIcon from './assets/exolix.svg'; import ExternalLinkTagIcon from './assets/external-link-tag.svg'; import ExternalLinkIcon from './assets/external-link.svg'; import EyeClosedBoldIcon from './assets/eye-closed-bold.svg'; @@ -78,19 +73,15 @@ import GoogleDriveNativeIcon from './assets/google-drive-native.svg'; import GoogleDriveIcon from './assets/google-drive.svg'; import HelpCircleIcon from './assets/help-circle.svg'; import HourGlassesIcon from './assets/hourglasses.svg'; -import HummerIcon from './assets/hummer.svg'; import ImportSquareIcon from './assets/import-square.svg'; import InfoAltIcon from './assets/info-alt.svg'; import InfoFilledAltIcon from './assets/info-filled-alt.svg'; import InfoFilledIcon from './assets/info-gray.svg'; -import InfoIcon from './assets/info.svg'; import InputXCircleIcon from './assets/input-x-circle.svg'; import InvertedCheckboxOffIcon from './assets/inverted-checkbox-off.svg'; import InvertedCheckboxOnIcon from './assets/inverted-checkbox-on.svg'; import IosSearchIcon from './assets/ios-search.svg'; import KeyIcon from './assets/key.svg'; -import LbDappIcon from './assets/lb-dapp-icon.svg'; -import LbTokenIcon from './assets/lb-token-icon.svg'; import LinkIcon from './assets/link.svg'; import LiquidityBakingLogo from './assets/liquidity-baking-logo.svg'; import LockIcon from './assets/lock.svg'; @@ -98,7 +89,6 @@ import LogOutIcon from './assets/log-out.svg'; import ManualBackupIcon from './assets/manual-backup.svg'; import MarketIcon from './assets/market.svg'; import MessageCircleIcon from './assets/message-circle.svg'; -import MinusIcon from './assets/minus-icon.svg'; import MissedEndorsementsIcon from './assets/missed-endorsements.svg'; import MissedOwnBlocksIcon from './assets/missed-own-blocks.svg'; import MoonPayIcon from './assets/moonpay.svg'; @@ -112,21 +102,16 @@ import NotificationDotIcon from './assets/notification-dot.svg'; import OwnBlocksIcon from './assets/own-blocks.svg'; import OXtzIcon from './assets/oxtz.svg'; import PlentyIcon from './assets/plenty.svg'; -import PlusCircleIcon from './assets/plus-circle.svg'; import PlusIconOrange from './assets/plus-icon-orange.svg'; -import PlusIcon from './assets/plus-icon.svg'; import PlusSquareIcon from './assets/plus-square.svg'; import QrScannerBoldIcon from './assets/qr-scanner-bold.svg'; import QrScannerIcon from './assets/qr-scanner.svg'; import QsEarnSource from './assets/qs-earn-source.svg'; import QuipuSwapIcon from './assets/quipuswap.svg'; import QuipuSwapDarkIcon from './assets/quipuswapDark.svg'; -import RampIcon from './assets/ramp.svg'; -import RefreshIcon from './assets/refresh-icon.svg'; import RetryIcon from './assets/retry.svg'; import ScamInfoIcon from './assets/scam-info.svg'; import SearchNewIcon from './assets/search-new.svg'; -import SearchIcon from './assets/search.svg'; import SettingsIcon from './assets/settings.svg'; import ShareIcon from './assets/share.svg'; import ShoppingCardIcon from './assets/shopping-card.svg'; @@ -134,32 +119,23 @@ import SmileWithDollarIcon from './assets/smile-with-dollar.svg'; import SmileWithGlassesIcon from './assets/smile-with-glasses.svg'; import SmileIcon from './assets/smile.svg'; import DiscordIcon from './assets/socials/discord.svg'; -import GithubIcon from './assets/socials/github.svg'; import RedditIcon from './assets/socials/reddit.svg'; import TelegramIcon from './assets/socials/telegram.svg'; import TwitterIcon from './assets/socials/twitter.svg'; -import WebsiteIcon from './assets/socials/website.svg'; import YouTubeIcon from './assets/socials/you-tube.svg'; -import SoonBadgeIcon from './assets/soon-badge.svg'; import SpicyIcon from './assets/spicy.svg'; import StakeIcon from './assets/stake.svg'; import SuccessIcon from './assets/success.svg'; import SwapArrowIcon from './assets/swap-arrow.svg'; import SwapInfo from './assets/swap-info.svg'; -import SwapRouteItemBackgroundIcon from './assets/swap-route-item-background.svg'; -import SwapSettingsNewIcon from './assets/swap-settings-new.svg'; import SwapSettings from './assets/swap-settings.svg'; import SwapIcon from './assets/swap.svg'; import SyncIcon from './assets/sync.svg'; -import TagIcon from './assets/tag.svg'; import TempleLogoBottomIcon from './assets/temple-logo-bottom.svg'; import TempleLogoUpIcon from './assets/temple-logo-up.svg'; import TempleLogoWithTextIcon from './assets/temple-logo-with-text.svg'; import TempleLogoIcon from './assets/temple-logo.svg'; -import TerminalIcon from './assets/terminal.svg'; import TezWalletIcon from './assets/tez-wallet.svg'; -import EtherlinkTokenIcon from './assets/tokens/etherlink.svg'; -import FilmTokenIcon from './assets/tokens/film.svg'; import NoNameTokenIcon from './assets/tokens/no-name.svg'; import SwapTokenPlaceholderIcon from './assets/tokens/swap-token-placeholder.svg'; import TezShieldedTokenIcon from './assets/tokens/tez-shielded.svg'; @@ -168,14 +144,12 @@ import TzBtcTokenIcon from './assets/tokens/tzBtc.svg'; import TouchIdIcon from './assets/touch-id.svg'; import TrashIcon from './assets/trash.svg'; import TriangleDownIcon from './assets/triangle-down.svg'; -import UkraineIcon from './assets/ukraine.svg'; import UpdateIcon from './assets/update.svg'; import UtorgIcon from './assets/utorg.svg'; import VortexIcon from './assets/vortex.svg'; import WTezIcon from './assets/wtez.svg'; import XBoldIcon from './assets/x-bold.svg'; import XCircleIcon from './assets/x-circle.svg'; -import XSearchIcon from './assets/x-search.svg'; import XIcon from './assets/x.svg'; import YouvesEarnSourceDarkIcon from './assets/youves-earn-source-dark.svg'; import YouvesEarnSourceLargeIcon from './assets/youves-earn-source-large.svg'; @@ -189,7 +163,6 @@ export const iconNameMap: Record> = { [IconNameEnum.ArrowUp]: ArrowUpIcon, [IconNameEnum.ArrowDown]: ArrowDownIcon, [IconNameEnum.ArrowRight]: ArrowRightIcon, - [IconNameEnum.ArrowLeft]: ArrowLeftIcon, [IconNameEnum.Bell]: BellIcon, [IconNameEnum.Burn]: BurnIcon, [IconNameEnum.BrokenImage]: BrokenImage, @@ -203,8 +176,6 @@ export const iconNameMap: Record> = { [IconNameEnum.CycleStatusFuture]: CycleStatusFutureIcon, [IconNameEnum.CycleStatusInProgress]: CycleStatusInProgressIcon, [IconNameEnum.CycleStatusUnlocked]: CycleStatusUnlockedIcon, - [IconNameEnum.BookOpen]: BookOpenIcon, - [IconNameEnum.Terminal]: TerminalIcon, [IconNameEnum.Download]: DownloadIcon, [IconNameEnum.Diez]: DiezIcon, [IconNameEnum.FaceId]: FaceIdIcon, @@ -217,14 +188,12 @@ export const iconNameMap: Record> = { [IconNameEnum.InvertedCheckboxOff]: InvertedCheckboxOffIcon, [IconNameEnum.InvertedCheckboxOn]: InvertedCheckboxOnIcon, [IconNameEnum.PlusSquare]: PlusSquareIcon, - [IconNameEnum.PlusCircle]: PlusCircleIcon, [IconNameEnum.HelpCircle]: HelpCircleIcon, [IconNameEnum.ShoppingCard]: ShoppingCardIcon, [IconNameEnum.SwapArrow]: SwapArrowIcon, [IconNameEnum.SwapInfo]: SwapInfo, [IconNameEnum.Swap]: SwapIcon, [IconNameEnum.SwapSettings]: SwapSettings, - [IconNameEnum.SwapSettingsNew]: SwapSettingsNewIcon, [IconNameEnum.InputXCircle]: InputXCircleIcon, [IconNameEnum.X]: XIcon, [IconNameEnum.XBold]: XBoldIcon, @@ -243,24 +212,17 @@ export const iconNameMap: Record> = { [IconNameEnum.QuipuSwap]: QuipuSwapIcon, [IconNameEnum.QuipuSwapDark]: QuipuSwapDarkIcon, [IconNameEnum.DApps]: DAppsIcon, - [IconNameEnum.SoonBadge]: SoonBadgeIcon, [IconNameEnum.Close]: CloseIcon, [IconNameEnum.TezToken]: TezTokenIcon, [IconNameEnum.TezShieldedToken]: TezShieldedTokenIcon, - [IconNameEnum.EtherlinkToken]: EtherlinkTokenIcon, - [IconNameEnum.FilmToken]: FilmTokenIcon, [IconNameEnum.TzBtcToken]: TzBtcTokenIcon, [IconNameEnum.InfoFilled]: InfoFilledIcon, [IconNameEnum.InfoFilledAlt]: InfoFilledAltIcon, - [IconNameEnum.Github]: GithubIcon, - [IconNameEnum.Website]: WebsiteIcon, [IconNameEnum.NFTCollection]: NFTCollectionIcon, [IconNameEnum.GoogleDrive]: GoogleDriveIcon, /** topup icons **/ - [IconNameEnum.Exolix]: ExolixIcon, [IconNameEnum.MoonPay]: MoonPayIcon, [IconNameEnum.Utorg]: UtorgIcon, - [IconNameEnum.Ramp]: RampIcon, [IconNameEnum.BlurEyeBlack]: BlurEyeBlack, [IconNameEnum.BlurEyeWhite]: BlurEyeWhite, /** deprecated icons **/ @@ -269,7 +231,6 @@ export const iconNameMap: Record> = { [IconNameEnum.Share]: ShareIcon, [IconNameEnum.Copy]: CopyIcon, [IconNameEnum.CopyBold]: CopyBoldIcon, - [IconNameEnum.Tag]: TagIcon, [IconNameEnum.QrScanner]: QrScannerIcon, [IconNameEnum.QrScannerBold]: QrScannerBoldIcon, [IconNameEnum.TriangleDown]: TriangleDownIcon, @@ -283,7 +244,6 @@ export const iconNameMap: Record> = { [IconNameEnum.AlertCircle]: AlertCircleIcon, [IconNameEnum.AlertTriangle]: AlertTriangleIcon, [IconNameEnum.Clock]: ClockIcon, - [IconNameEnum.Info]: InfoIcon, [IconNameEnum.InfoAlt]: InfoAltIcon, [IconNameEnum.ChevronRight]: ChevronRightIcon, [IconNameEnum.ChevronUp]: ChevronUpIcon, @@ -301,9 +261,7 @@ export const iconNameMap: Record> = { [IconNameEnum.ExternalLink]: ExternalLinkIcon, [IconNameEnum.ExternalLinkTag]: ExternalLinkTagIcon, [IconNameEnum.IosSearch]: IosSearchIcon, - [IconNameEnum.Search]: SearchIcon, [IconNameEnum.SearchNew]: SearchNewIcon, - [IconNameEnum.XSearch]: XSearchIcon, [IconNameEnum.Alert]: AlertIcon, [IconNameEnum.AlertMonochrome]: AlertMonochromeIcon, [IconNameEnum.Edit]: EditIcon, @@ -319,18 +277,9 @@ export const iconNameMap: Record> = { [IconNameEnum.Delegate4]: Delegate4Icon, [IconNameEnum.Gear]: GearIcon, [IconNameEnum.Link]: LinkIcon, - [IconNameEnum.Shield]: ShieldIcon, [IconNameEnum.Success]: SuccessIcon, - [IconNameEnum.Hummer]: HummerIcon, - [IconNameEnum.LbDappIcon]: LbDappIcon, - [IconNameEnum.LbTokenIcon]: LbTokenIcon, - [IconNameEnum.RefreshIcon]: RefreshIcon, [IconNameEnum.RetryIcon]: RetryIcon, - [IconNameEnum.ChartIcon]: ChartIcon, - [IconNameEnum.MinusIcon]: MinusIcon, - [IconNameEnum.PlusIcon]: PlusIcon, [IconNameEnum.PlusIconOrange]: PlusIconOrange, - [IconNameEnum.UkraineIcon]: UkraineIcon, [IconNameEnum.Market]: MarketIcon, [IconNameEnum.Earn]: EarnIcon, [IconNameEnum.EarnDapp]: EarnDappIcon, @@ -339,7 +288,6 @@ export const iconNameMap: Record> = { [IconNameEnum.CreditCard]: CreditCardIcon, [IconNameEnum.Favourite]: FavoriteIcon, [IconNameEnum.Update]: UpdateIcon, - [IconNameEnum.SwapRouteItemBackground]: SwapRouteItemBackgroundIcon, [IconNameEnum.NFT]: NFT, [IconNameEnum.BlurLight]: BlurLight, [IconNameEnum.BlurDark]: BlurDark, diff --git a/src/components/icon/icon.tsx b/src/components/icon/icon.tsx index 3d3ec3f4b..f0196884f 100644 --- a/src/components/icon/icon.tsx +++ b/src/components/icon/icon.tsx @@ -19,6 +19,7 @@ export interface IconProps extends TestIdProps, SvgProps { style?: StyleProp; } +/** @deprecated Extend and use IconV2 or CryptoLogo */ export const Icon: FC = ({ name, size = formatSize(16), diff --git a/src/components/touchable-icon-v2/index.tsx b/src/components/touchable-icon-v2/index.tsx new file mode 100644 index 000000000..31e200371 --- /dev/null +++ b/src/components/touchable-icon-v2/index.tsx @@ -0,0 +1,43 @@ +import { FC } from 'react'; + +import { isAndroid } from 'src/config/system'; +import { formatSize } from 'src/styles/format-size'; +import { generateHitSlop } from 'src/styles/generate-hit-slop'; + +import { IconV2, IconV2Props } from '../icon-v2'; +import { SafeTouchableOpacity } from '../safe-touchable-opacity'; +import { TouchableWithAnalytics } from '../touchable-with-analytics'; + +import { TouchableIconStyles } from './styles'; + +interface Props extends Omit { + size?: number; + iconSize?: IconV2Props['size']; + disabled?: boolean; + onPress: EmptyFn; +} + +export const TouchableIconV2: FC = ({ + size = formatSize(28), + iconSize = 12, + style, + disabled, + testID, + testIDProperties, + onPress, + name, + color +}) => ( + + + +); diff --git a/src/components/touchable-icon-v2/styles.ts b/src/components/touchable-icon-v2/styles.ts new file mode 100644 index 000000000..17e9058a7 --- /dev/null +++ b/src/components/touchable-icon-v2/styles.ts @@ -0,0 +1,8 @@ +import { StyleSheet } from 'react-native'; + +export const TouchableIconStyles = StyleSheet.create({ + container: { + justifyContent: 'center', + alignItems: 'center' + } +}); diff --git a/src/layouts/reveal-seed-phrase/index.tsx b/src/layouts/reveal-seed-phrase/index.tsx index 61b5259ca..208d66c30 100644 --- a/src/layouts/reveal-seed-phrase/index.tsx +++ b/src/layouts/reveal-seed-phrase/index.tsx @@ -10,7 +10,7 @@ import { HeaderButton } from 'src/components/header/header-button/header-button' import { HeaderProgress } from 'src/components/header/header-progress/header-progress'; import { HeaderTitle } from 'src/components/header/header-title/header-title'; import { useNavigationSetOptions } from 'src/components/header/use-navigation-set-options.hook'; -import { IconNameEnum } from 'src/components/icon/icon-name.enum'; +import { IconNameV2Enum } from 'src/components/icon-v2/icon-name.enum'; import { InsetSubstitute } from 'src/components/inset-substitute/inset-substitute'; import { Label } from 'src/components/label/label'; import { NewSeedPhraseAttention } from 'src/components/new-seed-phrase-attention/new-seed-phrase-attention'; @@ -52,7 +52,7 @@ export const RevealSeedPhrase: FC = ({ useNavigationSetOptions( { - headerLeft: () => , + headerLeft: () => , headerRight: () => , headerTitle: () => }, diff --git a/src/modals/receive-modal/address-card/index.tsx b/src/modals/receive-modal/address-card/index.tsx new file mode 100644 index 000000000..e89b34faf --- /dev/null +++ b/src/modals/receive-modal/address-card/index.tsx @@ -0,0 +1,74 @@ +import { useCallback } from 'react'; +import { Text, View } from 'react-native'; + +import { useBottomSheetController } from 'src/components/bottom-sheet/use-bottom-sheet-controller'; +import { IconV2 } from 'src/components/icon-v2'; +import { IconNameV2Enum } from 'src/components/icon-v2/icon-name.enum'; +import { SafeTouchableOpacity } from 'src/components/safe-touchable-opacity'; +import { useColors } from 'src/styles/use-colors'; +import { AnalyticsEventCategory } from 'src/utils/analytics/analytics-event.enum'; +import { useAnalytics } from 'src/utils/analytics/use-analytics.hook'; +import { copyStringToClipboard } from 'src/utils/clipboard.utils'; + +import { NetworkIcon } from '../network-icon'; +import { QrBottomSheet } from '../qr-bottom-sheet'; +import { ReceiveModalSelectors } from '../receive-modal.selectors'; +import { AddressCardProps } from '../types'; + +import { useAddressCardStyles } from './styles'; + +export const AddressCard = ({ title, address, cryptoLogoName, showWarningOnCard, warningText }: AddressCardProps) => { + const bottomSheetController = useBottomSheetController(); + const colors = useColors(); + const { trackEvent } = useAnalytics(); + const styles = useAddressCardStyles(); + + const handleCopyClick = useCallback(() => { + copyStringToClipboard(address); + trackEvent(ReceiveModalSelectors.publicAddressCopyButton, AnalyticsEventCategory.ButtonPress, { type: title }); + }, [address, trackEvent, title]); + + const handleQrButtonClick = useCallback(() => { + trackEvent(ReceiveModalSelectors.qrCodeButton, AnalyticsEventCategory.ButtonPress, { type: title }); + bottomSheetController.open(); + }, [bottomSheetController, trackEvent, title]); + + return ( + <> + + + + + {title} + + + + {address} + + + + + + + + + + + {showWarningOnCard && ( + + + {warningText} + + )} + + + + + ); +}; diff --git a/src/modals/receive-modal/address-card/styles.ts b/src/modals/receive-modal/address-card/styles.ts new file mode 100644 index 000000000..512298b9b --- /dev/null +++ b/src/modals/receive-modal/address-card/styles.ts @@ -0,0 +1,58 @@ +import { black } from 'src/config/styles'; +import { createUseStylesMemoized } from 'src/styles/create-use-styles'; +import { formatSize } from 'src/styles/format-size'; +import { generateShadow } from 'src/styles/generate-shadow'; + +export const useAddressCardStyles = createUseStylesMemoized(({ colors, typography }) => ({ + root: { + ...generateShadow(1, black), + backgroundColor: colors.cardBG, + padding: formatSize(16), + borderRadius: formatSize(10), + gap: formatSize(8) + }, + header: { + flexDirection: 'row', + alignItems: 'center', + gap: formatSize(4) + }, + headerTitle: { + ...typography.caption13Semibold, + color: colors.black + }, + addressRow: { + flexDirection: 'row', + alignItems: 'flex-start', + gap: formatSize(8) + }, + address: { + ...typography.caption13Regular, + lineHeight: formatSize(18), + color: colors.gray1, + marginRight: formatSize(16), + flex: 1 + }, + actionButton: { + flex: 0, + backgroundColor: colors.blue10, + borderRadius: formatSize(8), + padding: formatSize(10) + }, + actionIcon: { + color: colors.blue + }, + warningContainer: { + backgroundColor: colors.peach10, + borderRadius: formatSize(8), + padding: formatSize(8), + paddingBottom: formatSize(10), + flexDirection: 'row', + gap: formatSize(8), + alignItems: 'flex-end' + }, + warningText: { + ...typography.caption13Regular, + lineHeight: formatSize(18), + color: colors.black + } +})); diff --git a/src/modals/receive-modal/network-icon/index.tsx b/src/modals/receive-modal/network-icon/index.tsx new file mode 100644 index 000000000..cac756fa4 --- /dev/null +++ b/src/modals/receive-modal/network-icon/index.tsx @@ -0,0 +1,21 @@ +import { View } from 'react-native'; + +import { CryptoLogo } from 'src/components/crypto-logo'; +import { CryptoLogoNameEnum } from 'src/components/crypto-logo/logo-name.enum'; +import { formatSize } from 'src/styles/format-size'; + +import { useNetworkIconStyles } from './styles'; + +interface NetworkIconProps { + iconName: CryptoLogoNameEnum; +} + +export const NetworkIcon = ({ iconName }: NetworkIconProps) => { + const styles = useNetworkIconStyles(); + + return ( + + + + ); +}; diff --git a/src/modals/receive-modal/network-icon/styles.ts b/src/modals/receive-modal/network-icon/styles.ts new file mode 100644 index 000000000..f24ad7948 --- /dev/null +++ b/src/modals/receive-modal/network-icon/styles.ts @@ -0,0 +1,14 @@ +import { createUseStylesMemoized } from 'src/styles/create-use-styles'; +import { formatSize } from 'src/styles/format-size'; + +export const useNetworkIconStyles = createUseStylesMemoized(({ colors }) => ({ + root: { + borderRadius: formatSize(18), + borderColor: colors.gray4, + borderWidth: formatSize(1), + justifyContent: 'center', + alignItems: 'center', + width: formatSize(36), + height: formatSize(36) + } +})); diff --git a/src/modals/receive-modal/qr-bottom-sheet/index.tsx b/src/modals/receive-modal/qr-bottom-sheet/index.tsx new file mode 100644 index 000000000..df68b9c62 --- /dev/null +++ b/src/modals/receive-modal/qr-bottom-sheet/index.tsx @@ -0,0 +1,44 @@ +import { FC } from 'react'; +import { Text, View } from 'react-native'; +import QRCode from 'react-native-qrcode-svg'; + +import { BottomSheet } from 'src/components/bottom-sheet/bottom-sheet'; +import { BottomSheetController } from 'src/components/bottom-sheet/use-bottom-sheet-controller'; +import { black, white } from 'src/config/styles'; +import { formatSize } from 'src/styles/format-size'; + +import { NetworkIcon } from '../network-icon'; +import { AddressCardProps } from '../types'; + +import { useQrBottomSheetStyles } from './styles'; + +interface QrBottomSheetProps extends Omit { + controller: BottomSheetController; +} + +export const QrBottomSheet: FC = ({ controller, title, address, cryptoLogoName, warningText }) => { + const styles = useQrBottomSheetStyles(); + + return ( + + + + + + + + + + + {warningText} + + + ); +}; diff --git a/src/modals/receive-modal/qr-bottom-sheet/styles.ts b/src/modals/receive-modal/qr-bottom-sheet/styles.ts new file mode 100644 index 000000000..76c76d329 --- /dev/null +++ b/src/modals/receive-modal/qr-bottom-sheet/styles.ts @@ -0,0 +1,36 @@ +import { black, white } from 'src/config/styles'; +import { createUseStylesMemoized } from 'src/styles/create-use-styles'; +import { formatSize } from 'src/styles/format-size'; +import { generateShadow } from 'src/styles/generate-shadow'; + +export const useQrBottomSheetStyles = createUseStylesMemoized(({ colors, typography }) => ({ + root: { + height: '100%', + marginBottom: formatSize(32), + marginHorizontal: formatSize(8), + backgroundColor: colors.cardBG, + borderRadius: formatSize(12), + overflow: 'hidden' + }, + text: { + ...typography.caption13Regular, + color: colors.gray1 + }, + contentContainer: { + paddingHorizontal: formatSize(12), + paddingVertical: formatSize(24), + gap: formatSize(8), + alignItems: 'center' + }, + qrCodeRow: { + marginBottom: formatSize(8), + flexDirection: 'row', + justifyContent: 'center' + }, + qrCodeContainer: { + ...generateShadow(1, black), + backgroundColor: white, + borderRadius: formatSize(8), + padding: formatSize(20) + } +})); diff --git a/src/modals/receive-modal/receive-modal.selectors.ts b/src/modals/receive-modal/receive-modal.selectors.ts index ea1afc04b..79f228f1f 100644 --- a/src/modals/receive-modal/receive-modal.selectors.ts +++ b/src/modals/receive-modal/receive-modal.selectors.ts @@ -1,5 +1,4 @@ export enum ReceiveModalSelectors { publicAddressCopyButton = 'Receive/Public Address Copy Button', - domainCopyButton = 'Receive/Domain Copy Button', - copyButton = 'Receive/Copy Button' + qrCodeButton = 'Receive/QR Code Button' } diff --git a/src/modals/receive-modal/receive-modal.styles.ts b/src/modals/receive-modal/receive-modal.styles.ts index 075f4e971..e83471137 100644 --- a/src/modals/receive-modal/receive-modal.styles.ts +++ b/src/modals/receive-modal/receive-modal.styles.ts @@ -1,105 +1,13 @@ import { createUseStyles } from 'src/styles/create-use-styles'; import { formatSize } from 'src/styles/format-size'; -export const useReceiveModalStyles = createUseStyles(({ colors, typography }) => ({ - rootContainer: { - paddingVertical: formatSize(16), - paddingHorizontal: formatSize(0) - }, - shieldedContentContainer: { +export const useReceiveModalStyles = createUseStyles(() => ({ + cardsListContainer: { + paddingTop: formatSize(16), paddingHorizontal: 0 }, - page: { - alignItems: 'center' - }, - pagerContainer: { - flexGrow: 0 - }, - tokenContainer: { - flexDirection: 'row', - marginBottom: formatSize(26), - gap: formatSize(4) - }, - iconContainer: { - width: formatSize(22), - height: formatSize(22), - marginLeft: formatSize(8), - paddingHorizontal: formatSize(4), - paddingVertical: formatSize(2), - backgroundColor: colors.blue10, - borderRadius: formatSize(4) - }, - pkhWrapper: { - flexDirection: 'row', - alignItems: 'center' - }, - tokenInfoContainer: { - justifyContent: 'center' - }, - tokenSymbol: { - ...typography.numbersRegular15, - color: colors.black - }, - tokenName: { - ...typography.numbersRegular11, - color: colors.gray1 - }, - addressTitle: { - ...typography.body15Semibold, - color: colors.black - }, - card: { - width: '100%', - alignItems: 'center', - backgroundColor: colors.cardBG, - borderRadius: formatSize(16), - paddingVertical: formatSize(16), - paddingHorizontal: formatSize(12) - }, - publicKeyHashContainer: { - alignSelf: 'stretch', - padding: formatSize(12), - backgroundColor: colors.blue10, - borderRadius: formatSize(8) - }, - publicKeyHash: { - ...typography.body17Regular, - color: colors.blue - }, - dotsContainer: { - flexDirection: 'row', - justifyContent: 'center', - alignItems: 'center', - marginVertical: formatSize(16) - }, - dot: { - width: formatSize(8), - height: formatSize(8), - borderRadius: formatSize(4) - }, - dotActive: { - backgroundColor: colors.orange - }, - dotInactive: { - backgroundColor: colors.gray3 - }, - warningContainer: { - alignSelf: 'stretch', - flexDirection: 'row', - alignItems: 'center', - backgroundColor: colors.peach10, - borderRadius: formatSize(8), + cardsList: { paddingHorizontal: formatSize(16), - paddingVertical: formatSize(12), - gap: formatSize(8) - }, - warningIcon: { - fontSize: formatSize(18), - color: colors.orange - }, - warningText: { - ...typography.caption13Regular, - color: colors.black, - flex: 1 + gap: formatSize(24) } })); diff --git a/src/modals/receive-modal/receive-modal.tsx b/src/modals/receive-modal/receive-modal.tsx index 1bb5d2468..c65bda638 100644 --- a/src/modals/receive-modal/receive-modal.tsx +++ b/src/modals/receive-modal/receive-modal.tsx @@ -1,244 +1,77 @@ -import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import { NativeScrollEvent, NativeSyntheticEvent, ScrollView, Text, useWindowDimensions, View } from 'react-native'; -import QRCode from 'react-native-qrcode-svg'; -import { useDispatch } from 'react-redux'; +import React, { useMemo } from 'react'; +import { View } from 'react-native'; -import { ButtonLargePrimary } from 'src/components/button/button-large/button-large-primary/button-large-primary'; -import { ButtonsFloatingContainer } from 'src/components/button/buttons-floating-container/buttons-floating-container'; -import { Divider } from 'src/components/divider/divider'; -import { IconNameEnum } from 'src/components/icon/icon-name.enum'; -import { TouchableIcon } from 'src/components/icon/touchable-icon/touchable-icon'; -import { InsetSubstitute } from 'src/components/inset-substitute/inset-substitute'; -import { ModalStatusBar } from 'src/components/modal-status-bar/modal-status-bar'; -import { SafeTouchableOpacity } from 'src/components/safe-touchable-opacity'; +import { CryptoLogoNameEnum } from 'src/components/crypto-logo/logo-name.enum'; import { ScreenContainer } from 'src/components/screen-container/screen-container'; -import { TokenIcon } from 'src/components/token-icon/token-icon'; -import { useDomainName } from 'src/hooks/use-domain-name.hook'; import { ModalsEnum } from 'src/navigator/enums/modals.enum'; -import { useModalParams } from 'src/navigator/hooks/use-navigation.hook'; import { useSaplingAddressSelector } from 'src/store/sapling'; -import { toggleDomainAddressShown } from 'src/store/settings/settings-actions'; -import { useIsShownDomainNameSelector } from 'src/store/settings/settings-selectors'; import { useAccount } from 'src/store/wallet/wallet-selectors'; -import { formatSize } from 'src/styles/format-size'; -import { useColors } from 'src/styles/use-colors'; import { getAccountAddressForEvm, getAccountAddressForTezos } from 'src/utils/account.utils'; -import { AnalyticsEventCategory } from 'src/utils/analytics/analytics-event.enum'; -import { useAnalytics, usePageAnalytic } from 'src/utils/analytics/use-analytics.hook'; -import { copyStringToClipboard } from 'src/utils/clipboard.utils'; +import { usePageAnalytic } from 'src/utils/analytics/use-analytics.hook'; import { isString } from 'src/utils/is-string'; -import { ReceiveModalSelectors } from './receive-modal.selectors'; +import { AddressCard } from './address-card'; import { useReceiveModalStyles } from './receive-modal.styles'; - -interface ReceivePage { - address: string; - symbol: string; - name: string; - iconName?: IconNameEnum; - thumbnailUri?: string; - copyTestID: ReceiveModalSelectors; - showDomainToggle?: boolean; - warningText?: string; -} +import { AddressCardProps } from './types'; + +const makeTezosComponentsProps = (tezosAddress: string) => ({ + title: 'Tezos', + address: tezosAddress, + cryptoLogoName: CryptoLogoNameEnum.Tezos, + warningText: 'Send only Tezos tokens to this address' +}); + +const makeEtherlinkComponentsProps = (evmAddress: string) => ({ + title: 'Etherlink', + address: evmAddress, + cryptoLogoName: CryptoLogoNameEnum.Etherlink, + warningText: 'Send only Etherlink tokens to this address' +}); + +const makeTezosSaplingComponentsProps = (saplingAddress: string) => ({ + title: 'Shielded Tezos', + address: saplingAddress, + cryptoLogoName: CryptoLogoNameEnum.ShieldedTezos, + warningText: 'Send only TEZ tokens to this address', + showWarningOnCard: true +}); + +const cardKeyExtractor = ({ address, title }: AddressCardProps) => `${title}-${address}`; export const ReceiveModal = () => { - const colors = useColors(); - const styles = useReceiveModalStyles(); - const { width: screenWidth } = useWindowDimensions(); const selectedAccount = useAccount(); const tezosAddress = getAccountAddressForTezos(selectedAccount); const evmAddress = getAccountAddressForEvm(selectedAccount); - const { token } = useModalParams(); - - const dispatch = useDispatch(); - const { trackEvent } = useAnalytics(); - const isShownDomainName = useIsShownDomainNameSelector(); - const domainName = useDomainName(tezosAddress ?? ''); - + const styles = useReceiveModalStyles(); const saplingAddress = useSaplingAddressSelector(); - const [activePageIndex, setActivePageIndex] = useState(0); - - const pages = useMemo(() => { - const receivePages: ReceivePage[] = []; + const cardsContentProps = useMemo(() => { + const componentsProps: AddressCardProps[] = []; if (isString(tezosAddress)) { - receivePages.push({ - address: tezosAddress, - symbol: token.symbol, - name: token.name, - iconName: token.iconName, - thumbnailUri: token.thumbnailUri, - copyTestID: ReceiveModalSelectors.publicAddressCopyButton, - showDomainToggle: true - }); + componentsProps.push(makeTezosComponentsProps(tezosAddress)); } if (isString(tezosAddress) && isString(saplingAddress)) { - receivePages.push({ - address: saplingAddress, - symbol: 'TEZ', - name: 'Shielded', - iconName: IconNameEnum.TezShieldedToken, - copyTestID: ReceiveModalSelectors.copyButton, - warningText: 'Send only TEZ tokens to this address' - }); + componentsProps.push(makeTezosSaplingComponentsProps(saplingAddress)); } if (isString(evmAddress)) { - receivePages.push({ - address: evmAddress, - symbol: 'TEZ', - name: 'Etherlink', - iconName: IconNameEnum.EtherlinkToken, - copyTestID: ReceiveModalSelectors.publicAddressCopyButton - }); - } - - return receivePages; - }, [evmAddress, saplingAddress, tezosAddress, token.iconName, token.name, token.symbol, token.thumbnailUri]); - - const handleScroll = useCallback( - (event: NativeSyntheticEvent) => { - const offsetX = event.nativeEvent.contentOffset.x; - const page = Math.round(offsetX / screenWidth); - setActivePageIndex(page); - }, - [screenWidth] - ); - - useEffect(() => { - if (activePageIndex >= pages.length) { - setActivePageIndex(Math.max(pages.length - 1, 0)); + componentsProps.push(makeEtherlinkComponentsProps(evmAddress)); } - }, [activePageIndex, pages.length]); - - const activePage = pages[activePageIndex] ?? pages[0]; - const currentAddress = activePage?.address ?? ''; - - const testID = useMemo( - () => - activePage?.showDomainToggle && isShownDomainName && isString(domainName) - ? ReceiveModalSelectors.domainCopyButton - : activePage?.copyTestID ?? ReceiveModalSelectors.publicAddressCopyButton, - [activePage, isShownDomainName, domainName] - ); - const handleCopyButtonPress = () => { - copyStringToClipboard(currentAddress); - trackEvent(testID, AnalyticsEventCategory.ButtonPress); - }; + return componentsProps; + }, [evmAddress, saplingAddress, tezosAddress]); usePageAnalytic(ModalsEnum.Receive); - const pageContentWidth = screenWidth - formatSize(32); - - const renderPage = (page: ReceivePage) => ( - - - - - - {page.symbol} - {page.name} - - - - - - - Address - {page.showDomainToggle && isString(domainName) ? ( - dispatch(toggleDomainAddressShown())} - /> - ) : null} - - - - - {page.showDomainToggle && isShownDomainName && isString(domainName) ? ( - {domainName} - ) : ( - {page.address} - )} - - - {page.warningText ? ( - <> - - - - - {page.warningText} - - - ) : null} - - - ); - - if (pages.length < 2) { - return ( - <> - - - {activePage ? renderPage(activePage) : null} - - - - - - - - ); - } - return ( - <> - - - - - {pages.map(page => ( - {renderPage(page)} - ))} - - - - {pages.map((page, index) => ( - - {index > 0 ? : null} - - - ))} - - - - - - - - + + + {cardsContentProps.map(props => ( + + ))} + + ); }; diff --git a/src/modals/receive-modal/types.ts b/src/modals/receive-modal/types.ts new file mode 100644 index 000000000..8c478b96b --- /dev/null +++ b/src/modals/receive-modal/types.ts @@ -0,0 +1,9 @@ +import { CryptoLogoNameEnum } from 'src/components/crypto-logo/logo-name.enum'; + +export interface AddressCardProps { + title: string; + address: string; + cryptoLogoName: CryptoLogoNameEnum; + warningText: string; + showWarningOnCard?: boolean; +} diff --git a/src/screens/contacts/contacts.tsx b/src/screens/contacts/contacts.tsx index 051d1baf0..e7d5cac28 100644 --- a/src/screens/contacts/contacts.tsx +++ b/src/screens/contacts/contacts.tsx @@ -6,7 +6,7 @@ import { generateScreenOptions } from 'src/components/header/generate-screen-opt import { HeaderButton } from 'src/components/header/header-button/header-button'; import { HeaderTitle } from 'src/components/header/header-title/header-title'; import { useNavigationSetOptions } from 'src/components/header/use-navigation-set-options.hook'; -import { IconNameEnum } from 'src/components/icon/icon-name.enum'; +import { IconNameV2Enum } from 'src/components/icon-v2/icon-name.enum'; import { Contact } from 'src/interfaces/contact.interface'; import { ModalsEnum } from 'src/navigator/enums/modals.enum'; import { useNavigateToModal } from 'src/navigator/hooks/use-navigation.hook'; @@ -25,7 +25,7 @@ export const Contacts = memo(() => { generateScreenOptions( , navigateToModal(ModalsEnum.AddContact)} testID={ContactsSelectors.addContactButton} /> diff --git a/src/screens/manage-accounts/manage-accounts.tsx b/src/screens/manage-accounts/manage-accounts.tsx index b9f98f26c..1355264af 100644 --- a/src/screens/manage-accounts/manage-accounts.tsx +++ b/src/screens/manage-accounts/manage-accounts.tsx @@ -9,7 +9,7 @@ import { generateScreenOptions } from 'src/components/header/generate-screen-opt import { HeaderButton } from 'src/components/header/header-button/header-button'; import { HeaderTitle } from 'src/components/header/header-title/header-title'; import { useNavigationSetOptions } from 'src/components/header/use-navigation-set-options.hook'; -import { IconNameEnum } from 'src/components/icon/icon-name.enum'; +import { IconNameV2Enum } from 'src/components/icon-v2/icon-name.enum'; import { TextSegmentControl } from 'src/components/segmented-control/text-segment-control/text-segment-control'; import { useCallbackIfOnline } from 'src/hooks/use-callback-if-online'; import { ModalsEnum } from 'src/navigator/enums/modals.enum'; @@ -43,7 +43,7 @@ export const ManageAccounts = () => { generateScreenOptions( , revealSelectBottomSheetController.open()} testID={ManageAccountsSelectors.addAccountButton} /> diff --git a/src/screens/manage-assets/manage-assets.tsx b/src/screens/manage-assets/manage-assets.tsx index a1fe49133..a788142b7 100644 --- a/src/screens/manage-assets/manage-assets.tsx +++ b/src/screens/manage-assets/manage-assets.tsx @@ -6,7 +6,7 @@ import { generateScreenOptions } from 'src/components/header/generate-screen-opt import { HeaderButton } from 'src/components/header/header-button/header-button'; import { HeaderTitle } from 'src/components/header/header-title/header-title'; import { useNavigationSetOptions } from 'src/components/header/use-navigation-set-options.hook'; -import { IconNameEnum } from 'src/components/icon/icon-name.enum'; +import { IconNameV2Enum } from 'src/components/icon-v2/icon-name.enum'; import { TextSegmentControl } from 'src/components/segmented-control/text-segment-control/text-segment-control'; import { ModalsEnum } from 'src/navigator/enums/modals.enum'; import { ScreensEnum } from 'src/navigator/enums/screens.enum'; @@ -32,7 +32,7 @@ export const ManageAssets = () => { useNavigationSetOptions( generateScreenOptions( , - navigateToModal(ModalsEnum.AddAsset)} /> + navigateToModal(ModalsEnum.AddAsset)} /> ), [] ); diff --git a/src/screens/manual-backup/verify-seed-phrase/verify-seed-phrase.tsx b/src/screens/manual-backup/verify-seed-phrase/verify-seed-phrase.tsx index 577c42917..54ef111de 100644 --- a/src/screens/manual-backup/verify-seed-phrase/verify-seed-phrase.tsx +++ b/src/screens/manual-backup/verify-seed-phrase/verify-seed-phrase.tsx @@ -11,7 +11,7 @@ import { HeaderButton } from 'src/components/header/header-button/header-button' import { HeaderProgress } from 'src/components/header/header-progress/header-progress'; import { HeaderTitle } from 'src/components/header/header-title/header-title'; import { useNavigationSetOptions } from 'src/components/header/use-navigation-set-options.hook'; -import { IconNameEnum } from 'src/components/icon/icon-name.enum'; +import { IconNameV2Enum } from 'src/components/icon-v2/icon-name.enum'; import { InsetSubstitute } from 'src/components/inset-substitute/inset-substitute'; import { ScreenContainer } from 'src/components/screen-container/screen-container'; import { LIMIT_FIN_FEATURES } from 'src/config/system'; @@ -44,7 +44,7 @@ export const VerifySeedPhrase: FC = ({ onGoBackPress }) => { useNavigationSetOptions( { - headerLeft: () => , + headerLeft: () => , headerRight: () => , headerTitle: () => }, diff --git a/src/screens/networks/all-networks-options/index.tsx b/src/screens/networks/all-networks-options/index.tsx index 78d7877bd..138332b33 100644 --- a/src/screens/networks/all-networks-options/index.tsx +++ b/src/screens/networks/all-networks-options/index.tsx @@ -1,8 +1,10 @@ import { memo, useCallback } from 'react'; import { StyleProp, Text, View, ViewStyle } from 'react-native'; -import { Icon } from 'src/components/icon/icon'; -import { IconNameEnum } from 'src/components/icon/icon-name.enum'; +import { CryptoLogo } from 'src/components/crypto-logo'; +import { CryptoLogoNameEnum } from 'src/components/crypto-logo/logo-name.enum'; +import { IconV2 } from 'src/components/icon-v2'; +import { IconNameV2Enum } from 'src/components/icon-v2/icon-name.enum'; import { TouchableWithAnalytics } from 'src/components/touchable-with-analytics'; import { TempleChainKind } from 'src/enums/temple-chain-kind.enum'; import { useEvmChains } from 'src/hooks/use-evm-chains.hook'; @@ -57,9 +59,9 @@ const AllNetworksOptionHOC = ( testID={NetworksSelectors.networkOption} testIDProperties={{ network: chainId }} > - + {name} - + ); }); @@ -68,10 +70,10 @@ const AllNetworksOptionHOC = ( }; const TezosNetworkOption = AllNetworksOptionHOC(({ size, style }) => ( - + )); // TODO: Add icons for other EVM chains const EvmNetworkOption = AllNetworksOptionHOC(({ size, style }) => ( - + )); diff --git a/src/screens/tezos-token-screen/tezos-token-screen.tsx b/src/screens/tezos-token-screen/tezos-token-screen.tsx index fbf4ad7b5..b95989661 100644 --- a/src/screens/tezos-token-screen/tezos-token-screen.tsx +++ b/src/screens/tezos-token-screen/tezos-token-screen.tsx @@ -14,6 +14,7 @@ import { HeaderCardActionButtons } from 'src/components/header-card-action-butto import { HideBalance } from 'src/components/hide-balance/hide-balance'; import { Icon } from 'src/components/icon/icon'; import { IconNameEnum } from 'src/components/icon/icon-name.enum'; +import { IconNameV2Enum } from 'src/components/icon-v2/icon-name.enum'; import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; import { TextSegmentControl } from 'src/components/segmented-control/text-segment-control/text-segment-control'; import { TokenDropdownItem } from 'src/components/token-dropdown/token-dropdown-item/token-dropdown-item'; @@ -151,7 +152,7 @@ export const TezosTokenScreen = () => { useNavigationSetOptions( { - headerRight: () => + headerRight: () => }, [tezosToken] ); diff --git a/src/screens/token-screen/token-screen.tsx b/src/screens/token-screen/token-screen.tsx index 74c2cec9a..f43f2731d 100644 --- a/src/screens/token-screen/token-screen.tsx +++ b/src/screens/token-screen/token-screen.tsx @@ -8,7 +8,7 @@ import { HeaderTokenInfo } from 'src/components/header/header-token-info/header- import { useNavigationSetOptions } from 'src/components/header/use-navigation-set-options.hook'; import { HeaderCard } from 'src/components/header-card/header-card'; import { HeaderCardActionButtons } from 'src/components/header-card-action-buttons/header-card-action-buttons'; -import { IconNameEnum } from 'src/components/icon/icon-name.enum'; +import { IconNameV2Enum } from 'src/components/icon-v2/icon-name.enum'; import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-key-hash-text'; import { TokenEquityValue } from 'src/components/token-equity-value/token-equity-value'; import { TokenScreenContentContainer } from 'src/components/token-screen-content-container/token-screen-content-container'; @@ -73,7 +73,7 @@ export const TokenScreen = () => { useNavigationSetOptions( { headerTitle: () => , - headerRight: () => + headerRight: () => }, [token] ); diff --git a/src/screens/wallet/backup-your-wallet-overlay/backup-your-wallet-overlay.tsx b/src/screens/wallet/backup-your-wallet-overlay/backup-your-wallet-overlay.tsx index f1eef59c6..13d274edd 100644 --- a/src/screens/wallet/backup-your-wallet-overlay/backup-your-wallet-overlay.tsx +++ b/src/screens/wallet/backup-your-wallet-overlay/backup-your-wallet-overlay.tsx @@ -44,10 +44,12 @@ export const BackupYourWalletOverlay = () => { ]} > - Backup your wallet - - {'Don’t lose your wallet! Save your access\n' + 'to account using backup.'} - + + Backup your wallet + + {'Don’t lose your wallet! Save your access\n' + 'to account using backup.'} + + (({ isStart }) => { return ( - {isLinkLoading ? ( - - - - ) : ( - <> - {isStart ? 'Jump in Tezos right now!' : 'Insufficient TEZ balance'} - - {isStart ? ( - - Buy TEZ using credit card and start working with the Tezos blockchain - immediately. - - ) : ( - - Buy TEZ using credit card and continue your Tezos blockchain journey - without delay. - - )} - - - handleOnRampButtonPress(50)} - testID={OnRampOverlaySelectors.fiftyDollarButton} - /> - - handleOnRampButtonPress(100)} - testID={OnRampOverlaySelectors.oneHundredDollarButton} - /> + + {isLinkLoading ? ( + + + + ) : ( + <> + {isStart ? 'Jump in Tezos right now!' : 'Insufficient TEZ balance'} - handleOnRampButtonPress(200)} - testID={OnRampOverlaySelectors.twoHundredDollarButton} + {isStart ? ( + + Buy TEZ using credit card and start working with the Tezos blockchain + immediately. + + ) : ( + + Buy TEZ using credit card and continue your Tezos blockchain journey + without delay. + + )} + + + handleOnRampButtonPress(50)} + testID={OnRampOverlaySelectors.fiftyDollarButton} + /> + + handleOnRampButtonPress(100)} + testID={OnRampOverlaySelectors.oneHundredDollarButton} + /> + + handleOnRampButtonPress(200)} + testID={OnRampOverlaySelectors.twoHundredDollarButton} + /> + + + handleOnRampButtonPress()} + testID={OnRampOverlaySelectors.customAmountButton} /> - - handleOnRampButtonPress()} - testID={OnRampOverlaySelectors.customAmountButton} - /> + - - - - The token exchange feature is provided by third-party. - - - )} + + The token exchange feature is provided by third-party. + + + )} + ); }); From 3907df7597d350ef5560f774548258dec9978c92 Mon Sep 17 00:00:00 2001 From: Illia Pospielov Date: Mon, 20 Jul 2026 20:48:56 +0300 Subject: [PATCH 20/20] TW-2256: add etherlink data layer (api, on-chain, redux) (#1222) --- ios/Podfile.lock | 206 ++++++------- src/apis/etherlink/constants.ts | 1 + src/apis/etherlink/index.ts | 68 +++++ src/apis/etherlink/types.ts | 76 +++++ src/apis/liquidity-baking/index.ts | 6 +- src/apis/utils.ts | 19 ++ .../account-dropdown-item.tsx | 6 +- .../asset-value-text/asset-value-text.tsx | 2 +- .../header-card-action-buttons.tsx | 5 +- .../header-token-info/header-token-info.tsx | 4 +- .../token-dropdown/token-equality-fn.ts | 4 +- .../token-equity-value/token-equity-value.tsx | 20 +- src/components/token-icon/evm-token-icon.tsx | 44 +++ src/components/token-icon/token-icon.tsx | 4 +- src/config/fixed-times.ts | 2 + src/form/validation/asset-amount.ts | 4 +- .../evm/use-etherlink-data-loading.hook.ts | 206 +++++++++++++ .../use-etherlink-public-client.hook.ts | 0 src/hooks/{ => evm}/use-evm-chains.hook.ts | 0 .../use-multichain-displayed-tokens.hook.ts | 188 ++++++++++++ src/hooks/use-images-stack.ts | 2 +- src/hooks/use-token-standard.ts | 4 +- src/hooks/use-total-balance.ts | 93 +++++- .../send-asset-action-payload.interface.ts | 4 +- .../utils/use-burn-collectible.hook.ts | 4 +- ...reate-stableswap-stake-transfers-params.ts | 6 +- src/navigator/enums/modals.enum.ts | 6 +- src/navigator/main-stack.tsx | 2 +- .../collectibles-home/collectibles-home.tsx | 86 +++++- .../collectible-item/evm-collectible-item.tsx | 87 ++++++ .../collectible-item/index.tsx | 8 +- .../collectible-item/styles.ts | 16 + .../collectibles-list/index.tsx | 59 ++-- src/screens/d-apps/d-apps.tsx | 4 +- src/screens/debug/debug.tsx | 3 + src/screens/debug/etherlink-fallback-demo.tsx | 2 +- .../debug/etherlink-manual-asset-debug.tsx | 285 ++++++++++++++++++ .../import-watch-only-debug.form.tsx | 15 +- .../import-watch-only-debug.tsx | 3 +- src/screens/network-settings/index.tsx | 2 +- .../networks/all-networks-options/index.tsx | 2 +- src/screens/token-info/token-info.tsx | 4 +- .../multichain-token-list-item.styles.ts | 109 +++++++ .../multichain-token-list-item.tsx | 176 +++++++++++ .../token-list-item/tezos-token.styles.ts | 47 --- .../token-list-item/tezos-token.tsx | 101 ------- .../token-list-item/token-list-item.styles.ts | 21 -- .../token-list-item/token-list-item.tsx | 44 --- src/screens/wallet/token-list/token-list.tsx | 113 ++++--- src/screens/wallet/wallet.tsx | 2 + src/store/evm/assets/evm-assets-actions.ts | 24 ++ src/store/evm/assets/evm-assets-reducers.ts | 61 ++++ src/store/evm/assets/evm-assets-selectors.ts | 8 + src/store/evm/assets/evm-assets-state.mock.ts | 7 + src/store/evm/assets/evm-assets-state.ts | 20 ++ .../evm/balances/evm-balances-actions.ts | 24 ++ .../evm/balances/evm-balances-reducers.ts | 69 +++++ .../evm/balances/evm-balances-selectors.ts | 14 + .../evm/balances/evm-balances-state.mock.ts | 6 + src/store/evm/balances/evm-balances-state.ts | 13 + .../evm-collectibles-metadata-actions.ts | 13 + .../evm-collectibles-metadata-reducers.ts | 41 +++ .../evm-collectibles-metadata-selectors.ts | 9 + .../evm-collectibles-metadata-state.mock.ts | 7 + .../evm-collectibles-metadata-state.ts | 11 + src/store/evm/collectibles-metadata/utils.ts | 30 ++ .../evm-exchange-rates-actions.ts | 10 + .../evm-exchange-rates-reducers.ts | 30 ++ .../evm-exchange-rates-selectors.ts | 6 + .../evm-exchange-rates-state.mock.ts | 7 + .../evm-exchange-rates-state.ts | 9 + .../evm-tokens-metadata-actions.ts | 12 + .../evm-tokens-metadata-reducers.ts | 38 +++ .../evm-tokens-metadata-selectors.ts | 8 + .../evm-tokens-metadata-state.mock.ts | 7 + .../evm-tokens-metadata-state.ts | 13 + src/store/evm/tokens-metadata/utils.ts | 24 ++ src/store/migrations.types.ts | 6 +- src/store/root-state.map.ts | 12 +- src/store/root-state.mock.ts | 12 +- src/store/root-state.reducers.ts | 6 +- .../tokens-metadata-actions.ts | 14 +- .../tokens-metadata-selectors.ts | 4 +- .../tokens-metadata/tokens-metadata-state.ts | 6 +- src/store/wallet/wallet-actions.ts | 4 +- src/store/wallet/wallet-selectors.ts | 7 +- src/token/data/token-methods-assertions.ts | 8 +- src/token/data/tokens-metadata.ts | 76 ++--- .../token-metadata.interface.mock.ts | 6 +- .../interfaces/token-metadata.interface.ts | 35 ++- src/token/interfaces/token.interface.ts | 4 +- src/token/utils/token.utils.ts | 12 +- src/types/networks.ts | 25 +- src/utils/assets/hooks/evm-collectibles.ts | 55 ++++ src/utils/assets/hooks/index.ts | 2 + src/utils/assets/hooks/utils.ts | 4 +- src/utils/assets/types.ts | 19 ++ src/utils/chain-asset-slug.ts | 4 + src/utils/concurrency-limiter.utils.ts | 32 ++ src/utils/earn.utils.ts | 4 +- src/utils/evm/etherlink-balances.utils.ts | 241 +++++++++++++++ src/utils/evm/on-chain/abi/erc1155.abi.ts | 8 + src/utils/evm/on-chain/balance.ts | 68 +++++ src/utils/evm/on-chain/common.utils.ts | 56 ++++ .../evm/on-chain/evm-rpc-requests-executor.ts | 105 +++++++ src/utils/evm/on-chain/metadata.ts | 254 ++++++++++++++++ src/utils/evm/on-chain/multicall-balances.ts | 117 +++++++ src/utils/evm/on-chain/types.ts | 28 ++ src/utils/exchange-rate.util.ts | 2 + src/utils/from-token-slug.ts | 6 + src/utils/image.utils.ts | 51 +++- src/utils/tezos.util.ts | 4 +- src/utils/token-balance.utils.ts | 4 +- src/utils/token-metadata.utils.spec.ts | 2 +- src/utils/token-metadata.utils.ts | 14 +- src/utils/token-operations.util.ts | 6 +- src/utils/transfer-params.utils.ts | 6 +- 117 files changed, 3475 insertions(+), 550 deletions(-) create mode 100644 src/apis/etherlink/constants.ts create mode 100644 src/apis/etherlink/index.ts create mode 100644 src/apis/etherlink/types.ts create mode 100644 src/apis/utils.ts create mode 100644 src/components/token-icon/evm-token-icon.tsx create mode 100644 src/hooks/evm/use-etherlink-data-loading.hook.ts rename src/hooks/{ => evm}/use-etherlink-public-client.hook.ts (100%) rename src/hooks/{ => evm}/use-evm-chains.hook.ts (100%) create mode 100644 src/hooks/evm/use-multichain-displayed-tokens.hook.ts create mode 100644 src/screens/collectibles-home/collectibles-list/collectible-item/evm-collectible-item.tsx create mode 100644 src/screens/debug/etherlink-manual-asset-debug.tsx create mode 100644 src/screens/wallet/token-list/token-list-item/multichain-token-list-item.styles.ts create mode 100644 src/screens/wallet/token-list/token-list-item/multichain-token-list-item.tsx delete mode 100644 src/screens/wallet/token-list/token-list-item/tezos-token.styles.ts delete mode 100644 src/screens/wallet/token-list/token-list-item/tezos-token.tsx delete mode 100644 src/screens/wallet/token-list/token-list-item/token-list-item.styles.ts delete mode 100644 src/screens/wallet/token-list/token-list-item/token-list-item.tsx create mode 100644 src/store/evm/assets/evm-assets-actions.ts create mode 100644 src/store/evm/assets/evm-assets-reducers.ts create mode 100644 src/store/evm/assets/evm-assets-selectors.ts create mode 100644 src/store/evm/assets/evm-assets-state.mock.ts create mode 100644 src/store/evm/assets/evm-assets-state.ts create mode 100644 src/store/evm/balances/evm-balances-actions.ts create mode 100644 src/store/evm/balances/evm-balances-reducers.ts create mode 100644 src/store/evm/balances/evm-balances-selectors.ts create mode 100644 src/store/evm/balances/evm-balances-state.mock.ts create mode 100644 src/store/evm/balances/evm-balances-state.ts create mode 100644 src/store/evm/collectibles-metadata/evm-collectibles-metadata-actions.ts create mode 100644 src/store/evm/collectibles-metadata/evm-collectibles-metadata-reducers.ts create mode 100644 src/store/evm/collectibles-metadata/evm-collectibles-metadata-selectors.ts create mode 100644 src/store/evm/collectibles-metadata/evm-collectibles-metadata-state.mock.ts create mode 100644 src/store/evm/collectibles-metadata/evm-collectibles-metadata-state.ts create mode 100644 src/store/evm/collectibles-metadata/utils.ts create mode 100644 src/store/evm/exchange-rates/evm-exchange-rates-actions.ts create mode 100644 src/store/evm/exchange-rates/evm-exchange-rates-reducers.ts create mode 100644 src/store/evm/exchange-rates/evm-exchange-rates-selectors.ts create mode 100644 src/store/evm/exchange-rates/evm-exchange-rates-state.mock.ts create mode 100644 src/store/evm/exchange-rates/evm-exchange-rates-state.ts create mode 100644 src/store/evm/tokens-metadata/evm-tokens-metadata-actions.ts create mode 100644 src/store/evm/tokens-metadata/evm-tokens-metadata-reducers.ts create mode 100644 src/store/evm/tokens-metadata/evm-tokens-metadata-selectors.ts create mode 100644 src/store/evm/tokens-metadata/evm-tokens-metadata-state.mock.ts create mode 100644 src/store/evm/tokens-metadata/evm-tokens-metadata-state.ts create mode 100644 src/store/evm/tokens-metadata/utils.ts create mode 100644 src/utils/assets/hooks/evm-collectibles.ts create mode 100644 src/utils/chain-asset-slug.ts create mode 100644 src/utils/concurrency-limiter.utils.ts create mode 100644 src/utils/evm/etherlink-balances.utils.ts create mode 100644 src/utils/evm/on-chain/abi/erc1155.abi.ts create mode 100644 src/utils/evm/on-chain/balance.ts create mode 100644 src/utils/evm/on-chain/common.utils.ts create mode 100644 src/utils/evm/on-chain/evm-rpc-requests-executor.ts create mode 100644 src/utils/evm/on-chain/metadata.ts create mode 100644 src/utils/evm/on-chain/multicall-balances.ts create mode 100644 src/utils/evm/on-chain/types.ts diff --git a/ios/Podfile.lock b/ios/Podfile.lock index b79319c4e..c14f06653 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -4119,131 +4119,131 @@ SPEC CHECKSUMS: GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 GTMAppAuth: 217a876b249c3c585a54fd6f73e6b58c4f5c4238 GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 - hermes-engine: 3abac177d439900c0bea965ffa9165e5e9be9c68 + hermes-engine: 1887d821aabf73487e281c61c126c940f97744cd libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7 libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8 nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 - RCT-Folly: 36c4f904fb6cd0219dcb76b94e9502d2a72fab0b + RCT-Folly: 957659fd132051eccf60310f242798220177d26e RCTDeprecation: 225e022b85a206cf0883a909c4a114159783363c RCTRequired: 827a95c181af0886a11e21bc66c084088cf87839 RCTSwiftUI: 7babb07156ae0a8e5ea97f77e43959ddaca2c6f2 - RCTSwiftUIWrapper: 30f2e591ca57d625a244acd866fa169fd4859273 + RCTSwiftUIWrapper: 1881335e8550060ec743f9fd08ea7929b37c6d51 RCTTypeSafety: 47f936a87875e1a08ccf1ffe34e8bf29f1d85567 React: e2dc35338068bbd299c66f043ae0d7f25de8499e React-callinvoker: d3163d80425735b095cff517da3b8631691fd734 React-Codegen: 4b8b4817cea7a54b83851d4c1f91f79aa73de30a - React-Core: 821522bb86acc8bbe37698e87a6862a1f0504b05 - React-CoreModules: f732869c77b076b962a4e3ee5becd704a87d2817 - React-cxxreact: 84b7c9400c1c84bde649d06755b9c64b48114904 + React-Core: 938621f33da5880ac305fa30a43291da175e67ab + React-CoreModules: 04255fdc438664fc5fe43ca89b1bfb3ecd2fe7dc + React-cxxreact: eefc1566058dea853e2c3fa37a7005418813a5bd React-debug: f6293d03b643d4bcc487c7da7c745a75fd48ad7d - React-defaultsnativemodule: c412503114bae304c667d832bf838619f82e6937 - React-domnativemodule: c4fd125653b3753879e75adf5aa7c8438d9a9142 - React-Fabric: c6bfb98333f99e6c81916ffa4705326e1716745c - React-FabricComponents: 8b869a560a7db0b208ae33550f0aa6f9ce446b27 - React-FabricImage: e78a213d6a359c9927de1eb4f81444c5bc65cf7a - React-featureflags: bb7e30ca0fe9a8421e094536a25650c6ce9e5212 - React-featureflagsnativemodule: 1a09ad358e71d6d69b1d7a4b54fd93a0f8acd5cf - React-graphics: 268f4c2718610747287d32d25287d8b50d303e7e - React-hermes: c14b3df7089e74ebe956636598734f6996985641 - React-idlecallbacksnativemodule: dfd9165a261c4b5c7cb4ed741642bce63fdbea7c - React-ImageManager: 3fdbb547b886755b08eb4cc20c3087292adb4d1d - React-intersectionobservernativemodule: cd85dd1826f19f2473d83f100e18c5f5860c515e - React-jserrorhandler: ee2d3ffb79eabd6663a908fd5a5cab8ff9d2363d - React-jsi: d2616066314453f8059b4e2f5f7967b926ba5bf6 - React-jsiexecutor: f9c7fba6062530924ae402fd72789dd7479002dd - React-jsinspector: 34e269fd0bf776dabaa62678b25c0be73670c31a - React-jsinspectorcdp: 98fd3b1d42052813788a1a06a3cbbf84c2f4a5e9 - React-jsinspectornetwork: b3f3af03024340c1403a79dc4cc65fa9e13a7bec - React-jsinspectortracing: 2c8b432316abf2b089f6e6c108b7ddd82e3d335d - React-jsitooling: 22410dec7b0df633e0635b7607971175bca736ea - React-jsitracing: cb1c2483e0263022c88359a8438cf44711197342 - React-logger: 65c987d6465d254c08c9eb0fb6145be6eb8ca9ba - React-Mapbuffer: 9c9e5f0871d36f59b5b3421b6121596a6a74e67b - React-microtasksnativemodule: c8315d5f4ae7188f30cbfa499d8ec2e9281b97b1 - React-mutationobservernativemodule: 9bb7f57044059bcaf28e0287154942acd9b9b6dc - react-native-biometrics: 43ed5b828646a7862dbc7945556446be00798e7d - react-native-blur: b83ffbc5380d8bd2f06804b4b0e848be3507e65c - react-native-cloud-fs: 1f838a872b0204376514f5df175ccbbd342f496f - react-native-config: 916e53e7333d5b2bcb7ee9882f5605143b4fc4c5 - react-native-document-picker: 910f7b853dc56664285752289d477a48537f0178 - react-native-get-random-values: 9ef342c6e33fa57ac82f73e9270d5d651a48071a - react-native-netinfo: cec9c4e86083cb5b6aba0e0711f563e2fbbff187 - react-native-orientation-locker: cc6f357b289a2e0dd2210fea0c52cb8e0727fdaa - react-native-restart: 0bc732f4461709022a742bb29bcccf6bbc5b4863 - react-native-safe-area-context: 0a3b034bb63a5b684dd2f5fffd3c90ef6ed41ee8 - react-native-sapling: dcefd6adbe3dc7717a8336f7a9719c046b35ddab - react-native-slider: 05e7080478df08489251c2a6739a0d5628b7c198 - react-native-themis: b681fd9654ec2b55b9fb81d086159d974f752d6c - react-native-video: 624deff94be379ffaba289bed13fc0917f01abcb - react-native-webview: cdce419e8022d0ef6f07db21890631258e7a9e6e - React-NativeModulesApple: 67c09c715a8763a07a8a241a3019661ffc3f71d6 - React-networking: 72b8973a280b6a54e46930717e6c15f7c389d76e + React-defaultsnativemodule: 87877b6b437203de83f99516a227558e5aa0c3d1 + React-domnativemodule: 65131b18a850c5c533b2a3e1e2080ff698f3e791 + React-Fabric: 83e227a41a07d0a9c37cb3b9e5f9bb46839bf3c9 + React-FabricComponents: 03815669ec582613feca3a1ba3538471509db6e1 + React-FabricImage: 238bef3a0709a9402bf7365e98dc9239a5cab7b9 + React-featureflags: c1607cfb5ceb81d4fe49e86d555fe33e62b9a077 + React-featureflagsnativemodule: c0acbc91084196636df7551185d8d4b05e78b0a6 + React-graphics: b367762f684d37d33170cd1e04755ea883bf5d3b + React-hermes: b526b3bbbd0760854bff39f3ad8bec9db0ec8653 + React-idlecallbacksnativemodule: 363d4e57c056b4602ea554f3e55b152587e85292 + React-ImageManager: 18687914252c709b4fd7bc590524611eb40f45a2 + React-intersectionobservernativemodule: 274ba0f57f3a960d3532aca564b7527dd30b1f42 + React-jserrorhandler: be44f5bd0a29210275b696b532eeb370ad853131 + React-jsi: d3f42e5745c214c529b290ac80290239af19a25e + React-jsiexecutor: edb0911ad6909ceec70cb4b7b65db9827b4efb13 + React-jsinspector: 11f71225d72a27381711303088e57343a387e08c + React-jsinspectorcdp: caa9837d1de3799142bd152e526054e71d9710be + React-jsinspectornetwork: 353c8c9210778200f6d521a480efdbbbfdba1979 + React-jsinspectortracing: 99174a520b148d6e13b015093148d05a9a56c04c + React-jsitooling: 553356e43220901475a21531845a5719d24a44af + React-jsitracing: c526ff8dc0bc61b424eeeedf649b00f40c7715e4 + React-logger: 59df304cf4441e34a240bf7d9c90b3243d1b3d77 + React-Mapbuffer: fd584964feca35a75f9b7570a907ba074ecea354 + React-microtasksnativemodule: 87c69aee0a4a287cfff47ae574522f153c45f686 + React-mutationobservernativemodule: 38d184e54edf19141f893bb46d5c97c92a11ab48 + react-native-biometrics: 352e5a794bfffc46a0c86725ea7dc62deb085bdc + react-native-blur: 981b2ec64b3084ecf98812333f2a8c6e83643a1e + react-native-cloud-fs: cd21282c5cecaf285225e447dd7f3cf2f9015496 + react-native-config: 81fd713bbbc6fbe39588c975edf5485d0e15adf8 + react-native-document-picker: ca09736423f98ee844aec0ecf76c280103ef05cd + react-native-get-random-values: 4c1e8378eb5a30b2ac9aa6e28da7c3a987350e8a + react-native-netinfo: f0a9899081c185db1de5bb2fdc1c88c202a059ac + react-native-orientation-locker: 5819fd23ca89cbac0d736fb4314745f62716d517 + react-native-restart: 7595693413fe3ca15893702f2c8306c62a708162 + react-native-safe-area-context: fea29ae0275beaa22f72d0a8be1eb0ab09c3feae + react-native-sapling: 36b28bc90d96e6ccc754c515d0dd3ba99049a094 + react-native-slider: f44eb4f327db65c7c0519cc91aefb7b0d50f1615 + react-native-themis: 52e1ff00dbd17ca8ddec02c6e071259602f4b5c7 + react-native-video: f9758cda5b9dd6fd378389002f28f3f19017a406 + react-native-webview: 5887b6094417c75a9bee446261f89c32adf6b602 + React-NativeModulesApple: 35627d2202a25d100fdea60c65f098f3ee64eabe + React-networking: cc9c7a509935a89c0725ec204b949222a9ea716f React-oscompat: 563c536fc2d9cece1f54442fa2a3d9f68a9621e3 - React-perflogger: 69b12c83ec90d61e9fc8055bdce33f3fed9978b3 - React-performancecdpmetrics: dc08b5f87fa0c9c43915bfcd58b8124d2d07c8f9 - React-performancetimeline: 773a4631cf1a12499d25e5afe356c0d4934cb509 + React-perflogger: 3cc195751fa67a4bca5693ea9ab416c5d552b903 + React-performancecdpmetrics: 64a72eeef585fe607e4513292d29ce73c1c8b090 + React-performancetimeline: a189b6f26a11d2a46a403c99ddf01e2f99aca2ed React-RCTActionSheet: ea8200cac284d410090bd780baf729903912e4e6 - React-RCTAnimation: 2612fabae23447a1afa7ac7405fbb4d0f6fa52b0 - React-RCTAppDelegate: cf9ecbc46ee5d6aa9f06c60d8395aa13495d1368 - React-RCTBlob: 7b4d7420a6d46327eeeeacdbd54a392253517772 - React-RCTFabric: bcd85c8a26c49635e8056af7bdb480969244ae9d - React-RCTFBReactNativeSpec: 68368860f257ac2ec24a8584b933a9b10dd5dc4a - React-RCTImage: 9424c680b0866903ff65a9a093641f3d1e6ce85d - React-RCTLinking: c5dd340d5fee2fa01fee28750ae4211449fd3904 - React-RCTNetwork: 3fe661f94974cfba5126800d834f98e4608b2d68 - React-RCTRuntime: 1d8ae939d193598ff7de5043196cdc1b90135b71 - React-RCTSettings: 1ba76e945f541c1c246618d2775caea0c6a76e26 - React-RCTText: 1d7a4f263266efbd5fa5335a107fbd00ff94ba9e - React-RCTVibration: 0de7b5cc470892e4a65358ae7853f117fe5c2173 + React-RCTAnimation: 84673c17af3f31b14f806cba174c19f2e143dffd + React-RCTAppDelegate: ff6ad862522c40b30300f76037df920616a857f8 + React-RCTBlob: 88732cb198725639e55050b06024743427cab86f + React-RCTFabric: c9a87bcaad6fdbac504f1081e39041625848b7bb + React-RCTFBReactNativeSpec: fba55e7f8b0041e88cd56c9193f60072646580e1 + React-RCTImage: 58a1bd96d51c0124566c6f8aac9171bc2a845532 + React-RCTLinking: 9929cc2f7eccc9ec8dcfd45f1e9a26f118ca895c + React-RCTNetwork: 23b4bdb536437cd5ae3088de216d454a34ca6f7f + React-RCTRuntime: ab8d9655de2acfc03edc721d0d665d190d00fdaa + React-RCTSettings: 8639885421cd563fe9ead68798fe015f3a9d8e98 + React-RCTText: 85eae800067e04d0eb2b720b30d45c8be642a46e + React-RCTVibration: 4743a0c15c5b9f2ab8beca5beecae5240dae8caa React-rendererconsistency: e90b9e1bab21c3fabbaa220c3fab820ee81c59d9 - React-renderercss: 41759ec6208f3afe6f7cd0205d4358a983f7ac6d - React-rendererdebug: 0ddb9d40c7e40d47b03e7ef76b8ea02157ccf83c - React-RuntimeApple: 345c69430aba5a1f958962e7ea03d2bd88f017d0 - React-RuntimeCore: 189d7e79c2c57cc292973c9a21b595b5ab32f5ee - React-runtimeexecutor: 07bf5c4b99250eeb87d11c6a7525b2e23c4d9335 - React-RuntimeHermes: 7ab04f8717cb8cb4a95788d822e1d52c17b59f7c - React-runtimescheduler: 3a5dfc9754d01a25573a7814e204ce2285d10290 - React-timing: 52725a5eac08312f63ddf2fcedb11887249e62dc - React-utils: 13434fd45de041d5170cdb0a8e7fa593d9c3dc13 - React-webperformancenativemodule: 7c40fad73f558c60f3101e4b3fed0a3e66f7a312 - ReactAppDependencyProvider: 25c9c516839be2c5e3d3344f95dc7da5f7e63fc2 - ReactCodegen: 3a96f3289dc44bc80ba172d16419c058874afa20 - ReactCommon: f7748c97e657e7be0df505a5fc51c4ace9791a32 - ReactNativeExceptionHandler: a23922ca00122b050ae9412f960061791c232c47 - RNBootSplash: 7fcc9a58ae343aeb1a1dd49f9030832fe432c544 - RNCAsyncStorage: fd44f4b03e007e642e98df6726737bc66e9ba609 - RNCClipboard: e560338bf6cc4656a09ff90610b62ddc0dbdad65 - RNCMaskedView: d707a83784c67099b54b37d056ababb2767ce15e - RNDeviceInfo: 36d7f232bfe7c9b5c494cb7793230424ed32c388 - RNExitApp: a2fd7923ab37b9166704fdc488622a48dcd372a2 - RNFastImage: 674d5912e174468a60971d2ba9efc7bb43d116fa - RNFBApp: 59a5f1280d8c7d48ed5cb658682ed12904bca65e - RNFBAppCheck: 5a1a36ca7f428d174930bd6ecfdfcd8579cc0296 - RNFBMessaging: 296600da7f02e92bb6631c11ef5e19bc1b89a54d - RNFS: 89de7d7f4c0f6bafa05343c578f61118c8282ed8 - RNGestureHandler: 35e1f5f04f5b224777890a3e93c6208072c2057b - RNGoogleSignin: c1de96d92d6dd4335fa8e0f0ed4312a9d34e4ecb - RNKeychain: 76d042fc1dfba47f3945920bc82e0bce9ad1ff55 - RNNotifee: 5e3b271e8ea7456a36eec994085543c9adca9168 - RNPermissions: 0dbae39cf157f6c699f1454bbdcc25a0977eca83 - RNQuickAction: c2c8f379e614428be0babe4d53a575739667744d - RNReactNativeHapticFeedback: 5f1542065f0b24c9252bd8cf3e83bc9c548182e4 - RNReanimated: 4405484a956444df1df51a49493ca2824a281226 - RNScreens: d6413aeb1878cdafd3c721e2c5218faf5d5d3b13 - RNScrypt: 3e8612600c93aaa3bfa7849b6d1a4ab61613e2af - RNSentry: 0cb5c73bdb064318193d5b658774bd34f83107cf - RNSha256: 4d35f112e967f58273d625a19376f4eafc72bd5c - RNSVG: 0b9792eb17fbbc8e6d186581cb2cf712998dcc2a - RNWorklets: dd22aad568254990d6f3dc4655d54364c5a3eb3a + React-renderercss: 36a93ea68b7707cfc8df03265fb533db4357a699 + React-rendererdebug: 362c5f335930b79a14cd4a546264405768de9c5e + React-RuntimeApple: b4da67a2f11720cbbb2410c4438dad91fac5525a + React-RuntimeCore: 4a9854d5d8f7b724e6c0022ad4d47ae97c4cf963 + React-runtimeexecutor: a4b000263beb67fc4607acf2bfc882042543c0c0 + React-RuntimeHermes: 6d8018fc02844ed9d7803d97e419ab14e6663fe5 + React-runtimescheduler: 6e79c3b243d4c85f7a7816e4c72851d6c3fc08fb + React-timing: 2891d179d31fc9687dc43be7c03b01e19fe6b8b5 + React-utils: 92d73ea2a11254149303249386d4a005e3500f07 + React-webperformancenativemodule: 9c23efd5f795b2ac175bcba8cfa04cf0c679173f + ReactAppDependencyProvider: a54c0c9b976766e1b6d5e2bb4d1ad0d15913e9e1 + ReactCodegen: d7325fa5a05569fa9c30125f01c66cd28abcb602 + ReactCommon: 841a11dd3d8249bede53341d52f9b668a5d50bd5 + ReactNativeExceptionHandler: b11ff67c78802b2f62eed0e10e75cb1ef7947c60 + RNBootSplash: d8407c268d5159ea026dc741ec867ebbe4708f25 + RNCAsyncStorage: 8857fb173af29664cb90897903902dc8533e36cc + RNCClipboard: 4eea71d801c880175c12f6ab14332ca86fed935f + RNCMaskedView: 8bfc13a356455b15d56114738f4d2a804769c1bf + RNDeviceInfo: 53f9c84e28e854a308d3e548e25ef120b4615531 + RNExitApp: a804a6de055a698e2f6c11e8fce146c5c8ce3ead + RNFastImage: 94681302bfbe8076b0163450183ae2121b45e525 + RNFBApp: 60f4af1a2a4d35178aa4faccf1dbba6792ad0ece + RNFBAppCheck: d1f0a18764096dd66e33805a911ee0f34a36710e + RNFBMessaging: 55269ab548e741b512386230d5d3856b3e963584 + RNFS: 4ac0f0ea233904cb798630b3c077808c06931688 + RNGestureHandler: f07a92527a176c390ad2c30aa59811a60e635508 + RNGoogleSignin: 9c5c73089b78fd865f9a6758fc05ef7da7bd2be2 + RNKeychain: d0bdaca4688ae123909b137de08491f49a6cf6b1 + RNNotifee: 4a6ee5c7deaf00e005050052d73ee6315dff7ec9 + RNPermissions: d5c31fdf7f0368d8740f2d3aefe212ed007e6cca + RNQuickAction: 6d404a869dc872cde841ad3147416a670d13fa93 + RNReactNativeHapticFeedback: 43c09eb41d8321be2e1375cb87ae734e58f677b0 + RNReanimated: 66431475d3a350b9dd8f7f926312cadc201af06f + RNScreens: c73f6bcfc19e209736c4e069f62b0f274535214b + RNScrypt: 95fdef077b482e9fdf8a761120cb69d129ef4016 + RNSentry: f3c0498f67c1a7ff86155b66b74318cdfcaeb693 + RNSha256: e1bc64e9e50b293d5282bb4caa1b2043931f1c9d + RNSVG: c26deb3c924fd1933589eacfc42aa23a58b33289 + RNWorklets: a9b64c5325db72962c9895aecd931837d851131f SDWebImage: e9fc87c1aab89a8ab1bbd74eba378c6f53be8abf SDWebImageAVIFCoder: afe194a084e851f70228e4be35ef651df0fc5c57 SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c SDWebImageWebPCoder: 0e06e365080397465cc73a7a9b472d8a3bd0f377 Sentry: d587a8fe91ca13503ecd69a1905f3e8a0fcf61be SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 - VisionCamera: b51af005669c6642dd1b4fca434eda4c1778de87 + VisionCamera: 68d40255fa8866e815cbbb063730102d3da276fd Yoga: 9d8e8094a2bed6a175d9e6001a0546d5dae663ee PODFILE CHECKSUM: a1b45771ff02f9813c28a409db7c90feec8bef1d diff --git a/src/apis/etherlink/constants.ts b/src/apis/etherlink/constants.ts new file mode 100644 index 000000000..b96ec7c09 --- /dev/null +++ b/src/apis/etherlink/constants.ts @@ -0,0 +1 @@ +export const ETHERLINK_API_BASE_URL = 'https://explorer.etherlink.com/api/v2'; diff --git a/src/apis/etherlink/index.ts b/src/apis/etherlink/index.ts new file mode 100644 index 000000000..3ce158f76 --- /dev/null +++ b/src/apis/etherlink/index.ts @@ -0,0 +1,68 @@ +import axios from 'axios'; + +import { ConcurrencyLimiter } from 'src/utils/concurrency-limiter.utils'; + +import { refetchOnce429 } from '../utils'; + +import { ETHERLINK_API_BASE_URL } from './constants'; +import { + EtherlinkAccountInfo, + EtherlinkAccountNftsPageParams, + EtherlinkAccountNftsResponse, + EtherlinkAddressNftInstance, + EtherlinkTokenBalance, + EtherlinkTokenInfo +} from './types'; + +export { isErc20TokenBalance, isEtherlinkCollectibleTokenType } from './types'; +export type { EtherlinkTokenType, EtherlinkTokenInfo, EtherlinkAddressNftInstance } from './types'; + +const api = axios.create({ baseURL: ETHERLINK_API_BASE_URL }); + +const apiConcurrencyLimiter = new ConcurrencyLimiter(10); + +interface FetchGetParams

{ + endpoint: string; + pageParams?: P; +} + +async function fetchGet({ endpoint, pageParams }: FetchGetParams

) { + const release = await apiConcurrencyLimiter.acquire(); + setTimeout(release, 1000); + + const { data } = await api.get(endpoint, { + params: pageParams + }); + + return data; +} + +export const fetchGetAccountInfo = (address: string) => + fetchGet({ endpoint: `/addresses/${address}` }); + +export const fetchGetTokensBalances = (address: string) => + fetchGet({ endpoint: `/addresses/${address}/token-balances` }); + +export const fetchGetTokenInfo = (contract: string) => + fetchGet({ endpoint: `/tokens/${contract}` }); + +const fetchGetAccountNfts = (address: string, pageParams?: EtherlinkAccountNftsPageParams) => + fetchGet({ + endpoint: `/addresses/${address}/nft`, + pageParams + }); + +export const fetchAllAccountNfts = async (address: string) => { + let nextPageParams: EtherlinkAccountNftsPageParams | undefined; + let allItems: EtherlinkAddressNftInstance[] = []; + + do { + const { items, next_page_params: newNextPageParams } = await refetchOnce429(() => + fetchGetAccountNfts(address, nextPageParams) + ); + allItems = allItems.concat(items); + nextPageParams = newNextPageParams ?? undefined; + } while (nextPageParams != null); + + return allItems; +}; diff --git a/src/apis/etherlink/types.ts b/src/apis/etherlink/types.ts new file mode 100644 index 000000000..53a90b5e7 --- /dev/null +++ b/src/apis/etherlink/types.ts @@ -0,0 +1,76 @@ +export type EtherlinkTokenType = 'ERC-20' | 'ERC-721' | 'ERC-1155'; + +export interface EtherlinkTokenInfo { + icon_url: string | null; + name: string | null; + decimals: string | null; + symbol: string | null; + address: HexString; + address_hash: HexString; + type: T; + exchange_rate: string | null; +} + +export interface EtherlinkAccountInfo { + coin_balance: string | null; + hash: HexString; +} + +interface EtherlinkAddressParam { + hash: HexString; + name: string | null; +} + +interface EtherlinkNFTMetadata { + attributes: Array<{ trait_type: string; value: string }> | null; + description: string | null; + image: string | null; + name: string | null; +} + +interface EtherlinkNFTInstance { + id: string; + animation_url: string | null; + external_app_url: string | null; + image_url: string | null; + media_type: string | null; + media_url: string | null; + token: EtherlinkTokenInfo<'ERC-721' | 'ERC-1155'>; + metadata: EtherlinkNFTMetadata | null; + owner: EtherlinkAddressParam | null; +} + +export interface EtherlinkAddressNftInstance extends Omit { + value: string; +} + +export interface EtherlinkTokenBalance { + token_instance: EtherlinkNFTInstance | null; + token_id: string | null; + token: EtherlinkTokenInfo; + value: string; +} + +interface EtherlinkERC20TokenBalance extends EtherlinkTokenBalance { + token: EtherlinkTokenInfo<'ERC-20'>; + token_id: null; + token_instance: null; +} + +export const isErc20TokenBalance = (balance: EtherlinkTokenBalance): balance is EtherlinkERC20TokenBalance => + balance.token.type === 'ERC-20'; + +export const isEtherlinkCollectibleTokenType = (type: string): type is Exclude => + type === 'ERC-721' || type === 'ERC-1155'; + +export interface EtherlinkAccountNftsPageParams { + items_count: number; + token_contract_address_hash: HexString; + token_id: string; + token_type: Exclude; +} + +export interface EtherlinkAccountNftsResponse { + items: EtherlinkAddressNftInstance[]; + next_page_params: EtherlinkAccountNftsPageParams | null; +} diff --git a/src/apis/liquidity-baking/index.ts b/src/apis/liquidity-baking/index.ts index 30f191263..f30cdc4ba 100644 --- a/src/apis/liquidity-baking/index.ts +++ b/src/apis/liquidity-baking/index.ts @@ -5,7 +5,7 @@ import { EarnOpportunityTokenStandardEnum } from 'src/enums/earn-opportunity-tok import { EarnOpportunityTypeEnum } from 'src/enums/earn-opportunity-type.enum'; import { LIQUIDITY_BAKING_DEX_ADDRESS, SIRS_TOKEN } from 'src/token/data/token-slugs'; import { SIRS_TOKEN_METADATA, TEZ_TOKEN_METADATA, TZBTC_TOKEN_METADATA } from 'src/token/data/tokens-metadata'; -import { TokenMetadataInterface, TokenStandardsEnum } from 'src/token/interfaces/token-metadata.interface'; +import { TezosTokenMetadata, TezosTokenStandardsEnum } from 'src/token/interfaces/token-metadata.interface'; import { getFirstAccountActivityTime } from 'src/utils/earn.utils'; import { isDefined } from 'src/utils/is-defined'; import { tzktUrl } from 'src/utils/linking'; @@ -24,10 +24,10 @@ import { getLiquidityBakingStats } from '../temple-wallet'; import { liquidityBakingStakingId, THREE_ROUTE_LB_TOKENS } from './consts'; import { LiquidityBakingFarmResponse } from './types'; -const toFarmToken = (token: TokenMetadataInterface) => ({ +const toFarmToken = (token: TezosTokenMetadata) => ({ contractAddress: token.address, type: - token.standard === TokenStandardsEnum.Fa2 + token.standard === TezosTokenStandardsEnum.Fa2 ? EarnOpportunityTokenStandardEnum.Fa2 : EarnOpportunityTokenStandardEnum.Fa12, isWhitelisted: true, diff --git a/src/apis/utils.ts b/src/apis/utils.ts new file mode 100644 index 000000000..9ced446fd --- /dev/null +++ b/src/apis/utils.ts @@ -0,0 +1,19 @@ +import axios from 'axios'; + +import { sleep } from 'src/utils/timeouts.util'; + +export async function refetchOnce429(fetcher: () => Promise, delayAroundInMS = 1000): Promise { + try { + return await fetcher(); + } catch (err) { + if (axios.isAxiosError(err) && err.response?.status === 429) { + await sleep(delayAroundInMS); + const res = await fetcher(); + await sleep(delayAroundInMS); + + return res; + } + + throw err; + } +} diff --git a/src/components/account-dropdown/account-dropdown-item/account-dropdown-item.tsx b/src/components/account-dropdown/account-dropdown-item/account-dropdown-item.tsx index 22e188508..93073e290 100644 --- a/src/components/account-dropdown/account-dropdown-item/account-dropdown-item.tsx +++ b/src/components/account-dropdown/account-dropdown-item/account-dropdown-item.tsx @@ -6,11 +6,13 @@ import { AssetValueText } from 'src/components/asset-value-text/asset-value-text import { CryptoLogo } from 'src/components/crypto-logo'; import { CryptoLogoNameEnum } from 'src/components/crypto-logo/logo-name.enum'; import { DropdownListItemComponent } from 'src/components/dropdown/dropdown'; +import { FormattedAmount } from 'src/components/formatted-amount'; import { HideBalance } from 'src/components/hide-balance/hide-balance'; import { Icon } from 'src/components/icon/icon'; import { RobotIcon } from 'src/components/robot-icon/robot-icon'; import { getSeedFromAccount } from 'src/components/robot-icon/robot-icon.utils.ts'; import { TruncatedText } from 'src/components/truncated-text'; +import { useTotalFiatBalanceOfAccount } from 'src/hooks/use-total-balance'; import { Account } from 'src/interfaces/account.interfaces.ts'; import { useAllCollectiblesDetailsSelector } from 'src/store/collectibles/collectibles-selectors'; import { useContactsSelector } from 'src/store/contact-book/contact-book-selectors'; @@ -79,7 +81,7 @@ const AccountDropdownListItem = memo>( const tezosAddress = getAccountAddressForTezos(account); const evmAddress = getAccountAddressForEvm(account); - const tezos = useTezosTokenOfKnownAccount(account.id); + const totalFiatBalance = useTotalFiatBalanceOfAccount(account); return ( <> @@ -88,7 +90,7 @@ const AccountDropdownListItem = memo>( {account.name} - + diff --git a/src/components/asset-value-text/asset-value-text.tsx b/src/components/asset-value-text/asset-value-text.tsx index 7cb9413a2..04e0e58bb 100644 --- a/src/components/asset-value-text/asset-value-text.tsx +++ b/src/components/asset-value-text/asset-value-text.tsx @@ -12,7 +12,7 @@ interface Props { amount: string; /** * @deprecated - * Rework to accept TokenMetadataInterface + * Rework to accept TezosTokenMetadata * with `exchangeRate` as a separate property */ asset: TokenInterface; diff --git a/src/components/header-card-action-buttons/header-card-action-buttons.tsx b/src/components/header-card-action-buttons/header-card-action-buttons.tsx index 9a14aa353..f9ff144e1 100644 --- a/src/components/header-card-action-buttons/header-card-action-buttons.tsx +++ b/src/components/header-card-action-buttons/header-card-action-buttons.tsx @@ -1,4 +1,3 @@ -import { BigNumber } from 'bignumber.js'; import React, { FC, useCallback, useEffect, useMemo, useRef } from 'react'; import { Animated } from 'react-native'; import { useDispatch } from 'react-redux'; @@ -46,7 +45,7 @@ export const HeaderCardActionButtons: FC = ({ token, onSendPress }) => { const selectedAccount = useAccount(); const { isTezosMainnet } = useNetworkInfo(); const tezosToken = useTezosTokenOfCurrentAccount(); - const { balance } = useTotalBalance(); + const totalBalance = useTotalBalance(); const styles = useHeaderCardActionButtonsStyles(); const defaultStyleConfig = useButtonMediumStyleConfig(); const isLoaderBeingShown = useIsShowLoaderSelector(); @@ -163,7 +162,7 @@ export const HeaderCardActionButtons: FC = ({ token, onSendPress }) => { style={styles.buttonContainer} testID={WalletSelectors.earnButton} testIDProperties={{ - isZeroBalance: new BigNumber(balance).isLessThanOrEqualTo(0) + isZeroBalance: totalBalance.isLessThanOrEqualTo(0) }} /> diff --git a/src/components/header/header-token-info/header-token-info.tsx b/src/components/header/header-token-info/header-token-info.tsx index f2771d429..ec87f7302 100644 --- a/src/components/header/header-token-info/header-token-info.tsx +++ b/src/components/header/header-token-info/header-token-info.tsx @@ -4,13 +4,13 @@ import { View } from 'react-native'; import { TokenIcon } from 'src/components/token-icon/token-icon'; import { TruncatedText } from 'src/components/truncated-text'; import { formatSize } from 'src/styles/format-size'; -import { TokenMetadataInterface } from 'src/token/interfaces/token-metadata.interface'; +import { TezosTokenMetadata } from 'src/token/interfaces/token-metadata.interface'; import { isString } from 'src/utils/is-string'; import { useHeaderTokenInfoStyles } from './header-token-info.styles'; interface Props { - token: TokenMetadataInterface; + token: TezosTokenMetadata; } export const HeaderTokenInfo: FC = ({ token }) => { diff --git a/src/components/token-dropdown/token-equality-fn.ts b/src/components/token-dropdown/token-equality-fn.ts index 08a8cd653..184168ebb 100644 --- a/src/components/token-dropdown/token-equality-fn.ts +++ b/src/components/token-dropdown/token-equality-fn.ts @@ -1,9 +1,9 @@ -import { TokenMetadataInterface } from 'src/token/interfaces/token-metadata.interface'; +import { TezosTokenMetadata } from 'src/token/interfaces/token-metadata.interface'; import { isDefined } from 'src/utils/is-defined'; import { DropdownEqualityFn } from '../dropdown/dropdown'; -export const tokenEqualityFn: DropdownEqualityFn = (item, value) => { +export const tokenEqualityFn: DropdownEqualityFn = (item, value) => { if (!isDefined(value)) { return false; } diff --git a/src/components/token-equity-value/token-equity-value.tsx b/src/components/token-equity-value/token-equity-value.tsx index 29a5057e4..d0bb32f55 100644 --- a/src/components/token-equity-value/token-equity-value.tsx +++ b/src/components/token-equity-value/token-equity-value.tsx @@ -1,18 +1,22 @@ import BigNumber from 'bignumber.js'; -import React, { memo, useLayoutEffect, useRef } from 'react'; +import React, { memo, useLayoutEffect, useMemo, useRef } from 'react'; import { StyleProp, Text, TextStyle, View } from 'react-native'; import { useHideBalance } from 'src/hooks/hide-balance/hide-balance.hook'; import { useTotalBalance } from 'src/hooks/use-total-balance'; import { WalletSelectors } from 'src/screens/wallet/wallet.selectors'; -import { useCurrentFiatCurrencyMetadataSelector } from 'src/store/settings/settings-selectors'; +import { + useCurrentFiatCurrencyMetadataSelector, + useFiatToUsdRateSelector +} from 'src/store/settings/settings-selectors'; import { formatSize } from 'src/styles/format-size'; import { TokenInterface } from 'src/token/interfaces/token.interface'; import { isDefined } from 'src/utils/is-defined'; -import { formatAssetAmount } from 'src/utils/number.util'; +import { formatAssetAmount, ZERO } from 'src/utils/number.util'; import { AssetValueText } from '../asset-value-text/asset-value-text'; import { ErrorBoundary } from '../error-boundary'; +import { FormattedAmount } from '../formatted-amount'; import { HideBalance } from '../hide-balance/hide-balance'; import { IconNameEnum } from '../icon/icon-name.enum'; import { TouchableIcon } from '../icon/touchable-icon/touchable-icon'; @@ -56,7 +60,13 @@ const TokenEquityValueContent = memo(({ token, forTotalBalance = false }) const styles = useTokenEquityValueStyles(); const { toggleHideBalance, isBalanceHidden } = useHideBalance(); - const totalBalance = useTotalBalance(); + const totalDollarBalance = useTotalBalance(); + const fiatToUsdRate = useFiatToUsdRateSelector(); + + const totalFiatBalance = useMemo( + () => (isDefined(fiatToUsdRate) ? totalDollarBalance.times(fiatToUsdRate) : ZERO), + [totalDollarBalance, fiatToUsdRate] + ); const exchangeRate = token.exchangeRate; @@ -93,7 +103,7 @@ const TokenEquityValueContent = memo(({ token, forTotalBalance = false }) ) : ( - + )} diff --git a/src/components/token-icon/evm-token-icon.tsx b/src/components/token-icon/evm-token-icon.tsx new file mode 100644 index 000000000..ae857656f --- /dev/null +++ b/src/components/token-icon/evm-token-icon.tsx @@ -0,0 +1,44 @@ +import FastImage from '@d11/react-native-fast-image'; +import React, { memo, useMemo } from 'react'; +import { StyleProp, View, ViewStyle } from 'react-native'; + +import { useImagesStack } from 'src/hooks/use-images-stack'; +import { formatSize } from 'src/styles/format-size'; +import { buildEvmTokenIconSources } from 'src/utils/image.utils'; + +import { CryptoLogo } from '../crypto-logo'; +import { CryptoLogoNameEnum } from '../crypto-logo/logo-name.enum'; + +import { TokenIconStyles } from './token-icon.styles'; + +interface Props { + chainId: number; + address: string; + iconURL?: string; + size?: number; + style?: StyleProp; +} + +export const EvmTokenIcon = memo(({ chainId, address, iconURL, size = formatSize(32), style }) => { + const sourcesStack = useMemo(() => buildEvmTokenIconSources(chainId, address, iconURL), [chainId, address, iconURL]); + + const { src, isLoading, isStackFailed, onSuccess, onFail } = useImagesStack(sourcesStack); + + const isShowPlaceholder = isLoading || isStackFailed; + + const containerStyle = useMemo( + () => [TokenIconStyles.container, { borderRadius: size / 2, width: size, height: size }, style], + [size, style] + ); + const imageStyle = useMemo( + () => [isShowPlaceholder && TokenIconStyles.hiddenImage, { width: size, height: size }], + [isShowPlaceholder, size] + ); + + return ( + + {isShowPlaceholder && } + {src != null && } + + ); +}); diff --git a/src/components/token-icon/token-icon.tsx b/src/components/token-icon/token-icon.tsx index e837e8346..55f4e498a 100644 --- a/src/components/token-icon/token-icon.tsx +++ b/src/components/token-icon/token-icon.tsx @@ -4,7 +4,7 @@ import { StyleProp, View, ViewStyle } from 'react-native'; import { formatSize } from 'src/styles/format-size'; import { useColors } from 'src/styles/use-colors'; import { TEZ_TOKEN_METADATA } from 'src/token/data/tokens-metadata'; -import { TokenMetadataInterface } from 'src/token/interfaces/token-metadata.interface'; +import { TezosTokenMetadata } from 'src/token/interfaces/token-metadata.interface'; import { isImageRectangular, isImgUriDataUri } from 'src/utils/image.utils'; import { isDefined } from 'src/utils/is-defined'; import { isString } from 'src/utils/is-string'; @@ -16,7 +16,7 @@ import { IconNameEnum } from '../icon/icon-name.enum'; import { LoadableTokenIconImage } from './loadable-image'; import { TokenIconStyles } from './token-icon.styles'; -interface Props extends Pick { +interface Props extends Pick { size?: number; style?: StyleProp; } diff --git a/src/config/fixed-times.ts b/src/config/fixed-times.ts index 853f088c1..97b1a5b0e 100644 --- a/src/config/fixed-times.ts +++ b/src/config/fixed-times.ts @@ -10,6 +10,8 @@ export const ONE_MINUTE = 60000; export const PROMO_SYNC_INTERVAL = ONE_MINUTE; +export const EVM_BALANCES_SYNC_INTERVAL = ONE_MINUTE; + const LONG_INTERVAL = 5 * ONE_MINUTE; export const RATES_SYNC_INTERVAL = LONG_INTERVAL; diff --git a/src/form/validation/asset-amount.ts b/src/form/validation/asset-amount.ts index 375dc7f85..f8c59c6ad 100644 --- a/src/form/validation/asset-amount.ts +++ b/src/form/validation/asset-amount.ts @@ -2,7 +2,7 @@ import { BigNumber } from 'bignumber.js'; import { object, ValidationError } from 'yup'; import { DEFAULT_EXPECTED_GAS_EXPENSE } from 'src/config/general'; -import { TokenMetadataInterface } from 'src/token/interfaces/token-metadata.interface'; +import { TezosTokenMetadata } from 'src/token/interfaces/token-metadata.interface'; import { toTokenSlug } from 'src/token/utils/token.utils'; import { isDefined } from 'src/utils/is-defined'; import { formatAssetAmount } from 'src/utils/number.util'; @@ -26,7 +26,7 @@ export const assetAmountValidation = object().shape({ }); export const createAssetAmountWithMaxValidation = ( - gasToken: TokenMetadataInterface, + gasToken: TezosTokenMetadata, expectedGasExpense: BigNumber.Value = DEFAULT_EXPECTED_GAS_EXPENSE ) => assetAmountValidation.clone().test('max-amount', (value, context) => { diff --git a/src/hooks/evm/use-etherlink-data-loading.hook.ts b/src/hooks/evm/use-etherlink-data-loading.hook.ts new file mode 100644 index 000000000..9c83d6aa5 --- /dev/null +++ b/src/hooks/evm/use-etherlink-data-loading.hook.ts @@ -0,0 +1,206 @@ +import { useIsFocused } from '@react-navigation/native'; +import { useCallback, useEffect, useRef, useState } from 'react'; +import { isAddress } from 'viem'; + +import { EVM_BALANCES_SYNC_INTERVAL } from 'src/config/fixed-times'; +import { useEvmChain } from 'src/hooks/evm/use-evm-chains.hook'; +import { useAppStateStatus } from 'src/hooks/use-app-state-status.hook'; +import { dispatch } from 'src/store'; +import { useEvmAccountChainAssetsSelector } from 'src/store/evm/assets/evm-assets-selectors'; +import { processLoadedEvmCollectiblesMetadataAction } from 'src/store/evm/collectibles-metadata/evm-collectibles-metadata-actions'; +import { useEvmChainCollectiblesMetadataSelector } from 'src/store/evm/collectibles-metadata/evm-collectibles-metadata-selectors'; +import { buildEvmCollectibleMetadataFromOnChain } from 'src/store/evm/collectibles-metadata/utils'; +import { processLoadedEvmTokensMetadataAction } from 'src/store/evm/tokens-metadata/evm-tokens-metadata-actions'; +import { useEvmChainTokensMetadataSelector } from 'src/store/evm/tokens-metadata/evm-tokens-metadata-selectors'; +import { buildEvmTokenMetadataFromOnChain } from 'src/store/evm/tokens-metadata/utils'; +import { useAccountAddressForEvm } from 'src/store/wallet/wallet-selectors'; +import { EvmAssetStandardEnum } from 'src/token/interfaces/token-metadata.interface'; +import { toEvmNetworkEssentials } from 'src/types/networks'; +import { + dispatchEtherlinkAccountData, + getEtherlinkAccountData, + loadEtherlinkBalancesOnChain, + readContractAssetsBalancesOnChain +} from 'src/utils/evm/etherlink-balances.utils'; +import { getEvmCollectibleMetadata, getEvmTokenMetadata } from 'src/utils/evm/on-chain/metadata'; +import { fromTokenSlug } from 'src/utils/from-token-slug'; +import { useInterval } from 'src/utils/hooks/use-interval'; +import { ETHERLINK_MAINNET_CHAIN_ID } from 'src/utils/rpc/rpc-list'; + +const inFlightMap: Record = {}; +const lastLoadTimestampMap: Record = {}; +/** Slightly below the sync interval, so a tick arriving a few ms early is not skipped for a whole period */ +const REFRESH_THROTTLE = EVM_BALANCES_SYNC_INTERVAL - 5000; +const checkedMetadataSlugs = new Set(); +const inFlightMetadataFetches = new Set(); + +export const useEtherlinkDataLoading = () => { + const evmAddress = useAccountAddressForEvm(); + const etherlinkChain = useEvmChain(ETHERLINK_MAINNET_CHAIN_ID); + + const chainAssets = useEvmAccountChainAssetsSelector(evmAddress, ETHERLINK_MAINNET_CHAIN_ID); + const tokensMetadata = useEvmChainTokensMetadataSelector(ETHERLINK_MAINNET_CHAIN_ID); + const collectiblesMetadata = useEvmChainCollectiblesMetadataSelector(ETHERLINK_MAINNET_CHAIN_ID); + + const isFocused = useIsFocused(); + const [isAppActive, setIsAppActive] = useState(true); + useAppStateStatus({ + onAppActiveState: () => setIsAppActive(true), + onAppInactiveState: () => setIsAppActive(false), + onAppBackgroundState: () => setIsAppActive(false) + }); + + const etherlinkChainRef = useRef(etherlinkChain); + etherlinkChainRef.current = etherlinkChain; + const chainAssetsRef = useRef(chainAssets); + chainAssetsRef.current = chainAssets; + + const refresh = useCallback(async (account: HexString) => { + const chain = etherlinkChainRef.current; + if (!chain) { + return; + } + const currentNetwork = toEvmNetworkEssentials(chain); + + const key = `${account}_${ETHERLINK_MAINNET_CHAIN_ID}`; + if (inFlightMap[key] || Date.now() - (lastLoadTimestampMap[key] ?? 0) < REFRESH_THROTTLE) { + return; + } + inFlightMap[key] = true; + lastLoadTimestampMap[key] = Date.now(); + + try { + try { + const data = await getEtherlinkAccountData(account); + + // Manual assets may be missing from the API response, but their balances must survive the refresh + const chainAssets = chainAssetsRef.current; + const manualAssetsMissingFromApi: typeof chainAssets = {}; + for (const slug in chainAssets) { + if (chainAssets[slug].manual && data.balances[slug] == null) { + manualAssetsMissingFromApi[slug] = chainAssets[slug]; + } + } + + let preservedSlugs: string[] | undefined; + if (Object.keys(manualAssetsMissingFromApi).length > 0) { + const manualResult = await readContractAssetsBalancesOnChain( + currentNetwork, + account, + manualAssetsMissingFromApi + ); + Object.assign(data.balances, manualResult.balances); + preservedSlugs = manualResult.failed; + } + + dispatchEtherlinkAccountData({ account, data, preservedSlugs }); + } catch (apiError) { + console.error(apiError); + await loadEtherlinkBalancesOnChain({ + network: currentNetwork, + account, + knownAssets: chainAssetsRef.current + }); + } + } finally { + inFlightMap[key] = false; + } + }, []); + + const hasNetwork = etherlinkChain != null; + + useInterval( + () => { + if (isFocused && isAppActive && evmAddress && hasNetwork) { + refresh(evmAddress); + } + }, + EVM_BALANCES_SYNC_INTERVAL, + [isFocused, isAppActive, evmAddress, hasNetwork] + ); + + useEffect(() => { + const chain = etherlinkChainRef.current; + if (!chain || !evmAddress) { + return; + } + const currentNetwork = toEvmNetworkEssentials(chain); + + for (const slug in chainAssets) { + const { standard } = chainAssets[slug]; + if (standard === EvmAssetStandardEnum.NATIVE) { + continue; + } + + const checkedKey = `${ETHERLINK_MAINNET_CHAIN_ID}_${slug}`; + if (checkedMetadataSlugs.has(checkedKey) || inFlightMetadataFetches.has(checkedKey)) { + continue; + } + + if (standard === EvmAssetStandardEnum.ERC20) { + if (tokensMetadata[slug]) { + continue; + } + + if (!isAddress(slug)) { + checkedMetadataSlugs.add(checkedKey); + continue; + } + + inFlightMetadataFetches.add(checkedKey); + (async () => { + const metadata = await getEvmTokenMetadata(currentNetwork, slug); + if (metadata == null || metadata.decimals == null) { + checkedMetadataSlugs.add(checkedKey); + + return; + } + + dispatch( + processLoadedEvmTokensMetadataAction({ + chainId: ETHERLINK_MAINNET_CHAIN_ID, + metadata: { [slug]: buildEvmTokenMetadataFromOnChain(slug, metadata, metadata.decimals) } + }) + ); + checkedMetadataSlugs.add(checkedKey); + })() + .catch(error => console.error(error)) + .finally(() => { + inFlightMetadataFetches.delete(checkedKey); + }); + } else { + if (collectiblesMetadata[slug]) { + continue; + } + + const [contract, tokenId] = fromTokenSlug(slug); + if (!isAddress(contract)) { + checkedMetadataSlugs.add(checkedKey); + continue; + } + + inFlightMetadataFetches.add(checkedKey); + (async () => { + const metadata = await getEvmCollectibleMetadata(currentNetwork, contract, tokenId, standard); + if (metadata == null) { + checkedMetadataSlugs.add(checkedKey); + + return; + } + + dispatch( + processLoadedEvmCollectiblesMetadataAction({ + chainId: ETHERLINK_MAINNET_CHAIN_ID, + metadata: { [slug]: buildEvmCollectibleMetadataFromOnChain(contract, tokenId ?? '0', standard, metadata) } + }) + ); + checkedMetadataSlugs.add(checkedKey); + })() + .catch(error => console.error(error)) + .finally(() => { + inFlightMetadataFetches.delete(checkedKey); + }); + } + } + }, [chainAssets, tokensMetadata, collectiblesMetadata, evmAddress, hasNetwork]); +}; diff --git a/src/hooks/use-etherlink-public-client.hook.ts b/src/hooks/evm/use-etherlink-public-client.hook.ts similarity index 100% rename from src/hooks/use-etherlink-public-client.hook.ts rename to src/hooks/evm/use-etherlink-public-client.hook.ts diff --git a/src/hooks/use-evm-chains.hook.ts b/src/hooks/evm/use-evm-chains.hook.ts similarity index 100% rename from src/hooks/use-evm-chains.hook.ts rename to src/hooks/evm/use-evm-chains.hook.ts diff --git a/src/hooks/evm/use-multichain-displayed-tokens.hook.ts b/src/hooks/evm/use-multichain-displayed-tokens.hook.ts new file mode 100644 index 000000000..20399266b --- /dev/null +++ b/src/hooks/evm/use-multichain-displayed-tokens.hook.ts @@ -0,0 +1,188 @@ +import { ChainIds } from '@taquito/taquito'; +import { BigNumber } from 'bignumber.js'; +import { uniqBy } from 'lodash-es'; +import { useMemo } from 'react'; + +import { TempleChainKind } from 'src/enums/temple-chain-kind.enum'; +import { useTokenExchangeRateGetter } from 'src/hooks/use-token-exchange-rate-getter.hook'; +import { useEvmAccountChainAssetsSelector } from 'src/store/evm/assets/evm-assets-selectors'; +import { useEvmAccountChainBalancesSelector } from 'src/store/evm/balances/evm-balances-selectors'; +import { useEvmChainExchangeRatesSelector } from 'src/store/evm/exchange-rates/evm-exchange-rates-selectors'; +import { useEvmChainTokensMetadataSelector } from 'src/store/evm/tokens-metadata/evm-tokens-metadata-selectors'; +import { useShieldedBalanceSelector } from 'src/store/sapling'; +import { useFiatToUsdRateSelector } from 'src/store/settings/settings-selectors'; +import { useAccountAddressForEvm, useAccountAddressForTezos } from 'src/store/wallet/wallet-selectors'; +import { TEZ_TOKEN_SLUG } from 'src/token/data/tokens-metadata'; +import { EvmAssetStandardEnum, EVM_TOKEN_SLUG } from 'src/token/interfaces/token-metadata.interface'; +import { TokenInterface } from 'src/token/interfaces/token.interface'; +import { getTokenSlug } from 'src/token/utils/token.utils'; +import { ETHERLINK_MAINNET_CHAIN_SPECS } from 'src/types/networks'; +import { useAccountTkeyToken, useCurrentAccountTokens } from 'src/utils/assets/hooks'; +import { getDollarValue } from 'src/utils/balance.utils'; +import { isEvmCollectibleSlug } from 'src/utils/from-token-slug'; +import { isDefined } from 'src/utils/is-defined'; +import { isPositiveNumber } from 'src/utils/number.util'; +import { ETHERLINK_MAINNET_CHAIN_ID } from 'src/utils/rpc/rpc-list'; +import { mutezToTz } from 'src/utils/tezos.util'; +import { useTezosTokenOfCurrentAccount } from 'src/utils/wallet.utils'; + +const etherlinkNativeCurrency = ETHERLINK_MAINNET_CHAIN_SPECS.currency; + +export interface MultichainDisplayedToken { + slug: string; + chainKind: TempleChainKind; + chainId: string | number; + symbol: string; + name: string; + iconUri?: string; + atomicBalance: string; + decimals: number; + fiatValue: number | undefined; + /** Set only on the TEZ gas-token row, whose atomicBalance is the combined public + shielded amount */ + shieldedAtomicBalance?: string; + original?: TokenInterface; +} + +const buildTezosDisplayedToken = ( + token: TokenInterface, + fiatValue: number | undefined, + shieldedAtomicBalance?: string +): MultichainDisplayedToken => ({ + slug: getTokenSlug(token), + chainKind: TempleChainKind.Tezos, + chainId: ChainIds.MAINNET, + symbol: token.symbol, + name: token.name, + iconUri: token.thumbnailUri, + atomicBalance: token.balance, + decimals: token.decimals, + fiatValue, + shieldedAtomicBalance, + original: token +}); + +const getAtomicBalanceAsNumber = ({ atomicBalance, decimals }: MultichainDisplayedToken) => + mutezToTz(new BigNumber(atomicBalance), decimals).toNumber(); + +interface SortableDisplayedToken { + token: MultichainDisplayedToken; + balanceForSort: number; +} + +const compareDisplayedTokens = (a: SortableDisplayedToken, b: SortableDisplayedToken) => { + const aFiat = a.token.fiatValue ?? 0; + const bFiat = b.token.fiatValue ?? 0; + + if (aFiat !== bFiat) { + return bFiat - aFiat; + } + + if (a.balanceForSort !== b.balanceForSort) { + return b.balanceForSort - a.balanceForSort; + } + + return a.token.symbol.localeCompare(b.token.symbol); +}; + +export const useMultichainDisplayedTokens = (): MultichainDisplayedToken[] => { + const tezosToken = useTezosTokenOfCurrentAccount(); + const tkeyToken = useAccountTkeyToken(); + const visibleTokensList = useCurrentAccountTokens(true); + const getExchangeRate = useTokenExchangeRateGetter(); + + const tezosAddress = useAccountAddressForTezos(); + const evmAddress = useAccountAddressForEvm(); + const evmBalances = useEvmAccountChainBalancesSelector(evmAddress, ETHERLINK_MAINNET_CHAIN_ID); + const evmAssets = useEvmAccountChainAssetsSelector(evmAddress, ETHERLINK_MAINNET_CHAIN_ID); + const evmMetadata = useEvmChainTokensMetadataSelector(ETHERLINK_MAINNET_CHAIN_ID); + const evmExchangeRates = useEvmChainExchangeRatesSelector(ETHERLINK_MAINNET_CHAIN_ID); + const fiatToUsdRate = useFiatToUsdRateSelector(); + const shieldedBalanceMutez = useShieldedBalanceSelector(); + + return useMemo(() => { + const accountTezosTokens = tezosAddress == null ? [] : [tezosToken, tkeyToken].concat(visibleTokensList); + const tezosTokens = uniqBy(accountTezosTokens, getTokenSlug).map(token => { + const slug = getTokenSlug(token); + const isGasToken = slug === TEZ_TOKEN_SLUG; + // The gas-token row displays and sorts by the combined public + shielded balance + const balance = isGasToken ? new BigNumber(token.balance).plus(shieldedBalanceMutez).toFixed() : token.balance; + const exchangeRate = token.exchangeRate ?? getExchangeRate(slug); + const fiatValue = isDefined(exchangeRate) + ? getDollarValue(balance, token.decimals, exchangeRate).toNumber() + : undefined; + + return buildTezosDisplayedToken( + { ...token, balance, exchangeRate }, + fiatValue, + isGasToken ? shieldedBalanceMutez : undefined + ); + }); + + const evmTokens: MultichainDisplayedToken[] = []; + + // Manually added assets are displayed even with a zero balance + const evmSlugs = new Set(Object.keys(evmBalances)); + for (const slug in evmAssets) { + if (evmAssets[slug].manual) { + evmSlugs.add(slug); + } + } + + for (const slug of evmSlugs) { + const atomicBalance = evmBalances[slug] ?? '0'; + if (!isPositiveNumber(atomicBalance) && evmAssets[slug]?.manual !== true) { + continue; + } + + const isNative = slug === EVM_TOKEN_SLUG; + const standard = isNative + ? EvmAssetStandardEnum.NATIVE + : evmAssets[slug]?.standard ?? evmMetadata[slug]?.standard; + const isFungible = standard === EvmAssetStandardEnum.NATIVE || standard === EvmAssetStandardEnum.ERC20; + if (!isFungible || isEvmCollectibleSlug(slug)) { + continue; + } + + const nativeCurrency = isNative ? etherlinkNativeCurrency : undefined; + const metadata = evmMetadata[slug]; + const decimals = nativeCurrency?.decimals ?? metadata?.decimals; + if (decimals == null) { + continue; + } + const symbol = nativeCurrency?.symbol ?? metadata?.symbol ?? ''; + const usdRate = evmExchangeRates[slug]; + const fiatRate = isDefined(usdRate) && isDefined(fiatToUsdRate) ? usdRate * fiatToUsdRate : undefined; + const fiatValue = isDefined(fiatRate) ? getDollarValue(atomicBalance, decimals, fiatRate).toNumber() : undefined; + + evmTokens.push({ + slug, + chainKind: TempleChainKind.EVM, + chainId: ETHERLINK_MAINNET_CHAIN_ID, + symbol, + name: nativeCurrency?.name ?? metadata?.name ?? symbol, + iconUri: nativeCurrency?.iconURL ?? metadata?.iconURL, + atomicBalance, + decimals, + fiatValue + }); + } + + return tezosTokens + .concat(evmTokens) + .map(token => ({ token, balanceForSort: getAtomicBalanceAsNumber(token) })) + .sort(compareDisplayedTokens) + .map(({ token }) => token); + }, [ + tezosAddress, + tezosToken, + tkeyToken, + visibleTokensList, + getExchangeRate, + shieldedBalanceMutez, + evmBalances, + evmAssets, + evmMetadata, + evmExchangeRates, + fiatToUsdRate + ]); +}; diff --git a/src/hooks/use-images-stack.ts b/src/hooks/use-images-stack.ts index 8e49ca8f8..c28ead74b 100644 --- a/src/hooks/use-images-stack.ts +++ b/src/hooks/use-images-stack.ts @@ -24,7 +24,7 @@ export const useTokenImagesStack = (url: string, preferDirectSource = false) => return useImagesStack(sourcesStack); }; -const useImagesStack = (sourcesStack: string[]) => { +export const useImagesStack = (sourcesStack: string[]) => { const emptyStack = sourcesStack.length < 1; const [isLoading, setIsLoading] = useState(emptyStack === false); diff --git a/src/hooks/use-token-standard.ts b/src/hooks/use-token-standard.ts index 72f435daa..85002d3fb 100644 --- a/src/hooks/use-token-standard.ts +++ b/src/hooks/use-token-standard.ts @@ -1,6 +1,6 @@ import { startTransition, useEffect, useState } from 'react'; -import { TokenStandardsEnum } from 'src/token/interfaces/token-metadata.interface'; +import { TezosTokenStandardsEnum } from 'src/token/interfaces/token-metadata.interface'; import { getTokenStandard } from 'src/token/utils/token.utils'; import { useReadOnlyTezosToolkit } from './use-read-only-tezos-toolkit.hook'; @@ -9,7 +9,7 @@ export const useTokenStandard = (address: string) => { const tezos = useReadOnlyTezosToolkit(); const [loading, setLoading] = useState(false); - const [tokenStandard, setTokenStandard] = useState(TokenStandardsEnum.Fa12); + const [tokenStandard, setTokenStandard] = useState(TezosTokenStandardsEnum.Fa12); useEffect(() => { startTransition(async () => { diff --git a/src/hooks/use-total-balance.ts b/src/hooks/use-total-balance.ts index 941a55ec7..464eb97f3 100644 --- a/src/hooks/use-total-balance.ts +++ b/src/hooks/use-total-balance.ts @@ -1,35 +1,110 @@ import { BigNumber } from 'bignumber.js'; import { useMemo } from 'react'; +import { VisibilityEnum } from 'src/enums/visibility.enum'; +import { Account } from 'src/interfaces/account.interfaces'; import { useUsdToTokenRates } from 'src/store/currency/currency-selectors'; +import { useEvmAccountChainBalancesSelector } from 'src/store/evm/balances/evm-balances-selectors'; +import { useEvmChainExchangeRatesSelector } from 'src/store/evm/exchange-rates/evm-exchange-rates-selectors'; +import { useEvmChainTokensMetadataSelector } from 'src/store/evm/tokens-metadata/evm-tokens-metadata-selectors'; +import { useFiatToUsdRateSelector } from 'src/store/settings/settings-selectors'; +import { useTokensMetadataSelector } from 'src/store/tokens-metadata/tokens-metadata-selectors'; +import { + useAccountAddressForEvm, + useStoredTokensOfKnownAccountSelector, + useTezosBalanceOfKnownAccountSelector +} from 'src/store/wallet/wallet-selectors'; +import { getAccountAddressForEvm } from 'src/utils/account.utils'; import { useCurrentAccountTokens } from 'src/utils/assets/hooks'; +import { isEvmCollectibleSlug } from 'src/utils/from-token-slug'; +import { ETHERLINK_MAINNET_CHAIN_ID } from 'src/utils/rpc/rpc-list'; import { TEZ_TOKEN_DECIMALS } from '../token/data/tokens-metadata'; import { getTokenSlug } from '../token/utils/token.utils'; import { getDollarValue } from '../utils/balance.utils'; -import { tzToMutez } from '../utils/tezos.util'; -import { useTezosToken, useTezosTokenOfCurrentAccount } from '../utils/wallet.utils'; +import { ZERO } from '../utils/number.util'; +import { useTezosTokenOfCurrentAccount } from '../utils/wallet.utils'; +const useEvmDollarBalance = (evmAddress: HexString | undefined) => { + const balances = useEvmAccountChainBalancesSelector(evmAddress, ETHERLINK_MAINNET_CHAIN_ID); + const metadata = useEvmChainTokensMetadataSelector(ETHERLINK_MAINNET_CHAIN_ID); + const exchangeRates = useEvmChainExchangeRatesSelector(ETHERLINK_MAINNET_CHAIN_ID); + + return useMemo(() => { + let dollarValue = new BigNumber(0); + + for (const slug in balances) { + if (isEvmCollectibleSlug(slug)) { + continue; + } + + const usdRate = exchangeRates[slug]; + const decimals = metadata[slug]?.decimals; + if (usdRate == null || decimals == null) { + continue; + } + + dollarValue = dollarValue.plus(getDollarValue(balances[slug], decimals, usdRate)); + } + + return dollarValue; + }, [balances, metadata, exchangeRates]); +}; + +/** Total value of the current account's visible assets across all chains, in USD */ export const useTotalBalance = () => { const exchangeRates = useUsdToTokenRates(); const visibleTokens = useCurrentAccountTokens(true); const tezosToken = useTezosTokenOfCurrentAccount(); - const totalBalance = useMemo(() => { + const evmAddress = useAccountAddressForEvm(); + const evmDollarBalance = useEvmDollarBalance(evmAddress); + + return useMemo(() => { let dollarValue = new BigNumber(0); for (const token of visibleTokens) { const exchangeRate = exchangeRates[getTokenSlug(token)]; - const tokenDollarValue = getDollarValue(token.balance, token.decimals, exchangeRate); - dollarValue = dollarValue.plus(tokenDollarValue); + dollarValue = dollarValue.plus(getDollarValue(token.balance, token.decimals, exchangeRate)); } const tezosDollarValue = getDollarValue(tezosToken.balance, tezosToken.decimals, exchangeRates.tez); - dollarValue = dollarValue.plus(tezosDollarValue); - return tzToMutez(dollarValue.dividedBy(exchangeRates.tez), TEZ_TOKEN_DECIMALS); - }, [tezosToken, visibleTokens, exchangeRates]); + return dollarValue.plus(tezosDollarValue).plus(evmDollarBalance); + }, [tezosToken, visibleTokens, exchangeRates, evmDollarBalance]); +}; + +export const useTotalFiatBalanceOfAccount = (account: Account) => { + const exchangeRates = useUsdToTokenRates(); + const metadatas = useTokensMetadataSelector(); + const tezosBalance = useTezosBalanceOfKnownAccountSelector(account.id); + const storedTokens = useStoredTokensOfKnownAccountSelector(account.id); + const fiatToUsdRate = useFiatToUsdRateSelector(); + + const evmDollarBalance = useEvmDollarBalance(getAccountAddressForEvm(account)); + + return useMemo(() => { + if (fiatToUsdRate == null) { + return ZERO; + } + + let dollarValue = getDollarValue(tezosBalance, TEZ_TOKEN_DECIMALS, exchangeRates.tez); + + for (const token of storedTokens) { + if (token.visibility !== VisibilityEnum.Visible) { + continue; + } + + const decimals = metadatas[token.slug]?.decimals; + const exchangeRate = exchangeRates[token.slug]; + if (decimals == null || exchangeRate == null) { + continue; + } + + dollarValue = dollarValue.plus(getDollarValue(token.balance, decimals, exchangeRate)); + } - return useTezosToken(totalBalance.toFixed()); + return dollarValue.plus(evmDollarBalance).times(fiatToUsdRate); + }, [tezosBalance, storedTokens, metadatas, exchangeRates, evmDollarBalance, fiatToUsdRate]); }; diff --git a/src/interfaces/send-asset-action-payload.interface.ts b/src/interfaces/send-asset-action-payload.interface.ts index 12e48cd07..847ca8163 100644 --- a/src/interfaces/send-asset-action-payload.interface.ts +++ b/src/interfaces/send-asset-action-payload.interface.ts @@ -1,7 +1,7 @@ -import { TokenMetadataInterface } from '../token/interfaces/token-metadata.interface'; +import { TezosTokenMetadata } from '../token/interfaces/token-metadata.interface'; export interface SendAssetActionPayloadInterface { - asset: TokenMetadataInterface; + asset: TezosTokenMetadata; receiverPublicKeyHash: string; amount: string; } diff --git a/src/modals/collectible-modal/utils/use-burn-collectible.hook.ts b/src/modals/collectible-modal/utils/use-burn-collectible.hook.ts index 225113529..4822b08cb 100644 --- a/src/modals/collectible-modal/utils/use-burn-collectible.hook.ts +++ b/src/modals/collectible-modal/utils/use-burn-collectible.hook.ts @@ -4,10 +4,10 @@ import { useDispatch } from 'react-redux'; import { LIMIT_NFT_FEATURES } from 'src/config/system'; import { sendAssetActions } from 'src/store/wallet/wallet-actions'; -import { TokenMetadataInterface } from 'src/token/interfaces/token-metadata.interface'; +import { TezosTokenMetadata } from 'src/token/interfaces/token-metadata.interface'; import { BURN_ADDRESS } from 'src/utils/known-addresses'; -export const useBurnCollectible = (collectible: TokenMetadataInterface | nullish) => { +export const useBurnCollectible = (collectible: TezosTokenMetadata | nullish) => { const dispatch = useDispatch(); return useMemo(() => { diff --git a/src/modals/manage-earn-opportunity-modal/stake-form/create-stableswap-stake-transfers-params.ts b/src/modals/manage-earn-opportunity-modal/stake-form/create-stableswap-stake-transfers-params.ts index d7b8d3f83..d88adf481 100644 --- a/src/modals/manage-earn-opportunity-modal/stake-form/create-stableswap-stake-transfers-params.ts +++ b/src/modals/manage-earn-opportunity-modal/stake-form/create-stableswap-stake-transfers-params.ts @@ -6,7 +6,7 @@ import { StableswapFarm, StableswapPoolVersion } from 'src/apis/quipuswap-stakin import { Route3TokenStandardEnum } from 'src/enums/route3.enum'; import { getTransactionTimeoutDate } from 'src/op-params/op-params.utils'; import { TEZ_TOKEN_SLUG, WTEZ_TOKEN_METADATA } from 'src/token/data/tokens-metadata'; -import { TokenStandardsEnum } from 'src/token/interfaces/token-metadata.interface'; +import { TezosTokenStandardsEnum } from 'src/token/interfaces/token-metadata.interface'; import { TokenInterface } from 'src/token/interfaces/token.interface'; import { toTokenSlug } from 'src/token/utils/token.utils'; import { getReadOnlyContract } from 'src/utils/rpc/contract.utils'; @@ -79,7 +79,9 @@ export const createStableswapStakeTransfersParams = async ( accountPkh, { standard: - tokenToInvest.standard === TokenStandardsEnum.Fa2 ? Route3TokenStandardEnum.fa2 : Route3TokenStandardEnum.fa12, + tokenToInvest.standard === TezosTokenStandardsEnum.Fa2 + ? Route3TokenStandardEnum.fa2 + : Route3TokenStandardEnum.fa12, contract: tokenToInvest.address, tokenId: tokenToInvest.id.toString() }, diff --git a/src/navigator/enums/modals.enum.ts b/src/navigator/enums/modals.enum.ts index 4f3c9ed87..ecf20cbec 100644 --- a/src/navigator/enums/modals.enum.ts +++ b/src/navigator/enums/modals.enum.ts @@ -1,7 +1,7 @@ import { Account } from 'src/interfaces/account.interfaces'; import { Contact } from 'src/interfaces/contact.interface'; import { ConfirmationModalParams } from 'src/modals/confirmation-modal/confirmation-modal.params'; -import { TokenMetadataInterface } from 'src/token/interfaces/token-metadata.interface'; +import { TezosTokenMetadata } from 'src/token/interfaces/token-metadata.interface'; import { EarnOpportunity } from 'src/types/earn-opportunity.types'; export enum ModalsEnum { @@ -37,8 +37,8 @@ export enum ModalsEnum { } export type ModalsParamList = { - [ModalsEnum.Receive]: { token: TokenMetadataInterface }; - [ModalsEnum.Send]: { token: TokenMetadataInterface; receiverPublicKeyHash?: string }; + [ModalsEnum.Receive]: { token: TezosTokenMetadata }; + [ModalsEnum.Send]: { token: TezosTokenMetadata; receiverPublicKeyHash?: string }; [ModalsEnum.AddAsset]: undefined; [ModalsEnum.RenameAccount]: { account: Account }; [ModalsEnum.SelectBaker]: undefined; diff --git a/src/navigator/main-stack.tsx b/src/navigator/main-stack.tsx index 2ea2263bb..51b2c473d 100644 --- a/src/navigator/main-stack.tsx +++ b/src/navigator/main-stack.tsx @@ -12,8 +12,8 @@ import { ScreenStatusBar } from 'src/components/screen-status-bar/screen-status- import { emptyFn } from 'src/config/general'; import { transparent } from 'src/config/styles'; import { LIMIT_FIN_FEATURES } from 'src/config/system'; +import { useEvmChains } from 'src/hooks/evm/use-evm-chains.hook'; import { useMainHooks } from 'src/hooks/main-hooks'; -import { useEvmChains } from 'src/hooks/use-evm-chains.hook'; import { useTezosChains } from 'src/hooks/use-tezos-chains.hook'; import { SecurityUpdate } from 'src/modals/security-update'; import { About } from 'src/screens/about/about'; diff --git a/src/screens/collectibles-home/collectibles-home.tsx b/src/screens/collectibles-home/collectibles-home.tsx index e2a77f150..9f786b0aa 100644 --- a/src/screens/collectibles-home/collectibles-home.tsx +++ b/src/screens/collectibles-home/collectibles-home.tsx @@ -2,6 +2,7 @@ import BottomSheet from '@gorhom/bottom-sheet'; import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { ActivityIndicator, ListRenderItem, Text, TouchableOpacity, View } from 'react-native'; import { FlatList } from 'react-native-gesture-handler'; +import { useSharedValue } from 'react-native-reanimated'; import { CurrentAccountDropdown } from 'src/components/account-dropdown/current-account-dropdown'; import { CheckboxIcon } from 'src/components/checkbox-icon/checkbox-icon'; @@ -12,6 +13,8 @@ import { IconNameEnum } from 'src/components/icon/icon-name.enum'; import { TouchableIcon } from 'src/components/icon/touchable-icon/touchable-icon'; import { ImageWithIndicator } from 'src/components/image'; import { Search } from 'src/components/search/search'; +import { TempleChainKind } from 'src/enums/temple-chain-kind.enum'; +import { useEtherlinkDataLoading } from 'src/hooks/evm/use-etherlink-data-loading.hook'; import { useFilteredAssetsList } from 'src/hooks/use-filtered-assets-list.hook'; import { ScreensEnum } from 'src/navigator/enums/screens.enum'; import { useNavigateToScreen } from 'src/navigator/hooks/use-navigation.hook'; @@ -21,12 +24,15 @@ import { useCreatedCollectionsSelector } from 'src/store/collectons/collections- import { Collection } from 'src/store/collectons/collections-state'; import { switchIsShowCollectibleInfoAction } from 'src/store/settings/settings-actions'; import { useIsShowCollectibleInfoSelector } from 'src/store/settings/settings-selectors'; -import { useAccountAddressForTezos } from 'src/store/wallet/wallet-selectors'; +import { useAccountAddressForEvm, useAccountAddressForTezos } from 'src/store/wallet/wallet-selectors'; import { formatSize } from 'src/styles/format-size'; import { usePageAnalytic } from 'src/utils/analytics/use-analytics.hook'; -import { useCurrentAccountCollectibles } from 'src/utils/assets/hooks'; +import { useCurrentAccountCollectibles, useCurrentAccountEvmCollectibles } from 'src/utils/assets/hooks'; +import { DisplayedCollectible } from 'src/utils/assets/types'; import { useDidUpdate } from 'src/utils/hooks'; import { formatObjktLogoUri } from 'src/utils/image.utils'; +import { isString } from 'src/utils/is-string'; +import { isAssetSearched } from 'src/utils/token-metadata.utils'; import { CollectiblesList } from './collectibles-list'; import { useCollectiblesHomeStyles, useCollectionButtonStyles } from './styles'; @@ -36,10 +42,14 @@ export const CollectiblesHome = memo(() => { usePageAnalytic(ScreensEnum.CollectiblesHome); const collections = useCreatedCollectionsSelector(); - const collectibles = useCurrentAccountCollectibles(true); + const tezosCollectibles = useCurrentAccountCollectibles(true); + const evmCollectibles = useCurrentAccountEvmCollectibles(); const tezosAddress = useAccountAddressForTezos(); + const evmAddress = useAccountAddressForEvm(); - if (!tezosAddress) { + useEtherlinkDataLoading(); + + if (!tezosAddress && !evmAddress) { throw new DeadEndBoundaryError(); } @@ -51,6 +61,8 @@ export const CollectiblesHome = memo(() => { const [headerHeight, setHeaderHeight] = useState(0); const [profileHeight, setProfileHeight] = useState(0); + const hasCollections = collections.length > 0; + const snapPoints = useMemo(() => { const firstSnapPoint = screenHeight - headerHeight; if (firstSnapPoint < 1) { @@ -59,14 +71,68 @@ export const CollectiblesHome = memo(() => { const secondSnapPoint = firstSnapPoint + profileHeight; - return firstSnapPoint === secondSnapPoint ? [firstSnapPoint] : [firstSnapPoint, secondSnapPoint]; - }, [screenHeight, headerHeight, profileHeight]); + return !hasCollections || firstSnapPoint === secondSnapPoint ? [firstSnapPoint] : [firstSnapPoint, secondSnapPoint]; + }, [screenHeight, headerHeight, profileHeight, hasCollections]); + + const bottomSheetRef = useRef(null); + const animatedIndex = useSharedValue(-1); + const firstSnapPoint = snapPoints?.[0]; + // gorhom v5 + reanimated v4: the mount animation sometimes never starts, leaving the + // sheet stuck closed off-screen (animatedIndex stays -1), detect it and snap into place manually + useEffect(() => { + if (firstSnapPoint == null) { + return; + } + + let ticks = 0; + const id = setInterval(() => { + if (animatedIndex.value > -0.9 || ++ticks > 10) { + clearInterval(id); + + return; + } + + bottomSheetRef.current?.snapToPosition(firstSnapPoint); + }, 300); + + return () => clearInterval(id); + }, [firstSnapPoint, animatedIndex]); useEffect(() => { - dispatch(loadCollectionsActions.submit(tezosAddress)); + if (tezosAddress != null) { + dispatch(loadCollectionsActions.submit(tezosAddress)); + } }, [tezosAddress]); - const { setSearchValue, filteredAssetsList } = useFilteredAssetsList(collectibles); + const { + setSearchValue, + searchValue, + filteredAssetsList: filteredTezosCollectibles + } = useFilteredAssetsList(tezosCollectibles); + + const collectibles = useMemo(() => { + const searchValueLowercased = searchValue?.toLowerCase(); + const filteredEvmCollectibles = isString(searchValueLowercased) + ? evmCollectibles.filter(({ metadata, tokenId }) => + isAssetSearched( + { + name: metadata?.collectibleName ?? metadata?.name ?? tokenId, + symbol: metadata?.symbol ?? '', + address: metadata?.address + }, + searchValueLowercased + ) + ) + : evmCollectibles; + + const tezosDisplayed: DisplayedCollectible[] = filteredTezosCollectibles.map(asset => ({ + chainKind: TempleChainKind.Tezos, + slug: asset.slug, + asset + })); + + return tezosDisplayed.concat(filteredEvmCollectibles); + }, [filteredTezosCollectibles, evmCollectibles, searchValue]); const handleSwitchShowInfo = () => void dispatch(switchIsShowCollectibleInfoAction()); @@ -116,6 +182,8 @@ export const CollectiblesHome = memo(() => { {snapPoints ? ( { - + ) : null} diff --git a/src/screens/collectibles-home/collectibles-list/collectible-item/evm-collectible-item.tsx b/src/screens/collectibles-home/collectibles-list/collectible-item/evm-collectible-item.tsx new file mode 100644 index 000000000..7dd77d837 --- /dev/null +++ b/src/screens/collectibles-home/collectibles-list/collectible-item/evm-collectible-item.tsx @@ -0,0 +1,87 @@ +import FastImage from '@d11/react-native-fast-image'; +import React, { memo, useMemo } from 'react'; +import { StyleProp, Text, View, ViewStyle } from 'react-native'; + +import { ActivityIndicator } from 'src/components/activity-indicator'; +import { BrokenImage } from 'src/components/broken-image'; +import { useCollectibleImageStyles } from 'src/components/collectible-image/styles'; +import { CryptoLogo } from 'src/components/crypto-logo'; +import { CryptoLogoNameEnum } from 'src/components/crypto-logo/logo-name.enum'; +import { useImagesStack } from 'src/hooks/use-images-stack'; +import { formatSize } from 'src/styles/format-size'; +import { EvmDisplayedCollectible } from 'src/utils/assets/types'; +import { buildEvmCollectibleImagesStack } from 'src/utils/image.utils'; + +import { Balance } from './balance'; +import { useCollectibleItemStyles, useEvmCollectibleChainBadgeStyles } from './styles'; + +interface Props { + collectible: EvmDisplayedCollectible; + size: number; + showInfo?: boolean; + style?: StyleProp; +} + +export const EvmCollectibleItem = memo(({ collectible, size, showInfo = false, style }) => { + const styles = useCollectibleItemStyles(); + const badgeStyles = useEvmCollectibleChainBadgeStyles(); + + const { metadata, tokenId, balance } = collectible; + const displayName = metadata?.collectibleName ?? metadata?.name ?? tokenId; + const imageUri = metadata?.image ?? metadata?.iconURL; + + return ( + + + + + {showInfo ? : null} + + + + + + + {showInfo ? ( + + + {displayName} + + + + + ) : null} + + ); +}); + +interface EvmCollectibleImageProps { + uri?: string; + size: number; +} + +const EvmCollectibleImage = memo(({ uri, size }) => { + const styles = useCollectibleImageStyles(); + + const sourcesStack = useMemo(() => buildEvmCollectibleImagesStack(uri), [uri]); + + const { src, isLoading, isStackFailed, onSuccess, onFail } = useImagesStack(sourcesStack); + + if (isStackFailed) { + return ; + } + + return ( + <> + + + {isLoading ? : null} + + ); +}); diff --git a/src/screens/collectibles-home/collectibles-list/collectible-item/index.tsx b/src/screens/collectibles-home/collectibles-list/collectible-item/index.tsx index 27e743f7f..7d9f5815a 100644 --- a/src/screens/collectibles-home/collectibles-list/collectible-item/index.tsx +++ b/src/screens/collectibles-home/collectibles-list/collectible-item/index.tsx @@ -24,11 +24,11 @@ interface Props { slug: string; collectible: TokenInterface; size: number; - isShowInfo?: boolean; + showInfo?: boolean; style?: StyleProp; } -export const CollectibleItem = memo(({ slug, collectible, size, isShowInfo = false, style }) => { +export const CollectibleItem = memo(({ slug, collectible, size, showInfo = false, style }) => { const navigateToModal = useNavigateToModal(); const styles = useCollectibleItemStyles(); @@ -79,10 +79,10 @@ export const CollectibleItem = memo(({ slug, collectible, size, isShowInf areDetailsLoading={areDetailsLoading && details === undefined} /> - {isShowInfo && isDefined(balance) ? : null} + {showInfo && isDefined(balance) ? : null} - {isShowInfo ? ( + {showInfo ? ( {collectible.name} diff --git a/src/screens/collectibles-home/collectibles-list/collectible-item/styles.ts b/src/screens/collectibles-home/collectibles-list/collectible-item/styles.ts index cf61a5cd2..82344279e 100644 --- a/src/screens/collectibles-home/collectibles-list/collectible-item/styles.ts +++ b/src/screens/collectibles-home/collectibles-list/collectible-item/styles.ts @@ -49,3 +49,19 @@ export const useBalanceStyles = createUseStylesMemoized(({ typography }) => ({ color: basicLightColors.white } })); + +export const useEvmCollectibleChainBadgeStyles = createUseStylesMemoized(({ colors }) => ({ + badge: { + position: 'absolute', + right: formatSize(4), + bottom: formatSize(4), + width: formatSize(16), + height: formatSize(16), + alignItems: 'center', + justifyContent: 'center', + borderRadius: formatSize(8), + borderWidth: formatSize(0.8), + borderColor: colors.lines, + backgroundColor: colors.pageBG + } +})); diff --git a/src/screens/collectibles-home/collectibles-list/index.tsx b/src/screens/collectibles-home/collectibles-list/index.tsx index 0291ce123..7cce65bbd 100644 --- a/src/screens/collectibles-home/collectibles-list/index.tsx +++ b/src/screens/collectibles-home/collectibles-list/index.tsx @@ -11,33 +11,36 @@ import { } from 'src/components/screen-container/screen-container.styles'; import { SIDEBAR_WIDTH } from 'src/config/styles'; import { LIMIT_NFT_FEATURES } from 'src/config/system'; +import { TempleChainKind } from 'src/enums/temple-chain-kind.enum'; import { useAreMetadatasLoadingSelector } from 'src/store/tokens-metadata/tokens-metadata-selectors'; import { formatSize } from 'src/styles/format-size'; -import { UsableAccountAsset } from 'src/utils/assets/types'; +import { DisplayedCollectible } from 'src/utils/assets/types'; +import { toChainAssetSlug } from 'src/utils/chain-asset-slug'; import { createGetItemLayout } from 'src/utils/flat-list.utils'; import { useCollectiblesGridStyles } from '../styles'; import { CollectibleItem } from './collectible-item'; +import { EvmCollectibleItem } from './collectible-item/evm-collectible-item'; import { useCollectibleItemStyles } from './collectible-item/styles'; import { CollectiblesListStyles, GRID_GAP } from './styles'; interface Props { - collectibles: UsableAccountAsset[]; - isShowInfo: boolean; + collectibles: DisplayedCollectible[]; + showInfo: boolean; } const ITEMS_PER_ROW = 3; const GRID_GAPS_TOTAL_WIDTH = GRID_GAP * (ITEMS_PER_ROW - 1); -const keyExtractor = (item: UsableAccountAsset) => item.slug; +const keyExtractor = (item: DisplayedCollectible) => + item.chainKind === TempleChainKind.EVM ? toChainAssetSlug(item.chainKind, item.chainId, item.slug) : item.slug; -export const CollectiblesList = memo(({ collectibles, isShowInfo }) => { +export const CollectiblesList = memo(({ collectibles, showInfo }) => { const screenStyles = useScreenContainerStyles(); const itemStyles = useCollectibleItemStyles(); - const areMetadatasLoading = useAreMetadatasLoadingSelector(); - const isSyncing = areMetadatasLoading; + const isSyncing = useAreMetadatasLoadingSelector(); const { width: windowWidth } = useWindowDimensions(); @@ -51,8 +54,8 @@ export const CollectiblesList = memo(({ collectibles, isShowInfo }) => { const getItemLayout = useMemo( () => - createGetItemLayout( - isShowInfo + createGetItemLayout( + showInfo ? itemSize + itemStyles.description.paddingTop + itemStyles.description.paddingBottom + @@ -61,21 +64,33 @@ export const CollectiblesList = memo(({ collectibles, isShowInfo }) => { : itemSize, GRID_GAP ), - [isShowInfo, itemSize, itemStyles] + [showInfo, itemSize, itemStyles] ); - const renderItem: ListRenderItem = useCallback( - ({ item: collectible, index }) => ( - - ), - [itemSize, isShowInfo] + const renderItem: ListRenderItem = useCallback( + ({ item: collectible, index }) => { + const style = (index + 1) % ITEMS_PER_ROW !== 0 ? CollectiblesListStyles.marginRight : undefined; + + return collectible.chainKind === TempleChainKind.EVM ? ( + + ) : ( + + ); + }, + [itemSize, showInfo] ); return ( diff --git a/src/screens/d-apps/d-apps.tsx b/src/screens/d-apps/d-apps.tsx index 3e9e6d144..3b5c0d425 100644 --- a/src/screens/d-apps/d-apps.tsx +++ b/src/screens/d-apps/d-apps.tsx @@ -49,7 +49,7 @@ export const DApps = () => { const { maxApr: farmsMaxApr } = useUserFarmingStats(); const { maxApr: savingsMaxApr } = useUserSavingsStats(); - const { balance } = useTotalBalance(); + const totalBalance = useTotalBalance(); const maxRoundedApr = useMemo( () => formatOptionalPercentage(farmsMaxApr && savingsMaxApr && BigNumber.max(farmsMaxApr, savingsMaxApr)), @@ -146,7 +146,7 @@ export const DApps = () => { onPress={() => navigateToScreen({ screen: ScreensEnum.Earn })} testID={DAppsSelectors.earnButton} testIDProperties={{ - isZeroBalance: new BigNumber(balance).isLessThanOrEqualTo(0) + isZeroBalance: totalBalance.isLessThanOrEqualTo(0) }} /> diff --git a/src/screens/debug/debug.tsx b/src/screens/debug/debug.tsx index 4b02c2316..fe81d8b1e 100644 --- a/src/screens/debug/debug.tsx +++ b/src/screens/debug/debug.tsx @@ -10,6 +10,7 @@ import { usePageAnalytic } from 'src/utils/analytics/use-analytics.hook'; import { AsyncStorageDetails } from './async-storage-details'; import { EtherlinkFallbackDemo } from './etherlink-fallback-demo'; +import { EtherlinkManualAssetDebug } from './etherlink-manual-asset-debug'; import { ImportWatchOnlyDebug } from './import-watch-only-debug/import-watch-only-debug'; import { TezosFallbackDemo } from './tezos-fallback-demo'; @@ -43,6 +44,8 @@ export const Debug: FC = () => { + + ); diff --git a/src/screens/debug/etherlink-fallback-demo.tsx b/src/screens/debug/etherlink-fallback-demo.tsx index 390b35b2d..11ff895dd 100644 --- a/src/screens/debug/etherlink-fallback-demo.tsx +++ b/src/screens/debug/etherlink-fallback-demo.tsx @@ -1,7 +1,7 @@ import { useCallback } from 'react'; import { WatchBlocksReturnType } from 'viem'; -import { useEtherlinkPublicClient } from 'src/hooks/use-etherlink-public-client.hook'; +import { useEtherlinkPublicClient } from 'src/hooks/evm/use-etherlink-public-client.hook'; import { FallbackDemo, FallbackDemoProps } from './fallback-demo'; diff --git a/src/screens/debug/etherlink-manual-asset-debug.tsx b/src/screens/debug/etherlink-manual-asset-debug.tsx new file mode 100644 index 000000000..a9f5e6035 --- /dev/null +++ b/src/screens/debug/etherlink-manual-asset-debug.tsx @@ -0,0 +1,285 @@ +import { useMemo, useState } from 'react'; +import { Text, TouchableOpacity, View } from 'react-native'; +import { useDispatch } from 'react-redux'; +import { isAddress } from 'viem'; + +import { fetchGetTokenInfo } from 'src/apis/etherlink'; +import { ButtonMedium } from 'src/components/button/button-medium/button-medium'; +import { IconNameEnum } from 'src/components/icon/icon-name.enum'; +import { StyledTextInput } from 'src/components/styled-text-input/styled-text-input'; +import { Switch } from 'src/components/switch/switch'; +import { useEvmChain } from 'src/hooks/evm/use-evm-chains.hook'; +import { setEvmAssetManualAction } from 'src/store/evm/assets/evm-assets-actions'; +import { useEvmAccountChainAssetsSelector } from 'src/store/evm/assets/evm-assets-selectors'; +import { + useEvmAccountChainBalancesSelector, + useEvmAccountChainBalancesTimestampSelector +} from 'src/store/evm/balances/evm-balances-selectors'; +import { processLoadedEvmCollectiblesMetadataAction } from 'src/store/evm/collectibles-metadata/evm-collectibles-metadata-actions'; +import { buildEvmCollectibleMetadataFromOnChain } from 'src/store/evm/collectibles-metadata/utils'; +import { processLoadedEvmExchangeRatesAction } from 'src/store/evm/exchange-rates/evm-exchange-rates-actions'; +import { processLoadedEvmTokensMetadataAction } from 'src/store/evm/tokens-metadata/evm-tokens-metadata-actions'; +import { buildEvmTokenMetadataFromApi, buildEvmTokenMetadataFromOnChain } from 'src/store/evm/tokens-metadata/utils'; +import { useAccountAddressForEvm } from 'src/store/wallet/wallet-selectors'; +import { createUseStylesMemoized } from 'src/styles/create-use-styles'; +import { formatSize } from 'src/styles/format-size'; +import { EvmAssetStandardEnum } from 'src/token/interfaces/token-metadata.interface'; +import { toEvmNetworkEssentials } from 'src/types/networks'; +import { dispatchEtherlinkAccountData, getEtherlinkAccountData } from 'src/utils/evm/etherlink-balances.utils'; +import { getEvmAssetMetadata } from 'src/utils/evm/on-chain/metadata'; +import { fromTokenSlug } from 'src/utils/from-token-slug'; +import { ETHERLINK_MAINNET_CHAIN_ID } from 'src/utils/rpc/rpc-list'; + +export const EtherlinkManualAssetDebug = () => { + const styles = useStyles(); + const dispatch = useDispatch(); + const account = useAccountAddressForEvm(); + + const [slug, setSlug] = useState(''); + const [isRefreshing, setIsRefreshing] = useState(false); + const [isDetecting, setIsDetecting] = useState(false); + const [addError, setAddError] = useState(); + const [refreshError, setRefreshError] = useState(); + + const knownAssets = useEvmAccountChainAssetsSelector(account, ETHERLINK_MAINNET_CHAIN_ID); + const balances = useEvmAccountChainBalancesSelector(account, ETHERLINK_MAINNET_CHAIN_ID); + const balancesTimestamp = useEvmAccountChainBalancesTimestampSelector(account, ETHERLINK_MAINNET_CHAIN_ID); + const etherlinkChain = useEvmChain(ETHERLINK_MAINNET_CHAIN_ID); + + const network = useMemo( + () => (etherlinkChain ? toEvmNetworkEssentials(etherlinkChain) : undefined), + [etherlinkChain] + ); + + const knownSlugs = useMemo(() => Object.keys(knownAssets), [knownAssets]); + + const trimmedSlug = slug.trim().toLowerCase(); + const selectedAsset = knownAssets[trimmedSlug]; + + const handleManualToggle = async (manual: boolean) => { + if (!account || trimmedSlug === '') { + return; + } + + const chainId = ETHERLINK_MAINNET_CHAIN_ID; + const [contract, tokenId] = fromTokenSlug(trimmedSlug); + + setAddError(undefined); + + if (!manual || selectedAsset) { + dispatch(setEvmAssetManualAction({ account, chainId, slug: trimmedSlug, manual })); + + return; + } + + if (!network || !isAddress(contract)) { + setAddError('Not a valid contract address'); + + return; + } + + setIsDetecting(true); + try { + if (tokenId == null) { + try { + const tokenInfo = await fetchGetTokenInfo(contract); + + if (tokenInfo.type === 'ERC-20' && tokenInfo.decimals != null) { + dispatch( + setEvmAssetManualAction({ + account, + chainId, + slug: trimmedSlug, + manual, + standard: EvmAssetStandardEnum.ERC20 + }) + ); + dispatch( + processLoadedEvmTokensMetadataAction({ + chainId, + metadata: { [trimmedSlug]: buildEvmTokenMetadataFromApi(tokenInfo, Number(tokenInfo.decimals)) } + }) + ); + if (tokenInfo.exchange_rate != null) { + dispatch( + processLoadedEvmExchangeRatesAction({ + chainId, + rates: { [trimmedSlug]: Number(tokenInfo.exchange_rate) } + }) + ); + } + + return; + } + } catch (error) { + console.error(error); + } + } + + const detected = await getEvmAssetMetadata(network, contract, tokenId); + + if (!detected || (detected.standard === EvmAssetStandardEnum.ERC20 && detected.metadata.decimals == null)) { + setAddError('Token not found via API or on-chain'); + + return; + } + + dispatch(setEvmAssetManualAction({ account, chainId, slug: trimmedSlug, manual, standard: detected.standard })); + + if (detected.standard === EvmAssetStandardEnum.ERC20 && detected.metadata.decimals != null) { + dispatch( + processLoadedEvmTokensMetadataAction({ + chainId, + metadata: { + [trimmedSlug]: buildEvmTokenMetadataFromOnChain(contract, detected.metadata, detected.metadata.decimals) + } + }) + ); + } else if (detected.standard !== EvmAssetStandardEnum.ERC20) { + dispatch( + processLoadedEvmCollectiblesMetadataAction({ + chainId, + metadata: { + [trimmedSlug]: buildEvmCollectibleMetadataFromOnChain( + contract, + tokenId ?? '0', + detected.standard, + detected.metadata + ) + } + }) + ); + } + } catch (error) { + console.error(error); + setAddError('Token not found via API or on-chain'); + } finally { + setIsDetecting(false); + } + }; + + const handleForceRefresh = async () => { + if (!account) { + return; + } + + setIsRefreshing(true); + setRefreshError(undefined); + + try { + const data = await getEtherlinkAccountData(account); + dispatchEtherlinkAccountData({ account, data }); + } catch (error) { + setRefreshError(error instanceof Error ? error.message : String(error)); + } finally { + setIsRefreshing(false); + } + }; + + return ( + + Etherlink manual asset + + {account ? ( + <> + Account: {account} + + Balances timestamp:{' '} + {balancesTimestamp ? `${new Date(balancesTimestamp).toISOString()} (${balancesTimestamp})` : 'none'} + + + + + {knownSlugs.length > 0 && ( + + Stored assets (tap to select): + {knownSlugs.map(knownSlug => ( + setSlug(knownSlug)}> + + {knownSlug} — {knownAssets[knownSlug].standard} + {knownAssets[knownSlug].manual ? ' (manual)' : ''} + + + ))} + + )} + + + + Manual flag{' '} + {isDetecting + ? '(detecting…)' + : selectedAsset + ? `for ${trimmedSlug}` + : trimmedSlug !== '' + ? '(will be added)' + : ''} + : + + + + {addError != null && Add error: {addError}} + + + Stored balance for {trimmedSlug || '—'}: {trimmedSlug ? balances[trimmedSlug] ?? 'none' : '—'} + + + {refreshError != null && Refresh error: {refreshError}} + + ) : ( + No EVM account selected. + )} + + ); +}; + +const useStyles = createUseStylesMemoized(({ colors, typography }) => ({ + title: { + ...typography.numbersMedium15, + color: colors.black, + marginBottom: formatSize(8) + }, + infoText: { + ...typography.numbersRegular13, + color: colors.black, + marginBottom: formatSize(4) + }, + slugsList: { + marginBottom: formatSize(8) + }, + slugItem: { + ...typography.numbersRegular13, + color: colors.blue, + paddingVertical: formatSize(2) + }, + row: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + marginBottom: formatSize(8) + }, + rowLabel: { + flexShrink: 1, + marginRight: formatSize(8) + }, + errorText: { + ...typography.numbersRegular13, + color: colors.destructive, + marginTop: formatSize(4) + } +})); diff --git a/src/screens/debug/import-watch-only-debug/import-watch-only-debug.form.tsx b/src/screens/debug/import-watch-only-debug/import-watch-only-debug.form.tsx index 2caba6c0d..c2bd64140 100644 --- a/src/screens/debug/import-watch-only-debug/import-watch-only-debug.form.tsx +++ b/src/screens/debug/import-watch-only-debug/import-watch-only-debug.form.tsx @@ -1,3 +1,4 @@ +import { isAddress } from 'viem'; import { object, SchemaOf, string } from 'yup'; import { makeRequiredErrorMessage } from 'src/form/validation/messages'; @@ -15,5 +16,17 @@ export const importWatchOnlyDebugInitialValues: ImportWatchOnlyDebugValues = { export const importWatchOnlyDebugValidationSchema: SchemaOf = object().shape({ name: string().required(makeRequiredErrorMessage('Name')), - address: walletAddressValidation + address: string() + .required(makeRequiredErrorMessage('Address')) + .test('is-valid-address', 'Invalid address', value => { + if (value == null) { + return false; + } + + if (isAddress(value)) { + return true; + } + + return walletAddressValidation.isValidSync(value); + }) }); diff --git a/src/screens/debug/import-watch-only-debug/import-watch-only-debug.tsx b/src/screens/debug/import-watch-only-debug/import-watch-only-debug.tsx index a76e6d27f..c43eed425 100644 --- a/src/screens/debug/import-watch-only-debug/import-watch-only-debug.tsx +++ b/src/screens/debug/import-watch-only-debug/import-watch-only-debug.tsx @@ -2,6 +2,7 @@ import { Formik } from 'formik'; import React, { FC } from 'react'; import { View } from 'react-native'; import { useDispatch } from 'react-redux'; +import { isAddress } from 'viem'; import { ButtonLargePrimary } from 'src/components/button/button-large/button-large-primary/button-large-primary'; import { AccountTypeEnum } from 'src/enums/account-type.enum'; @@ -29,7 +30,7 @@ export const ImportWatchOnlyDebug: FC = () => { id: values.address, name: values.name, type: AccountTypeEnum.WATCH_ONLY_DEBUG, - chain: TempleChainKind.Tezos, + chain: isAddress(values.address) ? TempleChainKind.EVM : TempleChainKind.Tezos, address: values.address, publicKey: '' }; diff --git a/src/screens/network-settings/index.tsx b/src/screens/network-settings/index.tsx index 520cc3e2f..33777ef21 100644 --- a/src/screens/network-settings/index.tsx +++ b/src/screens/network-settings/index.tsx @@ -3,7 +3,7 @@ import { StyleSheet } from 'react-native'; import { ScreenContainer } from 'src/components/screen-container/screen-container'; import { TempleChainKind } from 'src/enums/temple-chain-kind.enum'; -import { useEvmChain } from 'src/hooks/use-evm-chains.hook'; +import { useEvmChain } from 'src/hooks/evm/use-evm-chains.hook'; import { useTezosChain } from 'src/hooks/use-tezos-chains.hook'; import { ScreensEnum } from 'src/navigator/enums/screens.enum'; import { useScreenParams } from 'src/navigator/hooks/use-navigation.hook'; diff --git a/src/screens/networks/all-networks-options/index.tsx b/src/screens/networks/all-networks-options/index.tsx index 138332b33..101c2ae35 100644 --- a/src/screens/networks/all-networks-options/index.tsx +++ b/src/screens/networks/all-networks-options/index.tsx @@ -7,7 +7,7 @@ import { IconV2 } from 'src/components/icon-v2'; import { IconNameV2Enum } from 'src/components/icon-v2/icon-name.enum'; import { TouchableWithAnalytics } from 'src/components/touchable-with-analytics'; import { TempleChainKind } from 'src/enums/temple-chain-kind.enum'; -import { useEvmChains } from 'src/hooks/use-evm-chains.hook'; +import { useEvmChains } from 'src/hooks/evm/use-evm-chains.hook'; import { useTezosChains } from 'src/hooks/use-tezos-chains.hook'; import { formatSize } from 'src/styles/format-size'; import { ChainId, ChainOfKind } from 'src/types/networks'; diff --git a/src/screens/token-info/token-info.tsx b/src/screens/token-info/token-info.tsx index 3bb5af840..2a1ecdbbe 100644 --- a/src/screens/token-info/token-info.tsx +++ b/src/screens/token-info/token-info.tsx @@ -8,7 +8,7 @@ import { StyledTextInput } from 'src/components/styled-text-input/styled-text-in import { useTokenStandard } from 'src/hooks/use-token-standard'; import { ScreensEnum } from 'src/navigator/enums/screens.enum'; import { useScreenParams } from 'src/navigator/hooks/use-navigation.hook'; -import { TokenStandardsEnum } from 'src/token/interfaces/token-metadata.interface'; +import { TezosTokenStandardsEnum } from 'src/token/interfaces/token-metadata.interface'; import { copyStringToClipboard } from 'src/utils/clipboard.utils'; import { isDefined } from 'src/utils/is-defined'; @@ -37,7 +37,7 @@ export const TokenInfo = () => { - {isDefined(token.id) && !loading && tokenStandard === TokenStandardsEnum.Fa2 && ( + {isDefined(token.id) && !loading && tokenStandard === TezosTokenStandardsEnum.Fa2 && ( <>