Add custom bootnodes
Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
parent
7711dc51ad
commit
33ad919508
|
@ -19,3 +19,4 @@ INSTABUG_SURVEYS=1
|
||||||
GROUP_CHATS_ENABLED=0
|
GROUP_CHATS_ENABLED=0
|
||||||
FORCE_SENT_RECEIVED_TRACKING=1
|
FORCE_SENT_RECEIVED_TRACKING=1
|
||||||
ADD_CUSTOM_MAILSERVERS_ENABLED=0
|
ADD_CUSTOM_MAILSERVERS_ENABLED=0
|
||||||
|
BOOTNODES_SETTINGS_ENABLED=0
|
||||||
|
|
|
@ -20,3 +20,4 @@ GROUP_CHATS_ENABLED=0
|
||||||
FORCE_SENT_RECEIVED_TRACKING=0
|
FORCE_SENT_RECEIVED_TRACKING=0
|
||||||
USE_SYM_KEY=0
|
USE_SYM_KEY=0
|
||||||
ADD_CUSTOM_MAILSERVERS_ENABLED=0
|
ADD_CUSTOM_MAILSERVERS_ENABLED=0
|
||||||
|
BOOTNODES_SETTINGS_ENABLED=0
|
||||||
|
|
|
@ -17,7 +17,7 @@ dependencies {
|
||||||
implementation 'com.github.ericwlange:AndroidJSCore:3.0.1'
|
implementation 'com.github.ericwlange:AndroidJSCore:3.0.1'
|
||||||
implementation 'status-im:function:0.0.1'
|
implementation 'status-im:function:0.0.1'
|
||||||
|
|
||||||
String statusGoVersion = 'develop-g5aae87ab'
|
String statusGoVersion = 'develop-gbc14e6fa'
|
||||||
final String statusGoGroup = 'status-im', statusGoName = 'status-go'
|
final String statusGoGroup = 'status-im', statusGoName = 'status-go'
|
||||||
|
|
||||||
// Check if the local status-go jar exists, and compile against that if it does
|
// Check if the local status-go jar exists, and compile against that if it does
|
||||||
|
|
|
@ -183,6 +183,8 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int testnetNetworkId = 3;
|
||||||
String testnetDataDir = root + "/ethereum/testnet";
|
String testnetDataDir = root + "/ethereum/testnet";
|
||||||
String oldKeystoreDir = testnetDataDir + "/keystore";
|
String oldKeystoreDir = testnetDataDir + "/keystore";
|
||||||
String newKeystoreDir = root + "/keystore";
|
String newKeystoreDir = root + "/keystore";
|
||||||
|
@ -204,14 +206,19 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String config = Statusgo.GenerateConfig(testnetDataDir, 3);
|
String config;
|
||||||
try {
|
try {
|
||||||
JSONObject customConfig = new JSONObject(defaultConfig);
|
JSONObject customConfig = new JSONObject(defaultConfig);
|
||||||
|
|
||||||
|
String dataDir = root + customConfig.get("DataDir");
|
||||||
|
|
||||||
|
config = Statusgo.GenerateConfig(dataDir, customConfig.getInt("NetworkId"));
|
||||||
|
|
||||||
JSONObject jsonConfig = new JSONObject(config);
|
JSONObject jsonConfig = new JSONObject(config);
|
||||||
|
|
||||||
String gethLogFilePath = prepareLogsFile();
|
String gethLogFilePath = prepareLogsFile();
|
||||||
boolean logsEnabled = (gethLogFilePath != null) && !TextUtils.isEmpty(this.logLevel);
|
boolean logsEnabled = (gethLogFilePath != null) && !TextUtils.isEmpty(this.logLevel);
|
||||||
String dataDir = root + customConfig.get("DataDir");
|
|
||||||
jsonConfig.put("LogEnabled", (gethLogFilePath != null && logsEnabled));
|
jsonConfig.put("LogEnabled", (gethLogFilePath != null && logsEnabled));
|
||||||
jsonConfig.put("LogFile", gethLogFilePath);
|
jsonConfig.put("LogFile", gethLogFilePath);
|
||||||
jsonConfig.put("LogLevel", TextUtils.isEmpty(this.logLevel) ? "ERROR" : this.logLevel.toUpperCase());
|
jsonConfig.put("LogLevel", TextUtils.isEmpty(this.logLevel) ? "ERROR" : this.logLevel.toUpperCase());
|
||||||
|
@ -236,10 +243,22 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
Object clusterConfig = customConfig.get("ClusterConfig");
|
||||||
|
if (clusterConfig != null) {
|
||||||
|
Log.d(TAG, "ClusterConfig is not null");
|
||||||
|
jsonConfig.put("ClusterConfig", clusterConfig);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.w(TAG, "Something went wrong parsing cluster config" + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
jsonConfig.put("KeyStoreDir", newKeystoreDir);
|
jsonConfig.put("KeyStoreDir", newKeystoreDir);
|
||||||
|
|
||||||
config = jsonConfig.toString();
|
config = jsonConfig.toString();
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
|
config = Statusgo.GenerateConfig(testnetDataDir, testnetNetworkId);
|
||||||
Log.d(TAG, "Something went wrong " + e.getMessage());
|
Log.d(TAG, "Something went wrong " + e.getMessage());
|
||||||
Log.d(TAG, "Default configuration will be used");
|
Log.d(TAG, "Default configuration will be used");
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self
|
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self
|
||||||
options:(NSJSONWritingOptions) (prettyPrint ? NSJSONWritingPrettyPrinted : 0)
|
options:(NSJSONWritingOptions) (prettyPrint ? NSJSONWritingPrettyPrinted : 0)
|
||||||
error:&error];
|
error:&error];
|
||||||
|
|
||||||
if (! jsonData) {
|
if (! jsonData) {
|
||||||
NSLog(@"bv_jsonStringWithPrettyPrint: error: %@", error.localizedDescription);
|
NSLog(@"bv_jsonStringWithPrettyPrint: error: %@", error.localizedDescription);
|
||||||
return @"{}";
|
return @"{}";
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self
|
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self
|
||||||
options:(NSJSONWritingOptions) (prettyPrint ? NSJSONWritingPrettyPrinted : 0)
|
options:(NSJSONWritingOptions) (prettyPrint ? NSJSONWritingPrettyPrinted : 0)
|
||||||
error:&error];
|
error:&error];
|
||||||
|
|
||||||
if (! jsonData) {
|
if (! jsonData) {
|
||||||
NSLog(@"bv_jsonStringWithPrettyPrint: error: %@", error.localizedDescription);
|
NSLog(@"bv_jsonStringWithPrettyPrint: error: %@", error.localizedDescription);
|
||||||
return @"[]";
|
return @"[]";
|
||||||
|
@ -90,7 +90,7 @@ RCT_EXPORT_METHOD(parseJail:(NSString *)chatId
|
||||||
}
|
}
|
||||||
NSDictionary *result = [_jail parseJail:chatId withCode:js];
|
NSDictionary *result = [_jail parseJail:chatId withCode:js];
|
||||||
stringResult = [result bv_jsonStringWithPrettyPrint:NO];
|
stringResult = [result bv_jsonStringWithPrettyPrint:NO];
|
||||||
|
|
||||||
callback(@[stringResult]);
|
callback(@[stringResult]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ RCT_EXPORT_METHOD(callJail:(NSString *)chatId
|
||||||
NSLog(@"CallJail() method called");
|
NSLog(@"CallJail() method called");
|
||||||
#endif
|
#endif
|
||||||
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
|
||||||
NSString *stringResult;
|
NSString *stringResult;
|
||||||
if(_jail == nil) {
|
if(_jail == nil) {
|
||||||
_jail = [Jail new];
|
_jail = [Jail new];
|
||||||
|
@ -130,12 +130,12 @@ RCT_EXPORT_METHOD(startNode:(NSString *)configString) {
|
||||||
URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]
|
URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]
|
||||||
lastObject];
|
lastObject];
|
||||||
NSURL *testnetFolderName = [rootUrl URLByAppendingPathComponent:@"ethereum/testnet"];
|
NSURL *testnetFolderName = [rootUrl URLByAppendingPathComponent:@"ethereum/testnet"];
|
||||||
|
|
||||||
if (![fileManager fileExistsAtPath:testnetFolderName.path])
|
if (![fileManager fileExistsAtPath:testnetFolderName.path])
|
||||||
[fileManager createDirectoryAtPath:testnetFolderName.path withIntermediateDirectories:YES attributes:nil error:&error];
|
[fileManager createDirectoryAtPath:testnetFolderName.path withIntermediateDirectories:YES attributes:nil error:&error];
|
||||||
|
|
||||||
NSURL *flagFolderUrl = [rootUrl URLByAppendingPathComponent:@"ropsten_flag"];
|
NSURL *flagFolderUrl = [rootUrl URLByAppendingPathComponent:@"ropsten_flag"];
|
||||||
|
|
||||||
if(![fileManager fileExistsAtPath:flagFolderUrl.path]){
|
if(![fileManager fileExistsAtPath:flagFolderUrl.path]){
|
||||||
NSLog(@"remove lightchaindata");
|
NSLog(@"remove lightchaindata");
|
||||||
NSURL *lightChainData = [testnetFolderName URLByAppendingPathComponent:@"StatusIM/lightchaindata"];
|
NSURL *lightChainData = [testnetFolderName URLByAppendingPathComponent:@"StatusIM/lightchaindata"];
|
||||||
|
@ -148,9 +148,9 @@ RCT_EXPORT_METHOD(startNode:(NSString *)configString) {
|
||||||
attributes:nil
|
attributes:nil
|
||||||
error:&error];
|
error:&error];
|
||||||
}
|
}
|
||||||
|
|
||||||
NSLog(@"after remove lightchaindata");
|
NSLog(@"after remove lightchaindata");
|
||||||
|
|
||||||
NSURL *oldKeystoreUrl = [testnetFolderName URLByAppendingPathComponent:@"keystore"];
|
NSURL *oldKeystoreUrl = [testnetFolderName URLByAppendingPathComponent:@"keystore"];
|
||||||
NSURL *newKeystoreUrl = [rootUrl URLByAppendingPathComponent:@"keystore"];
|
NSURL *newKeystoreUrl = [rootUrl URLByAppendingPathComponent:@"keystore"];
|
||||||
if([fileManager fileExistsAtPath:oldKeystoreUrl.path]){
|
if([fileManager fileExistsAtPath:oldKeystoreUrl.path]){
|
||||||
|
@ -158,15 +158,16 @@ RCT_EXPORT_METHOD(startNode:(NSString *)configString) {
|
||||||
[fileManager copyItemAtPath:oldKeystoreUrl.path toPath:newKeystoreUrl.path error:nil];
|
[fileManager copyItemAtPath:oldKeystoreUrl.path toPath:newKeystoreUrl.path error:nil];
|
||||||
[fileManager removeItemAtPath:oldKeystoreUrl.path error:nil];
|
[fileManager removeItemAtPath:oldKeystoreUrl.path error:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
NSLog(@"after lightChainData");
|
NSLog(@"after lightChainData");
|
||||||
|
|
||||||
NSLog(@"preconfig: %@", configString);
|
NSLog(@"preconfig: %@", configString);
|
||||||
NSData *configData = [configString dataUsingEncoding:NSUTF8StringEncoding];
|
NSData *configData = [configString dataUsingEncoding:NSUTF8StringEncoding];
|
||||||
NSDictionary *configJSON = [NSJSONSerialization JSONObjectWithData:configData options:NSJSONReadingMutableContainers error:nil];
|
NSDictionary *configJSON = [NSJSONSerialization JSONObjectWithData:configData options:NSJSONReadingMutableContainers error:nil];
|
||||||
int networkId = [configJSON[@"NetworkId"] integerValue];
|
int networkId = [configJSON[@"NetworkId"] integerValue];
|
||||||
NSString *dataDir = [configJSON objectForKey:@"DataDir"];
|
NSString *dataDir = [configJSON objectForKey:@"DataDir"];
|
||||||
NSString *upstreamURL = [configJSON valueForKeyPath:@"UpstreamConfig.URL"];
|
NSString *upstreamURL = [configJSON valueForKeyPath:@"UpstreamConfig.URL"];
|
||||||
|
NSArray *bootnodes = [configJSON valueForKeyPath:@"ClusterConfig.BootNodes"];
|
||||||
NSString *networkDir = [rootUrl.path stringByAppendingString:dataDir];
|
NSString *networkDir = [rootUrl.path stringByAppendingString:dataDir];
|
||||||
NSString *devCluster = [ReactNativeConfig envFor:@"ETHEREUM_DEV_CLUSTER"];
|
NSString *devCluster = [ReactNativeConfig envFor:@"ETHEREUM_DEV_CLUSTER"];
|
||||||
NSString *logLevel = [[ReactNativeConfig envFor:@"LOG_LEVEL_STATUS_GO"] uppercaseString];
|
NSString *logLevel = [[ReactNativeConfig envFor:@"LOG_LEVEL_STATUS_GO"] uppercaseString];
|
||||||
|
@ -180,19 +181,27 @@ RCT_EXPORT_METHOD(startNode:(NSString *)configString) {
|
||||||
[resultingConfigJson setValue:[NSNumber numberWithBool:[logLevel length] != 0] forKey:@"LogEnabled"];
|
[resultingConfigJson setValue:[NSNumber numberWithBool:[logLevel length] != 0] forKey:@"LogEnabled"];
|
||||||
[resultingConfigJson setValue:logUrl.path forKey:@"LogFile"];
|
[resultingConfigJson setValue:logUrl.path forKey:@"LogFile"];
|
||||||
[resultingConfigJson setValue:([logLevel length] == 0 ? [NSString stringWithUTF8String: "ERROR"] : logLevel) forKey:@"LogLevel"];
|
[resultingConfigJson setValue:([logLevel length] == 0 ? [NSString stringWithUTF8String: "ERROR"] : logLevel) forKey:@"LogLevel"];
|
||||||
|
|
||||||
[resultingConfigJson setValue:[NSNumber numberWithBool:YES] forKeyPath:@"WhisperConfig.LightClient"];
|
[resultingConfigJson setValue:[NSNumber numberWithBool:YES] forKeyPath:@"WhisperConfig.LightClient"];
|
||||||
|
|
||||||
if(upstreamURL != nil) {
|
if(upstreamURL != nil) {
|
||||||
[resultingConfigJson setValue:[NSNumber numberWithBool:YES] forKeyPath:@"UpstreamConfig.Enabled"];
|
[resultingConfigJson setValue:[NSNumber numberWithBool:YES] forKeyPath:@"UpstreamConfig.Enabled"];
|
||||||
[resultingConfigJson setValue:upstreamURL forKeyPath:@"UpstreamConfig.URL"];
|
[resultingConfigJson setValue:upstreamURL forKeyPath:@"UpstreamConfig.URL"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(bootnodes != nil) {
|
||||||
|
[resultingConfigJson setValue:[NSNumber numberWithBool:YES] forKeyPath:@"ClusterConfig.Enabled"];
|
||||||
|
[resultingConfigJson setValue:bootnodes forKeyPath:@"ClusterConfig.BootNodes"];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NSString *resultingConfig = [resultingConfigJson bv_jsonStringWithPrettyPrint:NO];
|
NSString *resultingConfig = [resultingConfigJson bv_jsonStringWithPrettyPrint:NO];
|
||||||
NSLog(@"node config %@", resultingConfig);
|
NSLog(@"node config %@", resultingConfig);
|
||||||
|
|
||||||
if(![fileManager fileExistsAtPath:networkDirUrl.path]) {
|
if(![fileManager fileExistsAtPath:networkDirUrl.path]) {
|
||||||
[fileManager createDirectoryAtPath:networkDirUrl.path withIntermediateDirectories:YES attributes:nil error:nil];
|
[fileManager createDirectoryAtPath:networkDirUrl.path withIntermediateDirectories:YES attributes:nil error:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
NSLog(@"logUrlPath %@", logUrl.path);
|
NSLog(@"logUrlPath %@", logUrl.path);
|
||||||
if(![fileManager fileExistsAtPath:logUrl.path]) {
|
if(![fileManager fileExistsAtPath:logUrl.path]) {
|
||||||
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
|
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
|
||||||
|
@ -353,7 +362,7 @@ RCT_EXPORT_METHOD(clearCookies) {
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(clearStorageAPIs) {
|
RCT_EXPORT_METHOD(clearStorageAPIs) {
|
||||||
[[NSURLCache sharedURLCache] removeAllCachedResponses];
|
[[NSURLCache sharedURLCache] removeAllCachedResponses];
|
||||||
|
|
||||||
NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
|
NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
|
||||||
NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
|
NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
|
||||||
for (NSString *string in array) {
|
for (NSString *string in array) {
|
||||||
|
@ -408,7 +417,7 @@ RCT_EXPORT_METHOD(getDeviceUUID:(RCTResponseSenderBlock)callback) {
|
||||||
NSLog(@"getDeviceUUID() method called");
|
NSLog(@"getDeviceUUID() method called");
|
||||||
#endif
|
#endif
|
||||||
NSString* Identifier = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
|
NSString* Identifier = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
|
||||||
|
|
||||||
callback(@[Identifier]);
|
callback(@[Identifier]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,7 +429,7 @@ RCT_EXPORT_METHOD(getDeviceUUID:(RCTResponseSenderBlock)callback) {
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSString *sig = [NSString stringWithUTF8String:signal];
|
NSString *sig = [NSString stringWithUTF8String:signal];
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
NSLog(@"SignalEvent");
|
NSLog(@"SignalEvent");
|
||||||
|
@ -428,7 +437,7 @@ RCT_EXPORT_METHOD(getDeviceUUID:(RCTResponseSenderBlock)callback) {
|
||||||
#endif
|
#endif
|
||||||
[bridge.eventDispatcher sendAppEventWithName:@"gethEvent"
|
[bridge.eventDispatcher sendAppEventWithName:@"gethEvent"
|
||||||
body:@{@"jsonEvent": sig}];
|
body:@{@"jsonEvent": sig}];
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,7 +456,7 @@ RCT_EXPORT_METHOD(getDeviceUUID:(RCTResponseSenderBlock)callback) {
|
||||||
#endif
|
#endif
|
||||||
[bridge.eventDispatcher sendAppEventWithName:@"gethEvent"
|
[bridge.eventDispatcher sendAppEventWithName:@"gethEvent"
|
||||||
body:@{@"jsonEvent": signal}];
|
body:@{@"jsonEvent": signal}];
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
<artifactItem>
|
<artifactItem>
|
||||||
<groupId>status-im</groupId>
|
<groupId>status-im</groupId>
|
||||||
<artifactId>status-go-ios-simulator</artifactId>
|
<artifactId>status-go-ios-simulator</artifactId>
|
||||||
<version>develop-g5aae87ab</version>
|
<version>develop-gbc14e6fa</version>
|
||||||
<type>zip</type>
|
<type>zip</type>
|
||||||
<overWrite>true</overWrite>
|
<overWrite>true</overWrite>
|
||||||
<outputDirectory>./</outputDirectory>
|
<outputDirectory>./</outputDirectory>
|
||||||
|
|
|
@ -10,9 +10,22 @@
|
||||||
(core/single-clj :account)
|
(core/single-clj :account)
|
||||||
(update :settings core/deserialize)))
|
(update :settings core/deserialize)))
|
||||||
|
|
||||||
|
(defn- deserialize-bootnodes [bootnodes]
|
||||||
|
(reduce-kv
|
||||||
|
(fn [acc id {:keys [chain] :as bootnode}]
|
||||||
|
(assoc-in acc [chain id] bootnode))
|
||||||
|
{}
|
||||||
|
bootnodes))
|
||||||
|
|
||||||
|
(defn- serialize-bootnodes [bootnodes]
|
||||||
|
(->> bootnodes
|
||||||
|
vals
|
||||||
|
(mapcat vals)))
|
||||||
|
|
||||||
(defn- deserialize-account [account]
|
(defn- deserialize-account [account]
|
||||||
(-> account
|
(-> account
|
||||||
(update :settings core/deserialize)
|
(update :settings core/deserialize)
|
||||||
|
(update :bootnodes deserialize-bootnodes)
|
||||||
(update :networks (partial reduce-kv
|
(update :networks (partial reduce-kv
|
||||||
(fn [acc network-id props]
|
(fn [acc network-id props]
|
||||||
(assoc acc network-id
|
(assoc acc network-id
|
||||||
|
@ -31,6 +44,7 @@
|
||||||
(defn- serialize-account [account]
|
(defn- serialize-account [account]
|
||||||
(-> account
|
(-> account
|
||||||
(update :settings core/serialize)
|
(update :settings core/serialize)
|
||||||
|
(update :bootnodes serialize-bootnodes)
|
||||||
(update :networks (partial map (fn [[_ props]]
|
(update :networks (partial map (fn [[_ props]]
|
||||||
(update props :config types/clj->json))))))
|
(update props :config types/clj->json))))))
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
(ns status-im.data-store.realm.schemas.base.core
|
(ns status-im.data-store.realm.schemas.base.core
|
||||||
(:require [status-im.data-store.realm.schemas.base.v1.core :as v1]
|
(:require [status-im.data-store.realm.schemas.base.v1.core :as v1]
|
||||||
[status-im.data-store.realm.schemas.base.v2.core :as v2]
|
[status-im.data-store.realm.schemas.base.v2.core :as v2]
|
||||||
[status-im.data-store.realm.schemas.base.v3.core :as v3]))
|
[status-im.data-store.realm.schemas.base.v3.core :as v3]
|
||||||
|
[status-im.data-store.realm.schemas.base.v4.core :as v4]))
|
||||||
|
|
||||||
;; put schemas ordered by version
|
;; put schemas ordered by version
|
||||||
(def schemas [{:schema v1/schema
|
(def schemas [{:schema v1/schema
|
||||||
|
@ -12,4 +13,7 @@
|
||||||
:migration v2/migration}
|
:migration v2/migration}
|
||||||
{:schema v3/schema
|
{:schema v3/schema
|
||||||
:schemaVersion 3
|
:schemaVersion 3
|
||||||
:migration v3/migration}])
|
:migration v3/migration}
|
||||||
|
{:schema v4/schema
|
||||||
|
:schemaVersion 4
|
||||||
|
:migration v4/migration}])
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
(ns status-im.data-store.realm.schemas.base.v4.account)
|
||||||
|
|
||||||
|
(def schema {:name :account
|
||||||
|
:primaryKey :address
|
||||||
|
:properties {:address :string
|
||||||
|
:public-key :string
|
||||||
|
:name {:type :string :optional true}
|
||||||
|
:email {:type :string :optional true}
|
||||||
|
:status {:type :string :optional true}
|
||||||
|
:debug? {:type :bool :default false}
|
||||||
|
:photo-path :string
|
||||||
|
:signing-phrase {:type :string}
|
||||||
|
:mnemonic {:type :string :optional true}
|
||||||
|
:last-updated {:type :int :default 0}
|
||||||
|
:last-sign-in {:type :int :default 0}
|
||||||
|
:signed-up? {:type :bool
|
||||||
|
:default false}
|
||||||
|
:network :string
|
||||||
|
:networks {:type :list
|
||||||
|
:objectType :network}
|
||||||
|
:bootnodes {:type :list
|
||||||
|
:objectType :bootnode}
|
||||||
|
:last-request {:type :int :optional true}
|
||||||
|
:settings {:type :string}
|
||||||
|
:sharing-usage-data? {:type :bool :default false}
|
||||||
|
:dev-mode? {:type :bool :default false}
|
||||||
|
:seed-backed-up? {:type :bool :default false}
|
||||||
|
:wallet-set-up-passed? {:type :bool
|
||||||
|
:default false}}})
|
|
@ -0,0 +1,8 @@
|
||||||
|
(ns status-im.data-store.realm.schemas.base.v4.bootnode)
|
||||||
|
|
||||||
|
(def schema {:name :bootnode
|
||||||
|
:primaryKey :id
|
||||||
|
:properties {:id :string
|
||||||
|
:name {:type :string}
|
||||||
|
:chain {:type :string}
|
||||||
|
:address {:type :string}}})
|
|
@ -0,0 +1,12 @@
|
||||||
|
(ns status-im.data-store.realm.schemas.base.v4.core
|
||||||
|
(:require [status-im.data-store.realm.schemas.base.v1.network :as network]
|
||||||
|
[status-im.data-store.realm.schemas.base.v4.account :as account]
|
||||||
|
[status-im.data-store.realm.schemas.base.v4.bootnode :as bootnode]
|
||||||
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
|
(def schema [network/schema
|
||||||
|
bootnode/schema
|
||||||
|
account/schema])
|
||||||
|
|
||||||
|
(defn migration [old-realm new-realm]
|
||||||
|
(log/debug "migrating base database v4: " old-realm new-realm))
|
|
@ -622,6 +622,14 @@
|
||||||
:close-app-button "Confirm"
|
:close-app-button "Confirm"
|
||||||
:connect-wnode-content "Connect to {{name}}?"
|
:connect-wnode-content "Connect to {{name}}?"
|
||||||
|
|
||||||
|
;; Bootnodes
|
||||||
|
:bootnodes "Bootnodes"
|
||||||
|
:bootnodes-settings "Bootnodes settings"
|
||||||
|
:bootnodes-enabled "Bootnodes enabled"
|
||||||
|
:bootnode-address "Bootnode address"
|
||||||
|
:add-bootnode "Add bootnode"
|
||||||
|
:specify-bootnode-address "Specify bootnode address"
|
||||||
|
|
||||||
:mainnet-warning-title "Warning!"
|
:mainnet-warning-title "Warning!"
|
||||||
:mainnet-warning-text "While we highly appreciate your contribution as a tester of Status, we’d like to point out the dangers. You’re switching to Mainnet mode which is still in Alpha. This means it is still in development and has not been audited yet. Some of the risks you may be exposed to include:\n\n- Accounts may be unrecoverable due to breaking changes\n- Loss of ETH and tokens\n- Failure to send or receive messages\n\nSwitching to Mainnet should be done for testing purposes only. By tapping \"I understand\", you confirm that you assume the full responsibility for all risks concerning your data and funds. "
|
:mainnet-warning-text "While we highly appreciate your contribution as a tester of Status, we’d like to point out the dangers. You’re switching to Mainnet mode which is still in Alpha. This means it is still in development and has not been audited yet. Some of the risks you may be exposed to include:\n\n- Accounts may be unrecoverable due to breaking changes\n- Loss of ETH and tokens\n- Failure to send or receive messages\n\nSwitching to Mainnet should be done for testing purposes only. By tapping \"I understand\", you confirm that you assume the full responsibility for all risks concerning your data and funds. "
|
||||||
:mainnet-warning-ok-text "I understand"
|
:mainnet-warning-ok-text "I understand"
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
(:require [cljs.spec.alpha :as spec]
|
(:require [cljs.spec.alpha :as spec]
|
||||||
status-im.utils.db
|
status-im.utils.db
|
||||||
status-im.ui.screens.network-settings.db
|
status-im.ui.screens.network-settings.db
|
||||||
|
status-im.ui.screens.bootnodes-settings.db
|
||||||
[status-im.constants :as const]))
|
[status-im.constants :as const]))
|
||||||
|
|
||||||
(defn valid-length? [password]
|
(defn valid-length? [password]
|
||||||
|
@ -24,6 +25,7 @@
|
||||||
(spec/def :account/status (spec/nilable string?))
|
(spec/def :account/status (spec/nilable string?))
|
||||||
(spec/def :account/network (spec/nilable string?))
|
(spec/def :account/network (spec/nilable string?))
|
||||||
(spec/def :account/networks (spec/nilable :networks/networks))
|
(spec/def :account/networks (spec/nilable :networks/networks))
|
||||||
|
(spec/def :account/bootnodes (spec/nilable :bootnodes/bootnodes))
|
||||||
(spec/def :account/wnode (spec/nilable string?))
|
(spec/def :account/wnode (spec/nilable string?))
|
||||||
(spec/def :account/settings (spec/nilable (spec/map-of keyword? any?)))
|
(spec/def :account/settings (spec/nilable (spec/map-of keyword? any?)))
|
||||||
(spec/def :account/signing-phrase :global/not-empty-string)
|
(spec/def :account/signing-phrase :global/not-empty-string)
|
||||||
|
@ -41,7 +43,8 @@
|
||||||
:account/networks :account/settings :account/wnode
|
:account/networks :account/settings :account/wnode
|
||||||
:account/last-sign-in :account/sharing-usage-data? :account/dev-mode?
|
:account/last-sign-in :account/sharing-usage-data? :account/dev-mode?
|
||||||
:account/seed-backed-up? :account/mnemonic
|
:account/seed-backed-up? :account/mnemonic
|
||||||
:account/wallet-set-up-passed? :account/last-request]))
|
:account/wallet-set-up-passed? :account/last-request
|
||||||
|
:account/bootnodes]))
|
||||||
|
|
||||||
(spec/def :accounts/accounts (spec/nilable (spec/map-of :account/address :accounts/account)))
|
(spec/def :accounts/accounts (spec/nilable (spec/map-of :account/address :accounts/account)))
|
||||||
|
|
||||||
|
|
|
@ -63,12 +63,32 @@
|
||||||
(assoc db :node/after-start nil)
|
(assoc db :node/after-start nil)
|
||||||
address password)))
|
address password)))
|
||||||
|
|
||||||
|
(defn add-custom-bootnodes [config network all-bootnodes]
|
||||||
|
(let [bootnodes (as-> all-bootnodes $
|
||||||
|
(get $ network)
|
||||||
|
(vals $)
|
||||||
|
(map :address $))]
|
||||||
|
(if (seq bootnodes)
|
||||||
|
(assoc config :ClusterConfig {:Enabled true
|
||||||
|
:BootNodes bootnodes})
|
||||||
|
config)))
|
||||||
|
|
||||||
(defn get-network-by-address [db address]
|
(defn get-network-by-address [db address]
|
||||||
(let [accounts (get db :accounts/accounts)
|
(let [accounts (get db :accounts/accounts)
|
||||||
{:keys [network networks]} (get accounts address)
|
{:keys [network
|
||||||
config (get-in networks [network :config])]
|
settings
|
||||||
{:network network
|
bootnodes
|
||||||
:config config}))
|
networks]} (get accounts address)
|
||||||
|
use-custom-bootnodes (get-in settings [:bootnodes network])
|
||||||
|
config (cond-> (get-in networks [network :config])
|
||||||
|
|
||||||
|
(and
|
||||||
|
config/bootnodes-settings-enabled?
|
||||||
|
use-custom-bootnodes)
|
||||||
|
(add-custom-bootnodes network bootnodes))]
|
||||||
|
{:use-custom-bootnodes use-custom-bootnodes
|
||||||
|
:network network
|
||||||
|
:config config}))
|
||||||
|
|
||||||
(defn wrap-with-initialize-geth-fx [db address password]
|
(defn wrap-with-initialize-geth-fx [db address password]
|
||||||
(let [{:keys [network config]} (get-network-by-address db address)]
|
(let [{:keys [network config]} (get-network-by-address db address)]
|
||||||
|
@ -87,21 +107,31 @@
|
||||||
{:db (assoc db :node/after-stop [::start-node address password])
|
{:db (assoc db :node/after-stop [::start-node address password])
|
||||||
::stop-node nil})
|
::stop-node nil})
|
||||||
|
|
||||||
|
(defn- restart-node? [account-network network use-custom-bootnodes]
|
||||||
|
(or (not= account-network network)
|
||||||
|
(and config/bootnodes-settings-enabled?
|
||||||
|
use-custom-bootnodes)))
|
||||||
|
|
||||||
|
(defn login-account [{{:keys [network status-node-started?] :as db} :db} [_ address password]]
|
||||||
|
(let [{use-custom-bootnodes :use-custom-bootnodes
|
||||||
|
account-network :network} (get-network-by-address db address)
|
||||||
|
db' (-> db
|
||||||
|
(assoc-in [:accounts/login :processing] true))
|
||||||
|
wrap-fn (cond (not status-node-started?)
|
||||||
|
wrap-with-initialize-geth-fx
|
||||||
|
|
||||||
|
(not (restart-node? account-network
|
||||||
|
network
|
||||||
|
use-custom-bootnodes))
|
||||||
|
wrap-with-login-account-fx
|
||||||
|
|
||||||
|
:else
|
||||||
|
wrap-with-stop-node-fx)]
|
||||||
|
(wrap-fn db' address password)))
|
||||||
|
|
||||||
(register-handler-fx
|
(register-handler-fx
|
||||||
:login-account
|
:login-account
|
||||||
(fn [{{:keys [network status-node-started?] :as db} :db} [_ address password]]
|
login-account)
|
||||||
(let [{account-network :network} (get-network-by-address db address)
|
|
||||||
db' (-> db
|
|
||||||
(assoc-in [:accounts/login :processing] true))
|
|
||||||
wrap-fn (cond (not status-node-started?)
|
|
||||||
wrap-with-initialize-geth-fx
|
|
||||||
|
|
||||||
(= account-network network)
|
|
||||||
wrap-with-login-account-fx
|
|
||||||
|
|
||||||
:else
|
|
||||||
wrap-with-stop-node-fx)]
|
|
||||||
(wrap-fn db' address password))))
|
|
||||||
|
|
||||||
(register-handler-fx
|
(register-handler-fx
|
||||||
:login-handler
|
:login-handler
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
(ns status-im.ui.screens.bootnodes-settings.db
|
||||||
|
(:require-macros [status-im.utils.db :refer [allowed-keys]])
|
||||||
|
(:require
|
||||||
|
[clojure.string :as string]
|
||||||
|
[cljs.spec.alpha :as spec]))
|
||||||
|
|
||||||
|
(spec/def ::not-blank-string (complement string/blank?))
|
||||||
|
|
||||||
|
(spec/def :bootnode/address ::not-blank-string)
|
||||||
|
(spec/def :bootnode/name ::not-blank-string)
|
||||||
|
(spec/def :bootnode/id ::not-blank-string)
|
||||||
|
(spec/def :bootnode/chain ::not-blank-string)
|
||||||
|
(spec/def :bootnode/bootnode (allowed-keys :req-un [:bootnode/chain
|
||||||
|
:bootnode/address
|
||||||
|
:bootnode/name
|
||||||
|
:bootnode/id]))
|
||||||
|
|
||||||
|
(spec/def :bootnodes/bootnodes (spec/nilable (spec/map-of :bootnode/id (spec/map-of :bootnode/id :bootnode/bootnode))))
|
|
@ -0,0 +1,51 @@
|
||||||
|
(ns status-im.ui.screens.bootnodes-settings.edit-bootnode.events
|
||||||
|
(:require [clojure.string :as string]
|
||||||
|
[re-frame.core :as re-frame]
|
||||||
|
[status-im.utils.handlers :refer [register-handler] :as handlers]
|
||||||
|
[status-im.utils.handlers-macro :as handlers-macro]
|
||||||
|
[status-im.ui.screens.accounts.utils :as accounts.utils]
|
||||||
|
[status-im.utils.ethereum.core :as ethereum]
|
||||||
|
[status-im.utils.types :as types]
|
||||||
|
[status-im.utils.inbox :as utils.inbox]))
|
||||||
|
|
||||||
|
(defn- new-bootnode [id bootnode-name address chain]
|
||||||
|
{:address address
|
||||||
|
:chain chain
|
||||||
|
:id (string/replace id "-" "")
|
||||||
|
:name bootnode-name})
|
||||||
|
|
||||||
|
(defn save-new-bootnode [{{:bootnodes/keys [manage] :account/keys [account] :as db} :db :as cofx} _]
|
||||||
|
(let [{:keys [name url]} manage
|
||||||
|
network (:network db)
|
||||||
|
bootnode (new-bootnode
|
||||||
|
(:random-id cofx)
|
||||||
|
(:value name)
|
||||||
|
(:value url)
|
||||||
|
network)
|
||||||
|
new-bootnodes (assoc-in (:bootnodes account) [network (:id bootnode)] bootnode)]
|
||||||
|
|
||||||
|
(handlers-macro/merge-fx cofx
|
||||||
|
{:db (dissoc db :bootnodes/manage)
|
||||||
|
:dispatch [:navigate-back]}
|
||||||
|
(accounts.utils/account-update {:bootnodes new-bootnodes}))))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:save-new-bootnode
|
||||||
|
[(re-frame/inject-cofx :random-id)]
|
||||||
|
save-new-bootnode)
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:bootnode-set-input
|
||||||
|
(fn [{db :db} [_ input-key value]]
|
||||||
|
{:db (update db :bootnodes/manage assoc input-key {:value value
|
||||||
|
:error (if (= input-key :name)
|
||||||
|
(string/blank? value)
|
||||||
|
(not (utils.inbox/valid-enode-address? value)))})}))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:edit-bootnode
|
||||||
|
(fn [{db :db} _]
|
||||||
|
{:db (update-in db [:bootnodes/manage] assoc
|
||||||
|
:name {:error true}
|
||||||
|
:url {:error true})
|
||||||
|
:dispatch [:navigate-to :edit-bootnode]}))
|
|
@ -0,0 +1,15 @@
|
||||||
|
(ns status-im.ui.screens.bootnodes-settings.edit-bootnode.styles
|
||||||
|
(:require-macros [status-im.utils.styles :refer [defstyle]]))
|
||||||
|
|
||||||
|
(def edit-bootnode-view
|
||||||
|
{:flex 1
|
||||||
|
:margin-horizontal 16
|
||||||
|
:margin-vertical 15})
|
||||||
|
|
||||||
|
(def input-container
|
||||||
|
{:margin-bottom 15})
|
||||||
|
|
||||||
|
(def bottom-container
|
||||||
|
{:flex-direction :row
|
||||||
|
:margin-horizontal 12
|
||||||
|
:margin-vertical 15})
|
|
@ -0,0 +1,14 @@
|
||||||
|
(ns status-im.ui.screens.bootnodes-settings.edit-bootnode.subs
|
||||||
|
(:require [re-frame.core :refer [reg-sub]]))
|
||||||
|
|
||||||
|
(reg-sub
|
||||||
|
:get-manage-bootnode
|
||||||
|
:<- [:get :bootnodes/manage]
|
||||||
|
(fn [manage]
|
||||||
|
manage))
|
||||||
|
|
||||||
|
(reg-sub
|
||||||
|
:manage-bootnode-valid?
|
||||||
|
:<- [:get-manage-bootnode]
|
||||||
|
(fn [manage]
|
||||||
|
(not-any? :error (vals manage))))
|
|
@ -0,0 +1,42 @@
|
||||||
|
(ns status-im.ui.screens.bootnodes-settings.edit-bootnode.views
|
||||||
|
(:require-macros [status-im.utils.views :as views])
|
||||||
|
(:require
|
||||||
|
[re-frame.core :as re-frame]
|
||||||
|
[status-im.ui.components.react :as react]
|
||||||
|
[status-im.i18n :as i18n]
|
||||||
|
[status-im.ui.components.styles :as components.styles]
|
||||||
|
[status-im.ui.components.common.common :as components.common]
|
||||||
|
[status-im.ui.components.status-bar.view :as status-bar]
|
||||||
|
[status-im.ui.components.toolbar.view :as toolbar]
|
||||||
|
[status-im.ui.components.text-input.view :as text-input]
|
||||||
|
[status-im.ui.screens.bootnodes-settings.edit-bootnode.styles :as styles]))
|
||||||
|
|
||||||
|
(views/defview edit-bootnode []
|
||||||
|
(views/letsubs [manage-bootnode [:get-manage-bootnode]
|
||||||
|
is-valid? [:manage-bootnode-valid?]]
|
||||||
|
[react/view components.styles/flex
|
||||||
|
[status-bar/status-bar]
|
||||||
|
[react/keyboard-avoiding-view components.styles/flex
|
||||||
|
[toolbar/simple-toolbar (i18n/label :t/add-bootnode)]
|
||||||
|
[react/scroll-view
|
||||||
|
[react/view styles/edit-bootnode-view
|
||||||
|
[text-input/text-input-with-label
|
||||||
|
{:label (i18n/label :t/name)
|
||||||
|
:placeholder (i18n/label :t/specify-name)
|
||||||
|
:container styles/input-container
|
||||||
|
:default-value (get-in manage-bootnode [:name :value])
|
||||||
|
:on-change-text #(re-frame/dispatch [:bootnode-set-input :name %])
|
||||||
|
:auto-focus true}]
|
||||||
|
[text-input/text-input-with-label
|
||||||
|
{:label (i18n/label :t/bootnode-address)
|
||||||
|
:placeholder (i18n/label :t/specify-bootnode-address)
|
||||||
|
:container styles/input-container
|
||||||
|
:default-value (get-in manage-bootnode [:url :value])
|
||||||
|
:on-change-text #(re-frame/dispatch [:bootnode-set-input :url %])}]]]
|
||||||
|
[react/view styles/bottom-container
|
||||||
|
[react/view components.styles/flex]
|
||||||
|
[components.common/bottom-button
|
||||||
|
{:forward? true
|
||||||
|
:label (i18n/label :t/save)
|
||||||
|
:disabled? (not is-valid?)
|
||||||
|
:on-press #(re-frame/dispatch [:save-new-bootnode])}]]]]))
|
|
@ -0,0 +1,22 @@
|
||||||
|
(ns status-im.ui.screens.bootnodes-settings.events
|
||||||
|
(:require [re-frame.core :as re-frame]
|
||||||
|
[status-im.utils.handlers :as handlers]
|
||||||
|
[status-im.utils.handlers-macro :as handlers-macro]
|
||||||
|
[status-im.ui.screens.accounts.events :as accounts-events]
|
||||||
|
[status-im.i18n :as i18n]
|
||||||
|
[status-im.transport.core :as transport]
|
||||||
|
status-im.ui.screens.bootnodes-settings.edit-bootnode.events
|
||||||
|
[status-im.utils.ethereum.core :as ethereum]))
|
||||||
|
|
||||||
|
(defn toggle-custom-bootnodes [value {:keys [db] :as cofx}]
|
||||||
|
(let [network (get-in db [:account/account :network])
|
||||||
|
settings (get-in db [:account/account :settings])]
|
||||||
|
(handlers-macro/merge-fx cofx
|
||||||
|
(accounts-events/update-settings
|
||||||
|
(assoc-in settings [:bootnodes network] value)
|
||||||
|
[:logout]))))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:toggle-custom-bootnodes
|
||||||
|
(fn [cofx [_ value]]
|
||||||
|
(toggle-custom-bootnodes value cofx)))
|
|
@ -0,0 +1,30 @@
|
||||||
|
(ns status-im.ui.screens.bootnodes-settings.styles
|
||||||
|
(:require [status-im.ui.components.colors :as colors])
|
||||||
|
(:require-macros [status-im.utils.styles :refer [defstyle]]))
|
||||||
|
|
||||||
|
(def wrapper
|
||||||
|
{:flex 1
|
||||||
|
:background-color :white})
|
||||||
|
|
||||||
|
(def bootnode-item-inner
|
||||||
|
{:padding-horizontal 16})
|
||||||
|
|
||||||
|
(defstyle bootnode-item
|
||||||
|
{:flex-direction :row
|
||||||
|
:background-color :white
|
||||||
|
:align-items :center
|
||||||
|
:padding-horizontal 16
|
||||||
|
:ios {:height 64}
|
||||||
|
:android {:height 56}})
|
||||||
|
|
||||||
|
(defstyle bootnode-item-name-text
|
||||||
|
{:color colors/black
|
||||||
|
:ios {:font-size 17
|
||||||
|
:letter-spacing -0.2
|
||||||
|
:line-height 20}
|
||||||
|
:android {:font-size 16}})
|
||||||
|
|
||||||
|
(defstyle switch-container
|
||||||
|
{:height 50
|
||||||
|
:background-color colors/white
|
||||||
|
:padding-left 15})
|
|
@ -0,0 +1,15 @@
|
||||||
|
(ns status-im.ui.screens.bootnodes-settings.subs
|
||||||
|
(:require [re-frame.core :as re-frame]
|
||||||
|
status-im.ui.screens.bootnodes-settings.edit-bootnode.subs
|
||||||
|
[status-im.utils.ethereum.core :as ethereum]))
|
||||||
|
|
||||||
|
(re-frame/reg-sub :settings/bootnodes-enabled
|
||||||
|
:<- [:get :account/account]
|
||||||
|
(fn [account]
|
||||||
|
(let [{:keys [network settings]} account]
|
||||||
|
(get-in settings [:bootnodes network]))))
|
||||||
|
|
||||||
|
(re-frame/reg-sub :settings/network-bootnodes
|
||||||
|
:<- [:get :account/account]
|
||||||
|
(fn [account]
|
||||||
|
(get-in account [:bootnodes (:network account)])))
|
|
@ -0,0 +1,46 @@
|
||||||
|
(ns status-im.ui.screens.bootnodes-settings.views
|
||||||
|
(:require-macros [status-im.utils.views :as views])
|
||||||
|
(:require [re-frame.core :as re-frame]
|
||||||
|
[status-im.i18n :as i18n]
|
||||||
|
[status-im.utils.config :as config]
|
||||||
|
[status-im.ui.components.colors :as colors]
|
||||||
|
[status-im.ui.components.icons.vector-icons :as vector-icons]
|
||||||
|
[status-im.ui.components.list.views :as list]
|
||||||
|
[status-im.ui.components.react :as react]
|
||||||
|
[status-im.ui.components.status-bar.view :as status-bar]
|
||||||
|
[status-im.ui.components.toolbar.view :as toolbar]
|
||||||
|
[status-im.ui.components.toolbar.actions :as toolbar.actions]
|
||||||
|
[status-im.ui.screens.profile.components.views :as profile.components]
|
||||||
|
[status-im.ui.screens.bootnodes-settings.styles :as styles]))
|
||||||
|
|
||||||
|
(defn navigate-to-add-bootnode []
|
||||||
|
(re-frame/dispatch [:edit-bootnode]))
|
||||||
|
|
||||||
|
(defn render-row [{:keys [name id]}]
|
||||||
|
[react/view
|
||||||
|
{:accessibility-label :bootnode-item}
|
||||||
|
[react/view styles/bootnode-item
|
||||||
|
[react/view styles/bootnode-item-inner
|
||||||
|
[react/text {:style styles/bootnode-item-name-text}
|
||||||
|
name]]]])
|
||||||
|
|
||||||
|
(views/defview bootnodes-settings []
|
||||||
|
(views/letsubs [bootnodes-enabled [:settings/bootnodes-enabled]
|
||||||
|
bootnodes [:settings/network-bootnodes]]
|
||||||
|
[react/view {:flex 1}
|
||||||
|
[status-bar/status-bar]
|
||||||
|
[toolbar/toolbar {}
|
||||||
|
toolbar/default-nav-back
|
||||||
|
[toolbar/content-title (i18n/label :t/bootnodes-settings)]
|
||||||
|
[toolbar/actions
|
||||||
|
[(toolbar.actions/add false navigate-to-add-bootnode)]]]
|
||||||
|
[react/view styles/switch-container
|
||||||
|
[profile.components/settings-switch-item
|
||||||
|
{:label-kw :t/bootnodes-enabled
|
||||||
|
:value bootnodes-enabled
|
||||||
|
:action-fn #(re-frame/dispatch [:toggle-custom-bootnodes %])}]]
|
||||||
|
[react/view styles/wrapper
|
||||||
|
[list/flat-list {:data (vals bootnodes)
|
||||||
|
:default-separator? false
|
||||||
|
:key-fn :id
|
||||||
|
:render-fn render-row}]]]))
|
|
@ -170,6 +170,7 @@
|
||||||
:networks/networks
|
:networks/networks
|
||||||
:networks/manage
|
:networks/manage
|
||||||
:mailservers/manage
|
:mailservers/manage
|
||||||
|
:bootnodes/manage
|
||||||
:node/after-start
|
:node/after-start
|
||||||
:node/after-stop
|
:node/after-stop
|
||||||
:inbox/wnodes
|
:inbox/wnodes
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
status-im.ui.screens.wallet.choose-recipient.events
|
status-im.ui.screens.wallet.choose-recipient.events
|
||||||
status-im.ui.screens.browser.events
|
status-im.ui.screens.browser.events
|
||||||
status-im.ui.screens.offline-messaging-settings.events
|
status-im.ui.screens.offline-messaging-settings.events
|
||||||
|
status-im.ui.screens.bootnodes-settings.events
|
||||||
status-im.ui.screens.currency-settings.events
|
status-im.ui.screens.currency-settings.events
|
||||||
status-im.ui.screens.usage-data.events
|
status-im.ui.screens.usage-data.events
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
(:require [re-frame.core :refer [dispatch dispatch-sync after] :as re-frame]
|
(:require [re-frame.core :refer [dispatch dispatch-sync after] :as re-frame]
|
||||||
[status-im.utils.handlers :refer [register-handler] :as handlers]
|
[status-im.utils.handlers :refer [register-handler] :as handlers]
|
||||||
status-im.ui.screens.network-settings.edit-network.events
|
status-im.ui.screens.network-settings.edit-network.events
|
||||||
status-im.ui.screens.offline-messaging-settings.edit-mailserver.events
|
|
||||||
[status-im.utils.handlers-macro :as handlers-macro]
|
[status-im.utils.handlers-macro :as handlers-macro]
|
||||||
[status-im.ui.screens.accounts.utils :as accounts.utils]
|
[status-im.ui.screens.accounts.utils :as accounts.utils]
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
[status-im.ui.screens.accounts.events :as accounts-events]
|
[status-im.ui.screens.accounts.events :as accounts-events]
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
[status-im.transport.core :as transport]
|
[status-im.transport.core :as transport]
|
||||||
|
status-im.ui.screens.offline-messaging-settings.edit-mailserver.events
|
||||||
[status-im.utils.ethereum.core :as ethereum]))
|
[status-im.utils.ethereum.core :as ethereum]))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
|
|
|
@ -152,6 +152,11 @@
|
||||||
{:label-kw :t/offline-messaging
|
{:label-kw :t/offline-messaging
|
||||||
:action-fn #(re-frame/dispatch [:navigate-to :offline-messaging-settings])
|
:action-fn #(re-frame/dispatch [:navigate-to :offline-messaging-settings])
|
||||||
:accessibility-label :offline-messages-settings-button}])
|
:accessibility-label :offline-messages-settings-button}])
|
||||||
|
(when config/bootnodes-settings-enabled?
|
||||||
|
[profile.components/settings-item
|
||||||
|
{:label-kw :t/bootnodes
|
||||||
|
:action-fn #(re-frame/dispatch [:navigate-to :bootnodes-settings])
|
||||||
|
:accessibility-label :bootnodes-settings-button}])
|
||||||
[profile.components/settings-item-separator]
|
[profile.components/settings-item-separator]
|
||||||
[profile.components/settings-item
|
[profile.components/settings-item
|
||||||
{:label-kw :t/help-improve?
|
{:label-kw :t/help-improve?
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
status-im.ui.screens.wallet.transactions.subs
|
status-im.ui.screens.wallet.transactions.subs
|
||||||
status-im.ui.screens.network-settings.subs
|
status-im.ui.screens.network-settings.subs
|
||||||
status-im.ui.screens.offline-messaging-settings.subs
|
status-im.ui.screens.offline-messaging-settings.subs
|
||||||
|
status-im.ui.screens.bootnodes-settings.subs
|
||||||
status-im.ui.screens.currency-settings.subs
|
status-im.ui.screens.currency-settings.subs
|
||||||
status-im.ui.screens.browser.subs
|
status-im.ui.screens.browser.subs
|
||||||
status-im.bots.subs
|
status-im.bots.subs
|
||||||
|
|
|
@ -39,6 +39,8 @@
|
||||||
[status-im.ui.screens.network-settings.edit-network.views :refer [edit-network]]
|
[status-im.ui.screens.network-settings.edit-network.views :refer [edit-network]]
|
||||||
[status-im.ui.screens.offline-messaging-settings.views :refer [offline-messaging-settings]]
|
[status-im.ui.screens.offline-messaging-settings.views :refer [offline-messaging-settings]]
|
||||||
[status-im.ui.screens.offline-messaging-settings.edit-mailserver.views :refer [edit-mailserver]]
|
[status-im.ui.screens.offline-messaging-settings.edit-mailserver.views :refer [edit-mailserver]]
|
||||||
|
[status-im.ui.screens.bootnodes-settings.views :refer [bootnodes-settings]]
|
||||||
|
[status-im.ui.screens.bootnodes-settings.edit-bootnode.views :refer [edit-bootnode]]
|
||||||
[status-im.ui.screens.currency-settings.views :refer [currency-settings]]
|
[status-im.ui.screens.currency-settings.views :refer [currency-settings]]
|
||||||
[status-im.ui.screens.browser.views :refer [browser]]
|
[status-im.ui.screens.browser.views :refer [browser]]
|
||||||
[status-im.ui.screens.add-new.open-dapp.views :refer [open-dapp dapp-description]]
|
[status-im.ui.screens.add-new.open-dapp.views :refer [open-dapp dapp-description]]
|
||||||
|
@ -85,6 +87,8 @@
|
||||||
:edit-network edit-network
|
:edit-network edit-network
|
||||||
:offline-messaging-settings offline-messaging-settings
|
:offline-messaging-settings offline-messaging-settings
|
||||||
:edit-mailserver edit-mailserver
|
:edit-mailserver edit-mailserver
|
||||||
|
:bootnodes-settings bootnodes-settings
|
||||||
|
:edit-bootnode edit-bootnode
|
||||||
:currency-settings currency-settings
|
:currency-settings currency-settings
|
||||||
:recent-recipients recent-recipients
|
:recent-recipients recent-recipients
|
||||||
:recipient-qr-code recipient-qr-code
|
:recipient-qr-code recipient-qr-code
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
(def stub-status-go? (enabled? (get-config :STUB_STATUS_GO 0)))
|
(def stub-status-go? (enabled? (get-config :STUB_STATUS_GO 0)))
|
||||||
(def mainnet-warning-enabled? (enabled? (get-config :MAINNET_WARNING_ENABLED 0)))
|
(def mainnet-warning-enabled? (enabled? (get-config :MAINNET_WARNING_ENABLED 0)))
|
||||||
(def offline-inbox-enabled? (enabled? (get-config :OFFLINE_INBOX_ENABLED "1")))
|
(def offline-inbox-enabled? (enabled? (get-config :OFFLINE_INBOX_ENABLED "1")))
|
||||||
|
(def bootnodes-settings-enabled? (enabled? (get-config :BOOTNODES_SETTINGS_ENABLED "1")))
|
||||||
(def log-level
|
(def log-level
|
||||||
(-> (get-config :LOG_LEVEL "error")
|
(-> (get-config :LOG_LEVEL "error")
|
||||||
string/lower-case
|
string/lower-case
|
||||||
|
|
|
@ -35,7 +35,9 @@
|
||||||
[status-im.test.utils.datetime]
|
[status-im.test.utils.datetime]
|
||||||
[status-im.test.utils.mixpanel]
|
[status-im.test.utils.mixpanel]
|
||||||
[status-im.test.utils.prices]
|
[status-im.test.utils.prices]
|
||||||
[status-im.test.ui.screens.network-settings.edit-network.events]))
|
[status-im.test.ui.screens.network-settings.edit-network.events]
|
||||||
|
[status-im.test.ui.screens.bootnodes-settings.edit-bootnode.events]
|
||||||
|
[status-im.test.ui.screens.accounts.login.events]))
|
||||||
|
|
||||||
(enable-console-print!)
|
(enable-console-print!)
|
||||||
|
|
||||||
|
@ -81,4 +83,6 @@
|
||||||
'status-im.test.utils.datetime
|
'status-im.test.utils.datetime
|
||||||
'status-im.test.utils.mixpanel
|
'status-im.test.utils.mixpanel
|
||||||
'status-im.test.utils.prices
|
'status-im.test.utils.prices
|
||||||
'status-im.test.ui.screens.network-settings.edit-network.events)
|
'status-im.test.ui.screens.network-settings.edit-network.events
|
||||||
|
'status-im.test.ui.screens.bootnodes-settings.edit-bootnode.events
|
||||||
|
'status-im.test.ui.screens.accounts.login.events)
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
(ns status-im.test.ui.screens.accounts.login.events
|
||||||
|
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||||
|
[status-im.utils.config :as config]
|
||||||
|
[status-im.ui.screens.accounts.login.events :as events]))
|
||||||
|
|
||||||
|
(deftest login-account
|
||||||
|
(let [mainnet-account {:network "mainnet_rpc"
|
||||||
|
:networks {"mainnet_rpc" {:config {:NetworkId 1}}}}
|
||||||
|
testnet-account {:network "testnet_rpc"
|
||||||
|
:networks {"testnet_rpc" {:config {:NetworkId 3}}}}
|
||||||
|
accounts {"mainnet" mainnet-account
|
||||||
|
"testnet" testnet-account}
|
||||||
|
initial-db {:db {:network "mainnet_rpc"
|
||||||
|
:accounts/accounts accounts}}]
|
||||||
|
|
||||||
|
(testing "status-go has not started"
|
||||||
|
(let [actual (events/login-account initial-db [nil "testnet" "password"])]
|
||||||
|
(testing "it starts status-node if it has not started"
|
||||||
|
(is (= {:NetworkId 3}
|
||||||
|
(:initialize-geth-fx
|
||||||
|
actual))))
|
||||||
|
(testing "it logins the user after the node started"
|
||||||
|
(is (= [::events/login-account "testnet" "password"] (get-in actual [:db :node/after-start]))))))
|
||||||
|
|
||||||
|
(testing "status-go has started & the user is on mainnet"
|
||||||
|
(let [db (assoc-in initial-db [:db :status-node-started?] true)
|
||||||
|
actual (events/login-account
|
||||||
|
db
|
||||||
|
[nil "mainnet" "password"])]
|
||||||
|
(testing "it does not start status-node if it has already started"
|
||||||
|
(is (not (:initialize-geth-fx actual))))
|
||||||
|
(testing "it logs in the user"
|
||||||
|
(is (= ["mainnet" "password"] (::events/login actual))))))
|
||||||
|
|
||||||
|
(testing "the user has selected a different network"
|
||||||
|
(testing "status-go has started"
|
||||||
|
(let [db (assoc-in initial-db [:db :status-node-started?] true)
|
||||||
|
actual (events/login-account
|
||||||
|
db
|
||||||
|
[nil "testnet" "password"])]
|
||||||
|
(testing "it dispatches start-node"
|
||||||
|
(is (get-in actual [:db :node/after-stop] [::events/start-node "testnet" "password"])))
|
||||||
|
(testing "it stops status-node"
|
||||||
|
(is (contains? actual ::events/stop-node)))))
|
||||||
|
|
||||||
|
(testing "status-go has not started"
|
||||||
|
(let [actual (events/login-account
|
||||||
|
initial-db
|
||||||
|
[nil "testnet" "password"])]
|
||||||
|
(testing "it starts status-node"
|
||||||
|
(is (= {:NetworkId 3} (:initialize-geth-fx actual))))
|
||||||
|
(testing "it logins the user after the node started"
|
||||||
|
(is (= [::events/login-account "testnet" "password"] (get-in actual [:db :node/after-start])))))))
|
||||||
|
|
||||||
|
(testing "custom bootnodes"
|
||||||
|
(let [custom-bootnodes {"a" {:id "a"
|
||||||
|
:name "name-a"
|
||||||
|
:address "address-a"}
|
||||||
|
"b" {:id "b"
|
||||||
|
:name "name-b"
|
||||||
|
:address "address-b"}}
|
||||||
|
bootnodes-db (assoc-in
|
||||||
|
initial-db
|
||||||
|
[:db :accounts/accounts "mainnet" :bootnodes]
|
||||||
|
{"mainnet_rpc" custom-bootnodes})]
|
||||||
|
|
||||||
|
(testing "custom bootnodes enabled"
|
||||||
|
(let [bootnodes-enabled-db (assoc-in
|
||||||
|
bootnodes-db
|
||||||
|
[:db :accounts/accounts "mainnet" :settings]
|
||||||
|
{:bootnodes {"mainnet_rpc" true}})
|
||||||
|
actual (events/login-account
|
||||||
|
bootnodes-enabled-db
|
||||||
|
[nil "mainnet" "password"])]
|
||||||
|
(testing "status-node has started"
|
||||||
|
(let [db (assoc-in bootnodes-enabled-db [:db :status-node-started?] true)
|
||||||
|
actual (events/login-account
|
||||||
|
db
|
||||||
|
[nil "mainnet" "password"])]
|
||||||
|
(testing "it dispatches start-node"
|
||||||
|
(is (get-in actual [:db :node/after-stop] [::events/start-node "testnet" "password"])))
|
||||||
|
(testing "it stops status-node"
|
||||||
|
(is (contains? actual ::events/stop-node)))))
|
||||||
|
(testing "status-node has not started"
|
||||||
|
(let [actual (events/login-account
|
||||||
|
bootnodes-enabled-db
|
||||||
|
[nil "mainnet" "password"])]
|
||||||
|
(testing "it adds bootnodes to the config"
|
||||||
|
(is (= {:ClusterConfig {:Enabled true
|
||||||
|
:BootNodes ["address-a" "address-b"]}
|
||||||
|
:NetworkId 1} (:initialize-geth-fx actual))))
|
||||||
|
(testing "it logins the user after the node started"
|
||||||
|
(is (= [::events/login-account "mainnet" "password"] (get-in actual [:db :node/after-start]))))))))
|
||||||
|
|
||||||
|
(testing "custom bootnodes not enabled"
|
||||||
|
(testing "status-node has started"
|
||||||
|
(let [db (assoc-in bootnodes-db [:db :status-node-started?] true)
|
||||||
|
actual (events/login-account
|
||||||
|
db
|
||||||
|
[nil "mainnet" "password"])]
|
||||||
|
(testing "it does not start status-node if it has already started"
|
||||||
|
(is (not (:initialize-geth-fx actual))))
|
||||||
|
(testing "it logs in the user"
|
||||||
|
(is (= ["mainnet" "password"] (::events/login actual))))))
|
||||||
|
(testing "status-node has not started"
|
||||||
|
(let [actual (events/login-account
|
||||||
|
bootnodes-db
|
||||||
|
[nil "mainnet" "password"])]
|
||||||
|
(testing "it starts status-node without custom bootnodes"
|
||||||
|
(is (= {:NetworkId 1} (:initialize-geth-fx actual))))
|
||||||
|
(testing "it logins the user after the node started"
|
||||||
|
(is (= [::events/login-account "mainnet" "password"] (get-in actual [:db :node/after-start])))))))))))
|
||||||
|
|
||||||
|
(deftest restart-node?
|
||||||
|
(testing "custom bootnodes is toggled off"
|
||||||
|
(with-redefs [config/bootnodes-settings-enabled? false]
|
||||||
|
(testing "it returns true when the network is different"
|
||||||
|
(is (events/restart-node? "mainnet_rpc" "mainnet" true)))
|
||||||
|
(testing "it returns false when the network is the same"
|
||||||
|
(is (not (events/restart-node? "mainnet" "mainnet" true))))))
|
||||||
|
(testing "custom bootnodes is toggled on"
|
||||||
|
(with-redefs [config/bootnodes-settings-enabled? true]
|
||||||
|
(testing "the user is not using custom bootnodes"
|
||||||
|
(testing "it returns true when the network is different"
|
||||||
|
(is (events/restart-node? "mainnet_rpc" "mainnet" false)))
|
||||||
|
(testing "it returns false when the network is the same"
|
||||||
|
(is (not (events/restart-node? "mainnet" "mainnet" false)))))
|
||||||
|
(testing "the user is using custom bootnodes"
|
||||||
|
(testing "it returns true when the network is different"
|
||||||
|
(is (events/restart-node? "mainnet" "mainnet" true)))
|
||||||
|
(testing "it returns true when the network is the same"
|
||||||
|
(is (events/restart-node? "mainnet_rpc" "mainnet" true)))))))
|
|
@ -0,0 +1,19 @@
|
||||||
|
(ns status-im.test.ui.screens.bootnodes-settings.edit-bootnode.events
|
||||||
|
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||||
|
[status-im.ui.screens.bootnodes-settings.edit-bootnode.events :as events]))
|
||||||
|
|
||||||
|
(deftest add-new-bootnode
|
||||||
|
(testing "adding a bootnode"
|
||||||
|
(let [new-bootnode {:name {:value "name"}
|
||||||
|
:url {:value "url"}}
|
||||||
|
expected {"mainnet_rpc" {"someid" {:name "name"
|
||||||
|
:address "url"
|
||||||
|
:chain "mainnet_rpc"
|
||||||
|
:id "someid"}}}
|
||||||
|
actual (events/save-new-bootnode
|
||||||
|
{:random-id "some-id"
|
||||||
|
:db {:bootnodes/manage new-bootnode
|
||||||
|
:network "mainnet_rpc"
|
||||||
|
:account/account {}}}
|
||||||
|
nil)]
|
||||||
|
(is (= expected (get-in actual [:db :account/account :bootnodes]))))))
|
Loading…
Reference in New Issue