Compare commits
16
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6adfb10255 | ||
|
|
2e07a3ddfe | ||
|
|
5b81006f88 | ||
|
|
8ddea30542 | ||
|
|
13d40203f1 | ||
|
|
5d0e30a238 | ||
|
|
9f7cc76daf | ||
|
|
1be5be1ff9 | ||
|
|
4ceb5c890e | ||
|
|
1636a1d231 | ||
|
|
d4eae9ee46 | ||
|
|
b4dc36b406 | ||
|
|
5032104bab | ||
|
|
664d9f0f05 | ||
|
|
a6c346ea7d | ||
|
|
7812b393ce |
@@ -299,8 +299,6 @@ dependencies {
|
||||
implementation("com.squareup.okhttp3:okhttp-tls:4.11.0")
|
||||
implementation("com.google.prefab:cli:2.0.0")
|
||||
implementation("com.android.tools.build:aapt2:8.1.1-10154469")
|
||||
implementation "com.github.bumptech.glide:okhttp3-integration:4.12.0"
|
||||
annotationProcessor "com.github.bumptech.glide:compiler:4.12.0"
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
package im.status.ethereum
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.Registry
|
||||
import com.bumptech.glide.module.GlideModule
|
||||
import com.bumptech.glide.GlideBuilder
|
||||
import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader
|
||||
import com.bumptech.glide.load.model.GlideUrl
|
||||
import java.io.InputStream
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
class CustomGlideModule : GlideModule {
|
||||
override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
|
||||
// Create a single thread executor for background operations
|
||||
val executor = Executors.newSingleThreadExecutor()
|
||||
val mainHandler = Handler(Looper.getMainLooper())
|
||||
|
||||
// Execute network operation in background
|
||||
executor.execute {
|
||||
val client = StatusOkHttpClientFactory().createNewNetworkModuleClient()
|
||||
|
||||
// Post results back to main thread
|
||||
mainHandler.post {
|
||||
client?.let {
|
||||
val factory = OkHttpUrlLoader.Factory(it)
|
||||
registry.replace(
|
||||
GlideUrl::class.java,
|
||||
InputStream::class.java,
|
||||
factory
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up executor
|
||||
executor.shutdown()
|
||||
}
|
||||
|
||||
override fun applyOptions(context: Context, builder: GlideBuilder) {
|
||||
// No additional options needed
|
||||
}
|
||||
}
|
||||
@@ -15,10 +15,8 @@ import cl.json.RNSharePackage
|
||||
import com.reactnativecommunity.blurview.BlurViewPackage
|
||||
import im.status.ethereum.keycard.RNStatusKeycardPackage
|
||||
import im.status.ethereum.module.StatusPackage
|
||||
import im.status.ethereum.module.StatusBackendClient
|
||||
import im.status.ethereum.pushnotifications.PushNotificationPackage
|
||||
import im.status.ethereum.StatusOkHttpClientFactory
|
||||
import android.util.Log
|
||||
|
||||
class MainApplication : NavigationApplication() {
|
||||
|
||||
@@ -41,26 +39,6 @@ class MainApplication : NavigationApplication() {
|
||||
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
|
||||
|
||||
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
|
||||
|
||||
override fun createReactInstanceManager() =
|
||||
super.createReactInstanceManager().apply {
|
||||
addReactInstanceEventListener {
|
||||
val serverEnabledEnv = true
|
||||
val statusGoEndpointEnv = "127.0.0.1:60000"
|
||||
val rootDataDirEnv = "/Users/frank/Downloads/tmp"
|
||||
val statusGoEndpoint = "http://${statusGoEndpointEnv}/statusgo/"
|
||||
val signalEndpoint = "ws://${statusGoEndpointEnv}/signals"
|
||||
Log.d("MainApplication", "Configuring StatusBackendServer with serverEnabled=$serverEnabledEnv, statusGoEndpoint=$statusGoEndpoint, signalEndpoint=$signalEndpoint, rootDataDir=$rootDataDirEnv")
|
||||
StatusBackendClient.getInstance()?.configStatusBackendServer(
|
||||
serverEnabled = serverEnabledEnv,
|
||||
statusGoEndpoint = statusGoEndpoint,
|
||||
signalEndpoint = signalEndpoint,
|
||||
rootDataDir = rootDataDirEnv
|
||||
)
|
||||
OkHttpClientProvider.setOkHttpClientFactory(StatusOkHttpClientFactory())
|
||||
Log.d("MainApplication", "StatusBackendServer configured")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override val reactNativeHost: ReactNativeHost
|
||||
@@ -69,7 +47,7 @@ class MainApplication : NavigationApplication() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
||||
//OkHttpClientProvider.setOkHttpClientFactory(StatusOkHttpClientFactory())
|
||||
OkHttpClientProvider.setOkHttpClientFactory(StatusOkHttpClientFactory())
|
||||
|
||||
WebView.setWebContentsDebuggingEnabled(BuildConfig.DEBUG_WEBVIEW == "1")
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
initscript {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.gradle:github-dependency-graph-gradle-plugin:+"
|
||||
}
|
||||
}
|
||||
apply plugin: org.gradle.dependencygraph.simple.SimpleDependencyGraphPlugin
|
||||
@@ -1,12 +1,12 @@
|
||||
pluginManagement {
|
||||
includeBuild('../node_modules/@react-native/gradle-plugin')
|
||||
include ':react-native-share'
|
||||
project(':react-native-share').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-share/android')
|
||||
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'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.12'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.12'
|
||||
|
||||
import groovy.json.JsonBuilder
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.12'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.12'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.12'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.12'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.12'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.12'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.12'
|
||||
|
||||
pipeline {
|
||||
agent { label 'macos' }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.12'
|
||||
|
||||
pipeline {
|
||||
agent { label params.AGENT_LABEL }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.12'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.9.13'
|
||||
library 'status-jenkins-lib@v1.9.12'
|
||||
|
||||
pipeline {
|
||||
agent {
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
## Solution to use Status Backend Server
|
||||
`StatusBackendClient` is the entry point to use Status Backend Server. We need always to call `status-im.setup.status-backend-client/init` whether `STATUS_BACKEND_SERVER_ENABLED` is `1` or not. If it's not enabled, the invocation to functions in `native-module.core` will be delegated to built-in status-go library, otherwise it will be delegated to status-go running in status-backend server. Currently, all functions has usages in `native-module.core` should be supported delegated to.
|
||||
|
||||
related [PR](https://github.com/status-im/status-mobile/pull/21550)
|
||||
|
||||
## Usage
|
||||
### Add environment variables to your local machine:
|
||||
```shell
|
||||
# enable using status backend server or not, otherwise it will use built-in status-go library
|
||||
export STATUS_BACKEND_SERVER_ENABLED=1
|
||||
|
||||
#The host should contain an IP address and a port separated by a colon.
|
||||
#The port comes from your running status backend server.
|
||||
#If you run it by PORT=60000 make run-status-backend , then host will likely be 127.0.0.1:60000
|
||||
export STATUS_BACKEND_SERVER_HOST="127.0.0.1:60000"
|
||||
|
||||
export STATUS_BACKEND_SERVER_ROOT_DATA_DIR="/path/to/your/root/data/dir"
|
||||
```
|
||||
You need to change `STATUS_BACKEND_SERVER_ROOT_DATA_DIR` to your preferred directory and ensure it exists, it should be in absolute path.
|
||||
All the db files and log files(requests.log/geth.log) and keystore files etc will be stored in this directory.
|
||||
|
||||
### Start the status backend server:
|
||||
```shell
|
||||
PORT=60000 make run-status-backend
|
||||
```
|
||||
MAKE SURE the status-backend is checked out to a revision that's at least compatible with the revision in status-mobile/status-go-version.json before starting the server.
|
||||
|
||||
For the Android simulator, you need to reverse the port:
|
||||
```shell
|
||||
adb reverse tcp:60000 tcp:60000
|
||||
```
|
||||
|
||||
### Known issues
|
||||
- Android devices may not display images due to TLS certificate validation issues with the image server
|
||||
- exportUnencryptedDatabaseV2/import-multiaccount does not work for android, probably cause of tech debt, I found it during creating the draft PR.
|
||||
@@ -219,6 +219,7 @@ PLATFORMS
|
||||
arm64-darwin-22
|
||||
arm64-darwin-23
|
||||
x86_64-darwin-22
|
||||
x86_64-darwin-23
|
||||
|
||||
DEPENDENCIES
|
||||
activesupport (>= 6.1.7.3, < 7.1.0)
|
||||
|
||||
+29
-30
@@ -1,7 +1,6 @@
|
||||
PODS:
|
||||
- BigInt (5.2.0)
|
||||
- boost (1.83.0)
|
||||
- CryptoSwift (1.8.3)
|
||||
- CryptoSwift (1.5.1)
|
||||
- DoubleConversion (1.1.6)
|
||||
- FBLazyVector (0.73.5)
|
||||
- FBReactNativeSpec (0.73.5):
|
||||
@@ -17,24 +16,20 @@ PODS:
|
||||
- hermes-engine/Pre-built (= 0.73.5)
|
||||
- hermes-engine/Pre-built (0.73.5)
|
||||
- HMSegmentedControl (1.5.6)
|
||||
- Keycard (3.1.0):
|
||||
- BigInt
|
||||
- Keycard (3.0.6):
|
||||
- CryptoSwift
|
||||
- secp256k1
|
||||
- SSZipArchive
|
||||
- libevent (2.1.12)
|
||||
- libwebp (1.3.2):
|
||||
- libwebp/demux (= 1.3.2)
|
||||
- libwebp/mux (= 1.3.2)
|
||||
- libwebp/sharpyuv (= 1.3.2)
|
||||
- libwebp/webp (= 1.3.2)
|
||||
- libwebp/demux (1.3.2):
|
||||
- libwebp (1.2.4):
|
||||
- libwebp/demux (= 1.2.4)
|
||||
- libwebp/mux (= 1.2.4)
|
||||
- libwebp/webp (= 1.2.4)
|
||||
- libwebp/demux (1.2.4):
|
||||
- libwebp/webp
|
||||
- libwebp/mux (1.3.2):
|
||||
- libwebp/mux (1.2.4):
|
||||
- libwebp/demux
|
||||
- libwebp/sharpyuv (1.3.2)
|
||||
- libwebp/webp (1.3.2):
|
||||
- libwebp/sharpyuv
|
||||
- libwebp/webp (1.2.4)
|
||||
- RCT-Folly (2022.05.16.00):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
@@ -940,6 +935,8 @@ PODS:
|
||||
- React
|
||||
- react-native-orientation-locker (1.5.0):
|
||||
- React-Core
|
||||
- react-native-pdf (6.7.5):
|
||||
- React-Core
|
||||
- react-native-shake (3.4.0):
|
||||
- React
|
||||
- react-native-slider (3.0.0):
|
||||
@@ -1153,15 +1150,15 @@ PODS:
|
||||
- glog
|
||||
- RCT-Folly (= 2022.05.16.00)
|
||||
- React-Core
|
||||
- RNImageCropPicker (0.41.2):
|
||||
- RNImageCropPicker (0.40.0):
|
||||
- React-Core
|
||||
- React-RCTImage
|
||||
- RNImageCropPicker/QBImagePickerController (= 0.41.2)
|
||||
- TOCropViewController (~> 2.7.4)
|
||||
- RNImageCropPicker/QBImagePickerController (0.41.2):
|
||||
- RNImageCropPicker/QBImagePickerController (= 0.40.0)
|
||||
- TOCropViewController
|
||||
- RNImageCropPicker/QBImagePickerController (0.40.0):
|
||||
- React-Core
|
||||
- React-RCTImage
|
||||
- TOCropViewController (~> 2.7.4)
|
||||
- TOCropViewController
|
||||
- RNKeychain (8.1.2):
|
||||
- React-Core
|
||||
- RNLinearGradient (3.0.0-alpha.1):
|
||||
@@ -1190,7 +1187,7 @@ PODS:
|
||||
- secp256k1 (0.1.6)
|
||||
- SocketRocket (0.6.1)
|
||||
- SSZipArchive (2.4.3)
|
||||
- TOCropViewController (2.7.4)
|
||||
- TOCropViewController (2.6.1)
|
||||
- Yoga (1.14.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
@@ -1238,6 +1235,7 @@ DEPENDENCIES:
|
||||
- react-native-lottie-splash-screen (from `../node_modules/react-native-lottie-splash-screen`)
|
||||
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
|
||||
- react-native-orientation-locker (from `../node_modules/react-native-orientation-locker`)
|
||||
- react-native-pdf (from `../node_modules/react-native-pdf`)
|
||||
- react-native-shake (from `../node_modules/react-native-shake`)
|
||||
- "react-native-slider (from `../node_modules/@react-native-community/slider`)"
|
||||
- react-native-status (from `../modules/react-native-status`)
|
||||
@@ -1287,7 +1285,6 @@ DEPENDENCIES:
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- BigInt
|
||||
- CryptoSwift
|
||||
- fmt
|
||||
- HMSegmentedControl
|
||||
@@ -1383,6 +1380,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/@react-native-community/netinfo"
|
||||
react-native-orientation-locker:
|
||||
:path: "../node_modules/react-native-orientation-locker"
|
||||
react-native-pdf:
|
||||
:path: "../node_modules/react-native-pdf"
|
||||
react-native-shake:
|
||||
:path: "../node_modules/react-native-shake"
|
||||
react-native-slider:
|
||||
@@ -1477,27 +1476,26 @@ EXTERNAL SOURCES:
|
||||
|
||||
CHECKOUT OPTIONS:
|
||||
Keycard:
|
||||
:commit: afb19836d6730ade5035f6f86ad90715be336af2
|
||||
:commit: 17381678bb981c3c553bb7202a26e642cecb1817
|
||||
:git: https://github.com/status-im/Keycard.swift.git
|
||||
secp256k1:
|
||||
:commit: 4ab977cc2b2d7319be858bcb30a5d189bb149884
|
||||
:commit: 46a1fa30d9b8babeae85ff519050f42394ab5fcc
|
||||
:git: https://github.com/status-im/secp256k1.swift.git
|
||||
:submodules: true
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
BigInt: f668a80089607f521586bbe29513d708491ef2f7
|
||||
boost: d3f49c53809116a5d38da093a8aa78bf551aed09
|
||||
CryptoSwift: 967f37cea5a3294d9cce358f78861652155be483
|
||||
CryptoSwift: c4f2debceb38bf44c80659afe009f71e23e4a082
|
||||
DoubleConversion: fea03f2699887d960129cc54bba7e52542b6f953
|
||||
FBLazyVector: 56e0e498dbb513b96c40bac6284729ba4e62672d
|
||||
FBReactNativeSpec: 146c741a3f40361f6bc13a4ba284678cbedb5881
|
||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||
glog: 53cc9a00a2af0495ac1613e9fe3df6e646a3f405
|
||||
glog: 36c15c01d70ed395c6e4f3619f98a23ee415b07a
|
||||
hermes-engine: 1d1835b2cc54c381909d94d1b3c8e0a2f1a94a0e
|
||||
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
|
||||
Keycard: 3bd24405b9a875b3b3cf1ab1be69b5c30c5f28bc
|
||||
Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8
|
||||
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
|
||||
libwebp: 1786c9f4ff8a279e4dac1e8f385004d5fc253009
|
||||
libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef
|
||||
RCT-Folly: 7169b2b1c44399c76a47b5deaaba715eeeb476c0
|
||||
RCTRequired: 2544c0f1081a5fa12e108bb8cb40e5f4581ccd87
|
||||
RCTTypeSafety: 50efabe2b115c11ed03fbf3fd79e2f163ddb5d7c
|
||||
@@ -1532,6 +1530,7 @@ SPEC CHECKSUMS:
|
||||
react-native-lottie-splash-screen: 4e1b1fd9d6633f9cd2106d6877eb5ba0147f3e2b
|
||||
react-native-netinfo: ddaca8bbb9e6e914b1a23787ccb879bc642931c9
|
||||
react-native-orientation-locker: 851f6510d8046ea2f14aa169b1e01fcd309a94ba
|
||||
react-native-pdf: 103940c90d62adfd259f63cca99c7c0c306b514c
|
||||
react-native-shake: de052eaa3eadc4a326b8ddd7ac80c06e8d84528c
|
||||
react-native-slider: 12bd76d3d568c9c5500825db54123d44b48e4ad4
|
||||
react-native-status: 21f75d492fd311dc111303da38a7a2b23a8a8466
|
||||
@@ -1567,7 +1566,7 @@ SPEC CHECKSUMS:
|
||||
RNFastImage: 1f2cab428712a4baaf78d6169eaec7f622556dd7
|
||||
RNFS: 2bd9eb49dc82fa9676382f0585b992c424cd59df
|
||||
RNGestureHandler: 15c6ef51acba34c49ff03003806cf5dd6098f383
|
||||
RNImageCropPicker: 771e2ca319d2cf92e04ebf334ece892ee9a6728f
|
||||
RNImageCropPicker: 486e2f7e2b0461ce24321f751410dce1b3b49e6d
|
||||
RNKeychain: a65256b6ca6ba6976132cc4124b238a5b13b3d9c
|
||||
RNLinearGradient: ccaaebce083b54180da61d992e7fa56abfe000d6
|
||||
RNPermissions: 08e619529cced22695f4b6d0efcc0a233e278903
|
||||
@@ -1580,7 +1579,7 @@ SPEC CHECKSUMS:
|
||||
secp256k1: f61d67e6fdcb85fd727acf1bf35ace6036db540c
|
||||
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
|
||||
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
|
||||
TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654
|
||||
TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863
|
||||
Yoga: a716eea57d0d3430219c0a5a233e1e93ee931eb7
|
||||
|
||||
PODFILE CHECKSUM: 5dd4a5279260d370bcdf016158c825ceb404ee06
|
||||
|
||||
@@ -572,8 +572,6 @@
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests-resources.sh",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift/CryptoSwift.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/RNImageCropPickerPrivacyInfo.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNPermissions/RNPermissionsPrivacyInfo.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
|
||||
@@ -581,8 +579,6 @@
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/CryptoSwift.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNImageCropPickerPrivacyInfo.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNPermissionsPrivacyInfo.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
|
||||
@@ -618,8 +614,6 @@
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusIm/Pods-Status-StatusIm-resources.sh",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift/CryptoSwift.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/RNImageCropPickerPrivacyInfo.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNPermissions/RNPermissionsPrivacyInfo.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
|
||||
@@ -627,8 +621,6 @@
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/CryptoSwift.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNImageCropPickerPrivacyInfo.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNPermissionsPrivacyInfo.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
|
||||
@@ -736,8 +728,6 @@
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Status-StatusImPR/Pods-Status-StatusImPR-resources.sh",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/CryptoSwift/CryptoSwift.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/RNImageCropPickerPrivacyInfo.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNImageCropPicker/QBImagePicker.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNPermissions/RNPermissionsPrivacyInfo.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
|
||||
@@ -745,8 +735,6 @@
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/CryptoSwift.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNImageCropPickerPrivacyInfo.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/QBImagePicker.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNPermissionsPrivacyInfo.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
|
||||
|
||||
@@ -29,8 +29,6 @@
|
||||
#import <Security/Security.h>
|
||||
#import <react/config/ReactNativeConfig.h>
|
||||
|
||||
#import "StatusBackendClient.h"
|
||||
|
||||
//TODO: properly import the framework
|
||||
extern "C" NSString* StatusgoImageServerTLSCert();
|
||||
|
||||
@@ -190,12 +188,7 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
|
||||
NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
|
||||
__block NSURLCredential *credential = nil;
|
||||
|
||||
NSString *pemCert = [StatusBackendClient executeStatusGoRequestWithResult:@"ImageServerTLSCert"
|
||||
body:@""
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoImageServerTLSCert();
|
||||
}];
|
||||
|
||||
NSString *pemCert = StatusgoImageServerTLSCert();
|
||||
pemCert = [pemCert stringByReplacingOccurrencesOfString:@"-----BEGIN CERTIFICATE-----\n" withString:@""];
|
||||
pemCert = [pemCert stringByReplacingOccurrencesOfString:@"\n-----END CERTIFICATE-----" withString:@""];
|
||||
NSData *derCert = [[NSData alloc] initWithBase64EncodedString:pemCert options:NSDataBase64DecodingIgnoreUnknownCharacters];
|
||||
|
||||
+62
-128
@@ -24,23 +24,25 @@ class AccountManager(private val reactContext: ReactApplicationContext) : ReactC
|
||||
@ReactMethod
|
||||
fun createAccountAndLogin(createAccountRequest: String) {
|
||||
Log.d(TAG, "createAccountAndLogin")
|
||||
|
||||
StatusBackendClient.executeStatusGoRequest(
|
||||
endpoint = "CreateAccountAndLogin",
|
||||
requestBody = createAccountRequest,
|
||||
statusgoFunction = { Statusgo.createAccountAndLogin(createAccountRequest) }
|
||||
)
|
||||
val result = Statusgo.createAccountAndLogin(createAccountRequest)
|
||||
if (result.startsWith("{\"error\":\"\"")) {
|
||||
Log.d(TAG, "createAccountAndLogin success: $result")
|
||||
Log.d(TAG, "Geth node started")
|
||||
} else {
|
||||
Log.e(TAG, "createAccountAndLogin failed: $result")
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun restoreAccountAndLogin(restoreAccountRequest: String) {
|
||||
Log.d(TAG, "restoreAccountAndLogin")
|
||||
|
||||
StatusBackendClient.executeStatusGoRequest(
|
||||
endpoint = "RestoreAccountAndLogin",
|
||||
requestBody = restoreAccountRequest,
|
||||
statusgoFunction = { Statusgo.restoreAccountAndLogin(restoreAccountRequest) }
|
||||
)
|
||||
val result = Statusgo.restoreAccountAndLogin(restoreAccountRequest)
|
||||
if (result.startsWith("{\"error\":\"\"")) {
|
||||
Log.d(TAG, "restoreAccountAndLogin success: $result")
|
||||
Log.d(TAG, "Geth node started")
|
||||
} else {
|
||||
Log.e(TAG, "restoreAccountAndLogin failed: $result")
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateConfig(jsonConfigString: String, absRootDirPath: String, keystoreDirPath: String): String {
|
||||
@@ -171,7 +173,12 @@ class AccountManager(private val reactContext: ReactApplicationContext) : ReactC
|
||||
accountsData,
|
||||
chatKey
|
||||
)
|
||||
utils.handleStatusGoResponse(result, "saveAccountAndLoginWithKeycard")
|
||||
if (result.startsWith("{\"error\":\"\"")) {
|
||||
Log.d(TAG, "saveAccountAndLoginWithKeycard result: $result")
|
||||
Log.d(TAG, "Geth node started")
|
||||
} else {
|
||||
Log.e(TAG, "saveAccountAndLoginWithKeycard failed: $result")
|
||||
}
|
||||
} catch (e: JSONException) {
|
||||
Log.e(TAG, "JSON conversion failed: ${e.message}")
|
||||
}
|
||||
@@ -182,7 +189,11 @@ class AccountManager(private val reactContext: ReactApplicationContext) : ReactC
|
||||
Log.d(TAG, "loginWithKeycard")
|
||||
utils.migrateKeyStoreDir(accountData, password)
|
||||
val result = Statusgo.loginWithKeycard(accountData, password, chatKey, nodeConfigJSON)
|
||||
utils.handleStatusGoResponse(result, "loginWithKeycard")
|
||||
if (result.startsWith("{\"error\":\"\"")) {
|
||||
Log.d(TAG, "LoginWithKeycard result: $result")
|
||||
} else {
|
||||
Log.e(TAG, "LoginWithKeycard failed: $result")
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@@ -190,17 +201,22 @@ class AccountManager(private val reactContext: ReactApplicationContext) : ReactC
|
||||
Log.d(TAG, "loginWithConfig")
|
||||
utils.migrateKeyStoreDir(accountData, password)
|
||||
val result = Statusgo.loginWithConfig(accountData, password, configJSON)
|
||||
utils.handleStatusGoResponse(result, "loginWithConfig")
|
||||
if (result.startsWith("{\"error\":\"\"")) {
|
||||
Log.d(TAG, "LoginWithConfig result: $result")
|
||||
} else {
|
||||
Log.e(TAG, "LoginWithConfig failed: $result")
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun loginAccount(request: String) {
|
||||
Log.d(TAG, "loginAccount")
|
||||
StatusBackendClient.executeStatusGoRequest(
|
||||
endpoint = "LoginAccount",
|
||||
requestBody = request,
|
||||
statusgoFunction = { Statusgo.loginAccount(request) }
|
||||
)
|
||||
val result = Statusgo.loginAccount(request)
|
||||
if (result.startsWith("{\"error\":\"\"")) {
|
||||
Log.d(TAG, "loginAccount result: $result")
|
||||
} else {
|
||||
Log.e(TAG, "loginAccount failed: $result")
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@@ -208,31 +224,16 @@ class AccountManager(private val reactContext: ReactApplicationContext) : ReactC
|
||||
val absRootDirPath = utils.getNoBackupDirectory()
|
||||
val newKeystoreDir = utils.pathCombine(absRootDirPath, "keystore")
|
||||
|
||||
val jsonParams = JSONObject()
|
||||
jsonParams.put("keyStoreDir", newKeystoreDir)
|
||||
jsonParams.put("address", address)
|
||||
jsonParams.put("password", password)
|
||||
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "VerifyAccountPasswordV2",
|
||||
requestBody = jsonParams.toString(),
|
||||
statusgoFunction = { Statusgo.verifyAccountPasswordV2(jsonParams.toString()) },
|
||||
utils.executeRunnableStatusGoMethod(
|
||||
{ Statusgo.verifyAccountPassword(newKeystoreDir, address, password) },
|
||||
callback
|
||||
)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun verifyDatabasePassword(keyUID: String, password: String, callback: Callback) {
|
||||
val jsonParams = JSONObject()
|
||||
jsonParams.put("keyUID", keyUID)
|
||||
jsonParams.put("password", password)
|
||||
|
||||
val jsonString = jsonParams.toString()
|
||||
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "VerifyDatabasePasswordV2",
|
||||
requestBody = jsonString,
|
||||
statusgoFunction = { Statusgo.verifyDatabasePasswordV2(jsonString) },
|
||||
utils.executeRunnableStatusGoMethod(
|
||||
{ Statusgo.verifyDatabasePassword(keyUID, password) },
|
||||
callback
|
||||
)
|
||||
}
|
||||
@@ -248,136 +249,74 @@ class AccountManager(private val reactContext: ReactApplicationContext) : ReactC
|
||||
@ReactMethod
|
||||
private fun initializeApplication(request: String, callback: Callback) {
|
||||
Log.d(TAG, "initializeApplication")
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"InitializeApplication",
|
||||
request,
|
||||
{ Statusgo.initializeApplication(request) },
|
||||
callback
|
||||
)
|
||||
Log.d(TAG, "[Initializing application $request")
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.initializeApplication(request) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
private fun acceptTerms(callback: Callback) {
|
||||
Log.d(TAG, "acceptTerms")
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"AcceptTerms",
|
||||
"",
|
||||
{ Statusgo.acceptTerms() },
|
||||
callback
|
||||
)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun logout() {
|
||||
Log.d(TAG, "logout")
|
||||
StatusBackendClient.executeStatusGoRequest(
|
||||
endpoint = "Logout",
|
||||
requestBody = "",
|
||||
statusgoFunction = { Statusgo.logout() }
|
||||
)
|
||||
val runnable = Runnable {
|
||||
val result = Statusgo.logout()
|
||||
if (result.startsWith("{\"error\":\"\"")) {
|
||||
Log.d(TAG, "Logout result: $result")
|
||||
} else {
|
||||
Log.e(TAG, "Logout failed: $result")
|
||||
}
|
||||
}
|
||||
StatusThreadPoolExecutor.getInstance().execute(runnable)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun multiAccountStoreAccount(json: String, callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "MultiAccountStoreAccount",
|
||||
requestBody = json,
|
||||
statusgoFunction = { Statusgo.multiAccountStoreAccount(json) },
|
||||
callback = callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.multiAccountStoreAccount(json) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun multiAccountLoadAccount(json: String, callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "MultiAccountLoadAccount",
|
||||
requestBody = json,
|
||||
statusgoFunction = { Statusgo.multiAccountLoadAccount(json) },
|
||||
callback = callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.multiAccountLoadAccount(json) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun multiAccountDeriveAddresses(json: String, callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "MultiAccountDeriveAddresses",
|
||||
requestBody = json,
|
||||
statusgoFunction = { Statusgo.multiAccountDeriveAddresses(json) },
|
||||
callback = callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.multiAccountDeriveAddresses(json) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun multiAccountGenerateAndDeriveAddresses(json: String, callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "MultiAccountGenerateAndDeriveAddresses",
|
||||
requestBody = json,
|
||||
statusgoFunction = { Statusgo.multiAccountGenerateAndDeriveAddresses(json) },
|
||||
callback = callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.multiAccountGenerateAndDeriveAddresses(json) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun multiAccountStoreDerived(json: String, callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "MultiAccountStoreDerivedAccounts",
|
||||
requestBody = json,
|
||||
statusgoFunction = { Statusgo.multiAccountStoreDerivedAccounts(json) },
|
||||
callback = callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.multiAccountStoreDerivedAccounts(json) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun multiAccountImportMnemonic(json: String, callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "MultiAccountImportMnemonic",
|
||||
requestBody = json,
|
||||
statusgoFunction = { Statusgo.multiAccountImportMnemonic(json) },
|
||||
callback = callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.multiAccountImportMnemonic(json) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun multiAccountImportPrivateKey(json: String, callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "MultiAccountImportPrivateKey",
|
||||
requestBody = json,
|
||||
statusgoFunction = { Statusgo.multiAccountImportPrivateKey(json) },
|
||||
callback = callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.multiAccountImportPrivateKey(json) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun deleteMultiaccount(keyUID: String, callback: Callback) {
|
||||
val keyStoreDir = utils.getKeyStorePath(keyUID)
|
||||
val params = JSONObject().apply {
|
||||
put("keyUID", keyUID)
|
||||
put("keyStoreDir", keyStoreDir)
|
||||
}
|
||||
val jsonString = params.toString()
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "DeleteMultiaccountV2",
|
||||
requestBody = jsonString,
|
||||
statusgoFunction = { Statusgo.deleteMultiaccountV2(jsonString) },
|
||||
callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.deleteMultiaccount(keyUID, keyStoreDir) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun getRandomMnemonic(callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"GetRandomMnemonic",
|
||||
"",
|
||||
{ Statusgo.getRandomMnemonic() },
|
||||
callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.getRandomMnemonic() }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun createAccountFromMnemonicAndDeriveAccountsForPaths(mnemonic: String, callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"CreateAccountFromMnemonicAndDeriveAccountsForPaths",
|
||||
mnemonic,
|
||||
utils.executeRunnableStatusGoMethod(
|
||||
{ Statusgo.createAccountFromMnemonicAndDeriveAccountsForPaths(mnemonic) },
|
||||
callback
|
||||
)
|
||||
@@ -385,12 +324,7 @@ class AccountManager(private val reactContext: ReactApplicationContext) : ReactC
|
||||
|
||||
@ReactMethod
|
||||
fun createAccountFromPrivateKey(json: String, callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "CreateAccountFromPrivateKey",
|
||||
requestBody = json,
|
||||
statusgoFunction = { Statusgo.createAccountFromPrivateKey(json) },
|
||||
callback = callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.createAccountFromPrivateKey(json) }, callback)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
+11
-48
@@ -9,8 +9,6 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule
|
||||
import com.facebook.react.bridge.ReactMethod
|
||||
import statusgo.Statusgo
|
||||
import java.io.File
|
||||
import org.json.JSONObject
|
||||
import org.json.JSONException
|
||||
|
||||
class DatabaseManager(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
|
||||
|
||||
@@ -19,43 +17,22 @@ class DatabaseManager(private val reactContext: ReactApplicationContext) : React
|
||||
override fun getName() = "DatabaseManager"
|
||||
|
||||
private fun getExportDBFile(): File {
|
||||
StatusBackendClient.getInstance()?.let {
|
||||
if (it.serverEnabled) {
|
||||
return File(it.rootDataDir, exportDBFileName)
|
||||
}
|
||||
}
|
||||
val pubDirectory = reactContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
|
||||
return File(pubDirectory, exportDBFileName)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun exportUnencryptedDatabase(accountData: String, password: String, callback: Callback) {
|
||||
Log.d(TAG, "exportUnencryptedDatabase")
|
||||
Log.d(TAG, "login")
|
||||
|
||||
val newFile = getExportDBFile()
|
||||
|
||||
utils.migrateKeyStoreDir(accountData, password)
|
||||
|
||||
try {
|
||||
val accountJson = JSONObject(accountData)
|
||||
|
||||
val params = JSONObject().apply {
|
||||
put("account", accountJson)
|
||||
put("password", password)
|
||||
put("databasePath", newFile.absolutePath)
|
||||
}
|
||||
|
||||
val jsonParams = params.toString()
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "ExportUnencryptedDatabaseV2",
|
||||
requestBody = jsonParams,
|
||||
statusgoFunction = { Statusgo.exportUnencryptedDatabaseV2(jsonParams) },
|
||||
callback = null
|
||||
)
|
||||
callback.invoke(newFile.absolutePath)
|
||||
|
||||
} catch (e: JSONException) {
|
||||
Log.e(TAG, "Error parsing account data: ${e.message}")
|
||||
val result = Statusgo.exportUnencryptedDatabase(accountData, password, newFile.absolutePath)
|
||||
if (result.startsWith("{\"error\":\"\"")) {
|
||||
Log.d(TAG, "Login result: $result")
|
||||
} else {
|
||||
Log.e(TAG, "Login failed: $result")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,25 +43,11 @@ class DatabaseManager(private val reactContext: ReactApplicationContext) : React
|
||||
val newFile = getExportDBFile()
|
||||
|
||||
utils.migrateKeyStoreDir(accountData, password)
|
||||
|
||||
try {
|
||||
val accountJson = JSONObject(accountData)
|
||||
|
||||
val params = JSONObject().apply {
|
||||
put("account", accountJson)
|
||||
put("password", password)
|
||||
put("databasePath", newFile.absolutePath)
|
||||
}
|
||||
|
||||
val jsonParams = params.toString()
|
||||
|
||||
StatusBackendClient.executeStatusGoRequest(
|
||||
endpoint = "ImportUnencryptedDatabaseV2",
|
||||
requestBody = jsonParams,
|
||||
statusgoFunction = { Statusgo.importUnencryptedDatabaseV2(jsonParams) }
|
||||
)
|
||||
} catch (e: JSONException) {
|
||||
Log.e(TAG, "Error parsing account data: ${e.message}")
|
||||
val result = Statusgo.importUnencryptedDatabase(accountData, password, newFile.absolutePath)
|
||||
if (result.startsWith("{\"error\":\"\"")) {
|
||||
Log.d(TAG, "import result: $result")
|
||||
} else {
|
||||
Log.e(TAG, "import failed: $result")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+20
-134
@@ -7,7 +7,6 @@ import com.facebook.react.bridge.Callback;
|
||||
import android.util.Log;
|
||||
import statusgo.Statusgo;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import java.util.function.Function;
|
||||
import android.app.Activity;
|
||||
import android.view.WindowManager;
|
||||
@@ -40,151 +39,67 @@ public class EncryptionUtils extends ReactContextBaseJavaModule {
|
||||
final String commonKeydir = this.utils.pathCombine(this.utils.getNoBackupDirectory(), "/keystore");
|
||||
final String keydir = this.utils.pathCombine(commonKeydir, keyUID);
|
||||
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"InitKeystore",
|
||||
keydir,
|
||||
() -> Statusgo.initKeystore(keydir),
|
||||
callback
|
||||
);
|
||||
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.initKeystore(keydir), callback);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void reEncryptDbAndKeystore(final String keyUID, final String password, final String newPassword, final Callback callback) throws JSONException {
|
||||
JSONObject params = new JSONObject();
|
||||
params.put("keyUID", keyUID);
|
||||
params.put("oldPassword", password);
|
||||
params.put("newPassword", newPassword);
|
||||
String jsonParams = params.toString();
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"ChangeDatabasePasswordV2",
|
||||
jsonParams,
|
||||
() -> Statusgo.changeDatabasePasswordV2(jsonParams),
|
||||
callback
|
||||
);
|
||||
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.changeDatabasePassword(keyUID, password, newPassword), callback);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void convertToKeycardAccount(final String keyUID, final String accountData, final String options, final String keycardUID, final String password,
|
||||
final String newPassword, final Callback callback) throws JSONException {
|
||||
final String keyStoreDir = this.utils.getKeyStorePath(keyUID);
|
||||
JSONObject params = new JSONObject();
|
||||
params.put("keyUID", keyUID);
|
||||
params.put("account", new JSONObject(accountData));
|
||||
params.put("settings", new JSONObject(options));
|
||||
params.put("keycardUID", keycardUID);
|
||||
params.put("oldPassword", password);
|
||||
params.put("newPassword", newPassword);
|
||||
final String jsonParams = params.toString();
|
||||
StatusBackendClient.executeStatusGoRequest(
|
||||
"InitKeystore",
|
||||
keyStoreDir,
|
||||
() -> Statusgo.initKeystore(keyStoreDir)
|
||||
);
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"ConvertToKeycardAccountV2",
|
||||
jsonParams,
|
||||
() -> Statusgo.convertToKeycardAccountV2(jsonParams),
|
||||
callback
|
||||
);
|
||||
this.utils.executeRunnableStatusGoMethod(() -> {
|
||||
Statusgo.initKeystore(keyStoreDir);
|
||||
return Statusgo.convertToKeycardAccount(accountData, options, keycardUID, password, newPassword);
|
||||
}, callback);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String encodeTransfer(final String to, final String value) {
|
||||
try {
|
||||
JSONObject params = new JSONObject();
|
||||
params.put("to", to);
|
||||
params.put("value", value);
|
||||
String jsonParams = params.toString();
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"EncodeTransferV2",
|
||||
jsonParams,
|
||||
() -> Statusgo.encodeTransferV2(jsonParams)
|
||||
);
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "Error creating JSON for encodeTransfer: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
return Statusgo.encodeTransfer(to, value);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String encodeFunctionCall(final String method, final String paramsJSON) {
|
||||
try {
|
||||
JSONObject params = new JSONObject();
|
||||
params.put("method", method);
|
||||
params.put("paramsJSON", new JSONObject(paramsJSON));
|
||||
String jsonString = params.toString();
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"EncodeFunctionCallV2",
|
||||
jsonString,
|
||||
() -> Statusgo.encodeFunctionCallV2(jsonString)
|
||||
);
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "Error creating JSON for encodeFunctionCall: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
return Statusgo.encodeFunctionCall(method, paramsJSON);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String decodeParameters(final String decodeParamJSON) {
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"DecodeParameters",
|
||||
decodeParamJSON,
|
||||
() -> Statusgo.decodeParameters(decodeParamJSON)
|
||||
);
|
||||
return Statusgo.decodeParameters(decodeParamJSON);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String hexToNumber(final String hex) {
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"HexToNumber",
|
||||
hex,
|
||||
() -> Statusgo.hexToNumber(hex)
|
||||
);
|
||||
return Statusgo.hexToNumber(hex);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String numberToHex(final String numString) {
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"NumberToHex",
|
||||
numString,
|
||||
() -> Statusgo.numberToHex(numString)
|
||||
);
|
||||
return Statusgo.numberToHex(numString);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String sha3(final String str) {
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"Sha3",
|
||||
str,
|
||||
() -> Statusgo.sha3(str)
|
||||
);
|
||||
return Statusgo.sha3(str);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String utf8ToHex(final String str) {
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"Utf8ToHex",
|
||||
str,
|
||||
() -> Statusgo.utf8ToHex(str)
|
||||
);
|
||||
return Statusgo.utf8ToHex(str);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String hexToUtf8(final String str) {
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"HexToUtf8",
|
||||
str,
|
||||
() -> Statusgo.hexToUtf8(str)
|
||||
);
|
||||
return Statusgo.hexToUtf8(str);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String serializeLegacyKey(final String publicKey) {
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
"SerializeLegacyKey",
|
||||
publicKey,
|
||||
() -> Statusgo.serializeLegacyKey(publicKey)
|
||||
);
|
||||
return Statusgo.serializeLegacyKey(publicKey);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@@ -215,46 +130,22 @@ public class EncryptionUtils extends ReactContextBaseJavaModule {
|
||||
|
||||
@ReactMethod
|
||||
public void hashTransaction(final String txArgsJSON, final Callback callback) throws JSONException {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"HashTransaction",
|
||||
txArgsJSON,
|
||||
() -> Statusgo.hashTransaction(txArgsJSON),
|
||||
callback
|
||||
);
|
||||
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.hashTransaction(txArgsJSON), callback);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void hashMessage(final String message, final Callback callback) throws JSONException {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"HashMessage",
|
||||
message,
|
||||
() -> Statusgo.hashMessage(message),
|
||||
callback
|
||||
);
|
||||
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.hashMessage(message), callback);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void multiformatDeserializePublicKey(final String multiCodecKey, final String base58btc, final Callback callback) throws JSONException {
|
||||
JSONObject params = new JSONObject();
|
||||
params.put("key", multiCodecKey);
|
||||
params.put("outBase", base58btc);
|
||||
String jsonParams = params.toString();
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"MultiformatDeserializePublicKeyV2",
|
||||
jsonParams,
|
||||
() -> Statusgo.multiformatDeserializePublicKeyV2(jsonParams),
|
||||
callback
|
||||
);
|
||||
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.multiformatDeserializePublicKey(multiCodecKey,base58btc), callback);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void deserializeAndCompressKey(final String desktopKey, final Callback callback) throws JSONException {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"DeserializeAndCompressKey",
|
||||
desktopKey,
|
||||
() -> Statusgo.deserializeAndCompressKey(desktopKey),
|
||||
callback
|
||||
);
|
||||
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.deserializeAndCompressKey(desktopKey), callback);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@@ -269,12 +160,7 @@ public class EncryptionUtils extends ReactContextBaseJavaModule {
|
||||
|
||||
@ReactMethod
|
||||
public void signMessage(final String rpcParams, final Callback callback) throws JSONException {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
"SignMessage",
|
||||
rpcParams,
|
||||
() -> Statusgo.signMessage(rpcParams),
|
||||
callback
|
||||
);
|
||||
this.utils.executeRunnableStatusGoMethod(() -> Statusgo.signMessage(rpcParams), callback);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
|
||||
+1
-6
@@ -206,12 +206,7 @@ class LogManager(private val reactContext: ReactApplicationContext) : ReactConte
|
||||
put("LogRequestFile", getRequestLogFile().absolutePath)
|
||||
}
|
||||
val config = jsonConfig.toString()
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "InitLogging",
|
||||
requestBody = config,
|
||||
statusgoFunction = { Statusgo.initLogging(config) },
|
||||
callback = callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.initLogging(config) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
|
||||
+20
-73
@@ -16,12 +16,7 @@ class NetworkManager(private val reactContext: ReactApplicationContext) : ReactC
|
||||
|
||||
@ReactMethod
|
||||
fun startSearchForLocalPairingPeers(callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "StartSearchForLocalPairingPeers",
|
||||
requestBody = "",
|
||||
statusgoFunction = { Statusgo.startSearchForLocalPairingPeers() },
|
||||
callback = callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.startSearchForLocalPairingPeers() }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@@ -31,85 +26,48 @@ class NetworkManager(private val reactContext: ReactApplicationContext) : ReactC
|
||||
val keyUID = senderConfig.getString("keyUID")
|
||||
val keyStorePath = utils.getKeyStorePath(keyUID)
|
||||
senderConfig.put("keystorePath", keyStorePath)
|
||||
val jsonString = jsonConfig.toString()
|
||||
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "GetConnectionStringForBootstrappingAnotherDevice",
|
||||
requestBody = jsonString,
|
||||
statusgoFunction = { Statusgo.getConnectionStringForBootstrappingAnotherDevice(jsonString) },
|
||||
utils.executeRunnableStatusGoMethod(
|
||||
{ Statusgo.getConnectionStringForBootstrappingAnotherDevice(jsonConfig.toString()) },
|
||||
callback
|
||||
)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun inputConnectionStringForBootstrapping(connectionString: String, configJSON: String, callback: Callback) {
|
||||
val receiverClientConfig = JSONObject(configJSON)
|
||||
val params = JSONObject().apply {
|
||||
put("connectionString", connectionString)
|
||||
put("receiverClientConfig", receiverClientConfig)
|
||||
}
|
||||
val jsonString = params.toString()
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "InputConnectionStringForBootstrappingV2",
|
||||
requestBody = jsonString,
|
||||
statusgoFunction = { Statusgo.inputConnectionStringForBootstrappingV2(jsonString) },
|
||||
val jsonConfig = JSONObject(configJSON)
|
||||
utils.executeRunnableStatusGoMethod(
|
||||
{ Statusgo.inputConnectionStringForBootstrapping(connectionString, jsonConfig.toString()) },
|
||||
callback
|
||||
)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun sendTransactionWithSignature(txArgsJSON: String, signature: String, callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "SendTransactionWithSignature",
|
||||
requestBody = txArgsJSON,
|
||||
statusgoFunction = { Statusgo.sendTransactionWithSignature(txArgsJSON, signature) },
|
||||
utils.executeRunnableStatusGoMethod(
|
||||
{ Statusgo.sendTransactionWithSignature(txArgsJSON, signature) },
|
||||
callback
|
||||
)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun sendTransaction(txArgsJSON: String, password: String, callback: Callback) {
|
||||
val jsonParams = JSONObject().apply {
|
||||
put("txArgs", JSONObject(txArgsJSON))
|
||||
put("password", password)
|
||||
}
|
||||
val jsonString = jsonParams.toString()
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "SendTransactionV2",
|
||||
requestBody = jsonString,
|
||||
statusgoFunction = { Statusgo.sendTransactionV2(jsonString) },
|
||||
callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.sendTransaction(txArgsJSON, password) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun callRPC(payload: String, callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "CallRPC",
|
||||
requestBody = payload,
|
||||
statusgoFunction = { Statusgo.callRPC(payload) },
|
||||
callback = callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.callRPC(payload) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun callPrivateRPC(payload: String, callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "CallPrivateRPC",
|
||||
requestBody = payload,
|
||||
statusgoFunction = { Statusgo.callPrivateRPC(payload) },
|
||||
callback = callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.callPrivateRPC(payload) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun recover(rpcParams: String, callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "Recover",
|
||||
requestBody = rpcParams,
|
||||
statusgoFunction = { Statusgo.recover(rpcParams) },
|
||||
callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.recover(rpcParams) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@@ -119,33 +77,22 @@ class NetworkManager(private val reactContext: ReactApplicationContext) : ReactC
|
||||
val keyUID = senderConfig.getString("loggedInKeyUid")
|
||||
val keyStorePath = utils.getKeyStorePath(keyUID)
|
||||
senderConfig.put("keystorePath", keyStorePath)
|
||||
val jsonString = jsonConfig.toString()
|
||||
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "GetConnectionStringForExportingKeypairsKeystores",
|
||||
requestBody = jsonString,
|
||||
statusgoFunction = { Statusgo.getConnectionStringForExportingKeypairsKeystores(jsonString) },
|
||||
callback = callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod(
|
||||
{ Statusgo.getConnectionStringForExportingKeypairsKeystores(jsonConfig.toString()) },
|
||||
callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun inputConnectionStringForImportingKeypairsKeystores(connectionString: String, configJSON: String, callback: Callback) {
|
||||
val keystoreFilesReceiverClientConfig = JSONObject(configJSON)
|
||||
val receiverConfig = keystoreFilesReceiverClientConfig.getJSONObject("receiverConfig")
|
||||
val jsonConfig = JSONObject(configJSON)
|
||||
val receiverConfig = jsonConfig.getJSONObject("receiverConfig")
|
||||
val keyStorePath = utils.pathCombine(utils.getNoBackupDirectory(), "/keystore")
|
||||
receiverConfig.put("keystorePath", keyStorePath)
|
||||
|
||||
val params = JSONObject().apply {
|
||||
put("connectionString", connectionString)
|
||||
put("keystoreFilesReceiverClientConfig", keystoreFilesReceiverClientConfig)
|
||||
}
|
||||
val jsonString = params.toString()
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "InputConnectionStringForImportingKeypairsKeystoresV2",
|
||||
requestBody = jsonString,
|
||||
statusgoFunction = { Statusgo.inputConnectionStringForImportingKeypairsKeystoresV2(jsonString) },
|
||||
callback = callback
|
||||
utils.executeRunnableStatusGoMethod(
|
||||
{ Statusgo.inputConnectionStringForImportingKeypairsKeystores(connectionString, jsonConfig.toString()) },
|
||||
callback
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
-231
@@ -1,231 +0,0 @@
|
||||
package im.status.ethereum.module
|
||||
|
||||
import android.util.Log
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.Response
|
||||
import okhttp3.WebSocket
|
||||
import okhttp3.WebSocketListener
|
||||
import com.facebook.react.bridge.ReactApplicationContext
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
||||
import com.facebook.react.bridge.ReactMethod
|
||||
import com.facebook.react.bridge.Callback
|
||||
import java.net.SocketException
|
||||
import java.net.SocketTimeoutException
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class StatusBackendClient(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
|
||||
companion object {
|
||||
private const val TAG = "StatusBackendClient"
|
||||
private val JSON = "application/json; charset=utf-8".toMediaType()
|
||||
private const val TIMEOUT_SECONDS = 30L
|
||||
@Volatile private var instance: StatusBackendClient? = null
|
||||
private lateinit var utils: Utils
|
||||
|
||||
private val initializationCallbacks = mutableListOf<() -> Unit>()
|
||||
|
||||
fun getInstance(): StatusBackendClient? = instance
|
||||
|
||||
@JvmStatic
|
||||
fun executeStatusGoRequest(
|
||||
endpoint: String,
|
||||
requestBody: String,
|
||||
statusgoFunction: () -> String
|
||||
) {
|
||||
val statusBackendClient = getInstance()
|
||||
if (statusBackendClient?.serverEnabled == true) {
|
||||
val result = statusBackendClient.request(endpoint, requestBody)
|
||||
result.onSuccess { response ->
|
||||
utils.handleStatusGoResponse(response, endpoint)
|
||||
}.onFailure { error ->
|
||||
Log.e(TAG, "request to $endpoint failed", error)
|
||||
}
|
||||
} else {
|
||||
val result = statusgoFunction()
|
||||
utils.handleStatusGoResponse(result, endpoint)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun executeStatusGoRequestWithCallback(
|
||||
endpoint: String,
|
||||
requestBody: String,
|
||||
statusgoFunction: () -> String,
|
||||
callback: Callback?
|
||||
) {
|
||||
val statusBackendClient = getInstance()
|
||||
if (statusBackendClient?.serverEnabled == true) {
|
||||
val runnable = Runnable {
|
||||
val result = statusBackendClient.request(endpoint, requestBody)
|
||||
result.onSuccess { response ->
|
||||
callback?.invoke(response)
|
||||
}.onFailure { error ->
|
||||
Log.e(TAG, "request to $endpoint failed", error)
|
||||
callback?.invoke(false)
|
||||
}
|
||||
}
|
||||
StatusThreadPoolExecutor.getInstance().execute(runnable)
|
||||
} else {
|
||||
utils.executeRunnableStatusGoMethod(statusgoFunction, callback)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun executeStatusGoRequestWithResult(
|
||||
endpoint: String,
|
||||
requestBody: String,
|
||||
statusgoFunction: () -> String
|
||||
): String {
|
||||
val statusBackendClient = getInstance()
|
||||
return if (statusBackendClient?.serverEnabled == true) {
|
||||
val result = statusBackendClient.request(endpoint, requestBody)
|
||||
result.getOrElse { error ->
|
||||
Log.e(TAG, "request to $endpoint failed", error)
|
||||
""
|
||||
}
|
||||
} else {
|
||||
if (endpoint == "ImageServerTLSCert") {
|
||||
Log.i(TAG, "ImageServerTLSCert endpoint called without server enabled - " +
|
||||
"stacktrace: ${Thread.currentThread().stackTrace.joinToString("\n")}")
|
||||
}
|
||||
statusgoFunction()
|
||||
}
|
||||
}
|
||||
|
||||
fun addInitializationCallback(callback: () -> Unit) {
|
||||
if (instance?.initialized == true) {
|
||||
Log.d(TAG, "Executing initialization callback immediately")
|
||||
callback()
|
||||
} else {
|
||||
Log.d(TAG, "Adding initialization callback")
|
||||
initializationCallbacks.add(callback)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
instance = this
|
||||
utils = Utils(reactContext)
|
||||
}
|
||||
|
||||
override fun getName(): String = "StatusBackendClient"
|
||||
|
||||
private val httpClient = OkHttpClient.Builder()
|
||||
.connectTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
||||
.writeTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
||||
.readTimeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
||||
.retryOnConnectionFailure(true)
|
||||
.build()
|
||||
|
||||
private val wsClient = OkHttpClient.Builder()
|
||||
.retryOnConnectionFailure(true)
|
||||
.build()
|
||||
|
||||
private var webSocket: WebSocket? = null
|
||||
|
||||
@Volatile var serverEnabled = true
|
||||
@Volatile private var statusGoEndpoint: String? = null
|
||||
@Volatile private var signalEndpoint: String? = null
|
||||
@Volatile var rootDataDir: String? = null
|
||||
@Volatile var initialized = false
|
||||
|
||||
@ReactMethod
|
||||
fun configStatusBackendServer(
|
||||
serverEnabled: Boolean,
|
||||
statusGoEndpoint: String,
|
||||
signalEndpoint: String,
|
||||
rootDataDir: String
|
||||
) {
|
||||
configure(serverEnabled, statusGoEndpoint, signalEndpoint, rootDataDir)
|
||||
this.initialized = true
|
||||
// Execute callbacks
|
||||
initializationCallbacks.forEach { it() }
|
||||
initializationCallbacks.clear()
|
||||
Log.d(TAG, "StatusBackendClient initialized")
|
||||
}
|
||||
|
||||
private fun configure(
|
||||
serverEnabled: Boolean,
|
||||
statusGoEndpoint: String,
|
||||
signalEndpoint: String,
|
||||
rootDataDir: String
|
||||
) {
|
||||
Log.d(TAG, "configure: serverEnabled=$serverEnabled, statusGoEndpoint=$statusGoEndpoint, " +
|
||||
"signalEndpoint=$signalEndpoint, rootDataDir=$rootDataDir")
|
||||
|
||||
this.serverEnabled = serverEnabled
|
||||
if (serverEnabled) {
|
||||
this.statusGoEndpoint = statusGoEndpoint
|
||||
this.signalEndpoint = signalEndpoint
|
||||
this.rootDataDir = rootDataDir
|
||||
connectWebSocket()
|
||||
} else {
|
||||
disconnectWebSocket()
|
||||
this.statusGoEndpoint = null
|
||||
this.signalEndpoint = null
|
||||
this.rootDataDir = null
|
||||
}
|
||||
}
|
||||
|
||||
private fun connectWebSocket() {
|
||||
if (!serverEnabled || signalEndpoint == null) {
|
||||
return
|
||||
}
|
||||
|
||||
val request = Request.Builder()
|
||||
.url("$signalEndpoint")
|
||||
.build()
|
||||
|
||||
webSocket = wsClient.newWebSocket(request, object : WebSocketListener() {
|
||||
override fun onMessage(webSocket: WebSocket, text: String) {
|
||||
StatusModule.getInstance()?.handleSignal(text)
|
||||
}
|
||||
|
||||
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
|
||||
Log.e(TAG, "WebSocket error: ${t.message}")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun disconnectWebSocket() {
|
||||
webSocket?.cancel()
|
||||
webSocket = null
|
||||
}
|
||||
|
||||
fun request(endpoint: String, body: String): Result<String> {
|
||||
if (!serverEnabled || statusGoEndpoint == null) {
|
||||
return Result.failure(IllegalStateException("Status backend server is not enabled"))
|
||||
}
|
||||
|
||||
val fullUrl = "$statusGoEndpoint$endpoint"
|
||||
|
||||
return try {
|
||||
val request = Request.Builder()
|
||||
.url(fullUrl)
|
||||
.post(body.toRequestBody(JSON))
|
||||
.build()
|
||||
|
||||
httpClient.newCall(request).execute().use { response ->
|
||||
val responseBody = response.body?.string() ?: ""
|
||||
|
||||
if (response.isSuccessful) {
|
||||
Log.d(TAG, "Request to $endpoint succeeded: $responseBody")
|
||||
Result.success(responseBody)
|
||||
} else {
|
||||
val errorMsg = "Request failed with code ${response.code}: $responseBody"
|
||||
Log.e(TAG, "Request to $endpoint failed: $errorMsg")
|
||||
Result.failure(Exception(errorMsg))
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
when (e) {
|
||||
is SocketTimeoutException -> Log.e(TAG, "Request to $endpoint timed out", e)
|
||||
is SocketException -> Log.e(TAG, "Socket error for $endpoint", e)
|
||||
else -> Log.e(TAG, "Request to $endpoint failed with exception", e)
|
||||
}
|
||||
Result.failure(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
-67
@@ -9,17 +9,12 @@ import statusgo.SignalHandler
|
||||
import statusgo.Statusgo
|
||||
import org.json.JSONException
|
||||
import android.view.WindowManager
|
||||
import org.json.JSONObject
|
||||
|
||||
class StatusModule(private val reactContext: ReactApplicationContext, private val rootedDevice: Boolean) : ReactContextBaseJavaModule(reactContext), LifecycleEventListener, SignalHandler {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "StatusModule"
|
||||
private var module: StatusModule? = null
|
||||
|
||||
fun getInstance(): StatusModule? {
|
||||
return module
|
||||
}
|
||||
}
|
||||
|
||||
private val utils: Utils = Utils(reactContext)
|
||||
@@ -61,97 +56,45 @@ class StatusModule(private val reactContext: ReactApplicationContext, private va
|
||||
@ReactMethod
|
||||
fun connectionChange(type: String, isExpensive: Boolean) {
|
||||
Log.d(TAG, "ConnectionChange: $type, is expensive $isExpensive")
|
||||
val params = JSONObject().apply {
|
||||
put("type", type)
|
||||
put("expensive", isExpensive)
|
||||
}
|
||||
|
||||
val jsonString = params.toString()
|
||||
StatusBackendClient.executeStatusGoRequest(
|
||||
endpoint = "ConnectionChangeV2",
|
||||
requestBody = jsonString,
|
||||
statusgoFunction = { Statusgo.connectionChangeV2(jsonString) }
|
||||
)
|
||||
Statusgo.connectionChange(type, if (isExpensive) 1 else 0)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun appStateChange(state: String) {
|
||||
Log.d(TAG, "AppStateChange: $state")
|
||||
val params = JSONObject().apply {
|
||||
put("state", state)
|
||||
}
|
||||
val jsonString = params.toString()
|
||||
StatusBackendClient.executeStatusGoRequest(
|
||||
endpoint = "AppStateChangeV2",
|
||||
requestBody = jsonString,
|
||||
statusgoFunction = { Statusgo.appStateChangeV2(jsonString) }
|
||||
)
|
||||
fun appStateChange(type: String) {
|
||||
Log.d(TAG, "AppStateChange: $type")
|
||||
Statusgo.appStateChange(type)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun startLocalNotifications() {
|
||||
Log.d(TAG, "startLocalNotifications")
|
||||
StatusBackendClient.executeStatusGoRequest(
|
||||
endpoint = "StartLocalNotifications",
|
||||
requestBody = "",
|
||||
statusgoFunction = { Statusgo.startLocalNotifications() }
|
||||
)
|
||||
Statusgo.startLocalNotifications()
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun getNodeConfig(callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "GetNodeConfig",
|
||||
requestBody = "",
|
||||
statusgoFunction = { Statusgo.getNodeConfig() },
|
||||
callback = callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.getNodeConfig() }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun addCentralizedMetric(request: String, callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "AddCentralizedMetric",
|
||||
requestBody = request,
|
||||
statusgoFunction = { Statusgo.addCentralizedMetric(request) },
|
||||
callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.addCentralizedMetric(request) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun toggleCentralizedMetrics(request: String, callback: Callback) {
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "ToggleCentralizedMetrics",
|
||||
requestBody = request,
|
||||
statusgoFunction = { Statusgo.toggleCentralizedMetrics(request) },
|
||||
callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.toggleCentralizedMetrics(request) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun deleteImportedKey(keyUID: String, address: String, password: String, callback: Callback) {
|
||||
val keyStoreDir = utils.getKeyStorePath(keyUID)
|
||||
val params = JSONObject().apply {
|
||||
put("address", address)
|
||||
put("password", password)
|
||||
put("keyStoreDir", keyStoreDir)
|
||||
}
|
||||
val jsonString = params.toString()
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "DeleteImportedKeyV2",
|
||||
requestBody = jsonString,
|
||||
statusgoFunction = { Statusgo.deleteImportedKeyV2(jsonString) },
|
||||
callback
|
||||
)
|
||||
utils.executeRunnableStatusGoMethod({ Statusgo.deleteImportedKey(address, password, keyStoreDir) }, callback)
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
fun fleets(): String {
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
endpoint = "Fleets",
|
||||
requestBody = "",
|
||||
statusgoFunction = { Statusgo.fleets() }
|
||||
)
|
||||
return Statusgo.fleets()
|
||||
}
|
||||
|
||||
override fun getConstants(): Map<String, Any>? {
|
||||
|
||||
+1
-7
@@ -9,12 +9,7 @@ import statusgo.Statusgo
|
||||
class StatusPackage(private val rootedDevice: Boolean) : ReactPackage {
|
||||
|
||||
companion object {
|
||||
fun getImageTLSCert(): String =
|
||||
StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
endpoint = "ImageServerTLSCert",
|
||||
requestBody = "",
|
||||
statusgoFunction = { Statusgo.imageServerTLSCert() }
|
||||
)
|
||||
fun getImageTLSCert(): String = Statusgo.imageServerTLSCert()
|
||||
}
|
||||
|
||||
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
||||
@@ -31,7 +26,6 @@ class StatusPackage(private val rootedDevice: Boolean) : ReactPackage {
|
||||
add(NetworkManager(reactContext))
|
||||
add(MailManager(reactContext))
|
||||
add(RNSelectableTextInputModule(reactContext))
|
||||
add(StatusBackendClient(reactContext))
|
||||
}
|
||||
|
||||
return modules
|
||||
|
||||
+10
-67
@@ -25,11 +25,6 @@ class Utils(private val reactContext: ReactApplicationContext) : ReactContextBas
|
||||
}
|
||||
|
||||
fun getNoBackupDirectory(): String {
|
||||
StatusBackendClient.getInstance()?.let { client ->
|
||||
if (client.serverEnabled && client.rootDataDir != null) {
|
||||
return client.rootDataDir!!
|
||||
}
|
||||
}
|
||||
return reactContext.noBackupFilesDir.absolutePath
|
||||
}
|
||||
|
||||
@@ -39,11 +34,6 @@ class Utils(private val reactContext: ReactApplicationContext) : ReactContextBas
|
||||
}
|
||||
|
||||
fun getPublicStorageDirectory(): File? {
|
||||
StatusBackendClient.getInstance()?.let { client ->
|
||||
if (client.serverEnabled && client.rootDataDir != null) {
|
||||
return File(client.rootDataDir!!)
|
||||
}
|
||||
}
|
||||
// Environment.getExternalStoragePublicDirectory doesn't work as expected on Android Q
|
||||
// https://developer.android.com/reference/android/os/Environment#getExternalStoragePublicDirectory(java.lang.String)
|
||||
return reactContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
|
||||
@@ -79,22 +69,8 @@ class Utils(private val reactContext: ReactApplicationContext) : ReactContextBas
|
||||
val keydirFile = File(keydir)
|
||||
if (!keydirFile.exists() || keydirFile.list().isEmpty()) {
|
||||
Log.d(TAG, "migrateKeyStoreDir")
|
||||
val jsonParams = JSONObject()
|
||||
jsonParams.put("account", JSONObject(accountData)) // Remove 'new' keyword
|
||||
jsonParams.put("password", password)
|
||||
jsonParams.put("oldDir", commonKeydir)
|
||||
jsonParams.put("newDir", keydir)
|
||||
|
||||
StatusBackendClient.executeStatusGoRequest(
|
||||
endpoint = "MigrateKeyStoreDirV2",
|
||||
requestBody = jsonParams.toString(),
|
||||
statusgoFunction = { Statusgo.migrateKeyStoreDirV2(jsonParams.toString()) }
|
||||
)
|
||||
StatusBackendClient.executeStatusGoRequest(
|
||||
endpoint = "InitKeystore",
|
||||
requestBody = keydir,
|
||||
statusgoFunction = { Statusgo.initKeystore(keydir) }
|
||||
)
|
||||
Statusgo.migrateKeyStoreDir(accountData, password, commonKeydir, keydir)
|
||||
Statusgo.initKeystore(keydir)
|
||||
}
|
||||
} catch (e: JSONException) {
|
||||
Log.e(TAG, "JSON conversion failed: ${e.message}")
|
||||
@@ -123,15 +99,15 @@ class Utils(private val reactContext: ReactApplicationContext) : ReactContextBas
|
||||
return false
|
||||
}
|
||||
|
||||
fun executeRunnableStatusGoMethod(method: Supplier<String>, callback: Callback?) {
|
||||
fun executeRunnableStatusGoMethod(method: Supplier<String>, callback: Callback) {
|
||||
if (!checkAvailability()) {
|
||||
callback?.invoke(false)
|
||||
callback.invoke(false)
|
||||
return
|
||||
}
|
||||
|
||||
val runnableTask = Runnable {
|
||||
val res = method.get()
|
||||
callback?.invoke(res)
|
||||
callback.invoke(res)
|
||||
}
|
||||
|
||||
StatusThreadPoolExecutor.getInstance().execute(runnableTask)
|
||||
@@ -139,15 +115,7 @@ class Utils(private val reactContext: ReactApplicationContext) : ReactContextBas
|
||||
|
||||
@ReactMethod
|
||||
fun validateMnemonic(seed: String, callback: Callback) {
|
||||
val jsonParams = JSONObject()
|
||||
jsonParams.put("mnemonic", seed)
|
||||
val jsonString = jsonParams.toString()
|
||||
StatusBackendClient.executeStatusGoRequestWithCallback(
|
||||
endpoint = "ValidateMnemonicV2",
|
||||
requestBody = jsonString,
|
||||
statusgoFunction = { Statusgo.validateMnemonicV2(jsonString) },
|
||||
callback
|
||||
)
|
||||
executeRunnableStatusGoMethod({ Statusgo.validateMnemonic(seed) }, callback)
|
||||
}
|
||||
|
||||
fun is24Hour(): Boolean {
|
||||
@@ -156,29 +124,17 @@ class Utils(private val reactContext: ReactApplicationContext) : ReactContextBas
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
fun checkAddressChecksum(address: String): String {
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
endpoint = "CheckAddressChecksum",
|
||||
requestBody = address,
|
||||
statusgoFunction = { Statusgo.checkAddressChecksum(address) }
|
||||
)
|
||||
return Statusgo.checkAddressChecksum(address)
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
fun isAddress(address: String): String {
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
endpoint = "IsAddress",
|
||||
requestBody = address,
|
||||
statusgoFunction = { Statusgo.isAddress(address) }
|
||||
)
|
||||
return Statusgo.isAddress(address)
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
fun toChecksumAddress(address: String): String {
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
endpoint = "ToChecksumAddress",
|
||||
requestBody = address,
|
||||
statusgoFunction = { Statusgo.toChecksumAddress(address) }
|
||||
)
|
||||
return Statusgo.toChecksumAddress(address)
|
||||
}
|
||||
|
||||
fun readableArrayToStringArray(r: ReadableArray): Array<String> {
|
||||
@@ -194,19 +150,6 @@ class Utils(private val reactContext: ReactApplicationContext) : ReactContextBas
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
fun validateConnectionString(connectionString: String): String {
|
||||
return StatusBackendClient.executeStatusGoRequestWithResult(
|
||||
endpoint = "ValidateConnectionString",
|
||||
requestBody = connectionString,
|
||||
statusgoFunction = { Statusgo.validateConnectionString(connectionString) }
|
||||
)
|
||||
}
|
||||
|
||||
fun handleStatusGoResponse(response: String, source: String) {
|
||||
//TODO(frank) we should remove sensitive data from the response
|
||||
if (response.startsWith("{\"error\":\"\"")) {
|
||||
Log.d(TAG, "$source success: $response")
|
||||
} else {
|
||||
Log.e(TAG, "$source failed: $response")
|
||||
}
|
||||
return Statusgo.validateConnectionString(connectionString)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#import "React/RCTEventDispatcher.h"
|
||||
#import "Statusgo.h"
|
||||
#import "Utils.h"
|
||||
#import "StatusBackendClient.h"
|
||||
|
||||
@implementation AccountManager
|
||||
|
||||
@@ -13,29 +12,23 @@ RCT_EXPORT_METHOD(createAccountAndLogin:(NSString *)request) {
|
||||
#if DEBUG
|
||||
NSLog(@"createAccountAndLogin() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequest:@"CreateAccountAndLogin"
|
||||
body:request
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoCreateAccountAndLogin(request);
|
||||
}];
|
||||
StatusgoCreateAccountAndLogin(request);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(restoreAccountAndLogin:(NSString *)request) {
|
||||
#if DEBUG
|
||||
NSLog(@"restoreAccountAndLogin() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequest:@"RestoreAccountAndLogin"
|
||||
body:request
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoRestoreAccountAndLogin(request);
|
||||
}];
|
||||
StatusgoRestoreAccountAndLogin(request);
|
||||
}
|
||||
|
||||
-(NSString *) prepareDirAndUpdateConfig:(NSString *)config
|
||||
withKeyUID:(NSString *)keyUID {
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSError *error = nil;
|
||||
NSURL *rootUrl =[Utils getRootUrl];
|
||||
NSURL *rootUrl =[[fileManager
|
||||
URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask]
|
||||
lastObject];
|
||||
NSURL *absTestnetFolderName = [rootUrl URLByAppendingPathComponent:@"ethereum/testnet"];
|
||||
|
||||
if (![fileManager fileExistsAtPath:absTestnetFolderName.path])
|
||||
@@ -109,24 +102,8 @@ RCT_EXPORT_METHOD(deleteMultiaccount:(NSString *)keyUID
|
||||
NSLog(@"DeleteMultiaccount() method called");
|
||||
#endif
|
||||
NSURL *multiaccountKeystoreDir = [Utils getKeyStoreDirForKeyUID:keyUID];
|
||||
NSDictionary *params = @{
|
||||
@"keyUID": keyUID,
|
||||
@"keyStoreDir": multiaccountKeystoreDir.path
|
||||
};
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error creating JSON: %@", error);
|
||||
return;
|
||||
}
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"DeleteMultiaccountV2"
|
||||
body:jsonString
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoDeleteMultiaccountV2(jsonString);
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoDeleteMultiaccount(keyUID, multiaccountKeystoreDir.path);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(prepareDirAndUpdateConfig:(NSString *)keyUID
|
||||
@@ -186,69 +163,36 @@ RCT_EXPORT_METHOD(loginWithConfig:(NSString *)accountData
|
||||
|
||||
RCT_EXPORT_METHOD(loginAccount:(NSString *)request) {
|
||||
#if DEBUG
|
||||
NSLog(@"loginAccount() method called");
|
||||
NSLog(@"LoginAccount() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequest:@"LoginAccount"
|
||||
body:request
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoLoginAccount(request);
|
||||
}];
|
||||
NSString *result = StatusgoLoginAccount(request);
|
||||
NSLog(@"%@", result);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(verify:(NSString *)address
|
||||
password:(NSString *)password
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"VerifyAccountPasswordV2() method called");
|
||||
NSLog(@"VerifyAccountPassword() method called");
|
||||
#endif
|
||||
NSURL *rootUrl = [Utils getRootUrl];
|
||||
NSString *keystorePath = [rootUrl.path stringByAppendingPathComponent:@"keystore"];
|
||||
|
||||
NSDictionary *params = @{
|
||||
@"keyStoreDir": keystorePath,
|
||||
@"address": address,
|
||||
@"password": password
|
||||
};
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error creating JSON: %@", error);
|
||||
return;
|
||||
}
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"VerifyAccountPasswordV2"
|
||||
body:jsonString
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoVerifyAccountPasswordV2(jsonString);
|
||||
}
|
||||
callback:callback];
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSURL *rootUrl =[[fileManager
|
||||
URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask]
|
||||
lastObject];
|
||||
NSURL *absKeystoreUrl = [rootUrl URLByAppendingPathComponent:@"keystore"];
|
||||
|
||||
NSString *result = StatusgoVerifyAccountPassword(absKeystoreUrl.path, address, password);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(verifyDatabasePassword:(NSString *)keyUID
|
||||
password:(NSString *)password
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"VerifyDatabasePasswordV2() method called");
|
||||
NSLog(@"VerifyDatabasePassword() method called");
|
||||
#endif
|
||||
NSDictionary *params = @{
|
||||
@"keyUID": keyUID,
|
||||
@"password": password
|
||||
};
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error creating JSON: %@", error);
|
||||
return;
|
||||
}
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"VerifyDatabasePasswordV2"
|
||||
body:jsonString
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoVerifyDatabasePasswordV2(jsonString);
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoVerifyDatabasePassword(keyUID, password);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(initializeApplication:(NSString *)request
|
||||
@@ -256,173 +200,54 @@ RCT_EXPORT_METHOD(initializeApplication:(NSString *)request
|
||||
#if DEBUG
|
||||
NSLog(@"initializeApplication() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"InitializeApplication"
|
||||
body:request
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoInitializeApplication(request);
|
||||
}
|
||||
callback:callback];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(acceptTerms:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"acceptTerms() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"AcceptTerms"
|
||||
body:@""
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoAcceptTerms();
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoInitializeApplication(request);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(openAccounts:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"OpenAccounts() method called");
|
||||
#endif
|
||||
NSURL *rootUrl =[Utils getRootUrl];
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSURL *rootUrl =[[fileManager
|
||||
URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask]
|
||||
lastObject];
|
||||
|
||||
NSString *result = StatusgoOpenAccounts(rootUrl.path);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(logout) {
|
||||
#if DEBUG
|
||||
NSLog(@"Logout() method called");
|
||||
NSLog(@"Logout() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequest:@"Logout"
|
||||
body:@""
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoLogout();
|
||||
}];
|
||||
}
|
||||
NSString *result = StatusgoLogout();
|
||||
|
||||
RCT_EXPORT_METHOD(multiAccountStoreAccount:(NSString *)json
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"MultiAccountStoreAccount() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"MultiAccountStoreAccount"
|
||||
body:json
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoMultiAccountStoreAccount(json);
|
||||
}
|
||||
callback:callback];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(multiAccountLoadAccount:(NSString *)json
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"MultiAccountLoadAccount() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"MultiAccountLoadAccount"
|
||||
body:json
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoMultiAccountLoadAccount(json);
|
||||
}
|
||||
callback:callback];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(multiAccountDeriveAddresses:(NSString *)json
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"multiAccountDeriveAddresses() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"MultiAccountDeriveAddresses"
|
||||
body:json
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoMultiAccountDeriveAddresses(json);
|
||||
}
|
||||
callback:callback];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(multiAccountGenerateAndDeriveAddresses:(NSString *)json
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"MultiAccountGenerateAndDeriveAddresses() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"MultiAccountGenerateAndDeriveAddresses"
|
||||
body:json
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoMultiAccountGenerateAndDeriveAddresses(json);
|
||||
}
|
||||
callback:callback];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(multiAccountStoreDerived:(NSString *)json
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"MultiAccountStoreDerived() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"MultiAccountStoreDerivedAccounts"
|
||||
body:json
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoMultiAccountStoreDerivedAccounts(json);
|
||||
}
|
||||
callback:callback];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(multiAccountImportMnemonic:(NSString *)json
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"MultiAccountImportMnemonic() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"MultiAccountImportMnemonic"
|
||||
body:json
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoMultiAccountImportMnemonic(json);
|
||||
}
|
||||
callback:callback];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(multiAccountImportPrivateKey:(NSString *)json
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"MultiAccountImportPrivateKey() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"MultiAccountImportPrivateKey"
|
||||
body:json
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoMultiAccountImportPrivateKey(json);
|
||||
}
|
||||
callback:callback];
|
||||
NSLog(@"%@", result);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getRandomMnemonic:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"GetRandomMnemonic() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"GetRandomMnemonic"
|
||||
body:@""
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoGetRandomMnemonic();
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoGetRandomMnemonic();
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(createAccountFromMnemonicAndDeriveAccountsForPaths:(NSString *)mnemonic
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
RCT_EXPORT_METHOD(createAccountFromMnemonicAndDeriveAccountsForPaths:(NSString *)mnemonic callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"createAccountFromMnemonicAndDeriveAccountsForPaths() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"CreateAccountFromMnemonicAndDeriveAccountsForPaths"
|
||||
body:mnemonic
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoCreateAccountFromMnemonicAndDeriveAccountsForPaths(mnemonic);
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoCreateAccountFromMnemonicAndDeriveAccountsForPaths(mnemonic);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(createAccountFromPrivateKey:(NSString *)json
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
RCT_EXPORT_METHOD(createAccountFromPrivateKey:(NSString *)configJSON callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"createAccountFromPrivateKey() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"CreateAccountFromPrivateKey"
|
||||
body:json
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoCreateAccountFromPrivateKey(json);
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoCreateAccountFromPrivateKey(configJSON);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#import "React/RCTEventDispatcher.h"
|
||||
#import "Statusgo.h"
|
||||
#import "Utils.h"
|
||||
#import "StatusBackendClient.h"
|
||||
|
||||
@implementation DatabaseManager
|
||||
|
||||
RCT_EXPORT_MODULE();
|
||||
@@ -16,31 +16,8 @@ RCT_EXPORT_METHOD(exportUnencryptedDatabase:(NSString *)accountData
|
||||
#endif
|
||||
|
||||
NSString *filePath = [Utils getExportDbFilePath];
|
||||
|
||||
NSDictionary *params = @{
|
||||
@"account": [NSJSONSerialization JSONObjectWithData:[accountData dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil],
|
||||
@"password": password,
|
||||
@"databasePath": filePath
|
||||
};
|
||||
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
|
||||
|
||||
if (error) {
|
||||
NSLog(@"Error creating JSON: %@", [error localizedDescription]);
|
||||
callback(@[filePath]);
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"ExportUnencryptedDatabaseV2"
|
||||
body:jsonString
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoExportUnencryptedDatabaseV2(jsonString);
|
||||
}
|
||||
callback:nil];
|
||||
|
||||
StatusgoExportUnencryptedDatabase(accountData, password, filePath);
|
||||
|
||||
callback(@[filePath]);
|
||||
}
|
||||
|
||||
@@ -49,31 +26,7 @@ RCT_EXPORT_METHOD(importUnencryptedDatabase:(NSString *)accountData
|
||||
#if DEBUG
|
||||
NSLog(@"importUnencryptedDatabase() method called");
|
||||
#endif
|
||||
|
||||
NSString *filePath = [Utils getExportDbFilePath];
|
||||
[Utils migrateKeystore:accountData password:password];
|
||||
|
||||
NSDictionary *params = @{
|
||||
@"account": [NSJSONSerialization JSONObjectWithData:[accountData dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil],
|
||||
@"password": password,
|
||||
@"databasePath": filePath
|
||||
};
|
||||
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
|
||||
|
||||
if (error) {
|
||||
NSLog(@"Error creating JSON: %@", [error localizedDescription]);
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
|
||||
[StatusBackendClient executeStatusGoRequest:@"ImportUnencryptedDatabaseV2"
|
||||
body:jsonString
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoImportUnencryptedDatabaseV2(jsonString);
|
||||
}];
|
||||
"";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#import "React/RCTEventDispatcher.h"
|
||||
#import "Statusgo.h"
|
||||
#import "Utils.h"
|
||||
#import "StatusBackendClient.h"
|
||||
|
||||
@implementation EncryptionUtils
|
||||
|
||||
@@ -16,14 +15,21 @@ RCT_EXPORT_METHOD(initKeystore:(NSString *)keyUID
|
||||
#if DEBUG
|
||||
NSLog(@"initKeystore() method called");
|
||||
#endif
|
||||
NSURL *multiaccountKeystoreDir = [Utils getKeyStoreDirForKeyUID:keyUID];
|
||||
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"InitKeystore"
|
||||
body:multiaccountKeystoreDir.path
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoInitKeystore(multiaccountKeystoreDir.path);
|
||||
}
|
||||
callback:callback];
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSURL *rootUrl =[[fileManager
|
||||
URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask]
|
||||
lastObject];
|
||||
|
||||
NSURL *commonKeystoreDir = [rootUrl URLByAppendingPathComponent:@"keystore"];
|
||||
NSURL *keystoreDir = [commonKeystoreDir URLByAppendingPathComponent:keyUID];
|
||||
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
|
||||
^(void)
|
||||
{
|
||||
NSString *res = StatusgoInitKeystore(keystoreDir.path);
|
||||
NSLog(@"InitKeyStore result %@", res);
|
||||
callback(@[]);
|
||||
});
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(reEncryptDbAndKeystore:(NSString *)keyUID
|
||||
@@ -33,26 +39,9 @@ RCT_EXPORT_METHOD(reEncryptDbAndKeystore:(NSString *)keyUID
|
||||
#if DEBUG
|
||||
NSLog(@"reEncryptDbAndKeystore() method called");
|
||||
#endif
|
||||
// Construct params into JSON string
|
||||
NSDictionary *params = @{
|
||||
@"keyUID": keyUID,
|
||||
@"oldPassword": currentPassword,
|
||||
@"newPassword": newPassword
|
||||
};
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error creating JSON: %@", error);
|
||||
return;
|
||||
}
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"ChangeDatabasePasswordV2"
|
||||
body:jsonString
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoChangeDatabasePasswordV2(jsonString);
|
||||
}
|
||||
callback:callback];
|
||||
// changes password and re-encrypts keystore
|
||||
NSString *result = StatusgoChangeDatabasePassword(keyUID, currentPassword, newPassword);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(convertToKeycardAccount:(NSString *)keyUID
|
||||
@@ -66,141 +55,47 @@ RCT_EXPORT_METHOD(convertToKeycardAccount:(NSString *)keyUID
|
||||
NSLog(@"convertToKeycardAccount() method called");
|
||||
#endif
|
||||
NSURL *multiaccountKeystoreDir = [Utils getKeyStoreDirForKeyUID:keyUID];
|
||||
|
||||
// First initialize keystore
|
||||
[StatusBackendClient executeStatusGoRequest:@"InitKeystore"
|
||||
body:multiaccountKeystoreDir.path
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoInitKeystore(multiaccountKeystoreDir.path);
|
||||
}];
|
||||
|
||||
// Prepare parameters for conversion
|
||||
NSDictionary *params = @{
|
||||
@"keyUID": keyUID,
|
||||
@"account": [NSJSONSerialization JSONObjectWithData:[accountData dataUsingEncoding:NSUTF8StringEncoding]
|
||||
options:0
|
||||
error:nil],
|
||||
@"settings": [NSJSONSerialization JSONObjectWithData:[settings dataUsingEncoding:NSUTF8StringEncoding]
|
||||
options:0
|
||||
error:nil],
|
||||
@"keycardUID": keycardUID,
|
||||
@"oldPassword": currentPassword,
|
||||
@"newPassword": newPassword
|
||||
};
|
||||
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error creating JSON: %@", [error localizedDescription]);
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"ConvertToKeycardAccountV2"
|
||||
body:jsonString
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoConvertToKeycardAccountV2(jsonString);
|
||||
}
|
||||
callback:callback];
|
||||
StatusgoInitKeystore(multiaccountKeystoreDir.path);
|
||||
NSString *result = StatusgoConvertToKeycardAccount(accountData, settings, keycardUID, currentPassword, newPassword);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(encodeTransfer:(NSString *)to
|
||||
value:(NSString *)value) {
|
||||
NSDictionary *params = @{
|
||||
@"to": to,
|
||||
@"value": value
|
||||
};
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error creating JSON: %@", [error localizedDescription]);
|
||||
return nil;
|
||||
}
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
|
||||
return [StatusBackendClient executeStatusGoRequestWithResult:@"EncodeTransferV2"
|
||||
body:jsonString
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoEncodeTransferV2(jsonString);
|
||||
}];
|
||||
value:(NSString *)value) {
|
||||
return StatusgoEncodeTransfer(to,value);
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(encodeFunctionCall:(NSString *)method
|
||||
paramsJSON:(NSString *)paramsJSON) {
|
||||
NSDictionary *params = @{
|
||||
@"method": method,
|
||||
@"paramsJSON": paramsJSON
|
||||
};
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error creating JSON: %@", [error localizedDescription]);
|
||||
return nil;
|
||||
}
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
|
||||
return [StatusBackendClient executeStatusGoRequestWithResult:@"EncodeFunctionCallV2"
|
||||
body:jsonString
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoEncodeFunctionCallV2(jsonString);
|
||||
}];
|
||||
paramsJSON:(NSString *)paramsJSON) {
|
||||
return StatusgoEncodeFunctionCall(method,paramsJSON);
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(decodeParameters:(NSString *)decodeParamJSON) {
|
||||
return [StatusBackendClient executeStatusGoRequestWithResult:@"DecodeParameters"
|
||||
body:decodeParamJSON
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoDecodeParameters(decodeParamJSON);
|
||||
}];
|
||||
return StatusgoDecodeParameters(decodeParamJSON);
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(hexToNumber:(NSString *)hex) {
|
||||
return [StatusBackendClient executeStatusGoRequestWithResult:@"HexToNumber"
|
||||
body:hex
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoHexToNumber(hex);
|
||||
}];
|
||||
return StatusgoHexToNumber(hex);
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(numberToHex:(NSString *)numString) {
|
||||
return [StatusBackendClient executeStatusGoRequestWithResult:@"NumberToHex"
|
||||
body:numString
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoNumberToHex(numString);
|
||||
}];
|
||||
return StatusgoNumberToHex(numString);
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(sha3:(NSString *)str) {
|
||||
return [StatusBackendClient executeStatusGoRequestWithResult:@"Sha3"
|
||||
body:str
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoSha3(str);
|
||||
}];
|
||||
return StatusgoSha3(str);
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(utf8ToHex:(NSString *)str) {
|
||||
return [StatusBackendClient executeStatusGoRequestWithResult:@"Utf8ToHex"
|
||||
body:str
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoUtf8ToHex(str);
|
||||
}];
|
||||
return StatusgoUtf8ToHex(str);
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(hexToUtf8:(NSString *)str) {
|
||||
return [StatusBackendClient executeStatusGoRequestWithResult:@"HexToUtf8"
|
||||
body:str
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoHexToUtf8(str);
|
||||
}];
|
||||
return StatusgoHexToUtf8(str);
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(serializeLegacyKey:(NSString *)str) {
|
||||
return [StatusBackendClient executeStatusGoRequestWithResult:@"SerializeLegacyKey"
|
||||
body:str
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoSerializeLegacyKey(str);
|
||||
}];
|
||||
return StatusgoSerializeLegacyKey(str);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setBlankPreviewFlag:(BOOL *)newValue)
|
||||
@@ -215,14 +110,10 @@ RCT_EXPORT_METHOD(setBlankPreviewFlag:(BOOL *)newValue)
|
||||
RCT_EXPORT_METHOD(hashTransaction:(NSString *)txArgsJSON
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"hashTransaction() method called");
|
||||
NSLog(@"HashTransaction() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"HashTransaction"
|
||||
body:txArgsJSON
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoHashTransaction(txArgsJSON);
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoHashTransaction(txArgsJSON);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(hashMessage:(NSString *)message
|
||||
@@ -230,12 +121,8 @@ RCT_EXPORT_METHOD(hashMessage:(NSString *)message
|
||||
#if DEBUG
|
||||
NSLog(@"hashMessage() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"HashMessage"
|
||||
body:message
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoHashMessage(message);
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoHashMessage(message);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(localPairingPreflightOutboundCheck:(RCTResponseSenderBlock)callback) {
|
||||
@@ -249,34 +136,14 @@ RCT_EXPORT_METHOD(localPairingPreflightOutboundCheck:(RCTResponseSenderBlock)cal
|
||||
RCT_EXPORT_METHOD(multiformatDeserializePublicKey:(NSString *)multiCodecKey
|
||||
base58btc:(NSString *)base58btc
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
NSDictionary *params = @{
|
||||
@"key": multiCodecKey,
|
||||
@"outBase": base58btc
|
||||
};
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error creating JSON: %@", error);
|
||||
return;
|
||||
}
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"MultiformatDeserializePublicKeyV2"
|
||||
body:jsonString
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoMultiformatDeserializePublicKeyV2(jsonString);
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoMultiformatDeserializePublicKey(multiCodecKey,base58btc);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(deserializeAndCompressKey:(NSString *)desktopKey
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"DeserializeAndCompressKey"
|
||||
body:desktopKey
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoDeserializeAndCompressKey(desktopKey);
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoDeserializeAndCompressKey(desktopKey);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(hashTypedData:(NSString *)data
|
||||
@@ -299,14 +166,13 @@ RCT_EXPORT_METHOD(hashTypedDataV4:(NSString *)data
|
||||
|
||||
#pragma mark - SignMessage
|
||||
|
||||
RCT_EXPORT_METHOD(signMessage:(NSString *)rpcParams
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"SignMessage"
|
||||
body:rpcParams
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoSignMessage(rpcParams);
|
||||
}
|
||||
callback:callback];
|
||||
RCT_EXPORT_METHOD(signMessage:(NSString *)message
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"SignMessage() method called");
|
||||
#endif
|
||||
NSString *result = StatusgoSignMessage(message);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
#pragma mark - SignTypedData
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#import "Statusgo.h"
|
||||
#import "Utils.h"
|
||||
#import "SSZipArchive.h"
|
||||
#import "StatusBackendClient.h"
|
||||
|
||||
@implementation LogManager
|
||||
|
||||
@@ -21,7 +20,9 @@ RCT_EXPORT_METHOD(sendLogs:(NSString *)dbJson
|
||||
#endif
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSError *error = nil;
|
||||
NSURL *rootUrl =[Utils getRootUrl];
|
||||
NSURL *rootUrl =[[fileManager
|
||||
URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask]
|
||||
lastObject];
|
||||
|
||||
NSURL *zipFile = [rootUrl URLByAppendingPathComponent:@"logs.zip"];
|
||||
[fileManager removeItemAtPath:zipFile.path error:nil];
|
||||
@@ -87,36 +88,37 @@ RCT_EXPORT_METHOD(initLogging:(BOOL)enabled
|
||||
NSString *logFilePath = [logDirectory stringByAppendingPathComponent:@"geth.log"];
|
||||
NSString *logRequestFilePath = [logDirectory stringByAppendingPathComponent:@"requests.log"];
|
||||
|
||||
NSDictionary *config = @{
|
||||
@"Enabled": @(enabled),
|
||||
@"MobileSystem": @(mobileSystem),
|
||||
@"Level": logLevel,
|
||||
@"File": logFilePath,
|
||||
@"LogRequestGo": @(logRequestGo),
|
||||
@"LogRequestFile": logRequestFilePath
|
||||
};
|
||||
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:config options:0 error:&error];
|
||||
|
||||
NSMutableDictionary *jsonConfig = [NSMutableDictionary dictionary];
|
||||
jsonConfig[@"Enabled"] = @(enabled);
|
||||
jsonConfig[@"MobileSystem"] = @(mobileSystem);
|
||||
jsonConfig[@"Level"] = logLevel;
|
||||
jsonConfig[@"File"] = logFilePath;
|
||||
jsonConfig[@"LogRequestGo"] = @(logRequestGo);
|
||||
jsonConfig[@"LogRequestFile"] = logRequestFilePath;
|
||||
NSError *error = nil;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonConfig options:0 error:&error];
|
||||
|
||||
if (error) {
|
||||
NSLog(@"Error creating JSON: %@", [error localizedDescription]);
|
||||
// Handle JSON serialization error
|
||||
callback(@[error.localizedDescription]);
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *configJson = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"InitLogging"
|
||||
body:configJson
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoInitLogging(configJson);
|
||||
}
|
||||
callback:callback];
|
||||
NSString *config = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
|
||||
// Call your native logging initialization method here
|
||||
NSString *initResult = StatusgoInitLogging(config);
|
||||
|
||||
callback(@[initResult]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(logFileDirectory) {
|
||||
NSURL *rootUrl = [Utils getRootUrl];
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSURL *rootUrl =[[fileManager
|
||||
URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask]
|
||||
lastObject];
|
||||
return rootUrl.path;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -3,18 +3,14 @@
|
||||
#import "React/RCTEventDispatcher.h"
|
||||
#import "Statusgo.h"
|
||||
#import "Utils.h"
|
||||
#import "StatusBackendClient.h"
|
||||
|
||||
@implementation NetworkManager
|
||||
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
RCT_EXPORT_METHOD(startSearchForLocalPairingPeers:(RCTResponseSenderBlock)callback) {
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"StartSearchForLocalPairingPeers"
|
||||
body:@""
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoStartSearchForLocalPairingPeers();
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoStartSearchForLocalPairingPeers();
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getConnectionStringForBootstrappingAnotherDevice:(NSString *)configJSON
|
||||
@@ -23,11 +19,6 @@ RCT_EXPORT_METHOD(getConnectionStringForBootstrappingAnotherDevice:(NSString *)c
|
||||
NSData *configData = [configJSON dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSError *error;
|
||||
NSMutableDictionary *configDict = [NSJSONSerialization JSONObjectWithData:configData options:NSJSONReadingMutableContainers error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error parsing JSON: %@", error);
|
||||
return;
|
||||
}
|
||||
|
||||
NSMutableDictionary *senderConfig = configDict[@"senderConfig"];
|
||||
NSString *keyUID = senderConfig[@"keyUID"];
|
||||
NSURL *multiaccountKeystoreDir = [Utils getKeyStoreDirForKeyUID:keyUID];
|
||||
@@ -36,43 +27,16 @@ RCT_EXPORT_METHOD(getConnectionStringForBootstrappingAnotherDevice:(NSString *)c
|
||||
[senderConfig setValue:keystoreDir forKey:@"keystorePath"];
|
||||
NSString *modifiedConfigJSON = [Utils jsonStringWithPrettyPrint:NO fromDictionary:configDict];
|
||||
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"GetConnectionStringForBootstrappingAnotherDevice"
|
||||
body:modifiedConfigJSON
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoGetConnectionStringForBootstrappingAnotherDevice(modifiedConfigJSON);
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoGetConnectionStringForBootstrappingAnotherDevice(modifiedConfigJSON);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(inputConnectionStringForBootstrapping:(NSString *)cs
|
||||
configJSON:(NSString *)configJSON
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
|
||||
NSData *configData = [configJSON dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSError *jsonError;
|
||||
NSDictionary *configDict = [NSJSONSerialization JSONObjectWithData:configData options:0 error:&jsonError];
|
||||
if (jsonError) {
|
||||
NSLog(@"Error parsing JSON: %@", jsonError);
|
||||
return;
|
||||
}
|
||||
|
||||
NSDictionary *params = @{
|
||||
@"connectionString": cs,
|
||||
@"receiverClientConfig": configDict
|
||||
};
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error creating JSON: %@", error);
|
||||
return;
|
||||
}
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"InputConnectionStringForBootstrappingV2"
|
||||
body:jsonString
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoInputConnectionStringForBootstrappingV2(jsonString);
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoInputConnectionStringForBootstrapping(cs, configJSON);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(sendTransactionWithSignature:(NSString *)txArgsJSON
|
||||
@@ -81,12 +45,8 @@ RCT_EXPORT_METHOD(sendTransactionWithSignature:(NSString *)txArgsJSON
|
||||
#if DEBUG
|
||||
NSLog(@"sendTransactionWithSignature() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"SendTransactionWithSignature"
|
||||
body:txArgsJSON
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoSendTransactionWithSignature(txArgsJSON, signature);
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoSendTransactionWithSignature(txArgsJSON, signature);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
#pragma mark - SendTransaction
|
||||
@@ -95,53 +55,30 @@ RCT_EXPORT_METHOD(sendTransaction:(NSString *)txArgsJSON
|
||||
password:(NSString *)password
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"SendTransactionV2() method called");
|
||||
NSLog(@"SendTransaction() method called");
|
||||
#endif
|
||||
NSData *txArgsData = [txArgsJSON dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSError *jsonError;
|
||||
NSDictionary *txArgsDict = [NSJSONSerialization JSONObjectWithData:txArgsData options:0 error:&jsonError];
|
||||
if (jsonError) {
|
||||
NSLog(@"Error parsing JSON: %@", jsonError);
|
||||
return;
|
||||
}
|
||||
|
||||
NSDictionary *params = @{
|
||||
@"txArgs": txArgsDict,
|
||||
@"password": password
|
||||
};
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error creating JSON: %@", error);
|
||||
return;
|
||||
}
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"SendTransactionV2"
|
||||
body:jsonString
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoSendTransactionV2(jsonString);
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoSendTransaction(txArgsJSON, password);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(callRPC:(NSString *)payload
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"CallRPC"
|
||||
body:payload
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoCallRPC(payload);
|
||||
}
|
||||
callback:callback];
|
||||
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
NSString *result = StatusgoCallRPC(payload);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
callback(@[result]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(callPrivateRPC:(NSString *)payload
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"CallPrivateRPC"
|
||||
body:payload
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoCallPrivateRPC(payload);
|
||||
}
|
||||
callback:callback];
|
||||
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
NSString *result = StatusgoCallPrivateRPC(payload);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
callback(@[result]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - Recover
|
||||
@@ -151,12 +88,8 @@ RCT_EXPORT_METHOD(recover:(NSString *)message
|
||||
#if DEBUG
|
||||
NSLog(@"Recover() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"Recover"
|
||||
body:message
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoRecover(message);
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoRecover(message);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getConnectionStringForExportingKeypairsKeystores:(NSString *)configJSON
|
||||
@@ -173,12 +106,8 @@ RCT_EXPORT_METHOD(getConnectionStringForExportingKeypairsKeystores:(NSString *)c
|
||||
[senderConfig setValue:keystoreDir forKey:@"keystorePath"];
|
||||
NSString *modifiedConfigJSON = [Utils jsonStringWithPrettyPrint:NO fromDictionary:configDict];
|
||||
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"GetConnectionStringForExportingKeypairsKeystores"
|
||||
body:modifiedConfigJSON
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoGetConnectionStringForExportingKeypairsKeystores(modifiedConfigJSON);
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoGetConnectionStringForExportingKeypairsKeystores(modifiedConfigJSON);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(inputConnectionStringForImportingKeypairsKeystores:(NSString *)cs
|
||||
@@ -190,25 +119,14 @@ RCT_EXPORT_METHOD(inputConnectionStringForImportingKeypairsKeystores:(NSString *
|
||||
NSMutableDictionary *configDict = [NSJSONSerialization JSONObjectWithData:configData options:NSJSONReadingMutableContainers error:&error];
|
||||
NSMutableDictionary *receiverConfig = configDict[@"receiverConfig"];
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSURL *rootUrl =[Utils getRootUrl];
|
||||
NSURL *rootUrl =[[fileManager URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject];
|
||||
NSURL *multiaccountKeystoreDir = [rootUrl URLByAppendingPathComponent:@"keystore"];
|
||||
NSString *keystoreDir = multiaccountKeystoreDir.path;
|
||||
|
||||
[receiverConfig setValue:keystoreDir forKey:@"keystorePath"];
|
||||
NSString *modifiedConfigJSON = [Utils jsonStringWithPrettyPrint:NO fromDictionary:configDict];
|
||||
|
||||
NSDictionary *params = @{
|
||||
@"connectionString": cs,
|
||||
@"keystoreFilesReceiverClientConfig": modifiedConfigJSON
|
||||
};
|
||||
NSString *paramsJSON = [Utils jsonStringWithPrettyPrint:NO fromDictionary:params];
|
||||
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"InputConnectionStringForImportingKeypairsKeystoresV2"
|
||||
body:paramsJSON
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoInputConnectionStringForImportingKeypairsKeystoresV2(paramsJSON);
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoInputConnectionStringForImportingKeypairsKeystores(cs, modifiedConfigJSON);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -5,6 +5,5 @@
|
||||
#import "RCTLog.h"
|
||||
|
||||
@interface Status : NSObject <RCTBridgeModule, StatusgoSignalHandler>
|
||||
+ (Status *)sharedInstance;
|
||||
- (void)handleSignal:(NSString *)signal;
|
||||
@end
|
||||
|
||||
@@ -2,22 +2,13 @@
|
||||
#import "React/RCTBridge.h"
|
||||
#import "React/RCTEventDispatcher.h"
|
||||
#import "Statusgo.h"
|
||||
#import "StatusBackendClient.h"
|
||||
|
||||
#import "Utils.h"
|
||||
|
||||
static RCTBridge *bridge;
|
||||
|
||||
@implementation Status
|
||||
|
||||
+ (Status *)sharedInstance {
|
||||
static Status *sharedInstance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedInstance = [[self alloc] init];
|
||||
});
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
@@ -82,17 +73,74 @@ RCT_EXPORT_METHOD(deleteImportedKey:(NSString *)keyUID
|
||||
password:(NSString *)password
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"DeleteImportedKeyV2() method called");
|
||||
NSLog(@"DeleteImportedKey() method called");
|
||||
#endif
|
||||
NSURL *multiaccountKeystoreDir = [Utils getKeyStoreDirForKeyUID:keyUID];
|
||||
NSString *jsonParams = [NSString stringWithFormat:@"{\"address\":\"%@\",\"password\":\"%@\",\"keyStoreDir\":\"%@\"}",
|
||||
address, password, multiaccountKeystoreDir.path];
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"DeleteImportedKeyV2"
|
||||
body:jsonParams
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoDeleteImportedKeyV2(jsonParams);
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoDeleteImportedKey(address, password, multiaccountKeystoreDir.path);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(multiAccountGenerateAndDeriveAddresses:(NSString *)json
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"MultiAccountGenerateAndDeriveAddresses() method called");
|
||||
#endif
|
||||
NSString *result = StatusgoMultiAccountGenerateAndDeriveAddresses(json);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(multiAccountStoreAccount:(NSString *)json
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"MultiAccountStoreAccount() method called");
|
||||
#endif
|
||||
NSString *result = StatusgoMultiAccountStoreAccount(json);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(multiAccountLoadAccount:(NSString *)json
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"MultiAccountLoadAccount() method called");
|
||||
#endif
|
||||
NSString *result = StatusgoMultiAccountLoadAccount(json);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(multiAccountStoreDerived:(NSString *)json
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"MultiAccountStoreDerived() method called");
|
||||
#endif
|
||||
NSString *result = StatusgoMultiAccountStoreDerivedAccounts(json);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(multiAccountImportPrivateKey:(NSString *)json
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"MultiAccountImportPrivateKey() method called");
|
||||
#endif
|
||||
NSString *result = StatusgoMultiAccountImportPrivateKey(json);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(multiAccountImportMnemonic:(NSString *)json
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"MultiAccountImportMnemonic() method called");
|
||||
#endif
|
||||
NSString *result = StatusgoMultiAccountImportMnemonic(json);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(multiAccountDeriveAddresses:(NSString *)json
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"MultiAccountDeriveAddresses() method called");
|
||||
#endif
|
||||
NSString *result = StatusgoMultiAccountDeriveAddresses(json);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
#pragma mark - GetNodeConfig
|
||||
@@ -101,20 +149,12 @@ RCT_EXPORT_METHOD(getNodeConfig:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"GetNodeConfig() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"GetNodeConfig"
|
||||
body:@""
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoGetNodeConfig();
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoGetNodeConfig();
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(fleets) {
|
||||
return [StatusBackendClient executeStatusGoRequestWithResult:@"Fleets"
|
||||
body:@""
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoFleets();
|
||||
}];
|
||||
return StatusgoFleets();
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(closeApplication) {
|
||||
@@ -126,55 +166,14 @@ RCT_EXPORT_METHOD(connectionChange:(NSString *)type
|
||||
#if DEBUG
|
||||
NSLog(@"ConnectionChange() method called");
|
||||
#endif
|
||||
NSDictionary *params = @{
|
||||
@"type": type,
|
||||
@"expensive": @(isExpensive)
|
||||
};
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params
|
||||
options:0
|
||||
error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error creating JSON: %@", error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (jsonData) {
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
[StatusBackendClient executeStatusGoRequest:@"ConnectionChangeV2"
|
||||
body:jsonString
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoConnectionChangeV2(jsonString);
|
||||
}];
|
||||
} else {
|
||||
NSLog(@"Failed to create JSON data");
|
||||
}
|
||||
StatusgoConnectionChange(type, isExpensive ? 1 : 0);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(appStateChange:(NSString *)state) {
|
||||
RCT_EXPORT_METHOD(appStateChange:(NSString *)type) {
|
||||
#if DEBUG
|
||||
NSLog(@"AppStateChange() method called");
|
||||
#endif
|
||||
NSDictionary *params = @{@"state": state};
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params
|
||||
options:0
|
||||
error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error creating JSON: %@", error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (jsonData) {
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
[StatusBackendClient executeStatusGoRequest:@"AppStateChangeV2"
|
||||
body:jsonString
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoAppStateChangeV2(jsonString);
|
||||
}];
|
||||
} else {
|
||||
NSLog(@"Failed to create JSON data");
|
||||
}
|
||||
StatusgoAppStateChange(type);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(addCentralizedMetric:(NSString *)request
|
||||
@@ -182,12 +181,8 @@ RCT_EXPORT_METHOD(addCentralizedMetric:(NSString *)request
|
||||
#if DEBUG
|
||||
NSLog(@"addCentralizedMetric() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"AddCentralizedMetric"
|
||||
body:request
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoAddCentralizedMetric(request);
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoAddCentralizedMetric(request);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(toggleCentralizedMetrics:(NSString *)request
|
||||
@@ -195,23 +190,15 @@ RCT_EXPORT_METHOD(toggleCentralizedMetrics:(NSString *)request
|
||||
#if DEBUG
|
||||
NSLog(@"toggleCentralizedMetrics() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequestWithCallback:@"ToggleCentralizedMetrics"
|
||||
body:request
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoToggleCentralizedMetrics(request);
|
||||
}
|
||||
callback:callback];
|
||||
NSString *result = StatusgoToggleCentralizedMetrics(request);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(startLocalNotifications) {
|
||||
#if DEBUG
|
||||
NSLog(@"StartLocalNotifications() method called");
|
||||
#endif
|
||||
[StatusBackendClient executeStatusGoRequest:@"StartLocalNotifications"
|
||||
body:@""
|
||||
statusgoFunction:^NSString *{
|
||||
return StatusgoStartLocalNotifications();
|
||||
}];
|
||||
StatusgoStartLocalNotifications();
|
||||
}
|
||||
|
||||
#pragma mark - deviceinfo
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <React/RCTBridgeModule.h>
|
||||
|
||||
@interface StatusBackendClient : NSObject <RCTBridgeModule>
|
||||
|
||||
@property (nonatomic) BOOL serverEnabled;
|
||||
@property (nonatomic, strong) NSString *statusGoEndpoint;
|
||||
@property (nonatomic, strong) NSString *signalEndpoint;
|
||||
@property (nonatomic, strong) NSString *rootDataDir;
|
||||
@property (nonatomic, strong) NSURLSessionWebSocketTask *webSocket;
|
||||
|
||||
// Add sharedInstance class method declaration
|
||||
+ (instancetype)sharedInstance;
|
||||
- (void)request:(NSString *)endpoint
|
||||
body:(NSString *)body
|
||||
callback:(void (^)(NSString *response, NSError *error))callback;
|
||||
|
||||
+ (void)executeStatusGoRequest:(NSString *)endpoint
|
||||
body:(NSString *)body
|
||||
statusgoFunction:(NSString * (^)(void))statusgoFunction;
|
||||
|
||||
+ (void)executeStatusGoRequestWithCallback:(NSString *)endpoint
|
||||
body:(NSString *)body
|
||||
statusgoFunction:(NSString * (^)(void))statusgoFunction
|
||||
callback:(RCTResponseSenderBlock)callback;
|
||||
|
||||
+ (NSString *)executeStatusGoRequestWithResult:(NSString *)endpoint
|
||||
body:(NSString *)body
|
||||
statusgoFunction:(NSString * (^)(void))statusgoFunction;
|
||||
|
||||
@end
|
||||
@@ -1,246 +0,0 @@
|
||||
#import "StatusBackendClient.h"
|
||||
#import "RCTStatus.h"
|
||||
#import "Utils.h"
|
||||
|
||||
@implementation StatusBackendClient {
|
||||
NSURLSessionWebSocketTask *_webSocket;
|
||||
BOOL _serverEnabled;
|
||||
NSString *_statusGoEndpoint;
|
||||
NSString *_signalEndpoint;
|
||||
NSString *_rootDataDir;
|
||||
}
|
||||
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
+ (BOOL)requiresMainQueueSetup {
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (instancetype)allocWithZone:(NSZone *)zone {
|
||||
static StatusBackendClient *sharedInstance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedInstance = [super allocWithZone:zone];
|
||||
});
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
+ (instancetype)sharedInstance {
|
||||
return [[self alloc] init];
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
static StatusBackendClient *sharedInstance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedInstance = [super init];
|
||||
if (sharedInstance) {
|
||||
sharedInstance->_serverEnabled = NO;
|
||||
sharedInstance->_statusGoEndpoint = nil;
|
||||
sharedInstance->_signalEndpoint = nil;
|
||||
sharedInstance->_rootDataDir = nil;
|
||||
sharedInstance->_webSocket = nil;
|
||||
}
|
||||
});
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone {
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)serverEnabled {
|
||||
return _serverEnabled;
|
||||
}
|
||||
|
||||
- (NSString *)statusGoEndpoint {
|
||||
return _statusGoEndpoint;
|
||||
}
|
||||
|
||||
- (NSString *)signalEndpoint {
|
||||
return _signalEndpoint;
|
||||
}
|
||||
|
||||
- (NSString *)rootDataDir {
|
||||
return _rootDataDir;
|
||||
}
|
||||
|
||||
- (void)connectWebSocket {
|
||||
if (!self.serverEnabled || !self.signalEndpoint) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *fullUrl = [NSString stringWithFormat:@"%@", self.signalEndpoint];
|
||||
NSURL *url = [NSURL URLWithString:fullUrl];
|
||||
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
|
||||
self.webSocket = [session webSocketTaskWithURL:url];
|
||||
|
||||
[self.webSocket resume];
|
||||
[self receiveMessage];
|
||||
}
|
||||
|
||||
- (void)receiveMessage {
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[self.webSocket receiveMessageWithCompletionHandler:^(NSURLSessionWebSocketMessage *message, NSError *error) {
|
||||
__strong typeof(weakSelf) strongSelf = weakSelf;
|
||||
if (!strongSelf || !strongSelf.webSocket) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
NSLog(@"WebSocket error: %@", error);
|
||||
// Attempt to reconnect after error
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
[strongSelf connectWebSocket];
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (message) {
|
||||
if (message.type == NSURLSessionWebSocketMessageTypeString && message.string) {
|
||||
[[Status sharedInstance] handleSignal:message.string];
|
||||
}
|
||||
// Continue receiving messages only if the connection is still active
|
||||
if (strongSelf.webSocket) {
|
||||
[strongSelf receiveMessage];
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)disconnectWebSocket {
|
||||
if (self.webSocket) {
|
||||
[self.webSocket cancel];
|
||||
self.webSocket = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)request:(NSString *)endpoint
|
||||
body:(NSString *)body
|
||||
callback:(void (^)(NSString *response, NSError *error))callback {
|
||||
NSString *fullUrlString = [NSString stringWithFormat:@"%@%@", self.statusGoEndpoint, endpoint];
|
||||
NSURL *url = [NSURL URLWithString:fullUrlString];
|
||||
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
|
||||
request.HTTPMethod = @"POST";
|
||||
[request setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
|
||||
|
||||
NSData *bodyData = [body dataUsingEncoding:NSUTF8StringEncoding];
|
||||
request.HTTPBody = bodyData;
|
||||
|
||||
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
|
||||
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
|
||||
|
||||
NSURLSessionDataTask *task = [session dataTaskWithRequest:request
|
||||
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
|
||||
if (error) {
|
||||
NSLog(@"request error: %@", error);
|
||||
callback(nil, error);
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
callback(responseString, nil);
|
||||
}];
|
||||
|
||||
[task resume];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(configStatusBackendServer:(BOOL)serverEnabled
|
||||
statusGoEndpoint:(NSString *)statusGoEndpoint
|
||||
signalEndpoint:(NSString *)signalEndpoint
|
||||
rootDataDir:(NSString *)rootDataDir) {
|
||||
[self configureWithEnabled:serverEnabled
|
||||
statusGoEndpoint:statusGoEndpoint
|
||||
signalEndpoint:signalEndpoint
|
||||
rootDataDir:rootDataDir];
|
||||
}
|
||||
|
||||
- (void)configureWithEnabled:(BOOL)serverEnabled
|
||||
statusGoEndpoint:(NSString *)statusGoEndpoint
|
||||
signalEndpoint:(NSString *)signalEndpoint
|
||||
rootDataDir:(NSString *)rootDataDir {
|
||||
_serverEnabled = serverEnabled;
|
||||
|
||||
if (serverEnabled) {
|
||||
_statusGoEndpoint = statusGoEndpoint;
|
||||
_signalEndpoint = signalEndpoint;
|
||||
_rootDataDir = rootDataDir;
|
||||
[self connectWebSocket];
|
||||
} else {
|
||||
[self disconnectWebSocket];
|
||||
_statusGoEndpoint = nil;
|
||||
_signalEndpoint = nil;
|
||||
_rootDataDir = nil;
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)executeStatusGoRequest:(NSString *)endpoint
|
||||
body:(NSString *)body
|
||||
statusgoFunction:(NSString * (^)(void))statusgoFunction {
|
||||
StatusBackendClient *client = [StatusBackendClient sharedInstance];
|
||||
if (client.serverEnabled) {
|
||||
[client request:endpoint body:body callback:^(NSString *response, NSError *error) {
|
||||
[Utils handleStatusGoResponse:response source:endpoint error:error];
|
||||
}];
|
||||
} else {
|
||||
NSString *result = statusgoFunction();
|
||||
[Utils handleStatusGoResponse:result source:endpoint error:nil];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)executeStatusGoRequestWithCallback:(NSString *)endpoint
|
||||
body:(NSString *)body
|
||||
statusgoFunction:(NSString * (^)(void))statusgoFunction
|
||||
callback:(RCTResponseSenderBlock)callback {
|
||||
StatusBackendClient *client = [StatusBackendClient sharedInstance];
|
||||
if (client.serverEnabled) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
[client request:endpoint body:body callback:^(NSString *response, NSError *error) {
|
||||
if (error) {
|
||||
NSLog(@"request to %@ failed: %@", endpoint, error);
|
||||
if (callback) {
|
||||
callback(@[@(NO)]);
|
||||
}
|
||||
} else {
|
||||
if (callback) {
|
||||
callback(@[response]);
|
||||
}
|
||||
}
|
||||
}];
|
||||
});
|
||||
} else {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
NSString *result = statusgoFunction();
|
||||
if (callback) {
|
||||
callback(@[result]);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSString *)executeStatusGoRequestWithResult:(NSString *)endpoint
|
||||
body:(NSString *)body
|
||||
statusgoFunction:(NSString * (^)(void))statusgoFunction {
|
||||
StatusBackendClient *client = [StatusBackendClient sharedInstance];
|
||||
if (client.serverEnabled) {
|
||||
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
|
||||
__block NSString *resultString = @"";
|
||||
|
||||
[client request:endpoint body:body callback:^(NSString *response, NSError *error) {
|
||||
if (error) {
|
||||
NSLog(@"request to %@ failed: %@", endpoint, error);
|
||||
resultString = @"";
|
||||
} else {
|
||||
resultString = response;
|
||||
}
|
||||
dispatch_semaphore_signal(semaphore);
|
||||
}];
|
||||
|
||||
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
|
||||
return resultString;
|
||||
} else {
|
||||
return statusgoFunction();
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -6,13 +6,11 @@
|
||||
|
||||
@interface Utils : NSObject <RCTBridgeModule>
|
||||
|
||||
+ (NSURL *)getRootUrl;
|
||||
+ (NSString *)jsonStringWithPrettyPrint:(BOOL)prettyPrint fromDictionary:(NSDictionary *)dictionary;
|
||||
+ (NSString *)jsonStringWithPrettyPrint:(BOOL)prettyPrint fromArray:(NSArray *)array;
|
||||
+ (NSURL *)getKeyStoreDirForKeyUID:(NSString *)keyUID;
|
||||
+ (NSString *)getExportDbFilePath;
|
||||
+ (NSString *)getKeyUID:(NSString *)jsonString;
|
||||
+ (void)migrateKeystore:(NSString *)accountData password:(NSString *)password;
|
||||
+ (void)handleStatusGoResponse:(NSString *)response source:(NSString *)source error:(NSError *)error;
|
||||
|
||||
@end
|
||||
|
||||
@@ -3,28 +3,11 @@
|
||||
#import "React/RCTEventDispatcher.h"
|
||||
#import "Statusgo.h"
|
||||
#import "Utils.h"
|
||||
#import "StatusBackendClient.h"
|
||||
|
||||
@implementation Utils
|
||||
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
#pragma mark - Private Methods
|
||||
|
||||
+ (NSURL *)getRootUrl {
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSURL *rootUrl;
|
||||
|
||||
StatusBackendClient *client = [StatusBackendClient sharedInstance];
|
||||
if (client.serverEnabled && client.rootDataDir) {
|
||||
rootUrl = [NSURL fileURLWithPath:client.rootDataDir];
|
||||
} else {
|
||||
rootUrl = [[fileManager URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject];
|
||||
}
|
||||
|
||||
return rootUrl;
|
||||
}
|
||||
|
||||
+ (NSString *)jsonStringWithPrettyPrint:(BOOL)prettyPrint fromDictionary:(NSDictionary *)dictionary {
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary
|
||||
@@ -55,7 +38,7 @@ RCT_EXPORT_MODULE();
|
||||
|
||||
+ (NSURL *)getKeyStoreDirForKeyUID:(NSString *)keyUID {
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSURL *rootUrl = [self getRootUrl];
|
||||
NSURL *rootUrl = [[fileManager URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject];
|
||||
|
||||
NSURL *oldKeystoreDir = [rootUrl URLByAppendingPathComponent:@"keystore"];
|
||||
NSURL *multiaccountKeystoreDir = [oldKeystoreDir URLByAppendingPathComponent:keyUID];
|
||||
@@ -74,11 +57,6 @@ RCT_EXPORT_MODULE();
|
||||
}
|
||||
|
||||
+ (NSString *) getExportDbFilePath {
|
||||
StatusBackendClient *client = [StatusBackendClient sharedInstance];
|
||||
if (client.serverEnabled && client.rootDataDir) {
|
||||
return [client.rootDataDir stringByAppendingPathComponent:@"export.db"];
|
||||
}
|
||||
|
||||
NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"export.db"];
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
|
||||
@@ -92,36 +70,17 @@ RCT_EXPORT_MODULE();
|
||||
+ (void) migrateKeystore:(NSString *)accountData
|
||||
password:(NSString *)password {
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSURL *rootUrl =[self getRootUrl];
|
||||
NSURL *rootUrl =[[fileManager
|
||||
URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask]
|
||||
lastObject];
|
||||
|
||||
NSData *jsonData = [accountData dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSError *error;
|
||||
NSDictionary *accountJson = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error parsing accountData: %@", error);
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *keyUID = [self getKeyUID:accountData];
|
||||
NSURL *keyUID = [self getKeyStoreDirForKeyUID:accountData];
|
||||
NSURL *oldKeystoreDir = [rootUrl URLByAppendingPathComponent:@"keystore"];
|
||||
NSURL *multiaccountKeystoreDir = [self getKeyStoreDirForKeyUID:keyUID];
|
||||
NSURL *multiaccountKeystoreDir = [self getKeyStoreDirForKeyUID:keyUID.path];
|
||||
|
||||
NSArray *keys = [fileManager contentsOfDirectoryAtPath:multiaccountKeystoreDir.path error:nil];
|
||||
if (keys.count == 0) {
|
||||
NSDictionary *params = @{
|
||||
@"account": accountJson,
|
||||
@"password": password,
|
||||
@"oldDir": oldKeystoreDir.path,
|
||||
@"newDir": multiaccountKeystoreDir.path
|
||||
};
|
||||
NSData *paramsJsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error creating params JSON: %@", error);
|
||||
return;
|
||||
}
|
||||
NSString *jsonString = [[NSString alloc] initWithData:paramsJsonData encoding:NSUTF8StringEncoding];
|
||||
|
||||
NSString *migrationResult = StatusgoMigrateKeyStoreDirV2(jsonString);
|
||||
NSString *migrationResult = StatusgoMigrateKeyStoreDir(accountData, password, oldKeystoreDir.path, multiaccountKeystoreDir.path);
|
||||
NSLog(@"keystore migration result %@", migrationResult);
|
||||
|
||||
NSString *initKeystoreResult = StatusgoInitKeystore(multiaccountKeystoreDir.path);
|
||||
@@ -130,19 +89,18 @@ RCT_EXPORT_MODULE();
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(backupDisabledDataDir) {
|
||||
StatusBackendClient *client = [StatusBackendClient sharedInstance];
|
||||
if (client.serverEnabled && client.rootDataDir) {
|
||||
return client.rootDataDir;
|
||||
}
|
||||
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSURL *rootUrl = [Utils getRootUrl];
|
||||
NSURL *rootUrl =[[fileManager
|
||||
URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask]
|
||||
lastObject];
|
||||
return rootUrl.path;
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(keystoreDir) {
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSURL *rootUrl =[Utils getRootUrl];
|
||||
NSURL *rootUrl =[[fileManager
|
||||
URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask]
|
||||
lastObject];
|
||||
|
||||
NSURL *commonKeystoreDir = [rootUrl URLByAppendingPathComponent:@"keystore"];
|
||||
|
||||
@@ -152,17 +110,9 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(keystoreDir) {
|
||||
RCT_EXPORT_METHOD(validateMnemonic:(NSString *)seed
|
||||
callback:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"validateMnemonicV2() method called");
|
||||
NSLog(@"validateMnemonic() method called");
|
||||
#endif
|
||||
NSDictionary *params = @{@"mnemonic": seed};
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error creating JSON: %@", error);
|
||||
return;
|
||||
}
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
NSString *result = StatusgoValidateMnemonicV2(jsonString);
|
||||
NSString *result = StatusgoValidateMnemonic(seed);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
@@ -182,17 +132,4 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(validateConnectionString:(NSString *)cs)
|
||||
return StatusgoValidateConnectionString(cs);
|
||||
}
|
||||
|
||||
+ (void)handleStatusGoResponse:(NSString *)response source:(NSString *)source error:(NSError *)error {
|
||||
if (error) {
|
||||
NSLog(@"%@ failed: %@", source, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if ([response hasPrefix:@"{\"error\":\"\""]) {
|
||||
NSLog(@"%@ success: %@", source, response);
|
||||
} else {
|
||||
NSLog(@"%@ failed: %@", source, response);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -761,26 +761,6 @@ void _Logout(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
}
|
||||
|
||||
void _AcceptTerms(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
|
||||
if (args.Length() != 0) {
|
||||
// Throw an Error that is passed back to JavaScript
|
||||
isolate->ThrowException(Exception::TypeError(
|
||||
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for AcceptTerms")));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the argument types
|
||||
|
||||
// Call exported Go function, which returns a C string
|
||||
char *c = AcceptTerms();
|
||||
|
||||
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
|
||||
args.GetReturnValue().Set(ret);
|
||||
delete c;
|
||||
}
|
||||
|
||||
void _HashMessage(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
@@ -2018,7 +1998,6 @@ void init(Local<Object> exports) {
|
||||
NODE_SET_METHOD(exports, "multiAccountStoreAccount", _MultiAccountStoreAccount);
|
||||
NODE_SET_METHOD(exports, "initKeystore", _InitKeystore);
|
||||
NODE_SET_METHOD(exports, "initializeApplication", _InitializeApplication);
|
||||
NODE_SET_METHOD(exports, "acceptTerms", _AcceptTerms);
|
||||
NODE_SET_METHOD(exports, "fleets", _Fleets);
|
||||
NODE_SET_METHOD(exports, "stopCPUProfiling", _StopCPUProfiling);
|
||||
NODE_SET_METHOD(exports, "encodeTransfer", _EncodeTransfer);
|
||||
|
||||
+541
-453
File diff suppressed because it is too large
Load Diff
+13
-55
@@ -315,7 +315,6 @@ 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
|
||||
@@ -340,7 +339,6 @@ 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
|
||||
@@ -383,43 +381,32 @@ 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
|
||||
@@ -587,7 +574,6 @@ 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
|
||||
@@ -597,7 +583,6 @@ 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
|
||||
@@ -609,7 +594,6 @@ 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
|
||||
@@ -626,14 +610,9 @@ 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
|
||||
@@ -806,8 +785,6 @@ 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
|
||||
@@ -821,64 +798,45 @@ 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
|
||||
@@ -890,18 +848,13 @@ 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
|
||||
@@ -910,7 +863,6 @@ 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
|
||||
@@ -922,7 +874,6 @@ 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
|
||||
@@ -932,7 +883,6 @@ 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
|
||||
@@ -944,19 +894,15 @@ 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
|
||||
@@ -1018,8 +964,20 @@ 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:3.5.4
|
||||
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.facebook.react:hermes-android:0.73.5
|
||||
+38
-30
@@ -416,7 +416,6 @@ 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
|
||||
@@ -488,43 +487,32 @@ 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
|
||||
@@ -534,14 +522,9 @@ 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
|
||||
@@ -552,7 +535,6 @@ 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
|
||||
@@ -751,7 +733,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.35.1/error_prone_annotations-2.35.1.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_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
|
||||
@@ -764,7 +746,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.35.1/error_prone_parent-2.35.1.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/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
|
||||
@@ -809,7 +791,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-RC2/protobuf-bom-4.29.0-RC2.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-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
|
||||
@@ -826,7 +808,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-RC2/protobuf-java-4.29.0-RC2.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-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
|
||||
@@ -837,7 +819,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-RC2/protobuf-parent-4.29.0-RC2.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/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
|
||||
@@ -859,7 +841,11 @@ 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
|
||||
@@ -1211,68 +1197,81 @@ 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
|
||||
@@ -1284,21 +1283,27 @@ 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
|
||||
@@ -1321,6 +1326,7 @@ 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
|
||||
@@ -1339,7 +1345,6 @@ 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
|
||||
@@ -1357,7 +1362,6 @@ 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
|
||||
@@ -1387,6 +1391,7 @@ 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
|
||||
@@ -1396,13 +1401,16 @@ 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
|
||||
@@ -1412,7 +1420,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.3/junit-bom-5.11.3.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/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,10 +42,22 @@ function gen_deps_list() {
|
||||
# https://github.com/status-im/status-mobile/issues/15447
|
||||
function add_deps_hack() {
|
||||
echo -n \
|
||||
'org.gradle.toolchains.foojay-resolver-convention:org.gradle.toolchains.foojay-resolver-convention.gradle.plugin:0.5.0
|
||||
'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:3.5.4
|
||||
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.facebook.react:hermes-android:0.73.5' \
|
||||
>> "${DEPS_LIST}"
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
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"
|
||||
|
||||
@@ -16,11 +15,23 @@ GRADLE_LOG_FILE='/tmp/gradle.log'
|
||||
function show_gradle_log() { cat "${GRADLE_LOG_FILE}" >&2; }
|
||||
trap show_gradle_log ERR
|
||||
|
||||
./gradlew -I init.gradle \
|
||||
--dependency-verification=off \
|
||||
--no-configuration-cache --no-configure-on-demand \
|
||||
:ForceDependencyResolutionPlugin_resolveAllDependencies > "${GRADLE_LOG_FILE}" 2>&1
|
||||
# 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
|
||||
|
||||
# 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"
|
||||
# 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}"
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# 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]
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -56,7 +56,7 @@ in {
|
||||
yarn = super.yarn.override { nodejs = super.nodejs_20; };
|
||||
openjdk = super.openjdk17_headless;
|
||||
xcodeWrapper = callPackage ./pkgs/xcodeenv/compose-xcodewrapper.nix { } {
|
||||
versions = ["15.1" "15.2" "15.3" "15.4" "16.0"];
|
||||
versions = ["15.1" "15.2" "15.3" "15.4"];
|
||||
};
|
||||
go = super.go_1_21;
|
||||
clang = super.clang_15;
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@
|
||||
"react-native-get-random-values": "^1.11.0",
|
||||
"react-native-gifted-charts": "^1.3.2",
|
||||
"react-native-hole-view": "^3.0.0-alpha4",
|
||||
"react-native-image-crop-picker": "0.41.2",
|
||||
"react-native-image-crop-picker": "0.40.0",
|
||||
"react-native-image-resizer": "^1.2.3",
|
||||
"react-native-keychain": "8.1.2",
|
||||
"react-native-linear-gradient": "3.0.0-alpha.1",
|
||||
|
||||
+55
-62
@@ -51,60 +51,55 @@
|
||||
;; the target files (a.k.a hot reload). When false, you can manually
|
||||
;; reload by calling `shadow.cljs.devtools.api/watch-compile-all!`.
|
||||
:devtools {:autobuild #shadow/env ["SHADOW_AUTOBUILD_ENABLED" :default true :as :bool]}
|
||||
:dev
|
||||
{:devtools {:before-load-async status-im.setup.hot-reload/before-reload
|
||||
:after-load-async status-im.setup.hot-reload/reload
|
||||
:build-notify status-im.setup.hot-reload/build-notify
|
||||
:preloads [;; The official recommendation is to
|
||||
;; load the debugger preload first.
|
||||
flow-storm.api
|
||||
re-frisk-remote.preload
|
||||
status-im.setup.schema-preload
|
||||
;; In order to use component test helpers in the REPL we need to
|
||||
;; preload namespaces that are not normally required by
|
||||
;; production code, such as @testing-library/react-native.
|
||||
test-helpers.component]}
|
||||
:closure-defines
|
||||
{status-im.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
|
||||
status-im.config/INFURA_TOKEN #shadow/env "INFURA_TOKEN"
|
||||
status-im.config/STATUS_BUILD_PROXY_USER #shadow/env "STATUS_BUILD_PROXY_USER"
|
||||
status-im.config/STATUS_BUILD_PROXY_PASSWORD #shadow/env "STATUS_BUILD_PROXY_PASSWORD"
|
||||
status-im.config/STATUS_BACKEND_SERVER_ENABLED #shadow/env "STATUS_BACKEND_SERVER_ENABLED"
|
||||
status-im.config/STATUS_BACKEND_SERVER_HOST #shadow/env "STATUS_BACKEND_SERVER_HOST"
|
||||
status-im.config/STATUS_BACKEND_SERVER_ROOT_DATA_DIR #shadow/env
|
||||
"STATUS_BACKEND_SERVER_ROOT_DATA_DIR"
|
||||
status-im.config/MIXPANEL_APP_ID #shadow/env "MIXPANEL_APP_ID"
|
||||
status-im.config/MIXPANEL_TOKEN #shadow/env "MIXPANEL_TOKEN"
|
||||
status-im.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"
|
||||
status-im.config/RARIBLE_MAINNET_API_KEY #shadow/env "RARIBLE_MAINNET_API_KEY"
|
||||
status-im.config/RARIBLE_TESTNET_API_KEY #shadow/env "RARIBLE_TESTNET_API_KEY"
|
||||
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
|
||||
;; are managing deprecation via clj-kondo and we
|
||||
;; don't want the terminal output to be littered
|
||||
;; with warnings on every code reload.
|
||||
:warnings {:fn-deprecated false}
|
||||
:closure-defines {re-frame.trace/trace-enabled? true}
|
||||
:source-map false
|
||||
;; This seems to be necessary while using the REPL,
|
||||
;; otherwise sometimes you'll get weird errors when
|
||||
;; instrumenting functions.
|
||||
:static-fns false
|
||||
:infer-externs true
|
||||
:reader-features #{:mobile}}
|
||||
;; if you want to use a real device, set your local ip
|
||||
;; in the SHADOW_HOST env variable to make sure that
|
||||
;; it will use the right interface
|
||||
:local-ip #shadow/env "SHADOW_HOST"}
|
||||
:dev {:devtools {:before-load-async status-im.setup.hot-reload/before-reload
|
||||
:after-load-async status-im.setup.hot-reload/reload
|
||||
:build-notify status-im.setup.hot-reload/build-notify
|
||||
:preloads [;; The official recommendation is to
|
||||
;; load the debugger preload first.
|
||||
flow-storm.api
|
||||
re-frisk-remote.preload
|
||||
status-im.setup.schema-preload
|
||||
;; In order to use component test helpers in the REPL we
|
||||
;; need to preload namespaces that are not normally required
|
||||
;; by production code, such as
|
||||
;; @testing-library/react-native.
|
||||
test-helpers.component]}
|
||||
:closure-defines
|
||||
{status-im.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
|
||||
status-im.config/INFURA_TOKEN #shadow/env "INFURA_TOKEN"
|
||||
status-im.config/STATUS_BUILD_PROXY_USER #shadow/env "STATUS_BUILD_PROXY_USER"
|
||||
status-im.config/STATUS_BUILD_PROXY_PASSWORD #shadow/env "STATUS_BUILD_PROXY_PASSWORD"
|
||||
status-im.config/MIXPANEL_APP_ID #shadow/env "MIXPANEL_APP_ID"
|
||||
status-im.config/MIXPANEL_TOKEN #shadow/env "MIXPANEL_TOKEN"
|
||||
status-im.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"
|
||||
status-im.config/RARIBLE_MAINNET_API_KEY #shadow/env "RARIBLE_MAINNET_API_KEY"
|
||||
status-im.config/RARIBLE_TESTNET_API_KEY #shadow/env "RARIBLE_TESTNET_API_KEY"
|
||||
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
|
||||
;; are managing deprecation via clj-kondo and we
|
||||
;; don't want the terminal output to be littered
|
||||
;; with warnings on every code reload.
|
||||
:warnings {:fn-deprecated false}
|
||||
:closure-defines {re-frame.trace/trace-enabled? true}
|
||||
:source-map false
|
||||
;; This seems to be necessary while using the REPL,
|
||||
;; otherwise sometimes you'll get weird errors when
|
||||
;; instrumenting functions.
|
||||
:static-fns false
|
||||
:infer-externs true}
|
||||
;; if you want to use a real device, set your local ip
|
||||
;; in the SHADOW_HOST env variable to make sure that
|
||||
;; it will use the right interface
|
||||
:local-ip #shadow/env "SHADOW_HOST"}
|
||||
:chunks {:fleets legacy.status-im.fleet.default-fleet/default-fleets}
|
||||
:release
|
||||
{:closure-defines
|
||||
@@ -134,8 +129,7 @@
|
||||
:static-fns true
|
||||
:fn-invoke-direct true
|
||||
:optimizations :advanced
|
||||
:js-options {:js-provider :closure}
|
||||
:reader-features #{:mobile}}}}
|
||||
:js-options {:js-provider :closure}}}}
|
||||
;; the tests are ran with node, react-native dependencies are mocked
|
||||
;; by using node --require override.js, which uses the node-library
|
||||
;; produced by the target :mocks below and redefines node require
|
||||
@@ -175,13 +169,12 @@
|
||||
{;; needed because we override require and it
|
||||
;; messes with source-map which reports callstack
|
||||
;; exceeded exceptions instead of real issues
|
||||
:source-map false
|
||||
:source-map false
|
||||
;; needed because we use deref in tests
|
||||
:static-fns false
|
||||
:optimizations :simple
|
||||
:warnings {:fn-deprecated false}
|
||||
:infer-externs true
|
||||
:reader-features #{:mobile}}}
|
||||
:static-fns false
|
||||
:optimizations :simple
|
||||
:warnings {:fn-deprecated false}
|
||||
:infer-externs true}}
|
||||
|
||||
;; mock.js-dependencies is mocking the react-native libraries
|
||||
;; we build it as a node library so that it can be required by
|
||||
|
||||
@@ -79,12 +79,6 @@
|
||||
(types/clj->json request)
|
||||
#(callback (types/json->clj %))))
|
||||
|
||||
(defn accept-terms
|
||||
([]
|
||||
(native-utils/promisify-native-module-call accept-terms))
|
||||
([callback]
|
||||
(.acceptTerms ^js (account-manager) callback)))
|
||||
|
||||
(defn prepare-dir-and-update-config
|
||||
[key-uid config callback]
|
||||
(log/debug "[native-module] prepare-dir-and-update-config")
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
:seed :i/seed
|
||||
:key :i/password
|
||||
nil)
|
||||
:color :neutral
|
||||
:blur? true
|
||||
:border? true}]
|
||||
[rn/view
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.common.confirmation-drawer.style :as style]
|
||||
[status-im.constants :as constants]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -36,12 +35,11 @@
|
||||
close-button-text]}]
|
||||
(let [extra-action-selected? (reagent/atom false)]
|
||||
(fn []
|
||||
(let [{:keys [group-chat chat-id public-key color chat-type
|
||||
(let [{:keys [group-chat chat-id public-key color
|
||||
profile-picture name]} context
|
||||
id (or chat-id public-key)
|
||||
theme (quo.theme/use-theme)
|
||||
[primary-name _] (when-not (or group-chat
|
||||
(= chat-type constants/public-chat-type))
|
||||
[primary-name _] (when-not group-chat
|
||||
(rf/sub [:contacts/contact-two-names-by-identity id]))
|
||||
display-name (cond
|
||||
(= primary-name "Unknown")
|
||||
|
||||
@@ -232,11 +232,12 @@
|
||||
:sub-label nil
|
||||
:chevron? false})))
|
||||
|
||||
;; TODO(OmarBasem): Requires design input.
|
||||
(defn edit-name-image-entry
|
||||
[chat-id]
|
||||
[]
|
||||
(entry {:icon :i/edit
|
||||
:label (i18n/label :t/edit-name-and-image)
|
||||
:on-press #(rf/dispatch [:open-modal :screen/group-update chat-id])
|
||||
:on-press #(js/alert "TODO: to be implemented, requires design input")
|
||||
:danger? false
|
||||
:accessibility-label :edit-name-and-image
|
||||
:sub-label nil
|
||||
@@ -358,7 +359,7 @@
|
||||
(rf/dispatch [:chats-list/load-chat chat-id])
|
||||
(rf/dispatch [:pin-message/load-pin-messages chat-id])
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(rf/dispatch [:navigate-to :screen/group-details chat-id]))
|
||||
(rf/dispatch [:navigate-to :group-details chat-id]))
|
||||
:danger? false
|
||||
:accessibility-label :group-details
|
||||
:sub-label nil
|
||||
@@ -368,17 +369,18 @@
|
||||
[chat-id admin?]
|
||||
(entry {:icon :i/add-user
|
||||
:label (i18n/label (if admin? :t/manage-members :t/add-members))
|
||||
:on-press #(rf/dispatch [:open-modal :screen/group-add-manage-members chat-id])
|
||||
:on-press #(rf/dispatch [:open-modal :group-add-manage-members chat-id])
|
||||
:danger? false
|
||||
:accessibility-label :manage-members
|
||||
:sub-label nil
|
||||
:chevron? false}))
|
||||
|
||||
;; TODO(OmarBasem): to be implemented.
|
||||
(defn edit-group-entry
|
||||
[chat-id]
|
||||
[]
|
||||
(entry {:icon :i/edit
|
||||
:label (i18n/label :t/edit-name-and-image)
|
||||
:on-press #(rf/dispatch [:open-modal :screen/group-update chat-id])
|
||||
:on-press #(js/alert "TODO: to be implemented")
|
||||
:danger? false
|
||||
:accessibility-label :edit-group
|
||||
:sub-label nil
|
||||
@@ -396,11 +398,10 @@
|
||||
:chevron? false}))
|
||||
|
||||
(defn destructive-actions
|
||||
[{:keys [group-chat chat-type] :as item} inside-chat?]
|
||||
[{:keys [group-chat] :as item} inside-chat?]
|
||||
[(when (not group-chat)
|
||||
(close-chat-entry item inside-chat? (not= chat-type constants/public-chat-type)))
|
||||
(when-not (= chat-type constants/public-chat-type)
|
||||
(clear-history-entry item group-chat))
|
||||
(close-chat-entry item inside-chat? (not group-chat)))
|
||||
(clear-history-entry item group-chat)
|
||||
(when group-chat
|
||||
(leave-group-entry item nil))])
|
||||
|
||||
@@ -424,7 +425,8 @@
|
||||
(when inside-chat?
|
||||
(add-manage-members-entry chat-id admin?))
|
||||
(when (and admin? inside-chat?)
|
||||
(edit-group-entry chat-id))
|
||||
(when config/show-not-implemented-features?
|
||||
(edit-group-entry)))
|
||||
(when (and admin? inside-chat?)
|
||||
(when config/show-not-implemented-features?
|
||||
(group-privacy-entry)))]))
|
||||
@@ -436,11 +438,6 @@
|
||||
(notification-actions item inside-chat? true)
|
||||
(destructive-actions item inside-chat?)]])
|
||||
|
||||
(defn public-chat-actions
|
||||
[item inside-chat?]
|
||||
[quo/action-drawer
|
||||
[(destructive-actions item inside-chat?)]])
|
||||
|
||||
(defn private-group-chat-actions
|
||||
[item inside-chat?]
|
||||
[quo/action-drawer
|
||||
@@ -476,8 +473,6 @@
|
||||
[one-to-one-actions chat inside-chat?]
|
||||
constants/private-group-chat-type
|
||||
[private-group-chat-actions chat inside-chat?]
|
||||
constants/public-chat-type
|
||||
[public-chat-actions chat inside-chat?]
|
||||
constants/community-chat-type
|
||||
[communities-chat-actions/actions chat inside-chat? hide-show-members?]
|
||||
nil))
|
||||
@@ -485,12 +480,13 @@
|
||||
(chat-actions chat inside-chat? nil)))
|
||||
|
||||
(defn group-details-actions
|
||||
[{:keys [chat-id admins] :as group}]
|
||||
[{:keys [admins] :as group}]
|
||||
(let [current-pub-key (rf/sub [:multiaccount/public-key])
|
||||
admin? (get admins current-pub-key)]
|
||||
[quo/action-drawer
|
||||
[(when admin?
|
||||
[(edit-name-image-entry chat-id)])
|
||||
[(when config/show-not-implemented-features?
|
||||
(edit-name-image-entry))])
|
||||
[(when config/show-not-implemented-features?
|
||||
(notifications-entry admin?))]
|
||||
(destructive-actions group false)]]))
|
||||
|
||||
@@ -134,14 +134,3 @@
|
||||
;; Alert banners are disabled for debug builds because alert banners overlay
|
||||
;; interfere with react-native debug tools, such as inspector and Perf monitor
|
||||
(def enable-alert-banner? (enabled? (get-config :ENABLE_ALERT_BANNER "0")))
|
||||
|
||||
;; enable using status backend server or not, otherwise it will use built-in status-go library
|
||||
;; see doc/use-status-backend-server.md for more details
|
||||
(goog-define STATUS_BACKEND_SERVER_ENABLED "0")
|
||||
;; The host should contain an IP address and a port separated by a colon.
|
||||
;; The port comes from your running status backend server.
|
||||
;; If you run it by PORT=60000 make run-status-backend , then host will likely be 127.0.0.1:60000
|
||||
(goog-define STATUS_BACKEND_SERVER_HOST "")
|
||||
;; /path/to/root/data/dir
|
||||
;; make sure it exists, it should be in absolute path
|
||||
(goog-define STATUS_BACKEND_SERVER_ROOT_DATA_DIR "")
|
||||
|
||||
@@ -566,7 +566,6 @@
|
||||
(def ^:const bridge-name-erc-1155-transfer "ERC1155Transfer")
|
||||
(def ^:const bridge-name-hop "Hop")
|
||||
(def ^:const bridge-name-paraswap "Paraswap")
|
||||
(def ^:const bridge-name-celer "CBridge")
|
||||
|
||||
(def ^:const bridge-assets #{"ETH" "USDT" "USDC" "DAI"})
|
||||
|
||||
|
||||
@@ -14,13 +14,10 @@
|
||||
|
||||
(defn centralized-metrics-interceptor
|
||||
[context]
|
||||
(when (push-event? (interceptor/get-coeffect context :db))
|
||||
(when-let [event (tracking/metrics-event (interceptor/get-coeffect context :event))]
|
||||
(log/debug "tracking event" event)
|
||||
(if (or (seq? event) (vector? event))
|
||||
(doseq [e event]
|
||||
(native-module/add-centralized-metric e))
|
||||
(native-module/add-centralized-metric event))))
|
||||
(when-let [event (tracking/tracked-event (interceptor/get-coeffect context :event))]
|
||||
(log/debug "tracking event" event)
|
||||
(when (push-event? (interceptor/get-coeffect context :db))
|
||||
(native-module/add-centralized-metric event)))
|
||||
context)
|
||||
|
||||
(def interceptor
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
(deftest centralized-metrics-interceptor-test
|
||||
(testing "processes context correctly"
|
||||
(with-redefs [tracking/metrics-event (fn [_] {:metric "mocked-event"})
|
||||
(with-redefs [tracking/tracked-event (fn [_] {:metric "mocked-event"})
|
||||
events/push-event? (fn [_] true)]
|
||||
(let [context {:coeffects {:event [:some-event]
|
||||
:db {:centralized-metrics/enabled? true}}}]
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
(ns status-im.contexts.centralized-metrics.tracking
|
||||
(:require
|
||||
[clojure.string]
|
||||
[legacy.status-im.utils.build :as build]
|
||||
[react-native.platform :as platform]
|
||||
[status-im.navigation.screens :as screens]))
|
||||
[react-native.platform :as platform]))
|
||||
|
||||
(defn key-value-event
|
||||
[event-name event-value]
|
||||
@@ -21,54 +19,47 @@
|
||||
[view-id]
|
||||
(key-value-event "navigation" {:viewId view-id}))
|
||||
|
||||
(defn screen-event
|
||||
[screen event-data]
|
||||
(let [screen-id (:name screen)
|
||||
view-id (get-in screen [:metrics :alias-id] screen-id)]
|
||||
{:metric
|
||||
{:eventName "navigation"
|
||||
:platform platform/os
|
||||
:appVersion build/app-short-version
|
||||
:eventValue (assoc event-data :viewId (name view-id))}}))
|
||||
|
||||
(def ^:const app-started-event "app-started")
|
||||
|
||||
(def ^:const view-ids-to-track
|
||||
#{;; Tabs
|
||||
:communities-stack
|
||||
:chats-stack
|
||||
:wallet-stack})
|
||||
:wallet-stack
|
||||
|
||||
;; Onboarding
|
||||
:screen/onboarding.intro
|
||||
:screen/onboarding.new-to-status
|
||||
:screen/onboarding.sync-or-recover-profile
|
||||
:screen/onboarding.enter-seed-phrase
|
||||
:screen/onboarding.create-profile
|
||||
:screen/onboarding.create-profile-password
|
||||
:screen/onboarding.enable-biometrics
|
||||
:screen/onboarding.generating-keys
|
||||
:screen/onboarding.enable-notifications
|
||||
:screen/onboarding.preparing-status
|
||||
:screen/onboarding.sign-in-intro
|
||||
:screen/onboarding.sign-in
|
||||
:screen/onboarding.syncing-progress
|
||||
:screen/onboarding.syncing-progress-intro
|
||||
:screen/onboarding.syncing-results
|
||||
:screen/onboarding.welcome})
|
||||
|
||||
(defn track-view-id-event
|
||||
[view-id]
|
||||
(if-let [screen (get screens/screens-by-name view-id)]
|
||||
(when (get-in screen [:metrics :track?])
|
||||
(screen-event screen {}))
|
||||
(when (contains? view-ids-to-track view-id)
|
||||
(navigation-event (name view-id)))))
|
||||
(when (contains? view-ids-to-track view-id)
|
||||
(navigation-event (name view-id))))
|
||||
|
||||
(defn navigated-to-collectibles-tab-event
|
||||
[location]
|
||||
(key-value-event "navigated-to-collectibles-tab" {:location location}))
|
||||
|
||||
(defn metrics-event
|
||||
[[rf-event-name rf-event-parameter]]
|
||||
(case rf-event-name
|
||||
(defn tracked-event
|
||||
[[event-name second-parameter]]
|
||||
(case event-name
|
||||
:profile/get-profiles-overview-success
|
||||
(user-journey-event app-started-event)
|
||||
|
||||
:centralized-metrics/toggle-centralized-metrics
|
||||
(key-value-event "events.metrics-enabled" {:enabled rf-event-parameter})
|
||||
(key-value-event "events.metrics-enabled" {:enabled second-parameter})
|
||||
|
||||
:set-view-id
|
||||
(track-view-id-event rf-event-parameter)
|
||||
|
||||
:wallet/select-account-tab
|
||||
(when (= rf-event-parameter :collectibles)
|
||||
(navigated-to-collectibles-tab-event :account))
|
||||
|
||||
:wallet/select-home-tab
|
||||
(when (= rf-event-parameter :collectibles)
|
||||
(navigated-to-collectibles-tab-event :home))
|
||||
(track-view-id-event second-parameter)
|
||||
|
||||
nil))
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
{:eventName "navigation"
|
||||
:platform platform-os
|
||||
:appVersion app-version
|
||||
:eventValue {:viewId "onboarding.create-profile-info"}}}
|
||||
:eventValue {:viewId "onboarding.create-profile"}}}
|
||||
(tracking/track-view-id-event :screen/onboarding.create-profile)))
|
||||
(is (nil? (tracking/track-view-id-event :unknown-stack)))))
|
||||
|
||||
@@ -63,23 +63,17 @@
|
||||
:platform platform-os
|
||||
:appVersion app-version
|
||||
:eventValue {:action tracking/app-started-event}}}
|
||||
(tracking/metrics-event [:profile/get-profiles-overview-success])))
|
||||
(tracking/tracked-event [:profile/get-profiles-overview-success])))
|
||||
(is (= {:metric
|
||||
{:eventName "events.metrics-enabled"
|
||||
:platform platform-os
|
||||
:appVersion app-version
|
||||
:eventValue {:enabled true}}}
|
||||
(tracking/metrics-event [:centralized-metrics/toggle-centralized-metrics true])))
|
||||
(tracking/tracked-event [:centralized-metrics/toggle-centralized-metrics true])))
|
||||
(is (= {:metric
|
||||
{:eventName "navigation"
|
||||
:platform platform-os
|
||||
:appVersion app-version
|
||||
:eventValue {:viewId "wallet-stack"}}}
|
||||
(tracking/metrics-event [:set-view-id :wallet-stack])))
|
||||
(is (nil? (tracking/metrics-event [:unknown-event])))
|
||||
(is (= {:metric
|
||||
{:eventName "navigation"
|
||||
:platform platform-os
|
||||
:appVersion app-version
|
||||
:eventValue {:viewId "onboarding.intro"}}}
|
||||
(tracking/metrics-event [:set-view-id :screen/onboarding.intro])))))
|
||||
(tracking/tracked-event [:set-view-id :wallet-stack])))
|
||||
(is (nil? (tracking/tracked-event [:unknown-event])))))
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.chat.contacts.events :as contacts-store]
|
||||
status-im.contexts.chat.effects
|
||||
status-im.contexts.chat.group.events
|
||||
status-im.contexts.chat.group-create.events
|
||||
[status-im.contexts.chat.messenger.composer.link-preview.events :as link-preview]
|
||||
status-im.contexts.chat.messenger.messages.content.reactions.events
|
||||
[status-im.contexts.chat.messenger.messages.delete-message-for-me.events :as delete-for-me]
|
||||
@@ -33,8 +33,8 @@
|
||||
(multi-user-chat? (get-chat cofx chat-id))))
|
||||
|
||||
(defn public-chat?
|
||||
([{:keys [chat-type]}]
|
||||
(= chat-type constants/public-chat-type))
|
||||
([chat]
|
||||
(:public? chat))
|
||||
([cofx chat-id]
|
||||
(public-chat? (get-chat cofx chat-id))))
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
(defn group-chat?
|
||||
([chat]
|
||||
(and (multi-user-chat? chat)
|
||||
(not (:public? chat))))
|
||||
(not (public-chat? chat))))
|
||||
([cofx chat-id]
|
||||
(group-chat? (get-chat cofx chat-id))))
|
||||
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
(ns status-im.contexts.chat.group.create.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.foundations.colors :as colors]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.chat.group.common.group-edit :as group-edit]
|
||||
[status-im.contexts.profile.utils :as profile.utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[{:keys [close]}]
|
||||
(let [contacts (rf/sub [:selected-group-contacts])
|
||||
contact-string (string/join ", " (map profile.utils/displayed-name contacts))
|
||||
default-group-name (subs contact-string
|
||||
0
|
||||
(min (count contact-string) constants/max-group-chat-name-length))
|
||||
profile (rf/sub [:profile/profile-with-image])
|
||||
contacts (conj contacts profile)]
|
||||
[group-edit/view
|
||||
{:default-group-name default-group-name
|
||||
:default-group-color (rand-nth colors/account-colors)
|
||||
:contacts contacts
|
||||
:submit-button-label (i18n/label :t/create-group-chat)
|
||||
:submit-event :group-chat/create
|
||||
:back-button-icon :i/arrow-left
|
||||
:close close}]))
|
||||
@@ -1,23 +0,0 @@
|
||||
(ns status-im.contexts.chat.group.update.view
|
||||
(:require
|
||||
[status-im.contexts.chat.group.common.group-edit :as group-edit]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[{:keys [close]}]
|
||||
(let [chat-id (rf/sub [:get-screen-params :screen/group-update])
|
||||
{:keys [chat-name color image]} (rf/sub [:chats/chat-by-id chat-id])
|
||||
contacts (rf/sub [:contacts/contacts-by-chat chat-id])]
|
||||
[group-edit/view
|
||||
{:default-group-name chat-name
|
||||
:default-group-color color
|
||||
:default-group-image image
|
||||
:contacts contacts
|
||||
:submit-button-label (i18n/label :t/update-group-chat)
|
||||
:submit-event :group-chat/edit
|
||||
:back-button-icon :i/close
|
||||
:chat-id chat-id
|
||||
:close close
|
||||
:on-success close
|
||||
:editing-group? true}]))
|
||||
+18
-16
@@ -1,12 +1,12 @@
|
||||
(ns status-im.contexts.chat.group.events
|
||||
(ns status-im.contexts.chat.group-create.events
|
||||
(:require [clojure.string :as string]
|
||||
[legacy.status-im.data-store.chats :as data-store.chats]
|
||||
[oops.core :as oops]
|
||||
[re-frame.core :as rf]
|
||||
[status-im.common.avatar-picture-picker.view :as avatar-picture-picker]
|
||||
[taoensso.timbre :as log]))
|
||||
[status-im.common.avatar-picture-picker.view :as avatar-picture-picker]))
|
||||
|
||||
(rf/reg-event-fx :group-chat/create
|
||||
(fn [{:keys [db]} [{:keys [group-name group-color group-image]}]]
|
||||
(fn [{:keys [db]} [group-name color image]]
|
||||
(let [selected-contacts (:group/selected-contacts db)]
|
||||
{:json-rpc/call [{:method "wakuext_createGroupChatWithMembers"
|
||||
:params [nil group-name (into [] selected-contacts)]
|
||||
@@ -17,23 +17,25 @@
|
||||
(oops/oget :id))]
|
||||
(rf/dispatch [:chat-updated response])
|
||||
(rf/dispatch [:group-chat/edit
|
||||
{:chat-id chat-id
|
||||
:group-name group-name
|
||||
:group-color group-color
|
||||
:group-image group-image}])))}]})))
|
||||
{:chat-id chat-id
|
||||
:group-name group-name
|
||||
:color color
|
||||
:image image}])))}]})))
|
||||
|
||||
(rf/reg-event-fx :group-chat/edit-success
|
||||
(fn [{:keys [db]} [{:keys [chat-id name color image]}]]
|
||||
(let [new-chat {:name name :color color :image image}]
|
||||
{:db (update-in db [:chats chat-id] #(merge % new-chat))})))
|
||||
|
||||
(rf/reg-event-fx :group-chat/edit
|
||||
(fn [_ [{:keys [chat-id group-name group-color group-image on-success]}]]
|
||||
(fn [_ [{:keys [chat-id group-name color image]}]]
|
||||
{:json-rpc/call [{:method "chat_editChat"
|
||||
:params ["" chat-id group-name (name group-color)
|
||||
{:imagePath (when group-image
|
||||
(string/replace-first group-image #"file://" ""))
|
||||
:params ["" chat-id group-name (name color)
|
||||
{:imagePath (when image (string/replace-first image #"file://" ""))
|
||||
:x 0
|
||||
:y 0
|
||||
:width avatar-picture-picker/crop-size
|
||||
:height avatar-picture-picker/crop-size}]
|
||||
:js-response true
|
||||
:on-error #(log/error "failed to edit group" {:error %})
|
||||
:on-success (fn [response]
|
||||
(rf/dispatch [:chat-updated response true])
|
||||
(when on-success (on-success)))}]}))
|
||||
:on-success #(rf/dispatch [:group-chat/edit-success
|
||||
(data-store.chats/<-rpc-js %)])}]}))
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
(ns status-im.contexts.chat.group.common.style
|
||||
(ns status-im.contexts.chat.group-create.style
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(def avatar {:width 88 :margin-top 12 :margin-left 20})
|
||||
+35
-32
@@ -1,11 +1,13 @@
|
||||
(ns status-im.contexts.chat.group.common.group-edit
|
||||
(:require [quo.core :as quo]
|
||||
(ns status-im.contexts.chat.group-create.view
|
||||
(:require [clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.avatar-picture-picker.view :as avatar-picture-picker]
|
||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.chat.group.common.style :as style]
|
||||
[status-im.contexts.chat.group-create.style :as style]
|
||||
[status-im.contexts.profile.utils :as profile.utils]
|
||||
[utils.debounce :as debounce]
|
||||
utils.emojilib
|
||||
@@ -39,28 +41,35 @@
|
||||
:i/camera]]))
|
||||
|
||||
(defn view
|
||||
[{:keys [default-group-name default-group-color default-group-image contacts
|
||||
submit-button-label submit-event back-button-icon chat-id close on-success editing-group?]}]
|
||||
[]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
{window-width :width} (rn/get-window)
|
||||
profile (rf/sub [:profile/profile-with-image])
|
||||
contacts (rf/sub [:selected-group-contacts])
|
||||
contacts-count (count contacts)
|
||||
[group-name set-group-name] (rn/use-state default-group-name)
|
||||
default-value (rn/use-memo
|
||||
(fn []
|
||||
(let [contact-string (string/join ", "
|
||||
(map
|
||||
profile.utils/displayed-name
|
||||
contacts))]
|
||||
(subs contact-string
|
||||
0
|
||||
(min (count contact-string)
|
||||
constants/max-group-chat-name-length))))
|
||||
[])
|
||||
[group-name set-group-name] (rn/use-state default-value)
|
||||
[error-message
|
||||
set-error-message] (rn/use-state nil)
|
||||
group-name-empty? (not (and (string? group-name) (not-empty group-name)))
|
||||
[group-color set-group-color] (rn/use-state default-group-color)
|
||||
[group-image set-group-image] (rn/use-state default-group-image)
|
||||
on-submit (rn/use-callback #(debounce/throttle-and-dispatch
|
||||
[submit-event
|
||||
{:group-name group-name
|
||||
:group-color group-color
|
||||
:group-image (when (not= group-image
|
||||
default-group-image)
|
||||
group-image)
|
||||
:chat-id chat-id
|
||||
:on-success on-success}]
|
||||
[group-color set-group-color] (rn/use-state (rand-nth colors/account-colors))
|
||||
[group-image set-group-image] (rn/use-state nil)
|
||||
create-group-on-press (rn/use-callback #(debounce/throttle-and-dispatch
|
||||
[:group-chat/create group-name group-color
|
||||
group-image]
|
||||
300)
|
||||
[group-name group-color group-image])
|
||||
back-on-press (rn/use-callback #(rf/dispatch [:navigate-back]))
|
||||
on-change-text (rn/use-callback
|
||||
(fn [text]
|
||||
(if (boolean (re-find utils.emojilib/emoji-regex text))
|
||||
@@ -68,13 +77,7 @@
|
||||
{:check (i18n/label
|
||||
:t/emojis)}))
|
||||
(set-error-message nil))
|
||||
(set-group-name text)))
|
||||
disabled? (or group-name-empty?
|
||||
error-message
|
||||
(and editing-group?
|
||||
(= group-name default-group-name)
|
||||
(= group-color default-group-color)
|
||||
(= group-image default-group-image)))]
|
||||
(set-group-name text)))]
|
||||
[floating-button-page/view
|
||||
{:customization-color group-color
|
||||
:gradient-cover? true
|
||||
@@ -82,13 +85,13 @@
|
||||
:header [quo/page-nav
|
||||
{:background :photo
|
||||
:type :no-title
|
||||
:icon-name back-button-icon
|
||||
:on-press close}]
|
||||
:icon-name :i/arrow-left
|
||||
:on-press back-on-press}]
|
||||
:footer [quo/button
|
||||
{:customization-color group-color
|
||||
:disabled? disabled?
|
||||
:on-press on-submit}
|
||||
submit-button-label]}
|
||||
:disabled? (boolean (or group-name-empty? error-message))
|
||||
:on-press create-group-on-press}
|
||||
(i18n/label :t/create-group-chat)]}
|
||||
[:<>
|
||||
[avatar
|
||||
{:customization-color group-color
|
||||
@@ -96,7 +99,7 @@
|
||||
:set-group-image set-group-image}]
|
||||
[quo/title-input
|
||||
{:on-change-text on-change-text
|
||||
:default-value default-group-name
|
||||
:default-value default-value
|
||||
:container-style {:padding-horizontal 20 :padding-top 12 :padding-bottom (if error-message 0 16)}
|
||||
:placeholder (i18n/label :t/name-your-group)
|
||||
:max-length constants/max-group-chat-name-length}]
|
||||
@@ -123,9 +126,9 @@
|
||||
:padding-left (responsiveness/iphone-11-Pro-20-pixel-from-width
|
||||
window-width)}}]]
|
||||
[quo/divider-label
|
||||
(i18n/label :t/n-m-people {:n contacts-count :m constants/max-group-chat-participants})]
|
||||
(i18n/label :t/n-m-people {:n (inc contacts-count) :m constants/max-group-chat-participants})]
|
||||
[rn/view {:style style/tags}
|
||||
(for [contact contacts]
|
||||
(for [contact (conj contacts profile)]
|
||||
^{:key contact}
|
||||
[quo/context-tag
|
||||
{:container-style style/tag
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
(ns status-im.contexts.chat.group.details.style
|
||||
(ns status-im.contexts.chat.group-details.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
+6
-7
@@ -1,4 +1,4 @@
|
||||
(ns status-im.contexts.chat.group.details.view
|
||||
(ns status-im.contexts.chat.group-details.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
@@ -11,7 +11,7 @@
|
||||
[status-im.common.contact-list.view :as contact-list]
|
||||
[status-im.common.home.actions.view :as actions]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.chat.group.details.style :as style]
|
||||
[status-im.contexts.chat.group-details.style :as style]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -54,7 +54,7 @@
|
||||
(let [theme (quo.theme/use-theme)
|
||||
selected-participants (rf/sub [:group-chat/selected-participants])
|
||||
deselected-members (rf/sub [:group-chat/deselected-members])
|
||||
chat-id (rf/sub [:get-screen-params :screen/group-add-manage-members])
|
||||
chat-id (rf/sub [:get-screen-params :group-add-manage-members])
|
||||
{:keys [admins] :as group} (rf/sub [:chats/chat-by-id chat-id])
|
||||
current-pk (rf/sub [:multiaccount/public-key])
|
||||
admin? (get admins current-pk)]
|
||||
@@ -123,9 +123,9 @@
|
||||
[_]
|
||||
[rn/view {:style {:height 8}}])
|
||||
|
||||
(defn view
|
||||
(defn group-details
|
||||
[]
|
||||
(let [chat-id (rf/sub [:get-screen-params :screen/group-details])
|
||||
(let [chat-id (rf/sub [:get-screen-params :group-details])
|
||||
{:keys [admins chat-id chat-name color muted contacts image]
|
||||
:as group} (rf/sub [:chats/chat-by-id chat-id])
|
||||
members (rf/sub [:contacts/group-members-sections chat-id])
|
||||
@@ -176,8 +176,7 @@
|
||||
:icon :i/add-user
|
||||
:label (i18n/label (if admin? :t/manage-members :t/add-members))
|
||||
:counter-value (count contacts)
|
||||
:on-press #(rf/dispatch [:open-modal
|
||||
:screen/group-add-manage-members
|
||||
:on-press #(rf/dispatch [:open-modal :group-add-manage-members
|
||||
chat-id])}]}]
|
||||
[rn/section-list
|
||||
{:key-fn :title
|
||||
@@ -237,17 +237,11 @@
|
||||
|
||||
(defn chat-item
|
||||
[{:keys [chat-id group-chat color name last-message timestamp muted image
|
||||
chat-type unviewed-messages-count]
|
||||
unviewed-messages-count]
|
||||
:as item}]
|
||||
(let [[primary-name secondary-name]
|
||||
(cond
|
||||
group-chat
|
||||
(if group-chat
|
||||
[name ""]
|
||||
|
||||
(= chat-type constants/public-chat-type)
|
||||
[(str "#" name) ""]
|
||||
|
||||
:else
|
||||
(rf/sub [:contacts/contact-two-names-by-identity chat-id]))
|
||||
{:keys [ens-verified added?] :as contact} (when-not group-chat
|
||||
(rf/sub [:contacts/contact-by-address chat-id]))
|
||||
|
||||
@@ -149,7 +149,7 @@
|
||||
:on-press (fn []
|
||||
(if one-contact-selected?
|
||||
(rf/dispatch [:chat.ui/start-chat public-key])
|
||||
(rf/dispatch [:open-modal :screen/group-create])))}
|
||||
(rf/dispatch [:open-modal :group-create])))}
|
||||
(if one-contact-selected?
|
||||
(i18n/label :t/chat-with {:selected-user primary-name})
|
||||
(i18n/label :t/setup-group-chat))]])]))
|
||||
|
||||
+2
-5
@@ -12,13 +12,10 @@
|
||||
(defn view
|
||||
[{:keys [contact-id]}]
|
||||
(let [customization-color (rf/sub [:profile/customization-color])
|
||||
[primary-name _] (rf/sub [:contacts/contact-two-names-by-identity contact-id])
|
||||
{:keys [contact-request-state
|
||||
community-id
|
||||
chat-name]} (rf/sub [:chats/current-chat-chat-view])
|
||||
community-id]} (rf/sub [:chats/current-chat-chat-view])
|
||||
chat-type (rf/sub [:chats/chat-type])
|
||||
[primary-name _] (if (= chat-type :public-chat)
|
||||
[(str "#" chat-name) ""]
|
||||
(rf/sub [:contacts/contact-two-names-by-identity contact-id]))
|
||||
community-chat? (= chat-type :community-chat)
|
||||
joined (when community-chat?
|
||||
(rf/sub [:communities/community-joined community-id]))
|
||||
|
||||
@@ -67,28 +67,6 @@
|
||||
(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}]
|
||||
@@ -110,9 +88,9 @@
|
||||
(when-not syncing-account-recovered?
|
||||
[:dispatch [:syncing/clear-syncing-installation-id]])]
|
||||
:dispatch-later [{:ms constants/onboarding-generating-keys-animation-duration-ms
|
||||
:dispatch [:onboarding/account-creation-complete
|
||||
{:loading-animation-complete? true
|
||||
:loading-screen loading-screen}]}]
|
||||
:dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.enable-notifications
|
||||
loading-screen]]}]
|
||||
:db (-> db
|
||||
(dissoc :profile/login)
|
||||
(dissoc :auth-method)
|
||||
|
||||
@@ -11,93 +11,66 @@
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- show-terms-of-use
|
||||
[]
|
||||
(rf/dispatch [:show-bottom-sheet {:content terms/terms-of-use :shell? true}]))
|
||||
|
||||
(defn- show-privacy-policy
|
||||
[]
|
||||
(rf/dispatch [:show-bottom-sheet {:content privacy/privacy-statement :shell? true}]))
|
||||
|
||||
(defn- terms
|
||||
[terms-accepted? set-terms-accepted?]
|
||||
[rn/view {:style style/terms-privacy-container}
|
||||
[rn/view
|
||||
{:accessibility-label :terms-privacy-checkbox-container}
|
||||
[quo/selectors
|
||||
{:type :checkbox
|
||||
:blur? true
|
||||
:checked? terms-accepted?
|
||||
:on-change #(set-terms-accepted? not)}]]
|
||||
[rn/view {:style style/text-container}
|
||||
[quo/text
|
||||
{:style style/plain-text
|
||||
:size :paragraph-2}
|
||||
(str (i18n/label :t/accept-status-tos-prefix) " ")]
|
||||
[quo/text
|
||||
{:on-press show-terms-of-use
|
||||
:style style/highlighted-text
|
||||
:size :paragraph-2
|
||||
:weight :medium}
|
||||
(i18n/label :t/terms-of-service)]
|
||||
[quo/text
|
||||
{:style style/plain-text
|
||||
:size :paragraph-2}
|
||||
" " (i18n/label :t/and) " "]
|
||||
[quo/text
|
||||
{:on-press show-privacy-policy
|
||||
:style style/highlighted-text
|
||||
:size :paragraph-2
|
||||
:weight :medium}
|
||||
(i18n/label :t/intro-privacy-policy)]]])
|
||||
|
||||
(defn- explore-new-status
|
||||
[]
|
||||
(rf/dispatch [:profile/explore-new-status]))
|
||||
|
||||
(defn- sync-or-recover-profile
|
||||
[]
|
||||
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
|
||||
(blur-show-fn))
|
||||
(rf/dispatch [:open-modal :screen/onboarding.sync-or-recover-profile]))
|
||||
|
||||
(defn- create-profile
|
||||
[]
|
||||
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
|
||||
(blur-show-fn))
|
||||
(rf/dispatch [:open-modal :screen/onboarding.new-to-status]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [[terms-accepted? set-terms-accepted?] (rn/use-state false)
|
||||
has-profiles-and-unaccepted-terms? (rf/sub [:profile/has-profiles-and-unaccepted-terms?])]
|
||||
(let [[terms-accepted? set-terms-accepted?] (rn/use-state false)]
|
||||
[rn/view {:style style/page-container}
|
||||
[background/view false]
|
||||
[quo/bottom-actions
|
||||
(cond->
|
||||
{:container-style (style/bottom-actions-container (safe-area/get-bottom))
|
||||
:actions :two-vertical-actions
|
||||
:description :top
|
||||
:description-top-text [terms terms-accepted? set-terms-accepted?]}
|
||||
|
||||
has-profiles-and-unaccepted-terms?
|
||||
(assoc
|
||||
:actions :one-action
|
||||
:button-one-label (i18n/label :t/explore-the-new-status)
|
||||
:button-one-props {:disabled? (not terms-accepted?)
|
||||
:accessibility-label :explore-new-status
|
||||
:on-press explore-new-status})
|
||||
|
||||
(not has-profiles-and-unaccepted-terms?)
|
||||
(assoc
|
||||
:actions :two-vertical-actions
|
||||
:button-one-label (i18n/label :t/sync-or-recover-profile)
|
||||
:button-one-props {:type :dark-grey
|
||||
:disabled? (not terms-accepted?)
|
||||
:accessibility-label :already-use-status-button
|
||||
:on-press sync-or-recover-profile}
|
||||
:button-two-label (i18n/label :t/create-profile)
|
||||
:button-two-props {:accessibility-label :new-to-status-button
|
||||
:disabled? (not terms-accepted?)
|
||||
:on-press create-profile}))]
|
||||
{:container-style (style/bottom-actions-container (safe-area/get-bottom))
|
||||
:actions :two-vertical-actions
|
||||
:description :top
|
||||
:description-top-text [rn/view
|
||||
{:style style/terms-privacy-container}
|
||||
[rn/view
|
||||
{:accessibility-label :terms-privacy-checkbox-container}
|
||||
[quo/selectors
|
||||
{:type :checkbox
|
||||
:blur? true
|
||||
:checked? terms-accepted?
|
||||
:on-change #(set-terms-accepted? not)}]]
|
||||
[rn/view {:style style/text-container}
|
||||
[quo/text
|
||||
{:style style/plain-text
|
||||
:size :paragraph-2}
|
||||
(str (i18n/label :t/accept-status-tos-prefix) " ")]
|
||||
[quo/text
|
||||
{:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content terms/terms-of-use
|
||||
:shell? true}])
|
||||
:style style/highlighted-text
|
||||
:size :paragraph-2
|
||||
:weight :medium}
|
||||
(i18n/label :t/terms-of-service)]
|
||||
[quo/text
|
||||
{:style style/plain-text
|
||||
:size :paragraph-2}
|
||||
" " (i18n/label :t/and) " "]
|
||||
[quo/text
|
||||
{:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content privacy/privacy-statement
|
||||
:shell? true}])
|
||||
:style style/highlighted-text
|
||||
:size :paragraph-2
|
||||
:weight :medium}
|
||||
(i18n/label :t/intro-privacy-policy)]]]
|
||||
:button-one-label (i18n/label :t/sync-or-recover-profile)
|
||||
:button-one-props {:type :dark-grey
|
||||
:disabled? (not terms-accepted?)
|
||||
:accessibility-label :already-use-status-button
|
||||
:on-press (fn []
|
||||
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
|
||||
(blur-show-fn))
|
||||
(rf/dispatch
|
||||
[:open-modal
|
||||
:screen/onboarding.sync-or-recover-profile]))}
|
||||
:button-two-label (i18n/label :t/create-profile)
|
||||
:button-two-props {:accessibility-label :new-to-status-button
|
||||
:disabled? (not terms-accepted?)
|
||||
:on-press
|
||||
(fn []
|
||||
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
|
||||
(blur-show-fn))
|
||||
(rf/dispatch
|
||||
[:open-modal :screen/onboarding.new-to-status]))}}]
|
||||
[overlay/view]]))
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
(ns status-im.contexts.profile.data-store)
|
||||
|
||||
(defn accepted-terms?
|
||||
[accounts]
|
||||
(some :hasAcceptedTerms accounts))
|
||||
@@ -1,14 +0,0 @@
|
||||
(ns status-im.contexts.profile.effects
|
||||
(:require
|
||||
[native-module.core :as native-module]
|
||||
[promesa.core :as promesa]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/reg-fx :effects.profile/accept-terms
|
||||
(fn [{:keys [on-success]}]
|
||||
(-> (native-module/accept-terms)
|
||||
(promesa/then (fn []
|
||||
(rf/call-continuation on-success)))
|
||||
(promesa/catch (fn [error]
|
||||
(log/error "Failed to accept terms" {:error error}))))))
|
||||
@@ -4,12 +4,10 @@
|
||||
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[native-module.core :as native-module]
|
||||
[status-im.config :as config]
|
||||
[status-im.contexts.profile.data-store :as profile.data-store]
|
||||
[status-im.contexts.profile.edit.accent-colour.events]
|
||||
[status-im.contexts.profile.edit.bio.events]
|
||||
[status-im.contexts.profile.edit.header.events]
|
||||
[status-im.contexts.profile.edit.name.events]
|
||||
status-im.contexts.profile.effects
|
||||
status-im.contexts.profile.login.events
|
||||
[status-im.contexts.profile.rpc :as profile.rpc]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -44,27 +42,26 @@
|
||||
(rf/reg-event-fx
|
||||
:profile/get-profiles-overview-success
|
||||
(fn [{:keys [db]} [{:keys [accounts] {:keys [userConfirmed enabled]} :centralizedMetricsInfo}]]
|
||||
(let [db-with-settings (assoc db
|
||||
:centralized-metrics/user-confirmed? userConfirmed
|
||||
:centralized-metrics/enabled? enabled)
|
||||
profiles (reduce-profiles accounts)
|
||||
{:keys [key-uid]} (first (sort-by :timestamp > (vals profiles)))
|
||||
new-db (cond-> db-with-settings
|
||||
(seq profiles)
|
||||
(assoc :profile/profiles-overview profiles)
|
||||
|
||||
key-uid
|
||||
(update :profile/login #(select-profile % key-uid)))]
|
||||
{:db new-db
|
||||
:fx (if (profile.data-store/accepted-terms? accounts)
|
||||
[[:dispatch [:update-theme-and-init-root :screen/profile.profiles]]
|
||||
(when (and key-uid userConfirmed)
|
||||
[:effects.biometric/check-if-available
|
||||
{:key-uid key-uid
|
||||
:on-success (fn [auth-method]
|
||||
(rf/dispatch [:profile.login/check-biometric-success key-uid
|
||||
auth-method]))}])]
|
||||
[[:dispatch [:update-theme-and-init-root :screen/onboarding.intro]]])})))
|
||||
(let [db-with-settings (assoc db
|
||||
:centralized-metrics/user-confirmed? userConfirmed
|
||||
:centralized-metrics/enabled? enabled)]
|
||||
(if (seq accounts)
|
||||
(let [profiles (reduce-profiles accounts)
|
||||
{:keys [key-uid]} (first (sort-by :timestamp > (vals profiles)))]
|
||||
{:db (if key-uid
|
||||
(-> db-with-settings
|
||||
(assoc :profile/profiles-overview profiles)
|
||||
(update :profile/login #(select-profile % key-uid)))
|
||||
db-with-settings)
|
||||
:fx [[:dispatch [:update-theme-and-init-root :screen/profile.profiles]]
|
||||
(when (and key-uid userConfirmed)
|
||||
[:effects.biometric/check-if-available
|
||||
{:key-uid key-uid
|
||||
:on-success (fn [auth-method]
|
||||
(rf/dispatch [:profile.login/check-biometric-success key-uid
|
||||
auth-method]))}])]})
|
||||
{:db db-with-settings
|
||||
:fx [[:dispatch [:update-theme-and-init-root :screen/onboarding.intro]]]}))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:profile/update-setting-from-backup
|
||||
@@ -85,8 +82,3 @@
|
||||
:messages-from-contacts-only
|
||||
(not (get-in db [:profile/profile :messages-from-contacts-only]))
|
||||
{})))
|
||||
|
||||
(rf/reg-event-fx :profile/explore-new-status
|
||||
(fn []
|
||||
{:fx [[:effects.profile/accept-terms
|
||||
{:on-success [:navigate-to :screen/profile.profiles]}]]}))
|
||||
|
||||
@@ -83,8 +83,7 @@
|
||||
[[:dispatch [:update-theme-and-init-root :screen/onboarding.syncing-results]]]
|
||||
|
||||
(get db :onboarding/new-account?)
|
||||
[[:dispatch [:onboarding/finalize-setup]]
|
||||
[:dispatch [:onboarding/account-creation-complete {:login-signal-received? true}]]]
|
||||
[[:dispatch [:onboarding/finalize-setup]]]
|
||||
|
||||
:else
|
||||
[[:dispatch [:update-theme-and-init-root :shell-stack]]
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
(defn- bridge-token-component
|
||||
[]
|
||||
(fn [{:keys [chain-id network-name]} {:keys [supported-networks] :as token}]
|
||||
(fn [{:keys [chain-id network-name]} {:keys [networks] :as token}]
|
||||
(let [network (rf/sub [:wallet/network-details-by-chain-id chain-id])
|
||||
currency (rf/sub [:profile/currency])
|
||||
currency-symbol (rf/sub [:profile/currency-symbol])
|
||||
@@ -28,8 +28,7 @@
|
||||
fiat-formatted (utils/get-standard-fiat-format crypto-value
|
||||
currency-symbol
|
||||
fiat-value)
|
||||
token-available-on-network? (network-utils/token-available-on-network? supported-networks
|
||||
chain-id)]
|
||||
token-available-on-network? (network-utils/token-available-on-network? networks chain-id)]
|
||||
[quo/network-list
|
||||
{:label (name network-name)
|
||||
:network-image (quo.resources/get-network (:network-name network))
|
||||
@@ -50,10 +49,7 @@
|
||||
mainnet (first network-details)
|
||||
layer-2-networks (rest network-details)
|
||||
account-token (some #(when (= token-symbol (:symbol %)) %) tokens)
|
||||
account-token (when account-token
|
||||
(assoc account-token
|
||||
:networks (:networks token)
|
||||
:supported-networks (:supported-networks token)))
|
||||
account-token (when account-token (assoc account-token :networks (:networks token)))
|
||||
bridge-to-title (i18n/label :t/bridge-to
|
||||
{:name (string/upper-case (str token-symbol))})]
|
||||
|
||||
|
||||
@@ -10,17 +10,14 @@
|
||||
[]
|
||||
[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}
|
||||
: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]))}]])
|
||||
{: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]))}]])
|
||||
|
||||
@@ -43,18 +43,10 @@
|
||||
|
||||
(defn flush-collectibles
|
||||
[{:keys [db]}]
|
||||
(let [collectibles-per-account (get-in db [:wallet :ui :collectibles :fetched])
|
||||
updated-accounts (move-collectibles-to-accounts (get-in db [:wallet :accounts])
|
||||
collectibles-per-account)
|
||||
has-collectibles? (some (fn [account]
|
||||
(pos? (count (:collectibles account))))
|
||||
(vals updated-accounts))]
|
||||
(let [collectibles-per-account (get-in db [:wallet :ui :collectibles :fetched])]
|
||||
{:db (-> db
|
||||
(update-in [:wallet :ui :collectibles] dissoc :pending-requests :fetched)
|
||||
(assoc-in [:wallet :accounts] updated-accounts))
|
||||
:fx [[:dispatch
|
||||
[:centralized-metrics/track :metric/wallet-collectibles-fetched
|
||||
{:has-collectibles? has-collectibles?}]]]}))
|
||||
(update-in [:wallet :accounts] move-collectibles-to-accounts collectibles-per-account))}))
|
||||
|
||||
(rf/reg-event-fx :wallet/flush-collectibles-fetched flush-collectibles)
|
||||
|
||||
|
||||
@@ -77,13 +77,12 @@
|
||||
(defn token-value-drawer
|
||||
[token watch-only? entry-point]
|
||||
(let [token-symbol (:token token)
|
||||
token-data (rf/sub [:wallet/token-by-symbol token-symbol])
|
||||
token-data (first (rf/sub [:wallet/current-viewing-account-tokens-filtered
|
||||
{:query token-symbol}]))
|
||||
selected-account (rf/sub [:wallet/current-viewing-account-address])
|
||||
token-owners (rf/sub [:wallet/operable-addresses-with-token-symbol token-symbol])
|
||||
testnet-mode? (rf/sub [:profile/test-networks-enabled?])
|
||||
account-owns-token? (rf/sub [:wallet/current-account-owns-token token-symbol])
|
||||
receive-token-symbol (if (= token-symbol "SNT") "ETH" "SNT")
|
||||
token-owned? (if selected-account account-owns-token? (seq token-owners))
|
||||
asset-to-receive (rf/sub [:wallet/token-by-symbol receive-token-symbol])
|
||||
params (cond-> {:start-flow? true
|
||||
:owners token-owners
|
||||
@@ -104,12 +103,11 @@
|
||||
(action-hide))]
|
||||
(not watch-only?)
|
||||
(concat [(action-buy)
|
||||
(when token-owned?
|
||||
(when (seq token-owners)
|
||||
(action-send params entry-point))
|
||||
(action-receive selected-account)
|
||||
(when token-owned?
|
||||
(action-swap params))
|
||||
(when token-owned?
|
||||
(action-swap params)
|
||||
(when (seq token-owners)
|
||||
(action-bridge (assoc params
|
||||
:bridge-disabled?
|
||||
(send-utils/bridge-disabled? token-symbol))))]))]]))
|
||||
|
||||
@@ -27,12 +27,18 @@
|
||||
[balance]
|
||||
(cut-fiat-balance balance 2))
|
||||
|
||||
(defn prettify-balance
|
||||
[currency-symbol balance]
|
||||
(defn prepend-curency-symbol-to-fiat-balance
|
||||
[fiat-balance currency-symbol]
|
||||
(let [formatted-symbol (if (> (count currency-symbol) 1)
|
||||
(str currency-symbol " ")
|
||||
currency-symbol)]
|
||||
(str formatted-symbol (cut-fiat-balance-to-two-decimals balance))))
|
||||
(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)))
|
||||
|
||||
(defn get-derivation-path
|
||||
[number-of-accounts]
|
||||
@@ -104,11 +110,15 @@
|
||||
: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]
|
||||
(str (cut-crypto-decimals-to-fit-usd-cents crypto-balance conversion-rate)
|
||||
" "
|
||||
(string/upper-case token-symbol)))
|
||||
(-> crypto-balance
|
||||
(cut-crypto-decimals-to-fit-usd-cents conversion-rate)
|
||||
(add-token-symbol-to-crypto-balance token-symbol)))
|
||||
|
||||
(defn get-standard-crypto-format
|
||||
"For full details: https://github.com/status-im/status-mobile/issues/18225"
|
||||
@@ -495,7 +505,9 @@
|
||||
:TokenIDTo token-id-to
|
||||
:SlippagePercentage slippage-percentage))
|
||||
|
||||
(= bridge-name constants/bridge-name-celer)
|
||||
(not (or (= bridge-name constants/bridge-name-erc-721-transfer)
|
||||
(= bridge-name constants/bridge-name-transfer)
|
||||
(= bridge-name constants/bridge-name-hop)))
|
||||
(assoc :CbridgeTx
|
||||
(assoc tx-data
|
||||
:ChainID to-chain-id
|
||||
@@ -522,10 +534,9 @@
|
||||
[tokens networks chain-ids]
|
||||
(map (fn [token]
|
||||
(assoc token
|
||||
:networks (network-utils/network-list-with-positive-balance token networks)
|
||||
:supported-networks (network-utils/network-list token networks)
|
||||
:available-balance (calculate-total-token-balance token)
|
||||
:total-balance (calculate-total-token-balance token chain-ids)))
|
||||
:networks (network-utils/network-list token networks)
|
||||
:available-balance (calculate-total-token-balance token)
|
||||
:total-balance (calculate-total-token-balance token chain-ids)))
|
||||
tokens))
|
||||
|
||||
(defn estimated-time-format
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
(ns status-im.contexts.wallet.common.utils.networks
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.foundations.resources :as resources]
|
||||
[status-im.constants :as constants]
|
||||
[utils.money :as money]
|
||||
[utils.number]))
|
||||
(:require [clojure.string :as string]
|
||||
[quo.foundations.resources :as resources]
|
||||
[status-im.constants :as constants]
|
||||
[utils.number]))
|
||||
|
||||
(def ^:private last-comma-followed-by-text-to-end-regex #",\s(?=[^,]+$)")
|
||||
|
||||
@@ -65,21 +63,12 @@
|
||||
|
||||
(defn network-list
|
||||
[{:keys [balances-per-chain]} networks]
|
||||
(->> balances-per-chain
|
||||
keys
|
||||
(map (fn [chain-id]
|
||||
(first (filter #(or (= (:chain-id %) chain-id)
|
||||
(= (:related-chain-id %) chain-id))
|
||||
networks))))
|
||||
set))
|
||||
|
||||
(defn network-list-with-positive-balance
|
||||
"Same as `network-list`, but only returns the networks that have a positive token balance"
|
||||
[{:keys [balances-per-chain] :as token} networks]
|
||||
(as-> balances-per-chain $
|
||||
(filter #(-> % second :raw-balance (money/greater-than 0)) $)
|
||||
(assoc token :balances-per-chain $)
|
||||
(network-list $ networks)))
|
||||
(into #{}
|
||||
(mapv (fn [chain-id]
|
||||
(first (filter #(or (= (:chain-id %) chain-id)
|
||||
(= (:related-chain-id %) chain-id))
|
||||
networks)))
|
||||
(keys balances-per-chain))))
|
||||
|
||||
(defn get-default-chain-ids-by-mode
|
||||
[{:keys [test-networks-enabled? is-goerli-enabled?]}]
|
||||
|
||||
@@ -72,32 +72,11 @@
|
||||
(update :testPreferredChainIds chain-ids-set->string)
|
||||
(dissoc :watch-only? :default-account? :operable? :tokens :collectibles)))
|
||||
|
||||
(defn add-missing-balance-per-chain-values
|
||||
"Adds any missing chain balance (0) to the balance-per-chain map based on token supported chains as
|
||||
status-go returns balance for that chain only if the balance is positive."
|
||||
[balances-per-chain supported-chains]
|
||||
(let [zero-balance-per-chain (fn [chain-id]
|
||||
{:chain-id chain-id
|
||||
:raw-balance (money/->bignumber 0)
|
||||
:balance "0"})]
|
||||
(reduce
|
||||
(fn [result chain-id]
|
||||
(if (contains? result chain-id)
|
||||
result
|
||||
(assoc result chain-id (zero-balance-per-chain chain-id))))
|
||||
balances-per-chain
|
||||
supported-chains)))
|
||||
|
||||
(defn- rpc->balances-per-chain
|
||||
[token supported-chains]
|
||||
[token]
|
||||
(-> token
|
||||
(update :balances-per-chain update-vals #(update % :raw-balance money/bignumber))
|
||||
(update :balances-per-chain update-keys (comp utils.number/parse-int name))
|
||||
(update :balances-per-chain #(add-missing-balance-per-chain-values % supported-chains))))
|
||||
|
||||
(defn- update-balances-per-chain
|
||||
[tokens supported-chains-by-token-symbol]
|
||||
(mapv #(rpc->balances-per-chain % (get supported-chains-by-token-symbol (:symbol %))) tokens))
|
||||
(update :balances-per-chain update-keys (comp utils.number/parse-int name))))
|
||||
|
||||
(defn- remove-tokens-with-empty-values
|
||||
[tokens]
|
||||
@@ -106,12 +85,12 @@
|
||||
tokens))
|
||||
|
||||
(defn rpc->tokens
|
||||
[tokens supported-chains-by-token-symbol]
|
||||
[tokens]
|
||||
(-> tokens
|
||||
(update-keys name)
|
||||
(update-vals #(cske/transform-keys transforms/->kebab-case-keyword %))
|
||||
(update-vals remove-tokens-with-empty-values)
|
||||
(update-vals #(update-balances-per-chain % supported-chains-by-token-symbol))))
|
||||
(update-vals #(mapv rpc->balances-per-chain %))))
|
||||
|
||||
(defn rpc->network
|
||||
[network]
|
||||
|
||||
@@ -10,5 +10,4 @@
|
||||
;; Note: we set it to nil by default to differentiate when the user logs
|
||||
;; 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}})
|
||||
:tokens-loading nil}})
|
||||
|
||||
@@ -59,10 +59,6 @@
|
||||
(fn [{:keys [db]} [tab]]
|
||||
{:db (assoc-in db [:wallet :ui :account-page :active-tab] tab)}))
|
||||
|
||||
(rf/reg-event-fx :wallet/select-home-tab
|
||||
(fn [{:keys [db]} [tab]]
|
||||
{:db (assoc-in db [:wallet :ui :active-tab] tab)}))
|
||||
|
||||
(rf/reg-event-fx :wallet/clear-account-tab
|
||||
(fn [{:keys [db]}]
|
||||
{:db (assoc-in db [:wallet :ui :account-page :active-tab] nil)}))
|
||||
@@ -229,17 +225,14 @@
|
||||
(rf/reg-event-fx
|
||||
:wallet/store-wallet-token
|
||||
(fn [{:keys [db]} [address raw-tokens-data]]
|
||||
(let [supported-chains-by-token-symbol (get-in db [:wallet :tokens :supported-chains-by-symbol])
|
||||
tokens (data-store/rpc->tokens raw-tokens-data
|
||||
supported-chains-by-token-symbol)
|
||||
add-tokens (fn [stored-accounts tokens-per-account]
|
||||
(reduce-kv
|
||||
(fn [accounts address tokens-data]
|
||||
(if (contains? accounts address)
|
||||
(update accounts address assoc :tokens tokens-data)
|
||||
accounts))
|
||||
stored-accounts
|
||||
tokens-per-account))]
|
||||
(let [tokens (data-store/rpc->tokens raw-tokens-data)
|
||||
add-tokens (fn [stored-accounts tokens-per-account]
|
||||
(reduce-kv (fn [accounts address tokens-data]
|
||||
(if (contains? accounts address)
|
||||
(update accounts address assoc :tokens tokens-data)
|
||||
accounts))
|
||||
stored-accounts
|
||||
tokens-per-account))]
|
||||
{:db (-> db
|
||||
(update-in [:wallet :accounts] add-tokens tokens)
|
||||
(assoc-in [:wallet :ui :tokens-loading address] false))})))
|
||||
|
||||
@@ -41,8 +41,6 @@
|
||||
(when (ff/enabled? ::ff/wallet.home-activity)
|
||||
{:id :activity :label (i18n/label :t/activity) :accessibility-label :activity-tab})])
|
||||
|
||||
(defn- change-tab [id] (rf/dispatch [:wallet/select-home-tab id]))
|
||||
|
||||
(defn- render-cards
|
||||
[cards ref]
|
||||
[rn/flat-list
|
||||
@@ -66,15 +64,15 @@
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [selected-tab (rf/sub [:wallet/home-tab])
|
||||
account-list-ref (rn/use-ref-atom nil)
|
||||
tokens-loading? (rf/sub [:wallet/home-tokens-loading?])
|
||||
networks (rf/sub [:wallet/selected-network-details])
|
||||
account-cards-data (rf/sub [:wallet/account-cards-data])
|
||||
cards (conj account-cards-data (new-account-card-data))
|
||||
[init-loaded? set-init-loaded] (rn/use-state false)
|
||||
{:keys [formatted-balance]} (rf/sub [:wallet/aggregated-token-values-and-balance])
|
||||
theme (quo.theme/use-theme)]
|
||||
(let [[selected-tab set-selected-tab] (rn/use-state (:id (first tabs-data)))
|
||||
account-list-ref (rn/use-ref-atom nil)
|
||||
tokens-loading? (rf/sub [:wallet/home-tokens-loading?])
|
||||
networks (rf/sub [:wallet/selected-network-details])
|
||||
account-cards-data (rf/sub [:wallet/account-cards-data])
|
||||
cards (conj account-cards-data (new-account-card-data))
|
||||
[init-loaded? set-init-loaded] (rn/use-state false)
|
||||
{:keys [formatted-balance]} (rf/sub [:wallet/aggregated-token-values-and-balance])
|
||||
theme (quo.theme/use-theme)]
|
||||
(rn/use-effect (fn []
|
||||
(when (and @account-list-ref (pos? (count cards)))
|
||||
(.scrollToOffset ^js @account-list-ref
|
||||
@@ -106,7 +104,7 @@
|
||||
(when (ff/enabled? ::ff/wallet.graph)
|
||||
[quo/wallet-graph {:time-frame :empty}])
|
||||
[render-cards cards account-list-ref]
|
||||
[render-tabs tabs-data change-tab selected-tab]]
|
||||
[render-tabs tabs-data set-selected-tab selected-tab]]
|
||||
:content-container-style style/list-container
|
||||
:sticky-header-indices [0]
|
||||
:data []
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
token-decimals (if collectible 0 (:decimals token))
|
||||
native-token? (and token (= token-display-name "ETH"))
|
||||
routes-available? (pos? (count chosen-route))
|
||||
token-networks (:supported-networks token)
|
||||
token-networks (:networks token)
|
||||
token-networks-ids (when token-networks
|
||||
(map #(:chain-id %) token-networks))
|
||||
from-network-amounts-by-chain (send-utils/network-amounts-by-chain
|
||||
@@ -190,21 +190,17 @@
|
||||
;; `token` is a map extracted from the sender, but in the wallet home page we don't know the
|
||||
;; sender yet, so we only provide the `token-symbol`, later in
|
||||
;; `:wallet/select-from-account` the `token` key will be set.
|
||||
(let [{:keys [networks]} token
|
||||
receiver-networks (get-in db [:wallet :ui :send :receiver-networks])
|
||||
token-networks-ids (map :chain-id networks)
|
||||
unsupported-token? (not-any? (set receiver-networks) token-networks-ids)
|
||||
unique-owner (when (= (count owners) 1)
|
||||
(first owners))
|
||||
unique-owner-tokens (get-in db [:wallet :accounts unique-owner :tokens])
|
||||
token-data (or token
|
||||
(when (and token-symbol unique-owner)
|
||||
(some #(when (= (:symbol %) token-symbol) %)
|
||||
unique-owner-tokens)))
|
||||
test-networks-enabled? (get-in db [:profile/profile :test-networks-enabled?])
|
||||
network-details (-> (get-in db
|
||||
[:wallet :networks (if test-networks-enabled? :test :prod)])
|
||||
(network-utils/sorted-networks-with-details))]
|
||||
(let [{:keys [networks]} token
|
||||
receiver-networks (get-in db [:wallet :ui :send :receiver-networks])
|
||||
token-networks-ids (map :chain-id networks)
|
||||
unsupported-token? (not-any? (set receiver-networks) token-networks-ids)
|
||||
unique-owner (when (= (count owners) 1)
|
||||
(first owners))
|
||||
unique-owner-tokens (get-in db [:wallet :accounts unique-owner :tokens])
|
||||
token-data (or token
|
||||
(when (and token-symbol unique-owner)
|
||||
(some #(when (= (:symbol %) token-symbol) %)
|
||||
unique-owner-tokens)))]
|
||||
(when (or token-data token-symbol)
|
||||
{:db (cond-> db
|
||||
:always (update-in [:wallet :ui :send]
|
||||
@@ -215,11 +211,7 @@
|
||||
token-symbol (assoc-in [:wallet :ui :send :token-symbol] token-symbol)
|
||||
token-data (update-in [:wallet :ui :send]
|
||||
#(assoc %
|
||||
:token (assoc token-data
|
||||
:supported-networks
|
||||
(network-utils/network-list
|
||||
token-data
|
||||
network-details))
|
||||
:token token-data
|
||||
:token-display-name (:symbol token-data)))
|
||||
unique-owner (assoc-in [:wallet :current-viewing-account-address] unique-owner)
|
||||
entry-point (assoc-in [:wallet :ui :send :entry-point] entry-point))
|
||||
@@ -238,7 +230,7 @@
|
||||
(rf/reg-event-fx
|
||||
:wallet/edit-token-to-send
|
||||
(fn [{:keys [db]} [token]]
|
||||
(let [{token-networks :supported-networks
|
||||
(let [{token-networks :networks
|
||||
token-symbol :symbol} token
|
||||
receiver-networks (get-in db [:wallet :ui :send :receiver-networks])
|
||||
token-networks-ids (map :chain-id token-networks)
|
||||
@@ -434,7 +426,7 @@
|
||||
{:balances-per-chain balances-per-chain
|
||||
:disabled-chain-ids disabled-from-chain-ids
|
||||
:only-with-balance? false}))
|
||||
token-networks-ids (when token (map #(:chain-id %) (:supported-networks token)))
|
||||
token-networks-ids (when token (map #(:chain-id %) (:networks token)))
|
||||
sender-network-values (when sender-token-available-networks-for-suggested-routes
|
||||
(send-utils/loading-network-amounts
|
||||
{:valid-networks
|
||||
@@ -716,11 +708,7 @@
|
||||
;; account, so we extract the token data from the picked account.
|
||||
(let [token (utils/get-token-from-account db token-symbol address)]
|
||||
(assoc token
|
||||
:networks (network-utils/network-list-with-positive-balance
|
||||
token
|
||||
network-details)
|
||||
:supported-networks (network-utils/network-list token
|
||||
network-details)
|
||||
:networks (network-utils/network-list token network-details)
|
||||
:total-balance (utils/calculate-total-token-balance token))))
|
||||
bridge-tx? (= tx-type :tx/bridge)
|
||||
flow-id (if bridge-tx?
|
||||
|
||||
@@ -79,14 +79,11 @@
|
||||
(h/deftest-event :wallet/edit-token-to-send
|
||||
[event-id dispatch]
|
||||
(let [token-symbol "ETH"
|
||||
token {:symbol "ETH"
|
||||
:name "Ether"
|
||||
:networks #{{:chain-id 421614}
|
||||
{:chain-id 11155420}
|
||||
{:chain-id 11155111}}
|
||||
:supported-networks #{{:chain-id 421614}
|
||||
{:chain-id 11155420}
|
||||
{:chain-id 11155111}}}
|
||||
token {:symbol "ETH"
|
||||
:name "Ether"
|
||||
:networks #{{:chain-id 421614}
|
||||
{:chain-id 11155420}
|
||||
{:chain-id 11155111}}}
|
||||
receiver-networks [421614 11155420]]
|
||||
(testing "can be called with :token"
|
||||
(let [initial-db {:wallet {:ui {:send {:receiver-networks receiver-networks
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
:wallet/wallet-send-tx-type :tx/send
|
||||
:wallet/wallet-send-fee-fiat-formatted "$5,00"
|
||||
:wallet/sending-collectible? false
|
||||
:wallet/total-amount (money/bignumber "250")})
|
||||
:wallet/total-amount-in-to-chains (money/bignumber "250")})
|
||||
|
||||
(h/describe "Send > input amount screen"
|
||||
(h/setup-restorable-re-frame)
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
(ns status-im.contexts.wallet.send.input-amount.controlled-input-logic
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[status-im.contexts.wallet.common.utils :as wallet-utils]
|
||||
[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,497 @@
|
||||
(ns status-im.contexts.wallet.send.input-amount.controller
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.send.input-amount.controlled-input-logic :as controlled-input-logic]
|
||||
[utils.money :as money]
|
||||
[utils.number :as number]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
;; notes
|
||||
;; token-by-symbol and token looks very similar but they have difference in market values data
|
||||
;; inside token structure :total-balance and :available-balance are same, not sure if they have
|
||||
;; different
|
||||
;; meaning
|
||||
|
||||
;; subs
|
||||
|
||||
(rf/reg-sub :layers/ui
|
||||
:<- [:layers]
|
||||
:-> :ui)
|
||||
|
||||
(rf/reg-sub :ui/send
|
||||
:<- [:layers/ui]
|
||||
:-> :send)
|
||||
|
||||
(rf/reg-sub :ui/send-input-amount-screen
|
||||
:<- [:ui/send]
|
||||
:-> :input-amount-screen)
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/controller
|
||||
:<- [:ui/send-input-amount-screen]
|
||||
:-> :controller)
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/currency-information
|
||||
:<- [:wallet/wallet-send-token]
|
||||
:<- [:profile/currency]
|
||||
:<- [:profile/currency-symbol]
|
||||
:<- [:profile/profile]
|
||||
(fn [[{token-symbol :symbol
|
||||
:as
|
||||
token}
|
||||
currency
|
||||
currency-symbol
|
||||
{fiat-currency :currency}]]
|
||||
{:usd-conversion-rate (utils/token-usd-price token)
|
||||
:currency currency
|
||||
:fiat-currency fiat-currency
|
||||
:currency-symbol currency-symbol
|
||||
:token-symbol token-symbol
|
||||
:conversion-rate (-> token
|
||||
:market-values-per-currency
|
||||
currency
|
||||
:price)
|
||||
:token-decimals (-> token
|
||||
utils/token-usd-price
|
||||
utils/one-cent-value
|
||||
utils/calc-max-crypto-decimals)
|
||||
:token token}))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/max-decimals
|
||||
:<- [:send-input-amount-screen/controller]
|
||||
:<- [:send-input-amount-screen/currency-information]
|
||||
:<- [:wallet/wallet-send-receiver-preferred-networks]
|
||||
(fn [[{:keys [crypto-currency?]}
|
||||
{:keys [token-decimals]}]]
|
||||
(if crypto-currency? token-decimals 2)))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/enabled-from-chain-ids
|
||||
:<- [:wallet/wallet-send-tx-type]
|
||||
:<- [:wallet/wallet-send-enabled-from-chain-ids]
|
||||
:<- [:wallet/bridge-from-chain-ids]
|
||||
(fn [[tx-type send-chain-ids bridge-chain-ids]]
|
||||
(if (= tx-type :tx/bridge)
|
||||
bridge-chain-ids
|
||||
send-chain-ids)))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/from-enabled-networks
|
||||
:<- [:wallet/wallet-send-tx-type]
|
||||
:<- [:wallet/wallet-send-enabled-networks]
|
||||
:<- [:wallet/bridge-from-networks]
|
||||
(fn [[tx-type send-enabled-networks bridge-enabled-networks]]
|
||||
(if (= tx-type :tx/bridge)
|
||||
bridge-enabled-networks
|
||||
send-enabled-networks)))
|
||||
|
||||
(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))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/routes-information
|
||||
:<- [:wallet/wallet-send-route]
|
||||
:<- [:wallet/wallet-send-sender-network-values]
|
||||
:<- [:wallet/wallet-send-receiver-network-values]
|
||||
:<- [:wallet/wallet-send-suggested-routes]
|
||||
:<- [:wallet/wallet-send-loading-suggested-routes?]
|
||||
:<- [:wallet/wallet-send-tx-type]
|
||||
(fn [[route
|
||||
sender-network-values
|
||||
receiver-network-values
|
||||
suggested-routes
|
||||
loading-routes?
|
||||
tx-type]]
|
||||
(let [token-not-supported-in-receiver-networks? (and (not= tx-type :tx/bridge)
|
||||
(->> receiver-network-values
|
||||
(remove #(= (:type %) :add))
|
||||
(every? #(= (:type %) :not-available))))
|
||||
routes (when suggested-routes
|
||||
(or (:best suggested-routes) []))]
|
||||
{:route route
|
||||
:sender-network-values sender-network-values
|
||||
:receiver-network-values receiver-network-values
|
||||
:suggested-routes suggested-routes
|
||||
:loading-routes? loading-routes?
|
||||
:routes routes
|
||||
:token-not-supported-in-receiver-networks? token-not-supported-in-receiver-networks?
|
||||
:no-routes-found? (and
|
||||
(every-network-value-is-zero?
|
||||
sender-network-values)
|
||||
(not (nil? routes))
|
||||
(not loading-routes?)
|
||||
(not token-not-supported-in-receiver-networks?))})))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/networks-information
|
||||
:<- [:wallet/wallet-send-token]
|
||||
:<- [:wallet/wallet-send-receiver-networks]
|
||||
:<- [:wallet/wallet-send-receiver-preferred-networks]
|
||||
(fn [[{token-networks :networks}
|
||||
receiver-networks
|
||||
receiver-preferred-networks]]
|
||||
{:token-networks token-networks
|
||||
:receiver-networks receiver-networks
|
||||
:sending-to-unpreferred-networks? (not (every? (fn [receiver-selected-network]
|
||||
(contains?
|
||||
(set receiver-preferred-networks)
|
||||
receiver-selected-network))
|
||||
receiver-networks))}))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/token-by-symbol
|
||||
:<- [:send-input-amount-screen/enabled-from-chain-ids]
|
||||
:<- [:send-input-amount-screen/currency-information]
|
||||
(fn [[enabled-from-chain-ids {:keys [token-symbol]}]]
|
||||
(rf/sub [:wallet/token-by-symbol
|
||||
(str token-symbol)
|
||||
enabled-from-chain-ids])))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/total-balance
|
||||
:<- [:send-input-amount-screen/token-by-symbol]
|
||||
(fn [{:keys [total-balance]}]
|
||||
total-balance))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/upper-limit
|
||||
:<- [:send-input-amount-screen/controller]
|
||||
:<- [:send-input-amount-screen/currency-information]
|
||||
:<- [:send-input-amount-screen/total-balance]
|
||||
(fn [[{:keys [crypto-currency?]}
|
||||
{:keys [usd-conversion-rate conversion-rate]}
|
||||
total-balance]]
|
||||
(if crypto-currency?
|
||||
(utils/cut-crypto-decimals-to-fit-usd-cents
|
||||
total-balance
|
||||
usd-conversion-rate)
|
||||
(-> (money/crypto->fiat
|
||||
total-balance
|
||||
conversion-rate)
|
||||
utils/cut-fiat-balance-to-two-decimals))))
|
||||
|
||||
(rf/reg-sub
|
||||
:send-input-amount-screen/amount-in-crypto
|
||||
:<- [:send-input-amount-screen/controller]
|
||||
:<- [:send-input-amount-screen/currency-information]
|
||||
(fn [[{:keys [crypto-currency? token-input-value]}
|
||||
{:keys [conversion-rate token-decimals]}]]
|
||||
(if crypto-currency?
|
||||
token-input-value
|
||||
(number/remove-trailing-zeroes
|
||||
(.toFixed (/ token-input-value conversion-rate)
|
||||
token-decimals)))))
|
||||
|
||||
(defn- fiat->crypto
|
||||
[value conversion-rate]
|
||||
(-> value
|
||||
(money/fiat->crypto conversion-rate)
|
||||
(utils/cut-crypto-decimals-to-fit-usd-cents conversion-rate)))
|
||||
|
||||
(defn- crypto->fiat
|
||||
[value conversion-rate]
|
||||
(-> value
|
||||
(money/crypto->fiat conversion-rate)
|
||||
(utils/cut-fiat-balance-to-two-decimals)))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/token-input-converted-value
|
||||
:<- [:send-input-amount-screen/controller]
|
||||
:<- [:send-input-amount-screen/currency-information]
|
||||
(fn [[{:keys [crypto-currency? token-input-value]}
|
||||
{:keys [conversion-rate]}]]
|
||||
(if crypto-currency?
|
||||
(crypto->fiat token-input-value conversion-rate)
|
||||
(fiat->crypto token-input-value conversion-rate))))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/token-input-converted-value-prettified
|
||||
:<- [:send-input-amount-screen/controller]
|
||||
:<- [:send-input-amount-screen/token-input-converted-value]
|
||||
:<- [:send-input-amount-screen/currency-information]
|
||||
(fn [[{:keys [crypto-currency?]}
|
||||
token-input-converted-value
|
||||
{:keys [currency-symbol token-symbol]}]]
|
||||
(if crypto-currency?
|
||||
(utils/prepend-curency-symbol-to-fiat-balance token-input-converted-value currency-symbol)
|
||||
(utils/add-token-symbol-to-crypto-balance token-input-converted-value
|
||||
(or (clj->js token-symbol) "")))))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/upper-limit-prettified
|
||||
:<- [:send-input-amount-screen/controller]
|
||||
:<- [:send-input-amount-screen/currency-information]
|
||||
:<- [:send-input-amount-screen/upper-limit]
|
||||
(fn [[{:keys [crypto-currency?]}
|
||||
{:keys [currency-symbol token-symbol conversion-rate]}
|
||||
upper-limit]]
|
||||
(if crypto-currency?
|
||||
(utils/prettify-crypto-balance
|
||||
(or (clj->js token-symbol) "")
|
||||
(money/bignumber upper-limit)
|
||||
conversion-rate)
|
||||
(utils/prettify-balance currency-symbol
|
||||
(money/bignumber upper-limit)))
|
||||
))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/value-out-of-limits?
|
||||
:<- [:send-input-amount-screen/controller]
|
||||
:<- [:send-input-amount-screen/upper-limit]
|
||||
(fn [[{:keys [token-input-value]}
|
||||
upper-limit]]
|
||||
(controlled-input-logic/value-out-of-limits? token-input-value upper-limit 0)))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/recipient-gets-amount
|
||||
:<- [:send-input-amount-screen/currency-information]
|
||||
:<- [:wallet/total-amount-in-to-chains]
|
||||
(fn [[{:keys [conversion-rate token-symbol]}
|
||||
total-amount-receiver]]
|
||||
(utils/prettify-crypto-balance
|
||||
token-symbol
|
||||
total-amount-receiver
|
||||
conversion-rate)))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/owned-eth-balance-is-zero?
|
||||
:<- [:send-input-amount-screen/enabled-from-chain-ids]
|
||||
(fn [enabled-from-chain-ids]
|
||||
(let [owned-eth-token (rf/sub [:wallet/token-by-symbol
|
||||
(string/upper-case
|
||||
constants/mainnet-short-name)
|
||||
enabled-from-chain-ids])]
|
||||
(money/equal-to (:total-balance owned-eth-token) 0))))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/fee-formatted
|
||||
:<- [:send-input-amount-screen/routes-information]
|
||||
(fn [{:keys [route]}]
|
||||
(let [native-currency-symbol (when-not (or (nil? route) (empty? route))
|
||||
(get-in (first route)
|
||||
[:from :native-currency-symbol]))]
|
||||
(rf/sub [:wallet/wallet-send-fee-fiat-formatted native-currency-symbol]))))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/upper-limit-exceeded?
|
||||
:<- [:send-input-amount-screen/controller]
|
||||
:<- [:send-input-amount-screen/upper-limit]
|
||||
(fn [[{:keys [token-input-value]}
|
||||
upper-limit]]
|
||||
(controlled-input-logic/upper-limit-exceeded?
|
||||
token-input-value
|
||||
upper-limit)))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/upper-limit-equals-input-value?
|
||||
:<- [:send-input-amount-screen/controller]
|
||||
:<- [:send-input-amount-screen/upper-limit]
|
||||
(fn [[{:keys [token-input-value]}
|
||||
upper-limit]]
|
||||
(money/equal-to
|
||||
(money/bignumber token-input-value)
|
||||
(money/bignumber upper-limit))))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/should-try-again?
|
||||
:<- [:send-input-amount-screen/upper-limit-exceeded?]
|
||||
:<- [:send-input-amount-screen/routes-information]
|
||||
(fn [[upper-limit-exceeded?
|
||||
{:keys [no-routes-found?]}]]
|
||||
(and (not upper-limit-exceeded?) no-routes-found?)))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/not-enough-asset?
|
||||
:<- [:send-input-amount-screen/upper-limit-exceeded?]
|
||||
:<- [:send-input-amount-screen/upper-limit-equals-input-value?]
|
||||
:<- [:send-input-amount-screen/routes-information]
|
||||
:<- [:send-input-amount-screen/currency-information]
|
||||
:<- [:send-input-amount-screen/owned-eth-balance-is-zero?]
|
||||
(fn [[upper-limit-exceeded?
|
||||
upper-limit-equals-input-value?
|
||||
{:keys [sender-network-values no-routes-found?]}
|
||||
{:keys [token-symbol]}
|
||||
owned-eth-balance-is-zero?]]
|
||||
(and
|
||||
(or no-routes-found? upper-limit-exceeded?)
|
||||
(not-empty sender-network-values)
|
||||
(if (= token-symbol
|
||||
(string/upper-case
|
||||
constants/mainnet-short-name))
|
||||
upper-limit-equals-input-value?
|
||||
owned-eth-balance-is-zero?))))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/show-no-routes?
|
||||
:<- [:send-input-amount-screen/upper-limit-exceeded?]
|
||||
:<- [:send-input-amount-screen/routes-information]
|
||||
:<- [:send-input-amount-screen/not-enough-asset?]
|
||||
(fn [[upper-limit-exceeded?
|
||||
{:keys [sender-network-values no-routes-found?]}
|
||||
not-enough-asset?]]
|
||||
(and
|
||||
(or no-routes-found? upper-limit-exceeded?)
|
||||
(not-empty sender-network-values)
|
||||
(not not-enough-asset?))))
|
||||
|
||||
(comment
|
||||
(rf/sub [:send-input-amount-screen/not-enough-asset?])
|
||||
(rf/sub [:send-input-amount-screen/upper-limit-equals-input-value?])
|
||||
(:no-routes-found? (rf/sub [:send-input-amount-screen/routes-information]))
|
||||
(:sender-network-values (rf/sub [:send-input-amount-screen/currency-information]))
|
||||
(rf/sub [:send-input-amount-screen/not-enough-asset?]))
|
||||
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/view-subs
|
||||
:<- [:send-input-amount-screen/currency-information]
|
||||
:<- [:send-input-amount-screen/value-out-of-limits?]
|
||||
:<- [:send-input-amount-screen/routes-information]
|
||||
:<- [:send-input-amount-screen/networks-information]
|
||||
:<- [:send-input-amount-screen/recipient-gets-amount]
|
||||
:<- [:send-input-amount-screen/max-decimals]
|
||||
:<- [:send-input-amount-screen/fee-formatted]
|
||||
:<- [:wallet/current-viewing-account-address]
|
||||
:<- [:send-input-amount-screen/not-enough-asset?]
|
||||
:<- [:send-input-amount-screen/show-no-routes?]
|
||||
(fn
|
||||
[[{:keys [token-symbol] :as currency-information}
|
||||
value-out-of-limits?
|
||||
{:keys [route
|
||||
sender-network-values
|
||||
loading-routes?
|
||||
token-not-supported-in-receiver-networks?
|
||||
no-routes-found?]
|
||||
:as routes-information}
|
||||
{:keys [token-networks
|
||||
receiver-networks]}
|
||||
recipient-gets-amount
|
||||
max-decimals
|
||||
fee-formatted
|
||||
current-address
|
||||
not-enough-asset?
|
||||
show-no-routes?]]
|
||||
{:token-symbol token-symbol
|
||||
:value-out-of-limits? value-out-of-limits?
|
||||
:route route
|
||||
:sender-network-values sender-network-values
|
||||
:loading-routes? loading-routes?
|
||||
:token-not-supported-in-receiver-networks? token-not-supported-in-receiver-networks?
|
||||
:token-networks token-networks
|
||||
:receiver-networks receiver-networks
|
||||
:recipient-gets-amount recipient-gets-amount
|
||||
:max-decimals max-decimals
|
||||
:fee-formatted fee-formatted
|
||||
:no-routes-found? no-routes-found?
|
||||
:current-address current-address
|
||||
:not-enough-asset? not-enough-asset?
|
||||
:show-no-routes? show-no-routes?}))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/token-input-subs
|
||||
:<- [:send-input-amount-screen/controller]
|
||||
:<- [:send-input-amount-screen/currency-information]
|
||||
:<- [:send-input-amount-screen/token-input-converted-value]
|
||||
:<- [:send-input-amount-screen/token-input-converted-value-prettified]
|
||||
:<- [:send-input-amount-screen/value-out-of-limits?]
|
||||
:<- [:send-input-amount-screen/upper-limit-prettified]
|
||||
:<- [:send-input-amount-screen/from-enabled-networks]
|
||||
(fn
|
||||
[[{:keys [crypto-currency? token-input-value] :as controller}
|
||||
{:keys [fiat-currency token-symbol] :as currency-information}
|
||||
token-input-converted-value
|
||||
token-input-converted-value-prettified
|
||||
value-out-of-limits?
|
||||
upper-limit-prettified
|
||||
from-enabled-networks]]
|
||||
{:crypto-currency? crypto-currency?
|
||||
:fiat-currency fiat-currency
|
||||
:token-symbol token-symbol
|
||||
:upper-limit-prettified upper-limit-prettified
|
||||
:input-value token-input-value
|
||||
:value-out-of-limits? value-out-of-limits?
|
||||
:token-input-converted-value token-input-converted-value
|
||||
:token-input-converted-value-prettified token-input-converted-value-prettified
|
||||
:from-enabled-networks from-enabled-networks}))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/routes-subs
|
||||
:<- [:send-input-amount-screen/controller]
|
||||
:<- [:send-input-amount-screen/currency-information]
|
||||
:<- [:send-input-amount-screen/amount-in-crypto]
|
||||
:<- [:send-input-amount-screen/value-out-of-limits?]
|
||||
:<- [:send-input-amount-screen/routes-information]
|
||||
:<- [:send-input-amount-screen/token-by-symbol]
|
||||
:<- [:send-input-amount-screen/upper-limit-exceeded?]
|
||||
|
||||
(fn
|
||||
[[{:keys [token-input-value] :as controller}
|
||||
{:keys [token] :as currency-information}
|
||||
amount-in-crypto
|
||||
value-out-of-limits?
|
||||
{:keys [routes
|
||||
token-not-supported-in-receiver-networks?]
|
||||
:as routes-information}
|
||||
token-by-symbol
|
||||
upper-limit-exceeded?]]
|
||||
{:token token
|
||||
:valid-input? (not (or (controlled-input-logic/empty-value?
|
||||
token-input-value)
|
||||
value-out-of-limits?))
|
||||
:upper-limit-exceeded? upper-limit-exceeded?
|
||||
:amount-in-crypto amount-in-crypto
|
||||
:routes routes
|
||||
:token-not-supported-in-receiver-networks? token-not-supported-in-receiver-networks?
|
||||
:token-by-symbol token-by-symbol}))
|
||||
|
||||
(rf/reg-sub :send-input-amount-screen/bottom-actions-subs
|
||||
:<- [:send-input-amount-screen/controller]
|
||||
:<- [:send-input-amount-screen/amount-in-crypto]
|
||||
:<- [:send-input-amount-screen/value-out-of-limits?]
|
||||
:<- [:send-input-amount-screen/routes-information]
|
||||
:<- [:send-input-amount-screen/networks-information]
|
||||
:<- [:send-input-amount-screen/token-by-symbol]
|
||||
:<- [:send-input-amount-screen/should-try-again?]
|
||||
(fn
|
||||
[[{:keys [token-input-value] :as controller}
|
||||
amount-in-crypto
|
||||
value-out-of-limits?
|
||||
{:keys [route loading-routes?]
|
||||
:as routes-information}
|
||||
{:keys [sending-to-unpreferred-networks?]}
|
||||
token-by-symbol
|
||||
should-try-again?]]
|
||||
{:valid-input? (not (or (controlled-input-logic/empty-value?
|
||||
token-input-value)
|
||||
value-out-of-limits?))
|
||||
:amount-in-crypto amount-in-crypto
|
||||
:route route
|
||||
:loading-routes? loading-routes?
|
||||
:token-by-symbol token-by-symbol
|
||||
:sending-to-unpreferred-networks? sending-to-unpreferred-networks?
|
||||
:should-try-again? should-try-again?}))
|
||||
|
||||
|
||||
;; events
|
||||
(def token-input-value-path [:layers :ui :send :input-amount-screen :controller :token-input-value])
|
||||
|
||||
(rf/reg-event-fx :send-input-amount-screen/set-input-state
|
||||
(fn [{:keys [db]} [f]]
|
||||
{:db (update-in db [:layers :ui :send :input-amount-screen :controller :input-state] f)}))
|
||||
|
||||
(rf/reg-event-fx :send-input-amount-screen/set-token-input-value
|
||||
(fn [{:keys [db]} [v]]
|
||||
{:db (assoc-in db token-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 [:layers :ui :send :input-amount-screen :controller :crypto-currency?] 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 token-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 token-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 token-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 token-input-value-path "")}))
|
||||
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
(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.common.utils :as utils]
|
||||
[status-im.contexts.wallet.send.input-amount.controller]
|
||||
[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]
|
||||
@@ -19,12 +16,10 @@
|
||||
[status-im.setup.hot-reload :as hot-reload]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.money :as money]
|
||||
[utils.number :as number]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- estimated-fees
|
||||
[{:keys [loading-routes? fees amount]}]
|
||||
[{:keys [loading-routes? fees 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}
|
||||
@@ -48,20 +43,12 @@
|
||||
:status (if loading-routes? :loading :default)
|
||||
:size :small
|
||||
:title (i18n/label :t/recipient-gets)
|
||||
:subtitle amount}]])
|
||||
:subtitle recipient-gets-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
|
||||
@@ -73,7 +60,8 @@
|
||||
:preselected-token-symbol preselected-token-symbol
|
||||
:on-token-press (fn [token]
|
||||
(rf/dispatch [:wallet/edit-token-to-send token])
|
||||
(clear-input!))}]]))
|
||||
#(rf/dispatch
|
||||
[:send-input-amount-screen/token-input-delete-all]))}]]))
|
||||
|
||||
(defn- token-not-available
|
||||
[token-symbol receiver-networks token-networks]
|
||||
@@ -140,163 +128,122 @@
|
||||
|
||||
:else (rf/dispatch [:wallet/stop-and-clean-suggested-routes])))
|
||||
|
||||
(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 token-input
|
||||
[]
|
||||
(let [{:keys [crypto-currency?
|
||||
upper-limit-prettified
|
||||
input-value
|
||||
value-out-of-limits?
|
||||
token-input-converted-value
|
||||
token-input-converted-value-prettified
|
||||
fiat-currency
|
||||
token-symbol
|
||||
from-enabled-networks]} (rf/sub [:send-input-amount-screen/token-input-subs])
|
||||
show-select-asset-sheet #(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn [] [select-asset-bottom-sheet])}])]
|
||||
[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
|
||||
token-input-converted-value])
|
||||
:on-token-press show-select-asset-sheet
|
||||
:error? value-out-of-limits?
|
||||
:currency-symbol (if crypto-currency? token-symbol fiat-currency)
|
||||
:converted-value token-input-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 [{:keys [valid-input?
|
||||
upper-limit-exceeded?
|
||||
amount-in-crypto
|
||||
routes
|
||||
token-not-supported-in-receiver-networks?
|
||||
token
|
||||
token-by-symbol]} (rf/sub [:send-input-amount-screen/routes-subs])
|
||||
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 upper-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? token-not-supported-in-receiver-networks?
|
||||
:current-screen-id current-screen-id
|
||||
:request-fetch-routes request-fetch-routes}]))
|
||||
|
||||
(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 bottom-actions
|
||||
[on-confirm button-one-label button-one-props]
|
||||
(let [{:keys [valid-input?
|
||||
amount-in-crypto
|
||||
route
|
||||
loading-routes?
|
||||
token-by-symbol
|
||||
sending-to-unpreferred-networks?
|
||||
should-try-again?]} (rf/sub [:send-input-amount-screen/bottom-actions-subs])]
|
||||
[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 loading-routes?
|
||||
(and (not should-try-again?)
|
||||
(or (nil? route)
|
||||
(empty? route)
|
||||
(not valid-input?))))
|
||||
: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))}
|
||||
(when should-try-again?
|
||||
{:type :grey}))}])
|
||||
)
|
||||
|
||||
(defn view
|
||||
;; crypto-decimals, limit-crypto and initial-crypto-currency? args are needed
|
||||
;; for component tests only
|
||||
[{default-on-confirm :on-confirm
|
||||
default-limit-crypto :limit-crypto
|
||||
default-crypto-decimals :crypto-decimals
|
||||
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 (-> token
|
||||
utils/token-usd-price
|
||||
utils/one-cent-value
|
||||
utils/calc-max-crypto-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)
|
||||
crypto-decimals (or token-decimals default-crypto-decimals)
|
||||
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
|
||||
(number/remove-trailing-zeroes
|
||||
(.toFixed (/ input-value conversion-rate)
|
||||
crypto-decimals)))
|
||||
total-amount-receiver (rf/sub [:wallet/total-amount true])
|
||||
amount-text (str (number/remove-trailing-zeroes
|
||||
(.toFixed total-amount-receiver
|
||||
(min token-decimals 6)))
|
||||
" "
|
||||
token-symbol)
|
||||
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?)))]
|
||||
[{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 [{:keys [value-out-of-limits?
|
||||
route
|
||||
sender-network-values
|
||||
loading-routes?
|
||||
token-not-supported-in-receiver-networks?
|
||||
token-networks
|
||||
receiver-networks
|
||||
token-symbol
|
||||
recipient-gets-amount
|
||||
max-decimals
|
||||
fee-formatted
|
||||
no-routes-found?
|
||||
current-address
|
||||
not-enough-asset?
|
||||
show-no-routes?]
|
||||
:as state} (rf/sub [:send-input-amount-screen/view-subs])
|
||||
view-id (rf/sub [:view-id])
|
||||
active-screen? (= view-id current-screen-id)
|
||||
bottom (safe-area/get-bottom)
|
||||
on-navigate-back on-navigate-back]
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(when active-screen?
|
||||
@@ -310,125 +257,52 @@
|
||||
(hot-reload/use-safe-unmount on-navigate-back)
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(set-input-state #(controlled-input/set-upper-limit % max-limit)))
|
||||
[max-limit])
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(when input-error
|
||||
(when value-out-of-limits?
|
||||
(rf/dispatch [:wallet/stop-get-suggested-routes])
|
||||
(debounce/clear-all)))
|
||||
[input-error])
|
||||
[value-out-of-limits?])
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(clear-input!)
|
||||
(rf/dispatch [:send-input-amount-screen/token-input-delete-all])
|
||||
(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 (controlled-input/input-error input-state) "-error"))}
|
||||
(when value-out-of-limits? "-error"))}
|
||||
[account-switcher/view
|
||||
{:icon-name :i/arrow-left
|
||||
:on-press #(rf/dispatch [:navigate-back])
|
||||
:switcher-type :select-account}]
|
||||
[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}]
|
||||
[token-input]
|
||||
[routes-view current-screen-id]
|
||||
(when (and (not loading-routes?)
|
||||
sender-network-values
|
||||
unsupported-token-in-receiver?)
|
||||
token-not-supported-in-receiver-networks?)
|
||||
[token-not-available token-symbol receiver-networks token-networks])
|
||||
(when not-enough-asset?
|
||||
[not-enough-asset])
|
||||
(when (or (and (not no-routes-found?) (or loading-routes? route))
|
||||
not-enough-asset?)
|
||||
(when (and (not no-routes-found?) (or loading-routes? route))
|
||||
[estimated-fees
|
||||
{:loading-routes? loading-routes?
|
||||
:fees fee-formatted
|
||||
:amount amount-text}])
|
||||
(when show-no-routes?
|
||||
[no-routes-found])
|
||||
[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}))}]
|
||||
{:loading-routes? loading-routes?
|
||||
:fees fee-formatted
|
||||
:recipient-gets-amount recipient-gets-amount}])
|
||||
(cond
|
||||
show-no-routes? [no-routes-found]
|
||||
not-enough-asset? [not-enough-asset])
|
||||
[bottom-actions on-confirm button-one-label button-one-props]
|
||||
[quo/numbered-keyboard
|
||||
{:container-style (style/keyboard-container bottom)
|
||||
:left-action :dot
|
||||
:delete-key? true
|
||||
:on-press (fn [c]
|
||||
(let [new-text (str input-value c)
|
||||
max-decimals (if crypto-currency? crypto-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)))))
|
||||
(rf/dispatch [:send-input-amount-screen/token-input-add-character c
|
||||
max-decimals]))
|
||||
:on-delete (fn []
|
||||
(debounce/clear-all)
|
||||
(set-input-state controlled-input/delete-last)
|
||||
(rf/dispatch [:send-input-amount-screen/token-input-delete-last])
|
||||
(rf/dispatch-sync [:wallet/stop-and-clean-suggested-routes]))
|
||||
:on-long-press-delete (fn []
|
||||
(debounce/clear-all)
|
||||
(set-input-state controlled-input/delete-all)
|
||||
(rf/dispatch [:send-input-amount-screen/token-input-delete-all])
|
||||
(rf/dispatch-sync [:wallet/stop-and-clean-suggested-routes]))}]]))
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
receiver-preferred-networks (rf/sub
|
||||
[:wallet/wallet-send-receiver-preferred-networks])
|
||||
{token-symbol :symbol
|
||||
token-networks :supported-networks} (rf/sub [:wallet/wallet-send-token])
|
||||
token-networks :networks} (rf/sub [:wallet/wallet-send-token])
|
||||
token-chain-ids-set (set (mapv #(:chain-id %) token-networks))
|
||||
[selected-receiver-networks
|
||||
set-selected-receiver-networks] (rn/use-state receiver-networks)
|
||||
@@ -340,15 +340,11 @@
|
||||
(let [token-symbol (:symbol token)
|
||||
nav-current-screen-id (rf/sub [:view-id])
|
||||
active-screen? (= nav-current-screen-id current-screen-id)
|
||||
loading-routes? (rf/sub
|
||||
[:wallet/wallet-send-loading-suggested-routes?])
|
||||
sender-network-values (rf/sub
|
||||
[:wallet/wallet-send-sender-network-values])
|
||||
receiver-network-values (rf/sub
|
||||
[:wallet/wallet-send-receiver-network-values])
|
||||
loading-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?])
|
||||
sender-network-values (rf/sub [:wallet/wallet-send-sender-network-values])
|
||||
receiver-network-values (rf/sub [:wallet/wallet-send-receiver-network-values])
|
||||
network-links (rf/sub [:wallet/wallet-send-network-links])
|
||||
disabled-from-chain-ids (rf/sub
|
||||
[:wallet/wallet-send-disabled-from-chain-ids])
|
||||
disabled-from-chain-ids (rf/sub [:wallet/wallet-send-disabled-from-chain-ids])
|
||||
{token-balances-per-chain :balances-per-chain} (rf/sub [:wallet/wallet-send-token])
|
||||
token-available-networks-for-suggested-routes
|
||||
(send-utils/token-available-networks-for-suggested-routes
|
||||
|
||||
@@ -8,12 +8,14 @@
|
||||
(defn view
|
||||
[]
|
||||
[input-amount/view
|
||||
{: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]))}])
|
||||
{: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]))}])
|
||||
|
||||
@@ -221,9 +221,8 @@
|
||||
bridge-to-network (when bridge-to-chain-id
|
||||
(rf/sub [:wallet/network-details-by-chain-id
|
||||
bridge-to-chain-id]))
|
||||
loading-suggested-routes? (rf/sub
|
||||
[:wallet/wallet-send-loading-suggested-routes?])
|
||||
total-amount-receiver (rf/sub [:wallet/total-amount true])
|
||||
loading-suggested-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?])
|
||||
total-amount-receiver (rf/sub [:wallet/total-amount-in-to-chains])
|
||||
from-account-props {:customization-color account-color
|
||||
:size 32
|
||||
:emoji (:emoji account)
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
(fn [{:keys [db]} [{:keys [network asset-to-receive open-new-screen?] :as data}]]
|
||||
(let [{:keys [wallet]} db
|
||||
test-networks-enabled? (get-in db [:profile/profile :test-networks-enabled?])
|
||||
view-id (:view-id db)
|
||||
account (swap-utils/wallet-account wallet)
|
||||
asset-to-pay (if (get-in data [:asset-to-pay :networks])
|
||||
(:asset-to-pay data)
|
||||
@@ -31,13 +30,12 @@
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :swap :asset-to-pay] asset-to-pay)
|
||||
(assoc-in [:wallet :ui :swap :asset-to-receive] asset-to-receive)
|
||||
(assoc-in [:wallet :ui :swap :network] network')
|
||||
(assoc-in [:wallet :ui :swap :launch-screen] view-id))
|
||||
(assoc-in [:wallet :ui :swap :network] network'))
|
||||
:fx (if network'
|
||||
[[:dispatch [:wallet/switch-current-viewing-account (:address account)]]
|
||||
[:dispatch
|
||||
(if open-new-screen?
|
||||
[:open-modal :screen/wallet.setup-swap]
|
||||
[:navigate-to :screen/wallet.setup-swap]
|
||||
[:navigate-to-within-stack
|
||||
[:screen/wallet.setup-swap :screen/wallet.swap-select-asset-to-pay]])]
|
||||
[:dispatch [:wallet.swap/set-default-slippage]]]
|
||||
@@ -206,6 +204,12 @@
|
||||
(fn [{:keys [db]}]
|
||||
{:db (update-in db [:wallet :ui] dissoc :swap)}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/on-swap-done
|
||||
(fn [_]
|
||||
{:fx [[:dispatch [:wallet/select-account-tab :activity]]
|
||||
[:dispatch [:wallet/clean-swap]]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/swap-transaction
|
||||
(fn [{:keys [db]} [sha3-pwd]]
|
||||
(let [wallet-address (get-in db
|
||||
@@ -295,7 +299,6 @@
|
||||
:screen/wallet.swap-set-spending-cap
|
||||
:screen/wallet.swap-confirmation)])
|
||||
(when-not approval-required?
|
||||
(rf/dispatch [:wallet/end-swap-flow])
|
||||
(debounce/debounce-and-dispatch
|
||||
[:toasts/upsert
|
||||
{:id :swap-transaction-pending
|
||||
@@ -421,12 +424,3 @@
|
||||
:last-request-uuid
|
||||
:approved-amount
|
||||
:approval-transaction-id)))})))
|
||||
|
||||
(rf/reg-event-fx :wallet/end-swap-flow
|
||||
(fn [{:keys [db]}]
|
||||
(let [launch-screen (get-in db [:wallet :ui :swap :launch-screen])
|
||||
address (get-in db [:wallet :current-viewing-account-address])]
|
||||
{:fx [(when (= launch-screen :wallet-stack)
|
||||
[:dispatch [:wallet/navigate-to-account-within-stack address]])
|
||||
[:dispatch [:wallet/fetch-activities-for-current-account]]
|
||||
[:dispatch [:wallet/select-account-tab :activity]]]})))
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
(let [pay-token-symbol (:symbol token)
|
||||
asset-to-receive (if (= pay-token-symbol "SNT") eth-token snt-token)]
|
||||
(rf/dispatch [:wallet.swap/start
|
||||
{:asset-to-pay {:symbol pay-token-symbol}
|
||||
{:asset-to-pay token
|
||||
:asset-to-receive asset-to-receive
|
||||
:open-new-screen? false}])))]
|
||||
[:<>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user