Compare commits

...
Author SHA1 Message Date
frank 9a9ad0ccea feat!:enable sync fallback 2024-08-01 17:10:23 +08:00
Parvesh Monu a8a08c82b0 fix styling and navigation 2024-07-25 16:05:05 +05:30
Parvesh Monu aa28678188 lint and status-go update
https://github.com/status-im/status-go/compare/4a43b2b2...c39d9dc2
2024-07-25 15:11:58 +05:30
Parvesh Monu 67aa733736 Implement seed phrase fallback flow 2024-07-25 14:35:38 +05:30
Lungu Cristian cee21241d4 WalletConnect no internet edge-cases (#20826)
* feat: only initialize wc if internet online

* feat: no internet toast for session establishment

* feat: no internet banner on session requests

* feat: reloading walletconnect on connection change

* fix: re-initialize only when previously failed to

* fix: removed legacy net-info ns

* ref: renamed :network-status to :network/status

* ref: moved network subs to own "category"

* fix: device network fx args

* fix: tests & showing persisted dapps when offline

* fix: addressed review comments

* fix: rebase issues

* fix: linting

* fix: usage of web3-wallet (#20864)

* fix: moved networks to contextx and renaming

* ref: moved building supported namespaces into fx
2024-07-25 11:21:31 +03:00
Icaro Motta 60ad7c8a29 chore(tests): New match-strict? cljs.test directive (#20825)
Equality checks in tests using = give a bad experience by default on test
failures containing nested data structures. We use the cljs.test directive
match? from matcher-combinators library to help compare nested structures. The
problem with match? is that its default matcher for maps (embeds) can be too
permissive, and this causes surprises.

Here we upgrade matcher-combinators to latest, where a new matcher called
nested-equals is available. This matcher won't allow extra keys in maps. This
matcher eliminates the need for manually adding nested equals matchers as we
have to do currently.

- Upgrades matcher-combinators from 3.8.8 to 3.9.1 (latest as of 2024-07-19)

What changes?

When asserting in tests, we now have the option to use match-strict? or match?.
Both directives are available by integrating with cljs.test. The code
implementing the new match-strict? directive was 100% copied from the library
matcher-combinators because we need to wrap the expected value ourselves with
matcher-combinators.matchers/nested-equals. It's ugly code, but it's how we can
integrate with cljs.test/assert-expr.
2024-07-24 23:06:41 -03:00
Mohamed Javid 4989c92780 fix_: Adding own address as saved addresses (#20839)
This commit:

- prevents the user from saving their wallet address as the saved address
- fixes button not capturing taps when the keyboard is open in saved address flows

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2024-07-24 19:46:59 +05:30
Lungu Cristian c6a63e30b2 fix: usage of web3-wallet (#20864) 2024-07-24 13:54:30 +03:00
Lungu Cristian 07005f8ad5 Reject typeddata request when wrong chainId inside typed data (#20821)
* fix: reject typeddata request if wrong chainid

* fix: lint
2024-07-24 12:12:40 +03:00
Jamie Caprani 3ab345563c fix(wallet): adjust max amount to not include network being bridged to (#20604) 2024-07-24 01:54:12 -07:00
Icaro Motta cef1308b3a chore(tests): Allow test-watch-for-repl target to run while the app is running (#20827)
Fix a long standing problem where we can't run in parallel the make target
run-clojure and test-watch-for-repl, or in other words, we can't run tests via
the REPL while the app is running.

Details:

I found out that shadow-cljs fails to build because it does not expand the
environment variables SHADOW_OUTPUT_TO and SHADOW_NS_REGEXP if and only if the
run-clojure target was executed.

This is the top of the stacktrace, and it happens because it doesn't know where
to output the test build because the env var wasn't expanded:

    [build] NullPointerException:
    [build]         shadow.build.node/configure (node.clj:59)
    [build]         shadow.build.node/configure (node.clj:45)
    [build]         shadow.build.targets.node-script/configure (node_script.clj:37)

The solution is to pass the option --config-merge to shadow-cljs and override
both :ns-regexp and :output-to because CLI args override options from env vars
in shadow-cljs.
2024-07-24 00:18:27 -03:00
Icaro Motta 4b8a612df4 chore(docs): Document some of our existing testing practices (#20691)
Document some of our current testing practices in hopes of helping reduce
friction in PRs and communication in general. In theory, nothing in the text
should be a surprise because these are things we have been discussing over many
months (some things for almost 1.5 years) and are already present in the code.
2024-07-23 23:45:14 -03:00
Ulises Manuel e4639c153f feat(wallet): Skip From page while sending an asset only owned by one account (#20773)
- Update tests

- Omit from page while sending a token in home page

- Hide send and bridge option for not owned tokens

- Fix subscription to return accounts owning an asset
2024-07-23 16:08:33 -06:00
Alexander 8597b899bd Remove dApps tab from Wallet (#20818) 2024-07-23 18:57:27 +03:00
John Ngei a5c8182461 fix onboarding navigation to enable notification screen and blur issues (#20725) 2024-07-23 15:18:43 +02:00
mmilad75 89bb3ea5c3 Watch-only collectibles should not be included on the main wallet page by default #20735 (#20761) 2024-07-23 14:45:02 +02:00
Shivek Khurana 3bb7c308e3 🦁 Fix issues with missing dapp images and dapp names (#20811)
* 🦁 Beast mode

* 🗑️ Remove `prn` calls

* 🌎 Add utils to remove http:// prefix

* ⏭️ Extracted name and avatar computation

* 🧹 Cleanup

* ✏️ Fix lint and remove REPL flow

*  Remove broken test

* 🖊️ Fix lint
2024-07-23 17:04:03 +05:30
Parvesh Monu 1a4987478c fix UI elements are misplaced on the 'Sign in by syncing' screen when adding a new profile (#20837) 2024-07-23 16:09:04 +05:30
Parvesh Monu 540094c229 fix Missing 'Mark as read' option on community channels (#20838) 2024-07-22 22:55:50 +05:30
Alexander 08b65cbcb7 Proper handling of disconnection, both from the dapp itself and from the list of connected dapps (#20817) 2024-07-22 15:20:52 +02:00
AlexanderandLungu Cristian d623cc8444 Only show the Wallet Connect requests for the logged in user (#20815)
Co-authored-by: Lungu Cristian <lungucristian95@gmail.com>
2024-07-22 14:57:45 +02:00
Brian Sztamfater 4b7c906df2 feat(swap): set spending cap screen (#20727)
Signed-off-by: Brian Sztamfater <brian@status.im>
2024-07-22 08:50:29 -03:00
Omar Basem 3b446963ef fix: assets sort order on bridge and assets screen (#20813)
* fix: assets sort order on bridge and assets screen (#20813)
2024-07-22 14:16:40 +04:00
Icaro Motta cec46f985a chore(style): Sort JSON keys in translations/en.json (#20785)
Sorts keys (non-recursively) in translations/en.json. The solution uses
the prettier plugin https://github.com/Gudahtt/prettier-plugin-sort-json.

We only format translations/en.json because it’s the only file we need to
manually change.

- Dependency added: prettier-plugin-sort-json version 4.0.0
- Dependency upgraded: prettier, from version 2.8.8 to 3.3.3.
2024-07-21 22:39:50 -03:00
Volodymyr Kozieiev 06b2996167 Do not update disabled networks when receiver network updated (#20756) 2024-07-19 15:10:13 +01:00
Lungu Cristian 02e24208db Wallet Connect transactions (#20755)
* feat: updated signing endpoints and refactor

https://github.com/status-im/status-go/compare/6e056348...e8aec741

* fix: using the generic warning at the bottom

* fix: show parsed transaction parameters

* feat: adding fees to transactions

https://github.com/status-im/status-go/compare/6e056348...b2e5e7a8

* feat: added fees

* feat: added eip-1559 fee estimation & tx priority

* feat: added fees and failed processing handling

* fix: show testnet name in the request

* fix: address review comments

* feat: added max-fee color when not enough balance

* ref: broke down tx fees subscription

* fix: handle gas estimation on status-go

https://github.com/status-im/status-go/compare/1ef2434b...5389f281

* fix: don't overwrite dynamic fees if already there

* fix: malli schema and review comments

* fix: addressed review comments 1

* fix: addressed comments 2

* fix: removed unused require

* fix: addressed QA review

https://github.com/status-im/status-go/compare/484b8aca...d07f9b5b

* fix: requests being shown simultaneously

* fix: removed support for eth_signTransaction
2024-07-19 14:16:51 +03:00
frank 84b8943fd4 fix_:still return the image when image server is unable to get public key (#20538)
https://github.com/status-im/status-go/compare/cba3ac57...4a43b2b2
2024-07-19 17:17:53 +08:00
Ajay Sivan c52b3e457e Wallet/Swap Input Component (#20318) 2024-07-19 01:00:38 -07:00
Omar Basem 21cc8a199a fix: button width (#20792)
* fix: button width (#20792)
2024-07-19 08:13:50 +04:00
Yevheniia Berdnyk 59374543ef e2e: disabled activity verification in wallet tests 2024-07-18 19:45:20 +03:00
Alexander 9f84a7b912 A pack of bugfixes for the user story "Connect to dApps" (#20711) 2024-07-18 14:57:53 +02:00
Vit∀ly Vlasov 2b0847ef76 fix_: ui part for share-all-future-addresses storage (PR #20549) (#20549)
Related status-go PR: https://github.com/status-im/status-go/pull/5354

https://github.com/status-im/status-go/compare/6e056348...8458cafe

Signed-off-by: Vitaly Vlasov <mail@vitv.ly>
2024-07-18 15:36:38 +03:00
Yevheniia Berdnyk 97b19c5440 e2e: fixes for wallet and deep/universal links tests 2024-07-18 00:52:06 +03:00
Icaro Motta b3e88508ac chore(activity-center): Various small refactors (#20690)
Potentially a solution to https://github.com/status-im/status-mobile/issues/15706

- [x] Fixes swipe button on Android and iOS.
- [x] Performance: we now subscribe only to the minimum from each community.
      This could be the reason the AC would lag as described in the parent
      issue.
- [x] Performance: was able to use flex and removed swipe button height
      calculation that was using `onLayout` and was causing a re-render.
- [x] Performance: reduced the initial number of items to render in the flatlist
      from 10 to 7.
- [x] Performance: delay rendering the heavy list of notification components.
      See in the video below how slow it is to open the AC with just 6
      notifications and that the opening animation is never displayed. And then
      check the improved version with the artificial delay provided by
      `rn/delay-render`. By opening the AC first and animating, this gives the
      user something to look for, and hopefully a few milliseconds more to think
      the app is not stuck, which will be preciously used to render
      notifications.

We refactor all views in the AC to:

- [x] Follow our newest standards with React hooks.
- [x] Removed prop-drilling by creating a separate React context to store the
      current swipeable item (because we need to call `.close` on a `Gesture
      Swipeable` instance whenever a new swipeable opens.
2024-07-17 12:16:06 -03:00
Mohsen 7b09402fcb [#20742] fix: blue background behind the "Save address" button (#20754) 2024-07-17 16:04:40 +03:30
mmilad75 a912125ba9 Token value shows fiat value on the transaction confirmation page #20734 (#20770) 2024-07-17 10:47:27 +02:00
Ulises Manuel 2d0437dd5e fix(wallet): Improvements on activity tab (#20703)
* Fix schema for networks in context-tags

* Fix wallet-activity component overflowing the activity tab

* Improve robustness of the activity tab fetching mechanism

* Handle `wallet-activity-filtering-entries-updated` signal

* Improve processing of data received for the activity tab
2024-07-16 15:07:33 -06:00
Parvesh Monu 43651ef0d0 Adjust on-boarding illustrations position and scale (#20692) 2024-07-16 20:43:19 +05:30
Yevheniia Berdnyk 13232dc7b7 e2e: updated create profile flow 2024-07-16 15:46:23 +01:00
Andrea Maria Piana 93b5f7a918 Add confirmation to centralized metrics
This commit add a confirmation for centralized metrics.
It is added in 3 places:

1) Onboarding -> Create new account
2) Onboarding -> Sync profile
3) On the accounts view if the user is upgrading

To test 1 & 2, you should just be able to do that on a newly installed
device.

To test 3, you will have to upgrade from a PR without this feature that
has at least an account. It should show the confirmation modal until you
either click on Not now or Share usage data.

The modal should also be added in settings, but I will do that as a
separate PR.
2024-07-16 15:46:23 +01:00
Mohsen 4898d32243 [#20664] feat: add share usage data confirmation modal 2024-07-16 15:46:23 +01:00
Lungu Cristian 588692e0eb Wallet Connect message signing (#20693)
* feat: updated signing endpoints and refactor

https://github.com/status-im/status-go/compare/6e056348...e8aec741

* fix: address review comments
2024-07-16 14:36:16 +03:00
Nikolay bd9e440839 [18942] Slideshow: slider-bar component (#20615) 2024-07-16 12:42:38 +02:00
Ulises Manuel 940edc2e53 fix(wallet): Some collectibles were displayed as "can iOS can't fetch collectible error (#20714) 2024-07-15 12:34:02 -06:00
mmilad75 5a93cd755e Cover wallet send events with tests #20411 (#20533) 2024-07-15 14:56:50 +02:00
Yevheniia Berdnyk 942c130d23 e2e: separated tests to run in PRs 2024-07-15 12:46:18 +03:00
Andrea Maria Piana bb8aad3be8 set fleet to status.staging
https://github.com/status-im/status-go/compare/1ef2434b...484b8aca
2024-07-15 10:30:01 +01:00
Andrea Maria Piana ba76b9fd51 Allow setting store confirmations
This commit adds the ability to enable store confirmations in the UI,
under advanced settings.

https://github.com/status-im/status-go/compare/1ef2434b...0d1e5aae
2024-07-15 07:46:13 +01:00
Brian Sztamfater 5f085e9cea feat(swap): swap confirmation screen (#20669)
Signed-off-by: Brian Sztamfater <brian@status.im>
2024-07-14 00:51:02 -03:00
Mohamed Javid 12b8dcf1e7 fix(saved-addresses): grouping and sorting of saved addresses (#20689)
This commit fixes the grouping and sorting of saved addresses.

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2024-07-12 19:25:39 +05:30
Omar Basem 0e6d59b312 fix: hardware induced back actions (#20183)
* fix: hardware induced back actions (#20183)
2024-07-12 17:09:42 +04:00
Omar Basem 087fcb1010 Fix(wallet): navigation after transaction from settings (#20676)
* fix(wallet): navigation after transaction from settings (#20676)
2024-07-12 16:07:45 +04:00
Ajay Sivan 0de4c8cabb List-Items/Approval-Info Component (#20317) 2024-07-12 04:55:36 -07:00
Parvesh Monu 6553d5ca44 fix peer count invisible in Light mode (#20733) 2024-07-12 16:59:44 +05:30
Ajay Sivan 20b256b0d0 Settings/Data Item - editable variant (#20656) 2024-07-12 04:15:37 -07:00
Mohamed Javid 1c85b292f8 fix(community): remove non operable accounts in the selection of sharing addresses with the community (#20636)
This commit removes the non-operable accounts in the "Addresses for permission" and "Airdrop address" selections while joining a community

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2024-07-12 16:29:43 +05:30
flexsurfer d2e975f6d9 [#20434] Allow users from v1 to login with keycard (#20558) 2024-07-12 12:02:17 +02:00
Shivek KhuranaandLungu Cristian 721aa51d8d 🎣 Fix wallet connect init issue in release bundles (#20665)
* 👀 Added alerts so I peek into build

* 🆙 Update logs

* 🅰️ Annotate

* 📤 Don't refer

* 🖊️ Use default import

* added ^js

*  Added ocall

* 🎣 Isolate WC js calls to rn ns

* 🧯Fix on-scan-connection issue

---------

Co-authored-by: Lungu Cristian <lungucristian95@gmail.com>
2024-07-12 14:47:25 +05:30
Parvesh Monu 23c25d7715 Fix missing avatar and name in members of the community channels and group chats (#20619) 2024-07-12 11:12:49 +05:30
Icaro Motta 54e4b597ed chore(communities): Hide non-implemented tabs in Discover communities (#20684)
Tabs "Open" and "Gated" in Discover communities screen were never implemented in
the code, they are dummies. We now hide them under the flag
config/show-not-implemented-features?, which is disabled for users.

Fixes: https://github.com/status-im/status-mobile/issues/20682

To avoid regressions and be quicker, I opted to not remove the "All" tab even
though is the only one shown now, as that would require me to check non-trivial
code due to the fact that the tabs can be sticky as the user scrolls.
2024-07-11 22:38:18 -03:00
Icaro Motta 0b5dac0ad0 feat(settings): Revamp legacy Privacy and security settings (#20671)
Revamps the legacy "Privacy and security" screen to meet the new designs.

Fixes https://github.com/status-im/status-mobile/issues/20618

- Removed setting "Set dApp access permissions" (won't be used anymore).
- Removed setting "Display collectibles" (won't be used anymore).
- Removed setting "Chat link previews setting" (they already had no effect).
- Removed "Reset password setting". This setting is already supported in Profile
  > Password > Change password.
- Removed "Delete my profile". Profile deletion is already supported in the
  login screen.
- Moved setting "Show your profile picture" to Profile > Privacy and security.
- Moved setting "Accept new chats from <XYZ>" to "Allow new contact requests" in
  Profile > Messages. Now it's just a toggle.
- Moved Block screenshots (Android) or Hide Preview (iOS) which are both
  accessible in Profile > Privacy and security.
- Created function utils.navigation/navigate-back, but I only used this in 2
  namespaces to keep the PR under scope.

Areas that may be impacted: old legacy settings that are still relevant.
2024-07-11 22:23:17 -03:00
Mohamed Javid 180065129f fix(saved-addresses): clean QR scanned address (#20699)
This commit cleans the scanned QR address/result on the unmount of the add new saved address flow.

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2024-07-11 20:01:55 +05:30
Mohamed Javid 866b854ee0 fix(key-pairs)_: error message on scanning different key pair QR (#20612)
This commit:

- update the connection string validation method to use the method from status-go
- updates the error message if the user tries to scan a different key pair QR for importing a missing key pair
- updates the text for exporting an individual key pair

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2024-07-11 15:55:00 +05:30
Shivek KhuranaandLungu Cristian 072370b0d6 🙅 Gracefully reject proposals and requests (#20649)
* 🙅 Gracefully reject proposals and requests

* 🔑 Remove redudant fx, send correct error

* ➡️ Docstring to comment

---------

Co-authored-by: Lungu Cristian <lungucristian95@gmail.com>
2024-07-11 13:03:14 +03:00
Shivek KhuranaandLungu Cristian d74edff9b9 2️⃣ Use v2 api for persisting sessions (#20648)
* 2️⃣ Use v2 api for persisting sessions

* 🗑️ Remove traces of REPL and v2 suffix

---------

Co-authored-by: Lungu Cristian <lungucristian95@gmail.com>
2024-07-11 12:50:42 +03:00
Andrea Maria Piana 0a0591f67a Add centralized metrics
https://github.com/status-im/status-go/compare/6e056348...1ef2434b

This commit adds support for pushing centralized metrics to mixpanel.

It uses an interceptor and only picks a few selected events to push
through.

In order to test:

1) Create an account in the app
2) Go to Settings->Privacy
3) Enable metrics

You should now see the events on the mixpanel dashboard (login with your
status-im account for access).
Only some example events are tracked, they are just for testing
2024-07-11 10:06:46 +01:00
Andrea Maria Piana 7a8db689f4 enable light client by default 2024-07-11 09:01:23 +01:00
John NgeiandYevheniia Berdnyk 311fde9409 chore: remove identifiers screens (#20503)
* chore: remove identifiers screens so users are navigated straight to enable notifications during onboarding

* removed navigated back button from enable notification screen

* fix top margin

* e2e: updated sign in flow

* make lint-fix

---------

Co-authored-by: Yevheniia Berdnyk <ie.berdnyk@gmail.com>
2024-07-11 02:09:03 +02:00
Yevheniia Berdnyk f89b66f562 e2e: adding android.gpu.mode capability to fix emulators crash 2024-07-11 02:43:32 +03:00
Yevheniia Berdnyk d179cbf59b e2e: updated discover communities test 2024-07-10 19:53:48 +05:30
Parvesh Monu 7ff7e78691 fix user lands on the Home screen after closing a community opened from Discover Communities 2024-07-10 19:53:47 +05:30
Omar Basem 6c352397ab fix(wallet): asset sorting (#20659)
* fix(wallet): asset sorting (#20659)
2024-07-10 14:49:24 +04:00
Mohsen 3521421098 [#20543] fix: incorrect black background behind floating button (#20585) 2024-07-09 21:12:18 +03:30
Omar Basem f70a743a8c Fix(wallet): address validation (#20674)
* fix(wallet): address validation (#20674)
2024-07-09 15:59:48 +04:00
NikolayandJamie Caprani a2178951d7 chore(wallet): import private key - backend integration
Co-authored-by: Jamie Caprani <jamiecaprani@gmail.com>
2024-07-09 03:49:31 -07:00
Ulises Manuel 7774c4eac1 fix(wallet): Improve collectible UX and fix data displayed (#20657)
* Add variant unknown variant for collectibles

* Fix blank collectibles listed

* Improve `expanded-collectible` animation and add support for different gradient-colors

* Make :wallet/collectible-details-owner subscription depend on `wallet/accounts` instead of `:wallet`

* Make collectible tabs component more flexible

* Remove now unused subscriptions

* Improve UX navigation to collectible detail page

* Pass the current collectible gradient-color when a collectible is pressed

* Fix tests
2024-07-08 14:19:01 -06:00
Alexander 4c4a8b65d4 Add QR scanner to connect Dapps through Connected Dapps screen (#20647)
* Add QR scanner to connect Dapps through Connected Dapps screen

* Style fix

* use-mount
2024-07-08 13:55:32 +02:00
Parvesh Monu de6d9a6c3b chore: remove hot reload while theme changing (#20663) 2024-07-08 14:51:27 +05:30
Mohsen da16d1f69e [#20571] fix: cleanup save address on mount (#20650) 2024-07-08 12:27:16 +03:30
John Ngei a13975f3f6 fix the warning message when the user enters the wrong password (#20605) 2024-07-06 00:15:36 +02:00
Icaro Motta c473b8c9b1 chore(settings): Add boilerplate for the new Privacy and security screen (#20668) 2024-07-05 14:07:01 -03:00
Parvesh Monu 1f333cc937 fix wallet send flow wrong status bar color on select assets screen (#20662) 2024-07-05 20:57:20 +05:30
Yevheniia Berdnyk 460aaedbca e2e: false failures fixes 2024-07-05 16:25:12 +03:00
mmilad75 66639fc3ed fix(wallet): fix checkbox (#19756) 2024-07-05 13:33:15 +01:00
Mohsen 2cc689a896 [#20638] fix: Scan missing keypair keep scanning after success attempt (#20640) 2024-07-05 14:33:38 +03:30
Ajay Sivan b4866ff728 Swap: Edit slippage drawer (#20554) 2024-07-05 02:44:38 -07:00
Sean Hagstrom eaa5016094 feat: add support for updating key-pairs and accounts from app signal (#20550)
This change adds support for processing app signals for syncing changes when adding, editing, or removing keypairs, accounts, and watch-only accounts.
2024-07-04 16:25:30 +01:00
Sean Hagstrom 66f77e1467 fix: configure selectable key-pair to use box-only for pointer-events (#20611)
This change attempts to only to override the default `pointer-events` behaviour for the `quo/keypair` component when the component uses the `selector` action. Now when the `quo/keypair` component is rendered with a selector, only the top-level view of the component will be pressable. And when the `quo/keypair` component is rendered without a selector it will allow for the children of the component to be pressable too.
2024-07-04 15:48:45 +01:00
Volodymyr Kozieiev d16c1a3c85 Disable possibility to changes amounts to send (#20639) 2024-07-04 15:02:57 +01:00
Mohamed Javid a049fd341e chore(docs)_: include new status-go tagging command in the merging PR process (#20607)
Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2024-07-04 15:37:27 +05:30
Volodymyr Kozieiev 140fa3115c Add possibility to edit networks list when routes not found (#20642) 2024-07-04 10:54:17 +01:00
Siddarth Kumar 147676ae8c chore: add Xcode 15.4 to allowed versions (#20641)
This commit adds Xcode 15.4 to allowed versions in xcode-wrapper overlay.
2024-07-04 14:39:23 +05:30
Ulises Manuel 1e40d49369 feat(wallet): Add modal to remove :key and :seed accounts (#20569) 2024-07-03 11:48:10 -06:00
BalogunofAfrica b17f2892c7 feat: collectibles details loading (#20400) 2024-07-03 15:49:12 +01:00
Volodymyr Kozieiev b28a8e153e Fixes for screen where user locks network amounts to send (#20519) 2024-07-03 15:17:29 +01:00
Alexander 35a1905396 Fix auth slider resetting when wallet connect signing is finished (#20589)
* Fix auth slider resetting when wallet connect signing is finished

* Lint fix

* Fixes

* Fixes
2024-07-03 15:27:27 +02:00
Brian Sztamfater 2e8776d0a6 feat(swap): implement network selection drawer (#20368) 2024-07-03 09:15:07 -03:00
Alexander 99506c810d Re-hide connected dapps screen behind a feature flag (#20627)
* Connected dapps screen is not hidden behind a feature flag

* Style fix
2024-07-03 13:01:24 +02:00
jakub e83f6ff445 fix(ci): add missing import for JsonBuilder
Signed-off-by: Jakub Sokołowski <jakub@status.im>
2024-07-03 12:21:39 +02:00
Lungu Cristian f51f52ec27 Fix WalletConnect transactions (#20608)
* fix: sign-transaction

Signed-off-by: Lungu Cristian <lungucristian95@gmail.com>

* fix: sendTranasaction not working

Signed-off-by: Lungu Cristian <lungucristian95@gmail.com>

* ref: removing 0x from the signature

Signed-off-by: Lungu Cristian <lungucristian95@gmail.com>

* ref: tx data from responding to processing events

Signed-off-by: Lungu Cristian <lungucristian95@gmail.com>

* fix: request dapp subscription

Signed-off-by: Lungu Cristian <lungucristian95@gmail.com>

* fix: tx data bug

Signed-off-by: Lungu Cristian <lungucristian95@gmail.com>

---------

Signed-off-by: Lungu Cristian <lungucristian95@gmail.com>
2024-07-03 12:13:13 +02:00
Parvesh Monu e58e2209bb fix endless loading skeleton for some empty channels on IOS (#20602) 2024-07-03 15:26:43 +05:30
Parvesh Monu 8aa1cadc66 fix chat screen design issues (#20621) 2024-07-03 13:02:11 +05:30
Icaro Motta 91c22df498 Remove all integrations with signal wakuv2.peerstats (#20501)
Removes code integrating with the signal wakuv2.peerstats. The response from
this signal is rather large and it can sometimes happen in short bursts.

- Fixes https://github.com/status-im/status-mobile/issues/20176

We were using it to keep track of the number of peers in real-time. We now only
fetch the peer count in two instances (synchronously inside rn/use-mount):

- When the user opens the legacy screen Settings > Advanced > Peers stats.
- When the user opens the visibility status dropdown in Settings, because the
  peers count will be used when the user chooses "Offline" (status inactive).

Note: we don't send anymore the peers count when the user shakes the phone. We
assume this value is already available in :peers-summary (which will be shared
by the user).

status-go still publishes the signal, we just ignore it to remove the
performance overhead of transforming to cljs and mutating the app-db (thus
interrupting the queue from more important stuff).

Steps to test:

- Verify user can see peers count in Settings > Advanced > Peers stats
- Verify changing the visibility status of user Alice in the Settings screen
  leads to the desired effect to the other party seeing Alice's visibility
  status.
2024-07-02 19:48:15 -03:00
Ulises Manuel e221e23255 fix(wallet): Validation of addresses in send-to screen (#20570)
* Fix validation of addresses in send-to screen
2024-07-02 13:57:31 -06:00
Yevheniia Berdnyk e8e05e58e0 e2e: update for Syncing view 2024-07-02 18:30:06 +03:00
Lungu Cristian ac4ffd83db Wallet Connect session establish networks (#20576)
* feat: showing supported networks in wc connection

* feat: added :large size for quo/data-item

* feat: added required networks check
2024-07-02 16:39:33 +02:00
Shivek KhuranaandLungu Cristian b021b1e20a 🎛️ Account switcher UI for Wallet Connect sessions (#20573)
* 🎛️ Account switcher UI for Wallet Connect sessions

* 😢 Remove repl workflow

* 🔀 Merge current-proposal request and account

*  Remove redundant test

* 🐛 Lint fix

---------

Co-authored-by: Lungu Cristian <lungucristian95@gmail.com>
2024-07-02 18:48:48 +05:30
Ajay Sivan b650591e58 Refactor - Info/Info Message component (#20551) 2024-07-02 04:06:37 -07:00
Mohamed Javid 0581fc2f9d feat(wallet): sync saved addresses (#20546)
This commit adds syncing saved addresses across paired devices whenever a new saved address is added or an existing one is edited or removed.

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2024-07-02 15:33:54 +05:30
yqrashawn ef9cc55501 feat: check before syncing doc (#20504) 2024-07-02 16:36:42 +08:00
Yevheniia Berdnyk 3b3a39e37b e2e: fixes for community,wallet and removed outdated xfails 2024-07-02 01:50:29 +03:00
Icaro Motta b255874e95 fix(communities)_: Buggy scroll behavior in community channel member list (#20517)
Fixes the scroll behavior in a community channel member list. The problem was
that the code wasn't enforcing the correct height.

Partially solves https://github.com/status-im/status-mobile/issues/20514

Steps to test: Long press on any community channel and press View channel
members and details. The user should be able to correctly scroll throughout the
entire list of members.
2024-07-01 18:55:24 -03:00
Icaro Motta 1c83916fc3 fix: Make BigNumber comparator safe against unsupported data types (#20614)
BigNumber instances are not comparable to other data types, except numbers and
strings (supported directly by the library). This commit makes = safe on
bignumbers (no exceptions should be thrown), even when comparing a bignumber
with a nil value.

There's another important benefit from having a custom comparator: performance,
because re-frame will be able to correctly compare data with bignumbers and thus
reuse cached subscriptions and also Reagent will be able to skip processing when
props are equal.

The IComparable interface was not changed. Similarly to core CLJS data types,
sorting heterogeneous collections throws (ignore nils).

```clojure
;; This throws with message: cannot compare 10 to foo
(sort ["foo" 10])
```

We could make sorting work with heterogeneous collections, but then we would
need to extend many core data types to play nice with BigNumber and that sounds
more like a hack, and it's also not a problem we have nowadays.
2024-07-01 18:38:10 -03:00
jakub 31acf51b1e feat(ci): use s5cmd instead of obsolete s3cmd
It's actively maintained and has better concurrency support.

Depends on:
- https://github.com/status-im/status-jenkins-lib/pull/92

Signed-off-by: Jakub Sokołowski <jakub@status.im>
2024-07-01 16:31:29 +02:00
Parvesh Monu 424d2d4b5c fix can't pair with dApp on android with WalletConnect (#20600) 2024-07-01 18:01:58 +05:30
423 changed files with 13693 additions and 7873 deletions
+2 -1
View File
@@ -74,7 +74,8 @@
;; https://github.com/borkdude/clj-kondo/issues/867
:unresolved-symbol {:exclude [PersistentPriorityMap.EMPTY
number
legacy.status-im.test-helpers/restore-app-db]}
legacy.status-im.test-helpers/restore-app-db
(cljs.test/is [match-strict?])]}
:unresolved-var {:level :error}
:unsorted-required-namespaces {:level :error}
:unused-alias {:level :warning}
-2
View File
@@ -4,7 +4,6 @@ DEFAULT_NETWORK=mainnet_rpc
DEV_BUILD=1
ETHEREUM_DEV_CLUSTER=1
EXTENSIONS=0
FLEET=status.prod
GROUP_CHATS_ENABLED=1
LOG_LEVEL=info
MAILSERVER_CONFIRMATIONS_ENABLED=1
@@ -26,7 +25,6 @@ APN_TOPIC=im.status.ethereum.pr
COMMUNITIES_ENABLED=1
DATABASE_MANAGEMENT_ENABLED=1
DELETE_MESSAGE_ENABLED=1
COLLECTIBLES_ENABLED=1
COMMANDS_ENABLED=1
TWO_MINUTES_SYNCING=1
SWAP_ENABLED=1
+1 -1
View File
@@ -2,7 +2,7 @@ DEBUG_WEBVIEW=1
DEFAULT_NETWORK=goerli_rpc
ETHEREUM_DEV_CLUSTER=1
EXTENSIONS=0
FLEET=status.prod
FLEET=status.staging
GROUP_CHATS_ENABLED=1
LOG_LEVEL=debug
MAILSERVER_CONFIRMATIONS_ENABLED=0
-1
View File
@@ -3,7 +3,6 @@ DEBUG_WEBVIEW=1
DEFAULT_NETWORK=goerli_rpc
ETHEREUM_DEV_CLUSTER=1
EXTENSIONS=0
FLEET=status.prod
GROUP_CHATS_ENABLED=1
LOG_LEVEL=debug
MAILSERVER_CONFIRMATIONS_ENABLED=1
-1
View File
@@ -2,7 +2,6 @@ DEBUG_WEBVIEW=1
DEFAULT_NETWORK=mainnet_rpc
ETHEREUM_DEV_CLUSTER=1
EXTENSIONS=0
FLEET=status.prod
GROUP_CHATS_ENABLED=1
LOG_LEVEL=info
MAILSERVER_CONFIRMATIONS_ENABLED=1
-2
View File
@@ -2,7 +2,6 @@ DEBUG_WEBVIEW=0
DEFAULT_NETWORK=mainnet_rpc
ETHEREUM_DEV_CLUSTER=0
EXTENSIONS=0
FLEET=status.prod
GROUP_CHATS_ENABLED=1
LOG_LEVEL=
MAILSERVER_CONFIRMATIONS_ENABLED=1
@@ -18,6 +17,5 @@ PARTITIONED_TOPIC=0
ENABLE_ROOT_ALERT=1
MAX_IMAGES_BATCH=1
DELETE_MESSAGE_ENABLED=1
COLLECTIBLES_ENABLED=1
FAST_CREATE_COMMUNITY_ENABLED=0
TEST_NETWORKS_ENABLED=0
+14 -9
View File
@@ -1,10 +1,15 @@
*
/*
# Format top-level js files.
!*.js
!*/
*.clj-kondo
*.shadow-cljs
modules
result
target
component-spec
/app
# Ignore all except src/js/**/*.js
!/src/
/src/*
!/src/js
!/src/js/**/*.js
# Ignore all except translations/en.json
!/translations/
/translations/*
!/translations/en.json
+4
View File
@@ -6,4 +6,8 @@ module.exports = {
tabWidth: 2,
trailingComma: 'all',
useTabs: false,
// JSON sorting
jsonSortOrder: '{ "/.*/": "caseInsensitiveLexical" } ',
plugins: ['prettier-plugin-sort-json'],
};
+12 -2
View File
@@ -317,7 +317,7 @@ lint: ##@test Run code style checks
scripts/lint/translations.clj && \
zprint '{:search-config? true}' -sfc $$ALL_CLOJURE_FILES && \
sh scripts/lint/trailing-newline.sh && \
node_modules/.bin/prettier --write .
node_modules/.bin/prettier --check .
# NOTE: We run the linter twice because of https://github.com/kkinnear/zprint/issues/271
lint-fix: export TARGET := clojure
@@ -353,13 +353,17 @@ test: export SHADOW_NS_REGEXP := .*-test$$
test: ##@test Run all Clojure tests
test: _test-clojure
# Note: we need to override the :output-to and :ns-regexp options because
# shadow-cljs has a bug where it will not read from the env vars to expand the
# configuration when the shadow-cljs mobile target is already running.
test-watch-for-repl: export TARGET := default
test-watch-for-repl: export SHADOW_OUTPUT_TO := target/test/test.js
test-watch-for-repl: export SHADOW_NS_REGEXP := .*-test$$
test-watch-for-repl: ##@test Watch all Clojure tests and support REPL connections
rm -f "$$SHADOW_OUTPUT_TO" && \
yarn install && shadow-cljs compile mocks && \
concurrently --kill-others --prefix-colors 'auto' --names 'build,repl' \
'yarn shadow-cljs watch test --verbose' \
"yarn shadow-cljs watch test --verbose --config-merge '{:output-to \"$(SHADOW_OUTPUT_TO)\" :ns-regexp \"$(SHADOW_NS_REGEXP)\"}'" \
"until [ -f $$SHADOW_OUTPUT_TO ] ; do sleep 1 ; done ; node --require ./test-resources/override.js $$SHADOW_OUTPUT_TO --repl"
test-unit: export SHADOW_OUTPUT_TO := target/unit_test/test.js
@@ -457,6 +461,12 @@ android-tail-geth: export VERSION ?= debug
android-tail-geth:
adb shell 'while true; do cat; sleep 1; done < /storage/emulated/0/Android/data/im.status.ethereum$$( [ "$(VERSION)" = "release" ] || echo ".$(VERSION)" )/files/Download/geth.log'
android-clean-geth: export TARGET := android-sdk
android-clean-geth: export VERSION ?= debug
android-clean-geth:
adb shell 'rm /storage/emulated/0/Android/data/im.status.ethereum$$( [ "$(VERSION)" = "release" ] || echo ".$(VERSION)" )/files/Download/geth.log'
android-logcat: export TARGET := android-sdk
android-logcat: ##@other Read status-mobile logs from Android phone using adb
adb logcat | grep -e RNBootstrap -e ReactNativeJS -e ReactNative -e StatusModule -e StatusNativeLogs -e 'F DEBUG :' -e 'Go :' -e 'GoLog :' -e 'libc :'
+2 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.12'
library 'status-jenkins-lib@v1.9.1'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
@@ -71,7 +71,7 @@ pipeline {
}
stage('Upload') {
steps { script {
def urls = apks.collect { s3.uploadArtifact(it) }
def urls = apks.collect { s5cmd.upload(it) }
if (urls.size() > 1) { /* Return only the universal APK. */
env.PKG_URL = urls.find { it.contains('universal') }
} else { /* If no universal is available pick first. */
+24 -3
View File
@@ -1,5 +1,7 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.12'
library 'status-jenkins-lib@v1.9.1'
import groovy.json.JsonBuilder
pipeline {
agent { label 'linux' }
@@ -72,7 +74,7 @@ pipeline {
iOS: utils.pkgUrl(ios),
Diawi: utils.getEnv(ios, 'DIAWI_URL'),
/* upload the sha256 checksums file too */
SHA: s3.uploadArtifact(sha),
SHA: s5cmd.upload(sha),
]
/* add URLs to the build description */
jenkins.setBuildDesc(urls)
@@ -83,7 +85,7 @@ pipeline {
steps { script {
switch (utils.getBuildType()) {
case 'nightly': /* Create JSON file with newest build URLs */
s3.updateBucketJSON(urls, 'latest.json');
updateBucketJSON(urls, 'latest.json');
break;
case 'release':
github.publishReleaseFiles(repo: 'status-mobile');
@@ -114,3 +116,22 @@ def Boolean getPublishDefault(Boolean previousValue) {
if (previousValue != null) { return previousValue }
return false
}
/* Helper for updating JSON with newest builds. */
def updateBucketJSON(urls, fileName) {
/* latest.json has slightly different key names */
def content = [
DIAWI: urls.Diawi,
APK: urls.Apk, IOS: urls.iOS,
APP: urls.App, MAC: urls.Mac,
WIN: urls.Win, SHA: urls.SHA
]
def filePath = "${pwd()}/pkg/${fileName}"
/* it might not exist */
sh "mkdir -p ${pwd()}/pkg"
def contentJson = new JsonBuilder(content).toPrettyString()
println "${filePath}:\n${contentJson}"
writeFile(file: filePath, text: contentJson)
return s5cmd.upload(filePath)
}
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.12'
library 'status-jenkins-lib@v1.9.1'
pipeline {
agent { label 'linux' }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.12'
library 'status-jenkins-lib@v1.9.1'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
+2 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.12'
library 'status-jenkins-lib@v1.9.1'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
@@ -75,7 +75,7 @@ pipeline {
stage('Upload') {
steps {
script {
env.PKG_URL = s3.uploadArtifact(LOG_FILE)
env.PKG_URL = s5cmd.upload(LOG_FILE)
}
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.12'
library 'status-jenkins-lib@v1.9.1'
pipeline {
@@ -99,7 +99,7 @@ pipeline {
--rerun_count=2 \
--testrail_report=True \
-m testrail_id \
-m \"new_ui_critical or new_ui_medium\" \
-m \"nightly\" \
-k \"${params.KEYWORD_EXPRESSION}\" \
--apk=${params.APK_URL ?: apk_path}
"""
+2 -4
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.12'
library 'status-jenkins-lib@v1.9.1'
pipeline {
@@ -35,13 +35,11 @@ pipeline {
description: 'OBSOLETE ARGUMENT TO BE REMOVED',
defaultValue: 'DUMMY',
)
/* Commented to use TEST_MARKERS values from job params
string(
name: 'TEST_MARKERS',
description: 'Marker expression for matching tests to run.',
defaultValue: 'new_ui_critical',
defaultValue: 'smoke',
)
*/
}
options {
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.12'
library 'status-jenkins-lib@v1.9.1'
pipeline {
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.12'
library 'status-jenkins-lib@v1.9.1'
pipeline {
agent { label 'macos' }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.12'
library 'status-jenkins-lib@v1.9.1'
pipeline {
agent { label params.AGENT_LABEL }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.12'
library 'status-jenkins-lib@v1.9.1'
pipeline {
agent { label 'linux' }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.12'
library 'status-jenkins-lib@v1.9.1'
pipeline {
agent {
+27 -51
View File
@@ -1,67 +1,43 @@
## Getting Started
[Starting Guide](starting-guide.md)
[IDE Setup](ide-setup.md)
## Getting Started
- [Starting Guide](starting-guide.md)
- [IDE Setup](ide-setup.md)
## Development Process
[Coding guidelines](new-guidelines.md)
[UI components coding guidelines](ui-guidelines.md)
[Release Checklist](release-checklist.md)
[Release Guide](release-guide.md)
[Merging PR process](merging-pr-process.md)
[PR Review Policy](pr-review-policy.md)
[Working on PR together with QA team](pipeline_process.md)
[Debugging](debugging.md)
[Patching](patching.md)
[Creating a pixel perfect UI](pixel-perfection.md)
[Contributing to status-go](status-go-changes.md)
[Malli schemas (recorded demo)](https://www.youtube.com/watch?v=SlRio70aYVI) ([slides](files/forging-code-with-schemas-sep-2023-slides.pdf))
- [Coding guidelines](new-guidelines.md)
- [UI components coding guidelines](ui-guidelines.md)
- [Release Checklist](release-checklist.md)
- [Release Guide](release-guide.md)
- [Merging PR process](merging-pr-process.md)
- [PR Review Policy](pr-review-policy.md)
- [Working on PR together with QA team](pipeline_process.md)
- [Debugging](debugging.md)
- [Patching](patching.md)
- [Creating a pixel perfect UI](pixel-perfection.md)
- [Contributing to status-go](status-go-changes.md)
- [Malli schemas (recorded demo)](https://www.youtube.com/watch?v=SlRio70aYVI) ([slides](files/forging-code-with-schemas-sep-2023-slides.pdf))
## Testing
[How to run local tests](testing.md)
[End-to-end tests (e2e) overview](how-to-launch-e2e.md)
[Component tests (jest) overview](component-tests-overview.md)
- [Overview](tests/tests-overview.md)
- [How to run local tests](tests/how-to-run-local-tests.md)
- [End-to-end tests (e2e) overview](tests/how-to-launch-e2e.md)
- [Component tests (jest) overview](tests/component-tests-overview.md)
## Project details
[status-go introduction (recorded meeting)](https://drive.google.com/file/d/1B7TljmTZ8fHkqJH8ChU1Cp4FGDFM03gq/view)
[re-frame usage (recorded meeting)](https://drive.google.com/file/d/1qv_E0CEGzQpu_zGXD0gCTU5EvhC2k8Jy/view)
[status app functionality demo](https://drive.google.com/file/u/0/d/1PmwsMLTLDNNIdv5_6wvMOwoj2PfT50c6/view)
- [status-go introduction (recorded meeting)](https://drive.google.com/file/d/1B7TljmTZ8fHkqJH8ChU1Cp4FGDFM03gq/view)
- [re-frame usage (recorded meeting)](https://drive.google.com/file/d/1qv_E0CEGzQpu_zGXD0gCTU5EvhC2k8Jy/view)
- [status app functionality demo](https://drive.google.com/file/u/0/d/1PmwsMLTLDNNIdv5_6wvMOwoj2PfT50c6/view)
## Misc
[Importing icons from Figma into project](export-icons.md)
[Updating Status APK builds for the F-Droid Android application catalogue](fdroid.md)
[Troubleshooting for known errors](troubleshooting.md)
- [Importing icons from Figma into project](export-icons.md)
- [Updating Status APK builds for the F-Droid Android application catalogue](fdroid.md)
- [Troubleshooting for known errors](troubleshooting.md)
## Outdated:
[Old guidelines](codebase-structure-and-guidelines.md)
[Post mortem analysis](post-mortem.md)
- [Old guidelines](codebase-structure-and-guidelines.md)
- [Post mortem analysis](post-mortem.md)
+5 -3
View File
@@ -32,14 +32,16 @@ status-mobile code that makes it to the `develop` branch, should always point to
In practice, this means that sometimes they need to be merged in lockstep.
1) Create a PR in status-go and status-mobile. Update the status-go version to the PR revision `scripts/update-status-go.sh $git_revision`.
2) Get both PRs reviewed and approved. Once status-mobile PR has been approved, go through manual QA testing if necessary. Don't merge status-mobile PR just yet.
3) Now that you know the integration between client & server is working, bump the `VERSION` in status-go and merge it.
4) Once merged, tag the version with the new version and push the tag:
3) Now that you know the integration between client & server is working, merge the status-go PR first.
4) Once merged, tag the merged commit with the new version and push the tag:
```
git checkout develop
git pull develop
git tag vx.y.z
make tag-version
git push origin vx.y.z
```
:warning: If a specific commit need to tagged in status-go, use `make tag-version TARGET_COMMIT={hash}`. More info about tagging in [status-go](https://github.com/status-im/status-go/blob/develop/RELEASING.md#tagging-versions).
5) Update status-mobile with the new status-go version, using the new tag `scripts/update-status-go.sh "vx.y.z"`
6) If you had to rebase status-go to include new changes, e2e test MUST be re-run. If there's any issue you will
have to fix in status-go with another PR and follow the same process.
+9 -9
View File
@@ -32,9 +32,9 @@ Ready for testing, a PR should meet the following criteria:
### E2E tests and analyzing the results
The PR **MUST** be moved to the E2E column when it is ready for testing (**mandatory for all PRs**).
That will also trigger e2e tests run. QAs are monitoring PRs from E2E column and take it into test.
That will also trigger e2e tests run. QAs are monitoring PRs from E2E column and take it into test.
This step cannot be skipped. So, at least one comment from the `status-im-auto` bot with results is a prerequisite for moving forward.
Information on how to analyze tests can be found [here](https://github.com/status-im/status-mobile/blob/develop/doc/how-to-launch-e2e.md).
Information on how to analyze tests can be found [here](https://github.com/status-im/status-mobile/blob/develop/doc/tests/how-to-launch-e2e.md).
Tests might be flaky, as they depend on infrastructure - SauceLabs and Waku.
If there are `Failed tests` and you are not sure about the reason, you can always ping the mobile QAs for help (preferably in PRs by `@status-im/mobile-qa`).
@@ -46,14 +46,14 @@ Please, respect this rule.**
### Adding `skip-manual-qa`
**Do not hesitate to use a `skip-manual-qa`** if you're sure that it is a simple flow and you checked it.
**Do not hesitate to use a `skip-manual-qa`** if you're sure that it is a simple flow and you checked it.
- Please ask another team member before adding the `skip-manual-qa` label (PR/Status community/DMs) so that there's a second opinion.
- The PR MUST have a proper reasoning why manual QA is skipped.
- The PR MUST include the steps of testing that has been done by the developer prior to moving it forward.
**NOTE:** Make sure that QAs are OK with that;
Before merging PRs, please make sure that information is added about how you tested the PRs, that e2s have been passed and their results have been reviewed.
Before merging PRs, please make sure that information is added about how you tested the PRs, that e2s have been passed and their results have been reviewed.
The QA team appreciates your help!
@@ -72,7 +72,7 @@ The QA team appreciates your help!
- QA engineer picks up one of PRs with the ```request-manual-qa``` label, drags the item to the ```IN TESTING``` column and assigns it to themselves.
- During testing, QA will add comments describing the issues found, and also review automation tests results.
Usually found issues are numbered as "Issue 1, Issue 2", etc.
When the first round of testing is completed and all issues for this stage are found, the QA can add the ```Tested - Issues``` label and drag the card to the ```CONTRIBUTOR``` column. These two actions are optional.
When the first round of testing is completed and all issues for this stage are found, the QA can add the ```Tested - Issues``` label and drag the card to the ```CONTRIBUTOR``` column. These two actions are optional.
**IMPORTANT NOTE:** when the issues are fixed, developer **MUST** notify the QA that it is ready to be re-tested again by mention them in the PR.
@@ -86,7 +86,7 @@ After that the developer merges PR into develop.
_**How do I know if a design review is needed?**_
There are three cases here depending on the changes in the PR:
1. **Functional PRs with UI changes:** after the ```Tested - OK``` label is added, the QA moves the PR to the ```Design review``` column + mentions ```@Francesca-G``` in comments.
1. **Functional PRs with UI changes:** after the ```Tested - OK``` label is added, the QA moves the PR to the ```Design review``` column + mentions ```@Francesca-G``` in comments.
2. **Component PRs:** once the PR has received a review from developers and e2e tests results, it can be moved directly to the ```Design review``` column by the developer (manual testing step can be skipped) + the developer mentions ```@Francesca-G``` in comments.
3. **Functional PRs changes in which are not related to UI (e.g. a crash fix):** skip the ```Design review``` step (the PR should only be manually tested by QA).
@@ -99,7 +99,7 @@ There are three possible scenarios when the design review is completed:
**Notes:**
- If your PR has a long story and started from `develop` branch several days ago, please rebase it to current develop before adding label
- if PR can be tested by developer (in case of small changes) and/or developer is sure that the changes made cannot introduce a regression, then PR can be merged without manual testing. Also, currently, PRs are not manually tested if the changes relate only the design (creation of components, etc.) and do not affect the functionality (see `skip-manual-qa` label)
---
---
#### Why my PR is in `Contributor` column?
PR can be moved to this column by the ```status-github-bot``` or by QA engineer with label `Tested-issues` or if one of the requirements for manual QA was not met.
@@ -120,6 +120,6 @@ In the second case - after fixing of all found issues, the developer should ping
6. In case of manual testing - the label ```Tested - OK``` from QA
7. In case of design review - the approval from the designer
You can merge your PR into develop - some useful clues you can find [here](https://notes.status.im/setup-e2e#3-Merging-PR)
You can merge your PR into develop - some useful clues you can find [here](https://notes.status.im/setup-e2e#3-Merging-PR)
HAPPY DEVELOPMENT! :tada:
HAPPY DEVELOPMENT! :tada:
@@ -8,7 +8,7 @@ As a part of CI for Status mobile app and in order to ensure there are no regres
- Automated tests written on Python 3.9 and pytest.
- Appium (server) and Selenium WebDriver (protocol) are the base of test automation framework.
TestRail is a test case management system tool where we have test cases.
TestRail is a test case management system tool where we have test cases.
Each of the test case gets a priority (Critical/High/Medium)
@@ -20,21 +20,21 @@ For now we support e2e for Android only.
Whenever we need to push set of test scripts we create 16 parallel sessions (max, but depending on amount of cases that are included in job) and each thread: 1) uploads Android .apk file to SauceLabs -> 2) runs through the test steps -> 3) receives results whether test failed on particular step or succeeded with no errors -> 3) Parse test results and push them as a Github comment (if the suite ran against respective PR) and into TestRail.
We push **whole automation test suite (currently 155, amount is changing)** against each nightly build (if the nightly builds job succeeded). Results of the test run are saved in TestRail.
And also we push set of autotests whenever PR with successful builds got moved in to `E2E Tests` column from [Pipeline for QA dashboard ](https://github.com/status-im/status-react/projects/7).
And also we push set of autotests whenever PR with successful builds got moved in to `E2E Tests` column from [Pipeline for QA dashboard ](https://github.com/status-im/status-react/projects/7).
In that case we save results in TestRail as well and push a comment with test results in a respective PR.
For example: https://github.com/status-im/status-react/pull/9147#issuecomment-540008770
![](images/how-to-launch-e2e/how-to-launch-e2e-1.png)
![](../images/how-to-launch-e2e/how-to-launch-e2e-1.png)
The test_send_stt_from_wallet opens link in TestRail https://ethstatus.testrail.net/index.php?/tests/view/890885 where performed steps could be found
List of all runs performed by test jobs could be found here https://ethstatus.testrail.net/index.php?/runs/overview/14
List of all runs performed by test jobs could be found here https://ethstatus.testrail.net/index.php?/runs/overview/14
**For credentials for TestRail to see results ping Chu in DM**:
Opening any test run navigates you to list of test cases with results:
![](images/how-to-launch-e2e/how-to-launch-e2e-2.png)
![](../images/how-to-launch-e2e/how-to-launch-e2e-2.png)
## What about launching e2e manually
@@ -53,12 +53,12 @@ Params to specify:
- test_marks: tests by priorities (by default: `critical or high or medium`, which corresponds the whole suite; to launch the same suite as in PRs, use `critical or high`)
- testrail_case_id: here is the list of test cases which you may find in test rail (4-digit value)
For easier access you can hit `Rerun tests` in GH comment and testrail_case_id/ apk_name/ pr_id will be filled automatically. For making sure that tests are being rerun on most recent e2e build it is recommended to paste link to the last e2e build in apk_name field. The list of PR builds can be found in Jenkins Builds block on PR page.
![](images/how-to-launch-e2e/how-to-launch-e2e-3.png)
For easier access you can hit `Rerun tests` in GH comment and testrail_case_id/ apk_name/ pr_id will be filled automatically. For making sure that tests are being rerun on most recent e2e build it is recommended to paste link to the last e2e build in apk_name field. The list of PR builds can be found in Jenkins Builds block on PR page.
![](../images/how-to-launch-e2e/how-to-launch-e2e-3.png)
And then hit Build.
Once the job starts it picks up specified tests, runs them against provided apk and sends results to pull request.
Even we have 16 parallel sessions for testing its a time consuming operation (whole test suite we have automated at the moment takes ~140 minutes to finish).
Even we have 16 parallel sessions for testing its a time consuming operation (whole test suite we have automated at the moment takes ~140 minutes to finish).
So for PRs we pick only set of `critical or high` (you can also use this in TEST_MARKS param for job)
tests (otherwise some PRs could wait their turn of the scheduled Jenkins job till the next day).
@@ -78,9 +78,9 @@ Several examples of when test fails to succeed:
- **Valid issue in the automated test scripts** - that's what we're looking for
Example: here is the test results https://github.com/status-im/status-react/pull/13015#issuecomment-1016495043 where one test failed.
Example: here is the test results https://github.com/status-im/status-react/pull/13015#issuecomment-1016495043 where one test failed.
1. Open the test in TestRail and open session recorded for this test in SauceLabs
![](images/how-to-launch-e2e/how-to-launch-e2e-4.png)
![](../images/how-to-launch-e2e/how-to-launch-e2e-4.png)
In TestRail you may find all the steps performed by the test.
@@ -98,6 +98,6 @@ Not all features of the app could be covered by e2e at the moment:
## Brief flow for test to be automated
Whenever there is a need to have a new test:
1) Create a test scenario in TestRail.
1) Create a test scenario in TestRail.
2) If certain item could be checked in scope of existing test case we update existing one (otherwise we may have thousands of test cases which is overkill to manage in TestRail as well as in automated test scripts). And also complex autotests increase probability to not catch regressions by stopping test execution (due to valid bug or changed feature) keeping the rest test steps uncovered. So here we need to balance when it makes sense to update existing test case with more checks.
3) Then we create test script based on the test case, ensure test passes for the build and pushing the changes to repo.
+167
View File
@@ -0,0 +1,167 @@
# Tests
## Introduction
This document provides a general overview of the types of tests we use and when
to use them. It is not meant to be a tutorial or a detailed documentation about
testing in software development.
## Types of tests
Tests in `status-mobile` are comprised of:
- Unit tests
- Subscription tests
- Event tests
- Tests for various utilities
- [Component tests](./component-tests-overview.md)
- Integration/contract tests
- [End-to-end tests](./how-to-launch-e2e.md)
We apply the [test
pyramid](https://en.wikipedia.org/wiki/Test_automation#Testing_at_different_levels)
strategy, which means we want the majority of tests at the bottom of the
pyramid. Those should be fast and deterministic and support REPL-Driven
development (RDD). Slightly above them, we have component tests, then
integration/contract tests and finally end-to-end tests. The closer to the top
of the pyramid, the more valuable a test can be, but also more difficult to
pinpoint why it failed and harder to make it dependable.
*Note*: there are literally dozens of [types of
tests](https://en.wikipedia.org/wiki/Software_testing), each with its strengths
and weaknesses.
We tend not to stub or mock implementations in our tests, which means our tests
are [sociable](https://martinfowler.com/bliki/UnitTest.html).
## What to test?
The UI is driven by global & local state changes caused by events. Global state
is managed by re-frame and local state by Reagent atoms or React hooks. Except
for component and end-to-end tests, we test only non-UI code in `status-mobile`.
Given that the UI is greatly derived from global state, by guaranteeing the
state is correct we can prevent bugs and, more importantly, reduce the [cost of
change](https://www.pmi.org/disciplined-agile/agile/costofchange).
We strive to minimize the amount of _business logic_ in views (UI code). We
achieve this by moving capabilities to status-go and also by adhering to
re-frame's architecture.
Whenever appropriate (see section `When to test?`), we _may_ test:
- Re-frame events.
- Re-frame subscriptions.
- Utility functions.
- User journeys through integration/contract tests.
Interestingly, we don't test re-frame _effects_ in isolation.
### What are status-mobile integration and contract tests?
The mobile _integration tests_ can be used to "simulate" user interactions and
make actual calls to status-go via the RPC layer and actually receive signals.
We can also use these tests to verify the app-db and multiple subscriptions are
correct. We use the word _simulate_ because there is no UI. Basically, any flow
that can be driven by re-frame events is possible to automatically test. There
is no way to change or inspect local state managed by React.
A _contract test_ has the same capabilities as an integration test, but we want
to draw the line that they should focus more on a particupar RPC endpoint or
signal, and not on a user journey (e.g. create a wallet account). In the future,
we may consider running them automatically in status-go.
**Note:** integration tests and contract tests are currently overlapping in
their responsibilities and still require a clearer distinction.
## When to test?
(Automated) tests basically exist to support rapid software changes, but not
every piece of code should be tested. The following are general recommendations,
not rules.
- What would be the consequences to the user of a bug in the implementation you
are working on?
- Can a QA exercise all the branches in the code you changed? Not surprisingly,
usually QAs can't test many code paths (it may be nearly impossible), and
because PRs are not often tested by reviewers, many PRs can get into `develop`
without the necessary quality assurance.
- How costly was it for you to verify a function/event/etc was correct? Now
consider that this cost will be dispersed to every developer who needs to
change the implementation if there are no tests.
- Check the number of conditionals, and if they nest as well. Every conditional
may require two different assertions, and the number of assertions can grow
exponentially.
- How complicated are the arguments to the function? If they contain nested maps
or data that went through a few transformations, it may be tricky to decipher
what they are, unless you are familiar with the code. A test would be able to
capture the data, however complex they are.
### When to unit-test subscriptions?
Only test [layer-3
subscriptions](https://day8.github.io/re-frame/subscriptions/#the-four-layers),
i.e. don't bother testing extractor subscriptions (check the related
[guideline](https://github.com/status-im/status-mobile/blob/7774c4eac16fdee950a17bf5d07630c45a980f41/doc/new-guidelines.md#subscription-tests)).
Some layer-3 subscriptions can still be straightforward and may not be worth
testing.
- Check the number of _inputs_ to the sub (from the graph). The higher this
number, the greater the chance the subscription can break if any of the
input's implementation changes.
**Note**: if a tested subscription changes inadvertently, even if its own tests
still pass, other subscriptions that depend on it and have tests may still fail.
This is why we don't directly test the subscription handler, but instead, use
the macro `test-helpers.unit/deftest-sub`.
### When to unit-test events?
A good hint is to ask if you and other CCs need to rely on re-frisk, UI, REPL,
or FlowStorm to understand the event. If the answer is yes or probably, then a
test would be prudent.
- Many events only receive arguments and pass them along without much or any
transformation to an RPC call. These are straightforward and usually don't
need tests ([example](https://github.com/status-im/status-mobile/blob/7774c4eac16fdee950a17bf5d07630c45a980f41/src/status_im/contexts/contact/blocking/events.cljs#L79-L85)).
- Overall, every event basically returns two effects at most, `:fx` and/or
`:db`. Usually, the complicated part lies in the computation to return the new
app-db. If the event doesn't perform transformations in the app-db or just
does a trivial `assoc`, for example, it may not be worth testing.
For reference, the re-frame author particularly [suggests testing events and
subscriptions](https://github.com/day8/re-frame/blob/09e2d7132c479aa43f2a64164e54e42bf8511902/docs/Testing.md#what-to-test).
### When to unit-test utility functions?
Most utility functions in `status-mobile` are pure and can be readily and
cheaply tested.
- If the utility is used in an event/subscription and if the event/subscription
has tests, you may prefer to test the event/subscription and not the utility,
or the other way around sometimes.
- If the utility is tricky to verify, such as functions manipulating time, write
tests ([example](https://github.com/status-im/status-mobile/blob/7774c4eac16fdee950a17bf5d07630c45a980f41/src/utils/datetime.cljs#L1)).
- Utilities can be particularly hard to verify by QAs because they can be lower
level and require very particular inputs. In such cases, consider writing
tests.
### When to write integration/contract tests?
- You want to make real calls to status-go because you think the unit tests are
not enough (test pyramid strategy).
- You constantly need to retest the same things on the UI, sometimes over
multiple screens.
- The flow is too important to rely only on manual QA, which can't always be
done due to resource limits, so an integration/contract test fills this gap.
- You want to rely less on end-to-end tests, which can be more unreliable and
slower to change.
- You want automatic verifications for some area of the mobile app whenever
status-go is upgraded.
**Note**: the feedback cycle to write integration tests is longer than unit
tests because they are slower and harder to debug. Using the REPL with them is
difficult due to their stateful nature.
### When to test Quo components?
This is covered in [quo/README.md#component-tests](https://github.com/status-im/status-mobile/blob/7774c4eac16fdee950a17bf5d07630c45a980f41/src/quo/README.md#component-tests).
+2 -2
View File
@@ -31,7 +31,7 @@ NOW:
(defn view
[{:keys [on-press on-long-press icon]}]
(let [[pressed? set-pressed] (rn/use-state false)
theme (theme/use-theme-value)
theme (theme/use-theme)
on-press-in (rn/use-callback #(set-pressed true))
on-press-out (rn/use-callback #(set-pressed nil))]
[rn/pressable
@@ -47,7 +47,7 @@ NOW:
- We no longer need to create an anonymous function for rendering. This removes unnecessary confusion and the need for specific knowledge on how it works and why it was needed.
- `rn/use-state` is used instead of `reagent/atom`
- State values no longer need to be dereferenced; they are accessible as regular symbols. This eliminates a common bug where the "@" symbol was inadvertently omitted.
- `theme/with-theme` wrapper is not needed anymore, `(theme/use-theme-value)` hook can be used directly in the components
- `theme/with-theme` wrapper is not needed anymore, `(theme/use-theme)` hook can be used directly in the components
- `:f>` not needed anymore, all components are functional by default
- `rn/use-callback` hook should be used for anon callback functions
+2 -2
View File
@@ -915,7 +915,7 @@ PODS:
- glog
- RCT-Folly (= 2022.05.16.00)
- React-Core
- react-native-compat (2.12.2):
- react-native-compat (2.11.2):
- glog
- RCT-Folly (= 2022.05.16.00)
- React-Core
@@ -1517,7 +1517,7 @@ SPEC CHECKSUMS:
react-native-blob-util: 600972b1782380a5a7d5db61a3817ea32349dae9
react-native-blur: 799045500f56146afc46245148080e7b7623cb75
react-native-cameraroll: af8eec1e585d053ff485d98ec837f9a8a11b5745
react-native-compat: 84e00e8dcff9251278c0d48f2bce81f4502e3925
react-native-compat: 3af9add14d349701306d3d052638435f6795ac2c
react-native-config: 5330c8258265c1e5fdb8c009d2cabd6badd96727
react-native-get-random-values: 21325b2244dfa6b58878f51f9aa42821e7ba3d06
react-native-hole-view: 6935448993bac79f2b5a4ad7e9741094cf810679
@@ -246,6 +246,14 @@ class AccountManager(private val reactContext: ReactApplicationContext) : ReactC
utils.executeRunnableStatusGoMethod({ Statusgo.openAccounts(rootDir) }, callback)
}
@ReactMethod
private fun initializeApplication(request: String, callback: Callback) {
Log.d(TAG, "initializeApplication")
Log.d(TAG, "[Initializing application $request")
utils.executeRunnableStatusGoMethod({ Statusgo.initializeApplication(request) }, callback)
}
@ReactMethod
fun logout() {
Log.d(TAG, "logout")
@@ -92,6 +92,11 @@ public class EncryptionUtils extends ReactContextBaseJavaModule {
return Statusgo.hexToUtf8(str);
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String serializeLegacyKey(final String publicKey) {
return Statusgo.serializeLegacyKey(publicKey);
}
@ReactMethod
public void setBlankPreviewFlag(final Boolean blankPreview) {
final SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this.reactContext);
@@ -76,6 +76,16 @@ class StatusModule(private val reactContext: ReactApplicationContext, private va
utils.executeRunnableStatusGoMethod({ Statusgo.getNodeConfig() }, callback)
}
@ReactMethod
fun addCentralizedMetric(request: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.addCentralizedMetric(request) }, callback)
}
@ReactMethod
fun toggleCentralizedMetrics(request: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.toggleCentralizedMetrics(request) }, callback)
}
@ReactMethod
fun deleteImportedKey(keyUID: String, address: String, password: String, callback: Callback) {
val keyStoreDir = utils.getKeyStorePath(keyUID)
@@ -153,4 +153,9 @@ class Utils(private val reactContext: ReactApplicationContext) : ReactContextBas
return strArray
}
@ReactMethod(isBlockingSynchronousMethod = true)
fun validateConnectionString(connectionString: String): String {
return Statusgo.validateConnectionString(connectionString)
}
}
@@ -195,6 +195,15 @@ RCT_EXPORT_METHOD(verifyDatabasePassword:(NSString *)keyUID
callback(@[result]);
}
RCT_EXPORT_METHOD(initializeApplication:(NSString *)request
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"initializeApplication() method called");
#endif
NSString *result = StatusgoInitializeApplication(request);
callback(@[result]);
}
RCT_EXPORT_METHOD(openAccounts:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"OpenAccounts() method called");
@@ -94,6 +94,10 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(hexToUtf8:(NSString *)str) {
return StatusgoHexToUtf8(str);
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(serializeLegacyKey:(NSString *)str) {
return StatusgoSerializeLegacyKey(str);
}
RCT_EXPORT_METHOD(setBlankPreviewFlag:(BOOL *)newValue)
{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
@@ -176,6 +176,24 @@ RCT_EXPORT_METHOD(appStateChange:(NSString *)type) {
StatusgoAppStateChange(type);
}
RCT_EXPORT_METHOD(addCentralizedMetric:(NSString *)request
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"addCentralizedMetric() method called");
#endif
NSString *result = StatusgoAddCentralizedMetric(request);
callback(@[result]);
}
RCT_EXPORT_METHOD(toggleCentralizedMetrics:(NSString *)request
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"toggleCentralizedMetrics() method called");
#endif
NSString *result = StatusgoToggleCentralizedMetrics(request);
callback(@[result]);
}
RCT_EXPORT_METHOD(startLocalNotifications) {
#if DEBUG
NSLog(@"StartLocalNotifications() method called");
@@ -128,4 +128,8 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(toChecksumAddress:(NSString *)address) {
return StatusgoToChecksumAddress(address);
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(validateConnectionString:(NSString *)cs) {
return StatusgoValidateConnectionString(cs);
}
@end
+65 -1
View File
@@ -302,6 +302,36 @@ void _MultiAccountStoreAccount(const FunctionCallbackInfo<Value>& args) {
delete c;
}
void _InitializeApplication(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
if (args.Length() != 1) {
// Throw an Error that is passed back to JavaScript
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for InitializeApplication")));
return;
}
// Check the argument types
if (!args[0]->IsString()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong argument type for request")));
return;
}
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
char *arg0 = *arg0Obj;
// Call exported Go function, which returns a C string
char *c = InitializeApplication(arg0);
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
args.GetReturnValue().Set(ret);
delete c;
}
void _InitKeystore(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
@@ -642,6 +672,38 @@ void _Sha3(const FunctionCallbackInfo<Value>& args) {
}
void _SerializeLegacyKey(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
if (args.Length() != 1) {
// Throw an Error that is passed back to JavaScript
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for SerializeLegacyKey")));
return;
}
// Check the argument types
if (!args[0]->IsString()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'str'")));
return;
}
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
char *arg0 = *arg0Obj;
// Call exported Go function, which returns a C string
char *c = SerializeLegacyKey(arg0);
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
args.GetReturnValue().Set(ret);
delete c;
}
void _ToChecksumAddress(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
@@ -1935,6 +1997,7 @@ void init(Local<Object> exports) {
NODE_SET_METHOD(exports, "multiAccountStoreDerivedAccounts", _MultiAccountStoreDerivedAccounts);
NODE_SET_METHOD(exports, "multiAccountStoreAccount", _MultiAccountStoreAccount);
NODE_SET_METHOD(exports, "initKeystore", _InitKeystore);
NODE_SET_METHOD(exports, "initializeApplication", _InitializeApplication);
NODE_SET_METHOD(exports, "fleets", _Fleets);
NODE_SET_METHOD(exports, "stopCPUProfiling", _StopCPUProfiling);
NODE_SET_METHOD(exports, "encodeTransfer", _EncodeTransfer);
@@ -1945,6 +2008,7 @@ void init(Local<Object> exports) {
NODE_SET_METHOD(exports, "checkAddressChecksum", _CheckAddressChecksum);
NODE_SET_METHOD(exports, "isAddress", _IsAddress);
NODE_SET_METHOD(exports, "sha3", _Sha3);
NODE_SET_METHOD(exports, "serializeLegacyKey", _SerializeLegacyKey);
NODE_SET_METHOD(exports, "toChecksumAddress", _ToChecksumAddress);
NODE_SET_METHOD(exports, "logout", _Logout);
NODE_SET_METHOD(exports, "hashMessage", _HashMessage);
@@ -1972,7 +2036,7 @@ void init(Local<Object> exports) {
NODE_SET_METHOD(exports, "signTypedData", _SignTypedData);
NODE_SET_METHOD(exports, "sendTransaction", _SendTransaction);
NODE_SET_METHOD(exports, "appStateChange", _AppStateChange);
NODE_SET_METHOD(exports, "setSignalEventCallback", _SetSignalEventCallback);
NODE_SET_METHOD(exports, "setSignalEventCallback", _SetSignalEventCallback);
NODE_SET_METHOD(exports, "validateNodeConfig", _ValidateNodeConfig);
NODE_SET_METHOD(exports, "hashTypedData", _HashTypedData);
NODE_SET_METHOD(exports, "recover", _Recover);
+3 -3
View File
@@ -711,11 +711,11 @@
},
{
"path": "nubank/matcher-combinators/3.8.8/matcher-combinators-3.8.8",
"path": "nubank/matcher-combinators/3.9.1/matcher-combinators-3.9.1",
"host": "https://repo.clojars.org",
"jar": {
"sha1": "4c94bd510f0c18a20191e46dd6becedebc640bbd",
"sha256": "0wpla2hx0s4mda58ndyd8938zmnz1gyhgfr6pzfphy27xfbvsssl"
"sha1": "f0830a112cae8ee931a90d9f39214a0ed4d44150",
"sha256": "1rjcgqhms84xmnhs7sqcd3b2dpa37mmzgz2yz33yz2rdb9skl96g"
}
},
+1 -1
View File
@@ -77,7 +77,7 @@ net/cgrand/macrovich/0.2.1/macrovich-0.2.1.jar
net/java/dev/jna/jna/5.12.1/jna-5.12.1.jar
nrepl/bencode/1.1.0/bencode-1.1.0.jar
nrepl/nrepl/1.0.0/nrepl-1.0.0.jar
nubank/matcher-combinators/3.8.8/matcher-combinators-3.8.8.jar
nubank/matcher-combinators/3.9.1/matcher-combinators-3.9.1.jar
org/apache/ant/ant/1.10.11/ant-1.10.11.jar
org/apache/ant/ant-launcher/1.10.11/ant-launcher-1.10.11.jar
org/apache/commons/commons-lang3/3.12.0/commons-lang3-3.12.0.jar
+1 -1
View File
@@ -57,7 +57,7 @@ in {
yarn = super.yarn.override { nodejs = super.nodejs-18_x; };
openjdk = super.openjdk11_headless;
xcodeWrapper = callPackage ./pkgs/xcodeenv/compose-xcodewrapper.nix { } {
versions = ["15.1" "15.2" "15.3"];
versions = ["15.1" "15.2" "15.3" "15.4"];
};
go = super.go_1_21;
clang = super.clang_15;
+5 -3
View File
@@ -20,9 +20,10 @@
"@react-native-community/netinfo": "^4.4.0",
"@react-native-community/push-notification-ios": "^1.4.1",
"@react-native-community/slider": "^3.0.0",
"@walletconnect/react-native-compat": "^2.12.2",
"@walletconnect/web3wallet": "^1.11.2",
"@walletconnect/react-native-compat": "2.11.2",
"@walletconnect/web3wallet": "1.10.2",
"base-64": "^1.0.0",
"big-integer": "1.6.51",
"bignumber.js": "git+https://github.com/status-im/bignumber.js.git#refs/tags/v4.0.2-status",
"chance": "^1.1.0",
"emojilib": "^2.4.0",
@@ -96,7 +97,8 @@
"jest-silent-reporter": "^0.5.0",
"nodemon": "^2.0.16",
"nyc": "^14.1.1",
"prettier": "^2.8.8",
"prettier": "^3.3.3",
"prettier-plugin-sort-json": "^4.0.0",
"process": "0.11.10",
"react-test-renderer": "18.1.0",
"shadow-cljs": "2.26.2",
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

+2
View File
@@ -45,6 +45,8 @@ SECRETS_ENV_VARS=(
'INFURA_TOKEN'
'INFURA_TOKEN_SECRET'
'OPENSEA_API_KEY'
'MIXPANEL_APP_ID'
'MIXPANEL_TOKEN'
'POKT_TOKEN'
)
+7 -1
View File
@@ -19,7 +19,7 @@
[cider/piggieback "0.4.1"]
[org.slf4j/slf4j-nop "2.0.9"]
[re-frisk-remote "1.6.0"]
[nubank/matcher-combinators "3.8.8"]
[nubank/matcher-combinators "3.9.1"]
;; Use the same version specified in the Nix dependency.
[clj-kondo/clj-kondo "2024.03.13"]
@@ -67,6 +67,8 @@
:closure-defines
{status-im.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
status-im.config/INFURA_TOKEN #shadow/env "INFURA_TOKEN"
status-im.config/MIXPANEL_APP_ID #shadow/env "MIXPANEL_APP_ID"
status-im.config/MIXPANEL_TOKEN #shadow/env "MIXPANEL_TOKEN"
status-im.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"
status-im.config/RARIBLE_MAINNET_API_KEY #shadow/env "RARIBLE_MAINNET_API_KEY"
status-im.config/RARIBLE_TESTNET_API_KEY #shadow/env "RARIBLE_TESTNET_API_KEY"
@@ -102,6 +104,8 @@
{status-im.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
status-im.config/INFURA_TOKEN #shadow/env "INFURA_TOKEN"
status-im.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"
status-im.config/MIXPANEL_APP_ID #shadow/env "MIXPANEL_APP_ID"
status-im.config/MIXPANEL_TOKEN #shadow/env "MIXPANEL_TOKEN"
status-im.config/RARIBLE_MAINNET_API_KEY #shadow/env "RARIBLE_MAINNET_API_KEY"
status-im.config/RARIBLE_TESTNET_API_KEY #shadow/env "RARIBLE_TESTNET_API_KEY"
status-im.config/ALCHEMY_ETHEREUM_MAINNET_TOKEN #shadow/env "ALCHEMY_ETHEREUM_MAINNET_TOKEN"
@@ -143,6 +147,8 @@
status-im.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
status-im.config/INFURA_TOKEN #shadow/env "INFURA_TOKEN"
status-im.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"
status-im.config/MIXPANEL_APP_ID #shadow/env "MIXPANEL_APP_ID"
status-im.config/MIXPANEL_TOKEN #shadow/env "MIXPANEL_TOKEN"
status-im.config/RARIBLE_MAINNET_API_KEY #shadow/env "RARIBLE_MAINNET_API_KEY"
status-im.config/RARIBLE_TESTNET_API_KEY #shadow/env "RARIBLE_TESTNET_API_KEY"
status-im.config/ALCHEMY_ETHEREUM_MAINNET_TOKEN #shadow/env "ALCHEMY_ETHEREUM_MAINNET_TOKEN"
+276 -37
View File
@@ -1,38 +1,277 @@
(ns keycard.keycard)
(ns keycard.keycard
(:require
["react-native" :as rn]
["react-native-status-keycard" :default status-keycard]
[react-native.platform :as platform]
[taoensso.timbre :as log]
[utils.address :as address]))
(defprotocol Keycard
(start-nfc [this args])
(stop-nfc [this args])
(set-nfc-message [this args])
(check-nfc-support [this args])
(check-nfc-enabled [this args])
(open-nfc-settings [this])
(register-card-events [this args])
(set-pairings [this args])
(on-card-disconnected [this callback])
(on-card-connected [this callback])
(remove-event-listener [this event])
(remove-event-listeners [this])
(get-application-info [this args])
(factory-reset [this args])
(install-applet [this args])
(install-cash-applet [this args])
(init-card [this args])
(install-applet-and-init-card [this args])
(pair [this args])
(generate-and-load-key [this args])
(unblock-pin [this args])
(verify-pin [this args])
(change-pin [this args])
(change-puk [this args])
(change-pairing [this args])
(unpair [this args])
(delete [this args])
(remove-key [this args])
(remove-key-with-unpair [this args])
(export-key [this args])
(unpair-and-delete [this args])
(import-keys [this args])
(get-keys [this args])
(sign [this args])
(sign-typed-data [this args]))
(defonce event-emitter
(if platform/ios?
(new (.-NativeEventEmitter rn) status-keycard)
(.-DeviceEventEmitter rn)))
(defn start-nfc
[{:keys [on-success on-failure prompt-message]}]
(log/debug "start-nfc")
(.. status-keycard
(startNFC (str prompt-message))
(then on-success)
(catch on-failure)))
(defn stop-nfc
[{:keys [on-success on-failure error-message]}]
(log/debug "stop-nfc")
(.. status-keycard
(stopNFC (str error-message))
(then on-success)
(catch on-failure)))
(defn set-nfc-message
[{:keys [on-success on-failure status-message]}]
(log/debug "set-nfc-message")
(.. status-keycard
(setNFCMessage (str status-message))
(then on-success)
(catch on-failure)))
(defn check-nfc-support
[{:keys [on-success]}]
(.. status-keycard
nfcIsSupported
(then on-success)))
(defn check-nfc-enabled
[{:keys [on-success]}]
(.. status-keycard
nfcIsEnabled
(then on-success)))
(defn open-nfc-settings
[]
(.openNfcSettings status-keycard))
(defn remove-event-listeners
[]
(doseq [event ["keyCardOnConnected" "keyCardOnDisconnected" "keyCardOnNFCUserCancelled"
"keyCardOnNFCTimeout"]]
(.removeAllListeners ^js event-emitter event)))
(defn remove-event-listener
[^js event]
(when event
(.remove event)))
(defn on-card-connected
[callback]
(.addListener ^js event-emitter "keyCardOnConnected" callback))
(defn on-card-disconnected
[callback]
(.addListener ^js event-emitter "keyCardOnDisconnected" callback))
(defn on-nfc-user-cancelled
[callback]
(.addListener ^js event-emitter "keyCardOnNFCUserCancelled" callback))
(defn on-nfc-timeout
[callback]
(.addListener ^js event-emitter "keyCardOnNFCTimeout" callback))
(defn on-nfc-enabled
[callback]
(.addListener ^js event-emitter "keyCardOnNFCEnabled" callback))
(defn on-nfc-disabled
[callback]
(.addListener ^js event-emitter "keyCardOnNFCDisabled" callback))
(defn set-pairings
[pairings]
(.. status-keycard (setPairings (clj->js (or pairings {})))))
(defn get-application-info
[{:keys [on-success on-failure]}]
(.. status-keycard
(getApplicationInfo)
(then (fn [response]
(let [info (-> response
(js->clj :keywordize-keys true)
(update :key-uid address/normalized-hex))]
(on-success info))))
(catch on-failure)))
(defn factory-reset
[{:keys [on-success on-failure]}]
(.. status-keycard
(factoryReset)
(then (fn [response]
(let [info (-> response
(js->clj :keywordize-keys true)
(update :key-uid address/normalized-hex))]
(on-success info))))
(catch on-failure)))
(defn install-applet
[{:keys [on-success on-failure]}]
(.. status-keycard
installApplet
(then on-success)
(catch on-failure)))
(defn install-cash-applet
[{:keys [on-success on-failure]}]
(.. status-keycard
installCashApplet
(then on-success)
(catch on-failure)))
(defn init-card
[{:keys [pin on-success on-failure]}]
(.. status-keycard
(init pin)
(then on-success)
(catch on-failure)))
(defn install-applet-and-init-card
[{:keys [pin on-success on-failure]}]
(.. status-keycard
(installAppletAndInitCard pin)
(then on-success)
(catch on-failure)))
(defn pair
[{:keys [password on-success on-failure]}]
(when password
(.. status-keycard
(pair password)
(then on-success)
(catch on-failure))))
(defn generate-and-load-key
[{:keys [mnemonic pin on-success on-failure]}]
(.. status-keycard
(generateAndLoadKey mnemonic pin)
(then on-success)
(catch on-failure)))
(defn unblock-pin
[{:keys [puk new-pin on-success on-failure]}]
(when (and new-pin puk)
(.. status-keycard
(unblockPin puk new-pin)
(then on-success)
(catch on-failure))))
(defn verify-pin
[{:keys [pin on-success on-failure]}]
(when (not-empty pin)
(.. status-keycard
(verifyPin pin)
(then on-success)
(catch on-failure))))
(defn change-pin
[{:keys [current-pin new-pin on-success on-failure]}]
(when (and current-pin new-pin)
(.. status-keycard
(changePin current-pin new-pin)
(then on-success)
(catch on-failure))))
(defn change-puk
[{:keys [pin puk on-success on-failure]}]
(when (and pin puk)
(.. status-keycard
(changePUK pin puk)
(then on-success)
(catch on-failure))))
(defn change-pairing
[{:keys [pin pairing on-success on-failure]}]
(when (and pin pairing)
(.. status-keycard
(changePairingPassword pin pairing)
(then on-success)
(catch on-failure))))
(defn unpair
[{:keys [pin on-success on-failure]}]
(when pin
(.. status-keycard
(unpair pin)
(then on-success)
(catch on-failure))))
(defn delete
[{:keys [on-success on-failure]}]
(.. status-keycard
(delete)
(then on-success)
(catch on-failure)))
(defn remove-key
[{:keys [pin on-success on-failure]}]
(.. status-keycard
(removeKey pin)
(then on-success)
(catch on-failure)))
(defn remove-key-with-unpair
[{:keys [pin on-success on-failure]}]
(.. status-keycard
(removeKeyWithUnpair pin)
(then on-success)
(catch on-failure)))
(defn export-key
[{:keys [pin path on-success on-failure]}]
(.. status-keycard
(exportKeyWithPath pin path)
(then on-success)
(catch on-failure)))
(defn unpair-and-delete
[{:keys [pin on-success on-failure]}]
(when (not-empty pin)
(.. status-keycard
(unpairAndDelete pin)
(then on-success)
(catch on-failure))))
(defn import-keys
[{:keys [pin on-success on-failure]}]
(when (not-empty pin)
(.. status-keycard
(importKeys pin)
(then on-success)
(catch on-failure))))
(defn get-keys
[{:keys [pin on-success on-failure]}]
(when (not-empty pin)
(.. status-keycard
(getKeys pin)
(then on-success)
(catch on-failure))))
(defn sign
[{pin :pin path :path card-hash :hash on-success :on-success on-failure :on-failure}]
(when (and pin card-hash)
(if path
(.. status-keycard
(signWithPath pin path card-hash)
(then on-success)
(catch on-failure))
(.. status-keycard
(sign pin card-hash)
(then on-success)
(catch on-failure)))))
(defn sign-typed-data
[{card-hash :hash on-success :on-success on-failure :on-failure}]
(when card-hash
(.. status-keycard
(signPinless card-hash)
(then on-success)
(catch on-failure))))
-365
View File
@@ -1,365 +0,0 @@
(ns keycard.real-keycard
(:require
["react-native" :as rn]
["react-native-status-keycard" :default status-keycard]
[keycard.keycard :as keycard]
[react-native.platform :as platform]
[taoensso.timbre :as log]
[utils.address :as address]))
(defonce event-emitter
(if platform/ios?
(new (.-NativeEventEmitter rn) status-keycard)
(.-DeviceEventEmitter rn)))
(defonce active-listeners (atom []))
(defn start-nfc
[{:keys [on-success on-failure prompt-message]}]
(log/debug "start-nfc")
(.. status-keycard
(startNFC (str prompt-message))
(then on-success)
(catch on-failure)))
(defn stop-nfc
[{:keys [on-success on-failure error-message]}]
(log/debug "stop-nfc")
(.. status-keycard
(stopNFC (str error-message))
(then on-success)
(catch on-failure)))
(defn set-nfc-message
[{:keys [on-success on-failure status-message]}]
(log/debug "set-nfc-message")
(.. status-keycard
(setNFCMessage (str status-message))
(then on-success)
(catch on-failure)))
(defn check-nfc-support
[{:keys [on-success]}]
(.. status-keycard
nfcIsSupported
(then on-success)))
(defn check-nfc-enabled
[{:keys [on-success]}]
(.. status-keycard
nfcIsEnabled
(then on-success)))
(defn open-nfc-settings
[]
(.openNfcSettings status-keycard))
(defn remove-event-listeners
[]
(doseq [event ["keyCardOnConnected" "keyCardOnDisconnected" "keyCardOnNFCUserCancelled"
"keyCardOnNFCTimeout"]]
(.removeAllListeners ^js event-emitter event)))
(defn remove-event-listener
[^js event]
(.remove event))
(defn on-card-connected
[callback]
(.addListener ^js event-emitter "keyCardOnConnected" callback))
(defn on-card-disconnected
[callback]
(.addListener ^js event-emitter "keyCardOnDisconnected" callback))
(defn on-nfc-user-cancelled
[callback]
(.addListener ^js event-emitter "keyCardOnNFCUserCancelled" callback))
(defn on-nfc-timeout
[callback]
(.addListener ^js event-emitter "keyCardOnNFCTimeout" callback))
(defn on-nfc-enabled
[callback]
(.addListener ^js event-emitter "keyCardOnNFCEnabled" callback))
(defn on-nfc-disabled
[callback]
(.addListener ^js event-emitter "keyCardOnNFCDisabled" callback))
(defn set-pairings
[{:keys [pairings]}]
(.. status-keycard (setPairings (clj->js (or pairings {})))))
(defn register-card-events
[args]
(doseq [listener @active-listeners]
(remove-event-listener listener))
(reset! active-listeners
[(on-card-connected (:on-card-connected args))
(on-card-disconnected (:on-card-disconnected args))
(on-nfc-user-cancelled (:on-nfc-user-cancelled args))
(on-nfc-timeout (:on-nfc-timeout args))
(on-nfc-enabled (:on-nfc-enabled args))
(on-nfc-disabled (:on-nfc-disabled args))]))
(defn get-application-info
[{:keys [on-success on-failure]}]
(.. status-keycard
(getApplicationInfo)
(then (fn [response]
(let [info (-> response
(js->clj :keywordize-keys true)
(update :key-uid address/normalized-hex))]
(on-success info))))
(catch on-failure)))
(defn factory-reset
[{:keys [on-success on-failure]}]
(.. status-keycard
(factoryReset)
(then (fn [response]
(let [info (-> response
(js->clj :keywordize-keys true)
(update :key-uid address/normalized-hex))]
(on-success info))))
(catch on-failure)))
(defn install-applet
[{:keys [on-success on-failure]}]
(.. status-keycard
installApplet
(then on-success)
(catch on-failure)))
(defn install-cash-applet
[{:keys [on-success on-failure]}]
(.. status-keycard
installCashApplet
(then on-success)
(catch on-failure)))
(defn init-card
[{:keys [pin on-success on-failure]}]
(.. status-keycard
(init pin)
(then on-success)
(catch on-failure)))
(defn install-applet-and-init-card
[{:keys [pin on-success on-failure]}]
(.. status-keycard
(installAppletAndInitCard pin)
(then on-success)
(catch on-failure)))
(defn pair
[{:keys [password on-success on-failure]}]
(when password
(.. status-keycard
(pair password)
(then on-success)
(catch on-failure))))
(defn generate-and-load-key
[{:keys [mnemonic pin on-success on-failure]}]
(.. status-keycard
(generateAndLoadKey mnemonic pin)
(then on-success)
(catch on-failure)))
(defn unblock-pin
[{:keys [puk new-pin on-success on-failure]}]
(when (and new-pin puk)
(.. status-keycard
(unblockPin puk new-pin)
(then on-success)
(catch on-failure))))
(defn verify-pin
[{:keys [pin on-success on-failure]}]
(when (not-empty pin)
(.. status-keycard
(verifyPin pin)
(then on-success)
(catch on-failure))))
(defn change-pin
[{:keys [current-pin new-pin on-success on-failure]}]
(when (and current-pin new-pin)
(.. status-keycard
(changePin current-pin new-pin)
(then on-success)
(catch on-failure))))
(defn change-puk
[{:keys [pin puk on-success on-failure]}]
(when (and pin puk)
(.. status-keycard
(changePUK pin puk)
(then on-success)
(catch on-failure))))
(defn change-pairing
[{:keys [pin pairing on-success on-failure]}]
(when (and pin pairing)
(.. status-keycard
(changePairingPassword pin pairing)
(then on-success)
(catch on-failure))))
(defn unpair
[{:keys [pin on-success on-failure]}]
(when pin
(.. status-keycard
(unpair pin)
(then on-success)
(catch on-failure))))
(defn delete
[{:keys [on-success on-failure]}]
(.. status-keycard
(delete)
(then on-success)
(catch on-failure)))
(defn remove-key
[{:keys [pin on-success on-failure]}]
(.. status-keycard
(removeKey pin)
(then on-success)
(catch on-failure)))
(defn remove-key-with-unpair
[{:keys [pin on-success on-failure]}]
(.. status-keycard
(removeKeyWithUnpair pin)
(then on-success)
(catch on-failure)))
(defn export-key
[{:keys [pin path on-success on-failure]}]
(.. status-keycard
(exportKeyWithPath pin path)
(then on-success)
(catch on-failure)))
(defn unpair-and-delete
[{:keys [pin on-success on-failure]}]
(when (not-empty pin)
(.. status-keycard
(unpairAndDelete pin)
(then on-success)
(catch on-failure))))
(defn import-keys
[{:keys [pin on-success on-failure]}]
(when (not-empty pin)
(.. status-keycard
(importKeys pin)
(then on-success)
(catch on-failure))))
(defn get-keys
[{:keys [pin on-success on-failure]}]
(when (not-empty pin)
(.. status-keycard
(getKeys pin)
(then on-success)
(catch on-failure))))
(defn sign
[{pin :pin path :path card-hash :hash on-success :on-success on-failure :on-failure}]
(when (and pin card-hash)
(if path
(.. status-keycard
(signWithPath pin path card-hash)
(then on-success)
(catch on-failure))
(.. status-keycard
(sign pin card-hash)
(then on-success)
(catch on-failure)))))
(defn sign-typed-data
[{card-hash :hash on-success :on-success on-failure :on-failure}]
(when card-hash
(.. status-keycard
(signPinless card-hash)
(then on-success)
(catch on-failure))))
(defrecord RealKeycard []
keycard/Keycard
(keycard/start-nfc [_this args]
(start-nfc args))
(keycard/stop-nfc [_this args]
(stop-nfc args))
(keycard/set-nfc-message [_this args]
(set-nfc-message args))
(keycard/check-nfc-support [_this args]
(check-nfc-support args))
(keycard/check-nfc-enabled [_this args]
(check-nfc-enabled args))
(keycard/open-nfc-settings [_this]
(open-nfc-settings))
(keycard/register-card-events [_this args]
(register-card-events args))
(keycard/on-card-connected [_this callback]
(on-card-connected callback))
(keycard/on-card-disconnected [_this callback]
(on-card-disconnected callback))
(keycard/remove-event-listener [_this event]
(remove-event-listener event))
(keycard/remove-event-listeners [_this]
(remove-event-listeners))
(keycard/set-pairings [_this args]
(set-pairings args))
(keycard/get-application-info [_this args]
(get-application-info args))
(keycard/factory-reset [_this args]
(factory-reset args))
(keycard/install-applet [_this args]
(install-applet args))
(keycard/install-cash-applet [_this args]
(install-cash-applet args))
(keycard/init-card [_this args]
(init-card args))
(keycard/install-applet-and-init-card [_this args]
(install-applet-and-init-card args))
(keycard/pair [_this args]
(pair args))
(keycard/generate-and-load-key [_this args]
(generate-and-load-key args))
(keycard/unblock-pin [_this args]
(unblock-pin args))
(keycard/verify-pin [_this args]
(verify-pin args))
(keycard/change-pin [_this args]
(change-pin args))
(keycard/change-puk [_this args]
(change-puk args))
(keycard/change-pairing [_this args]
(change-pairing args))
(keycard/unpair [_this args]
(unpair args))
(keycard/delete [_this args]
(delete args))
(keycard/remove-key [_this args]
(remove-key args))
(keycard/remove-key-with-unpair [_this args]
(remove-key-with-unpair args))
(keycard/export-key [_this args]
(export-key args))
(keycard/unpair-and-delete [_this args]
(unpair-and-delete args))
(keycard/import-keys [_this args]
(import-keys args))
(keycard/get-keys [_this args]
(get-keys args))
(keycard/sign [_this args]
(sign args))
(keycard/sign-typed-data [_this args]
(sign-typed-data args)))
+1 -4
View File
@@ -18,7 +18,6 @@
legacy.status-im.multiaccounts.logout.core
[legacy.status-im.multiaccounts.model :as multiaccounts.model]
legacy.status-im.multiaccounts.update.core
legacy.status-im.network.net-info
legacy.status-im.pairing.core
legacy.status-im.profile.core
legacy.status-im.search.core
@@ -26,7 +25,6 @@
legacy.status-im.ui.components.invite.events
[legacy.status-im.ui.components.react :as react]
legacy.status-im.ui.screens.notifications-settings.events
legacy.status-im.ui.screens.privacy-and-security-settings.events
[legacy.status-im.utils.dimensions :as dimensions]
legacy.status-im.utils.logging.core
[legacy.status-im.utils.utils :as utils]
@@ -108,8 +106,7 @@
(when (and (multiaccounts.model/logged-in? db)
(= current-theme-type status-im.constants/theme-type-system))
{:profile.settings/switch-theme-fx
[(get-in db [:profile/profile :appearance])
(:view-id db) true]})))
[(get-in db [:profile/profile :appearance]) (:view-id db)]})))
(defn- on-biometric-auth-fail
[{:keys [code]}]
@@ -120,12 +120,3 @@
{:events [:multiaccounts.ui/switch-backup-enabled]}
[cofx enabled?]
(multiaccount-update cofx :backup-enabled? enabled? {}))
(rf/defn toggle-opensea-nfts-visibility
{:events [::toggle-opensea-nfts-visiblity]}
[cofx visible?]
(rf/merge cofx
{:db (assoc-in (:db cofx) [:profile/profile :opensea-enabled?] visible?)
;; need to add fully qualified namespace to counter circular deps
:dispatch [:legacy.status-im.wallet.core/fetch-collectibles-collection]}
(multiaccount-update :opensea-enabled? visible? {})))
@@ -1,56 +0,0 @@
(ns legacy.status-im.network.net-info
(:require
["@react-native-community/netinfo" :default net-info]
[native-module.core :as native-module]
[re-frame.core :as re-frame]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
(rf/defn change-network-status
[{:keys [db] :as cofx} is-connected?]
(rf/merge cofx
{:db (assoc db :network-status (if is-connected? :online :offline))}))
(rf/defn change-network-type
[{:keys [db] :as cofx} network-type expensive?]
(rf/merge cofx
{:db (assoc db :network/type network-type)
:network/notify-status-go [network-type expensive?]
:dispatch [:mobile-network/on-network-status-change]}))
(rf/defn handle-network-info-change
{:events [::network-info-changed]}
[{:keys [db] :as cofx} {:keys [isConnected type details] :as state}]
(let [old-network-status (:network-status db)
old-network-type (:network/type db)
connectivity-status (if isConnected :online :offline)
status-changed? (= connectivity-status old-network-status)
type-changed? (= type old-network-type)]
(log/debug "[net-info]"
"old-network-status" old-network-status
"old-network-type" old-network-type
"connectivity-status" connectivity-status
"type" type
"details" details)
(rf/merge cofx
(when-not status-changed?
(change-network-status isConnected))
(when-not type-changed?
(change-network-type type (:is-connection-expensive details))))))
(defn add-net-info-listener
[]
(when net-info
(.addEventListener ^js net-info
#(re-frame/dispatch [::network-info-changed
(js->clj % :keywordize-keys true)]))))
(re-frame/reg-fx
:network/listen-to-network-info
(fn []
(add-net-info-listener)))
(re-frame/reg-fx
:network/notify-status-go
(fn [[network-type expensive?]]
(native-module/connection-change network-type expensive?)))
+29 -1
View File
@@ -4,6 +4,7 @@
[re-frame.core :as re-frame]
[react-native.platform :as utils.platform]
[status-im.common.json-rpc.events :as json-rpc]
[status-im.common.new-device-sheet.view :as new-device-sheet]
[status-im.config :as config]
[status-im.navigation.events :as navigation]
[taoensso.timbre :as log]
@@ -220,6 +221,12 @@
:name (:name metadata)
:device-type (:deviceType metadata))})
(defn should-show-syncing-pop-up?
[db installations]
(and (:syncing/pairing-process-initiated? db)
(first (filter #(not (get-in db [:pairing/installations (:id %)])) installations))))
(rf/defn handle-installations
[{:keys [db]} installations]
{:db (update db
@@ -228,7 +235,10 @@
(fn [acc {:keys [id] :as i}]
(update acc id merge (installation<-rpc i)))
%
installations))})
installations))
:fx [(when-let [new-installation (should-show-syncing-pop-up? db installations)]
[:dispatch
[:show-bottom-sheet {:content (fn [] [new-device-sheet/view (:id new-installation)])}]])]})
(rf/defn load-installations
{:events [:pairing.callback/get-our-installations-success]}
@@ -243,6 +253,24 @@
{}
installations))})
(rf/defn finish-seed-phrase-fallback-syncing
{:events [:pairing/finish-seed-phrase-fallback-syncing]}
[{:keys [db]}]
{:fx [[:dispatch [:show-bottom-sheet {:content (fn [] [new-device-sheet/view-2])}]]
[:json-rpc/call
[{:method "wakuext_finishPairingThroughSeedPhraseProcess"
:params [{:installationId (:syncing/installation-id db)}]
:js-response true
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])}]]]})
(rf/defn pair-and-sync
{:events [:pairing/pair-and-sync]}
[cofx installation-id]
{:fx [[:json-rpc/call
[{:method "wakuext_enableAndSyncInstallation"
:params [{:installationId installation-id}]
:on-success #(log/debug "successfully synced devices")}]]]})
(rf/defn enable-installation-success
{:events [:pairing.callback/enable-installation-success]}
[cofx installation-id]
+1 -3
View File
@@ -15,9 +15,7 @@
(reg-root-key-sub :visibility-status-updates :visibility-status-updates)
(reg-root-key-sub :fleets/custom-fleets :custom-fleets)
(reg-root-key-sub :ui/search :ui/search)
(reg-root-key-sub :network/type :network/type)
(reg-root-key-sub :network-status :network-status)
(reg-root-key-sub :peers-count :peers-count)
(reg-root-key-sub :peer-stats/count :peer-stats/count)
(reg-root-key-sub :peers-summary :peers-summary)
(reg-root-key-sub :web3-node-version :web3-node-version)
@@ -1,14 +1,9 @@
(ns legacy.status-im.ui.components.connectivity.view
(:require
[clojure.string :as string]
[legacy.status-im.ui.components.animation :as animation]
[legacy.status-im.ui.components.colors :as colors]
[legacy.status-im.ui.components.core :as quo]
[legacy.status-im.ui.components.list.item :as list.item]
[legacy.status-im.ui.components.react :as react]
[re-frame.core :as re-frame]
[utils.i18n :as i18n])
(:require-macros [legacy.status-im.utils.views :as views :refer [defview letsubs]]))
[legacy.status-im.ui.components.react :as react])
(:require-macros [legacy.status-im.utils.views :as views]))
(defn easing
[direction n]
@@ -72,112 +67,3 @@
colors/white)
:left
(* 0.15 parent-width))}]]]))
(defview loading-indicator
[]
(letsubs [fetching? [:mailserver/fetching?]
window-width [:dimensions/window-width]]
(when fetching?
[loading-indicator-anim window-width])))
(defn hide-sheet-and-dispatch
[event]
(re-frame/dispatch [:bottom-sheet/hide-old])
(re-frame/dispatch event))
(defview connectivity-sheet
[]
(letsubs [{:keys [peers node mobile sync]} [:connectivity/state]
current-mailserver-name [:mailserver/current-name]
peers-count [:peers-count]
{:keys [syncing-on-mobile-network?]} [:profile/profile]]
[:<>
[quo/header {:title (i18n/label :t/connection-status) :border-bottom false}]
[quo/list-header (i18n/label :t/peer-to-peer)]
(if (= peers :offline)
[list.item/list-item
{:title (i18n/label :t/not-connected-to-peers)
:accessibility-label "not-connected-to-peers"
:subtitle (i18n/label :t/unable-to-send-messages)
:subtitle-max-lines 2
:theme :negative
:icon :main-icons/network}]
[list.item/list-item
{:title (str (i18n/label :t/connected-to)
" " peers-count
" " (string/lower-case (i18n/label :t/peers)))
:accessibility-label "connected-to-n-peers"
:subtitle (i18n/label :t/can-send-messages)
:subtitle-max-lines 2
:theme :positive
:icon :main-icons/network}])
[quo/list-header (i18n/label :t/history-nodes)]
(cond
(#{:error :offline} node)
[list.item/list-item
{:title (i18n/label :t/not-connected-nodes)
:accessibility-label "not-connected-nodes"
:subtitle (i18n/label :t/unable-to-fetch)
:theme :negative
:icon :main-icons/mailserver}]
(= node :disabled)
[list.item/list-item
{:title (i18n/label :t/nodes-disabled)
:accessibility-label "nodes-disabled"
:subtitle (i18n/label :t/unable-to-fetch)
:disabled true
:icon :main-icons/mailserver}]
(and mobile (not sync))
[list.item/list-item
{:title (i18n/label :t/waiting-wi-fi)
:accessibility-label "waiting-wi-fi"
:subtitle (i18n/label :t/unable-to-fetch)
:disabled true
:icon :main-icons/mailserver}]
(= node :connecting)
[list.item/list-item
{:title (i18n/label :t/connecting)
:accessibility-label "connecting"
:subtitle (i18n/label :t/unable-to-fetch)
:icon :main-icons/mailserver}]
(= node :online)
[list.item/list-item
{:title (str (i18n/label :t/connected-to) " " current-mailserver-name)
:accessibility-label "connected-to-mailserver"
:subtitle (i18n/label :t/you-can-fetch)
:theme :positive
:icon :main-icons/mailserver}])
[list.item/list-item
{:title (i18n/label :t/settings)
:accessibility-label "settings"
:theme :accent
:on-press #(hide-sheet-and-dispatch [:navigate-to :legacy-sync-settings])
:icon :main-icons/settings}]
(when mobile
[:<>
[react/view
{:margin-vertical 8
:background-color colors/gray-lighter
:height 36
:align-items :center
:justify-content :center}
[react/text {:style {:color colors/gray}} (i18n/label :t/youre-on-mobile-network)]]
[list.item/list-item
{:title (i18n/label :t/mobile-network-use-mobile)
:accessibility-label "mobile-network-use-mobile"
:accessory :switch
:on-press #(re-frame/dispatch [:mobile-network/set-syncing
(not syncing-on-mobile-network?)])
:active syncing-on-mobile-network?}]
[react/text {:style {:margin-horizontal 16 :margin-bottom 12 :color colors/gray}}
(i18n/label :t/status-mobile-descr)]])]))
(defn get-icon
[{:keys [peers node mobile sync]}]
(if (or (= peers :offline)
(= node :offline)
(= node :connecting))
:main-icons/offline
(if mobile
(if sync :main-icons/mobile-sync :main-icons/mobile-sync-off)
(when (#{:error :disabled} node) :main-icons/node-offline))))
@@ -18,6 +18,7 @@
[{:keys [current-log-level
telemetry-enabled?
light-client-enabled?
store-confirmations-enabled?
current-fleet
test-networks-enabled?
is-goerli-enabled?
@@ -77,6 +78,15 @@
[:wakuv2.ui/toggle-light-client (not light-client-enabled?)])
:accessory :switch
:active light-client-enabled?}
{:size :small
:title (i18n/label :t/store-confirmations)
:accessibility-label :store-confirmations
:container-margin-bottom 8
:on-press
#(re-frame/dispatch
[:wakuv2.ui/toggle-store-confirmations (not store-confirmations-enabled?)])
:accessory :switch
:active store-confirmations-enabled?}
{:size :small
:title "Testnet mode"
:accessibility-label :test-networks-enabled
@@ -114,13 +124,14 @@
(views/defview advanced-settings
[]
(views/letsubs [test-networks-enabled? [:profile/test-networks-enabled?]
is-goerli-enabled? [:profile/is-goerli-enabled?]
light-client-enabled? [:profile/light-client-enabled?]
telemetry-enabled? [:profile/telemetry-enabled?]
current-log-level [:log-level/current-log-level]
current-fleet [:fleets/current-fleet]
peer-syncing-enabled? [:profile/peer-syncing-enabled?]]
(views/letsubs [test-networks-enabled? [:profile/test-networks-enabled?]
is-goerli-enabled? [:profile/is-goerli-enabled?]
light-client-enabled? [:profile/light-client-enabled?]
store-confirmations-enabled? [:profile/store-confirmations-enabled?]
telemetry-enabled? [:profile/telemetry-enabled?]
current-log-level [:log-level/current-log-level]
current-fleet [:fleets/current-fleet]
peer-syncing-enabled? [:profile/peer-syncing-enabled?]]
[:<>
[quo/page-nav
{:type :title
@@ -130,13 +141,14 @@
:on-press #(rf/dispatch [:navigate-back])}]
[list/flat-list
{:data (flat-list-data
{:current-log-level current-log-level
:telemetry-enabled? telemetry-enabled?
:light-client-enabled? light-client-enabled?
:current-fleet current-fleet
:dev-mode? false
:test-networks-enabled? test-networks-enabled?
:is-goerli-enabled? is-goerli-enabled?
:peer-syncing-enabled? peer-syncing-enabled?})
{:current-log-level current-log-level
:telemetry-enabled? telemetry-enabled?
:light-client-enabled? light-client-enabled?
:store-confirmations-enabled? store-confirmations-enabled?
:current-fleet current-fleet
:dev-mode? false
:test-networks-enabled? test-networks-enabled?
:is-goerli-enabled? is-goerli-enabled?
:peer-syncing-enabled? peer-syncing-enabled?})
:key-fn (fn [_ i] (str i))
:render-fn render-item}]]))
@@ -1,11 +0,0 @@
(ns legacy.status-im.ui.screens.dapps-permissions.styles
(:require
[legacy.status-im.ui.components.colors :as colors]))
(def icon-container
{:width 40
:height 40
:border-radius 20
:background-color colors/gray-lighter
:align-items :center
:justify-content :center})
@@ -1,64 +0,0 @@
(ns legacy.status-im.ui.screens.dapps-permissions.views
(:require-macros [legacy.status-im.utils.views :as views])
(:require
[legacy.status-im.ui.components.colors :as colors]
[legacy.status-im.ui.components.core :as quo]
[legacy.status-im.ui.components.icons.icons :as icons]
[legacy.status-im.ui.components.list.item :as list.item]
[legacy.status-im.ui.components.list.views :as list]
[legacy.status-im.ui.components.react :as react]
[legacy.status-im.ui.components.topbar :as topbar]
[legacy.status-im.ui.screens.dapps-permissions.styles :as styles]
[re-frame.core :as re-frame]
[status-im.constants :as constants]
[utils.i18n :as i18n]))
(defn d-icon
[]
[react/view styles/icon-container
[icons/icon :main-icons/dapp {:color colors/gray}]])
(defn prepare-items
[{:keys [dapp permissions]}]
{:title dapp
:chevron true
:on-press #(re-frame/dispatch [:navigate-to :manage-dapps-permissions
{:dapp dapp :permissions permissions}])
:icon [d-icon]})
(defn prepare-items-manage
[name]
(fn [permission]
{:title (cond
(= permission constants/dapp-permission-web3)
name
(= permission constants/dapp-permission-contact-code)
(i18n/label :t/contact-code))
:size :small
:accessory [icons/icon :main-icons/check {}]}))
(views/defview dapps-permissions
[]
(views/letsubs [permissions [:dapps/permissions]]
[list/flat-list
{:data (vec (map prepare-items (vals permissions)))
:key-fn (fn [_ i] (str i))
:render-fn list.item/list-item}]))
(views/defview manage
[]
(views/letsubs [{:keys [dapp permissions]} [:get-screen-params]
{:keys [name]} [:dapps-account]]
[:<>
[topbar/topbar {:title dapp}]
[list/flat-list
{:data (vec (map (prepare-items-manage name) permissions))
:key-fn (fn [_ i] (str i))
:render-fn list.item/list-item}]
[react/view
{:padding-vertical 16
:padding-horizontal 16}
[quo/button
{:theme :negative
:on-press #(re-frame/dispatch [:dapps/revoke-access dapp])}
(i18n/label :t/revoke-access)]]]))
@@ -1,13 +0,0 @@
(ns legacy.status-im.ui.screens.link-previews-settings.styles)
(def link-preview-settings-image
{:height 100
:align-self :center
:margin-top 16})
(def whitelist-container
{:flex-direction :row
:justify-content :space-between})
(def enable-all
{:align-self :flex-end})
@@ -1,67 +0,0 @@
(ns legacy.status-im.ui.screens.link-previews-settings.views
(:require-macros [legacy.status-im.utils.views :as views])
(:require
[legacy.status-im.react-native.resources :as resources]
[legacy.status-im.ui.components.core :as components]
[legacy.status-im.ui.components.list.item :as list.item]
[legacy.status-im.ui.components.list.views :as list]
[legacy.status-im.ui.components.react :as react]
[legacy.status-im.ui.screens.link-previews-settings.styles :as styles]
[quo.core :as quo]
[re-frame.core :as re-frame]
[status-im.contexts.chat.messenger.messages.link-preview.events]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn prepare-urls-items-data
[link-previews-enabled-sites]
(fn [{:keys [title address]}]
(let [enabled? (contains? link-previews-enabled-sites title)]
{:title title
:subtitle address
:size :small
:accessory :switch
:active (contains? link-previews-enabled-sites title)
:on-press #(re-frame/dispatch
[:chat.ui/enable-link-previews title ((complement boolean) enabled?)])})))
(views/defview link-previews-settings
[]
(views/letsubs [link-previews-whitelist [:link-previews-whitelist]
link-previews-enabled-sites [:link-preview/enabled-sites]]
(let [all-enabled (= (count link-previews-whitelist) (count link-previews-enabled-sites))]
[:<>
[quo/page-nav
{:type :title
:title (i18n/label :t/chat-link-previews)
:background :blur
:icon-name :i/close
:on-press #(rf/dispatch [:navigate-back])}]
[react/image
{:source (resources/get-theme-image :unfurl)
:style styles/link-preview-settings-image}]
[components/text {:style {:margin 16}}
(i18n/label :t/you-can-choose-preview-websites)]
[components/separator {:style {:margin-vertical 8}}]
[react/view styles/whitelist-container
[components/list-header (i18n/label :t/websites)]
(when (> (count link-previews-whitelist) 1)
[components/button
{:on-press #(re-frame/dispatch [:chat.ui/enable-all-link-previews
link-previews-whitelist
(not all-enabled)])
:type :secondary
:style styles/enable-all}
(if all-enabled
(i18n/label :t/disable-all)
(i18n/label :t/enable-all))])]
[list/flat-list
{:data (vec (map (prepare-urls-items-data link-previews-enabled-sites)
link-previews-whitelist))
:key-fn (fn [_ i] (str i))
:render-fn list.item/list-item
:footer [quo/text
{:color :secondary
:style {:margin 16}} (i18n/label :t/previewing-may-share-metadata)]}]])))
@@ -1,17 +1,24 @@
(ns legacy.status-im.ui.screens.peers-stats
(:require
[react-native.core :as react-native.core]
[quo.foundations.colors :as colors]
[react-native.core :as rn]
[utils.i18n :as i18n]
[utils.re-frame :as re-frame]))
[utils.re-frame :as rf]))
(defn peers-stats
[]
(let [peers-count (re-frame/sub [:peers-count])]
[react-native.core/view
{:flex 1
:margin-horizontal 8}
[react-native.core/view
(let [peers-count (rf/sub [:peer-stats/count])
theme (rf/sub [:theme])]
(rn/use-mount
(fn []
(rf/dispatch [:peer-stats/get-count])))
[rn/view
{:style {:flex 1
:margin-horizontal 8}}
[rn/view
{:style {:flex-direction :row
:margin-vertical 8
:justify-content :space-between}}
[react-native.core/text (str (i18n/label :t/peers-count) ": " peers-count)]]]))
[rn/text {:style {:color (colors/theme-colors colors/neutral-100 colors/white theme)}}
(str (i18n/label :t/peers-count) ": " peers-count)]]]))
@@ -1,81 +0,0 @@
(ns legacy.status-im.ui.screens.privacy-and-security-settings.delete-profile
(:require
[legacy.status-im.ui.components.chat-icon.screen :as chat-icon.screen]
[legacy.status-im.ui.components.core :as quo]
[legacy.status-im.ui.components.list.item :as list.item]
[legacy.status-im.ui.components.react :as react]
[legacy.status-im.ui.screens.privacy-and-security-settings.events :as delete-profile]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im.contexts.profile.utils :as profile.utils]
[utils.i18n :as i18n]
[utils.security.core :as security]))
(defn valid-password?
[password]
(>= (count password) 6))
(defn on-delete-profile
[password]
#(do
(re-frame/dispatch
[::delete-profile/delete-profile @password])
(reset! password nil)))
(defn delete-profile
[]
(let [password (reagent/atom nil)
text-input-ref (atom nil)]
(fn []
(let [profile @(re-frame/subscribe [:profile/profile])
error @(re-frame/subscribe [:delete-profile/error])
keep-keys-on-keycard? @(re-frame/subscribe
[:delete-profile/keep-keys-on-keycard?])]
(when (and @text-input-ref error (not @password))
(.clear ^js @text-input-ref))
[react/keyboard-avoiding-view {:style {:flex 1}}
[react/scroll-view {:style {:flex 1}}
[react/view {:style {:align-items :center}}
[quo/text
{:weight :bold
:size :x-large}
(i18n/label :t/delete-profile)]]
[list.item/list-item
{:title (profile.utils/displayed-name profile)
:icon [chat-icon.screen/contact-icon-contacts-tab profile]}]
[quo/text
{:style {:margin-horizontal 24}
:align :center
:color :negative}
(i18n/label :t/delete-profile-warning)]
[quo/text-input
{:style {:margin-horizontal 36
:margin-top 36}
:show-cancel false
:secure-text-entry true
:return-key-type :next
:on-submit-editing nil
:auto-focus true
:on-change-text #(reset! password (security/mask-data %))
:bottom-value 36
:get-ref #(reset! text-input-ref %)
:error (when (and error (not @password))
(if (= :wrong-password error)
(i18n/label :t/wrong-password)
(str error)))}]]
[react/view {:style {:align-items :center}}
[quo/separator]
(when (not keep-keys-on-keycard?)
[quo/text
{:style {:margin-horizontal 24 :margin-bottom 16}
:align :center
:color :negative}
(i18n/label :t/delete-profile-warning)])
[react/view
{:style {:margin-vertical 8}}
[quo/button
{:on-press (on-delete-profile password)
:theme :negative
:accessibility-label :delete-profile-confirm
:disabled ((complement valid-password?) @password)}
(i18n/label :t/delete-profile)]]]]))))
@@ -1,73 +0,0 @@
(ns legacy.status-im.ui.screens.privacy-and-security-settings.events
(:require
[clojure.string :as string]
[legacy.status-im.utils.deprecated-types :as types]
[native-module.core :as native-module]
[re-frame.core :as re-frame]
[taoensso.timbre :as log]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.security.core :as security]))
(defn safe-blank?
[s]
(or (not s)
(string/blank? s)))
(re-frame/reg-fx
::delete-profile
(fn [{:keys [address key-uid callback masked-password]}]
(let [hashed-password
(-> masked-password
security/safe-unmask-data
native-module/sha3)]
(native-module/verify
address
hashed-password
(fn [result]
(let [{:keys [error]} (types/json->clj result)]
(log/info "[delete-profile] verify-password" result error)
(if-not (safe-blank? error)
(callback :wrong-password nil)
(native-module/delete-multiaccount
key-uid
(fn [result]
(let [{:keys [error]} (types/json->clj result)]
(callback error nil)))))))))))
(rf/defn delete-profile
{:events [::delete-profile]}
[{:keys [db] :as cofx} masked-password]
(log/info "[delete-profile] delete")
(let [{:keys [key-uid wallet-root-address]} (:profile/profile db)]
{:db (dissoc db :delete-profile/error)
::delete-profile
{:masked-password masked-password
:key-uid key-uid
:address wallet-root-address
:callback
(fn [error result]
(log/info "[delete-profile] callback" error)
(if (safe-blank? error)
(re-frame/dispatch [::on-delete-profile-success result])
(re-frame/dispatch [::on-delete-profile-failure error])))}}))
(rf/defn on-delete-profile-success
{:events [::on-delete-profile-success]}
[cofx]
(log/info "[delete-profile] on-success")
{:effects.utils/show-popup
{:title (i18n/label :t/profile-deleted-title)
:content (i18n/label :t/profile-deleted-content)
:on-dismiss #(re-frame/dispatch [:logout])}})
(rf/defn on-delete-profile-failure
{:events [::on-delete-profile-failure]}
[{:keys [db]} error]
(log/info "[delete-profile] on-failure" error)
{:db (assoc db :delete-profile/error error)})
(rf/defn keep-keys-on-keycard
{:events [::keep-keys-on-keycard]}
[{:keys [db] :as cofx} checked?]
{:db (assoc-in db [:delete-profile/keep-keys-on-keycard?] checked?)})
@@ -1,34 +0,0 @@
(ns legacy.status-im.ui.screens.privacy-and-security-settings.messages-from-contacts-only
(:require-macros [legacy.status-im.utils.views :as views])
(:require
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
[legacy.status-im.ui.components.list.item :as list.item]
[legacy.status-im.ui.components.react :as react]
[re-frame.core :as re-frame]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(rf/defn handle-messages-from-contacts-only-switched
{:events [::messages-from-contacts-only-switched]}
[cofx value]
(multiaccounts.update/multiaccount-update cofx
:messages-from-contacts-only
value
{}))
(views/defview messages-from-contacts-only-view
[]
(views/letsubs [{:keys [messages-from-contacts-only]} [:profile/profile]]
[react/view {:margin-top 8}
[list.item/list-item
{:active (not messages-from-contacts-only)
:accessory :radio
:title (i18n/label :t/anyone)
:on-press #(re-frame/dispatch [::messages-from-contacts-only-switched false])}]
[list.item/list-item
{:active messages-from-contacts-only
:accessory :radio
:title (i18n/label :t/contacts)
:subtitle (i18n/label :t/messages-from-contacts-only-subtitle)
:subtitle-max-lines 4
:on-press #(re-frame/dispatch [::messages-from-contacts-only-switched true])}]]))
@@ -1,175 +0,0 @@
(ns legacy.status-im.ui.screens.privacy-and-security-settings.views
(:require
[legacy.status-im.multiaccounts.reset-password.core :as reset-password]
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
[legacy.status-im.ui.components.core :as components]
[legacy.status-im.ui.components.list.item :as list.item]
[legacy.status-im.ui.components.react :as react]
[quo.core :as quo]
[re-frame.core :as re-frame]
[react-native.platform :as platform]
[status-im.config :as config]
[status-im.constants :as constants]
[utils.i18n :as i18n]
[utils.re-frame :as rf])
(:require-macros [legacy.status-im.utils.views :as views]))
(defn separator
[]
[components/separator {:style {:margin-vertical 8}}])
(def titles
{constants/profile-pictures-visibility-contacts-only (i18n/label :t/recent-recipients)
constants/profile-pictures-visibility-everyone (i18n/label :t/everyone)
constants/profile-pictures-visibility-none (i18n/label :t/none)
constants/profile-pictures-show-to-contacts-only (i18n/label :t/recent-recipients)
constants/profile-pictures-show-to-everyone (i18n/label :t/everyone)
constants/profile-pictures-show-to-none (i18n/label :t/none)})
(views/defview privacy-and-security
[]
(views/letsubs [{:keys [preview-privacy?
messages-from-contacts-only
webview-allow-permission-requests?
opensea-enabled?
profile-pictures-visibility]}
[:profile/profile]
has-picture [:profile/has-picture]
profile-pictures-show-to [:multiaccount/profile-pictures-show-to]]
[:<>
[quo/page-nav
{:type :no-title
:background :blur
:icon-name :i/close
:on-press #(rf/dispatch [:navigate-back])}]
[react/scroll-view {:padding-vertical 8}
[components/list-header (i18n/label :t/privacy)]
[list.item/list-item
{:size :small
:title (i18n/label :t/set-dapp-access-permissions)
:on-press #(re-frame/dispatch [:navigate-to :dapps-permissions])
:accessibility-label :dapps-permissions-button
:chevron true}]
[list.item/list-item
{:size :small
:title (if platform/android?
(i18n/label :t/hide-content-when-switching-apps)
(i18n/label :t/hide-content-when-switching-apps-ios))
:container-margin-bottom 8
:active preview-privacy?
:accessory :switch
:on-press #(re-frame/dispatch
[:profile.settings/change-preview-privacy
((complement boolean) preview-privacy?)])}]
(when config/collectibles-enabled?
[list.item/list-item
{:size :small
:title (i18n/label :t/display-collectibles)
:container-margin-bottom 8
:active opensea-enabled?
:accessory :switch
:on-press #(re-frame/dispatch
[::multiaccounts.update/toggle-opensea-nfts-visiblity
(not opensea-enabled?)])}])
[list.item/list-item
{:size :small
:title (i18n/label :t/chat-link-previews)
:chevron true
:on-press #(re-frame/dispatch [:open-modal :legacy-link-previews-settings])
:accessibility-label :chat-link-previews}]
[list.item/list-item
{:size :small
:title (i18n/label :t/accept-new-chats-from)
:chevron true
:accessory :text
:accessory-text (i18n/label (if messages-from-contacts-only
:t/contacts
:t/anyone))
:on-press #(re-frame/dispatch [:navigate-to :messages-from-contacts-only])
:accessibility-label :accept-new-chats-from}]
[list.item/list-item
{:size :small
:title (i18n/label :t/reset-password)
:chevron true
:accessory :text
:on-press #(do
(re-frame/dispatch [::reset-password/clear-form-vals])
(re-frame/dispatch [:navigate-to :reset-password]))
:accessibility-label :reset-password}]
(when platform/android?
[list.item/list-item
{:size :small
:title (i18n/label :t/webview-camera-permission-requests)
:active webview-allow-permission-requests?
:accessory :switch
:subtitle (i18n/label :t/webview-camera-permission-requests-subtitle)
:subtitle-max-lines 2
:on-press #(re-frame/dispatch
[:profile.settings/profile-update
:webview-allow-permission-requests?
((complement boolean) webview-allow-permission-requests?)])}])
[separator]
[components/list-header (i18n/label :t/privacy-photos)]
[list.item/list-item
{:size :small
:title (i18n/label :t/show-profile-pictures)
:accessibility-label :show-profile-pictures
:accessory :text
:accessory-text (get titles profile-pictures-visibility)
:on-press #(re-frame/dispatch [:navigate-to :privacy-and-security-profile-pic])
:chevron true}]
[list.item/list-item
{:size :small
:title (i18n/label :t/show-profile-pictures-to)
:disabled (not has-picture)
:accessibility-label :show-profile-pictures-to
:accessory :text
:accessory-text (get titles profile-pictures-show-to)
:on-press #(re-frame/dispatch [:navigate-to
:privacy-and-security-profile-pic-show-to])
:chevron true}]
[separator]
[list.item/list-item
{:size :small
:theme :negative
:title (i18n/label :t/delete-my-profile)
:on-press #(re-frame/dispatch [:navigate-to :delete-profile])
:accessibility-label :dapps-permissions-button
:chevron true}]]]))
(defn ppst-radio-item
[id value]
[list.item/list-item
{:active (= value id)
:accessory :radio
:title (get titles id)
:on-press #(re-frame/dispatch [:profile.settings/change-profile-pictures-show-to id])}])
(views/defview profile-pic-show-to
[]
(views/letsubs [{:keys [profile-pictures-show-to]} [:profile/profile]]
[react/view {:margin-top 8}
[ppst-radio-item constants/profile-pictures-show-to-everyone profile-pictures-show-to]
[ppst-radio-item constants/profile-pictures-show-to-contacts-only profile-pictures-show-to]
[ppst-radio-item constants/profile-pictures-show-to-none profile-pictures-show-to]
[react/view {:style {:margin-horizontal 16}}
[components/text {:color :secondary}
(i18n/label :t/privacy-show-to-warning)]]]))
(defn ppvf-radio-item
[id value]
[list.item/list-item
{:active (= value id)
:accessory :radio
:title (get titles id)
:on-press #(re-frame/dispatch [:profile.settings/profile-update :profile-pictures-visibility id])}])
(views/defview profile-pic
[]
(views/letsubs [{:keys [profile-pictures-visibility]} [:profile/profile]]
[react/view {:margin-top 8}
[ppvf-radio-item constants/profile-pictures-visibility-everyone profile-pictures-visibility]
[ppvf-radio-item constants/profile-pictures-visibility-contacts-only profile-pictures-visibility]
[ppvf-radio-item constants/profile-pictures-visibility-none profile-pictures-visibility]]))
@@ -13,12 +13,6 @@
[]
[rn/scroll-view {:flex 1}
[components/list-header "Legacy settings"]
[list.item/list-item
{:icon :main-icons/security
:title (i18n/label :t/privacy-and-security)
:accessibility-label :privacy-and-security-settings-button
:chevron true
:on-press #(re-frame/dispatch [:open-modal :legacy-privacy-and-security])}]
[list.item/list-item
{:icon :main-icons/mobile
:title (i18n/label :t/sync-settings)
@@ -8,12 +8,10 @@
[legacy.status-im.ui.screens.bug-report :as bug-report]
[legacy.status-im.ui.screens.communities.invite :as communities.invite]
[legacy.status-im.ui.screens.communities.members :as members]
[legacy.status-im.ui.screens.dapps-permissions.views :as dapps-permissions]
[legacy.status-im.ui.screens.default-sync-period-settings.view :as default-sync-period-settings]
[legacy.status-im.ui.screens.fleet-settings.views :as fleet-settings]
[legacy.status-im.ui.screens.glossary.view :as glossary]
[legacy.status-im.ui.screens.help-center.views :as help-center]
[legacy.status-im.ui.screens.link-previews-settings.views :as link-previews-settings]
[legacy.status-im.ui.screens.log-level-settings.views :as log-level-settings]
[legacy.status-im.ui.screens.mobile-network-settings.view :as mobile-network-settings]
[legacy.status-im.ui.screens.notifications-settings.views :as notifications-settings]
@@ -21,10 +19,6 @@
[legacy.status-im.ui.screens.offline-messaging-settings.views :as offline-messaging-settings]
[legacy.status-im.ui.screens.pairing.views :as pairing]
[legacy.status-im.ui.screens.peers-stats :as peers-stats]
[legacy.status-im.ui.screens.privacy-and-security-settings.delete-profile :as delete-profile]
[legacy.status-im.ui.screens.privacy-and-security-settings.messages-from-contacts-only :as
messages-from-contacts-only]
[legacy.status-im.ui.screens.privacy-and-security-settings.views :as privacy-and-security]
[legacy.status-im.ui.screens.profile.seed.views :as profile.seed]
[legacy.status-im.ui.screens.profile.user.views :as profile.user]
[legacy.status-im.ui.screens.progress.views :as progress]
@@ -94,17 +88,6 @@
:insets {:top? platform/android?}}
:component profile.user/legacy-settings}
;; PRIVACY AND SECURITY
{:name :legacy-privacy-and-security
:options {:topBar {:visible false}
:insets {:top? platform/android?}}
:component privacy-and-security/privacy-and-security}
{:name :legacy-link-previews-settings
:options {:topBar {:visible false}
:insets {:top? platform/android?}}
:component link-previews-settings/link-previews-settings}
;; SYNC
{:name :legacy-sync-settings
:options {:topBar {:visible false}
@@ -150,25 +133,6 @@
{:name :edit-mailserver
:options {:insets {:top? true}}
:component edit-mailserver/edit-mailserver}
{:name :dapps-permissions
:options {:topBar (topbar-options :t/dapps-permissions)
:insets {:top? true}}
:component dapps-permissions/dapps-permissions}
{:name :messages-from-contacts-only
:options {:topBar (topbar-options :t/accept-new-chats-from)
:insets {:top? true}}
:component messages-from-contacts-only/messages-from-contacts-only-view}
{:name :privacy-and-security-profile-pic-show-to
:options {:topbar (topbar-options :t/show-profile-pictures-to)
:insets {:top? true}}
:component privacy-and-security/profile-pic-show-to}
{:name :privacy-and-security-profile-pic
:options {:topBar (topbar-options :t/show-profile-pictures)
:insets {:top? true}}
:component privacy-and-security/profile-pic}
{:name :manage-dapps-permissions
:options {:insets {:top? true}}
:component dapps-permissions/manage}
{:name :rpc-usage-info
:options {:topBar (topbar-options :t/rpc-usage-info)
:insets {:top? true}}
@@ -196,9 +160,6 @@
:options {:topBar (topbar-options :t/reset-password)
:insets {:top? true}}
:component reset-password/reset-password}
{:name :delete-profile
:insets {:bottom? true}
:component delete-profile/delete-profile}
{:name :default-sync-period-settings
:options {:topBar (topbar-options :t/default-sync-period)
:insets {:top? true}}
-16
View File
@@ -1,16 +0,0 @@
(ns legacy.status-im.utils.hex
(:require
[clojure.string :as string]))
(defn normalize-hex
[hex]
(when hex
(string/lower-case (if (string/starts-with? hex "0x")
(subs hex 2)
hex))))
(defn valid-hex?
[hex]
(let [hex (normalize-hex hex)]
(and (re-matches #"^[0-9a-fA-F]+$" hex)
(not= (js/parseInt hex 16) 0))))
@@ -1,58 +0,0 @@
(ns legacy.status-im.utils.keychain.core
(:require
[oops.core :as oops]
[re-frame.core :as re-frame]
[react-native.keychain :as keychain]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
(defn- whisper-key-name
[address]
(str address "-whisper"))
(re-frame/reg-fx
:keychain/get-keycard-keys
(fn [[key-uid callback]]
(keychain/get-credentials
key-uid
(fn [encryption-key-data]
(if encryption-key-data
(keychain/get-credentials
(whisper-key-name key-uid)
(fn [whisper-key-data]
(if whisper-key-data
(callback [(oops/oget encryption-key-data "password")
(oops/oget whisper-key-data "password")])
(callback nil))))
(callback nil))))))
(re-frame/reg-fx
:keychain/save-keycard-keys
(fn [[key-uid encryption-public-key whisper-private-key]]
(keychain/save-credentials
key-uid
key-uid
encryption-public-key
#(when-not %
(log/error
(str "Error while saving encryption-public-key"))))
(keychain/save-credentials
(whisper-key-name key-uid)
key-uid
whisper-private-key
#(when-not %
(log/error
(str "Error while saving whisper-private-key"))))))
(rf/defn get-keycard-keys
[_ key-uid]
{:keychain/get-keycard-keys
[key-uid
#(re-frame/dispatch
[:multiaccounts.login.callback/get-keycard-keys-success key-uid %])]})
(rf/defn save-keycard-keys
[_ key-uid encryption-public-key whisper-private-key]
{:keychain/save-keycard-keys [key-uid
encryption-public-key
whisper-private-key]})
+1 -2
View File
@@ -127,8 +127,7 @@
[:app-state
:current-chat-id
:network
:network-status
:peers-count
:network/status
:peers-summary
:sync-state
:view-id
-130
View File
@@ -1,130 +0,0 @@
(ns legacy.status-im.utils.test
(:require
[legacy.status-im.utils.deprecated-types :as types]
[re-frame.core :as re-frame]))
(def native-status (js/require "../../modules/react-native-status/nodejs/bindings"))
(def fs (js/require "fs"))
(def path (js/require "path"))
(def os (js/require "os"))
(def tmpdir (.tmpdir os))
(def test-dir-prefix (.join path tmpdir "status-mobile-tests"))
(def test-dir (.mkdtempSync fs test-dir-prefix))
(def initialized? (atom false))
(defn signal-received-callback
[a]
(re-frame/dispatch [:signals/signal-received a]))
;; We poll for signals, could not get callback working
(defn init!
[]
(when-not @initialized?
(.setSignalEventCallback native-status)
(reset! initialized? true)
(js/setInterval (fn []
(.pollSignal native-status signal-received-callback)
100))))
(def ui-helper
(clj->js
{:clearCookies identity
:clearStorageAPIs identity}))
(def encryption-utils
(clj->js
{:sha3
(fn [s] (.sha3 native-status s))
:setBlankPreviewFlag
identity
:encodeTransfer
(fn [to-norm amount-hex]
(.encodeTransfer native-status to-norm amount-hex))
:hexToNumber
(fn [hex] (.hexToNumber native-status hex))
:decodeParameters
(fn [decode-param-json]
(.decodeParameters native-status decode-param-json))
:numberToHex
(fn [num-str] (.numberToHex native-status num-str))
:initKeystore
(fn [key-uid callback]
(callback (.initKeystore native-status
(str test-dir "/keystore/" key-uid))))
:multiformatDeserializePublicKey
(fn [public-key deserialization-key callback]
(callback (.multiformatDeserializePublicKey
native-status
public-key
deserialization-key)))}))
(def account-manager
(clj->js
{:openAccounts
(fn [callback]
(callback (.openAccounts native-status test-dir)))
:createAccountAndLogin
(fn [request] (.createAccountAndLogin native-status request))
:logout
(fn [] (.logout native-status))
:multiAccountImportMnemonic
(fn [json callback]
(callback (.multiAccountImportMnemonic native-status json)))
:multiAccountLoadAccount
(fn [json callback]
(callback (.multiAccountLoadAccount native-status json)))
:multiAccountDeriveAddresses
(fn [json callback]
(callback (.multiAccountDeriveAddresses native-status json)))
:multiAccountGenerateAndDeriveAddresses
(fn [json callback]
(callback (.multiAccountGenerateAndDeriveAddresses native-status json)))
:multiAccountStoreDerived
(fn [json callback]
(callback (.multiAccountStoreDerivedAccounts native-status json)))}))
(def utils
(clj->js
{:backupDisabledDataDir
(fn [] (str test-dir "/backup"))
:keystoreDir (fn [] "")
:toChecksumAddress
(fn [address] (.toChecksumAddress native-status address))
:checkAddressChecksum
(fn [address] (.checkAddressChecksum native-status address))
:validateMnemonic
(fn [json callback] (callback (.validateMnemonic native-status json)))
:isAddress
(fn [address] (.isAddress native-status address))}))
(def log-manager
(clj->js
{:logFileDirectory
(fn [] (str test-dir "/log"))
:initLogging
(fn [enabled mobile-system log-level callback]
(callback (.initLogging native-status
(types/clj->json {:Enabled enabled
:MobileSystem mobile-system
:Level log-level
:File (str test-dir "/geth.log")}))))}))
(def network
(clj->js
{:callPrivateRPC
(fn [payload callback]
(callback (.callPrivateRPC native-status payload)))}))
(def status
(clj->js
{:getNodeConfig
(fn [] (types/clj->json {:WakuV2Config ""}))
:fleets
(fn [] (.fleets native-status))
:startLocalNotifications
identity}))
@@ -130,7 +130,7 @@
status-type]}]
(and
(= status-type constants/visibility-status-inactive)
(> (:peers-count db) 0))
(pos? (:peer-stats/count db)))
;; Disable broadcasting further updates
(conj {:ms 1000
:dispatch
+16
View File
@@ -137,3 +137,19 @@
:on-error #(log/error "failed to set light client"
{:error %
:enabled? enabled?})}]})
(rf/defn toggle-store-confirmations
{:events [:wakuv2.ui/toggle-store-confirmations]}
[{:keys [db]} enabled?]
{:db (assoc-in db
[:profile/profile :wakuv2-config :EnableStoreConfirmationForMessagesSent]
enabled?)
:json-rpc/call [{:method "wakuext_setStoreConfirmationForMessagesSent"
:params [{:enabled enabled?}]
:on-success (fn []
(log/info "store confirmation set successfully" enabled?)
(re-frame/dispatch [:logout]))
:on-error #(log/error "failed to set store confirmation"
{:error %
:enabled? enabled?})}]})
+6 -3
View File
@@ -110,8 +110,11 @@
(def status-keycard
#js
{:default #js
{:nfcIsSupported (fn [] #js {:then identity})
:nfcIsEnabled (fn [] #js {:then identity})}})
{:nfcIsSupported (fn [] #js {:then identity})
:nfcIsEnabled (fn [] #js {:then identity})
:getApplicationInfo (fn [] #js {:then identity})
:getKeys (fn [] #js {:then identity})
:setPairings (fn [] #js {:then identity})}})
(def snoopy #js {:default #js {}})
(def snoopy-filter #js {:default #js {}})
@@ -168,7 +171,7 @@
#js
{:getEnforcing {}})
(def net-info #js {})
(def net-info #js {:addEventListener identity})
(def react-native-biometrics #js {:default {}})
(def react-native-static-safe-area-insets #js {:default {}})
+26 -100
View File
@@ -72,10 +72,12 @@
(log/debug "[native-module] init-keystore" key-uid)
(.initKeystore ^js (encryption) key-uid callback))
(defn open-accounts
[callback]
(log/debug "[native-module] open-accounts")
(.openAccounts ^js (account-manager) #(callback (types/json->clj %))))
(defn initialize-application
[request callback]
(log/debug "[native-module] initialize-application")
(.initializeApplication ^js (account-manager)
(types/clj->json request)
#(callback (types/json->clj %))))
(defn prepare-dir-and-update-config
[key-uid config callback]
@@ -85,31 +87,6 @@
config
#(callback (types/json->clj %))))
(defn save-multiaccount-and-login-with-keycard
"NOTE: chat-key is a whisper private key sent from keycard"
[key-uid multiaccount-data password settings config accounts-data chat-key]
(log/debug "[native-module] save-account-and-login-with-keycard")
(init-keystore
key-uid
#(.saveAccountAndLoginWithKeycard
^js (account-manager)
multiaccount-data
password
settings
config
accounts-data
chat-key)))
(defn login-with-config
"NOTE: beware, the password has to be sha3 hashed"
[key-uid account-data hashed-password config]
(log/debug "[native-module] loginWithConfig")
(clear-web-data)
(let [config (if config (types/clj->json config) "")]
(init-keystore
key-uid
#(.loginWithConfig ^js (account-manager) account-data hashed-password config))))
(defn login-account
"NOTE: beware, the password has to be sha3 hashed"
[{:keys [keyUid] :as request}]
@@ -151,19 +128,6 @@
(clear-web-data)
(.logout ^js (account-manager)))
(defn multiaccount-load-account
"NOTE: beware, the password has to be sha3 hashed
this function is used after storing an account when you still want to
derive accounts from it, because saving an account flushes the loaded keys
from memory"
[address hashed-password callback]
(log/debug "[native-module] multiaccount-load-account")
(.multiAccountLoadAccount ^js (account-manager)
(types/clj->json {:address address
:password hashed-password})
callback))
(defn multiaccount-derive-addresses
"NOTE: this should be named derive-accounts
this only derive addresses, they still need to be stored
@@ -177,38 +141,6 @@
:paths paths})
callback)))
(defn multiaccount-store-account
"NOTE: beware, the password has to be sha3 hashed
this stores the account and flush keys in memory so
in order to also store derived accounts like initial wallet
and chat accounts, you need to load the account again with
`multiaccount-load-account` before using `multiaccount-store-derived`
and the id of the account stored will have changed"
[account-id key-uid hashed-password callback]
(log/debug "[native-module] multiaccount-store-account")
(when (status)
(init-keystore
key-uid
#(.multiAccountStoreAccount ^js (account-manager)
(types/clj->json {:accountID account-id
:password hashed-password})
callback))))
(defn multiaccount-store-derived
"NOTE: beware, the password has to be sha3 hashed"
[account-id key-uid paths hashed-password callback]
(log/debug "[native-module] multiaccount-store-derived"
"account-id"
account-id)
(init-keystore
key-uid
#(.multiAccountStoreDerived ^js (account-manager)
(types/clj->json {:accountID account-id
:paths paths
:password hashed-password})
callback)))
(defn multiaccount-generate-and-derive-addresses
"used to generate multiple multiaccounts for onboarding
NOTE: nothing is saved so you will need to use
@@ -232,37 +164,12 @@
:Bip39Passphrase password})
callback))
(defn multiaccount-import-private-key
[private-key callback]
(log/debug "[native-module] multiaccount-import-private-key")
(.multiAccountImportPrivateKey ^js (account-manager)
(types/clj->json {:privateKey private-key})
callback))
(defn verify
"NOTE: beware, the password has to be sha3 hashed"
[address hashed-password callback]
(log/debug "[native-module] verify")
(.verify ^js (account-manager) address hashed-password callback))
(defn verify-database-password
"NOTE: beware, the password has to be sha3 hashed"
[key-uid hashed-password callback]
(log/debug "[native-module] verify-database-password")
(.verifyDatabasePassword ^js (account-manager) key-uid hashed-password callback))
(defn login-with-keycard
[{:keys [key-uid multiaccount-data password chat-key node-config]}]
(log/debug "[native-module] login-with-keycard")
(clear-web-data)
(init-keystore
key-uid
#(.loginWithKeycard ^js (account-manager)
multiaccount-data
password
chat-key
(types/clj->json node-config))))
(defn set-soft-input-mode
[mode]
(log/debug "[native-module] set-soft-input-mode")
@@ -331,6 +238,11 @@
:key input-key})
(.deserializeAndCompressKey ^js (encryption) input-key callback))
(defn serialize-legacy-key
"Compresses an old format public key (0x04...) to the new one zQ..."
[public-key]
(.serializeLegacyKey ^js (encryption) public-key))
(defn compressed-key->public-key
"Provides compressed key to status-go and gets back the uncompressed public key via deserialization"
[public-key deserialization-key callback]
@@ -513,6 +425,14 @@
(let [result (.checkAddressChecksum ^js (utils) address)]
(types/json->clj result)))
(defn toggle-centralized-metrics
[enabled callback]
(.toggleCentralizedMetrics ^js (status) (types/clj->json {:enabled enabled}) callback))
(defn add-centralized-metric
[metric]
(.addCentralizedMetric ^js (status) (types/clj->json metric) #(log/debug "pushed metric" % metric)))
(defn address?
[address]
(log/debug "[native-module] address?")
@@ -533,6 +453,13 @@
(log/debug "[native-module] validate-mnemonic")
(.validateMnemonic ^js (utils) mnemonic callback)))
(defn validate-connection-string
[connection-string]
(log/debug "[native-module] validate-connection-string")
(->> connection-string
(.validateConnectionString ^js (utils))
types/json->clj))
(defn delete-multiaccount
"Delete multiaccount from database, deletes multiaccount's database and
key files."
@@ -643,7 +570,6 @@
(native-utils/promisify-native-module-call create-account-from-private-key private-key))
([private-key callback]
(log/debug "[native-module] create-account-from-private-key")
(.createAccountFromPrivateKey ^js (account-manager)
(types/clj->json {:privateKey private-key})
callback)))
@@ -5,6 +5,7 @@
(defn- get-dimensions
[size]
(case size
:size-32 32
:size-24 24
:size-20 20
nil))
@@ -1,5 +1,6 @@
(ns quo.components.avatars.token-avatar.view
(:require [quo.components.avatars.token-avatar.style :as style]
[quo.components.utilities.token.view :as token]
[react-native.core :as rn]
[react-native.hole-view :as hole-view]
[react-native.platform :as platform]
@@ -12,13 +13,14 @@
[:map {:closed true}
[:type {:optional true} [:enum :asset :collectible]]
[:context? {:optional true} [:maybe :boolean]]
[:image :schema.common/image-source]
[:image {:optional true} [:maybe :schema.common/image-source]]
[:token {:optional true} [:maybe [:or :keyword :string]]]
[:network-image {:optional true} [:maybe :schema.common/image-source]]
[:container-style {:optional true} [:maybe :map]]]]]
:any])
(defn- view-internal
[{:keys [type context? image network-image container-style]}]
[{:keys [type context? image token network-image container-style]}]
[rn/view
{:style (merge style/container container-style)
:accessibility-label :token-avatar}
@@ -32,9 +34,11 @@
[])
:style style/hole-view}
platform/android? (assoc :key context?))
[rn/image
{:source image
:style (style/image type)}]]
[token/view
{:size :size-32
:token token
:style (style/image type)
:image-source image}]]
(when context?
[rn/image
{:source network-image
@@ -2,7 +2,7 @@
(:require
[quo.components.buttons.button.view :as button]
[quo.components.buttons.predictive-keyboard.style :as style]
[quo.components.info.info-message :as info-message]
[quo.components.info.info-message.view :as info-message]
[quo.foundations.colors :as colors]
[quo.theme]
[react-native.core :as rn]
@@ -57,17 +57,17 @@
:key-fn str}]
:error
[info-message/info-message
{:icon :i/info
:size :default
:type :error}
[info-message/view
{:icon :i/info
:size :default
:status :error}
text]
:info
[info-message/info-message
(merge {:icon :i/info
:size :default
:type (if (= type :error) :error :default)}
[info-message/view
(merge {:icon :i/info
:size :default
:status (if (= type :error) :error :default)}
(when blur?
{:text-color colors/white-opa-70
:icon-color colors/white-opa-40}))
@@ -26,7 +26,8 @@
(reanimated/set-shared-value x-pos clamped-x)
(when (and reached-end? (not sliding-complete?))
(set-sliding-complete true)
(when on-complete (on-complete reset-fn))))))
(when on-complete
(on-complete reset-fn))))))
(gesture/on-end (fn [event]
(let [x-translation (oops/oget event "translationX")
reached-end? (>= x-translation track-width)]
@@ -54,9 +55,10 @@
on-track-layout (rn/use-callback
#(set-track-width (oops/oget % "nativeEvent.layout.width")))
reset-fn (rn/use-callback
(fn []
(fn [keep-at-end-after-slide?]
(set-sliding-complete false)
(animations/reset-track-position x-pos)))
(when-not keep-at-end-after-slide?
(animations/reset-track-position x-pos))))
dimensions (rn/use-callback
(partial utils/get-dimensions
(or track-width constants/default-width)
@@ -21,15 +21,17 @@
(colors/theme-colors colors/white colors/neutral-95 theme))})
(defn buttons-container
[actions]
{:flex-direction (if (= actions :two-vertical-actions) :column :row)
:justify-content :space-around
:padding-vertical 12
:gap 12
:padding-horizontal 20})
[actions container-style]
(merge
{:flex-direction (if (= actions :two-vertical-actions) :column :row)
:justify-content :space-around
:padding-vertical 12
:gap 12
:padding-horizontal 20}
container-style))
(def button-container
{:flex 1})
{:flex-grow 1})
(def description-top
{:flex-direction :row
@@ -30,7 +30,8 @@
[:button-two-props {:optional true} [:maybe :map]]
[:scroll? {:optional true} [:maybe :boolean]]
[:blur? {:optional true} [:maybe :boolean]]
[:container-style {:optional true} [:maybe :map]]]]]
[:container-style {:optional true} [:maybe :map]]
[:buttons-container-style {:optional true} [:maybe :map]]]]]
:any])
(def ^:private role-icon
@@ -42,7 +43,7 @@
(defn- view-internal
[{:keys [actions description description-text description-top-text error-message role button-one-label
button-two-label blur? button-one-props button-two-props scroll? container-style
context-tag-props]}]
buttons-container-style context-tag-props]}]
(let [theme (quo.theme/use-theme)]
[rn/view
{:style (merge (style/container scroll? blur? theme) container-style)}
@@ -72,14 +73,14 @@
:context (i18n/label (keyword "t" role))}
context-tag-props)]])
[rn/view {:style (style/buttons-container actions)}
[rn/view {:style (style/buttons-container actions buttons-container-style)}
(when (or (= actions :two-actions)
(= actions :two-vertical-actions))
[button/button
(merge
{:size 40
:background (when (or blur? scroll?) :blur)
:container-style style/button-container
:background (when (or blur? scroll?) :blur)
:theme theme
:accessibility-label :button-two}
button-two-props)
-48
View File
@@ -1,48 +0,0 @@
(ns quo.components.info.info-message
(:require
[quo.components.icon :as quo.icons]
[quo.components.markdown.text :as text]
[quo.foundations.colors :as colors]
[quo.theme :as quo.theme]
[react-native.core :as rn]))
(defn get-color
[k theme]
(case k
:success (colors/resolve-color :success theme)
:error (colors/resolve-color :danger theme)
:warning (colors/resolve-color :warning theme)
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
(defn info-message
"[info-message opts \"message\"]
opts
{:type :default/:success/:error
:size :default/:tiny
:icon :i/info ;; info message icon
:text-color colors/white ;; text color override
:icon-color colors/white ;; icon color override
:no-icon-color? false ;; disable tint color for icon"
[{:keys [type size icon text-color icon-color no-icon-color? style accessibility-label
container-style]} message]
(let [theme (quo.theme/use-theme)
weight (if (= size :default) :regular :medium)
icon-size (if (= size :default) 16 12)
size (if (= size :default) :paragraph-2 :label)
text-color (or text-color (get-color type theme))
icon-color (or icon-color text-color)]
[rn/view
{:style (merge {:flex-direction :row
:align-items :center}
style
container-style)}
[quo.icons/icon icon
{:color icon-color
:no-color no-icon-color?
:size icon-size}]
[text/text
{:accessibility-label accessibility-label
:size size
:weight weight
:style {:color text-color
:margin-horizontal 4}} message]]))
@@ -0,0 +1,32 @@
(ns quo.components.info.info-message.component-spec
(:require
[quo.components.info.info-message.view :as info-message]
[test-helpers.component :as h]))
(h/describe "Info: Info Message"
(h/test "basic render"
(h/render-with-theme-provider
[info-message/view
{:status :default
:size :default
:accessibility-label :info-message
:icon :i/placeholder} "Message"])
(h/is-truthy (h/get-by-label-text :info-message)))
(h/test "render with correct message"
(h/render-with-theme-provider
[info-message/view
{:status :default
:size :default
:accessibility-label :info-message
:icon :i/placeholder} "Message"])
(h/is-truthy (h/get-by-text "Message")))
(h/test "render icon"
(h/render-with-theme-provider
[info-message/view
{:status :default
:size :default
:accessibility-label :info-message
:icon :i/placeholder} "Message"])
(h/is-truthy (h/get-by-label-text :icon))))
@@ -0,0 +1,6 @@
(ns quo.components.info.info-message.style)
(def container
{:flex-direction :row
:gap 4
:align-items :center})
@@ -0,0 +1,53 @@
(ns quo.components.info.info-message.view
(:require [quo.components.icon :as icons]
[quo.components.info.info-message.style :as style]
[quo.components.markdown.text :as text]
[quo.foundations.colors :as colors]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[schema.core :as schema]))
(def ?schema
[:=>
[:catn
[:props
[:map {:closed true}
[:status {:optional true} [:maybe [:enum :default :success :error :warning]]]
[:size {:optional true} [:maybe [:enum :default :tiny]]]
[:blur? {:optional true} [:maybe :boolean]]
[:icon :keyword]
[:color {:optional true} [:maybe :string]]
[:text-color {:optional true} [:maybe :string]]
[:icon-color {:optional true} [:maybe :string]]
[:no-icon-color? {:optional true} [:maybe :boolean]]
[:accessibility-label {:optional true} [:maybe :keyword]]
[:container-style {:optional true} [:maybe :map]]]]
[:message :string]]
:any])
(defn- get-color
[status theme blur?]
(case status
:success (if blur? colors/success-60 (colors/resolve-color :success theme))
:error (if blur? colors/danger-60 (colors/resolve-color :danger theme))
:warning (if blur? colors/warning-60 (colors/resolve-color :warning theme))
(if blur? colors/white-opa-40 (colors/theme-colors colors/neutral-50 colors/neutral-40 theme))))
(defn view-internal
[{:keys [status size blur? icon color icon-color text-color no-icon-color? container-style
accessibility-label]} message]
(let [theme (quo.theme/use-theme)
default-color (get-color status theme blur?)
text-color (or text-color color default-color)
icon-color (or icon-color color default-color)]
[rn/view {:style (merge style/container container-style)}
[icons/icon icon
{:size (if (= size :tiny) 12 16)
:color icon-color
:no-color? no-icon-color?}]
[text/text
{:size (if (= size :tiny) :label :paragraph-2)
:accessibility-label accessibility-label
:style {:color text-color}} message]]))
(def view (schema/instrument #'view-internal ?schema))
@@ -0,0 +1,58 @@
(ns quo.components.list-items.approval-info.component-spec
(:require [quo.components.list-items.approval-info.view :as approval-info]
[test-helpers.component :as h]))
(h/describe "List Items: Approval Info"
(h/test "should render correctly with basic props"
(h/render-with-theme-provider
[approval-info/view
{:type :spending-cap
:label "Spending Cap"
:avatar-props {:image "image"}}])
(h/is-truthy (h/get-by-label-text :approval-info)))
(h/test "should render correctly with label & description"
(h/render-with-theme-provider
[approval-info/view
{:type :spending-cap
:label "Spending Cap"
:description "Description"
:avatar-props {:image "image"}}])
(h/is-truthy (h/get-by-text "Spending Cap"))
(h/is-truthy (h/get-by-text "Description")))
(h/test "on-button-press event is called when button is pressed"
(let [on-button-press (h/mock-fn)]
(h/render-with-theme-provider
[approval-info/view
{:type :spending-cap
:label "Spending Cap"
:button-label "Edit"
:button-icon :i/options
:on-button-press on-button-press
:avatar-props {:image "image"}}])
(h/fire-event :press (h/get-by-text "Edit"))
(h/was-called on-button-press)))
(h/test "on-option-press event is called when option icon is pressed"
(let [on-option-press (h/mock-fn)]
(h/render-with-theme-provider
[approval-info/view
{:type :spending-cap
:label "Spending Cap"
:option-icon :i/options
:on-option-press on-option-press
:avatar-props {:image "image"}}])
(h/fire-event :press (h/get-by-label-text :icon))
(h/was-called on-option-press)))
(h/test "on-avatar-press event is called when avatar is pressed"
(let [on-avatar-press (h/mock-fn)]
(h/render-with-theme-provider
[approval-info/view
{:type :spending-cap
:label "Spending Cap"
:on-avatar-press on-avatar-press
:avatar-props {:image "image"}}])
(h/fire-event :press (h/get-by-label-text :token-avatar))
(h/was-called on-avatar-press))))
@@ -0,0 +1,36 @@
(ns quo.components.list-items.approval-info.style
(:require [quo.foundations.colors :as colors]))
(defn icon-description-color
[blur? theme]
(if blur?
colors/white-opa-40
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
(defn container
[description? blur? theme]
{:flex-direction :row
:padding-horizontal 12
:padding-vertical (if description? 8 12)
:border-radius 16
:gap 8
:align-items :center
:border-width 1
:border-color (if blur?
colors/white-opa-5
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})
(def labels
{:flex 1
:justify-content :center
:padding-right 4})
(defn label
[blur? theme]
{:color (if blur?
colors/white
(colors/theme-colors colors/neutral-100 colors/white theme))})
(defn description
[blur? theme]
{:color (icon-description-color blur? theme)})
@@ -0,0 +1,124 @@
(ns quo.components.list-items.approval-info.view
(:require [clojure.string :as string]
[quo.components.avatars.account-avatar.view :as account-avatar]
[quo.components.avatars.collection-avatar.view :as collection-avatar]
[quo.components.avatars.community-avatar.view :as community-avatar]
[quo.components.avatars.dapp-avatar.view :as dapp-avatar]
[quo.components.avatars.icon-avatar :as icon-avatar]
[quo.components.avatars.token-avatar.view :as token-avatar]
[quo.components.avatars.wallet-user-avatar.view :as wallet-user-avatar]
[quo.components.buttons.button.view :as button]
[quo.components.icon :as icon]
[quo.components.list-items.approval-info.style :as style]
[quo.components.markdown.text :as text]
[quo.components.tags.tiny-tag.view :as tiny-tag]
[quo.foundations.colors :as colors]
quo.theme
[react-native.core :as rn]
[schema.core :as schema]))
(def ?schema
[:=>
[:catn
[:props
[:map {:closed true}
[:type
[:enum :spending-cap :token-contract :account :spending-contract :network :date-signed
:collectible :address :community :collectible-contract]]
[:avatar-props :map]
[:label :string]
[:description {:optional true} [:maybe :string]]
[:button-label {:optional true} [:maybe :string]]
[:button-icon {:optional true} [:maybe :keyword]]
[:blur? {:optional true} [:maybe :boolean]]
[:unlimited-icon? {:optional true} [:maybe :boolean]]
[:option-icon {:optional true} [:maybe :keyword]]
[:tag-label {:optional true} [:maybe :string]]
[:on-button-press {:optional true} [:maybe fn?]]
[:on-avatar-press {:optional true} [:maybe fn?]]
[:on-option-press {:optional true} [:maybe fn?]]
[:container-style {:optional true} [:maybe :any]]]]]
:any])
(defn- avatar
[{:keys [type avatar-props blur? theme on-press]}]
[rn/pressable {:on-press on-press}
(case type
:account [account-avatar/view (assoc avatar-props :size 32)]
:collectible-contract [collection-avatar/view (assoc avatar-props :size :size-32)]
:spending-contract [dapp-avatar/view avatar-props]
:date-signed [icon-avatar/icon-avatar
(assoc avatar-props
:size :size-32
:opacity 10
:color (if blur?
colors/white
(colors/theme-colors colors/neutral-50
colors/neutral-40
theme)))]
:address [wallet-user-avatar/wallet-user-avatar
(assoc avatar-props
:size :size-32
:monospace? true
:lowercase? true
:neutral? true)]
:community [community-avatar/view avatar-props]
[token-avatar/view
(assoc avatar-props
:type
(if (= type :collectible) :collectible :asset))])])
(defn- view-internal
[{:keys [type avatar-props label description blur? unlimited-icon? container-style
on-option-press on-avatar-press on-button-press button-label button-icon tag-label
option-icon]}]
(let [theme (quo.theme/use-theme)
description? (not (string/blank? description))]
[rn/view
{:style (merge (style/container description? blur? theme) container-style)
:accessibility-label :approval-info}
[avatar
{:type type
:blur? blur?
:theme theme
:on-press on-avatar-press
:avatar-props avatar-props}]
[rn/view
{:style style/labels}
[rn/view
{:style {:flex-direction :row :align-items :center}}
[text/text
{:size :paragraph-1
:weight (if (= type :address) :monospace :semi-bold)
:style (style/label blur? theme)}
label]
(when unlimited-icon?
[icon/icon :i/alert
{:container-style {:margin-left 4}
:size 16
:color (style/icon-description-color blur? theme)}])]
(when description?
[text/text
{:size :paragraph-2
:weight (if (contains? #{:collectible-contract :spending-contract :account :token-contract}
type)
:monospace
:regular)
:style (style/description blur? theme)}
description])]
(when (= type :account) [tiny-tag/view {:label tag-label}])
(when (and (= type :spending-cap) button-icon)
[button/button
{:type :outline
:size 24
:blur? blur?
:icon-left button-icon
:on-press on-button-press}
button-label])
(when option-icon
[rn/pressable {:on-press on-option-press}
[icon/icon option-icon
{:color (style/icon-description-color blur? theme)
:size 20}]])]))
(def view (schema/instrument #'view-internal ?schema))
@@ -47,3 +47,12 @@
(defn style-text-value
[theme]
{:color (colors/theme-colors colors/neutral-50 colors/white theme)})
(def initials-avatar-container
{:width 32
:height 32})
(def image-avatar
{:width 32
:height 32
:border-radius 32})
+10 -3
View File
@@ -1,5 +1,6 @@
(ns quo.components.list-items.dapp.view
(:require
[quo.components.avatars.user-avatar.view :as user-avatar]
[quo.components.list-items.dapp.style :as style]
[quo.components.markdown.text :as text]
[quo.theme :as quo.theme]
@@ -20,9 +21,15 @@
:on-press-in on-press-in
:on-press-out on-press-out}
[rn/view {:style style/container-info}
[fast-image/fast-image
{:source (:avatar dapp)
:style {:width 32 :height 32}}]
(if (:avatar dapp)
[fast-image/fast-image
{:source (:avatar dapp)
:style style/image-avatar}]
[rn/view {:style style/initials-avatar-container}
[user-avatar/initials-avatar
{:full-name (:name dapp)
:size :small
:customization-color (:customization-color dapp)}]])
[rn/view {:style style/user-info}
[text/text
{:weight :semi-bold
@@ -44,13 +44,14 @@
[:label :string]
[:fiat-value :string]
[:token-value :string]
[:container-style {:optional true} [:maybe :map]]
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
[:state {:optional true} [:enum :pressed :active :disabled :default]]
[:on-press {:optional true} [:maybe fn?]]]]]
:any])
(defn- view-internal
[{:keys [on-press state customization-color]
[{:keys [on-press container-style state customization-color]
:as props
:or {customization-color :blue}}]
(let [theme (quo.theme/use-theme)
@@ -59,7 +60,8 @@
on-press-out (rn/use-callback #(set-pressed false))
internal-state (if pressed? :pressed state)]
[rn/pressable
{:style (style/container internal-state customization-color theme)
{:style (merge (style/container internal-state customization-color theme)
container-style)
:on-press-in (when-not (= state :disabled) on-press-in)
:on-press-out (when-not (= state :disabled) on-press-out)
:on-press (when-not (= state :disabled) on-press)
+3 -3
View File
@@ -8,7 +8,7 @@
[quo.foundations.colors :as colors]
[react-native.core :as rn]))
(def container-style
(def container
{:margin-horizontal 8
:padding-vertical 8
:padding-horizontal 12
@@ -43,9 +43,9 @@
(defn user
[{:keys [short-chat-key primary-name secondary-name photo-path online? contact? verified?
untrustworthy? on-press on-long-press accessory customization-color theme
allow-multiple-presses? disabled?]}]
allow-multiple-presses? disabled? container-style]}]
[rn/touchable-highlight
{:style container-style
{:style (merge container container-style)
:underlay-color (colors/resolve-color customization-color theme 5)
:allow-multiple-presses? allow-multiple-presses?
:accessibility-label :user-list

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