Compare commits

..
Author SHA1 Message Date
Yevheniia Berdnyk 32542baa24 e2e: community names update 2024-04-15 05:53:07 +03:00
Andrea Maria Piana de56aed530 Replace creation on communities client side
https://github.com/status-im/status-go/compare/b744ff43...b710fa3e
2024-04-11 17:23:11 +01:00
flexsurfer cfc43be3cc migrate reagent part6 (#19270) 2024-04-11 16:43:33 +02:00
flexsurfer 3164cc6a6c Chore: setup feature-flag for not-implemented settings (#19591) 2024-04-11 16:43:09 +02:00
Mohsen 5badb5bdb5 [#19178] fix: jump card responsive (#19600) 2024-04-11 17:36:28 +03:00
flexsurfer 292fd78ff8 warning fixes (#19605) 2024-04-11 15:42:29 +02:00
Lungu Cristian c875fb33fa Show token requirements only for token gated channels (#19529)
* fix: use role-permissions? instead of token-permission

token-permissions contains channel-permissions as well, which don't
make the community token-gated

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

* fix: hide token requirements from open channels

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

* fixed tests

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

---------

Signed-off-by: Cristian Lungu <lungucristian95@gmail.com>
2024-04-11 16:27:18 +03:00
jakub b5962fd83a nix: fix detecting install type in Docker
Otherwise build fails in a Docker container for Desktop:
```
+ make status-go
Building: status-go
Unknown Nix installtion type!
Unknown Nix installtion type!
make[1]: *** [Makefile:223: statusgo-shared-library] Error 1
make: *** [Makefile:432: vendor/status-go/build/bin/libstatus.so] Error 2
```

Signed-off-by: Jakub Sokołowski <jakub@status.im>
2024-04-11 16:01:34 +03:00
Jamie Caprani 1d1eae13a9 chore(wallet): move add-account funcitonality into its own folder (#19476) 2024-04-11 12:01:35 +02:00
Jamie Caprani 63a168b6f4 chore: remove old wallet code, signing code and keycard code (#19467) 2024-04-10 10:41:24 -07:00
Ulises Manuel ce7912632c [#18739] Fix ENS resolution (#19238)
* Resolve ENS on address-to-watch screen based on test-net settings

* Resolve ENS on `:wallet/search-ens` event based on test-net settings
2024-04-10 11:09:40 -06:00
Jamie Caprani ec53f17897 chore(wallet): add options menu for collectibles 2024-04-10 17:50:07 +01:00
Shivek Khurana 7987e537c8 🧰 Update GetSuggestedRoutes call (#19560)
- This is to reflect changes made in https://github.com/status-im/status-go/pull/5002/files
2024-04-10 17:09:40 +01:00
Parvesh Monu 074a2b292d fix alert banner flicker in ios (#19495) 2024-04-10 21:16:33 +05:30
Volodymyr Kozieiev 8b417524fa Remove unused subs (#19530)
* Remove unused subs

* lint fix
2024-04-10 16:25:41 +01:00
Siddarth Kumar f6a433c818 kotlinify account, database, Log & Network Manager (#19426)
parent issue: https://github.com/status-im/status-mobile/issues/18310

This commit converts the following `Java` files to `Kotlin` :

- modules/react-native-status/android/src/main/java/im/status/ethereum/module/AccountManager.java
- modules/react-native-status/android/src/main/java/im/status/ethereum/module/DatabaseManager.java
- modules/react-native-status/android/src/main/java/im/status/ethereum/module/LogManager.java
- modules/react-native-status/android/src/main/java/im/status/ethereum/module/NetworkManager.java


status: ready
2024-04-10 20:32:56 +05:30
Siddarth Kumar 4940341504 point statusgo to gomobile xcode 15 patch (#19577)
## Summary
A patch is added to `gomobile` on status-go side to fix building with Xcode 15.
related status go PR -> https://github.com/status-im/status-go/pull/5035

## Platforms
- Android
- iOS

status: ready
2024-04-10 20:07:06 +05:30
Ibrahem Khalil 06aa4671b6 Sometimes toast about old join community notification starts appearing on every login (#19557) 2024-04-09 21:46:58 +02:00
andrey 7eaa5f6bb1 revert status-go version 2024-04-09 17:32:54 +02:00
flexsurfer d48f933502 Feature/allow user to select a picture for a group chat #18983 (#19128) 2024-04-09 17:20:17 +02:00
flexsurfer 14d76eb4d4 Remove the bottom context from "Sign in by syncing" #19549 (#19571) 2024-04-09 15:45:07 +02:00
flexsurfer ae1f82f33c Fix the "Choose profile" button in the profile #19551 (#19570) 2024-04-09 15:44:22 +02:00
Ibrahem Khalil c5a3eea048 Drawer in the chat is not fully expanded when reply message is closed and reopened (#19460) 2024-04-09 13:11:31 +02:00
Ibrahem Khalil c847cb5d03 [16315] Implement Community Channel option: view channel members and details (#18489) 2024-04-09 10:38:48 +02:00
Lungu Cristian 4e1851d53c Fix the channel-action when the text is too long (#19462)
* fix: don't increase action with text

* addressed review comments
2024-04-09 10:43:33 +03:00
Alexander edd1d0661d [iOS] Wrong bottom sheet opacity on onboarding and in the activity center (#19319)
* [iOS] Wrong bottom sheet opacity on onboarding and in the activity center

* Blur amount update
2024-04-09 08:36:44 +02:00
Ibrahem Khalil 18fc168537 [Android] The text within buttons is slightly visible when buttons ar… (#19461) 2024-04-09 02:06:57 +02:00
Ibrahem Khalil ca8b404e5b Account selection sheet price (#19295) 2024-04-09 01:53:29 +02:00
Yevheniia Berdnyk f98e5cf11f e2e: fixes 8.04 2024-04-08 23:00:46 +03:00
Volodymyr Kozieiev 5aca098aa2 Support for multiple collectibles transaction on confirmation page (#19502) 2024-04-08 20:43:23 +01:00
Siddarth Kumar 55a182f430 kotlinify parts of status module, package & Utils (#19408)
parent issue: https://github.com/status-im/status-mobile/issues/18310

This commit converts the following `Java` files to `Kotlin` :

- modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java
- modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusPackage.java
- modules/react-native-status/android/src/main/java/im/status/ethereum/module/Utils.java

This commit converts Java code to `Kotlin` which involves a helper function that is used to execute `statusgo` methods.
It may impact everything or nothing.

- Android
2024-04-08 22:46:01 +05:30
Ulises Manuel 8e31dae33b [#16953] Implement change asset action in wallet send flow (#19393)
* Refactor :wallet/tokens-filtered sub to filter only when `query` is provided

* Make token input logo pressable and make components more flexible

* Change asset-list's rn/scroll-view -> gesture/scroll-view to make it scrollable on bottom-sheets

* Add bottom-sheet to edit the token to send
2024-04-08 10:52:09 -06:00
Siddarth Kumar ce69df19ac apply patches with patch files (#19451)
fixes #19449

In this commit we change the way patches are applied.
We no longer have to write patches in a patch phase like we used to, we can now place individual changes in a patch file inside the `patches` directory and they will be automatically applied.

Because of this change we can get rid of forks and instead have those changes in patch files.

To generate a patch file this make command can be used `make patch-file`
This will open an interactive shell which will allow you to specify which file you want to patch and then wait till you make those changes and generate a patch for it.

```
make patch-file
Configuring Nix shell for target 'default'...
Enter the path of the file to patch: ./node_modules/is-glob/index.js
File to patch: ./node_modules/is-glob/index.js
Temporary directory created: /tmp/tmp-status-mobile-40bc588fa/tmp.xrXarXoTPZ
Original file copied to temporary directory.
Please make the necessary changes to the file: ./node_modules/is-glob/index.js
Press any key when you are done with the changes...
Generating patch file...
Patch file created at /Users/siddarthkumar/code/status-im/PR/status-mobile/patches/index.js.patch
Info: Please execute 'make run-clojure' to test if the patch file works as expected.
```

- Android
- iOS
2024-04-08 21:06:41 +05:30
Ajay Sivan 681bcbf726 Token gated documentation drawer ui fix (#19394) 2024-04-08 08:14:47 -07:00
Lungu Cristian aeef913f63 Fix chat permission-context (#19284)
* feat: moved permission-context logic to quo component

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

* feat: multiple-token-gating and previews

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

* fix: refactored quo component

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

* feat: request join community on press

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

* feat: added shadow (rn-shadow-2)

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

* fix: formatting

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

* test: added tests for permission-context

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

* feat: added blur

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

* fix: adjusted shadows

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

* fix: added shadow mocks

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

* fix: shadow rendered below the context

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

* fix: addressed review comments

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

* fix: replaced seq with string/blank?

---------

Signed-off-by: Cristian Lungu <lungucristian95@gmail.com>
2024-04-08 17:14:07 +03:00
Omar Basem 74e84644aa Wallet: Derivation Path - Scanning for Activity (#19482)
Wallet: Derivation Path - Scanning for Activity (#19482)
2024-04-08 17:53:41 +04:00
Sean Hagstrom 0e29149363 Truncate text inside contact request notifications (#19499)
* tweak: truncate text inside contact request notifications to be a max of two lines

* tweak: truncate text inside the activity-center contact-requests to be a max of two lines
2024-04-08 13:32:17 +01:00
Parvesh Monu 5fe28a2c9b fix android composer background shadow not visible when image is attached (#19492) 2024-04-08 16:58:17 +05:30
Lungu Cristian 5fba1dbfa3 Fix invalid schemas (#19548)
* fix: account selection invalid schema definition

* fix: token-input invalid schema definition
2024-04-08 13:33:30 +03:00
Ajay Sivan 32098d2548 Community collapsed header title animation fix (#19395) 2024-04-07 14:14:21 -07:00
Yevheniia Berdnyk 60a4aa2f8e e2e: fix for passwrod input 2024-04-05 18:46:23 +03:00
Mohsen f8699c582a [#19265] fix: cursor overlapping placeholder in android (#19526) 2024-04-05 15:25:33 +03:00
Mohamed Javid 9ba6c6262e [Feature] Wallet - Network based assets and fiat balance calculation (#19150)
This commit:

(UI changes)

- adds the feature to filter assets (tokens and collectibles) and balances based on networks
- fixes network color for eth not shown on the multichain address (e.g. Account Options bottom sheet)
- fixes blur type in the confirm button in the network preferences sheet
- fixes the User ability to unselect all networks in the network preferences sheet
- fixes account address and color not shown in network-preferences sheet on Shell > Share Multichain address
- added STT token image

(Non-UI changes)

- Refactors the functions used for balance calculations and network details


Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2024-04-05 17:18:35 +05:30
Yevheniia Berdnyk 5fc23816a6 e2e: false failures fixes for wallet and image 2024-04-05 13:38:09 +03:00
Sean Hagstrom 59513eae65 Tweak layout of quo/author component to use flex-baseline (#19489)
* tweak: re-structure layout of quo/author component to use flex-baseline for alignment

* tweak: use top on container to balance layout while using top to offset primary-name

* tidy: remove margin-bottom: 0

* tweak: add comments and fix layout glitch
2024-04-05 11:33:35 +01:00
Mohsen aead730d28 [#19406] fix: add min char validation for nickname (#19517) 2024-04-05 08:28:08 +03:00
Yevheniia Berdnyk 5bff89a58f e2e: wallet tests added 2024-04-04 19:50:54 +03:00
Parvesh Monu e1177d20b5 Improve navigate-to-jump-to (#19434) 2024-04-04 22:07:11 +05:30
Lungu Cristian 0a6eaf1c12 fix: reverted the faulty navigation keyword rename (#19487)
Signed-off-by: Cristian Lungu <lungucristian95@gmail.com>
2024-04-04 18:35:28 +03:00
Sean Hagstrom d24eb96c9d Use scrollable multiline text-input in contact request form (#19383)
* tweak: augment bottom-sheet component to be aware of keyboard height

* tweak: augment quo input component to allow for styling of the input, the input container, and container

* tweak: augment contact request input to grow until max screen size is reached for the bottom-sheet

* tweak: handle blurring the contact request input when keyboard is dismissed on android

* tidy: refactor with the use-keyboard hook

* tweak: use on-layout for measuring sheet max-height

* tweak: remove use of input-style and flex-direction column

* tidy: remove unused requires

* tidy: use container-style prop

* tidy: fix formatting

* fix: default layout-height to window-height
2024-04-04 15:54:22 +01:00
Sean Hagstrom 3dfd9df935 fix: dismiss keyboard when opening a modal (#19403) 2024-04-04 15:01:54 +01:00
Shivek Khurana d0374d9fd2 🖇️ Connect getSavedAddresses RPC to show or hide save address button (#19508)
* 🖇️ Connect getSavedAddresses

- The save button will not show if the address is already saved

* ⚒️ Fix PR reviews

* 🗑️ Remove code from wallet events ns
2024-04-04 13:51:29 +01:00
Ibrahem Khalil f0026b4d10 Fix background color on communities/chat home (#19520) 2024-04-04 12:35:44 +02:00
Mohsen b9a02f707d [#19351] fix: animate username in profile (#19370) 2024-04-04 13:21:23 +03:00
Parvesh Monu d4e1b63ef7 fix top bar disappearing when removing or blocking contact (#19430) 2024-04-04 15:28:44 +05:30
jakub e9b973196b ci: fix Pulish stage by using getBuildType()
Signed-off-by: Jakub Sokołowski <jakub@status.im>
2024-04-04 11:35:39 +02:00
Ibrahem Khalil 74149c1ff0 Use correct schema keyword (#19522) 2024-04-04 11:19:35 +02:00
Yevheniia Berdnyk 288f57192a e2e: fixes after testet mode enabled changes 2024-04-03 23:58:11 +03:00
John Ngei a52bc11592 updated community rules to display the actual rules
* updated community rules to display the actual rules

* updated scroll behaviours on community rules inside the bottom sheet

* added standard rules for communities without rules

* fix android scroll issues
2024-04-03 22:40:22 +02:00
Tetiana Churikova 354cda3be5 e2e: updating PR pipeline (#19478) 2024-04-03 18:00:04 +02:00
John Ngei f114908c4d updated leave button background color to community color 2024-04-03 17:38:41 +02:00
yqrashawn b0964eff64 feat: contact CustomizationColor (#19087) 2024-04-03 23:15:26 +08:00
mmilad75 b0d2e6e5d7 Bottom sheet with save and send options not displayed after scanning wallet QR using universal scanner #18928 (#19250) 2024-04-03 18:27:46 +03:30
Siddarth Kumar df0e9313da fix for failing iOS nightly build (#19486)
iOS nightly builds were failing with :

```
07:54:15  The following build commands failed:
07:54:15  	PhaseScriptExecution Run\ Script /Users/jenkins/Library/Developer/Xcode/DerivedData/
StatusIm-hasrsefeolwghadhqaakilqvfzrk/Build/Intermediates.noindex/ArchiveIntermediates/StatusIm/
IntermediateBuildFilesPath/StatusIm.build/Release-iphoneos/StatusIm.build/
Script-E3914A731DF919ED00EBB515.sh (in target 'StatusIm' from project 'StatusIm')
07:54:15  (1 failure)
07:54:15  [05:24:14]: Exit status: 65
.
.
.
07:54:15  [05:24:14]: ▸     /bin/sh -c /Users/jenkins/Library/Developer/Xcode/DerivedData/
StatusIm-hasrsefeolwghadhqaakilqvfzrk/Build/Intermediates.noindex/ArchiveIntermediates/StatusIm/
IntermediateBuildFilesPath/StatusIm.build/Release-iphoneos/StatusIm.build/
Script-E3914A731DF919ED00EBB515.sh

07:54:15  [05:24:14]: ▸ /Users/jenkins/Library/Developer/Xcode/DerivedData/
StatusIm-hasrsefeolwghadhqaakilqvfzrk/Build/Intermediates.noindex/ArchiveIntermediates/StatusIm/
IntermediateBuildFilesPath/StatusIm.build/Release-iphoneos/StatusIm.build/
Script-E3914A731DF919ED00EBB515.sh: line 2: ./logs/set_xcode_version.log: No such file or directory

07:54:15  [05:24:14]: ▸ Command PhaseScriptExecution failed with a nonzero exit code
```

In this commit the path to the logfile `set_xcode_version.log` has been fixed.
2024-04-03 18:05:48 +05:30
Lungu CristianandVolodymyr 76bf8d365c Allow to undo muting the chat/channel from toast (#19074)
* feat: added undo action to mute chat toast

* fix: removed trailing spaces from toast text

* test: integration test for mute-chat undo

* fix: added space before newline to toast messages text

* feat: add undo to community mute toast

* fix: integration tests

* fix: integration tests

---------

Co-authored-by: Volodymyr <52490791+VolodLytvynenko@users.noreply.github.com>
2024-04-03 15:12:43 +03:00
Mohamed JavidandYevheniia Berdnyk 41763689e0 [Feature] Show "Testnet mode enabled" banner if testnet enabled (#19348)
This commit 
- adds the "Testnet mode enabled" banner if the User has enabled the testnet
- fixes a E2E bug

---------

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
Co-authored-by: Yevheniia Berdnyk <ie.berdnyk@gmail.com>
2024-04-03 16:15:07 +05:30
Mohsen a6a7ec8bc0 [#19264] fix: add contact bottom margin (#19398) 2024-04-03 12:56:40 +03:00
Ibrahem Khalil 7e896979f6 Add biometric auth if available to communities password input (#19336) 2024-04-03 11:18:15 +02:00
Omar Basem 68402ae669 fix: Wrong UI for network preferences bottom sheet (#19475)
fix: Wrong UI for network preferences bottom sheet (#19475)
2024-04-02 22:24:55 +04:00
Flavio Fraschetti 8c67ce0b75 [Wallet]Fraschetti/Temporarily hide Activity Tab on Collectible Detail Page (#19447)
Temporarily hide the collectibles activity tab.
2024-04-02 11:10:57 -03:00
Omar Basem e2b9e12038 feat: Keypair name handling (#19423)
feat: Keypair name handling (#19423)
2024-04-02 15:44:48 +04:00
Shivek Khurana a03cc3c3ab Add methods for fetching and saving addresses (#19356)
*  Add methods for fetching and saving addresses

* 🔨 Fix RPC calls but get addresses not working

* 🔨 Fix rpc call

* 🧰 Fix lint, and change var names
2024-04-02 12:25:28 +01:00
Siddarth Kumar da25280555 clean up unused libraries (#19456)
## Summary

This PR removes all of the unused `npm` libraries and their corresponding `gradle`/`cocoapods` dependencies.
The list of npm dependencies removed are :
- `@babel/preset-typescript`
- `create-react-class`
- `react-native-haptic-feedback`
- `react-native-image-viewing`
- `react-native-languages`
- `react-native-randombytes`
- `react-syntax-highlighter`
- `rn-emoji-keyboard`
- `tdigest`

This saves us some bytes in the bundle size.

## Platforms
- Android
- iOS
2024-04-02 16:32:54 +05:30
Siddarth Kumar 68e4cf3632 add logs inside wait-for and before,after logout (#19362)
## Summary

PR made to add logs to help determine why integration test hangs on logout.

## Testing notes

No need for testing since we only ever add logs in test code here.

related to: #19256
2024-04-02 13:54:44 +05:30
Sean Hagstrom dd7795a8b8 Truncate secondary names in username and author components (#19468)
* fix: allow name-container inside message content to shrink so secondary-name can be truncated

* fix: responsively truncate contact profile secondary-name

* fix: ensure home chat-list-items use full available width in layout

* fix: adjust layout of home chat-list-item shrinking with notification counter

* fix: adjust layout of home chat-list-item when displaying notification counter

* tidy: simplify alignment

* tweak: adjust alignment of quo/author component for different text sizes

* tidy: extract styles and reformat notification-layout
2024-04-02 08:14:08 +01:00
Ulises Manuel feb875310e [#19401] Wallet share QR code - multiple fixes (#19425)
* Fix key extractions in re-frame/reg-sub

* Add `:width` to share-qr-code
  By adding this prop, `on-layout` can be skipped and the component can be properly rendered faster.

* Use `share-qr-code`'s `:width` prop in share profile shell

* Fix share qr code for wallet addresses

* Fix the height of the component being cropped.

* Fix the bottom dots not being accurately highlighted.

* Fix the blink when the component is mounted
2024-04-01 09:53:26 -06:00
Parvesh Monu 8b0681c44a fix status and nav bar color (#19089) 2024-04-01 18:52:03 +05:30
Parvesh Monu 9bbde035dc fix 1-1 Chat not removed after user is blocked (#19432) 2024-04-01 18:34:59 +05:30
Flavio Fraschetti 260a741b17 Fraschetti - Add wallet-search-ens-test (#19338)
Introduces comprehensive tests for the ens_addressOf endpoint
2024-04-01 09:11:07 -03:00
Siddarth Kumar 48789e8793 keep existing metro session alive (#19458)
The killing of metro terminal upset a few people and this PR fixes that.

## Summary
Modify build step to check if metro is running already.
If so then we do not attempt to start metro again.
If not then we start metro after building android / iOS.

## Review notes
* case 1
    - `make run-clojure`
    - `make run-metro`
    - `make run-android` or `make run-ios` should work the way it did before.
* case 2
    - `make run-clojure`
    - `make run-android` or `make run-ios` should also work.

## Platforms
- Android
- iOS
2024-04-01 16:47:48 +05:30
Siddarth Kumar 2dfb3ab838 upgrade nixpkgs to 23-11 (#19369)
fixes #18311

This PR upgrades `nixpkgs` to latest release version of 23-11
ref -> https://github.com/NixOS/nixpkgs/releases/tag/23.11

- `Gradle` from `8.0.1` -> `8.4`
- `Git` from `2.40.1` -> `2.42.0`
- `Curl` from `8.0.1` -> `8.4.0`
- `OpenSSL` from `3.0.8` -> `3.0.13`
- `NodeJS` from `18.16.0` -> `18.19.1`
-  `Python` from `3.10.11` -> `3.10.13`
- `Clojure` from `1.11.1.1273` -> `1.11.1.1413`
- and some more stuff

- `xcbeautify` , this was added in 23-11 ->https://github.com/NixOS/nixpkgs/pull/289446
- `idb-companion`, this was also added in 23-11 -> https://github.com/NixOS/nixpkgs/pull/296440
2024-04-01 16:26:44 +05:30
Parvesh Monu e05d5000b1 fix jump-to community card animation (#19437) 2024-04-01 16:05:14 +05:30
John Ngei 3067b814b1 fix: token requirements margin issues 2024-03-31 00:03:34 +01:00
426 changed files with 7400 additions and 14140 deletions
+1
View File
@@ -35,3 +35,4 @@ LOCAL_PAIRING_ENABLED=1
TEST_STATEOFUS=1
FAST_CREATE_COMMUNITY_ENABLED=1
TEST_NETWORKS_ENABLED=1
SHOW_NOT_IMPLEMENTED_FEATURES=1
+1
View File
@@ -34,3 +34,4 @@ STICKERS_TEST_ENABLED=1
LOCAL_PAIRING_ENABLED=1
FAST_CREATE_COMMUNITY_ENABLED=1
TEST_NETWORKS_ENABLED=1
SHOW_NOT_IMPLEMENTED_FEATURES=1
+1
View File
@@ -36,3 +36,4 @@ STICKERS_TEST_ENABLED=1
LOCAL_PAIRING_ENABLED=1
FAST_CREATE_COMMUNITY_ENABLED=1
TEST_NETWORKS_ENABLED=1
SHOW_NOT_IMPLEMENTED_FEATURES=1
+4
View File
@@ -441,6 +441,10 @@ _list: SHELL := /bin/sh
_list:
@$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
patch-file: export TARGET := default
patch-file: ##@other Generates patch file for npm deps
@scripts/patch-npm-lib.sh
#--------------
# REPLs
#--------------
+1 -1
View File
@@ -81,7 +81,7 @@ pipeline {
stage('Publish') {
when { expression { params.PUBLISH } }
steps { script {
switch (btype) {
switch (utils.getBuildType()) {
case 'nightly': /* Create JSON file with newest build URLs */
s3.updateBucketJSON(urls, 'latest.json');
break;
+5 -15
View File
@@ -20,12 +20,6 @@ required by bignumber.js otherwise there is a compilation error
used to generate guids and random values in `status-im.utils.random`
## "create-react-class": "15.6.2"
fixed version because even bugfix update causes compilation error with current version of react-native (0.59)
internal react library, used by figwheel for instance but also probably react
## "emojilib": "^2.4.0"
used for emojis
@@ -113,11 +107,6 @@ used for profile picture
used for storing password when user saves password
TODO: check if fork is necessary, merge with upstream?
## "react-native-languages": "^3.0.2"
TODO DEPRECATED, should be replaced with https://github.com/react-native-community/react-native-localize
used to get user language and interact with i18n.js
## "react-native-mail": "git+https://github.com/status-im/react-native-mail.git#v3.0.8_status"
used to send email to support when phone is shaked
@@ -131,6 +120,7 @@ TODO: update once bug is fixed for Android that causes crash when app is back fr
## "react-native-shake": "^3.3.1"
used to send email to support when phone is shaked
## "react-native-lottie-splash-screen": "^1.0.1"
used to make splash screen with lottie animation during initial loading for android, also used as replacement of "react-native-splash-screen" for iOS
@@ -157,10 +147,10 @@ used for browser
used for native navigation
fixed because even bugfix version upgrade causes runtime errors with current version of react-native
## "rn-emoji-keyboard": "https://github.com/status-im/rn-emoji-keyboard"
Used for taking emoji input, for custom emoji thumbnails for community channels
## "react-native-draggable-flatlist": "https://github.com/computerjazz/react-native-draggable-flatlist"
A drag-and-drop-enabled FlatList component for React Native
## "react-native-shadow-2": "https://github.com/SrBrahma/react-native-shadow-2"
A shadow component that is consistent across both platforms
+48 -14
View File
@@ -2,7 +2,7 @@
[Pipeline for QA](https://github.com/status-im/status-mobile/projects/7) is a project board for developers and testers used to track the status of a pull request, get reviews and manual testing, and run autotests.
The generally accepted recommendations for its use are described below:
The generally accepted requirements for its use are described below:
## Opening a PR
- Once a PR is created, it moves to the ```REVIEW``` column where a review will be requested automatically.
@@ -13,35 +13,70 @@ The generally accepted recommendations for its use are described below:
### What if the work is still in progress?
- If PR work is not finished yet, please mark it as a draft or add [WIP] to the title and keep it in the `CONTRIBUTOR` column until it's ready to be reviewed/tested.
- Alternatively, you can open a `draft`.
### When is a PR considered ready to move forward?
### When is a PR considered to be Ready for testing by QA team? 


Ready for testing PR should meet the following criteria:
Ready for testing, a PR should meet the following criteria:
1. Reviewed and has at least 1 approval
2. Rebased to `develop` branch (both `status-mobile` and `status-go` if needed, depending on what part has changes)
3. All possible conflicts have been resolved
4. Has the label: `request-manual-qa`
1. Reviewed and has at least 1 approval.
2. Rebased to the `develop` branch (both `status-mobile` and `status-go` if needed, depending on what part has changes).
- **NOTE:** QAs can use the `Update with rebase` button from GitHub if:
- The PR has no `status-go` changes.
- The PR has no conflict with the develop branch.
3. All possible conflicts have been resolved.
4. Has the label: `request-manual-qa` or `skip-manual-qa`.
5. PRs **MUST** identify what area is affected and should have a description.
**NOTE:** Make sure that QAs are OK with that
### Adding `skip-manual-qa`
- 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.
**From the perspective of a developer it means that once work on PR is finished:**
1. It should be rebased to the latest `develop`. If there are conflicts - they should be resolved if possible.
2. If the PR was in the `Contributor` column - it should be moved to `Review` column.
3. Wait for the review.
4. Make sure that after review and before requesting manual QA your PR is rebased to current develop.
5. Once the PR has been approved by reviewer(s) - label `request-manual-qa` should be applied to the PR
6. Move PR 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.
5. 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.
After that - PR will be taken into manual testing by the QA team.
6. After that - PR will be taken into manual testing by the QA team.
### E2E tests and analyzing the results
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).
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`).
**For now, it is the only reliable source of regression in the app because, due to time constraints, it is not possible to test thoroughly each PR.
Please, respect this rule.**
## Testing PR
### Manual testing
- If you think PR needs and is ready for manual testing, please add the ```request-manual-qa``` label.
#### Prerequisites for manual testing
1. PR has a description of the change and details the area of the application affected by the change.
2. PR has automation results from the previous E2E test run step.
3. PR includes a demo, test steps, and any possible regression(s)
4. If appropriate, PR details what elements of a feature are out of scope.
**If one of the prerequisites is missing, the PR will be moved to the contributor folder with a corresponding comment.**
- If you think a PR needs and is ready for manual testing, please add the `request-manual-qa` label.
- 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.
- When manual testing of the PR is fully completed and all the issues are fixed, the QA adds the ```Tested - OK``` label and drags the card to the ```Design review``` column (the cases when design review is necessary are described below).
- If design review is not required, the QA drags the PR to the ```MERGE``` column. After that the developer merges PR into develop.
- If design review has been done, the designer (```@Francesca-G```) drags the PR to the ```MERGE``` column.
@@ -68,7 +103,7 @@ There are three possible scenarios when the design review is completed:
---
#### 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`.
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.
In the first case most often this happens due to conflicting files in PR.
In the second case - after fixing of all found issues, the developer should ping the QA in the PR comments for retesting.
@@ -86,7 +121,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)
HAPPY DEVELOPMENT! :tada:
+1
View File
@@ -217,6 +217,7 @@ GEM
PLATFORMS
arm64-darwin-22
x86_64-darwin-22
DEPENDENCIES
activesupport (>= 6.1.7.3, < 7.1.0)
+4 -22
View File
@@ -891,7 +891,7 @@ PODS:
- React-Core
- react-native-image-resizer (1.2.3):
- React
- react-native-lottie-splash-screen (1.0.1):
- react-native-lottie-splash-screen (1.1.2):
- React
- react-native-mail (6.1.1):
- React-Core
@@ -899,8 +899,6 @@ PODS:
- React
- react-native-orientation-locker (1.5.0):
- React-Core
- react-native-randombytes (3.6.1):
- React-Core
- react-native-shake (3.4.0):
- React
- react-native-slider (3.0.0):
@@ -1123,12 +1121,8 @@ PODS:
- TOCropViewController
- RNKeychain (8.1.2):
- React-Core
- RNLanguages (3.0.2):
- React
- RNPermissions (3.8.0):
- React-Core
- RNReactNativeHapticFeedback (1.9.0):
- React
- RNReanimated (3.6.1):
- glog
- RCT-Folly (= 2022.05.16.00)
@@ -1197,7 +1191,6 @@ DEPENDENCIES:
- react-native-mail (from `../node_modules/react-native-mail`)
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
- react-native-orientation-locker (from `../node_modules/react-native-orientation-locker`)
- react-native-randombytes (from `../node_modules/react-native-randombytes`)
- react-native-shake (from `../node_modules/react-native-shake`)
- "react-native-slider (from `../node_modules/@react-native-community/slider`)"
- react-native-status (from `../modules/react-native-status`)
@@ -1236,9 +1229,7 @@ DEPENDENCIES:
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
- RNImageCropPicker (from `../node_modules/react-native-image-crop-picker`)
- RNKeychain (from `../node_modules/react-native-keychain`)
- RNLanguages (from `../node_modules/react-native-languages`)
- RNPermissions (from `../node_modules/react-native-permissions`)
- RNReactNativeHapticFeedback (from `../node_modules/react-native-haptic-feedback`)
- RNReanimated (from `../node_modules/react-native-reanimated`)
- RNShare (from `../node_modules/react-native-share`)
- RNStaticSafeAreaInsets (from `../node_modules/react-native-static-safe-area-insets`)
@@ -1344,8 +1335,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/@react-native-community/netinfo"
react-native-orientation-locker:
:path: "../node_modules/react-native-orientation-locker"
react-native-randombytes:
:path: "../node_modules/react-native-randombytes"
react-native-shake:
:path: "../node_modules/react-native-shake"
react-native-slider:
@@ -1422,12 +1411,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-image-crop-picker"
RNKeychain:
:path: "../node_modules/react-native-keychain"
RNLanguages:
:path: "../node_modules/react-native-languages"
RNPermissions:
:path: "../node_modules/react-native-permissions"
RNReactNativeHapticFeedback:
:path: "../node_modules/react-native-haptic-feedback"
RNReanimated:
:path: "../node_modules/react-native-reanimated"
RNShare:
@@ -1459,7 +1444,7 @@ SPEC CHECKSUMS:
FBLazyVector: 56e0e498dbb513b96c40bac6284729ba4e62672d
FBReactNativeSpec: 146c741a3f40361f6bc13a4ba284678cbedb5881
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 5ce14391bd2885c921f691b0abdff44138728fac
glog: 530710e7949eb12c82670bd09e946becf50a3c2a
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8
libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef
@@ -1494,11 +1479,10 @@ SPEC CHECKSUMS:
react-native-config: 5330c8258265c1e5fdb8c009d2cabd6badd96727
react-native-hole-view: 6935448993bac79f2b5a4ad7e9741094cf810679
react-native-image-resizer: 2f1577efa3bc762597681f530c8e8d05ce0ceeb3
react-native-lottie-splash-screen: 068688c15dd478301fda00f8d87d7fb7d5b9a93e
react-native-lottie-splash-screen: 4e1b1fd9d6633f9cd2106d6877eb5ba0147f3e2b
react-native-mail: 8fdcd3aef007c33a6877a18eb4cf7447a1d4ce4a
react-native-netinfo: ddaca8bbb9e6e914b1a23787ccb879bc642931c9
react-native-orientation-locker: 851f6510d8046ea2f14aa169b1e01fcd309a94ba
react-native-randombytes: 421f1c7d48c0af8dbcd471b0324393ebf8fe7846
react-native-shake: de052eaa3eadc4a326b8ddd7ac80c06e8d84528c
react-native-slider: 12bd76d3d568c9c5500825db54123d44b48e4ad4
react-native-status: 21f75d492fd311dc111303da38a7a2b23a8a8466
@@ -1537,9 +1521,7 @@ SPEC CHECKSUMS:
RNGestureHandler: 15c6ef51acba34c49ff03003806cf5dd6098f383
RNImageCropPicker: 486e2f7e2b0461ce24321f751410dce1b3b49e6d
RNKeychain: a65256b6ca6ba6976132cc4124b238a5b13b3d9c
RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e
RNPermissions: 215c54462104b3925b412b0fb3c9c497b21c358b
RNReactNativeHapticFeedback: 2566b468cc8d0e7bb2f84b23adc0f4614594d071
RNReanimated: dee37576492f1a375017515f5c77e66e5eec696b
RNShare: 859ff710211285676b0bcedd156c12437ea1d564
RNStaticSafeAreaInsets: 055ddbf5e476321720457cdaeec0ff2ba40ec1b8
@@ -1554,4 +1536,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: c9c6dfac28e31314e1a2ee2dc47364ad151f13f2
COCOAPODS: 1.12.0
COCOAPODS: 1.13.0
+148 -154
View File
@@ -8,11 +8,10 @@
/* Begin PBXBuildFile section */
00E356F31AD99517003FC87E /* StatusImTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* StatusImTests.m */; };
061AC5E3D44813C6D987FC70 /* libPods-Status-StatusImPR.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C5D722CC6309CA4C8BC48244 /* libPods-Status-StatusImPR.a */; };
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
17F5C611511E64ACE76B00A3 /* libPods-Status-StatusIm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7AFB8653840373E5B625E16E /* libPods-Status-StatusIm.a */; };
25DC9C9DC25846BD8D084888 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B9A886A2CB448B1ABA0EB62 /* libc++.tbd */; };
2B6F8F28B81E862D44C8723D /* libPods-Status-StatusImPR.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 87038678EE47E8EF6E93EB54 /* libPods-Status-StatusImPR.a */; };
3870E1E692E24133A80B07DE /* Inter-SemiBold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 693A62DB37BC4CD5A30E5C96 /* Inter-SemiBold.otf */; };
393D26E3080B443A998F4A2F /* Inter-Italic.otf in Resources */ = {isa = PBXBuildFile; fileRef = B07176ACDAA1422E8F0A3D6B /* Inter-Italic.otf */; };
3A2626CF245C3F2200D5F94B /* Dummy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A2626CE245C3F2200D5F94B /* Dummy.swift */; };
@@ -37,7 +36,7 @@
3AAD2AD324A3A60E0075D594 /* Inter-SemiBold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 693A62DB37BC4CD5A30E5C96 /* Inter-SemiBold.otf */; };
3AAD2AD424A3A60E0075D594 /* Inter-SemiBoldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = A4F2BBE8D4DD4140A6CCAC39 /* Inter-SemiBoldItalic.otf */; };
3ABC7AF8245FF85900612C45 /* InterStatus-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 9C76AF5A418D4D65A4CAD1D9 /* InterStatus-Regular.otf */; };
536FC260A89500EC9FDB1585 /* libPods-Status-StatusIm-StatusImTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F311917BE57976CED3B9842 /* libPods-Status-StatusIm-StatusImTests.a */; };
42AC64E4D3CA4E676400C598 /* libPods-Status-StatusIm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D2D9E4943562065BF98E304 /* libPods-Status-StatusIm.a */; };
57C854A7993C47A3B1AECD32 /* Inter-MediumItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = C6B1215047604CD59A4C74D6 /* Inter-MediumItalic.otf */; };
65F6941925780A4F00A45E76 /* Bridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F6941825780A4F00A45E76 /* Bridge.swift */; };
65F6941A25780A4F00A45E76 /* Bridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F6941825780A4F00A45E76 /* Bridge.swift */; };
@@ -47,6 +46,7 @@
715D8133290BE850006F5C88 /* UbuntuMono-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 715D8131290BE850006F5C88 /* UbuntuMono-Regular.ttf */; };
74B758FC20D7C00B003343C3 /* launch-image-universal.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 74B758FB20D7C00B003343C3 /* launch-image-universal.storyboard */; };
8391E8E0E93C41A98AAA6631 /* Inter-SemiBoldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = A4F2BBE8D4DD4140A6CCAC39 /* Inter-SemiBoldItalic.otf */; };
8CF1CA9463A4048F97BABB82 /* libPods-Status-StatusIm-StatusImTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 466C47BA171B53CAE0AD6A19 /* libPods-Status-StatusIm-StatusImTests.a */; };
B24FC7FD1DE7195700D694FF /* Social.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B24FC7FC1DE7195700D694FF /* Social.framework */; };
B24FC7FF1DE7195F00D694FF /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B24FC7FE1DE7195F00D694FF /* MessageUI.framework */; };
B2F2D1BC1D9D531B00B7B453 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B2F2D1BB1D9D531B00B7B453 /* Images.xcassets */; };
@@ -61,8 +61,6 @@
D1786306E0184916B11F4C37 /* Inter-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = B2A38FC3D3954DE7B2B171F8 /* Inter-Medium.otf */; };
D84616FB563A48EBB1678699 /* Inter-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = CD4A2C27D6D5473184DC1F7E /* Inter-Bold.otf */; };
D99C50E5E18942A39C8DDF61 /* Inter-BoldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = B321D25F4493470980039457 /* Inter-BoldItalic.otf */; };
E9AC7FD92BB8FDAB0024A0AF /* HelloWorldJSI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E9AC7FD72BB8FDAB0024A0AF /* HelloWorldJSI.cpp */; };
E9AC7FDA2BB8FDAB0024A0AF /* HelloWorldJSI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E9AC7FD72BB8FDAB0024A0AF /* HelloWorldJSI.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -110,37 +108,39 @@
00E356EE1AD99517003FC87E /* StatusImTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StatusImTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
00E356F21AD99517003FC87E /* StatusImTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StatusImTests.m; sourceTree = "<group>"; };
0C331FD392B615DDAD0997F5 /* Pods-Status-StatusImPR.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusImPR.release.xcconfig"; path = "Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR.release.xcconfig"; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* StatusIm.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = StatusIm.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = StatusIm/AppDelegate.h; sourceTree = "<group>"; };
13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = StatusIm/AppDelegate.mm; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = StatusIm/Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = StatusIm/main.m; sourceTree = "<group>"; };
1426DF592BA248FC81D955CB /* Inter-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-Regular.otf"; path = "../resources/fonts/Inter-Regular.otf"; sourceTree = "<group>"; };
1E0A54C37353D912620563B4 /* Pods-Status-StatusIm.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm.release.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm.release.xcconfig"; sourceTree = "<group>"; };
1F311917BE57976CED3B9842 /* libPods-Status-StatusIm-StatusImTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusIm-StatusImTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
2756A97EBFF084FA94990AA5 /* Pods-Status-StatusIm-StatusImTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm-StatusImTests.release.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests.release.xcconfig"; sourceTree = "<group>"; };
2D2D9E4943562065BF98E304 /* libPods-Status-StatusIm.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusIm.a"; sourceTree = BUILT_PRODUCTS_DIR; };
3A2626CE245C3F2200D5F94B /* Dummy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dummy.swift; sourceTree = "<group>"; };
3A6406FB24A3ADF90046ED37 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
3A8F8EA924A4D31600BF206D /* GameKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameKit.framework; path = System/Library/Frameworks/GameKit.framework; sourceTree = SDKROOT; };
3AAD2ADC24A3A60E0075D594 /* Status PR.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Status PR.app"; sourceTree = BUILT_PRODUCTS_DIR; };
3AB1C3AD245C043900098F67 /* StatusIm-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "StatusIm-Bridging-Header.h"; sourceTree = "<group>"; };
466C47BA171B53CAE0AD6A19 /* libPods-Status-StatusIm-StatusImTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusIm-StatusImTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
4C16DE0B1F89508700AA10DB /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
4E586E1B0E544F64AA9F5BD1 /* libz.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
5AAC8D9B1AF8BB7C8AB89845 /* Pods-Status-StatusImPR.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusImPR.debug.xcconfig"; path = "Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR.debug.xcconfig"; sourceTree = "<group>"; };
65F693BD2578002500A45E76 /* CoreNFC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreNFC.framework; path = System/Library/Frameworks/CoreNFC.framework; sourceTree = SDKROOT; };
65F693BF2578003600A45E76 /* CoreNFC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreNFC.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk/System/iOSSupport/System/Library/Frameworks/CoreNFC.framework; sourceTree = DEVELOPER_DIR; };
65F6941725780A4E00A45E76 /* StatusImTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "StatusImTests-Bridging-Header.h"; sourceTree = "<group>"; };
65F6941825780A4F00A45E76 /* Bridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bridge.swift; sourceTree = "<group>"; };
680C14B0F642A5F544C397B7 /* Pods-Status-StatusIm.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm.debug.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm.debug.xcconfig"; sourceTree = "<group>"; };
693A62DB37BC4CD5A30E5C96 /* Inter-SemiBold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-SemiBold.otf"; path = "../resources/fonts/Inter-SemiBold.otf"; sourceTree = "<group>"; };
715D8131290BE850006F5C88 /* UbuntuMono-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "UbuntuMono-Regular.ttf"; path = "../resources/fonts/UbuntuMono-Regular.ttf"; sourceTree = "<group>"; };
74B758FB20D7C00B003343C3 /* launch-image-universal.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = "launch-image-universal.storyboard"; sourceTree = "<group>"; };
7625793B15B3B2A8E58F6277 /* Pods-Status-StatusIm-StatusImTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm-StatusImTests.release.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests.release.xcconfig"; sourceTree = "<group>"; };
79B38E3D4B033A711A7852FF /* Pods-Status-StatusImPR.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusImPR.release.xcconfig"; path = "Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR.release.xcconfig"; sourceTree = "<group>"; };
7AFB8653840373E5B625E16E /* libPods-Status-StatusIm.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusIm.a"; sourceTree = BUILT_PRODUCTS_DIR; };
7FA4F04CE45319370F87C4FD /* Pods-Status-StatusIm.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm.release.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm.release.xcconfig"; sourceTree = "<group>"; };
87038678EE47E8EF6E93EB54 /* libPods-Status-StatusImPR.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusImPR.a"; sourceTree = BUILT_PRODUCTS_DIR; };
8B9A886A2CB448B1ABA0EB62 /* libc++.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
922C4CA61F4D5F8B0033C753 /* StatusIm.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = StatusIm.entitlements; path = StatusIm/StatusIm.entitlements; sourceTree = "<group>"; };
9C76AF5A418D4D65A4CAD1D9 /* InterStatus-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "InterStatus-Regular.otf"; path = "../resources/fonts/InterStatus-Regular.otf"; sourceTree = "<group>"; };
9EC0135C1E06FB1900155B5C /* RCTWKWebView.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWKWebView.xcodeproj; path = "../node_modules/react-native-wkwebview-reborn/ios/RCTWKWebView.xcodeproj"; sourceTree = "<group>"; };
A4F2BBE8D4DD4140A6CCAC39 /* Inter-SemiBoldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-SemiBoldItalic.otf"; path = "../resources/fonts/Inter-SemiBoldItalic.otf"; sourceTree = "<group>"; };
AE3313A464E280B64599C3BA /* Pods-Status-StatusIm.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm.debug.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm.debug.xcconfig"; sourceTree = "<group>"; };
B07176ACDAA1422E8F0A3D6B /* Inter-Italic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-Italic.otf"; path = "../resources/fonts/Inter-Italic.otf"; sourceTree = "<group>"; };
B24FC7FC1DE7195700D694FF /* Social.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Social.framework; path = System/Library/Frameworks/Social.framework; sourceTree = SDKROOT; };
B24FC7FE1DE7195F00D694FF /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; };
@@ -150,14 +150,10 @@
C14C5F8C29C0A149005C58A7 /* launch-icon@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "launch-icon@3x.png"; path = "StatusIm/launch-icon@3x.png"; sourceTree = "<group>"; };
C14C5F9029C0AD9C005C58A7 /* launch-icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "launch-icon@2x.png"; path = "StatusIm/launch-icon@2x.png"; sourceTree = "<group>"; };
C14C5F9229C0ADB5005C58A7 /* launch-icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "launch-icon.png"; path = "StatusIm/launch-icon.png"; sourceTree = "<group>"; };
C5D722CC6309CA4C8BC48244 /* libPods-Status-StatusImPR.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusImPR.a"; sourceTree = BUILT_PRODUCTS_DIR; };
C6B1215047604CD59A4C74D6 /* Inter-MediumItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-MediumItalic.otf"; path = "../resources/fonts/Inter-MediumItalic.otf"; sourceTree = "<group>"; };
CA58075FD8E5F9A0CA74E512 /* Pods-Status-StatusImPR.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusImPR.debug.xcconfig"; path = "Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR.debug.xcconfig"; sourceTree = "<group>"; };
CD4A2C27D6D5473184DC1F7E /* Inter-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-Bold.otf"; path = "../resources/fonts/Inter-Bold.otf"; sourceTree = "<group>"; };
CE4E31B21D8695250033ED64 /* Statusgo.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Statusgo.xcframework; path = "../modules/react-native-status/ios/RCTStatus/Statusgo.xcframework"; sourceTree = "<group>"; };
D1CE733E3486B3A8B9185945 /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm-StatusImTests.debug.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests.debug.xcconfig"; sourceTree = "<group>"; };
E9AC7FD72BB8FDAB0024A0AF /* HelloWorldJSI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HelloWorldJSI.cpp; path = "../modules/react-native-status/jsi/HelloWorldJSI.cpp"; sourceTree = "<group>"; };
E9AC7FD82BB8FDAB0024A0AF /* HelloWorldJSI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HelloWorldJSI.h; path = "../modules/react-native-status/jsi/HelloWorldJSI.h"; sourceTree = "<group>"; };
D42A8AC52E48DA4C89F20C13 /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm-StatusImTests.debug.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -165,7 +161,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
536FC260A89500EC9FDB1585 /* libPods-Status-StatusIm-StatusImTests.a in Frameworks */,
8CF1CA9463A4048F97BABB82 /* libPods-Status-StatusIm-StatusImTests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -178,7 +174,7 @@
CE4E31B31D8695250033ED64 /* Statusgo.xcframework in Frameworks */,
25DC9C9DC25846BD8D084888 /* libc++.tbd in Frameworks */,
BA68A2377A20496EA737000D /* libz.tbd in Frameworks */,
17F5C611511E64ACE76B00A3 /* libPods-Status-StatusIm.a in Frameworks */,
42AC64E4D3CA4E676400C598 /* libPods-Status-StatusIm.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -192,7 +188,7 @@
3AAD2AC224A3A60E0075D594 /* Statusgo.xcframework in Frameworks */,
3AAD2AC524A3A60E0075D594 /* libc++.tbd in Frameworks */,
3AAD2AC624A3A60E0075D594 /* libz.tbd in Frameworks */,
061AC5E3D44813C6D987FC70 /* libPods-Status-StatusImPR.a in Frameworks */,
2B6F8F28B81E862D44C8723D /* libPods-Status-StatusImPR.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -272,8 +268,6 @@
83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup;
children = (
E9AC7FD72BB8FDAB0024A0AF /* HelloWorldJSI.cpp */,
E9AC7FD82BB8FDAB0024A0AF /* HelloWorldJSI.h */,
65F6941825780A4F00A45E76 /* Bridge.swift */,
3AAD2AB624A3A5F10075D594 /* StatusImPR */,
13B07FAE1A68108700A75B9A /* StatusIm */,
@@ -320,9 +314,9 @@
CE4E31B21D8695250033ED64 /* Statusgo.xcframework */,
8B9A886A2CB448B1ABA0EB62 /* libc++.tbd */,
4E586E1B0E544F64AA9F5BD1 /* libz.tbd */,
7AFB8653840373E5B625E16E /* libPods-Status-StatusIm.a */,
1F311917BE57976CED3B9842 /* libPods-Status-StatusIm-StatusImTests.a */,
C5D722CC6309CA4C8BC48244 /* libPods-Status-StatusImPR.a */,
2D2D9E4943562065BF98E304 /* libPods-Status-StatusIm.a */,
466C47BA171B53CAE0AD6A19 /* libPods-Status-StatusIm-StatusImTests.a */,
87038678EE47E8EF6E93EB54 /* libPods-Status-StatusImPR.a */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -330,12 +324,12 @@
D0D5C8D06825D33BA2D2121E /* Pods */ = {
isa = PBXGroup;
children = (
AE3313A464E280B64599C3BA /* Pods-Status-StatusIm.debug.xcconfig */,
1E0A54C37353D912620563B4 /* Pods-Status-StatusIm.release.xcconfig */,
D1CE733E3486B3A8B9185945 /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */,
7625793B15B3B2A8E58F6277 /* Pods-Status-StatusIm-StatusImTests.release.xcconfig */,
CA58075FD8E5F9A0CA74E512 /* Pods-Status-StatusImPR.debug.xcconfig */,
79B38E3D4B033A711A7852FF /* Pods-Status-StatusImPR.release.xcconfig */,
680C14B0F642A5F544C397B7 /* Pods-Status-StatusIm.debug.xcconfig */,
7FA4F04CE45319370F87C4FD /* Pods-Status-StatusIm.release.xcconfig */,
D42A8AC52E48DA4C89F20C13 /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */,
2756A97EBFF084FA94990AA5 /* Pods-Status-StatusIm-StatusImTests.release.xcconfig */,
5AAC8D9B1AF8BB7C8AB89845 /* Pods-Status-StatusImPR.debug.xcconfig */,
0C331FD392B615DDAD0997F5 /* Pods-Status-StatusImPR.release.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
@@ -347,11 +341,11 @@
isa = PBXNativeTarget;
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "StatusImTests" */;
buildPhases = (
8F717D50D3D590696A6046EB /* [CP] Check Pods Manifest.lock */,
99EA576680D5849CA4274106 /* [CP] Check Pods Manifest.lock */,
00E356EA1AD99517003FC87E /* Sources */,
00E356EB1AD99517003FC87E /* Frameworks */,
00E356EC1AD99517003FC87E /* Resources */,
1A83906735641F17B807EB39 /* [CP] Copy Pods Resources */,
835B3E5945D5F723935FD4E1 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -367,14 +361,14 @@
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "StatusIm" */;
buildPhases = (
FD7194DC9A3E5A5277869CFC /* [CP] Check Pods Manifest.lock */,
140572B0EA34D6F884AB6CC4 /* [CP] Check Pods Manifest.lock */,
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
20B6B6891D92C42700CC5C6A /* Embed Frameworks */,
E3914A731DF919ED00EBB515 /* Run Script */,
88DEE6D9CF4D6BA6F6D8DCB5 /* [CP] Copy Pods Resources */,
5BEC29A10D63DFF8AFF5B788 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -389,14 +383,14 @@
isa = PBXNativeTarget;
buildConfigurationList = 3AAD2AD924A3A60E0075D594 /* Build configuration list for PBXNativeTarget "StatusImPR" */;
buildPhases = (
4EE2E0EC4F119397E1A6B768 /* [CP] Check Pods Manifest.lock */,
78F85303177A5D4820A08DC1 /* [CP] Check Pods Manifest.lock */,
3AAD2ABB24A3A60E0075D594 /* Sources */,
3AAD2ABF24A3A60E0075D594 /* Frameworks */,
3AAD2AC924A3A60E0075D594 /* Resources */,
3AAD2AD524A3A60E0075D594 /* Bundle React Native code and images */,
3AAD2AD624A3A60E0075D594 /* Embed Frameworks */,
3AAD2AD724A3A60E0075D594 /* Run Script */,
1B5C687FDBFFB60FD1043432 /* [CP] Copy Pods Resources */,
776D3E96946780BFE216ACF2 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -548,81 +542,9 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = "/usr/bin/env sh";
shellScript = "set -o errexit\nexport NODE_BINARY=\"${NODE_BINARY:-node}\"\nexport NODE_ARGS=\"${NODE_ARGS:- --max-old-space-size=16384 }\"\n\nbash -x ../node_modules/react-native/scripts/react-native-xcode.sh > ../logs/react-native-xcode.log 2>&1";
shellScript = "set -o errexit\nexport NODE_BINARY=\"${NODE_BINARY:-node}\"\nexport NODE_ARGS=\"${NODE_ARGS:- --max-old-space-size=16384 }\"\n\n\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n";
};
1A83906735641F17B807EB39 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
1B5C687FDBFFB60FD1043432 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR-resources.sh\"\n";
showEnvVarsInLog = 0;
};
3AAD2AD524A3A60E0075D594 /* Bundle React Native code and images */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Bundle React Native code and images";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = "/usr/bin/env sh";
shellScript = "set -o errexit\nexport NODE_BINARY=\"${NODE_BINARY:-node}\"\nexport NODE_ARGS=\"${NODE_ARGS:- --max-old-space-size=16384 }\"\n\nbash -x ../node_modules/react-native/scripts/react-native-xcode.sh > ../logs/react-native-xcode.log 2>&1";
};
3AAD2AD724A3A60E0075D594 /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 8;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 1;
shellPath = "/usr/bin/env sh";
shellScript = "\"${PROJECT_DIR}/scripts/set_xcode_version.sh\" > ../logs/set_xcode_version.log 2>&1";
};
4EE2E0EC4F119397E1A6B768 /* [CP] Check Pods Manifest.lock */ = {
140572B0EA34D6F884AB6CC4 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -637,14 +559,42 @@
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Status-StatusImPR-checkManifestLockResult.txt",
"$(DERIVED_FILE_DIR)/Pods-Status-StatusIm-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
88DEE6D9CF4D6BA6F6D8DCB5 /* [CP] Copy Pods Resources */ = {
3AAD2AD524A3A60E0075D594 /* Bundle React Native code and images */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Bundle React Native code and images";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = "/usr/bin/env sh";
shellScript = "set -o errexit\nexport NODE_BINARY=\"${NODE_BINARY:-node}\"\nexport NODE_ARGS=\"${NODE_ARGS:- --max-old-space-size=16384 }\"\n\n\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n";
};
3AAD2AD724A3A60E0075D594 /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 8;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 1;
shellPath = "/usr/bin/env sh";
shellScript = "\"${PROJECT_DIR}/scripts/set_xcode_version.sh\" > ../logs/set_xcode_version.log 2>&1\n";
};
5BEC29A10D63DFF8AFF5B788 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -666,7 +616,73 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm-resources.sh\"\n";
showEnvVarsInLog = 0;
};
8F717D50D3D590696A6046EB /* [CP] Check Pods Manifest.lock */ = {
776D3E96946780BFE216ACF2 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR-resources.sh\"\n";
showEnvVarsInLog = 0;
};
78F85303177A5D4820A08DC1 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Status-StatusImPR-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
835B3E5945D5F723935FD4E1 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/TOCropViewController/TOCropViewControllerBundle.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TOCropViewControllerBundle.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
99EA576680D5849CA4274106 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -700,29 +716,7 @@
);
runOnlyForDeploymentPostprocessing = 1;
shellPath = "/usr/bin/env sh";
shellScript = "\"${PROJECT_DIR}/scripts/set_xcode_version.sh\" > ../logs/set_xcode_version.log 2>&1";
};
FD7194DC9A3E5A5277869CFC /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Status-StatusIm-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
shellScript = "\"${PROJECT_DIR}/scripts/set_xcode_version.sh\" > ../logs/set_xcode_version.log 2>&1\n";
};
/* End PBXShellScriptBuildPhase section */
@@ -743,7 +737,6 @@
65F6941925780A4F00A45E76 /* Bridge.swift in Sources */,
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */,
3A2626CF245C3F2200D5F94B /* Dummy.swift in Sources */,
E9AC7FD92BB8FDAB0024A0AF /* HelloWorldJSI.cpp in Sources */,
13B07FC11A68108700A75B9A /* main.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -755,7 +748,6 @@
65F6941B25780A4F00A45E76 /* Bridge.swift in Sources */,
3AAD2ABC24A3A60E0075D594 /* AppDelegate.mm in Sources */,
3AAD2ABD24A3A60E0075D594 /* Dummy.swift in Sources */,
E9AC7FDA2BB8FDAB0024A0AF /* HelloWorldJSI.cpp in Sources */,
3AAD2ABE24A3A60E0075D594 /* main.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -773,7 +765,7 @@
/* Begin XCBuildConfiguration section */
00E356F61AD99517003FC87E /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = D1CE733E3486B3A8B9185945 /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */;
baseConfigurationReference = D42A8AC52E48DA4C89F20C13 /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_ID_SUFFIX = .debug;
@@ -803,14 +795,14 @@
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "StatusImTests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 5.2;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StatusIm.app/StatusIm";
};
name = Debug;
};
00E356F71AD99517003FC87E /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7625793B15B3B2A8E58F6277 /* Pods-Status-StatusIm-StatusImTests.release.xcconfig */;
baseConfigurationReference = 2756A97EBFF084FA94990AA5 /* Pods-Status-StatusIm-StatusImTests.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_ID_SUFFIX = "";
@@ -836,14 +828,14 @@
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "StatusImTests-Bridging-Header.h";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 5.2;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StatusIm.app/StatusIm";
};
name = Release;
};
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = AE3313A464E280B64599C3BA /* Pods-Status-StatusIm.debug.xcconfig */;
baseConfigurationReference = 680C14B0F642A5F544C397B7 /* Pods-Status-StatusIm.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon$(BUNDLE_ID_SUFFIX)";
BUNDLE_ID_SUFFIX = .debug;
@@ -909,14 +901,14 @@
"$(inherited)",
"-lc++",
"-ObjC",
"-lresolv",
);
PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES;
PRODUCT_BUNDLE_IDENTIFIER = im.status.ethereum;
PRODUCT_NAME = StatusIm;
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "StatusIm-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 5.2;
TARGETED_DEVICE_FAMILY = 1;
VALID_ARCHS = "x86_64 arm64";
"VALID_ARCHS[sdk=iphonesimulator*]" = "x86_64 ";
@@ -925,7 +917,7 @@
};
13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 1E0A54C37353D912620563B4 /* Pods-Status-StatusIm.release.xcconfig */;
baseConfigurationReference = 7FA4F04CE45319370F87C4FD /* Pods-Status-StatusIm.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon$(BUNDLE_ID_SUFFIX)";
BUNDLE_ID_SUFFIX = "";
@@ -985,14 +977,14 @@
"$(inherited)",
"-lc++",
"-ObjC",
"-lresolv",
);
PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES;
PRODUCT_BUNDLE_IDENTIFIER = im.status.ethereum;
PRODUCT_NAME = StatusIm;
PROVISIONING_PROFILE = "e2202b12-7a66-4ff7-af3c-a52e35f32dc1";
PROVISIONING_PROFILE_SPECIFIER = "match AdHoc im.status.ethereum";
SWIFT_OBJC_BRIDGING_HEADER = "StatusIm-Bridging-Header.h";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 5.2;
TARGETED_DEVICE_FAMILY = 1;
VALID_ARCHS = arm64;
};
@@ -1000,7 +992,7 @@
};
3AAD2ADA24A3A60E0075D594 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = CA58075FD8E5F9A0CA74E512 /* Pods-Status-StatusImPR.debug.xcconfig */;
baseConfigurationReference = 5AAC8D9B1AF8BB7C8AB89845 /* Pods-Status-StatusImPR.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon$(BUNDLE_ID_SUFFIX)";
BUNDLE_ID_SUFFIX = .debug;
@@ -1065,13 +1057,14 @@
"$(inherited)",
"-lc++",
"-ObjC",
"-lresolv",
);
PRODUCT_BUNDLE_IDENTIFIER = im.status.ethereum.pr;
PRODUCT_NAME = "Status PR";
PROVISIONING_PROFILE_SPECIFIER = "match Development im.status.ethereum.pr";
SWIFT_OBJC_BRIDGING_HEADER = "StatusIm-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 5.2;
TARGETED_DEVICE_FAMILY = 1;
VALID_ARCHS = arm64;
};
@@ -1079,7 +1072,7 @@
};
3AAD2ADB24A3A60E0075D594 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 79B38E3D4B033A711A7852FF /* Pods-Status-StatusImPR.release.xcconfig */;
baseConfigurationReference = 0C331FD392B615DDAD0997F5 /* Pods-Status-StatusImPR.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIconPR$(BUNDLE_ID_SUFFIX)";
BUNDLE_ID_SUFFIX = "";
@@ -1138,12 +1131,13 @@
"$(inherited)",
"-lc++",
"-ObjC",
"-lresolv",
);
PRODUCT_BUNDLE_IDENTIFIER = im.status.ethereum.pr;
PRODUCT_NAME = "Status PR";
PROVISIONING_PROFILE_SPECIFIER = "match AdHoc im.status.ethereum.pr";
SWIFT_OBJC_BRIDGING_HEADER = "StatusIm-Bridging-Header.h";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 5.2;
TARGETED_DEVICE_FAMILY = 1;
VALID_ARCHS = arm64;
};
@@ -1182,6 +1176,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
COPY_PHASE_STRIP = NO;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 8B5X2M6H2Y;
ENABLE_BITCODE = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
@@ -1236,7 +1231,6 @@
"-DFOLLY_CFG_NO_COROUTINES=1",
);
OTHER_LDFLAGS = "$(inherited)";
PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES;
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
USE_HERMES = false;
@@ -1278,6 +1272,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
COPY_PHASE_STRIP = YES;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 8B5X2M6H2Y;
ENABLE_BITCODE = NO;
ENABLE_NS_ASSERTIONS = NO;
@@ -1323,7 +1318,6 @@
"-DFOLLY_CFG_NO_COROUTINES=1",
);
OTHER_LDFLAGS = "$(inherited)";
PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES;
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
USE_HERMES = false;
-11
View File
@@ -73,17 +73,6 @@ extern "C" NSString* StatusgoImageServerTLSCert();
[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
[RNSplashScreen show];
RCTCxxBridge *bridge = (RCTCxxBridge *)[[_bridge batchedBridge] valueForKey:@"_batchedBridge"];
facebook::react::RCTJSIExecutorFactory *executorFactory = [bridge jsExecutorFactoryForBridge:bridge];
if (executorFactory) {
bridge.jsiExecutorFactory = ^{
facebook::jsi::Runtime *runtime = executorFactory();
HelloWorldJSI::install(*runtime);
return runtime;
};
}
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
+3 -1
View File
@@ -22,6 +22,8 @@ This directory is the destination of logs created during build time of debug bui
These log files are uploaded to Jenkins as CI job artifacts on failure using `archiveArtifacts`.
* `react-native-xcode.log` - Output from `node_modules/react-native/scripts/react-native-xcode.sh`.
- Created by redirecting output of `shellScript` in `ios/StatusIm.xcodeproj/project.pbxproj`.
- Created by redirecting output of `shellScript` in `ios/StatusIm.xcodeproj/project.pbxproj` for "Bundle React Native code and images" build Phase.
* `set_xcode_version.log` - Output from `node_modules/react-native/scripts/react-native-xcode.sh`.
- Created by redirecting output of `shellScript` in `ios/StatusIm.xcodeproj/project.pbxproj` for "Run Script" build Phase.
* `Status PR-StatusImPR.log - Created by [Fastlane Gym](https://docs.fastlane.tools/actions/gym/).
- Configred via [`Fastfile`](../Fastfile) using `buildlog_path` argument for `build_ios_app`.
@@ -1,355 +0,0 @@
package im.status.ethereum.module;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import statusgo.Statusgo;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import org.json.JSONObject;
import org.json.JSONException;
import android.util.Log;
import android.content.Context;
import android.app.Activity;
public class AccountManager extends ReactContextBaseJavaModule {
private static final String TAG = "AccountManager";
private static final String gethLogFileName = "geth.log";
private ReactApplicationContext reactContext;
private Utils utils;
private LogManager logManager;
public AccountManager(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
this.utils = new Utils(reactContext);
this.logManager = new LogManager(reactContext);
}
@Override
public String getName() {
return "AccountManager";
}
private String getTestnetDataDir(final String absRootDirPath) {
return this.utils.pathCombine(absRootDirPath, "ethereum/testnet");
}
@ReactMethod
public void createAccountAndLogin(final String createAccountRequest) {
Log.d(TAG, "createAccountAndLogin");
String result = Statusgo.createAccountAndLogin(createAccountRequest);
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "createAccountAndLogin success: " + result);
Log.d(TAG, "Geth node started");
} else {
Log.e(TAG, "createAccountAndLogin failed: " + result);
}
}
@ReactMethod
public void restoreAccountAndLogin(final String restoreAccountRequest) {
Log.d(TAG, "restoreAccountAndLogin");
String result = Statusgo.restoreAccountAndLogin(restoreAccountRequest);
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "restoreAccountAndLogin success: " + result);
Log.d(TAG, "Geth node started");
} else {
Log.e(TAG, "restoreAccountAndLogin failed: " + result);
}
}
private String updateConfig(final String jsonConfigString, final String absRootDirPath, final String keystoreDirPath) throws JSONException {
final JSONObject jsonConfig = new JSONObject(jsonConfigString);
// retrieve parameters from app config, that will be applied onto the Go-side config later on
final String dataDirPath = jsonConfig.getString("DataDir");
final Boolean logEnabled = jsonConfig.getBoolean("LogEnabled");
final Context context = this.getReactApplicationContext();
final File gethLogFile = logEnabled ? this.logManager.prepareLogsFile(context) : null;
String gethLogDirPath = null;
if (gethLogFile != null) {
gethLogDirPath = gethLogFile.getParent();
}
Log.d(TAG, "log dir: " + gethLogDirPath + " log name: " + gethLogFileName);
jsonConfig.put("DataDir", dataDirPath);
jsonConfig.put("KeyStoreDir", keystoreDirPath);
jsonConfig.put("LogDir", gethLogDirPath);
jsonConfig.put("LogFile", gethLogFileName);
return jsonConfig.toString();
}
private static void prettyPrintConfig(final String config) {
Log.d(TAG, "startNode() with config (see below)");
String configOutput = config;
final int maxOutputLen = 4000;
Log.d(TAG, "********************** NODE CONFIG ****************************");
while (!configOutput.isEmpty()) {
Log.d(TAG, "Node config:" + configOutput.substring(0, Math.min(maxOutputLen, configOutput.length())));
if (configOutput.length() > maxOutputLen) {
configOutput = configOutput.substring(maxOutputLen);
} else {
break;
}
}
Log.d(TAG, "******************* ENDOF NODE CONFIG *************************");
}
private void copyDirectory(File sourceLocation, File targetLocation) throws IOException {
if (sourceLocation.isDirectory()) {
if (!targetLocation.exists() && !targetLocation.mkdirs()) {
throw new IOException("Cannot create dir " + targetLocation.getAbsolutePath());
}
String[] children = sourceLocation.list();
for (int i = 0; i < children.length; i++) {
copyDirectory(new File(sourceLocation, children[i]), new File(targetLocation, children[i]));
}
} else {
File directory = targetLocation.getParentFile();
if (directory != null && !directory.exists() && !directory.mkdirs()) {
throw new IOException("Cannot create dir " + directory.getAbsolutePath());
}
InputStream in = new FileInputStream(sourceLocation);
OutputStream out = new FileOutputStream(targetLocation);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
}
private String prepareDirAndUpdateConfig(final String jsonConfigString, final String keyUID) {
final String absRootDirPath = this.utils.getNoBackupDirectory();
final String dataFolder = this.getTestnetDataDir(absRootDirPath);
Log.d(TAG, "Starting Geth node in folder: " + dataFolder);
try {
final File newFile = new File(dataFolder);
// todo handle error?
newFile.mkdir();
} catch (Exception e) {
Log.e(TAG, "error making folder: " + dataFolder, e);
}
final String ropstenFlagPath = this.utils.pathCombine(absRootDirPath, "ropsten_flag");
final File ropstenFlag = new File(ropstenFlagPath);
if (!ropstenFlag.exists()) {
try {
final String chaindDataFolderPath = this.utils.pathCombine(dataFolder, "StatusIM/lightchaindata");
final File lightChainFolder = new File(chaindDataFolderPath);
if (lightChainFolder.isDirectory()) {
String[] children = lightChainFolder.list();
for (int i = 0; i < children.length; i++) {
new File(lightChainFolder, children[i]).delete();
}
}
lightChainFolder.delete();
ropstenFlag.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
String testnetDataDir = dataFolder;
String oldKeystoreDir = this.utils.pathCombine(testnetDataDir, "keystore");
String newKeystoreDir = this.utils.pathCombine(absRootDirPath, "keystore");
final File oldKeystore = new File(oldKeystoreDir);
if (oldKeystore.exists()) {
try {
final File newKeystore = new File(newKeystoreDir);
copyDirectory(oldKeystore, newKeystore);
if (oldKeystore.isDirectory()) {
String[] children = oldKeystore.list();
for (int i = 0; i < children.length; i++) {
new File(oldKeystoreDir, children[i]).delete();
}
}
oldKeystore.delete();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
final String multiaccountKeystoreDir = this.utils.pathCombine("/keystore", keyUID);
final String updatedJsonConfigString = this.updateConfig(jsonConfigString, absRootDirPath, multiaccountKeystoreDir);
prettyPrintConfig(updatedJsonConfigString);
return updatedJsonConfigString;
} catch (JSONException e) {
Log.e(TAG, "updateConfig failed: " + e.getMessage());
System.exit(1);
return "";
}
}
@ReactMethod
public void prepareDirAndUpdateConfig(final String keyUID, final String config, final Callback callback) {
Log.d(TAG, "prepareDirAndUpdateConfig");
String finalConfig = prepareDirAndUpdateConfig(config, keyUID);
callback.invoke(finalConfig);
}
@ReactMethod
public void saveAccountAndLoginWithKeycard(final String multiaccountData, final String password, final String settings, final String config, final String accountsData, final String chatKey) {
try {
Log.d(TAG, "saveAccountAndLoginWithKeycard");
String finalConfig = prepareDirAndUpdateConfig(config, this.utils.getKeyUID(multiaccountData));
String result = Statusgo.saveAccountAndLoginWithKeycard(multiaccountData, password, settings, finalConfig, accountsData, chatKey);
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "saveAccountAndLoginWithKeycard result: " + result);
Log.d(TAG, "Geth node started");
} else {
Log.e(TAG, "saveAccountAndLoginWithKeycard failed: " + result);
}
} catch (JSONException e) {
Log.e(TAG, "JSON conversion failed: " + e.getMessage());
}
}
@ReactMethod
public void loginWithKeycard(final String accountData, final String password, final String chatKey, final String nodeConfigJSON) {
Log.d(TAG, "loginWithKeycard");
this.utils.migrateKeyStoreDir(accountData, password);
String result = Statusgo.loginWithKeycard(accountData, password, chatKey, nodeConfigJSON);
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "LoginWithKeycard result: " + result);
} else {
Log.e(TAG, "LoginWithKeycard failed: " + result);
}
}
@ReactMethod
public void loginWithConfig(final String accountData, final String password, final String configJSON) {
Log.d(TAG, "loginWithConfig");
this.utils.migrateKeyStoreDir(accountData, password);
String result = Statusgo.loginWithConfig(accountData, password, configJSON);
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "LoginWithConfig result: " + result);
} else {
Log.e(TAG, "LoginWithConfig failed: " + result);
}
}
@ReactMethod
public void loginAccount(final String request) {
Log.d(TAG, "loginAccount");
String result = Statusgo.loginAccount(request);
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "loginAccount result: " + result);
} else {
Log.e(TAG, "loginAccount failed: " + result);
}
}
@ReactMethod
public void verify(final String address, final String password, final Callback callback) throws JSONException {
Activity currentActivity = getCurrentActivity();
final String absRootDirPath = this.utils.getNoBackupDirectory();
final String newKeystoreDir = this.utils.pathCombine(absRootDirPath, "keystore");
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.verifyAccountPassword(newKeystoreDir, address, password), callback);
}
@ReactMethod
public void verifyDatabasePassword(final String keyUID, final String password, final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.verifyDatabasePassword(keyUID, password), callback);
}
@ReactMethod
private void openAccounts(final Callback callback) throws JSONException {
Log.d(TAG, "openAccounts");
final String rootDir = this.utils.getNoBackupDirectory();
Log.d(TAG, "[Opening accounts" + rootDir);
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.openAccounts(rootDir), callback);
}
//TODO : refactor logout usage to accept callback so that we can do this.utils.executeRunnableStatusGoMethod
@ReactMethod
public void logout() {
Log.d(TAG, "logout");
Runnable r = new Runnable() {
@Override
public void run() {
String result = Statusgo.logout();
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "Logout result: " + result);
} else {
Log.e(TAG, "Logout failed: " + result);
}
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void multiAccountStoreAccount(final String json, final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.multiAccountStoreAccount(json), callback);
}
@ReactMethod
public void multiAccountLoadAccount(final String json, final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.multiAccountLoadAccount(json), callback);
}
@ReactMethod
public void multiAccountDeriveAddresses(final String json, final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.multiAccountDeriveAddresses(json), callback);
}
@ReactMethod
public void multiAccountGenerateAndDeriveAddresses(final String json, final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.multiAccountGenerateAndDeriveAddresses(json), callback);
}
@ReactMethod
public void multiAccountStoreDerived(final String json, final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.multiAccountStoreDerivedAccounts(json), callback);
}
@ReactMethod
public void multiAccountImportMnemonic(final String json, final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.multiAccountImportMnemonic(json), callback);
}
@ReactMethod
public void multiAccountImportPrivateKey(final String json, final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.multiAccountImportPrivateKey(json), callback);
}
@ReactMethod
public void deleteMultiaccount(final String keyUID, final Callback callback) throws JSONException {
final String keyStoreDir = this.utils.getKeyStorePath(keyUID);
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.deleteMultiaccount(keyUID, keyStoreDir), callback);
}
@ReactMethod
public void getRandomMnemonic(final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.getRandomMnemonic(), callback);
}
@ReactMethod
public void createAccountFromMnemonicAndDeriveAccountsForPaths(final String mnemonic, final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.createAccountFromMnemonicAndDeriveAccountsForPaths(mnemonic), callback);
}
}
@@ -0,0 +1,333 @@
package im.status.ethereum.module
import android.app.Activity
import android.content.Context
import android.util.Log
import com.facebook.react.bridge.Callback
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import org.json.JSONException
import org.json.JSONObject
import statusgo.Statusgo
import java.io.*
class AccountManager(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
private val utils = Utils(reactContext)
private val logManager = LogManager(reactContext)
override fun getName() = "AccountManager"
private fun getTestnetDataDir(absRootDirPath: String) = utils.pathCombine(absRootDirPath, "ethereum/testnet")
@ReactMethod
fun createAccountAndLogin(createAccountRequest: String) {
Log.d(TAG, "createAccountAndLogin")
val result = Statusgo.createAccountAndLogin(createAccountRequest)
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "createAccountAndLogin success: $result")
Log.d(TAG, "Geth node started")
} else {
Log.e(TAG, "createAccountAndLogin failed: $result")
}
}
@ReactMethod
fun restoreAccountAndLogin(restoreAccountRequest: String) {
Log.d(TAG, "restoreAccountAndLogin")
val result = Statusgo.restoreAccountAndLogin(restoreAccountRequest)
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "restoreAccountAndLogin success: $result")
Log.d(TAG, "Geth node started")
} else {
Log.e(TAG, "restoreAccountAndLogin failed: $result")
}
}
private fun updateConfig(jsonConfigString: String, absRootDirPath: String, keystoreDirPath: String): String {
val jsonConfig = JSONObject(jsonConfigString)
val dataDirPath = jsonConfig.getString("DataDir")
val logEnabled = jsonConfig.getBoolean("LogEnabled")
val gethLogFile = if (logEnabled) logManager.prepareLogsFile(reactContext) else null
val gethLogDirPath = gethLogFile?.parent
Log.d(TAG, "log dir: $gethLogDirPath log name: $gethLogFileName")
jsonConfig.put("DataDir", dataDirPath)
jsonConfig.put("KeyStoreDir", keystoreDirPath)
jsonConfig.put("LogDir", gethLogDirPath)
jsonConfig.put("LogFile", gethLogFileName)
return jsonConfig.toString()
}
private fun copyDirectory(sourceLocation: File, targetLocation: File) {
if (sourceLocation.isDirectory) {
if (!targetLocation.exists() && !targetLocation.mkdirs()) {
throw IOException("Cannot create dir ${targetLocation.absolutePath}")
}
val children = sourceLocation.list()
children?.forEach { child ->
copyDirectory(File(sourceLocation, child), File(targetLocation, child))
}
} else {
val directory = targetLocation.parentFile
if (directory != null && !directory.exists() && !directory.mkdirs()) {
throw IOException("Cannot create dir ${directory.absolutePath}")
}
sourceLocation.inputStream().use { input ->
targetLocation.outputStream().use { output ->
input.copyTo(output)
}
}
}
}
private fun prepareDirAndUpdateConfig(jsonConfigString: String, keyUID: String): String {
val absRootDirPath = utils.getNoBackupDirectory()
val dataFolder = getTestnetDataDir(absRootDirPath)
Log.d(TAG, "Starting Geth node in folder: $dataFolder")
try {
File(dataFolder).mkdir()
} catch (e: Exception) {
Log.e(TAG, "error making folder: $dataFolder", e)
}
val ropstenFlagPath = utils.pathCombine(absRootDirPath, "ropsten_flag")
val ropstenFlag = File(ropstenFlagPath)
if (!ropstenFlag.exists()) {
try {
val chaindDataFolderPath = utils.pathCombine(dataFolder, "StatusIM/lightchaindata")
val lightChainFolder = File(chaindDataFolderPath)
if (lightChainFolder.isDirectory) {
lightChainFolder.listFiles()?.forEach { it.delete() }
}
lightChainFolder.delete()
ropstenFlag.createNewFile()
} catch (e: IOException) {
e.printStackTrace()
}
}
val testnetDataDir = dataFolder
val oldKeystoreDir = utils.pathCombine(testnetDataDir, "keystore")
val newKeystoreDir = utils.pathCombine(absRootDirPath, "keystore")
val oldKeystore = File(oldKeystoreDir)
if (oldKeystore.exists()) {
try {
val newKeystore = File(newKeystoreDir)
copyDirectory(oldKeystore, newKeystore)
if (oldKeystore.isDirectory) {
oldKeystore.listFiles()?.forEach { it.delete() }
}
oldKeystore.delete()
} catch (e: IOException) {
e.printStackTrace()
}
}
return try {
val multiaccountKeystoreDir = utils.pathCombine("/keystore", keyUID)
val updatedJsonConfigString = updateConfig(jsonConfigString, absRootDirPath, multiaccountKeystoreDir)
prettyPrintConfig(updatedJsonConfigString)
updatedJsonConfigString
} catch (e: JSONException) {
Log.e(TAG, "updateConfig failed: ${e.message}")
System.exit(1)
""
}
}
@ReactMethod
fun prepareDirAndUpdateConfig(keyUID: String, config: String, callback: Callback) {
Log.d(TAG, "prepareDirAndUpdateConfig")
val finalConfig = prepareDirAndUpdateConfig(config, keyUID)
callback.invoke(finalConfig)
}
@ReactMethod
fun saveAccountAndLoginWithKeycard(
multiaccountData: String,
password: String,
settings: String,
config: String,
accountsData: String,
chatKey: String
) {
try {
Log.d(TAG, "saveAccountAndLoginWithKeycard")
val keyUID = utils.getKeyUID(multiaccountData)
val finalConfig = prepareDirAndUpdateConfig(config, keyUID)
val result = Statusgo.saveAccountAndLoginWithKeycard(
multiaccountData,
password,
settings,
finalConfig,
accountsData,
chatKey
)
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "saveAccountAndLoginWithKeycard result: $result")
Log.d(TAG, "Geth node started")
} else {
Log.e(TAG, "saveAccountAndLoginWithKeycard failed: $result")
}
} catch (e: JSONException) {
Log.e(TAG, "JSON conversion failed: ${e.message}")
}
}
@ReactMethod
fun loginWithKeycard(accountData: String, password: String, chatKey: String, nodeConfigJSON: String) {
Log.d(TAG, "loginWithKeycard")
utils.migrateKeyStoreDir(accountData, password)
val result = Statusgo.loginWithKeycard(accountData, password, chatKey, nodeConfigJSON)
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "LoginWithKeycard result: $result")
} else {
Log.e(TAG, "LoginWithKeycard failed: $result")
}
}
@ReactMethod
fun loginWithConfig(accountData: String, password: String, configJSON: String) {
Log.d(TAG, "loginWithConfig")
utils.migrateKeyStoreDir(accountData, password)
val result = Statusgo.loginWithConfig(accountData, password, configJSON)
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "LoginWithConfig result: $result")
} else {
Log.e(TAG, "LoginWithConfig failed: $result")
}
}
@ReactMethod
fun loginAccount(request: String) {
Log.d(TAG, "loginAccount")
val result = Statusgo.loginAccount(request)
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "loginAccount result: $result")
} else {
Log.e(TAG, "loginAccount failed: $result")
}
}
@ReactMethod
fun verify(address: String, password: String, callback: Callback) {
val absRootDirPath = utils.getNoBackupDirectory()
val newKeystoreDir = utils.pathCombine(absRootDirPath, "keystore")
utils.executeRunnableStatusGoMethod(
{ Statusgo.verifyAccountPassword(newKeystoreDir, address, password) },
callback
)
}
@ReactMethod
fun verifyDatabasePassword(keyUID: String, password: String, callback: Callback) {
utils.executeRunnableStatusGoMethod(
{ Statusgo.verifyDatabasePassword(keyUID, password) },
callback
)
}
@ReactMethod
private fun openAccounts(callback: Callback) {
Log.d(TAG, "openAccounts")
val rootDir = utils.getNoBackupDirectory()
Log.d(TAG, "[Opening accounts $rootDir")
utils.executeRunnableStatusGoMethod({ Statusgo.openAccounts(rootDir) }, callback)
}
@ReactMethod
fun logout() {
Log.d(TAG, "logout")
val runnable = Runnable {
val result = Statusgo.logout()
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "Logout result: $result")
} else {
Log.e(TAG, "Logout failed: $result")
}
}
StatusThreadPoolExecutor.getInstance().execute(runnable)
}
@ReactMethod
fun multiAccountStoreAccount(json: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.multiAccountStoreAccount(json) }, callback)
}
@ReactMethod
fun multiAccountLoadAccount(json: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.multiAccountLoadAccount(json) }, callback)
}
@ReactMethod
fun multiAccountDeriveAddresses(json: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.multiAccountDeriveAddresses(json) }, callback)
}
@ReactMethod
fun multiAccountGenerateAndDeriveAddresses(json: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.multiAccountGenerateAndDeriveAddresses(json) }, callback)
}
@ReactMethod
fun multiAccountStoreDerived(json: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.multiAccountStoreDerivedAccounts(json) }, callback)
}
@ReactMethod
fun multiAccountImportMnemonic(json: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.multiAccountImportMnemonic(json) }, callback)
}
@ReactMethod
fun multiAccountImportPrivateKey(json: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.multiAccountImportPrivateKey(json) }, callback)
}
@ReactMethod
fun deleteMultiaccount(keyUID: String, callback: Callback) {
val keyStoreDir = utils.getKeyStorePath(keyUID)
utils.executeRunnableStatusGoMethod({ Statusgo.deleteMultiaccount(keyUID, keyStoreDir) }, callback)
}
@ReactMethod
fun getRandomMnemonic(callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.getRandomMnemonic() }, callback)
}
@ReactMethod
fun createAccountFromMnemonicAndDeriveAccountsForPaths(mnemonic: String, callback: Callback) {
utils.executeRunnableStatusGoMethod(
{ Statusgo.createAccountFromMnemonicAndDeriveAccountsForPaths(mnemonic) },
callback
)
}
companion object {
private const val TAG = "AccountManager"
private const val gethLogFileName = "geth.log"
private fun prettyPrintConfig(config: String) {
Log.d(TAG, "startNode() with config (see below)")
var configOutput = config
val maxOutputLen = 4000
Log.d(TAG, "********************** NODE CONFIG ****************************")
while (configOutput.isNotEmpty()) {
Log.d(TAG, "Node config:${configOutput.take(maxOutputLen)}")
configOutput = configOutput.drop(maxOutputLen)
}
Log.d(TAG, "******************* ENDOF NODE CONFIG *************************")
}
}
}
@@ -1,66 +0,0 @@
package im.status.ethereum.module;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
import statusgo.Statusgo;
import android.util.Log;
import java.io.File;
import android.os.Environment;
import android.content.Context;
public class DatabaseManager extends ReactContextBaseJavaModule {
private static final String TAG = "DatabaseManager";
private ReactApplicationContext reactContext;
private static final String exportDBFileName = "export.db";
private Utils utils;
public DatabaseManager(ReactApplicationContext reactContext) {
this.reactContext = reactContext;
this.utils = new Utils(reactContext);
}
@Override
public String getName() {
return "DatabaseManager";
}
private File getExportDBFile() {
final Context context = this.getReactApplicationContext();
// Environment.getExternalStoragePublicDirectory doesn't work as expected on Android Q
// https://developer.android.com/reference/android/os/Environment#getExternalStoragePublicDirectory(java.lang.String)
final File pubDirectory = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
final File filename = new File(pubDirectory, exportDBFileName);
return filename;
}
@ReactMethod
public void exportUnencryptedDatabase(final String accountData, final String password, final Callback callback) {
Log.d(TAG, "login");
final File newFile = getExportDBFile();
this.utils.migrateKeyStoreDir(accountData, password);
String result = Statusgo.exportUnencryptedDatabase(accountData, password, newFile.getAbsolutePath());
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "Login result: " + result);
} else {
Log.e(TAG, "Login failed: " + result);
}
}
@ReactMethod
public void importUnencryptedDatabase(final String accountData, final String password) {
Log.d(TAG, "importUnencryptedDatabase");
final File newFile = getExportDBFile();
this.utils.migrateKeyStoreDir(accountData, password);
String result = Statusgo.importUnencryptedDatabase(accountData, password, newFile.getAbsolutePath());
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "import result: " + result);
} else {
Log.e(TAG, "import failed: " + result);
}
}
}
@@ -0,0 +1,58 @@
package im.status.ethereum.module
import android.content.Context
import android.os.Environment
import android.util.Log
import com.facebook.react.bridge.Callback
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import statusgo.Statusgo
import java.io.File
class DatabaseManager(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
private val utils = Utils(reactContext)
override fun getName() = "DatabaseManager"
private fun getExportDBFile(): File {
val pubDirectory = reactContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
return File(pubDirectory, exportDBFileName)
}
@ReactMethod
fun exportUnencryptedDatabase(accountData: String, password: String, callback: Callback) {
Log.d(TAG, "login")
val newFile = getExportDBFile()
utils.migrateKeyStoreDir(accountData, password)
val result = Statusgo.exportUnencryptedDatabase(accountData, password, newFile.absolutePath)
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "Login result: $result")
} else {
Log.e(TAG, "Login failed: $result")
}
}
@ReactMethod
fun importUnencryptedDatabase(accountData: String, password: String) {
Log.d(TAG, "importUnencryptedDatabase")
val newFile = getExportDBFile()
utils.migrateKeyStoreDir(accountData, password)
val result = Statusgo.importUnencryptedDatabase(accountData, password, newFile.absolutePath)
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "import result: $result")
} else {
Log.e(TAG, "import failed: $result")
}
}
companion object {
private const val TAG = "DatabaseManager"
private const val exportDBFileName = "export.db"
}
}
@@ -1,227 +0,0 @@
package im.status.ethereum.module;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.Callback;
import java.io.File;
import java.util.Stack;
import android.util.Log;
import android.net.Uri;
import java.io.OutputStreamWriter;
import java.io.IOException;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import androidx.core.content.FileProvider;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipOutputStream;
import java.io.FileInputStream;
import java.util.zip.ZipEntry;
import org.json.JSONObject;
import statusgo.Statusgo;
import android.content.Context;
import org.json.JSONException;
public class LogManager extends ReactContextBaseJavaModule {
private static final String TAG = "LogManager";
private static final String gethLogFileName = "geth.log";
private static final String statusLogFileName = "Status.log";
private static final String logsZipFileName = "Status-debug-logs.zip";
private ReactApplicationContext reactContext;
private Utils utils;
public LogManager(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
this.utils = new Utils(reactContext);
}
@Override
public String getName() {
return "LogManager";
}
private File getLogsFile() {
final File pubDirectory = this.utils.getPublicStorageDirectory();
final File logFile = new File(pubDirectory, gethLogFileName);
return logFile;
}
public File prepareLogsFile(final Context context) {
final File logFile = this.utils.getLogsFile();
try {
logFile.setReadable(true);
File parent = logFile.getParentFile();
if (!parent.canWrite()) {
return null;
}
if (!parent.exists()) {
parent.mkdirs();
}
logFile.createNewFile();
logFile.setWritable(true);
Log.d(TAG, "Can write " + logFile.canWrite());
Uri gethLogUri = Uri.fromFile(logFile);
String gethLogFilePath = logFile.getAbsolutePath();
Log.d(TAG, gethLogFilePath);
return logFile;
} catch (Exception e) {
Log.d(TAG, "Can't create geth.log file! " + e.getMessage());
}
return null;
}
private void showErrorMessage(final String message) {
final Activity activity = getCurrentActivity();
new AlertDialog.Builder(activity)
.setTitle("Error")
.setMessage(message)
.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, final int id) {
dialog.dismiss();
}
}).show();
}
private void dumpAdbLogsTo(final FileOutputStream statusLogStream) throws IOException {
final String filter = "logcat -d -b main ReactNativeJS:D StatusModule:D StatusService:D StatusNativeLogs:D *:S";
final java.lang.Process p = Runtime.getRuntime().exec(filter);
final java.io.BufferedReader in = new java.io.BufferedReader(new java.io.InputStreamReader(p.getInputStream()));
final java.io.BufferedWriter out = new java.io.BufferedWriter(new java.io.OutputStreamWriter(statusLogStream));
String line;
while ((line = in.readLine()) != null) {
out.write(line);
out.newLine();
}
out.close();
in.close();
}
private Boolean zip(File[] _files, File zipFile, Stack<String> errorList) {
final int BUFFER = 0x8000;
try {
BufferedInputStream origin = null;
FileOutputStream dest = new FileOutputStream(zipFile);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
byte data[] = new byte[BUFFER];
for (int i = 0; i < _files.length; i++) {
final File file = _files[i];
if (file == null || !file.exists()) {
continue;
}
Log.v("Compress", "Adding: " + file.getAbsolutePath());
try {
FileInputStream fi = new FileInputStream(file);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(file.getName());
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
errorList.push(e.getMessage());
}
}
out.close();
return true;
} catch (Exception e) {
Log.e(TAG, e.getMessage());
e.printStackTrace();
return false;
}
}
@ReactMethod
public void sendLogs(final String dbJson, final String jsLogs, final Callback callback) {
Log.d(TAG, "sendLogs");
if (!this.utils.checkAvailability()) {
return;
}
final Context context = this.getReactApplicationContext();
final File logsTempDir = new File(context.getCacheDir(), "logs"); // This path needs to be in sync with android/app/src/main/res/xml/file_provider_paths.xml
logsTempDir.mkdir();
final File dbFile = new File(logsTempDir, "db.json");
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(dbFile));
outputStreamWriter.write(dbJson);
outputStreamWriter.close();
} catch (IOException e) {
Log.e(TAG, "File write failed: " + e.toString());
showErrorMessage(e.getLocalizedMessage());
}
final File zipFile = new File(logsTempDir, logsZipFileName);
final File statusLogFile = new File(logsTempDir, statusLogFileName);
final File gethLogFile = getLogsFile();
try {
if (zipFile.exists() || zipFile.createNewFile()) {
final long usableSpace = zipFile.getUsableSpace();
if (usableSpace < 20 * 1024 * 1024) {
final String message = String.format("Insufficient space available on device (%s) to write logs.\nPlease free up some space.", android.text.format.Formatter.formatShortFileSize(context, usableSpace));
Log.e(TAG, message);
showErrorMessage(message);
return;
}
}
dumpAdbLogsTo(new FileOutputStream(statusLogFile));
final Stack<String> errorList = new Stack<String>();
final Boolean zipped = zip(new File[]{dbFile, gethLogFile, statusLogFile}, zipFile, errorList);
if (zipped && zipFile.exists()) {
zipFile.setReadable(true, false);
Uri extUri = FileProvider.getUriForFile(context, context.getPackageName() + ".provider", zipFile);
callback.invoke(extUri.toString());
} else {
Log.d(TAG, "File " + zipFile.getAbsolutePath() + " does not exist");
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
showErrorMessage(e.getLocalizedMessage());
e.printStackTrace();
return;
} finally {
dbFile.delete();
statusLogFile.delete();
zipFile.deleteOnExit();
}
}
@ReactMethod
public void initLogging(final boolean enabled, final boolean mobileSystem, final String logLevel, final Callback callback) throws JSONException {
final JSONObject jsonConfig = new JSONObject();
jsonConfig.put("Enabled", enabled);
jsonConfig.put("MobileSystem", mobileSystem);
jsonConfig.put("Level", logLevel);
jsonConfig.put("File", getLogsFile().getAbsolutePath());
final String config = jsonConfig.toString();
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.initLogging(config), callback);
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String logFileDirectory() {
return this.utils.getPublicStorageDirectory().getAbsolutePath();
}
}
@@ -0,0 +1,211 @@
package im.status.ethereum.module
import android.app.Activity
import android.app.AlertDialog
import android.content.Context
import android.content.DialogInterface
import android.net.Uri
import android.util.Log
import androidx.core.content.FileProvider
import com.facebook.react.bridge.Callback
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import org.json.JSONException
import org.json.JSONObject
import statusgo.Statusgo
import java.io.*
import java.util.*
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
class LogManager(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
private val utils = Utils(reactContext)
override fun getName() = "LogManager"
private fun getLogsFile(): File {
val pubDirectory = utils.getPublicStorageDirectory()
return File(pubDirectory, gethLogFileName)
}
fun prepareLogsFile(context: Context): File? {
val logFile = utils.getLogsFile()
try {
logFile.setReadable(true)
val parent = logFile.parentFile
if (!parent?.canWrite()!!) {
return null
}
if (!parent.exists()) {
parent.mkdirs()
}
logFile.createNewFile()
logFile.setWritable(true)
Log.d(TAG, "Can write ${logFile.canWrite()}")
val gethLogUri = Uri.fromFile(logFile)
val gethLogFilePath = logFile.absolutePath
Log.d(TAG, gethLogFilePath)
return logFile
} catch (e: Exception) {
Log.d(TAG, "Can't create geth.log file! ${e.message}")
}
return null
}
private fun showErrorMessage(message: String) {
val activity = currentActivity
AlertDialog.Builder(activity)
.setTitle("Error")
.setMessage(message)
.setNegativeButton("Exit") { dialog, _ ->
dialog.dismiss()
}.show()
}
private fun dumpAdbLogsTo(statusLogStream: FileOutputStream) {
val filter = "logcat -d -b main ReactNativeJS:D StatusModule:D StatusService:D StatusNativeLogs:D *:S"
val p = Runtime.getRuntime().exec(filter)
val input = BufferedReader(InputStreamReader(p.inputStream))
val output = BufferedWriter(OutputStreamWriter(statusLogStream))
var line: String?
while (input.readLine().also { line = it } != null) {
output.write(line)
output.newLine()
}
output.close()
input.close()
}
private fun zip(files: Array<File>, zipFile: File, errorList: Stack<String>): Boolean {
val BUFFER = 0x8000
try {
var origin: BufferedInputStream? = null
val dest = FileOutputStream(zipFile)
val out = ZipOutputStream(BufferedOutputStream(dest))
val data = ByteArray(BUFFER)
for (file in files) {
if (file == null || !file.exists()) {
continue
}
Log.v("Compress", "Adding: ${file.absolutePath}")
try {
val fi = FileInputStream(file)
origin = BufferedInputStream(fi, BUFFER)
val entry = ZipEntry(file.name)
out.putNextEntry(entry)
var count: Int
while (origin.read(data, 0, BUFFER).also { count = it } != -1) {
out.write(data, 0, count)
}
origin.close()
} catch (e: IOException) {
Log.e(TAG, e.message!!)
errorList.push(e.message!!)
}
}
out.close()
return true
} catch (e: Exception) {
Log.e(TAG, e.message!!)
e.printStackTrace()
return false
}
}
@ReactMethod
fun sendLogs(dbJson: String, jsLogs: String, callback: Callback) {
Log.d(TAG, "sendLogs")
if (!utils.checkAvailability()) {
return
}
val context = reactApplicationContext
val logsTempDir = File(context.cacheDir, "logs") // This path needs to be in sync with android/app/src/main/res/xml/file_provider_paths.xml
logsTempDir.mkdir()
val dbFile = File(logsTempDir, "db.json")
try {
val outputStreamWriter = OutputStreamWriter(FileOutputStream(dbFile))
outputStreamWriter.write(dbJson)
outputStreamWriter.close()
} catch (e: IOException) {
Log.e(TAG, "File write failed: ${e}")
showErrorMessage(e.localizedMessage!!)
}
val zipFile = File(logsTempDir, logsZipFileName)
val statusLogFile = File(logsTempDir, statusLogFileName)
val gethLogFile = getLogsFile()
try {
if (zipFile.exists() || zipFile.createNewFile()) {
val usableSpace = zipFile.usableSpace
if (usableSpace < 20 * 1024 * 1024) {
val message = "Insufficient space available on device (${android.text.format.Formatter.formatShortFileSize(context, usableSpace)}) to write logs.\nPlease free up some space."
Log.e(TAG, message)
showErrorMessage(message)
return
}
}
dumpAdbLogsTo(FileOutputStream(statusLogFile))
val errorList = Stack<String>()
val zipped = zip(arrayOf(dbFile, gethLogFile, statusLogFile), zipFile, errorList)
if (zipped && zipFile.exists()) {
zipFile.setReadable(true, false)
val extUri = FileProvider.getUriForFile(context, "${context.packageName}.provider", zipFile)
callback.invoke(extUri.toString())
} else {
Log.d(TAG, "File ${zipFile.absolutePath} does not exist")
}
} catch (e: Exception) {
Log.e(TAG, e.message!!)
showErrorMessage(e.localizedMessage!!)
e.printStackTrace()
return
} finally {
dbFile.delete()
statusLogFile.delete()
zipFile.deleteOnExit()
}
}
@ReactMethod
fun initLogging(enabled: Boolean, mobileSystem: Boolean, logLevel: String, callback: Callback) {
val jsonConfig = JSONObject().apply {
put("Enabled", enabled)
put("MobileSystem", mobileSystem)
put("Level", logLevel)
put("File", getLogsFile().absolutePath)
}
val config = jsonConfig.toString()
utils.executeRunnableStatusGoMethod({ Statusgo.initLogging(config) }, callback)
}
@ReactMethod(isBlockingSynchronousMethod = true)
fun logFileDirectory(): String? {
return utils.getPublicStorageDirectory()?.absolutePath
}
companion object {
private const val TAG = "LogManager"
private const val gethLogFileName = "geth.log"
private const val statusLogFileName = "Status.log"
private const val logsZipFileName = "Status-debug-logs.zip"
}
}
@@ -1,78 +0,0 @@
package im.status.ethereum.module;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
import org.json.JSONException;
import statusgo.Statusgo;
import org.json.JSONObject;
public class NetworkManager extends ReactContextBaseJavaModule {
private ReactApplicationContext reactContext;
private Utils utils;
public NetworkManager(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
this.utils = new Utils(reactContext);
}
@Override
public String getName() {
return "NetworkManager";
}
@ReactMethod
public void startSearchForLocalPairingPeers(final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.startSearchForLocalPairingPeers(), callback);
}
@ReactMethod
public void getConnectionStringForBootstrappingAnotherDevice(final String configJSON, final Callback callback) throws JSONException {
final JSONObject jsonConfig = new JSONObject(configJSON);
final JSONObject senderConfig = jsonConfig.getJSONObject("senderConfig");
final String keyUID = senderConfig.getString("keyUID");
final String keyStorePath = this.utils.getKeyStorePath(keyUID);
senderConfig.put("keystorePath", keyStorePath);
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.getConnectionStringForBootstrappingAnotherDevice(jsonConfig.toString()), callback);
}
@ReactMethod
public void inputConnectionStringForBootstrapping(final String connectionString, final String configJSON, final Callback callback) throws JSONException {
final JSONObject jsonConfig = new JSONObject(configJSON);
final JSONObject receiverConfig = jsonConfig.getJSONObject("receiverConfig");
final String keyStorePath = this.utils.pathCombine(this.utils.getNoBackupDirectory(), "/keystore");
receiverConfig.put("keystorePath", keyStorePath);
receiverConfig.getJSONObject("nodeConfig").put("rootDataDir", this.utils.getNoBackupDirectory());
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.inputConnectionStringForBootstrapping(connectionString, jsonConfig.toString()), callback);
}
@ReactMethod
public void sendTransactionWithSignature(final String txArgsJSON, final String signature, final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.sendTransactionWithSignature(txArgsJSON, signature), callback);
}
@ReactMethod
public void sendTransaction(final String txArgsJSON, final String password, final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.sendTransaction(txArgsJSON, password), callback);
}
@ReactMethod
public void callRPC(final String payload, final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.callRPC(payload), callback);
}
@ReactMethod
public void callPrivateRPC(final String payload, final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.callPrivateRPC(payload), callback);
}
@ReactMethod
public void recover(final String rpcParams, final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.recover(rpcParams), callback);
}
}
@@ -0,0 +1,77 @@
package im.status.ethereum.module
import com.facebook.react.bridge.Callback
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import org.json.JSONException
import org.json.JSONObject
import statusgo.Statusgo
class NetworkManager(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
private val utils = Utils(reactContext)
override fun getName() = "NetworkManager"
@ReactMethod
fun startSearchForLocalPairingPeers(callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.startSearchForLocalPairingPeers() }, callback)
}
@ReactMethod
fun getConnectionStringForBootstrappingAnotherDevice(configJSON: String, callback: Callback) {
val jsonConfig = JSONObject(configJSON)
val senderConfig = jsonConfig.getJSONObject("senderConfig")
val keyUID = senderConfig.getString("keyUID")
val keyStorePath = utils.getKeyStorePath(keyUID)
senderConfig.put("keystorePath", keyStorePath)
utils.executeRunnableStatusGoMethod(
{ Statusgo.getConnectionStringForBootstrappingAnotherDevice(jsonConfig.toString()) },
callback
)
}
@ReactMethod
fun inputConnectionStringForBootstrapping(connectionString: String, configJSON: String, callback: Callback) {
val jsonConfig = JSONObject(configJSON)
val receiverConfig = jsonConfig.getJSONObject("receiverConfig")
val keyStorePath = utils.pathCombine(utils.getNoBackupDirectory(), "/keystore")
receiverConfig.put("keystorePath", keyStorePath)
receiverConfig.getJSONObject("nodeConfig").put("rootDataDir", utils.getNoBackupDirectory())
utils.executeRunnableStatusGoMethod(
{ Statusgo.inputConnectionStringForBootstrapping(connectionString, jsonConfig.toString()) },
callback
)
}
@ReactMethod
fun sendTransactionWithSignature(txArgsJSON: String, signature: String, callback: Callback) {
utils.executeRunnableStatusGoMethod(
{ Statusgo.sendTransactionWithSignature(txArgsJSON, signature) },
callback
)
}
@ReactMethod
fun sendTransaction(txArgsJSON: String, password: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.sendTransaction(txArgsJSON, password) }, callback)
}
@ReactMethod
fun callRPC(payload: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.callRPC(payload) }, callback)
}
@ReactMethod
fun callPrivateRPC(payload: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.callPrivateRPC(payload) }, callback)
}
@ReactMethod
fun recover(rpcParams: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.recover(rpcParams) }, callback)
}
}
@@ -1,147 +0,0 @@
package im.status.ethereum.module;
import android.app.Activity;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;
import android.os.Build;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import statusgo.SignalHandler;
import statusgo.Statusgo;
import org.json.JSONException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nullable;
class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventListener, SignalHandler {
private static final String TAG = "StatusModule";
private static StatusModule module;
private ReactApplicationContext reactContext;
private boolean rootedDevice;
private boolean background;
private Utils utils;
StatusModule(ReactApplicationContext reactContext, boolean rootedDevice) {
super(reactContext);
this.reactContext = reactContext;
this.rootedDevice = rootedDevice;
this.utils = new Utils(reactContext);
reactContext.addLifecycleEventListener(this);
}
@Override
public String getName() {
return "Status";
}
@Override
public void onHostResume() {
module = this;
this.background = false;
Statusgo.setMobileSignalHandler(this);
}
@Override
public void onHostPause() {
this.background = true;
}
@Override
public void onHostDestroy() {
Log.d(TAG, "******************* ON HOST DESTROY *************************");
}
public void handleSignal(final String jsonEventString) {
Log.d(TAG, "Signal event");
WritableMap params = Arguments.createMap();
params.putString("jsonEvent", jsonEventString);
this.getReactApplicationContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("gethEvent", params);
}
@ReactMethod
public void closeApplication() {
System.exit(0);
}
@ReactMethod
public void connectionChange(final String type, final boolean isExpensive) {
Log.d(TAG, "ConnectionChange: " + type + ", is expensive " + isExpensive);
Statusgo.connectionChange(type, isExpensive ? 1 : 0);
}
@ReactMethod
public void appStateChange(final String type) {
Log.d(TAG, "AppStateChange: " + type);
Statusgo.appStateChange(type);
}
@ReactMethod
public void startLocalNotifications() {
Log.d(TAG, "startLocalNotifications");
Statusgo.startLocalNotifications();
}
@ReactMethod
public void getNodeConfig(final Callback callback) throws JSONException {
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.getNodeConfig(), callback);
}
@ReactMethod
public void deleteImportedKey(final String keyUID, final String address, final String password, final Callback callback) throws JSONException {
final String keyStoreDir = this.utils.getKeyStorePath(keyUID);
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.deleteImportedKey(address, password, keyStoreDir), callback);
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String fleets() {
return Statusgo.fleets();
}
@Override
public @Nullable
Map<String, Object> getConstants() {
HashMap<String, Object> constants = new HashMap<String, Object>();
constants.put("is24Hour", this.utils.is24Hour());
constants.put("model", Build.MODEL);
constants.put("brand", Build.BRAND);
constants.put("buildId", Build.ID);
constants.put("deviceId", Build.BOARD);
return constants;
}
@ReactMethod
public void isDeviceRooted(final Callback callback) {
callback.invoke(rootedDevice);
}
@ReactMethod
public void deactivateKeepAwake() {
final Activity activity = getCurrentActivity();
if (activity != null) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
activity.getWindow().clearFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
});
}
}
}
@@ -0,0 +1,114 @@
package im.status.ethereum.module
import android.app.Activity
import android.os.Build
import android.util.Log
import com.facebook.react.bridge.*
import com.facebook.react.modules.core.DeviceEventManagerModule
import statusgo.SignalHandler
import statusgo.Statusgo
import org.json.JSONException
import android.view.WindowManager
class StatusModule(private val reactContext: ReactApplicationContext, private val rootedDevice: Boolean) : ReactContextBaseJavaModule(reactContext), LifecycleEventListener, SignalHandler {
companion object {
private const val TAG = "StatusModule"
private var module: StatusModule? = null
}
private val utils: Utils = Utils(reactContext)
private var background: Boolean = false
init {
reactContext.addLifecycleEventListener(this)
}
override fun getName(): String {
return "Status"
}
override fun onHostResume() {
module = this
background = false
Statusgo.setMobileSignalHandler(this)
}
override fun onHostPause() {
background = true
}
override fun onHostDestroy() {
Log.d(TAG, "******************* ON HOST DESTROY *************************")
}
override fun handleSignal(jsonEventString: String) {
Log.d(TAG, "Signal event")
val params = Arguments.createMap()
params.putString("jsonEvent", jsonEventString)
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java).emit("gethEvent", params)
}
@ReactMethod
fun closeApplication() {
System.exit(0)
}
@ReactMethod
fun connectionChange(type: String, isExpensive: Boolean) {
Log.d(TAG, "ConnectionChange: $type, is expensive $isExpensive")
Statusgo.connectionChange(type, if (isExpensive) 1 else 0)
}
@ReactMethod
fun appStateChange(type: String) {
Log.d(TAG, "AppStateChange: $type")
Statusgo.appStateChange(type)
}
@ReactMethod
fun startLocalNotifications() {
Log.d(TAG, "startLocalNotifications")
Statusgo.startLocalNotifications()
}
@ReactMethod
fun getNodeConfig(callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.getNodeConfig() }, callback)
}
@ReactMethod
fun deleteImportedKey(keyUID: String, address: String, password: String, callback: Callback) {
val keyStoreDir = utils.getKeyStorePath(keyUID)
utils.executeRunnableStatusGoMethod({ Statusgo.deleteImportedKey(address, password, keyStoreDir) }, callback)
}
@ReactMethod(isBlockingSynchronousMethod = true)
fun fleets(): String {
return Statusgo.fleets()
}
override fun getConstants(): Map<String, Any>? {
return hashMapOf(
"is24Hour" to utils.is24Hour(),
"model" to Build.MODEL,
"brand" to Build.BRAND,
"buildId" to Build.ID,
"deviceId" to Build.BOARD
)
}
@ReactMethod
fun isDeviceRooted(callback: Callback) {
callback.invoke(rootedDevice)
}
@ReactMethod
fun deactivateKeepAwake() {
val activity = currentActivity
activity?.runOnUiThread {
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
}
}
@@ -1,51 +0,0 @@
package im.status.ethereum.module;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import statusgo.Statusgo;
public class StatusPackage implements ReactPackage {
private boolean rootedDevice;
public static String getImageTLSCert() {
return Statusgo.imageServerTLSCert();
}
public StatusPackage(boolean rootedDevice) {
this.rootedDevice = rootedDevice;
}
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new StatusModule(reactContext, this.rootedDevice));
modules.add(new AccountManager(reactContext));
modules.add(new EncryptionUtils(reactContext));
modules.add(new DatabaseManager(reactContext));
modules.add(new UIHelper(reactContext));
modules.add(new LogManager(reactContext));
modules.add(new Utils(reactContext));
modules.add(new NetworkManager(reactContext));
modules.add(new RNSelectableTextInputModule(reactContext));
return modules;
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Arrays.<ViewManager>asList(
new RNSelectableTextInputViewManager()
);
}
}
@@ -0,0 +1,38 @@
package im.status.ethereum.module
import com.facebook.react.ReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ViewManager
import statusgo.Statusgo
class StatusPackage(private val rootedDevice: Boolean) : ReactPackage {
companion object {
fun getImageTLSCert(): String = Statusgo.imageServerTLSCert()
}
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
val modules = mutableListOf<NativeModule>()
modules.apply {
add(StatusModule(reactContext, rootedDevice))
add(AccountManager(reactContext))
add(EncryptionUtils(reactContext))
add(DatabaseManager(reactContext))
add(UIHelper(reactContext))
add(LogManager(reactContext))
add(Utils(reactContext))
add(NetworkManager(reactContext))
add(RNSelectableTextInputModule(reactContext))
}
return modules
}
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
return listOf(
RNSelectableTextInputViewManager()
)
}
}
@@ -1,155 +0,0 @@
package im.status.ethereum.module;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import android.util.Log;
import java.util.function.Supplier;
import java.io.File;
import android.content.Context;
import android.os.Environment;
import org.json.JSONObject;
import org.json.JSONException;
import statusgo.Statusgo;
public class Utils extends ReactContextBaseJavaModule {
private static final String gethLogFileName = "geth.log";
private static final String TAG = "Utils";
private ReactApplicationContext reactContext;
public Utils(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}
@Override
public String getName() {
return "Utils";
}
public String getNoBackupDirectory() {
return this.getReactApplicationContext().getNoBackupFilesDir().getAbsolutePath();
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String backupDisabledDataDir() {
return getNoBackupDirectory();
}
public File getPublicStorageDirectory() {
final Context context = this.getReactApplicationContext();
// Environment.getExternalStoragePublicDirectory doesn't work as expected on Android Q
// https://developer.android.com/reference/android/os/Environment#getExternalStoragePublicDirectory(java.lang.String)
return context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
}
public File getLogsFile() {
final File pubDirectory = getPublicStorageDirectory();
final File logFile = new File(pubDirectory, gethLogFileName);
return logFile;
}
public String getKeyUID(final String json) throws JSONException {
final JSONObject jsonObj = new JSONObject(json);
return jsonObj.getString("key-uid");
}
public String pathCombine(final String path1, final String path2) {
// Replace this logic with Paths.get(path1, path2) once API level 26+ becomes the minimum supported API level
final File file = new File(path1, path2);
return file.getAbsolutePath();
}
public String getKeyStorePath(String keyUID) {
final String commonKeydir = pathCombine(getNoBackupDirectory(), "/keystore");
final String keydir = pathCombine(commonKeydir, keyUID);
return keydir;
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String keystoreDir() {
final String absRootDirPath = getNoBackupDirectory();
return pathCombine(absRootDirPath, "keystore");
}
public void migrateKeyStoreDir(final String accountData, final String password) {
try {
final String commonKeydir = pathCombine(getNoBackupDirectory(), "/keystore");
final String keydir = getKeyStorePath(getKeyUID(accountData));
Log.d(TAG, "before migrateKeyStoreDir " + keydir);
File keydirFile = new File(keydir);
if(!keydirFile.exists() || keydirFile.list().length == 0) {
Log.d(TAG, "migrateKeyStoreDir");
Statusgo.migrateKeyStoreDir(accountData, password, commonKeydir, keydir);
Statusgo.initKeystore(keydir);
}
} catch (JSONException e) {
Log.e(TAG, "JSON conversion failed: " + e.getMessage());
}
}
public boolean checkAvailability() {
// We wait at least 10s for getCurrentActivity to return a value,
// otherwise we give up
for (int attempts = 0; attempts < 100; attempts++) {
if (getCurrentActivity() != null) {
return true;
}
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
if (getCurrentActivity() != null) {
return true;
}
Log.d(TAG, "Activity doesn't exist");
return false;
}
}
Log.d(TAG, "Activity doesn't exist");
return false;
}
public void executeRunnableStatusGoMethod(Supplier<String> method, Callback callback) throws JSONException {
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable runnableTask = () -> {
String res = method.get();
callback.invoke(res);
};
StatusThreadPoolExecutor.getInstance().execute(runnableTask);
}
@ReactMethod
public void validateMnemonic(final String seed, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.validateMnemonic(seed), callback);
}
public Boolean is24Hour() {
return android.text.format.DateFormat.is24HourFormat(this.reactContext.getApplicationContext());
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String checkAddressChecksum(final String address) {
return Statusgo.checkAddressChecksum(address);
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String isAddress(final String address) {
return Statusgo.isAddress(address);
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String toChecksumAddress(final String address) {
return Statusgo.toChecksumAddress(address);
}
}
@@ -0,0 +1,144 @@
package im.status.ethereum.module
import android.content.Context
import android.os.Environment
import com.facebook.react.bridge.Callback
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import android.util.Log
import org.json.JSONException
import org.json.JSONObject
import java.io.File
import java.util.function.Supplier
import statusgo.Statusgo
class Utils(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
companion object {
private const val gethLogFileName = "geth.log"
private const val TAG = "Utils"
}
override fun getName(): String {
return "Utils"
}
fun getNoBackupDirectory(): String {
return reactContext.noBackupFilesDir.absolutePath
}
@ReactMethod(isBlockingSynchronousMethod = true)
fun backupDisabledDataDir(): String {
return getNoBackupDirectory()
}
fun getPublicStorageDirectory(): File? {
// Environment.getExternalStoragePublicDirectory doesn't work as expected on Android Q
// https://developer.android.com/reference/android/os/Environment#getExternalStoragePublicDirectory(java.lang.String)
return reactContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
}
fun getLogsFile(): File {
val pubDirectory = getPublicStorageDirectory()
return File(pubDirectory, gethLogFileName)
}
fun getKeyUID(json: String): String {
val jsonObj = JSONObject(json)
return jsonObj.getString("key-uid")
}
fun pathCombine(path1: String, path2: String): String {
val file = File(path1, path2)
return file.absolutePath
}
fun getKeyStorePath(keyUID: String): String {
val commonKeydir = pathCombine(getNoBackupDirectory(), "/keystore")
return pathCombine(commonKeydir, keyUID)
}
@ReactMethod(isBlockingSynchronousMethod = true)
fun keystoreDir(): String {
val absRootDirPath = getNoBackupDirectory()
return pathCombine(absRootDirPath, "keystore")
}
fun migrateKeyStoreDir(accountData: String, password: String) {
try {
val commonKeydir = pathCombine(getNoBackupDirectory(), "/keystore")
val keydir = getKeyStorePath(getKeyUID(accountData))
Log.d(TAG, "before migrateKeyStoreDir $keydir")
val keydirFile = File(keydir)
if (!keydirFile.exists() || keydirFile.list().isEmpty()) {
Log.d(TAG, "migrateKeyStoreDir")
Statusgo.migrateKeyStoreDir(accountData, password, commonKeydir, keydir)
Statusgo.initKeystore(keydir)
}
} catch (e: JSONException) {
Log.e(TAG, "JSON conversion failed: ${e.message}")
}
}
fun checkAvailability(): Boolean {
// We wait at least 10s for getCurrentActivity to return a value,
// otherwise we give up
for (attempts in 0 until 100) {
if (currentActivity != null) {
return true
}
try {
Thread.sleep(100)
} catch (ex: InterruptedException) {
if (currentActivity != null) {
return true
}
Log.d(TAG, "Activity doesn't exist")
return false
}
}
Log.d(TAG, "Activity doesn't exist")
return false
}
fun executeRunnableStatusGoMethod(method: Supplier<String>, callback: Callback) {
if (!checkAvailability()) {
callback.invoke(false)
return
}
val runnableTask = Runnable {
val res = method.get()
callback.invoke(res)
}
StatusThreadPoolExecutor.getInstance().execute(runnableTask)
}
@ReactMethod
fun validateMnemonic(seed: String, callback: Callback) {
executeRunnableStatusGoMethod({ Statusgo.validateMnemonic(seed) }, callback)
}
fun is24Hour(): Boolean {
return android.text.format.DateFormat.is24HourFormat(reactContext.applicationContext)
}
@ReactMethod(isBlockingSynchronousMethod = true)
fun checkAddressChecksum(address: String): String {
return Statusgo.checkAddressChecksum(address)
}
@ReactMethod(isBlockingSynchronousMethod = true)
fun isAddress(address: String): String {
return Statusgo.isAddress(address)
}
@ReactMethod(isBlockingSynchronousMethod = true)
fun toChecksumAddress(address: String): String {
return Statusgo.toChecksumAddress(address)
}
}
@@ -1,17 +0,0 @@
#include "HelloWorldJSI.h"
#include <jsi/jsi.h>
#include <iostream>
using namespace facebook::jsi;
void HelloWorldJSI::install(Runtime& runtime) {
auto helloWorldFunction = Function::createFromHostFunction(runtime,
PropNameID::forAscii(runtime, "helloWorld"),
0,
[](Runtime& runtime, Value thisValue, Value* arguments, size_t count) -> Value {
std::cout << "Hello, World! from C++" << std::endl;
return Value::undefined();
});
runtime.global().setProperty(runtime, "helloWorld", std::move(helloWorldFunction));
}
@@ -1,13 +0,0 @@
#pragma once
#include <jsi/jsi.h>
using namespace facebook::jsi;
class HelloWorldJSI {
public:
static void install(Runtime& runtime);
private:
static void helloWorld(Runtime& runtime, Value thisValue, Value* arguments, size_t count);
};
+258 -659
View File
File diff suppressed because it is too large Load Diff
-26
View File
@@ -162,7 +162,6 @@ com.afollestad.material-dialogs:core:0.9.6.0
com.airbnb.android:lottie:3.4.4
com.almworks.sqlite4java:sqlite4java:1.0.392
com.android.databinding:baseLibrary:1.0-rc5
com.android.databinding:baseLibrary:3.0.0
com.android.databinding:baseLibrary:3.0.1
com.android.databinding:baseLibrary:3.2.1
com.android.databinding:baseLibrary:3.5.4
@@ -172,7 +171,6 @@ com.android.databinding:baseLibrary:7.2.1
com.android.databinding:baseLibrary:7.3.1
com.android.databinding:baseLibrary:8.1.1
com.android.databinding:compilerCommon:1.0-rc5
com.android.databinding:compilerCommon:3.0.0
com.android.databinding:compilerCommon:3.0.1
com.android.tools.analytics-library:crash:26.2.1
com.android.tools.analytics-library:crash:26.5.4
@@ -181,7 +179,6 @@ com.android.tools.analytics-library:crash:30.0.4
com.android.tools.analytics-library:crash:30.2.1
com.android.tools.analytics-library:crash:30.3.1
com.android.tools.analytics-library:crash:31.1.1
com.android.tools.analytics-library:protos:26.0.0
com.android.tools.analytics-library:protos:26.0.1
com.android.tools.analytics-library:protos:26.2.1
com.android.tools.analytics-library:protos:26.5.4
@@ -190,7 +187,6 @@ com.android.tools.analytics-library:protos:30.0.4
com.android.tools.analytics-library:protos:30.2.1
com.android.tools.analytics-library:protos:30.3.1
com.android.tools.analytics-library:protos:31.1.1
com.android.tools.analytics-library:shared:26.0.0
com.android.tools.analytics-library:shared:26.0.1
com.android.tools.analytics-library:shared:26.2.1
com.android.tools.analytics-library:shared:26.5.4
@@ -199,7 +195,6 @@ com.android.tools.analytics-library:shared:30.0.4
com.android.tools.analytics-library:shared:30.2.1
com.android.tools.analytics-library:shared:30.3.1
com.android.tools.analytics-library:shared:31.1.1
com.android.tools.analytics-library:tracker:26.0.0
com.android.tools.analytics-library:tracker:26.0.1
com.android.tools.analytics-library:tracker:26.2.1
com.android.tools.analytics-library:tracker:26.5.4
@@ -229,7 +224,6 @@ com.android.tools.build:aaptcompiler:7.0.4
com.android.tools.build:aaptcompiler:7.2.1
com.android.tools.build:aaptcompiler:7.3.1
com.android.tools.build:aaptcompiler:8.1.1
com.android.tools.build:apksig:3.0.0
com.android.tools.build:apksig:3.0.1
com.android.tools.build:apksig:3.2.1
com.android.tools.build:apksig:3.5.4
@@ -247,7 +241,6 @@ com.android.tools.build:apkzlib:7.3.1
com.android.tools.build:apkzlib:8.1.1
com.android.tools.build:builder-model:1.3.1
com.android.tools.build:builder-model:1.5.0
com.android.tools.build:builder-model:3.0.0
com.android.tools.build:builder-model:3.0.1
com.android.tools.build:builder-model:3.2.1
com.android.tools.build:builder-model:3.5.4
@@ -258,7 +251,6 @@ com.android.tools.build:builder-model:7.3.1
com.android.tools.build:builder-model:8.1.1
com.android.tools.build:builder-test-api:1.3.1
com.android.tools.build:builder-test-api:1.5.0
com.android.tools.build:builder-test-api:3.0.0
com.android.tools.build:builder-test-api:3.0.1
com.android.tools.build:builder-test-api:3.2.1
com.android.tools.build:builder-test-api:3.5.4
@@ -269,7 +261,6 @@ com.android.tools.build:builder-test-api:7.3.1
com.android.tools.build:builder-test-api:8.1.1
com.android.tools.build:builder:1.3.1
com.android.tools.build:builder:1.5.0
com.android.tools.build:builder:3.0.0
com.android.tools.build:builder:3.0.1
com.android.tools.build:builder:3.2.1
com.android.tools.build:builder:3.5.4
@@ -285,7 +276,6 @@ com.android.tools.build:bundletool:1.6.0
com.android.tools.build:bundletool:1.8.2
com.android.tools.build:bundletool:1.9.0
com.android.tools.build:bundletool:1.14.0
com.android.tools.build:gradle-api:3.0.0
com.android.tools.build:gradle-api:3.0.1
com.android.tools.build:gradle-api:3.2.1
com.android.tools.build:gradle-api:3.5.4
@@ -296,12 +286,10 @@ com.android.tools.build:gradle-api:7.3.1
com.android.tools.build:gradle-api:8.1.1
com.android.tools.build:gradle-core:1.3.1
com.android.tools.build:gradle-core:1.5.0
com.android.tools.build:gradle-core:3.0.0
com.android.tools.build:gradle-core:3.0.1
com.android.tools.build:gradle-settings-api:8.1.1
com.android.tools.build:gradle:1.3.1
com.android.tools.build:gradle:1.5.0
com.android.tools.build:gradle:3.0.0
com.android.tools.build:gradle:3.0.1
com.android.tools.build:gradle:3.2.1
com.android.tools.build:gradle:3.5.4
@@ -311,7 +299,6 @@ com.android.tools.build:gradle:7.2.1
com.android.tools.build:gradle:7.3.1
com.android.tools.build:manifest-merger:24.3.1
com.android.tools.build:manifest-merger:24.5.0
com.android.tools.build:manifest-merger:26.0.0
com.android.tools.build:manifest-merger:26.0.1
com.android.tools.build:manifest-merger:26.2.1
com.android.tools.build:manifest-merger:26.5.4
@@ -324,7 +311,6 @@ com.android.tools.build:transform-api:1.5.0
com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api
com.android.tools.ddms:ddmlib:24.3.1
com.android.tools.ddms:ddmlib:24.5.0
com.android.tools.ddms:ddmlib:26.0.0
com.android.tools.ddms:ddmlib:26.0.1
com.android.tools.ddms:ddmlib:26.2.1
com.android.tools.ddms:ddmlib:26.5.4
@@ -333,16 +319,13 @@ com.android.tools.ddms:ddmlib:30.0.4
com.android.tools.ddms:ddmlib:30.2.1
com.android.tools.ddms:ddmlib:30.3.1
com.android.tools.ddms:ddmlib:31.1.1
com.android.tools.external.com-intellij:intellij-core:26.0.0
com.android.tools.external.com-intellij:intellij-core:26.0.1
com.android.tools.external.lombok:lombok-ast:0.2.3
com.android.tools.external.org-jetbrains:uast:26.0.0
com.android.tools.external.org-jetbrains:uast:26.0.1
com.android.tools.jack:jack-api:0.9.0
com.android.tools.jill:jill-api:0.9.0
com.android.tools.layoutlib:layoutlib-api:24.3.1
com.android.tools.layoutlib:layoutlib-api:24.5.0
com.android.tools.layoutlib:layoutlib-api:26.0.0
com.android.tools.layoutlib:layoutlib-api:26.0.1
com.android.tools.layoutlib:layoutlib-api:26.2.1
com.android.tools.layoutlib:layoutlib-api:26.5.4
@@ -353,11 +336,9 @@ com.android.tools.layoutlib:layoutlib-api:30.3.1
com.android.tools.layoutlib:layoutlib-api:31.1.1
com.android.tools.lint:lint-api:24.3.1
com.android.tools.lint:lint-api:24.5.0
com.android.tools.lint:lint-api:26.0.0
com.android.tools.lint:lint-api:26.0.1
com.android.tools.lint:lint-checks:24.3.1
com.android.tools.lint:lint-checks:24.5.0
com.android.tools.lint:lint-checks:26.0.0
com.android.tools.lint:lint-checks:26.0.1
com.android.tools.lint:lint-gradle-api:26.2.1
com.android.tools.lint:lint-gradle-api:26.5.4
@@ -372,7 +353,6 @@ com.android.tools.lint:lint-typedef-remover:30.3.1
com.android.tools.lint:lint-typedef-remover:31.1.1
com.android.tools.lint:lint:24.3.1
com.android.tools.lint:lint:24.5.0
com.android.tools.lint:lint:26.0.0
com.android.tools.lint:lint:26.0.1
com.android.tools.utp:android-device-provider-ddmlib-proto:30.2.1
com.android.tools.utp:android-device-provider-ddmlib-proto:30.3.1
@@ -400,7 +380,6 @@ com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.3.1
com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:31.1.1
com.android.tools:annotations:24.3.1
com.android.tools:annotations:24.5.0
com.android.tools:annotations:26.0.0
com.android.tools:annotations:26.0.1
com.android.tools:annotations:26.2.1
com.android.tools:annotations:26.5.4
@@ -411,7 +390,6 @@ com.android.tools:annotations:30.3.1
com.android.tools:annotations:31.1.1
com.android.tools:common:24.3.1
com.android.tools:common:24.5.0
com.android.tools:common:26.0.0
com.android.tools:common:26.0.1
com.android.tools:common:26.2.1
com.android.tools:common:26.5.4
@@ -422,7 +400,6 @@ com.android.tools:common:30.3.1
com.android.tools:common:31.1.1
com.android.tools:dvlib:24.3.1
com.android.tools:dvlib:24.5.0
com.android.tools:dvlib:26.0.0
com.android.tools:dvlib:26.0.1
com.android.tools:dvlib:26.2.1
com.android.tools:dvlib:26.5.4
@@ -431,7 +408,6 @@ com.android.tools:dvlib:30.0.4
com.android.tools:dvlib:30.2.1
com.android.tools:dvlib:30.3.1
com.android.tools:dvlib:31.1.1
com.android.tools:repository:26.0.0
com.android.tools:repository:26.0.1
com.android.tools:repository:26.2.1
com.android.tools:repository:26.5.4
@@ -442,7 +418,6 @@ com.android.tools:repository:30.3.1
com.android.tools:repository:31.1.1
com.android.tools:sdklib:24.3.1
com.android.tools:sdklib:24.5.0
com.android.tools:sdklib:26.0.0
com.android.tools:sdklib:26.0.1
com.android.tools:sdklib:26.2.1
com.android.tools:sdklib:26.5.4
@@ -453,7 +428,6 @@ com.android.tools:sdklib:30.3.1
com.android.tools:sdklib:31.1.1
com.android.tools:sdk-common:24.3.1
com.android.tools:sdk-common:24.5.0
com.android.tools:sdk-common:26.0.0
com.android.tools:sdk-common:26.0.1
com.android.tools:sdk-common:26.2.1
com.android.tools:sdk-common:26.5.4
+38 -65
View File
@@ -179,7 +179,6 @@ https://dl.google.com/dl/android/maven2/androidx/webkit/webkit/1.4.0/webkit-1.4.
https://dl.google.com/dl/android/maven2/android/arch/core/common/1.0.0/common-1.0.0.pom
https://dl.google.com/dl/android/maven2/android/arch/lifecycle/common/1.0.0/common-1.0.0.pom
https://dl.google.com/dl/android/maven2/android/arch/lifecycle/runtime/1.0.0/runtime-1.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/databinding/baseLibrary/3.0.0/baseLibrary-3.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/databinding/baseLibrary/3.0.1/baseLibrary-3.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/databinding/baseLibrary/3.2.1/baseLibrary-3.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/databinding/baseLibrary/3.5.4/baseLibrary-3.5.4.pom
@@ -188,7 +187,6 @@ https://dl.google.com/dl/android/maven2/com/android/databinding/baseLibrary/7.0.
https://dl.google.com/dl/android/maven2/com/android/databinding/baseLibrary/7.2.1/baseLibrary-7.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/databinding/baseLibrary/7.3.1/baseLibrary-7.3.1.pom
https://dl.google.com/dl/android/maven2/com/android/databinding/baseLibrary/8.1.1/baseLibrary-8.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/databinding/compilerCommon/3.0.0/compilerCommon-3.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/databinding/compilerCommon/3.0.1/compilerCommon-3.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/signflinger/4.1.0/signflinger-4.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/signflinger/7.0.4/signflinger-7.0.4.pom
@@ -222,7 +220,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/cras
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/crash/30.2.1/crash-30.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/crash/30.3.1/crash-30.3.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/crash/31.1.1/crash-31.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/protos/26.0.0/protos-26.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/protos/26.0.1/protos-26.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/protos/26.2.1/protos-26.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/protos/26.5.4/protos-26.5.4.pom
@@ -231,7 +228,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/prot
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/protos/30.2.1/protos-30.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/protos/30.3.1/protos-30.3.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/protos/31.1.1/protos-31.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/shared/26.0.0/shared-26.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/shared/26.0.1/shared-26.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/shared/26.2.1/shared-26.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/shared/26.5.4/shared-26.5.4.pom
@@ -240,7 +236,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/shar
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/shared/30.2.1/shared-30.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/shared/30.3.1/shared-30.3.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/shared/31.1.1/shared-31.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/tracker/26.0.0/tracker-26.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/tracker/26.0.1/tracker-26.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/tracker/26.2.1/tracker-26.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/tracker/26.5.4/tracker-26.5.4.pom
@@ -249,7 +244,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/trac
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/tracker/30.2.1/tracker-30.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/tracker/30.3.1/tracker-30.3.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/tracker/31.1.1/tracker-31.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/annotations/26.0.0/annotations-26.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/annotations/26.0.1/annotations-26.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/annotations/26.2.1/annotations-26.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/annotations/26.5.4/annotations-26.5.4.pom
@@ -274,7 +268,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/build/aaptcompiler/7.0
https://dl.google.com/dl/android/maven2/com/android/tools/build/aaptcompiler/7.2.1/aaptcompiler-7.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/aaptcompiler/7.3.1/aaptcompiler-7.3.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/aaptcompiler/8.1.1/aaptcompiler-8.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/apksig/3.0.0/apksig-3.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/apksig/3.0.1/apksig-3.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/apksig/3.2.1/apksig-3.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/apksig/3.5.4/apksig-3.5.4.pom
@@ -290,7 +283,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/build/apkzlib/7.0.4/ap
https://dl.google.com/dl/android/maven2/com/android/tools/build/apkzlib/7.2.1/apkzlib-7.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/apkzlib/7.3.1/apkzlib-7.3.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/apkzlib/8.1.1/apkzlib-8.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-model/3.0.0/builder-model-3.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-model/3.0.1/builder-model-3.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-model/3.2.1/builder-model-3.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-model/3.5.4/builder-model-3.5.4.pom
@@ -299,7 +291,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-model/7.
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-model/7.2.1/builder-model-7.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-model/7.3.1/builder-model-7.3.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-model/8.1.1/builder-model-8.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-test-api/3.0.0/builder-test-api-3.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-test-api/3.0.1/builder-test-api-3.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-test-api/3.2.1/builder-test-api-3.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-test-api/3.5.4/builder-test-api-3.5.4.pom
@@ -308,7 +299,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-test-api
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-test-api/7.2.1/builder-test-api-7.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-test-api/7.3.1/builder-test-api-7.3.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-test-api/8.1.1/builder-test-api-8.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder/3.0.0/builder-3.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder/3.0.1/builder-3.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder/3.2.1/builder-3.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder/3.5.4/builder-3.5.4.pom
@@ -324,7 +314,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/build/bundletool/1.6.0
https://dl.google.com/dl/android/maven2/com/android/tools/build/bundletool/1.8.2/bundletool-1.8.2.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/bundletool/1.9.0/bundletool-1.9.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/bundletool/1.14.0/bundletool-1.14.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle-api/3.0.0/gradle-api-3.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle-api/3.0.1/gradle-api-3.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle-api/3.2.1/gradle-api-3.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle-api/3.5.4/gradle-api-3.5.4.pom
@@ -333,10 +322,8 @@ https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle-api/7.0.4
https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle-api/7.2.1/gradle-api-7.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle-api/7.3.1/gradle-api-7.3.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle-api/8.1.1/gradle-api-8.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle-core/3.0.0/gradle-core-3.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle-core/3.0.1/gradle-core-3.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle-settings-api/8.1.1/gradle-settings-api-8.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle/3.0.0/gradle-3.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle/3.0.1/gradle-3.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle/3.2.1/gradle-3.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle/3.5.4/gradle-3.5.4.pom
@@ -353,7 +340,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/build/jetifier/jetifie
https://dl.google.com/dl/android/maven2/com/android/tools/build/jetifier/jetifier-processor/1.0.0-beta04/jetifier-processor-1.0.0-beta04.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/jetifier/jetifier-processor/1.0.0-beta09/jetifier-processor-1.0.0-beta09.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/jetifier/jetifier-processor/1.0.0-beta10/jetifier-processor-1.0.0-beta10.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/manifest-merger/26.0.0/manifest-merger-26.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/manifest-merger/26.0.1/manifest-merger-26.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/manifest-merger/26.2.1/manifest-merger-26.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/manifest-merger/26.5.4/manifest-merger-26.5.4.pom
@@ -362,7 +348,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/build/manifest-merger/
https://dl.google.com/dl/android/maven2/com/android/tools/build/manifest-merger/30.2.1/manifest-merger-30.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/manifest-merger/30.3.1/manifest-merger-30.3.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/manifest-merger/31.1.1/manifest-merger-31.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/common/26.0.0/common-26.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/common/26.0.1/common-26.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/common/26.2.1/common-26.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/common/26.5.4/common-26.5.4.pom
@@ -371,7 +356,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/common/30.0.4/common-3
https://dl.google.com/dl/android/maven2/com/android/tools/common/30.2.1/common-30.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/common/30.3.1/common-30.3.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/common/31.1.1/common-31.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/ddms/ddmlib/26.0.0/ddmlib-26.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/ddms/ddmlib/26.0.1/ddmlib-26.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/ddms/ddmlib/26.2.1/ddmlib-26.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/ddms/ddmlib/26.5.4/ddmlib-26.5.4.pom
@@ -380,7 +364,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/ddms/ddmlib/30.0.4/ddm
https://dl.google.com/dl/android/maven2/com/android/tools/ddms/ddmlib/30.2.1/ddmlib-30.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/ddms/ddmlib/30.3.1/ddmlib-30.3.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/ddms/ddmlib/31.1.1/ddmlib-31.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/dvlib/26.0.0/dvlib-26.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/dvlib/26.0.1/dvlib-26.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/dvlib/26.2.1/dvlib-26.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/dvlib/26.5.4/dvlib-26.5.4.pom
@@ -389,14 +372,11 @@ https://dl.google.com/dl/android/maven2/com/android/tools/dvlib/30.0.4/dvlib-30.
https://dl.google.com/dl/android/maven2/com/android/tools/dvlib/30.2.1/dvlib-30.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/dvlib/30.3.1/dvlib-30.3.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/dvlib/31.1.1/dvlib-31.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/external/com-intellij/intellij-core/26.0.0/intellij-core-26.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/external/com-intellij/intellij-core/26.0.1/intellij-core-26.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/external/com-intellij/intellij-core/31.1.1/intellij-core-31.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/external/com-intellij/kotlin-compiler/31.1.1/kotlin-compiler-31.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/external/org-jetbrains/uast/26.0.0/uast-26.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/external/org-jetbrains/uast/26.0.1/uast-26.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/external/org-jetbrains/uast/31.1.1/uast-31.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/layoutlib/layoutlib-api/26.0.0/layoutlib-api-26.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/layoutlib/layoutlib-api/26.0.1/layoutlib-api-26.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/layoutlib/layoutlib-api/26.2.1/layoutlib-api-26.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/layoutlib/layoutlib-api/26.5.4/layoutlib-api-26.5.4.pom
@@ -405,10 +385,8 @@ https://dl.google.com/dl/android/maven2/com/android/tools/layoutlib/layoutlib-ap
https://dl.google.com/dl/android/maven2/com/android/tools/layoutlib/layoutlib-api/30.2.1/layoutlib-api-30.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/layoutlib/layoutlib-api/30.3.1/layoutlib-api-30.3.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/layoutlib/layoutlib-api/31.1.1/layoutlib-api-31.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint-api/26.0.0/lint-api-26.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint-api/26.0.1/lint-api-26.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint-api/31.1.1/lint-api-31.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint-checks/26.0.0/lint-checks-26.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint-checks/26.0.1/lint-checks-26.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint-checks/31.1.1/lint-checks-31.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint-gradle-api/26.2.1/lint-gradle-api-26.2.1.pom
@@ -423,11 +401,9 @@ https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint-model/31.1.1
https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint-typedef-remover/30.2.1/lint-typedef-remover-30.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint-typedef-remover/30.3.1/lint-typedef-remover-30.3.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint-typedef-remover/31.1.1/lint-typedef-remover-31.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint/26.0.0/lint-26.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint/26.0.1/lint-26.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint/31.1.1/lint-31.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/play-sdk-proto/31.1.1/play-sdk-proto-31.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/repository/26.0.0/repository-26.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/repository/26.0.1/repository-26.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/repository/26.2.1/repository-26.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/repository/26.5.4/repository-26.5.4.pom
@@ -436,7 +412,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/repository/30.0.4/repo
https://dl.google.com/dl/android/maven2/com/android/tools/repository/30.2.1/repository-30.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/repository/30.3.1/repository-30.3.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/repository/31.1.1/repository-31.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/sdklib/26.0.0/sdklib-26.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/sdklib/26.0.1/sdklib-26.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/sdklib/26.2.1/sdklib-26.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/sdklib/26.5.4/sdklib-26.5.4.pom
@@ -445,7 +420,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/sdklib/30.0.4/sdklib-3
https://dl.google.com/dl/android/maven2/com/android/tools/sdklib/30.2.1/sdklib-30.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/sdklib/30.3.1/sdklib-30.3.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/sdklib/31.1.1/sdklib-31.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/sdk-common/26.0.0/sdk-common-26.0.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/sdk-common/26.0.1/sdk-common-26.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/sdk-common/26.2.1/sdk-common-26.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/sdk-common/26.5.4/sdk-common-26.5.4.pom
@@ -527,10 +501,10 @@ https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.10/commons-co
https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.11/commons-codec-1.11.pom
https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.16.1/commons-codec-1.16.1.pom
https://repo.maven.apache.org/maven2/commons-io/commons-io/2.4/commons-io-2.4.pom
https://repo.maven.apache.org/maven2/commons-io/commons-io/2.15.1/commons-io-2.15.1.pom
https://repo.maven.apache.org/maven2/commons-io/commons-io/2.16.0/commons-io-2.16.0.pom
https://repo.maven.apache.org/maven2/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.pom
https://repo.maven.apache.org/maven2/commons-logging/commons-logging/1.2/commons-logging-1.2.pom
https://repo.maven.apache.org/maven2/commons-logging/commons-logging/1.3.0/commons-logging-1.3.0.pom
https://repo.maven.apache.org/maven2/commons-logging/commons-logging/1.3.1/commons-logging-1.3.1.pom
https://repo.maven.apache.org/maven2/com/adobe/xmp/xmpcore/6.1.11/xmpcore-6.1.11.pom
https://repo.maven.apache.org/maven2/com/afollestad/material-dialogs/commons/0.9.6.0/commons-0.9.6.0.pom
https://repo.maven.apache.org/maven2/com/afollestad/material-dialogs/core/0.9.6.0/core-0.9.6.0.pom
@@ -630,22 +604,22 @@ https://repo.maven.apache.org/maven2/com/facebook/soloader/soloader/0.10.1/soloa
https://repo.maven.apache.org/maven2/com/facebook/soloader/soloader/0.10.5/soloader-0.10.5.pom
https://repo.maven.apache.org/maven2/com/facebook/yoga/proguard-annotations/1.19.0/proguard-annotations-1.19.0.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.11.1/jackson-annotations-2.11.1.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.17.0-rc1/jackson-annotations-2.17.0-rc1.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.17.0/jackson-annotations-2.17.0.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-core/2.11.1/jackson-core-2.11.1.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-core/2.17.0-rc1/jackson-core-2.17.0-rc1.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-core/2.17.0/jackson-core-2.17.0.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.11.1/jackson-databind-2.11.1.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.17.0-rc1/jackson-databind-2.17.0-rc1.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.17.0/jackson-databind-2.17.0.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/dataformat/jackson-dataformat-xml/2.11.1/jackson-dataformat-xml-2.11.1.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/jackson-base/2.11.1/jackson-base-2.11.1.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/jackson-base/2.17.0-rc1/jackson-base-2.17.0-rc1.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/jackson-base/2.17.0/jackson-base-2.17.0.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/jackson-bom/2.11.1/jackson-bom-2.11.1.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/jackson-bom/2.17.0-rc1/jackson-bom-2.17.0-rc1.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/jackson-bom/2.17.0/jackson-bom-2.17.0.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/jackson-parent/2.11/jackson-parent-2.11.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/jackson-parent/2.17-rc1/jackson-parent-2.17-rc1.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/jackson-parent/2.17/jackson-parent-2.17.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/module/jackson-modules-base/2.11.1/jackson-modules-base-2.11.1.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/module/jackson-modules-base/2.17.0-rc1/jackson-modules-base-2.17.0-rc1.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/module/jackson-modules-base/2.17.0/jackson-modules-base-2.17.0.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/module/jackson-module-jaxb-annotations/2.11.1/jackson-module-jaxb-annotations-2.11.1.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/module/jackson-module-jaxb-annotations/2.17.0-rc1/jackson-module-jaxb-annotations-2.17.0-rc1.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/module/jackson-module-jaxb-annotations/2.17.0/jackson-module-jaxb-annotations-2.17.0.pom
https://repo.maven.apache.org/maven2/com/fasterxml/jackson/module/jackson-module-kotlin/2.11.1/jackson-module-kotlin-2.11.1.pom
https://repo.maven.apache.org/maven2/com/fasterxml/oss-parent/38/oss-parent-38.pom
https://repo.maven.apache.org/maven2/com/fasterxml/oss-parent/58/oss-parent-58.pom
@@ -713,7 +687,7 @@ https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotatio
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.9.0/error_prone_annotations-2.9.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.10.0/error_prone_annotations-2.10.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.11.0/error_prone_annotations-2.11.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.25.0/error_prone_annotations-2.25.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.26.1/error_prone_annotations-2.26.1.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.0.18/error_prone_parent-2.0.18.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.2.0/error_prone_parent-2.2.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.3.1/error_prone_parent-2.3.1.pom
@@ -725,7 +699,7 @@ https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.9.0/error_prone_parent-2.9.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.10.0/error_prone_parent-2.10.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.11.0/error_prone_parent-2.11.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.25.0/error_prone_parent-2.25.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.26.1/error_prone_parent-2.26.1.pom
https://repo.maven.apache.org/maven2/com/google/flatbuffers/flatbuffers-java/1.12.0/flatbuffers-java-1.12.0.pom
https://repo.maven.apache.org/maven2/com/google/google/1/google-1.pom
https://repo.maven.apache.org/maven2/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.pom
@@ -742,8 +716,8 @@ https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/30.1-jre/guav
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/31.0.1-android/guava-parent-31.0.1-android.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/31.0.1-jre/guava-parent-31.0.1-jre.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/31.1-jre/guava-parent-31.1-jre.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/33.0.0-jre/guava-parent-33.0.0-jre.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava-testlib/33.0.0-jre/guava-testlib-33.0.0-jre.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava-parent/33.1.0-jre/guava-parent-33.1.0-jre.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava-testlib/33.1.0-jre/guava-testlib-33.1.0-jre.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava/17.0/guava-17.0.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava/22.0/guava-22.0.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava/23.0/guava-23.0.pom
@@ -756,12 +730,12 @@ https://repo.maven.apache.org/maven2/com/google/guava/guava/30.1-jre/guava-30.1-
https://repo.maven.apache.org/maven2/com/google/guava/guava/31.0.1-android/guava-31.0.1-android.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava/31.0.1-jre/guava-31.0.1-jre.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava/31.1-jre/guava-31.1-jre.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava/33.0.0-jre/guava-33.0.0-jre.pom
https://repo.maven.apache.org/maven2/com/google/guava/guava/33.1.0-jre/guava-33.1.0-jre.pom
https://repo.maven.apache.org/maven2/com/google/guava/listenablefuture/1.0/listenablefuture-1.0.pom
https://repo.maven.apache.org/maven2/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.pom
https://repo.maven.apache.org/maven2/com/google/j2objc/j2objc-annotations/1.1/j2objc-annotations-1.1.pom
https://repo.maven.apache.org/maven2/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.pom
https://repo.maven.apache.org/maven2/com/google/j2objc/j2objc-annotations/2.8/j2objc-annotations-2.8.pom
https://repo.maven.apache.org/maven2/com/google/j2objc/j2objc-annotations/3.0.0/j2objc-annotations-3.0.0.pom
https://repo.maven.apache.org/maven2/com/google/jimfs/jimfs-parent/1.1/jimfs-parent-1.1.pom
https://repo.maven.apache.org/maven2/com/google/jimfs/jimfs/1.1/jimfs-1.1.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-bom/3.7.1/protobuf-bom-3.7.1.pom
@@ -770,7 +744,7 @@ https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-bom/3.13.0/pro
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-bom/3.17.2/protobuf-bom-3.17.2.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-bom/3.19.2/protobuf-bom-3.19.2.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-bom/3.19.3/protobuf-bom-3.19.3.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-bom/4.26.0-RC3/protobuf-bom-4.26.0-RC3.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-bom/4.26.1/protobuf-bom-4.26.1.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-javalite/3.17.2/protobuf-javalite-3.17.2.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-javalite/3.19.2/protobuf-javalite-3.19.2.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java-util/3.4.0/protobuf-java-util-3.4.0.pom
@@ -787,7 +761,7 @@ https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java/3.13.0/pr
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java/3.17.2/protobuf-java-3.17.2.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java/3.19.2/protobuf-java-3.19.2.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java/3.19.3/protobuf-java-3.19.3.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java/4.26.0-RC3/protobuf-java-4.26.0-RC3.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java/4.26.1/protobuf-java-4.26.1.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-lite/3.0.1/protobuf-lite-3.0.1.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/3.0.0/protobuf-parent-3.0.0.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/3.4.0/protobuf-parent-3.4.0.pom
@@ -798,7 +772,7 @@ https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/3.13.0/
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/3.17.2/protobuf-parent-3.17.2.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/3.19.2/protobuf-parent-3.19.2.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/3.19.3/protobuf-parent-3.19.3.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/4.26.0-RC3/protobuf-parent-4.26.0-RC3.pom
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/4.26.1/protobuf-parent-4.26.1.pom
https://repo.maven.apache.org/maven2/com/google/truth/truth-parent/1.4.2/truth-parent-1.4.2.pom
https://repo.maven.apache.org/maven2/com/google/truth/truth/1.4.2/truth-1.4.2.pom
https://repo.maven.apache.org/maven2/com/ibm/icu/icu4j/53.1/icu4j-53.1.pom
@@ -815,7 +789,7 @@ https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp/3.12.1/okhttp-3
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp/4.9.2/okhttp-4.9.2.pom
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/parent/3.9.1/parent-3.9.1.pom
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/parent/3.12.1/parent-3.12.1.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-jvm/3.8.0/okio-jvm-3.8.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-jvm/3.9.0/okio-jvm-3.9.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-metadata/2.8.0/okio-metadata-2.8.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-parent/1.13.0/okio-parent-1.13.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-parent/1.15.0/okio-parent-1.15.0.pom
@@ -825,7 +799,7 @@ https://repo.maven.apache.org/maven2/com/squareup/okio/okio/1.15.0/okio-1.15.0.p
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/1.17.4/okio-1.17.4.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.8.0/okio-2.8.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.9.0/okio-2.9.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/3.8.0/okio-3.8.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/3.9.0/okio-3.9.0.pom
https://repo.maven.apache.org/maven2/com/sun/activation/all/1.2.0/all-1.2.0.pom
https://repo.maven.apache.org/maven2/com/sun/activation/all/1.2.1/all-1.2.1.pom
https://repo.maven.apache.org/maven2/com/sun/activation/all/1.2.2/all-1.2.2.pom
@@ -841,18 +815,18 @@ https://repo.maven.apache.org/maven2/com/sun/istack/istack-commons/4.2.0/istack-
https://repo.maven.apache.org/maven2/com/sun/xml/bind/jaxb-bom-ext/2.2.11/jaxb-bom-ext-2.2.11.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/jaxb-bom-ext/2.3.1/jaxb-bom-ext-2.3.1.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/jaxb-bom-ext/2.3.2/jaxb-bom-ext-2.3.2.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/jaxb-bom-ext/4.0.4/jaxb-bom-ext-4.0.4.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/jaxb-bom-ext/4.0.5/jaxb-bom-ext-4.0.5.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-parent/2.2.11/jaxb-parent-2.2.11.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-parent/2.3.1/jaxb-parent-2.3.1.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-parent/2.3.2/jaxb-parent-2.3.2.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-parent/4.0.4/jaxb-parent-4.0.4.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-parent/4.0.5/jaxb-parent-4.0.5.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-runtime-parent/2.2.11/jaxb-runtime-parent-2.2.11.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-runtime-parent/2.3.1/jaxb-runtime-parent-2.3.1.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-runtime-parent/2.3.2/jaxb-runtime-parent-2.3.2.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-txw-parent/2.2.11/jaxb-txw-parent-2.2.11.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-txw-parent/2.3.1/jaxb-txw-parent-2.3.1.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-txw-parent/2.3.2/jaxb-txw-parent-2.3.2.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-txw-parent/4.0.4/jaxb-txw-parent-4.0.4.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-txw-parent/4.0.5/jaxb-txw-parent-4.0.5.pom
https://repo.maven.apache.org/maven2/com/sun/xml/fastinfoset/FastInfoset/1.2.13/FastInfoset-1.2.13.pom
https://repo.maven.apache.org/maven2/com/sun/xml/fastinfoset/FastInfoset/1.2.15/FastInfoset-1.2.15.pom
https://repo.maven.apache.org/maven2/com/sun/xml/fastinfoset/FastInfoset/1.2.16/FastInfoset-1.2.16.pom
@@ -931,9 +905,9 @@ https://repo.maven.apache.org/maven2/io/netty/netty-resolver/4.1.52.Final/netty-
https://repo.maven.apache.org/maven2/io/netty/netty-resolver/4.1.72.Final/netty-resolver-4.1.72.Final.pom
https://repo.maven.apache.org/maven2/io/netty/netty-resolver/5.0.0.Alpha2/netty-resolver-5.0.0.Alpha2.pom
https://repo.maven.apache.org/maven2/io/netty/netty-tcnative-classes/2.0.46.Final/netty-tcnative-classes-2.0.46.Final.pom
https://repo.maven.apache.org/maven2/io/netty/netty-tcnative-classes/2.0.63.Final/netty-tcnative-classes-2.0.63.Final.pom
https://repo.maven.apache.org/maven2/io/netty/netty-tcnative-classes/2.0.65.Final/netty-tcnative-classes-2.0.65.Final.pom
https://repo.maven.apache.org/maven2/io/netty/netty-tcnative-parent/2.0.46.Final/netty-tcnative-parent-2.0.46.Final.pom
https://repo.maven.apache.org/maven2/io/netty/netty-tcnative-parent/2.0.63.Final/netty-tcnative-parent-2.0.63.Final.pom
https://repo.maven.apache.org/maven2/io/netty/netty-tcnative-parent/2.0.65.Final/netty-tcnative-parent-2.0.65.Final.pom
https://repo.maven.apache.org/maven2/io/netty/netty-transport/4.1.34.Final/netty-transport-4.1.34.Final.pom
https://repo.maven.apache.org/maven2/io/netty/netty-transport/4.1.52.Final/netty-transport-4.1.52.Final.pom
https://repo.maven.apache.org/maven2/io/netty/netty-transport/4.1.72.Final/netty-transport-4.1.72.Final.pom
@@ -947,9 +921,9 @@ https://repo.maven.apache.org/maven2/jakarta/activation/jakarta.activation-api/1
https://repo.maven.apache.org/maven2/jakarta/activation/jakarta.activation-api/1.2.2/jakarta.activation-api-1.2.2.pom
https://repo.maven.apache.org/maven2/jakarta/activation/jakarta.activation-api/2.1.3/jakarta.activation-api-2.1.3.pom
https://repo.maven.apache.org/maven2/jakarta/xml/bind/jakarta.xml.bind-api-parent/2.3.2/jakarta.xml.bind-api-parent-2.3.2.pom
https://repo.maven.apache.org/maven2/jakarta/xml/bind/jakarta.xml.bind-api-parent/4.0.1/jakarta.xml.bind-api-parent-4.0.1.pom
https://repo.maven.apache.org/maven2/jakarta/xml/bind/jakarta.xml.bind-api-parent/4.0.2/jakarta.xml.bind-api-parent-4.0.2.pom
https://repo.maven.apache.org/maven2/jakarta/xml/bind/jakarta.xml.bind-api/2.3.2/jakarta.xml.bind-api-2.3.2.pom
https://repo.maven.apache.org/maven2/jakarta/xml/bind/jakarta.xml.bind-api/4.0.1/jakarta.xml.bind-api-4.0.1.pom
https://repo.maven.apache.org/maven2/jakarta/xml/bind/jakarta.xml.bind-api/4.0.2/jakarta.xml.bind-api-4.0.2.pom
https://repo.maven.apache.org/maven2/javax/activation/activation/1.1/activation-1.1.pom
https://repo.maven.apache.org/maven2/javax/activation/javax.activation-api/1.2.0/javax.activation-api-1.2.0.pom
https://repo.maven.apache.org/maven2/javax/annotation/javax.annotation-api/1.3.2/javax.annotation-api-1.3.2.pom
@@ -1036,8 +1010,8 @@ https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/39/common
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/42/commons-parent-42.pom
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/48/commons-parent-48.pom
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/52/commons-parent-52.pom
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/65/commons-parent-65.pom
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/66/commons-parent-66.pom
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/67/commons-parent-67.pom
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpclient/4.1.1/httpclient-4.1.1.pom
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpclient/4.2.6/httpclient-4.2.6.pom
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpclient/4.5.2/httpclient-4.5.2.pom
@@ -1123,7 +1097,6 @@ https://repo.maven.apache.org/maven2/org/eclipse/ee4j/project/1.0.2/project-1.0.
https://repo.maven.apache.org/maven2/org/eclipse/ee4j/project/1.0.5/project-1.0.5.pom
https://repo.maven.apache.org/maven2/org/eclipse/ee4j/project/1.0.6/project-1.0.6.pom
https://repo.maven.apache.org/maven2/org/eclipse/ee4j/project/1.0.7/project-1.0.7.pom
https://repo.maven.apache.org/maven2/org/eclipse/ee4j/project/1.0.8/project-1.0.8.pom
https://repo.maven.apache.org/maven2/org/eclipse/ee4j/project/1.0.9/project-1.0.9.pom
https://repo.maven.apache.org/maven2/org/eclipse/jdt/core/compiler/ecj/4.4.2/ecj-4.4.2.pom
https://repo.maven.apache.org/maven2/org/eclipse/jdt/core/compiler/ecj/4.6.1/ecj-4.6.1.pom
@@ -1137,16 +1110,16 @@ https://repo.maven.apache.org/maven2/org/fusesource/jansi/jansi/1.18/jansi-1.18.
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-bom/2.2.11/jaxb-bom-2.2.11.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-bom/2.3.1/jaxb-bom-2.3.1.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-bom/2.3.2/jaxb-bom-2.3.2.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-bom/4.0.4/jaxb-bom-4.0.4.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-bom/4.0.5/jaxb-bom-4.0.5.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-core/2.2.11/jaxb-core-2.2.11.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-core/4.0.4/jaxb-core-4.0.4.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-core/4.0.5/jaxb-core-4.0.5.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-runtime/2.2.11/jaxb-runtime-2.2.11.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-runtime/2.3.1/jaxb-runtime-2.3.1.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-runtime/2.3.2/jaxb-runtime-2.3.2.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/txw2/2.2.11/txw2-2.2.11.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/txw2/2.3.1/txw2-2.3.1.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/txw2/2.3.2/txw2-2.3.2.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/txw2/4.0.4/txw2-4.0.4.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/txw2/4.0.5/txw2-4.0.5.pom
https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.pom
https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-core/2.2/hamcrest-core-2.2.pom
https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-parent/1.3/hamcrest-parent-1.3.pom
@@ -1250,7 +1223,7 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.6.10/
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.6.20/kotlin-reflect-1.6.20.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.7.22/kotlin-reflect-1.7.22.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.8.20-RC2/kotlin-reflect-1.8.20-RC2.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/2.0.0-Beta4/kotlin-reflect-2.0.0-Beta4.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/2.0.0-Beta5/kotlin-reflect-2.0.0-Beta5.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-common/1.6.20/kotlin-scripting-common-1.6.20.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-common/1.7.22/kotlin-scripting-common-1.7.22.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-common/1.8.0/kotlin-scripting-common-1.8.0.pom
@@ -1352,7 +1325,7 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.8.20-R
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.8.21/kotlin-stdlib-1.8.21.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.0/kotlin-stdlib-1.9.0.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.21/kotlin-stdlib-1.9.21.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/2.0.0-Beta4/kotlin-stdlib-2.0.0-Beta4.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/2.0.0-Beta5/kotlin-stdlib-2.0.0-Beta5.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-tooling-core/1.7.22/kotlin-tooling-core-1.7.22.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-tooling-core/1.8.0/kotlin-tooling-core-1.8.0.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-tooling-core/1.9.0/kotlin-tooling-core-1.9.0.pom
@@ -1391,14 +1364,14 @@ https://repo.maven.apache.org/maven2/org/ow2/asm/asm-analysis/7.0/asm-analysis-7
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-analysis/8.0.1/asm-analysis-8.0.1.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-analysis/9.1/asm-analysis-9.1.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-analysis/9.2/asm-analysis-9.2.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-bom/9.6/asm-bom-9.6.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-bom/9.7/asm-bom-9.7.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-commons/5.1/asm-commons-5.1.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-commons/6.0/asm-commons-6.0.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-commons/7.0/asm-commons-7.0.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-commons/8.0.1/asm-commons-8.0.1.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-commons/9.1/asm-commons-9.1.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-commons/9.2/asm-commons-9.2.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-commons/9.6/asm-commons-9.6.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-commons/9.7/asm-commons-9.7.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-debug-all/5.0.1/asm-debug-all-5.0.1.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-debug-all/6.0_BETA/asm-debug-all-6.0_BETA.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-parent/5.0.1/asm-parent-5.0.1.pom
@@ -1413,7 +1386,7 @@ https://repo.maven.apache.org/maven2/org/ow2/asm/asm-tree/7.0/asm-tree-7.0.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-tree/8.0.1/asm-tree-8.0.1.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-tree/9.1/asm-tree-9.1.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-tree/9.2/asm-tree-9.2.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-tree/9.6/asm-tree-9.6.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-tree/9.7/asm-tree-9.7.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-util/5.1/asm-util-5.1.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-util/6.0/asm-util-6.0.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm-util/7.0/asm-util-7.0.pom
@@ -1427,7 +1400,7 @@ https://repo.maven.apache.org/maven2/org/ow2/asm/asm/7.0/asm-7.0.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm/8.0.1/asm-8.0.1.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.1/asm-9.1.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.2/asm-9.2.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.6/asm-9.6.pom
https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.7/asm-9.7.pom
https://repo.maven.apache.org/maven2/org/ow2/ow2/1.3/ow2-1.3.pom
https://repo.maven.apache.org/maven2/org/ow2/ow2/1.5.1/ow2-1.5.1.pom
https://repo.maven.apache.org/maven2/org/ow2/ow2/1.5/ow2-1.5.pom
-3
View File
@@ -16,12 +16,10 @@ react-native-dialogs
react-native-fast-image
react-native-fs
react-native-gesture-handler
react-native-haptic-feedback
react-native-hole-view
react-native-image-crop-picker
react-native-image-resizer
react-native-keychain
react-native-languages
react-native-linear-gradient
react-native-lottie-splash-screen
react-native-mail
@@ -29,7 +27,6 @@ react-native-navigation
react-native-nfc-manager
react-native-orientation-locker
react-native-permissions
react-native-randombytes
react-native-reanimated
react-native-shake
react-native-share
+9 -43
View File
@@ -4,16 +4,16 @@
{ stdenv, deps, nodejs, patchMavenSources }:
let
patchesDir = ./../../../patches;
patches = builtins.attrNames (builtins.readDir patchesDir);
in
stdenv.mkDerivation {
name = "${deps.nodejs.name}-patched";
phases = [
"unpackPhase"
"patchGradlePhase"
"patchBuildIdPhase"
"patchKeyChainPhase"
"patchGlogPhase"
"patchNativeNavigationPhase"
"patchRNScriptPhase"
"patchNodeLibsPhase"
"installPhase"
];
@@ -50,49 +50,15 @@ stdenv.mkDerivation {
done
'';
# Do not add a BuildId to the generated libraries, for reproducibility
patchBuildIdPhase = ''
substituteInPlace ./node_modules/react-native/ReactAndroid/src/main/jni/CMakeLists.txt --replace \
'-Wl,--build-id' \
'-Wl,--build-id=none'
'';
installPhase = ''
mkdir -p $out
cp -R node_modules $out/
'';
# Remove gradle-test-logger-plugin:
# https://github.com/oblador/react-native-keychain/issues/595
# TODO: remove this patch when we this library fixes above issue
patchKeyChainPhase = ''
sed -i -e '/classpath/d' \
-e '/apply plugin: "com\.adarshr\.test-logger"/d' \
./node_modules/react-native-keychain/android/build.gradle
'';
# Fix pod issue after upgrading to MacOS Sonoma and Xcode 15
# https://github.com/status-im/status-mobile/issues/17682
patchGlogPhase = ''
substituteInPlace ./node_modules/react-native/scripts/ios-configure-glog.sh \
--replace 'export CC="' '#export CC="' \
--replace 'export CXX="' '#export CXX="'
'';
# https://github.com/wix/react-native-navigation/issues/7819
patchNativeNavigationPhase = ''
substituteInPlace ./node_modules/react-native-navigation/lib/android/app/build.gradle \
--replace 'JavaVersion.VERSION_1_8' 'JavaVersion.VERSION_17'
substituteInPlace ./node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/button/ButtonPresenter.kt \
--replace 'host: View?,' 'host: View,' \
--replace 'info: AccessibilityNodeInfoCompat?' 'info: AccessibilityNodeInfoCompat'
'';
# to fix https://github.com/status-im/status-mobile/issues/18548
patchRNScriptPhase = ''
substituteInPlace ./node_modules/react-native/scripts/react_native_pods_utils/script_phases.sh \
--replace 'cp -R -X' 'cp -R'
patchNodeLibsPhase = ''
for patch in ${toString patches}; do
patch -p1 < ${patchesDir}/$patch
done
'';
# The ELF types are incompatible with the host platform, so let's not even try
-1
View File
@@ -27,7 +27,6 @@ deps node_modules
> ls node_modules | grep react-native-image
react-native-image-crop-picker
react-native-image-resizer
react-native-image-viewing
```
# Known Issues
+11 -7
View File
@@ -51,7 +51,7 @@ in {
};
# Package version adjustments
gradle = super.gradle_8_3;
gradle = super.gradle_8;
nodejs = super.nodejs-18_x;
ruby = super.ruby_3_1;
yarn = super.yarn.override { nodejs = super.nodejs-18_x; };
@@ -65,10 +65,16 @@ in {
buildGoPackage = super.buildGo119Package;
buildGoModule = super.buildGo119Module;
gomobile = (super.gomobile.overrideAttrs (old: {
patches = self.fetchurl { # https://github.com/golang/mobile/pull/84
url = "https://github.com/golang/mobile/commit/f20e966e05b8f7e06bed500fa0da81cf6ebca307.patch";
sha256 = "sha256-TZ/Yhe8gMRQUZFAs9G5/cf2b9QGtTHRSObBFD5Pbh7Y=";
};
patches = [
(self.fetchurl { # https://github.com/golang/mobile/pull/84
url = "https://github.com/golang/mobile/commit/f20e966e05b8f7e06bed500fa0da81cf6ebca307.patch";
sha256 = "sha256-TZ/Yhe8gMRQUZFAs9G5/cf2b9QGtTHRSObBFD5Pbh7Y=";
})
(self.fetchurl { # https://github.com/golang/go/issues/58426
url = "https://github.com/golang/mobile/commit/406ed3a7b8e44dc32844953647b49696d8847d51.patch";
sha256 = "sha256-dqbYukHkQEw8npOkKykOAzMC3ot/Y4DEuh7fE+ptlr8=";
})
];
})).override {
# FIXME: No Android SDK packages for aarch64-darwin.
withAndroidPkgs = stdenv.system != "aarch64-darwin";
@@ -84,6 +90,4 @@ in {
aapt2 = callPackage ./pkgs/aapt2 { };
patchMavenSources = callPackage ./pkgs/patch-maven-srcs { };
goMavenResolver = callPackage ./pkgs/go-maven-resolver { };
xcbeautify = callPackage ./pkgs/xcbeautify { };
idb-companion = callPackage ./pkgs/idb-companion { };
}
+4 -3
View File
@@ -6,10 +6,11 @@ let
# For testing local version of nixpkgs
#nixpkgsSrc = (import <nixpkgs> { }).lib.cleanSource "/home/jakubgs/work/nixpkgs";
# We follow a fork of nixpkgs where we bump gradle to 8.3 and update build tools
# We follow release 23-11 of nixpkgs
# https://github.com/NixOS/nixpkgs/releases/tag/23.11
nixpkgsSrc = builtins.fetchTarball {
url = "https://github.com/status-im/nixpkgs/archive/44d8b23ebbe40ed16ef1aecef6c5354657c48b19.tar.gz";
sha256 = "sha256:0s7kjnc8drchzp268yzbv5snc4702hswcns9hrncjq4im8cv6mf9";
url = "https://github.com/NixOS/nixpkgs/archive/224fd9a362487ab2894dac0df161c84ab1d8880b.tar.gz";
sha256 = "sha256:1syvl39pi1h8lf5gkd9h7ksn5hp34cj7pa3abr59217kv0bdklhy";
};
# Status specific configuration defaults
-29
View File
@@ -1,29 +0,0 @@
{ stdenv, fetchurl, lib }:
stdenv.mkDerivation rec {
pname = "idb-companion";
version = "1.1.8";
src = fetchurl {
url = "https://github.com/facebook/idb/releases/download/v${version}/idb-companion.universal.tar.gz";
sha256 = "sha256-O3LMappbGiKhiCBahAkNOilDR6hGGA79dVzxo8hI4+c=";
};
buildInputs = [ ];
unpackPhase = ''
tar -xzf $src
'';
installPhase = ''
mkdir -p $out/bin
cp -r ./* $out/bin/
'';
meta = with lib; {
description = "A powerful command line tool for automating iOS simulators and devices";
homepage = "https://github.com/facebook/idb";
license = licenses.mit;
platforms = platforms.darwin;
};
}
-36
View File
@@ -1,36 +0,0 @@
{ stdenv, fetchurl, unzip, lib }:
let
inherit (lib) getAttr;
in
stdenv.mkDerivation rec {
pname = "xcbeautify";
version = "1.4.0";
arch = if stdenv.hostPlatform.isAarch64 then "arm64" else "x86_64";
src = fetchurl {
url = "https://github.com/cpisciotta/xcbeautify/releases/download/${version}/xcbeautify-${version}-${arch}-apple-macosx.zip";
sha256 = getAttr arch {
arm64 = "sha256-4b4mXT5IfNOS8iOrZASDhTrmOehG4mePcoiKxR+IdZk=";
x86_64 = "sha256-adEfAK7n3Q/Yd1deyJx7htX7hZaGDztEeBv4z2A0wzg=";
};
};
buildInputs = [ unzip ];
unpackPhase = ''
unzip $src
'';
installPhase = ''
install -D xcbeautify $out/bin/xcbeautify
'';
meta = with lib; {
description = "A little beautifier tool for xcodebuild";
homepage = "https://github.com/cpisciotta/xcbeautify";
license = licenses.mit;
platforms = platforms.darwin;
};
}
+1
View File
@@ -27,6 +27,7 @@ nix_install_type() {
if [[ "$(os_name)" =~ NixOS ]]; then
echo "nixos"
else
USER=$(id -un) # Missing in Docker.
case "${NIX_STORE_DIR_GROUP}" in
"nixbld") echo "multi";;
"30000") echo "multi";;
+2 -9
View File
@@ -8,7 +8,6 @@
"preinstall": "scripts/check-nix-shell.sh && make status-go-library"
},
"dependencies": {
"@babel/preset-typescript": "^7.17.12",
"@react-native-async-storage/async-storage": "1.19.3",
"@react-native-camera-roll/camera-roll": "git+https://github.com/status-im/react-native-camera-roll.git#refs/tags/v5.1.1.1",
"@react-native-clipboard/clipboard": "1.13.2",
@@ -22,7 +21,6 @@
"base-64": "^1.0.0",
"bignumber.js": "git+https://github.com/status-im/bignumber.js.git#refs/tags/v4.0.2-status",
"chance": "^1.1.0",
"create-react-class": "^15.6.2",
"emojilib": "^2.4.0",
"eth-phishing-detect": "^1.2.0",
"form-data": "^4.0.0",
@@ -44,22 +42,19 @@
"react-native-fs": "^2.14.1",
"react-native-gesture-handler": "2.14.1",
"react-native-gifted-charts": "^1.3.2",
"react-native-haptic-feedback": "^1.9.0",
"react-native-hole-view": "^3.0.0-alpha4",
"react-native-image-crop-picker": "0.40.0",
"react-native-image-resizer": "^1.2.3",
"react-native-image-viewing": "git+https://github.com/status-im/react-native-image-viewing.git#refs/tags/v0.2.1.status",
"react-native-keychain": "8.1.2",
"react-native-languages": "^3.0.2",
"react-native-linear-gradient": "^2.8.0",
"react-native-lottie-splash-screen": "^1.0.1",
"react-native-mail": "git+https://github.com/status-im/react-native-mail.git#refs/tags/v6.1.2-status",
"react-native-navigation": "7.38.3",
"react-native-orientation-locker": "^1.5.0",
"react-native-permissions": "3.8.0",
"react-native-randombytes": "^3.6.1",
"react-native-reanimated": "3.6.1",
"react-native-redash": "18.1.0",
"react-native-shadow-2": "^7.0.8",
"react-native-shake": "^3.3.1",
"react-native-share": "10.0.2",
"react-native-static-safe-area-insets": "^2.2.0",
@@ -67,9 +62,7 @@
"react-native-svg": "13.10.0",
"react-native-transparent-video": "git+https://github.com/status-im/react-native-transparent-video.git#refs/tags/0.1.1",
"react-native-webview": "13.6.3",
"react-syntax-highlighter": "^15.5.0",
"rn-emoji-keyboard": "0.7.0",
"tdigest": "^0.1.1"
"react-syntax-highlighter": "^15.5.0"
},
"devDependencies": {
"@babel/core": "^7.20.0",
+12
View File
@@ -0,0 +1,12 @@
# Do not add a BuildId to the generated libraries, for reproducibility
--- ./node_modules/react-native/ReactAndroid/src/main/jni/CMakeLists.txt
+++ ./node_modules/react-native/ReactAndroid/src/main/jni/CMakeLists-patched.txt
@@ -21,7 +21,7 @@
endif(CCACHE_FOUND)
# Make sure every shared lib includes a .note.gnu.build-id header
-add_link_options(-Wl,--build-id)
+add_link_options(-Wl,--build-id=none)
add_compile_options(-Wall -Werror -std=c++20)
function(add_react_android_subdir relative_path)
+20
View File
@@ -0,0 +1,20 @@
# Remove gradle-test-logger-plugin:
# https://github.com/oblador/react-native-keychain/issues/595
# TODO: remove this patch when we this library fixes above issue
--- ./node_modules/react-native-keychain/android/build.gradle
+++ ./node_modules/react-native-keychain/android/build-patched.gradle
@@ -4,13 +4,9 @@
url 'https://plugins.gradle.org/m2/'
}
}
- dependencies {
- classpath 'com.adarshr:gradle-test-logger-plugin:2.0.0'
- }
}
apply plugin: 'com.android.library'
-apply plugin: "com.adarshr.test-logger"
def safeExtGet(prop, fallback) {
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
@@ -0,0 +1,22 @@
# https://github.com/wix/react-native-navigation/issues/7819
--- ./node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/button/ButtonPresenter.kt
+++ ./node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/button/ButtonPresenter-patched.kt
@@ -194,8 +194,8 @@
class WixAccessibilityDelegateCompat: AccessibilityDelegateCompat(){
override fun onInitializeAccessibilityNodeInfo(
- host: View?,
- info: AccessibilityNodeInfoCompat?
+ host: View,
+ info: AccessibilityNodeInfoCompat
) {
super.onInitializeAccessibilityNodeInfo(host, info)
@@ -216,4 +216,4 @@
}
-}
\ No newline at end of file
+}
+19
View File
@@ -0,0 +1,19 @@
# https://github.com/wix/react-native-navigation/issues/7819
--- ./node_modules/react-native-navigation/lib/android/app/build.gradle
+++ ./node_modules/react-native-navigation/lib/android/app/build-patched.gradle
@@ -62,11 +62,11 @@
}
}
compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
+ sourceCompatibility JavaVersion.VERSION_17
+ targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
- jvmTarget = JavaVersion.VERSION_1_8
+ jvmTarget = JavaVersion.VERSION_17
}
flavorDimensions "RNN.reactNativeVersion"
+13
View File
@@ -0,0 +1,13 @@
# to fix https://github.com/status-im/status-mobile/issues/18548
--- ./node_modules/react-native/scripts/react_native_pods_utils/script_phases.sh
+++ ./node_modules/react-native/scripts/react_native_pods_utils/script_phases-patched.sh
@@ -104,7 +104,7 @@
mkdir -p "$RCT_SCRIPT_OUTPUT_DIR"
# Copy all output to output_dir
- cp -R -X "$TEMP_OUTPUT_DIR/." "$RCT_SCRIPT_OUTPUT_DIR" || exit 1
+ cp -R "$TEMP_OUTPUT_DIR/." "$RCT_SCRIPT_OUTPUT_DIR" || exit 1
echo "$LIBRARY_NAME output has been written to $RCT_SCRIPT_OUTPUT_DIR:" >> "${SCRIPT_OUTPUT_FILE_0}" 2>&1
ls -1 "$RCT_SCRIPT_OUTPUT_DIR" >> "${SCRIPT_OUTPUT_FILE_0}" 2>&1
}
+15
View File
@@ -0,0 +1,15 @@
# Fix pod issue after upgrading to MacOS Sonoma and Xcode 15
# https://github.com/status-im/status-mobile/issues/17682
--- ./node_modules/react-native/scripts/ios-configure-glog.sh
+++ ./node_modules/react-native/scripts/ios-configure-glog-patched.sh
@@ -42,9 +42,6 @@
patch -p1 config.sub fix_glog_0.3.5_apple_silicon.patch
fi
-export CC="$(xcrun -find -sdk $PLATFORM_NAME cc) -arch $CURRENT_ARCH -isysroot $(xcrun -sdk $PLATFORM_NAME --show-sdk-path)"
-export CXX="$CC"
-
# Remove automake symlink if it exists
if [ -h "test-driver" ]; then
rm test-driver
Binary file not shown.

After

Width:  |  Height:  |  Size: 750 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 889 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

+45
View File
@@ -0,0 +1,45 @@
#!/usr/bin/env bash
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
read -p "Enter the path of the file to patch: " FILE_PATH
if [ ! -f "${FILE_PATH}" ]; then
echo "File not found: ${FILE_PATH}" >&2
exit 1
fi
if [[ "${FILE_PATH}" == *"node_modules"* ]]; then
if [[ "${FILE_PATH}" != *"./node_modules"* ]]; then
echo "Please prefix the file path like this './node_modules/'. The path you provided was: ${FILE_PATH}" >&2
exit 1
fi
fi
FILE_NAME=$(basename "${FILE_PATH}")
echo "File to patch: ${FILE_PATH}"
TEMP_DIR=$(mktemp -d)
trap 'rm -rf "${TEMP_DIR}"' EXIT
echo "Temporary directory created: ${TEMP_DIR}"
cp "${FILE_PATH}" "${TEMP_DIR}"
echo "Original file copied to temporary directory."
echo "Please make the necessary changes to the file: ${FILE_PATH}"
echo "Press any key when you are done with the changes..."
ORIGINAL_MTIME=$(stat -c %Y "${FILE_PATH}")
read -n 1 -s
CURRENT_MTIME=$(stat -c %Y "${FILE_PATH}")
if [[ "${ORIGINAL_MTIME}" -eq "${CURRENT_MTIME}" ]]; then
echo "Warning: No changes were made to the file. Patch file will not be generated."
exit 0
fi
echo "Generating patch file..."
diff -Naur "${TEMP_DIR}/${FILE_NAME}" "${FILE_PATH}" > "${GIT_ROOT}/patches/${FILE_NAME}.patch"
echo "Patch file created at ${GIT_ROOT}/patches/${FILE_NAME}.patch"
echo "Info: Please execute 'make run-clojure' to test if the patch file works as expected."
+2 -1
View File
@@ -6,6 +6,7 @@ GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
XCRUN_INSTALL_LOG_FILE="${GIT_ROOT}/logs/xcrun_install.log"
XCRUN_LAUNCH_LOG_FILE="${GIT_ROOT}/logs/xcrun_launch.log"
XCRUN_SIMULATOR_JSON_FILE="${GIT_ROOT}/logs/ios_simulators_list.log"
XCODEBUILD_LOG_FILE="${GIT_ROOT}/logs/react-native-xcode.log"
# Install on the simulator
installAndLaunchApp() {
@@ -60,7 +61,7 @@ open -a Simulator --args -CurrentDeviceUDID "${UDID}"
BUILD_DIR="${GIT_ROOT}/build"
#iOS build of debug scheme
xcodebuild -workspace "ios/StatusIm.xcworkspace" -configuration Debug -scheme StatusIm -destination id="${UDID}" -derivedDataPath "${BUILD_DIR}" -verbose | xcbeautify
xcodebuild -workspace "ios/StatusIm.xcworkspace" -configuration Debug -scheme StatusIm -destination id="${UDID}" -derivedDataPath "${BUILD_DIR}" -verbose | xcbeautify | tee -a "${XCODEBUILD_LOG_FILE}" 2>&1
APP_PATH="${BUILD_DIR}/Build/Products/Debug-iphonesimulator/StatusIm.app"
+6 -3
View File
@@ -1,5 +1,8 @@
#!/usr/bin/env bash
pkill -f 'react-native start'
react-native start --reset-cache
if pgrep -f 'react-native start' > /dev/null; then
echo "Info: metro is already running in another terminal"
else
echo "Info: starting a new metro terminal"
react-native start --reset-cache
fi
+24 -1
View File
@@ -1,4 +1,4 @@
import { useDerivedValue, withTiming } from 'react-native-reanimated';
import { useDerivedValue, withTiming, withDelay } from 'react-native-reanimated';
export function scrollDownButtonOpacity(chatListScrollY, isComposerFocused, windowHeight) {
return useDerivedValue(function () {
@@ -24,3 +24,26 @@ export function jumpToButtonPosition(scrollDownButtonOpacity, isComposerFocused)
return withTiming(scrollDownButtonOpacity.value == 1 || isComposerFocused.value ? 35 : 0);
});
}
export function composerContainerOpacity(isComposerFocused, isEmptyInput, emptyOpacity) {
return useDerivedValue(function () {
'worklet';
return isEmptyInput.value && !isComposerFocused.value
? withDelay(300, withTiming(emptyOpacity, { duration: 0 }))
: 1;
});
}
export function blurContainerElevation(isComposerFocused, isEmptyInput) {
return useDerivedValue(function () {
'worklet';
return isEmptyInput.value && !isComposerFocused.value ? 10 : 0;
});
}
export function composerElevation(isComposerFocused, isEmptyInput) {
return useDerivedValue(function () {
'worklet';
return isEmptyInput.value && !isComposerFocused.value ? 0 : 10;
});
}
+14
View File
@@ -0,0 +1,14 @@
import { useAnimatedStyle, withTiming } from 'react-native-reanimated';
export function profileHeaderAnimation(scrollY, threshold, topBarHeight) {
return useAnimatedStyle(() => {
'worklet';
const opacity = scrollY.value < threshold ? withTiming(0) : withTiming(1);
const translateY = scrollY.value < threshold ? withTiming(topBarHeight) : withTiming(0);
return {
opacity: opacity,
transform: [{ translateY: translateY }],
};
});
}
-131
View File
@@ -1,131 +0,0 @@
(ns legacy.status-im.bootnodes.core
(:require
[clojure.string :as string]
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
[re-frame.core :as re-frame]
[status-im.navigation.events :as navigation]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(def address-regex #"enode://[a-zA-Z0-9]+:?(.*)\@\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b:(\d{1,5})")
(defn valid-address?
[address]
(re-matches address-regex address))
(defn- build
[id bootnode-name address chain]
{:address address
:chain chain
:id (string/replace id "-" "")
:name bootnode-name})
(rf/defn fetch
[cofx id]
(let [network (get-in cofx [:db :networks/current-network])]
(get-in cofx [:db :profile/profile :custom-bootnodes network id])))
(rf/defn set-input
{:events [:bootnodes.ui/input-changed]}
[{:keys [db]} input-key value]
{:db (update
db
:bootnodes/manage
assoc
input-key
{:value value
:error (case input-key
:id false
:name (string/blank? value)
:url (not (valid-address? value)))})})
(rf/defn edit
{:events [:bootnodes.ui/add-bootnode-pressed]}
[{:keys [db] :as cofx} id]
(let [{:keys [id
address
name]}
(fetch cofx id)
fxs (rf/merge cofx
(set-input :id id)
(set-input :url (str address))
(set-input :name (str name)))]
(assoc fxs :dispatch [:navigate-to :edit-bootnode])))
(defn custom-bootnodes-in-use?
[{:keys [db]}]
(let [network (:networks/current-network db)]
(get-in db [:profile/profile :custom-bootnodes-enabled? network])))
(rf/defn delete
[{{:profile/keys [profile] :as db} :db :as cofx} id]
(let [network (:networks/current-network db)
new-profile (update-in profile [:custom-bootnodes network] dissoc id)]
(rf/merge cofx
{:db (assoc db :profile/profile new-profile)}
(multiaccounts.update/multiaccount-update
:custom-bootnodes
(:custom-bootnodes new-profile)
{:success-event (when (custom-bootnodes-in-use? cofx)
[:multiaccounts.update.callback/save-settings-success])}))))
(rf/defn upsert
{:events [:bootnodes.ui/save-pressed]
:interceptors [(re-frame/inject-cofx :random-id-generator)]}
[{{:bootnodes/keys [manage] :profile/keys [profile] :as db} :db
random-id-generator :random-id-generator
:as cofx}]
(let [{:keys [name id url]} manage
network (:networks/current-network db)
bootnode (build
(or (:value id) (random-id-generator))
(:value name)
(:value url)
network)
new-bootnodes (assoc-in
(:custom-bootnodes profile)
[network (:id bootnode)]
bootnode)]
(rf/merge cofx
{:db (dissoc db :bootnodes/manage)
:dispatch [:navigate-back]}
(multiaccounts.update/multiaccount-update
:custom-bootnodes
new-bootnodes
{:success-event (when (custom-bootnodes-in-use? cofx)
[:multiaccounts.update.callback/save-settings-success])}))))
(rf/defn toggle-custom-bootnodes
{:events [:bootnodes.ui/custom-bootnodes-switch-toggled]}
[{:keys [db] :as cofx} value]
(let [current-network (:networks/current-network db)
bootnodes-settings (get-in db [:profile/profile :custom-bootnodes-enabled?])]
(multiaccounts.update/multiaccount-update
cofx
:custom-bootnodes-enabled?
(assoc bootnodes-settings current-network value)
{:success-event [:multiaccounts.update.callback/save-settings-success]})))
(rf/defn set-bootnodes-from-qr
{:events [:bootnodes.callback/qr-code-scanned]}
[cofx url]
(assoc (set-input cofx :url (string/trim url))
:dispatch
[:navigate-back]))
(rf/defn show-delete-bootnode-confirmation
{:events [:bootnodes.ui/delete-pressed]}
[_ bootnode-id]
{:ui/show-confirmation {:title (i18n/label :t/delete-bootnode-title)
:content (i18n/label :t/delete-bootnode-are-you-sure)
:confirm-button-text (i18n/label :t/delete-bootnode)
:on-accept #(re-frame/dispatch [:bootnodes.ui/delete-confirmed
bootnode-id])}})
(rf/defn delete-bootnode
{:events [:bootnodes.ui/delete-confirmed]}
[cofx bootnode-id]
(rf/merge cofx
(delete bootnode-id)
(navigation/navigate-back)))
@@ -1,180 +0,0 @@
(ns legacy.status-im.bootnodes.core-test
(:require
[cljs.test :refer-macros [deftest is testing]]
[legacy.status-im.bootnodes.core :as model]))
(def bootnode-id
"1da276e34126e93babf24ec88aac1a7602b4cbb2e11b0961d0ab5e989ca9c261aa7f7c1c85f15550a5f1e5a5ca2305b53b9280cf5894d5ecf7d257b173136d40")
(def host "167.99.209.61:30504")
(def valid-bootnode-address (str "enode://" bootnode-id "@" host))
(deftest upsert-bootnode
(testing "adding a new bootnode"
(let [new-bootnode {:name {:value "name"}
:url {:value "url"}}
expected {"mainnet_rpc" {"someid" {:name "name"
:address "url"
:chain "mainnet_rpc"
:id "someid"}}}
actual (model/upsert
{:random-id-generator (constantly "some-id")
:db {:bootnodes/manage new-bootnode
:networks/current-network "mainnet_rpc"
:profile/profile {:not-empty
"would throw an error if was empty"}}})]
(is (= expected (get-in actual [:db :profile/profile :custom-bootnodes])))))
(testing "adding an existing bootnode"
(let [new-bootnode {:id {:value "a"}
:name {:value "new-name"}
:url {:value "new-url"}}
expected {"mainnet_rpc" {"a" {:name "new-name"
:address "new-url"
:chain "mainnet_rpc"
:id "a"}}}
actual (model/upsert
{:random-id-generator (constantly "some-id")
:db {:bootnodes/manage new-bootnode
:networks/current-network "mainnet_rpc"
:profile/profile {:custom-bootnodes
{"mainnet_rpc"
{"a" {:name "name"
:address "url"
:chain "mainnet_rpc"
:id "a"}}}}}})]
(is (= expected (get-in actual [:db :profile/profile :custom-bootnodes]))))))
(deftest set-input-bootnode
(testing "it validates names"
(testing "correct name"
(is (= {:db {:bootnodes/manage {:name {:value "value"
:error false}}}}
(model/set-input {:db {}} :name "value"))))
(testing "blank name"
(is (= {:db {:bootnodes/manage {:name {:value ""
:error true}}}}
(model/set-input {:db {}} :name "")))))
(testing "it validates bootnode url"
(testing "correct url"
(is (= {:db {:bootnodes/manage {:url {:value valid-bootnode-address
:error false}}}}
(model/set-input {:db {}} :url valid-bootnode-address))))
(testing "broken url"
(is (= {:db {:bootnodes/manage {:url {:value "broken"
:error true}}}}
(model/set-input {:db {}} :url "broken"))))))
(deftest set-bootnode-from-qr
(testing "correct name"
(is (= {:dispatch [:navigate-back]
:db {:bootnodes/manage {:url {:value valid-bootnode-address
:error false}}}}
(model/set-bootnodes-from-qr {:db {}} (str valid-bootnode-address " "))))))
(deftest edit-bootnode
(let [db {:networks/current-network "mainnet_rpc"
:profile/profile
{:custom-bootnodes
{"mainnet_rpc"
{"a" {:id "a"
:name "name"
:address valid-bootnode-address}}}}}
cofx {:db db}]
(testing "when no id is given"
(let [actual (model/edit cofx nil)]
(testing "it resets :bootnodes/manage"
(is (= {:id {:value nil
:error false}
:url {:value ""
:error true}
:name {:value ""
:error true}}
(-> actual :db :bootnodes/manage))))
(testing "it navigates to edit-bootnode view"
(is (= [:navigate-to :edit-bootnode]
(-> actual :dispatch))))))
(testing "when an id is given"
(testing "when the bootnode is in the list"
(let [actual (model/edit cofx "a")]
(testing "it populates the fields with the correct values"
(is (= {:id {:value "a"
:error false}
:url {:value valid-bootnode-address
:error false}
:name {:value "name"
:error false}}
(-> actual :db :bootnodes/manage))))
(testing "it navigates to edit-bootnode view"
(is (= [:navigate-to :edit-bootnode]
(-> actual :dispatch))))))
(testing "when the bootnode is not in the list"
(let [actual (model/edit cofx "not-existing")]
(testing "it populates the fields with the correct values"
(is (= {:id {:value nil
:error false}
:url {:value ""
:error true}
:name {:value ""
:error true}}
(-> actual :db :bootnodes/manage))))
(testing "it navigates to edit-bootnode view"
(is (= [:navigate-to :edit-bootnode]
(-> actual :dispatch)))))))))
(deftest fetch-bootnode
(testing "it fetches the bootnode from the db"
(let [cofx {:db {:networks/current-network "mainnet_rpc"
:profile/profile {:custom-bootnodes
{"mainnet_rpc"
{"a" {:id "a"
:name "name"
:address
"enode://old-id:old-password@url:port"}}}}}}]
(is (model/fetch cofx "a")))))
(deftest custom-bootnodes-in-use?
(testing "is on the same network"
(testing "it returns false when not enabled"
(is (not (model/custom-bootnodes-in-use? {:db {:networks/current-network "mainnet_rpc"}}))))
(testing "it returns true when enabled"
(is (model/custom-bootnodes-in-use?
{:db {:networks/current-network "mainnet_rpc"
:profile/profile {:custom-bootnodes-enabled?
{"mainnet_rpc" true}}}}))))
(testing "is on a different network"
(testing "it returns false when not enabled"
(is (not (model/custom-bootnodes-in-use? {:db {:networks/current-network "goerli_rpc"}}))))
(testing "it returns true when enabled"
(is (not (model/custom-bootnodes-in-use?
{:db {:networks/current-network "goerli_rpc"
:profile/profile {:custom-bootnodes-enabled?
{"mainnnet_rpc" true}}}}))))))
(deftest delete-bootnode
(testing "non existing bootnode"
(let [cofx {:db {:networks/current-network "mainnet_rpc"
:profile/profile {:custom-bootnodes
{"mainnet_rpc"
{"a" {:id "a"
:name "name"
:address
"enode://old-id:old-password@url:port"}}}
:custom-bootnodes-enabled?
{"mainnnet_rpc" true}}}}
actual (model/delete cofx "b")]
(testing "it does not removes the bootnode"
(is (model/fetch actual "a")))))
(testing "existing bootnode"
(let [cofx {:db {:networks/current-network "mainnet_rpc"
:profile/profile {:custom-bootnodes
{"mainnet_rpc"
{"a" {:id "a"
:name "name"
:address
"enode://old-id:old-password@url:port"}}}
:custom-bootnodes-enabled?
{"mainnnet_rpc" true}}}}
actual (model/delete cofx "a")]
(testing "it removes the bootnode"
(is (not (model/fetch actual "a")))))))
+6 -6
View File
@@ -187,9 +187,9 @@
(with-animation (+ bg-height-expanded (.-value pan-y))))
;; Workaround for
;; https://github.com/software-mansion/react-native-reanimated/issues/1758#issue-817145741
;; withTiming/withSpring callback not working on-expanded should
;; be called as a callback of with-animation instead, once this
;; issue has been resolved
;; withTiming/withSpring callback not working on-expanded
;; should be called as a callback of with-animation instead,
;; once this issue has been resolved
(timer/set-timeout on-expanded animation-delay))
(do
(reanimated/set-shared-value
@@ -197,9 +197,9 @@
(with-animation (+ bg-height (.-value pan-y))))
;; Workaround for
;; https://github.com/software-mansion/react-native-reanimated/issues/1758#issue-817145741
;; withTiming/withSpring callback not working on-collapsed should
;; be called as a callback of with-animation instead, once this
;; issue has been resolved
;; withTiming/withSpring callback not working on-collapsed
;; should be called as a callback of with-animation instead,
;; once this issue has been resolved
(timer/set-timeout on-collapsed animation-delay)))
(= @show-bottom-sheet? false)
+2 -63
View File
@@ -3,12 +3,10 @@
["eth-phishing-detect" :as eth-phishing-detect]
[clojure.string :as string]
[legacy.status-im.bottom-sheet.events :as bottom-sheet]
[legacy.status-im.browser.eip3326 :as eip3326]
[legacy.status-im.browser.permissions :as browser.permissions]
[legacy.status-im.browser.webview-ref :as webview-ref]
[legacy.status-im.ethereum.ens :as ens]
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
[legacy.status-im.signing.core :as signing]
[legacy.status-im.ui.components.list-selection :as list-selection]
[legacy.status-im.utils.deprecated-types :as types]
[legacy.status-im.utils.random :as random]
@@ -393,64 +391,6 @@
constants/web3-eth-sign constants/web3-keycard-sign-typed-data}
method))
(rf/defn web3-send-async
[cofx dapp-name {:keys [method params id] :as payload} message-id]
(let [message? (web3-sign-message? method)
dapps-address (get-in cofx [:db :profile/profile :dapps-address])
typed? (and (not= constants/web3-personal-sign method)
(not= constants/web3-eth-sign method))]
(if (or message? (= constants/web3-send-transaction method))
(let [[address data] (cond (and (= method constants/web3-keycard-sign-typed-data)
(not (vector? params)))
;; We don't use signer argument for keycard sign-typed-data
["0x0" params]
message? (normalize-sign-message-params params
typed?)
:else [nil nil])]
(when (or (not message?) (and address data))
(signing/sign cofx
(merge
(if message?
{:message {:address address
:data data
:v4 (= constants/web3-sign-typed-data-v4 method)
:typed? typed?
:pinless? (= method constants/web3-keycard-sign-typed-data)
:from dapps-address}}
{:tx-obj (-> params
first
(update :from #(or % dapps-address))
(dissoc :gasPrice))})
{:on-result [:browser.dapp/transaction-on-result message-id id]
:on-error [:browser.dapp/transaction-on-error message-id]}))))
(cond
(#{"eth_accounts" "eth_coinbase"} method)
(send-to-bridge
cofx
{:type constants/web3-send-async-callback
:messageId message-id
:result {:jsonrpc "2.0"
:id (int id)
:result (if (= method "eth_coinbase") dapps-address [dapps-address])}})
(= method "personal_ecRecover")
{:signing.fx/recover-message {:params {:message (first params)
:signature (second params)}
:on-completed #(re-frame/dispatch
[:browser.callback/call-rpc
{:type constants/web3-send-async-callback
:messageId message-id
:result (types/json->clj %)}])}}
(= method "wallet_switchEthereumChain")
(eip3326/handle-switch-ethereum-chain cofx dapp-name id message-id (first params))
:else
{:browser/call-rpc [payload
#(re-frame/dispatch [:browser.callback/call-rpc
{:type constants/web3-send-async-callback
:messageId message-id
:error %1
:result %2}])]}))))
(rf/defn handle-no-permissions
[cofx {:keys [method id]} message-id]
(if (= method "eth_accounts")
@@ -479,9 +419,8 @@
(rf/defn web3-send-async-read-only
[{:keys [db] :as cofx} dapp-name {:keys [method] :as payload} message-id]
(if (has-permissions? db dapp-name method)
(handle-no-permissions cofx payload message-id)
(web3-send-async cofx dapp-name payload message-id)))
(when (has-permissions? db dapp-name method)
(handle-no-permissions cofx payload message-id)))
(rf/defn handle-scanned-qr-code
{:events [:browser.bridge.callback/qr-code-scanned]}
-38
View File
@@ -1,38 +0,0 @@
;reference https://eips.ethereum.org/EIPS/eip-3085 EIP-3085: Wallet Add Ethereum Chain RPC Method
;(`wallet_addEthereumChain`)
(ns legacy.status-im.browser.eip3085
(:require
[re-frame.core :as re-frame]
[status-im.constants :as constants]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
(rf/defn send-success-call-to-bridge
{:events [:eip3085/send-success-call-to-bridge]}
[_ id messageId]
{:browser/send-to-bridge {:type constants/web3-send-async-callback
:messageId messageId
:result {:jsonrpc "2.0"
:id (int id)
:result nil}}})
(rf/defn allow-permission
{:events [:eip3085.ui/dapp-permission-allowed]}
[{:keys [db] :as cofx} message-id {:keys [new-networks id]}]
{:db (assoc db :networks/networks new-networks)
:json-rpc/call [{:method "settings_saveSetting"
:params [:networks/networks (vals new-networks)]
:on-success #(re-frame/dispatch [:eip3085/send-success-call-to-bridge cofx id
message-id])
:on-error #(log/error "failed to perform settings_saveSetting" %)}]
:dispatch [:bottom-sheet/hide-old]})
(rf/defn deny-permission
{:events [:eip3085.ui/dapp-permission-denied]}
[_ message-id _]
{:browser/send-to-bridge {:type constants/web3-send-async-callback
:messageId message-id
:error {:code 4001
:message "User rejected the request."}}
:dispatch [:bottom-sheet/hide-old]})
-55
View File
@@ -1,55 +0,0 @@
;reference https://eips.ethereum.org/EIPS/eip-3326 EIP-3326: Wallet Switch Ethereum Chain RPC Method
;(`wallet_switchEthereumChain`)
(ns legacy.status-im.browser.eip3326
(:require
[legacy.status-im.ui.screens.browser.eip3326.sheet :as sheet]
[status-im.constants :as constants]
[utils.ethereum.chain :as chain]
[utils.re-frame :as rf]))
(rf/defn deny-permission
{:events [:eip3326.ui/dapp-permission-denied]}
[{:keys [db] :as cofx} message-id _]
{:browser/send-to-bridge {:type constants/web3-send-async-callback
:messageId message-id
:error {:code 4001
:message "User rejected the request."}}
:dispatch [:bottom-sheet/hide-old]})
(rf/defn handle-switch-ethereum-chain
{:events [:eip3326/handle-switch-ethereum-chain]}
[{:keys [db] :as cofx} dapp-name id message-id {:keys [chainId] :as params}]
(let [target-chain-id (js/parseInt chainId 16)
networks (vals (get-in db [:networks/networks]))
exist-chain-ids (set (map chain/network->chain-id networks))
current-chain-id (chain/chain-id db)]
(if (exist-chain-ids target-chain-id)
(if (= current-chain-id target-chain-id)
{:browser/send-to-bridge {:type constants/web3-send-async-callback
:messageId message-id
:result {:jsonrpc "2.0"
:id (int id)
:result nil}}}
(let [target-network (first (filter #(= (chain/network->chain-id %1) target-chain-id)
networks))
target-network-id (:id target-network)
current-network (chain/current-network db)
network-from (:name current-network)
network-to (:name target-network)
params (assoc params
:target-network-id target-network-id
:network-from network-from
:network-to network-to)]
{:dispatch [:bottom-sheet/show-sheet-old
{:content (fn []
[sheet/permissions-panel dapp-name message-id params])}]}))
{:browser/send-to-bridge {:type constants/web3-send-async-callback
:messageId message-id
:error
{:code 4902
:message
(str
"Unrecognized chain ID: "
target-chain-id
". Try adding the chain using wallet_addEthereumChain first.")}}})))
@@ -120,12 +120,13 @@
{:keys [message-id from]
:as message}]
(let [message
;; For example, when a user receives a list of 4 image messages while inside
;; the chat screen we shouldn't group the images into albums. When the user
;; exists the chat screen then enters the chat screen again, we now need to
;; group the images into albums (like WhatsApp). The albumize? boolean is used
;; to know whether we need to group these images into albums now or not. The
;; album-id can't be used for this because it will always be there.
;; For example, when a user receives a list of 4 image messages while
;; inside the chat screen we shouldn't group the images into albums. When
;; the user exists the chat screen then enters the chat screen again, we
;; now need to group the images into albums (like WhatsApp). The albumize?
;; boolean is used to know whether we need to group these images into
;; albums now or not. The album-id can't be used for this because it will
;; always be there.
(if (and (:album-id message) (nil? (get all-messages message-id)))
(assoc message :albumize? true)
message)]
@@ -22,9 +22,7 @@
:alias "alias"
:name "name"
:from "from"}]
;; <- cursor
;; <- message
;; <- top of the chat
;; <- cursor <- message <- top of the chat
(testing "there's no hidden item"
(with-redefs [list.state/first-not-visible-item (atom nil)]
(is
@@ -41,10 +39,7 @@
cofx
#js {:messages (to-array [message])})
:utils/dispatch-later)))))
;; <- cursor
;; <- first-hidden-item
;; <- message
;; <- top of the chat
;; <- cursor <- first-hidden-item <- message <- top of the chat
(testing "the hidden item has a clock value less than the current"
(with-redefs [list.state/first-not-visible-item (atom {:clock-value (dec clock-value)})]
(is
@@ -61,10 +56,7 @@
cofx
#js {:messages (to-array [message])})
:utils/dispatch-later)))))
;; <- cursor
;; <- message
;; <- first-hidden-item
;; <- top of the chat
;; <- cursor <- message <- first-hidden-item <- top of the chat
(testing "the message falls between the first-hidden-item and cursor"
(with-redefs [list.state/first-not-visible-item (atom {:clock-value (inc clock-value)})]
(let [result (dissoc (message/receive-many
@@ -77,9 +69,7 @@
(is (= clock-value (get-in result [:db :pagination-info chat-id :cursor-clock-value])))
(is (= (loading/clock-value->cursor clock-value)
(get-in result [:db :pagination-info chat-id :cursor])))))))
;; <- message
;; <- first-hidden-item
;; <- top of the chat
;; <- message <- first-hidden-item <- top of the chat
(testing "the message falls between the first-hidden-item and cursor is nil"
(with-redefs [list.state/first-not-visible-item (atom {:clock-value (inc clock-value)})]
(let [result (dissoc (message/receive-many
@@ -96,10 +86,7 @@
(is (= clock-value (get-in result [:db :pagination-info chat-id :cursor-clock-value])))
(is (= (loading/clock-value->cursor clock-value)
(get-in result [:db :pagination-info chat-id :cursor])))))))
;; <- message
;; <- cursor
;; <- first-hidden-item
;; <- top of the chat
;; <- message <- cursor <- first-hidden-item <- top of the chat
(testing "the message falls before both the first-hidden-item and cursor"
(with-redefs [list.state/first-not-visible-item (atom {:clock-value (inc clock-value)})]
(let [message #js
+246 -24
View File
@@ -1,35 +1,257 @@
(ns legacy.status-im.communities.e2e
(:require [taoensso.timbre :as log]
(:require [promesa.core :as promesa]
[status-im.common.json-rpc.events :as rpc]
[status-im.constants :as constants]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
;;NOTE: ONLY FOR QA
(rf/defn create-closed-community
{:events [:fast-create-community/create-closed-community]}
[_]
{:json-rpc/call [{:method "wakuext_createClosedCommunity"
:params []
:js-response true
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/error "failed to create closed community." {:error %})}]
:dispatch [:hide-bottom-sheet]})
(def one-stt-in-wei "1000000000000000000")
(def one-eth-in-wei "1000000000000000000")
(def ten-stt-in-wei "10000000000000000000")
(def stt-symbol "STT")
(def eth-symbol "ETH")
(def null-address "0x0000000000000000000000000000000000000000")
(defn- eth-token-criteria
[amount-in-wei]
{:contractAddresses {constants/ethereum-sepolia-chain-id null-address
constants/arbitrum-sepolia-chain-id null-address
constants/optimism-sepolia-chain-id null-address}
:type constants/community-token-type-erc20
:symbol "ETH"
:name "Ethereum"
:amountInWei amount-in-wei
:decimals 18})
(defn- stt-token-criteria
[amount-in-wei]
{:contractAddresses {constants/ethereum-sepolia-chain-id constants/sepolia-stt-contract-address}
:type constants/community-token-type-erc20
:symbol "STT"
:name "Status Test Token"
:amountInWei amount-in-wei
:decimals 18})
(def token-criteria
{stt-symbol stt-token-criteria
eth-symbol eth-token-criteria})
(def base-channel-permissions
[{:permission-type constants/community-token-permission-can-view-channel
:token-symbol stt-symbol
:amount one-stt-in-wei}
{:permission-type constants/community-token-permission-can-view-channel
:token-symbol eth-symbol
:amount one-eth-in-wei}
{:permission-type constants/community-token-permission-can-view-and-post-channel
:token-symbol stt-symbol
:amount one-stt-in-wei}
{:permission-type constants/community-token-permission-can-view-and-post-channel
:token-symbol eth-symbol
:amount one-eth-in-wei}])
(defn- channel-names->description
[channel-names]
(map #(hash-map :name %1
:permissions [%2])
channel-names
base-channel-permissions))
(def community-descriptions
{:open
{:community-name "Open community"
:membership constants/community-permissions-auto-accept
:pin-message-allowed false}
:closed
{:community-name "Closed community"
:membership constants/community-permissions-manual-accept
:pin-message-allowed true
:categories [{:category-name "Pets" :channels #{"Cats" "Dogs"}}
{:category-name "Household" :channels #{"Rules"}}]
:channel-list [{:name "Cats"} {:name "Dogs"} {:name "Rules"}]}
:token-gated
{:community-name "Token gated community"
:membership constants/community-permissions-auto-accept
:pin-message-allowed true
:community-permissions [{:amount-in-wei ten-stt-in-wei
:permission-type constants/community-token-permission-become-member
:token-symbol stt-symbol}]
:channel-list (channel-names->description ["Lions" "Birds" "Trees" "Flowers"])}
:snt-admin
{:community-name "SNT Admin Community"
:membership constants/community-permissions-auto-accept
:pin-message-allowed true
:community-permissions [{:amount-in-wei one-stt-in-wei
:permission-type constants/community-token-permission-become-admin
:token-symbol stt-symbol}]
:channel-list (channel-names->description ["Sounds" "Colors" "Books" "Sports"])}
:admin-and-member
{:community-name "Admin and Member"
:membership constants/community-permissions-auto-accept
:pin-message-allowed true
:community-permissions [{:amount-in-wei one-stt-in-wei
:permission-type constants/community-token-permission-become-member
:token-symbol stt-symbol}
{:amount-in-wei one-eth-in-wei
:permission-type constants/community-token-permission-become-admin
:token-symbol eth-symbol}]
:channel-list (channel-names->description ["Party" "Birthday" "Travel" "Cars"])}})
(defn- js-messenger-response->community-id
[response]
(-> response .-communities first .-id))
(defn- js-messenger-response->channel-id
[channel-name response]
(->> response
.-communities
first
.-chats
js->clj
vals
(some #(when (= channel-name (get % "name")) (get % "id")))))
(defn- channel-token-criteria->request
[community-id channel-id {:keys [token-symbol amount]}]
(fn []
(rpc/call
{:method "wakuext_createCommunityTokenPermissionV2"
:js-response true
:params [{:communityID community-id
:type constants/community-token-permission-become-member
:chatIds [channel-id]
:tokenCriteria [((token-criteria token-symbol) amount)]}]})))
(defn- channel-token-criteria->requests
[community-id channel-id tokens]
(let [keep-fn (partial channel-token-criteria->request community-id channel-id)]
(keep keep-fn tokens)))
(defn- create-community-channel!
[channel community-id]
(->
(rpc/call
{:method "wakuext_createCommunityChannel"
:js-response true
:params [{:name (:name channel)
:communityId community-id
:description (:name channel)}]})
(.then (fn [response]
(if (:permissions channel)
(let [channel-id (js-messenger-response->channel-id (:name channel) response)]
(apply
promesa/chain
(promesa/resolved nil)
(channel-token-criteria->requests community-id channel-id (:permissions channel))))
response)))
(.catch #(log/error "failed to create token gated community channel."
{:error %
:channel-name (:name channel)}))))
(defn- create-category!
[response {:keys [category-name channels]}]
(let [community-id (js-messenger-response->community-id response)
channel-ids (map #(js-messenger-response->channel-id % response)
channels)]
(rpc/call
{:method "wakuext_createCommunityCategory"
:js-response true
:params [{:communityId community-id
:categoryName category-name
:chatIds channel-ids}]})))
(defn- create-community!
[community-name membership pin-message-allowed]
(rpc/call
{:method "wakuext_createCommunity"
:js-response true
:params [{:name community-name
:description community-name
:color "#887af9"
:historyArchiveSupportEnabled true
:membership membership
:pinMessageAllMembersEnabled pin-message-allowed}]}))
(defn- create-token-gated-permission!
[{:keys [token-symbol permission-type amount-in-wei]} community-id]
(rpc/call
{:method "wakuext_createCommunityTokenPermissionV2"
:js-response true
:params [{:communityId community-id
:type permission-type
:tokenCriteria [((token-criteria token-symbol) amount-in-wei)]}]}))
(def passthrough [identity])
(defn- create-community-from-description
[{:keys [community-name
membership
community-permissions
pin-message-allowed
categories
channel-list]}]
(let [create-community-permissions-fn (if (seq community-permissions)
(map
(fn [permission]
(fn [response]
(create-token-gated-permission!
permission
(js-messenger-response->community-id response))))
community-permissions)
passthrough)
create-channels-fn (if (seq channel-list)
(map
(fn [channel]
(fn [response]
(create-community-channel!
channel
(js-messenger-response->community-id response))))
channel-list)
passthrough)
create-categories-fn (if (seq categories)
(map
(fn [category]
(fn [messenger-response]
(create-category! messenger-response category)))
categories)
passthrough)]
(as-> (create-community! community-name membership pin-message-allowed) $
(apply promesa/chain $ create-community-permissions-fn)
(apply promesa/chain $ create-channels-fn)
(apply promesa/chain $ create-categories-fn)
(promesa/then $ #(rf/dispatch [:hide-bottom-sheet]))
(promesa/catch $ #(log/error "failed to create community e2e" {:error %})))))
(rf/defn create-open-community
{:events [:fast-create-community/create-open-community]}
{:events [:e2e/create-open-community]}
[_]
{:json-rpc/call [{:method "wakuext_createOpenCommunity"
:params []
:js-response true
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/error "failed to create open community." {:error %})}]
:dispatch [:hide-bottom-sheet]})
(create-community-from-description (community-descriptions :open))
nil)
(rf/defn create-closed-community
{:events [:e2e/create-closed-community]}
[_]
(create-community-from-description (community-descriptions :closed))
nil)
(rf/defn create-token-gated-community
{:events [:fast-create-community/create-token-gated-community]}
{:events [:e2e/create-token-gated-community]}
[_]
{:json-rpc/call [{:method "wakuext_createTokenGatedCommunity"
:params []
:js-response true
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/error "failed to create token gated community." {:error %})}]
:dispatch [:hide-bottom-sheet]})
(create-community-from-description (community-descriptions :token-gated))
nil)
(rf/defn snt-admin-community
{:events [:e2e/create-snt-admin-community]}
[_]
(create-community-from-description (community-descriptions :snt-admin))
nil)
(rf/defn admin-and-member-community
{:events [:e2e/create-admin-and-member-community]}
[_]
(create-community-from-description (community-descriptions :admin-and-member))
nil)
+7 -6
View File
@@ -53,21 +53,22 @@
false))
:fx [[:activity-center.notifications/fetch-unread-count]
[:effects/push-notifications-clear-message-notifications [public-key]]
[:dispatch [:shell/close-switcher-card public-key]]]}
[:dispatch-later
[{:ms 500
:dispatch [:chat.ui/close-and-remove-chat public-key]}]]]}
fxs)))
(rf/defn block-contact
{:events [:contact.ui/block-contact-confirmed]}
[{:keys [db] :as cofx} public-key
{:keys [handle-navigation?]
:or {handle-navigation? true}}]
[{:keys [db] :as cofx} public-key]
(let [contact (-> (contact.db/public-key->contact
(:contacts/contacts db)
public-key)
(assoc :blocked? true
:added? false
:active? false))
from-one-to-one-chat? (not (get-in db [:chats (:current-chat-id db) :group-chat]))]
current-chat-id (:current-chat-id db)
from-one-to-one-chat? (not (get-in db [:chats current-chat-id :group-chat]))]
(rf/merge cofx
{:db (assoc-in db [:contacts/contacts public-key] contact)}
(contacts-store/block
@@ -77,7 +78,7 @@
(re-frame/dispatch [:sanitize-messages-and-process-response block-contact])
(re-frame/dispatch [:hide-popover])))
;; reset navigation to avoid going back to non existing one to one chat
(when handle-navigation?
(when current-chat-id
(if from-one-to-one-chat?
(navigation/pop-to-root :shell-stack)
(navigation/navigate-back))))))
@@ -125,6 +125,7 @@
:profile-public-key (.-profile chat)
:highlight (.-highlight chat)
:active (.-active chat)
:image (.-image chat)
:members (types/js->clj (.-members chat))
:hide-if-permissions-not-met (.-hideIfPermissionsNotMet chat)}
rpc->type
@@ -2,18 +2,8 @@
(:require
[clojure.set :as set]
[legacy.status-im.data-store.visibility-status-updates :as visibility-status-updates]
[status-im.config :as config]
[utils.ethereum.eip.eip55 :as eip55]))
(defn rpc->networks
[networks]
(reduce (fn [acc {:keys [id] :as network}]
(assoc acc id network))
{}
(if (seq networks)
networks
config/default-networks)))
(defn rpc->visible-tokens
[visible-tokens]
(reduce-kv (fn [acc chain visible-tokens]
@@ -28,25 +18,14 @@
{}
pinned-mailservers))
(defn rpc->custom-bootnodes
[custom-bootnodes]
(reduce-kv (fn [acc chain custom-bootnodes]
(assoc acc (name chain) custom-bootnodes))
{}
custom-bootnodes))
(defn rpc->settings
[settings]
(-> settings
(update :dapps-address eip55/address->checksum)
(update :address eip55/address->checksum)
(update :networks/networks rpc->networks)
(update :networks/current-network #(if (seq %) % config/default-network))
(update :wallet-legacy/visible-tokens rpc->visible-tokens)
(update :pinned-mailservers rpc->pinned-mailservers)
(update :link-previews-enabled-sites set)
(update :custom-bootnodes rpc->custom-bootnodes)
(update :custom-bootnodes-enabled? rpc->custom-bootnodes)
(update :currency keyword)
(visibility-status-updates/<-rpc-settings)
(set/rename-keys {:compressedKey :compressed-key
+4 -6
View File
@@ -56,8 +56,7 @@
(rf/defn redirect-to-ens-summary
{:events [::redirect-to-ens-summary]}
[cofx]
;; we reset navigation so that navigate back doesn't return
;; into the registration flow
;; we reset navigation so that navigate back doesn't return into the registration flow
(rf/merge cofx
(navigation/navigate-back-to :my-profile)
(navigation/navigate-to :ens-confirmation {})))
@@ -161,8 +160,8 @@
(and (= response utils.ens/default-address) (not custom-domain?))
(re-frame/dispatch [::name-resolved username :available])
;; if we get an address back, we try to get the public key associated
;; with the username as well
;; if we get an address back, we try to get the public key associated with the username as
;; well
(get addresses (eip55/address->checksum response))
(ens/pubkey
chain-id
@@ -271,8 +270,7 @@
(rf/merge cofx
;; clear registration data
{:db (dissoc db :ens/registration)}
;; we reset navigation so that navigate back doesn't return
;; into the registration flow
;; we reset navigation so that navigate back doesn't return into the registration flow
(navigation/navigate-back-to :my-profile)
(navigation/navigate-to :ens-main {})))
+1 -10
View File
@@ -2,7 +2,6 @@
(:require
clojure.set
legacy.status-im.backup.core
legacy.status-im.bootnodes.core
legacy.status-im.browser.core
legacy.status-im.browser.permissions
legacy.status-im.chat.models.loading
@@ -13,7 +12,6 @@
legacy.status-im.data-store.visibility-status-updates
legacy.status-im.fleet.core
legacy.status-im.group-chats.core
[legacy.status-im.keycard.core :as keycard]
legacy.status-im.log-level.core
legacy.status-im.mailserver.constants
[legacy.status-im.mailserver.core :as mailserver]
@@ -192,14 +190,7 @@
(not (get db :screens/was-focused-once?))
{:db (assoc db :screens/was-focused-once? true)})
#(case view-id
:keycard-settings (keycard/settings-screen-did-load %)
:reset-card (keycard/reset-card-screen-did-load %)
:enter-pin-settings (keycard/enter-pin-screen-did-load %)
:keycard-login-pin (keycard/login-pin-screen-did-load %)
:keycard-authentication-method (keycard/authentication-method-screen-did-load %)
:multiaccounts (keycard/multiaccounts-screen-did-load %)
nil)))
))
;;TODO :replace by named events
(rf/defn set-event
@@ -1,73 +0,0 @@
(ns legacy.status-im.keycard.backup-key
(:require
[legacy.status-im.ethereum.mnemonic :as mnemonic]
[legacy.status-im.keycard.common :as common]
[legacy.status-im.multiaccounts.recover.core :as multiaccounts.recover]
[legacy.status-im.signing.core :as signing.core]
[legacy.status-im.utils.utils :as utils]
[re-frame.core :as re-frame]
[status-im.navigation.events :as navigation]
[taoensso.timbre :as log]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(rf/defn backup-card-pressed
{:events [:keycard-settings.ui/backup-card-pressed]}
[{:keys [db] :as cofx} backup-type]
(log/debug "[keycard] start backup")
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :creating-backup?] backup-type))}
(when (:profile/profile db)
(navigation/navigate-to :my-profile nil))
(navigation/navigate-to :seed-phrase nil)))
(rf/defn recovery-card-pressed
{:events [:keycard-settings.ui/recovery-card-pressed]}
[{:keys [db] :as cofx} show-warning]
(rf/merge cofx
{:db (-> db
;setting pin-retry-counter is a workaround for the way the PIN view
;decides if it should accept PUK or PIN
(assoc-in [:keycard :application-info :pin-retry-counter] 3)
(assoc-in [:keycard :factory-reset-card?] true)
(dissoc :popover/popover))
:hide-popover nil}
(signing.core/discard)
(if show-warning
(utils/show-confirmation
{:title (i18n/label :t/keycard-recover-title)
:content (i18n/label :t/keycard-recover-text)
:confirm-button-text (i18n/label :t/yes)
:cancel-button-text (i18n/label :t/no)
:on-accept #(re-frame/dispatch [:keycard-settings.ui/backup-card-pressed
:recovery-card])
:on-cancel #()})
(backup-card-pressed :recovery-card))))
(rf/defn start-keycard-backup
{:events [::start-keycard-backup]}
[{:keys [db] :as cofx}]
{::multiaccounts.recover/import-multiaccount {:passphrase (-> db
:profile/key-storage
:seed-phrase
mnemonic/sanitize-passphrase)
:password nil
:success-event ::create-backup-card}})
(rf/defn create-backup-card
{:events [::create-backup-card]}
[{:keys [db] :as cofx} root-data derived-data]
(rf/merge cofx
{:db (-> db
(update :intro-wizard
assoc
:root-key root-data
:derived derived-data
:recovering? true
:selected-storage-type :advanced)
(assoc-in [:keycard :flow] :recovery)
(update :profile/key-storage dissoc :seed-phrase))
:dismiss-keyboard nil}
(common/listen-to-hardware-back-button)
(navigation/navigate-to :keycard-onboarding-intro nil)))
-565
View File
@@ -1,565 +0,0 @@
(ns legacy.status-im.keycard.card
(:require
[clojure.string :as string]
[keycard.keycard :as keycard]
[keycard.real-keycard :as real-keycard]
[legacy.status-im.keycard.simulated-keycard :as simulated-keycard]
[legacy.status-im.node.core :as node]
[native-module.core :as native-module]
[re-frame.core :as re-frame]
[status-im.config :as config]
[taoensso.timbre :as log]
[utils.transforms :as types]))
(defonce card
(if config/keycard-test-menu-enabled?
(simulated-keycard/SimulatedKeycard.)
(real-keycard/RealKeycard.)))
(defn check-nfc-support
[]
(log/debug "[keycard] check-nfc-support")
(keycard/check-nfc-support
card
{:on-success
(fn [response]
(log/debug "[keycard response] check-nfc-support")
(re-frame/dispatch
[:keycard.callback/check-nfc-support-success response]))}))
(defn check-nfc-enabled
[]
(log/debug "[keycard] check-nfc-enabled")
(keycard/check-nfc-enabled
card
{:on-success
(fn [response]
(log/debug "[keycard response] check-nfc-enabled")
(re-frame/dispatch
[:keycard.callback/check-nfc-enabled-success response]))}))
(defn open-nfc-settings
[]
(log/debug "[keycard] open-nfc-settings")
(keycard/open-nfc-settings card))
(defn remove-event-listener
[event]
(log/debug "[keycard] remove-event-listener")
(keycard/remove-event-listener card event))
(defn on-card-disconnected
[callback]
(log/debug "[keycard] on-card-disconnected")
(keycard/on-card-disconnected card callback))
(defn on-card-connected
[callback]
(log/debug "[keycard] on-card-connected")
(keycard/on-card-connected card callback))
(defn remove-event-listeners
[]
(log/debug "[keycard] remove-event-listeners")
(keycard/remove-event-listeners card))
(defn register-card-events
[]
(log/debug "[keycard] register-card-events")
(keycard/register-card-events
card
{:on-card-connected
#(re-frame/dispatch [:keycard.callback/on-card-connected])
:on-card-disconnected
#(re-frame/dispatch [:keycard.callback/on-card-disconnected])
:on-nfc-user-cancelled
#(re-frame/dispatch [:keycard.callback/on-nfc-user-cancelled])
:on-nfc-timeout
#(re-frame/dispatch [:keycard.callback/on-nfc-timeout])
:on-nfc-enabled
#(re-frame/dispatch [:keycard.callback/check-nfc-enabled-success true])
:on-nfc-disabled
#(re-frame/dispatch [:keycard.callback/check-nfc-enabled-success false])}))
(defn- error-object->map
[^js object]
{:code (.-code object)
:error (.-message object)})
(defn set-pairings
[pairings]
(log/debug "[keycard] open-nfc-settings")
(keycard/set-pairings card {:pairings pairings}))
(defn get-application-info
[{:keys [on-success] :as args}]
(log/debug "[keycard] get-application-info")
(keycard/get-application-info
card
(merge
args
{:on-success
(fn [response]
(log/debug "[keycard response succ] get-application-info")
(re-frame/dispatch
[:keycard.callback/on-get-application-info-success
response on-success]))
:on-failure
(fn [response]
(log/debug "[keycard response fail] get-application-info")
(re-frame/dispatch
[:keycard.callback/on-get-application-info-error
(error-object->map response)]))})))
(defn factory-reset
[{:keys [on-success] :as args}]
(log/debug "[keycard] factory-reset")
(keycard/factory-reset
card
(merge
args
{:on-success
(fn [response]
(log/debug "[keycard response succ] get-application-info")
(re-frame/dispatch
[:keycard.callback/on-get-application-info-success
response on-success]))
:on-failure
(fn [response]
(log/debug "[keycard response fail] get-application-info")
(re-frame/dispatch
[:keycard.callback/on-get-application-info-error
(error-object->map response)]))})))
(defn install-applet
[]
(log/debug "[keycard] install-applet")
(keycard/install-applet
card
{:on-success
(fn [response]
(log/debug "[keycard response succ] install-applet")
(re-frame/dispatch
[:keycard.callback/on-install-applet-success response]))
:on-failure
(fn [response]
(log/debug "[keycard response fail] install-applet")
(re-frame/dispatch
[:keycard.callback/on-install-applet-error
(error-object->map response)]))}))
(defn init-card
[pin]
(log/debug "[keycard] init-card")
(keycard/init-card
card
{:pin pin
:on-success
(fn [response]
(log/debug "[keycard response succ] init-card")
(re-frame/dispatch
[:keycard.callback/on-init-card-success response]))
:on-failure
(fn [response]
(log/debug "[keycard response fail] init-card")
(re-frame/dispatch
[:keycard.callback/on-init-card-error
(error-object->map response)]))}))
(defn install-applet-and-init-card
[pin]
(log/debug "[keycard] install-applet-and-init-card")
(keycard/install-applet-and-init-card
card
{:pin pin
:on-success
(fn [response]
(log/debug "[keycard response succ] install-applet-and-init-card")
#(re-frame/dispatch
[:keycard.callback/on-install-applet-and-init-card-success
response]))
:on-failure
(fn [response]
(log/debug "[keycard response fail] install-applet-and-init-card")
(re-frame/dispatch
[:keycard.callback/on-install-applet-and-init-card-error
(error-object->map response)]))}))
(defn pair
[args]
(log/debug "[keycard] pair")
(keycard/pair
card
(merge
args
{:on-success
(fn [response]
(log/debug "[keycard response succ] pair")
(re-frame/dispatch
[:keycard.callback/on-pair-success response]))
:on-failure
(fn [response]
(log/debug "[keycard response fail] pair")
(re-frame/dispatch
[:keycard.callback/on-pair-error (error-object->map response)]))})))
(defn generate-and-load-key
[args]
(log/debug "[keycard] generate-and-load-key")
(keycard/generate-and-load-key
card
(merge
args
{:on-success
(fn [response]
(log/debug "[keycard response succ] generate-and-load-key")
(re-frame/dispatch
[:keycard.callback/on-generate-and-load-key-success response]))
:on-failure
(fn [response]
(log/debug "[keycard response fail] generate-and-load-key")
(re-frame/dispatch
[:keycard.callback/on-generate-and-load-key-error
(error-object->map response)]))})))
(defn unblock-pin
[args]
(log/debug "[keycard] unblock-pin")
(keycard/unblock-pin
card
(merge
args
{:on-success
(fn [response]
(log/debug "[keycard response succ] unblock-pin")
(re-frame/dispatch
[:keycard.callback/on-unblock-pin-success response]))
:on-failure
(fn [response]
(log/debug "[keycard response fail] unblock-pin")
(re-frame/dispatch [:keycard.callback/on-unblock-pin-error
(error-object->map response)]))})))
(defn verify-pin
[args]
(log/debug "[keycard] verify-pin")
(keycard/verify-pin
card
(merge
args
{:on-success
(fn [response]
(log/debug "[keycard response succ] verify-pin")
(re-frame/dispatch [:keycard.callback/on-verify-pin-success
response]))
:on-failure
(fn [response]
(log/debug "[keycard response fail] verify-pin")
(re-frame/dispatch
[:keycard.callback/on-verify-pin-error
(error-object->map response)]))})))
(defn change-pin
[args]
(log/debug "[keycard] change-pin")
(keycard/change-pin
card
(merge
args
{:on-success
(fn [response]
(log/debug "[keycard response succ] change-pin")
(re-frame/dispatch
[:keycard.callback/on-change-pin-success response]))
:on-failure
(fn [response]
(log/debug "[keycard response fail] change-pin")
(re-frame/dispatch
[:keycard.callback/on-change-pin-error
(error-object->map response)]))})))
(defn change-puk
[args]
(log/debug "[keycard] change-puk")
(keycard/change-puk
card
(merge
args
{:on-success
(fn [response]
(log/debug "[keycard response succ] change-puk")
(re-frame/dispatch
[:keycard.callback/on-change-puk-success response]))
:on-failure
(fn [response]
(log/debug "[keycard response fail] change-puk")
(re-frame/dispatch
[:keycard.callback/on-change-pin-error
(error-object->map response)]))})))
(defn change-pairing
[args]
(log/debug "[keycard] change-pairing")
(keycard/change-pairing
card
(merge
args
{:on-success
(fn [response]
(log/debug "[keycard response succ] change-pairing")
(re-frame/dispatch
[:keycard.callback/on-change-pairing-success response]))
:on-failure
(fn [response]
(log/debug "[keycard response fail] change-pairing")
(re-frame/dispatch
[:keycard.callback/on-change-pin-error
(error-object->map response)]))})))
(defn unpair
[args]
(log/debug "[keycard] unpair")
(keycard/unpair
card
(merge
args
{:on-success
(fn [response]
(log/debug "[keycard response succ] unpair")
(re-frame/dispatch
[:keycard.callback/on-unpair-success response]))
:on-failure
(fn [response]
(log/debug "[keycard response fail] unpair")
(re-frame/dispatch
[:keycard.callback/on-unpair-error
(error-object->map response)]))})))
(defn delete
[]
(log/debug "[keycard] delete")
(keycard/delete
card
{:on-success
(fn [response]
(log/debug "[keycard response succ] delete")
(re-frame/dispatch
[:keycard.callback/on-delete-success response]))
:on-failure
(fn [response]
(log/debug "[keycard response fail] delete")
(re-frame/dispatch
[:keycard.callback/on-delete-error
(error-object->map response)]))}))
(defn remove-key
[args]
(log/debug "[keycard] remove-key")
(keycard/remove-key
card
(merge
args
{:on-success
(fn [response]
(log/debug "[keycard response succ] remove-key")
(re-frame/dispatch [:keycard.callback/on-remove-key-success
response]))
:on-failure
(fn [response]
(log/debug "[keycard response fail] remove-key")
(re-frame/dispatch [:keycard.callback/on-remove-key-error
(error-object->map response)]))})))
(defn remove-key-with-unpair
[args]
(log/debug "[keycard] remove-key-with-unpair")
(keycard/remove-key-with-unpair
card
(merge
args
{:on-success
(fn [response]
(log/debug "[keycard response succ] remove-key-with-unpair")
(re-frame/dispatch [:keycard.callback/on-remove-key-success
response]))
:on-failure
(fn [response]
(log/debug "[keycard response fail] remove-key-with-unpair")
(re-frame/dispatch [:keycard.callback/on-remove-key-error
(error-object->map response)]))})))
(defn export-key
[args]
(log/debug "[keycard] export-key")
(keycard/export-key
card
(merge
args
{:on-success
(fn [_response]
(log/debug "[keycard response succ] export-key")
(js/alert "feature no longer supported"))
:on-failure
(fn [_response]
(log/debug "[keycard response fail] export-key"))})))
(defn unpair-and-delete
[args]
(log/debug "[keycard] unpair-and-delete")
(keycard/unpair
card
(merge
args
{:on-success
(fn [response]
(log/debug "[keycard response succ] unpair-and-delete")
(re-frame/dispatch [:keycard.callback/on-unpair-and-delete-success
response]))
:on-failure
(fn [response]
(log/debug "[keycard response fail] unpair-and-delete")
(re-frame/dispatch [:keycard.callback/on-unpair-and-delete-error
(error-object->map response)]))})))
(defn import-keys
[{:keys [on-success] :as args}]
(log/debug "[keycard] import-keys")
(keycard/import-keys
card
(assoc
args
:on-success
(fn [response]
(log/debug "[keycard response succ] import-keys")
(re-frame/dispatch
[(or on-success :keycard.callback/on-generate-and-load-key-success)
response]))
:on-failure
(fn [response]
(log/warn "[keycard response fail] import-keys"
(error-object->map response))
(re-frame/dispatch [:keycard.callback/on-get-keys-error
(error-object->map response)])))))
(defn get-keys
[{:keys [on-success] :as args}]
(log/debug "[keycard] get-keys")
(keycard/get-keys
card
(assoc
args
:on-success
(fn [response]
(log/debug "[keycard response succ] get-keys")
(re-frame/dispatch
[(or on-success :keycard.callback/on-get-keys-success)
response]))
:on-failure
(fn [response]
(log/warn "[keycard response fail] get-keys"
(error-object->map response))
(re-frame/dispatch [:keycard.callback/on-get-keys-error
(error-object->map response)])))))
(defn sign
[{:keys [on-success on-failure] :as args}]
(log/debug "[keycard] sign")
(keycard/sign
card
(merge
args
{:on-success
(fn [response]
(log/debug "[keycard response succ] sign")
(if on-success
(on-success response)
(re-frame/dispatch [:keycard.callback/on-sign-success response])))
:on-failure
(fn [response]
(log/debug "[keycard response fail] sign")
(if on-failure
(on-failure response)
(re-frame/dispatch
[:keycard.callback/on-sign-error
(error-object->map response)])))})))
(defn install-cash-applet
[]
(log/debug "[keycard] install-cash-applet")
(keycard/install-cash-applet
card
{:on-success
(fn [response]
(log/debug "[keycard response succ] install-cash-applet")
(re-frame/dispatch
[:keycard.callback/on-install-applet-success response]))
:on-failure
(fn [response]
(log/debug "[keycard response fail] install-cash-applet")
(re-frame/dispatch
[:keycard.callback/on-install-applet-error
(error-object->map response)]))}))
(defn sign-typed-data
[{card-hash :hash}]
(log/debug "[keycard] sign-typed-data")
(keycard/sign-typed-data
card
{:hash card-hash
:on-success
(fn [response]
(log/debug "[keycard response succ] sign-typed-data")
(re-frame/dispatch [:keycard.callback/on-sign-success
response]))
:on-failure
(fn [response]
(log/debug "[keycard response fail] sign-typed-data")
(re-frame/dispatch
[:keycard.callback/on-sign-error
(error-object->map response)]))}))
(defn save-multiaccount-and-login
[_])
(defn login
[{:keys [key-uid multiaccount-data password] :as args}]
(if config/keycard-test-menu-enabled?
(native-module/login-with-config key-uid multiaccount-data password node/login-node-config)
(native-module/login-with-keycard (assoc args :node-config {:ProcessBackedupMessages false}))))
(def account-password (native-module/sha3 "no password"))
(defn send-transaction-with-signature
[{:keys [transaction signature on-completed]}]
(if config/keycard-test-menu-enabled?
(native-module/send-transaction transaction account-password on-completed)
(native-module/send-transaction-with-signature transaction signature on-completed)))
(defn start-nfc
[args]
(keycard/start-nfc card args))
(defn stop-nfc
[args]
(keycard/stop-nfc card args))
(defn set-nfc-message
[args]
(keycard/set-nfc-message card args))
(defn delete-multiaccount-before-migration
[{:keys [key-uid on-success on-error]}]
(if config/keycard-test-menu-enabled?
(on-success)
(native-module/delete-multiaccount
key-uid
(fn [result]
(let [{:keys [error]} (types/json->clj result)]
(if-not (string/blank? error)
(on-error error)
(on-success)))))))
@@ -1,216 +0,0 @@
(ns legacy.status-im.keycard.change-pin
(:require
[legacy.status-im.keycard.common :as common]
[legacy.status-im.keycard.onboarding :as onboarding]
[status-im.navigation.events :as navigation]
[taoensso.timbre :as log]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.security.core :as security]))
(rf/defn change-credentials-pressed
{:events [:keycard-settings.ui/change-credentials-pressed]}
[{:keys [db] :as cofx} changing]
(rf/merge cofx
{:db
(assoc-in db
[:keycard :pin]
{:enter-step :current
:current []
:puk []
:original []
:confirmation []
:puk-original []
:puk-confirmation []
:status nil
:error-label nil
:on-verified (case changing
:pin :keycard/proceed-to-change-pin
:puk :keycard/proceed-to-change-puk
:pairing :keycard/proceed-to-change-pairing)})}
(common/navigate-to-enter-pin-screen)))
(rf/defn proceed-to-change-pin
{:events [:keycard/proceed-to-change-pin]}
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :pin :enter-step] :original)
(assoc-in [:keycard :pin :status] nil))}
(navigation/navigate-replace :enter-pin-settings nil)))
(rf/defn proceed-to-change-puk
{:events [:keycard/proceed-to-change-puk]}
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :pin :enter-step] :puk-original)
(assoc-in [:keycard :pin :status] nil))}
(navigation/navigate-replace :enter-pin-settings nil)))
(rf/defn proceed-to-change-pairing
{:events [:keycard/proceed-to-change-pairing]}
[{:keys [db] :as cofx}]
(navigation/navigate-replace cofx :change-pairing-code nil))
(rf/defn discard-pin-change
{:events [::on-cancel]}
[{:keys [db] :as cofx}]
(rf/merge cofx
(common/clear-pin)
(common/hide-connection-sheet)
(if (get-in db [:keycard :pin :puk-restore?])
(navigation/navigate-to :multiaccounts nil)
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings]))))
(rf/defn change-pin
{:events [:keycard/change-pin]}
[{:keys [db] :as cofx}]
(let [setup-step (get-in db [:keycard :setup-step])]
(log/debug "[keycard] change-pin"
"setup-step"
setup-step)
(if (= setup-step :pin)
(onboarding/load-preparing-screen cofx)
(common/show-connection-sheet
cofx
{:sheet-options {:on-cancel [::on-cancel]}
:on-card-connected :keycard/change-pin
:handler
(fn [{:keys [db] :as cofx}]
(let [new-pin (common/vector->string
(get-in db [:keycard :pin :original]))
current-pin (common/vector->string
(get-in db [:keycard :pin :current]))]
(rf/merge
cofx
{:db (assoc-in db [:keycard :pin :status] :verifying)
:keycard/change-pin
{:new-pin new-pin
:current-pin current-pin}})))}))))
(rf/defn change-puk
{:events [:keycard/change-puk]}
[{:keys [db] :as cofx}]
(common/show-connection-sheet
cofx
{:sheet-options {:on-cancel [::on-cancel]}
:on-card-connected :keycard/change-puk
:handler
(fn [{:keys [db] :as cofx}]
(let [puk (common/vector->string
(get-in db [:keycard :pin :puk-original]))
pin (common/vector->string
(get-in db [:keycard :pin :current]))]
(rf/merge
cofx
{:db (assoc-in db [:keycard :pin :status] :verifying)
:keycard/change-puk {:puk puk
:pin pin}})))}))
(rf/defn change-pairing
{:events [:keycard/change-pairing]}
[{:keys [db] :as cofx}]
(common/show-connection-sheet
cofx
{:sheet-options {:on-cancel [::on-cancel]}
:on-card-connected :keycard/change-pairing
:handler
(fn [{:keys [db] :as cofx}]
(let [pairing (get-in db [:keycard :pin :pairing-code])
pin (common/vector->string
(get-in db [:keycard :pin :current]))]
(rf/merge
cofx
{:db (assoc-in db [:keycard :pin :status] :verifying)
:keycard/change-pairing {:pairing pairing
:pin pin}})))}))
(rf/defn change-pairing-code
{:events [:keycard/change-pairing-code]}
[{:keys [db] :as cofx} pairing]
(rf/merge
cofx
{:db (assoc-in db [:keycard :pin :pairing-code] (security/unmask pairing))}
(change-pairing)))
(rf/defn on-change-pin-success
{:events [:keycard.callback/on-change-pin-success]}
[{:keys [db] :as cofx}]
(let [pin (get-in db [:keycard :pin :original])
puk-restore? (get-in db [:keycard :pin :puk-restore?])]
(rf/merge cofx
{:db (assoc-in db
[:keycard :pin]
{:status nil
:login pin
:confirmation []
:error-label nil})
:effects.utils/show-popup {:title ""
:content (i18n/label :t/pin-changed)}}
(common/hide-connection-sheet)
(if puk-restore?
(navigation/navigate-to :multiaccounts nil)
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings]))
(when (:profile/login db)
(common/get-keys-from-keycard)))))
(rf/defn on-change-puk-success
{:events [:keycard.callback/on-change-puk-success]}
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (assoc-in db
[:keycard :pin]
{:status nil
:puk-original []
:puk-confirmation []
:error-label nil})
:effects.utils/show-popup {:title ""
:content (i18n/label :t/puk-changed)}}
(common/hide-connection-sheet)
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings])))
(rf/defn on-change-pairing-success
{:events [:keycard.callback/on-change-pairing-success]}
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (assoc-in db
[:keycard :pin]
{:status nil
:pairing-code nil
:error-label nil})
:effects.utils/show-popup {:title ""
:content (i18n/label :t/pairing-changed)}}
(common/hide-connection-sheet)
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings])))
(rf/defn on-change-pin-error
{:events [:keycard.callback/on-change-pin-error]}
[{:keys [db] :as cofx} error]
(log/debug "[keycard] change pin error" error)
(let [tag-was-lost? (common/tag-lost? (:error error))
pin-retries (common/pin-retries (:error error))]
(rf/merge
cofx
(if tag-was-lost?
(rf/merge cofx
{:db (assoc-in db [:keycard :pin :status] nil)}
(common/set-on-card-connected :keycard/change-pin))
(if-not (nil? pin-retries)
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :application-info :pin-retry-counter] pin-retries)
(update-in [:keycard :pin]
assoc
:status :error
:enter-step :current
:puk []
:current []
:original []
:confirmation []
:sign []
:error-label :t/pin-mismatch))}
(when (zero? pin-retries) (common/frozen-keycard-popup))
(navigation/navigate-to :enter-pin-settings nil))
(common/show-wrong-keycard-alert))))))
-560
View File
@@ -1,560 +0,0 @@
(ns legacy.status-im.keycard.common
(:require
[clojure.string :as string]
[legacy.status-im.bottom-sheet.events :as bottom-sheet]
[legacy.status-im.keycard.nfc :as nfc]
[legacy.status-im.popover.core :as popover]
[legacy.status-im.utils.deprecated-types :as types]
[legacy.status-im.utils.keychain.core :as keychain]
[re-frame.core :as re-frame]
[react-native.platform :as platform]
[status-im.navigation.events :as navigation]
[taoensso.timbre :as log]
[utils.address :as address]
[utils.datetime :as datetime]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(def default-pin "000000")
(def pin-mismatch-error #"Unexpected error SW, 0x63C(\d+)|wrongPIN\(retryCounter: (\d+)\)")
(defn pin-retries
[error]
(when-let [matched-error (re-matches pin-mismatch-error error)]
(js/parseInt (second (filter some? matched-error)))))
(rf/defn dispatch-event
[_ event]
{:dispatch-n [[event]]})
(defn vector->string
"Converts numbers stored in vector into string,
e.g. [1 2 3 4 5 6] -> \"123456\""
[v]
(apply str v))
(defn get-card-state
[{:keys [has-master-key?
applet-installed?
initialized?
free-pairing-slots
paired?]}]
(cond
(not applet-installed?)
:blank
(not initialized?)
:pre-init
(not has-master-key?)
:init
has-master-key?
:profile/profile
(and (not paired?)
(zero? free-pairing-slots))
:no-pairing-slots))
(defn tag-lost?
[error]
(or
(= error "Tag was lost.")
(= error "NFCError:100")
(re-matches #".*NFCError:100.*" error)))
(defn find-multiaccount-by-keycard-instance-uid
[db keycard-instance-uid]
(when keycard-instance-uid
(->> (:profile/profiles-overview db)
vals
(filter #(= keycard-instance-uid (:keycard-instance-uid %)))
first)))
(defn find-multiaccount-by-key-uid
[db key-uid]
(when key-uid
(->> (:profile/profiles-overview db)
vals
(filter #(= (address/normalized-hex key-uid) (:key-uid %)))
first)))
(defn get-pairing
([db]
(get-pairing db (get-in db [:keycard :application-info :key-uid])))
([db key-uid]
(or
(get-in db [:profile/profile :keycard-pairing])
(get-in db [:keycard :secrets :pairing])
(when key-uid
(:keycard-pairing
(find-multiaccount-by-key-uid db key-uid))))))
(re-frame/reg-fx
:keycard/set-nfc-supported
(fn [supported?]
(nfc/set-nfc-supported? supported?)))
(rf/defn listen-to-hardware-back-button
[{:keys [db]}]
(when-not (get-in db [:keycard :back-button-listener])
{:keycard/listen-to-hardware-back-button nil}))
(rf/defn remove-listener-to-hardware-back-button
[{:keys [db]}]
(when-let [listener (get-in db [:keycard :back-button-listener])]
{:keycard/remove-listener-to-hardware-back-button listener}))
(rf/defn set-on-card-connected
[{:keys [db]} on-connect]
(log/debug "[keycard] set-on-card-connected" on-connect)
{:db (-> db
(assoc-in [:keycard :on-card-connected] on-connect)
(assoc-in [:keycard :last-on-card-connected] nil))})
(rf/defn stash-on-card-connected
[{:keys [db]}]
(let [on-connect (get-in db [:keycard :on-card-connected])]
(log/debug "[keycard] stash-on-card-connected" on-connect)
{:db (-> db
(assoc-in [:keycard :last-on-card-connected] on-connect)
(assoc-in [:keycard :on-card-connected] nil))}))
(rf/defn restore-on-card-connected
[{:keys [db]}]
(let [on-connect (or
(get-in db [:keycard :on-card-connected])
(get-in db [:keycard :last-on-card-connected]))]
(log/debug "[keycard] restore-on-card-connected" on-connect)
{:db (-> db
(assoc-in [:keycard :on-card-connected] on-connect)
(assoc-in [:keycard :last-on-card-connect] nil))}))
(rf/defn clear-on-card-connected
[{:keys [db]}]
(log/debug "[keycard] clear-on-card-connected")
{:db (-> db
(assoc-in [:keycard :on-card-connected] nil)
(assoc-in [:keycard :last-on-card-connected] nil))})
(rf/defn set-on-card-read
[{:keys [db]} on-connect]
(log/debug "[keycard] set-on-card-read" on-connect)
{:db (-> db
(assoc-in [:keycard :on-card-read] on-connect)
(assoc-in [:keycard :last-on-card-read] nil))})
(rf/defn stash-on-card-read
[{:keys [db]}]
(let [on-connect (get-in db [:keycard :on-card-read])]
(log/debug "[keycard] stash-on-card-read" on-connect)
{:db (-> db
(assoc-in [:keycard :last-on-card-read] on-connect)
(assoc-in [:keycard :on-card-read] nil))}))
(rf/defn restore-on-card-read
[{:keys [db]}]
(let [on-connect (or
(get-in db [:keycard :on-card-read])
(get-in db [:keycard :last-on-card-read]))]
(log/debug "[keycard] restore-on-card-read" on-connect)
{:db (-> db
(assoc-in [:keycard :on-card-read] on-connect)
(assoc-in [:keycard :last-on-card-connect] nil))}))
(rf/defn clear-on-card-read
[{:keys [db]}]
(log/debug "[keycard] clear-on-card-read")
{:db (-> db
(assoc-in [:keycard :on-card-read] nil)
(assoc-in [:keycard :last-on-card-read] nil))})
(rf/defn show-connection-sheet-component
[{:keys [db] :as cofx}
{:keys [on-card-connected on-card-read handler]
{:keys [on-cancel]
:or {on-cancel [::cancel-sheet-confirm]}}
:sheet-options}]
(assert (keyword? on-card-connected))
(assert (fn? handler))
(let [connected? (get-in db [:keycard :card-connected?])]
(log/debug "[keycard] show-sheet-with-connection-check"
"card-connected?"
connected?)
(rf/merge
cofx
(bottom-sheet/show-bottom-sheet-old
{:view {:transparent platform/ios?
:show-handle? false
:backdrop-dismiss? false
:disable-drag? true
:back-button-cancel false}})
(when on-card-read
(set-on-card-read on-card-read))
(set-on-card-connected on-card-connected)
(when connected?
(stash-on-card-connected))
(when connected?
handler))))
(rf/defn show-connection-sheet
[{:keys [db] :as cofx} args]
(let [nfc-running? (get-in db [:keycard :nfc-running?])]
(log/debug "show connection; already running?" nfc-running?)
(if nfc-running?
(show-connection-sheet-component cofx args)
{:keycard/start-nfc-and-show-connection-sheet args})))
(rf/defn on-nfc-ready-for-sheet
{:events [:keycard.callback/show-connection-sheet]}
[cofx args]
(log/debug "on-nfc-ready-for-sheet")
(show-connection-sheet-component cofx args))
(rf/defn hide-connection-sheet-component
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (assoc-in db [:keycard :card-read-in-progress?] false)}
(restore-on-card-connected)
(restore-on-card-read)
(bottom-sheet/hide-bottom-sheet-old)))
(rf/defn hide-connection-sheet
[cofx]
(log/debug "hide-connection-sheet")
{:keycard/stop-nfc-and-hide-connection-sheet nil})
(rf/defn on-nfc-ready-to-close-sheet
{:events [:keycard.callback/hide-connection-sheet]}
[cofx]
(log/debug "on-nfc-ready-to-close-sheet")
(hide-connection-sheet-component cofx))
(rf/defn clear-pin
[{:keys [db] :as cofx}]
(rf/merge
cofx
{:db (assoc-in db
[:keycard :pin]
{:status nil
:login (get-in db [:keycard :pin :original])
:export-key []
:sign []
:puk []
:current []
:original []
:confirmation []
:error-label nil
:on-verified (get-in db [:keycard :pin :on-verified])
:on-verified-failure (get-in db [:keycard :pin :on-verified])})}))
(rf/defn cancel-sheet-confirm
{:events [::cancel-sheet-confirm
:keycard/back-button-pressed]}
[{:keys [db] :as cofx}]
(when-not (get-in db [:keycard :card-connected?])
(rf/merge cofx
(hide-connection-sheet)
(clear-pin))))
(rf/defn cancel-sheet
{:events [::cancel-sheet]}
[_]
{:ui/show-confirmation {:title (i18n/label :t/keycard-cancel-setup-title)
:content (i18n/label :t/keycard-cancel-setup-text)
:confirm-button-text (i18n/label :t/yes)
:cancel-button-text (i18n/label :t/no)
:on-accept #(re-frame/dispatch [::cancel-sheet-confirm])
:on-cancel #()}})
(rf/defn on-add-listener-to-hardware-back-button
"Adds listener to hardware back button on Android.
During keycard setup we show user a warning that setup will be cancelled
when back button pressed. This prevents user from going back during setup
flow as some of the actions changing keycard step could not be repeated."
{:events [:keycard/add-listener-to-hardware-back-button]}
[{:keys [db]} listener]
{:db (assoc-in db [:keycard :back-button-listener] listener)})
(rf/defn show-wrong-keycard-alert
[_]
(log/debug "show-wrong-keycard-alert")
{:effects.utils/show-popup {:title (i18n/label :t/wrong-card)
:content (i18n/label :t/wrong-card-text)}})
(rf/defn unauthorized-operation
[cofx]
(rf/merge cofx
{:effects.utils/show-popup {:title ""
:content (i18n/label :t/keycard-unauthorized-operation)}}
(clear-on-card-connected)
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings])))
(rf/defn navigate-to-enter-pin-screen
{:events [:keycard/navigate-to-enter-pin-screen]}
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (assoc-in db [:keycard :pin :current] [])}
(navigation/navigate-to :enter-pin-settings nil)))
(defn- tag-lost-exception?
[code error]
(or
(= code "android.nfc.TagLostException")
(= error "Tag was lost.")
(= error "NFCError:100")))
(rf/defn process-error
[{:keys [db]} code error]
(when-not (tag-lost-exception? code error)
{:db (assoc-in db [:keycard :setup-step] :error)}))
(rf/defn get-keys-from-keycard
[{:keys [db]}]
(let [key-uid (get-in db [:profile/login :key-uid])
pin (string/join (get-in db [:keycard :pin :login]))]
(log/debug "[keycard] get-keys-from-keycard"
", not empty pin:"
(boolean (seq pin)))
(when (seq pin)
{:db (assoc-in db [:keycard :pin :status] :verifying)
:keycard/get-keys {:pin pin}})))
(rf/defn on-get-keys-success
{:events [:keycard.callback/on-get-keys-success]}
[{:keys [db] :as cofx} data]
(let [{:keys [key-uid encryption-public-key whisper-private-key]
:as account-data}
(js->clj data :keywordize-keys true)
{:keys [name]} (get-in db [:profile/profiles-overview key-uid])
key-uid (get-in db [:keycard :application-info :key-uid])
multiaccount-data (types/clj->json {:name name
:key-uid key-uid})
save-keys? (get-in db [:profile/login :save-password?])]
(rf/merge cofx
{:db
(-> db
(assoc-in [:keycard :pin :status] nil)
(assoc-in [:keycard :pin :login] [])
(update-in [:keycard :application-info]
assoc
:puk-retry-counter 5
:pin-retry-counter 3)
(assoc-in [:keycard :profile/profile]
(update account-data :whisper-public-key address/normalized-hex))
(assoc-in [:keycard :flow] nil)
(update :profile/login assoc
:password encryption-public-key
:key-uid key-uid
:name name))
:keycard/login-with-keycard {:multiaccount-data multiaccount-data
:password encryption-public-key
:chat-key whisper-private-key
:key-uid key-uid}}
(when save-keys?
(keychain/save-keycard-keys key-uid encryption-public-key whisper-private-key))
(clear-on-card-connected)
(clear-on-card-read)
(hide-connection-sheet))))
(rf/defn blocked-or-frozen-keycard-popup
[{:keys [db] :as cofx} card-status]
(rf/merge
cofx
{:db (assoc-in db [:keycard :pin :status] card-status)}
(hide-connection-sheet)
; do not try to display the popover if it is already open or
; we are in the login interface (which has a different handling)
(when-not (or (:profile/login db) (:popover/popover db))
(popover/show-popover {:view card-status}))))
(rf/defn blocked-keycard-popup
[cofx]
(blocked-or-frozen-keycard-popup cofx :blocked-card))
(rf/defn frozen-keycard-popup
[cofx]
(blocked-or-frozen-keycard-popup cofx :frozen-card))
(rf/defn on-get-keys-error
{:events [:keycard.callback/on-get-keys-error]}
[{:keys [db] :as cofx} error]
(log/debug "[keycard] get keys error: " error)
(let [tag-was-lost? (tag-lost? (:error error))
key-uid (get-in db [:keycard :application-info :key-uid])
flow (get-in db [:keycard :flow])
pin-retries-count (pin-retries (:error error))]
(if tag-was-lost?
{:db (assoc-in db [:keycard :pin :status] nil)}
(if-not (nil? pin-retries-count)
(rf/merge
cofx
{:db (-> db
(assoc-in [:keycard :application-info :pin-retry-counter] pin-retries-count)
(update-in [:keycard :pin]
assoc
:status :error
:login []
:import-multiaccount []
:error-label :t/pin-mismatch))}
(hide-connection-sheet)
(when (zero? pin-retries-count) (frozen-keycard-popup)))
(show-wrong-keycard-alert)))))
(rf/defn factory-reset
{:events [:keycard/factory-reset]}
[{:keys [db]} on-card-read]
(log/debug "[keycard] factory-reset")
{:db (update db :keycard dissoc :factory-reset-card?)
:keycard/factory-reset {:on-success on-card-read}})
;; Get application info
(rf/defn update-pairings
[{:keys [db]} instance-uid pairing]
(let [paired-on (datetime/timestamp)
pairings (-> (get-in db [:keycard :pairings])
(assoc instance-uid {:pairing pairing :paired-on paired-on}))]
{:keycard/persist-pairings pairings
:db (assoc-in db [:keycard :pairings] pairings)}))
(rf/defn get-application-info
{:events [:keycard/get-application-info]}
[{:keys [db]} on-card-read]
(log/debug "[keycard] get-application-info")
{:keycard/get-application-info {:on-success on-card-read}})
(rf/defn on-get-application-info-success
{:events [:keycard.callback/on-get-application-info-success]}
[{:keys [db] :as cofx} info on-success]
(let [{:keys [pin-retry-counter puk-retry-counter instance-uid new-pairing]} info
view-id (:view-id db)
{:keys [on-card-read]} (:keycard db)
on-success' (or on-success
on-card-read)
enter-step (get-in db
[:keycard :pin
:enter-step])]
(log/debug "[keycard] on-get-application-info-success"
"on-success" on-success'
"pin-retry-counter" pin-retry-counter
"puk-retry-counter" puk-retry-counter)
(rf/merge
cofx
{:db (-> db
(assoc-in [:keycard :pin :enter-step] enter-step)
(assoc-in [:keycard :application-info] info)
(assoc-in [:keycard :application-info :applet-installed?] true)
(assoc-in [:keycard :application-info-error] nil))}
(stash-on-card-read)
(when new-pairing
(update-pairings instance-uid new-pairing))
(when (and (zero? pin-retry-counter)
(pos? puk-retry-counter)
(not= enter-step :puk))
(frozen-keycard-popup))
(fn [{:keys [db] :as cofx}]
(if (zero? puk-retry-counter)
(blocked-keycard-popup cofx)
(when on-success'
(dispatch-event cofx on-success')))))))
(rf/defn on-get-application-info-error
{:events [:keycard.callback/on-get-application-info-error]}
[{:keys [db] :as cofx} error]
(let [on-card-read (get-in db [:keycard :on-card-read])
on-card-connected (get-in db [:keycard :on-card-connected])
last-on-card-connected (get-in db [:keycard :last-on-card-connected])
login? (= on-card-read :keycard/login-with-keycard)
tag-was-lost? (tag-lost? (:error error))]
(log/debug "[keycard] application info error"
error
on-card-connected
last-on-card-connected)
(when-not tag-was-lost?
(if login?
(rf/merge cofx
(clear-on-card-read)
(navigation/navigate-to :not-keycard nil))
(rf/merge cofx
{:db (assoc-in db [:keycard :application-info-error] error)}
(when (contains?
#{last-on-card-connected on-card-connected}
:keycard/prepare-to-sign)
(show-wrong-keycard-alert))
(when on-card-read
(dispatch-event on-card-read)))))))
(rf/defn on-card-connected
{:events [::on-card-connected]}
[{:keys [db] :as cofx} _]
(let [instance-uid (get-in db [:keycard :application-info :instance-uid])
key-uid (get-in db [:keycard :application-info :key-uid])
should-read-instance-uid? (nil? instance-uid)
on-card-connected (get-in db [:keycard :on-card-connected])
on-card-read (cond
should-read-instance-uid? :keycard/get-application-info
:else (get-in db [:keycard :on-card-read]))]
(log/debug "[keycard] on-card-connected" on-card-connected
"on-card-read" on-card-read)
(when on-card-connected
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :card-read-in-progress?] (boolean on-card-read)))}
(when on-card-connected
(dispatch-event on-card-connected))
(stash-on-card-connected)
(when (and on-card-read
(nil? on-card-connected))
(get-application-info on-card-read))))))
(rf/defn on-card-disconnected
{:events [::on-card-disconnected]}
[{:keys [db] :as cofx} _]
(log/debug "[keycard] card disconnected")
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :card-read-in-progress?] false))}
(restore-on-card-connected)
(restore-on-card-read)))
(defn keycard-multiaccount?
[db]
(boolean (get-in db [:profile/profile :keycard-pairing])))
(rf/defn verify-pin
{:events [:keycard/verify-pin]}
[{:keys [db] :as cofx} {:keys [pin-step on-card-connected on-failure on-success]}]
(let [on-success (or on-success
(get-in db [:keycard :pin :on-verified]))
on-failure (or on-failure
(get-in db [:keycard :pin :on-verified-failure]))
pin-step (or pin-step
(get-in db [:keycard :pin :step]))]
(rf/merge
cofx
{:db (update-in db
[:keycard :pin]
assoc
:step pin-step
:on-verified on-success
:on-verified-failure on-failure)}
(show-connection-sheet
{:on-card-connected (or on-card-connected :keycard/verify-pin)
:handler
(fn [{:keys [db] :as cofx}]
(let [pin (vector->string (get-in db [:keycard :pin pin-step]))]
(rf/merge
cofx
{:db (assoc-in db [:keycard :pin :status] :verifying)
:keycard/verify-pin {:pin pin}})))}))))
(rf/defn navigete-to-keycard-settings
{:events [::navigate-to-keycard-settings]}
[cofx]
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings]))
@@ -1,43 +0,0 @@
(ns legacy.status-im.keycard.common-test
(:require
[cljs.test :refer-macros [deftest is testing]]
[legacy.status-im.keycard.common :as common]))
(deftest test-show-connection-sheet
(testing "the card is not connected yet"
(let [db {:keycard {:card-connected? false}}
res (common/show-connection-sheet-component
{:db db}
{:on-card-connected :do-something
:handler (fn [{:keys [db]}]
{:db (assoc db :some-key :some-value)})})]
(is (= :do-something
(get-in res [:db :keycard :on-card-connected])))
(is (nil? (get-in res [:db :some-key])))
(is (true? (get-in res [:db :bottom-sheet/show?])))))
(testing "the card is connected before the interaction"
(let [db {:keycard {:card-connected? true}}
res (common/show-connection-sheet-component
{:db db}
{:on-card-connected :do-something
:handler (fn [{:keys [db]}]
{:db (assoc db :some-key :some-value)})})]
(is (nil? (get-in res [:db :keycard :on-card-connected])))
(is (= :do-something
(get-in res [:db :keycard :last-on-card-connected])))
(is (= :some-value (get-in res [:db :some-key])))
(is (true? (get-in res [:db :bottom-sheet/show?])))))
(testing "on-card-connected is not specified"
(is
(thrown?
js/Error
(common/show-connection-sheet-component
{:db {}}
{:handler (fn [_])}))))
(testing "handler is not specified"
(is
(thrown?
js/Error
(common/show-connection-sheet-component
{:db {}}
{:on-card-connected :do-something})))))
-688
View File
@@ -1,688 +0,0 @@
(ns legacy.status-im.keycard.core
(:require
legacy.status-im.keycard.backup-key
[legacy.status-im.keycard.card :as card]
[legacy.status-im.keycard.change-pin :as change-pin]
[legacy.status-im.keycard.common :as common]
legacy.status-im.keycard.delete-key
legacy.status-im.keycard.export-key
[legacy.status-im.keycard.login :as login]
[legacy.status-im.keycard.mnemonic :as mnemonic]
[legacy.status-im.keycard.onboarding :as onboarding]
[legacy.status-im.keycard.recovery :as recovery]
[legacy.status-im.keycard.sign :as sign]
legacy.status-im.keycard.unpair
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
[re-frame.db]
[status-im.navigation.events :as navigation]
[taoensso.timbre :as log]
[utils.datetime :as datetime]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(rf/defn show-keycard-has-multiaccount-alert
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (assoc-in db [:keycard :setup-step] nil)
:effects.utils/show-confirmation {:title nil
:content (i18n/label
:t/keycard-has-multiaccount-on-it)
:cancel-button-text ""
:confirm-button-text :t/okay}}))
(rf/defn load-pin-screen
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :setup-step] :pin)
(assoc-in [:keycard :pin]
{:enter-step :original
:original []
:confirmation []}))}
(navigation/navigate-to :keycard-onboarding-pin nil)))
(rf/defn load-recovery-pin-screen
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :pin]
{:enter-step :import-multiaccount
:import-multiaccount []
:current []}))}
(common/listen-to-hardware-back-button)
(navigation/navigate-replace :keycard-recovery-pin nil)))
(rf/defn load-pairing
[{:keys [db]}]
(let [instance-uid (get-in db [:keycard :application-info :instance-uid])
pairing-data (or (get-in db [:keycard :pairings (keyword instance-uid)])
(get-in db [:keycard :pairings instance-uid]))]
{:db (update-in db [:keycard :secrets] merge pairing-data)}))
(rf/defn proceed-setup-with-initialized-card
[{:keys [db] :as cofx} flow instance-uid paired?]
(log/debug "[keycard] proceed-setup-with-initialized-card"
"instance-uid"
instance-uid)
(if (= flow :import)
(navigation/navigate-to cofx :keycard-recovery-no-key nil)
(if paired?
(rf/merge cofx
(common/listen-to-hardware-back-button)
(when (= flow :create)
(mnemonic/set-mnemonic))
(when (= flow :recovery)
(onboarding/proceed-with-generating-key)))
(if (get-in db [:keycard :secrets :password])
(onboarding/load-pairing-screen cofx)
(recovery/load-pair-screen cofx)))))
(rf/defn navigate-to-keycard-settings
{:events [:profile.ui/keycard-settings-button-pressed]}
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :pin :on-verified] nil)
(assoc-in [:keycard :setup-step] nil))}
(common/clear-on-card-connected)
(navigation/navigate-to :keycard-settings nil)))
(rf/defn password-option-pressed
{:eevents [:keycard.ui/password-option-pressed]}
[{:keys [db]}]
(when (= (get-in db [:keycard :flow]) :create)
#())) ;;TODO with v1 flow
(rf/defn settings-screen-did-load
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :pin :on-verified] nil)
(assoc-in [:keycard :setup-step] nil))}
(common/clear-on-card-connected)))
(defn reset-card-screen-did-load
[{:keys [db]}]
{:db (assoc-in db [:keycard :reset-card :disabled?] false)})
(defn enter-pin-screen-did-load
[{:keys [db]}]
(let [enter-step (get-in db [:keycard :pin :enter-step])]
{:db (assoc-in db [:keycard :pin enter-step] [])}))
(defn login-pin-screen-did-load
[{:keys [db]}]
(let [enter-step (get-in db [:keycard :pin :enter-step])]
{:db (-> db
(assoc-in [:keycard :pin enter-step] [])
(dissoc :intro-wizard :recovered-account?))}))
(defn multiaccounts-screen-did-load
[{:keys [db]}]
{:db (assoc-in db [:keycard :setup-step] nil)})
(defn authentication-method-screen-did-load
[{:keys [db]}]
{:db (assoc-in db [:keycard :setup-step] nil)})
(rf/defn set-nfc-supported
{:events [:keycard.callback/check-nfc-support-success]}
[_ supported?]
{:keycard/set-nfc-supported supported?})
;; TODO: Should be listener and replace the view in bottom sheet to avoid this
(rf/defn on-check-nfc-enabled-success
{:events [:keycard.callback/check-nfc-enabled-success]}
[{:keys [db]} nfc-enabled?]
(log/debug "[keycard] check-nfc-enabled-success"
"nfc-enabled?"
nfc-enabled?)
{:db (assoc-in db [:keycard :nfc-enabled?] nfc-enabled?)})
(defn- proceed-to-pin-confirmation
[fx]
(assoc-in fx [:db :keycard :pin :enter-step] :confirmation))
(defn- proceed-to-change-puk-confirmation
[fx]
(assoc-in fx [:db :keycard :pin :enter-step] :puk-confirmation))
(defn- proceed-to-pin-reset-confirmation
[fx]
(-> fx
(update-in [:db :keycard :pin] dissoc :reset-confirmation)
(assoc-in [:db :keycard :pin :enter-step] :reset-confirmation)))
(defn- proceed-to-puk-confirmation
[fx]
(assoc-in fx [:db :keycard :pin :enter-step] :puk))
(rf/defn on-unblock-pin-success
{:events [:keycard.callback/on-unblock-pin-success]}
[{:keys [db] :as cofx}]
(let [reset-pin (get-in db [:keycard :pin :reset])]
(rf/merge cofx
{:db
(-> db
(update-in [:keycard :application-info]
assoc
:puk-retry-counter 5
:pin-retry-counter 3)
(update-in [:keycard :pin]
assoc
:status :after-unblocking
:enter-step :login
:login reset-pin
:confirmation []
:puk []
:puk-restore? true
:error-label nil))}
(common/hide-connection-sheet)
(common/clear-on-card-connected)
(common/clear-on-card-read))))
(rf/defn on-unblock-pin-error
{:events [:keycard.callback/on-unblock-pin-error]}
[{:keys [db] :as cofx} error]
(let [tag-was-lost? (common/tag-lost? (:error error))
puk-retries (common/pin-retries (:error error))]
(log/debug "[keycard] unblock pin error" error)
(when-not tag-was-lost?
(rf/merge cofx
{:db
(-> db
(assoc-in [:keycard :application-info :puk-retry-counter] puk-retries)
(update-in [:keycard :pin]
merge
{:status (if (zero? puk-retries) :blocked-card :error)
:error-label :t/puk-mismatch
:enter-step :puk
:puk []}))}
(common/hide-connection-sheet)))))
(rf/defn clear-on-verify-handlers
[{:keys [db]}]
{:db (update-in db
[:keycard :pin]
dissoc
:on-verified-failure
:on-verified)})
(rf/defn on-verify-pin-success
{:events [:keycard.callback/on-verify-pin-success]}
[{:keys [db] :as cofx}]
(let [on-verified (get-in db [:keycard :pin :on-verified])]
(log/debug "[hardwaller] success pin verification. on-verified" on-verified)
(rf/merge cofx
{:db (update-in db
[:keycard :pin]
merge
{:status nil
:error-label nil})}
(common/clear-on-card-connected)
(common/clear-on-card-read)
;; TODO(Ferossgp): Each pin input should handle this event on it's own,
;; now for simplicity do not hide bottom sheet when generating key
;; and exporting key but should be refactored.
(when-not (contains? #{:keycard/generate-and-load-key
:wallet-legacy.accounts/generate-new-keycard-account
:keycard/remove-key-with-unpair
:keycard/unpair-and-delete}
on-verified)
(common/hide-connection-sheet))
(when-not (contains? #{:keycard/unpair
:keycard/generate-and-load-key
:keycard/remove-key-with-unpair
:keycard/unpair-and-delete
:wallet-legacy.accounts/generate-new-keycard-account}
on-verified)
(common/get-application-info nil))
(when on-verified
(common/dispatch-event on-verified))
(clear-on-verify-handlers))))
(rf/defn on-verify-pin-error
{:events [:keycard.callback/on-verify-pin-error]}
[{:keys [db] :as cofx} error]
(let [tag-was-lost? (common/tag-lost? (:error error))
setup? (boolean (get-in db [:keycard :setup-step]))
on-verified-failure (get-in db [:keycard :pin :on-verified-failure])
exporting? (get-in db [:keycard :on-export-success])
pin-retries (common/pin-retries (:error error))]
(log/debug "[keycard] verify pin error" error)
(when-not tag-was-lost?
(if-not (nil? pin-retries)
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :application-info :pin-retry-counter] pin-retries)
(update-in [:keycard :pin]
assoc
:status :error
:enter-step :current
:puk []
:current []
:original []
:confirmation []
:sign []
:error-label :t/pin-mismatch))}
(common/hide-connection-sheet)
(when (and (not setup?)
(not on-verified-failure))
(when exporting?
(navigation/navigate-back)))
;(navigation/navigate-to :enter-pin-settings nil)))
(when (zero? pin-retries) (common/frozen-keycard-popup))
(when on-verified-failure
(fn [_]
{:utils/dispatch-later
[{:dispatch [on-verified-failure]
:ms 200}]}))
#_(clear-on-verify-handlers))
(rf/merge cofx
(common/hide-connection-sheet)
(common/show-wrong-keycard-alert)
(clear-on-verify-handlers))))))
(rf/defn unblock-pin
{:events [:keycard/unblock-pin]}
[cofx]
(common/show-connection-sheet
cofx
{:on-card-connected :keycard/unblock-pin
:handler
(fn [{:keys [db]}]
(let [puk (common/vector->string (get-in db [:keycard :pin :puk]))
pin (common/vector->string (get-in db [:keycard :pin :reset]))
key-uid (get-in db [:keycard :application-info :key-uid])]
{:db (assoc-in db [:keycard :pin :status] :verifying)
:keycard/unblock-pin
{:puk puk
:new-pin pin}}))}))
(def pin-code-length 6)
(def puk-code-length 12)
(rf/defn handle-pin-input
[{:keys [db]} enter-step]
(let [numbers-entered (count (get-in db [:keycard :pin enter-step]))]
(when (or (= numbers-entered pin-code-length)
(= numbers-entered puk-code-length))
{:dispatch [:keycard/process-pin-input]})))
(rf/defn update-pin
{:events [:keycard.ui/pin-numpad-button-pressed]}
[{:keys [db] :as cofx} number enter-step]
(log/debug "update-pin" enter-step)
(let [numbers-entered (count (get-in db [:keycard :pin enter-step]))
need-update? (if (or (= enter-step :puk)
(= enter-step :puk-original)
(= enter-step :puk-confirmation))
(< numbers-entered puk-code-length)
(< numbers-entered pin-code-length))]
(rf/merge cofx
{:db (cond-> (-> db
(assoc-in [:keycard :pin :enter-step] enter-step)
(assoc-in [:keycard :pin :status] nil))
need-update? (update-in [:keycard :pin enter-step] (fnil conj []) number))}
(when need-update?
(handle-pin-input enter-step)))))
(defn- pin-enter-error
[fx error-label]
(update-in fx
[:db :keycard :pin]
merge
{:status :error
:error-label error-label
:enter-step :original
:original []
:confirmation []}))
(defn- puk-enter-error
[fx error-label]
(update-in fx
[:db :keycard :pin]
merge
{:status :error
:error-label error-label
:enter-step :puk-original
:puk-original []
:puk-confirmation []}))
(defn- pin-reset-error
[fx error-label]
(update-in fx
[:db :keycard :pin]
merge
{:status :error
:error-label error-label
:enter-step :reset
:reset []
:reset-confirmation []}))
; PIN enter steps:
; login - PIN is used to login
; sign - PIN for transaction sign
; current - current PIN to perform actions which require PIN auth
; original - new PIN when user changes it or creates new one
; confirmation - confirmation for new PIN
(rf/defn process-pin-input
{:events [:keycard/process-pin-input]}
[{:keys [db]}]
(let [enter-step (get-in db [:keycard :pin :enter-step])
pin (get-in db [:keycard :pin enter-step])
numbers-entered (count pin)]
(log/debug "[keycard] process-pin-input"
"enter-step" enter-step
"numbers-entered" numbers-entered)
(cond-> {:db (assoc-in db [:keycard :pin :status] nil)}
(and (= enter-step :login)
(= 6 numbers-entered))
(login/proceed-to-login)
(and (= enter-step :original)
(= pin-code-length numbers-entered))
(proceed-to-pin-confirmation)
(and (= enter-step :original)
(= pin-code-length numbers-entered)
(= common/default-pin (common/vector->string pin)))
(pin-enter-error :t/cannot-use-default-pin)
(and (= enter-step :import-multiaccount)
(= pin-code-length numbers-entered))
(recovery/load-recovering-key-screen)
(and (= enter-step :current)
(= pin-code-length numbers-entered))
(common/verify-pin {:pin-step :current})
(and (= enter-step :sign)
(= pin-code-length numbers-entered))
(sign/prepare-to-sign)
(and (= enter-step :puk)
(= puk-code-length numbers-entered))
(unblock-pin)
(and (= enter-step :confirmation)
(= (get-in db [:keycard :pin :original])
(get-in db [:keycard :pin :confirmation])))
(change-pin/change-pin)
(and (= enter-step :confirmation)
(= pin-code-length numbers-entered)
(not= (get-in db [:keycard :pin :original])
(get-in db [:keycard :pin :confirmation])))
(pin-enter-error :t/pin-mismatch)
(and (= enter-step :puk-original)
(= puk-code-length numbers-entered))
(proceed-to-change-puk-confirmation)
(and (= enter-step :puk-confirmation)
(= (get-in db [:keycard :pin :puk-original])
(get-in db [:keycard :pin :puk-confirmation])))
(change-pin/change-puk)
(and (= enter-step :puk-confirmation)
(= puk-code-length numbers-entered)
(not= (get-in db [:keycard :pin :puk-original])
(get-in db [:keycard :pin :puk-confirmation])))
(puk-enter-error :t/puk-mismatch)
(= enter-step :reset)
(proceed-to-pin-reset-confirmation)
(and (= enter-step :reset-confirmation)
(= (get-in db [:keycard :pin :reset])
(get-in db [:keycard :pin :reset-confirmation])))
(proceed-to-puk-confirmation)
(and (= enter-step :reset-confirmation)
(= pin-code-length numbers-entered)
(not= (get-in db [:keycard :pin :reset])
(get-in db [:keycard :pin :reset-confirmation])))
(pin-reset-error :t/pin-mismatch))))
(rf/defn set-multiaccount-pairing
[cofx _ pairing paired-on]
(rf/merge cofx
(multiaccounts.update/multiaccount-update
:keycard-pairing
pairing
{})
(multiaccounts.update/multiaccount-update
:keycard-paired-on
paired-on
{})))
(rf/defn on-retrieve-pairings-success
{:events [:keycard.callback/on-retrieve-pairings-success]}
[{:keys [db]} pairings]
(card/set-pairings pairings)
{:db (assoc-in db [:keycard :pairings] pairings)})
;; When pairing to device has completed, we need to persist pairing data to
;; local storage. That's needed to ensure that during keycard setup
;; keycard won't run out of pairings slots, ie. we don't pair the same
;; card to the same device more than one time. Also, this allows the user to proceed
;; with setup and skip the pairing step if the pairing was already done during a previous
;; unfinished setup.
(rf/defn on-pair-success
{:events [:keycard.callback/on-pair-success]}
[{:keys [db] :as cofx} pairing]
(let [setup-step (get-in db [:keycard :setup-step])
flow (get-in db [:keycard :flow])
instance-uid (get-in db [:keycard :application-info :instance-uid])
multiaccount (common/find-multiaccount-by-keycard-instance-uid db instance-uid)
paired-on (datetime/timestamp)
pairings (-> (get-in db [:keycard :pairings])
(dissoc (keyword instance-uid))
(assoc instance-uid {:pairing pairing :paired-on paired-on}))
next-step (if (= setup-step :pair)
:begin
:card-ready)]
(rf/merge cofx
{:keycard/persist-pairings pairings
:db (-> db
(assoc-in [:keycard :pairings] pairings)
(assoc-in [:keycard :application-info :paired?] true)
(assoc-in [:keycard :setup-step] next-step)
(assoc-in [:keycard :secrets :pairing] pairing)
(assoc-in [:keycard :secrets :paired-on] paired-on))}
(when-not (and (= flow :recovery) (= next-step :card-ready))
(common/hide-connection-sheet))
(when multiaccount
(set-multiaccount-pairing multiaccount pairing paired-on))
(when (= flow :login)
(navigation/navigate-to :multiaccounts nil))
(when (= flow :recovery)
(onboarding/proceed-with-generating-key))
(when (= flow :import)
(load-recovery-pin-screen))
;; TODO: If card is already initialized need to confirm pin only then go to mnenmonic
;; https://github.com/status-im/status-mobile/issues/9451
(when (= flow :create)
(mnemonic/set-mnemonic)))))
(rf/defn on-pair-error
{:events [:keycard.callback/on-pair-error]}
[{:keys [db] :as cofx} {:keys [error code]}]
(log/debug "[keycard] pair error: " error)
(let [setup-step (get-in db [:keycard :setup-step])
tag-was-lost? (common/tag-lost? error)
flow (get-in db [:keycard :flow])]
(log/debug "[keycard] on-pair-error" setup-step "flow:" flow)
(when-not tag-was-lost?
(rf/merge cofx
{:db (assoc-in db [:keycard :setup-error] (i18n/label :t/invalid-pairing-password))}
(common/set-on-card-connected (if (= setup-step :pairing)
:keycard/load-pairing-screen
:keycard/pair))
(common/hide-connection-sheet)
(when (= flow :import)
(navigation/navigate-to :keycard-recovery-pair nil))
(when (not= setup-step :enter-pair-code)
(common/process-error code error))))))
(rf/defn set-setup-step
[{:keys [db]} card-state]
{:db (assoc-in db
[:keycard :setup-step]
(case card-state
:not-paired :pair
:no-pairing-slots :no-slots
:init :card-ready
:profile/profile :import-multiaccount
:begin))})
(rf/defn show-no-keycard-applet-alert
[_]
{:effects.utils/show-confirmation {:title (i18n/label :t/no-keycard-applet-on-card)
:content (i18n/label
:t/keycard-applet-install-instructions)
:cancel-button-text ""
:confirm-button-text :t/okay}})
;; NOTE: Maybe replaced by multiple events based on on flow to make it easier to maintain.
;; Because there are many execution paths it is harder to follow all possible states.
(rf/defn check-card-state
{:events [:keycard/check-card-state]}
[{:keys [db] :as cofx}]
(let [app-info (get-in db [:keycard :application-info])
flow (get-in db [:keycard :flow])
{:keys [instance-uid key-uid paired?]} app-info
card-state (common/get-card-state app-info)]
(log/debug "[keycard] check-card-state"
"card-state" card-state
"flow" flow)
(rf/merge cofx
{:db (assoc-in db [:keycard :card-state] card-state)}
(set-setup-step card-state)
(when paired?
(load-pairing))
(if (and flow
(= card-state :init))
(proceed-setup-with-initialized-card flow instance-uid paired?)
(common/hide-connection-sheet))
(when (= card-state :pre-init)
(if (= flow :import)
(navigation/navigate-to :keycard-recovery-no-key nil)
(fn [cofx]
(rf/merge
cofx
(common/clear-on-card-read)
(load-pin-screen)))))
(when (and (= card-state :profile/profile)
(= flow :import))
(if (common/find-multiaccount-by-key-uid db key-uid)
;; reimplement
;;(multiaccounts.recover/show-existing-multiaccount-alert key-uid)
(if paired?
(load-recovery-pin-screen)
(recovery/load-pair-screen))))
(when (= card-state :blank)
(if (= flow :import)
(navigation/navigate-to :keycard-recovery-no-key nil)
(show-no-keycard-applet-alert)))
(when (and (= card-state :profile/profile)
(#{:create :recovery} flow))
(show-keycard-has-multiaccount-alert)))))
(rf/defn on-card-connected
{:events [:keycard.callback/on-card-connected]}
[{:keys [db]} _]
(log/debug "[keycard] card globally connected")
{:db (assoc-in db [:keycard :card-connected?] true)})
(rf/defn on-card-disconnected
{:events [:keycard.callback/on-card-disconnected]}
[{:keys [db]} _]
(log/debug "[keycard] card disconnected")
{:db (assoc-in db [:keycard :card-connected?] false)})
(rf/defn on-nfc-user-cancelled
{:events [:keycard.callback/on-nfc-user-cancelled]}
[{:keys [db]} _]
(log/debug "[keycard] nfc user cancelled")
{:dispatch [:signing.ui/cancel-is-pressed]})
(rf/defn on-nfc-timeout
{:events [:keycard.callback/on-nfc-timeout]}
[{:keys [db]} _]
(log/debug "[keycard] nfc timeout")
{:db (-> db
(assoc-in [:keycard :nfc-running?] false)
(assoc-in [:keycard :card-connected?] false))
:dispatch-later [{:ms 500 :dispatch [:keycard.ui/start-nfc]}]})
(rf/defn on-register-card-events
{:events [:keycard.callback/on-register-card-events]}
[{:keys [db]} listeners]
{:db (update-in db [:keycard :listeners] merge listeners)})
(rf/defn ui-recovery-phrase-cancel-pressed
{:events [:keycard.ui/recovery-phrase-cancel-pressed]}
[{:keys [db]}]
{:db (assoc-in db [:keycard :setup-step] :recovery-phrase)})
(rf/defn ui-pin-numpad-delete-button-pressed
{:events [:keycard.ui/pin-numpad-delete-button-pressed]}
[{:keys [db]} step]
(when-not (empty? (get-in db [:keycard :pin step]))
{:db (update-in db [:keycard :pin step] pop)}))
(rf/defn start-nfc
{:events [:keycard.ui/start-nfc]}
[cofx]
{:keycard/start-nfc nil})
(rf/defn stop-nfc
{:events [:keycard.ui/stop-nfc]}
[cofx]
{:keycard/stop-nfc nil
:keycard.callback/on-card-disconnected nil})
(rf/defn start-nfc-success
{:events [:keycard.callback/start-nfc-success]}
[{:keys [db]} _]
(log/debug "[keycard] nfc started success")
{:db (assoc-in db [:keycard :nfc-running?] true)})
(rf/defn start-nfc-failure
{:events [:keycard.callback/start-nfc-failure]}
[{:keys [db]} _]
(log/debug "[keycard] nfc failed starting")) ;; leave current value on :nfc-running
(rf/defn stop-nfc-success
{:events [:keycard.callback/stop-nfc-success]}
[{:keys [db]} _]
(log/debug "[keycard] nfc stopped success")
(log/debug "[keycard] setting card-connected? and nfc-running? to false")
{:db (-> db
(assoc-in [:keycard :nfc-running?] false)
(assoc-in [:keycard :card-connected?] false))})
(rf/defn stop-nfc-failure
{:events [:keycard.callback/stop-nfc-failure]}
[{:keys [db]} _]
(log/debug "[keycard] nfc failed stopping")) ;; leave current value on :nfc-running
(rf/defn init
{:events [:keycard/init]}
[_]
{:keycard/register-card-events nil
:keycard/check-nfc-support nil
:keycard/check-nfc-enabled nil
:keycard/retrieve-pairings nil})
@@ -1,77 +0,0 @@
(ns legacy.status-im.keycard.core-test)
;;TODO re-enable after fixing keycard flow
#_(deftest process-pin-input
(testing "start entering PIN"
(is (= {:db {:keycard {:pin {:original [1]
:confirmation []
:status nil
:enter-step :original}}}}
(keycard/process-pin-input {:db {:keycard {:pin {:original [1]
:confirmation []
:enter-step :original}}}}))))
(testing "first 6 numbers entered"
(is (= {:db {:keycard {:pin {:original [1 2 3 4 5 6]
:confirmation []
:status nil
:enter-step :confirmation}}}}
(keycard/process-pin-input {:db {:keycard {:pin {:original [1 2 3 4 5 6]
:confirmation []
:enter-step :original}}}}))))
(testing "confirmation entered"
(is (= {:db {:keycard {:pin {:original [1 2 3 4 5 6]
:confirmation [1 2 3 4 5 6]
:current [1 1 1 1 1 1]
:enter-step :confirmation
:status :verifying}
:card-connected? true}}
:keycard/change-pin {:new-pin "123456"
:current-pin "111111"
:pairing nil}}
(keycard/process-pin-input {:db {:keycard {:pin {:original [1 2 3 4 5 6]
:confirmation [1 2 3 4 5 6]
:current [1 1 1 1 1 1]
:enter-step :confirmation}
:card-connected? true}}}))))
(testing "confirmation doesn't match"
(is (= {:db {:keycard {:pin {:original []
:confirmation []
:enter-step :original
:error-label :t/pin-mismatch
:status :error}}}}
(keycard/process-pin-input {:db {:keycard {:pin {:original [1 2 3 4 5 6]
:confirmation [1 2 3 4 5 7]
:enter-step :confirmation}}}})))))
#_(deftest on-generate-and-load-key-success
(is
(=
(select-keys
(get-in
(keycard/on-generate-and-load-key-success
{:random-guid-generator (constantly "")
:signing-phrase ""
:status ""
:db {}}
#js
{"whisper-private-key" "f342f3ef17ce86abfa92b912b3a108a4546cfc687fd8e0f02fedf87a60ee4c0f"
"whisper-public-key"
"04de2e21f1642ebee03b9aa4bf1936066124cc89967eaf269544c9b90c539fd5c980166a897d06dd4d3732b38116239f63c89395a8d73eac72881fab802010cb56"
"encryption-public-key"
"04f2a432677a1b7c4f1bb22078135821d1d10fce23422297b5c808a545f2b61cdba38ee7394762172fc6ff5e9e28db7535e555efe2812905ffd4e0c25e82a98ae8"
"whisper-address" "87df2285f90b71221fab6267b7cb37532fedbb1f"
"wallet-address" "7e92236392a850980d00d0cd2a4b92886bd7fe7b"})
[:db :keycard :profile/profile])
[:whisper-private-key
:whisper-public-key
:encryption-public-key
:wallet-address
:whisper-address]))
{:whisper-private-key "f342f3ef17ce86abfa92b912b3a108a4546cfc687fd8e0f02fedf87a60ee4c0f"
:whisper-public-key
"0x04de2e21f1642ebee03b9aa4bf1936066124cc89967eaf269544c9b90c539fd5c980166a897d06dd4d3732b38116239f63c89395a8d73eac72881fab802010cb56"
:encryption-public-key
"04f2a432677a1b7c4f1bb22078135821d1d10fce23422297b5c808a545f2b61cdba38ee7394762172fc6ff5e9e28db7535e555efe2812905ffd4e0c25e82a98ae8"
:whisper-address "87df2285f90b71221fab6267b7cb37532fedbb1f"
:wallet-address "7e92236392a850980d00d0cd2a4b92886bd7fe7b"}))
@@ -1,47 +0,0 @@
(ns legacy.status-im.keycard.delete-key
(:require
[legacy.status-im.keycard.common :as common]
[status-im.navigation.events :as navigation]
[utils.re-frame :as rf]))
(rf/defn reset-card-pressed
{:events [:keycard-settings.ui/reset-card-pressed]}
[cofx]
(navigation/navigate-to cofx :reset-card nil))
(rf/defn delete-card
[{:keys [db] :as cofx}]
(let [key-uid (get-in db [:keycard :application-info :key-uid])
multiaccount-key-uid (get-in db [:profile/profile :key-uid])]
(if (and key-uid
(= key-uid multiaccount-key-uid))
{:keycard/delete nil}
(common/unauthorized-operation cofx))))
(rf/defn navigate-to-reset-card-screen
{:events [:keycard/navigate-to-reset-card-screen]}
[cofx]
(navigation/navigate-to cofx :reset-card nil))
(rf/defn reset-card-next-button-pressed
{:events [:keycard-settings.ui/reset-card-next-button-pressed]}
[{:keys [db]}]
{:db (assoc-in db [:keycard :reset-card :disabled?] true)
:dispatch [:keycard/proceed-to-reset-card false]})
(rf/defn proceed-to-reset-card
{:events [:keycard/proceed-to-reset-card]}
[{:keys [db] :as cofx} keep-keys-on-keycard?]
(rf/merge cofx
{:db (assoc-in db
[:keycard :pin]
{:enter-step :current
:current []
:puk []
:status nil
:error-label nil
:on-verified (if keep-keys-on-keycard?
:keycard/unpair-and-delete
:keycard/remove-key-with-unpair)})}
(common/set-on-card-connected :keycard/navigate-to-enter-pin-screen)
(common/navigate-to-enter-pin-screen)))
@@ -1,13 +0,0 @@
(ns legacy.status-im.keycard.export-key
(:require
[legacy.status-im.keycard.common :as common]
[utils.re-frame :as rf]))
(rf/defn on-export-key-success
{:events [:keycard.callback/on-export-key-success]}
[{:keys [db] :as cofx} pubkey]
(let [callback-fn (get-in db [:keycard :on-export-success])]
(rf/merge cofx
{:dispatch (callback-fn pubkey)}
(common/clear-pin)
(common/hide-connection-sheet))))
-208
View File
@@ -1,208 +0,0 @@
(ns legacy.status-im.keycard.fx
(:require
["@react-native-async-storage/async-storage" :default AsyncStorage]
["react-native" :refer (BackHandler)]
[legacy.status-im.keycard.card :as card]
[legacy.status-im.utils.deprecated-types :as types]
[re-frame.core :as re-frame]
[taoensso.timbre :as log]))
(re-frame/reg-fx
:keycard/start-nfc
(fn []
(log/debug "fx start-nfc")
(card/start-nfc
{:on-success #(re-frame/dispatch [:keycard.callback/start-nfc-success])
:on-failure #(re-frame/dispatch [:keycard.callback/start-nfc-failure])})))
(re-frame/reg-fx
:keycard/stop-nfc
(fn []
(log/debug "fx stop-nfc")
(card/stop-nfc
{:on-success #(re-frame/dispatch [:keycard.callback/stop-nfc-success])
:on-failure #(re-frame/dispatch [:keycard.callback/stop-nfc-failure])})))
(re-frame/reg-fx
:keycard/set-nfc-message
card/set-nfc-message)
(re-frame/reg-fx
:keycard/start-nfc-and-show-connection-sheet
(fn [args]
(log/debug "fx start-nfc-and-show-connection-sheet")
(card/start-nfc
{:on-success
(fn []
(log/debug "nfc started successfully. next: show-connection-sheet")
(re-frame/dispatch [:keycard.callback/start-nfc-success])
(re-frame/dispatch [:keycard.callback/show-connection-sheet args]))
:on-failure
(fn []
(log/debug "nfc failed star starting. not calling show-connection-sheet")
(re-frame/dispatch [:keycard.callback/start-nfc-failure]))})))
(re-frame/reg-fx
:keycard/stop-nfc-and-hide-connection-sheet
(fn []
(log/debug "fx stop-nfc-and-hide-connection-sheet")
(card/stop-nfc
{:on-success
(fn []
(re-frame/dispatch [:keycard.callback/stop-nfc-success])
(re-frame/dispatch [:keycard.callback/hide-connection-sheet]))
:on-failure
(fn []
(re-frame/dispatch [:keycard.callback/stop-nfc-failure]))})))
(re-frame/reg-fx
:keycard/get-application-info
card/get-application-info)
(re-frame/reg-fx
:keycard/factory-reset
card/factory-reset)
(re-frame/reg-fx
:keycard/check-nfc-support
card/check-nfc-support)
(re-frame/reg-fx
:keycard/check-nfc-enabled
card/check-nfc-enabled)
(re-frame/reg-fx
:keycard/open-nfc-settings
card/open-nfc-settings)
(re-frame/reg-fx
:keycard/install-applet-and-init-card
card/install-applet-and-init-card)
(re-frame/reg-fx
:keycard/init-card
card/init-card)
(re-frame/reg-fx
:keycard/register-card-events
card/register-card-events)
(re-frame/reg-fx
:keycard/remove-event-listeners
card/remove-event-listeners)
(re-frame/reg-fx
:keycard/pair
card/pair)
(re-frame/reg-fx
:keycard/generate-and-load-key
card/generate-and-load-key)
(re-frame/reg-fx
:keycard/unblock-pin
card/unblock-pin)
(re-frame/reg-fx
:keycard/verify-pin
card/verify-pin)
(re-frame/reg-fx
:keycard/change-pin
card/change-pin)
(re-frame/reg-fx
:keycard/change-puk
card/change-puk)
(re-frame/reg-fx
:keycard/change-pairing
card/change-pairing)
(re-frame/reg-fx
:keycard/unpair
card/unpair)
(re-frame/reg-fx
:keycard/delete
card/delete)
(re-frame/reg-fx
:keycard/remove-key
card/remove-key)
(re-frame/reg-fx
:keycard/remove-key-with-unpair
card/remove-key-with-unpair)
(re-frame/reg-fx
:keycard/export-key
card/export-key)
(re-frame/reg-fx
:keycard/unpair-and-delete
card/unpair-and-delete)
(re-frame/reg-fx
:keycard/import-keys
card/import-keys)
(re-frame/reg-fx
:keycard/get-keys
card/get-keys)
(re-frame/reg-fx
:keycard/sign
card/sign)
(re-frame/reg-fx
:keycard/sign-typed-data
card/sign-typed-data)
(re-frame/reg-fx
:keycard/login-with-keycard
card/login)
(re-frame/reg-fx
:send-transaction-with-signature
card/send-transaction-with-signature)
(re-frame/reg-fx
:keycard/persist-pairings
(fn [pairings]
(.. AsyncStorage
(setItem "status-keycard-pairings" (types/serialize pairings)))))
(re-frame/reg-fx
:keycard/retrieve-pairings
(fn []
(.. AsyncStorage
(getItem "status-keycard-pairings")
(then #(re-frame/dispatch [:keycard.callback/on-retrieve-pairings-success
(types/deserialize %)])))))
;; TODO: Should act differently on different views
(re-frame/reg-fx
:keycard/listen-to-hardware-back-button
;;NOTE: not done in view because effect should happen under different conditions and is not dependent on
;;particular screen to be loaded. An fx is easier to re-use and test.
(fn []
(re-frame/dispatch [:keycard/add-listener-to-hardware-back-button
(.addEventListener BackHandler
"hardwareBackPress"
(fn []
(re-frame/dispatch [:keycard/back-button-pressed])
true))])))
(re-frame/reg-fx
:keycard/remove-listener-to-hardware-back-button
(fn [^js listener]
(.remove listener)))
(re-frame/reg-fx
:keycard/save-multiaccount-and-login
card/save-multiaccount-and-login)
(re-frame/reg-fx
:keycard/delete-multiaccount-before-migration
card/delete-multiaccount-before-migration)
-182
View File
@@ -1,182 +0,0 @@
(ns legacy.status-im.keycard.login
(:require
[legacy.status-im.bottom-sheet.events :as bottom-sheet]
[legacy.status-im.keycard.common :as common]
legacy.status-im.keycard.fx
[legacy.status-im.keycard.onboarding :as onboarding]
[legacy.status-im.keycard.recovery :as recovery]
[legacy.status-im.signing.core :as signing.core]
[legacy.status-im.utils.deprecated-types :as types]
[status-im.navigation.events :as navigation]
[taoensso.timbre :as log]
[utils.address :as address]
[utils.re-frame :as rf]))
(rf/defn login-got-it-pressed
{:events [:keycard.login.pin.ui/got-it-pressed
:keycard.login.pin.ui/cancel-pressed]}
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db db}
(navigation/pop-to-root :screen/profile.profiles)))
(rf/defn login-pin-more-icon-pressed
{:events [:keycard.login.pin.ui/more-icon-pressed]}
[cofx]
(bottom-sheet/hide-bottom-sheet-old cofx))
(rf/defn login-create-key-pressed
{:events [:keycard.login.ui/create-new-key-pressed]}
[cofx]
(rf/merge cofx
(bottom-sheet/hide-bottom-sheet-old)
(onboarding/start-onboarding-flow)))
(rf/defn login-add-key-pressed
{:events [:keycard.login.ui/add-key-pressed]}
[cofx]
(recovery/start-import-flow cofx))
(rf/defn login-remember-me-changed
{:events [:keycard.login.ui/remember-me-changed]}
[{:keys [db] :as cofx} value]
(rf/merge cofx
{:db (assoc-in db [:keycard :remember-me?] value)}))
(rf/defn login-pair-card-pressed
{:events [:keycard.login.ui/pair-card-pressed]}
[{:keys [db] :as cofx}]
(log/debug "[keycard] load-pair-card-pressed")
(rf/merge cofx
{:db (assoc-in db [:keycard :flow] :login)}
(navigation/navigate-to :keycard-recovery-pair nil)))
(rf/defn reset-pin
{:events [::reset-pin]}
[{:keys [db] :as cofx}]
(rf/merge
cofx
(signing.core/discard)
(fn [{:keys [db]}]
{:db (-> db
(dissoc :popover/popover)
(update-in [:keycard :pin]
dissoc
:reset
:puk)
(update-in [:keycard :pin]
assoc
:enter-step :reset
:error nil
:status nil))
:hide-popover nil})
(when (:profile/profile db)
(navigation/navigate-to :my-profile nil))
(when-not (:profile/login db)
(if (:popover/popover db)
(navigation/navigate-replace :keycard-pin nil)
(navigation/navigate-to :keycard-pin nil)))))
(rf/defn dismiss-frozen-keycard-popover
{:events [::frozen-keycard-popover-dismissed]}
[{:keys [db]}]
{:db (-> db
(dissoc :popover/popover)
(update :keycard dissoc :setup-step))
:hide-popover nil})
(rf/defn login-with-keycard
{:events [:keycard/login-with-keycard]}
[{:keys [db] :as cofx}]
(let [{:keys [:pin-retry-counter :puk-retry-counter]
:as application-info}
(get-in db [:keycard :application-info])
key-uid (get-in db [:keycard :application-info :key-uid])
paired? (get-in db [:keycard :application-info :paired?])
multiaccount (get-in db
[:profile/profiles-overview (get-in db [:profile/login :key-uid])])
multiaccount-key-uid (get multiaccount :key-uid)
multiaccount-mismatch? (or (nil? multiaccount)
(not= multiaccount-key-uid key-uid))]
(log/debug "[keycard] login-with-keycard"
"empty application info" (empty? application-info)
"no key-uid" (empty? key-uid)
"multiaccount-mismatch?" multiaccount-mismatch?
"no pairing" paired?)
(cond
(empty? application-info)
(rf/merge cofx
(common/hide-connection-sheet)
(navigation/navigate-to :not-keycard nil))
(empty? key-uid)
(rf/merge cofx
(common/hide-connection-sheet)
(navigation/navigate-to :keycard-blank nil))
multiaccount-mismatch?
(rf/merge cofx
(common/hide-connection-sheet)
(navigation/navigate-to :keycard-wrong nil))
(not paired?)
(rf/merge cofx
(common/hide-connection-sheet)
(navigation/navigate-to :keycard-unpaired nil))
(and (zero? pin-retry-counter)
(or (nil? puk-retry-counter)
(pos? puk-retry-counter)))
nil
:else
(common/get-keys-from-keycard cofx))))
(rf/defn proceed-to-login
{:events [::login-after-reset]}
[cofx]
(log/debug "[keycard] proceed-to-login")
(common/show-connection-sheet
cofx
{:sheet-options {:on-cancel [::common/cancel-sheet-confirm]}
:on-card-connected :keycard/get-application-info
:on-card-read :keycard/login-with-keycard
:handler (common/get-application-info :keycard/login-with-keycard)}))
(rf/defn on-keycard-keychain-keys
{:events [:multiaccounts.login.callback/get-keycard-keys-success]}
[{:keys [db] :as cofx} key-uid [encryption-public-key whisper-private-key :as creds]]
(if (nil? creds)
(navigation/set-stack-root cofx
:multiaccounts-stack
[:multiaccounts
:keycard-login-pin])
(let [{:keys [name]} (get-in db [:profile/profiles-overview key-uid])
multiaccount-data (types/clj->json {:name name
:key-uid key-uid})
account-data {:key-uid key-uid
:encryption-public-key encryption-public-key
:whisper-private-key whisper-private-key}]
{:db
(-> db
(assoc-in [:keycard :pin :status] nil)
(assoc-in [:keycard :pin :login] [])
(assoc-in [:keycard :profile/profile]
(update account-data :whisper-public-key address/normalized-hex))
(assoc-in [:keycard :flow] nil)
(update :profile/login assoc
:password encryption-public-key
:key-uid key-uid
:name name
:save-password? true))
:keycard/login-with-keycard
{:multiaccount-data multiaccount-data
:key-uid key-uid
:password encryption-public-key
:chat-key whisper-private-key}})))
(rf/defn on-login-success
{:events [:keycard.login.callback/login-success]}
[_ result]
(log/debug "loginWithKeycard success: " result))
@@ -1,37 +0,0 @@
(ns legacy.status-im.keycard.mnemonic
(:require
[legacy.status-im.keycard.common :as common]
legacy.status-im.keycard.fx
[status-im.navigation.events :as navigation]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
(rf/defn set-mnemonic
[{:keys [db] :as cofx}]
(log/debug "[keycard] set-mnemonic")
(let [selected-id (get-in db [:intro-wizard :selected-id])
mnemonic (reduce
(fn [_ {:keys [id mnemonic]}]
(when (= selected-id id)
(reduced mnemonic)))
nil
(get-in db [:intro-wizard :multiaccounts]))]
(rf/merge
cofx
{:db (-> db
(assoc-in [:keycard :setup-step] :recovery-phrase)
(assoc-in [:keycard :secrets :mnemonic] mnemonic))}
(common/clear-on-card-connected)
(common/hide-connection-sheet)
(navigation/navigate-replace :keycard-onboarding-recovery-phrase nil))))
(rf/defn load-loading-keys-screen
{:events [:keycard.ui/recovery-phrase-confirm-pressed
:keycard/load-loading-keys-screen]}
[{:keys [db] :as cofx}]
(rf/merge
cofx
{:db (assoc-in db [:keycard :setup-step] :loading-keys)}
(common/show-connection-sheet
{:on-card-connected :keycard/load-loading-keys-screen
:handler (common/dispatch-event :keycard/generate-and-load-key)})))
-11
View File
@@ -1,11 +0,0 @@
(ns legacy.status-im.keycard.nfc)
(def is-nfc-supported? (atom nil))
(defn set-nfc-supported?
[supported?]
(reset! is-nfc-supported? supported?))
(defn nfc-supported?
[]
@is-nfc-supported?)
@@ -1,335 +0,0 @@
(ns legacy.status-im.keycard.onboarding
(:require
[clojure.string :as string]
[legacy.status-im.keycard.common :as common]
legacy.status-im.keycard.fx
[legacy.status-im.keycard.mnemonic :as mnemonic]
[legacy.status-im.ui.components.react :as react]
[legacy.status-im.utils.utils :as utils]
[re-frame.core :as re-frame]
[status-im.constants :as constants]
[status-im.navigation.events :as navigation]
[taoensso.timbre :as log]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(rf/defn begin-setup-button-pressed
{:keys [:keycard.ui/begin-setup-button-pressed]}
[{:keys [db]}]
{:db (-> db
(assoc-in [:keycard :setup-step] :pin)
(assoc-in [:keycard :pin :enter-step] :original)
(assoc-in [:keycard :pin :original] [])
(assoc-in [:keycard :pin :confirmation] []))})
(rf/defn start-installation
[{:keys [db] :as cofx}]
(let [card-state (get-in db [:keycard :card-state])
pin (common/vector->string (get-in db [:keycard :pin :original]))]
(log/debug "start-installation: card-state" card-state)
(case card-state
:pre-init
{:keycard/init-card pin}
(do
(log/debug (str "Cannot start keycard installation from state: " card-state))
(rf/merge cofx
{:effects.utils/show-popup {:title (i18n/label :t/error)
:content (i18n/label :t/something-went-wrong)}}
(navigation/navigate-to :keycard-authentication-method nil))))))
(rf/defn load-preparing-screen
{:events [:keycard/load-preparing-screen]}
[cofx]
(common/show-connection-sheet
cofx
{:sheet-options {:on-cancel [::cancel-pressed]}
:on-card-connected :keycard/load-preparing-screen
:handler start-installation}))
(rf/defn load-pairing-screen
{:events [:keycard/load-pairing-screen
:keycard.onboarding.puk-code.ui/confirm-pressed]}
[{:keys [db] :as cofx}]
(rf/merge
cofx
{:db (assoc-in db [:keycard :setup-step] :pairing)}
(common/show-connection-sheet
{:sheet-options {:on-cancel [::cancel-pressed]}
:on-card-connected :keycard/load-pairing-screen
:handler (common/dispatch-event :keycard/pair)})))
(rf/defn puk-code-next-pressed
{:events [:keycard.onboarding.puk-code.ui/next-pressed]}
[_]
{:ui/show-confirmation {:title (i18n/label :t/secret-keys-confirmation-title)
:content (i18n/label :t/secret-keys-confirmation-text)
:confirm-button-text (i18n/label :t/yes)
:cancel-button-text (i18n/label :t/cancel)
:on-accept #(re-frame/dispatch
[:keycard.onboarding.puk-code.ui/confirm-pressed])
:on-cancel #()}})
(rf/defn load-finishing-screen
{:events [:keycard.onboarding.recovery-phrase-confirm-word2.ui/next-pressed
:keycard/load-finishing-screen]}
[{:keys [db] :as cofx}]
(rf/merge
cofx
{:db (assoc-in db [:keycard :setup-step] :loading-keys)}
(common/show-connection-sheet
{:sheet-options {:on-cancel [::cancel-pressed]}
:on-card-connected :keycard/load-finishing-screen
:handler (common/dispatch-event :keycard/generate-and-load-key)})))
(rf/defn recovery-phrase-learn-more-pressed
{:events [:keycard.onboarding.recovery-phrase.ui/learn-more-pressed]}
[_]
(.openURL ^js react/linking constants/keycard-integration-link))
(rf/defn recovery-phrase-next-pressed
{:events [:keycard.onboarding.recovery-phrase.ui/next-pressed
:keycard.ui/recovery-phrase-next-button-pressed]}
[_]
{:ui/show-confirmation {:title (i18n/label :t/keycard-recovery-phrase-confirmation-title)
:content (i18n/label :t/keycard-recovery-phrase-confirmation-text)
:confirm-button-text (i18n/label :t/yes)
:cancel-button-text (i18n/label :t/cancel)
:on-accept #(re-frame/dispatch
[:keycard.onboarding.recovery-phrase.ui/confirm-pressed])
:on-cancel #()}})
(rf/defn recovery-phrase-start-confirmation
[{:keys [db] :as cofx}]
(let [mnemonic (get-in db [:keycard :secrets :mnemonic])
[word1 word2] (shuffle (map-indexed vector (clojure.string/split mnemonic #" ")))
word1 (zipmap [:idx :word] word1)
word2 (zipmap [:idx :word] word2)]
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :setup-step] :recovery-phrase-confirm-word1)
(assoc-in [:keycard :recovery-phrase :step] :word1)
(assoc-in [:keycard :recovery-phrase :confirm-error] nil)
(assoc-in [:keycard :recovery-phrase :input-word] nil)
(assoc-in [:keycard :recovery-phrase :word1] word1)
(assoc-in [:keycard :recovery-phrase :word2] word2))}
(common/remove-listener-to-hardware-back-button))))
(rf/defn recovery-phrase-confirm-pressed
{:events [:keycard.onboarding.recovery-phrase.ui/confirm-pressed]}
[cofx]
(rf/merge cofx
(recovery-phrase-start-confirmation)
(navigation/navigate-to :keycard-onboarding-recovery-phrase-confirm-word1 nil)))
(rf/defn recovery-phrase-next-word
[{:keys [db]}]
{:db (-> db
(assoc-in [:keycard :recovery-phrase :step] :word2)
(assoc-in [:keycard :recovery-phrase :confirm-error] nil)
(assoc-in [:keycard :recovery-phrase :input-word] nil)
(assoc-in [:keycard :setup-step] :recovery-phrase-confirm-word2))})
(rf/defn proceed-with-generating-key
[{:keys [db] :as cofx}]
(let [pin (get-in db
[:keycard :secrets :pin]
(common/vector->string (get-in db [:keycard :pin :current])))]
(if (empty? pin)
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :pin]
{:enter-step :current
:on-verified :keycard/generate-and-load-key
:current []})
(assoc-in [:keycard :setup-step] :loading-keys))}
(navigation/navigate-to :keycard-onboarding-pin nil))
(load-finishing-screen cofx))))
(rf/defn recovery-phrase-confirm-word-next-pressed
{:events [:keycard.onboarding.recovery-phrase-confirm-word.ui/next-pressed
:keycard.onboarding.recovery-phrase-confirm-word.ui/input-submitted]}
[{:keys [db] :as cofx}]
(let [step (get-in db [:keycard :recovery-phrase :step])
input-word (get-in db [:keycard :recovery-phrase :input-word])
{:keys [word]} (get-in db [:keycard :recovery-phrase step])]
(if (= word input-word)
(if (= (:view-id db) :keycard-onboarding-recovery-phrase-confirm-word1)
(rf/merge cofx
(recovery-phrase-next-word)
(navigation/navigate-replace :keycard-onboarding-recovery-phrase-confirm-word2 nil))
(proceed-with-generating-key cofx))
{:db (assoc-in db [:keycard :recovery-phrase :confirm-error] (i18n/label :t/wrong-word))})))
(rf/defn recovery-phrase-confirm-word-input-changed
{:events [:keycard.onboarding.recovery-phrase-confirm-word.ui/input-changed]}
[{:keys [db]} input]
{:db (assoc-in db [:keycard :recovery-phrase :input-word] input)})
(rf/defn pair-code-input-changed
{:events [:keycard.onboarding.pair.ui/input-changed]}
[{:keys [db]} input]
{:db (assoc-in db [:keycard :secrets :password] input)})
(rf/defn keycard-option-pressed
{:events [:onboarding.ui/keycard-option-pressed]}
[{:keys [db] :as cofx}]
(let [flow (get-in db [:keycard :flow])]
(rf/merge cofx
{:keycard/check-nfc-enabled nil}
(if (= flow :import)
(navigation/navigate-to :keycard-recovery-intro nil)
(do
(common/listen-to-hardware-back-button)
(navigation/navigate-to :keycard-onboarding-intro nil))))))
(rf/defn start-onboarding-flow
{:events [:keycard/start-onboarding-flow]}
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (assoc-in db [:keycard :flow] :create)
:keycard/check-nfc-enabled nil}
(common/listen-to-hardware-back-button)
(navigation/navigate-to :keycard-onboarding-intro nil)))
(rf/defn open-nfc-settings-pressed
{:events [:keycard.onboarding.nfc-on/open-nfc-settings-pressed]}
[_]
{:keycard/open-nfc-settings nil})
(defn- show-recover-confirmation
[]
{:ui/show-confirmation {:title (i18n/label :t/are-you-sure?)
:content (i18n/label :t/are-you-sure-description)
:confirm-button-text (clojure.string/upper-case (i18n/label :t/yes))
:cancel-button-text (i18n/label :t/see-it-again)
:on-accept #(re-frame/dispatch
[:keycard.ui/recovery-phrase-confirm-pressed])
:on-cancel #(re-frame/dispatch
[:keycard.ui/recovery-phrase-cancel-pressed])}})
(rf/defn recovery-phrase-confirm-word
{:events [:keycard.ui/recovery-phrase-confirm-word-next-button-pressed]}
[{:keys [db]}]
(let [step (get-in db [:keycard :recovery-phrase :step])
input-word (get-in db [:keycard :recovery-phrase :input-word])
{:keys [word]} (get-in db [:keycard :recovery-phrase step])]
(if (= word input-word)
(if (= step :word1)
(recovery-phrase-next-word db)
(show-recover-confirmation))
{:db (assoc-in db [:keycard :recovery-phrase :confirm-error] (i18n/label :t/wrong-word))})))
(rf/defn recovery-phrase-next-button-pressed
[{:keys [db] :as cofx}]
(if (= (get-in db [:keycard :flow]) :create)
(recovery-phrase-start-confirmation cofx)
(let [mnemonic (get-in db [:multiaccounts/recover :passphrase])]
(rf/merge cofx
{:db (assoc-in db [:keycard :secrets :mnemonic] mnemonic)}
(mnemonic/load-loading-keys-screen)))))
(rf/defn on-install-applet-and-init-card-success
{:events [:keycard.callback/on-install-applet-and-init-card-success
:keycard.callback/on-init-card-success]}
[{:keys [db] :as cofx} secrets]
(let [secrets' (js->clj secrets :keywordize-keys true)]
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :card-state] :init)
(assoc-in [:keycard :setup-step] :secret-keys)
(update-in [:keycard :secrets] merge secrets'))}
(common/show-connection-sheet
{:on-card-connected :keycard/get-application-info
:on-card-read :keycard/check-card-state
:handler (common/get-application-info :keycard/check-card-state)}))))
(rf/defn on-install-applet-and-init-card-error
{:events [:keycard.callback/on-install-applet-and-init-card-error
:keycard.callback/on-init-card-error]}
[{:keys [db] :as cofx} {:keys [code error]}]
(log/debug "[keycard] install applet and init card error: " error)
(rf/merge cofx
{:db (assoc-in db [:keycard :setup-error] error)}
(common/set-on-card-connected :keycard/load-preparing-screen)
(common/process-error code error)))
(rf/defn generate-and-load-key
{:events [:keycard/generate-and-load-key]}
[{:keys [db] :as cofx}]
(let [{:keys [pin]}
(get-in db [:keycard :secrets])
{:keys [selected-id multiaccounts]}
(:intro-wizard db)
multiaccount (or (->> multiaccounts
(filter #(= (:id %) selected-id))
first)
(assoc (get-in db [:intro-wizard :root-key])
:derived
(get-in db [:intro-wizard :derived])))
recovery-mnemonic (get-in db [:intro-wizard :passphrase])
mnemonic (or (:mnemonic multiaccount)
recovery-mnemonic)
pin' (or pin
(common/vector->string (get-in db
[:keycard :pin
:current])))]
{:keycard/generate-and-load-key
{:mnemonic mnemonic
:pin pin'
:key-uid (:key-uid multiaccount)
:delete-multiaccount? (get-in db [:keycard :delete-account?])}}))
(rf/defn factory-reset-card-toggle
{:events [:keycard.onboarding.intro.ui/factory-reset-card-toggle]}
[{:keys [db] :as cofx} checked?]
{:db (assoc-in db [:keycard :factory-reset-card?] checked?)})
(rf/defn begin-setup-pressed
{:events [:keycard.onboarding.intro.ui/begin-setup-pressed]}
[{:keys [db] :as cofx}]
(rf/merge
cofx
{:db (-> db
(update :keycard
dissoc
:secrets
:card-state :multiaccount-wallet-address
:multiaccount-whisper-public-key :application-info)
(assoc-in [:keycard :setup-step] :begin)
(assoc-in [:keycard :pin :on-verified] nil))}
(if (get-in db [:keycard :factory-reset-card?])
(utils/show-confirmation {:title (i18n/label :t/keycard-factory-reset-title)
:content (i18n/label :t/keycard-factory-reset-text)
:confirm-button-text (i18n/label :t/yes)
:cancel-button-text (i18n/label :t/no)
:on-accept #(re-frame/dispatch [::factory-reset])
:on-cancel #(re-frame/dispatch [::factory-reset-cancel])})
(common/show-connection-sheet
{:on-card-connected :keycard/get-application-info
:on-card-read :keycard/check-card-state
:handler (common/get-application-info :keycard/check-card-state)}))))
(rf/defn factory-reset
{:events [::factory-reset]}
[cofx]
(common/show-connection-sheet
cofx
{:on-card-connected :keycard/factory-reset
:on-card-read :keycard/check-card-state
:handler (common/factory-reset :keycard/check-card-state)}))
(rf/defn factory-reset-cancel
{:events [::factory-reset-cancel]}
[{:keys [db] :as cofx}]
{:db (update db :keycard dissoc :factory-reset-card?)})
(rf/defn cancel-pressed
{:events [::cancel-pressed]}
[cofx]
(rf/merge cofx
(navigation/navigate-back)
(common/cancel-sheet-confirm)))
-355
View File
@@ -1,355 +0,0 @@
(ns legacy.status-im.keycard.recovery
(:require
[clojure.string :as string]
[legacy.status-im.bottom-sheet.events :as bottom-sheet]
[legacy.status-im.keycard.common :as common]
legacy.status-im.keycard.fx
[legacy.status-im.multiaccounts.create.core :as multiaccounts.create]
[legacy.status-im.multiaccounts.model :as multiaccounts.model]
[legacy.status-im.popover.core :as popover]
[legacy.status-im.utils.deprecated-types :as types]
[native-module.core :as native-module]
[re-frame.core :as re-frame]
[react-native.platform :as platform]
[status-im.constants :as constants]
[status-im.navigation.events :as navigation]
[taoensso.timbre :as log]
[utils.address :as address]
[utils.datetime :as datetime]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.security.core :as security]))
(rf/defn pair*
[_ password]
{:keycard/pair {:password password}})
(rf/defn pair
{:events [:keycard/pair]}
[cofx]
(let [{:keys [password]} (get-in cofx [:db :keycard :secrets])]
(common/show-connection-sheet
cofx
{:on-card-connected :keycard/pair
:handler (pair* password)})))
(rf/defn pair-code-next-button-pressed
{:events [:keycard.onboarding.pair.ui/input-submitted
:keycard.ui/pair-code-next-button-pressed
:keycard.onboarding.pair.ui/next-pressed]}
[{:keys [db] :as cofx}]
(let [pairing (get-in db [:keycard :secrets :pairing])
paired-on (get-in db [:keycard :secrets :paired-on] (datetime/timestamp))]
(rf/merge cofx
(if pairing
{:db (-> db
(assoc-in [:keycard :setup-step] :import-multiaccount)
(assoc-in [:keycard :secrets :paired-on] paired-on))}
(pair)))))
(rf/defn load-pair-screen
[{:keys [db] :as cofx}]
(log/debug "[keycard] load-pair-screen")
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :setup-step] :pair))
:dispatch [:bottom-sheet/hide-old]}
(common/listen-to-hardware-back-button)
(navigation/navigate-to :keycard-recovery-pair nil)))
(rf/defn keycard-storage-selected-for-recovery
{:events [:recovery.ui/keycard-storage-selected]}
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (assoc-in db [:keycard :flow] :recovery)}
(navigation/navigate-to :keycard-recovery-enter-mnemonic nil)))
(rf/defn start-import-flow
{:events [::recover-with-keycard-pressed]}
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db
(-> db
(assoc-in [:keycard :flow] :import)
(assoc :recovered-account? true))
:keycard/check-nfc-enabled nil}
(bottom-sheet/hide-bottom-sheet-old)
(navigation/navigate-to-within-stack [:keycard-recovery-intro
:screen/onboarding.new-to-status])))
(rf/defn access-key-pressed
{:events [:multiaccounts.recover.ui/recover-multiaccount-button-pressed]}
[_]
{:dispatch [:bottom-sheet/show-sheet-old :recover-sheet]})
(rf/defn recovery-keycard-selected
{:events [:recovery.ui/keycard-option-pressed]}
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (assoc-in db [:keycard :flow] :recovery)
:keycard/check-nfc-enabled nil}
(common/listen-to-hardware-back-button)
(navigation/navigate-to :keycard-onboarding-intro nil)))
(rf/defn cancel-pressed
{:events [::cancel-pressed]}
[cofx]
(rf/merge cofx
(common/cancel-sheet-confirm)
(navigation/navigate-back)))
(rf/defn begin-setup-pressed
{:events [:keycard.recovery.intro.ui/begin-recovery-pressed]}
[{:keys [db] :as cofx}]
(rf/merge
cofx
{:db (-> db
(update :keycard
dissoc
:secrets
:card-state :multiaccount-wallet-address
:multiaccount-whisper-public-key
:application-info)
(assoc-in [:keycard :setup-step] :begin)
(assoc-in [:keycard :pin :on-verified] nil))}
(common/show-connection-sheet
{:on-card-connected :keycard/get-application-info
:on-card-read :keycard/check-card-state
:sheet-options {:on-cancel [::cancel-pressed]}
:handler (common/get-application-info :keycard/check-card-state)})))
(rf/defn recovery-success-finish-pressed
{:events [:keycard.recovery.success/finish-pressed]}
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (update db
:keycard dissoc
:multiaccount-wallet-address
:multiaccount-whisper-public-key)}
(navigation/navigate-to (if platform/android?
:notifications-settings
:screen/onboarding.welcome)
nil)))
(rf/defn intro-wizard
{:events [:multiaccounts.create.ui/intro-wizard]}
[{:keys [db] :as cofx}]
(let [accs (get db :profile/profiles-overview)]
(rf/merge cofx
{:db (-> db
(update :keycard dissoc :flow)
(dissoc :restored-account?))}
(if (pos? (count accs))
(navigation/navigate-to :get-your-keys nil)
(navigation/set-stack-root :onboarding [:get-your-keys])))))
(rf/defn recovery-no-key
{:events [:keycard.recovery.no-key.ui/generate-key-pressed]}
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (assoc-in db [:keycard :flow] :create)
:keycard/check-nfc-enabled nil}
(intro-wizard)))
;; NOTE: currently non functional, keycard needs to be reimplemented
(rf/defn create-keycard-multiaccount
{:events [::create-keycard-multiaccount]
:interceptors [(re-frame/inject-cofx :random-guid-generator)
(re-frame/inject-cofx ::multiaccounts.create/get-signing-phrase)]}
[{:keys [db] :as cofx}]
(let [{{:keys [secrets flow] :profile/keys [profile]} :keycard} db
{:keys [address
name
public-key
whisper-public-key
wallet-public-key
wallet-root-public-key
whisper-address
wallet-address
wallet-root-address
whisper-private-key
encryption-public-key
instance-uid
key-uid
recovered]}
profile
{:keys [pairing paired-on]} secrets
{:keys [name]}
(if (nil? name)
;; name might have been generated during recovery via passphrase
(get-in db [:intro-wizard :derived constants/path-whisper-keyword])
{:name name})]
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :setup-step] nil)
(dissoc :intro-wizard))})))
(rf/defn return-to-keycard-login
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (-> db
(update-in [:keycard :pin]
assoc
:enter-step :login
:status nil
:login [])
(update :keycard dissoc :application-info))}
(navigation/set-stack-root :multiaccounts-stack
[:multiaccounts
:keycard-login-pin])))
(rf/defn on-backup-success
[{:keys [db] :as cofx} backup-type]
(rf/merge cofx
{:effects.utils/show-popup {:title (i18n/label (if (= backup-type :recovery-card)
:t/keycard-access-reset
:t/keycard-backup-success-title))
:content (i18n/label (if (= backup-type :recovery-card)
:t/keycard-can-use-with-new-passcode
:t/keycard-backup-success-body))}}
(cond
(multiaccounts.model/logged-in? db)
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings])
(:profile/login db)
(return-to-keycard-login)
:else
(navigation/set-stack-root :onboarding [:get-your-keys]))))
(re-frame/reg-fx
::finish-migration
(fn [[account settings password encryption-pass login-params]]
(native-module/convert-to-keycard-account
account
settings
password
encryption-pass
#(let [{:keys [error]} (types/json->clj %)]
(if (string/blank? error)
(native-module/login-with-keycard
(assoc login-params :node-config {:ProcessBackedupMessages true}))
(throw
(js/Error.
"Please shake the phone to report this error and restart the app. Migration failed unexpectedly.")))))))
(rf/defn migrate-account
[{:keys [db] :as cofx}]
(let [pairing (get-in db [:keycard :secrets :pairing])
paired-on (get-in db [:keycard :secrets :paired-on])
instance-uid (get-in db [:keycard :profile/profile :instance-uid])
account (-> db
:profile/login
(assoc :keycard-pairing pairing)
(assoc :save-password? false))
key-uid (-> account :key-uid)
settings {:keycard-instance-uid instance-uid
:keycard-paired-on paired-on
:keycard-pairing pairing}
password (native-module/sha3 (security/safe-unmask-data (get-in db
[:keycard
:migration-password])))
encryption-pass (get-in db [:keycard :profile/profile :encryption-public-key])
login-params {:key-uid key-uid
:multiaccount-data (types/clj->json account)
:password encryption-pass
:chat-key (get-in db
[:keycard :profile/profile :whisper-private-key])}]
{:db (-> db
(assoc-in [:profile/profiles-overview key-uid :keycard-pairing] pairing)
(assoc :profile/login account)
(assoc :auth-method "none")
(update :keycard dissoc :flow :migration-password)
(dissoc :recovered-account?))
::finish-migration [account settings password encryption-pass login-params]}))
(rf/defn delete-multiaccount
[{:keys [db]}]
(let [key-uid (get-in db [:profile/login :key-uid])]
{:keycard/delete-multiaccount-before-migration
{:key-uid key-uid
:on-error #(re-frame/dispatch [::delete-multiaccount-error %])
:on-success #(re-frame/dispatch [::create-keycard-multiaccount])}}))
(rf/defn handle-delete-multiaccount-error
{:events [::delete-multiaccount-error]}
[cofx _]
(popover/show-popover cofx {:view :transfer-multiaccount-unknown-error}))
(rf/defn on-generate-and-load-key-success
{:events [:keycard.callback/on-generate-and-load-key-success]
:interceptors [(re-frame/inject-cofx :random-guid-generator)
(re-frame/inject-cofx ::multiaccounts.create/get-signing-phrase)]}
[{:keys [db random-guid-generator] :as cofx} data]
(let [account-data (js->clj data :keywordize-keys true)
backup? (get-in db [:keycard :creating-backup?])
migration? (get-in db [:keycard :converting-account?])]
(rf/merge
cofx
{:db (-> db
(assoc-in
[:keycard :profile/profile]
(-> account-data
(update :address address/normalized-hex)
(update :whisper-address address/normalized-hex)
(update :wallet-address address/normalized-hex)
(update :wallet-root-address address/normalized-hex)
(update :public-key address/normalized-hex)
(update :whisper-public-key address/normalized-hex)
(update :wallet-public-key address/normalized-hex)
(update :wallet-root-public-key address/normalized-hex)
(update :instance-uid #(get-in db [:keycard :profile/profile :instance-uid] %))))
(assoc-in [:keycard :multiaccount-wallet-address] (:wallet-address account-data))
(assoc-in [:keycard :multiaccount-whisper-public-key] (:whisper-public-key account-data))
(assoc-in [:keycard :pin :status] nil)
(assoc-in [:keycard :application-info :key-uid]
(address/normalized-hex (:key-uid account-data)))
(update :keycard dissoc :recovery-phrase :creating-backup? :converting-account?)
(update-in [:keycard :secrets] dissoc :pin :puk :password :mnemonic)
(assoc :multiaccounts/new-installation-id (random-guid-generator)))}
(common/remove-listener-to-hardware-back-button)
(common/hide-connection-sheet)
(cond backup? (on-backup-success backup?)
migration? (migrate-account)
(get-in db [:keycard :delete-account?])
(delete-multiaccount)
:else (create-keycard-multiaccount)))))
(rf/defn on-generate-and-load-key-error
{:events [:keycard.callback/on-generate-and-load-key-error]}
[{:keys [db] :as cofx} {:keys [error code]}]
(log/debug "[keycard] generate and load key error: " error)
(when-not (common/tag-lost? error)
(rf/merge cofx
{:db (assoc-in db [:keycard :setup-error] error)}
(common/set-on-card-connected :keycard/load-loading-keys-screen)
(common/process-error code error))))
(rf/defn import-multiaccount
{:events [:keycard/import-multiaccount]}
[{:keys [db] :as cofx}]
(let [{:keys [pairing]} (get-in db [:keycard :secrets])
instance-uid (get-in db [:keycard :application-info :instance-uid])
key-uid (get-in db [:keycard :application-info :key-uid])
pairing' (or pairing (common/get-pairing db key-uid))
pin (common/vector->string (get-in db [:keycard :pin :import-multiaccount]))]
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :profile/profile :instance-uid] instance-uid)
(assoc-in [:keycard :pin :status] :verifying)
(assoc-in [:keycard :secrets]
{:pairing pairing'
:paired-on (datetime/timestamp)}))
:keycard/import-keys
{:pin pin
:on-success :keycard.callback/on-generate-and-load-key-success}})))
(rf/defn load-recovering-key-screen
{:events [:keycard/load-recovering-key-screen]}
[cofx]
(common/show-connection-sheet
cofx
{:on-card-connected :keycard/load-recovering-key-screen
:handler (common/dispatch-event :keycard/import-multiaccount)}))
-196
View File
@@ -1,196 +0,0 @@
(ns legacy.status-im.keycard.sign
(:require
[clojure.string :as string]
[legacy.status-im.keycard.common :as common]
[legacy.status-im.utils.deprecated-types :as types]
[re-frame.core :as re-frame]
[taoensso.timbre :as log]
[utils.address :as address]
[utils.ethereum.chain :as chain]
[utils.money :as money]
[utils.re-frame :as rf]))
(rf/defn sign
{:events [:keycard/sign]}
[{:keys [db] :as cofx} hash on-success]
(let [card-connected? (get-in db [:keycard :card-connected?])
key-uid (get-in db [:profile/profile :key-uid])
keycard-key-uid (get-in db [:keycard :application-info :key-uid])
keycard-pin-retries (get-in db [:keycard :application-info :pin-retry-counter])
keycard-match? (= key-uid keycard-key-uid)
hash (or hash (get-in db [:keycard :hash]))
data (get-in db [:keycard :data])
typed? (get-in db [:keycard :typed?])
pin (common/vector->string (get-in db [:keycard :pin :sign]))
from (or (get-in db [:signing/tx :from :address])
(get-in db [:signing/tx :message :from]))
path (reduce
(fn [_ {:keys [address path]}]
(when (address/address= from address)
(reduced path)))
nil
(:profile/wallet-accounts db))]
(cond
(not keycard-match?)
(common/show-wrong-keycard-alert cofx)
(not card-connected?)
(rf/merge cofx
{:db (assoc-in db [:signing/sign :keycard-step] :signing)}
(common/set-on-card-connected :keycard/sign))
(pos? keycard-pin-retries) ; if 0, get-application-info will have already closed the
; connection sheet and opened the frozen card popup
{:db (-> db
(assoc-in [:keycard :card-read-in-progress?] true)
(assoc-in [:keycard :pin :status] :verifying))
:keycard/sign {:hash (address/naked-address hash)
:data data
:typed? typed? ; this parameter is for e2e
:on-success on-success
:pin pin
:path path}})))
(defn normalize-signature
[signature]
(-> signature
(string/replace-first #"00$" "1b")
(string/replace-first #"01$" "1c")
address/normalized-hex))
(rf/defn sign-message
{:events [:keycard/sign-message]}
[cofx params result]
(let [{:keys [result error]} (types/json->clj result)
on-success #(re-frame/dispatch [:keycard/on-sign-message-success params
(normalize-signature %)])
hash (address/naked-address result)]
(sign cofx hash on-success)))
(rf/defn on-sign-message-success
{:events [:keycard/on-sign-message-success]}
[{:keys [db] :as cofx} {:keys [tx-hash message-id chat-id value contract]} signature]
(rf/merge
cofx
{:dispatch
(if message-id
[:sign/send-accept-transaction-message message-id tx-hash signature]
[:sign/send-transaction-message chat-id value contract tx-hash signature])
:signing/show-transaction-result nil
:db (-> db
(assoc-in [:keycard :pin :sign] [])
(assoc-in [:keycard :pin :status] nil))}
(common/clear-on-card-connected)
(common/get-application-info nil)
(common/hide-connection-sheet)))
(rf/defn sign-typed-data
{:events [:keycard/sign-typed-data]}
[{:keys [db] :as cofx}]
(let [card-connected? (get-in db [:keycard :card-connected?])
hash (get-in db [:keycard :hash])]
(if card-connected?
{:db (-> db
(assoc-in [:keycard :card-read-in-progress?] true)
(assoc-in [:signing/sign :keycard-step] :signing))
:keycard/sign-typed-data {:hash (address/naked-address hash)}}
(rf/merge cofx
(common/set-on-card-connected :keycard/sign-typed-data)
{:db (assoc-in db [:signing/sign :keycard-step] :signing)}))))
(rf/defn fetch-currency-token-on-success
{:events [:keycard/fetch-currency-token-on-success]}
[{:keys [db]} {:keys [decimals symbol]}]
{:db (-> db
(assoc-in [:signing/sign :formatted-data :message :formatted-currency] symbol)
(update-in [:signing/sign :formatted-data :message]
#(assoc %
:formatted-amount
(.dividedBy ^js (money/bignumber (:amount %))
(money/bignumber (money/from-decimal decimals))))))})
(rf/defn store-hash-and-sign-typed
{:events [:keycard/store-hash-and-sign-typed]}
[{:keys [db] :as cofx} result]
(let [{:keys [result]} (types/json->clj result)
message (get-in db [:signing/sign :formatted-data :message])
currency-contract (:currency message)]
(when currency-contract
{:json-rpc/call [{:method "wallet_discoverToken"
:params [(chain/chain-id db) currency-contract]
:on-success #(re-frame/dispatch [:keycard/fetch-currency-token-on-success
%])}]})
(rf/merge cofx
{:db (assoc-in db [:keycard :hash] result)}
sign-typed-data)))
(rf/defn prepare-to-sign
{:events [:keycard/prepare-to-sign]}
[{:keys [db] :as cofx}]
(common/show-connection-sheet
cofx
{:on-card-connected :keycard/prepare-to-sign
:handler (common/get-application-info :keycard/sign)}))
(rf/defn sign-message-completed
[_ signature]
{:dispatch
[:signing/sign-message-completed signature]})
(rf/defn send-transaction-with-signature
[_ data]
{:send-transaction-with-signature data})
(rf/defn on-sign-success
{:events [:keycard.callback/on-sign-success]}
[{:keys [db] :as cofx} signature]
(log/debug "[keycard] sign success: " signature)
(let [signature-json (types/clj->json {:result (normalize-signature signature)})
transaction (get-in db [:keycard :transaction])
tx-obj (select-keys transaction
[:from :to :value :gas :gasPrice :command? :chat-id :message-id])
command? (:command? transaction)]
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :hash] nil)
(assoc-in [:keycard :transaction] nil))}
(when-not command?
(fn [{:keys [db] :as cofx}]
(rf/merge
cofx
{:db (-> db
(assoc-in [:keycard :pin :sign] [])
(assoc-in [:keycard :pin :status] nil))}
(common/clear-on-card-connected)
(common/get-application-info nil)
(common/hide-connection-sheet))))
(if transaction
(send-transaction-with-signature
{:transaction (types/clj->json transaction)
:signature signature
:on-completed #(re-frame/dispatch [:signing/transaction-completed % tx-obj])})
(sign-message-completed signature-json)))))
(rf/defn on-sign-error
{:events [:keycard.callback/on-sign-error]}
[{:keys [db] :as cofx} error]
(log/debug "[keycard] sign error: " error)
(let [tag-was-lost? (common/tag-lost? (:error error))
pin-retries (common/pin-retries (:error error))]
(when-not tag-was-lost?
(if (not (nil? pin-retries))
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :application-info :pin-retry-counter] pin-retries)
(update-in [:keycard :pin]
assoc
:status :error
:sign []
:error-label :t/pin-mismatch)
(assoc-in [:signing/sign :keycard-step] :pin))}
(common/hide-connection-sheet)
(when (zero? pin-retries) (common/frozen-keycard-popup)))
(rf/merge cofx
(common/hide-connection-sheet)
(common/show-wrong-keycard-alert))))))
@@ -1,588 +0,0 @@
(ns legacy.status-im.keycard.simulated-keycard
(:require
[clojure.string :as string]
[keycard.keycard :as keycard]
[legacy.status-im.multiaccounts.create.core :as multiaccounts.create]
[legacy.status-im.utils.deprecated-types :as types]
[native-module.core :as native-module]
re-frame.db
[status-im.constants :as constants]
[taoensso.timbre :as log]
[utils.address :as address]
[utils.i18n :as i18n]
[utils.re-frame :as re-frame]))
(def kk1-password "000000")
(def default-pin "111111")
(def default-puk "000000000000")
(def account-password (native-module/sha3 "no password"))
(def initial-state
{:card-connected? false
:application-info {:initialized? false}})
(defonce state (atom initial-state))
(defn connect-card
[]
(swap! state assoc :card-connected? true)
(doseq [callback (vals (get @state :on-card-connected))]
(callback)))
(defn connect-selected-card
[]
(swap! state assoc
:application-info
{:free-pairing-slots 5
:app-version "3.0"
:secure-channel-pub-key
"04c3071768912a515c00aeab7ceb8a5bfda91d036f4a4e60b7944cee3ca7fb67b6d118e8df1e2480b87fd636c6615253245bbbc93a6a407f155f2c58f76c96ef0e"
:instance-uid "1b360b10a9a68b7d494e8f059059f118"
:paired? true
:has-master-key? true
:initialized? true
:pin-retry-counter 3
:puk-retry-counter 5
:key-uid (get-in @re-frame.db/app-db [:profile/login :key-uid])})
(swap! state assoc :pin default-pin :puk default-puk :password kk1-password)
(connect-card))
(def initialization (atom false))
(defn connect-pairing-card
[]
(reset! initialization false)
(swap! state assoc
:application-info
{:free-pairing-slots 5
:app-version "3.0"
:secure-channel-pub-key
"04c3071768912a515c00aeab7ceb8a5bfda91d036f4a4e60b7944cee3ca7fb67b6d118e8df1e2480b87fd636c6615253245bbbc93a6a407f155f2c58f76c96ef0e"
:instance-uid "1b360b10a9a68b7d494e8f059059f118"
:paired? false
:has-master-key? true
:initialized? true
:pin-retry-counter 3
:puk-retry-counter 5
:key-uid "0x16839e8b1b8a395acb18100c7e2b161701c225adf31eefa02114099b4d81a30b"})
(swap! state assoc :pin default-pin :puk default-puk :password kk1-password)
(connect-card))
(defn disconnect-card
[]
(swap! state assoc :card-connected? false)
(doseq [callback (vals (get @state :on-card-disconnected))]
(callback)))
(defn reset-state
[]
(swap! state assoc :application-info {:initialized? false}))
(defn- later
[f]
(when f (js/setTimeout f 500)))
(defn pin-error
[]
#js
{:code "EUNSPECIFIED"
:message (str "Unexpected error SW, 0x63C" (get-in @state [:application-info :pin-retry-counter]))})
(defn puk-error
[]
#js
{:code "EUNSPECIFIED"
:message (str "Unexpected error SW, 0x63C" (get-in @state [:application-info :puk-retry-counter]))})
(defn with-pin
[pin on-failure on-valid]
(cond
(= (get-in @state [:application-info :pin-retry-counter]) 0)
(later #(on-failure (pin-error)))
(= pin (get @state :pin))
(do
(swap! state update
:application-info assoc
:pin-retry-counter 3
:puk-retry-counter 5)
(later on-valid))
:else
(do
(swap! state update-in
[:application-info :pin-retry-counter]
(fnil dec 3))
(later #(on-failure (pin-error))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn start-nfc
[{:keys [on-success]}]
(when (get @state :card-connected?) (connect-card))
(later #(on-success true)))
(defn stop-nfc
[{:keys [on-success]}]
(later #(on-success true)))
(defn set-nfc-message
[{:keys [on-success]}]
(later #(on-success true)))
(defn check-nfc-support
[{:keys [on-success]}]
(later #(on-success true)))
(defn check-nfc-enabled
[{:keys [on-success]}]
(later #(on-success true)))
(defn open-nfc-settings [])
(defn on-card-connected
[callback]
(let [id (random-uuid)]
(swap! state update :on-card-connected assoc id callback)
id))
(defn on-card-disconnected
[callback]
(let [id (random-uuid)]
(swap! state update :on-card-disconnected assoc id callback)
id))
(defn register-card-events
[args]
(log/debug "register-card-events")
(on-card-connected (:on-card-connected args))
(on-card-disconnected (:on-card-disconnected args)))
(defn set-pairings
[args]
(log/warn "set-pairings not implemented" args))
(defn remove-event-listener
[id]
(log/debug "remove-event-listener")
(swap! state update :on-card-connected dissoc id)
(swap! state update :on-card-disconnected dissoc id))
(defn remove-event-listeners
[]
(log/debug "remove-event-listeners")
(swap! state dissoc :on-card-connected)
(swap! state dissoc :on-card-disconnected))
(defn get-application-info
[{:keys [on-success]}]
(log/debug "get-application-info")
(later #(on-success (get @state :application-info))))
(defn factory-reset
[args]
(log/debug "factory-reset")
(reset-state)
(get-application-info args))
(defn install-applet [_])
(defn install-cash-applet [_])
(defn init-card
[{:keys [pin on-success]}]
(reset! initialization true)
(swap! state assoc
:application-info
{:free-pairing-slots 5
:app-version "3.0"
:secure-channel-pub-key
"04c3071768912a515c00aeab7ceb8a5bfda91d036f4a4e60b7944cee3ca7fb67b6d118e8df1e2480b87fd636c6615253245bbbc93a6a407f155f2c58f76c96ef0e"
:key-uid ""
:instance-uid "1b360b10a9a68b7d494e8f059059f118"
:paired? false
:has-master-key? false
:pin-retry-counter 3
:puk-retry-counter 5
:initialized? true})
(swap! state assoc :pin pin :puk default-puk :password kk1-password)
(later
#(on-success {:password kk1-password
:puk default-puk
:pin pin})))
(defn install-applet-and-init-card [_])
(def derived-acc (atom nil))
(defn multiaccount->keys
[data]
(let [{:keys [selected-id multiaccounts root-key derived]}
data
{:keys [id address public-key derived key-uid]}
(or (->> multiaccounts
(filter #(= (:id %) selected-id))
first)
(assoc root-key :derived derived))
whisper (get derived constants/path-whisper-keyword)
wallet (get derived constants/path-default-wallet-keyword)
wallet-root (get derived constants/path-wallet-root-keyword)
password account-password
response {:key-uid key-uid
:encryption-public-key password
:address address
:whisper-public-key (:public-key whisper)
:instance-uid "1b360b10a9a68b7d494e8f059059f118"
:wallet-root-public-key (:public-key wallet-root)
:wallet-root-address (:address wallet-root)
:whisper-address (:address whisper)
:public-key public-key
:whisper-private-key "34bc7d0c258c4f2ac1dac4fd6c55c9478bac1f4a9d8b9f1152c8551ab7187b43"
:wallet-address (:address wallet)
:wallet-public-key (:public-key wallet)}]
[id response]))
(defn pair
[{:keys [password on-success]}]
(when (and (not @initialization)
(not @derived-acc))
(native-module/multiaccount-import-mnemonic
"night fortune spider version version armed amused winner matter tonight cave flag"
nil
(fn [result]
(let [{:keys [id] :as root-data}
(multiaccounts.create/normalize-multiaccount-data-keys
(types/json->clj result))]
(native-module.core/multiaccount-derive-addresses
id
[constants/path-wallet-root
constants/path-eip1581
constants/path-whisper
constants/path-default-wallet]
(fn [result]
(let [derived-data (multiaccounts.create/normalize-derived-data-keys
(types/json->clj result))]
(reset! derived-acc
{:root-key root-data
:derived derived-data}))))))))
(when (= password (get @state :password))
(swap! state assoc-in [:application-info :paired?] true)
(later #(on-success (str (rand-int 10000000))))))
(defn generate-and-load-key
[{:keys [pin on-success key-uid delete-multiaccount?]}]
(when (= pin (get @state :pin))
(let [[id response] (multiaccount->keys
(:intro-wizard @re-frame.db/app-db))]
(log/debug "[simulated kk] generate-and-load-key response" response)
(swap! state assoc-in
[:application-info :key-uid]
(:key-uid response))
(let [deletion-wrapper
(if delete-multiaccount?
(fn [on-deletion-success]
(js/alert "OH SHEET")
(native-module/delete-multiaccount
key-uid
(fn [result]
(let [{:keys [error]} (types/json->clj result)]
(if-not (string/blank? error)
(log/error error)
(on-deletion-success))))))
(fn [cb] (cb)))]
(deletion-wrapper
(fn []
(native-module/multiaccount-store-derived
id
(:key-uid response)
[constants/path-wallet-root
constants/path-eip1581
constants/path-whisper
constants/path-default-wallet]
account-password
#(on-success response))))))))
(defn unblock-pin
[{:keys [puk new-pin on-success on-failure]}]
(cond
(= (get-in @state [:application-info :puk-retry-counter]) 0)
(later #(on-failure (puk-error)))
(= puk (get @state :puk))
(do
(swap! state update
:application-info assoc
:pin-retry-counter 3
:puk-retry-counter 5)
(swap! state assoc :pin new-pin)
(later #(on-success true)))
:else
(do
(swap! state update-in
[:application-info :puk-retry-counter]
(fnil dec 5))
(later
#(on-failure (puk-error))))))
(defn verify-pin
[{:keys [pin on-success on-failure]}]
(with-pin pin on-failure #(on-success 3)))
(defn change-pin
[{:keys [current-pin new-pin on-success on-failure]}]
(with-pin current-pin
on-failure
(fn []
(swap! state assoc :pin new-pin)
(on-success))))
(defn change-puk
[{:keys [pin puk on-success on-failure]}]
(with-pin pin
on-failure
(fn []
(swap! state assoc :puk puk)
(on-success))))
(defn change-pairing
[{:keys [pin pairing on-success on-failure]}]
(with-pin pin
on-failure
(fn []
(swap! state assoc :password pairing)
(on-success))))
(defn unpair
[args]
(log/warn "unpair not implemented" args))
(defn delete
[args]
(log/warn "delete not implemented" args))
(defn remove-key
[args]
(log/warn "remove-key not implemented" args))
(defn remove-key-with-unpair
[args]
(log/warn "remove-key-with-unpair not implemented" args))
(defn normalize-path
[path]
(if (string/starts-with? path "m/")
(str constants/path-wallet-root
"/"
(last (string/split path "/")))
path))
(defn export-key
[{:keys [pin on-success on-failure]}]
(with-pin
pin
on-failure
#(let [{:keys [key-uid wallet-root-address]}
(get @re-frame.db/app-db :profile/profile)
accounts (get @re-frame.db/app-db :profile/wallet-accounts)
hashed-password account-password
path-num (inc (get-in @re-frame.db/app-db
[:profile/profile :latest-derived-path]))
path (str "m/" path-num)]
(native-module/multiaccount-load-account
wallet-root-address
hashed-password
(fn [value]
(let [{:keys [id error]} (types/json->clj value)]
(if error
(re-frame/dispatch [::new-account-error :password-error error])
(native-module/multiaccount-derive-addresses
id
[path]
(fn [derived]
(let [derived-address (get-in (types/json->clj derived) [(keyword path) :address])]
(if (some (fn [a] (= derived-address (get a :address))) accounts)
(re-frame/dispatch [::new-account-error :account-error
(i18n/label :t/account-exists-title)])
(native-module/multiaccount-store-derived
id
key-uid
[path]
hashed-password
(fn [result]
(let [{:keys [error] :as result} (types/json->clj result)
{:keys [publicKey]} (get result (keyword path))]
(if error
(on-failure error)
(on-success publicKey))))))))))))))))
(defn unpair-and-delete [_])
(defn get-keys
[{:keys [on-success on-failure pin]}]
(with-pin pin
on-failure
(if @derived-acc
(let [[id account-keys] (multiaccount->keys @derived-acc)]
(swap! state assoc-in
[:application-info :key-uid]
(:key-uid account-keys))
(native-module/multiaccount-store-derived
id
(:key-uid account-keys)
[constants/path-wallet-root
constants/path-eip1581
constants/path-whisper
constants/path-default-wallet]
account-password
#(on-success account-keys)))
#(on-success
{:key-uid (get-in @state [:application-info :key-uid])
:instance-uid (get-in @state [:application-info :instance-uid])
:encryption-public-key account-password}))))
(def import-keys get-keys)
(defn sign
[{:keys [pin data path typed? on-success on-failure] :as card}]
(with-pin pin
on-failure
#(let [address
(if path
(reduce
(fn [_ {:keys [address] :as acc}]
(when (= path (:path acc))
(reduced address)))
nil
(:profile/wallet-accounts @re-frame.db/app-db))
(-> (:profile/wallet-accounts @re-frame.db/app-db)
first
:address))
password account-password]
(if-not typed?
(let [params (types/clj->json
{:account address
:password password
:data (or data (str "0x" (:hash card)))})]
(native-module/sign-message
params
(fn [res]
(let [signature (-> res
types/json->clj
:result
address/normalized-hex)]
(on-success signature)))))
(native-module/sign-typed-data
data
address
password
(fn [res]
(let [signature (-> res
types/json->clj
:result
address/normalized-hex)]
(on-success signature))))))))
(defn sign-typed-data
[args]
(log/warn "sign-typed-data not implemented" args))
(defrecord SimulatedKeycard []
keycard/Keycard
(keycard/start-nfc [_this args]
(log/debug "simulated card start-nfc")
(start-nfc args))
(keycard/stop-nfc [_this args]
(log/debug "simulated card stop-nfc")
(stop-nfc args))
(keycard/set-nfc-message [_this args]
(log/debug "simulated card set-nfc-message")
(set-nfc-message args))
(keycard/check-nfc-support [_this args]
(log/debug "simulated card check-nfc-support")
(check-nfc-support args))
(keycard/check-nfc-enabled [_this args]
(log/debug "simulated card check-nfc-enabled")
(check-nfc-enabled args))
(keycard/open-nfc-settings [_this]
(log/debug "simulated card open-nfc-setting")
(open-nfc-settings))
(keycard/register-card-events [_this args]
(log/debug "simulated card register-card-event")
(register-card-events args))
(keycard/set-pairings [_this args]
(log/debug "simulated card set-pairings")
(set-pairings args))
(keycard/on-card-connected [_this callback]
(log/debug "simulated card on-card-connected")
(on-card-connected callback))
(keycard/on-card-disconnected [_this callback]
(log/debug "simulated card on-card-disconnected")
(on-card-disconnected callback))
(keycard/remove-event-listener [_this event]
(log/debug "simulated card remove-event-listener")
(remove-event-listener event))
(keycard/remove-event-listeners [_this]
(log/debug "simulated card remove-event-listener")
(remove-event-listeners))
(keycard/get-application-info [_this args]
(log/debug "simulated card get-application-info")
(get-application-info args))
(keycard/factory-reset [_this args]
(log/debug "simulated card factory-reset")
(factory-reset args))
(keycard/install-applet [_this args]
(log/debug "simulated card install-applet")
(install-applet args))
(keycard/init-card [_this args]
(log/debug "simulated card init-card")
(init-card args))
(keycard/install-applet-and-init-card [_this args]
(log/debug "simulated card install-applet-and-init-card")
(install-applet-and-init-card args))
(keycard/pair [_this args]
(log/debug "simulated card pair")
(pair args))
(keycard/generate-and-load-key [_this args]
(log/debug "simulated card generate-and-load-key")
(generate-and-load-key args))
(keycard/unblock-pin [_this args]
(log/debug "simulated card unblock-pin")
(unblock-pin args))
(keycard/verify-pin [_this args]
(log/debug "simulated card verify-pin")
(verify-pin args))
(keycard/change-pin [_this args]
(log/debug "simulated card change-pin")
(change-pin args))
(keycard/change-puk [_this args]
(log/debug "simulated card change-puk")
(change-puk args))
(keycard/change-pairing [_this args]
(log/debug "simulated card change-pairing")
(change-pairing args))
(keycard/unpair [_this args]
(log/debug "simulated card unpair")
(unpair args))
(keycard/delete [_this args]
(log/debug "simulated card delete")
(delete args))
(keycard/remove-key [_this args]
(log/debug "simulated card remove-key")
(remove-key args))
(keycard/remove-key-with-unpair [_this args]
(log/debug "simulated card remove-key-with-unpair")
(remove-key-with-unpair args))
(keycard/export-key [_this args]
(log/debug "simulated card export-key")
(export-key args))
(keycard/unpair-and-delete [_this args]
(log/debug "simulated card unpair-and-delete")
(unpair-and-delete args))
(keycard/import-keys [_this args]
(log/debug "simulated card import-keys")
(import-keys args))
(keycard/get-keys [_this args]
(log/debug "simulated card get-keys")
(get-keys args))
(keycard/sign [_this args]
(log/debug "simulated card sign")
(sign args)))
@@ -1,32 +0,0 @@
(ns legacy.status-im.keycard.test-menu
(:require
[legacy.status-im.keycard.simulated-keycard :as simulated-keycard]
[legacy.status-im.ui.components.react :as react]))
(defn button
[label accessibility-label handler]
[react/view
{:style {:width 20
:height 30
:justify-content :center
:align-items :center}}
[react/text
{:on-press handler
:style {:font-size 8}
:accessibility-label accessibility-label}
label]])
(defn test-menu
[]
[react/view
{:style {:position :absolute
:top 70
:right 0
:width 50
:justify-content :center
:align-items :center}}
[button "conn" :connect-card simulated-keycard/connect-card]
[button "conn sell" :connect-selected-card simulated-keycard/connect-selected-card]
[button "pair" :connect-pairing-card simulated-keycard/connect-pairing-card]
[button "disc" :disconnect-card simulated-keycard/disconnect-card]
[button "res" :keycard-reset-state simulated-keycard/reset-state]])
-187
View File
@@ -1,187 +0,0 @@
(ns legacy.status-im.keycard.unpair
(:require
[legacy.status-im.keycard.common :as common]
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
[re-frame.core :as re-frame]
[status-im.navigation.events :as navigation]
[taoensso.timbre :as log]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(rf/defn unpair-card-pressed
{:events [:keycard-settings.ui/unpair-card-pressed]}
[_]
{:ui/show-confirmation {:title (i18n/label :t/unpair-card)
:content (i18n/label :t/unpair-card-confirmation)
:confirm-button-text (i18n/label :t/yes)
:cancel-button-text (i18n/label :t/no)
:on-accept #(re-frame/dispatch
[:keycard-settings.ui/unpair-card-confirmed])
:on-cancel #()}})
(rf/defn unpair-card-confirmed
{:events [:keycard-settings.ui/unpair-card-confirmed]}
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (assoc-in db
[:keycard :pin]
{:enter-step :current
:current []
:puk []
:status nil
:error-label nil
:on-verified :keycard/unpair})}
(common/navigate-to-enter-pin-screen)))
(rf/defn unpair
{:events [:keycard/unpair]}
[{:keys [db]}]
(let [pin (common/vector->string (get-in db [:keycard :pin :current]))]
{:keycard/unpair {:pin pin}}))
(rf/defn unpair-and-delete
{:events [:keycard/unpair-and-delete]}
[cofx]
(common/show-connection-sheet
cofx
{:on-card-connected :keycard/unpair-and-delete
:handler
(fn [{:keys [db]}]
(let [pin (common/vector->string (get-in db [:keycard :pin :current]))]
{:keycard/unpair-and-delete
{:pin pin}}))}))
(rf/defn remove-pairing-from-multiaccount
[cofx {:keys [remove-instance-uid?]}]
(rf/merge cofx
(multiaccounts.update/multiaccount-update
:keycard-pairing
nil
{})
(multiaccounts.update/multiaccount-update
:keycard-paired-on
nil
{})
(when remove-instance-uid?
(multiaccounts.update/multiaccount-update
:keycard-instance-uid
nil
{}))))
(rf/defn on-unpair-success
{:events [:keycard.callback/on-unpair-success]}
[{:keys [db] :as cofx}]
(let [instance-uid (get-in db [:keycard :application-info :instance-uid])
pairings (get-in db [:keycard :pairings])]
(rf/merge
cofx
{:db (-> db
(assoc-in [:keycard :secrets] nil)
(update-in [:keycard :pairings] dissoc (keyword instance-uid))
(assoc-in [:keycard :pin]
{:status nil
:error-label nil
:on-verified nil}))
:keycard/persist-pairings (dissoc pairings (keyword instance-uid))
:effects.utils/show-popup {:title ""
:content (i18n/label :t/card-unpaired)}}
(common/clear-on-card-connected)
(remove-pairing-from-multiaccount nil)
(navigation/navigate-to :keycard-settings nil))))
(rf/defn on-unpair-error
{:events [:keycard.callback/on-unpair-error]}
[{:keys [db] :as cofx} error]
(log/debug "[keycard] unpair error" error)
(rf/merge cofx
{:db (assoc-in db
[:keycard :pin]
{:status nil
:error-label nil
:on-verified nil})
:keycard/get-application-info nil
:effects.utils/show-popup {:title ""
:content (i18n/label :t/something-went-wrong)}}
(common/clear-on-card-connected)
(navigation/navigate-to :keycard-settings nil)))
(rf/defn remove-key-with-unpair
{:events [:keycard/remove-key-with-unpair]}
[cofx]
(common/show-connection-sheet
cofx
{:on-card-connected :keycard/remove-key-with-unpair
:handler
(fn [{:keys [db]}]
(let [pin (common/vector->string (get-in db [:keycard :pin :current]))]
{:keycard/remove-key-with-unpair
{:pin pin}}))}))
(defn handle-account-removal
[{:keys [db] :as cofx} keys-removed-from-card?]
(let [key-uid (get-in db [:profile/profile :key-uid])
instance-uid (get-in db [:keycard :application-info :instance-uid])
pairings (get-in db [:keycard :pairings])]
(rf/merge
cofx
{:db (-> db
(update :profile/profiles-overview dissoc key-uid)
(assoc-in [:keycard :secrets] nil)
(update-in [:keycard :pairings]
dissoc
(keyword instance-uid))
(update-in [:keycard :pairings] dissoc instance-uid)
(assoc-in [:keycard :whisper-public-key] nil)
(assoc-in [:keycard :wallet-address] nil)
(assoc-in [:keycard :application-info] nil)
(assoc-in [:keycard :pin]
{:status nil
:error-label nil
:on-verified nil}))
:keycard/persist-pairings (dissoc pairings (keyword instance-uid))
:effects.utils/show-popup {:title (i18n/label (if keys-removed-from-card?
:t/profile-deleted-title
:t/database-reset-title))
:content (i18n/label (if keys-removed-from-card?
:t/profile-deleted-keycard
:t/database-reset-content))
:on-dismiss #(re-frame/dispatch [:logout])}}
;;should be reimplemented :key-storage/delete-profile {:key-uid key-uid
;;:on-success #(log/debug "[keycard] remove account ok")
;; :on-error #(log/warn "[keycard] remove account: " %)}
(common/clear-on-card-connected)
(common/hide-connection-sheet))))
(rf/defn on-remove-key-success
{:events [:keycard.callback/on-remove-key-success]}
[cofx]
(handle-account-removal cofx true))
(rf/defn on-remove-key-error
{:events [:keycard.callback/on-remove-key-error]}
[{:keys [db] :as cofx} error]
(log/debug "[keycard] remove key error" error)
(let [tag-was-lost? (common/tag-lost? (:error error))]
(rf/merge cofx
(if tag-was-lost?
(rf/merge cofx
{:db (assoc-in db [:keycard :pin :status] nil)}
(common/set-on-card-connected :keycard/remove-key-with-unpair))
(common/show-wrong-keycard-alert)))))
(rf/defn on-unpair-and-delete-success
{:events [:keycard.callback/on-unpair-and-delete-success]}
[cofx]
(handle-account-removal cofx false))
(rf/defn on-unpair-and-delete-error
{:events [:keycard.callback/on-unpair-and-delete-error]}
[{:keys [db] :as cofx} error]
(log/debug "[keycard] unpair and delete error" error)
(let [tag-was-lost? (common/tag-lost? (:error error))]
(rf/merge cofx
(if tag-was-lost?
(rf/merge cofx
{:db (assoc-in db [:keycard :pin :status] nil)}
(common/set-on-card-connected :keycard/unpair-and-delete))
(common/show-wrong-keycard-alert)))))
@@ -10,7 +10,7 @@
[{:keys [db]}]
(let [{:keys [name preferred-name display-name address]} (:profile/profile db)]
{:json-rpc/call [{:method "wakuext_sendContactUpdates"
:params [(or preferred-name display-name name) ""]
:params [(or preferred-name display-name name) "" ""]
:on-success #(log/debug "sent contact update")}]}))
(rf/defn update-multiaccount-account-name
+2 -21
View File
@@ -5,16 +5,6 @@
[react-native.platform :as platform]
[status-im.config :as config]))
(defn- add-custom-bootnodes
[config network all-bootnodes]
(let [bootnodes (as-> all-bootnodes $
(get $ network)
(vals $)
(map :address $))]
(if (seq bootnodes)
(assoc-in config [:ClusterConfig :BootNodes] bootnodes)
config)))
(defn- add-log-level
[config log-level]
(if (empty? log-level)
@@ -124,10 +114,8 @@
waku-nodes (get config/waku-nodes-config fleet-key)
rendezvous-nodes (pick-nodes 3 (vals (:rendezvous current-fleet)))
{:keys [installation-id log-level
waku-bloom-filter-mode
custom-bootnodes custom-bootnodes-enabled?]}
profile
use-custom-bootnodes (get custom-bootnodes-enabled? current-network)]
waku-bloom-filter-mode]}
profile]
(cond-> (get-in networks [current-network :config])
:always
(get-base-node-config)
@@ -144,8 +132,6 @@
(if wakuv2-enabled
waku-nodes
[])
:BootNodes
(if wakuv2-enabled [] (pick-nodes 4 (vals (:boot current-fleet))))
:TrustedMailServers
(if wakuv2-enabled [] (pick-nodes 6 (vals (:mail current-fleet))))
:StaticNodes
@@ -185,11 +171,6 @@
:RequireTopics (get-topics current-network)
:StatusAccountsConfig {:Enabled true})
(and
config/bootnodes-settings-enabled?
use-custom-bootnodes)
(add-custom-bootnodes current-network custom-bootnodes)
:always
(add-log-level log-level))))
+2 -2
View File
@@ -8,8 +8,8 @@
(let [delay-ms (or (:delay-ms value) 250)
value (dissoc value :delay-ms)]
{:show-popover nil
;; We should probably refactor to start the animation on mount, so that the
;; delay can be removed. See comment for more details:
;; We should probably refactor to start the animation on mount, so that the delay can be
;; removed. See comment for more details:
;; https://github.com/status-im/status-mobile/pull/15222#issuecomment-1450162137
:dispatch-later [{:ms delay-ms :dispatch [:show-popover-db value]}]
:dismiss-keyboard nil}))
-650
View File
@@ -1,650 +0,0 @@
(ns legacy.status-im.signing.core
(:require
[clojure.set :as set]
[clojure.string :as string]
[legacy.status-im.ethereum.tokens :as tokens]
[legacy.status-im.keycard.card :as keycard.card]
[legacy.status-im.keycard.common :as keycard.common]
[legacy.status-im.signing.eip1559 :as eip1559]
[legacy.status-im.signing.keycard :as signing.keycard]
[legacy.status-im.utils.deprecated-types :as types]
[legacy.status-im.utils.hex :as utils.hex]
[legacy.status-im.utils.utils :as utils]
[native-module.core :as native-module]
[re-frame.core :as re-frame]
[status-im.common.json-rpc.events :as json-rpc]
[status-im.constants :as constants]
[taoensso.timbre :as log]
[utils.address :as address]
[utils.ethereum.chain :as chain]
[utils.ethereum.eip.eip55 :as eip55]
[utils.i18n :as i18n]
[utils.money :as money]
[utils.re-frame :as rf]
[utils.security.core :as security]))
(re-frame/reg-fx
:signing/send-transaction-fx
(fn [{:keys [tx-obj hashed-password cb]}]
(native-module/send-transaction (types/clj->json tx-obj)
hashed-password
cb)))
(re-frame/reg-fx
:signing/show-transaction-error
(fn [message]
(utils/show-popup (i18n/label :t/transaction-failed) message)))
(re-frame/reg-fx
:signing/show-transaction-result
(fn []
(utils/show-popup (i18n/label :t/transaction-sent) (i18n/label :t/transaction-description))))
(re-frame/reg-fx
:signing.fx/sign-message
(fn [{:keys [params on-completed]}]
(native-module/sign-message (types/clj->json params)
on-completed)))
(re-frame/reg-fx
:signing.fx/recover-message
(fn [{:keys [params on-completed]}]
(native-module/recover-message (types/clj->json params)
on-completed)))
(re-frame/reg-fx
:signing.fx/sign-typed-data
(fn [{:keys [v4 data account on-completed hashed-password]}]
(if v4
(native-module/sign-typed-data-v4 data account hashed-password on-completed)
(native-module/sign-typed-data data account hashed-password on-completed))))
(defn get-contact
[db to]
(let [to (utils.hex/normalize-hex to)]
(or
(get-in db [:contacts/contacts to])
{:address (address/normalized-hex to)})))
(rf/defn change-password
{:events [:signing.ui/password-is-changed]}
[{db :db} password]
(let [unmasked-pass (security/safe-unmask-data password)]
{:db (update db
:signing/sign assoc
:password password
:error nil
:enabled? (and unmasked-pass (> (count unmasked-pass) 5)))}))
(rf/defn sign-message
[{{:signing/keys [sign tx] :as db} :db}]
(let [{{:keys [data typed? from v4]} :message} tx
{:keys [in-progress? password]} sign
from from
hashed-password (native-module/sha3 (security/safe-unmask-data
password))]
(when-not in-progress?
(merge
{:db (update db :signing/sign assoc :error nil :in-progress? true)}
(if typed?
{:signing.fx/sign-typed-data {:v4 v4
:data data
:account from
:hashed-password hashed-password
:on-completed #(re-frame/dispatch
[:signing/sign-message-completed %])}}
{:signing.fx/sign-message {:params {:data data
:password hashed-password
:account from}
:on-completed #(re-frame/dispatch [:signing/sign-message-completed
%])}})))))
(rf/defn send-transaction
{:events [:signing.ui/sign-is-pressed]}
[{{:signing/keys [sign tx] :ens/keys [registration] :as db} :db :as cofx}]
(let [{:keys [in-progress? password]} sign
{:keys [tx-obj gas gasPrice maxPriorityFeePerGas
maxFeePerGas message nonce]} tx
hashed-password (native-module/sha3 (security/safe-unmask-data
password))
{:keys [action username custom-domain?]} registration
{:keys [public-key]} (:profile/profile db)
chain-id (chain/chain-id db)]
(if message
(sign-message cofx)
(let [tx-obj-to-send (merge tx-obj
(when gas
{:gas (str "0x" (native-module/number-to-hex gas))})
(when gasPrice
{:gasPrice (str "0x" (native-module/number-to-hex gasPrice))})
(when nonce
{:nonce (str "0x" (native-module/number-to-hex nonce))})
(when maxPriorityFeePerGas
{:maxPriorityFeePerGas (str "0x"
(native-module/number-to-hex
(js/parseInt maxPriorityFeePerGas)))})
(when maxFeePerGas
{:maxFeePerGas (str "0x"
(native-module/number-to-hex
(js/parseInt maxFeePerGas)))}))
cb #(re-frame/dispatch
[:signing/transaction-completed %
tx-obj-to-send hashed-password])
watch-ens-tx-fn #(re-frame/dispatch
[:transactions/watch-transaction
%
{:trigger-fn
(fn [_ {:keys [hash type]}]
(and (= hash %)
(contains? #{:outbound :failed} type)))
:on-trigger
(fn [{:keys [type]}]
(case type
:outbound (do (rf/dispatch [:ens/clear-registration %])
(rf/dispatch [:ens/save-username custom-domain?
username false]))
:failed (rf/dispatch [:ens/update-ens-tx-state :failure username
custom-domain? %])
nil))}])]
(when-not in-progress?
(cond-> {:db (update db :signing/sign assoc :error nil :in-progress? true)}
(nil? action) (assoc :signing/send-transaction-fx
{:tx-obj tx-obj-to-send
:hashed-password hashed-password
:cb cb})
(= action constants/ens-action-type-register) (assoc :json-rpc/call
[{:method "ens_register"
:params [chain-id tx-obj-to-send
hashed-password username
public-key]
:on-success
#(do
(cb (types/clj->json
{:result %}))
(watch-ens-tx-fn %))
:on-error #(cb (types/clj->json
{:error %}))}])
(= action
constants/ens-action-type-set-pub-key) (assoc :json-rpc/call
[{:method "ens_setPubKey"
:params [chain-id tx-obj-to-send
hashed-password username
public-key]
:on-success #(do (cb (types/clj->json
{:result %}))
(watch-ens-tx-fn %))
:on-error #(cb (types/clj->json
{:error
%}))}])))))))
(rf/defn prepare-unconfirmed-transaction
[{:keys [db now]} new-tx-hash
{:keys [value gasPrice maxFeePerGas maxPriorityFeePerGas gas data to from hash]} symbol amount]
(let [token (tokens/symbol->token (:wallet-legacy/all-tokens db) symbol)
from (eip55/address->checksum from)
;;if there is a hash in the tx object that means we resending transaction
old-tx-hash hash
gas-price (money/to-fixed (money/bignumber gasPrice))
gas-limit (money/to-fixed (money/bignumber gas))
tx {:timestamp now
:to to
:from from
:type :pending
:hash new-tx-hash
:data data
:token token
:symbol symbol
:value (if token
(money/to-fixed (money/unit->token amount (:decimals token)))
(money/to-fixed (money/bignumber value)))
:gas-price gas-price
:fee-cap maxFeePerGas
:tip-cap maxPriorityFeePerGas
:gas-limit gas-limit}]
(log/info "[signing] prepare-unconfirmed-transaction" tx)
{:db (-> db
;;remove old transaction, because we replace it with the new one
(update-in [:wallet-legacy :accounts from :transactions] dissoc old-tx-hash)
(assoc-in [:wallet-legacy :accounts from :transactions new-tx-hash] tx))}))
(defn get-method-type
[data]
(cond
(string/starts-with? data constants/method-id-transfer)
:transfer
(string/starts-with? data constants/method-id-approve)
:approve
(string/starts-with? data constants/method-id-approve-and-call)
:approve-and-call))
(defn get-transfer-token
[db to data]
(let [{:keys [decimals] :as token} (tokens/address->token (:wallet-legacy/all-tokens db) to)]
(when (and token data (string? data))
(when-let [type (get-method-type data)]
(let [[address value _] (native-module/decode-parameters
(str "0x" (subs data 10))
(if (= type :approve-and-call)
["address" "uint256" "bytes"]
["address" "uint256"]))]
(when (and address value)
{:to address
:contact (get-contact db address)
:contract to
:approve? (not= type :transfer)
:value value
:amount (money/to-fixed (money/token->unit value decimals))
:token token
:symbol (:symbol token)}))))))
(defn parse-tx-obj
[db {:keys [from to value data cancel?] :as tx}]
(merge {:from {:address from}
:cancel? cancel?
:hash (:hash tx)}
(if (nil? to)
{:contact {:name (i18n/label :t/new-contract)}}
(let [eth-value (when value (money/bignumber value))
eth-amount (when eth-value (money/to-fixed (money/wei->ether eth-value)))
token (get-transfer-token db to data)]
(cond
(and eth-amount (or (not (.equals ^js (money/bignumber 0) ^js eth-amount)) (nil? data)))
{:to to
:contact (get-contact db to)
:symbol :ETH
:value value
:amount (str eth-amount)
:token (tokens/asset-for (:wallet-legacy/all-tokens db)
(chain/get-current-network db)
:ETH)}
(not (nil? token))
token
:else
{:to to
:contact {:address (address/normalized-hex to)}})))))
(defn prepare-tx
[db {{:keys [data gas gasPrice maxFeePerGas maxPriorityFeePerGas] :as tx-obj} :tx-obj :as tx}]
(merge
tx
(parse-tx-obj db tx-obj)
{:data data
:gas (when gas (money/bignumber gas))
:gasPrice (when gasPrice (money/bignumber gasPrice))
:maxFeePerGas (when maxFeePerGas
(money/bignumber maxFeePerGas))
:maxPriorityFeePerGas (when maxPriorityFeePerGas
(money/bignumber maxPriorityFeePerGas))}))
(defn hex-to-utf8
[s]
(let [utf8 (native-module/hex-to-utf8 s)]
(if (empty? utf8)
nil
utf8)))
(defn hex->text
"Converts a hexstring to UTF8 text."
[data]
(or (hex-to-utf8 data) data))
(rf/defn show-sign
[{:keys [db] :as cofx}]
(let [{:signing/keys [queue]} db
{{:keys [gas gasPrice maxFeePerGas] :as tx-obj} :tx-obj
{:keys [data typed? pinless?] :as message} :message
:as tx}
(last queue)
keycard-multiaccount? (boolean (get-in db [:profile/profile :keycard-pairing]))
wallet-set-up-passed? (get-in db [:profile/profile :wallet-set-up-passed?])]
(if message
(rf/merge
cofx
{:db (assoc db
:signing/queue (drop-last queue)
:signing/tx tx
:signing/sign {:type (cond pinless? :pinless
keycard-multiaccount? :keycard
:else :password)
:formatted-data (if typed?
(types/js->pretty-json
(types/json->js data))
(hex->text data))
:keycard-step (when pinless? :connect)})
:show-signing-sheet nil}
#(when-not wallet-set-up-passed?
{:dispatch-later [{:dispatch [:show-popover {:view :signing-phrase}] :ms 200}]})
(when pinless?
(keycard.card/start-nfc {:on-success #(re-frame/dispatch [:keycard.callback/start-nfc-success])
:on-failure #(re-frame/dispatch
[:keycard.callback/start-nfc-failure])})
(signing.keycard/hash-message
{:data data
:typed? true
:on-completed #(re-frame/dispatch [:keycard/store-hash-and-sign-typed %])})))
(rf/merge
cofx
{:db (assoc db
:signing/queue (drop-last queue)
:signing/tx (prepare-tx db tx))
:show-signing-sheet nil
:dismiss-keyboard nil}
#(when-not wallet-set-up-passed?
{:dispatch-later [{:dispatch [:show-popover {:view :signing-phrase}] :ms 200}]})
#(when-not gas
{:db (assoc-in (:db %) [:signing/edit-fee :gas-loading?] true)
:signing/update-estimated-gas {:obj (-> tx-obj
(dissoc :gasPrice)
(update :maxFeePerGas
(fn [fee]
(some-> fee
money/bignumber
(money/mul 2)
money/to-hex))))
:success-event :signing/update-estimated-gas-success
:error-event :signing/update-estimated-gas-error}})
(fn [cofx]
{:db (assoc-in (:db cofx) [:signing/edit-fee :gas-price-loading?] true)
:signing/update-gas-price
{:success-callback #(re-frame/dispatch
[:wallet-legacy.send/update-gas-price-success :signing/tx % tx-obj])
:error-callback #(re-frame/dispatch [:signing/update-gas-price-error %])
:network-id (get-in (chain/current-network db)
[:config :NetworkId])}})))))
(rf/defn check-queue
[{:keys [db] :as cofx}]
(let [{:signing/keys [tx queue]} db]
(when (and (not tx) (seq queue))
(show-sign cofx))))
(rf/defn send-transaction-message
{:events [:sign/send-transaction-message]}
[cofx chat-id value contract transaction-hash signature]
{:json-rpc/call [{:method "wakuext_sendTransaction"
;; We make sure `value` is serialized as string, and not as an integer or
;; big-int
:params [chat-id (str value) contract transaction-hash
(or (:result (types/json->clj signature))
(address/normalized-hex signature))]
:js-response true
:on-success
#(re-frame/dispatch [:transport/message-sent %])}]})
(rf/defn send-accept-request-transaction-message
{:events [:sign/send-accept-transaction-message]}
[cofx message-id transaction-hash signature]
{:json-rpc/call [{:method "wakuext_acceptRequestTransaction"
:params [transaction-hash message-id
(or (:result (types/json->clj signature))
(address/normalized-hex signature))]
:js-response true
:on-success
#(re-frame/dispatch [:transport/message-sent %])}]})
(rf/defn transaction-result
[{:keys [db] :as cofx} result tx-obj]
(let [{:keys [on-result symbol amount from]} (get db :signing/tx)]
(rf/merge cofx
{:db (dissoc db :signing/tx :signing/sign)
:signing/show-transaction-result nil}
(prepare-unconfirmed-transaction result tx-obj symbol amount)
(check-queue)
#(when on-result
{:dispatch (conj on-result result)}))))
(rf/defn command-transaction-result
[{:keys [db] :as cofx} transaction-hash hashed-password
{:keys [message-id chat-id from] :as tx-obj}]
(let [{:keys [on-result symbol amount contract value]} (get db :signing/tx)
data (str (get-in db [:profile/profile :public-key])
(subs transaction-hash 2))]
(rf/merge
cofx
{:db (dissoc db :signing/tx :signing/sign)}
(if (keycard.common/keycard-multiaccount? db)
(signing.keycard/hash-message
{:data data
:on-completed
(fn [hash]
(re-frame/dispatch
[:keycard/sign-message
{:tx-hash transaction-hash
:message-id message-id
:chat-id chat-id
:value value
:contract contract
:data data}
hash]))})
(fn [_]
{:signing.fx/sign-message
{:params {:data data
:password hashed-password
:account from}
:on-completed
(fn [res]
(re-frame/dispatch
(if message-id
[:sign/send-accept-transaction-message message-id transaction-hash res]
[:sign/send-transaction-message
chat-id value contract transaction-hash res])))}
:signing/show-transaction-result nil}))
(prepare-unconfirmed-transaction transaction-hash tx-obj symbol amount)
(check-queue)
#(when on-result
{:dispatch (conj on-result transaction-hash)}))))
(rf/defn transaction-error
[{:keys [db]} {:keys [code message]}]
(let [on-error (get-in db [:signing/tx :on-error])]
(if (= code constants/send-transaction-err-decrypt)
;;wrong password
{:db (assoc-in db [:signing/sign :error] (i18n/label :t/wrong-password))}
(merge {:db (dissoc db :signing/tx :signing/sign)
:signing/show-transaction-error message}
(when on-error
{:dispatch (conj on-error message)})))))
(rf/defn dissoc-signing-db-entries-and-check-queue
{:events [:signing/dissoc-entries-and-check-queue]}
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (dissoc db :signing/tx :signing/sign)}
check-queue))
(rf/defn sign-message-completed
{:events [:signing/sign-message-completed]}
[{:keys [db] :as cofx} result]
(let [{:keys [result error]} (types/json->clj result)
on-result (get-in db [:signing/tx :on-result])]
(if error
{:db (update db
:signing/sign
assoc
:error (if (= 5 (:code error))
(i18n/label :t/wrong-password)
(:message error))
:in-progress? false)}
(rf/merge cofx
(when-not (= (-> db :signing/sign :type) :pinless)
(dissoc-signing-db-entries-and-check-queue))
#(when (= (-> db :signing/sign :type) :pinless)
{:dispatch-later [{:ms 3000
:dispatch [:signing/dissoc-entries-and-check-queue]}]})
#(when on-result
{:dispatch (conj on-result result)})))))
(rf/defn transaction-completed
{:events [:signing/transaction-completed]
:interceptors [(re-frame/inject-cofx :random-id-generator)]}
[cofx response tx-obj hashed-password]
(log/info "transaction-completed" "tx-obj" tx-obj "response" response)
(let [cofx-in-progress-false (assoc-in cofx [:db :signing/sign :in-progress?] false)
{:keys [result error]} (types/json->clj response)]
(if error
(transaction-error cofx-in-progress-false error)
(if (:command? tx-obj)
(command-transaction-result cofx-in-progress-false result hashed-password tx-obj)
(transaction-result cofx-in-progress-false result tx-obj)))))
(rf/defn discard
"Discrad transaction signing"
{:events [:signing.ui/cancel-is-pressed]}
[{:keys [db] :as cofx}]
(let [{:keys [on-error]} (get-in db [:signing/tx])]
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :pin :status] nil)
(dissoc :signing/tx :signing/sign))
:hide-signing-sheet nil}
(check-queue)
(keycard.common/hide-connection-sheet)
(keycard.common/clear-pin)
#(when on-error
{:dispatch (conj on-error "transaction was cancelled by user")}))))
(defn normalize-tx-obj
[_db tx]
(update-in tx [:tx-obj :from] #(eip55/address->checksum %)))
(rf/defn sign
"Signing transaction or message, shows signing sheet
tx
{:tx-obj - transaction object to send https://github.com/ethereum/wiki/wiki/JavaScript-API#parameters-25
:message {:address :data :typed? } - message data to sign
:on-result - re-frame event vector
:on-error - re-frame event vector}"
{:events [:signing.ui/sign]}
[{:keys [db] :as cofx} tx]
(rf/merge cofx
{:db (update db :signing/queue conj (normalize-tx-obj db tx))}
(check-queue)))
(rf/defn sign-transaction-button-clicked-from-chat
{:events [:wallet-legacy.ui/sign-transaction-button-clicked-from-chat]}
[{:keys [db] :as cofx} {:keys [to amount from token]}]
(let [{:keys [symbol address]} token
amount-hex (str "0x" (native-module/number-to-hex amount))
to-norm (address/normalized-hex (if (string? to) to (:address to)))
from-address (:address from)
identity (:current-chat-id db)
db (dissoc db :wallet-legacy/prepare-transaction :signing/edit-fee)]
(if to-norm
(rf/merge
cofx
{:db db}
(sign {:tx-obj (if (= symbol :ETH)
{:to to-norm
:from from-address
:chat-id identity
:command? true
:value amount-hex}
{:to (address/normalized-hex address)
:from from-address
:chat-id identity
:command? true
:data (native-module/encode-transfer to-norm amount-hex)})}))
{:db db
:json-rpc/call
[{:method "wakuext_requestAddressForTransaction"
:params [(:current-chat-id db)
from-address
amount
(when-not (= symbol :ETH)
address)]
:js-response true
:on-success #(re-frame/dispatch [:transport/message-sent %])}]})))
(rf/defn sign-transaction-button-clicked-from-request
{:events [:wallet-legacy.ui/sign-transaction-button-clicked-from-request]}
[{:keys [db] :as cofx} {:keys [amount from token]}]
(let [{:keys [request-parameters chat-id]} (:wallet-legacy/prepare-transaction db)
{:keys [symbol address]} token
amount-hex (str "0x" (native-module/number-to-hex amount))
to-norm (:address request-parameters)
from-address (:address from)]
(rf/merge cofx
{:db (dissoc db :wallet-legacy/prepare-transaction :signing/edit-fee)}
(fn [cofx]
(sign
cofx
{:tx-obj (if (= symbol :ETH)
{:to to-norm
:from from-address
:message-id (:id request-parameters)
:chat-id chat-id
:command? true
:value amount-hex}
{:to (address/normalized-hex address)
:from from-address
:command? true
:message-id (:id request-parameters)
:chat-id chat-id
:data (native-module/encode-transfer to-norm amount-hex)})})))))
(rf/defn sign-transaction-button-clicked
{:events [:wallet-legacy.ui/sign-transaction-button-clicked]}
[{:keys [db] :as cofx} {:keys [to amount from token gas gasPrice maxFeePerGas maxPriorityFeePerGas]}]
(let [{:keys [symbol address]} token
amount-hex (str "0x" (native-module/number-to-hex amount))
to-norm (address/normalized-hex (if (string? to) to (:address to)))
from-address (:address from)]
(rf/merge cofx
{:db (dissoc db :wallet-legacy/prepare-transaction :signing/edit-fee)}
(sign
{:tx-obj (merge (if (eip1559/sync-enabled?)
{:from from-address
:gas gas
;; per eip1559
:maxFeePerGas maxFeePerGas
:maxPriorityFeePerGas maxPriorityFeePerGas}
{:from from-address
;;gas and gasPrice from qr (eip681)
:gas gas
:gasPrice gasPrice})
(if (= symbol :ETH)
{:to to-norm
:value amount-hex}
{:to (address/normalized-hex address)
:data (native-module/encode-transfer to-norm amount-hex)}))}))))
(re-frame/reg-fx
:signing/get-transaction-by-hash-fx
(fn [[tx-hash handler]]
(json-rpc/call
{:method "eth_getTransactionByHash"
:params [tx-hash]
:on-success handler})))
(rf/defn cancel-transaction-pressed
{:events [:signing.ui/cancel-transaction-pressed]}
[_ hash]
{:signing/get-transaction-by-hash-fx [hash #(re-frame/dispatch [:signing/cancel-transaction %])]})
(rf/defn increase-gas-pressed
{:events [:signing.ui/increase-gas-pressed]}
[_ hash]
{:signing/get-transaction-by-hash-fx [hash #(re-frame/dispatch [:signing/increase-gas %])]})
(rf/defn cancel-transaction
{:events [:signing/cancel-transaction]}
[cofx {:keys [from nonce hash]}]
(when (and from nonce hash)
(sign cofx
{:tx-obj {:from from
:to from
:nonce nonce
:value "0x0"
:cancel? true
:hash hash}})))
(rf/defn increase-gas
{:events [:signing/increase-gas]}
[cofx {:keys [from nonce] :as tx}]
(when (and from nonce)
(sign cofx
{:tx-obj (-> tx
(select-keys [:from :to :value :input :gas :nonce :hash])
(set/rename-keys {:input :data}))})))
@@ -1,64 +0,0 @@
(ns legacy.status-im.signing.core-test
(:require
[cljs.test :refer-macros [deftest is testing]]
[legacy.status-im.signing.core :as signing]
[native-module.core :as native-module]))
(deftest signing-test
(testing "showing sheet"
(let [to "0x2f88d65f3cb52605a54a833ae118fb1363acccd2"
contract "0xc55cf4b03948d7ebc8b9e8bad92643703811d162"
amount1-hex (str "0x" (native-module/number-to-hex "10000000000000000000"))
amount2-hex (str "0x" (native-module/number-to-hex "100000000000000000000"))
data (native-module/encode-transfer to amount2-hex)
first-tx {:tx-obj {:to to
:from nil
:value amount1-hex}}
second-tx {:tx-obj {:to contract
:from nil
:data data}}
sign-first (signing/sign {:db {}} first-tx)
sign-second (signing/sign sign-first second-tx)]
(testing "after fist transaction"
(testing "signing in progress"
(is (get-in sign-first [:db :signing/tx])))
(testing "qieue is empty"
(is (= (get-in sign-first [:db :signing/queue]) '())))
(testing "first tx object is parsed"
(is (= (dissoc (get-in sign-first [:db :signing/tx]) :token :hash :cancel?)
(merge first-tx
{:from {:address nil}
:gas nil
:gasPrice nil
:maxFeePerGas nil
:maxPriorityFeePerGas nil
:data nil
:to to
:contact {:address to}
:symbol :ETH
:value "0x8ac7230489e80000"
:amount "10"})))))
(testing "after second transaction"
(testing "signing still in progress"
(is (get-in sign-second [:db :signing/tx])))
(testing "queue is not empty, second tx in queue"
(is (= (get-in sign-second [:db :signing/queue]) (list second-tx))))
(testing "check queue does nothing"
(is (not (signing/check-queue sign-second))))
(let [first-discarded (signing/check-queue (update sign-second :db dissoc :signing/tx))]
(testing "after first transaction discarded"
(testing "signing still in progress"
(is (get-in first-discarded [:db :signing/tx])))
(testing "qieue is empty"
(is (= (get-in first-discarded [:db :signing/queue]) '())))
(testing "second tx object is parsed"
(is (= (dissoc (get-in first-discarded [:db :signing/tx]) :token :hash :cancel?)
(merge second-tx
{:from {:address nil}
:gas nil
:gasPrice nil
:maxFeePerGas nil
:maxPriorityFeePerGas nil
:data data
:to contract
:contact {:address contract}}))))))))))

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