Compare commits

..
681 changed files with 16689 additions and 10195 deletions
-1
View File
@@ -35,4 +35,3 @@ LOCAL_PAIRING_ENABLED=1
TEST_STATEOFUS=1
FAST_CREATE_COMMUNITY_ENABLED=1
TEST_NETWORKS_ENABLED=1
SHOW_NOT_IMPLEMENTED_FEATURES=0
-3
View File
@@ -34,6 +34,3 @@ STICKERS_TEST_ENABLED=1
LOCAL_PAIRING_ENABLED=1
FAST_CREATE_COMMUNITY_ENABLED=1
TEST_NETWORKS_ENABLED=1
SHOW_NOT_IMPLEMENTED_FEATURES=1
DELETE_MESSAGE_FOR_ME_UNDO_TIME_LIMIT=10000
DELETE_MESSAGE_UNDO_TIME_LIMIT=10000
-1
View File
@@ -36,4 +36,3 @@ STICKERS_TEST_ENABLED=1
LOCAL_PAIRING_ENABLED=1
FAST_CREATE_COMMUNITY_ENABLED=1
TEST_NETWORKS_ENABLED=1
SHOW_NOT_IMPLEMENTED_FEATURES=1
-7
View File
@@ -2,13 +2,6 @@
xmlns:tools="http://schemas.android.com/tools"
android:installLocation="auto">
<queries>
<intent>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<data android:mimeType="*/*" />
</intent>
</queries>
<!-- non-dangerous permissions -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE"/>
+1 -8
View File
@@ -36,12 +36,6 @@ pipeline {
))
}
environment {
/* Avoid race conditions with other builds using virtualenv. */
VIRTUAL_ENV = "${WORKSPACE_TMP}/venv"
PATH = "${VIRTUAL_ENV}/bin:${PATH}"
}
stages {
stage('Fetch') {
steps { script {
@@ -58,8 +52,7 @@ pipeline {
stage('Setup') {
steps { script {
dir('test/appium') {
sh "python3 -m venv ${VIRTUAL_ENV}"
sh 'pip3 install -r requirements.txt'
sh 'pip3 install --user -r requirements.txt'
}
} }
}
+1 -8
View File
@@ -54,12 +54,6 @@ pipeline {
))
}
environment {
/* Avoid race conditions with other builds using virtualenv. */
VIRTUAL_ENV = "${WORKSPACE_TMP}/venv"
PATH = "${VIRTUAL_ENV}/bin:${PATH}"
}
stages {
stage('Prep') {
steps { script {
@@ -85,8 +79,7 @@ pipeline {
stage('Setup') {
steps { script {
dir('test/appium') {
sh "python3 -m venv ${VIRTUAL_ENV}"
sh 'pip3 install -r requirements.txt'
sh 'pip3 install --user -r requirements.txt'
}
} }
}
+1 -7
View File
@@ -35,11 +35,6 @@ pipeline {
))
}
environment {
/* Avoid race conditions with other builds using virtualenv. */
VIRTUAL_ENV = "${WORKSPACE_TMP}/venv"
PATH = "${VIRTUAL_ENV}/bin:${PATH}"
}
stages {
stage('Prep') {
@@ -56,8 +51,7 @@ pipeline {
stage('Setup') {
steps { script {
dir('test/appium') {
sh "python3 -m venv ${VIRTUAL_ENV}"
sh 'pip3 install -r requirements.txt'
sh 'pip3 install --user -r requirements.txt'
}
} }
}
+1
View File
@@ -8,6 +8,7 @@
1) Read our [PR Review Policy](pr-review-policy.md) for more details on our approach to PR reviews.
2) Learn more about our [Pipeline for QA](pipeline_process.md) process
6) Once e2e tests have run, they will report the result on the PR, if it's less than 100%, ask QA to take a look to make sure everything is in order (some might fail for legitimate reasons)
1) Try pinging @status-im/mobile-qa for help when reviewing the e2e results on the PR.
7) Ask QA for manual testing if the PR requires it (more details [here](pipeline_process.md))
8) Once it has been tested successfully, squash everything into one commit. rebase and merge. The commands we use:
```
+19 -18
View File
@@ -8,7 +8,7 @@ The generally accepted requirements for its use are described below:
- Once a PR is created, it moves to the ```REVIEW``` column where a review will be requested automatically.
- You can also request a review inside the PR from a particular person if needed.
- When creating a PR, do not forget to assign it to yourself.
- Also in case the PR adds new functionality, a description **MUST** be added.
- Also in case the PR adds new functionality, a short description would be appreciated.
### What if the work is still in progress?
@@ -28,11 +28,26 @@ Ready for testing, a PR should meet the following criteria:
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. 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.
6. After that - PR will be taken into manual testing by the QA team.
### E2E tests and analyzing the results
The PR **MUST** be moved to the E2E column when it is ready for testing (**mandatory for all PRs**).
That will also trigger e2e tests run. QAs are monitoring PRs from E2E column and take it into test.
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.
@@ -44,20 +59,6 @@ Please, respect this rule.**
## Testing PR
### Adding `skip-manual-qa`
**Do not hesitate to use a `skip-manual-qa`** if you're sure that it is a simple flow and you checked it.
- Please ask another team member before adding the `skip-manual-qa` label (PR/Status community/DMs) so that there's a second opinion.
- The PR MUST have a proper reasoning why manual QA is skipped.
- The PR MUST include the steps of testing that has been done by the developer prior to moving it forward.
**NOTE:** Make sure that QAs are OK with that;
Before merging PRs, please make sure that information is added about how you tested the PRs, that e2s have been passed and their results have been reviewed.
The QA team appreciates your help!
### Manual testing
#### Prerequisites for manual testing
@@ -98,7 +99,7 @@ There are three possible scenarios when the design review is completed:
---
**Notes:**
- If your PR has a long story and started from `develop` branch several days ago, please rebase it to current develop before adding label
- if PR can be tested by developer (in case of small changes) and/or developer is sure that the changes made cannot introduce a regression, then PR can be merged without manual testing. Also, currently, PRs are not manually tested if the changes relate only the design (creation of components, etc.) and do not affect the functionality (see `skip-manual-qa` label)
- if PR can be tested by developer (in case of small changes) and/or developer is sure that the changes made cannot introduce a regression, then PR can be merged without manual testing. Also, currently, PRs are not manually tested if the changes relate only the design (creation of components, etc.) and do not affect the functionality.
---
#### Why my PR is in `Contributor` column?
-16
View File
@@ -128,19 +128,3 @@ Status-mobile uses `shadow-cljs` for hot reloading changes and uses its own [rel
### Solution
Open react native's [In-App Developer Menu](https://reactnative.dev/docs/debugging#accessing-the-in-app-developer-menu) and press "Disable Fast Refresh" or "Disable Hot Reloading"
# App crashing after running `make run-ios`
### Cause
It's possible that installing XCode from a `.xip` file might cause XCode to act funny
Since it's not installed from the App Store, Or you might be missing a Rosetta installation.
[Reference/Similar issue](https://github.com/expo/expo-cli/issues/3197)
You might see something like this after running `make run-ios`:
```
Underlying error (domain=FBSOpenApplicationServiceErrorDomain, code=1):
```
### Solution
Run `softwareupdate --install-rosetta --agree-to-license`
to accept XCode's license and install Rosetta.
+2 -2
View File
@@ -164,7 +164,7 @@ def build_ios_e2e
# 3. directory where to up StatusIm.app
derived_data_path: 'status-ios',
output_name: 'StatusIm.app',
buildlog_path: 'logs',
buildlog_path: 'ios/logs',
# -------------------------------------
# Normal stuff
scheme: 'StatusIm',
@@ -231,7 +231,7 @@ platform :ios do
clean: true,
export_method: 'app-store',
output_directory: 'status-ios',
buildlog_path: 'logs',
buildlog_path: 'ios/logs',
include_symbols: false,
export_options: {
"combileBitcode": true,
+9 -21
View File
@@ -1,28 +1,13 @@
def node_require(script)
# Resolve script with node to allow for hoisting
require Pod::Executable.execute_command('node', ['-p',
"require.resolve(
'#{script}',
{paths: [process.argv[1]]},
)", __dir__]).strip
end
node_require('react-native/scripts/react_native_pods.rb')
node_require('react-native-permissions/scripts/setup.rb')
# Resolve react_native_pods.rb with node to allow for hoisting
require Pod::Executable.execute_command('node', ['-p',
'require.resolve(
"react-native/scripts/react_native_pods.rb",
{paths: [process.argv[1]]},
)', __dir__]).strip
platform :ios, min_ios_version_supported
prepare_react_native_project!
setup_permissions([
'Camera',
'FaceID',
'MediaLibrary',
'Microphone',
'Notifications',
'PhotoLibrary',
'PhotoLibraryAddOnly',
])
linkage = ENV['USE_FRAMEWORKS']
if linkage != nil
Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
@@ -58,6 +43,9 @@ abstract_target 'Status' do
pod 'SSZipArchive', '2.4.3'
permissions_path = '../node_modules/react-native-permissions/ios'
pod 'Permission-Microphone', :path => "#{permissions_path}/Microphone/Permission-Microphone.podspec"
pod 'Permission-Camera', :path => "#{permissions_path}/Camera/Permission-Camera.podspec"
pod "react-native-status-keycard", path: "../node_modules/react-native-status-keycard"
pod "react-native-status", path: "../modules/react-native-status"
pod "Keycard", git: "https://github.com/status-im/Keycard.swift.git"
+25 -11
View File
@@ -28,6 +28,10 @@ PODS:
- libwebp/mux (1.2.4):
- libwebp/demux
- libwebp/webp (1.2.4)
- Permission-Camera (3.8.0):
- RNPermissions
- Permission-Microphone (3.8.0):
- RNPermissions
- RCT-Folly (2022.05.16.00):
- boost
- DoubleConversion
@@ -875,13 +879,9 @@ PODS:
- React-Core
- react-native-blob-util (0.13.18):
- React-Core
- react-native-blur (4.4.0):
- glog
- RCT-Folly (= 2022.05.16.00)
- react-native-blur (4.3.3):
- React-Core
- react-native-cameraroll (7.5.2):
- glog
- RCT-Folly (= 2022.05.16.00)
- react-native-cameraroll (5.10.0):
- React-Core
- react-native-config (1.5.0):
- react-native-config/App (= 1.5.0)
@@ -893,6 +893,8 @@ PODS:
- React
- react-native-lottie-splash-screen (1.1.2):
- React
- react-native-mail (6.1.1):
- React-Core
- react-native-netinfo (4.7.0):
- React
- react-native-orientation-locker (1.5.0):
@@ -1119,7 +1121,7 @@ PODS:
- TOCropViewController
- RNKeychain (8.1.2):
- React-Core
- RNPermissions (4.1.5):
- RNPermissions (3.8.0):
- React-Core
- RNReanimated (3.6.1):
- glog
@@ -1152,6 +1154,8 @@ DEPENDENCIES:
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- Keycard (from `https://github.com/status-im/Keycard.swift.git`)
- Permission-Camera (from `../node_modules/react-native-permissions/ios/Camera/Permission-Camera.podspec`)
- Permission-Microphone (from `../node_modules/react-native-permissions/ios/Microphone/Permission-Microphone.podspec`)
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
- RCT-Folly/Fabric (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
@@ -1184,6 +1188,7 @@ DEPENDENCIES:
- react-native-hole-view (from `../node_modules/react-native-hole-view`)
- react-native-image-resizer (from `../node_modules/react-native-image-resizer`)
- react-native-lottie-splash-screen (from `../node_modules/react-native-lottie-splash-screen`)
- 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-shake (from `../node_modules/react-native-shake`)
@@ -1260,6 +1265,10 @@ EXTERNAL SOURCES:
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
Keycard:
:git: https://github.com/status-im/Keycard.swift.git
Permission-Camera:
:path: "../node_modules/react-native-permissions/ios/Camera/Permission-Camera.podspec"
Permission-Microphone:
:path: "../node_modules/react-native-permissions/ios/Microphone/Permission-Microphone.podspec"
RCT-Folly:
:podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec"
RCTRequired:
@@ -1320,6 +1329,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-image-resizer"
react-native-lottie-splash-screen:
:path: "../node_modules/react-native-lottie-splash-screen"
react-native-mail:
:path: "../node_modules/react-native-mail"
react-native-netinfo:
:path: "../node_modules/@react-native-community/netinfo"
react-native-orientation-locker:
@@ -1437,6 +1448,8 @@ SPEC CHECKSUMS:
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8
libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef
Permission-Camera: e6d142d7d8b714afe0a83e5e6ae17eb949f1e3e9
Permission-Microphone: 644b1de8bcc2afcaf934e09a22bee507a95796a7
RCT-Folly: 7169b2b1c44399c76a47b5deaaba715eeeb476c0
RCTRequired: 2544c0f1081a5fa12e108bb8cb40e5f4581ccd87
RCTTypeSafety: 50efabe2b115c11ed03fbf3fd79e2f163ddb5d7c
@@ -1461,12 +1474,13 @@ SPEC CHECKSUMS:
react-native-background-timer: 1f7d560647b40e6a60b01c452ba29c54bf581fc4
react-native-biometrics: 352e5a794bfffc46a0c86725ea7dc62deb085bdc
react-native-blob-util: 600972b1782380a5a7d5db61a3817ea32349dae9
react-native-blur: 799045500f56146afc46245148080e7b7623cb75
react-native-cameraroll: af8eec1e585d053ff485d98ec837f9a8a11b5745
react-native-blur: c6d0a1dc2b4b519f7afe3b14d8151998632b6d18
react-native-cameraroll: 4701ae7c3dbcd3f5e9e150ca17f250a276154b35
react-native-config: 5330c8258265c1e5fdb8c009d2cabd6badd96727
react-native-hole-view: 6935448993bac79f2b5a4ad7e9741094cf810679
react-native-image-resizer: 2f1577efa3bc762597681f530c8e8d05ce0ceeb3
react-native-lottie-splash-screen: 4e1b1fd9d6633f9cd2106d6877eb5ba0147f3e2b
react-native-mail: 8fdcd3aef007c33a6877a18eb4cf7447a1d4ce4a
react-native-netinfo: ddaca8bbb9e6e914b1a23787ccb879bc642931c9
react-native-orientation-locker: 851f6510d8046ea2f14aa169b1e01fcd309a94ba
react-native-shake: de052eaa3eadc4a326b8ddd7ac80c06e8d84528c
@@ -1507,7 +1521,7 @@ SPEC CHECKSUMS:
RNGestureHandler: 15c6ef51acba34c49ff03003806cf5dd6098f383
RNImageCropPicker: 486e2f7e2b0461ce24321f751410dce1b3b49e6d
RNKeychain: a65256b6ca6ba6976132cc4124b238a5b13b3d9c
RNPermissions: 08e619529cced22695f4b6d0efcc0a233e278903
RNPermissions: 215c54462104b3925b412b0fb3c9c497b21c358b
RNReanimated: dee37576492f1a375017515f5c77e66e5eec696b
RNShare: 859ff710211285676b0bcedd156c12437ea1d564
RNStaticSafeAreaInsets: 055ddbf5e476321720457cdaeec0ff2ba40ec1b8
@@ -1520,6 +1534,6 @@ SPEC CHECKSUMS:
TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863
Yoga: a716eea57d0d3430219c0a5a233e1e93ee931eb7
PODFILE CHECKSUM: bb02c595a4aa4430da978b55da5440811cbd9d91
PODFILE CHECKSUM: c9c6dfac28e31314e1a2ee2dc47364ad151f13f2
COCOAPODS: 1.13.0
+126 -132
View File
@@ -11,6 +11,7 @@
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
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 */; };
@@ -35,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 */; };
4A976A097386605EB7E85E28 /* libPods-Status-StatusIm-StatusImTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 804FB5E6B0FBBDB034E6CD09 /* 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 */; };
@@ -45,11 +46,11 @@
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 */; };
BA68A2377A20496EA737000D /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E586E1B0E544F64AA9F5BD1 /* libz.tbd */; };
C0BA109CA441C3DB93714F1D /* libPods-Status-StatusIm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EA288D7C6590DC9ED1F8657F /* libPods-Status-StatusIm.a */; };
C14C5F8D29C0A149005C58A7 /* launch-icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = C14C5F8C29C0A149005C58A7 /* launch-icon@3x.png */; };
C14C5F9129C0AD9C005C58A7 /* launch-icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C14C5F9029C0AD9C005C58A7 /* launch-icon@2x.png */; };
C14C5F9329C0ADB5005C58A7 /* launch-icon.png in Resources */ = {isa = PBXBuildFile; fileRef = C14C5F9229C0ADB5005C58A7 /* launch-icon.png */; };
@@ -57,7 +58,6 @@
C1715FFB29C0BCE50088FA8B /* launch-icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = C14C5F8C29C0A149005C58A7 /* launch-icon@3x.png */; };
C1715FFC29C0BCE80088FA8B /* launch-icon.png in Resources */ = {isa = PBXBuildFile; fileRef = C14C5F9229C0ADB5005C58A7 /* launch-icon.png */; };
CE4E31B31D8695250033ED64 /* Statusgo.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE4E31B21D8695250033ED64 /* Statusgo.xcframework */; };
D0B4A2EA5E72EDB67CE6DA66 /* libPods-Status-StatusImPR.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B63C43A120FA22BB78FCC059 /* libPods-Status-StatusImPR.a */; };
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 */; };
@@ -108,34 +108,36 @@
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>"; };
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>"; };
3DE83268BA3216610DFF6337 /* 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>"; };
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>"; };
78655BCD07318E9885F5214B /* 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>"; };
804FB5E6B0FBBDB034E6CD09 /* libPods-Status-StatusIm-StatusImTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusIm-StatusImTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
857B0CA5528DF4E460CECF05 /* 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>"; };
870C29BCADFAAEC7F7C0ADD0 /* 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>"; };
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>"; };
94F1B9FD13C8504F50E31C94 /* 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>"; };
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>"; };
@@ -145,15 +147,13 @@
B2A38FC3D3954DE7B2B171F8 /* Inter-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-Medium.otf"; path = "../resources/fonts/Inter-Medium.otf"; sourceTree = "<group>"; };
B2F2D1BB1D9D531B00B7B453 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = StatusIm/Images.xcassets; sourceTree = "<group>"; };
B321D25F4493470980039457 /* Inter-BoldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-BoldItalic.otf"; path = "../resources/fonts/Inter-BoldItalic.otf"; sourceTree = "<group>"; };
B63C43A120FA22BB78FCC059 /* libPods-Status-StatusImPR.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusImPR.a"; sourceTree = BUILT_PRODUCTS_DIR; };
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>"; };
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>"; };
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>"; };
D272F46F39D037EC0EAB65C8 /* 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>"; };
EA288D7C6590DC9ED1F8657F /* libPods-Status-StatusIm.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Status-StatusIm.a"; sourceTree = BUILT_PRODUCTS_DIR; };
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 */
@@ -161,7 +161,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
4A976A097386605EB7E85E28 /* libPods-Status-StatusIm-StatusImTests.a in Frameworks */,
8CF1CA9463A4048F97BABB82 /* libPods-Status-StatusIm-StatusImTests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -174,7 +174,7 @@
CE4E31B31D8695250033ED64 /* Statusgo.xcframework in Frameworks */,
25DC9C9DC25846BD8D084888 /* libc++.tbd in Frameworks */,
BA68A2377A20496EA737000D /* libz.tbd in Frameworks */,
C0BA109CA441C3DB93714F1D /* libPods-Status-StatusIm.a in Frameworks */,
42AC64E4D3CA4E676400C598 /* libPods-Status-StatusIm.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -188,7 +188,7 @@
3AAD2AC224A3A60E0075D594 /* Statusgo.xcframework in Frameworks */,
3AAD2AC524A3A60E0075D594 /* libc++.tbd in Frameworks */,
3AAD2AC624A3A60E0075D594 /* libz.tbd in Frameworks */,
D0B4A2EA5E72EDB67CE6DA66 /* libPods-Status-StatusImPR.a in Frameworks */,
2B6F8F28B81E862D44C8723D /* libPods-Status-StatusImPR.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -314,9 +314,9 @@
CE4E31B21D8695250033ED64 /* Statusgo.xcframework */,
8B9A886A2CB448B1ABA0EB62 /* libc++.tbd */,
4E586E1B0E544F64AA9F5BD1 /* libz.tbd */,
EA288D7C6590DC9ED1F8657F /* libPods-Status-StatusIm.a */,
804FB5E6B0FBBDB034E6CD09 /* libPods-Status-StatusIm-StatusImTests.a */,
B63C43A120FA22BB78FCC059 /* libPods-Status-StatusImPR.a */,
2D2D9E4943562065BF98E304 /* libPods-Status-StatusIm.a */,
466C47BA171B53CAE0AD6A19 /* libPods-Status-StatusIm-StatusImTests.a */,
87038678EE47E8EF6E93EB54 /* libPods-Status-StatusImPR.a */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -324,12 +324,12 @@
D0D5C8D06825D33BA2D2121E /* Pods */ = {
isa = PBXGroup;
children = (
857B0CA5528DF4E460CECF05 /* Pods-Status-StatusIm.debug.xcconfig */,
78655BCD07318E9885F5214B /* Pods-Status-StatusIm.release.xcconfig */,
870C29BCADFAAEC7F7C0ADD0 /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */,
94F1B9FD13C8504F50E31C94 /* Pods-Status-StatusIm-StatusImTests.release.xcconfig */,
3DE83268BA3216610DFF6337 /* Pods-Status-StatusImPR.debug.xcconfig */,
D272F46F39D037EC0EAB65C8 /* 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>";
@@ -341,11 +341,11 @@
isa = PBXNativeTarget;
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "StatusImTests" */;
buildPhases = (
53D1210C251AB35BB66F64D1 /* [CP] Check Pods Manifest.lock */,
99EA576680D5849CA4274106 /* [CP] Check Pods Manifest.lock */,
00E356EA1AD99517003FC87E /* Sources */,
00E356EB1AD99517003FC87E /* Frameworks */,
00E356EC1AD99517003FC87E /* Resources */,
2E8578589647F2D1AB7D69B0 /* [CP] Copy Pods Resources */,
835B3E5945D5F723935FD4E1 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -361,14 +361,14 @@
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "StatusIm" */;
buildPhases = (
0792D7C164832E59371E617A /* [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 */,
70A851EF00039276F55A4FB3 /* [CP] Copy Pods Resources */,
5BEC29A10D63DFF8AFF5B788 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -383,14 +383,14 @@
isa = PBXNativeTarget;
buildConfigurationList = 3AAD2AD924A3A60E0075D594 /* Build configuration list for PBXNativeTarget "StatusImPR" */;
buildPhases = (
16ECB1DEB0091DFC0F3DED3C /* [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 */,
C15E3DDA7B1E1CB5EDF76A1E /* [CP] Copy Pods Resources */,
776D3E96946780BFE216ACF2 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -544,7 +544,7 @@
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";
};
0792D7C164832E59371E617A /* [CP] Check Pods Manifest.lock */ = {
140572B0EA34D6F884AB6CC4 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -566,52 +566,6 @@
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;
};
16ECB1DEB0091DFC0F3DED3C /* [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;
};
2E8578589647F2D1AB7D69B0 /* [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}/RNPermissions/RNPermissionsPrivacyInfo.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}/RNPermissionsPrivacyInfo.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;
};
3AAD2AD524A3A60E0075D594 /* Bundle React Native code and images */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -640,7 +594,95 @@
shellPath = "/usr/bin/env sh";
shellScript = "\"${PROJECT_DIR}/scripts/set_xcode_version.sh\" > ../logs/set_xcode_version.log 2>&1\n";
};
53D1210C251AB35BB66F64D1 /* [CP] Check Pods Manifest.lock */ = {
5BEC29A10D63DFF8AFF5B788 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm-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/Pods-Status-StatusIm-resources.sh\"\n";
showEnvVarsInLog = 0;
};
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 = (
@@ -662,54 +704,6 @@
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;
};
70A851EF00039276F55A4FB3 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm-resources.sh",
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/RNPermissions/RNPermissionsPrivacyInfo.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}/RNPermissionsPrivacyInfo.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/Pods-Status-StatusIm-resources.sh\"\n";
showEnvVarsInLog = 0;
};
C15E3DDA7B1E1CB5EDF76A1E /* [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}/RNPermissions/RNPermissionsPrivacyInfo.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}/RNPermissionsPrivacyInfo.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;
};
E3914A731DF919ED00EBB515 /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 8;
@@ -771,7 +765,7 @@
/* Begin XCBuildConfiguration section */
00E356F61AD99517003FC87E /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 870C29BCADFAAEC7F7C0ADD0 /* 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;
@@ -808,7 +802,7 @@
};
00E356F71AD99517003FC87E /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 94F1B9FD13C8504F50E31C94 /* Pods-Status-StatusIm-StatusImTests.release.xcconfig */;
baseConfigurationReference = 2756A97EBFF084FA94990AA5 /* Pods-Status-StatusIm-StatusImTests.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_ID_SUFFIX = "";
@@ -841,7 +835,7 @@
};
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 857B0CA5528DF4E460CECF05 /* 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;
@@ -923,7 +917,7 @@
};
13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 78655BCD07318E9885F5214B /* Pods-Status-StatusIm.release.xcconfig */;
baseConfigurationReference = 7FA4F04CE45319370F87C4FD /* Pods-Status-StatusIm.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon$(BUNDLE_ID_SUFFIX)";
BUNDLE_ID_SUFFIX = "";
@@ -998,7 +992,7 @@
};
3AAD2ADA24A3A60E0075D594 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3DE83268BA3216610DFF6337 /* 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;
@@ -1078,7 +1072,7 @@
};
3AAD2ADB24A3A60E0075D594 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = D272F46F39D037EC0EAB65C8 /* Pods-Status-StatusImPR.release.xcconfig */;
baseConfigurationReference = 0C331FD392B615DDAD0997F5 /* Pods-Status-StatusImPR.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIconPR$(BUNDLE_ID_SUFFIX)";
BUNDLE_ID_SUFFIX = "";
@@ -47,8 +47,7 @@ class AccountManager(private val reactContext: ReactApplicationContext) : ReactC
private fun updateConfig(jsonConfigString: String, absRootDirPath: String, keystoreDirPath: String): String {
val jsonConfig = JSONObject(jsonConfigString)
// when doing local pair syncing, backend will provide default data dir
val dataDirPath = jsonConfig.optString("DataDir","")
val dataDirPath = jsonConfig.getString("DataDir")
val logEnabled = jsonConfig.getBoolean("LogEnabled")
val gethLogFile = if (logEnabled) logManager.prepareLogsFile(reactContext) else null
val gethLogDirPath = gethLogFile?.parent
@@ -141,6 +140,7 @@ class AccountManager(private val reactContext: ReactApplicationContext) : ReactC
updatedJsonConfigString
} catch (e: JSONException) {
Log.e(TAG, "updateConfig failed: ${e.message}")
System.exit(1)
""
}
}
@@ -1,133 +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.ReadableMap
import com.facebook.react.bridge.Callback
import android.util.Log
import android.content.Intent
import android.net.Uri
import android.content.pm.PackageManager
import java.io.File
import androidx.core.content.FileProvider
import android.text.Html
class MailManager(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
private val utils = Utils(reactContext)
override fun getName() = "MailManager"
@ReactMethod
fun mail(options: ReadableMap, callback: Callback) {
Log.d(TAG, "attempting to send email")
val i = Intent(Intent.ACTION_SEND_MULTIPLE)
val selectorIntent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"))
i.selector = selectorIntent
if (options.hasKey("subject") && !options.isNull("subject")) {
i.putExtra(Intent.EXTRA_SUBJECT, options.getString("subject"))
}
if (options.hasKey("body") && !options.isNull("body")) {
val body = options.getString("body")
if (options.hasKey("isHTML") && options.getBoolean("isHTML")) {
i.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(body))
} else {
i.putExtra(Intent.EXTRA_TEXT, body)
}
}
if (options.hasKey("recipients") && !options.isNull("recipients")) {
val recipients = options.getArray("recipients")
i.putExtra(Intent.EXTRA_EMAIL, this.utils.readableArrayToStringArray(recipients!!))
}
if (options.hasKey("ccRecipients") && !options.isNull("ccRecipients")) {
val ccRecipients = options.getArray("ccRecipients")
i.putExtra(Intent.EXTRA_CC, this.utils.readableArrayToStringArray(ccRecipients!!))
}
if (options.hasKey("bccRecipients") && !options.isNull("bccRecipients")) {
val bccRecipients = options.getArray("bccRecipients")
i.putExtra(Intent.EXTRA_BCC, this.utils.readableArrayToStringArray(bccRecipients!!))
}
if (options.hasKey("attachments") && !options.isNull("attachments")) {
val r = options.getArray("attachments")
val length = r?.size() ?: 0
val provider = reactContext.applicationContext.packageName + ".rnmail.provider"
val resolvedIntentActivities = reactContext.packageManager.queryIntentActivities(i,
PackageManager.MATCH_DEFAULT_ONLY)
val uris = ArrayList<Uri>()
for (keyIndex in 0 until length) {
val clip = r?.getMap(keyIndex)
val uri: Uri
if (clip?.hasKey("path") == true && !clip.isNull("path")) {
val path = clip.getString("path")
val file = File(path)
uri = FileProvider.getUriForFile(reactContext, provider, file)
} else if (clip?.hasKey("uri") == true && !clip.isNull("uri")) {
val uriPath = clip.getString("uri")
uri = Uri.parse(uriPath)
} else {
callback.invoke("not_found")
return
}
uris.add(uri)
for (resolvedIntentInfo in resolvedIntentActivities) {
val packageName = resolvedIntentInfo.activityInfo.packageName
reactContext.grantUriPermission(packageName, uri,
Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
}
i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
i.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris)
}
val manager = reactContext.packageManager
val list = manager.queryIntentActivities(i, 0)
if (list == null || list.isEmpty()) {
Log.d(TAG, "not_available")
callback.invoke("not_available")
return
}
if (list.size == 1) {
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
try {
reactContext.startActivity(i)
} catch (ex: Exception) {
Log.e(TAG, ex.message!!)
callback.invoke("error")
}
} else {
var chooserTitle = "Send Mail"
if (options.hasKey("customChooserTitle") && !options.isNull("customChooserTitle")) {
chooserTitle = options.getString("customChooserTitle") ?: ""
}
val chooser = Intent.createChooser(i, chooserTitle)
chooser.flags = Intent.FLAG_ACTIVITY_NEW_TASK
try {
reactContext.startActivity(chooser)
} catch (ex: Exception) {
Log.e(TAG, ex.message!!)
callback.invoke("error")
}
}
}
companion object {
private const val TAG = "MailManager"
}
}
@@ -74,5 +74,4 @@ class NetworkManager(private val reactContext: ReactApplicationContext) : ReactC
fun recover(rpcParams: String, callback: Callback) {
utils.executeRunnableStatusGoMethod({ Statusgo.recover(rpcParams) }, callback)
}
}
@@ -43,6 +43,7 @@ class StatusModule(private val reactContext: ReactApplicationContext, private va
}
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)
@@ -24,7 +24,6 @@ class StatusPackage(private val rootedDevice: Boolean) : ReactPackage {
add(LogManager(reactContext))
add(Utils(reactContext))
add(NetworkManager(reactContext))
add(MailManager(reactContext))
add(RNSelectableTextInputModule(reactContext))
}
@@ -6,7 +6,6 @@ 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 com.facebook.react.bridge.ReadableArray;
import android.util.Log
import org.json.JSONException
import org.json.JSONObject
@@ -142,15 +141,4 @@ class Utils(private val reactContext: ReactApplicationContext) : ReactContextBas
fun toChecksumAddress(address: String): String {
return Statusgo.toChecksumAddress(address)
}
fun readableArrayToStringArray(r: ReadableArray): Array<String> {
val length = r.size()
val strArray = Array(length) { "" }
for (keyIndex in 0 until length) {
strArray[keyIndex] = r.getString(keyIndex) ?: ""
}
return strArray
}
}
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="rnmail_dl" path="Download/" />
<cache-path name="rnmail_cache" path="/" />
<root-path name="rnmail_sdcard" path="." />
</paths>
@@ -66,9 +66,6 @@ RCT_EXPORT_METHOD(restoreAccountAndLogin:(NSString *)request) {
NSData *configData = [config dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *configJSON = [NSJSONSerialization JSONObjectWithData:configData options:NSJSONReadingMutableContainers error:nil];
NSString *relativeDataDir = [configJSON objectForKey:@"DataDir"];
if (relativeDataDir == nil) {
relativeDataDir = @"";
}
NSString *absDataDir = [rootUrl.path stringByAppendingString:relativeDataDir];
NSURL *absDataDirUrl = [NSURL fileURLWithPath:absDataDir];
NSString *keystoreDir = [@"/keystore/" stringByAppendingString:keyUID];
@@ -1,9 +0,0 @@
#import <sys/utsname.h>
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <React/RCTBridgeModule.h>
#import "RCTLog.h"
@interface MailManager : NSObject <RCTBridgeModule, MFMailComposeViewControllerDelegate>
@end
@@ -1,207 +0,0 @@
#import <MessageUI/MessageUI.h>
#import "MailManager.h"
#import <React/RCTConvert.h>
#import <React/RCTLog.h>
#import "React/RCTBridge.h"
#import "React/RCTEventDispatcher.h"
@implementation MailManager
{
NSMutableDictionary *_callbacks;
}
- (instancetype)init
{
if ((self = [super init])) {
_callbacks = [[NSMutableDictionary alloc] init];
}
return self;
}
- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}
+ (BOOL)requiresMainQueueSetup
{
return YES;
}
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(mail:(NSDictionary *)options
callback: (RCTResponseSenderBlock)callback)
{
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mail = [[MFMailComposeViewController alloc] init];
mail.mailComposeDelegate = self;
_callbacks[RCTKeyForInstance(mail)] = callback;
if (options[@"subject"]){
NSString *subject = [RCTConvert NSString:options[@"subject"]];
[mail setSubject:subject];
}
BOOL isHTML = NO;
if (options[@"isHTML"]){
isHTML = [options[@"isHTML"] boolValue];
}
if (options[@"body"]){
NSString *body = [RCTConvert NSString:options[@"body"]];
[mail setMessageBody:body isHTML:isHTML];
}
if (options[@"recipients"]){
NSArray *recipients = [RCTConvert NSArray:options[@"recipients"]];
[mail setToRecipients:recipients];
}
if (options[@"ccRecipients"]){
NSArray *ccRecipients = [RCTConvert NSArray:options[@"ccRecipients"]];
[mail setCcRecipients:ccRecipients];
}
if (options[@"bccRecipients"]){
NSArray *bccRecipients = [RCTConvert NSArray:options[@"bccRecipients"]];
[mail setBccRecipients:bccRecipients];
}
if (options[@"attachments"]) {
NSArray *attachments = [RCTConvert NSArray:options[@"attachments"]];
for (NSDictionary *attachment in attachments) {
if ((attachment[@"path"] || attachment[@"uri"]) && (attachment[@"type"] || attachment[@"mimeType"])) {
NSString *attachmentPath = [RCTConvert NSString:attachment[@"path"]];
NSString *attachmentUri = [RCTConvert NSString:attachment[@"uri"]];
NSString *attachmentType = [RCTConvert NSString:attachment[@"type"]];
NSString *attachmentName = [RCTConvert NSString:attachment[@"name"]];
NSString *attachmentMimeType = [RCTConvert NSString:attachment[@"mimeType"]];
// Set default filename if not specificed
if (!attachmentName) {
attachmentName = [[attachmentPath lastPathComponent] stringByDeletingPathExtension];
}
NSData *fileData;
if (attachmentPath) {
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:attachmentPath]){
callback(@[[NSString stringWithFormat: @"attachment file with path '%@' does not exist", attachmentPath]]);
return;
}
// Get the resource path and read the file using NSData
fileData = [NSData dataWithContentsOfFile:attachmentPath];
} else if (attachmentUri) {
// Get the URI and read it using NSData
NSURL *attachmentURL = [[NSURLComponents componentsWithString:attachmentUri] URL];
NSError *error = nil;
fileData = [NSData dataWithContentsOfURL:attachmentURL options:0 error:&error];
if (!fileData) {
callback(@[[NSString stringWithFormat: @"attachment file with uri '%@' does not exist", attachmentUri]]);
return;
}
}
// Determine the MIME type
NSString *mimeType;
if (attachmentType) {
/*
* Add additional mime types and PR if necessary. Find the list
* of supported formats at http://www.iana.org/assignments/media-types/media-types.xhtml
*/
NSDictionary *supportedMimeTypes = @{
@"jpeg" : @"image/jpeg",
@"jpg" : @"image/jpeg",
@"png" : @"image/png",
@"doc" : @"application/msword",
@"docx" : @"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
@"ppt" : @"application/vnd.ms-powerpoint",
@"pptx" : @"application/vnd.openxmlformats-officedocument.presentationml.presentation",
@"html" : @"text/html",
@"csv" : @"text/csv",
@"pdf" : @"application/pdf",
@"vcard" : @"text/vcard",
@"json" : @"application/json",
@"zip" : @"application/zip",
@"text" : @"text/*",
@"mp3" : @"audio/mpeg",
@"wav" : @"audio/wav",
@"aiff" : @"audio/aiff",
@"flac" : @"audio/flac",
@"ogg" : @"audio/ogg",
@"xls" : @"application/vnd.ms-excel",
@"ics" : @"text/calendar",
@"xlsx" : @"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
};
if([supportedMimeTypes objectForKey:attachmentType]) {
mimeType = [supportedMimeTypes objectForKey:attachmentType];
} else {
callback(@[[NSString stringWithFormat: @"Mime type '%@' for attachment is not handled", attachmentType]]);
return;
}
} else if (attachmentMimeType) {
mimeType = attachmentMimeType;
}
// Add attachment
[mail addAttachmentData:fileData mimeType:mimeType fileName:attachmentName];
}
}
}
UIViewController *root = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
while (root.presentedViewController) {
root = root.presentedViewController;
}
[root presentViewController:mail animated:YES completion:nil];
} else {
callback(@[@"not_available"]);
}
}
#pragma mark MFMailComposeViewControllerDelegate Methods
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
NSString *key = RCTKeyForInstance(controller);
RCTResponseSenderBlock callback = _callbacks[key];
if (callback) {
switch (result) {
case MFMailComposeResultSent:
callback(@[[NSNull null] , @"sent"]);
break;
case MFMailComposeResultSaved:
callback(@[[NSNull null] , @"saved"]);
break;
case MFMailComposeResultCancelled:
callback(@[[NSNull null] , @"cancelled"]);
break;
case MFMailComposeResultFailed:
callback(@[@"failed"]);
break;
default:
callback(@[@"error"]);
break;
}
[_callbacks removeObjectForKey:key];
} else {
RCTLogWarn(@"No callback registered for mail: %@", controller.title);
}
UIViewController *ctrl = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
while (ctrl.presentedViewController && ctrl != controller) {
ctrl = ctrl.presentedViewController;
}
[ctrl dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark Private
static NSString *RCTKeyForInstance(id instance)
{
return [NSString stringWithFormat:@"%p", instance];
}
@end
@@ -38,6 +38,9 @@ static RCTBridge *bridge;
return;
}
#if DEBUG
NSLog(@"[handleSignal] Received an event from Status-Go: %@", signal);
#endif
[bridge.eventDispatcher sendAppEventWithName:@"gethEvent"
body:@{@"jsonEvent": signal}];
@@ -12,7 +12,6 @@
CE4E31B11D86951A0033ED64 /* Statusgo.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE4E31B01D86951A0033ED64 /* Statusgo.xcframework */; };
E92244EB2B485F2400915F4C /* UIHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = E92244E92B485F2400915F4C /* UIHelper.m */; };
E967A3AC2B47BD5A00FB19B2 /* Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = E967A3AB2B47BD5A00FB19B2 /* Utils.m */; };
E9AEB5FE2BD8EEB100FB2926 /* MailManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E9AEB5FD2BD8EEB100FB2926 /* MailManager.m */; };
E9BEF3602B470BF1001F6755 /* NetworkManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E9BEF35E2B470BF1001F6755 /* NetworkManager.m */; };
E9C33AA62B4828A60074B1C5 /* DatabaseManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E9C33AA52B4828A60074B1C5 /* DatabaseManager.m */; };
E9DB08932B4858B400F51053 /* LogManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E9DB08912B4858B400F51053 /* LogManager.m */; };
@@ -43,8 +42,6 @@
E92244EA2B485F2400915F4C /* UIHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIHelper.h; sourceTree = "<group>"; };
E967A3AA2B47BD5A00FB19B2 /* Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Utils.h; sourceTree = "<group>"; };
E967A3AB2B47BD5A00FB19B2 /* Utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Utils.m; sourceTree = "<group>"; };
E9AEB5FC2BD8EEB100FB2926 /* MailManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MailManager.h; sourceTree = "<group>"; };
E9AEB5FD2BD8EEB100FB2926 /* MailManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MailManager.m; sourceTree = "<group>"; };
E9BEF35E2B470BF1001F6755 /* NetworkManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NetworkManager.m; sourceTree = "<group>"; };
E9BEF35F2B470BF1001F6755 /* NetworkManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkManager.h; sourceTree = "<group>"; };
E9C33AA42B4828A60074B1C5 /* DatabaseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatabaseManager.h; sourceTree = "<group>"; };
@@ -89,8 +86,6 @@
206C9F3C1D474E910063E3E6 /* Status */ = {
isa = PBXGroup;
children = (
E9AEB5FC2BD8EEB100FB2926 /* MailManager.h */,
E9AEB5FD2BD8EEB100FB2926 /* MailManager.m */,
E92244EA2B485F2400915F4C /* UIHelper.h */,
E92244E92B485F2400915F4C /* UIHelper.m */,
E9DB08922B4858B400F51053 /* LogManager.h */,
@@ -168,7 +163,6 @@
buildActionMask = 2147483647;
files = (
E9DB08932B4858B400F51053 /* LogManager.m in Sources */,
E9AEB5FE2BD8EEB100FB2926 /* MailManager.m in Sources */,
E9F5C3322B483B6C001A7F40 /* EncryptionUtils.m in Sources */,
E967A3AC2B47BD5A00FB19B2 /* Utils.m in Sources */,
E92244EB2B485F2400915F4C /* UIHelper.m in Sources */,
@@ -1128,6 +1128,8 @@ Persistent<Function> r_call;
std::queue<std::string> q;
void run(char *json) {
printf("signal received %s\n", json);
std::string str(json);
q.push(str);
}
+54 -425
View File
@@ -1165,21 +1165,6 @@
}
},
{
"path": "androidx/databinding/databinding-common/3.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"databinding-common-3.5.3.pom": {
"sha1": "0f85f7500d68d4eaed465ec194e18779374a7a68",
"sha256": "sha256-paY7t0Iz/AxIVcvQLT4sAPgqTvvMChxgS3SmWRod2tw="
},
"databinding-common-3.5.3.jar": {
"sha1": "72bb6cb779ae61710a01ff76d9d3cab355c44a4f",
"sha256": "sha256-WRoV+qBtmUWoqA8m8n2vBosrLirqakvhN7/SixHZVgA="
}
}
},
{
"path": "androidx/databinding/databinding-common/3.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -1289,21 +1274,6 @@
}
},
{
"path": "androidx/databinding/databinding-compiler-common/3.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"databinding-compiler-common-3.5.3.pom": {
"sha1": "345b6f4cea120faa14f118c08150de5d8afccce1",
"sha256": "sha256-LRdv8FuX6tdlmxdHuhK/a/bhc8zIONVFAniG0toDu+A="
},
"databinding-compiler-common-3.5.3.jar": {
"sha1": "32bfc30c00fdc550723ffd9bff3ef2471fbd4a3a",
"sha256": "sha256-yDZslWiT00cwjhF5Be1v2xq+gFW54gEhOrjyMO3GNRg="
}
}
},
{
"path": "androidx/databinding/databinding-compiler-common/3.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -3002,21 +2972,6 @@
}
},
{
"path": "com/android/databinding/baseLibrary/3.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"baseLibrary-3.5.3.pom": {
"sha1": "81372394c257edc4595cf19c33f7460892eeaa3e",
"sha256": "sha256-knlU7d5unzROdh7YkGliIzSrDWc3i9B2rDIkfhX/Bmk="
},
"baseLibrary-3.5.3.jar": {
"sha1": "5da8b7daa2f10ec359a13ee778eeabf15c1758b1",
"sha256": "sha256-zebU7vY+5eBbiqtY/4Xq85zD5u2E/RhL9lWNgvjZwGc="
}
}
},
{
"path": "com/android/databinding/baseLibrary/3.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -3520,21 +3475,6 @@
}
},
{
"path": "com/android/tools/analytics-library/crash/26.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"crash-26.5.3.pom": {
"sha1": "2b6f117c8542a9132bbd1982960ff93be002eb77",
"sha256": "sha256-ZrYgjqqWCNZ7K84UQIlBptcRC4ePlCVTmsIeuEWnqBU="
},
"crash-26.5.3.jar": {
"sha1": "d199e964be1fa3e7162344b91336afae6c7ea789",
"sha256": "sha256-86x29qjj+M7mPiqew2n87T3przHhRQzZOdiHXWcT758="
}
}
},
{
"path": "com/android/tools/analytics-library/crash/26.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -3659,21 +3599,6 @@
}
},
{
"path": "com/android/tools/analytics-library/protos/26.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"protos-26.5.3.pom": {
"sha1": "a2452eb3233ef51f1dda9b5508cfe340134b4978",
"sha256": "sha256-FYV7IPvj+TmJoQA2xD32xOTygrtjh07jAghoOH7gRuY="
},
"protos-26.5.3.jar": {
"sha1": "16d70f0d597eac5d39180b1ce2d9b274f8802cf9",
"sha256": "sha256-8uut8euJZzFc/sTTw3UkQFSh8W15+N4l0eiYPVq0D70="
}
}
},
{
"path": "com/android/tools/analytics-library/protos/26.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -3798,21 +3723,6 @@
}
},
{
"path": "com/android/tools/analytics-library/shared/26.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"shared-26.5.3.pom": {
"sha1": "14c908921dd73687f66f496dfc73fa807d57e40d",
"sha256": "sha256-FkUuC4D4/OiS5yBlJvWnupvlSungNjArA0ktU240P54="
},
"shared-26.5.3.jar": {
"sha1": "594abc68f0518057cdb150e4c8cc73bc5c94183e",
"sha256": "sha256-dpzYinI6GR6dmPsEGULf5Irzo+8kqP6wCI2NTNfhurA="
}
}
},
{
"path": "com/android/tools/analytics-library/shared/26.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -3937,21 +3847,6 @@
}
},
{
"path": "com/android/tools/analytics-library/tracker/26.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"tracker-26.5.3.pom": {
"sha1": "8551b232bde0e0cd7a9983f4acc716ed2fa8d59b",
"sha256": "sha256-fAbjPrxxjgXSaoM5kD9ZoVTedhcXTPha/bxi0Nsgnkc="
},
"tracker-26.5.3.jar": {
"sha1": "6a84a345f5155eca774cd238c233a2f6fad551b9",
"sha256": "sha256-dqhsU6BlaXcW4tXGEAyd4LrpHVacu5vRn6U+Pw5n63M="
}
}
},
{
"path": "com/android/tools/analytics-library/tracker/26.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -4076,21 +3971,6 @@
}
},
{
"path": "com/android/tools/annotations/26.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"annotations-26.5.3.pom": {
"sha1": "03c6890f54f0b7c91aaeb7d66e87c52e53b10d79",
"sha256": "sha256-4vEHB5aOWAXrLslhHTRa1GVrKLeEpApil0rlXPIQzh4="
},
"annotations-26.5.3.jar": {
"sha1": "87a36f2086b41d1ec162a6e74c4f999d58eb1310",
"sha256": "sha256-/js3c6HdNGlY2KFUess2UN/74HfTmtdMX3b7f6k/NYw="
}
}
},
{
"path": "com/android/tools/annotations/26.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -4503,21 +4383,6 @@
}
},
{
"path": "com/android/tools/build/apksig/3.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"apksig-3.5.3.pom": {
"sha1": "fe080d599c11357971f21a2b7475d9915515d363",
"sha256": "sha256-5sSQBWPiQJf82rf++W6oPPf6sfSTn6teEVRL8Ng0LZ0="
},
"apksig-3.5.3.jar": {
"sha1": "d5ffda89f909743ad8e77b3c28ed351695037543",
"sha256": "sha256-SMfd+nhnEtdmpzyt1+3JGGhsGv1s6FcRyvUQYx+0CQ8="
}
}
},
{
"path": "com/android/tools/build/apksig/3.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -4627,21 +4492,6 @@
}
},
{
"path": "com/android/tools/build/apkzlib/3.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"apkzlib-3.5.3.pom": {
"sha1": "d41d21481aa9ea302638d5008d1c54e391981843",
"sha256": "sha256-unLu4SDrvKUNUxJUZlaH2INOewFTQfQfdi2GKoiPDrI="
},
"apkzlib-3.5.3.jar": {
"sha1": "8e17d7b8bb5f756c139619d86facca1675bc6164",
"sha256": "sha256-aNpGeSdH6yIHK7PygeptifcYAB6Mmaa75oYJM/73qdw="
}
}
},
{
"path": "com/android/tools/build/apkzlib/3.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -4766,21 +4616,6 @@
}
},
{
"path": "com/android/tools/build/builder-model/3.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"builder-model-3.5.3.pom": {
"sha1": "64d0223622a2c59fb67f8fb5c22b6535efef29b5",
"sha256": "sha256-8kaKB3hYve1NA/D8BkGjtpr5zskjdqqjht3XoSTIQQM="
},
"builder-model-3.5.3.jar": {
"sha1": "775377503072e1b6a701c3ea923c468cedd4e2eb",
"sha256": "sha256-U1xpawkp6LOZLwiCPpTFtci+UzCVThX8TuFhCW+gT6I="
}
}
},
{
"path": "com/android/tools/build/builder-model/3.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -4917,21 +4752,6 @@
}
},
{
"path": "com/android/tools/build/builder-test-api/3.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"builder-test-api-3.5.3.pom": {
"sha1": "f910b8864ae8e3e3c39823ca7ca6ba99a09d7564",
"sha256": "sha256-9IV0lJ6wAgzUWwuGES1aMXxpH+0OPxPYzY7VNbmksUI="
},
"builder-test-api-3.5.3.jar": {
"sha1": "cf9ce50cd19a816c5bc7d4c6362699aa98c8ac0f",
"sha256": "sha256-euZFcKEsjav85tiA+KSNsVqoMRHbcC2iTAWvv3H8FUc="
}
}
},
{
"path": "com/android/tools/build/builder-test-api/3.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -5068,21 +4888,6 @@
}
},
{
"path": "com/android/tools/build/builder/3.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"builder-3.5.3.pom": {
"sha1": "b327e842abd63da2281e74c59de69ab2b5998443",
"sha256": "sha256-dNWTs6MgZG6PVaytZxU/2aWQk8a3lqkGYmbXPzO99ZA="
},
"builder-3.5.3.jar": {
"sha1": "39bba1af533b25f6c1140e3c795ff815a6ad86ba",
"sha256": "sha256-BcvZGDubmg4SisvDkSVAwXLg11pcNY2kZcb3F5JMV0E="
}
}
},
{
"path": "com/android/tools/build/builder/3.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -5324,21 +5129,6 @@
}
},
{
"path": "com/android/tools/build/gradle-api/3.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"gradle-api-3.5.3.pom": {
"sha1": "ef22e3a71efd8cb517d4b039076f4b69013c0208",
"sha256": "sha256-1T+FRJWgpHkt+LVOWXFAdtk3HW9ah5AABwdUoYDS7kU="
},
"gradle-api-3.5.3.jar": {
"sha1": "c1d6a6b3e5b744caaf6eea2452d8db62c8e2882f",
"sha256": "sha256-yOi/eI7S+LRswAqWJOAKivQLwx/x2CmL10DxhAC9PS4="
}
}
},
{
"path": "com/android/tools/build/gradle-api/3.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -5509,21 +5299,6 @@
}
},
{
"path": "com/android/tools/build/gradle/3.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"gradle-3.5.3.pom": {
"sha1": "6bfb2b4c34c37c4f2addcb6d99db19fa7a1a5810",
"sha256": "sha256-k8NC3tdmWdVBdyaKn9lBLf4HLozxd26vtHxZCBmOZdI="
},
"gradle-3.5.3.jar": {
"sha1": "12e36e5f81cc2face28e0c14cb98941d773cae6a",
"sha256": "sha256-Zyk97dM5uJypz2xEAJvNj4Bb9CnCVYYuq/LeuBDYuRA="
}
}
},
{
"path": "com/android/tools/build/gradle/3.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -5788,21 +5563,6 @@
}
},
{
"path": "com/android/tools/build/manifest-merger/26.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"manifest-merger-26.5.3.pom": {
"sha1": "4cc40406dfe779b3b575e66c970ae0e9986b0c94",
"sha256": "sha256-ZjxoTo8jLgEYXLnqBwjqCRwxAhYiDHlQthqQZlX0Vj4="
},
"manifest-merger-26.5.3.jar": {
"sha1": "36674041b9d2644a30b75b6d8b7106bc16eac78a",
"sha256": "sha256-tGBtBgLyH5GhdM+4UWtabpj/rJWNPzzYmTuVDvSbgEk="
}
}
},
{
"path": "com/android/tools/build/manifest-merger/26.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -5939,21 +5699,6 @@
}
},
{
"path": "com/android/tools/common/26.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"common-26.5.3.pom": {
"sha1": "ace0f2945bba30c12223d7634a69da21a4242fd7",
"sha256": "sha256-9ikVDGRk14qviKUSEpiyeycF0HdW2W5hH6/yuJgdgeQ="
},
"common-26.5.3.jar": {
"sha1": "47409edcd2331596b42c33160101a86046e1c6f5",
"sha256": "sha256-YAVo9B+xn8eWSHtvxTnlKr0Jj60cZ4vONcAqMVGeJPY="
}
}
},
{
"path": "com/android/tools/common/26.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -6078,21 +5823,6 @@
}
},
{
"path": "com/android/tools/ddms/ddmlib/26.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"ddmlib-26.5.3.pom": {
"sha1": "f69c10111005d9ed625cc0b75fed9c5c2fcd1bcb",
"sha256": "sha256-y79URq2NFK1PQ/kl063FlIr3hP7NdEvk04bf50sXe1s="
},
"ddmlib-26.5.3.jar": {
"sha1": "804a61e67286eeec17d195c78a135f0ed2fbdb8a",
"sha256": "sha256-IlrK31Fopg4wIKM81mm6TYatse+ePnEhcREd4t+RrCs="
}
}
},
{
"path": "com/android/tools/ddms/ddmlib/26.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -6217,21 +5947,6 @@
}
},
{
"path": "com/android/tools/dvlib/26.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"dvlib-26.5.3.pom": {
"sha1": "1983f43ea2ef12519c4ac4579930af7494b4fb1c",
"sha256": "sha256-HNYT321rRp1fKslux7VIkAzONv7xDrPJAZVIITehh5c="
},
"dvlib-26.5.3.jar": {
"sha1": "9caa13fe83508ba5687199c02b7ddb885abd8f14",
"sha256": "sha256-+f3/TUDUJ1vhgAWJ2GlS33ErcQa7MD2o5f5zaqIogGU="
}
}
},
{
"path": "com/android/tools/dvlib/26.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -6431,21 +6146,6 @@
}
},
{
"path": "com/android/tools/layoutlib/layoutlib-api/26.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"layoutlib-api-26.5.3.pom": {
"sha1": "75263963e8b5baa185153cbdf1a5347628a71927",
"sha256": "sha256-Qs1kefYxk/LNrFGbBIi08IbYhToLabRA84yCWHE09eE="
},
"layoutlib-api-26.5.3.jar": {
"sha1": "6549e729f3f27c7d05049494f25cfd01890c00e0",
"sha256": "sha256-/7VaULd7u4vTgnr7gpGhRVzZU7EmBYzP3db/rvkwM9A="
}
}
},
{
"path": "com/android/tools/layoutlib/layoutlib-api/26.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -6615,21 +6315,6 @@
}
},
{
"path": "com/android/tools/lint/lint-gradle-api/26.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"lint-gradle-api-26.5.3.pom": {
"sha1": "ce7c04f4c18db0fe372667092500726dc1436b2b",
"sha256": "sha256-tD6Ht965r/ZdBmPvIpAUoOyV9OsgUpxwTbEXrkq7I00="
},
"lint-gradle-api-26.5.3.jar": {
"sha1": "34f6edb87863c7e9f89f24c36485374ad350166a",
"sha256": "sha256-+xQk+cpYS2WRw5znSR5tiXYAVx4XPPkogrqTQWPGDMQ="
}
}
},
{
"path": "com/android/tools/lint/lint-gradle-api/26.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -6874,21 +6559,6 @@
}
},
{
"path": "com/android/tools/repository/26.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"repository-26.5.3.pom": {
"sha1": "f8f4198066a0abb5dd28ddf7e7bbb9ce9c6df714",
"sha256": "sha256-1VAgYQtJuNTY+UgjN7nkcyAEjcxoEYb4tLuJAxaMxUE="
},
"repository-26.5.3.jar": {
"sha1": "91466e99a63da0267b17bdfb617f54582e311618",
"sha256": "sha256-X8tsUpwFkmiZtGzyUA46ChpjOV59RY6na8sHXKoF1Lg="
}
}
},
{
"path": "com/android/tools/repository/26.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -7013,21 +6683,6 @@
}
},
{
"path": "com/android/tools/sdklib/26.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"sdklib-26.5.3.pom": {
"sha1": "08fa943d8253d6301e2dd02bb953fe73bd1406f7",
"sha256": "sha256-UQ3bott3wc/Uw37/g/L25qPv4gXqt8Zkgu7QAUgtsTs="
},
"sdklib-26.5.3.jar": {
"sha1": "8c305bc044ad81115859eb964c2829cbea70b036",
"sha256": "sha256-H8X6i5qnJUBBwF5s8fPrqfR7BJH3p4ZDwhy+eylFHkI="
}
}
},
{
"path": "com/android/tools/sdklib/26.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -7152,21 +6807,6 @@
}
},
{
"path": "com/android/tools/sdk-common/26.5.3",
"repo": "https://dl.google.com/dl/android/maven2",
"files": {
"sdk-common-26.5.3.pom": {
"sha1": "3fda12d2fca4442d791813f7a73399ff5f6e1973",
"sha256": "sha256-RenED9V2i7mYpkVhbqjSVGv15o9fBkL34FpKhwZElZk="
},
"sdk-common-26.5.3.jar": {
"sha1": "cce8ff081940bb7c9b1368a4052f987091996887",
"sha256": "sha256-kDfQjhoo5b8rEzc6Dyo/hxRsRG/gkYeNNOtvHxyIBgk="
}
}
},
{
"path": "com/android/tools/sdk-common/26.5.4",
"repo": "https://dl.google.com/dl/android/maven2",
@@ -8401,16 +8041,16 @@
},
{
"path": "commons-io/commons-io/2.16.1",
"path": "commons-io/commons-io/2.16.0",
"repo": "https://repo.maven.apache.org/maven2",
"files": {
"commons-io-2.16.1.pom": {
"sha1": "553d6f69e338060a231755afe0ebf99d14b45da6",
"sha256": "sha256-V3fSkiUceJXASkxXAVaD7Ds1OhJIbJs+cXjpsLPDj/8="
"commons-io-2.16.0.pom": {
"sha1": "22e76fdc24c77e80b362d1f060a3cc073de3f0a9",
"sha256": "sha256-9EvmklZbB2a+vlkKSwQdm12rJP7QtGqs7niXBCiISlY="
},
"commons-io-2.16.1.jar": {
"sha1": "377d592e740dc77124e0901291dbfaa6810a200e",
"sha256": "sha256-9B97qs1xaJZEes6XWGIfYsHGsKkdiazuSI2ib8R3yE8="
"commons-io-2.16.0.jar": {
"sha1": "27875a7935f1ddcc13267eb6fae1f719e0409572",
"sha256": "sha256-0eQXkBI1+uOqDLlza66vW3Tec0mBfRxyOQ2C49g9Opc="
}
}
},
@@ -12238,12 +11878,12 @@
},
{
"path": "com/google/protobuf/protobuf-bom/4.27.0-RC1",
"path": "com/google/protobuf/protobuf-bom/4.26.1",
"repo": "https://repo.maven.apache.org/maven2",
"files": {
"protobuf-bom-4.27.0-RC1.pom": {
"sha1": "27a037f37e7e95b5e28ec5cd410ed99d34eb0a29",
"sha256": "sha256-ilnU8jEpEPRz7kIC0n8QQBt1nSyGY6xr/dQP299Bfy4="
"protobuf-bom-4.26.1.pom": {
"sha1": "7c6506f4a6d11e3aa7c3591c494433926eb4fefa",
"sha256": "sha256-hmAoc/EHNFQ9kMB/D/e/3+OXSeHCViGEwMiQmpJqbaw="
}
}
},
@@ -12489,16 +12129,16 @@
},
{
"path": "com/google/protobuf/protobuf-java/4.27.0-RC1",
"path": "com/google/protobuf/protobuf-java/4.26.1",
"repo": "https://repo.maven.apache.org/maven2",
"files": {
"protobuf-java-4.27.0-RC1.pom": {
"sha1": "8c2f747548d2fafc3e9b057cee34c343dc47e78e",
"sha256": "sha256-n9A6OYpEYg/F4Um5bKFXFb/1zQkxiNk7nGaSmmj087w="
"protobuf-java-4.26.1.pom": {
"sha1": "5d394cabfc69ca65c22694fabcc074f324a7af43",
"sha256": "sha256-Gqr40NPAcUMZpemmtrMDxw4PYHa3t0vTvz/bh133mXE="
},
"protobuf-java-4.27.0-RC1.jar": {
"sha1": "f37d7fb8ab06eee5ae3dd11c121f63a8b209e74f",
"sha256": "sha256-MW6bDi8Ee6d42j4PgT+0lqqzysiu/qRTRiIAi2bAcyk="
"protobuf-java-4.26.1.jar": {
"sha1": "594fabdcbceb7edfb883fe621d3e97d9cc05fa73",
"sha256": "sha256-CRkz5YcK+BB0gyb3rOSmc6ynISUxd1QoQvBEtUbxQoI="
}
}
},
@@ -12618,12 +12258,12 @@
},
{
"path": "com/google/protobuf/protobuf-parent/4.27.0-RC1",
"path": "com/google/protobuf/protobuf-parent/4.26.1",
"repo": "https://repo.maven.apache.org/maven2",
"files": {
"protobuf-parent-4.27.0-RC1.pom": {
"sha1": "59b00c8642d1166a189ebdcc529d3de170c8c56c",
"sha256": "sha256-mdkAVgkc3DOMTzc5ghqX3ICl1+ajWVFVWdw//1f73+E="
"protobuf-parent-4.26.1.pom": {
"sha1": "cc071c128d5a376a30a2ecf145127532e7a17bae",
"sha256": "sha256-rMorllL7bwEHXmdbfDShbtGZIVlUb651lvKZ2HYnbY0="
}
}
},
@@ -15945,17 +15585,6 @@
}
},
{
"path": "org/apache/commons/commons-parent/69",
"repo": "https://repo.maven.apache.org/maven2",
"files": {
"commons-parent-69.pom": {
"sha1": "6ebeacd37818d945d96c06b44af10e050d2ef7c4",
"sha256": "sha256-1Q2pw5vcqCPWGNG0oDtz8ZZJf8uGFv0NpyfIYjWSqbs="
}
}
},
{
"path": "org/apache/httpcomponents/httpclient/4.1.1",
"repo": "https://repo.maven.apache.org/maven2",
@@ -17512,12 +17141,12 @@
},
{
"path": "org/jacoco/org.jacoco.build/0.8.12",
"path": "org/jacoco/org.jacoco.build/0.8.11",
"repo": "https://repo.maven.apache.org/maven2",
"files": {
"org.jacoco.build-0.8.12.pom": {
"sha1": "ae9ec17957c52ffa34ec82bb59bc0a2b9b3554c0",
"sha256": "sha256-JQ3MmhAD6CCVkz9khpI3dS825wy4pj8s35mwyWE8Cbk="
"org.jacoco.build-0.8.11.pom": {
"sha1": "e5a356ca72993fc163a454402a55c2043071d350",
"sha256": "sha256-W4SxXPLu8+WeuRvCJ4SDMQCwnfmRHjMZAww7xki9iws="
}
}
},
@@ -17538,16 +17167,16 @@
},
{
"path": "org/jacoco/org.jacoco.core/0.8.12",
"path": "org/jacoco/org.jacoco.core/0.8.11",
"repo": "https://repo.maven.apache.org/maven2",
"files": {
"org.jacoco.core-0.8.12.pom": {
"sha1": "bc76db6af48fc259f0c66ac8b6d9ce2dd73ea77b",
"sha256": "sha256-qgsnc3hohtUdGI1+0aQ/Z276ISeFIERb/vDMtdjL5xc="
"org.jacoco.core-0.8.11.pom": {
"sha1": "e1aa8f9270a5fcc432cf0c185c871b3e4820f5e9",
"sha256": "sha256-u2E18Qo2NJy4SlYA/Yz3P8EpahNbLxStzYPejPJMq7E="
},
"org.jacoco.core-0.8.12.jar": {
"sha1": "c2a45bd054bbacfe9998cbbf1a49010c62e48cbc",
"sha256": "sha256-/KJts3wMX71dxJhSN+uChm35eZ1Qgq+JlHWnP5H1sDU="
"org.jacoco.core-0.8.11.jar": {
"sha1": "2ea73c899b5d6cde2a0a5e0ca29268b37622845d",
"sha256": "sha256-/NGIxohHP8jcwMbKrzVeeziVAiQ1J8M7lZej7Ch5H0c="
}
}
},
@@ -19238,16 +18867,16 @@
},
{
"path": "org/jetbrains/kotlin/kotlin-reflect/2.0.0-RC1",
"path": "org/jetbrains/kotlin/kotlin-reflect/2.0.0-Beta5",
"repo": "https://repo.maven.apache.org/maven2",
"files": {
"kotlin-reflect-2.0.0-RC1.pom": {
"sha1": "b08c97cfaffcdf60a6db35b13def6cde1aed6d31",
"sha256": "sha256-9NoPwtEYJp0xCTkijwRiV3ri4UFEdh0PojqTWH/nvpI="
"kotlin-reflect-2.0.0-Beta5.pom": {
"sha1": "dd7f7eb5dfa88db62699bcd48d1b6e1ef4ff48fc",
"sha256": "sha256-vZDJOB++CfFO6xpEb8Z+gk4Geh4UEr6WVoNRB4hcpxQ="
},
"kotlin-reflect-2.0.0-RC1.jar": {
"sha1": "3d4ec6ec94e86fd10957c78471f98373e899dd2e",
"sha256": "sha256-BsavyQLOwArroQNLg97ck3PaB6kJBpyLZDwq+mAvW5w="
"kotlin-reflect-2.0.0-Beta5.jar": {
"sha1": "ecb1578f5e5a1fa0cec6f4e926ced14989724274",
"sha256": "sha256-4xzU/UOloKuez/MUVapHwTl9ZzvkJ8FjkqxNQBf+BOo="
}
}
},
@@ -20780,28 +20409,28 @@
},
{
"path": "org/jetbrains/kotlin/kotlin-stdlib/2.0.0-RC1",
"path": "org/jetbrains/kotlin/kotlin-stdlib/2.0.0-Beta5",
"repo": "https://repo.maven.apache.org/maven2",
"files": {
"kotlin-stdlib-2.0.0-RC1.pom": {
"sha1": "acf44b7e30e2500a0e1fed7bfc0c9bc6cc8fe65e",
"sha256": "sha256-nVnonn+ye/SexoelpxZXCz8srOtUH95WNwKKAPXf86I="
"kotlin-stdlib-2.0.0-Beta5.pom": {
"sha1": "cfb0a9c66ddf657aac640d1a38169eb12de0f557",
"sha256": "sha256-NAO5vBthXEMJKGzn8eQ6teYhT5Brf53uG5G90li4pNk="
},
"kotlin-stdlib-2.0.0-RC1-all.jar": {
"sha1": "496ce100c4aa6dabf67dc1c0443076f42197a535",
"sha256": "sha256-aiXa9C5VAsj0YGF053MUD2Olq3z1Vj9CD849pASBoIo="
"kotlin-stdlib-2.0.0-Beta5-all.jar": {
"sha1": "e18c835dd9fe6430f006ef2060595f3e5c0473bf",
"sha256": "sha256-o+o5Diku/+bWDD4IQjottN68NiB4sQvtHmE7qy7ru3U="
},
"kotlin-stdlib-2.0.0-RC1-common.jar": {
"kotlin-stdlib-2.0.0-Beta5-common.jar": {
"sha1": "281e03983850e590dcc0d2474758f2fa8dd0e96a",
"sha256": "sha256-EsHDu0lApPmVlUD/tc8uLl6brNtoywDEvSidFjm9HSc="
},
"kotlin-stdlib-2.0.0-RC1.jar": {
"sha1": "ad47aa314788daa709fe419d843fccc28a6c6edf",
"sha256": "sha256-u7LJuBPmGW+a+p+a3Ys5XuOEqxdjoIgOCE0pQiFPHDA="
"kotlin-stdlib-2.0.0-Beta5.jar": {
"sha1": "763714203113a7f4a5477122be0c6c588df0116e",
"sha256": "sha256-vJdkbUp8fwtJ6An+ZapdbGVNWfM3rQziphgPVxdpfWk="
},
"kotlin-stdlib-2.0.0-RC1.module": {
"sha1": "d59c1362007ed529e61cabb999c5fba72ce232d2",
"sha256": "sha256-NZ7bRyR/SM+y/HVTWPsjAXt0sN1GUsynslWbvCKMu30="
"kotlin-stdlib-2.0.0-Beta5.module": {
"sha1": "e4e16c1cf436d27d4d80cd504e636feaffbc376a",
"sha256": "sha256-ZBntY3Vrx0lM5sR2jdkZhsSPB1ZTdTOSi5uggHroWjk="
}
}
},
+25 -26
View File
@@ -53,14 +53,14 @@ androidx.core:core:1.9.0
androidx.cursoradapter:cursoradapter:1.0.0
androidx.customview:customview:1.0.0
androidx.databinding:databinding-common:3.2.1
androidx.databinding:databinding-common:3.5.3
androidx.databinding:databinding-common:3.5.4
androidx.databinding:databinding-common:4.1.0
androidx.databinding:databinding-common:7.0.4
androidx.databinding:databinding-common:7.2.1
androidx.databinding:databinding-common:7.3.1
androidx.databinding:databinding-common:8.1.1
androidx.databinding:databinding-compiler-common:3.2.1
androidx.databinding:databinding-compiler-common:3.5.3
androidx.databinding:databinding-compiler-common:3.5.4
androidx.databinding:databinding-compiler-common:4.1.0
androidx.databinding:databinding-compiler-common:7.0.4
androidx.databinding:databinding-compiler-common:7.2.1
@@ -164,7 +164,7 @@ com.almworks.sqlite4java:sqlite4java:1.0.392
com.android.databinding:baseLibrary:1.0-rc5
com.android.databinding:baseLibrary:3.0.1
com.android.databinding:baseLibrary:3.2.1
com.android.databinding:baseLibrary:3.5.3
com.android.databinding:baseLibrary:3.5.4
com.android.databinding:baseLibrary:4.1.0
com.android.databinding:baseLibrary:7.0.4
com.android.databinding:baseLibrary:7.2.1
@@ -173,7 +173,7 @@ com.android.databinding:baseLibrary:8.1.1
com.android.databinding:compilerCommon:1.0-rc5
com.android.databinding:compilerCommon:3.0.1
com.android.tools.analytics-library:crash:26.2.1
com.android.tools.analytics-library:crash:26.5.3
com.android.tools.analytics-library:crash:26.5.4
com.android.tools.analytics-library:crash:27.1.0
com.android.tools.analytics-library:crash:30.0.4
com.android.tools.analytics-library:crash:30.2.1
@@ -181,7 +181,7 @@ 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.1
com.android.tools.analytics-library:protos:26.2.1
com.android.tools.analytics-library:protos:26.5.3
com.android.tools.analytics-library:protos:26.5.4
com.android.tools.analytics-library:protos:27.1.0
com.android.tools.analytics-library:protos:30.0.4
com.android.tools.analytics-library:protos:30.2.1
@@ -189,7 +189,7 @@ 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.1
com.android.tools.analytics-library:shared:26.2.1
com.android.tools.analytics-library:shared:26.5.3
com.android.tools.analytics-library:shared:26.5.4
com.android.tools.analytics-library:shared:27.1.0
com.android.tools.analytics-library:shared:30.0.4
com.android.tools.analytics-library:shared:30.2.1
@@ -197,7 +197,7 @@ 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.1
com.android.tools.analytics-library:tracker:26.2.1
com.android.tools.analytics-library:tracker:26.5.3
com.android.tools.analytics-library:tracker:26.5.4
com.android.tools.analytics-library:tracker:27.1.0
com.android.tools.analytics-library:tracker:30.0.4
com.android.tools.analytics-library:tracker:30.2.1
@@ -226,14 +226,14 @@ com.android.tools.build:aaptcompiler:7.3.1
com.android.tools.build:aaptcompiler:8.1.1
com.android.tools.build:apksig:3.0.1
com.android.tools.build:apksig:3.2.1
com.android.tools.build:apksig:3.5.3
com.android.tools.build:apksig:3.5.4
com.android.tools.build:apksig:4.1.0
com.android.tools.build:apksig:7.0.4
com.android.tools.build:apksig:7.2.1
com.android.tools.build:apksig:7.3.1
com.android.tools.build:apksig:8.1.1
com.android.tools.build:apkzlib:3.2.1
com.android.tools.build:apkzlib:3.5.3
com.android.tools.build:apkzlib:3.5.4
com.android.tools.build:apkzlib:4.1.0
com.android.tools.build:apkzlib:7.0.4
com.android.tools.build:apkzlib:7.2.1
@@ -243,7 +243,7 @@ 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.1
com.android.tools.build:builder-model:3.2.1
com.android.tools.build:builder-model:3.5.3
com.android.tools.build:builder-model:3.5.4
com.android.tools.build:builder-model:4.1.0
com.android.tools.build:builder-model:7.0.4
com.android.tools.build:builder-model:7.2.1
@@ -253,7 +253,7 @@ 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.1
com.android.tools.build:builder-test-api:3.2.1
com.android.tools.build:builder-test-api:3.5.3
com.android.tools.build:builder-test-api:3.5.4
com.android.tools.build:builder-test-api:4.1.0
com.android.tools.build:builder-test-api:7.0.4
com.android.tools.build:builder-test-api:7.2.1
@@ -263,7 +263,7 @@ com.android.tools.build:builder:1.3.1
com.android.tools.build:builder:1.5.0
com.android.tools.build:builder:3.0.1
com.android.tools.build:builder:3.2.1
com.android.tools.build:builder:3.5.3
com.android.tools.build:builder:3.5.4
com.android.tools.build:builder:4.1.0
com.android.tools.build:builder:7.0.4
com.android.tools.build:builder:7.2.1
@@ -278,7 +278,7 @@ com.android.tools.build:bundletool:1.9.0
com.android.tools.build:bundletool:1.14.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.3
com.android.tools.build:gradle-api:3.5.4
com.android.tools.build:gradle-api:4.1.0
com.android.tools.build:gradle-api:7.0.4
com.android.tools.build:gradle-api:7.2.1
@@ -292,7 +292,7 @@ com.android.tools.build:gradle:1.3.1
com.android.tools.build:gradle:1.5.0
com.android.tools.build:gradle:3.0.1
com.android.tools.build:gradle:3.2.1
com.android.tools.build:gradle:3.5.3
com.android.tools.build:gradle:3.5.4
com.android.tools.build:gradle:4.1.0
com.android.tools.build:gradle:7.0.4
com.android.tools.build:gradle:7.2.1
@@ -301,7 +301,7 @@ 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.1
com.android.tools.build:manifest-merger:26.2.1
com.android.tools.build:manifest-merger:26.5.3
com.android.tools.build:manifest-merger:26.5.4
com.android.tools.build:manifest-merger:27.1.0
com.android.tools.build:manifest-merger:30.0.4
com.android.tools.build:manifest-merger:30.2.1
@@ -313,7 +313,7 @@ com.android.tools.ddms:ddmlib:24.3.1
com.android.tools.ddms:ddmlib:24.5.0
com.android.tools.ddms:ddmlib:26.0.1
com.android.tools.ddms:ddmlib:26.2.1
com.android.tools.ddms:ddmlib:26.5.3
com.android.tools.ddms:ddmlib:26.5.4
com.android.tools.ddms:ddmlib:27.1.0
com.android.tools.ddms:ddmlib:30.0.4
com.android.tools.ddms:ddmlib:30.2.1
@@ -328,7 +328,7 @@ 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.1
com.android.tools.layoutlib:layoutlib-api:26.2.1
com.android.tools.layoutlib:layoutlib-api:26.5.3
com.android.tools.layoutlib:layoutlib-api:26.5.4
com.android.tools.layoutlib:layoutlib-api:27.1.0
com.android.tools.layoutlib:layoutlib-api:30.0.4
com.android.tools.layoutlib:layoutlib-api:30.2.1
@@ -341,7 +341,7 @@ 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.1
com.android.tools.lint:lint-gradle-api:26.2.1
com.android.tools.lint:lint-gradle-api:26.5.3
com.android.tools.lint:lint-gradle-api:26.5.4
com.android.tools.lint:lint-gradle-api:27.1.0
com.android.tools.lint:lint-model:27.1.0
com.android.tools.lint:lint-model:30.0.4
@@ -382,7 +382,7 @@ com.android.tools:annotations:24.3.1
com.android.tools:annotations:24.5.0
com.android.tools:annotations:26.0.1
com.android.tools:annotations:26.2.1
com.android.tools:annotations:26.5.3
com.android.tools:annotations:26.5.4
com.android.tools:annotations:27.1.0
com.android.tools:annotations:30.0.4
com.android.tools:annotations:30.2.1
@@ -392,7 +392,7 @@ com.android.tools:common:24.3.1
com.android.tools:common:24.5.0
com.android.tools:common:26.0.1
com.android.tools:common:26.2.1
com.android.tools:common:26.5.3
com.android.tools:common:26.5.4
com.android.tools:common:27.1.0
com.android.tools:common:30.0.4
com.android.tools:common:30.2.1
@@ -402,7 +402,7 @@ com.android.tools:dvlib:24.3.1
com.android.tools:dvlib:24.5.0
com.android.tools:dvlib:26.0.1
com.android.tools:dvlib:26.2.1
com.android.tools:dvlib:26.5.3
com.android.tools:dvlib:26.5.4
com.android.tools:dvlib:27.1.0
com.android.tools:dvlib:30.0.4
com.android.tools:dvlib:30.2.1
@@ -410,7 +410,7 @@ com.android.tools:dvlib:30.3.1
com.android.tools:dvlib:31.1.1
com.android.tools:repository:26.0.1
com.android.tools:repository:26.2.1
com.android.tools:repository:26.5.3
com.android.tools:repository:26.5.4
com.android.tools:repository:27.1.0
com.android.tools:repository:30.0.4
com.android.tools:repository:30.2.1
@@ -420,7 +420,7 @@ com.android.tools:sdklib:24.3.1
com.android.tools:sdklib:24.5.0
com.android.tools:sdklib:26.0.1
com.android.tools:sdklib:26.2.1
com.android.tools:sdklib:26.5.3
com.android.tools:sdklib:26.5.4
com.android.tools:sdklib:27.1.0
com.android.tools:sdklib:30.0.4
com.android.tools:sdklib:30.2.1
@@ -430,7 +430,7 @@ com.android.tools:sdk-common:24.3.1
com.android.tools:sdk-common:24.5.0
com.android.tools:sdk-common:26.0.1
com.android.tools:sdk-common:26.2.1
com.android.tools:sdk-common:26.5.3
com.android.tools:sdk-common:26.5.4
com.android.tools:sdk-common:27.1.0
com.android.tools:sdk-common:30.0.4
com.android.tools:sdk-common:30.2.1
@@ -942,5 +942,4 @@ org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:1.8.0
com.android.tools.build:gradle:8.1.1
com.google.errorprone:error_prone_annotations:2.7.1
com.android.tools.lint:lint-gradle:31.1.1
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0
com.android.tools.build:gradle:3.5.4
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0
+8 -33
View File
@@ -68,7 +68,6 @@ https://dl.google.com/dl/android/maven2/androidx/core/core/1.9.0/core-1.9.0.pom
https://dl.google.com/dl/android/maven2/androidx/cursoradapter/cursoradapter/1.0.0/cursoradapter-1.0.0.pom
https://dl.google.com/dl/android/maven2/androidx/customview/customview/1.0.0/customview-1.0.0.pom
https://dl.google.com/dl/android/maven2/androidx/databinding/databinding-common/3.2.1/databinding-common-3.2.1.pom
https://dl.google.com/dl/android/maven2/androidx/databinding/databinding-common/3.5.3/databinding-common-3.5.3.pom
https://dl.google.com/dl/android/maven2/androidx/databinding/databinding-common/3.5.4/databinding-common-3.5.4.pom
https://dl.google.com/dl/android/maven2/androidx/databinding/databinding-common/4.1.0/databinding-common-4.1.0.pom
https://dl.google.com/dl/android/maven2/androidx/databinding/databinding-common/7.0.4/databinding-common-7.0.4.pom
@@ -76,7 +75,6 @@ https://dl.google.com/dl/android/maven2/androidx/databinding/databinding-common/
https://dl.google.com/dl/android/maven2/androidx/databinding/databinding-common/7.3.1/databinding-common-7.3.1.pom
https://dl.google.com/dl/android/maven2/androidx/databinding/databinding-common/8.1.1/databinding-common-8.1.1.pom
https://dl.google.com/dl/android/maven2/androidx/databinding/databinding-compiler-common/3.2.1/databinding-compiler-common-3.2.1.pom
https://dl.google.com/dl/android/maven2/androidx/databinding/databinding-compiler-common/3.5.3/databinding-compiler-common-3.5.3.pom
https://dl.google.com/dl/android/maven2/androidx/databinding/databinding-compiler-common/3.5.4/databinding-compiler-common-3.5.4.pom
https://dl.google.com/dl/android/maven2/androidx/databinding/databinding-compiler-common/4.1.0/databinding-compiler-common-4.1.0.pom
https://dl.google.com/dl/android/maven2/androidx/databinding/databinding-compiler-common/7.0.4/databinding-compiler-common-7.0.4.pom
@@ -183,7 +181,6 @@ https://dl.google.com/dl/android/maven2/android/arch/lifecycle/common/1.0.0/comm
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.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.3/baseLibrary-3.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/databinding/baseLibrary/3.5.4/baseLibrary-3.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/databinding/baseLibrary/4.1.0/baseLibrary-4.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/databinding/baseLibrary/7.0.4/baseLibrary-7.0.4.pom
@@ -217,7 +214,6 @@ https://dl.google.com/dl/android/maven2/com/android/support/support-v4/26.0.2/su
https://dl.google.com/dl/android/maven2/com/android/support/support-vector-drawable/26.0.2/support-vector-drawable-26.0.2.pom
https://dl.google.com/dl/android/maven2/com/android/support/support-vector-drawable/27.0.1/support-vector-drawable-27.0.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/crash/26.2.1/crash-26.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/crash/26.5.3/crash-26.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/crash/26.5.4/crash-26.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/crash/27.1.0/crash-27.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/crash/30.0.4/crash-30.0.4.pom
@@ -226,7 +222,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/31.1.1/crash-31.1.1.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.3/protos-26.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/protos/26.5.4/protos-26.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/protos/27.1.0/protos-27.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/protos/30.0.4/protos-30.0.4.pom
@@ -235,7 +230,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/31.1.1/protos-31.1.1.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.3/shared-26.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/shared/26.5.4/shared-26.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/shared/27.1.0/shared-27.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/shared/30.0.4/shared-30.0.4.pom
@@ -244,7 +238,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/31.1.1/shared-31.1.1.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.3/tracker-26.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/tracker/26.5.4/tracker-26.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/tracker/27.1.0/tracker-27.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/analytics-library/tracker/30.0.4/tracker-30.0.4.pom
@@ -253,7 +246,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/31.1.1/tracker-31.1.1.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.3/annotations-26.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/tools/annotations/26.5.4/annotations-26.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/tools/annotations/27.1.0/annotations-27.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/annotations/30.0.4/annotations-30.0.4.pom
@@ -278,7 +270,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/build/aaptcompiler/7.3
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.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.3/apksig-3.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/apksig/3.5.4/apksig-3.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/apksig/4.1.0/apksig-4.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/apksig/7.0.4/apksig-7.0.4.pom
@@ -286,7 +277,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/build/apksig/7.2.1/apk
https://dl.google.com/dl/android/maven2/com/android/tools/build/apksig/7.3.1/apksig-7.3.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/apksig/8.1.1/apksig-8.1.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/apkzlib/3.2.1/apkzlib-3.2.1.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/apkzlib/3.5.3/apkzlib-3.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/apkzlib/3.5.4/apkzlib-3.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/apkzlib/4.1.0/apkzlib-4.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/apkzlib/7.0.4/apkzlib-7.0.4.pom
@@ -295,7 +285,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/build/apkzlib/7.3.1/ap
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.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.3/builder-model-3.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-model/3.5.4/builder-model-3.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-model/4.1.0/builder-model-4.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-model/7.0.4/builder-model-7.0.4.pom
@@ -304,7 +293,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/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.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.3/builder-test-api-3.5.3.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
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-test-api/4.1.0/builder-test-api-4.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder-test-api/7.0.4/builder-test-api-7.0.4.pom
@@ -313,7 +301,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/8.1.1/builder-test-api-8.1.1.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.3/builder-3.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder/3.5.4/builder-3.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder/4.1.0/builder-4.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/builder/7.0.4/builder-7.0.4.pom
@@ -329,7 +316,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/build/bundletool/1.9.0
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.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.3/gradle-api-3.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle-api/3.5.4/gradle-api-3.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle-api/4.1.0/gradle-api-4.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle-api/7.0.4/gradle-api-7.0.4.pom
@@ -340,7 +326,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle-core/3.0.
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.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.3/gradle-3.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle/3.5.4/gradle-3.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle/4.1.0/gradle-4.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle/7.0.4/gradle-7.0.4.pom
@@ -357,7 +342,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-beta10/jetifier-processor-1.0.0-beta10.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.3/manifest-merger-26.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/manifest-merger/26.5.4/manifest-merger-26.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/manifest-merger/27.1.0/manifest-merger-27.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/build/manifest-merger/30.0.4/manifest-merger-30.0.4.pom
@@ -366,7 +350,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/31.1.1/manifest-merger-31.1.1.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.3/common-26.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/tools/common/26.5.4/common-26.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/tools/common/27.1.0/common-27.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/common/30.0.4/common-30.0.4.pom
@@ -375,7 +358,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/common/30.3.1/common-3
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.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.3/ddmlib-26.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/tools/ddms/ddmlib/26.5.4/ddmlib-26.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/tools/ddms/ddmlib/27.1.0/ddmlib-27.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/ddms/ddmlib/30.0.4/ddmlib-30.0.4.pom
@@ -384,7 +366,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/ddms/ddmlib/30.3.1/ddm
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.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.3/dvlib-26.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/tools/dvlib/26.5.4/dvlib-26.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/tools/dvlib/27.1.0/dvlib-27.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/dvlib/30.0.4/dvlib-30.0.4.pom
@@ -398,7 +379,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/external/org-jetbrains
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.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.3/layoutlib-api-26.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/tools/layoutlib/layoutlib-api/26.5.4/layoutlib-api-26.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/tools/layoutlib/layoutlib-api/27.1.0/layoutlib-api-27.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/layoutlib/layoutlib-api/30.0.4/layoutlib-api-30.0.4.pom
@@ -410,7 +390,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint-api/31.1.1/l
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
https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint-gradle-api/26.5.3/lint-gradle-api-26.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint-gradle-api/26.5.4/lint-gradle-api-26.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint-gradle-api/27.1.0/lint-gradle-api-27.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint-gradle/31.1.1/lint-gradle-31.1.1.pom
@@ -427,7 +406,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/lint/lint/31.1.1/lint-
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.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.3/repository-26.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/tools/repository/26.5.4/repository-26.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/tools/repository/27.1.0/repository-27.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/repository/30.0.4/repository-30.0.4.pom
@@ -436,7 +414,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/repository/30.3.1/repo
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.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.3/sdklib-26.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/tools/sdklib/26.5.4/sdklib-26.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/tools/sdklib/27.1.0/sdklib-27.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/sdklib/30.0.4/sdklib-30.0.4.pom
@@ -445,7 +422,6 @@ https://dl.google.com/dl/android/maven2/com/android/tools/sdklib/30.3.1/sdklib-3
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.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.3/sdk-common-26.5.3.pom
https://dl.google.com/dl/android/maven2/com/android/tools/sdk-common/26.5.4/sdk-common-26.5.4.pom
https://dl.google.com/dl/android/maven2/com/android/tools/sdk-common/27.1.0/sdk-common-27.1.0.pom
https://dl.google.com/dl/android/maven2/com/android/tools/sdk-common/30.0.4/sdk-common-30.0.4.pom
@@ -525,7 +501,7 @@ 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.16.1/commons-io-2.16.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.1/commons-logging-1.3.1.pom
@@ -768,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.27.0-RC1/protobuf-bom-4.27.0-RC1.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
@@ -785,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.27.0-RC1/protobuf-java-4.27.0-RC1.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
@@ -796,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.27.0-RC1/protobuf-parent-4.27.0-RC1.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
@@ -1036,7 +1012,6 @@ https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/48/common
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/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/commons/commons-parent/69/commons-parent-69.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
@@ -1150,9 +1125,9 @@ https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-core/2.2/hamcrest-cor
https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-parent/1.3/hamcrest-parent-1.3.pom
https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest/2.2/hamcrest-2.2.pom
https://repo.maven.apache.org/maven2/org/jacoco/org.jacoco.build/0.7.4.201502262128/org.jacoco.build-0.7.4.201502262128.pom
https://repo.maven.apache.org/maven2/org/jacoco/org.jacoco.build/0.8.12/org.jacoco.build-0.8.12.pom
https://repo.maven.apache.org/maven2/org/jacoco/org.jacoco.build/0.8.11/org.jacoco.build-0.8.11.pom
https://repo.maven.apache.org/maven2/org/jacoco/org.jacoco.core/0.7.4.201502262128/org.jacoco.core-0.7.4.201502262128.pom
https://repo.maven.apache.org/maven2/org/jacoco/org.jacoco.core/0.8.12/org.jacoco.core-0.8.12.pom
https://repo.maven.apache.org/maven2/org/jacoco/org.jacoco.core/0.8.11/org.jacoco.core-0.8.11.pom
https://repo.maven.apache.org/maven2/org/jacoco/org.jacoco.report/0.7.4.201502262128/org.jacoco.report-0.7.4.201502262128.pom
https://repo.maven.apache.org/maven2/org/jdom/jdom2/2.0.6/jdom2-2.0.6.pom
https://repo.maven.apache.org/maven2/org/jetbrains/annotations/13.0/annotations-13.0.pom
@@ -1248,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-RC1/kotlin-reflect-2.0.0-RC1.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
@@ -1350,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-RC1/kotlin-stdlib-2.0.0-RC1.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
+1 -2
View File
@@ -54,8 +54,7 @@ org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:1.8.0
com.android.tools.build:gradle:8.1.1
com.google.errorprone:error_prone_annotations:2.7.1
com.android.tools.lint:lint-gradle:31.1.1
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0
com.android.tools.build:gradle:3.5.4' \
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0' \
>> "${DEPS_LIST}"
}
+1
View File
@@ -22,6 +22,7 @@ react-native-image-resizer
react-native-keychain
react-native-linear-gradient
react-native-lottie-splash-screen
react-native-mail
react-native-navigation
react-native-nfc-manager
react-native-orientation-locker
+3 -3
View File
@@ -60,10 +60,10 @@ in {
version = "15.0";
allowHigher = true;
};
go = super.go_1_20;
go = super.go_1_19;
clang = super.clang_15;
buildGoPackage = super.buildGo120Package;
buildGoModule = super.buildGo120Module;
buildGoPackage = super.buildGo119Package;
buildGoModule = super.buildGo119Module;
gomobile = (super.gomobile.overrideAttrs (old: {
patches = [
(self.fetchurl { # https://github.com/golang/mobile/pull/84
-1
View File
@@ -27,7 +27,6 @@ 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";;
+5 -3
View File
@@ -9,10 +9,10 @@
},
"dependencies": {
"@react-native-async-storage/async-storage": "1.19.3",
"@react-native-camera-roll/camera-roll": "7.5.2",
"@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",
"@react-native-community/audio-toolkit": "git+https://github.com/tbenr/react-native-audio-toolkit.git#refs/tags/v2.0.3-status-v6",
"@react-native-community/blur": "4.4.0",
"@react-native-community/blur": "git+https://github.com/status-im/react-native-blur.git#refs/tags/v4.3.3-status",
"@react-native-community/hooks": "^3.0.0",
"@react-native-community/masked-view": "^0.1.6",
"@react-native-community/netinfo": "^4.4.0",
@@ -48,9 +48,10 @@
"react-native-keychain": "8.1.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": "4.1.5",
"react-native-permissions": "3.8.0",
"react-native-reanimated": "3.6.1",
"react-native-redash": "18.1.0",
"react-native-shadow-2": "^7.0.8",
@@ -93,6 +94,7 @@
"prettier": "^2.8.8",
"process": "0.11.10",
"react-test-renderer": "18.1.0",
"rn-snoopy": "git+https://github.com/status-im/rn-snoopy.git#refs/tags/v2.0.2-status",
"shadow-cljs": "2.26.2"
},
"binary": {
-11
View File
@@ -1,11 +0,0 @@
--- /tmp/tmp-status-mobile-851dbcb56/tmp.gcyqIAUEIA/build.gradle 2024-04-16 18:11:12.481819000 +0200
+++ ./node_modules/@react-native-community/blur/android/build.gradle 2024-04-16 18:11:18.889991702 +0200
@@ -5,7 +5,7 @@
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.5.3'
+ classpath 'com.android.tools.build:gradle:3.5.4'
}
}
-10
View File
@@ -1,10 +0,0 @@
--- /tmp/tmp-status-mobile-61974dae4/tmp.6k5ZPUa0Hp/BlurView.ios.tsx 2024-04-16 17:07:33.229847000 +0200
+++ ./node_modules/@react-native-community/blur/src/components/BlurView.ios.tsx 2024-04-16 17:07:58.540617624 +0200
@@ -6,6 +6,7 @@
| 'dark'
| 'light'
| 'xlight'
+ | 'transparent'
| 'prominent'
| 'regular'
| 'extraDark'
-57
View File
@@ -1,57 +0,0 @@
--- /tmp/tmp-status-mobile-851dbcb56/tmp.beqWjtcNwi/BlurView.mm 2024-04-16 17:55:00.688450000 +0200
+++ ./node_modules/@react-native-community/blur/ios/BlurView.mm 2024-04-16 17:56:17.772952042 +0200
@@ -73,7 +73,7 @@
{
const auto &oldViewProps = *std::static_pointer_cast<const BlurViewProps>(_props);
const auto &newViewProps = *std::static_pointer_cast<const BlurViewProps>(props);
-
+
if (oldViewProps.blurAmount != newViewProps.blurAmount) {
NSNumber *blurAmount = [NSNumber numberWithInt:newViewProps.blurAmount];
[self setBlurAmount:blurAmount];
@@ -83,12 +83,12 @@
NSString *blurType = [NSString stringWithUTF8String:toString(newViewProps.blurType).c_str()];
[self setBlurType:blurType];
}
-
+
if (oldViewProps.reducedTransparencyFallbackColor != newViewProps.reducedTransparencyFallbackColor) {
UIColor *color = RCTUIColorFromSharedColor(newViewProps.reducedTransparencyFallbackColor);
[self setReducedTransparencyFallbackColor:color];
}
-
+
[super updateProps:props oldProps:oldProps];
}
#endif // RCT_NEW_ARCH_ENABLED
@@ -131,6 +131,7 @@
- (UIBlurEffectStyle)blurEffectStyle
{
+ if ([self.blurType isEqual: @"transparent"]) return UIBlurEffectStyleDark;
if ([self.blurType isEqual: @"xlight"]) return UIBlurEffectStyleExtraLight;
if ([self.blurType isEqual: @"light"]) return UIBlurEffectStyleLight;
if ([self.blurType isEqual: @"dark"]) return UIBlurEffectStyleDark;
@@ -160,7 +161,7 @@
if ([self.blurType isEqual: @"thinMaterialLight"]) return UIBlurEffectStyleSystemThinMaterialLight;
if ([self.blurType isEqual: @"ultraThinMaterialLight"]) return UIBlurEffectStyleSystemUltraThinMaterialLight;
#endif
-
+
#if TARGET_OS_TV
if ([self.blurType isEqual: @"regular"]) return UIBlurEffectStyleRegular;
if ([self.blurType isEqual: @"prominent"]) return UIBlurEffectStyleProminent;
@@ -183,6 +184,13 @@
UIBlurEffectStyle style = [self blurEffectStyle];
self.blurEffect = [BlurEffectWithAmount effectWithStyle:style andBlurAmount:self.blurAmount];
self.blurEffectView.effect = self.blurEffect;
+
+ if ([self.blurType isEqual: @"transparent"]) {
+ for (UIView *subview in self.blurEffectView.subviews) {
+ subview.backgroundColor = [UIColor clearColor];
+ }
+ }
+
}
- (void)updateFallbackView
-10
View File
@@ -1,10 +0,0 @@
--- /tmp/tmp-status-mobile-61974dae4/tmp.NHLSFZG6LG/BlurViewNativeComponent.ts 2024-04-16 17:08:42.755929000 +0200
+++ ./node_modules/@react-native-community/blur/src/fabric/BlurViewNativeComponent.ts 2024-04-16 17:08:57.634037113 +0200
@@ -10,6 +10,7 @@
| 'dark'
| 'light'
| 'xlight'
+ | 'transparent'
| 'prominent'
| 'regular'
| 'extraDark'
-22
View File
@@ -1,22 +0,0 @@
--- /tmp/tmp-status-mobile-3907e6b2e/tmp.re8kHerusA/CameraRoll.ts 2024-04-16 15:17:12.942432000 +0200
+++ ./node_modules/@react-native-camera-roll/camera-roll/src/CameraRoll.ts 2024-04-16 15:17:42.455250986 +0200
@@ -239,6 +239,19 @@
}
/**
+ * Returns total iOS image count
+ */
+ static getPhotosCountiOS(): Promise<number> {
+ return RNCCameraRoll.getPhotosCountiOS('');
+ }
+ /**
+ * Returns favorites and their count iOS
+ */
+ static getFavoritesiOS(): Promise<Album> {
+ return RNCCameraRoll.getFavoritesiOS('');
+ }
+
+ /**
* Saves the photo or video to the camera roll or photo library, and returns the URI of the newly created asset.
*
* @deprecated `save(...)` is deprecated - use `saveAsset(...)` instead.
-11
View File
@@ -1,11 +0,0 @@
--- /tmp/tmp-status-mobile-3907e6b2e/tmp.juxTO1BeCM/NativeCameraRollModule.ts 2024-04-16 15:21:28.379979000 +0200
+++ ./node_modules/@react-native-camera-roll/camera-roll/src/NativeCameraRollModule.ts 2024-04-16 15:21:40.490391291 +0200
@@ -81,6 +81,8 @@
getPhotos(params: Object): Promise<PhotoIdentifiersPage>;
getAlbums(params: Object): Promise<Album[]>;
deletePhotos(photoUris: Array<string>): Promise<void>;
+ getPhotosCountiOS(arg: string): Promise<number>;
+ getFavoritesiOS(arg: string): Promise<Album>;
getPhotoByInternalID(
internalID: string,
options: Object,
-56
View File
@@ -1,56 +0,0 @@
--- /tmp/tmp-status-mobile-3907e6b2e/tmp.O0mkyjqnsy/RNCCameraRoll.mm 2024-04-16 15:26:23.070258000 +0200
+++ ./node_modules/@react-native-camera-roll/camera-roll/ios/RNCCameraRoll.mm 2024-04-16 15:26:32.664996066 +0200
@@ -955,6 +955,53 @@
return [albumTitles copy];
}
+RCT_EXPORT_METHOD(getPhotosCountiOS:(NSString *)blank
+ resolve:(RCTPromiseResolveBlock)resolve
+ reject:(RCTPromiseRejectBlock)reject)
+{
+ __block NSInteger intTotalCount=0;
+ PHFetchOptions *allPhotosOptions = [PHFetchOptions new];
+ allPhotosOptions.predicate = [NSPredicate predicateWithFormat:@"mediaType == %d ",PHAssetMediaTypeImage];
+ PHFetchResult *allPhotosResult = [PHAsset fetchAssetsWithOptions:allPhotosOptions];
+ intTotalCount+=allPhotosResult.count;
+
+ resolve(@(intTotalCount));
+}
+
+RCT_EXPORT_METHOD(getFavoritesiOS:(NSString *)blank
+ resolve:(RCTPromiseResolveBlock)resolve
+ reject:(RCTPromiseRejectBlock)reject)
+{
+ __block NSInteger intTotalCount=0;
+ PHFetchOptions *fetchOptions = [PHFetchOptions new];
+ NSString *format = @"(favorite == true)";
+ fetchOptions.predicate = [NSPredicate predicateWithFormat:format];
+ PHFetchResult<PHAsset *> *const assetsFetchResult = [PHAsset fetchAssetsWithOptions:fetchOptions];
+ PHAsset *imageAsset = [assetsFetchResult firstObject];
+ NSMutableArray * result = [NSMutableArray new];
+
+ for (PHAsset* asset in assetsFetchResult) {
+ NSArray *resources = [PHAssetResource assetResourcesForAsset:asset ];
+ if ([resources count] < 1) continue;
+ NSString *orgFilename = ((PHAssetResource*)resources[0]).originalFilename;
+ NSString *uit = ((PHAssetResource*)resources[0]).uniformTypeIdentifier;
+ NSString *mimeType = (NSString *)CFBridgingRelease(UTTypeCopyPreferredTagWithClass((__bridge CFStringRef _Nonnull)(uit), kUTTagClassMIMEType));
+ CFStringRef extension = UTTypeCopyPreferredTagWithClass((__bridge CFStringRef _Nonnull)(uit), kUTTagClassFilenameExtension);
+ [result addObject:@{
+ @"width": @([asset pixelWidth]),
+ @"height": @([asset pixelHeight]),
+ @"filename": orgFilename ?: @"",
+ @"mimeType": mimeType ?: @"",
+ @"id": [asset localIdentifier],
+ @"creationDate": [asset creationDate],
+ @"uri": [NSString stringWithFormat:@"ph://%@", [asset localIdentifier]],
+ @"duration": @([asset duration])
+ }];
+ }
+ [result addObject:@{@"count": @(assetsFetchResult.count)}];
+ resolve(result);
+}
+
static void checkPhotoLibraryConfig()
{
#if RCT_DEV
@@ -1,10 +0,0 @@
--- /tmp/tmp-status-mobile-61974dae4/tmp.zy6uXqO4gW/VibrancyViewNativeComponent.ts 2024-04-16 17:09:23.772623000 +0200
+++ ./node_modules/@react-native-community/blur/src/fabric/VibrancyViewNativeComponent.ts 2024-04-16 17:09:39.033737349 +0200
@@ -10,6 +10,7 @@
| 'dark'
| 'light'
| 'xlight'
+ | 'transparent'
| 'prominent'
| 'regular'
| 'extraDark'
Binary file not shown.

Before

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

+2 -2
View File
@@ -1,9 +1,9 @@
#!/usr/bin/env sh
INVALID_CHANGES=$(grep -E -r '(/atom|re-frame/dispatch|rf/dispatch|re-frame/subscribe|rf/subscribe|rf/sub|<sub|>evt|status-im\.)' --include '*.cljs' --include '*.clj' './src/quo')
INVALID_CHANGES=$(grep -E -r '(re-frame/dispatch|rf/dispatch|re-frame/subscribe|rf/subscribe|rf/sub|<sub|>evt|status-im\.)' --include '*.cljs' --include '*.clj' './src/quo')
if test -n "$INVALID_CHANGES"; then
echo "WARNING: re-frame, status-im, reagent atoms are not allowed in quo components"
echo "WARNING: re-frame, status-im are not allowed in quo components"
echo ''
echo "$INVALID_CHANGES"
exit 1
+131
View File
@@ -0,0 +1,131 @@
(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)))
@@ -0,0 +1,180 @@
(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")))))))
@@ -0,0 +1,31 @@
(ns legacy.status-im.bottom-sheet.events
(:require
[utils.re-frame :as rf]))
(rf/defn show-bottom-sheet-old
[{:keys [db]} {:keys [view options]}]
{:dismiss-keyboard nil
:show-bottom-sheet-overlay-old nil
:db (assoc db
:bottom-sheet/show? true
:bottom-sheet/view view
:bottom-sheet/options options)})
(rf/defn show-bottom-sheet-event
{:events [:bottom-sheet/show-sheet-old]}
[cofx view options]
(show-bottom-sheet-old
cofx
{:view view
:options options}))
(rf/defn hide-bottom-sheet-old
{:events [:bottom-sheet/hide-old]}
[{:keys [db]}]
{:db (assoc db :bottom-sheet/show? false)
:dismiss-bottom-sheet-overlay-old nil})
(rf/defn hide-bottom-sheet-navigation-overlay
{:events [:bottom-sheet/hide-old-navigation-overlay]}
[{}]
{:dismiss-bottom-sheet-overlay-old nil})
@@ -0,0 +1,38 @@
(ns legacy.status-im.bottom-sheet.sheets
(:require
[legacy.status-im.bottom-sheet.view :as bottom-sheet]
[legacy.status-im.ui.screens.about-app.views :as about-app]
[legacy.status-im.ui.screens.mobile-network-settings.view :as mobile-network-settings]
[quo.theme :as theme]
[react-native.core :as rn]
[utils.re-frame :as rf]))
(defn bottom-sheet
[]
(let [dismiss-bottom-sheet-callback (fn []
(rf/dispatch [:bottom-sheet/hide-old])
true)
{:keys [show? view options]} (rf/sub [:bottom-sheet-old])
{:keys [content]
:as opts}
(cond-> {:visible? show?}
(map? view)
(merge view)
(= view :mobile-network-offline)
(merge mobile-network-settings/offline-sheet)
(= view :learn-more)
(merge about-app/learn-more))
page-theme (:theme options)]
[:f>
(fn []
(rn/use-mount (fn []
(rn/hw-back-add-listener dismiss-bottom-sheet-callback)
(fn []
(rn/hw-back-remove-listener dismiss-bottom-sheet-callback))))
[theme/provider {:theme (or page-theme (theme/get-theme))}
[bottom-sheet/bottom-sheet opts
(when content
[content (when options options)])]])]))
@@ -0,0 +1,59 @@
(ns legacy.status-im.bottom-sheet.styles
(:require
[quo.foundations.colors :as colors]))
(def border-radius 20)
(defn handle
[override-theme]
{:position :absolute
:top 8
:width 32
:height 4
:background-color (colors/theme-colors colors/neutral-100 colors/white override-theme)
:opacity 0.1
:border-radius 100
:align-self :center})
(def backdrop
{:position :absolute
:left 0
:right 0
:bottom 0
:top 0})
(def backdrop-color
{:background-color colors/neutral-100})
(def container
{:position :absolute
:left 0
:right 0
:top 0
:bottom 0
:overflow :hidden})
(defn content-style
[insets bottom-safe-area-spacing?]
{:position :absolute
:left 0
:right 0
:top 0
:padding-top border-radius
:padding-bottom (if bottom-safe-area-spacing? (:bottom insets) 0)})
(defn selected-background
[override-theme]
{:border-radius 12
:padding-left 12
:margin-horizontal 8
:margin-bottom 10
:height 48
:background-color (colors/theme-colors colors/white colors/neutral-90 override-theme)})
(defn background
[override-theme]
{:background-color (colors/theme-colors colors/white colors/neutral-95 override-theme)
:flex 1
:border-top-left-radius border-radius
:border-top-right-radius border-radius})
+240
View File
@@ -0,0 +1,240 @@
(ns legacy.status-im.bottom-sheet.view
(:require
[legacy.status-im.bottom-sheet.styles :as styles]
[oops.core :refer [oget]]
[re-frame.core :as re-frame]
[react-native.background-timer :as timer]
[react-native.core :as react]
[react-native.core :as rn]
[react-native.gesture :as gesture]
[react-native.hooks :as hooks]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[react-native.safe-area :as safe-area]
[reagent.core :as reagent]
[utils.worklets.bottom-sheet :as worklets.bottom-sheet]))
(def animation-delay 450)
(defn with-animation
[value]
(reanimated/with-spring
value
(clj->js {:mass 2
:stiffness 500
:damping 200})))
(defn get-bottom-sheet-gesture
[pan-y translate-y bg-height bg-height-expanded
window-height keyboard-shown disable-drag? expandable?
show-bottom-sheet? expanded? close-bottom-sheet gesture-running?]
(-> (gesture/gesture-pan)
(gesture/on-start
(fn [_]
(reset! gesture-running? true)
(when (and keyboard-shown (not disable-drag?) show-bottom-sheet?)
(re-frame/dispatch [:dismiss-keyboard]))))
(gesture/on-update
(fn [evt]
(when (and (not disable-drag?) show-bottom-sheet?)
(let [max-pan-up (if (or @expanded? (not expandable?))
0
(- (- bg-height-expanded bg-height)))
max-pan-down (if @expanded?
bg-height-expanded
bg-height)]
(reanimated/set-shared-value pan-y
(max
(min
(.-translationY evt)
max-pan-down)
max-pan-up))))))
(gesture/on-end
(fn [_]
(reset! gesture-running? false)
(when (and (not disable-drag?) show-bottom-sheet?)
(let [end-pan-y (- window-height (.-value translate-y))
expand-threshold (min (* bg-height 1.1) (+ bg-height 50))
collapse-threshold (max (* bg-height-expanded 0.9) (- bg-height-expanded 50))
should-close-bottom-sheet? (< end-pan-y (max (* bg-height 0.7) 50))]
(cond
should-close-bottom-sheet?
(close-bottom-sheet)
(and (not @expanded?) (> end-pan-y expand-threshold))
(reset! expanded? true)
(and @expanded? (< end-pan-y collapse-threshold))
(reset! expanded? false))))))))
(defn handle-view
[window-width override-theme]
[rn/view
{:style {:width window-width
:position :absolute
:background-color :transparent
:top 0
:height 20}}
[rn/view {:style (styles/handle override-theme)}]])
(defn bottom-sheet
[props children]
(let [{on-cancel :on-cancel
disable-drag? :disable-drag?
show-handle? :show-handle?
visible? :visible?
backdrop-dismiss? :backdrop-dismiss?
expandable? :expandable?
bottom-safe-area-spacing? :bottom-safe-area-spacing?
selected-item :selected-item
is-initially-expanded? :expanded?
override-theme :override-theme
:or {show-handle? true
backdrop-dismiss? true
expandable? false
bottom-safe-area-spacing? true
is-initially-expanded? false}}
props
content-height (reagent/atom nil)
show-bottom-sheet? (reagent/atom nil)
keyboard-was-shown? (reagent/atom false)
expanded? (reagent/atom is-initially-expanded?)
gesture-running? (reagent/atom false)
reset-atoms (fn []
(reset! show-bottom-sheet? nil)
(reset! content-height nil)
(reset! expanded? false)
(reset! keyboard-was-shown? false)
(reset! gesture-running? false))
close-bottom-sheet (fn []
(reset! show-bottom-sheet? false)
(when (fn? on-cancel) (on-cancel))
(timer/set-timeout
#(do
(re-frame/dispatch [:bottom-sheet/hide-old-navigation-overlay])
(reset-atoms))
animation-delay))]
[:f>
(fn []
(let [{height :height
window-width :width}
(rn/get-window)
window-height (if selected-item (- height 72) height)
{:keys [keyboard-shown]} (hooks/use-keyboard)
insets (safe-area/get-insets)
bg-height-expanded (- window-height (:top insets))
bg-height (max (min @content-height bg-height-expanded) 109)
bottom-sheet-dy (reanimated/use-shared-value 0)
pan-y (reanimated/use-shared-value 0)
translate-y (worklets.bottom-sheet/use-translate-y window-height bottom-sheet-dy pan-y)
bg-opacity
(worklets.bottom-sheet/use-background-opacity translate-y bg-height window-height 0.7)
on-content-layout (fn [evt]
(let [height (oget evt "nativeEvent" "layout" "height")]
(reset! content-height height)))
on-expanded (fn []
(reanimated/set-shared-value bottom-sheet-dy bg-height-expanded)
(reanimated/set-shared-value pan-y 0))
on-collapsed (fn []
(reanimated/set-shared-value bottom-sheet-dy bg-height)
(reanimated/set-shared-value pan-y 0))
bottom-sheet-gesture (get-bottom-sheet-gesture
pan-y
translate-y
bg-height
bg-height-expanded
window-height
keyboard-shown
disable-drag?
expandable?
show-bottom-sheet?
expanded?
close-bottom-sheet
gesture-running?)
handle-comp [gesture/gesture-detector {:gesture bottom-sheet-gesture}
[handle-view window-width override-theme]]]
(react/use-effect #(do
(cond
(and
(nil? @show-bottom-sheet?)
visible?
(some? @content-height)
(> @content-height 0))
(reset! show-bottom-sheet? true)
(and @show-bottom-sheet? (not visible?))
(close-bottom-sheet)))
[@show-bottom-sheet? @content-height visible?])
(react/use-effect #(do
(when @show-bottom-sheet?
(cond
keyboard-shown
(do
(reset! keyboard-was-shown? true)
(reset! expanded? true))
(and @keyboard-was-shown? (not keyboard-shown))
(reset! expanded? false))))
[@show-bottom-sheet? @keyboard-was-shown? keyboard-shown])
(react/use-effect #(do
(when-not @gesture-running?
(cond
@show-bottom-sheet?
(if @expanded?
(do
(reanimated/set-shared-value
bottom-sheet-dy
(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
(timer/set-timeout on-expanded animation-delay))
(do
(reanimated/set-shared-value
bottom-sheet-dy
(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
(timer/set-timeout on-collapsed animation-delay)))
(= @show-bottom-sheet? false)
(reanimated/set-shared-value bottom-sheet-dy (with-animation 0)))))
[@show-bottom-sheet? @expanded? @gesture-running?])
[:<>
[rn/pressable
{:on-press (when backdrop-dismiss? close-bottom-sheet)
:style styles/backdrop}
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:opacity bg-opacity}
styles/backdrop-color)}]]
(cond->> [reanimated/view
{:style (reanimated/apply-animations-to-style
{:transform [{:translateY translate-y}]}
{:width window-width
:height window-height})}
[rn/view {:style styles/container}
(when selected-item
[rn/view {:style (styles/selected-background override-theme)}
[selected-item]])
[rn/view {:style (styles/background override-theme)}
[rn/keyboard-avoiding-view
{:behaviour (if platform/ios? :padding :height)
:style {:flex 1}}
[rn/view
{:style (styles/content-style insets bottom-safe-area-spacing?)
:on-layout (when-not (and
(some? @content-height)
(> @content-height 0))
on-content-layout)}
children]]
(when show-handle?
handle-comp)]]]
(not show-handle?)
(conj [gesture/gesture-detector {:gesture bottom-sheet-gesture}]))]))]))
+65 -3
View File
@@ -2,10 +2,13 @@
(:require
["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]
@@ -390,6 +393,64 @@
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")
@@ -418,8 +479,9 @@
(rf/defn web3-send-async-read-only
[{:keys [db] :as cofx} dapp-name {:keys [method] :as payload} message-id]
(when (has-permissions? db dapp-name method)
(handle-no-permissions cofx 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)))
(rf/defn handle-scanned-qr-code
{:events [:browser.bridge.callback/qr-code-scanned]}
@@ -518,7 +580,7 @@
[{:keys [db] :as cofx} address]
(rf/merge cofx
{:browser/clear-web-data nil}
(navigation/hide-bottom-sheet)
(bottom-sheet/hide-bottom-sheet-old)
(browser.permissions/clear-dapps-permissions)
(multiaccounts.update/multiaccount-update :dapps-address address {})
#(when (= (:view-id db) :browser)
+38
View File
@@ -0,0 +1,38 @@
;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
@@ -0,0 +1,55 @@
;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.")}}})))
+59 -10
View File
@@ -1,9 +1,9 @@
(ns legacy.status-im.communities.core
(:require
[clojure.set :as set]
[legacy.status-im.bottom-sheet.events :as bottom-sheet]
legacy.status-im.communities.e2e
[re-frame.core :as re-frame]
[status-im.contexts.shell.activity-center.events :as activity-center]
[status-im.navigation.events :as navigation]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
@@ -22,10 +22,60 @@
{}
requests))
(defn- fetch-community-id-input
[{:keys [db]}]
(:communities/community-id-input db))
(rf/defn handle-response
[_ response-js]
{:dispatch [:sanitize-messages-and-process-response response-js]})
(rf/defn invite-users
{:events [::invite-people-confirmation-pressed]}
[cofx user-pk contacts]
(let [community-id (fetch-community-id-input cofx)
pks (if (seq user-pk)
(conj contacts user-pk)
contacts)]
(when (seq pks)
{:json-rpc/call [{:method "wakuext_inviteUsersToCommunity"
:params [{:communityId community-id
:users pks}]
:js-response true
:on-success #(re-frame/dispatch [::people-invited %])
:on-error #(do
(log/error "failed to invite-user community" %)
(re-frame/dispatch [::failed-to-invite-people %]))}]})))
(rf/defn share-community
{:events [::share-community-confirmation-pressed]}
[cofx user-pk contacts]
(let [community-id (fetch-community-id-input cofx)
pks (if (seq user-pk)
(conj contacts user-pk)
contacts)]
(when (seq pks)
{:json-rpc/call [{:method "wakuext_shareCommunity"
:params [{:communityId community-id
:users pks}]
:js-response true
:on-success #(re-frame/dispatch [::people-invited %])
:on-error #(do
(log/error "failed to invite-user community" %)
(re-frame/dispatch [::failed-to-share-community %]))}]})))
(re-frame/reg-event-fx :communities/invite-people-pressed
(fn [{:keys [db]} [id]]
{:db (assoc db :communities/community-id-input id)
:fx [[:dispatch [:hide-bottom-sheet]]
[:dispatch [:open-modal :legacy-invite-people-community {:invite? true}]]]}))
(re-frame/reg-event-fx :communities/share-community-pressed
(fn [{:keys [db]} [id]]
{:db (assoc db :communities/community-id-input id)
:fx [[:dispatch [:hide-bottom-sheet]]
[:dispatch [:open-modal :legacy-invite-people-community {}]]]}))
(rf/defn people-invited
{:events [::people-invited]}
[cofx response-js]
@@ -33,13 +83,12 @@
(navigation/navigate-back)
(handle-response response-js)))
(rf/defn member-banned
{:events [::member-banned]}
[cofx response-js]
(rf/merge cofx
(navigation/hide-bottom-sheet)
(handle-response response-js)
(activity-center/notifications-fetch-unread-count)))
(re-frame/reg-event-fx ::member-banned
(fn [{:keys [db]} [response-js]]
{:db (assoc db :bottom-sheet/show? false)
:fx [[:dismiss-bottom-sheet-overlay-old]
[:sanitize-messages-and-process-response response-js]
[:activity-center.notifications/fetch-unread-count]]}))
(rf/defn member-ban
{:events [::member-ban]}
@@ -58,7 +107,7 @@
{:events [::member-kicked]}
[cofx response-js]
(rf/merge cofx
(navigation/hide-bottom-sheet)
(bottom-sheet/hide-bottom-sheet-old)
(handle-response response-js)))
(rf/defn member-kick
@@ -92,7 +141,7 @@
{:events [:community.member/role-updated]}
[cofx response-js]
(rf/merge cofx
(navigation/hide-bottom-sheet)
(bottom-sheet/hide-bottom-sheet-old)
(handle-response response-js)))
(rf/defn add-role-to-member
+99
View File
@@ -0,0 +1,99 @@
(ns legacy.status-im.contact.block
(:require
[legacy.status-im.contact.db :as contact.db]
[legacy.status-im.data-store.chats :as chats-store]
[legacy.status-im.utils.deprecated-types :as types]
[re-frame.core :as re-frame]
[status-im.contexts.chat.contacts.events :as contacts-store]
[status-im.contexts.chat.messenger.messages.list.events :as message-list]
[status-im.navigation.events :as navigation]
[utils.re-frame :as rf]))
(rf/defn clean-up-chat
[{:keys [db]}
public-key
{:keys [chat-id
unviewed-messages-count
unviewed-mentions-count
last-message]}]
(let [removed-messages-ids (keep
(fn [[message-id {:keys [from]}]]
(when (= from public-key)
message-id))
(get-in db [:messages chat-id]))
db (-> db
;; remove messages
(update-in [:messages chat-id]
#(apply dissoc % removed-messages-ids))
(update-in [:chats chat-id]
assoc
:unviewed-messages-count unviewed-messages-count
:unviewed-mentions-count unviewed-mentions-count
:last-message last-message))]
{:db (assoc-in db
[:message-lists chat-id]
(message-list/add-many nil (vals (get-in db [:messages chat-id]))))}))
(rf/defn contact-blocked
{:events [:contacts/blocked]}
[{:keys [db] :as cofx} {:keys [public-key]} chats-js]
(let [fxs (when chats-js
(map #(->> (chats-store/<-rpc %)
(clean-up-chat public-key))
(types/js->clj chats-js)))]
(apply
rf/merge
cofx
{:db (->
db
(update :chats dissoc public-key)
(update :chats-home-list disj public-key)
(assoc-in [:contacts/contacts public-key
:added?]
false))
:fx [[:activity-center.notifications/fetch-unread-count]
[:effects/push-notifications-clear-message-notifications [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]
(let [contact (-> (contact.db/public-key->contact
(:contacts/contacts db)
public-key)
(assoc :blocked? true
:added? false
:active? false))
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
public-key
(fn [^js block-contact]
(re-frame/dispatch [:contacts/blocked contact (.-chats block-contact)])
(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 current-chat-id
(if from-one-to-one-chat?
(navigation/pop-to-root :shell-stack)
(navigation/navigate-back))))))
(rf/defn contact-unblocked
{:events [:contacts/unblocked]}
[{:keys [db]} contact-id]
(let [contact (-> (get-in db [:contacts/contacts contact-id])
(assoc :blocked? false))]
{:db (assoc-in db [:contacts/contacts contact-id] contact)}))
(rf/defn unblock-contact
{:events [:contact.ui/unblock-contact-pressed]}
[cofx contact-id]
(contacts-store/unblock
cofx
contact-id
#(re-frame/dispatch [:contacts/unblocked contact-id])))
+87
View File
@@ -0,0 +1,87 @@
(ns legacy.status-im.contact.db
(:require
[clojure.set :as set]
[clojure.string :as string]
[status-im.constants :as constants]
[utils.address :as address]))
(defn public-key-and-ens-name->new-contact
[public-key ens-name]
(let [contact {:public-key public-key}]
(if ens-name
(-> contact
(assoc :ens-name ens-name)
(assoc :ens-verified true)
(assoc :name ens-name))
contact)))
(defn public-key->contact
[contacts public-key]
(when public-key
(get contacts public-key {:public-key public-key})))
(defn- contact-by-address
[[addr contact] address]
(when (address/address= addr address)
contact))
(defn find-contact-by-address
[contacts address]
(some #(contact-by-address % address) contacts))
(defn sort-contacts
[contacts]
(sort (fn [c1 c2]
(let [name1 (:primary-name c1)
name2 (:primary-name c2)]
(when (and name1 name2)
(compare (string/lower-case name1)
(string/lower-case name2)))))
(vals contacts)))
(defn query-chat-contacts
[{:keys [contacts]} all-contacts query-fn]
(let [participant-set (into #{} (filter identity) contacts)]
(query-fn (comp participant-set :public-key) (vals all-contacts))))
(defn get-all-contacts-in-group-chat
[members admins contacts {:keys [public-key preferred-name name display-name] :as current-account}]
(let [current-contact (some->
current-account
(select-keys [:name :preferred-name :public-key :images :compressed-key])
(set/rename-keys {:name :alias :preferred-name :name})
(assoc :primary-name (or display-name preferred-name name)))
all-contacts (cond-> contacts
current-contact
(assoc public-key current-contact))]
(->> members
(map #(or (get all-contacts %)
{:public-key %}))
(sort-by (comp string/lower-case
(fn [{:keys [primary-name name alias public-key]}]
(or primary-name
name
alias
public-key))))
(map #(if (get admins (:public-key %))
(assoc % :admin? true)
%)))))
(defn enrich-contact
([contact] (enrich-contact contact nil nil))
([{:keys [public-key] :as contact} setting own-public-key]
(cond-> contact
(and setting
(not= public-key own-public-key)
(or (= setting constants/profile-pictures-visibility-none)
(and (= setting constants/profile-pictures-visibility-contacts-only)
(not (:added? contact)))))
(dissoc :images))))
(defn enrich-contacts
[contacts profile-pictures-visibility own-public-key]
(reduce-kv
(fn [acc public-key contact]
(assoc acc public-key (enrich-contact contact profile-pictures-visibility own-public-key)))
{}
contacts))
+49
View File
@@ -0,0 +1,49 @@
(ns legacy.status-im.contact.db-test
(:require [cljs.test :refer-macros [deftest is testing]]
[legacy.status-im.contact.db :as contact.db]))
(deftest contacts-subs
(testing "get-all-contacts-in-group-chat"
(let
[chat-contact-ids
#{"0x04fcf40c526b09ff9fb22f4a5dbd08490ef9b64af700870f8a0ba2133f4251d5607ed83cd9047b8c2796576bc83fa0de23a13a4dced07654b8ff137fe744047917"
"0x04985040682b77a32bb4bb58268a0719bd24ca4d07c255153fe1eb2ccd5883669627bd1a092d7cc76e8e4b9104327667b19dcda3ac469f572efabe588c38c1985f"
"0x048a2f8b80c60f89a91b4c1316e56f75b087f446e7b8701ceca06a40142d8efe1f5aa36bd0fee9e248060a8d5207b43ae98bef4617c18c71e66f920f324869c09f"}
admins
#{"0x04fcf40c526b09ff9fb22f4a5dbd08490ef9b64af700870f8a0ba2133f4251d5607ed83cd9047b8c2796576bc83fa0de23a13a4dced07654b8ff137fe744047917"}
contacts
{"0x04985040682b77a32bb4bb58268a0719bd24ca4d07c255153fe1eb2ccd5883669627bd1a092d7cc76e8e4b9104327667b19dcda3ac469f572efabe588c38c1985f"
{:last-updated 0
:name "User B"
:primary-name "User B"
:last-online 0
:public-key
"0x04985040682b77a32bb4bb58268a0719bd24ca4d07c255153fe1eb2ccd5883669627bd1a092d7cc76e8e4b9104327667b19dcda3ac469f572efabe588c38c1985f"}}
current-multiaccount
{:last-updated 0
:signed-up? true
:sharing-usage-data? false
:primary-name "User A"
:name "User A"
:public-key
"0x048a2f8b80c60f89a91b4c1316e56f75b087f446e7b8701ceca06a40142d8efe1f5aa36bd0fee9e248060a8d5207b43ae98bef4617c18c71e66f920f324869c09f"}]
(is
(=
(contact.db/get-all-contacts-in-group-chat chat-contact-ids
admins
contacts
current-multiaccount)
[{:admin? true
:public-key
"0x04fcf40c526b09ff9fb22f4a5dbd08490ef9b64af700870f8a0ba2133f4251d5607ed83cd9047b8c2796576bc83fa0de23a13a4dced07654b8ff137fe744047917"}
{:alias "User A"
:primary-name "User A"
:public-key
"0x048a2f8b80c60f89a91b4c1316e56f75b087f446e7b8701ceca06a40142d8efe1f5aa36bd0fee9e248060a8d5207b43ae98bef4617c18c71e66f920f324869c09f"}
{:last-updated 0
:name "User B"
:primary-name "User B"
:last-online 0
:public-key
"0x04985040682b77a32bb4bb58268a0719bd24ca4d07c255153fe1eb2ccd5883669627bd1a092d7cc76e8e4b9104327667b19dcda3ac469f572efabe588c38c1985f"}])))))
@@ -2,8 +2,18 @@
(: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]
@@ -18,14 +28,25 @@
{}
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
+2 -1
View File
@@ -3,6 +3,7 @@
(:require
[clojure.set :as set]
[clojure.string :as string]
[legacy.status-im.bottom-sheet.events :as bottom-sheet]
[legacy.status-im.ethereum.ens :as ens]
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
[legacy.status-im.utils.random :as random]
@@ -287,7 +288,7 @@
[{:keys [db] :as cofx} _ {:keys [address]}]
(rf/merge cofx
{:db (assoc-in db [:ens/registration :address] address)}
(navigation/hide-bottom-sheet)))
(bottom-sheet/hide-bottom-sheet-old)))
(rf/defn save-preferred-name
{:events [::save-preferred-name]}
+12 -2
View File
@@ -2,15 +2,18 @@
(: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
legacy.status-im.contact.block
legacy.status-im.currency.core
legacy.status-im.data-store.chats
legacy.status-im.data-store.switcher-cards
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]
@@ -188,8 +191,15 @@
:db (assoc db :screens/was-focused-once? true)}
(not (get db :screens/was-focused-once?))
{:db (assoc db :screens/was-focused-once? true)})))
{: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
@@ -0,0 +1,73 @@
(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
@@ -0,0 +1,565 @@
(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)))))))
@@ -0,0 +1,216 @@
(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
@@ -0,0 +1,560 @@
(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]))
@@ -0,0 +1,43 @@
(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
@@ -0,0 +1,688 @@
(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})
@@ -0,0 +1,77 @@
(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"}))
@@ -0,0 +1,47 @@
(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)))
@@ -0,0 +1,13 @@
(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
@@ -0,0 +1,208 @@
(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
@@ -0,0 +1,182 @@
(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))
@@ -0,0 +1,37 @@
(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
@@ -0,0 +1,11 @@
(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?)
@@ -0,0 +1,335 @@
(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
@@ -0,0 +1,355 @@
(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
@@ -0,0 +1,196 @@
(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))))))
@@ -0,0 +1,588 @@
(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)))
@@ -0,0 +1,32 @@
(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
@@ -0,0 +1,187 @@
(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)))))
@@ -1,5 +1,6 @@
(ns legacy.status-im.mobile-sync-settings.core
(:require
[legacy.status-im.bottom-sheet.events :as bottom-sheet]
[legacy.status-im.mailserver.core :as mailserver]
[legacy.status-im.multiaccounts.model :as multiaccounts.model]
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
@@ -30,7 +31,7 @@
(assoc :mailserver/current-request true))
:fx [(when fetch-historic-messages?
[:mailserver/request-all-historic-messages])
[:dispatch [:hide-bottom-sheet]]
[:dismiss-bottom-sheet-overlay-old]
(when previously-initialized?
(let [new-identity-input (get-in db [:contacts/new-identity :input])]
[:dispatch [:contacts/set-new-identity {:input new-identity-input}]]))]}
@@ -100,10 +101,10 @@
[cofx]
(rf/merge
cofx
(navigation/hide-bottom-sheet)
(bottom-sheet/hide-bottom-sheet-old)
(navigation/navigate-to :mobile-network-settings nil)))
(rf/defn mobile-network-show-offline-sheet
{:events [:mobile-network/show-offline-sheet]}
[cofx]
(navigation/hide-bottom-sheet cofx))
(bottom-sheet/hide-bottom-sheet-old cofx))
@@ -59,7 +59,7 @@
:selected-storage-type :default
:selected-id (-> result first :id)
:step :choose-key))))
:navigate-to [:choose-name (:theme db)]})
:navigate-to :choose-name})
(rf/defn generate-and-derive-addresses
{:events [:generate-and-derive-addresses]}
+25 -4
View File
@@ -5,6 +5,16 @@
[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)
@@ -105,7 +115,7 @@
(some #(string/includes? (str %) "waku") ks)))
(defn get-multiaccount-node-config
[{:keys [profile/profile :networks/current-network]
[{:keys [profile/profile :networks/networks :networks/current-network]
:as db}]
(let [wakuv2-config (get profile :wakuv2-config {})
fleet-key (current-fleet-key db)
@@ -114,9 +124,11 @@
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]}
profile]
(cond-> {}
waku-bloom-filter-mode
custom-bootnodes custom-bootnodes-enabled?]}
profile
use-custom-bootnodes (get custom-bootnodes-enabled? current-network)]
(cond-> (get-in networks [current-network :config])
:always
(get-base-node-config)
@@ -132,6 +144,8 @@
(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
@@ -171,5 +185,12 @@
: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))))
+650
View File
@@ -0,0 +1,650 @@
(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}))})))
@@ -0,0 +1,64 @@
(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}}))))))))))
+55
View File
@@ -0,0 +1,55 @@
(ns legacy.status-im.signing.eip1559
(:require
[re-frame.core :as re-frame]
[status-im.common.json-rpc.events :as json-rpc]))
(defonce london-activated? (atom false))
(defn london-is-definitely-activated
[network-id]
(contains? #{"1" "3"} network-id))
(defn on-block
[callback header]
(let [activated? (contains? header :baseFeePerGas)]
(reset! london-activated? activated?)
(callback activated?)))
(defn check-activation
[callback]
(json-rpc/call
{:method "eth_getBlockByNumber"
:params ["latest" false]
:on-success (partial on-block callback)
:on-error #(callback nil)}))
(defn sync-enabled? [] @london-activated?)
(defn enabled?
([] @london-activated?)
([network-id enabled-callback disabled-callback]
(let [definitely-activated? (london-is-definitely-activated network-id)
enabled-callback (or enabled-callback #())
disabled-callback (or disabled-callback #())]
(cond
definitely-activated?
(do
(reset! london-activated? true)
(enabled-callback))
(not definitely-activated?)
(check-activation
(fn [activated?]
(if activated?
(enabled-callback)
(disabled-callback))))
:else
(do
(reset! london-activated? false)
(disabled-callback))))))
(re-frame/reg-fx
:check-eip1559-activation
(fn [network-id]
(enabled? network-id nil nil)))
+430
View File
@@ -0,0 +1,430 @@
(ns legacy.status-im.signing.gas
(:require
[clojure.string :as string]
[legacy.status-im.bottom-sheet.events :as bottom-sheet]
[legacy.status-im.popover.core :as popover]
[legacy.status-im.signing.eip1559 :as eip1559]
[re-frame.core :as re-frame]
[status-im.common.json-rpc.events :as json-rpc]
[taoensso.timbre :as log]
[utils.ethereum.chain :as chain]
[utils.i18n :as i18n]
[utils.money :as money]
[utils.re-frame :as rf]))
(def min-gas-price-wei ^js (money/bignumber 1))
(def min-gas-units ^js (money/bignumber 21000))
(defmulti get-error-label-key (fn [type _] type))
(defmethod get-error-label-key :gasPrice
[_ value]
(cond
(not value) :t/invalid-number
(.lt ^js (money/->wei :gwei value) min-gas-price-wei) :t/wallet-send-min-wei
(-> (money/->wei :gwei value) .decimalPlaces pos?) :t/invalid-number))
(defmethod get-error-label-key :gas
[_ ^js value]
(cond
(not value) :t/invalid-number
(.lt value min-gas-units) :t/wallet-send-min-units
(-> value .decimalPlaces pos?) :t/invalid-number))
(defmethod get-error-label-key :default
[_ value]
(when (or (not value)
(<= value 0))
:t/invalid-number))
(defn calculate-max-fee
[^js gas ^js gasPrice]
(if (and gas gasPrice)
(money/to-fixed (money/wei->ether (.times gas gasPrice)))
"0"))
(defn edit-max-fee
[edit]
(let [gasPrice (get-in edit [:gasPrice :value-number])
gas (get-in edit [:gas :value-number])]
(assoc edit :max-fee (calculate-max-fee gas gasPrice))))
(defn build-edit
"Takes the previous edit, either :gas or :gas-price and a value as string.
Wei for gas, and gwei for gas price.
Validates them and sets max fee"
[edit-value k value]
(let [^js bn-value (money/bignumber value)
error-label-key (get-error-label-key k bn-value)
data (if error-label-key
{:value value
:max-fee 0
:error (i18n/label error-label-key)}
{:value value
:value-number (if (= :gasPrice k)
(money/->wei :gwei bn-value)
bn-value)})]
(-> edit-value
(assoc k data)
edit-max-fee)))
;; TODO(rasom): this number is almost arbitrary, I was able to sent txs with
;; 0.2 gwei tip, so it should be revisited lately
(def minimum-priority-fee-gwei
(money/bignumber 0.3))
(defn get-suggested-tip
[latest-priority-fee]
(money/bignumber latest-priority-fee))
(defn get-minimum-priority-fee
[latest-priority-fee]
(let [latest-priority-fee-bn (money/bignumber latest-priority-fee)
suggested-tip-gwei (money/wei->gwei (get-suggested-tip latest-priority-fee-bn))]
(if (money/greater-than minimum-priority-fee-gwei suggested-tip-gwei)
(money/div suggested-tip-gwei 2)
minimum-priority-fee-gwei)))
(defn get-suggestions-range
[latest-priority-fee]
(let [current-minimum-fee (get-minimum-priority-fee latest-priority-fee)]
[(if (money/greater-than minimum-priority-fee-gwei current-minimum-fee)
current-minimum-fee
minimum-priority-fee-gwei)
(money/wei->gwei (money/bignumber latest-priority-fee))]))
(def average-priority-fee
(money/wei->gwei (money/->wei :gwei 1.5)))
(defn validate-max-fee
[db]
(let [{:keys [maxFeePerGas maxPriorityFeePerGas]} (get db :signing/edit-fee)
latest-base-fee (money/wei->gwei
(money/bignumber
(get db :wallet-legacy/current-base-fee)))
fee-error (cond
(or (:error maxFeePerGas)
(:error maxPriorityFeePerGas))
nil
(money/greater-than latest-base-fee
(:value-number maxFeePerGas))
{:label (i18n/label :t/below-base-fee)
:severity :error})]
(if fee-error
(assoc-in db [:signing/edit-fee :maxFeePerGas :fee-error] fee-error)
(update-in db [:signing/edit-fee :maxFeePerGas] dissoc :fee-error))))
(defn validate-max-priority-fee
[db]
(let [{:keys [maxPriorityFeePerGas]} (get db :signing/edit-fee)
latest-priority-fee (get db :wallet-legacy/current-priority-fee)
fee-error (cond
(:error maxPriorityFeePerGas)
nil
(money/greater-than (get-minimum-priority-fee
(money/div
(money/wei->gwei (money/bignumber
latest-priority-fee))
2))
(:value-number maxPriorityFeePerGas))
{:label (i18n/label :t/low-tip)
:severity :error}
#_(money/greater-than average-priority-fee
(:value-number maxPriorityFeePerGas))
#_{:label (i18n/label :t/lower-than-average-tip)
:severity :error})]
(if fee-error
(assoc-in db [:signing/edit-fee :maxPriorityFeePerGas :fee-error] fee-error)
(update-in db [:signing/edit-fee :maxPriorityFeePerGas] dissoc :fee-error))))
(defn validate-eip1559-fees
[db]
(if (eip1559/sync-enabled?)
(reduce
(fn [acc f]
(f acc))
db
[validate-max-fee
validate-max-priority-fee])
db))
(rf/defn edit-value
{:events [:signing.edit-fee.ui/edit-value]}
[{:keys [db]} key value]
{:db (-> db
(assoc-in [:signing/edit-fee :selected-fee-option] :custom)
(update :signing/edit-fee build-edit key value)
validate-eip1559-fees)})
(defn get-fee-options
[tip slow normal fast]
(let [tip-bn (money/bignumber tip)
normal-bn (money/bignumber normal)
slow-bn (money/bignumber slow)
fast-bn (money/bignumber fast)]
{:normal
{:base-fee normal-bn
:tip tip-bn
:fee (money/add normal-bn tip-bn)}
:slow
{:base-fee slow-bn
:tip tip-bn
:fee (money/add slow-bn tip-bn)}
:fast
{:base-fee fast-bn
:tip tip-bn
:fee (money/add fast-bn tip-bn)}}))
(rf/defn set-fee-option
{:events [:signing.edit-fee.ui/set-option]}
[{:keys [db] :as cofx} option]
(let [tip (get db :wallet-legacy/current-priority-fee)
slow (get db :wallet-legacy/slow-base-fee)
normal (get db :wallet-legacy/normal-base-fee)
fast (get db :wallet-legacy/fast-base-fee)
{:keys [fee tip]} (get (get-fee-options tip slow normal fast) option)]
{:db (-> db
(assoc-in [:signing/edit-fee :selected-fee-option] option)
(update :signing/edit-fee
build-edit
:maxFeePerGas (money/wei->gwei fee))
(update :signing/edit-fee
build-edit
:maxPriorityFeePerGas (money/wei->gwei tip)))}))
(rf/defn set-priority-fee
{:events [:signing.edit-fee.ui/set-priority-fee]}
[{:keys [db]} value]
(let [{:keys [maxFeePerGas maxPriorityFeePerGas]}
(get db :signing/edit-fee)
latest-base-fee (get db :wallet-legacy/current-base-fee)
max-fee-value (:value-number maxFeePerGas)
max-priority-fee-value (:value-number maxPriorityFeePerGas)
new-value (money/bignumber value)
fee-without-tip (money/sub max-fee-value max-priority-fee-value)
base-fee (money/wei->gwei (money/bignumber latest-base-fee))
new-max-fee-value
(money/to-fixed
(if (money/greater-than base-fee fee-without-tip)
(money/add new-value base-fee)
(money/add new-value fee-without-tip)))]
{:db (-> db
(update :signing/edit-fee build-edit :maxPriorityFeePerGas value)
(update :signing/edit-fee build-edit :maxFeePerGas new-max-fee-value)
validate-eip1559-fees)}))
(rf/defn update-estimated-gas-success
{:events [:signing/update-estimated-gas-success]}
[{db :db} gas]
(when (contains? db :signing/tx)
{:db (-> db
(assoc-in [:signing/tx :gas] gas)
(assoc-in [:signing/edit-fee :gas-loading?] false))}))
(rf/defn update-gas-price-success
{:events [:signing/update-gas-price-success]}
[{db :db} price]
(if (eip1559/sync-enabled?)
(let [{:keys [normal-base-fee max-priority-fee]} price
max-priority-fee-bn (money/with-precision (get-suggested-tip
max-priority-fee)
0)]
{:db (-> db
(assoc-in [:signing/tx :maxFeePerGas]
(money/to-hex (money/add max-priority-fee-bn
(money/bignumber normal-base-fee))))
(assoc-in [:signing/tx :maxPriorityFeePerGas]
(money/to-hex max-priority-fee-bn))
(assoc-in [:signing/edit-fee :gas-price-loading?] false))})
{:db (-> db
(assoc-in [:signing/tx :gasPrice] price)
(assoc-in [:signing/edit-fee :gas-price-loading?] false))}))
(rf/defn update-estimated-gas-error
{:events [:signing/update-estimated-gas-error]}
[{db :db} {:keys [message]}]
(log/warn "signing/update-estimated-gas-error" message)
{:db (-> db
(assoc-in [:signing/edit-fee :gas-loading?] false)
(assoc-in [:signing/tx :gas-error-message] message))})
(rf/defn update-gas-price-error
{:events [:signing/update-gas-price-error]}
[{db :db}]
{:db (assoc-in db [:signing/edit-fee :gas-price-loading?] false)})
(rf/defn open-fee-sheet
{:events [:signing.ui/open-fee-sheet]}
[{{:signing/keys [tx] :as db} :db :as cofx} sheet-opts]
(let [{:keys [gas gasPrice maxFeePerGas maxPriorityFeePerGas]} tx
max-fee (money/to-fixed (money/wei->gwei
maxFeePerGas))
max-priority-fee (money/to-fixed (money/wei->gwei
maxPriorityFeePerGas))
edit-fee (reduce
(partial apply build-edit)
{:selected-fee-option
(get-in db
[:signing/edit-fee
:selected-fee-option])}
{:gas (money/to-fixed gas)
:gasPrice (money/to-fixed
(money/wei->gwei gasPrice))
:maxFeePerGas max-fee
:maxPriorityFeePerGas
max-priority-fee})]
(rf/merge cofx
{:db (assoc db :signing/edit-fee edit-fee)}
(bottom-sheet/show-bottom-sheet-old {:view sheet-opts}))))
(rf/defn submit-fee
{:events [:signing.edit-fee.ui/submit]}
[{{:signing/keys [edit-fee] :as db} :db :as cofx} force?]
(let [{:keys [gas gasPrice maxFeePerGas maxPriorityFeePerGas]} edit-fee
errors?
(keep
(fn [[k {:keys [fee-error]}]]
(when (= :error (:severity fee-error))
[k fee-error]))
edit-fee)]
(if (and (seq errors?)
(not force?))
(popover/show-popover cofx {:view :fees-warning})
(rf/merge cofx
{:db (update db
:signing/tx assoc
:gas (:value-number gas)
:gasPrice (:value-number gasPrice)
:maxFeePerGas (money/->wei :gwei (:value-number maxFeePerGas))
:maxPriorityFeePerGas (money/->wei :gwei
(:value-number maxPriorityFeePerGas)))}
(bottom-sheet/hide-bottom-sheet-old)))))
(rf/defn submit-nonce
{:events [:signing.nonce/submit]}
[{db :db :as cofx} nonce]
(rf/merge cofx
{:db (assoc-in db [:signing/tx :nonce] (if (string/blank? nonce) nil nonce))}
(bottom-sheet/hide-bottom-sheet-old)))
(re-frame/reg-fx
:signing/update-gas-price
(fn [{:keys [success-callback error-callback network-id] :as params}]
(eip1559/enabled?
network-id
(fn []
(json-rpc/call
{:method "eth_feeHistory"
;; NOTE(rasom): We don't need `reward` atm but if the last parameter is
;; `nil` request fails on some chains (particularly on xDai).
:params [101 "latest" [100]]
:on-success #(re-frame/dispatch [::header-fetched
(assoc params :fee-history %)])}))
(fn []
(json-rpc/call
{:method "eth_gasPrice"
:on-success #(success-callback (money/bignumber %))
:on-error (or error-callback #(log/warn "eth_gasPrice error" %))})))))
(def london-block-gas-limit (money/bignumber 30000000))
(defn calc-percentiles
[v ps]
(let [sorted-v (sort-by
identity
(fn [a b]
(utils.money/greater-than b a))
v)]
(reduce
(fn [acc p]
(assoc acc p (nth sorted-v p)))
{}
ps)))
;; It is very unlikely to be that small on mainnet, but on testnets current base
;; fee might be very small and using this value might slow transaction
(def minimum-base-fee (money/->wei :gwei (money/bignumber 1)))
(defn recommended-base-fee
[current perc20]
(let [fee
(cond (money/greater-than-or-equals current perc20)
current
(money/greater-than perc20 current)
perc20)]
(if (money/greater-than minimum-base-fee fee)
minimum-base-fee
fee)))
(defn slow-base-fee [_ perc10] perc10)
(defn fast-base-fee
[current]
(let [fee (money/mul current 2)]
(if (money/greater-than minimum-base-fee fee)
(money/mul minimum-base-fee 2)
fee)))
(defn check-base-fee
[{:keys [baseFeePerGas testnet?]}]
(let [all-base-fees (mapv money/bignumber baseFeePerGas)
next-base-fee (peek all-base-fees)
previous-fees (subvec all-base-fees 0 101)
current-base-fee (peek previous-fees)
percentiles (calc-percentiles previous-fees [10 20 80])]
{:normal-base-fee (money/to-hex
(if testnet?
(fast-base-fee next-base-fee)
(recommended-base-fee
next-base-fee
(get percentiles 20))))
:slow-base-fee (money/to-hex
(slow-base-fee
next-base-fee
(get percentiles 10)))
:fast-base-fee (money/to-hex (fast-base-fee next-base-fee))
:current-base-fee (money/to-hex current-base-fee)}))
(defn max-priority-fee-hex
[gas-price base-fee]
(money/to-hex
(money/sub (money/bignumber gas-price)
(money/bignumber base-fee))))
(rf/defn header-fetched
{:events [::header-fetched]}
[{{:networks/keys [current-network networks]} :db}
{:keys [error-callback success-callback fee-history] :as params}]
{:json-rpc/call
[;; NOTE(rasom): eth_maxPriorityFeePerGas is not supported by some networks
;; so it is more reliable to calculate maxPriorityFeePerGas using the value
;; returned by eth_gasPrice and current base fee.
{:method "eth_gasPrice"
:on-success #(success-callback
(let [{:keys [current-base-fee] :as base-fees}
(check-base-fee
(assoc fee-history
:testnet?
(chain/testnet?
(get-in networks [current-network :config :NetworkId]))))]
(merge {:max-priority-fee
(max-priority-fee-hex (money/bignumber %) current-base-fee)}
base-fees)))
:on-error (if error-callback
#(error-callback %)
#(log/error "Can't fetch header" %))}]})
(re-frame/reg-fx
:signing/update-estimated-gas
(fn [{:keys [obj success-event error-event]}]
(json-rpc/call
{:method "eth_estimateGas"
:params [obj]
:on-success #(re-frame/dispatch [success-event
(money/bignumber (if (= (int %) 21000) % (int (* % 1.2))))])
:on-error #(re-frame/dispatch [error-event %])})))
@@ -0,0 +1,39 @@
(ns legacy.status-im.signing.gas-test
(:require
[cljs.test :refer-macros [deftest is testing]]
[legacy.status-im.signing.gas :as signing.gas]))
(deftest build-edit-test
(testing "an invalid edit"
(let [actual (-> {}
(signing.gas/build-edit :gas "invalid")
(signing.gas/build-edit :gasPrice "0.00000000001"))]
(testing "it marks gasPrice as invalid"
(is (get-in actual [:gasPrice :error])))
(testing "it does not change value"
(is (= "0.00000000001" (get-in actual [:gasPrice :value]))))
(testing "it marks gas as invalid"
(is (get-in actual [:gas :error])))
(testing "it does not change gas value"
(is (= "invalid" (get-in actual [:gas :value]))))
(testing "it sets max-fee to 0"
(is (= "0" (:max-fee actual))))))
(testing "gas price in wei should be round"
(let [actual (-> {}
(signing.gas/build-edit :gas "21000")
(signing.gas/build-edit :gasPrice "0.0000000023"))]
(is (get-in actual [:gasPrice :error]))))
(testing "an valid edit"
(let [actual (-> {}
(signing.gas/build-edit :gas "21000")
(signing.gas/build-edit :gasPrice "10"))]
(testing "it does not mark gas-price as invalid"
(is (not (get-in actual [:gasPrice :error]))))
(testing "it sets the value in number for gas-price, in gwei"
(is (= "10000000000" (str (get-in actual [:gasPrice :value-number])))))
(testing "it does not mark gas as invalid"
(is (not (get-in actual [:gas :error]))))
(testing "it sets the value in number for gasi"
(is (= "21000" (str (get-in actual [:gas :value-number])))))
(testing "it calculates max-fee"
(is (= "0.00021" (:max-fee actual)))))))
+120
View File
@@ -0,0 +1,120 @@
(ns legacy.status-im.signing.keycard
(:require
[legacy.status-im.utils.deprecated-types :as types]
[native-module.core :as native-module]
[re-frame.core :as re-frame]
[taoensso.timbre :as log]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(re-frame/reg-fx
::hash-transaction
(fn [{:keys [transaction on-completed]}]
(native-module/hash-transaction (types/clj->json transaction) on-completed)))
(re-frame/reg-fx
::hash-message
(fn [{:keys [message on-completed]}]
(native-module/hash-message message on-completed)))
(re-frame/reg-fx
::hash-typed-data
(fn [{:keys [v4 data on-completed]}]
(if v4
(native-module/hash-typed-data-v4 data on-completed)
(native-module/hash-typed-data data on-completed))))
(defn prepare-transaction
[{:keys [gas gasPrice data nonce tx-obj] :as params}]
(let [{:keys [from to value chat-id message-id command? maxPriorityFeePerGas maxFeePerGas]} tx-obj
maxPriorityFeePerGas (or maxPriorityFeePerGas (get params :maxPriorityFeePerGas))
maxFeePerGas (or maxFeePerGas (get params :maxFeePerGas))]
(cond-> {:from from
:to to
:value value
:chat-id chat-id
:message-id message-id
:command? command?}
maxPriorityFeePerGas
(assoc :maxPriorityFeePerGas
(str "0x"
(native-module/number-to-hex
(js/parseInt maxPriorityFeePerGas))))
maxFeePerGas
(assoc :maxFeePerGas
(str "0x"
(native-module/number-to-hex
(js/parseInt maxFeePerGas))))
gas
(assoc :gas (str "0x" (native-module/number-to-hex gas)))
gasPrice
(assoc :gasPrice (str "0x" (native-module/number-to-hex gasPrice)))
data
(assoc :data data)
nonce
(assoc :nonce nonce))))
(rf/defn hash-message
[_ {:keys [v4 data typed? on-completed]}]
(if typed?
{::hash-typed-data
{:data data
:v4 v4
:on-completed
(or on-completed
#(re-frame/dispatch
[:signing.keycard.callback/hash-message-completed
data typed? %]))}}
{::hash-message
{:message data
:on-completed
(or on-completed
#(re-frame/dispatch
[:signing.keycard.callback/hash-message-completed
data typed? %]))}}))
(rf/defn hash-message-completed
{:events [:signing.keycard.callback/hash-message-completed]}
[{:keys [db]} data typed? result]
(let [{:keys [result error]} (types/json->clj result)]
(if error
{:dispatch [:signing.ui/cancel-is-pressed]
:effects.utils/show-popup {:title (i18n/label :t/sign-request-failed)
:content (:message error)}}
{:db (update db
:keycard assoc
:hash result
:typed? typed?
:data data)})))
(rf/defn hash-transaction
[{:keys [db]}]
(let [tx (prepare-transaction (:signing/tx db))]
(log/debug "hash-transaction" tx)
{::hash-transaction
{:transaction tx
:on-completed #(re-frame/dispatch
[:signing.keycard.callback/hash-transaction-completed tx %])}}))
(rf/defn hash-transaction-completed
{:events [:signing.keycard.callback/hash-transaction-completed]}
[{:keys [db]} original-tx result]
(let [{:keys [transaction hash]} (:result (types/json->clj result))]
{:db (-> db
(assoc-in [:keycard :transaction]
(merge original-tx transaction))
(assoc-in [:keycard :hash] hash))}))
(rf/defn sign-with-keycard
{:events [:signing.ui/sign-with-keycard-pressed]}
[{:keys [db] :as cofx}]
(let [{:keys [message maxPriorityFeePerGas maxFeePerGas]} (get db :signing/tx)]
(rf/merge
cofx
{:db (-> db
(assoc-in [:keycard :pin :enter-step] :sign)
(assoc-in [:signing/sign :type] :keycard)
(assoc-in [:signing/sign :keycard-step] :pin))}
#(if message
(hash-message % message)
(hash-transaction %)))))
+16
View File
@@ -38,6 +38,22 @@
:params []
:on-success [:stickers/stickers-recent-success]})))
(rf/defn load-packs
{:events [:stickers/load-packs]}
[{:keys [db]}]
{:json-rpc/call [{:method "stickers_market"
:params [(chain/chain-id db)]
:on-success #(re-frame/dispatch [:stickers/stickers-market-success %])}
{:method "stickers_installed"
:params []
:on-success #(re-frame/dispatch [:stickers/stickers-installed-success %])}
{:method "stickers_pending"
:params []
:on-success #(re-frame/dispatch [:stickers/stickers-pending-success %])}
{:method "stickers_recent"
:params []
:on-success #(re-frame/dispatch [:stickers/stickers-recent-success %])}]})
(rf/defn pending-pack
{:events [:stickers/pending-pack]}
[{db :db} id]
+32
View File
@@ -0,0 +1,32 @@
(ns legacy.status-im.subs.bootnodes
(:require
[re-frame.core :as re-frame]))
(re-frame/reg-sub
:custom-bootnodes/enabled?
:<- [:profile/profile]
:<- [:networks/current-network]
(fn [[{:keys [custom-bootnodes-enabled?]} current-network]]
(get custom-bootnodes-enabled? current-network)))
(re-frame/reg-sub
:custom-bootnodes/network-bootnodes
:<- [:profile/profile]
:<- [:networks/current-network]
(fn [[multiaccount current-network]]
(get-in multiaccount [:custom-bootnodes current-network])))
(re-frame/reg-sub
:get-manage-bootnode
:<- [:bootnodes/manage]
(fn [manage]
manage))
(re-frame/reg-sub
:wakuv2-nodes/validation-errors
:<- [:wakuv2-nodes/manage]
(fn [manage]
(set (keep
(fn [[k {:keys [error]}]]
(when error k))
manage))))
+210
View File
@@ -0,0 +1,210 @@
(ns legacy.status-im.subs.keycard
(:require
[clojure.string :as string]
[legacy.status-im.keycard.common :as common]
[re-frame.core :as re-frame]
[utils.address :as address]
[utils.datetime :as datetime]))
(re-frame/reg-sub
:keycard/nfc-enabled?
(fn [db]
(get-in db [:keycard :nfc-enabled?])))
(re-frame/reg-sub
:keycard/card-read-in-progress?
(fn [db]
(get-in db [:keycard :card-read-in-progress?] false)))
(re-frame/reg-sub
:keycard-setup-step
(fn [db]
(get-in db [:keycard :setup-step])))
(re-frame/reg-sub
:keycard-card-state
(fn [db]
(get-in db [:keycard :card-state])))
(re-frame/reg-sub
:keycard-flow
(fn [db]
(get-in db [:keycard :flow])))
(re-frame/reg-sub
:keycard-flow-steps
(fn [db]
(case (get-in db [:keycard :flow])
:recovery "2"
"3")))
(re-frame/reg-sub
:keycard-pair-code
(fn [db]
(get-in db [:keycard :secrets :password])))
(re-frame/reg-sub
:keycard-recovery-phrase-word
(fn [db]
(get-in db
[:keycard
:recovery-phrase
(get-in db [:keycard :recovery-phrase :step])])))
(re-frame/reg-sub
:keycard-recovery-phrase-input-word
(fn [db]
(get-in db [:keycard :recovery-phrase :input-word])))
(re-frame/reg-sub
:keycard-recovery-phrase-confirm-error
(fn [db]
(get-in db [:keycard :recovery-phrase :confirm-error])))
(re-frame/reg-sub
:keycard-recovery-phrase-step
(fn [db]
(get-in db [:keycard :recovery-phrase :step])))
(re-frame/reg-sub
:keycard-secrets
(fn [db]
(get-in db [:keycard :secrets])))
(re-frame/reg-sub
:keycard-puk-code
(fn [db]
(->> (get-in db [:keycard :secrets :puk])
(partition 4)
(map string/join)
(string/join " "))))
(re-frame/reg-sub
:keycard-setup-error
(fn [db]
(get-in db [:keycard :setup-error])))
(re-frame/reg-sub
:keycard-mnemonic
(fn [db]
(map-indexed vector
(partition 3
(map-indexed vector
(string/split
(get-in db [:keycard :secrets :mnemonic])
#" "))))))
(re-frame/reg-sub
:keycard-application-info
(fn [db]
(get-in db [:keycard :application-info])))
(re-frame/reg-sub
:keycard-application-info-error
(fn [db]
(get-in db [:keycard :application-info-error])))
(re-frame/reg-sub
:keycard-multiaccount
(fn [db]
(get-in db [:keycard :profile/profile])))
(re-frame/reg-sub
:keycard-multiaccount-wallet-address
(fn [db]
(str "0x" (get-in db [:keycard :multiaccount-wallet-address]))))
(re-frame/reg-sub
:keycard-multiaccount-whisper-public-key
(fn [db]
(address/normalized-hex (get-in db [:keycard :multiaccount-whisper-public-key]))))
(re-frame/reg-sub
:keycard-paired-on
(fn [db]
(some-> (get-in db [:profile/profile :keycard-paired-on])
(datetime/timestamp->year-month-day-date))))
(re-frame/reg-sub
:keycard-multiaccount-pairing
(fn [db]
(get-in db [:profile/profile :keycard-pairing])))
(re-frame/reg-sub
:keycard/pin-retry-counter
(fn [db]
(get-in db [:keycard :application-info :pin-retry-counter])))
(re-frame/reg-sub
:keycard/puk-retry-counter
(fn [db]
(get-in db [:keycard :application-info :puk-retry-counter])))
(re-frame/reg-sub
:keycard/retry-counter
:<- [:keycard/pin-retry-counter]
:<- [:keycard/puk-retry-counter]
(fn [[pin puk]]
(if (zero? pin) puk pin)))
(re-frame/reg-sub
:keycard-reset-card-disabled?
(fn [db]
(get-in db [:keycard :reset-card :disabled?] false)))
(re-frame/reg-sub
:keycard-multiaccount?
common/keycard-multiaccount?)
(re-frame/reg-sub
:keycard/original-pin
(fn [db]
(get-in db [:keycard :pin :original])))
(re-frame/reg-sub
:keycard/login-pin
(fn [db]
(get-in db [:keycard :pin :login])))
(re-frame/reg-sub
:keycard/pin-confirmation
(fn [db]
(get-in db [:keycard :pin :confirmation])))
(re-frame/reg-sub
:keycard/pin-enter-step
(fn [db]
(get-in db [:keycard :pin :enter-step])))
(re-frame/reg-sub
:keycard/pin-operation
(fn [db]
(get-in db [:keycard :pin :operation])))
(re-frame/reg-sub
:keycard/pin-data
(fn [db]
(get-in db [:keycard :pin])))
(re-frame/reg-sub
:keycard/pin
:<- [:keycard/pin-data]
:<- [:keycard/pin-enter-step]
(fn [[pin-data step]]
(get pin-data step)))
(re-frame/reg-sub
:keycard/pin-status
(fn [db]
(get-in db [:keycard :pin :status])))
(re-frame/reg-sub
:keycard/pin-error-label
(fn [db]
(get-in db [:keycard :pin :error-label])))
(re-frame/reg-sub
:keycard/frozen-card?
(fn [db]
(and (common/keycard-multiaccount? db)
(zero? (get-in db [:keycard :application-info :pin-retry-counter])))))
@@ -1,6 +1,7 @@
(ns legacy.status-im.subs.mailservers
(:require
[legacy.status-im.fleet.core :as fleet]
[legacy.status-im.mailserver.core :as mailserver]
[re-frame.core :as re-frame]))
(re-frame/reg-sub
@@ -23,6 +24,12 @@
(fn [state]
(#{:error :disconnected} state)))
(re-frame/reg-sub
:chats/fetching-gap-in-progress?
:<- [:mailserver/fetching-gaps-in-progress]
(fn [gaps [_ ids _]]
(seq (select-keys gaps ids))))
(re-frame/reg-sub
:mailserver/fetching?
:<- [:mailserver/state]
@@ -51,6 +58,11 @@
(= (get-in mailserver [:id :value])
current-mailserver-id)))
(re-frame/reg-sub
:mailserver/use-status-nodes?
(fn [db _]
(boolean (mailserver/fetch-use-mailservers? db))))
(re-frame/reg-sub
:mailserver.edit/validation-errors
:<- [:mailserver.edit/mailserver]
@@ -60,6 +72,15 @@
(when error k))
mailserver))))
(re-frame/reg-sub
:mailserver/connected?
:<- [:mailserver/state]
:<- [:disconnected?]
(fn [[mail-state disconnected?]]
(let [mailserver-connected? (= :connected mail-state)]
(and mailserver-connected?
(not disconnected?)))))
(re-frame/reg-sub
:mailserver/preferred-id
:<- [:profile/profile]
+6
View File
@@ -1,7 +1,9 @@
(ns legacy.status-im.subs.root
(:require
legacy.status-im.subs.bootnodes
legacy.status-im.subs.browser
legacy.status-im.subs.ens
legacy.status-im.subs.keycard
legacy.status-im.subs.mailservers
legacy.status-im.subs.stickers
[re-frame.core :as re-frame]))
@@ -21,6 +23,10 @@
(reg-root-key-sub :peers-summary :peers-summary)
(reg-root-key-sub :web3-node-version :web3-node-version)
;;keycard
(reg-root-key-sub :keycard :keycard)
(reg-root-key-sub :keycard/banner-hidden :keycard/banner-hidden)
;;bottom sheet old
(reg-root-key-sub :bottom-sheet/show? :bottom-sheet/show?)
(reg-root-key-sub :bottom-sheet/view :bottom-sheet/view)
+6
View File
@@ -3,6 +3,12 @@
[re-frame.core :as re-frame]
[status-im.constants :as constants]))
(re-frame/reg-sub
:stickers/installed-packs
:<- [:stickers/packs]
(fn [packs]
(filter #(= (:status %) constants/sticker-pack-status-installed) (vals packs))))
(re-frame/reg-sub
:stickers/all-packs
:<- [:stickers/packs]
@@ -8,7 +8,7 @@
[legacy.status-im.ui.screens.profile.visibility-status.utils :as visibility-status-utils]
[quo.components.avatars.user-avatar.style :as user-avatar.style]
[quo.core :as quo]
[quo.theme]
[quo.theme :as theme]
[re-frame.core :as re-frame.core]
[react-native.core :as rn]
[status-im.contexts.profile.utils :as profile.utils]
@@ -52,8 +52,7 @@
(defn profile-photo-plus-dot-view
[{:keys [public-key full-name customization-color photo-container photo-path community?]}]
(let [theme @(re-frame.core/subscribe [:theme])
photo-container (if (nil? photo-container)
(let [photo-container (if (nil? photo-container)
styles/container-chat-list
photo-container)
size (:width photo-container)
@@ -72,7 +71,8 @@
{:size size
:full-name full-name
:font-size (get text-style :font-size)
:background-color (user-avatar.style/customization-color customization-color theme)
:background-color (user-avatar.style/customization-color customization-color
(theme/get-theme))
:indicator-size 0
:indicator-border 0
:indicator-color "#000000"
@@ -2,7 +2,6 @@
(:require
[legacy.status-im.ui.components.core :as quo]
[quo.foundations.colors :as quo.colors]
[quo.theme]
[re-frame.core :as re-frame]
[react-native.safe-area :as safe-area]))
@@ -33,8 +32,7 @@
:or {border-bottom? true
new-ui? false}
:as props}]
(let [theme (quo.theme/use-theme)
navigation (if (= navigation :none)
(let [navigation (if (= navigation :none)
nil
[(default-navigation modal? navigation)])]
[quo/header
@@ -49,5 +47,4 @@
{:right-accessories right-accessories})
(when new-ui?
{:background (quo.colors/theme-colors quo.colors/neutral-5
quo.colors/neutral-95
theme)}))]))
quo.colors/neutral-95)}))]))
@@ -0,0 +1,30 @@
(ns legacy.status-im.ui.screens.bootnodes-settings.edit-bootnode.styles
(:require
[legacy.status-im.ui.components.colors :as colors]
[legacy.status-im.utils.styles :as styles]))
(def edit-bootnode-view
{:flex 1
:margin-horizontal 16
:margin-vertical 15})
(def button-container
{:margin-top 8
:margin-bottom 16
:margin-horizontal 16})
(styles/def button
{:height 52
:align-items :center
:justify-content :center
:border-radius 8
:ios {:opacity 0.9}})
(def button-label
{:color colors/white-persist
:font-size 17})
(def delete-button
(assoc button
:background-color
colors/red))
@@ -0,0 +1,76 @@
(ns legacy.status-im.ui.screens.bootnodes-settings.edit-bootnode.views
(:require
[clojure.string :as string]
[legacy.status-im.qr-scanner.core :as qr-scanner]
[legacy.status-im.ui.components.core :as quo]
[legacy.status-im.ui.components.react :as react]
[legacy.status-im.ui.components.toolbar :as toolbar]
[legacy.status-im.ui.components.topbar :as topbar]
[legacy.status-im.ui.screens.bootnodes-settings.edit-bootnode.styles :as styles]
[re-frame.core :as re-frame]
[utils.i18n :as i18n])
(:require-macros [legacy.status-im.utils.views :as views]))
(defn delete-button
[id]
[react/touchable-highlight {:on-press #(re-frame/dispatch [:bootnodes.ui/delete-pressed id])}
[react/view styles/button-container
[react/view
{:style styles/delete-button
:accessibility-label :bootnode-delete-button}
[react/text {:style styles/button-label}
(i18n/label :t/delete)]]]])
(views/defview edit-bootnode
[]
(views/letsubs [manage-bootnode [:get-manage-bootnode]
validation-errors [:wakuv2-nodes/validation-errors]]
(let [url (get-in manage-bootnode [:url :value])
id (get-in manage-bootnode [:id :value])
name (get-in manage-bootnode [:name :value])
is-valid? (empty? validation-errors)
invalid-url? (contains? validation-errors :url)]
[react/keyboard-avoiding-view
{:style {:flex 1}
:ignore-offset true}
[topbar/topbar {:title (i18n/label (if id :t/bootnode-details :t/add-bootnode))}]
[react/scroll-view {:keyboard-should-persist-taps :handled}
[react/view styles/edit-bootnode-view
[react/view {:padding-vertical 8}
[quo/text-input
{:label (i18n/label :t/name)
:placeholder (i18n/label :t/specify-name)
:accessibility-label :bootnode-name
:default-value name
:on-change-text #(re-frame/dispatch [:bootnodes.ui/input-changed :name %])
:auto-focus true}]]
[react/view
{:flex 1
:padding-vertical 8}
[quo/text-input
(merge
{:label (i18n/label :t/bootnode-address)
:placeholder (i18n/label :t/bootnode-format)
:accessibility-label :bootnode-address
:default-value url
:show-cancel false
:on-change-text #(re-frame/dispatch [:bootnodes.ui/input-changed :url %])
:error (when (and (not (string/blank? url)) invalid-url?)
(i18n/label :t/invalid-format
{:format (i18n/label :t/bootnode-format)}))
:bottom-value 0
:after {:icon :main-icons/qr
:on-press #(re-frame/dispatch
[::qr-scanner/scan-code
{:title (i18n/label :t/add-bootnode)
:handler :bootnodes.callback/qr-code-scanned}])}})]]
(when id
[delete-button id])]]
[toolbar/toolbar
{:right
[quo/button
{:type :secondary
:after :main-icon/next
:disabled (not is-valid?)
:on-press #(re-frame/dispatch [:bootnodes.ui/save-pressed])}
(i18n/label :t/save)]}]])))

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