Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3fd33d63a | ||
|
|
08fea7fe5f | ||
|
|
792caf5259 | ||
|
|
c02d97d380 | ||
|
|
3001fa91e9 | ||
|
|
2714c7b9e5 | ||
|
|
307155a4ca | ||
|
|
a5ef314d6a | ||
|
|
2ba16e6762 | ||
|
|
6acda08ebb | ||
|
|
90166ad45a | ||
|
|
ef8490961a | ||
|
|
e4ae78bb25 | ||
|
|
ea07780e9c | ||
|
|
ff569f328a | ||
|
|
e4b42fc0ca | ||
|
|
9397dd46e8 | ||
|
|
34d6b3c1d5 | ||
|
|
3c7d299ef7 | ||
|
|
43a8be9d52 | ||
|
|
adff7a5120 | ||
|
|
4db4b5c84b | ||
|
|
23d84a54fc | ||
|
|
5d51ae55b5 | ||
|
|
d51d88fc0b | ||
|
|
bf8fa45e52 | ||
|
|
077b885617 | ||
|
|
2e42da5996 | ||
|
|
f6dc9d1ad3 | ||
|
|
9f1eb60e21 | ||
|
|
8e7d5233df | ||
|
|
4f40fda6a3 | ||
|
|
f0079961f4 | ||
|
|
9862abb7eb | ||
|
|
6d7697870d | ||
|
|
4f53a2b11e | ||
|
|
fd9e8273e1 | ||
|
|
6afaba23b5 |
@@ -1,6 +1,5 @@
|
||||
CACHED_WEBVIEWS_ENABLED=1
|
||||
DEBUG_WEBVIEW=1
|
||||
DEFAULT_NETWORK=mainnet_rpc
|
||||
DEV_BUILD=1
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
DEBUG_WEBVIEW=1
|
||||
DEFAULT_NETWORK=goerli_rpc
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
FLEET=status.staging
|
||||
@@ -22,8 +21,8 @@ KEYCARD_TEST_MENU=1
|
||||
QR_READ_TEST_MENU=1
|
||||
ENABLE_ROOT_ALERT=0
|
||||
APN_TOPIC=im.status.ethereum.pr
|
||||
VERIFY_TRANSACTION_CHAIN_ID=5
|
||||
VERIFY_ENS_CHAIN_ID=5
|
||||
VERIFY_TRANSACTION_CHAIN_ID=11155111
|
||||
VERIFY_ENS_CHAIN_ID=11155111
|
||||
TEST_STATEOFUS=1
|
||||
DATABASE_MANAGEMENT_ENABLED=1
|
||||
COMMUNITIES_ENABLED=1
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
CACHED_WEBVIEWS_ENABLED=1
|
||||
DEBUG_WEBVIEW=1
|
||||
DEFAULT_NETWORK=goerli_rpc
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
GROUP_CHATS_ENABLED=1
|
||||
@@ -21,8 +20,8 @@ KEYCARD_TEST_MENU=0
|
||||
ENABLE_ROOT_ALERT=1
|
||||
DISABLE_WALLET_ON_MOBILE_NETWORK=1
|
||||
APN_TOPIC=im.status.ethereum.pr
|
||||
VERIFY_TRANSACTION_CHAIN_ID=5
|
||||
VERIFY_ENS_CHAIN_ID=5
|
||||
VERIFY_TRANSACTION_CHAIN_ID=11155111
|
||||
VERIFY_ENS_CHAIN_ID=11155111
|
||||
TEST_STATEOFUS=1
|
||||
BLANK_PREVIEW=0
|
||||
DATABASE_MANAGEMENT_ENABLED=1
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
DEBUG_WEBVIEW=1
|
||||
DEFAULT_NETWORK=mainnet_rpc
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
GROUP_CHATS_ENABLED=1
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
DEBUG_WEBVIEW=0
|
||||
DEFAULT_NETWORK=mainnet_rpc
|
||||
ETHEREUM_DEV_CLUSTER=0
|
||||
EXTENSIONS=0
|
||||
GROUP_CHATS_ENABLED=1
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name: Bug Report
|
||||
about: Bug Report
|
||||
title: ''
|
||||
labels: ['bug', ':1234: low prio']
|
||||
type: 'Bug'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
initscript {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.gradle:github-dependency-graph-gradle-plugin:+"
|
||||
}
|
||||
}
|
||||
apply plugin: org.gradle.dependencygraph.simple.SimpleDependencyGraphPlugin
|
||||
@@ -1,12 +1,12 @@
|
||||
pluginManagement {
|
||||
include ':react-native-share'
|
||||
project(':react-native-share').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-share/android')
|
||||
includeBuild('../node_modules/@react-native/gradle-plugin')
|
||||
repositories {
|
||||
mavenLocal() // Let's prioritize local Maven repos so that Nix can provide them offline
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
include ':react-native-share'
|
||||
project(':react-native-share').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-share/android')
|
||||
rootProject.name = 'StatusIm'
|
||||
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
|
||||
include ':react-native-nfc-manager'
|
||||
|
||||
@@ -92,7 +92,7 @@ For particular example it was failed on `Recover access(password:qwerty, keycard
|
||||
Not all features of the app could be covered by e2e at the moment:
|
||||
|
||||
- Colours or place of an element on UI.
|
||||
- Real ETH/token transactions. That’s the main reason we have separate .apk build for automation needs - it defaults to Goerli network. Also it has enabled keycard test menu, ENS names and chat commands are also on Goerli network (the same in PR builds, but not in nightlies / release)
|
||||
- Real ETH/token transactions. That’s the main reason we have separate .apk build for automation needs - it defaults to Sepolia network. Also it has enabled keycard test menu, ENS names and chat commands are also on Sepolia network (the same in PR builds, but not in nightlies / release)
|
||||
- Autologin/Biometric related actions (autologin available when device meets certain conditions like the it has set unlock password and device is not rooted: all emulators are rooted in SauceLabs)
|
||||
|
||||
## Brief flow for test to be automated
|
||||
|
||||
@@ -14,9 +14,8 @@ RCT_EXPORT_MODULE();
|
||||
RCT_EXPORT_METHOD(sendLogs:(NSString *)dbJson
|
||||
jsLogs:(NSString *)jsLogs
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
// TODO: Implement SendLogs for iOS
|
||||
#if DEBUG
|
||||
NSLog(@"SendLogs() method called, not implemented");
|
||||
NSLog(@"SendLogs() method called");
|
||||
#endif
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSError *error = nil;
|
||||
@@ -34,25 +33,6 @@ RCT_EXPORT_METHOD(sendLogs:(NSString *)dbJson
|
||||
|
||||
NSURL *dbFile = [logsFolderName URLByAppendingPathComponent:@"db.json"];
|
||||
NSURL *jsLogsFile = [logsFolderName URLByAppendingPathComponent:@"Status.log"];
|
||||
#if DEBUG
|
||||
NSString *networkDirPath = @"ethereum/mainnet_rpc_dev";
|
||||
#else
|
||||
NSString *networkDirPath = @"ethereum/mainnet_rpc";
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
NSString *goerliNetworkDirPath = @"ethereum/goerli_rpc_dev";
|
||||
#else
|
||||
NSString *goerliNetworkDirPath = @"ethereum/goerli_rpc";
|
||||
#endif
|
||||
|
||||
NSURL *networkDir = [rootUrl URLByAppendingPathComponent:networkDirPath];
|
||||
NSURL *originalGethLogsFile = [networkDir URLByAppendingPathComponent:@"geth.log"];
|
||||
NSURL *gethLogsFile = [logsFolderName URLByAppendingPathComponent:@"mainnet_geth.log"];
|
||||
|
||||
NSURL *goerliNetworkDir = [rootUrl URLByAppendingPathComponent:goerliNetworkDirPath];
|
||||
NSURL *goerliGethLogsFile = [goerliNetworkDir URLByAppendingPathComponent:@"geth.log"];
|
||||
NSURL *goerliLogsFile = [logsFolderName URLByAppendingPathComponent:@"goerli_geth.log"];
|
||||
|
||||
NSURL *mainGethLogsFile = [rootUrl URLByAppendingPathComponent:@"geth.log"];
|
||||
NSURL *mainLogsFile = [logsFolderName URLByAppendingPathComponent:@"geth.log"];
|
||||
@@ -62,10 +42,6 @@ RCT_EXPORT_METHOD(sendLogs:(NSString *)dbJson
|
||||
[dbJson writeToFile:dbFile.path atomically:YES encoding:NSUTF8StringEncoding error:nil];
|
||||
[jsLogs writeToFile:jsLogsFile.path atomically:YES encoding:NSUTF8StringEncoding error:nil];
|
||||
|
||||
//NSString* gethLogs = StatusgoExportNodeLogs();
|
||||
//[gethLogs writeToFile:gethLogsFile.path atomically:YES encoding:NSUTF8StringEncoding error:nil];
|
||||
[fileManager copyItemAtPath:originalGethLogsFile.path toPath:gethLogsFile.path error:nil];
|
||||
[fileManager copyItemAtPath:goerliGethLogsFile.path toPath:goerliLogsFile.path error:nil];
|
||||
[fileManager copyItemAtPath:mainGethLogsFile.path toPath:mainLogsFile.path error:nil];
|
||||
|
||||
if ([fileManager fileExistsAtPath:requestsLogFile.path]) {
|
||||
|
||||
@@ -315,6 +315,7 @@ com.android.tools.build:gradle:7.0.4
|
||||
com.android.tools.build:gradle:7.2.1
|
||||
com.android.tools.build:gradle:7.3.1
|
||||
com.android.tools.build:gradle:7.4.2
|
||||
com.android.tools.build:gradle:8.1.1
|
||||
com.android.tools.build:manifest-merger:24.3.1
|
||||
com.android.tools.build:manifest-merger:24.5.0
|
||||
com.android.tools.build:manifest-merger:26.0.1
|
||||
@@ -339,6 +340,7 @@ com.android.tools.ddms:ddmlib:30.2.1
|
||||
com.android.tools.ddms:ddmlib:30.3.1
|
||||
com.android.tools.ddms:ddmlib:30.4.2
|
||||
com.android.tools.ddms:ddmlib:31.1.1
|
||||
com.android.tools.emulator:proto:31.1.1
|
||||
com.android.tools.external.com-intellij:intellij-core:26.0.1
|
||||
com.android.tools.external.lombok:lombok-ast:0.2.3
|
||||
com.android.tools.external.org-jetbrains:uast:26.0.1
|
||||
@@ -381,32 +383,43 @@ com.android.tools.utp:android-device-provider-ddmlib-proto:30.2.1
|
||||
com.android.tools.utp:android-device-provider-ddmlib-proto:30.3.1
|
||||
com.android.tools.utp:android-device-provider-ddmlib-proto:30.4.2
|
||||
com.android.tools.utp:android-device-provider-ddmlib-proto:31.1.1
|
||||
com.android.tools.utp:android-device-provider-ddmlib:31.1.1
|
||||
com.android.tools.utp:android-device-provider-gradle-proto:30.0.4
|
||||
com.android.tools.utp:android-device-provider-gradle-proto:30.2.1
|
||||
com.android.tools.utp:android-device-provider-gradle-proto:30.3.1
|
||||
com.android.tools.utp:android-device-provider-gradle-proto:30.4.2
|
||||
com.android.tools.utp:android-device-provider-gradle-proto:31.1.1
|
||||
com.android.tools.utp:android-device-provider-gradle:31.1.1
|
||||
com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.2.1
|
||||
com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.3.1
|
||||
com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:30.4.2
|
||||
com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:31.1.1
|
||||
com.android.tools.utp:android-test-plugin-host-additional-test-output:31.1.1
|
||||
com.android.tools.utp:android-test-plugin-host-apk-installer-proto:31.1.1
|
||||
com.android.tools.utp:android-test-plugin-host-apk-installer:31.1.1
|
||||
com.android.tools.utp:android-test-plugin-host-coverage-proto:30.2.1
|
||||
com.android.tools.utp:android-test-plugin-host-coverage-proto:30.3.1
|
||||
com.android.tools.utp:android-test-plugin-host-coverage-proto:30.4.2
|
||||
com.android.tools.utp:android-test-plugin-host-coverage-proto:31.1.1
|
||||
com.android.tools.utp:android-test-plugin-host-coverage:31.1.1
|
||||
com.android.tools.utp:android-test-plugin-host-device-info-proto:31.1.1
|
||||
com.android.tools.utp:android-test-plugin-host-device-info:31.1.1
|
||||
com.android.tools.utp:android-test-plugin-host-emulator-control-proto:31.1.1
|
||||
com.android.tools.utp:android-test-plugin-host-emulator-control:31.1.1
|
||||
com.android.tools.utp:android-test-plugin-host-logcat-proto:31.1.1
|
||||
com.android.tools.utp:android-test-plugin-host-logcat:31.1.1
|
||||
com.android.tools.utp:android-test-plugin-host-retention-proto:30.0.4
|
||||
com.android.tools.utp:android-test-plugin-host-retention-proto:30.2.1
|
||||
com.android.tools.utp:android-test-plugin-host-retention-proto:30.3.1
|
||||
com.android.tools.utp:android-test-plugin-host-retention-proto:30.4.2
|
||||
com.android.tools.utp:android-test-plugin-host-retention-proto:31.1.1
|
||||
com.android.tools.utp:android-test-plugin-host-retention:31.1.1
|
||||
com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.0.4
|
||||
com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.2.1
|
||||
com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.3.1
|
||||
com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:30.4.2
|
||||
com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:31.1.1
|
||||
com.android.tools.utp:android-test-plugin-result-listener-gradle:31.1.1
|
||||
com.android.tools:annotations:24.3.1
|
||||
com.android.tools:annotations:24.5.0
|
||||
com.android.tools:annotations:26.0.1
|
||||
@@ -574,6 +587,7 @@ com.google.code.gson:gson:2.8.0
|
||||
com.google.code.gson:gson:2.8.5
|
||||
com.google.code.gson:gson:2.8.6
|
||||
com.google.code.gson:gson:2.8.9
|
||||
com.google.code.gson:gson:2.9.1
|
||||
com.google.crypto.tink:tink:1.3.0-rc2
|
||||
com.google.crypto.tink:tink:1.7.0
|
||||
com.google.dagger:dagger:2.28.3
|
||||
@@ -583,6 +597,7 @@ com.google.errorprone:error_prone_annotations:2.3.1
|
||||
com.google.errorprone:error_prone_annotations:2.3.2
|
||||
com.google.errorprone:error_prone_annotations:2.3.4
|
||||
com.google.errorprone:error_prone_annotations:2.4.0
|
||||
com.google.errorprone:error_prone_annotations:2.7.1
|
||||
com.google.errorprone:error_prone_annotations:2.9.0
|
||||
com.google.errorprone:error_prone_annotations:2.11.0
|
||||
com.google.flatbuffers:flatbuffers-java:1.12.0
|
||||
@@ -594,6 +609,7 @@ com.google.guava:guava:27.0.1-jre
|
||||
com.google.guava:guava:28.1-jre
|
||||
com.google.guava:guava:29.0-jre
|
||||
com.google.guava:guava:30.1-jre
|
||||
com.google.guava:guava:31.0.1-jre
|
||||
com.google.guava:guava:31.1-jre
|
||||
com.google.guava:listenablefuture:1.0
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
|
||||
@@ -610,9 +626,14 @@ com.google.protobuf:protobuf-java:3.4.0
|
||||
com.google.protobuf:protobuf-java:3.10.0
|
||||
com.google.protobuf:protobuf-java:3.17.2
|
||||
com.google.protobuf:protobuf-java:3.19.3
|
||||
com.google.testing.platform:android-device-provider-local:0.0.8-alpha08
|
||||
com.google.testing.platform:android-driver-instrumentation:0.0.8-alpha08
|
||||
com.google.testing.platform:android-test-plugin:0.0.8-alpha08
|
||||
com.google.testing.platform:core-proto:0.0.8-alpha04
|
||||
com.google.testing.platform:core-proto:0.0.8-alpha07
|
||||
com.google.testing.platform:core-proto:0.0.8-alpha08
|
||||
com.google.testing.platform:core:0.0.8-alpha08
|
||||
com.google.testing.platform:launcher:0.0.8-alpha08
|
||||
com.google.test.platform:core-proto:0.0.2-dev
|
||||
com.google.zxing:core:3.4.1
|
||||
com.ibm.icu:icu4j:53.1
|
||||
@@ -785,6 +806,8 @@ org.glassfish.jaxb:jaxb-runtime:2.3.2
|
||||
org.glassfish.jaxb:txw2:2.2.11
|
||||
org.glassfish.jaxb:txw2:2.3.1
|
||||
org.glassfish.jaxb:txw2:2.3.2
|
||||
org.gradle.toolchains:foojay-resolver:0.5.0
|
||||
org.gradle:github-dependency-graph-gradle-plugin:1.3.1
|
||||
org.hamcrest:hamcrest-core:1.3
|
||||
org.hamcrest:hamcrest:2.2
|
||||
org.jacoco:org.jacoco.core:0.7.4.201502262128
|
||||
@@ -798,45 +821,64 @@ org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.1
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.3
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.7.3
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.1
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.3
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.3
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3
|
||||
org.jetbrains.kotlin:kotlin-android-extensions:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-android-extensions:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-android-extensions:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-annotations-jvm:1.3.72
|
||||
org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-build-common:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-build-common:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-build-tools-impl:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-daemon-client:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-gradle-plugins-bom:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-gradle-plugin-annotations:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-native-utils:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-native-utils:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-native-utils:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-project-model:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-project-model:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-project-model:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-reflect:1.1.3-2
|
||||
org.jetbrains.kotlin:kotlin-reflect:1.2.0
|
||||
@@ -848,13 +890,18 @@ org.jetbrains.kotlin:kotlin-reflect:1.6.10
|
||||
org.jetbrains.kotlin:kotlin-reflect:1.7.10
|
||||
org.jetbrains.kotlin:kotlin-reflect:1.8.20-RC2
|
||||
org.jetbrains.kotlin:kotlin-scripting-common:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-scripting-common:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-scripting-common:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-scripting-jvm:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-scripting-jvm:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.2.71
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.3.50
|
||||
@@ -863,6 +910,7 @@ org.jetbrains.kotlin:kotlin-stdlib-common:1.4.32
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.20-RC2
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.8.21
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.0
|
||||
@@ -874,6 +922,7 @@ org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.32
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.20-RC2
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.21
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0
|
||||
@@ -883,6 +932,7 @@ org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.72
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.32
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.20-RC2
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.21
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0
|
||||
@@ -894,15 +944,19 @@ org.jetbrains.kotlin:kotlin-stdlib:1.4.32
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.5.31
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.7.10
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.8.20-RC2
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.8.21
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.9.22
|
||||
org.jetbrains.kotlin:kotlin-tooling-core:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-tooling-core:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-tooling-metadata:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-util-io:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-util-io:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-util-io:1.9.0
|
||||
org.jetbrains.kotlin:kotlin-util-klib:1.6.20
|
||||
org.jetbrains.kotlin:kotlin-util-klib:1.8.0
|
||||
org.jetbrains.kotlin:kotlin-util-klib:1.9.0
|
||||
org.jetbrains.trove4j:trove4j:20160824
|
||||
org.jetbrains:annotations:13.0
|
||||
@@ -964,20 +1018,8 @@ org.tensorflow:tensorflow-lite-metadata:0.1.0-rc1
|
||||
org.tensorflow:tensorflow-lite-metadata:0.1.0-rc2
|
||||
xerces:xercesImpl:2.12.0
|
||||
xml-apis:xml-apis:1.4.01
|
||||
com.android.tools.build:gradle:1.3.1
|
||||
com.squareup.okio:okio:1.13.0
|
||||
com.squareup.okio:okio:1.15.0
|
||||
com.squareup.okhttp3:okhttp:3.12.1
|
||||
org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:1.7.22
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2
|
||||
org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:1.9.0
|
||||
org.gradle.toolchains.foojay-resolver-convention:org.gradle.toolchains.foojay-resolver-convention.gradle.plugin:0.5.0
|
||||
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
|
||||
androidx.annotation:annotation:1.6.0
|
||||
androidx.annotation:annotation-jvm:1.6.0
|
||||
com.android.tools.lint:lint-gradle:31.1.1
|
||||
com.facebook.react:hermes-android:0.73.5
|
||||
@@ -416,6 +416,7 @@ https://dl.google.com/dl/android/maven2/com/android/tools/dvlib/30.2.1/dvlib-30.
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/dvlib/30.3.1/dvlib-30.3.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/dvlib/30.4.2/dvlib-30.4.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/dvlib/31.1.1/dvlib-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/emulator/proto/31.1.1/proto-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/external/com-intellij/intellij-core/26.0.1/intellij-core-26.0.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/external/com-intellij/intellij-core/31.1.1/intellij-core-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/external/com-intellij/kotlin-compiler/31.1.1/kotlin-compiler-31.1.1.pom
|
||||
@@ -487,32 +488,43 @@ https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-device-pro
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-device-provider-ddmlib-proto/30.3.1/android-device-provider-ddmlib-proto-30.3.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-device-provider-ddmlib-proto/30.4.2/android-device-provider-ddmlib-proto-30.4.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-device-provider-ddmlib-proto/31.1.1/android-device-provider-ddmlib-proto-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-device-provider-ddmlib/31.1.1/android-device-provider-ddmlib-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-device-provider-gradle-proto/30.0.4/android-device-provider-gradle-proto-30.0.4.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-device-provider-gradle-proto/30.2.1/android-device-provider-gradle-proto-30.2.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-device-provider-gradle-proto/30.3.1/android-device-provider-gradle-proto-30.3.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-device-provider-gradle-proto/30.4.2/android-device-provider-gradle-proto-30.4.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-device-provider-gradle-proto/31.1.1/android-device-provider-gradle-proto-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-device-provider-gradle/31.1.1/android-device-provider-gradle-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-additional-test-output-proto/30.2.1/android-test-plugin-host-additional-test-output-proto-30.2.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-additional-test-output-proto/30.3.1/android-test-plugin-host-additional-test-output-proto-30.3.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-additional-test-output-proto/30.4.2/android-test-plugin-host-additional-test-output-proto-30.4.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-additional-test-output-proto/31.1.1/android-test-plugin-host-additional-test-output-proto-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-additional-test-output/31.1.1/android-test-plugin-host-additional-test-output-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-apk-installer-proto/31.1.1/android-test-plugin-host-apk-installer-proto-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-apk-installer/31.1.1/android-test-plugin-host-apk-installer-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-coverage-proto/30.2.1/android-test-plugin-host-coverage-proto-30.2.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-coverage-proto/30.3.1/android-test-plugin-host-coverage-proto-30.3.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-coverage-proto/30.4.2/android-test-plugin-host-coverage-proto-30.4.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-coverage-proto/31.1.1/android-test-plugin-host-coverage-proto-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-coverage/31.1.1/android-test-plugin-host-coverage-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-device-info-proto/31.1.1/android-test-plugin-host-device-info-proto-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-device-info/31.1.1/android-test-plugin-host-device-info-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-emulator-control-proto/31.1.1/android-test-plugin-host-emulator-control-proto-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-emulator-control/31.1.1/android-test-plugin-host-emulator-control-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-logcat-proto/31.1.1/android-test-plugin-host-logcat-proto-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-logcat/31.1.1/android-test-plugin-host-logcat-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-retention-proto/30.0.4/android-test-plugin-host-retention-proto-30.0.4.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-retention-proto/30.2.1/android-test-plugin-host-retention-proto-30.2.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-retention-proto/30.3.1/android-test-plugin-host-retention-proto-30.3.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-retention-proto/30.4.2/android-test-plugin-host-retention-proto-30.4.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-retention-proto/31.1.1/android-test-plugin-host-retention-proto-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-host-retention/31.1.1/android-test-plugin-host-retention-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-result-listener-gradle-proto/30.0.4/android-test-plugin-result-listener-gradle-proto-30.0.4.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-result-listener-gradle-proto/30.2.1/android-test-plugin-result-listener-gradle-proto-30.2.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-result-listener-gradle-proto/30.3.1/android-test-plugin-result-listener-gradle-proto-30.3.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-result-listener-gradle-proto/30.4.2/android-test-plugin-result-listener-gradle-proto-30.4.2.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-result-listener-gradle-proto/31.1.1/android-test-plugin-result-listener-gradle-proto-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/tools/utp/android-test-plugin-result-listener-gradle/31.1.1/android-test-plugin-result-listener-gradle-31.1.1.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/zipflinger/4.1.0/zipflinger-4.1.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/zipflinger/7.0.4/zipflinger-7.0.4.pom
|
||||
https://dl.google.com/dl/android/maven2/com/android/zipflinger/7.2.1/zipflinger-7.2.1.pom
|
||||
@@ -522,9 +534,14 @@ https://dl.google.com/dl/android/maven2/com/android/zipflinger/8.1.1/zipflinger-
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/material/material/1.0.0/material-1.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/android/material/material/1.2.0-alpha03/material-1.2.0-alpha03.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/prefab/cli/2.0.0/cli-2.0.0.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/testing/platform/android-device-provider-local/0.0.8-alpha08/android-device-provider-local-0.0.8-alpha08.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/testing/platform/android-driver-instrumentation/0.0.8-alpha08/android-driver-instrumentation-0.0.8-alpha08.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/testing/platform/android-test-plugin/0.0.8-alpha08/android-test-plugin-0.0.8-alpha08.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/testing/platform/core-proto/0.0.8-alpha04/core-proto-0.0.8-alpha04.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/testing/platform/core-proto/0.0.8-alpha07/core-proto-0.0.8-alpha07.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/testing/platform/core-proto/0.0.8-alpha08/core-proto-0.0.8-alpha08.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/testing/platform/core/0.0.8-alpha08/core-0.0.8-alpha08.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/testing/platform/launcher/0.0.8-alpha08/launcher-0.0.8-alpha08.pom
|
||||
https://dl.google.com/dl/android/maven2/com/google/test/platform/core-proto/0.0.2-dev/core-proto-0.0.2-dev.pom
|
||||
https://jitpack.io/com/github/Dimezis/BlurView/version-2.0.4/BlurView-version-2.0.4.pom
|
||||
https://jitpack.io/com/github/status-im/function/0.0.1/function-0.0.1.pom
|
||||
@@ -535,6 +552,7 @@ https://jitpack.io/com/github/wix-playground/reflow-animator/1.0.6/reflow-animat
|
||||
https://jitpack.io/com/github/yalantis/ucrop/2.2.6-native/ucrop-2.2.6-native.pom
|
||||
https://jitpack.io/com/github/zacharee/AndroidPdfViewer/4.0.1/AndroidPdfViewer-4.0.1.pom
|
||||
https://plugins.gradle.org/m2/com/adarshr/gradle-test-logger-plugin/2.0.0/gradle-test-logger-plugin-2.0.0.pom
|
||||
https://plugins.gradle.org/m2/org/gradle/github-dependency-graph-gradle-plugin/1.3.1/github-dependency-graph-gradle-plugin-1.3.1.pom
|
||||
https://plugins.gradle.org/m2/org/gradle/toolchains/foojay-resolver-convention/org.gradle.toolchains.foojay-resolver-convention.gradle.plugin/0.5.0/org.gradle.toolchains.foojay-resolver-convention.gradle.plugin-0.5.0.pom
|
||||
https://plugins.gradle.org/m2/org/gradle/toolchains/foojay-resolver/0.5.0/foojay-resolver-0.5.0.pom
|
||||
https://repo.maven.apache.org/maven2/antlr/antlr/2.7.1/antlr-2.7.1.pom
|
||||
@@ -733,7 +751,7 @@ https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotatio
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.10.0/error_prone_annotations-2.10.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.11.0/error_prone_annotations-2.11.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.27.0/error_prone_annotations-2.27.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.33.0/error_prone_annotations-2.33.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.35.1/error_prone_annotations-2.35.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.0.18/error_prone_parent-2.0.18.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.2.0/error_prone_parent-2.2.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.3.1/error_prone_parent-2.3.1.pom
|
||||
@@ -746,7 +764,7 @@ https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.10.0/error_prone_parent-2.10.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.11.0/error_prone_parent-2.11.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.27.0/error_prone_parent-2.27.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.33.0/error_prone_parent-2.33.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.35.1/error_prone_parent-2.35.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/flatbuffers/flatbuffers-java/1.12.0/flatbuffers-java-1.12.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/google/1/google-1.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.pom
|
||||
@@ -791,7 +809,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.29.0-RC1/protobuf-bom-4.29.0-RC1.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-bom/4.29.0-RC2/protobuf-bom-4.29.0-RC2.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
|
||||
@@ -808,7 +826,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.29.0-RC1/protobuf-java-4.29.0-RC1.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-java/4.29.0-RC2/protobuf-java-4.29.0-RC2.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
|
||||
@@ -819,7 +837,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.29.0-RC1/protobuf-parent-4.29.0-RC1.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/protobuf/protobuf-parent/4.29.0-RC2/protobuf-parent-4.29.0-RC2.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/truth/truth-parent/1.4.4/truth-parent-1.4.4.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/truth/truth/1.4.4/truth-1.4.4.pom
|
||||
https://repo.maven.apache.org/maven2/com/google/zxing/core/3.4.1/core-3.4.1.pom
|
||||
@@ -841,11 +859,7 @@ https://repo.maven.apache.org/maven2/com/squareup/okhttp3/parent/3.9.1/parent-3.
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/parent/3.12.1/parent-3.12.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-jvm/3.2.0/okio-jvm-3.2.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-jvm/3.9.1/okio-jvm-3.9.1.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-parent/1.13.0/okio-parent-1.13.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-parent/1.15.0/okio-parent-1.15.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-parent/1.17.4/okio-parent-1.17.4.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/1.13.0/okio-1.13.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/1.15.0/okio-1.15.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/1.17.4/okio-1.17.4.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.8.0/okio-2.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.9.0/okio-2.9.0.pom
|
||||
@@ -1197,81 +1211,68 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-an
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-android/1.6.1/kotlinx-coroutines-android-1.6.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-android/1.7.3/kotlinx-coroutines-android-1.7.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-bom/1.6.1/kotlinx-coroutines-bom-1.6.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-bom/1.6.3/kotlinx-coroutines-bom-1.6.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-bom/1.7.3/kotlinx-coroutines-bom-1.7.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.4.1/kotlinx-coroutines-core-jvm-1.4.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.5.0/kotlinx-coroutines-core-jvm-1.5.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.5.2/kotlinx-coroutines-core-jvm-1.5.2.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.6.1/kotlinx-coroutines-core-jvm-1.6.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.6.3/kotlinx-coroutines-core-jvm-1.6.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.7.3/kotlinx-coroutines-core-jvm-1.7.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core/1.4.1/kotlinx-coroutines-core-1.4.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core/1.5.2/kotlinx-coroutines-core-1.5.2.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core/1.6.1/kotlinx-coroutines-core-1.6.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core/1.6.3/kotlinx-coroutines-core-1.6.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core/1.7.3/kotlinx-coroutines-core-1.7.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-metadata-jvm/0.1.0/kotlinx-metadata-jvm-0.1.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/jvm/org.jetbrains.kotlin.jvm.gradle.plugin/1.7.22/org.jetbrains.kotlin.jvm.gradle.plugin-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/jvm/org.jetbrains.kotlin.jvm.gradle.plugin/1.8.0/org.jetbrains.kotlin.jvm.gradle.plugin-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/jvm/org.jetbrains.kotlin.jvm.gradle.plugin/1.9.0/org.jetbrains.kotlin.jvm.gradle.plugin-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-android-extensions/1.6.20/kotlin-android-extensions-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-android-extensions/1.7.22/kotlin-android-extensions-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-android-extensions/1.8.0/kotlin-android-extensions-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-android-extensions/1.9.0/kotlin-android-extensions-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-annotations-jvm/1.3.72/kotlin-annotations-jvm-1.3.72.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-annotation-processing-gradle/1.6.20/kotlin-annotation-processing-gradle-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-annotation-processing-gradle/1.7.22/kotlin-annotation-processing-gradle-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-annotation-processing-gradle/1.8.0/kotlin-annotation-processing-gradle-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-build-common/1.6.20/kotlin-build-common-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-build-common/1.7.22/kotlin-build-common-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-build-common/1.8.0/kotlin-build-common-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-build-common/1.9.0/kotlin-build-common-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-build-tools-api/1.9.0/kotlin-build-tools-api-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-build-tools-impl/1.9.0/kotlin-build-tools-impl-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.6.20/kotlin-compiler-embeddable-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.7.22/kotlin-compiler-embeddable-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.8.0/kotlin-compiler-embeddable-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.9.0/kotlin-compiler-embeddable-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-runner/1.6.20/kotlin-compiler-runner-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-runner/1.7.22/kotlin-compiler-runner-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-runner/1.8.0/kotlin-compiler-runner-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-runner/1.9.0/kotlin-compiler-runner-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-daemon-client/1.6.20/kotlin-daemon-client-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-daemon-client/1.7.22/kotlin-daemon-client-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-daemon-client/1.8.0/kotlin-daemon-client-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-daemon-client/1.9.0/kotlin-daemon-client-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.6.20/kotlin-daemon-embeddable-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.7.22/kotlin-daemon-embeddable-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.8.0/kotlin-daemon-embeddable-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.9.0/kotlin-daemon-embeddable-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugins-bom/1.9.0/kotlin-gradle-plugins-bom-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin-annotations/1.9.0/kotlin-gradle-plugin-annotations-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin-api/1.6.20/kotlin-gradle-plugin-api-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin-api/1.7.22/kotlin-gradle-plugin-api-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin-api/1.8.0/kotlin-gradle-plugin-api-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin-api/1.9.0/kotlin-gradle-plugin-api-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea-proto/1.7.22/kotlin-gradle-plugin-idea-proto-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea-proto/1.8.0/kotlin-gradle-plugin-idea-proto-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea-proto/1.9.0/kotlin-gradle-plugin-idea-proto-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea/1.7.22/kotlin-gradle-plugin-idea-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea/1.8.0/kotlin-gradle-plugin-idea-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea/1.9.0/kotlin-gradle-plugin-idea-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin-model/1.6.20/kotlin-gradle-plugin-model-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin-model/1.7.22/kotlin-gradle-plugin-model-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin-model/1.8.0/kotlin-gradle-plugin-model-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin-model/1.9.0/kotlin-gradle-plugin-model-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin/1.6.20/kotlin-gradle-plugin-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin/1.7.22/kotlin-gradle-plugin-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin/1.8.0/kotlin-gradle-plugin-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-gradle-plugin/1.9.0/kotlin-gradle-plugin-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-klib-commonizer-api/1.6.20/kotlin-klib-commonizer-api-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-klib-commonizer-api/1.7.22/kotlin-klib-commonizer-api-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-klib-commonizer-api/1.8.0/kotlin-klib-commonizer-api-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-klib-commonizer-api/1.9.0/kotlin-klib-commonizer-api-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-klib-commonizer-embeddable/1.8.0/kotlin-klib-commonizer-embeddable-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-klib-commonizer-embeddable/1.9.0/kotlin-klib-commonizer-embeddable-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-native-utils/1.6.20/kotlin-native-utils-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-native-utils/1.7.22/kotlin-native-utils-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-native-utils/1.8.0/kotlin-native-utils-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-native-utils/1.9.0/kotlin-native-utils-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-project-model/1.6.20/kotlin-project-model-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-project-model/1.7.22/kotlin-project-model-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-project-model/1.8.0/kotlin-project-model-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-project-model/1.9.0/kotlin-project-model-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.1.3-2/kotlin-reflect-1.1.3-2.pom
|
||||
@@ -1283,27 +1284,21 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.5.31/
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.6.10/kotlin-reflect-1.6.10.pom
|
||||
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.10/kotlin-reflect-1.7.10.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.1.0-Beta2/kotlin-reflect-2.1.0-Beta2.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
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-common/1.9.0/kotlin-scripting-common-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.6.20/kotlin-scripting-compiler-embeddable-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.7.22/kotlin-scripting-compiler-embeddable-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.8.0/kotlin-scripting-compiler-embeddable-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.9.0/kotlin-scripting-compiler-embeddable-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/1.6.20/kotlin-scripting-compiler-impl-embeddable-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/1.7.22/kotlin-scripting-compiler-impl-embeddable-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/1.8.0/kotlin-scripting-compiler-impl-embeddable-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/1.9.0/kotlin-scripting-compiler-impl-embeddable-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.6.20/kotlin-scripting-jvm-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.7.22/kotlin-scripting-jvm-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.8.0/kotlin-scripting-jvm-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.9.0/kotlin-scripting-jvm-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-script-runtime/1.6.20/kotlin-script-runtime-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-script-runtime/1.7.22/kotlin-script-runtime-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-script-runtime/1.8.0/kotlin-script-runtime-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-script-runtime/1.9.0/kotlin-script-runtime-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.2.71/kotlin-stdlib-common-1.2.71.pom
|
||||
@@ -1326,7 +1321,6 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.6.20/kotlin-stdlib-common-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.6.21/kotlin-stdlib-common-1.6.21.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.7.10/kotlin-stdlib-common-1.7.10.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.7.22/kotlin-stdlib-common-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.0/kotlin-stdlib-common-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.20-RC2/kotlin-stdlib-common-1.8.20-RC2.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.20/kotlin-stdlib-common-1.8.20.pom
|
||||
@@ -1345,6 +1339,7 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.5
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.6.0/kotlin-stdlib-jdk7-1.6.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.6.10/kotlin-stdlib-jdk7-1.6.10.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.6.20/kotlin-stdlib-jdk7-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.6.21/kotlin-stdlib-jdk7-1.6.21.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.7.10/kotlin-stdlib-jdk7-1.7.10.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.8.0/kotlin-stdlib-jdk7-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.8.20-RC2/kotlin-stdlib-jdk7-1.8.20-RC2.pom
|
||||
@@ -1362,6 +1357,7 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.5
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.6.0/kotlin-stdlib-jdk8-1.6.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.6.10/kotlin-stdlib-jdk8-1.6.10.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.6.20/kotlin-stdlib-jdk8-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.6.21/kotlin-stdlib-jdk8-1.6.21.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.7.10/kotlin-stdlib-jdk8-1.7.10.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.0/kotlin-stdlib-jdk8-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.20-RC2/kotlin-stdlib-jdk8-1.8.20-RC2.pom
|
||||
@@ -1391,7 +1387,6 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.6.10/k
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.6.20/kotlin-stdlib-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.6.21/kotlin-stdlib-1.6.21.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.7.10/kotlin-stdlib-1.7.10.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.7.22/kotlin-stdlib-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.8.0/kotlin-stdlib-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.8.20-RC2/kotlin-stdlib-1.8.20-RC2.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.8.20/kotlin-stdlib-1.8.20.pom
|
||||
@@ -1401,16 +1396,13 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.0/ko
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.22/kotlin-stdlib-1.9.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.25/kotlin-stdlib-1.9.25.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/2.1.0-Beta2/kotlin-stdlib-2.1.0-Beta2.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
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-tooling-metadata/1.6.20/kotlin-tooling-metadata-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-util-io/1.6.20/kotlin-util-io-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-util-io/1.7.22/kotlin-util-io-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-util-io/1.8.0/kotlin-util-io-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-util-io/1.9.0/kotlin-util-io-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-util-klib/1.6.20/kotlin-util-klib-1.6.20.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-util-klib/1.7.22/kotlin-util-klib-1.7.22.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-util-klib/1.8.0/kotlin-util-klib-1.8.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-util-klib/1.9.0/kotlin-util-klib-1.9.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/jetbrains/markdown-jvm/0.2.1/markdown-jvm-0.2.1.pom
|
||||
@@ -1420,7 +1412,7 @@ https://repo.maven.apache.org/maven2/org/json/json/20180813/json-20180813.pom
|
||||
https://repo.maven.apache.org/maven2/org/json/json/20240303/json-20240303.pom
|
||||
https://repo.maven.apache.org/maven2/org/jsoup/jsoup/1.13.1/jsoup-1.13.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/jspecify/jspecify/1.0.0/jspecify-1.0.0.pom
|
||||
https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.11.2/junit-bom-5.11.2.pom
|
||||
https://repo.maven.apache.org/maven2/org/junit/junit-bom/5.11.3/junit-bom-5.11.3.pom
|
||||
https://repo.maven.apache.org/maven2/org/jvnet/staxex/stax-ex/1.7.7/stax-ex-1.7.7.pom
|
||||
https://repo.maven.apache.org/maven2/org/jvnet/staxex/stax-ex/1.8.1/stax-ex-1.8.1.pom
|
||||
https://repo.maven.apache.org/maven2/org/jvnet/staxex/stax-ex/1.8/stax-ex-1.8.pom
|
||||
|
||||
@@ -42,22 +42,10 @@ function gen_deps_list() {
|
||||
# https://github.com/status-im/status-mobile/issues/15447
|
||||
function add_deps_hack() {
|
||||
echo -n \
|
||||
'com.android.tools.build:gradle:1.3.1
|
||||
com.squareup.okio:okio:1.13.0
|
||||
com.squareup.okio:okio:1.15.0
|
||||
com.squareup.okhttp3:okhttp:3.12.1
|
||||
org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:1.7.22
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2
|
||||
org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:1.9.0
|
||||
org.gradle.toolchains.foojay-resolver-convention:org.gradle.toolchains.foojay-resolver-convention.gradle.plugin:0.5.0
|
||||
'org.gradle.toolchains.foojay-resolver-convention:org.gradle.toolchains.foojay-resolver-convention.gradle.plugin:0.5.0
|
||||
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
|
||||
androidx.annotation:annotation:1.6.0
|
||||
androidx.annotation:annotation-jvm:1.6.0
|
||||
com.android.tools.lint:lint-gradle:31.1.1
|
||||
com.facebook.react:hermes-android:0.73.5' \
|
||||
>> "${DEPS_LIST}"
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
set -Eeuo pipefail
|
||||
|
||||
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
|
||||
GRADLE_REPORTS_DIR="${GIT_ROOT}/android/build/reports/dependency-graph-snapshots"
|
||||
# Gradle needs to be run in 'android' subfolder.
|
||||
cd "${GIT_ROOT}/android"
|
||||
|
||||
@@ -15,23 +16,11 @@ GRADLE_LOG_FILE='/tmp/gradle.log'
|
||||
function show_gradle_log() { cat "${GRADLE_LOG_FILE}" >&2; }
|
||||
trap show_gradle_log ERR
|
||||
|
||||
# Run the gradle command for a project:
|
||||
# - ':buildEnvironment' to get build tools
|
||||
# - ':dependencies' to get direct deps limited those by
|
||||
# implementation config to avoid test dependencies
|
||||
DEPS=("${@}")
|
||||
declare -a BUILD_DEPS
|
||||
declare -a NORMAL_DEPS
|
||||
for i in "${!DEPS[@]}"; do
|
||||
BUILD_DEPS[${i}]="${DEPS[${i}]}:buildEnvironment"
|
||||
NORMAL_DEPS[${i}]="${DEPS[${i}]}:dependencies"
|
||||
done
|
||||
./gradlew -I init.gradle \
|
||||
--dependency-verification=off \
|
||||
--no-configuration-cache --no-configure-on-demand \
|
||||
:ForceDependencyResolutionPlugin_resolveAllDependencies > "${GRADLE_LOG_FILE}" 2>&1
|
||||
|
||||
# And clean up the output using AWK script.
|
||||
AWK_SCRIPT="${GIT_ROOT}/nix/deps/gradle/gradle_parser.awk"
|
||||
|
||||
./gradlew --no-daemon --console plain \
|
||||
"${BUILD_DEPS[@]}" \
|
||||
"${NORMAL_DEPS[@]}" \
|
||||
| tee "${GRADLE_LOG_FILE}" \
|
||||
| awk -f "${AWK_SCRIPT}"
|
||||
# skip org.webkit:android-jsc, its provided by react-native
|
||||
# remove when new architecture is enabled
|
||||
jq -r '.[].dependency | select(startswith("org.webkit:android-jsc") | not)' "${GRADLE_REPORTS_DIR}/dependency-resolution.json"
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
# This script parses the AWFUL Gradle output of :dependencies calls
|
||||
# and outputs just the names of the packages in the Maven format:
|
||||
# <groupId>:<artifactId>:<version>
|
||||
|
||||
function findPackage(line, regex) {
|
||||
rval = match(line, regex, matches)
|
||||
if (rval != 0) {
|
||||
dep = sprintf("%s:%s:%s", matches[1], matches[2], matches[3])
|
||||
if (deps[dep] == nil) {
|
||||
deps[dep] = 1
|
||||
}
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
# Gradle outputs dependencies in groups defined by configurations.
|
||||
# Those configurations are words followed by a dash and a description.
|
||||
# There's also a special 'classpath' configuration we want.
|
||||
/^(classpath|[a-zA-Z0-9]+)( - .*)?$/ {
|
||||
# Ignore configurations starting with 'test'
|
||||
if (tolower($1) ~ /^test/) {
|
||||
next
|
||||
}
|
||||
|
||||
# Lines after configuration name list packages
|
||||
for (getline line; line != ""; getline line) {
|
||||
|
||||
# JavaScript Core (JSC) is provided by node_modules
|
||||
if (line ~ "org.webkit:android-jsc") { continue }
|
||||
|
||||
# Example: +--- org.jetbrains.kotlin:kotlin-stdlib:1.3.50
|
||||
if (findPackage(line, "--- ([^ :]+):([^ :]+):([^ :]+)$")) {
|
||||
continue
|
||||
}
|
||||
|
||||
# Example: +--- androidx.lifecycle:lifecycle-common:{strictly 2.0.0} -> 2.0.0 (c)
|
||||
if (findPackage(line, "--- ([^ :]+):([^ :]+):[^:]+ -> ([^ :]+) ?(\\([*c]\\))?$")) {
|
||||
continue
|
||||
}
|
||||
|
||||
# Example: +--- com.android.support:appcompat-v7:28.0.0 -> androidx.appcompat:appcompat:1.0.2
|
||||
if (findPackage(line, "--- [^ :]+:[^ :]+:[^ ]+ -> ([^ :]+):([^ :]+):([^ :]+)$")) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
END{
|
||||
# It's nicer to sort it
|
||||
asorti(deps, sorted)
|
||||
for (i in sorted) {
|
||||
print sorted[i]
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 673 B After Width: | Height: | Size: 810 B |
|
Before Width: | Height: | Size: 1001 B After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 69 KiB |
@@ -32,12 +32,9 @@ trap "rm -vf ${SECRETS_FILE_PATH}" EXIT ERR INT QUIT
|
||||
# Names of variables containing secrets to save in env file.
|
||||
SECRETS_ENV_VARS=(
|
||||
'ALCHEMY_ETHEREUM_MAINNET_TOKEN'
|
||||
'ALCHEMY_ETHEREUM_GOERLI_TOKEN'
|
||||
'ALCHEMY_ETHEREUM_SEPOLIA_TOKEN'
|
||||
'ALCHEMY_ARBITRUM_GOERLI_TOKEN'
|
||||
'ALCHEMY_ARBITRUM_MAINNET_TOKEN'
|
||||
'ALCHEMY_ARBITRUM_SEPOLIA_TOKEN'
|
||||
'ALCHEMY_OPTIMISM_GOERLI_TOKEN'
|
||||
'ALCHEMY_OPTIMISM_MAINNET_TOKEN'
|
||||
'ALCHEMY_OPTIMISM_SEPOLIA_TOKEN'
|
||||
'RARIBLE_MAINNET_API_KEY'
|
||||
|
||||
@@ -75,13 +75,10 @@
|
||||
status-im.config/RARIBLE_MAINNET_API_KEY #shadow/env "RARIBLE_MAINNET_API_KEY"
|
||||
status-im.config/RARIBLE_TESTNET_API_KEY #shadow/env "RARIBLE_TESTNET_API_KEY"
|
||||
status-im.config/ALCHEMY_ETHEREUM_MAINNET_TOKEN #shadow/env "ALCHEMY_ETHEREUM_MAINNET_TOKEN"
|
||||
status-im.config/ALCHEMY_ETHEREUM_GOERLI_TOKEN #shadow/env "ALCHEMY_ETHEREUM_GOERLI_TOKEN"
|
||||
status-im.config/ALCHEMY_ETHEREUM_SEPOLIA_TOKEN #shadow/env "ALCHEMY_ETHEREUM_SEPOLIA_TOKEN"
|
||||
status-im.config/ALCHEMY_ARBITRUM_MAINNET_TOKEN #shadow/env "ALCHEMY_ARBITRUM_MAINNET_TOKEN"
|
||||
status-im.config/ALCHEMY_ARBITRUM_GOERLI_TOKEN #shadow/env "ALCHEMY_ARBITRUM_GOERLI_TOKEN"
|
||||
status-im.config/ALCHEMY_ARBITRUM_SEPOLIA_TOKEN #shadow/env "ALCHEMY_ARBITRUM_SEPOLIA_TOKEN"
|
||||
status-im.config/ALCHEMY_OPTIMISM_MAINNET_TOKEN #shadow/env "ALCHEMY_OPTIMISM_MAINNET_TOKEN"
|
||||
status-im.config/ALCHEMY_OPTIMISM_GOERLI_TOKEN #shadow/env "ALCHEMY_OPTIMISM_GOERLI_TOKEN"
|
||||
status-im.config/ALCHEMY_OPTIMISM_SEPOLIA_TOKEN #shadow/env "ALCHEMY_OPTIMISM_SEPOLIA_TOKEN"}
|
||||
:compiler-options {:output-feature-set :es5
|
||||
;; We disable `:fn-deprecated` warnings because we
|
||||
@@ -114,13 +111,10 @@
|
||||
status-im.config/RARIBLE_MAINNET_API_KEY #shadow/env "RARIBLE_MAINNET_API_KEY"
|
||||
status-im.config/RARIBLE_TESTNET_API_KEY #shadow/env "RARIBLE_TESTNET_API_KEY"
|
||||
status-im.config/ALCHEMY_ETHEREUM_MAINNET_TOKEN #shadow/env "ALCHEMY_ETHEREUM_MAINNET_TOKEN"
|
||||
status-im.config/ALCHEMY_ETHEREUM_GOERLI_TOKEN #shadow/env "ALCHEMY_ETHEREUM_GOERLI_TOKEN"
|
||||
status-im.config/ALCHEMY_ETHEREUM_SEPOLIA_TOKEN #shadow/env "ALCHEMY_ETHEREUM_SEPOLIA_TOKEN"
|
||||
status-im.config/ALCHEMY_ARBITRUM_MAINNET_TOKEN #shadow/env "ALCHEMY_ARBITRUM_MAINNET_TOKEN"
|
||||
status-im.config/ALCHEMY_ARBITRUM_GOERLI_TOKEN #shadow/env "ALCHEMY_ARBITRUM_GOERLI_TOKEN"
|
||||
status-im.config/ALCHEMY_ARBITRUM_SEPOLIA_TOKEN #shadow/env "ALCHEMY_ARBITRUM_SEPOLIA_TOKEN"
|
||||
status-im.config/ALCHEMY_OPTIMISM_MAINNET_TOKEN #shadow/env "ALCHEMY_OPTIMISM_MAINNET_TOKEN"
|
||||
status-im.config/ALCHEMY_OPTIMISM_GOERLI_TOKEN #shadow/env "ALCHEMY_OPTIMISM_GOERLI_TOKEN"
|
||||
status-im.config/ALCHEMY_OPTIMISM_SEPOLIA_TOKEN #shadow/env "ALCHEMY_OPTIMISM_SEPOLIA_TOKEN"}
|
||||
:compiler-options {:output-feature-set :es6
|
||||
;;disable for android build as there
|
||||
@@ -158,13 +152,10 @@
|
||||
status-im.config/RARIBLE_MAINNET_API_KEY #shadow/env "RARIBLE_MAINNET_API_KEY"
|
||||
status-im.config/RARIBLE_TESTNET_API_KEY #shadow/env "RARIBLE_TESTNET_API_KEY"
|
||||
status-im.config/ALCHEMY_ETHEREUM_MAINNET_TOKEN #shadow/env "ALCHEMY_ETHEREUM_MAINNET_TOKEN"
|
||||
status-im.config/ALCHEMY_ETHEREUM_GOERLI_TOKEN #shadow/env "ALCHEMY_ETHEREUM_GOERLI_TOKEN"
|
||||
status-im.config/ALCHEMY_ETHEREUM_SEPOLIA_TOKEN #shadow/env "ALCHEMY_ETHEREUM_SEPOLIA_TOKEN"
|
||||
status-im.config/ALCHEMY_ARBITRUM_MAINNET_TOKEN #shadow/env "ALCHEMY_ARBITRUM_MAINNET_TOKEN"
|
||||
status-im.config/ALCHEMY_ARBITRUM_GOERLI_TOKEN #shadow/env "ALCHEMY_ARBITRUM_GOERLI_TOKEN"
|
||||
status-im.config/ALCHEMY_ARBITRUM_SEPOLIA_TOKEN #shadow/env "ALCHEMY_ARBITRUM_SEPOLIA_TOKEN"
|
||||
status-im.config/ALCHEMY_OPTIMISM_MAINNET_TOKEN #shadow/env "ALCHEMY_OPTIMISM_MAINNET_TOKEN"
|
||||
status-im.config/ALCHEMY_OPTIMISM_GOERLI_TOKEN #shadow/env "ALCHEMY_OPTIMISM_GOERLI_TOKEN"
|
||||
status-im.config/ALCHEMY_OPTIMISM_SEPOLIA_TOKEN #shadow/env "ALCHEMY_OPTIMISM_SEPOLIA_TOKEN"
|
||||
status-im.config/WALLET_CONNECT_PROJECT_ID #shadow/env "WALLET_CONNECT_PROJECT_ID"}
|
||||
:compiler-options
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
["react-native" :as rn]
|
||||
["react-native-status-keycard" :default status-keycard]
|
||||
[react-native.platform :as platform]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.address :as address]))
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(defonce event-emitter
|
||||
(if platform/ios?
|
||||
@@ -94,22 +93,14 @@
|
||||
[{:keys [on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
(getApplicationInfo)
|
||||
(then (fn [response]
|
||||
(let [info (-> response
|
||||
(js->clj :keywordize-keys true)
|
||||
(update :key-uid address/normalized-hex))]
|
||||
(on-success info))))
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn factory-reset
|
||||
[{:keys [on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
(factoryReset)
|
||||
(then (fn [response]
|
||||
(let [info (-> response
|
||||
(js->clj :keywordize-keys true)
|
||||
(update :key-uid address/normalized-hex))]
|
||||
(on-success info))))
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn install-applet
|
||||
@@ -155,6 +146,13 @@
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn save-mnemonic
|
||||
[{:keys [mnemonic pin on-success on-failure]}]
|
||||
(.. status-keycard
|
||||
(saveMnemonic mnemonic pin)
|
||||
(then on-success)
|
||||
(catch on-failure)))
|
||||
|
||||
(defn unblock-pin
|
||||
[{:keys [puk new-pin on-success on-failure]}]
|
||||
(when (and new-pin puk)
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
{:mainnet {:name "Ether"
|
||||
:symbol :ETH
|
||||
:decimals 18}
|
||||
:goerli {:name "Goerli Ether"
|
||||
:sepolia {:name "Sepolia Ether"
|
||||
:symbol :ETH
|
||||
:symbol-display :ETHgo
|
||||
:symbol-display :ETH
|
||||
:decimals 18}
|
||||
:xdai {:name "xDAI"
|
||||
:symbol :ETH
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
|
||||
(def etherscan-supported?
|
||||
#{(chain/chain-keyword->chain-id :mainnet)
|
||||
(chain/chain-keyword->chain-id :goerli)})
|
||||
(chain/chain-keyword->chain-id :sepolia)})
|
||||
|
||||
(def binance-mainnet-chain-id (chain/chain-keyword->chain-id :bsc))
|
||||
(def binance-testnet-chain-id (chain/chain-keyword->chain-id :bsc-testnet))
|
||||
|
||||
(def network->subdomain {5 "goerli"})
|
||||
(def network->subdomain {11155111 "sepolia"})
|
||||
|
||||
(defn get-transaction-details-url
|
||||
[chain-id tx-hash]
|
||||
|
||||
@@ -508,17 +508,16 @@
|
||||
new-password-hashed
|
||||
callback))))
|
||||
|
||||
(defn convert-to-keycard-account
|
||||
[{:keys [key-uid] :as multiaccount-data} settings current-password# new-password callback]
|
||||
(log/debug "[native-module] convert-to-keycard-account")
|
||||
(defn convert-to-keycard-profile
|
||||
[{:keys [key-uid] :as profile} settings password new-password callback]
|
||||
(.convertToKeycardAccount ^js (encryption)
|
||||
key-uid
|
||||
(types/clj->json multiaccount-data)
|
||||
(types/clj->json profile)
|
||||
(types/clj->json settings)
|
||||
""
|
||||
current-password#
|
||||
(:keycard-instance-uid settings)
|
||||
password
|
||||
new-password
|
||||
callback))
|
||||
#(when callback (callback (types/json->clj %)))))
|
||||
|
||||
(defn backup-disabled-data-dir
|
||||
[]
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
|
||||
(def inner-container
|
||||
{:flex-direction :row
|
||||
:justify-content :center
|
||||
:justify-content :space-between
|
||||
:flex 1})
|
||||
|
||||
(def button-container
|
||||
{:padding-vertical 8
|
||||
:width 77.75
|
||||
:flex 1
|
||||
:justify-content :center
|
||||
:align-items :center})
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"
|
||||
[{:keys [holder-name locked?]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
label (if (boolean holder-name)
|
||||
label (if holder-name
|
||||
(i18n/label :t/user-keycard {:name holder-name})
|
||||
(i18n/label :t/empty-keycard))]
|
||||
[rn/view {:style (style/card-container locked? theme)}
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
(defn container
|
||||
[container-style]
|
||||
(merge container-style
|
||||
{:flex-direction :row
|
||||
:align-items :flex-start}))
|
||||
{:padding-vertical 7
|
||||
:padding-horizontal 20
|
||||
:flex-direction :row
|
||||
:align-items :flex-start}))
|
||||
|
||||
(def index
|
||||
{:margin-left 5})
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
:or {type :bullet}}]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[rn/view {:style (style/container container-style)}
|
||||
[rn/view {:style style/index}
|
||||
[rn/view
|
||||
(case type
|
||||
:step
|
||||
[step/view
|
||||
|
||||
@@ -55,26 +55,36 @@
|
||||
theme))}])]))
|
||||
|
||||
(defn- left-title
|
||||
[{:keys [title blur?]}]
|
||||
[{:keys [title blur? title-icon]}]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[rn/view {:style style/title-container}
|
||||
[text/text
|
||||
{:weight :regular
|
||||
:size :paragraph-2
|
||||
:style (style/title blur? theme)}
|
||||
title]]))
|
||||
title]
|
||||
(when title-icon
|
||||
[icons/icon title-icon
|
||||
{:accessibility-label :title-icon
|
||||
:size 12
|
||||
:color (if blur?
|
||||
colors/neutral-40
|
||||
(colors/theme-colors colors/neutral-50
|
||||
colors/neutral-40
|
||||
theme))}])]))
|
||||
|
||||
(defn- left-side
|
||||
"The description can either be given as a string `subtitle-type` or a component `custom-subtitle`"
|
||||
[{:keys [title status size blur? custom-subtitle icon subtitle subtitle-type subtitle-color icon-color
|
||||
customization-color network-image emoji]
|
||||
customization-color network-image emoji title-icon]
|
||||
:as props}]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[rn/view {:style style/left-side}
|
||||
[left-title
|
||||
{:title title
|
||||
:blur? blur?
|
||||
:theme theme}]
|
||||
[rn/view
|
||||
[left-title
|
||||
{:title title
|
||||
:title-icon title-icon
|
||||
:blur? blur?}]]
|
||||
(if (= status :loading)
|
||||
[left-loading
|
||||
{:size size
|
||||
@@ -132,6 +142,7 @@
|
||||
[:subtitle {:optional true} [:maybe [:or :string :double]]]
|
||||
[:custom-subtitle {:optional true} [:maybe fn?]]
|
||||
[:icon {:optional true} [:maybe :keyword]]
|
||||
[:title-icon {:optional true} [:maybe :keyword]]
|
||||
[:emoji {:optional true} [:maybe :string]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||
[:network-image {:optional true} [:maybe :schema.common/image-source]]
|
||||
|
||||
@@ -59,12 +59,15 @@
|
||||
- :image-source - resource - image to display on :network, :collectible and :user
|
||||
- :theme - :light / :dark"
|
||||
[{:keys [label customization-color type container-style]
|
||||
:as props
|
||||
:or {customization-color colors/neutral-80-opa-5}}]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
:as props}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
default-color (if (= theme :light)
|
||||
colors/neutral-80-opa-5
|
||||
colors/white-opa-5)
|
||||
color (or customization-color default-color)]
|
||||
[rn/view
|
||||
{:accessibility-label :container
|
||||
:style (merge (style/main (assoc props :customization-color customization-color)
|
||||
:style (merge (style/main (assoc props :customization-color color)
|
||||
theme)
|
||||
container-style)}
|
||||
[left-view props]
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
|
||||
(def header
|
||||
{:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:height 32})
|
||||
:justify-content :space-between})
|
||||
|
||||
(def header-title
|
||||
{:flex 1
|
||||
|
||||
@@ -59,7 +59,6 @@
|
||||
[rn/view {:style (merge style/container container-style)}
|
||||
[text/text
|
||||
{:size :heading-1
|
||||
:number-of-lines 1
|
||||
:weight :semi-bold
|
||||
:style style/text
|
||||
:accessibility-label accessibility-label}
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
:margin-bottom 8})
|
||||
|
||||
(def item-text
|
||||
{:margin-top 10
|
||||
:margin-left -4})
|
||||
{:margin-left -24})
|
||||
|
||||
(def info-text
|
||||
{:margin-top -5})
|
||||
|
||||
@@ -22,6 +22,11 @@
|
||||
:qr-code (js/require "../resources/images/ui2/qr-code.png")
|
||||
:keycard-logo (js/require "../resources/images/ui2/keycard-logo.png")
|
||||
:keycard-watermark (js/require "../resources/images/ui2/keycard-watermark.png")
|
||||
:keycard-buy (js/require "../resources/images/ui2/keycard-buy.png")
|
||||
:keycard-migration (js/require "../resources/images/ui2/keycard-migration.png")
|
||||
:keycard-migration-failed (js/require "../resources/images/ui2/keycard-migration-failed.png")
|
||||
:keycard-migration-succeeded (js/require "../resources/images/ui2/keycard-migration-succeeded.png")
|
||||
:not-keycard (js/require "../resources/images/ui2/not-keycard.png")
|
||||
:discover (js/require "../resources/images/ui2/discover.png")
|
||||
:invite-friends (js/require "../resources/images/ui2/invite-friends.png")
|
||||
:transaction-progress (js/require "../resources/images/ui2/transaction-progress.png")
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
(ns status-im.common.standard-authentication.enter-password.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.standard-authentication.core :as standard-authentication]
|
||||
[status-im.common.standard-authentication.enter-password.style :as style]
|
||||
[status-im.common.standard-authentication.password-input.view :as password-input]
|
||||
[status-im.contexts.profile.utils :as profile.utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -31,11 +32,12 @@
|
||||
:full-name (profile.utils/displayed-name profile)
|
||||
:customization-color customization-color
|
||||
:size 24}]]
|
||||
[password-input/view
|
||||
[standard-authentication/password-input
|
||||
{:on-press-biometrics on-press-biometrics
|
||||
:blur? true
|
||||
:processing processing
|
||||
:error error
|
||||
:error {:error? (not (string/blank? error))
|
||||
:error-message error}
|
||||
:default-password password
|
||||
:sign-in-enabled? sign-in-enabled?}]
|
||||
[quo/button
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
(ns status-im.common.standard-authentication.password-input.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
@@ -12,14 +11,6 @@
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(defn- get-error-message
|
||||
[error]
|
||||
(if (and (some? error)
|
||||
(or (= error "file is not a database")
|
||||
(string/starts-with? (string/lower-case error) "failed")))
|
||||
(i18n/label :t/oops-wrong-password)
|
||||
error))
|
||||
|
||||
(defn- error-info
|
||||
[error-message processing shell?]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
@@ -49,21 +40,21 @@
|
||||
(i18n/label :t/forgot-password)]]]))
|
||||
|
||||
(defn view
|
||||
[{:keys [shell? on-press-biometrics blur?]}]
|
||||
(let [{:keys [error processing]} (rf/sub [:profile/login])
|
||||
error-message (rn/use-memo #(get-error-message error) [error])
|
||||
error? (boolean (seq error-message))
|
||||
default-value (rn/use-ref-atom "") ;;bug on Android
|
||||
;;https://github.com/status-im/status-mobile/issues/19004
|
||||
theme (quo.theme/use-theme)
|
||||
on-change-password (rn/use-callback
|
||||
(fn [entered-password]
|
||||
(reset! default-value entered-password)
|
||||
(debounce/debounce-and-dispatch [:profile/on-password-input-changed
|
||||
{:password (security/mask-data
|
||||
entered-password)
|
||||
:error ""}]
|
||||
100)))]
|
||||
[{:keys [shell? on-press-biometrics blur? processing error]}]
|
||||
(let [{:keys [error?
|
||||
error-message]} error
|
||||
default-value (rn/use-ref-atom "") ;;bug on Android
|
||||
;;https://github.com/status-im/status-mobile/issues/19004
|
||||
theme (quo.theme/use-theme)
|
||||
on-change-password (rn/use-callback
|
||||
(fn [entered-password]
|
||||
(reset! default-value entered-password)
|
||||
(debounce/debounce-and-dispatch
|
||||
[:profile/on-password-input-changed
|
||||
{:password (security/mask-data
|
||||
entered-password)
|
||||
:error ""}]
|
||||
100)))]
|
||||
[:<>
|
||||
[rn/view {:style {:flex-direction :row}}
|
||||
[quo/input
|
||||
|
||||
@@ -18,28 +18,23 @@
|
||||
(goog-define RARIBLE_MAINNET_API_KEY "")
|
||||
(goog-define RARIBLE_TESTNET_API_KEY "")
|
||||
(goog-define ALCHEMY_ETHEREUM_MAINNET_TOKEN "")
|
||||
(goog-define ALCHEMY_ETHEREUM_GOERLI_TOKEN "")
|
||||
(goog-define ALCHEMY_ETHEREUM_SEPOLIA_TOKEN "")
|
||||
(goog-define ALCHEMY_ARBITRUM_MAINNET_TOKEN "")
|
||||
(goog-define ALCHEMY_ARBITRUM_GOERLI_TOKEN "")
|
||||
(goog-define ALCHEMY_ARBITRUM_SEPOLIA_TOKEN "")
|
||||
(goog-define ALCHEMY_OPTIMISM_MAINNET_TOKEN "")
|
||||
(goog-define ALCHEMY_OPTIMISM_GOERLI_TOKEN "")
|
||||
(goog-define ALCHEMY_OPTIMISM_SEPOLIA_TOKEN "")
|
||||
(goog-define WALLET_CONNECT_PROJECT_ID "87815d72a81d739d2a7ce15c2cfdefb3")
|
||||
(goog-define MIXPANEL_APP_ID "3350627")
|
||||
(goog-define MIXPANEL_TOKEN "5c73bda2d36a9f688a5ee45641fb6775")
|
||||
|
||||
(def mainnet-rpc-url (str "https://eth-archival.rpc.grove.city/v1/" POKT_TOKEN))
|
||||
(def goerli-rpc-url (str "https://goerli-archival.gateway.pokt.network/v1/lb/" POKT_TOKEN))
|
||||
(def sepolia-rpc-url (str "https://sepolia-archival.rpc.grove.city/v1/" POKT_TOKEN))
|
||||
(def mainnet-chain-explorer-link "https://etherscan.io/address/")
|
||||
(def optimism-mainnet-chain-explorer-link "https://optimistic.etherscan.io/address/")
|
||||
(def arbitrum-mainnet-chain-explorer-link "https://arbiscan.io/address/")
|
||||
(def sepolia-chain-explorer-link "https://sepolia.etherscan.io/address/")
|
||||
(def optimism-sepolia-chain-explorer-link "https://sepolia-optimistic.etherscan.io/address/")
|
||||
(def arbitrum-sepolia-chain-explorer-link "https://sepolia.arbiscan.io/address/")
|
||||
(def goerli-chain-explorer-link "https://goerli.etherscan.io/address/")
|
||||
(def optimism-goerli-chain-explorer-link "https://goerli-optimistic.etherscan.io/address/")
|
||||
(def opensea-link "https://opensea.io")
|
||||
(def opensea-tesnet-link "https://testnets.opensea.io")
|
||||
|
||||
@@ -79,7 +74,6 @@
|
||||
(def log-request-go (enabled? (get-config :LOG_REQUEST_GO "0")))
|
||||
(def fleet (get-config :FLEET ""))
|
||||
(def apn-topic (get-config :APN_TOPIC "im.status.ethereum"))
|
||||
(def default-network (get-config :DEFAULT_NETWORK "goerli_rpc"))
|
||||
(def max-installations 2)
|
||||
; currently not supported in status-go
|
||||
(def enable-remove-profile-picture? false)
|
||||
@@ -100,13 +94,13 @@
|
||||
(def verify-transaction-url
|
||||
(if (= :mainnet (chain/chain-id->chain-keyword verify-transaction-chain-id))
|
||||
mainnet-rpc-url
|
||||
goerli-rpc-url))
|
||||
sepolia-rpc-url))
|
||||
|
||||
(def verify-ens-chain-id (js/parseInt (get-config :VERIFY_ENS_CHAIN_ID "1")))
|
||||
(def verify-ens-url
|
||||
(if (= :mainnet (chain/chain-id->chain-keyword verify-ens-chain-id))
|
||||
mainnet-rpc-url
|
||||
goerli-rpc-url))
|
||||
sepolia-rpc-url))
|
||||
(def verify-ens-contract-address
|
||||
(get-config :VERIFY_ENS_CONTRACT_ADDRESS
|
||||
((chain/chain-id->chain-keyword verify-ens-chain-id) utils.ens/ens-registries)))
|
||||
|
||||
@@ -295,6 +295,8 @@
|
||||
|
||||
(def ^:const token-sort-priority {"SNT" 1 "STT" 1 "ETH" 2 "DAI" 3})
|
||||
|
||||
(def ^:const token-display-precision 6)
|
||||
|
||||
(def ^:const dapp-permission-contact-code "contact-code")
|
||||
(def ^:const dapp-permission-web3 "web3")
|
||||
(def ^:const dapp-permission-qr-code "qr-code")
|
||||
@@ -473,30 +475,22 @@
|
||||
|
||||
;; wallet
|
||||
(def ^:const ethereum-mainnet-chain-id 1)
|
||||
(def ^:const ethereum-goerli-chain-id 5)
|
||||
(def ^:const ethereum-sepolia-chain-id 11155111)
|
||||
(def ^:const arbitrum-mainnet-chain-id 42161)
|
||||
(def ^:const arbitrum-goerli-chain-id 421613)
|
||||
(def ^:const arbitrum-sepolia-chain-id 421614)
|
||||
(def ^:const optimism-mainnet-chain-id 10)
|
||||
(def ^:const optimism-goerli-chain-id 420)
|
||||
(def ^:const optimism-sepolia-chain-id 11155420)
|
||||
|
||||
(def opensea-url-names
|
||||
{:ethereum "ethereum"
|
||||
:sepolia "sepolia"
|
||||
:goerli "goerli"})
|
||||
:sepolia "sepolia"})
|
||||
|
||||
(def ^:const ethereum "ethereum")
|
||||
(def ^:const sepolia "sepolia")
|
||||
(def ^:const goerli "goerli")
|
||||
|
||||
(def ^:const mainnet-chain-ids
|
||||
#{ethereum-mainnet-chain-id arbitrum-mainnet-chain-id optimism-mainnet-chain-id})
|
||||
|
||||
(def ^:const goerli-chain-ids
|
||||
#{ethereum-goerli-chain-id arbitrum-goerli-chain-id optimism-goerli-chain-id})
|
||||
|
||||
(def ^:const sepolia-chain-ids
|
||||
#{ethereum-sepolia-chain-id arbitrum-sepolia-chain-id optimism-sepolia-chain-id})
|
||||
|
||||
@@ -516,7 +510,6 @@
|
||||
(def ^:const arbitrum-full-name "Arbitrum")
|
||||
|
||||
(def ^:const sepolia-full-name "Sepolia")
|
||||
(def ^:const goerli-full-name "Goerli")
|
||||
|
||||
(def ^:const mainnet-network-name :mainnet)
|
||||
(def ^:const ethereum-network-name :ethereum)
|
||||
@@ -580,13 +573,14 @@
|
||||
(def ^:const sheet-screen-handle-height 20)
|
||||
|
||||
(def ^:const status-hostname "status.app")
|
||||
(def ^:const get-keycard-url "https://get.keycard.tech/")
|
||||
|
||||
(def ^:const community-joined-notification-type "communityJoined")
|
||||
|
||||
(def ^:const default-telemetry-server-url "https://telemetry.status.im")
|
||||
|
||||
(def ^:const contact-item-height 56)
|
||||
|
||||
(def ^:const page-nav-height 56)
|
||||
(def ^:const currency-item-height 64)
|
||||
|
||||
(def ^:const slippages [0.1 0.5 1])
|
||||
|
||||
@@ -4,20 +4,18 @@
|
||||
[status-im.common.events-helper :as events-helper]
|
||||
[status-im.common.standard-authentication.core :as standard-auth]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [profile-name (rf/sub [:profile/name])
|
||||
profile-picture (rf/sub [:profile/image])
|
||||
customization-color (rf/sub [:profile/customization-color])]
|
||||
(let [profile-name (rf/sub [:profile/name])
|
||||
profile-picture (rf/sub [:profile/image])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
{:keys [on-success]} (rf/sub [:get-screen-params])]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:key :header
|
||||
:background :blur
|
||||
:icon-name :i/close
|
||||
:on-press events-helper/navigate-back}]
|
||||
{:icon-name :i/close
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/authorise-with-password)
|
||||
:description :context-tag
|
||||
@@ -31,5 +29,5 @@
|
||||
:container-style {}
|
||||
:customization-color customization-color
|
||||
:track-text (i18n/label :t/slide-to-authorise)
|
||||
:on-auth-success #(println "TBD" (security/safe-unmask-data %))
|
||||
:on-auth-success #(when on-success (on-success %))
|
||||
:auth-button-label (i18n/label :t/confirm)}]]]))
|
||||
|
||||
@@ -10,10 +10,8 @@
|
||||
[]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:key :header
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press events-helper/navigate-back}]
|
||||
{:icon-name :i/arrow-left
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/check-keycard)
|
||||
:description :text
|
||||
@@ -23,14 +21,9 @@
|
||||
{:resize-mode :contain
|
||||
:source (resources/get-image :check-your-keycard)}]]
|
||||
[quo/divider-label (i18n/label :t/tips-scan-keycard)]
|
||||
[rn/view {:style {:padding-horizontal 10}}
|
||||
[quo/markdown-list
|
||||
{:container-style {:padding-vertical 10}
|
||||
:description (i18n/label :t/remove-phone-case)}]
|
||||
[quo/markdown-list
|
||||
{:container-style {:padding-bottom 25}
|
||||
:description (i18n/label :t/keep-card-steady)}]]
|
||||
[quo/button
|
||||
{:on-press #(rf/dispatch [:keycard/connect])
|
||||
:container-style {:margin-horizontal 20}}
|
||||
(i18n/label :t/ready-to-scan)]])
|
||||
[quo/markdown-list {:description (i18n/label :t/remove-phone-case)}]
|
||||
[quo/markdown-list {:description (i18n/label :t/keep-card-steady)}]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (i18n/label :t/ready-to-scan)
|
||||
:button-one-props {:on-press #(rf/dispatch [:keycard/migration.check-empty-card])}}]])
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
[native-module.core :as native-module]
|
||||
[react-native.async-storage :as async-storage]
|
||||
[react-native.platform :as platform]
|
||||
status-im.contexts.keycard.nfc.effects
|
||||
[status-im.contexts.keycard.utils :as keycard.utils]
|
||||
[status-im.contexts.profile.config :as profile.config]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.transforms :as transforms]))
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defonce ^:private active-listeners (atom []))
|
||||
|
||||
@@ -32,106 +32,45 @@
|
||||
(rf/reg-fx :effects.keycard/register-card-events register-card-events)
|
||||
(rf/reg-fx :effects.keycard/unregister-card-events unregister-card-events)
|
||||
|
||||
(defn check-nfc-enabled
|
||||
[]
|
||||
(log/debug "[keycard] check-nfc-enabled")
|
||||
(keycard/check-nfc-enabled
|
||||
{:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response] check-nfc-enabled")
|
||||
(rf/dispatch [:keycard/on-check-nfc-enabled-success response]))}))
|
||||
(rf/reg-fx :effects.keycard/check-nfc-enabled check-nfc-enabled)
|
||||
(rf/reg-fx :effects.keycard/get-application-info
|
||||
(fn [args]
|
||||
(keycard/get-application-info (keycard.utils/wrap-handlers args))))
|
||||
|
||||
(rf/reg-fx :effects.keycard/get-keys
|
||||
(fn [args]
|
||||
(keycard/get-keys (keycard.utils/wrap-handlers args))))
|
||||
|
||||
(rf/reg-fx :effects.keycard/sign
|
||||
(fn [args]
|
||||
(keycard/sign (keycard.utils/wrap-handlers args))))
|
||||
|
||||
(rf/reg-fx :keycard/init-card
|
||||
(fn [args]
|
||||
(keycard/init-card (keycard.utils/wrap-handlers args))))
|
||||
|
||||
(rf/reg-fx :effects.keycard/generate-and-load-key
|
||||
(fn [args]
|
||||
(keycard/generate-and-load-key (keycard.utils/wrap-handlers args))))
|
||||
|
||||
(rf/reg-fx :effects.keycard/login-with-keycard
|
||||
(fn [{:keys [key-uid password whisper-private-key]}]
|
||||
(native-module/login-account
|
||||
(assoc (profile.config/login)
|
||||
:keyUid key-uid
|
||||
:password password
|
||||
:keycardWhisperPrivateKey whisper-private-key))))
|
||||
|
||||
(rf/reg-fx :effects.keycard/set-pairing-to-keycard
|
||||
(fn [pairings]
|
||||
(keycard/set-pairings pairings)))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.keycard.ios/start-nfc
|
||||
(fn [args]
|
||||
(log/debug "fx start-nfc")
|
||||
(keycard/start-nfc args)))
|
||||
:keycard/persist-pairings
|
||||
(fn [pairings]
|
||||
(async-storage/set-item! "status-keycard-pairings" pairings)))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.keycard.ios/stop-nfc
|
||||
(fn [args]
|
||||
(log/debug "fx stop-nfc")
|
||||
(keycard/stop-nfc args)))
|
||||
|
||||
(defn- error-object->map
|
||||
[^js object]
|
||||
{:code (.-code object)
|
||||
:error (.-message object)})
|
||||
|
||||
(defn get-application-info
|
||||
[{:keys [on-success on-failure] :as args}]
|
||||
(log/debug "[keycard] get-application-info")
|
||||
(keycard/get-application-info
|
||||
(assoc
|
||||
args
|
||||
:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] get-application-info")
|
||||
(when on-success
|
||||
(on-success response)))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/error "[keycard response fail] get-application-info")
|
||||
(when on-failure
|
||||
(on-failure (error-object->map response)))))))
|
||||
(rf/reg-fx :effects.keycard/get-application-info get-application-info)
|
||||
|
||||
(defn get-keys
|
||||
[{:keys [on-success on-failure] :as args}]
|
||||
(log/debug "[keycard] get-keys")
|
||||
(keycard/get-keys
|
||||
(assoc
|
||||
args
|
||||
:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] get-keys")
|
||||
(when on-success
|
||||
(on-success (transforms/js->clj response))))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/warn "[keycard response fail] get-keys"
|
||||
(error-object->map response))
|
||||
(when on-failure
|
||||
(on-failure (error-object->map response)))))))
|
||||
(rf/reg-fx :effects.keycard/get-keys get-keys)
|
||||
|
||||
(defn login
|
||||
[{:keys [key-uid password whisper-private-key]}]
|
||||
(native-module/login-account
|
||||
(assoc (profile.config/login)
|
||||
:keyUid key-uid
|
||||
:password password
|
||||
:keycardWhisperPrivateKey whisper-private-key)))
|
||||
(rf/reg-fx :effects.keycard/login-with-keycard login)
|
||||
|
||||
(defn retrieve-pairings
|
||||
[]
|
||||
(async-storage/get-item
|
||||
"status-keycard-pairings"
|
||||
#(rf/dispatch [:keycard/on-retrieve-pairings-success %])))
|
||||
(rf/reg-fx :effects.keycard/retrieve-pairings retrieve-pairings)
|
||||
|
||||
(defn set-pairing-to-keycard
|
||||
[pairings]
|
||||
(keycard/set-pairings pairings))
|
||||
(rf/reg-fx :effects.keycard/set-pairing-to-keycard set-pairing-to-keycard)
|
||||
|
||||
(defn sign
|
||||
[{:keys [on-success on-failure] :as args}]
|
||||
(log/debug "[keycard] sign")
|
||||
(keycard/sign
|
||||
(assoc
|
||||
args
|
||||
:on-success
|
||||
(fn [response]
|
||||
(log/debug "[keycard response succ] sign")
|
||||
(when on-success
|
||||
(on-success (transforms/js->clj response))))
|
||||
:on-failure
|
||||
(fn [response]
|
||||
(log/warn "[keycard response fail] sign"
|
||||
(error-object->map response))
|
||||
(when on-failure
|
||||
(on-failure (error-object->map response)))))))
|
||||
(rf/reg-fx :effects.keycard/sign sign)
|
||||
(rf/reg-fx :effects.keycard/retrieve-pairings
|
||||
(fn []
|
||||
(async-storage/get-item
|
||||
"status-keycard-pairings"
|
||||
#(rf/dispatch [:keycard/on-retrieve-pairings-success %]))))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.events-helper :as events-helper]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.contexts.keycard.sheets.migrate.view :as sheets.migrate]
|
||||
[status-im.contexts.keycard.migrate.sheets.view :as sheets.migrate]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -11,10 +11,8 @@
|
||||
[]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:key :header
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press events-helper/navigate-back}]
|
||||
{:icon-name :i/close
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/keycard-empty)
|
||||
:description :text
|
||||
@@ -26,10 +24,15 @@
|
||||
:subtitle (i18n/label :t/use-keycard-login-sign)
|
||||
:button-label (i18n/label :t/import-profile-key-pair)
|
||||
:accessibility-label :get-keycard
|
||||
:image (resources/get-image :generate-keys)
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:theme :dark
|
||||
:content (fn [] [sheets.migrate/view])}])}]]
|
||||
:image (resources/get-image :keycard-buy)
|
||||
:on-press (fn []
|
||||
(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:theme :dark
|
||||
:content (fn []
|
||||
[sheets.migrate/view
|
||||
{:on-continue #(rf/dispatch
|
||||
[:keycard/migration.get-phrase])}])}]))}]]
|
||||
[quo/information-box
|
||||
{:type :default
|
||||
:style {:margin-top 32 :margin-horizontal 28}}
|
||||
|
||||
@@ -1,42 +1,37 @@
|
||||
(ns status-im.contexts.keycard.error.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.events-helper :as events-helper]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def titles
|
||||
{:keycard/error.keycard-wrong {:title "Keycard is not empty"
|
||||
:description "You can’t use it to store new keys right now"}
|
||||
:keycard/error.keycard-unpaired {:title "Keycard is full"
|
||||
:description "All pairing slots are occupied"}
|
||||
:keycard/error.keycard-frozen {:title "Keycard is locked"
|
||||
:description "You can’t use it right now"}
|
||||
:keycard/error.keycard-locked {:title "Keycard is locked"
|
||||
:description "You can’t use it right now"}})
|
||||
{:keycard/error.keycard-blank {:title (i18n/label :t/keycard-empty)
|
||||
:description (i18n/label :t/no-key-pair-keycard)}
|
||||
:keycard/error.keycard-wrong-profile {:title (i18n/label :t/keycard-not-empty)
|
||||
:description (i18n/label :t/cant-store-new-keys)}
|
||||
:keycard/error.keycard-unpaired {:title (i18n/label :t/keycard-full)
|
||||
:description (i18n/label :t/pairing-slots-occupied)}
|
||||
:keycard/error.keycard-frozen {:title (i18n/label :t/keycard-locked)
|
||||
:description (i18n/label :t/cant-use-right-now)}
|
||||
:keycard/error.keycard-locked {:title (i18n/label :t/keycard-locked)
|
||||
:description (i18n/label :t/cant-use-right-now)}})
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [{:keys [top bottom]} (safe-area/get-insets)
|
||||
error (rf/sub [:keycard/application-info-error])
|
||||
(let [error (rf/sub [:keycard/application-info-error])
|
||||
{:keys [title description]} (get titles error)]
|
||||
[quo/overlay
|
||||
{:type :shell
|
||||
:container-style {:padding-top top
|
||||
:padding-bottom bottom}}
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:key :header
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press events-helper/navigate-back}]
|
||||
{:icon-name :i/close
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title title
|
||||
:description :text
|
||||
:description-text description}]
|
||||
[rn/view {:height 226}]
|
||||
[rn/view {:padding-horizontal 20}
|
||||
[quo/info-message
|
||||
{:container-style {:padding-top 15}
|
||||
:icon :i/info
|
||||
:size :default}
|
||||
"To unlock or factory reset the Keycard, please use the Status desktop app. If you'd like this features on mobile, feel free to upvote them and discuss in the Status community."]]]))
|
||||
[rn/view {:style {:margin-horizontal 20}}
|
||||
[quo/keycard {:holder-name ""}]
|
||||
[quo/information-box
|
||||
{:type :default
|
||||
:style {:margin-top 20}}
|
||||
(i18n/label :t/unlock-reset-instructions)]]]))
|
||||
|
||||
@@ -1,116 +1,117 @@
|
||||
(ns status-im.contexts.keycard.events
|
||||
(:require [re-frame.core :as rf]
|
||||
status-im.contexts.keycard.login.events
|
||||
status-im.contexts.keycard.nfc-sheet.events
|
||||
status-im.contexts.keycard.migrate.events
|
||||
status-im.contexts.keycard.migrate.re-encrypting.events
|
||||
status-im.contexts.keycard.nfc.events
|
||||
status-im.contexts.keycard.nfc.sheets.events
|
||||
status-im.contexts.keycard.pin.events
|
||||
status-im.contexts.keycard.sign.events
|
||||
[status-im.contexts.keycard.utils :as keycard.utils]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(rf/reg-event-fx :keycard/on-check-nfc-enabled-success
|
||||
(fn [{:keys [db]} [nfc-enabled?]]
|
||||
{:db (assoc-in db [:keycard :nfc-enabled?] nfc-enabled?)}))
|
||||
|
||||
(rf/reg-event-fx :keycard.ios/on-nfc-user-cancelled
|
||||
(fn [{:keys [db]}]
|
||||
(log/debug "[keycard] nfc user cancelled")
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :pin :status] nil)
|
||||
(assoc-in [:keycard :on-nfc-cancelled-event-vector] nil))
|
||||
:fx [(when-let [on-nfc-cancelled-event-vector (get-in db [:keycard :on-nfc-cancelled-event-vector])]
|
||||
[:dispatch on-nfc-cancelled-event-vector])]}))
|
||||
utils.datetime))
|
||||
|
||||
(rf/reg-event-fx :keycard/on-card-connected
|
||||
(fn [{:keys [db]} _]
|
||||
(log/debug "[keycard] card globally connected")
|
||||
{:db (assoc-in db [:keycard :card-connected?] true)
|
||||
:fx [(when-let [event (get-in db [:keycard :on-card-connected-event-vector])]
|
||||
[:dispatch event])]}))
|
||||
|
||||
(rf/reg-event-fx :keycard/on-card-disconnected
|
||||
(fn [{:keys [db]} _]
|
||||
(log/debug "[keycard] card disconnected")
|
||||
{:db (assoc-in db [:keycard :card-connected?] false)
|
||||
:fx [(when-let [event (get-in db [:keycard :on-card-disconnected-event-vector])]
|
||||
[:dispatch event])]}))
|
||||
|
||||
(rf/reg-event-fx :keycard.ios/start-nfc
|
||||
(fn [_]
|
||||
{:effects.keycard.ios/start-nfc nil}))
|
||||
|
||||
(rf/reg-event-fx :keycard.ios/on-nfc-timeout
|
||||
(fn [{:keys [db]} _]
|
||||
(log/debug "[keycard] nfc timeout")
|
||||
{:db (assoc-in db [:keycard :card-connected?] false)
|
||||
:fx [[:dispatch-later [{:ms 500 :dispatch [:keycard.ios/start-nfc]}]]]}))
|
||||
|
||||
(rf/reg-event-fx :keycard/on-retrieve-pairings-success
|
||||
(fn [{:keys [db]} [pairings]]
|
||||
{:db (assoc-in db [:keycard :pairings] pairings)
|
||||
:fx [[:effects.keycard/set-pairing-to-keycard pairings]]}))
|
||||
|
||||
(rf/reg-event-fx :keycard.ios/on-start-nfc-success
|
||||
(fn [{:keys [db]} [{:keys [on-cancel-event-vector]}]]
|
||||
(log/debug "[keycard] nfc started success")
|
||||
{:db (assoc-in db [:keycard :on-nfc-cancelled-event-vector] on-cancel-event-vector)}))
|
||||
(rf/reg-event-fx :keycard/update-pairings
|
||||
(fn [{:keys [db]} [instance-uid pairing]]
|
||||
(let [pairings (get-in db [:keycard :pairings])
|
||||
new-pairings (assoc pairings
|
||||
instance-uid
|
||||
{:pairing pairing
|
||||
:paired-on (utils.datetime/timestamp)})]
|
||||
{:db (assoc-in db [:keycard :pairings] new-pairings)
|
||||
:keycard/persist-pairings new-pairings})))
|
||||
|
||||
(rf/reg-event-fx :keycard/on-action-with-pin-error
|
||||
(fn [{:keys [db]} [error]]
|
||||
(log/debug "[keycard] on-action-with-pin-error: " error)
|
||||
(let [tag-was-lost? (keycard.utils/tag-lost? (:error error))
|
||||
pin-retries-count (keycard.utils/pin-retries (:error error))]
|
||||
(if tag-was-lost?
|
||||
(if (or tag-was-lost? (nil? pin-retries-count))
|
||||
{:db (assoc-in db [:keycard :pin :status] nil)}
|
||||
(if (nil? pin-retries-count)
|
||||
{:effects.utils/show-popup {:title "wrong-keycard"}}
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :application-info :pin-retry-counter] pin-retries-count)
|
||||
(assoc-in [:keycard :pin :status] :error))
|
||||
:fx [[:dispatch [:keycard/disconnect]]
|
||||
(when (zero? pin-retries-count)
|
||||
[:effects.utils/show-popup {:title "frozen-keycard"}])]})))))
|
||||
|
||||
(rf/reg-event-fx :keycard/on-get-application-info-success
|
||||
(fn [{:keys [db]} [application-info {:keys [key-uid on-success-fx]}]]
|
||||
(if-let [error (keycard.utils/validate-application-info key-uid application-info)]
|
||||
(case error
|
||||
:keycard/error.not-keycard
|
||||
{:fx [[:dispatch [:keycard/disconnect]]
|
||||
[:dispatch [:open-modal :screen/keycard.not-keycard]]]}
|
||||
:keycard/error.keycard-blank
|
||||
{:fx [[:dispatch [:keycard/disconnect]]
|
||||
[:dispatch [:open-modal :screen/keycard.empty]]]}
|
||||
{:db (assoc-in db [:keycard :application-info-error] error)
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :application-info :pin-retry-counter] pin-retries-count)
|
||||
(assoc-in [:keycard :pin :status] :error))
|
||||
:fx [[:dispatch [:keycard/disconnect]]
|
||||
[:dispatch [:open-modal :screen/keycard.error]]]})
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :application-info] application-info)
|
||||
(assoc-in [:keycard :pin :status] :verifying))
|
||||
:fx on-success-fx})))
|
||||
(when (zero? pin-retries-count)
|
||||
[:dispatch
|
||||
[:keycard/on-application-info-error
|
||||
:keycard/error.keycard-locked]])]}))))
|
||||
|
||||
(rf/reg-event-fx :keycard/get-application-info
|
||||
(fn [_ [{:keys [on-success on-failure]}]]
|
||||
{:effects.keycard/get-application-info {:on-success on-success :on-failure on-failure}}))
|
||||
(rf/reg-event-fx :keycard/get-keys
|
||||
(fn [_ [data]]
|
||||
{:effects.keycard/get-keys data}))
|
||||
|
||||
(rf/reg-event-fx :keycard/cancel-connection
|
||||
(fn [{:keys [db]}]
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :on-card-connected-event-vector] nil)
|
||||
(assoc-in [:keycard :on-nfc-cancelled-event-vector] nil))}))
|
||||
{:db (update db :keycard dissoc :on-card-connected-event-vector :on-nfc-cancelled-event-vector)}))
|
||||
|
||||
(rf/reg-event-fx :keycard/disconnect
|
||||
(fn [_ _]
|
||||
{:fx [[:dispatch [:keycard/cancel-connection]]
|
||||
[:dispatch [:keycard/hide-connection-sheet]]]}))
|
||||
|
||||
(rf/reg-event-fx :keycard/on-application-info-error
|
||||
(fn [{:keys [db]} [error]]
|
||||
{:db (assoc-in db [:keycard :application-info-error] error)
|
||||
:fx [[:dispatch [:keycard/disconnect]]
|
||||
[:dispatch
|
||||
[:open-modal
|
||||
(if (= :keycard/error.not-keycard error)
|
||||
:screen/keycard.not-keycard
|
||||
:screen/keycard.error)]]]}))
|
||||
|
||||
(rf/reg-event-fx :keycard/update-application-info
|
||||
(fn [{:keys [db]} [app-info]]
|
||||
{:db (update db
|
||||
:keycard
|
||||
#(-> %
|
||||
(assoc :application-info app-info)
|
||||
(dissoc :application-info-error)))}))
|
||||
|
||||
(rf/reg-event-fx :keycard/get-application-info
|
||||
(fn [_ [{:keys [key-uid on-success on-error]}]]
|
||||
{:effects.keycard/get-application-info
|
||||
{:on-success (fn [{:keys [instance-uid new-pairing] :as app-info}]
|
||||
(rf/dispatch [:keycard/update-application-info app-info])
|
||||
(when (and instance-uid new-pairing)
|
||||
(rf/dispatch [:keycard/update-pairings instance-uid new-pairing]))
|
||||
(if-let [error (keycard.utils/validate-application-info key-uid app-info)]
|
||||
(if on-error
|
||||
(on-error error)
|
||||
(rf/dispatch [:keycard/on-application-info-error error]))
|
||||
(when on-success (on-success app-info))))
|
||||
:on-error (fn []
|
||||
(if on-error
|
||||
(on-error :keycard/error.not-keycard)
|
||||
(rf/dispatch [:keycard/on-application-info-error
|
||||
:keycard/error.not-keycard])))}}))
|
||||
|
||||
(rf/reg-event-fx :keycard/connect
|
||||
(fn [{:keys [db]} [args]]
|
||||
(let [connected? (get-in db [:keycard :card-connected?])
|
||||
event-vector [:keycard/get-application-info
|
||||
{:on-success #(rf/dispatch [:keycard/on-get-application-info-success % args])}]]
|
||||
(fn [{:keys [db]} [{:keys [key-uid on-success on-error on-connect-event-vector]}]]
|
||||
(let [event-vector
|
||||
(or on-connect-event-vector
|
||||
[:keycard/get-application-info
|
||||
{:key-uid key-uid
|
||||
:on-success on-success
|
||||
:on-error on-error}])]
|
||||
{:db (assoc-in db [:keycard :on-card-connected-event-vector] event-vector)
|
||||
:fx [[:dispatch
|
||||
[:keycard/show-connection-sheet
|
||||
{:on-cancel-event-vector [:keycard/cancel-connection]}]]
|
||||
(when connected?
|
||||
(when (get-in db [:keycard :card-connected?])
|
||||
[:dispatch event-vector])]})))
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
(fn [{:keys [db]} [data]]
|
||||
(let [{:keys [key-uid encryption-public-key
|
||||
whisper-private-key]} data
|
||||
key-uid (str "0x" key-uid)
|
||||
profile (get-in db [:profile/profiles-overview key-uid])]
|
||||
{:db
|
||||
(-> db
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
(ns status-im.contexts.keycard.migrate.events
|
||||
(:require [clojure.string :as string]
|
||||
[status-im.contexts.keycard.pin.view :as keycard.pin]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(rf/reg-event-fx :keycard/migration.check-empty-card
|
||||
(fn [{:keys [db]}]
|
||||
{:fx [[:dispatch
|
||||
[:keycard/connect
|
||||
{:key-uid (get-in db [:profile/profile :key-uid])
|
||||
:on-success
|
||||
(fn []
|
||||
;;TODO keys already on the keycard, new flow needs to be implemented
|
||||
;; https://github.com/status-im/status-mobile/issues/21446
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch [:open-modal :screen/keycard.authorise
|
||||
{:on-success
|
||||
#(rf/dispatch [:keycard/migration.authorisation-success %])}]))
|
||||
:on-error
|
||||
(fn [error]
|
||||
(if (= error :keycard/error.keycard-blank)
|
||||
(do
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch [:open-modal :screen/keycard.empty]))
|
||||
(rf/dispatch [:keycard/on-application-info-error error])))}]]]}))
|
||||
|
||||
(defn get-application-info-and-continue
|
||||
[key-uid]
|
||||
(rf/dispatch [:keycard/get-application-info
|
||||
{:key-uid key-uid
|
||||
:on-success #(rf/dispatch [:keycard/migration.continue])
|
||||
:on-error
|
||||
(fn [error]
|
||||
(if (= error :keycard/error.keycard-blank)
|
||||
(rf/dispatch [:keycard/migration.continue])
|
||||
(rf/dispatch [:keycard/on-application-info-error error])))}]))
|
||||
|
||||
(rf/reg-event-fx :keycard/migration.continue
|
||||
(fn [{:keys [db]}]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])
|
||||
{:keys [initialized? has-master-key?]} (get-in db [:keycard :application-info])
|
||||
{:keys [masked-phrase pin]} (get-in db [:keycard :migration])
|
||||
on-failure (fn []
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch [:navigate-to
|
||||
:screen/keycard.migrate.fail]))]
|
||||
(cond
|
||||
|
||||
(not initialized?)
|
||||
{:fx [[:keycard/init-card
|
||||
{:pin pin
|
||||
:on-success #(get-application-info-and-continue key-uid)
|
||||
:on-failure on-failure}]]}
|
||||
|
||||
(not has-master-key?)
|
||||
{:fx [[:effects.keycard/generate-and-load-key
|
||||
{:mnemonic (security/safe-unmask-data masked-phrase)
|
||||
:pin pin
|
||||
:on-success #(get-application-info-and-continue key-uid)
|
||||
:on-failure on-failure}]]}
|
||||
|
||||
:else
|
||||
{:fx [[:effects.keycard/get-keys
|
||||
{:pin pin
|
||||
:on-success #(rf/dispatch [:keycard/migration.convert-to-keycard-profile %])
|
||||
:on-failure on-failure}]]}))))
|
||||
|
||||
(rf/reg-event-fx :keycard/migration.start
|
||||
(fn [{:keys [db]}]
|
||||
{:fx [[:dispatch
|
||||
[:keycard/connect
|
||||
{:key-uid (get-in db [:profile/profile :key-uid])
|
||||
:on-success #(rf/dispatch [:keycard/migration.continue])
|
||||
:on-error
|
||||
(fn [error]
|
||||
(if (= error :keycard/error.keycard-blank)
|
||||
(rf/dispatch [:keycard/migration.continue])
|
||||
(rf/dispatch [:keycard/on-application-info-error error])))}]]]}))
|
||||
|
||||
(rf/reg-event-fx :keycard/migration.get-phrase
|
||||
(fn [{:keys [db]}]
|
||||
{:db (assoc-in db [:keycard :migration] nil)
|
||||
:fx [[:dispatch [:navigate-back]]
|
||||
(if (string/blank? (get-in db [:profile/profile :mnemonic]))
|
||||
[:dispatch
|
||||
[:open-modal :screen/use-recovery-phrase
|
||||
{:on-success #(rf/dispatch [:keycard/migration.phrase-entered %])}]]
|
||||
[:dispatch
|
||||
[:open-modal :screen/backup-recovery-phrase
|
||||
{:on-success #(rf/dispatch [:keycard/migration.phrase-backed-up %])}]])]}))
|
||||
|
||||
(rf/reg-event-fx :keycard/migration.phrase-entered
|
||||
(fn [{:keys [db]} [{:keys [phrase]}]]
|
||||
{:db (assoc-in db [:keycard :migration :masked-phrase] (security/mask-data phrase))
|
||||
:fx [[:dispatch [:navigate-back]]
|
||||
[:dispatch
|
||||
[:open-modal :screen/keycard.authorise
|
||||
{:on-success #(rf/dispatch [:keycard/migration.authorisation-success %])}]]]}))
|
||||
|
||||
(rf/reg-event-fx :keycard/migration.phrase-backed-up
|
||||
(fn [{:keys [db]}]
|
||||
{:db (assoc-in db
|
||||
[:keycard :migration :masked-phrase]
|
||||
(security/mask-data (get-in db [:profile/profile :mnemonic])))
|
||||
:fx [[:dispatch [:profile.settings/profile-update :mnemonic nil]]
|
||||
[:dispatch [:navigate-back]]
|
||||
[:dispatch
|
||||
[:open-modal :screen/keycard.authorise
|
||||
{:on-success #(rf/dispatch [:keycard/migration.authorisation-success %])}]]]}))
|
||||
|
||||
(rf/reg-event-fx :keycard/migration.authorisation-success
|
||||
(fn [{:keys [db]} [masked-password]]
|
||||
(let [{:keys [initialized?]} (get-in db [:keycard :application-info])]
|
||||
{:db (assoc-in db [:keycard :migration :masked-password] masked-password)
|
||||
:fx [[:dispatch [:navigate-back]]
|
||||
(if initialized?
|
||||
[:dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn []
|
||||
[keycard.pin/auth
|
||||
{:on-complete #(rf/dispatch [:keycard/migration.pin-created %])}])}]]
|
||||
[:dispatch
|
||||
[:open-modal :screen/keycard.pin.create
|
||||
{:on-complete (fn [new-pin]
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:keycard/migration.pin-created new-pin]))}]])]})))
|
||||
|
||||
(rf/reg-event-fx :keycard/migration.pin-created
|
||||
(fn [{:keys [db]} [pin]]
|
||||
{:db (assoc-in db [:keycard :migration :pin] pin)
|
||||
:fx [[:dispatch [:open-modal :screen/keycard.migrate]]]}))
|
||||
@@ -0,0 +1,32 @@
|
||||
(ns status-im.contexts.keycard.migrate.fail.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.constants :as constants]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [profile-name (rf/sub [:profile/name])
|
||||
profile-picture (rf/sub [:profile/image])
|
||||
customization-color (rf/sub [:profile/customization-color])]
|
||||
[:<>
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/failed-to-migrate-key-pair)
|
||||
:description :context-tag
|
||||
:context-tag {:full-name profile-name
|
||||
:profile-picture profile-picture
|
||||
:customization-color customization-color}
|
||||
:container-style {:margin-top constants/page-nav-height}}]
|
||||
[rn/view {:style {:flex 1 :align-items :center :justify-content :center}}
|
||||
[rn/image
|
||||
{:resize-mode :contain
|
||||
:source (resources/get-image :keycard-migration-failed)}]]
|
||||
[quo/divider-label (i18n/label :t/what-you-can-do)]
|
||||
[quo/markdown-list {:description (i18n/label :t/log-out-remove-profile)}]
|
||||
[quo/markdown-list {:description (i18n/label :t/recover-status-profile)}]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (i18n/label :t/log-out-remove)
|
||||
:button-one-props {:on-press #(rf/dispatch [:logout])}}]]))
|
||||
@@ -0,0 +1,31 @@
|
||||
(ns status-im.contexts.keycard.migrate.re-encrypting.events
|
||||
(:require [clojure.string :as string]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(rf/reg-event-fx :keycard/migration.convert-to-keycard-profile
|
||||
(fn [{:keys [db]} [{:keys [key-uid instance-uid encryption-public-key]}]]
|
||||
(let [{:keys [masked-password]} (get-in db [:keycard :migration])
|
||||
{:keys [pairing paired-on]} (get-in db [:keycard :pairings instance-uid])
|
||||
{:keys [kdfIterations]} (:profile/profile db)]
|
||||
{:fx [[:dispatch [:keycard/disconnect]]
|
||||
[:dispatch [:navigate-back]]
|
||||
[:dispatch [:open-modal :screen/keycard.re-encrypting]]
|
||||
[:effects.profile/convert-to-keycard-profile
|
||||
{:profile
|
||||
{:key-uid key-uid
|
||||
:keycard-pairing pairing
|
||||
:kdfIterations kdfIterations}
|
||||
:settings
|
||||
{:keycard-instance-uid instance-uid
|
||||
:keycard-paired-on paired-on
|
||||
:keycard-pairing pairing}
|
||||
:password
|
||||
(security/safe-unmask-data masked-password)
|
||||
:new-password
|
||||
encryption-public-key
|
||||
:callback
|
||||
(fn [{:keys [error]}]
|
||||
(if (string/blank? error)
|
||||
(rf/dispatch [:navigate-to :screen/keycard.migrate.success])
|
||||
(rf/dispatch [:navigate-to :screen/keycard.migrate.fail])))}]]})))
|
||||
@@ -0,0 +1,27 @@
|
||||
(ns status-im.contexts.keycard.migrate.re-encrypting.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.constants :as constants]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [profile-name (rf/sub [:profile/name])
|
||||
profile-picture (rf/sub [:profile/image])
|
||||
customization-color (rf/sub [:profile/customization-color])]
|
||||
[:<>
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/re-encrypting-data)
|
||||
:description :context-tag
|
||||
:context-tag {:full-name profile-name
|
||||
:profile-picture profile-picture
|
||||
:customization-color customization-color}
|
||||
:container-style {:margin-top constants/page-nav-height}}]
|
||||
[quo/text {:style {:padding-horizontal 20}}
|
||||
(i18n/label :t/do-not-quit)]
|
||||
[rn/view {:style {:flex 1 :align-items :center :justify-content :center}}
|
||||
[rn/image
|
||||
{:resize-mode :contain
|
||||
:source (resources/get-image :keycard-migration)}]]]))
|
||||
@@ -1,15 +1,14 @@
|
||||
(ns status-im.contexts.keycard.sheets.migrate.view
|
||||
(ns status-im.contexts.keycard.migrate.sheets.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [profile-name (rf/sub [:profile/name])
|
||||
profile-picture (rf/sub [:profile/image])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
recovery-phrase-backed-up? (rf/sub [:profile/recovery-phrase-backed-up?])]
|
||||
[{:keys [on-continue]}]
|
||||
(let [profile-name (rf/sub [:profile/name])
|
||||
profile-picture (rf/sub [:profile/image])
|
||||
customization-color (rf/sub [:profile/customization-color])]
|
||||
[:<>
|
||||
[quo/drawer-top
|
||||
{:type :context-tag
|
||||
@@ -28,11 +27,7 @@
|
||||
[quo/bottom-actions
|
||||
{:actions :two-actions
|
||||
:button-one-label (i18n/label :t/continue)
|
||||
:button-one-props {:on-press #(if recovery-phrase-backed-up?
|
||||
(rf/dispatch [:open-modal :screen/use-recovery-phrase
|
||||
{:on-success (fn [])}])
|
||||
(rf/dispatch [:open-modal :screen/backup-recovery-phrase
|
||||
{:on-success (fn [])}]))}
|
||||
:button-one-props {:on-press on-continue}
|
||||
:button-two-label (i18n/label :t/cancel)
|
||||
:button-two-props {:type :grey
|
||||
:on-press #(rf/dispatch [:hide-bottom-sheet])}}]]))
|
||||
@@ -0,0 +1,31 @@
|
||||
(ns status-im.contexts.keycard.migrate.success.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.constants :as constants]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [profile-name (rf/sub [:profile/name])
|
||||
profile-picture (rf/sub [:profile/image])
|
||||
customization-color (rf/sub [:profile/customization-color])]
|
||||
[:<>
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/key-pair-migrated-successfully)
|
||||
:description :context-tag
|
||||
:context-tag {:full-name profile-name
|
||||
:profile-picture profile-picture
|
||||
:customization-color customization-color}
|
||||
:container-style {:margin-top constants/page-nav-height}}]
|
||||
[quo/text {:style {:padding-horizontal 20}}
|
||||
(i18n/label :t/use-keycard-for-status)]
|
||||
[rn/view {:style {:flex 1 :align-items :center :justify-content :center}}
|
||||
[rn/image
|
||||
{:resize-mode :contain
|
||||
:source (resources/get-image :keycard-migration-succeeded)}]]
|
||||
[quo/button
|
||||
{:on-press #(rf/dispatch [:logout])
|
||||
:container-style {:margin-horizontal 20}}
|
||||
(i18n/label :t/logout)]]))
|
||||
@@ -0,0 +1,34 @@
|
||||
(ns status-im.contexts.keycard.migrate.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.events-helper :as events-helper]
|
||||
[status-im.common.resources :as resources]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [profile-name (rf/sub [:profile/name])
|
||||
profile-picture (rf/sub [:profile/image])
|
||||
customization-color (rf/sub [:profile/customization-color])]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:icon-name :i/close
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/ready-to-migrate-key-pair)
|
||||
:description :context-tag
|
||||
:context-tag {:full-name profile-name
|
||||
:profile-picture profile-picture
|
||||
:customization-color customization-color}}]
|
||||
[rn/view {:style {:flex 1 :align-items :center :justify-content :center}}
|
||||
[rn/image
|
||||
{:resize-mode :contain
|
||||
:source (resources/get-image :keycard-migration)}]]
|
||||
[quo/divider-label (i18n/label :t/tips-scan-keycard)]
|
||||
[quo/markdown-list {:description (i18n/label :t/remove-phone-case)}]
|
||||
[quo/markdown-list {:description (i18n/label :t/keep-card-steady)}]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (i18n/label :t/scan-keycard)
|
||||
:button-one-props {:on-press #(rf/dispatch [:keycard/migration.start])}}]]))
|
||||
@@ -0,0 +1,11 @@
|
||||
(ns status-im.contexts.keycard.nfc.effects
|
||||
(:require [keycard.keycard :as keycard]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/reg-fx :effects.keycard/check-nfc-enabled
|
||||
(fn []
|
||||
(keycard/check-nfc-enabled
|
||||
{:on-success #(rf/dispatch [:keycard/on-check-nfc-enabled-success %])})))
|
||||
|
||||
(rf/reg-fx :effects.keycard.ios/start-nfc keycard/start-nfc)
|
||||
(rf/reg-fx :effects.keycard.ios/stop-nfc keycard/stop-nfc)
|
||||
@@ -0,0 +1,27 @@
|
||||
(ns status-im.contexts.keycard.nfc.events
|
||||
(:require [utils.re-frame :as rf]))
|
||||
|
||||
(rf/reg-event-fx :keycard.ios/start-nfc
|
||||
(fn [_]
|
||||
{:fx [[:effects.keycard.ios/start-nfc]]}))
|
||||
|
||||
(rf/reg-event-fx :keycard.ios/on-start-nfc-success
|
||||
(fn [{:keys [db]} [{:keys [on-cancel-event-vector]}]]
|
||||
{:db (assoc-in db [:keycard :on-nfc-cancelled-event-vector] on-cancel-event-vector)}))
|
||||
|
||||
(rf/reg-event-fx :keycard.ios/on-nfc-timeout
|
||||
(fn [{:keys [db]} _]
|
||||
{:db (assoc-in db [:keycard :card-connected?] false)
|
||||
:fx [[:dispatch-later [{:ms 500 :dispatch [:keycard.ios/start-nfc]}]]]}))
|
||||
|
||||
(rf/reg-event-fx :keycard/on-check-nfc-enabled-success
|
||||
(fn [{:keys [db]} [nfc-enabled?]]
|
||||
{:db (assoc-in db [:keycard :nfc-enabled?] nfc-enabled?)}))
|
||||
|
||||
(rf/reg-event-fx :keycard.ios/on-nfc-user-cancelled
|
||||
(fn [{:keys [db]}]
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :pin :status] nil)
|
||||
(assoc-in [:keycard :on-nfc-cancelled-event-vector] nil))
|
||||
:fx [(when-let [on-nfc-cancelled-event-vector (get-in db [:keycard :on-nfc-cancelled-event-vector])]
|
||||
[:dispatch on-nfc-cancelled-event-vector])]}))
|
||||
@@ -1,4 +1,4 @@
|
||||
(ns status-im.contexts.keycard.nfc-sheet.events
|
||||
(ns status-im.contexts.keycard.nfc.sheets.events
|
||||
(:require [re-frame.core :as rf]
|
||||
[react-native.platform :as platform]
|
||||
[taoensso.timbre :as log]))
|
||||
@@ -1,4 +1,4 @@
|
||||
(ns status-im.contexts.keycard.nfc-sheet.view
|
||||
(ns status-im.contexts.keycard.nfc.sheets.view
|
||||
(:require [quo.foundations.colors :as colors]
|
||||
quo.theme
|
||||
[react-native.core :as rn]
|
||||
@@ -1,28 +1,24 @@
|
||||
(ns status-im.contexts.keycard.not-keycard.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.events-helper :as events-helper]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
[status-im.common.resources :as resources]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [{:keys [top bottom]} (safe-area/get-insets)]
|
||||
[quo/overlay
|
||||
{:type :shell
|
||||
:container-style {:padding-top top
|
||||
:padding-bottom bottom}}
|
||||
[quo/page-nav
|
||||
{:key :header
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/oops-not-keycard)
|
||||
:description :text
|
||||
:description-text (i18n/label :t/make-sure-keycard)}]
|
||||
[rn/view {:flex 1}]
|
||||
[rn/view {:padding-horizontal 20}
|
||||
[quo/button {:on-press #(rf/dispatch [:keycard/connect])}
|
||||
(i18n/label :t/try-again)]]]))
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:icon-name :i/close
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/oops-not-keycard)
|
||||
:description :text
|
||||
:description-text (i18n/label :t/make-sure-keycard)}]
|
||||
[rn/view {:style {:flex 1 :align-items :center :justify-content :center}}
|
||||
[rn/image
|
||||
{:resize-mode :contain
|
||||
:source (resources/get-image :not-keycard)}]]
|
||||
[rn/view {:padding-horizontal 20}
|
||||
[quo/button {:on-press events-helper/navigate-back}
|
||||
(i18n/label :t/try-again)]]])
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
(:require [clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.events-helper :as events-helper]
|
||||
[status-im.constants :as constants]
|
||||
[utils.i18n :as i18n]))
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[{:keys [on-complete]}]
|
||||
(let [[pin set-pin] (rn/use-state "")
|
||||
[]
|
||||
(let [{:keys [on-complete]} (rf/sub [:get-screen-params])
|
||||
[pin set-pin] (rn/use-state "")
|
||||
[first-pin set-first-pin] (rn/use-state "")
|
||||
[error? set-error] (rn/use-state false)
|
||||
[stage set-stage] (rn/use-state :create)
|
||||
@@ -38,10 +41,15 @@
|
||||
(set-stage :repeat)))))))
|
||||
[pin stage first-pin])]
|
||||
[rn/view {:style {:padding-bottom 12 :flex 1}}
|
||||
[quo/drawer-top
|
||||
{:title (if (= :create stage)
|
||||
(i18n/label :t/create-keycard-pin)
|
||||
(i18n/label :t/repeat-keycard-pin))}]
|
||||
[quo/page-nav
|
||||
{:icon-name :i/close
|
||||
:on-press events-helper/navigate-back}]
|
||||
[quo/page-top
|
||||
{:title (if (= :create stage)
|
||||
(i18n/label :t/create-keycard-pin)
|
||||
(i18n/label :t/repeat-keycard-pin))
|
||||
:description :text
|
||||
:description-text "You’ll need this PIN to login and sign transactions"}]
|
||||
[rn/view {:style {:flex 1 :justify-content :center :align-items :center :padding-vertical 34}}
|
||||
[quo/pin-input
|
||||
{:blur? false
|
||||
|
||||
@@ -23,3 +23,7 @@
|
||||
(assoc-in [:keycard :pin :status] nil))
|
||||
:fx [(when (and on-complete (= (dec max-numbers) (count pin)))
|
||||
[:effects.keycard.pin/dispatch-on-complete [on-complete new-pin]])]}))))
|
||||
|
||||
(rf/reg-event-fx :keycard.pin/clear
|
||||
(fn [{:keys [db]}]
|
||||
{:db (assoc-in db [:keycard :pin] nil)}))
|
||||
|
||||
@@ -6,10 +6,12 @@
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn auth
|
||||
[{:keys [on-complete]}]
|
||||
(let [{:keys [text status]} (rf/sub [:keycard/pin])
|
||||
pin-retry-counter (rf/sub [:keycard/pin-retry-counter])
|
||||
error? (= status :error)]
|
||||
[{:keys [on-complete error]}]
|
||||
(let [{:keys [error? error-message]} error
|
||||
{:keys [text status]} (rf/sub [:keycard/pin])
|
||||
pin-retry-counter (rf/sub [:keycard/pin-retry-counter])
|
||||
error? (or error? (= status :error))]
|
||||
(rn/use-unmount #(rf/dispatch [:keycard.pin/clear]))
|
||||
[rn/view {:padding-bottom 12 :flex 1}
|
||||
[rn/view {:flex 1 :justify-content :center :align-items :center :padding 34}
|
||||
[quo/pin-input
|
||||
@@ -18,7 +20,9 @@
|
||||
:number-of-filled-pins (count text)
|
||||
:error? error?
|
||||
:info (when error?
|
||||
(i18n/label :t/pin-retries-left {:number pin-retry-counter}))}]]
|
||||
(if error-message
|
||||
error-message
|
||||
(i18n/label :t/pin-retries-left {:number pin-retry-counter})))}]]
|
||||
[quo/numbered-keyboard
|
||||
{:delete-key? true
|
||||
:on-delete #(rf/dispatch [:keycard.pin/delete-pressed])
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
:s (subs signature 64 128)
|
||||
:v (str (js/parseInt (subs signature 128 130) 16))}})
|
||||
|
||||
(rf/reg-event-fx :keycard/sign
|
||||
(fn [_ [data]]
|
||||
{:effects.keycard/sign data}))
|
||||
|
||||
(rf/reg-event-fx :keycard/sign-hash
|
||||
(fn [{:keys [db]} [pin-text tx-hash]]
|
||||
(let [current-address (get-in db [:wallet :current-viewing-account-address])
|
||||
@@ -15,16 +19,16 @@
|
||||
key-uid (get-in db [:profile/profile :key-uid])]
|
||||
{:fx [[:dispatch
|
||||
[:keycard/connect
|
||||
{:key-uid key-uid
|
||||
:on-success-fx [[:effects.keycard/sign
|
||||
{:pin pin-text
|
||||
:path path
|
||||
:hash (utils.address/naked-address tx-hash)
|
||||
:on-success
|
||||
#(do
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch
|
||||
[:wallet/proceed-with-transactions-signatures
|
||||
(get-signature-map tx-hash %)]))
|
||||
:on-failure #(rf/dispatch [:keycard/on-action-with-pin-error
|
||||
%])}]]}]]]})))
|
||||
{:key-uid key-uid
|
||||
:on-success
|
||||
(fn []
|
||||
(rf/dispatch
|
||||
[:keycard/sign
|
||||
{:pin pin-text
|
||||
:path path
|
||||
:hash (utils.address/naked-address tx-hash)
|
||||
:on-success (fn [signature]
|
||||
(rf/dispatch [:keycard/disconnect])
|
||||
(rf/dispatch [:wallet/proceed-with-transactions-signatures
|
||||
(get-signature-map tx-hash signature)]))
|
||||
:on-failure #(rf/dispatch [:keycard/on-action-with-pin-error %])}]))}]]]})))
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
(ns status-im.contexts.keycard.utils
|
||||
(:require [taoensso.timbre :as log]))
|
||||
(:require [clojure.string :as string]
|
||||
[utils.address :as address]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(def pin-mismatch-error #"Unexpected error SW, 0x63C(\d+)|wrongPIN\(retryCounter: (\d+)\)")
|
||||
|
||||
@@ -16,33 +18,55 @@
|
||||
(re-matches #".*NFCError:100.*" error)))
|
||||
|
||||
(defn validate-application-info
|
||||
[profile-key-uid {:keys [key-uid paired? pin-retry-counter puk-retry-counter] :as application-info}]
|
||||
(let [profile-mismatch? (or (nil? profile-key-uid) (not= profile-key-uid key-uid))]
|
||||
(log/debug "[keycard]" "login-with-keycard"
|
||||
"empty application info" (empty? application-info)
|
||||
"no key-uid" (empty? key-uid)
|
||||
"profile-mismatch?" profile-mismatch?
|
||||
"no pairing" paired?)
|
||||
(cond
|
||||
(empty? application-info)
|
||||
:keycard/error.not-keycard
|
||||
[profile-key-uid
|
||||
{:keys [key-uid has-master-key? paired? pin-retry-counter puk-retry-counter] :as application-info}]
|
||||
|
||||
(empty? (:key-uid application-info))
|
||||
:keycard/error.keycard-blank
|
||||
(cond
|
||||
(empty? application-info)
|
||||
:keycard/error.not-keycard
|
||||
|
||||
profile-mismatch?
|
||||
:keycard/error.keycard-wrong
|
||||
(not has-master-key?)
|
||||
:keycard/error.keycard-blank
|
||||
|
||||
(not paired?)
|
||||
:keycard/error.keycard-unpaired
|
||||
(not= profile-key-uid key-uid)
|
||||
:keycard/error.keycard-wrong-profile
|
||||
|
||||
(and (zero? pin-retry-counter)
|
||||
(or (nil? puk-retry-counter)
|
||||
(pos? puk-retry-counter)))
|
||||
:keycard/error.keycard-frozen
|
||||
(not paired?)
|
||||
:keycard/error.keycard-unpaired
|
||||
|
||||
(zero? puk-retry-counter)
|
||||
:keycard/error.keycard-locked
|
||||
(and (zero? pin-retry-counter)
|
||||
(or (nil? puk-retry-counter)
|
||||
(pos? puk-retry-counter)))
|
||||
:keycard/error.keycard-frozen
|
||||
|
||||
:else
|
||||
nil)))
|
||||
(zero? puk-retry-counter)
|
||||
:keycard/error.keycard-locked
|
||||
|
||||
:else
|
||||
nil))
|
||||
|
||||
(defn- error-object->map
|
||||
[^js object]
|
||||
{:code (.-code object)
|
||||
:error (.-message object)})
|
||||
|
||||
(defn normalize-key-uid
|
||||
[{:keys [key-uid] :as data}]
|
||||
(if (string/blank? key-uid)
|
||||
data
|
||||
(update data :key-uid address/normalized-hex)))
|
||||
|
||||
(defn get-on-success
|
||||
[{:keys [on-success]}]
|
||||
#(when on-success (on-success (normalize-key-uid (transforms/js->clj %)))))
|
||||
|
||||
(defn get-on-failure
|
||||
[{:keys [on-failure]}]
|
||||
#(when on-failure (on-failure (error-object->map %))))
|
||||
|
||||
(defn wrap-handlers
|
||||
[args]
|
||||
(assoc
|
||||
args
|
||||
:on-success (get-on-success args)
|
||||
:on-failure (get-on-failure args)))
|
||||
|
||||
@@ -37,24 +37,21 @@
|
||||
(defonce is-dragging? (atom nil))
|
||||
(defonce drag-amount (atom nil))
|
||||
|
||||
;; Layout height calculation
|
||||
;; 1. Always prefer on-layout height over window height, as some devices include status bar height in
|
||||
;; the window while others do not.
|
||||
;; https://github.com/status-im/status-mobile/issues/14633#issuecomment-1366191478
|
||||
;; 2. This preference is unless on-layout is triggered with a random value.
|
||||
;; https://github.com/status-im/status-mobile/issues/14849
|
||||
;; To ensure that on-layout height falls within the actual height range, a difference between window
|
||||
;; height and the maximum possible status bar height is allowed (assumed to be 60, as the Pixel emulator
|
||||
;; has a height of 52).
|
||||
(defn store-screen-height
|
||||
[evt]
|
||||
(let [window-height (:height (rn/get-window))
|
||||
height (or (oget evt "nativeEvent" "layout" "height") 0)
|
||||
width (or (oget evt "nativeEvent" "layout" "width") 0)]
|
||||
;; Layout height calculation
|
||||
;; 1. Make sure height is more than width, and on-layout is not fired while the
|
||||
;; screen is horizontal
|
||||
;; 2. Initialize values with 0 in case of nil
|
||||
;; 3. In the case of notch devices, the dimensions height will be smaller than
|
||||
;; on-layout,
|
||||
;; (without status bar height included)
|
||||
;; https://github.com/status-im/status-mobile/issues/14633
|
||||
;; 4. In the case of devices without a notch, both heights should be the same,
|
||||
;; but actual values differ in some pixels, so arbitrary 5 pixels is allowed
|
||||
(when (and (> height width)
|
||||
(>= (+ height 5) (or window-height 0))
|
||||
(not= height @shell.state/screen-height))
|
||||
(let [window-height (or (:height (rn/get-window)) 0)
|
||||
height (or (oget evt "nativeEvent" "layout" "height") 0)]
|
||||
(when (and (not= height @shell.state/screen-height)
|
||||
(< (Math/abs (- window-height height)) 60))
|
||||
(reset! shell.state/screen-height height)
|
||||
(async-storage/set-item! :screen-height height))))
|
||||
|
||||
|
||||
@@ -67,6 +67,28 @@
|
||||
(fn [_ [error]]
|
||||
{:dispatch [:biometric/show-message (ex-cause error)]}))
|
||||
|
||||
;; Navigate to next screen once onboarding animation and account creation both are complete
|
||||
;; Note: If account creation fails, user will get stuck on loading screen
|
||||
;; TODO: Show error screen in case account creation/restoration fails
|
||||
(rf/reg-event-fx :onboarding/account-creation-complete
|
||||
(fn [{:keys [db]} [opts]]
|
||||
(let [loading-animation-complete? (or (:loading-animation-complete? opts)
|
||||
(:onboarding/loading-animation-complete? db))
|
||||
loading-screen (or (:loading-screen opts) (:onboarding/loading-screen db))
|
||||
login-signal-received? (or (:login-signal-received? opts)
|
||||
(:onboarding/login-signal-received? db))]
|
||||
(if (and loading-animation-complete? login-signal-received?)
|
||||
{:db (-> db
|
||||
(dissoc :onboarding/loading-screen)
|
||||
(dissoc :onboarding/loading-animation-complete?)
|
||||
(dissoc :onboarding/login-signal-received?))
|
||||
:fx [[:dispatch
|
||||
[:navigate-to-within-stack [:screen/onboarding.enable-notifications loading-screen]]]]}
|
||||
{:db (-> db
|
||||
(assoc :onboarding/loading-screen loading-screen)
|
||||
(assoc :onboarding/loading-animation-complete? loading-animation-complete?)
|
||||
(assoc :onboarding/login-signal-received? login-signal-received?))}))))
|
||||
|
||||
(rf/defn create-account-and-login
|
||||
{:events [:onboarding/create-account-and-login]}
|
||||
[{:keys [db] :as cofx}]
|
||||
@@ -88,9 +110,9 @@
|
||||
(when-not syncing-account-recovered?
|
||||
[:dispatch [:syncing/clear-syncing-installation-id]])]
|
||||
:dispatch-later [{:ms constants/onboarding-generating-keys-animation-duration-ms
|
||||
:dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.enable-notifications
|
||||
loading-screen]]}]
|
||||
:dispatch [:onboarding/account-creation-complete
|
||||
{:loading-animation-complete? true
|
||||
:loading-screen loading-screen}]}]
|
||||
:db (-> db
|
||||
(dissoc :profile/login)
|
||||
(dissoc :auth-method)
|
||||
|
||||
@@ -25,6 +25,12 @@
|
||||
{:key :i/copy}
|
||||
{:key nil
|
||||
:value "None"}]}
|
||||
{:type :select
|
||||
:key :title-icon
|
||||
:options [{:key :i/chevron-right}
|
||||
{:key :i/copy}
|
||||
{:key nil
|
||||
:value "None"}]}
|
||||
{:type :select
|
||||
:key :right-content
|
||||
:options [{:key nil
|
||||
|
||||
@@ -22,13 +22,10 @@
|
||||
:raribleMainnetAPIKey config/RARIBLE_MAINNET_API_KEY
|
||||
:raribleTestnetAPIKey config/RARIBLE_TESTNET_API_KEY
|
||||
:alchemyEthereumMainnetToken config/ALCHEMY_ETHEREUM_MAINNET_TOKEN
|
||||
:alchemyEthereumGoerliToken config/ALCHEMY_ETHEREUM_GOERLI_TOKEN
|
||||
:alchemyEthereumSepoliaToken config/ALCHEMY_ETHEREUM_SEPOLIA_TOKEN
|
||||
:alchemyOptimismMainnetToken config/ALCHEMY_OPTIMISM_MAINNET_TOKEN
|
||||
:alchemyOptimismGoerliToken config/ALCHEMY_OPTIMISM_GOERLI_TOKEN
|
||||
:alchemyOptimismSepoliaToken config/ALCHEMY_OPTIMISM_SEPOLIA_TOKEN
|
||||
:alchemyArbitrumMainnetToken config/ALCHEMY_ARBITRUM_MAINNET_TOKEN
|
||||
:alchemyArbitrumGoerliToken config/ALCHEMY_ARBITRUM_GOERLI_TOKEN
|
||||
:alchemyArbitrumSepoliaToken config/ALCHEMY_ARBITRUM_SEPOLIA_TOKEN})
|
||||
|
||||
(defn create
|
||||
|
||||
@@ -13,3 +13,7 @@
|
||||
(rf/reg-fx :effects.profile/enable-local-notifications
|
||||
(fn []
|
||||
(native-module/start-local-notifications)))
|
||||
|
||||
(rf/reg-fx :effects.profile/convert-to-keycard-profile
|
||||
(fn [{:keys [profile settings password new-password callback]}]
|
||||
(native-module/convert-to-keycard-profile profile settings password new-password callback)))
|
||||
|
||||
@@ -83,7 +83,8 @@
|
||||
[[:dispatch [:update-theme-and-init-root :screen/onboarding.syncing-results]]]
|
||||
|
||||
(get db :onboarding/new-account?)
|
||||
[[:dispatch [:onboarding/finalize-setup]]]
|
||||
[[:dispatch [:onboarding/finalize-setup]]
|
||||
[:dispatch [:onboarding/account-creation-complete {:login-signal-received? true}]]]
|
||||
|
||||
:else
|
||||
[[:dispatch [:update-theme-and-init-root :shell-stack]]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
(ns status-im.contexts.profile.profiles.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[native-module.core :as native-module]
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
@@ -182,7 +183,7 @@
|
||||
:render-fn profile-card}]]))
|
||||
|
||||
(defn password-input
|
||||
[]
|
||||
[processing error]
|
||||
(let [auth-method (rf/sub [:auth-method])
|
||||
on-press-biometrics (fn []
|
||||
(rf/dispatch [:biometric/authenticate
|
||||
@@ -193,18 +194,31 @@
|
||||
%])}]))]
|
||||
|
||||
[standard-authentication/password-input
|
||||
{:shell? true
|
||||
{:processing processing
|
||||
:error error
|
||||
:shell? true
|
||||
:blur? true
|
||||
:on-press-biometrics (when (= auth-method constants/auth-method-biometric) on-press-biometrics)}]))
|
||||
|
||||
(defn- get-error-message
|
||||
[error]
|
||||
(if (and (some? error)
|
||||
(or (= error "file is not a database")
|
||||
(string/starts-with? (string/lower-case error) "failed")))
|
||||
(i18n/label :t/oops-wrong-password)
|
||||
error))
|
||||
|
||||
(defn login-section
|
||||
[{:keys [show-profiles]}]
|
||||
(let [processing (rf/sub [:profile/login-processing])
|
||||
{:keys [key-uid name keycard-pairing
|
||||
(let [{:keys [key-uid name keycard-pairing
|
||||
customization-color]} (rf/sub [:profile/login-profile])
|
||||
sign-in-enabled? (rf/sub [:sign-in-enabled?])
|
||||
profile-picture (rf/sub [:profile/login-profiles-picture key-uid])
|
||||
login-multiaccount (rn/use-callback #(rf/dispatch [:profile.login/login]))]
|
||||
{:keys [error processing]} (rf/sub [:profile/login])
|
||||
error-message (rn/use-memo #(get-error-message error) [error])
|
||||
error {:error? (boolean (seq error-message))
|
||||
:error-message error-message}
|
||||
login-profile (rn/use-callback #(rf/dispatch [:profile.login/login]))]
|
||||
[rn/keyboard-avoiding-view
|
||||
{:style style/login-container
|
||||
:keyboard-vertical-offset (- (safe-area/get-bottom))}
|
||||
@@ -239,17 +253,20 @@
|
||||
:card-style style/login-profile-card}]
|
||||
(if keycard-pairing
|
||||
[keycard.pin/auth
|
||||
{:on-complete
|
||||
(fn [pin-text]
|
||||
{:error error
|
||||
:on-complete
|
||||
(fn [pin]
|
||||
(rf/dispatch
|
||||
[:keycard/connect
|
||||
{:key-uid key-uid
|
||||
:on-success-fx [[:effects.keycard/get-keys
|
||||
{:pin pin-text
|
||||
:on-success #(rf/dispatch [:keycard.login/on-get-keys-success %])
|
||||
:on-failure #(rf/dispatch [:keycard/on-action-with-pin-error
|
||||
%])}]]}]))}]
|
||||
[password-input])]
|
||||
{:key-uid key-uid
|
||||
:on-success
|
||||
(fn []
|
||||
(rf/dispatch
|
||||
[:keycard/get-keys
|
||||
{:pin pin
|
||||
:on-success #(rf/dispatch [:keycard.login/on-get-keys-success %])
|
||||
:on-failure #(rf/dispatch [:keycard/on-action-with-pin-error %])}]))}]))}]
|
||||
[password-input processing error])]
|
||||
(when-not keycard-pairing
|
||||
[quo/button
|
||||
{:size 40
|
||||
@@ -258,7 +275,7 @@
|
||||
:accessibility-label :login-button
|
||||
:icon-left :i/unlocked
|
||||
:disabled? (or (not sign-in-enabled?) processing)
|
||||
:on-press login-multiaccount
|
||||
:on-press login-profile
|
||||
:container-style {:margin-bottom (+ (safe-area/get-bottom) 12)}}
|
||||
(i18n/label :t/log-in)])]))
|
||||
|
||||
|
||||
@@ -50,17 +50,6 @@
|
||||
{:on-success on-success}])
|
||||
:on-cancel nil}]]})))
|
||||
|
||||
(rf/reg-event-fx :profile.settings/toggle-goerli-test-network
|
||||
(fn [{:keys [db]}]
|
||||
(let [value (get-in db [:profile/profile :is-goerli-enabled?])
|
||||
on-success #(rf/dispatch [:logout])]
|
||||
{:fx [[:ui/show-confirmation
|
||||
{:content (i18n/label :t/goerli-testnet-toggle-confirmation)
|
||||
:on-accept #(rf/dispatch [:profile.settings/profile-update :is-goerli-enabled?
|
||||
(not value)
|
||||
{:on-success on-success}])
|
||||
:on-cancel nil}]]})))
|
||||
|
||||
(rf/reg-event-fx :profile.settings/change-preview-privacy
|
||||
(fn [_ [private?]]
|
||||
(let [private?' (boolean private?)]
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.events-helper :as events-helper]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.constants :as constants]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -27,11 +28,11 @@
|
||||
:subtitle (i18n/label :t/secure-wallet-card)
|
||||
:button-label (i18n/label :t/buy-keycard)
|
||||
:accessibility-label :get-keycard
|
||||
:image (resources/get-image :generate-keys)
|
||||
:on-press #()}]
|
||||
:image (resources/get-image :keycard-buy)
|
||||
:on-press #(rf/dispatch [:browser.ui/open-url constants/get-keycard-url])}]
|
||||
[rn/view {:style {:margin-top 24}}
|
||||
[quo/text
|
||||
{:style {:margin-bottom 12
|
||||
{:style {:margin-bottom 1
|
||||
:color colors/white-opa-70}
|
||||
:size :paragraph-2
|
||||
:weight :medium}
|
||||
|
||||
@@ -41,10 +41,9 @@
|
||||
(for [label points]
|
||||
^{:key label}
|
||||
[quo/markdown-list
|
||||
{:description (i18n/label label)
|
||||
:blur? true
|
||||
:type (when lock? :lock)
|
||||
:container-style {:padding-top 8}}])]})
|
||||
{:description (i18n/label label)
|
||||
:blur? true
|
||||
:type (when lock? :lock)}])]})
|
||||
|
||||
(defn- on-privacy-policy-press
|
||||
[]
|
||||
|
||||
@@ -10,14 +10,17 @@
|
||||
[]
|
||||
[rn/view {:style style/bridge-send-wrapper}
|
||||
[input-amount/view
|
||||
{:current-screen-id :screen/wallet.bridge-input-amount
|
||||
:button-one-label (i18n/label :t/review-bridge)
|
||||
:button-one-props {:icon-left :i/bridge}
|
||||
:on-confirm (fn [amount]
|
||||
(rf/dispatch [:wallet/set-token-amount-to-bridge
|
||||
{:amount amount
|
||||
:stack-id :screen/wallet.bridge-input-amount}]))
|
||||
:on-navigate-back (fn []
|
||||
(rf/dispatch-sync [:wallet/stop-and-clean-suggested-routes])
|
||||
(rf/dispatch [:wallet/clean-disabled-from-networks])
|
||||
(rf/dispatch [:wallet/clean-send-amount]))}]])
|
||||
{:current-screen-id :screen/wallet.bridge-input-amount
|
||||
:button-one-label (i18n/label :t/review-bridge)
|
||||
:button-one-props {:icon-left :i/bridge}
|
||||
:enabled-from-chain-ids (rf/sub
|
||||
[:wallet/bridge-from-chain-ids])
|
||||
:from-enabled-networks (rf/sub [:wallet/bridge-from-networks])
|
||||
:on-confirm (fn [amount]
|
||||
(rf/dispatch [:wallet/set-token-amount-to-bridge
|
||||
{:amount amount
|
||||
:stack-id :screen/wallet.bridge-input-amount}]))
|
||||
:on-navigate-back (fn []
|
||||
(rf/dispatch-sync [:wallet/stop-and-clean-suggested-routes])
|
||||
(rf/dispatch [:wallet/clean-disabled-from-networks])
|
||||
(rf/dispatch [:wallet/clean-send-amount]))}]])
|
||||
|
||||
@@ -357,8 +357,7 @@
|
||||
{:chain-id chain-id
|
||||
:token-id token-id
|
||||
:contract-address contract-address
|
||||
:test-networks-enabled? (get-in db [:profile/profile :test-networks-enabled?])
|
||||
:is-goerli-enabled? (get-in db [:profile/profile :is-goerli-enabled?])})]
|
||||
:test-networks-enabled? (get-in db [:profile/profile :test-networks-enabled?])})]
|
||||
{:fx [[:dispatch
|
||||
[:hide-bottom-sheet]]
|
||||
[:dispatch-later
|
||||
@@ -377,5 +376,4 @@
|
||||
{:chain-id chain-id
|
||||
:token-id token-id
|
||||
:contract-address contract-address
|
||||
:test-networks-enabled? (get-in db [:profile/profile :test-networks-enabled?])
|
||||
:is-goerli-enabled? (get-in db [:profile/profile :is-goerli-enabled?])})]]]}))
|
||||
:test-networks-enabled? (get-in db [:profile/profile :test-networks-enabled?])})]]]}))
|
||||
|
||||
@@ -33,17 +33,11 @@
|
||||
(when (> total 1) (str "x" total)))
|
||||
|
||||
(defn- get-opensea-network-name
|
||||
[chain-id test-networks-enabled? is-goerli-enabled?]
|
||||
[chain-id test-networks-enabled?]
|
||||
(let [network-kw (network-utils/id->network chain-id)
|
||||
network-name (name network-kw)
|
||||
mainnet? (= :mainnet network-kw)]
|
||||
(cond (and test-networks-enabled? is-goerli-enabled? mainnet?)
|
||||
(:goerli constants/opensea-url-names)
|
||||
|
||||
(and test-networks-enabled? is-goerli-enabled?)
|
||||
(str network-name "-" (:goerli constants/opensea-url-names))
|
||||
|
||||
(and test-networks-enabled? mainnet?)
|
||||
(cond (and test-networks-enabled? mainnet?)
|
||||
(:sepolia constants/opensea-url-names)
|
||||
|
||||
test-networks-enabled?
|
||||
@@ -63,11 +57,10 @@
|
||||
|
||||
(defn get-opensea-collectible-url
|
||||
[{:keys [chain-id token-id contract-address
|
||||
test-networks-enabled? is-goerli-enabled?]}]
|
||||
test-networks-enabled?]}]
|
||||
(let [base-link (get-opensea-base-url test-networks-enabled?)
|
||||
opensea-network-name (get-opensea-network-name chain-id
|
||||
test-networks-enabled?
|
||||
is-goerli-enabled?)]
|
||||
test-networks-enabled?)]
|
||||
(str base-link "/assets/" opensea-network-name "/" contract-address "/" token-id)))
|
||||
|
||||
(defn get-collectible-unique-id
|
||||
|
||||
@@ -43,26 +43,4 @@
|
||||
:contract-address contract-address
|
||||
:token-id token-id
|
||||
:test-networks-enabled? true})
|
||||
"https://testnets.opensea.io/assets/optimism-sepolia/0xC/0xT")))
|
||||
(testing "get-opensea-collectible-url goerli"
|
||||
(is (= (utils/get-opensea-collectible-url {:chain-id constants/ethereum-goerli-chain-id
|
||||
:contract-address contract-address
|
||||
:token-id token-id
|
||||
:test-networks-enabled? true
|
||||
:is-goerli-enabled? true})
|
||||
"https://testnets.opensea.io/assets/goerli/0xC/0xT")))
|
||||
(testing "get-opensea-collectible-url goerli arbitrum"
|
||||
(is (= (utils/get-opensea-collectible-url {:chain-id constants/arbitrum-goerli-chain-id
|
||||
:contract-address contract-address
|
||||
:token-id token-id
|
||||
:test-networks-enabled? true
|
||||
:is-goerli-enabled? true})
|
||||
"https://testnets.opensea.io/assets/arbitrum-goerli/0xC/0xT")))
|
||||
|
||||
(testing "get-opensea-collectible-url goerli optimism"
|
||||
(is (= (utils/get-opensea-collectible-url {:chain-id constants/optimism-goerli-chain-id
|
||||
:contract-address contract-address
|
||||
:token-id token-id
|
||||
:test-networks-enabled? true
|
||||
:is-goerli-enabled? true})
|
||||
"https://testnets.opensea.io/assets/optimism-goerli/0xC/0xT"))))
|
||||
"https://testnets.opensea.io/assets/optimism-sepolia/0xC/0xT"))))
|
||||
|
||||
@@ -27,18 +27,12 @@
|
||||
[balance]
|
||||
(cut-fiat-balance balance 2))
|
||||
|
||||
(defn prepend-curency-symbol-to-fiat-balance
|
||||
[fiat-balance currency-symbol]
|
||||
(defn prettify-balance
|
||||
[currency-symbol balance]
|
||||
(let [formatted-symbol (if (> (count currency-symbol) 1)
|
||||
(str currency-symbol " ")
|
||||
currency-symbol)]
|
||||
(str formatted-symbol fiat-balance)))
|
||||
|
||||
(defn prettify-balance
|
||||
[currency-symbol fiat-balance]
|
||||
(-> fiat-balance
|
||||
cut-fiat-balance-to-two-decimals
|
||||
(prepend-curency-symbol-to-fiat-balance currency-symbol)))
|
||||
(str formatted-symbol (cut-fiat-balance-to-two-decimals balance))))
|
||||
|
||||
(defn get-derivation-path
|
||||
[number-of-accounts]
|
||||
@@ -110,15 +104,11 @@
|
||||
:else (number/remove-trailing-zeroes
|
||||
(.toFixed token-units standardized-decimals-count)))))
|
||||
|
||||
(defn add-token-symbol-to-crypto-balance
|
||||
[crypto-balance token-symbol]
|
||||
(str crypto-balance " " (string/upper-case token-symbol)))
|
||||
|
||||
(defn prettify-crypto-balance
|
||||
[token-symbol crypto-balance conversion-rate]
|
||||
(-> crypto-balance
|
||||
(cut-crypto-decimals-to-fit-usd-cents conversion-rate)
|
||||
(add-token-symbol-to-crypto-balance token-symbol)))
|
||||
(str (cut-crypto-decimals-to-fit-usd-cents crypto-balance conversion-rate)
|
||||
" "
|
||||
(string/upper-case token-symbol)))
|
||||
|
||||
(defn get-standard-crypto-format
|
||||
"For full details: https://github.com/status-im/status-mobile/issues/18225"
|
||||
@@ -455,7 +445,7 @@
|
||||
(defn transaction-path
|
||||
[{:keys [from-address to-address token-id-from token-address token-id-to route data
|
||||
slippage-percentage eth-transfer?]}]
|
||||
(let [{:keys [bridge-name amount-in bonder-fees from
|
||||
(let [{:keys [bridge-name amount-in from
|
||||
to]} route
|
||||
tx-data (transaction-data {:from-address from-address
|
||||
:to-address to-address
|
||||
@@ -463,6 +453,7 @@
|
||||
:route route
|
||||
:data data
|
||||
:eth-transfer? eth-transfer?})
|
||||
bonder-fees (-> route :bounder-fees money/to-string)
|
||||
to-chain-id (:chain-id to)
|
||||
from-chain-id (:chain-id from)]
|
||||
(cond-> {:BridgeName bridge-name
|
||||
|
||||
@@ -14,12 +14,6 @@
|
||||
(= chain-id constants/optimism-mainnet-chain-id)
|
||||
config/optimism-mainnet-chain-explorer-link
|
||||
|
||||
(= chain-id constants/ethereum-goerli-chain-id)
|
||||
config/goerli-chain-explorer-link
|
||||
|
||||
(= chain-id constants/optimism-goerli-chain-id)
|
||||
config/optimism-goerli-chain-explorer-link
|
||||
|
||||
(= chain-id constants/ethereum-sepolia-chain-id)
|
||||
config/sepolia-chain-explorer-link
|
||||
|
||||
|
||||
@@ -10,58 +10,42 @@
|
||||
|
||||
(def id->network
|
||||
{constants/ethereum-mainnet-chain-id constants/mainnet-network-name
|
||||
constants/ethereum-goerli-chain-id constants/mainnet-network-name
|
||||
constants/ethereum-sepolia-chain-id constants/mainnet-network-name
|
||||
constants/optimism-mainnet-chain-id constants/optimism-network-name
|
||||
constants/optimism-goerli-chain-id constants/optimism-network-name
|
||||
constants/optimism-sepolia-chain-id constants/optimism-network-name
|
||||
constants/arbitrum-mainnet-chain-id constants/arbitrum-network-name
|
||||
constants/arbitrum-goerli-chain-id constants/arbitrum-network-name
|
||||
constants/arbitrum-sepolia-chain-id constants/arbitrum-network-name})
|
||||
|
||||
(defn- get-chain-id
|
||||
[{:keys [mainnet-chain-id sepolia-chain-id goerli-chain-id testnet-enabled? goerli-enabled?]}]
|
||||
(cond
|
||||
(and testnet-enabled? goerli-enabled?)
|
||||
goerli-chain-id
|
||||
|
||||
testnet-enabled?
|
||||
[{:keys [mainnet-chain-id sepolia-chain-id testnet-enabled?]}]
|
||||
(if testnet-enabled?
|
||||
sepolia-chain-id
|
||||
|
||||
:else
|
||||
mainnet-chain-id))
|
||||
|
||||
(defn network->chain-id
|
||||
([db network]
|
||||
(let [{:keys [test-networks-enabled? is-goerli-enabled?]} (:profile/profile db)]
|
||||
(let [{:keys [test-networks-enabled?]} (:profile/profile db)]
|
||||
(network->chain-id {:network network
|
||||
:testnet-enabled? test-networks-enabled?
|
||||
:goerli-enabled? is-goerli-enabled?})))
|
||||
([{:keys [network testnet-enabled? goerli-enabled?]}]
|
||||
:testnet-enabled? test-networks-enabled?})))
|
||||
([{:keys [network testnet-enabled?]}]
|
||||
(condp contains? (keyword network)
|
||||
#{constants/mainnet-network-name (keyword constants/mainnet-short-name)}
|
||||
(get-chain-id
|
||||
{:mainnet-chain-id constants/ethereum-mainnet-chain-id
|
||||
:sepolia-chain-id constants/ethereum-sepolia-chain-id
|
||||
:goerli-chain-id constants/ethereum-goerli-chain-id
|
||||
:testnet-enabled? testnet-enabled?
|
||||
:goerli-enabled? goerli-enabled?})
|
||||
:testnet-enabled? testnet-enabled?})
|
||||
|
||||
#{constants/optimism-network-name (keyword constants/optimism-short-name)}
|
||||
(get-chain-id
|
||||
{:mainnet-chain-id constants/optimism-mainnet-chain-id
|
||||
:sepolia-chain-id constants/optimism-sepolia-chain-id
|
||||
:goerli-chain-id constants/optimism-goerli-chain-id
|
||||
:testnet-enabled? testnet-enabled?
|
||||
:goerli-enabled? goerli-enabled?})
|
||||
:testnet-enabled? testnet-enabled?})
|
||||
|
||||
#{constants/arbitrum-network-name (keyword constants/arbitrum-short-name)}
|
||||
(get-chain-id
|
||||
{:mainnet-chain-id constants/arbitrum-mainnet-chain-id
|
||||
:sepolia-chain-id constants/arbitrum-sepolia-chain-id
|
||||
:goerli-chain-id constants/arbitrum-goerli-chain-id
|
||||
:testnet-enabled? testnet-enabled?
|
||||
:goerli-enabled? goerli-enabled?}))))
|
||||
:testnet-enabled? testnet-enabled?}))))
|
||||
|
||||
(defn network-list
|
||||
[{:keys [balances-per-chain]} networks]
|
||||
@@ -82,19 +66,13 @@
|
||||
(network-list $ networks)))
|
||||
|
||||
(defn get-default-chain-ids-by-mode
|
||||
[{:keys [test-networks-enabled? is-goerli-enabled?]}]
|
||||
(cond
|
||||
(and test-networks-enabled? is-goerli-enabled?)
|
||||
constants/goerli-chain-ids
|
||||
|
||||
test-networks-enabled?
|
||||
[{:keys [test-networks-enabled?]}]
|
||||
(if test-networks-enabled?
|
||||
constants/sepolia-chain-ids
|
||||
|
||||
:else
|
||||
constants/mainnet-chain-ids))
|
||||
|
||||
(defn resolve-receiver-networks
|
||||
[{:keys [prefix testnet-enabled? goerli-enabled?]}]
|
||||
[{:keys [prefix testnet-enabled?]}]
|
||||
(let [prefix (if (string/blank? prefix)
|
||||
constants/default-multichain-address-prefix
|
||||
prefix)
|
||||
@@ -104,8 +82,7 @@
|
||||
(mapv
|
||||
#(network->chain-id
|
||||
{:network %
|
||||
:testnet-enabled? testnet-enabled?
|
||||
:goerli-enabled? goerli-enabled?})))))
|
||||
:testnet-enabled? testnet-enabled?})))))
|
||||
|
||||
(def network->short-name
|
||||
{constants/mainnet-network-name constants/mainnet-short-name
|
||||
@@ -185,16 +162,13 @@
|
||||
[chain-id]
|
||||
(as-> chain-id $
|
||||
(condp contains? $
|
||||
#{constants/ethereum-mainnet-chain-id constants/ethereum-goerli-chain-id
|
||||
constants/ethereum-sepolia-chain-id}
|
||||
#{constants/ethereum-mainnet-chain-id constants/ethereum-sepolia-chain-id}
|
||||
mainnet-network-details
|
||||
|
||||
#{constants/arbitrum-mainnet-chain-id constants/arbitrum-goerli-chain-id
|
||||
constants/arbitrum-sepolia-chain-id}
|
||||
#{constants/arbitrum-mainnet-chain-id constants/arbitrum-sepolia-chain-id}
|
||||
arbitrum-network-details
|
||||
|
||||
#{constants/optimism-mainnet-chain-id constants/optimism-goerli-chain-id
|
||||
constants/optimism-sepolia-chain-id}
|
||||
#{constants/optimism-mainnet-chain-id constants/optimism-sepolia-chain-id}
|
||||
optimism-network-details
|
||||
|
||||
nil)
|
||||
|
||||
@@ -6,19 +6,17 @@
|
||||
|
||||
(deftest network->chain-id-test
|
||||
(testing "network->chain-id function"
|
||||
(is (= (utils/network->chain-id {:network :mainnet :testnet-enabled? false :goerli-enabled? false})
|
||||
(is (= (utils/network->chain-id {:network :mainnet :testnet-enabled? false})
|
||||
constants/ethereum-mainnet-chain-id))
|
||||
(is (= (utils/network->chain-id {:network :eth :testnet-enabled? true :goerli-enabled? false})
|
||||
(is (= (utils/network->chain-id {:network :eth :testnet-enabled? true})
|
||||
constants/ethereum-sepolia-chain-id))
|
||||
(is (= (utils/network->chain-id {:network "optimism" :testnet-enabled? true :goerli-enabled? false})
|
||||
(is (= (utils/network->chain-id {:network "optimism" :testnet-enabled? true})
|
||||
constants/optimism-sepolia-chain-id))
|
||||
(is (= (utils/network->chain-id {:network "oeth" :testnet-enabled? false :goerli-enabled? true})
|
||||
(is (= (utils/network->chain-id {:network "oeth" :testnet-enabled? false})
|
||||
constants/optimism-mainnet-chain-id))
|
||||
(is (= (utils/network->chain-id {:network :oeth :testnet-enabled? true :goerli-enabled? true})
|
||||
constants/optimism-goerli-chain-id))
|
||||
(is (= (utils/network->chain-id {:network :arb1 :testnet-enabled? false :goerli-enabled? false})
|
||||
(is (= (utils/network->chain-id {:network :arb1 :testnet-enabled? false})
|
||||
constants/arbitrum-mainnet-chain-id))
|
||||
(is (= (utils/network->chain-id {:network :arbitrum :testnet-enabled? true :goerli-enabled? false})
|
||||
(is (= (utils/network->chain-id {:network :arbitrum :testnet-enabled? true})
|
||||
constants/arbitrum-sepolia-chain-id))))
|
||||
|
||||
(deftest short-names->network-preference-prefix-test
|
||||
|
||||
@@ -233,13 +233,12 @@
|
||||
|
||||
(defn new->old-route-path
|
||||
[new-path]
|
||||
(let [bonder-fees (:tx-bonder-fees new-path)
|
||||
token-fees (+ (money/wei->ether bonder-fees)
|
||||
(money/wei->ether (:tx-token-fees new-path)))]
|
||||
(let [bonder-fees (-> new-path :tx-bonder-fees money/bignumber)
|
||||
token-fees (-> new-path :tx-token-fees money/bignumber)]
|
||||
{:from (:from-chain new-path)
|
||||
:amount-in-locked (:amount-in-locked new-path)
|
||||
:amount-in (:amount-in new-path)
|
||||
:max-amount-in "0x0"
|
||||
:max-amount-in (:max-amount-in new-path)
|
||||
:gas-fees {:gas-price "0"
|
||||
:base-fee (send-utils/convert-to-gwei (:tx-base-fee
|
||||
new-path)
|
||||
|
||||
@@ -11,7 +11,4 @@
|
||||
;; in and the device is offline, versus re-fetching when offline and
|
||||
;; tokens already exist in the app-db.
|
||||
:tokens-loading nil
|
||||
:active-tab :assets
|
||||
:screens {:input-amount-screen
|
||||
{:crypto-currency? true
|
||||
:input-value ""}}}})
|
||||
:active-tab :assets}})
|
||||
|
||||
@@ -387,23 +387,14 @@
|
||||
(rf/dispatch [:wallet/set-ens-address nil ens])
|
||||
(on-error-fn))))}]]]})))
|
||||
|
||||
(defn- resolved-address->prefixed-address
|
||||
[address networks]
|
||||
(let [prefixes (->> networks
|
||||
(map network-utils/network->short-name)
|
||||
network-utils/short-names->network-preference-prefix)]
|
||||
(str prefixes (eip55/address->checksum address))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/set-ens-address
|
||||
(fn [{:keys [db]} [result ens]]
|
||||
(let [networks [constants/ethereum-network-name constants/optimism-network-name]
|
||||
suggestion (if result
|
||||
(let [suggestion (if result
|
||||
[{:type item-types/address
|
||||
:ens ens
|
||||
:address (eip55/address->checksum result)
|
||||
:networks networks
|
||||
:full-address (resolved-address->prefixed-address result networks)}]
|
||||
:full-address (eip55/address->checksum result)}]
|
||||
[])]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :search-address :local-suggestions] suggestion)
|
||||
@@ -511,10 +502,8 @@
|
||||
(for [[k v] chains :when (= v "down")] k))
|
||||
keys)
|
||||
test-networks-enabled? (get-in db [:profile/profile :test-networks-enabled?])
|
||||
is-goerli-enabled? (get-in db [:profile/profile :is-goerli-enabled?])
|
||||
chain-ids-by-mode (network-utils/get-default-chain-ids-by-mode
|
||||
{:test-networks-enabled? test-networks-enabled?
|
||||
:is-goerli-enabled? is-goerli-enabled?})
|
||||
{:test-networks-enabled? test-networks-enabled?})
|
||||
chains-filtered-by-mode (remove #(not (contains? chain-ids-by-mode %)) down-chain-ids)
|
||||
chains-down? (and (network.data-store/online? db) (seq chains-filtered-by-mode))
|
||||
chain-names (when chains-down?
|
||||
@@ -527,8 +516,7 @@
|
||||
(when (seq down-chain-ids)
|
||||
(log/info "[wallet] Chain(s) down: " down-chain-ids)
|
||||
(log/info "[wallet] Chain name(s) down: " chain-names)
|
||||
(log/info "[wallet] Test network enabled: " (boolean test-networks-enabled?))
|
||||
(log/info "[wallet] Goerli network enabled: " (boolean is-goerli-enabled?)))
|
||||
(log/info "[wallet] Test network enabled: " (boolean test-networks-enabled?)))
|
||||
|
||||
;; NOTE <shivekkhurana>: We used to show an error toast, but disabled it because the down
|
||||
;; signal is sent randomly. Needs to be investigated and enabled again !
|
||||
|
||||
@@ -152,11 +152,9 @@
|
||||
(fn [{:keys [db]} [{:keys [address recipient stack-id start-flow?]}]]
|
||||
(let [[prefix to-address] (utils/split-prefix-and-address address)
|
||||
testnet-enabled? (get-in db [:profile/profile :test-networks-enabled?])
|
||||
goerli-enabled? (get-in db [:profile/profile :is-goerli-enabled?])
|
||||
receiver-networks (network-utils/resolve-receiver-networks
|
||||
{:prefix prefix
|
||||
:testnet-enabled? testnet-enabled?
|
||||
:goerli-enabled? goerli-enabled?})
|
||||
:testnet-enabled? testnet-enabled?})
|
||||
collectible-tx? (send-utils/tx-type-collectible?
|
||||
(-> db :wallet :ui :send :tx-type))
|
||||
collectible (when collectible-tx?
|
||||
@@ -561,7 +559,7 @@
|
||||
:error error-message}))
|
||||
{:fx [[:dispatch
|
||||
(cond
|
||||
(and failure? swap?) [:wallet/swap-proposal-error error-message]
|
||||
(and failure? swap?) [:wallet/swap-proposal-error error]
|
||||
failure? [:wallet/suggested-routes-error error-message]
|
||||
swap? [:wallet/swap-proposal-success (fix-routes data)]
|
||||
:else [:wallet/suggested-routes-success (fix-routes data)
|
||||
|
||||
@@ -357,11 +357,9 @@
|
||||
(testing "testing when collectible balance is more than 1"
|
||||
(let [collectible (collectible-with-balance 2)
|
||||
testnet-enabled? false
|
||||
goerli-enabled? false
|
||||
receiver-networks (network-utils/resolve-receiver-networks
|
||||
{:prefix prefix
|
||||
:testnet-enabled? testnet-enabled?
|
||||
:goerli-enabled? goerli-enabled?})
|
||||
:testnet-enabled? testnet-enabled?})
|
||||
expected-result {:db {:wallet {:ui {:send {:other-props :value
|
||||
:recipient recipient
|
||||
:to-address to-address
|
||||
@@ -371,8 +369,7 @@
|
||||
:receiver-networks receiver-networks
|
||||
:tx-type tx-type
|
||||
:collectible collectible}}}
|
||||
:profile/profile {:test-networks-enabled? false
|
||||
:is-goerli-enabled? false}}
|
||||
:profile/profile {:test-networks-enabled? false}}
|
||||
:fx [nil
|
||||
[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
@@ -383,8 +380,7 @@
|
||||
{:wallet {:ui {:send {:other-props :value
|
||||
:tx-type tx-type
|
||||
:collectible collectible}}}
|
||||
:profile/profile {:test-networks-enabled? testnet-enabled?
|
||||
:is-goerli-enabled? goerli-enabled?}})
|
||||
:profile/profile {:test-networks-enabled? testnet-enabled?}})
|
||||
(is (match? expected-result
|
||||
(dispatch [event-id
|
||||
{:address address
|
||||
@@ -394,11 +390,9 @@
|
||||
(testing "testing when collectible balance is 1"
|
||||
(let [collectible (collectible-with-balance 1)
|
||||
testnet-enabled? false
|
||||
goerli-enabled? false
|
||||
receiver-networks (network-utils/resolve-receiver-networks
|
||||
{:prefix prefix
|
||||
:testnet-enabled? testnet-enabled?
|
||||
:goerli-enabled? goerli-enabled?})
|
||||
:testnet-enabled? testnet-enabled?})
|
||||
expected-result {:db {:wallet {:ui {:send {:other-props :value
|
||||
:recipient recipient
|
||||
:to-address to-address
|
||||
@@ -408,8 +402,7 @@
|
||||
:receiver-networks receiver-networks
|
||||
:tx-type tx-type
|
||||
:collectible collectible}}}
|
||||
:profile/profile {:test-networks-enabled? false
|
||||
:is-goerli-enabled? false}}
|
||||
:profile/profile {:test-networks-enabled? false}}
|
||||
:fx [[:dispatch [:wallet/start-get-suggested-routes {:amount 1}]]
|
||||
[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
@@ -420,8 +413,7 @@
|
||||
{:wallet {:ui {:send {:other-props :value
|
||||
:tx-type tx-type
|
||||
:collectible collectible}}}
|
||||
:profile/profile {:test-networks-enabled? testnet-enabled?
|
||||
:is-goerli-enabled? goerli-enabled?}})
|
||||
:profile/profile {:test-networks-enabled? testnet-enabled?}})
|
||||
(is (match? expected-result
|
||||
(dispatch [event-id
|
||||
{:address address
|
||||
|
||||
@@ -104,16 +104,19 @@
|
||||
:wallet/wallet-send-tx-type :tx/send
|
||||
:wallet/wallet-send-fee-fiat-formatted "$5,00"
|
||||
:wallet/sending-collectible? false
|
||||
:wallet/total-amount-in-to-chains (money/bignumber "250")})
|
||||
:wallet/send-total-amount-formatted "250 ETH"
|
||||
:wallet/total-amount (money/bignumber "250")
|
||||
:wallet/bridge-to-network-details nil
|
||||
:wallet/send-amount-fixed ""
|
||||
:wallet/send-display-token-decimals 5})
|
||||
|
||||
(h/describe "Send > input amount screen"
|
||||
(h/setup-restorable-re-frame)
|
||||
|
||||
(h/test "Default render"
|
||||
(h/setup-subs sub-mocks)
|
||||
(h/setup-subs (assoc sub-mocks :wallet/send-display-token-decimals 2))
|
||||
(h/render-with-theme-provider [input-amount/view
|
||||
{:crypto-decimals 2
|
||||
:limit-crypto (money/bignumber 250)
|
||||
{:limit-crypto (money/bignumber 250)
|
||||
:initial-crypto-currency? false}])
|
||||
(h/is-truthy (h/get-by-text "0"))
|
||||
(h/is-truthy (h/get-by-text "USD"))
|
||||
@@ -122,12 +125,11 @@
|
||||
(h/is-disabled (h/get-by-label-text :button-one)))
|
||||
|
||||
(h/test "Fill token input and confirm"
|
||||
(h/setup-subs sub-mocks)
|
||||
(h/setup-subs (assoc sub-mocks :wallet/send-display-token-decimals 10))
|
||||
|
||||
(let [on-confirm (h/mock-fn)]
|
||||
(h/render-with-theme-provider [input-amount/view
|
||||
{:crypto-decimals 10
|
||||
:limit-crypto (money/bignumber 1000)
|
||||
{:limit-crypto (money/bignumber 1000)
|
||||
:on-confirm on-confirm
|
||||
:initial-crypto-currency? true}])
|
||||
|
||||
@@ -147,10 +149,9 @@
|
||||
(h/was-called on-confirm)))))))
|
||||
|
||||
(h/test "Try to fill more than limit"
|
||||
(h/setup-subs sub-mocks)
|
||||
(h/setup-subs (assoc sub-mocks :wallet/send-display-token-decimals 1))
|
||||
(h/render-with-theme-provider [input-amount/view
|
||||
{:crypto-decimals 1
|
||||
:limit-crypto (money/bignumber 1)}])
|
||||
{:limit-crypto (money/bignumber 1)}])
|
||||
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-9))
|
||||
@@ -159,11 +160,10 @@
|
||||
(h/is-truthy (h/get-by-label-text :container-error)))
|
||||
|
||||
(h/test "Switch from crypto to fiat and check limit"
|
||||
(h/setup-subs sub-mocks)
|
||||
(h/setup-subs (assoc sub-mocks :wallet/send-display-token-decimals 1))
|
||||
(h/render-with-theme-provider [input-amount/view
|
||||
{:crypto-decimals 1
|
||||
:limit-crypto (money/bignumber 10)
|
||||
:on-confirm #()}])
|
||||
{:limit-crypto (money/bignumber 10)
|
||||
:on-confirm #()}])
|
||||
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-9))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-9))
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
(ns status-im.contexts.wallet.send.input-amount.controlled-input-logic
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[utils.money :as money]))
|
||||
|
||||
(def ^:private default-max-limit 12)
|
||||
|
||||
(def ^:private not-digits-or-dot-pattern
|
||||
#"[^0-9+\.]")
|
||||
|
||||
(def ^:private dot ".")
|
||||
|
||||
(defn- can-add-character?
|
||||
[input-value character max-length]
|
||||
(let [length-overflow? (>= (count input-value) max-length)
|
||||
extra-dot? (and (= character dot) (string/includes? input-value dot))
|
||||
extra-leading-zero? (and (= input-value "0") (= "0" (str character)))
|
||||
non-numeric? (re-find not-digits-or-dot-pattern (str character))]
|
||||
(not (or non-numeric? extra-dot? extra-leading-zero? length-overflow?))))
|
||||
|
||||
(defn- normalize-value-as-numeric
|
||||
[value character]
|
||||
(cond
|
||||
(and (string/blank? value) (= character dot))
|
||||
(str "0" character)
|
||||
|
||||
(and (= value "0") (not= character dot))
|
||||
(str character)
|
||||
|
||||
:else
|
||||
(str value character)))
|
||||
|
||||
(defn add-character
|
||||
([input-value character]
|
||||
(add-character input-value character default-max-limit))
|
||||
([input-value character max-length]
|
||||
(if (can-add-character? input-value character max-length)
|
||||
(normalize-value-as-numeric input-value character)
|
||||
input-value)))
|
||||
|
||||
(defn delete-last
|
||||
([input-value]
|
||||
(delete-last input-value ""))
|
||||
([input-value default-value]
|
||||
(let [new-value (subs input-value 0 (dec (count input-value)))]
|
||||
(if (string/blank? new-value)
|
||||
default-value
|
||||
new-value))))
|
||||
|
||||
(defn upper-limit-exceeded?
|
||||
[input-value upper-limit]
|
||||
(and upper-limit
|
||||
(when (money/bignumber? (money/bignumber input-value))
|
||||
(money/greater-than (money/bignumber input-value) (money/bignumber upper-limit)))))
|
||||
|
||||
(defn lower-limit-exceeded?
|
||||
[input-value lower-limit]
|
||||
(and lower-limit
|
||||
(when (money/bignumber? (money/bignumber input-value))
|
||||
(money/less-than (money/bignumber input-value) (money/bignumber lower-limit)))))
|
||||
|
||||
(defn value-out-of-limits?
|
||||
[input-value upper-limit lower-limit]
|
||||
(or (upper-limit-exceeded? input-value upper-limit)
|
||||
(lower-limit-exceeded? input-value lower-limit)))
|
||||
|
||||
(defn value-numeric
|
||||
[input-value]
|
||||
(or (parse-double input-value) 0))
|
||||
|
||||
(defn empty-value?
|
||||
[input-value]
|
||||
(or (string/blank? input-value) (<= (value-numeric input-value) 0)))
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
(ns status-im.contexts.wallet.send.input-amount.estimated-fees
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.not-implemented :as not-implemented]
|
||||
[status-im.contexts.wallet.send.input-amount.style :as style]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- bonder-fee-info-sheet
|
||||
[]
|
||||
[:<>
|
||||
[quo/drawer-top
|
||||
{:title (i18n/label :t/understanding-bonder-fees-title)}]
|
||||
[rn/view {:style {:padding-horizontal 20}}
|
||||
[quo/text
|
||||
{:weight :regular
|
||||
:size :paragraph-2}
|
||||
(i18n/label :t/understanding-bonder-fees-description)]]])
|
||||
|
||||
(defn- show-bonder-fee-info
|
||||
[]
|
||||
(rf/dispatch
|
||||
[:show-bottom-sheet {:content bonder-fee-info-sheet}]))
|
||||
|
||||
(defn- received-amount
|
||||
[{:keys [loading-routes?]}]
|
||||
(let [amount (rf/sub [:wallet/send-total-amount-formatted])
|
||||
tx-type (rf/sub [:wallet/wallet-send-tx-type])
|
||||
{:keys [full-name]} (rf/sub [:wallet/bridge-to-network-details])]
|
||||
[quo/data-item
|
||||
(cond-> {:container-style style/amount-data-item
|
||||
:status (if loading-routes? :loading :default)
|
||||
:size :small
|
||||
:title (i18n/label :t/recipient-gets)
|
||||
:subtitle amount}
|
||||
|
||||
(= tx-type :tx/bridge)
|
||||
(assoc
|
||||
:title-icon :i/info
|
||||
:title (i18n/label :t/bridged-to
|
||||
{:network full-name})
|
||||
:on-press show-bonder-fee-info))]))
|
||||
|
||||
(defn view
|
||||
[{:keys [loading-routes? fees]}]
|
||||
[rn/view {:style style/estimated-fees-container}
|
||||
(when (ff/enabled? ::ff/wallet.advanced-sending)
|
||||
[rn/view {:style style/estimated-fees-content-container}
|
||||
[quo/button
|
||||
{:icon-only? true
|
||||
:type :outline
|
||||
:size 32
|
||||
:inner-style {:opacity 1}
|
||||
:accessibility-label :advanced-button
|
||||
:disabled? loading-routes?
|
||||
:on-press not-implemented/alert}
|
||||
:i/advanced]])
|
||||
[quo/data-item
|
||||
{:container-style style/fees-data-item
|
||||
:status (if loading-routes? :loading :default)
|
||||
:size :small
|
||||
:title (i18n/label :t/fees)
|
||||
:subtitle fees}]
|
||||
[received-amount {:loading-routes? loading-routes?}]])
|
||||
@@ -1,36 +0,0 @@
|
||||
(ns status-im.contexts.wallet.send.input-amount.events
|
||||
(:require
|
||||
[status-im.contexts.wallet.send.input-amount.controlled-input-logic :as controlled-input-logic]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def input-value-path [:wallet :ui :screens :input-amount-screen :input-value])
|
||||
(def crypto-currency?-path [:wallet :ui :screens :input-amount-screen :crypto-currency?])
|
||||
|
||||
(rf/reg-event-fx :send-input-amount-screen/set-token-input-value
|
||||
(fn [{:keys [db]} [v]]
|
||||
{:db (assoc-in db input-value-path v)}))
|
||||
|
||||
(rf/reg-event-fx :send-input-amount-screen/swap-between-fiat-and-crypto
|
||||
(fn [{:keys [db]} [token-input-converted-value]]
|
||||
{:db (update-in db crypto-currency?-path not)
|
||||
:fx [[:dispatch
|
||||
[:send-input-amount-screen/set-token-input-value token-input-converted-value]]]}))
|
||||
|
||||
(rf/reg-event-fx :send-input-amount-screen/token-input-add-character
|
||||
(fn [{:keys [db]} [c max-decimals]]
|
||||
(let [input-value (get-in db input-value-path)
|
||||
new-text (str input-value c)
|
||||
regex-pattern (str "^\\d*\\.?\\d{0," max-decimals "}$")
|
||||
regex (re-pattern regex-pattern)]
|
||||
(when (re-matches regex new-text)
|
||||
{:db (update-in db input-value-path #(controlled-input-logic/add-character % c))}))))
|
||||
|
||||
(rf/reg-event-fx :send-input-amount-screen/token-input-delete-last
|
||||
(fn [{:keys [db]}]
|
||||
{:db (update-in db input-value-path controlled-input-logic/delete-last)}))
|
||||
|
||||
(rf/reg-event-fx :send-input-amount-screen/token-input-delete-all
|
||||
(fn [{:keys [db]}]
|
||||
{:db (assoc-in db input-value-path "")}))
|
||||
|
||||
|
||||
@@ -1,56 +1,39 @@
|
||||
(ns status-im.contexts.wallet.send.input-amount.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.controlled-input.utils :as controlled-input]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.common.account-switcher.view :as account-switcher]
|
||||
[status-im.contexts.wallet.common.asset-list.view :as asset-list]
|
||||
[status-im.contexts.wallet.send.input-amount.events]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.send.input-amount.estimated-fees :as estimated-fees]
|
||||
[status-im.contexts.wallet.send.input-amount.style :as style]
|
||||
[status-im.contexts.wallet.send.routes.view :as routes]
|
||||
[status-im.contexts.wallet.sheets.buy-token.view :as buy-token]
|
||||
[status-im.contexts.wallet.sheets.unpreferred-networks-alert.view :as unpreferred-networks-alert]
|
||||
[status-im.feature-flags :as ff]
|
||||
[status-im.setup.hot-reload :as hot-reload]
|
||||
[status-im.subs.wallet.screens.input-amount]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.money :as money]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- estimated-fees
|
||||
[]
|
||||
(let [loading-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?])
|
||||
fees (rf/sub [:send-input-amount-screen/fee-formatted])
|
||||
amount (rf/sub [:send-input-amount-screen/recipient-gets-amount])]
|
||||
[rn/view {:style style/estimated-fees-container}
|
||||
(when (ff/enabled? ::ff/wallet.advanced-sending)
|
||||
[rn/view {:style style/estimated-fees-content-container}
|
||||
[quo/button
|
||||
{:icon-only? true
|
||||
:type :outline
|
||||
:size 32
|
||||
:inner-style {:opacity 1}
|
||||
:accessibility-label :advanced-button
|
||||
:disabled? loading-routes?
|
||||
:on-press #(js/alert "Not implemented yet")}
|
||||
:i/advanced]])
|
||||
[quo/data-item
|
||||
{:container-style style/fees-data-item
|
||||
:status (if loading-routes? :loading :default)
|
||||
:size :small
|
||||
:title (i18n/label :t/fees)
|
||||
:subtitle fees}]
|
||||
[quo/data-item
|
||||
{:container-style style/amount-data-item
|
||||
:status (if loading-routes? :loading :default)
|
||||
:size :small
|
||||
:title (i18n/label :t/recipient-gets)
|
||||
:subtitle amount}]]))
|
||||
(defn- every-network-value-is-zero?
|
||||
[sender-network-values]
|
||||
(every? (fn [{:keys [total-amount]}]
|
||||
(and
|
||||
total-amount
|
||||
(money/bignumber? total-amount)
|
||||
(money/equal-to total-amount
|
||||
(money/bignumber "0"))))
|
||||
sender-network-values))
|
||||
|
||||
(defn select-asset-bottom-sheet
|
||||
[]
|
||||
[clear-input!]
|
||||
(let [{preselected-token-symbol :symbol} (rf/sub [:wallet/wallet-send-token])]
|
||||
[:<> ;; Need to be a `:<>` to keep `asset-list` scrollable.
|
||||
[quo/drawer-top
|
||||
@@ -62,19 +45,15 @@
|
||||
:preselected-token-symbol preselected-token-symbol
|
||||
:on-token-press (fn [token]
|
||||
(rf/dispatch [:wallet/edit-token-to-send token])
|
||||
(rf/dispatch
|
||||
[:send-input-amount-screen/token-input-delete-all]))}]]))
|
||||
(clear-input!))}]]))
|
||||
|
||||
(defn- token-not-available
|
||||
[]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
{token-symbol :symbol
|
||||
token-networks :networks} (rf/sub [:wallet/wallet-send-token])
|
||||
receiver-networks (rf/sub [:wallet/wallet-send-receiver-networks])
|
||||
add-token-networks (fn []
|
||||
(let [chain-ids (concat receiver-networks
|
||||
(mapv #(:chain-id %) token-networks))]
|
||||
(rf/dispatch [:wallet/update-receiver-networks chain-ids])))]
|
||||
[token-symbol receiver-networks token-networks]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
add-token-networks (fn []
|
||||
(let [chain-ids (concat receiver-networks
|
||||
(mapv #(:chain-id %) token-networks))]
|
||||
(rf/dispatch [:wallet/update-receiver-networks chain-ids])))]
|
||||
[rn/view {:style (style/token-not-available-container theme)}
|
||||
[rn/view
|
||||
[quo/icon :i/alert
|
||||
@@ -133,117 +112,151 @@
|
||||
|
||||
:else (rf/dispatch [:wallet/stop-and-clean-suggested-routes])))
|
||||
|
||||
(defn token-input
|
||||
[]
|
||||
(let [show-select-asset-sheet #(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn [] [select-asset-bottom-sheet])}])
|
||||
{:keys [input-value crypto-currency?]} (rf/sub [:send-input-amount-screen/state])
|
||||
from-enabled-networks (rf/sub [:send-input-amount-screen/from-enabled-networks])
|
||||
{fiat-currency :currency} (rf/sub [:profile/profile])
|
||||
{token-symbol :symbol} (rf/sub [:wallet/wallet-send-token])
|
||||
input-value-converted (rf/sub [:send-input-amount-screen/input-value-converted])
|
||||
converted-value-prettified (rf/sub
|
||||
[:send-input-amount-screen/converted-value-prettified])
|
||||
value-out-of-limits? (rf/sub [:send-input-amount-screen/value-out-of-limits?])
|
||||
upper-limit-prettified (rf/sub
|
||||
[:send-input-amount-screen/upper-limit-prettified])]
|
||||
[quo/token-input
|
||||
{:container-style style/input-container
|
||||
:token-symbol token-symbol
|
||||
:value input-value
|
||||
:on-swap #(rf/dispatch [:send-input-amount-screen/swap-between-fiat-and-crypto
|
||||
input-value-converted])
|
||||
:on-token-press show-select-asset-sheet
|
||||
:error? value-out-of-limits?
|
||||
:currency-symbol (if crypto-currency? token-symbol fiat-currency)
|
||||
:converted-value converted-value-prettified
|
||||
:hint-component [quo/network-tags
|
||||
{:networks (seq from-enabled-networks)
|
||||
:title (i18n/label
|
||||
:t/send-limit
|
||||
{:limit upper-limit-prettified})
|
||||
:status (when value-out-of-limits? :error)}]}]))
|
||||
(defn routes-view
|
||||
[current-screen-id]
|
||||
(let [token-by-symbol (rf/sub [:send-input-amount-screen/token-by-symbol])
|
||||
token (rf/sub [:wallet/wallet-send-token])
|
||||
routes (rf/sub [:send-input-amount-screen/routes])
|
||||
valid-input? (rf/sub [:send-input-amount-screen/valid-input?])
|
||||
amount-in-crypto (rf/sub [:send-input-amount-screen/amount-in-crypto])
|
||||
limit-exceeded? (rf/sub [:send-input-amount-screen/upper-limit-exceeded?])
|
||||
unsupported-token-in-receiver? (rf/sub
|
||||
[:send-input-amount-screen/unsupported-token-in-receiver?])
|
||||
request-fetch-routes (fn [bounce-duration-ms]
|
||||
(fetch-routes
|
||||
{:amount amount-in-crypto
|
||||
:valid-input? valid-input?
|
||||
:bounce-duration-ms bounce-duration-ms
|
||||
:token token
|
||||
:reset-amounts-to-zero? (and limit-exceeded?
|
||||
(some? routes))}))]
|
||||
[routes/view
|
||||
{:token token-by-symbol
|
||||
:send-amount-in-crypto amount-in-crypto
|
||||
:valid-input? valid-input?
|
||||
:token-not-supported-in-receiver-networks? unsupported-token-in-receiver?
|
||||
:current-screen-id current-screen-id
|
||||
:request-fetch-routes request-fetch-routes}]))
|
||||
|
||||
(defn bottom-actions
|
||||
[button-one-label button-one-props on-confirm]
|
||||
(let [token-by-symbol (rf/sub [:send-input-amount-screen/token-by-symbol])
|
||||
loading-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?])
|
||||
amount-in-crypto (rf/sub [:send-input-amount-screen/amount-in-crypto])
|
||||
sending-to-unpreferred-networks? (rf/sub
|
||||
[:send-input-amount-screen/sending-to-unpreferred-networks?])
|
||||
current-color (rf/sub [:wallet/current-viewing-account-color])
|
||||
not-enough-asset? (rf/sub [:send-input-amount-screen/not-enough-asset?])
|
||||
should-try-again? (rf/sub [:send-input-amount-screen/should-try-again?])
|
||||
confirm-disabled? (rf/sub [:send-input-amount-screen/confirm-disabled?])]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (if should-try-again?
|
||||
(i18n/label :t/try-again)
|
||||
button-one-label)
|
||||
:button-one-props (merge (when-not should-try-again?
|
||||
button-one-props)
|
||||
{:disabled? (or not-enough-asset?
|
||||
loading-routes?
|
||||
(and (not should-try-again?)
|
||||
confirm-disabled?))
|
||||
:on-press (cond
|
||||
should-try-again?
|
||||
#(rf/dispatch [:wallet/start-get-suggested-routes
|
||||
{:amount amount-in-crypto
|
||||
:updated-token token-by-symbol}])
|
||||
sending-to-unpreferred-networks?
|
||||
#(show-unpreferred-networks-alert on-confirm)
|
||||
:else
|
||||
#(on-confirm amount-in-crypto))
|
||||
:customization-color current-color}
|
||||
(when should-try-again?
|
||||
{:type :grey}))}]))
|
||||
(defn- get-fee-formatted
|
||||
[route]
|
||||
(when-let [native-currency-symbol (-> route first :from :native-currency-symbol)]
|
||||
(rf/sub [:wallet/wallet-send-fee-fiat-formatted native-currency-symbol])))
|
||||
|
||||
(defn- insufficient-asset-amount?
|
||||
[{:keys [token-symbol owned-eth-token input-state no-routes-found? limit-exceeded?
|
||||
sender-network-values enough-assets?]}]
|
||||
(let [eth-selected? (= token-symbol (string/upper-case constants/mainnet-short-name))
|
||||
zero-owned-eth? (money/equal-to (:total-balance owned-eth-token) 0)
|
||||
input-at-max-owned-amount? (money/equal-to
|
||||
(controlled-input/value-bn input-state)
|
||||
(controlled-input/upper-limit-bn input-state))
|
||||
exceeded-input? (if eth-selected?
|
||||
input-at-max-owned-amount?
|
||||
zero-owned-eth?)]
|
||||
(and (or no-routes-found? limit-exceeded?)
|
||||
(seq sender-network-values)
|
||||
(or exceeded-input? (not enough-assets?)))))
|
||||
|
||||
(defn view
|
||||
;; crypto-decimals, limit-crypto and initial-crypto-currency? args are needed
|
||||
;; for component tests only
|
||||
[{on-confirm :on-confirm
|
||||
on-navigate-back :on-navigate-back
|
||||
button-one-label :button-one-label
|
||||
button-one-props :button-one-props
|
||||
current-screen-id :current-screen-id}]
|
||||
(let [view-id (rf/sub [:view-id])
|
||||
active-screen? (= view-id current-screen-id)
|
||||
bottom (safe-area/get-bottom)
|
||||
max-decimals (rf/sub [:send-input-amount-screen/max-decimals])
|
||||
value-out-of-limits? (rf/sub [:send-input-amount-screen/value-out-of-limits?])
|
||||
current-address (rf/sub [:wallet/current-viewing-account-address])
|
||||
not-enough-asset? (rf/sub [:send-input-amount-screen/not-enough-asset?])
|
||||
show-no-routes? (rf/sub [:send-input-amount-screen/show-no-routes?])
|
||||
show-estimated-fees? (rf/sub [:send-input-amount-screen/show-estimated-fees?])
|
||||
token-not-available? (rf/sub [:send-input-amount-screen/token-not-available?])]
|
||||
[{default-on-confirm :on-confirm
|
||||
default-limit-crypto :limit-crypto
|
||||
on-navigate-back :on-navigate-back
|
||||
button-one-label :button-one-label
|
||||
button-one-props :button-one-props
|
||||
current-screen-id :current-screen-id
|
||||
initial-crypto-currency? :initial-crypto-currency?
|
||||
enabled-from-chain-ids :enabled-from-chain-ids
|
||||
from-enabled-networks :from-enabled-networks
|
||||
:or {initial-crypto-currency? true}}]
|
||||
(let [view-id (rf/sub [:view-id])
|
||||
active-screen? (= view-id current-screen-id)
|
||||
bottom (safe-area/get-bottom)
|
||||
[crypto-currency?
|
||||
set-crypto-currency] (rn/use-state initial-crypto-currency?)
|
||||
handle-on-confirm (fn [amount]
|
||||
(rf/dispatch [:wallet/set-token-amount-to-send
|
||||
{:amount amount
|
||||
:stack-id current-screen-id}]))
|
||||
{fiat-currency :currency} (rf/sub [:profile/profile])
|
||||
{token-symbol :symbol
|
||||
token-networks :networks
|
||||
:as token} (rf/sub [:wallet/wallet-send-token])
|
||||
send-from-locked-amounts (rf/sub [:wallet/wallet-send-from-locked-amounts])
|
||||
{:keys [total-balance]
|
||||
:as token-by-symbol} (rf/sub [:wallet/token-by-symbol
|
||||
(str token-symbol)
|
||||
enabled-from-chain-ids])
|
||||
token-balance (or default-limit-crypto total-balance)
|
||||
usd-conversion-rate (utils/token-usd-price token)
|
||||
currency (rf/sub [:profile/currency])
|
||||
conversion-rate (-> token
|
||||
:market-values-per-currency
|
||||
currency
|
||||
:price)
|
||||
token-decimals (rf/sub [:wallet/send-display-token-decimals])
|
||||
[input-state set-input-state] (rn/use-state controlled-input/init-state)
|
||||
clear-input! #(set-input-state controlled-input/delete-all)
|
||||
currency-symbol (rf/sub [:profile/currency-symbol])
|
||||
loading-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?])
|
||||
route (rf/sub [:wallet/wallet-send-route])
|
||||
on-confirm (or default-on-confirm handle-on-confirm)
|
||||
max-limit (if crypto-currency?
|
||||
(utils/cut-crypto-decimals-to-fit-usd-cents
|
||||
token-balance
|
||||
usd-conversion-rate)
|
||||
(utils/cut-fiat-balance-to-two-decimals
|
||||
(money/crypto->fiat token-balance conversion-rate)))
|
||||
input-value (controlled-input/input-value input-state)
|
||||
valid-input? (not (or (controlled-input/empty-value? input-state)
|
||||
(controlled-input/input-error input-state)))
|
||||
amount-in-crypto (if crypto-currency?
|
||||
input-value
|
||||
(rf/sub [:wallet/send-amount-fixed
|
||||
(/ input-value conversion-rate)]))
|
||||
show-select-asset-sheet #(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn []
|
||||
[select-asset-bottom-sheet
|
||||
clear-input!])}])
|
||||
sender-network-values (rf/sub [:wallet/wallet-send-sender-network-values])
|
||||
receiver-network-values (rf/sub [:wallet/wallet-send-receiver-network-values])
|
||||
tx-type (rf/sub [:wallet/wallet-send-tx-type])
|
||||
unsupported-token-in-receiver? (and (not= tx-type :tx/bridge)
|
||||
(->> receiver-network-values
|
||||
(remove #(= (:type %) :add))
|
||||
(every? #(= (:type %) :not-available))))
|
||||
suggested-routes (rf/sub [:wallet/wallet-send-suggested-routes])
|
||||
routes (when suggested-routes
|
||||
(or (:best suggested-routes) []))
|
||||
no-routes-found? (and
|
||||
(every-network-value-is-zero? sender-network-values)
|
||||
(some? routes)
|
||||
(not loading-routes?)
|
||||
(not unsupported-token-in-receiver?))
|
||||
receiver-networks (rf/sub [:wallet/wallet-send-receiver-networks])
|
||||
receiver-preferred-networks (rf/sub [:wallet/wallet-send-receiver-preferred-networks])
|
||||
receiver-preferred-network? (set receiver-preferred-networks)
|
||||
sending-to-unpreferred-networks? (some (comp not receiver-preferred-network?)
|
||||
receiver-networks)
|
||||
input-error (controlled-input/input-error input-state)
|
||||
limit-exceeded? (controlled-input/upper-limit-exceeded? input-state)
|
||||
current-address (rf/sub [:wallet/current-viewing-account-address])
|
||||
current-color (rf/sub [:wallet/current-viewing-account-color])
|
||||
enough-assets? (rf/sub [:wallet/wallet-send-enough-assets?])
|
||||
owned-eth-token (rf/sub [:wallet/token-by-symbol
|
||||
(string/upper-case constants/mainnet-short-name)
|
||||
enabled-from-chain-ids])
|
||||
not-enough-asset? (insufficient-asset-amount?
|
||||
{:enough-assets? enough-assets?
|
||||
:token-symbol token-symbol
|
||||
:owned-eth-token owned-eth-token
|
||||
:input-state input-state
|
||||
:no-routes-found? no-routes-found?
|
||||
:limit-exceeded? limit-exceeded?
|
||||
:sender-network-values sender-network-values})
|
||||
should-try-again? (and (not limit-exceeded?)
|
||||
no-routes-found?
|
||||
(not not-enough-asset?))
|
||||
show-no-routes? (and (or no-routes-found? limit-exceeded?)
|
||||
(not-empty sender-network-values)
|
||||
(not not-enough-asset?))
|
||||
confirm-disabled? (or (nil? route)
|
||||
(empty? route)
|
||||
(not valid-input?))
|
||||
fee-formatted (when (or (not confirm-disabled?) not-enough-asset?)
|
||||
(get-fee-formatted route))
|
||||
request-fetch-routes (fn [bounce-duration-ms]
|
||||
(fetch-routes
|
||||
{:amount amount-in-crypto
|
||||
:valid-input? valid-input?
|
||||
:bounce-duration-ms bounce-duration-ms
|
||||
:token token
|
||||
:reset-amounts-to-zero? (and limit-exceeded?
|
||||
(some? routes))}))
|
||||
swap-between-fiat-and-crypto (fn []
|
||||
(if crypto-currency?
|
||||
(set-input-state
|
||||
#(controlled-input/->fiat % conversion-rate))
|
||||
(set-input-state
|
||||
#(controlled-input/->crypto % conversion-rate)))
|
||||
(set-crypto-currency (not crypto-currency?)))]
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(when active-screen?
|
||||
@@ -257,48 +270,124 @@
|
||||
(hot-reload/use-safe-unmount on-navigate-back)
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(when value-out-of-limits?
|
||||
(rf/dispatch [:wallet/stop-get-suggested-routes])
|
||||
(debounce/clear-all)))
|
||||
[value-out-of-limits?])
|
||||
(set-input-state #(controlled-input/set-upper-limit % max-limit)))
|
||||
[max-limit])
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(rf/dispatch [:send-input-amount-screen/token-input-delete-all])
|
||||
(when input-error
|
||||
(rf/dispatch [:wallet/stop-get-suggested-routes])
|
||||
(debounce/clear-all)))
|
||||
[input-error])
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(clear-input!)
|
||||
(rf/dispatch [:wallet/stop-and-clean-suggested-routes])
|
||||
(rf/dispatch [:wallet/clean-disabled-from-networks]))
|
||||
[current-address])
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(request-fetch-routes 0))
|
||||
[send-from-locked-amounts])
|
||||
[rn/view
|
||||
{:style style/screen
|
||||
:accessibility-label (str "container"
|
||||
(when value-out-of-limits? "-error"))}
|
||||
(when (controlled-input/input-error input-state) "-error"))}
|
||||
[account-switcher/view
|
||||
{:icon-name :i/arrow-left
|
||||
:on-press #(rf/dispatch [:navigate-back])
|
||||
:switcher-type :select-account}]
|
||||
[token-input]
|
||||
[routes-view current-screen-id]
|
||||
(when token-not-available?
|
||||
[token-not-available])
|
||||
[quo/token-input
|
||||
{:container-style style/input-container
|
||||
:token-symbol token-symbol
|
||||
:value input-value
|
||||
:on-swap swap-between-fiat-and-crypto
|
||||
:on-token-press show-select-asset-sheet
|
||||
:error? (controlled-input/input-error input-state)
|
||||
:currency-symbol (if crypto-currency? token-symbol fiat-currency)
|
||||
:converted-value (if crypto-currency?
|
||||
(utils/prettify-balance
|
||||
currency-symbol
|
||||
(money/crypto->fiat input-value
|
||||
conversion-rate))
|
||||
(utils/prettify-crypto-balance
|
||||
(or (clj->js token-symbol) "")
|
||||
(money/fiat->crypto input-value
|
||||
conversion-rate)
|
||||
conversion-rate))
|
||||
:hint-component [quo/network-tags
|
||||
{:networks (seq from-enabled-networks)
|
||||
:title (i18n/label
|
||||
:t/send-limit
|
||||
{:limit (if crypto-currency?
|
||||
(utils/prettify-crypto-balance
|
||||
(or (clj->js token-symbol) "")
|
||||
(controlled-input/upper-limit-bn input-state)
|
||||
conversion-rate)
|
||||
(utils/prettify-balance currency-symbol
|
||||
(controlled-input/upper-limit-bn
|
||||
input-state)))})
|
||||
:status (when (controlled-input/input-error input-state) :error)}]}]
|
||||
[routes/view
|
||||
{:token token-by-symbol
|
||||
:send-amount-in-crypto amount-in-crypto
|
||||
:valid-input? valid-input?
|
||||
:token-not-supported-in-receiver-networks? unsupported-token-in-receiver?
|
||||
:current-screen-id current-screen-id
|
||||
:request-fetch-routes request-fetch-routes}]
|
||||
(when (and (not loading-routes?)
|
||||
sender-network-values
|
||||
unsupported-token-in-receiver?)
|
||||
[token-not-available token-symbol receiver-networks token-networks])
|
||||
(when not-enough-asset?
|
||||
[not-enough-asset])
|
||||
(when show-estimated-fees?
|
||||
[estimated-fees])
|
||||
(when (or (and (not no-routes-found?) (or loading-routes? route))
|
||||
not-enough-asset?)
|
||||
[estimated-fees/view
|
||||
{:loading-routes? loading-routes?
|
||||
:fees fee-formatted}])
|
||||
(when show-no-routes?
|
||||
[no-routes-found])
|
||||
[bottom-actions button-one-label button-one-props on-confirm]
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (if should-try-again?
|
||||
(i18n/label :t/try-again)
|
||||
button-one-label)
|
||||
:button-one-props (merge (when-not should-try-again?
|
||||
button-one-props)
|
||||
{:disabled? (or not-enough-asset?
|
||||
loading-routes?
|
||||
(and (not should-try-again?)
|
||||
confirm-disabled?))
|
||||
:on-press (cond
|
||||
should-try-again?
|
||||
#(rf/dispatch [:wallet/start-get-suggested-routes
|
||||
{:amount amount-in-crypto
|
||||
:updated-token token-by-symbol}])
|
||||
sending-to-unpreferred-networks?
|
||||
#(show-unpreferred-networks-alert on-confirm)
|
||||
:else
|
||||
#(on-confirm amount-in-crypto))
|
||||
:customization-color current-color}
|
||||
(when should-try-again?
|
||||
{:type :grey}))}]
|
||||
[quo/numbered-keyboard
|
||||
{:container-style (style/keyboard-container bottom)
|
||||
:left-action :dot
|
||||
:delete-key? true
|
||||
:on-press (fn [c]
|
||||
(rf/dispatch [:send-input-amount-screen/token-input-add-character c
|
||||
max-decimals]))
|
||||
(let [new-text (str input-value c)
|
||||
max-decimals (if crypto-currency? token-decimals 2)
|
||||
regex-pattern (str "^\\d*\\.?\\d{0," max-decimals "}$")
|
||||
regex (re-pattern regex-pattern)]
|
||||
(when (re-matches regex new-text)
|
||||
(debounce/clear-all)
|
||||
(set-input-state #(controlled-input/add-character % c)))))
|
||||
:on-delete (fn []
|
||||
(debounce/clear-all)
|
||||
(rf/dispatch [:send-input-amount-screen/token-input-delete-last])
|
||||
(set-input-state controlled-input/delete-last)
|
||||
(rf/dispatch-sync [:wallet/stop-and-clean-suggested-routes]))
|
||||
:on-long-press-delete (fn []
|
||||
(debounce/clear-all)
|
||||
(rf/dispatch [:send-input-amount-screen/token-input-delete-all])
|
||||
(set-input-state controlled-input/delete-all)
|
||||
(rf/dispatch-sync [:wallet/stop-and-clean-suggested-routes]))}]]))
|
||||
|
||||
|
||||
@@ -243,37 +243,40 @@
|
||||
[{:keys [network-values token-symbol on-press on-long-press receiver? loading-routes?
|
||||
token-not-supported-in-receiver-networks?]}]
|
||||
[rn/view
|
||||
(map-indexed (fn [index
|
||||
{chain-id :chain-id
|
||||
network-value-type :type
|
||||
total-amount :total-amount}]
|
||||
(let [status (cond (and (= network-value-type :not-available)
|
||||
loading-routes?
|
||||
token-not-supported-in-receiver-networks?)
|
||||
:loading
|
||||
(= network-value-type :not-available)
|
||||
:disabled
|
||||
:else network-value-type)]
|
||||
[rn/view
|
||||
{:key (str (if receiver? "to" "from") "-" chain-id)
|
||||
:style {:margin-top (if (pos? index) 11 7.5)}}
|
||||
[quo/network-bridge
|
||||
{:amount (if (= network-value-type :not-available)
|
||||
(i18n/label :t/not-available)
|
||||
(str total-amount " " token-symbol))
|
||||
:network (network-utils/id->network chain-id)
|
||||
:status status
|
||||
:on-press #(when (not loading-routes?)
|
||||
(cond
|
||||
(= network-value-type :edit)
|
||||
(open-preferences)
|
||||
on-press (on-press chain-id total-amount)))
|
||||
:on-long-press #(when (and (not loading-routes?) (not= status :disabled))
|
||||
(cond
|
||||
(= network-value-type :add)
|
||||
(open-preferences)
|
||||
on-long-press (on-long-press chain-id total-amount)))}]]))
|
||||
network-values)])
|
||||
(doall
|
||||
(map-indexed (fn [index
|
||||
{chain-id :chain-id
|
||||
network-value-type :type
|
||||
total-amount :total-amount}]
|
||||
(let [status (cond (and (= network-value-type :not-available)
|
||||
loading-routes?
|
||||
token-not-supported-in-receiver-networks?)
|
||||
:loading
|
||||
(= network-value-type :not-available)
|
||||
:disabled
|
||||
:else network-value-type)
|
||||
amount-formatted (-> (rf/sub [:wallet/send-amount-fixed total-amount])
|
||||
(str " " token-symbol))]
|
||||
^{:key (str (if receiver? "to" "from") "-" chain-id)}
|
||||
[rn/view
|
||||
{:style {:margin-top (if (pos? index) 11 7.5)}}
|
||||
[quo/network-bridge
|
||||
{:amount (if (= network-value-type :not-available)
|
||||
(i18n/label :t/not-available)
|
||||
amount-formatted)
|
||||
:network (network-utils/id->network chain-id)
|
||||
:status status
|
||||
:on-press #(when (not loading-routes?)
|
||||
(cond
|
||||
(= network-value-type :edit)
|
||||
(open-preferences)
|
||||
on-press (on-press chain-id total-amount)))
|
||||
:on-long-press #(when (and (not loading-routes?) (not= status :disabled))
|
||||
(cond
|
||||
(= network-value-type :add)
|
||||
(open-preferences)
|
||||
on-long-press (on-long-press chain-id total-amount)))}]]))
|
||||
network-values))])
|
||||
|
||||
(defn render-network-links
|
||||
[{:keys [network-links sender-network-values]}]
|
||||
|
||||
@@ -8,14 +8,12 @@
|
||||
(defn view
|
||||
[]
|
||||
[input-amount/view
|
||||
{:current-screen-id :screen/wallet.send-input-amount
|
||||
:button-one-label (i18n/label :t/review-send)
|
||||
:on-confirm (fn [amount]
|
||||
(rf/dispatch [:wallet/set-token-amount-to-send
|
||||
{:amount amount
|
||||
:stack-id :screen/wallet.send-input-amount}]))
|
||||
:on-navigate-back (fn []
|
||||
(rf/dispatch-sync [:wallet/stop-and-clean-suggested-routes])
|
||||
(rf/dispatch [:wallet/clean-disabled-from-networks])
|
||||
(rf/dispatch [:wallet/clean-from-locked-amounts])
|
||||
(rf/dispatch [:wallet/clean-send-amount]))}])
|
||||
{:current-screen-id :screen/wallet.send-input-amount
|
||||
:button-one-label (i18n/label :t/review-send)
|
||||
:enabled-from-chain-ids (rf/sub [:wallet/wallet-send-enabled-from-chain-ids])
|
||||
:from-enabled-networks (rf/sub [:wallet/wallet-send-enabled-networks])
|
||||
:on-navigate-back (fn []
|
||||
(rf/dispatch-sync [:wallet/stop-and-clean-suggested-routes])
|
||||
(rf/dispatch [:wallet/clean-disabled-from-networks])
|
||||
(rf/dispatch [:wallet/clean-from-locked-amounts])
|
||||
(rf/dispatch [:wallet/clean-send-amount]))}])
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
(ns status-im.contexts.wallet.send.transaction-confirmation.account-summary
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.send.transaction-confirmation.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- account-summary-header
|
||||
[{:keys [label accessibility-label]}]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style (style/section-label theme)
|
||||
:accessibility-label accessibility-label}
|
||||
label]))
|
||||
|
||||
(defn- current-user-account-summary
|
||||
[{:keys [network-values]}]
|
||||
(let [{:keys [color emoji name address]} (rf/sub [:wallet/current-viewing-account])]
|
||||
[quo/summary-info
|
||||
{:type :status-account
|
||||
:networks? true
|
||||
:values network-values
|
||||
:account-props {:customization-color color
|
||||
:size 32
|
||||
:emoji emoji
|
||||
:type :default
|
||||
:name name
|
||||
:address (utils/get-shortened-address address)}}]))
|
||||
|
||||
(defn- recipient-account-summary
|
||||
[{:keys [network-values]}]
|
||||
(let [{:keys [label emoji customization-color recipient-type]} (rf/sub [:wallet/send-recipient])
|
||||
address (rf/sub [:wallet/send-to-address])
|
||||
shortened-address (utils/get-shortened-address address)
|
||||
summary-type (condp = recipient-type
|
||||
:saved-address :saved-account
|
||||
:account :status-account
|
||||
:address :account
|
||||
:account)]
|
||||
[quo/summary-info
|
||||
{:type summary-type
|
||||
:networks? true
|
||||
:values network-values
|
||||
:account-props (cond-> {:customization-color customization-color
|
||||
:size 32
|
||||
:emoji emoji
|
||||
:type :default
|
||||
:name (or label address)
|
||||
:full-name label
|
||||
:address shortened-address}
|
||||
|
||||
(= recipient-type :address)
|
||||
(assoc :full-name "0 x"
|
||||
:monospace? true
|
||||
:lowercase? true))}]))
|
||||
|
||||
(defn from-summary
|
||||
[]
|
||||
(let [network-values (rf/sub [:wallet/network-values false])]
|
||||
[rn/view {:style style/summary-container}
|
||||
[account-summary-header
|
||||
{:label (i18n/label :t/from-capitalized)
|
||||
:accessibility-label :summary-from-label}]
|
||||
[current-user-account-summary {:network-values network-values}]]))
|
||||
|
||||
(defn to-summary
|
||||
[]
|
||||
(let [network-values (rf/sub [:wallet/network-values true])
|
||||
tx-type (rf/sub [:wallet/send-tx-type])]
|
||||
[rn/view {:style style/summary-container}
|
||||
[account-summary-header
|
||||
{:label (i18n/label :t/to-capitalized)
|
||||
:accessibility-label :summary-to-label}]
|
||||
(if (= tx-type :tx/bridge)
|
||||
[current-user-account-summary {:network-values network-values}]
|
||||
[recipient-account-summary {:network-values network-values}])]))
|
||||
@@ -1,13 +1,17 @@
|
||||
(ns status-im.contexts.wallet.send.transaction-confirmation.style
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(def summary-container
|
||||
{:padding-horizontal 20
|
||||
:padding-bottom 16})
|
||||
|
||||
(def detail-item
|
||||
{:flex 1
|
||||
:height 36
|
||||
:background-color :transparent})
|
||||
|
||||
(def content-container
|
||||
{:padding-top 12
|
||||
{:padding-top 8
|
||||
:padding-horizontal 20
|
||||
:padding-bottom 32})
|
||||
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
(ns status-im.contexts.wallet.send.transaction-confirmation.transaction-title
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.utils :as rn.utils]
|
||||
[status-im.contexts.wallet.send.transaction-confirmation.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- title-container
|
||||
[& argv]
|
||||
(let [[_ children] (rn.utils/get-props-and-children argv)]
|
||||
(into [rn/view {:style style/content-container}]
|
||||
children)))
|
||||
|
||||
(defn- title-row
|
||||
[& argv]
|
||||
(let [[_ children] (rn.utils/get-props-and-children argv)]
|
||||
(into [rn/view
|
||||
{:style {:flex-direction :row
|
||||
:margin-top 4}}]
|
||||
children)))
|
||||
|
||||
(defn- title-text
|
||||
[text]
|
||||
[quo/text
|
||||
{:size :heading-1
|
||||
:weight :semi-bold
|
||||
:style style/title-container
|
||||
:accessibility-label :send-label}
|
||||
text])
|
||||
|
||||
(defn- title-token
|
||||
[]
|
||||
(let [amount (rf/sub [:wallet/send-amount])
|
||||
token-display-name (rf/sub [:wallet/wallet-send-token-symbol])]
|
||||
[quo/summary-tag
|
||||
{:token token-display-name
|
||||
:label (str amount " " token-display-name)
|
||||
:type :token}]))
|
||||
|
||||
(defn- title-collectible
|
||||
[]
|
||||
(let [{:keys [collectible-data preview-url]} (rf/sub [:wallet/send-collectible])]
|
||||
[quo/summary-tag
|
||||
{:label (:name collectible-data)
|
||||
:image-source (:uri preview-url)
|
||||
:type :collectible}]))
|
||||
|
||||
(defn- title-network
|
||||
[{:keys [chain-id]}]
|
||||
(let [{:keys [full-name source network-name]} (rf/sub [:wallet/network-details-by-chain-id chain-id])]
|
||||
[quo/summary-tag
|
||||
{:label full-name
|
||||
:type :network
|
||||
:image-source source
|
||||
:customization-color network-name}]))
|
||||
|
||||
(defn- from-bridge-networks
|
||||
[]
|
||||
(let [chain-ids (rf/sub [:wallet/send-from-chain-ids])]
|
||||
[:<>
|
||||
(doall (map-indexed (fn [idx chain-id]
|
||||
^{:key (str "transaction-title" idx)}
|
||||
[title-row
|
||||
[title-text
|
||||
(if (zero? idx)
|
||||
(i18n/label :t/from)
|
||||
(str (i18n/label :t/and) " "))]
|
||||
[title-network {:chain-id chain-id}]])
|
||||
chain-ids))]))
|
||||
|
||||
(defn- to-bridge-network
|
||||
[]
|
||||
(let [chain-id (rf/sub [:wallet/send-bridge-to-chain-id])]
|
||||
[title-network {:chain-id chain-id}]))
|
||||
|
||||
(defn- title-account
|
||||
[]
|
||||
(let [{:keys [name emoji color]} (rf/sub [:wallet/current-viewing-account])]
|
||||
[quo/summary-tag
|
||||
{:label name
|
||||
:type :account
|
||||
:emoji emoji
|
||||
:customization-color color}]))
|
||||
|
||||
(defn- title-recipient
|
||||
[]
|
||||
(let [{:keys [recipient-type emoji label customization-color]} (rf/sub [:wallet/send-recipient])]
|
||||
[quo/summary-tag
|
||||
{:type recipient-type
|
||||
:emoji emoji
|
||||
:label label
|
||||
:customization-color customization-color}]))
|
||||
|
||||
(defn- bridge-title
|
||||
[]
|
||||
[title-container
|
||||
[title-row
|
||||
[title-text (i18n/label :t/bridge)]
|
||||
[title-token]]
|
||||
[from-bridge-networks]
|
||||
[title-row
|
||||
[title-text (i18n/label :t/to)]
|
||||
[to-bridge-network]]
|
||||
[title-row
|
||||
[title-text (i18n/label :t/in)]
|
||||
[title-account]]])
|
||||
|
||||
(defn- send-title
|
||||
[]
|
||||
(let [sending-collectible? (rf/sub [:wallet/sending-collectible?])]
|
||||
[title-container
|
||||
[title-row
|
||||
[title-text (i18n/label :t/send)]
|
||||
(if sending-collectible?
|
||||
[title-collectible]
|
||||
[title-token])]
|
||||
[title-row
|
||||
[title-text (i18n/label :t/from)]
|
||||
[title-account]]
|
||||
[title-row
|
||||
[title-text (i18n/label :t/to)]
|
||||
[title-recipient]]]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [tx-type (rf/sub [:wallet/send-tx-type])]
|
||||
(condp = tx-type
|
||||
:tx/bridge [bridge-title]
|
||||
:tx/send [send-title]
|
||||
[send-title])))
|
||||