data_store and network_settings from #1115
missed default networks fix :load-default-networks network settings screen fix network details screen networks in account fix network property saving update startNode and stopNode on iOS test RPC proxy on iOS StopNode and StartNode on androd pass UpstreamConfig to status-go upgrade status-go added default network on login fixed UI, added vector icons added network name in drawer migrated accounts workaround for account v4 migration
This commit is contained in:
parent
dbb1487fbd
commit
cf7a9845c6
1
.env
1
.env
|
@ -3,3 +3,4 @@ WALLET_WIP_ENABLED=1
|
|||
NOTIFICATIONS_WIP_ENABLED=1
|
||||
DEBUG_LOGS_ENABLED=1
|
||||
STUB_STATUS_GO=0
|
||||
NETWORK_SWITCHING=0
|
||||
|
|
|
@ -3,4 +3,4 @@ WALLET_WIP_ENABLED=1
|
|||
NOTIFICATIONS_WIP_ENABLED=1
|
||||
DEBUG_LOGS_ENABLED=1
|
||||
STUB_STATUS_GO=0
|
||||
|
||||
NETWORK_SWITCHING=1
|
||||
|
|
|
@ -104,7 +104,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
|||
this.getReactApplicationContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("gethEvent", params);
|
||||
}
|
||||
|
||||
private void doStartNode() {
|
||||
private void doStartNode(final String defaultConfig) {
|
||||
|
||||
Activity currentActivity = getCurrentActivity();
|
||||
|
||||
|
@ -139,15 +139,52 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
|||
}
|
||||
}
|
||||
|
||||
String config;
|
||||
int devCluster = this.debug ? 1 : 0;
|
||||
String defaultConfig = Statusgo.GenerateConfig(dataFolder, 3, devCluster);
|
||||
String testnetDataDir = root + "/ethereum/testnet";
|
||||
String oldKeystoreDir = testnetDataDir + "/keystore";
|
||||
String newKeystoreDir = root + "/keystore";
|
||||
final File oldKeystore = new File(oldKeystoreDir);
|
||||
if (oldKeystore.exists()) {
|
||||
try {
|
||||
final File newKeystore = new File(newKeystoreDir);
|
||||
copyDirectory(oldKeystore, newKeystore);
|
||||
|
||||
if (oldKeystore.isDirectory()) {
|
||||
String[] children = oldKeystore.list();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
new File(oldKeystoreDir, children[i]).delete();
|
||||
}
|
||||
}
|
||||
oldKeystore.delete();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
int dev = 0;
|
||||
if (this.debug) {
|
||||
dev = 1;
|
||||
}
|
||||
|
||||
String config = Statusgo.GenerateConfig(testnetDataDir, 3, dev);
|
||||
try {
|
||||
JSONObject jsonConfig = new JSONObject(defaultConfig);
|
||||
JSONObject customConfig = new JSONObject(defaultConfig);
|
||||
JSONObject jsonConfig = new JSONObject(config);
|
||||
String gethLogFileName = "geth.log";
|
||||
jsonConfig.put("LogEnabled", true);
|
||||
jsonConfig.put("LogEnabled", false);
|
||||
jsonConfig.put("LogFile", gethLogFileName);
|
||||
jsonConfig.put("LogLevel", "DEBUG");
|
||||
jsonConfig.put("DataDir", root + customConfig.get("DataDir"));
|
||||
jsonConfig.put("NetworkId", customConfig.get("NetworkId"));
|
||||
try {
|
||||
Object upstreamConfig = customConfig.get("UpstreamConfig");
|
||||
if (upstreamConfig != null) {
|
||||
Log.d(TAG, "UpstreamConfig is not null");
|
||||
jsonConfig.put("UpstreamConfig", upstreamConfig);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
jsonConfig.put("KeyStoreDir", newKeystoreDir);
|
||||
String gethLogPath = dataFolder + "/" + gethLogFileName;
|
||||
File logFile = new File(gethLogPath);
|
||||
if (logFile.exists()) {
|
||||
|
@ -176,11 +213,12 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
|||
} catch (JSONException e) {
|
||||
Log.d(TAG, "Something went wrong " + e.getMessage());
|
||||
Log.d(TAG, "Default configuration will be used");
|
||||
|
||||
config = defaultConfig;
|
||||
}
|
||||
|
||||
Statusgo.StartNode(config);
|
||||
Log.d(TAG, "Node config " + config);
|
||||
|
||||
String res = Statusgo.StartNode(config);
|
||||
Log.d(TAG, "StartNode result: " + res);
|
||||
Log.d(TAG, "Geth node started");
|
||||
}
|
||||
|
||||
|
@ -265,24 +303,21 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
|||
}
|
||||
|
||||
@ReactMethod
|
||||
public void startNode(Callback callback) {
|
||||
public void startNode(final String config) {
|
||||
Log.d(TAG, "startNode");
|
||||
status.sendMessage();
|
||||
if (!checkAvailability()) {
|
||||
callback.invoke(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Thread thread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
doStartNode();
|
||||
doStartNode(config);
|
||||
}
|
||||
};
|
||||
|
||||
thread.start();
|
||||
|
||||
callback.invoke(false);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
|
@ -321,6 +356,20 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
|||
thread.start();
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void stopNode() {
|
||||
|
||||
Thread thread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
Log.d(TAG, "stopNode");
|
||||
String res = Statusgo.StopNode();
|
||||
}
|
||||
};
|
||||
|
||||
thread.start();
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void login(final String address, final String password, final Callback callback) {
|
||||
Log.d(TAG, "login");
|
||||
|
|
|
@ -101,157 +101,101 @@ RCT_EXPORT_METHOD(callJail:(NSString *)chatId
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
const int STATE_ACTIVE = 0;
|
||||
const int STATE_LOCKED_WITH_ACTIVE_APP = 1;
|
||||
const int STATE_BACKGROUND = 2;
|
||||
const int STATE_LOCKED_WITH_INACTIVE_APP = 3;
|
||||
int wozniakConstant = STATE_ACTIVE;
|
||||
|
||||
|
||||
static void displayStatusChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
|
||||
{
|
||||
// the "com.apple.springboard.lockcomplete" notification will always come after the "com.apple.springboard.lockstate" notification
|
||||
CFStringRef nameCFString = (CFStringRef)name;
|
||||
NSString *lockState = (__bridge NSString*)nameCFString;
|
||||
NSLog(@"Darwin notification NAME = %@",name);
|
||||
|
||||
NSString* sm = [NSString stringWithFormat:@"%i", wozniakConstant];
|
||||
NSString *s1 = [NSString stringWithFormat:@"%@ %@", @"LOCK MAGIC", sm];
|
||||
NSLog(s1);
|
||||
if([lockState isEqualToString:@"com.apple.springboard.lockcomplete"])
|
||||
{
|
||||
NSLog(@"DEVICE LOCKED");
|
||||
// User locks phone when application is active
|
||||
if(wozniakConstant == STATE_ACTIVE){
|
||||
wozniakConstant = STATE_LOCKED_WITH_ACTIVE_APP;
|
||||
StopNodeRPCServer();
|
||||
}
|
||||
|
||||
// Here lockcomplete event comes when app is unlocked
|
||||
// because it couldn't come when locking happened
|
||||
// as application was not active (it could not handle callback)
|
||||
if (wozniakConstant == STATE_LOCKED_WITH_INACTIVE_APP) {
|
||||
wozniakConstant = STATE_ACTIVE;
|
||||
StopNodeRPCServer();
|
||||
StartNodeRPCServer();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"LOCK STATUS CHANGED");
|
||||
NSString *s = [NSString stringWithFormat:@"%@ %@", @"LOCK", lockState];
|
||||
NSLog(s);
|
||||
|
||||
// if lockstate happens before lockcomplete it means
|
||||
// that phone was locked when application was not active
|
||||
if(wozniakConstant == STATE_ACTIVE){
|
||||
wozniakConstant = STATE_LOCKED_WITH_INACTIVE_APP;
|
||||
}
|
||||
|
||||
if(wozniakConstant == STATE_BACKGROUND){
|
||||
wozniakConstant = STATE_ACTIVE;
|
||||
StartNodeRPCServer();
|
||||
}
|
||||
|
||||
// one more lockstate event comes along with lockcomplete
|
||||
// when phone is locked with active application
|
||||
if(wozniakConstant == STATE_LOCKED_WITH_ACTIVE_APP){
|
||||
wozniakConstant = STATE_BACKGROUND;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#pragma mark - startNode
|
||||
//////////////////////////////////////////////////////////////////// startNode
|
||||
RCT_EXPORT_METHOD(startNode:(RCTResponseSenderBlock)onResultCallback) {
|
||||
RCT_EXPORT_METHOD(startNode:(NSString *)configString) {
|
||||
#if DEBUG
|
||||
NSLog(@"StartNode() method called");
|
||||
#endif
|
||||
if (!isStatusInitialized){
|
||||
isStatusInitialized = true;
|
||||
|
||||
NSError *error = nil;
|
||||
NSURL *folderName =[[[[NSFileManager defaultManager]
|
||||
URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]
|
||||
lastObject]
|
||||
URLByAppendingPathComponent:@"ethereum/testnet"];
|
||||
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:folderName.path])
|
||||
[[NSFileManager defaultManager] createDirectoryAtPath:folderName.path withIntermediateDirectories:NO attributes:nil error:&error];
|
||||
NSURL *flagFolderUrl = [[[[NSFileManager defaultManager]
|
||||
URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]
|
||||
lastObject]
|
||||
URLByAppendingPathComponent:@"ropsten_flag"];
|
||||
|
||||
if(![[NSFileManager defaultManager] fileExistsAtPath:flagFolderUrl.path]){
|
||||
NSURL *lightChainData = [folderName URLByAppendingPathComponent:@"StatusIM/lightchaindata"];
|
||||
[[NSFileManager defaultManager] removeItemAtPath:lightChainData.path
|
||||
error:nil];
|
||||
NSString *content = @"";
|
||||
NSData *fileContents = [content dataUsingEncoding:NSUTF8StringEncoding];
|
||||
[[NSFileManager defaultManager] createDirectoryAtPath:flagFolderUrl.path
|
||||
withIntermediateDirectories:NO
|
||||
attributes:nil
|
||||
error:&error];
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSError *error = nil;
|
||||
NSURL *rootUrl =[[fileManager
|
||||
URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]
|
||||
lastObject];
|
||||
NSURL *testnetFolderName = [rootUrl URLByAppendingPathComponent:@"ethereum/testnet"];
|
||||
|
||||
if (![fileManager fileExistsAtPath:testnetFolderName.path])
|
||||
[fileManager createDirectoryAtPath:testnetFolderName.path withIntermediateDirectories:YES attributes:nil error:&error];
|
||||
|
||||
NSURL *flagFolderUrl = [rootUrl URLByAppendingPathComponent:@"ropsten_flag"];
|
||||
|
||||
if(![fileManager fileExistsAtPath:flagFolderUrl.path]){
|
||||
NSLog(@"remove lightchaindata");
|
||||
NSURL *lightChainData = [testnetFolderName URLByAppendingPathComponent:@"StatusIM/lightchaindata"];
|
||||
if([fileManager fileExistsAtPath:lightChainData.path]) {
|
||||
[fileManager removeItemAtPath:lightChainData.path
|
||||
error:nil];
|
||||
}
|
||||
|
||||
if (error){
|
||||
NSLog(@"error %@", error);
|
||||
}else
|
||||
NSLog(@"folderName: %@", folderName);
|
||||
#if DEBUG
|
||||
int devCluster = 1;
|
||||
[fileManager createDirectoryAtPath:flagFolderUrl.path
|
||||
withIntermediateDirectories:NO
|
||||
attributes:nil
|
||||
error:&error];
|
||||
}
|
||||
|
||||
NSLog(@"after remove lightchaindata");
|
||||
|
||||
NSURL *oldKeystoreUrl = [testnetFolderName URLByAppendingPathComponent:@"keystore"];
|
||||
NSURL *newKeystoreUrl = [rootUrl URLByAppendingPathComponent:@"keystore"];
|
||||
if([fileManager fileExistsAtPath:oldKeystoreUrl.path]){
|
||||
NSLog(@"copy keystore");
|
||||
[fileManager copyItemAtPath:oldKeystoreUrl.path toPath:newKeystoreUrl.path error:nil];
|
||||
[fileManager removeItemAtPath:oldKeystoreUrl.path error:nil];
|
||||
}
|
||||
|
||||
NSLog(@"after lightChainData");
|
||||
|
||||
NSLog(@"preconfig: %@", configString);
|
||||
NSData *configData = [configString dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSDictionary *configJSON = [NSJSONSerialization JSONObjectWithData:configData options:NSJSONReadingMutableContainers error:nil];
|
||||
int networkId = [configJSON[@"NetworkId"] integerValue];
|
||||
NSString *dataDir = [configJSON objectForKey:@"DataDir"];
|
||||
NSString *upstreamURL = [configJSON valueForKeyPath:@"UpstreamConfig.URL"];
|
||||
NSString *networkDir = [rootUrl.path stringByAppendingString:dataDir];
|
||||
#ifdef DEBUG
|
||||
int dev = 1;
|
||||
#else
|
||||
int devCluster = 0;
|
||||
int dev = 0;
|
||||
#endif
|
||||
char *configChars = GenerateConfig([folderName.path UTF8String], 3, devCluster);
|
||||
NSString *config = [NSString stringWithUTF8String: configChars];
|
||||
NSData *configData = [config dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSDictionary *resultingConfigJson = [NSJSONSerialization JSONObjectWithData:configData options:NSJSONReadingMutableContainers error:nil];
|
||||
[resultingConfigJson setValue:[NSNumber numberWithBool:YES] forKey:@"LogEnabled"];
|
||||
[resultingConfigJson setValue:@"geth.log" forKey:@"LogFile"];
|
||||
[resultingConfigJson setValue:@"DEBUG" forKey:@"LogLevel"];
|
||||
NSString *resultingConfig = [resultingConfigJson bv_jsonStringWithPrettyPrint:NO];
|
||||
NSURL *logUrl = [folderName URLByAppendingPathComponent:@"geth.log"];
|
||||
NSFileManager *manager = [NSFileManager defaultManager];
|
||||
if([[NSFileManager defaultManager] fileExistsAtPath:logUrl.path]) {
|
||||
[manager removeItemAtPath:logUrl.path error:nil];
|
||||
}
|
||||
|
||||
if(![manager fileExistsAtPath:folderName.path]) {
|
||||
[manager createDirectoryAtPath:folderName.path withIntermediateDirectories:YES attributes:nil error:nil];
|
||||
}
|
||||
|
||||
char *configChars = GenerateConfig((char *)[networkDir UTF8String], networkId, dev);
|
||||
NSString *config = [NSString stringWithUTF8String: configChars];
|
||||
configData = [config dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSDictionary *resultingConfigJson = [NSJSONSerialization JSONObjectWithData:configData options:NSJSONReadingMutableContainers error:nil];
|
||||
[resultingConfigJson setValue:newKeystoreUrl.path forKey:@"KeyStoreDir"];
|
||||
[resultingConfigJson setValue:[NSNumber numberWithBool:YES] forKey:@"LogEnabled"];
|
||||
[resultingConfigJson setValue:@"geth.log" forKey:@"LogFile"];
|
||||
[resultingConfigJson setValue:@"DEBUG" forKey:@"LogLevel"];
|
||||
|
||||
if(upstreamURL != nil) {
|
||||
[resultingConfigJson setValue:[NSNumber numberWithBool:YES] forKeyPath:@"UpstreamConfig.Enabled"];
|
||||
[resultingConfigJson setValue:upstreamURL forKeyPath:@"UpstreamConfig.URL"];
|
||||
}
|
||||
NSString *resultingConfig = [resultingConfigJson bv_jsonStringWithPrettyPrint:NO];
|
||||
NSLog(@"node config %@", resultingConfig);
|
||||
NSURL *networkDirUrl = [NSURL fileURLWithPath:networkDir];
|
||||
NSURL *logUrl = [networkDirUrl URLByAppendingPathComponent:@"geth.log"];
|
||||
if([fileManager fileExistsAtPath:logUrl.path]) {
|
||||
[fileManager removeItemAtPath:logUrl.path error:nil];
|
||||
}
|
||||
|
||||
if(![fileManager fileExistsAtPath:networkDirUrl.path]) {
|
||||
[fileManager createDirectoryAtPath:networkDirUrl.path withIntermediateDirectories:YES attributes:nil error:nil];
|
||||
}
|
||||
|
||||
NSLog(@"logUrlPath %@", logUrl.path);
|
||||
if(![fileManager fileExistsAtPath:logUrl.path]) {
|
||||
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
|
||||
[dict setObject:[NSNumber numberWithInt:511] forKey:NSFilePosixPermissions];
|
||||
[manager createFileAtPath:logUrl.path contents:nil attributes:dict];
|
||||
#ifndef DEBUG
|
||||
[Instabug addFileAttachmentWithURL:[folderName URLByAppendingPathComponent:@"geth.log"]];
|
||||
#endif
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
|
||||
^(void) {
|
||||
StartNode((char *) [resultingConfig UTF8String]);
|
||||
});
|
||||
onResultCallback(@[[NSNull null]]);
|
||||
//Screen lock notifications
|
||||
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
|
||||
NULL, // observer
|
||||
displayStatusChanged, // callback
|
||||
CFSTR("com.apple.springboard.lockcomplete"), // event name
|
||||
NULL, // object
|
||||
CFNotificationSuspensionBehaviorDeliverImmediately);
|
||||
|
||||
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
|
||||
NULL, // observer
|
||||
displayStatusChanged, // callback
|
||||
CFSTR("com.apple.springboard.lockstate"), // event name
|
||||
NULL, // object
|
||||
CFNotificationSuspensionBehaviorDeliverImmediately);
|
||||
return;
|
||||
[fileManager createFileAtPath:logUrl.path contents:nil attributes:dict];
|
||||
}
|
||||
#ifndef DEBUG
|
||||
[Instabug addFileAttachmentWithURL:logUrl];
|
||||
#endif
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
|
||||
^(void)
|
||||
{
|
||||
char *res = StartNode((char *) [resultingConfig UTF8String]);
|
||||
NSLog(@"StartNode result %@", [NSString stringWithUTF8String: res]); });
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -290,13 +234,19 @@ RCT_EXPORT_METHOD(stopNodeRPCServer) {
|
|||
StopNodeRPCServer();
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(stopNode:(RCTResponseSenderBlock)callback) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#pragma mark - StopNode method
|
||||
//////////////////////////////////////////////////////////////////// StopNode
|
||||
RCT_EXPORT_METHOD(stopNode) {
|
||||
#if DEBUG
|
||||
NSLog(@"stopNode() method called");
|
||||
NSLog(@"StopNode() method called");
|
||||
#endif
|
||||
// TODO: stop node
|
||||
|
||||
callback(@[[NSNull null]]);
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
|
||||
^(void)
|
||||
{
|
||||
char *res = StopNode();
|
||||
NSLog(@"StopNode result %@", [NSString stringWithUTF8String: res]);
|
||||
});
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<g fill="">
|
||||
<path d="M17,17 C17.8284271,17 18.5,16.3284271 18.5,15.5 C18.5,14.6715729 17.8284271,14 17,14 C16.1715729,14 15.5,14.6715729 15.5,15.5 C15.5,16.3284271 16.1715729,17 17,17 Z M17,18.5 C15.3431458,18.5 14,17.1568542 14,15.5 C14,13.8431458 15.3431458,12.5 17,12.5 C18.6568542,12.5 20,13.8431458 20,15.5 C20,17.1568542 18.6568542,18.5 17,18.5 Z M7,17 C7.82842712,17 8.5,16.3284271 8.5,15.5 C8.5,14.6715729 7.82842712,14 7,14 C6.17157288,14 5.5,14.6715729 5.5,15.5 C5.5,16.3284271 6.17157288,17 7,17 Z M7,18.5 C5.34314575,18.5 4,17.1568542 4,15.5 C4,13.8431458 5.34314575,12.5 7,12.5 C8.65685425,12.5 10,13.8431458 10,15.5 C10,17.1568542 8.65685425,18.5 7,18.5 Z M9,14.75 L15,14.75 L15,16.25 L9,16.25 L9,14.75 Z"/>
|
||||
<path d="M13.299539,7.65049482 C13.7137526,6.93305589 13.4679399,6.01567028 12.7505009,5.60145672 C12.033062,5.18724315 11.1156764,5.43305589 10.7014628,6.15049482 C10.2872493,6.86793376 10.533062,7.78531937 11.2505009,8.19953293 C11.9679399,8.61374649 12.8853255,8.36793376 13.299539,7.65049482 Z M14.5985771,8.40049482 C13.77015,9.83537269 11.9353788,10.3269982 10.5005009,9.49857103 C9.06562306,8.67014391 8.57399759,6.83537269 9.40242471,5.40049482 C10.2308518,3.96561695 12.0656231,3.47399149 13.5005009,4.30241861 C14.9353788,5.13084574 15.4270043,6.96561695 14.5985771,8.40049482 Z M7.35098187,13.4536981 L10.3509819,8.25754563 L11.65002,9.00754563 L8.65001998,14.2036981 L7.35098187,13.4536981 Z M16.65002,13.4536981 L15.3509819,14.2036981 L12.3509819,9.00754563 L13.65002,8.25754563 L16.65002,13.4536981 Z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
|
@ -54,7 +54,7 @@ fi
|
|||
if [ "$device_type" = "genymotion" ]
|
||||
then
|
||||
# Find Device based on Android version 6.0.0
|
||||
device=$(/Applications/Genymotion\ Shell.app/Contents/MacOS/genyshell -c "devices list" | grep "6.0.0")
|
||||
device=$(/Applications/Genymotion\ Shell.app/Contents/MacOS/genyshell -c "devices list" | grep "6.0.0\|7.0.0")
|
||||
#echo ${device##*| }
|
||||
# Launch device in Genymotion
|
||||
open -a /Applications/Genymotion.app/Contents/MacOS/player.app --args --vm-name "${device##*| }"
|
||||
|
|
|
@ -145,10 +145,11 @@
|
|||
:uppercase? platform/android?}
|
||||
(i18n/label :t/view-all)]]])))
|
||||
|
||||
(defn current-network []
|
||||
[view {:style st/network-label-container}
|
||||
[text {:style st/network-label} (i18n/label :t/current-network)]
|
||||
[text {:style st/network-title} "Ropsten"]])
|
||||
(defview current-network []
|
||||
(letsubs [network [:get-current-account-network]]
|
||||
[view {:style st/network-label-container}
|
||||
[text {:style st/network-label} (i18n/label :t/current-network)]
|
||||
[text {:style st/network-title} (:name network)]]))
|
||||
|
||||
(defn options-btn []
|
||||
[view {:style st/options-button}
|
||||
|
|
|
@ -64,7 +64,8 @@
|
|||
:icons/dropdown-up (slurp-svg "./resources/icons/dropdown_up.svg")
|
||||
:icons/dropdown (slurp-svg "./resources/icons/dropdown.svg")
|
||||
:icons/grab (slurp-svg "./resources/icons/grab.svg")
|
||||
:icons/share (slurp-svg "./resources/icons/share.svg")})
|
||||
:icons/share (slurp-svg "./resources/icons/share.svg")
|
||||
:icons/network (slurp-svg "./resources/icons/network.svg")})
|
||||
|
||||
(defn normalize-property-name [n]
|
||||
(if (= n :icons/options)
|
||||
|
@ -78,25 +79,25 @@
|
|||
([name {:keys [color container-style style accessibility-label]
|
||||
:or {accessibility-label :icon}}]
|
||||
^{:key name}
|
||||
[react/view {:style container-style
|
||||
[react/view {:style container-style
|
||||
:accessibility-label accessibility-label}
|
||||
(if-let [icon-fn (get icons (normalize-property-name name))]
|
||||
(into []
|
||||
(concat
|
||||
[svg (merge default-viewbox style)]
|
||||
(icon-fn
|
||||
(cond
|
||||
(keyword? color)
|
||||
(case color
|
||||
:dark styles/icon-dark-color
|
||||
:gray styles/icon-gray-color
|
||||
:blue styles/color-light-blue
|
||||
:active styles/color-blue4
|
||||
:white styles/color-white
|
||||
:red styles/icon-red-color
|
||||
styles/icon-dark-color)
|
||||
(string? color)
|
||||
color
|
||||
:else
|
||||
styles/icon-dark-color))))
|
||||
[svg (merge default-viewbox style)]
|
||||
(icon-fn
|
||||
(cond
|
||||
(keyword? color)
|
||||
(case color
|
||||
:dark styles/icon-dark-color
|
||||
:gray styles/icon-gray-color
|
||||
:blue styles/color-light-blue
|
||||
:active styles/color-blue4
|
||||
:white styles/color-white
|
||||
:red styles/icon-red-color
|
||||
styles/icon-dark-color)
|
||||
(string? color)
|
||||
color
|
||||
:else
|
||||
styles/icon-dark-color))))
|
||||
(throw (js/Error. (str "Unknown icon: " name))))]))
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
(ns status-im.constants)
|
||||
(ns status-im.constants
|
||||
(:require [status-im.utils.types :as types]))
|
||||
|
||||
(def ethereum-rpc-url "http://localhost:8545")
|
||||
|
||||
|
@ -26,3 +27,28 @@
|
|||
|
||||
(def console-chat-id "console")
|
||||
(def wallet-chat-id "wallet")
|
||||
|
||||
(def default-network "testnet_rpc")
|
||||
(def default-networks
|
||||
{"mainnet" {:id "mainnet",
|
||||
:name "Mainnet",
|
||||
:config (types/clj->json
|
||||
{:NetworkId 1
|
||||
:DataDir "/ethereum/mainnet"})}
|
||||
"testnet" {:id "testnet",
|
||||
:name "Ropsten",
|
||||
:config (types/clj->json
|
||||
{:NetworkId 3
|
||||
:DataDir "/ethereum/testnet"})}
|
||||
"testnet_rpc" {:id "testnet_rpc",
|
||||
:name "Ropsten with RPC",
|
||||
:config (types/clj->json
|
||||
{:NetworkId 3
|
||||
:DataDir "/ethereum/testnet_rpc"
|
||||
:UpstreamConfig {:Enabled true
|
||||
:URL "https://ropsten.infura.io/z6GCTmjdP3FETEJmMBI4"}})}
|
||||
"rinkeby" {:id "rinkeby",
|
||||
:name "Rinkeby",
|
||||
:config (types/clj->json
|
||||
{:NetworkId 4
|
||||
:DataDir "/ethereum/rinkeby"})}})
|
||||
|
|
|
@ -9,6 +9,3 @@
|
|||
|
||||
(defn save [account update?]
|
||||
(data-store/save account update?))
|
||||
|
||||
(defn save-all [accounts update?]
|
||||
(data-store/save-all accounts update?))
|
|
@ -0,0 +1,22 @@
|
|||
(ns status-im.data-store.networks
|
||||
(:require [status-im.data-store.realm.networks :as data-store]))
|
||||
|
||||
(defn get-all
|
||||
[]
|
||||
(data-store/get-all-as-list))
|
||||
|
||||
(defn save
|
||||
[{:keys [id] :as network}]
|
||||
(data-store/save network (data-store/exists? id)))
|
||||
|
||||
(defn save-all
|
||||
[networks]
|
||||
(mapv save networks))
|
||||
|
||||
(defn save-property
|
||||
[id property-name value]
|
||||
(data-store/save-property id property-name value))
|
||||
|
||||
(defn delete
|
||||
[id]
|
||||
(data-store/delete id))
|
|
@ -1,20 +1,25 @@
|
|||
(ns status-im.data-store.realm.accounts
|
||||
(:require [status-im.data-store.realm.core :as realm]))
|
||||
|
||||
(defn- reformat-networks [account]
|
||||
(update account :networks
|
||||
(fn [networks]
|
||||
(into {}
|
||||
(map (fn [{:keys [id] :as network}]
|
||||
[id network])
|
||||
(vals (js->clj networks :keywordize-keys true)))))))
|
||||
|
||||
(defn get-all []
|
||||
(realm/get-all realm/base-realm :account))
|
||||
|
||||
(defn get-all-as-list []
|
||||
(realm/realm-collection->list (get-all)))
|
||||
(map reformat-networks (realm/realm-collection->list (get-all))))
|
||||
|
||||
(defn get-by-address [address]
|
||||
(realm/get-one-by-field-clj realm/base-realm :account :address address))
|
||||
(reformat-networks
|
||||
(realm/get-one-by-field-clj realm/base-realm :account :address address)))
|
||||
|
||||
(defn save [account update?]
|
||||
(realm/write realm/base-realm
|
||||
#(realm/create realm/base-realm :account account update?)))
|
||||
|
||||
(defn save-all [accounts update?]
|
||||
(realm/write realm/base-realm
|
||||
(fn []
|
||||
(mapv #(realm/create realm/base-realm :account % update?) accounts))))
|
||||
(let [account' (update account :networks (comp vec vals))]
|
||||
#(realm/create realm/base-realm :account account' update?))))
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
(ns status-im.data-store.realm.networks
|
||||
(:require [status-im.data-store.realm.core :as realm])
|
||||
(:refer-clojure :exclude [exists?]))
|
||||
|
||||
(defn get-all
|
||||
[]
|
||||
(-> @realm/account-realm
|
||||
(realm/get-all :network)))
|
||||
|
||||
(defn get-all-as-list
|
||||
[]
|
||||
(realm/realm-collection->list (get-all)))
|
||||
|
||||
(defn save
|
||||
[network update?]
|
||||
(realm/save @realm/account-realm :network network update?))
|
||||
|
||||
(defn save-property
|
||||
[id property-name value]
|
||||
(realm/write @realm/account-realm
|
||||
(fn []
|
||||
(-> @realm/account-realm
|
||||
(realm/get-one-by-field :network :id id)
|
||||
(aset (name property-name) value)))))
|
||||
|
||||
(defn exists?
|
||||
[id]
|
||||
(realm/exists? @realm/account-realm :network {:id id}))
|
||||
|
||||
(defn delete
|
||||
[id]
|
||||
(when-let [network (realm/get-one-by-field @realm/account-realm :network :id id)]
|
||||
(realm/delete @realm/account-realm network)))
|
|
@ -1,7 +1,8 @@
|
|||
(ns status-im.data-store.realm.schemas.base.core
|
||||
(: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.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
|
||||
(def schemas [{:schema v1/schema
|
||||
|
@ -12,4 +13,7 @@
|
|||
:migration v2/migration}
|
||||
{:schema v3/schema
|
||||
:schemaVersion 3
|
||||
:migration v3/migration}])
|
||||
:migration v3/migration}
|
||||
{:schema v4/schema
|
||||
:schemaVersion 4
|
||||
:migration v4/migration}])
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
(defn migration [_old-realm new-realm]
|
||||
(log/debug "migrating account schema v3")
|
||||
;; make sure that console chat has `:unremovable?` set to true
|
||||
(let [accounts (.objects new-realm "account")]
|
||||
(dotimes [i (.-length accounts)]
|
||||
(let [account (aget accounts i)
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
(ns status-im.data-store.realm.schemas.base.v4.account
|
||||
(:require [taoensso.timbre :as log]
|
||||
[status-im.constants :as constants]))
|
||||
|
||||
(def schema {:name :account
|
||||
:primaryKey :address
|
||||
:properties {:address :string
|
||||
:public-key :string
|
||||
:updates-public-key {:type :string
|
||||
:optional true}
|
||||
:updates-private-key {:type :string
|
||||
:optional true}
|
||||
:name {:type :string :optional true}
|
||||
:phone {: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}
|
||||
:last-updated {:type :int :default 0}
|
||||
:signed-up? {:type :bool
|
||||
:default false}
|
||||
:network :string
|
||||
:networks {:type :list
|
||||
:objectType :network}}})
|
||||
|
||||
(defn migration [_old-realm new-realm]
|
||||
(log/debug "migrating account schema v4")
|
||||
(let [accounts (.objects new-realm "account")]
|
||||
(dotimes [i (.-length accounts)]
|
||||
(let [account (aget accounts i)]
|
||||
(aset account "network" constants/default-network)))))
|
|
@ -0,0 +1,16 @@
|
|||
(ns status-im.data-store.realm.schemas.base.v4.core
|
||||
(:require [status-im.data-store.realm.schemas.base.v4.network :as network]
|
||||
[status-im.data-store.realm.schemas.base.v4.account :as account]
|
||||
[status-im.data-store.realm.schemas.base.v1.kv-store :as kv-store]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(def schema [network/schema
|
||||
account/schema
|
||||
kv-store/schema])
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating v4 base database: " old-realm new-realm)
|
||||
(network/migration old-realm new-realm)
|
||||
(account/migration old-realm new-realm))
|
||||
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
(ns status-im.data-store.realm.schemas.base.v4.network
|
||||
(:require [taoensso.timbre :as log]))
|
||||
|
||||
(def schema {:name :network
|
||||
:primaryKey :id
|
||||
:properties {:id :string
|
||||
:name {:type :string
|
||||
:optional true}
|
||||
:config {:type :string
|
||||
:optional true}
|
||||
:rpc-url {:type :string
|
||||
:optional true}}})
|
||||
|
||||
(defn migration [old-realm new-realm]
|
||||
(log/debug "migrating network schema v4"))
|
|
@ -28,8 +28,12 @@
|
|||
(module-interface/-move-to-internal-storage rns-module callback))
|
||||
|
||||
|
||||
(defn start-node [callback]
|
||||
(module-interface/-start-node rns-module callback))
|
||||
(defn start-node [config]
|
||||
(module-interface/-start-node rns-module config))
|
||||
|
||||
|
||||
(defn stop-node []
|
||||
(module-interface/-stop-node rns-module))
|
||||
|
||||
|
||||
(defn stop-rpc-server []
|
||||
|
|
|
@ -72,9 +72,14 @@
|
|||
(when status
|
||||
(call-module #(.moveToInternalStorage status on-result))))
|
||||
|
||||
(defn start-node [on-result]
|
||||
|
||||
(defn stop-node []
|
||||
(when status
|
||||
(call-module #(.startNode status on-result))))
|
||||
(call-module #(.stopNode status))))
|
||||
|
||||
(defn start-node [config]
|
||||
(when status
|
||||
(call-module #(.startNode status config))))
|
||||
|
||||
(defn stop-rpc-server []
|
||||
(when status
|
||||
|
@ -190,8 +195,10 @@
|
|||
;; status-go calls
|
||||
(-init-jail [this]
|
||||
(init-jail))
|
||||
(-start-node [this callback]
|
||||
(start-node callback))
|
||||
(-start-node [this config]
|
||||
(start-node config))
|
||||
(-stop-node [this]
|
||||
(stop-node))
|
||||
(-stop-rpc-server [this]
|
||||
(stop-rpc-server))
|
||||
(-start-rpc-server [this]
|
||||
|
|
|
@ -12,9 +12,10 @@
|
|||
module/IReactNativeStatus
|
||||
;; status-go calls
|
||||
(-init-jail [this])
|
||||
(-start-node [this callback]
|
||||
(-start-node [this config]
|
||||
(re-frame/dispatch [:signal-event "{\"type\":\"node.started\",\"event\":{}}"])
|
||||
(re-frame/dispatch [:signal-event "{\"type\":\"node.ready\",\"event\":{}}"]))
|
||||
(-stop-node [this])
|
||||
(-stop-rpc-server [this])
|
||||
(-start-rpc-server [this])
|
||||
(-restart-rpc [this])
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
(defprotocol IReactNativeStatus
|
||||
(-init-jail [this])
|
||||
(-move-to-internal-storage [this callback])
|
||||
(-start-node [this callback])
|
||||
(-start-node [this config])
|
||||
(-stop-node [this])
|
||||
(-stop-rpc-server [this])
|
||||
(-start-rpc-server [this])
|
||||
(-restart-rpc [this])
|
||||
|
|
|
@ -373,4 +373,24 @@
|
|||
:transactions-filter-title "Filter History"
|
||||
:transactions-filter-tokens "Tokens"
|
||||
:transactions-filter-type "Type"
|
||||
:transactions-filter-select-all "Select all"})
|
||||
:transactions-filter-select-all "Select all"
|
||||
|
||||
;network settings
|
||||
:new-network "New network"
|
||||
:add-network "Add network"
|
||||
:add-new-network "Add new network"
|
||||
:existing-networks "Existing networks"
|
||||
:add-json-file "Add a JSON file"
|
||||
:paste-json-as-text "Paste JSON as text"
|
||||
:paste-json "Paste JSON"
|
||||
:specify-rpc-url "Specify a RPC URL"
|
||||
:edit-rpc-url "Edit a RPC URL"
|
||||
:edit-network-config "Edit network config"
|
||||
:connected "Connected"
|
||||
:process-json "Process JSON"
|
||||
:error-processing-json "Error processing JSON"
|
||||
:rpc-url "RPC URL"
|
||||
:remove-network "Remove network"
|
||||
:network-settings "Network settings"
|
||||
:edit-network-warning "Be careful, editing the network data may disable this network for you"
|
||||
:connecting-requires-login "Connecting to another network requires login"})
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
(ns status-im.ui.screens.accounts.db
|
||||
(:require-macros [status-im.utils.db :refer [allowed-keys]])
|
||||
(:require [cljs.spec.alpha :as spec]
|
||||
status-im.utils.db))
|
||||
status-im.utils.db
|
||||
status-im.ui.screens.network-settings.db))
|
||||
|
||||
(spec/def :account/address :global/address)
|
||||
(spec/def :account/name :global/not-empty-string)
|
||||
|
@ -16,6 +17,7 @@
|
|||
(spec/def :account/debug? (spec/nilable boolean?))
|
||||
(spec/def :account/status (spec/nilable string?))
|
||||
(spec/def :account/network (spec/nilable string?))
|
||||
(spec/def :account/networks (spec/nilable :networks/networks))
|
||||
(spec/def :account/phone (spec/nilable string?))
|
||||
(spec/def :account/signing-phrase :global/not-empty-string)
|
||||
|
||||
|
@ -25,7 +27,7 @@
|
|||
:opt-un [:account/debug? :account/status :account/last-updated
|
||||
:account/updates-private-key :account/updates-public-key
|
||||
:account/email :account/signed-up? :account/network
|
||||
:account/phone]))
|
||||
:account/phone :account/networks]))
|
||||
|
||||
(spec/def :accounts/accounts (spec/nilable (spec/map-of :account/address :accounts/account)))
|
||||
|
||||
|
|
|
@ -96,11 +96,16 @@
|
|||
|
||||
(register-handler-fx
|
||||
:add-account
|
||||
(fn [{{:keys [network] :as db} :db} [_ {:keys [address] :as account} password]]
|
||||
(let [account' (assoc account :network network)]
|
||||
{:db (assoc-in db [:accounts/accounts address] account')
|
||||
::save-account account'
|
||||
:dispatch-later [{:ms 400 :dispatch [:login-account address password true]}]})))
|
||||
(fn [{{:keys [network]
|
||||
:networks/keys [networks]
|
||||
:as db} :db} [_ {:keys [address] :as account} password]]
|
||||
(let [account' (assoc account :network network
|
||||
:networks networks)]
|
||||
(merge
|
||||
{:db (assoc-in db [:accounts/accounts address] account')
|
||||
::save-account account'}
|
||||
(when password
|
||||
{:dispatch-later [{:ms 400 :dispatch [:login-account address password true]}]})))))
|
||||
|
||||
(register-handler-fx
|
||||
:create-account
|
||||
|
@ -123,8 +128,21 @@
|
|||
(let [accounts (->> all-accounts
|
||||
(map (fn [{:keys [address] :as account}]
|
||||
[address account]))
|
||||
(into {}))]
|
||||
{:db (assoc db :accounts/accounts accounts)})))
|
||||
(into {}))
|
||||
;;workaround for realm bug, migrating account v4
|
||||
events (mapv #(when (empty? (:networks %)) [:account-update-networks (:address %)]) (vals accounts))]
|
||||
(merge
|
||||
{:db (assoc db :accounts/accounts accounts)}
|
||||
(when-not (empty? events)
|
||||
{:dispatch-n events})))))
|
||||
|
||||
(register-handler-fx
|
||||
:account-update-networks
|
||||
(fn [{{:accounts/keys [accounts] :networks/keys [networks] :as db} :db} [_ id]]
|
||||
(let [current-account (get accounts id)
|
||||
new-account (assoc current-account :networks networks)]
|
||||
{:db (assoc-in db [:accounts/accounts id] new-account)
|
||||
::save-account new-account})))
|
||||
|
||||
(register-handler-fx
|
||||
:check-status-change
|
||||
|
@ -142,11 +160,9 @@
|
|||
|
||||
(register-handler-fx
|
||||
:account-update
|
||||
(fn [{{:keys [network]
|
||||
:accounts/keys [accounts current-account-id] :as db} :db} [_ new-account-fields]]
|
||||
(let [current-account (get accounts current-account-id)
|
||||
new-account-fields' (assoc new-account-fields :network (or (:network current-account) network))
|
||||
new-account (update-account current-account new-account-fields')]
|
||||
(fn [{{:accounts/keys [accounts current-account-id] :as db} :db} [_ new-account-fields]]
|
||||
(let [current-account (get accounts current-account-id)
|
||||
new-account (update-account current-account new-account-fields)]
|
||||
{:db (assoc-in db [:accounts/accounts current-account-id] new-account)
|
||||
::save-account new-account
|
||||
::broadcast-account-update (merge
|
||||
|
@ -161,8 +177,8 @@
|
|||
(let [{:accounts/keys [accounts current-account-id]} db
|
||||
{:keys [public private]} keypair
|
||||
current-account (get accounts current-account-id)
|
||||
new-account (update-account current-account {:updates-public-key public
|
||||
:updates-private-key private})]
|
||||
new-account (update-account current-account {:updates-public-key public
|
||||
:updates-private-key private})]
|
||||
{:db (assoc-in db [:accounts/accounts current-account-id] new-account)
|
||||
::save-account new-account
|
||||
::send-keys-update (merge
|
||||
|
@ -174,7 +190,7 @@
|
|||
:send-account-update-if-needed
|
||||
(fn [{{:accounts/keys [accounts current-account-id]} :db} _]
|
||||
(let [{:keys [last-updated]} (get accounts current-account-id)
|
||||
now (time/now-ms)
|
||||
now (time/now-ms)
|
||||
needs-update? (> (- now last-updated) time/week)]
|
||||
(log/info "Need to send account-update: " needs-update?)
|
||||
(when needs-update?
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
|
||||
;;;; FX
|
||||
|
||||
(reg-fx ::stop-node (fn [] (status/stop-node)))
|
||||
|
||||
|
||||
(reg-fx
|
||||
::login
|
||||
(fn [[address password]]
|
||||
|
@ -40,27 +43,73 @@
|
|||
:name name)
|
||||
:dispatch [:navigate-to :login]}))
|
||||
|
||||
(defn wrap-with-login-account-fx [db address password]
|
||||
{:db db
|
||||
::login [address password]})
|
||||
|
||||
(register-handler-fx
|
||||
::login-account
|
||||
(fn [{db :db} [_ address password]]
|
||||
(wrap-with-login-account-fx
|
||||
(assoc db :node/after-start nil)
|
||||
address password)))
|
||||
|
||||
(defn get-network-by-address [db address]
|
||||
(let [accounts (get db :accounts/accounts)
|
||||
{:keys [network networks]} (get accounts address)
|
||||
config (get-in networks [network :config])]
|
||||
{:network network
|
||||
:config config}))
|
||||
|
||||
(defn wrap-with-initialize-geth-fx [db address password]
|
||||
(let [{:keys [network config]} (get-network-by-address db address)]
|
||||
{:initialize-geth-fx config
|
||||
:db (assoc db :network network
|
||||
:node/after-start [::login-account address password])}))
|
||||
|
||||
(register-handler-fx
|
||||
::start-node
|
||||
(fn [{db :db} [_ address password]]
|
||||
(wrap-with-initialize-geth-fx
|
||||
(assoc db :node/after-stop nil)
|
||||
address password)))
|
||||
|
||||
(defn wrap-with-stop-node-fx [db address password]
|
||||
{:db (assoc db :node/after-stop [::start-node address password])
|
||||
::stop-node nil})
|
||||
|
||||
(register-handler-fx
|
||||
:login-account
|
||||
(fn [{db :db} [_ address password account-creation?]]
|
||||
{:db (-> db
|
||||
(assoc :accounts/account-creation? account-creation?)
|
||||
(assoc-in [:accounts/login :processing] true))
|
||||
::login [address password]}))
|
||||
(fn [{{:keys [network status-node-started?] :as db} :db}
|
||||
[_ address password account-creation?]]
|
||||
(let [{account-network :network} (get-network-by-address db address)
|
||||
db' (-> db
|
||||
(dissoc :db)
|
||||
(assoc :accounts/account-creation? account-creation?)
|
||||
(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
|
||||
:login-handler
|
||||
(fn [{db :db} [_ result address]]
|
||||
(let [data (json->clj result)
|
||||
error (:error data)
|
||||
(let [data (json->clj result)
|
||||
error (:error data)
|
||||
success (zero? (count error))
|
||||
db' (assoc-in db [:accounts/login :processing] false)]
|
||||
(log/debug "Logged in account: ")
|
||||
db' (assoc-in db [:accounts/login :processing] false)]
|
||||
(log/debug "Logged in account: " result)
|
||||
(merge
|
||||
{:db (if success db' (assoc-in db' [:accounts/login :error] error))}
|
||||
(when success
|
||||
(let [is-login-screen? (= (:view-id db) :login)
|
||||
new-account? (not is-login-screen?)]
|
||||
new-account? (not is-login-screen?)]
|
||||
(log/debug "Logged in: " (:view-id db) is-login-screen? new-account?)
|
||||
{::clear-web-data nil
|
||||
::change-account [address new-account?]}))))))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
(ns status-im.ui.screens.db
|
||||
(:require-macros [status-im.utils.db :refer [allowed-keys]])
|
||||
(:require [status-im.constants :refer [console-chat-id]]
|
||||
(:require [status-im.constants :as constants]
|
||||
[status-im.utils.platform :as platform]
|
||||
[cljs.spec.alpha :as spec]
|
||||
status-im.ui.screens.accounts.db
|
||||
|
@ -11,7 +11,8 @@
|
|||
status-im.chat.new-public-chat.db
|
||||
status-im.ui.screens.profile.db
|
||||
status-im.transactions.specs
|
||||
status-im.ui.screens.discover.db))
|
||||
status-im.ui.screens.discover.db
|
||||
status-im.ui.screens.network-settings.db))
|
||||
|
||||
;; initial state of app-db
|
||||
(def app-db {:current-public-key ""
|
||||
|
@ -24,7 +25,7 @@
|
|||
:group/contact-groups {}
|
||||
:group/selected-contacts #{}
|
||||
:chats {}
|
||||
:current-chat-id console-chat-id
|
||||
:current-chat-id constants/console-chat-id
|
||||
:loading-allowed true
|
||||
:selected-participants #{}
|
||||
:discoveries {}
|
||||
|
@ -34,7 +35,8 @@
|
|||
:wallet {}
|
||||
:prices {}
|
||||
:notifications {}
|
||||
:network "testnet"})
|
||||
:network constants/default-network
|
||||
:networks/networks constants/default-networks})
|
||||
|
||||
;;;;GLOBAL
|
||||
|
||||
|
@ -79,6 +81,11 @@
|
|||
|
||||
(spec/def ::network (spec/nilable string?))
|
||||
|
||||
;;;;NODE
|
||||
|
||||
(spec/def :node/after-start (spec/nilable vector?))
|
||||
(spec/def :node/after-stop (spec/nilable vector?))
|
||||
|
||||
(spec/def ::db (allowed-keys
|
||||
:opt
|
||||
[:contacts/contacts
|
||||
|
@ -104,7 +111,11 @@
|
|||
:my-profile/drawer
|
||||
:my-profile/profile
|
||||
:my-profile/default-name
|
||||
:wallet/request-transaction]
|
||||
:wallet/request-transaction
|
||||
:networks/selected-network
|
||||
:networks/networks
|
||||
:node/after-start
|
||||
:node/after-stop]
|
||||
:opt-un
|
||||
[::current-public-key
|
||||
::modal
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
status-im.ui.screens.group.chat-settings.events
|
||||
status-im.ui.screens.group.events
|
||||
status-im.ui.screens.navigation
|
||||
status-im.ui.screens.network-settings.events
|
||||
status-im.ui.screens.profile.events
|
||||
status-im.ui.screens.qr-scanner.events
|
||||
status-im.ui.screens.wallet.events
|
||||
|
@ -47,33 +48,29 @@
|
|||
::initialize-crypt-fx
|
||||
(fn []
|
||||
(crypt/gen-random-bytes
|
||||
1024
|
||||
(fn [{:keys [error buffer]}]
|
||||
(if error
|
||||
(log/error "Failed to generate random bytes to initialize sjcl crypto")
|
||||
(->> (.toString buffer "hex")
|
||||
(.toBits (.. dependencies/eccjs -sjcl -codec -hex))
|
||||
(.addEntropy (.. dependencies/eccjs -sjcl -random))))))))
|
||||
1024
|
||||
(fn [{:keys [error buffer]}]
|
||||
(if error
|
||||
(log/error "Failed to generate random bytes to initialize sjcl crypto")
|
||||
(->> (.toString buffer "hex")
|
||||
(.toBits (.. dependencies/eccjs -sjcl -codec -hex))
|
||||
(.addEntropy (.. dependencies/eccjs -sjcl -random))))))))
|
||||
|
||||
(defn node-started [result]
|
||||
(log/debug "Started Node"))
|
||||
|
||||
(defn move-to-internal-storage []
|
||||
(defn move-to-internal-storage [config]
|
||||
(status/move-to-internal-storage
|
||||
(fn []
|
||||
(status/start-node node-started))))
|
||||
#(status/start-node config)))
|
||||
|
||||
(reg-fx
|
||||
::initialize-geth-fx
|
||||
(fn []
|
||||
:initialize-geth-fx
|
||||
(fn [config]
|
||||
(status/should-move-to-internal-storage?
|
||||
(fn [should-move?]
|
||||
(if should-move?
|
||||
(dispatch [:request-permissions
|
||||
[:read-external-storage]
|
||||
#(move-to-internal-storage)
|
||||
#(dispatch [:move-to-internal-failure-message])])
|
||||
(status/start-node node-started))))))
|
||||
(fn [should-move?]
|
||||
(if should-move?
|
||||
(dispatch [:request-permissions
|
||||
[:read-external-storage]
|
||||
#(move-to-internal-storage config)
|
||||
#(dispatch [:move-to-internal-failure-message])])
|
||||
(status/start-node config))))))
|
||||
|
||||
(reg-fx
|
||||
::status-module-initialized-fx
|
||||
|
@ -100,8 +97,8 @@
|
|||
(fn []
|
||||
(when config/testfairy-enabled?
|
||||
(utils/show-popup
|
||||
(i18n/label :testfairy-title)
|
||||
(i18n/label :testfairy-message)))))
|
||||
(i18n/label :testfairy-title)
|
||||
(i18n/label :testfairy-message)))))
|
||||
|
||||
(reg-fx
|
||||
::get-fcm-token-fx
|
||||
|
@ -133,16 +130,18 @@
|
|||
|
||||
(register-handler-fx
|
||||
:initialize-db
|
||||
(fn [{{:keys [status-module-initialized? status-node-started?
|
||||
network-status network _]} :db} _]
|
||||
{::init-store nil
|
||||
:db (assoc app-db
|
||||
:accounts/current-account-id nil
|
||||
:contacts/contacts {}
|
||||
:network-status network-status
|
||||
:status-module-initialized? (or platform/ios? js/goog.DEBUG status-module-initialized?)
|
||||
:status-node-started? status-node-started?
|
||||
:network (or network "testnet"))}))
|
||||
(fn [{{:keys [status-module-initialized? status-node-started?
|
||||
network-status network _]
|
||||
:networks/keys [networks]} :db} _]
|
||||
(let [network' (or network (get app-db :network))]
|
||||
{::init-store nil
|
||||
:db (assoc app-db
|
||||
:accounts/current-account-id nil
|
||||
:contacts/contacts {}
|
||||
:network-status network-status
|
||||
:status-module-initialized? (or platform/ios? js/goog.DEBUG status-module-initialized?)
|
||||
:status-node-started? status-node-started?
|
||||
:network network')})))
|
||||
|
||||
(register-handler-db
|
||||
:initialize-account-db
|
||||
|
@ -181,14 +180,14 @@
|
|||
:chat
|
||||
:accounts)]
|
||||
(merge
|
||||
{:db (assoc db :view-id view
|
||||
:navigation-stack (list view))}
|
||||
(when (or (empty? accounts) open-console?)
|
||||
{:dispatch-n (concat
|
||||
[[:init-console-chat]
|
||||
[:load-commands!]]
|
||||
(when open-console?
|
||||
[[:navigate-to :chat console-chat-id]]))})))))
|
||||
{:db (assoc db :view-id view
|
||||
:navigation-stack (list view))}
|
||||
(when (or (empty? accounts) open-console?)
|
||||
{:dispatch-n (concat
|
||||
[[:init-console-chat]
|
||||
[:load-commands!]]
|
||||
(when open-console?
|
||||
[[:navigate-to :chat console-chat-id]]))})))))
|
||||
|
||||
(register-handler-fx
|
||||
:initialize-crypt
|
||||
|
@ -197,8 +196,14 @@
|
|||
|
||||
(register-handler-fx
|
||||
:initialize-geth
|
||||
(fn [_ _]
|
||||
{::initialize-geth-fx nil}))
|
||||
(fn [{db :db} _]
|
||||
(let [{:accounts/keys [current-account-id accounts]} db
|
||||
default-networks (:networks/networks db)
|
||||
default-network (:network db)
|
||||
{:keys [network networks]} (get accounts current-account-id)
|
||||
network-config (or (get-in networks [network :config])
|
||||
(get-in default-networks [default-network :config]))]
|
||||
{:initialize-geth-fx network-config})))
|
||||
|
||||
(register-handler-fx
|
||||
:webview-geo-permissions-granted
|
||||
|
@ -235,6 +240,7 @@
|
|||
"transaction.queued" (dispatch [:transaction-queued event])
|
||||
"transaction.failed" (dispatch [:transaction-failed event])
|
||||
"node.started" (dispatch [:status-node-started])
|
||||
"node.stopped" (dispatch [:status-node-stopped])
|
||||
"module.initialized" (dispatch [:status-module-initialized])
|
||||
"request_geo_permissions" (dispatch [:request-permissions [:geolocation]
|
||||
#(dispatch [:webview-geo-permissions-granted])])
|
||||
|
@ -244,13 +250,19 @@
|
|||
(register-handler-fx
|
||||
:status-module-initialized
|
||||
(fn [{:keys [db]} _]
|
||||
{:db (assoc db :status-module-initialized? true)
|
||||
{:db (assoc db :status-module-initialized? true)
|
||||
::status-module-initialized-fx nil}))
|
||||
|
||||
(register-handler-db
|
||||
(register-handler-fx
|
||||
:status-node-started
|
||||
(fn [db]
|
||||
(assoc db :status-node-started? true)))
|
||||
(fn [{{:node/keys [after-start] :as db} :db}]
|
||||
(merge {:db (assoc db :status-node-started? true)}
|
||||
(when after-start {:dispatch-n [after-start]}))))
|
||||
|
||||
(register-handler-fx
|
||||
:status-node-stopped
|
||||
(fn [{{:node/keys [after-stop]} :db}]
|
||||
(when after-stop {:dispatch-n [after-stop]})))
|
||||
|
||||
(register-handler-fx
|
||||
:app-state-change
|
||||
|
@ -272,19 +284,19 @@
|
|||
(fn []
|
||||
(let [watch-id (atom nil)]
|
||||
(.getCurrentPosition
|
||||
navigator.geolocation
|
||||
#(dispatch [:update-geolocation (js->clj % :keywordize-keys true)])
|
||||
#(dispatch [:update-geolocation (js->clj % :keywordize-keys true)])
|
||||
(clj->js {:enableHighAccuracy true :timeout 20000 :maximumAge 1000}))
|
||||
navigator.geolocation
|
||||
#(dispatch [:update-geolocation (js->clj % :keywordize-keys true)])
|
||||
#(dispatch [:update-geolocation (js->clj % :keywordize-keys true)])
|
||||
(clj->js {:enableHighAccuracy true :timeout 20000 :maximumAge 1000}))
|
||||
(when platform/android?
|
||||
(reset! watch-id
|
||||
(.watchPosition
|
||||
navigator.geolocation
|
||||
#(do
|
||||
(.clearWatch
|
||||
navigator.geolocation
|
||||
@watch-id)
|
||||
(dispatch [:update-geolocation (js->clj % :keywordize-keys true)])))))))]}))
|
||||
navigator.geolocation
|
||||
#(do
|
||||
(.clearWatch
|
||||
navigator.geolocation
|
||||
@watch-id)
|
||||
(dispatch [:update-geolocation (js->clj % :keywordize-keys true)])))))))]}))
|
||||
|
||||
(register-handler-db
|
||||
:update-geolocation
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
(ns status-im.ui.screens.network-settings.add-rpc.views
|
||||
(:require
|
||||
[re-frame.core :refer [dispatch]]
|
||||
[status-im.components.status-bar :as status-bar]
|
||||
[status-im.components.toolbar-new.view :as toolbar-new]
|
||||
[status-im.components.text-input-with-label.view :refer [text-input-with-label]]
|
||||
[status-im.ui.screens.network-settings.views :as network-settings]
|
||||
[status-im.components.react :as react]
|
||||
[status-im.components.sticky-button :as sticky-button]
|
||||
[status-im.i18n :as i18n]
|
||||
[clojure.string :as str]))
|
||||
|
||||
(defn add-rpc-url []
|
||||
(let [rpc-url "text"]
|
||||
[react/view {:flex 1}
|
||||
[status-bar/status-bar]
|
||||
[toolbar-new/toolbar {:title (i18n/label :t/add-network)}]
|
||||
[network-settings/network-badge]
|
||||
[react/view {:margin-top 8}
|
||||
[text-input-with-label {:label (i18n/label :t/rpc-url)}]]
|
||||
[react/view {:flex 1}]
|
||||
(when (not (str/blank? rpc-url))
|
||||
[sticky-button/sticky-button (i18n/label :t/add-network) #()])]))
|
|
@ -0,0 +1,14 @@
|
|||
(ns status-im.ui.screens.network-settings.db
|
||||
(:require-macros [status-im.utils.db :refer [allowed-keys]])
|
||||
(:require [cljs.spec.alpha :as spec]))
|
||||
|
||||
(spec/def :networks/id string?)
|
||||
(spec/def :networks/name string?)
|
||||
(spec/def :networks/config string?)
|
||||
|
||||
(spec/def :networks/network
|
||||
(spec/keys :req-un [:networks/id :networks/name :networks/config]))
|
||||
|
||||
(spec/def :networks/selected-network :networks/network)
|
||||
|
||||
(spec/def :networks/networks (spec/nilable (spec/map-of :networks/id :networks/network)))
|
|
@ -0,0 +1,33 @@
|
|||
(ns status-im.ui.screens.network-settings.events
|
||||
(:require [re-frame.core :refer [dispatch dispatch-sync after] :as re-frame]
|
||||
[status-im.utils.handlers :refer [register-handler] :as handlers]
|
||||
[status-im.data-store.networks :as networks]
|
||||
[status-im.ui.screens.network-settings.navigation]))
|
||||
|
||||
;;;; FX
|
||||
|
||||
(re-frame/reg-fx
|
||||
::save-networks
|
||||
(fn [networks]
|
||||
(networks/save-all networks)))
|
||||
|
||||
;; handlers
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:add-networks
|
||||
(fn [{{:networks/keys [networks] :as db} :db} [_ new-networks]]
|
||||
(let [identities (set (keys networks))
|
||||
new-networks' (->> new-networks
|
||||
(remove #(identities (:id %)))
|
||||
(map #(vector (:id %) %))
|
||||
(into {}))]
|
||||
{:db (-> db
|
||||
(update :networks merge new-networks')
|
||||
(assoc :new-networks (vals new-networks')))
|
||||
:save-networks new-networks'})))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:connect-network
|
||||
(fn [_ [_ network]]
|
||||
{:dispatch-n [[:account-update {:network network}]
|
||||
[:navigate-to-clean :accounts]]}))
|
|
@ -0,0 +1,6 @@
|
|||
(ns status-im.ui.screens.network-settings.navigation
|
||||
(:require [status-im.ui.screens.navigation :as navigation]))
|
||||
|
||||
(defmethod navigation/preload-data! :network-details
|
||||
[db [_ _ network]]
|
||||
(assoc db :networks/selected-network network))
|
|
@ -0,0 +1,54 @@
|
|||
(ns status-im.ui.screens.network-settings.network-details.views
|
||||
(:require-macros [status-im.utils.views :as views])
|
||||
(:require
|
||||
[re-frame.core :as rf]
|
||||
[status-im.components.status-bar :as status-bar]
|
||||
[status-im.components.toolbar-new.view :as new-toolbar]
|
||||
[status-im.components.context-menu :as context-menu]
|
||||
[status-im.ui.screens.network-settings.views :as network-settings]
|
||||
[status-im.components.react :as react]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.screens.network-settings.styles :as st]))
|
||||
|
||||
(def options
|
||||
[{:text (i18n/label :t/add-json-file)
|
||||
:value #(rf/dispatch [:network-add-json-file])}
|
||||
{:text (i18n/label :t/paste-json-as-text)
|
||||
:value #(rf/dispatch [:network-paste-json-as-text])}
|
||||
{:text (i18n/label :t/:edit-rpc-url)
|
||||
:value #(rf/dispatch [:network-edit-rpc-url])}
|
||||
{:text (i18n/label :t/:remove-network)
|
||||
:value #(rf/dispatch [:network-remove])}])
|
||||
|
||||
(views/defview network-details []
|
||||
(views/letsubs [{:keys [id name config]} [:get :networks/selected-network]
|
||||
{:keys [network]} [:get-current-account]]
|
||||
(let [connected? (= id network)]
|
||||
[react/view {:flex 1}
|
||||
[status-bar/status-bar]
|
||||
[new-toolbar/toolbar]
|
||||
(when-not connected?
|
||||
[react/touchable-highlight {:on-press #(rf/dispatch [:connect-network id])}
|
||||
[react/view st/connect-button-container
|
||||
[react/view st/connect-button
|
||||
[react/text {:style st/connect-button-label
|
||||
:uppercase? (get-in platform/platform-specific [:uppercase?])}
|
||||
(i18n/label :t/connect)]]
|
||||
[react/text {:style st/connect-button-description}
|
||||
(i18n/label :t/connecting-requires-login)]]])
|
||||
[react/view st/network-config-container
|
||||
[react/text {:style st/network-config-text}
|
||||
config]]
|
||||
[react/view {:opacity 0.4}
|
||||
[react/view st/edit-button-container
|
||||
[react/view st/edit-button
|
||||
[react/text {:style st/edit-button-label
|
||||
:uppercase? (get-in platform/platform-specific [:uppercase?])}
|
||||
(i18n/label :t/edit-network-config)]]
|
||||
#_[context-menu ; TODO should be implemented later
|
||||
[view st/edit-button
|
||||
[text {:style st/edit-button-label} (i18n/label :t/edit-network-config)]]
|
||||
options]
|
||||
[react/text {:style st/edit-button-description}
|
||||
(i18n/label :t/edit-network-warning)]]]])))
|
|
@ -0,0 +1,31 @@
|
|||
(ns status-im.ui.screens.network-settings.parse-json.views
|
||||
(:require
|
||||
[re-frame.core :refer [dispatch]]
|
||||
[status-im.components.status-bar :refer [status-bar]]
|
||||
[status-im.components.toolbar-new.view :refer [toolbar]]
|
||||
[status-im.ui.screens.network-settings.views :as network-settings]
|
||||
[status-im.components.react :refer [view text text-input]]
|
||||
[status-im.components.sticky-button :as sticky-button]
|
||||
[status-im.ui.screens.network-settings.styles :as st]
|
||||
[status-im.i18n :as i18n]
|
||||
[clojure.string :as str]))
|
||||
|
||||
(defn paste-json-text []
|
||||
(let [network-json "test"
|
||||
error nil]
|
||||
[view {:flex 1}
|
||||
[status-bar]
|
||||
[toolbar {:title (i18n/label :t/add-network)}]
|
||||
[network-settings/network-badge]
|
||||
[view {:margin-top 16
|
||||
:margin-left 16
|
||||
:flex 1}
|
||||
(when error
|
||||
[text {:style {:color :red}}
|
||||
(i18n/label :t/error-processing-json)])
|
||||
[text-input {:style st/paste-json-text-input
|
||||
:flex 1
|
||||
:placeholder (i18n/label :t/paste-json)
|
||||
:multiline true}]]
|
||||
(when (not (str/blank? network-json))
|
||||
[sticky-button/sticky-button (i18n/label :t/process-json) #()])]))
|
|
@ -0,0 +1,144 @@
|
|||
(ns status-im.ui.screens.network-settings.styles
|
||||
(:require-macros [status-im.utils.styles :refer [defstyle defnstyle]])
|
||||
(:require [status-im.components.styles :as common]))
|
||||
|
||||
(def networks-list
|
||||
{:background-color common/color-light-gray})
|
||||
|
||||
(defstyle badge-name-text
|
||||
{:color common/color-black
|
||||
:ios {:font-size 17
|
||||
:letter-spacing -0.2}
|
||||
:android {:font-size 16}})
|
||||
|
||||
(defstyle badge-connected-text
|
||||
{:color common/color-gray4
|
||||
:ios {:margin-top 5
|
||||
:font-size 14
|
||||
:letter-spacing -0.2}
|
||||
:android {:font-size 13}})
|
||||
|
||||
(defstyle paste-json-text-input
|
||||
{:ios {:font-size 17
|
||||
:line-height 24
|
||||
:letter-spacing -0.2}})
|
||||
|
||||
(def connect-button-container
|
||||
{:margin-top 8
|
||||
:align-items :center
|
||||
:margin-bottom 16
|
||||
:margin-horizontal 16})
|
||||
|
||||
(defstyle connect-button
|
||||
{:height 52
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:background-color common/color-light-blue
|
||||
:ios {:width 343
|
||||
:border-radius 8
|
||||
:opacity 0.9}
|
||||
:android {:width 328
|
||||
:border-radius 4}})
|
||||
|
||||
(defstyle connect-button-label
|
||||
{:color common/color-white
|
||||
:ios {:font-size 17
|
||||
:letter-spacing -0.2}
|
||||
:android {:font-size 14}})
|
||||
|
||||
(defstyle connect-button-description
|
||||
{:color common/color-gray4
|
||||
:ios {:margin-top 8
|
||||
:height 20
|
||||
:font-size 14
|
||||
:letter-spacing -0.2}
|
||||
:android {:margin-top 12
|
||||
:font-size 12}})
|
||||
|
||||
(defstyle network-config-container
|
||||
{:height 160
|
||||
:margin-top 8
|
||||
:padding-top 16
|
||||
:padding-left 16
|
||||
:margin-horizontal 16
|
||||
:background-color "#eef2f5"
|
||||
:ios {:border-radius 9
|
||||
:opacity 0.9}
|
||||
:android {:border-radius 4}})
|
||||
|
||||
(defstyle network-config-text
|
||||
{:color common/color-black
|
||||
:ios {:opacity 0.8
|
||||
:font-size 17
|
||||
:line-height 24
|
||||
:letter-spacing -0.2}
|
||||
:android {:opacity 0.4
|
||||
:font-size 16
|
||||
:line-height 24}})
|
||||
|
||||
(def edit-button-container
|
||||
{:margin-top 16
|
||||
:align-items :center
|
||||
:margin-bottom 16
|
||||
:margin-horizontal 16})
|
||||
|
||||
(defstyle edit-button
|
||||
{:height 52
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:background-color common/color-light-blue-transparent
|
||||
:ios {:width 343
|
||||
:border-radius 8}
|
||||
:android {:width 328
|
||||
:border-radius 4}})
|
||||
|
||||
(defstyle edit-button-label
|
||||
{:color common/color-light-blue
|
||||
:ios {:font-size 17
|
||||
:letter-spacing -0.2}
|
||||
:android {:font-size 14}})
|
||||
|
||||
(defstyle edit-button-description
|
||||
{:text-align :center
|
||||
:color common/color-gray4
|
||||
:ios {:margin-top 8
|
||||
:font-size 14
|
||||
:letter-spacing -0.2}
|
||||
:android {:margin-top 12
|
||||
:font-size 12}})
|
||||
|
||||
(defn network-icon [connected? size]
|
||||
{:width size
|
||||
:height size
|
||||
:border-radius (/ size 2)
|
||||
:background-color (if connected? "#729ae6" "#eef2f5")
|
||||
:align-items :center :justify-content :center})
|
||||
|
||||
(def network-badge
|
||||
{:height 88
|
||||
:padding-left 16
|
||||
:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
(defstyle network-item
|
||||
{:flex-direction :row
|
||||
:background-color :white
|
||||
:align-items :center
|
||||
:padding-horizontal 16
|
||||
:ios {:height 64}
|
||||
:android {:height 56}})
|
||||
|
||||
(defstyle network-item-name-text
|
||||
{:color common/color-black
|
||||
:ios {:font-size 17
|
||||
:letter-spacing -0.2
|
||||
:line-height 20}
|
||||
:android {:font-size 16}})
|
||||
|
||||
(defstyle network-item-connected-text
|
||||
{:color common/color-gray4
|
||||
:ios {:font-size 14
|
||||
:margin-top 6
|
||||
:letter-spacing -0.2}
|
||||
:android {:font-size 12
|
||||
:margin-top 2}})
|
|
@ -0,0 +1,9 @@
|
|||
(ns status-im.ui.screens.network-settings.subs
|
||||
(:require [re-frame.core :refer [reg-sub subscribe]]))
|
||||
|
||||
(reg-sub
|
||||
:get-current-account-network
|
||||
:<- [:get-current-account]
|
||||
:<- [:get :networks/networks]
|
||||
(fn [[current-account networks]]
|
||||
(get networks (:network current-account))))
|
|
@ -0,0 +1,80 @@
|
|||
(ns status-im.ui.screens.network-settings.views
|
||||
(:require-macros [status-im.utils.views :as views])
|
||||
(:require
|
||||
[status-im.utils.listview :as lw]
|
||||
[re-frame.core :as rf]
|
||||
[status-im.components.status-bar :as status-bar]
|
||||
[status-im.components.toolbar-new.view :as toolbar-new]
|
||||
[status-im.components.action-button.action-button :as action-button]
|
||||
[status-im.components.action-button.styles :as action-button-styles]
|
||||
[status-im.components.react :as react]
|
||||
[status-im.components.icons.vector-icons :as vi]
|
||||
#_[status-im.components.context-menu :refer [context-menu]]
|
||||
[status-im.components.common.common :as common]
|
||||
[status-im.components.renderers.renderers :as renderers]
|
||||
[status-im.ui.screens.network-settings.styles :as st]
|
||||
[status-im.i18n :as i18n]))
|
||||
|
||||
(defn network-icon [connected? size]
|
||||
[react/view (st/network-icon connected? size)
|
||||
[vi/icon :icons/network {:color (if connected? :white :gray)}]])
|
||||
|
||||
(defn network-badge [& [{:keys [name connected? options]}]]
|
||||
[react/view st/network-badge
|
||||
[network-icon connected? 56]
|
||||
[react/view {:padding-left 16}
|
||||
[react/text {:style st/badge-name-text}
|
||||
(or name (i18n/label :t/new-network))]
|
||||
(when connected?
|
||||
[react/text {:style st/badge-connected-text}
|
||||
(i18n/label :t/connected)])]])
|
||||
|
||||
(defn actions-view []
|
||||
[react/view action-button-styles/actions-list
|
||||
[react/view {:opacity 0.4}
|
||||
[action-button/action-button
|
||||
{:label (i18n/label :t/add-new-network)
|
||||
:icon :icons/add
|
||||
:icon-opts {:color :blue}}]]
|
||||
#_[context-menu ; TODO should be implemented later
|
||||
[action-button-view (i18n/label :t/add-new-network) :add_blue]
|
||||
[{:text (i18n/label :t/add-json-file) :value #(dispatch [:navigate-to :paste-json-text])}
|
||||
{:text (i18n/label :t/paste-json-as-text) :value #(dispatch [:navigate-to :paste-json-text])}
|
||||
{:text (i18n/label :t/specify-rpc-url) :value #(dispatch [:navigate-to :add-rpc-url])}]]])
|
||||
|
||||
(defn render-row [current-network]
|
||||
(fn [{:keys [id name config] :as row} _ _]
|
||||
(let [connected? (= id current-network)]
|
||||
(react/list-item
|
||||
^{:key row}
|
||||
[react/touchable-highlight
|
||||
{:on-press #(rf/dispatch [:navigate-to :network-details row])}
|
||||
[react/view st/network-item
|
||||
[network-icon connected? 40]
|
||||
[react/view {:padding-horizontal 16}
|
||||
[react/text {:style st/network-item-name-text}
|
||||
name]
|
||||
(when connected?
|
||||
[react/text {:style st/network-item-connected-text}
|
||||
(i18n/label :t/connected)])]]]))))
|
||||
|
||||
(views/defview network-settings []
|
||||
(views/letsubs [{:keys [network networks]} [:get-current-account]]
|
||||
[react/view {:flex 1}
|
||||
[status-bar/status-bar]
|
||||
[toolbar-new/toolbar {:title (i18n/label :t/network-settings)}]
|
||||
[react/view {:flex 1}
|
||||
[react/list-view {:dataSource (lw/to-datasource (vals networks))
|
||||
:renderRow (render-row network)
|
||||
:renderHeader #(react/list-item
|
||||
[react/view
|
||||
[actions-view]
|
||||
[common/bottom-shadow]
|
||||
[common/form-title (i18n/label :t/existing-networks)
|
||||
{:count-value (count networks)}]
|
||||
[common/list-header]])
|
||||
:renderFooter #(react/list-item [react/view
|
||||
[common/list-footer]
|
||||
[common/bottom-shadow]])
|
||||
:renderSeparator renderers/list-separator-renderer
|
||||
:style st/networks-list}]]]))
|
|
@ -62,7 +62,7 @@
|
|||
{:optionsContainer {:margin-top 78}})
|
||||
|
||||
(def edit-profile-name-container
|
||||
{:flex 1
|
||||
{:flex 1
|
||||
:padding-top 30})
|
||||
|
||||
(def edit-profile-icon-container
|
||||
|
@ -128,7 +128,19 @@
|
|||
{:color color-gray4}))
|
||||
|
||||
(def info-item-separator
|
||||
{:margin-left 16})
|
||||
{:margin-left 16})
|
||||
|
||||
(defstyle network-settings
|
||||
{:padding-horizontal 16
|
||||
:flex-direction :row
|
||||
:align-items :center
|
||||
:background-color color-white
|
||||
:android {:height 72}
|
||||
:ios {:height 64}})
|
||||
|
||||
(def network-settings-text
|
||||
(merge {:flex 1}
|
||||
profile-setting-text))
|
||||
|
||||
(def edit-line-color
|
||||
(if platform/ios?
|
||||
|
@ -154,7 +166,7 @@
|
|||
:padding-bottom 0}})
|
||||
|
||||
(defstyle profile-status-input
|
||||
{:line-height 24;;TODO doesnt' work for multiline because a bug in the RN
|
||||
{:line-height 24 ;;TODO doesnt' work for multiline because a bug in the RN
|
||||
:color text1-color
|
||||
:padding-left 0
|
||||
:ios {:font-size 17
|
||||
|
@ -162,18 +174,18 @@
|
|||
:padding-top 0
|
||||
:height 74
|
||||
:letter-spacing -0.2}
|
||||
:android {:font-size 16
|
||||
:padding-top 5
|
||||
:height 74
|
||||
:android {:font-size 16
|
||||
:padding-top 5
|
||||
:height 74
|
||||
:text-align-vertical :top
|
||||
:padding-bottom 0}})
|
||||
:padding-bottom 0}})
|
||||
|
||||
(defstyle profile-status-text
|
||||
{:color text1-color
|
||||
:line-height 24
|
||||
:ios {:font-size 17
|
||||
:letter-spacing -0.2}
|
||||
:android {:font-size 16}})
|
||||
{:color text1-color
|
||||
:line-height 24
|
||||
:ios {:font-size 17
|
||||
:letter-spacing -0.2}
|
||||
:android {:font-size 16}})
|
||||
|
||||
(defstyle edit-profile-status
|
||||
{:background-color color-light-gray
|
||||
|
|
|
@ -20,12 +20,13 @@
|
|||
[status-im.i18n :refer [label]]
|
||||
[status-im.ui.screens.profile.styles :as styles]
|
||||
[status-im.utils.datetime :as time]
|
||||
[status-im.utils.utils :refer [hash-tag?]])
|
||||
(:require-macros [status-im.utils.views :refer [defview]]))
|
||||
[status-im.utils.utils :refer [hash-tag?]]
|
||||
[status-im.utils.config :as config])
|
||||
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
|
||||
|
||||
(defn my-profile-toolbar []
|
||||
[toolbar/toolbar {:actions [(actions/opts [{:value #(dispatch [:my-profile/edit-profile])
|
||||
:text (label :t/edit)}])]}])
|
||||
:text (label :t/edit)}])]}])
|
||||
|
||||
(defn profile-toolbar [contact]
|
||||
[toolbar/toolbar
|
||||
|
@ -47,7 +48,7 @@
|
|||
[my-profile-icon {:account contact
|
||||
:edit? false}]
|
||||
[react/view styles/profile-badge-name-container
|
||||
[react/text {:style styles/profile-name-text
|
||||
[react/text {:style styles/profile-name-text
|
||||
:number-of-lines 1}
|
||||
name]
|
||||
(when-not (nil? last-online)
|
||||
|
@ -82,9 +83,9 @@
|
|||
[react/text {:style styles/profile-setting-title}
|
||||
label]
|
||||
[react/view styles/profile-setting-spacing]
|
||||
[react/text {:style (if empty-value?
|
||||
styles/profile-setting-text-empty
|
||||
styles/profile-setting-text)
|
||||
[react/text {:style (if empty-value?
|
||||
styles/profile-setting-text-empty
|
||||
styles/profile-setting-text)
|
||||
:number-of-lines 1
|
||||
:ellipsizeMode text-mode
|
||||
:accessibility-label accessibility-label}
|
||||
|
@ -103,7 +104,7 @@
|
|||
(defn profile-options [contact k text]
|
||||
(into []
|
||||
(concat [{:value (show-qr contact k)
|
||||
:text (label :t/show-qr)}]
|
||||
:text (label :t/show-qr)}]
|
||||
(when text
|
||||
(share-options text)))))
|
||||
|
||||
|
@ -128,7 +129,7 @@
|
|||
|
||||
(defn tag-view [tag]
|
||||
[react/text {:style {:color color-blue}
|
||||
:font :medium}
|
||||
:font :medium}
|
||||
(str tag " ")])
|
||||
|
||||
(defn colorize-status-hashtags [status]
|
||||
|
@ -150,6 +151,14 @@
|
|||
:empty-value? phone-empty?
|
||||
:accessibility-label :profile-phone-number}]))
|
||||
|
||||
(defn network-settings []
|
||||
[react/touchable-highlight
|
||||
{:on-press #(dispatch [:navigate-to :network-settings])}
|
||||
[react/view styles/network-settings
|
||||
[react/text {:style styles/network-settings-text}
|
||||
(label :t/network-settings)]
|
||||
[vi/icon :icons/forward {:color :gray}]]])
|
||||
|
||||
(defn profile-info [{:keys [whisper-identity status phone] :as contact}]
|
||||
[react/view
|
||||
[profile-info-address-item contact]
|
||||
|
@ -167,7 +176,10 @@
|
|||
[profile-info-phone-item
|
||||
phone
|
||||
[{:value #(dispatch [:my-profile/change-phone-number])
|
||||
:text (label :t/edit)}]]])
|
||||
:text (label :t/edit)}]]
|
||||
[info-item-separator]
|
||||
(when config/network-switching-enabled?
|
||||
[network-settings])])
|
||||
|
||||
(defn profile-status [status & [edit?]]
|
||||
[react/view styles/profile-status-container
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
status-im.ui.screens.profile.subs
|
||||
status-im.ui.screens.wallet.subs
|
||||
status-im.ui.screens.wallet.transactions.subs
|
||||
status-im.ui.screens.network-settings.subs
|
||||
status-im.transactions.subs
|
||||
status-im.bots.subs))
|
||||
|
||||
|
|
|
@ -46,7 +46,11 @@
|
|||
[status-im.ui.screens.wallet.request.views :refer [request-transaction]]
|
||||
[status-im.ui.screens.wallet.wallet-list.views :refer [wallet-list-screen]]
|
||||
[status-im.ui.screens.wallet.transactions.views :as wallet-transactions]
|
||||
[status-im.components.status-bar :as status-bar]))
|
||||
[status-im.components.status-bar :as status-bar]
|
||||
[status-im.ui.screens.network-settings.views :refer [network-settings]]
|
||||
[status-im.ui.screens.network-settings.add-rpc.views :refer [add-rpc-url]]
|
||||
[status-im.ui.screens.network-settings.network-details.views :refer [network-details]]
|
||||
[status-im.ui.screens.network-settings.parse-json.views :refer [paste-json-text]]))
|
||||
|
||||
(defn validate-current-view
|
||||
[current-view signed-up?]
|
||||
|
@ -91,8 +95,13 @@
|
|||
:accounts accounts
|
||||
:login login
|
||||
:recover recover
|
||||
:network-settings network-settings
|
||||
:paste-json-text paste-json-text
|
||||
:add-rpc-url add-rpc-url
|
||||
:network-details network-details
|
||||
(throw (str "Unknown view: " current-view)))]
|
||||
|
||||
|
||||
[(if android? menu-context view) common-styles/flex
|
||||
[view common-styles/flex
|
||||
[component]
|
||||
|
|
|
@ -13,4 +13,5 @@
|
|||
(def wallet-wip-enabled? (enabled? (get-config :WALLET_WIP_ENABLED 0)))
|
||||
(def notifications-wip-enabled? (enabled? (get-config :NOTIFICATIONS_WIP_ENABLED 0)))
|
||||
(def stub-status-go? (enabled? (get-config :STUB_STATUS_GO 0)))
|
||||
(def network-switching-enabled? (enabled? (get-config :NETWORK_SWITCHING 0)))
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
(defn get-network-subdomain [network]
|
||||
(case network
|
||||
"testnet" "ropsten"
|
||||
"testnet_rpc" "ropsten"
|
||||
"mainnet" "api"))
|
||||
|
||||
(defn get-transaction-details-url [network hash]
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
status-im.ui.screens.db
|
||||
status-im.ui.screens.subs
|
||||
[status-im.ui.screens.events :as events]
|
||||
[status-im.ui.screens.accounts.events :as account-events]))
|
||||
[status-im.ui.screens.accounts.events :as account-events]
|
||||
[status-im.constants :as constants]))
|
||||
|
||||
(def account-from-realm
|
||||
{:last-updated 1502965625859
|
||||
|
@ -17,11 +18,12 @@
|
|||
:name "Sleepy Serene Leopardseal"
|
||||
:updates-private-key "3849320857de8efe1e1ec57e08e92ed2bce196cb8763756ae4e6e7e011c1d857de0a115b3dc7eff066afe75a8794ea9905b"
|
||||
:updates-public-key "384975d68aec6426faacf8b4ba2c55d5a84b70a8a26eb616e06e9c9e63f95dfdf1c1c165773e1cdca2d198a0bc5386d8a6f2079414e073b4730c8f4745292a6cdfb3fa28143ad5937128643c6addf356b66962376dc8b12274d9abfb2e1c6447ac3"
|
||||
:photo-path "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAADAFBMVEXw8PCM2JYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADWF3ggAAABAHRSTlP//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKmfXxgAABnNJREFUeNoBaAaX+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEAAAAAAAABAQEBAQEAAAAAAAABAQEBAQEAAAAAAAAAAAAAAAEBAQEBAQAAAAAAAAEBAQEBAQAAAAAAAAEBAQEBAQAAAAAAAAAAAAAAAQEBAQEBAAAAAAAAAQEBAQEBAAAAAAAAAQEBAQEBAAAAAAAAAAAAAAABAQEBAQEAAAAAAAABAQEBAQEAAAAAAAABAQEBAQEAAAAAAAAAAAAAAAEBAQEBAQAAAAAAAAEBAQEBAQAAAAAAAAEBAQEBAQAAAAAAAAAAAAAAAQEBAQEBAAAAAAAAAQEBAQEBAAAAAAAAAQEBAQEBAAAAAAAAAAAAAAABAQEBAQEAAAAAAAABAQEBAQEAAAAAAAABAQEBAQEAAAAAAAAAAAAAAAEBAQEBAQAAAAAAAAEBAQEBAQAAAAAAAAEBAQEBAQAAAAAAAAAAAAAAAQEBAQEBAAAAAAAAAQEBAQEBAAAAAAAAAQEBAQEBAAAAAAAAAAAAAAABAQEBAQEAAAAAAAABAQEBAQEAAAAAAAABAQEBAQEAAAAAAAAAAAAAAAEBAQEBAQAAAAAAAAEBAQEBAQAAAAAAAAEBAQEBAQAAAAAAAAAAAAAAAQEBAQEBAAAAAAAAAQEBAQEBAAAAAAAAAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQAAAAAAAAEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAAAAAAAAAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQAAAAAAAAEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAAAAAAAAAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmBECiQccq18AAAAASUVORK5CYII="
|
||||
:photo-path "photo"
|
||||
:debug? false
|
||||
:signing-phrase "baby atom base"
|
||||
:status "be the hero of your own journey"
|
||||
:network "testnet"
|
||||
:network constants/default-network
|
||||
:networks constants/default-networks
|
||||
:public-key "0x049b3a8c04f2c5bccda91c1f5e6434ae72957e93a31c0301b4563eda1d6ce419f63c503ebaee143115f96c1f04f232a7a22ca0454e9ee3d579ad1f870315b151d0"})
|
||||
|
||||
(def new-account
|
||||
|
@ -30,8 +32,10 @@
|
|||
:name "Disloyal Trusting Rainbowfish"
|
||||
:updates-private-key "3849071831f581f5e2a4f095a53e0a697144b32ea6de9e92cc08936f2efa40d2f1702bdb131356df0930a3a0d301221f2b5"
|
||||
:updates-public-key "38453ecc298b8b35de00c85d3217f00aa7040a7d3053dbbf6831d03c750df40b27977906692b3b5d6fec8134706b2bf65900c61130047488520cb60080a59b118cb281f3aaf65ba704c7efde8f9357d2b22fe8110b38a4dd714c1c9e108a8b067fe"
|
||||
:photo-path "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAADAFBMVEXw8PDYjLoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG2YFqAAABAHRSTlP//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKmfXxgAABnNJREFUeNoBaAaX+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEAAAAAAAABAQEBAQEAAAAAAAABAQEBAQEAAAAAAAAAAAAAAAEBAQEBAQAAAAAAAAEBAQEBAQAAAAAAAAEBAQEBAQAAAAAAAAAAAAAAAQEBAQEBAAAAAAAAAQEBAQEBAAAAAAAAAQEBAQEBAAAAAAAAAAAAAAABAQEBAQEAAAAAAAABAQEBAQEAAAAAAAABAQEBAQEAAAAAAAAAAAAAAAEBAQEBAQAAAAAAAAEBAQEBAQAAAAAAAAEBAQEBAQAAAAAAAAAAAAAAAQEBAQEBAAAAAAAAAQEBAQEBAAAAAAAAAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEAAAAAAAAAAAAAAAEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQAAAAAAAAAAAAAAAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAAAAAAAAAAAAAAABAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEAAAAAAAAAAAAAAAEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQAAAAAAAAAAAAAAAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKUMBsXBa1BAAAAAASUVORK5CYII="
|
||||
:photo-path "new-account-photo"
|
||||
:status "the future starts today, not tomorrow"
|
||||
:network constants/default-network
|
||||
:networks constants/default-networks
|
||||
:signing-phrase "long loan limo"
|
||||
:public-key "0x04f5722fba79eb36d73263417531007f43d13af76c6233573a8e3e60f667710611feba0785d751b50609bfc0b7cef35448875c5392c0a91948c95798a0ce600847"})
|
||||
|
||||
|
@ -45,7 +49,7 @@
|
|||
(rf/reg-cofx
|
||||
:get-new-keypair!
|
||||
(fn [coeffects _]
|
||||
(assoc coeffects :keypair {:public "new public"
|
||||
(assoc coeffects :keypair {:public "new public"
|
||||
:private "new private"})))
|
||||
|
||||
(rf/reg-cofx
|
||||
|
@ -77,12 +81,12 @@
|
|||
(is (= {(:address account-from-realm) account-from-realm} @accounts)))
|
||||
|
||||
(testing ":add-account event"
|
||||
(let [new-account' (assoc new-account :network "testnet")]
|
||||
(let [new-account' (assoc new-account :network constants/default-network)]
|
||||
|
||||
(rf/dispatch [:add-account new-account])
|
||||
|
||||
(is (= {(:address account-from-realm) account-from-realm
|
||||
(:address new-account) new-account'} @accounts))
|
||||
(:address new-account) new-account'} @accounts))
|
||||
|
||||
(testing ":account-update event"
|
||||
|
||||
|
@ -95,7 +99,7 @@
|
|||
(rf/dispatch [:account-update {:status "new status" :name "new name"}])
|
||||
|
||||
(is (= {(:address account-from-realm) account-from-realm
|
||||
(:address new-account) new-account''}
|
||||
(:address new-account) new-account''}
|
||||
(update @accounts (:address new-account) dissoc :last-updated)))
|
||||
|
||||
(testing ":account-update-keys event"
|
||||
|
@ -103,7 +107,7 @@
|
|||
(rf/dispatch [:account-update-keys])
|
||||
|
||||
(is (= {(:address account-from-realm) account-from-realm
|
||||
(:address new-account) (assoc new-account''
|
||||
:updates-private-key "new private"
|
||||
:updates-public-key "new public")}
|
||||
(update @accounts (:address new-account) dissoc :last-updated)))))))))))
|
||||
(:address new-account) (assoc new-account''
|
||||
:updates-private-key "new private"
|
||||
:updates-public-key "new public")}
|
||||
(update @accounts (:address new-account) dissoc :last-updated)))))))))))
|
||||
|
|
Loading…
Reference in New Issue