Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08735b6933 |
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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'
|
||||
}
|
||||
} }
|
||||
}
|
||||
|
||||
@@ -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'
|
||||
}
|
||||
} }
|
||||
}
|
||||
|
||||
@@ -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'
|
||||
}
|
||||
} }
|
||||
}
|
||||
|
||||
@@ -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
@@ -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?
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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 = "";
|
||||
|
||||
+2
-2
@@ -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)
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
-133
@@ -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"
|
||||
}
|
||||
|
||||
}
|
||||
-1
@@ -74,5 +74,4 @@ class NetworkManager(private val reactContext: ReactApplicationContext) : ReactC
|
||||
fun recover(rpcParams: String, callback: Callback) {
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.recover(rpcParams) }, callback)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
@@ -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)
|
||||
|
||||
-1
@@ -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
@@ -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
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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}"
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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": {
|
||||
|
||||
@@ -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'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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'
|
||||
@@ -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
|
||||
@@ -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'
|
||||
@@ -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.
|
||||
@@ -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,
|
||||
@@ -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 |
@@ -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
|
||||
|
||||
@@ -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})
|
||||
@@ -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}]))]))]))
|
||||
@@ -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)
|
||||
|
||||
@@ -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]})
|
||||
|
||||
@@ -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.")}}})))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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])))
|
||||
@@ -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))
|
||||
@@ -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
|
||||
|
||||
@@ -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]}
|
||||
|
||||
@@ -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)))
|
||||
@@ -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))))))
|
||||
@@ -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})))))
|
||||
@@ -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))))
|
||||
@@ -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)
|
||||
@@ -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)})))
|
||||
@@ -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)))
|
||||
@@ -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)}))
|
||||
@@ -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]])
|
||||
@@ -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]}
|
||||
|
||||
@@ -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))))
|
||||
|
||||
|
||||
|
||||
@@ -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}}))))))))))
|
||||
@@ -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)))
|
||||
@@ -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)))))))
|
||||
@@ -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 %)))))
|
||||
@@ -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]
|
||||
|
||||
@@ -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))))
|
||||
@@ -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]
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user