integrate status-go accounts

This commit is contained in:
yenda 2019-08-01 22:11:59 +02:00
parent d2f1bbeb16
commit d7cd2b8a74
No known key found for this signature in database
GPG Key ID: 0095623C0069DCE6
82 changed files with 1347 additions and 2934 deletions

View File

@ -228,6 +228,7 @@ var TopLevel = {
"log" : function () {},
"login" : function () {},
"loginWithKeycard" : function () {},
"logout" : function () {},
"loop" : function () {},
"lt" : function () {},
"mail" : function () {},
@ -339,6 +340,7 @@ var TopLevel = {
"onNotification" : function () {},
"onNotificationOpened" : function () {},
"onTokenRefresh" : function () {},
"openAccounts" : function () {},
"openNfcSettings" : function () {},
"openPicker" : function () {},
"openURL" : function () {},
@ -368,6 +370,7 @@ var TopLevel = {
"Category" : function () {},
"High" : function () {},
"Importance" : function () {},
"prepareDirAndUpdateConfig" : function () {},
"Promise" : function () {},
"props" : function () {},
"prototype" : function () {},
@ -405,6 +408,7 @@ var TopLevel = {
"round" : function () {},
"routeName" : function () {},
"routes" : function () {},
"saveAccountAndLogin" : function () {},
"schemaVersion" : function () {},
"scrollTo" : function () {},
"scrollToEnd" : function () {},
@ -570,5 +574,5 @@ var TopLevel = {
"multiAccountReset" : function () {},
"multiAccountLoadAccount" : function () {},
"multiAccountStoreAccount" : function () {},
"multiAccountImportMnemonic" : function () {},
"multiAccountImportMnemonic" : function () {}
}

View File

@ -197,7 +197,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
return file.getAbsolutePath();
}
private void doStartNode(final String jsonConfigString) {
private String prepareDirAndUpdateConfig(final String jsonConfigString) {
Activity currentActivity = getCurrentActivity();
@ -258,17 +258,57 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
prettyPrintConfig(updatedJsonConfigString);
String res = Statusgo.startNode(updatedJsonConfigString);
if (res.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "StartNode result: " + res);
Log.d(TAG, "Geth node started");
}
else {
Log.e(TAG, "StartNode failed: " + res);
}
return updatedJsonConfigString;
} catch (JSONException e) {
Log.e(TAG, "updateConfig failed: " + e.getMessage());
System.exit(1);
return "";
}
}
@ReactMethod
public void prepareDirAndUpdateConfig(final String config, final Callback callback) {
Log.d(TAG, "prepareDirAndUpdateConfig");
String finalConfig = prepareDirAndUpdateConfig(config);
callback.invoke(finalConfig);
}
@ReactMethod
public void saveAccountAndLogin(final String accountData, final String password , final String config, final String subAccountsData) {
Log.d(TAG, "saveAccountAndLogin");
String finalConfig = prepareDirAndUpdateConfig(config);
String result = Statusgo.saveAccountAndLogin(accountData, password, finalConfig, subAccountsData);
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "StartNode result: " + result);
Log.d(TAG, "Geth node started");
}
else {
Log.e(TAG, "StartNode failed: " + result);
}
}
@ReactMethod
public void login(final String accountData, final String password) {
Log.d(TAG, "login");
String result = Statusgo.login(accountData, password);
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "Login result: " + result);
}
else {
Log.e(TAG, "Login failed: " + result);
}
}
@ReactMethod
public void logout() {
Log.d(TAG, "logout");
String result = Statusgo.logout();
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "Logout result: " + result);
}
else {
Log.e(TAG, "Logout failed: " + result);
}
}
@ -356,7 +396,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
private void initKeystore() {
Activity currentActivity = getCurrentActivity();
final String keydir = currentActivity.getApplicationInfo().dataDir;
final String keydir = pathCombine(currentActivity.getApplicationInfo().dataDir, "/keystore");
Log.d(TAG, "initKeystore");
if (!checkAvailability()) {
Log.e(TAG, "[initKeystore] Activity doesn't exist, cannot init keystore");
@ -375,54 +415,24 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
}
@ReactMethod
public void startNode(final String config) {
Log.d(TAG, "startNode");
private void openAccounts(final Callback callback) {
Activity currentActivity = getCurrentActivity();
final String rootDir = currentActivity.getApplicationInfo().dataDir;
Log.d(TAG, "openAccounts");
if (!checkAvailability()) {
Log.e(TAG, "[startNode] Activity doesn't exist, cannot start node");
Log.e(TAG, "[openAccounts] Activity doesn't exist, cannot call openAccounts");
System.exit(0);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
doStartNode(config);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void stopNode() {
Runnable r = new Runnable() {
@Override
public void run() {
Log.d(TAG, "stopNode");
String res = Statusgo.stopNode();
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void login(final String json, final Callback callback) {
Log.d(TAG, "login");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String result = Statusgo.login(json);
callback.invoke(result);
}
};
@Override
public void run() {
String result =Statusgo.openAccounts(rootDir);
callback.invoke(result);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ -807,11 +817,9 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
@Override
public void run() {
String res = Statusgo.multiAccountImportMnemonic(json);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}

View File

@ -78,10 +78,9 @@ void RCTStatus::getDeviceUUID(double callbackId) {
d->bridge->invokePromiseCallback(callbackId, QVariantList{"com.status.StatusIm"});
}
void RCTStatus::startNode(QString configString) {
QString RCTStatus::prepareDirAndUpdateConfig(QString configString) {
Q_D(RCTStatus);
qCDebug(RCTSTATUS) << "::startNode call - configString:" << configString;
qCDebug(RCTSTATUS) << "::prepareDirAndUpdateConfig call - configString:" << configString;
QJsonParseError jsonError;
const QJsonDocument& jsonDoc = QJsonDocument::fromJson(configString.toUtf8(), &jsonError);
@ -117,22 +116,23 @@ void RCTStatus::startNode(QString configString) {
const QJsonDocument& updatedJsonDoc = QJsonDocument::fromVariant(configJSON);
qCInfo(RCTSTATUS) << "::startNode updated configString: " << updatedJsonDoc.toVariant().toMap();
const char* result = StartNode(QString(updatedJsonDoc.toJson(QJsonDocument::Compact)).toUtf8().data());
logStatusGoResult("::startNode StartNode", result);
return QString(updatedJsonDoc.toJson(QJsonDocument::Compact));
}
void RCTStatus::stopNode() {
qCInfo(RCTSTATUS) << "::stopNode call";
const char* result = StopNode();
logStatusGoResult("::stopNode StopNode", result);
void RCTStatus::prepareDirAndUpdateConfig(QString configString, double callbackId) {
Q_D(RCTStatus);
qCInfo(RCTSTATUS) << "::prepareDirAndUpdateConfig call - callbackId:" << callbackId;
QtConcurrent::run([&](QString configString, double callbackId) {
QString updatedConfig = prepareDirAndUpdateConfig(configString);
d->bridge->invokePromiseCallback(callbackId, QVariantList{updatedConfig.toUtf8().data()});
}, configString, callbackId);
}
void RCTStatus::initKeystore() {
aCInfo(RCTSTATUS) << "::initKeystore call";
QString rootDirPath = getDataStoragePath();
const char* result = initKeystore(rootDirPath);
logStatusGoResult("::initKeystore InitKeystore", result);
qCInfo(RCTSTATUS) << "::initKeystore call";
QString rootDir = getDataStoragePath();
const char* result = InitKeystore(rootDir.toUtf8().data());
logStatusGoResult("::initKeystore InitKeystore", result);
}
void RCTStatus::createAccount(QString password, double callbackId) {
@ -271,16 +271,83 @@ void RCTStatus::recoverAccount(QString passphrase, QString password, double call
}
void RCTStatus::login(QString address, QString password, double callbackId) {
void RCTStatus::saveAccountAndLogin(QString accountData, QString password, QString config, QString subAccountsData) {
Q_D(RCTStatus);
qCInfo(RCTSTATUS) << "::login call - callbackId:" << callbackId;
QtConcurrent::run([&](QString address, QString password, double callbackId) {
const char* result = Login(address.toUtf8().data(), password.toUtf8().data());
logStatusGoResult("::login Login", result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
}, address, password, callbackId);
QString finalConfig = prepareDirAndUpdateConfig(config);
QtConcurrent::run([&](QString accountData, QString password, QString finalConfig, QString subAccountsData) {
const char* result = SaveAccountAndLogin(accountData.toUtf8().data(), password.toUtf8().data(), finalConfig.toUtf8().data(), subAccountsData.toUtf8().data());
logStatusGoResult("::saveAccountAndLogin", result);
}, accountData, password, finalConfig, subAccountsData);
}
void RCTStatus::login(QString accountData, QString password) {
Q_D(RCTStatus);
QtConcurrent::run([&](QString accountData, QString password) {
const char* result = Login(accountData.toUtf8().data(), password.toUtf8().data());
logStatusGoResult("::login", result);
}, accountData, password);
}
void RCTStatus::logout() {
Q_D(RCTStatus);
QtConcurrent::run([&]() {
const char* result = Logout();
logStatusGoResult("::logout", result);
});
}
void RCTStatus::openAccounts(double callbackId) {
Q_D(RCTStatus);
QtConcurrent::run([&](double callbackId) {
QString rootDir = getDataStoragePath();
const char* result = OpenAccounts(rootDir.toUtf8().data());
logStatusGoResult("::openAccounts", result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
}, callbackId);
}
void RCTStatus::multiAccountStoreAccount(QString json, double callbackId) {
Q_D(RCTStatus);
QtConcurrent::run([&](QString json, double callbackId) {
const char* result = MultiAccountStoreAccount(json.toUtf8().data());
logStatusGoResult("::multiAccountStoreAccount", result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
}, json, callbackId);
}
void RCTStatus::multiAccountLoadAccount(QString json, double callbackId) {
Q_D(RCTStatus);
QtConcurrent::run([&](QString json, double callbackId) {
const char* result = MultiAccountLoadAccount(json.toUtf8().data());
logStatusGoResult("::multiAccountLoadAccount", result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
}, json, callbackId);
}
void RCTStatus::multiAccountReset(double callbackId) {
Q_D(RCTStatus);
QtConcurrent::run([&](double callbackId) {
const char* result = MultiAccountReset();
logStatusGoResult("::multiAccountReset", result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
}, callbackId);
}
void RCTStatus::multiAccountDeriveAddresses(QString json, double callbackId) {
Q_D(RCTStatus);
QtConcurrent::run([&](QString json, double callbackId) {
const char* result = MultiAccountDeriveAddresses(json.toUtf8().data());
logStatusGoResult("::multiAccountDeriveAddresses", result);
d->bridge->invokePromiseCallback(callbackId, QVariantList{result});
}, json, callbackId);
}
void RCTStatus::verify(QString address, QString password, double callbackId) {
Q_D(RCTStatus);
qCInfo(RCTSTATUS) << "::verify call - callbackId:" << callbackId;

View File

@ -36,14 +36,20 @@ public:
QVariantMap constantsToExport() override;
Q_INVOKABLE void initKeystore();
Q_INVOKABLE void startNode(QString configString);
Q_INVOKABLE void stopNode();
Q_INVOKABLE void createAccount(QString password, double callbackId);
Q_INVOKABLE void sendDataNotification(QString dataPayloadJSON, QString tokensJSON, double callbackId);
Q_INVOKABLE void sendLogs(QString dbJSON, QString jsLogs, double callbackId);
Q_INVOKABLE void addPeer(QString enode, double callbackId);
Q_INVOKABLE void recoverAccount(QString passphrase, QString password, double callbackId);
Q_INVOKABLE void login(QString address, QString password, double callbackId);
Q_INVOKABLE void prepareDirAndUpdateConfig(QString configString, double callbackId);
Q_INVOKABLE void login(QString accountData, QString password);
Q_INVOKABLE void saveAccountAndLogin(QString accountData, QString password, QString config, QString subAccountsData);
Q_INVOKABLE void logout();
Q_INVOKABLE void openAccounts(double callbackId);
Q_INVOKABLE void multiAccountStoreAccount(QString json, double callbackId);
Q_INVOKABLE void multiAccountLoadAccount(QString json, double callbackId);
Q_INVOKABLE void multiAccountReset(double callbackId);
Q_INVOKABLE void multiAccountDeriveAddresses(QString json, double callbackId);
Q_INVOKABLE void verify(QString address, QString password, double callbackId);
Q_INVOKABLE void sendTransaction(QString txArgsJSON, QString password, double callbackId);
Q_INVOKABLE void signMessage(QString rpcParams, double callbackId);
@ -78,6 +84,7 @@ private Q_SLOTS:
private:
void logStatusGoResult(const char* methodName, const char* result);
QString prepareDirAndUpdateConfig(QString configString);
QScopedPointer<RCTStatusPrivate> d_ptr;
QString d_gethLogFilePath;
};

View File

@ -88,87 +88,8 @@ static RCTBridge *bridge;
return;
}
RCT_EXPORT_MODULE();
////////////////////////////////////////////////////////////////////
#pragma mark - startNode
//////////////////////////////////////////////////////////////////// startNode
RCT_EXPORT_METHOD(startNode:(NSString *)configString) {
#if DEBUG
NSLog(@"StartNode() method called");
#endif
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = nil;
NSURL *rootUrl =[[fileManager
URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]
lastObject];
NSURL *absTestnetFolderName = [rootUrl URLByAppendingPathComponent:@"ethereum/testnet"];
if (![fileManager fileExistsAtPath:absTestnetFolderName.path])
[fileManager createDirectoryAtPath:absTestnetFolderName.path withIntermediateDirectories:YES attributes:nil error:&error];
NSURL *flagFolderUrl = [rootUrl URLByAppendingPathComponent:@"ropsten_flag"];
if(![fileManager fileExistsAtPath:flagFolderUrl.path]){
NSLog(@"remove lightchaindata");
NSURL *absLightChainDataUrl = [absTestnetFolderName URLByAppendingPathComponent:@"StatusIM/lightchaindata"];
if([fileManager fileExistsAtPath:absLightChainDataUrl.path]) {
[fileManager removeItemAtPath:absLightChainDataUrl.path
error:nil];
}
[fileManager createDirectoryAtPath:flagFolderUrl.path
withIntermediateDirectories:NO
attributes:nil
error:&error];
}
NSLog(@"after remove lightchaindata");
NSURL *absTestnetKeystoreUrl = [absTestnetFolderName URLByAppendingPathComponent:@"keystore"];
NSURL *absKeystoreUrl = [rootUrl URLByAppendingPathComponent:@"keystore"];
if([fileManager fileExistsAtPath:absTestnetKeystoreUrl.path]){
NSLog(@"copy keystore");
[fileManager copyItemAtPath:absTestnetKeystoreUrl.path toPath:absKeystoreUrl.path error:nil];
[fileManager removeItemAtPath:absTestnetKeystoreUrl.path error:nil];
}
NSLog(@"after lightChainData");
NSLog(@"preconfig: %@", configString);
NSData *configData = [configString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *configJSON = [NSJSONSerialization JSONObjectWithData:configData options:NSJSONReadingMutableContainers error:nil];
NSString *relativeDataDir = [configJSON objectForKey:@"DataDir"];
NSString *absDataDir = [rootUrl.path stringByAppendingString:relativeDataDir];
NSURL *absDataDirUrl = [NSURL fileURLWithPath:absDataDir];
NSURL *absLogUrl = [absDataDirUrl URLByAppendingPathComponent:@"geth.log"];
[configJSON setValue:absDataDirUrl.path forKey:@"DataDir"];
[configJSON setValue:absKeystoreUrl.path forKey:@"KeyStoreDir"];
[configJSON setValue:absLogUrl.path forKey:@"LogFile"];
NSString *resultingConfig = [configJSON bv_jsonStringWithPrettyPrint:NO];
NSLog(@"node config %@", resultingConfig);
if(![fileManager fileExistsAtPath:absDataDirUrl.path]) {
[fileManager createDirectoryAtPath:absDataDirUrl.path withIntermediateDirectories:YES attributes:nil error:nil];
}
NSLog(@"logUrlPath %@", absLogUrl.path);
if(![fileManager fileExistsAtPath:absLogUrl.path]) {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:[NSNumber numberWithInt:511] forKey:NSFilePosixPermissions];
[fileManager createFileAtPath:absLogUrl.path contents:nil attributes:dict];
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^(void)
{
NSString *res = StatusgoStartNode(resultingConfig);
NSLog(@"StartNode result %@", res);
});
}
////////////////////////////////////////////////////////////////////
#pragma mark - shouldMoveToInternalStorage
//////////////////////////////////////////////////////////////////// shouldMoveToInternalStorage
@ -185,20 +106,6 @@ RCT_EXPORT_METHOD(moveToInternalStorage:(RCTResponseSenderBlock)onResultCallback
onResultCallback(@[[NSNull null]]);
}
////////////////////////////////////////////////////////////////////
#pragma mark - StopNode method
//////////////////////////////////////////////////////////////////// StopNode
RCT_EXPORT_METHOD(stopNode) {
#if DEBUG
NSLog(@"StopNode() method called");
#endif
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^(void)
{
NSString *res = StatusgoStopNode();
NSLog(@"StopNode result %@", res);
});
}
////////////////////////////////////////////////////////////////////
#pragma mark - InitKeystore method
@ -208,7 +115,6 @@ RCT_EXPORT_METHOD(initKeystore) {
NSLog(@"initKeystore() method called");
#endif
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = nil;
NSURL *rootUrl =[[fileManager
URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]
lastObject];
@ -426,17 +332,137 @@ RCT_EXPORT_METHOD(multiAccountDeriveAddresses:(NSString *)json
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// prepareDirAndUpdateConfig
-(NSString *) prepareDirAndUpdateConfig:(NSString *)config {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = nil;
NSURL *rootUrl =[[fileManager
URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]
lastObject];
NSURL *absTestnetFolderName = [rootUrl URLByAppendingPathComponent:@"ethereum/testnet"];
if (![fileManager fileExistsAtPath:absTestnetFolderName.path])
[fileManager createDirectoryAtPath:absTestnetFolderName.path withIntermediateDirectories:YES attributes:nil error:&error];
NSURL *flagFolderUrl = [rootUrl URLByAppendingPathComponent:@"ropsten_flag"];
if(![fileManager fileExistsAtPath:flagFolderUrl.path]){
NSLog(@"remove lightchaindata");
NSURL *absLightChainDataUrl = [absTestnetFolderName URLByAppendingPathComponent:@"StatusIM/lightchaindata"];
if([fileManager fileExistsAtPath:absLightChainDataUrl.path]) {
[fileManager removeItemAtPath:absLightChainDataUrl.path
error:nil];
}
[fileManager createDirectoryAtPath:flagFolderUrl.path
withIntermediateDirectories:NO
attributes:nil
error:&error];
}
NSLog(@"after remove lightchaindata");
NSURL *absTestnetKeystoreUrl = [absTestnetFolderName URLByAppendingPathComponent:@"keystore"];
NSURL *absKeystoreUrl = [rootUrl URLByAppendingPathComponent:@"keystore"];
if([fileManager fileExistsAtPath:absTestnetKeystoreUrl.path]){
NSLog(@"copy keystore");
[fileManager copyItemAtPath:absTestnetKeystoreUrl.path toPath:absKeystoreUrl.path error:nil];
[fileManager removeItemAtPath:absTestnetKeystoreUrl.path error:nil];
}
NSLog(@"after lightChainData");
NSLog(@"preconfig: %@", config);
NSData *configData = [config dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *configJSON = [NSJSONSerialization JSONObjectWithData:configData options:NSJSONReadingMutableContainers error:nil];
NSString *relativeDataDir = [configJSON objectForKey:@"DataDir"];
NSString *absDataDir = [rootUrl.path stringByAppendingString:relativeDataDir];
NSURL *absDataDirUrl = [NSURL fileURLWithPath:absDataDir];
NSURL *absLogUrl = [absDataDirUrl URLByAppendingPathComponent:@"geth.log"];
[configJSON setValue:absDataDirUrl.path forKey:@"DataDir"];
[configJSON setValue:absKeystoreUrl.path forKey:@"KeyStoreDir"];
[configJSON setValue:absLogUrl.path forKey:@"LogFile"];
NSString *resultingConfig = [configJSON bv_jsonStringWithPrettyPrint:NO];
NSLog(@"node config %@", resultingConfig);
if(![fileManager fileExistsAtPath:absDataDirUrl.path]) {
[fileManager createDirectoryAtPath:absDataDirUrl.path withIntermediateDirectories:YES attributes:nil error:nil];
}
NSLog(@"logUrlPath %@", absLogUrl.path);
if(![fileManager fileExistsAtPath:absLogUrl.path]) {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:[NSNumber numberWithInt:511] forKey:NSFilePosixPermissions];
[fileManager createFileAtPath:absLogUrl.path contents:nil attributes:dict];
}
return resultingConfig;
}
//////////////////////////////////////////////////////////////////// prepareDirAndUpdateConfig
RCT_EXPORT_METHOD(prepareDirAndUpdateConfig:(NSString *)config
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"PrepareDirAndUpdateConfig() method called");
#endif
NSString *updatedConfig = [self prepareDirAndUpdateConfig:config];
callback(@[updatedConfig]);
}
//////////////////////////////////////////////////////////////////// saveAccountAndLogin
RCT_EXPORT_METHOD(saveAccountAndLogin:(NSString *)accountData
password:(NSString *)password
config:(NSString *)config
subAccountsData:(NSString *)subAccountsData) {
#if DEBUG
NSLog(@"SaveAccountAndLogin() method called");
#endif
NSString *finalConfig = [self prepareDirAndUpdateConfig:config];
NSString *result = StatusgoSaveAccountAndLogin(accountData, password, finalConfig, subAccountsData);
NSLog(@"%@", result);
}
//////////////////////////////////////////////////////////////////// login
RCT_EXPORT_METHOD(login:(NSString *)json
callback:(RCTResponseSenderBlock)callback) {
RCT_EXPORT_METHOD(login:(NSString *)accountData
password:(NSString *)password) {
#if DEBUG
NSLog(@"Login() method called");
#endif
NSString *result = StatusgoLogin(json);
NSString *result = StatusgoLogin(accountData, password);
NSLog(@"%@", result);
}
//////////////////////////////////////////////////////////////////// logout
RCT_EXPORT_METHOD(logout) {
#if DEBUG
NSLog(@"Logout() method called");
#endif
NSString *result = StatusgoLogout();
NSLog(@"%@", result);
}
//////////////////////////////////////////////////////////////////// openAccounts
RCT_EXPORT_METHOD(openAccounts:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"OpenAccounts() method called");
#endif
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *rootUrl =[[fileManager
URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]
lastObject];
NSString *result = StatusgoOpenAccounts(rootUrl.path);
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// login
//////////////////////////////////////////////////////////////////// verityAccountPassword
RCT_EXPORT_METHOD(verify:(NSString *)address
password:(NSString *)password
callback:(RCTResponseSenderBlock)callback) {

View File

@ -75,18 +75,12 @@
(filters/load-filters)
(commands/load-commands commands/register))))
(defn load-chats-from-rpc
[cofx from to]
(data-store.chats/fetch-chats-rpc cofx {:from 0
:to 10
:on-success
#(re-frame/dispatch
[:chats-list/load-success %])}))
(fx/defn initialize-chats
"Initialize persisted chats on startup"
[cofx
{:keys [from to] :or {from 0 to nil}}]
(load-chats-from-rpc cofx from -1))
[cofx]
(data-store.chats/fetch-chats-rpc cofx {:on-success
#(re-frame/dispatch
[:chats-list/load-success %])}))
(fx/defn messages-loaded
"Loads more messages for current chat"

View File

@ -114,7 +114,7 @@
(into {} (filter network-enabled?
(merge testnet-networks mainnet-networks sidechain-networks))))
(defn default-multiaccount-settings []
(def default-multiaccount-settings
{:web3-opt-in? true
:preview-privacy? false
:wallet {:visible-tokens {}}})

View File

@ -133,7 +133,7 @@
(def receive-contact-update handle-contact-update)
(fx/defn initialize-contacts [cofx]
(contacts-store/fetch-contacts-rpc #(re-frame/dispatch [::contacts-loaded %])))
(contacts-store/fetch-contacts-rpc cofx #(re-frame/dispatch [::contacts-loaded %])))
(fx/defn open-contact-toggle-list
[{:keys [db :as cofx]}]

View File

@ -142,16 +142,16 @@
(dissoc :chatType :members)))
(fx/defn save-chat-rpc [cofx {:keys [chat-id] :as chat}]
(json-rpc/call {:method "shhext_saveChat"
:params [(->rpc chat)]
:on-success #(log/debug "saved chat" chat-id "successfuly")
:on-failure #(log/error "failed to save chat" chat-id %)}))
{::json-rpc/call [{:method "shhext_saveChat"
:params [(->rpc chat)]
:on-success #(log/debug "saved chat" chat-id "successfuly")
:on-failure #(log/error "failed to save chat" chat-id %)}]})
(fx/defn fetch-chats-rpc [cofx {:keys [from to on-success]}]
(json-rpc/call {:method "shhext_chats"
:params [from to]
:on-success #(on-success (map <-rpc %))
:on-failure #(log/error "failed to fetch chats" from to %)}))
(fx/defn fetch-chats-rpc [cofx {:keys [on-success]}]
{::json-rpc/call [{:method "shhext_chats"
:params [0 -1]
:on-success #(on-success (map <-rpc %))
:on-failure #(log/error "failed to fetch chats" 0 -1 %)}]})
(defn delete-chat-rpc [chat-id chat-type]
(json-rpc/call {:method "shhext_deleteChat"

View File

@ -48,13 +48,8 @@
:system-tags :systemTags
:last-updated :lastUpdated})))
(defn save-contact-rpc [{:keys [public-key] :as contact}]
{::json-rpc/call [{:method "shhext_saveContact"
:params [(->rpc contact)]
:on-success #(log/debug "saved contact" public-key "successfuly")
:on-failure #(log/error "failed to save contact" public-key %)}]})
(defn fetch-contacts-rpc [on-success]
(fx/defn fetch-contacts-rpc
[cofx on-success]
{::json-rpc/call [{:method "shhext_contacts"
:params []
:on-success #(on-success (map <-rpc %))
@ -67,12 +62,15 @@
(.objects "message")
(.filtered (str "(" (core/in-query "message-id" message-ids) ")")))))
(fx/defn save-contact
[cofx {:keys [public-key] :as contact}]
{::json-rpc/call [{:method "shhext_saveContact"
:params [(->rpc contact)]
:on-success #(log/debug "saved contact" public-key "successfuly")
:on-failure #(log/error "failed to save contact" public-key %)}]})
(fx/defn block [cofx contact on-success]
{::json-rpc/call [{:method "shhext_blockContact"
:params [(->rpc contact)]
:on-success on-success
:on-failure #(log/error "failed to block contact" % contact)}]})
(fx/defn save-contact [cofx contact]
(save-contact-rpc contact))

View File

@ -2,26 +2,26 @@
(:require [cljs.core.async :as async]
[re-frame.core :as re-frame]
[taoensso.timbre :as log]
[status-im.data-store.realm.core :as data-source]
[status-im.data-store.realm.core :as realm]
[status-im.utils.keychain.core :as keychain]
[status-im.utils.handlers :as handlers]
[status-im.utils.security :as security]
[status-im.native-module.core :as status]
[status-im.multiaccounts.model :as multiaccounts.model]
[status-im.utils.types :as types]
[status-im.i18n :as i18n]
status-im.data-store.chats
status-im.data-store.messages
status-im.data-store.contacts
status-im.data-store.installations
status-im.data-store.transport
status-im.data-store.multiaccounts
status-im.data-store.mailservers))
status-im.data-store.mailservers
[status-im.utils.fx :as fx]
[status-im.protocol.core :as protocol]))
(defn init [encryption-key]
(if @data-source/base-realm
(js/Promise.resolve)
(..
(data-source/ensure-directories)
;; This can be removed when we are confident all the users
;; have migrated the data, introduced in 0.9.23
(then #(data-source/move-realms))
(catch (fn [error]
(log/error "Could not move realms" error)))
(then #(data-source/open-base-realm encryption-key)))))
(fx/defn multiaccount-db-removed
{:events [::multiaccount-db-removed]}
[{:keys [db]}]
{:db (assoc-in db [:multiaccounts/login :processing] false)})
(defn change-multiaccount
[address password encryption-key create-database-if-not-exist?]
@ -30,7 +30,7 @@
(js/Promise.
(fn [on-success on-error]
(try
(data-source/close-account-realm)
(realm/close-account-realm)
(on-success)
(catch :default e
(on-error {:message (str e)
@ -38,11 +38,11 @@
(then
(if create-database-if-not-exist?
#(js/Promise. (fn [on-success] (on-success)))
#(data-source/db-exists? address)))
#(realm/db-exists? address)))
(then
#(data-source/check-db-encryption address password encryption-key))
#(realm/check-db-encryption address password encryption-key))
(then
#(data-source/open-account address password encryption-key))))
#(realm/open-account address password encryption-key))))
(defn merge-events-of-type [success-events event-type]
;; merges data value of events of specified type together
@ -70,24 +70,161 @@
(let [success-events (keep :success-event raw-transactions)
transactions (map (fn [{:keys [transaction] :as f}]
(or transaction f)) raw-transactions)]
(data-source/write realm #(doseq [transaction transactions]
(transaction realm)))
(realm/write realm #(doseq [transaction transactions]
(transaction realm)))
(let [optimized-events (merge-persistence-events success-events)]
(doseq [event optimized-events]
(re-frame/dispatch event)))))
(re-frame/reg-fx
:data-store/base-tx
(fn [transactions]
(async/go (async/>! data-source/realm-queue
(partial perform-transactions
transactions
@data-source/base-realm)))))
(re-frame/reg-fx
:data-store/tx
(fn [transactions]
(async/go (async/>! data-source/realm-queue
(async/go (async/>! realm/realm-queue
(partial perform-transactions
transactions
@data-source/account-realm)))))
@realm/account-realm)))))
(re-frame/reg-fx
::init-store
(fn []
(realm/ensure-directories)))
(handlers/register-handler-fx
::multiaccount-data-reset-accepted
(fn [_ [_ address]]
{::reset-multiaccount-data address}))
(re-frame/reg-fx
::reset-multiaccount-data
(fn [address]
(let [callback #(re-frame/dispatch [::multiaccount-db-removed])]
(.. (realm/delete-multiaccount-realm address)
(then callback)
(catch callback)))))
(fx/defn show-migration-error-dialog
[{:keys [db]} realm-error]
(let [{:keys [message]} realm-error
address (get-in db [:multiaccounts/login :address])
erase-button (i18n/label :migrations-erase-multiaccounts-data-button)]
{:ui/show-confirmation
{:title (i18n/label :invalid-key-title)
:content (i18n/label
:invalid-key-content
{:message message
:erase-multiaccounts-data-button-text erase-button})
:confirm-button-text (i18n/label :invalid-key-confirm)
:on-accept #(re-frame/dispatch
[::multiaccount-data-reset-accepted address])}}))
(fx/defn verify-callback
{:events [::verify-success]}
[{:keys [db] :as cofx} verify-result realm-error]
(let [data (types/json->clj verify-result)
error (:error data)
success (empty? error)]
(if success
(case (:error realm-error)
:decryption-failed
(show-migration-error-dialog cofx realm-error)
:database-does-not-exist
(let [{:keys [address password]} (multiaccounts.model/credentials cofx)]
{::change-multiaccount [address password]}))
{:db (update db :multiaccounts/login assoc
:error error
:processing false)})))
(fx/defn migrations-failed
[{:keys [db]} {:keys [realm-error erase-button]}]
(let [{:keys [message details]} realm-error
address (get-in db [:multiaccounts/login :address])]
{:ui/show-confirmation
{:title (i18n/label :migrations-failed-title)
:content (i18n/label
:migrations-failed-content
(merge
{:message message
:erase-multiaccounts-data-button-text erase-button}
details))
:confirm-button-text erase-button
:on-accept #(re-frame/dispatch
[::multiaccount-data-reset-accepted address])}}))
(fx/defn verify-multiaccount
[{:keys [db] :as cofx} {:keys [realm-error]}]
(let [{:keys [address password]} (multiaccounts.model/credentials cofx)]
{:db (assoc db :realm-error realm-error)
::verify [address password (:realm-error db)]}))
(fx/defn unknown-realm-error
[cofx {:keys [realm-error erase-button]}]
(let [{:keys [message]} realm-error
{:keys [address]} (multiaccounts.model/credentials cofx)]
{:ui/show-confirmation
{:title (i18n/label :unknown-realm-error)
:content (i18n/label
:unknown-realm-error-content
{:message message
:erase-multiaccounts-data-button-text erase-button})
:confirm-button-text (i18n/label :invalid-key-confirm)
:on-accept #(re-frame/dispatch
[::multiaccount-data-reset-accepted address])}}))
(fx/defn handle-change-multiaccount-error
{:events [::multiaccount-change-error]}
[{:keys [db] :as cofx} error]
(let [{:keys [error] :as realm-error}
(if (map? error)
error
{:message (str error)})
erase-button (i18n/label :migrations-erase-multiaccounts-data-button)]
(fx/merge
cofx
{:db (assoc-in db [:multiaccounts/login :save-password?] false)}
(case error
:migrations-failed
(migrations-failed {:realm-error realm-error
:erase-button erase-button})
(:database-does-not-exist :decryption-failed)
(verify-multiaccount {:realm-error realm-error})
(unknown-realm-error {:realm-error realm-error
:erase-button erase-button})))))
(re-frame/reg-fx
::verify
(fn [[address password realm-error]]
(status/verify address
(security/safe-unmask-data password)
#(re-frame/dispatch [::verify-success % realm-error]))))
(fx/defn handle-change-multiaccount-success
{:events [::multiaccount-change-success]
:interceptors [(re-frame/inject-cofx :data-store/get-all-mailservers)
(re-frame/inject-cofx :data-store/transport)
(re-frame/inject-cofx :data-store/mailserver-topics)]}
[cofx]
(protocol/initialize-protocol cofx))
(defn change-multiaccount!
[address password create-database-if-not-exist?]
;; No matter what is the keychain we use, as checks are done on decrypting base
(.. (keychain/safe-get-encryption-key)
(then #(change-multiaccount address password % create-database-if-not-exist?))
(then #(re-frame/dispatch [::multiaccount-change-success address]))
(catch (fn [error]
(log/warn "Could not change multiaccount" error)
;; If all else fails we fallback to showing initial error
(re-frame/dispatch [::multiaccount-change-error error])))))
(re-frame/reg-fx
::change-multiaccount
(fn [[address password]]
(change-multiaccount! address (security/safe-unmask-data password) false)))
(re-frame/reg-fx
::create-multiaccount
(fn [[address password]]
(change-multiaccount! address (security/safe-unmask-data password) true)))

View File

@ -1,37 +0,0 @@
(ns status-im.data-store.installations
(:require [re-frame.core :as re-frame]
[status-im.data-store.realm.core :as core]))
(re-frame/reg-cofx
:data-store/get-all-installations
(fn [coeffects _]
(assoc coeffects :all-installations (-> @core/account-realm
(core/get-all :installation)
(core/all-clj :installation)))))
(defn save
"Returns tx function for saving a installation"
[installation]
(fn [realm]
(core/create realm
:installation
installation
true)))
(defn enable
[installation-id]
(save {:installation-id installation-id
:enabled? true}))
(defn disable
[installation-id]
(save {:installation-id installation-id
:enabled? false}))
(defn delete
"Returns tx function for deleting an installation"
[id]
(fn [realm]
(core/delete realm
(core/get-by-field realm :installation :installation-id (name id)))))

View File

@ -74,17 +74,16 @@
(log/debug "saving ranges" chat-requests-range)
(core/create realm :chat-requests-range chat-requests-range true)))
(re-frame/reg-cofx
:data-store/all-chat-requests-ranges
(fn [cofx _]
(assoc cofx
:data-store/all-chat-requests-ranges
(reduce (fn [acc {:keys [chat-id] :as range}]
(assoc acc chat-id range))
{}
(-> @core/account-realm
(core/get-all :chat-requests-range)
(core/all-clj :chat-requests-range))))))
(re-frame/reg-fx
::all-chat-requests-ranges
(fn [on-success]
(on-success (reduce (fn [acc {:keys [chat-id] :as range}]
(assoc acc chat-id range))
{}
(-> @core/account-realm
(core/get-all :chat-requests-range)
(core/all-clj :chat-requests-range))))))
(re-frame/reg-cofx
:data-store/all-gaps
(fn [cofx _]

View File

@ -1,86 +0,0 @@
(ns status-im.data-store.multiaccounts
(:require [re-frame.core :as re-frame]
[status-im.data-store.realm.core :as core]
[status-im.utils.types :as types]))
;; TODO janherich: define as cofx once debug handlers are refactored
(defn get-by-address [address]
(-> @core/base-realm
(core/get-by-field :account :address address)
(core/single-clj :account)
(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- deserialize-networks [networks]
(reduce-kv
(fn [acc network-id props]
(assoc acc network-id (update props :config types/json->clj)))
{}
networks))
(defn- deserialize-extensions [extensions]
(reduce-kv
(fn [acc _ {:keys [url] :as extension}]
(assoc acc url (update extension :data core/deserialize)))
{}
extensions))
(defn- deserialize-multiaccount [multiaccount]
(-> multiaccount
(update :settings core/deserialize)
(update :accounts core/deserialize)
(update :extensions deserialize-extensions)
(update :bootnodes deserialize-bootnodes)
(update :networks deserialize-networks)))
(defn- serialize-bootnodes [bootnodes]
(->> bootnodes
vals
(mapcat vals)))
(defn- serialize-networks [networks]
(map (fn [[_ props]]
(update props :config types/clj->json))
networks))
(defn- serialize-extensions [extensions]
(or (map #(update % :data core/serialize) (vals extensions)) '()))
(defn- serialize-multiaccount [multiaccount]
(-> multiaccount
(update :settings core/serialize)
(update :accounts core/serialize)
(update :extensions serialize-extensions)
(update :bootnodes serialize-bootnodes)
(update :networks serialize-networks)
(update :recent-stickers #(if (nil? %) [] %))
(update :stickers #(if (nil? %) [] %))))
(defn save-multiaccount-tx
"Returns tx function for saving multiaccount"
[multiaccount]
(fn [realm]
(core/create realm :account (serialize-multiaccount multiaccount) true)))
(defn delete-multiaccount-tx
"Returns tx function for deleting multiaccount"
[address]
(fn [realm]
(let [multiaccount (core/single (core/get-by-field realm :account :address address))]
(when multiaccount
(core/delete realm multiaccount)))))
(re-frame/reg-cofx
:data-store/get-all-multiaccounts
(fn [coeffects _]
(assoc coeffects :all-multiaccounts (-> @core/base-realm
(core/get-all :account)
(core/all-clj :account)
(as-> multiaccounts
(map deserialize-multiaccount multiaccounts))))))

View File

@ -4,7 +4,6 @@
[goog.object :as object]
[re-frame.core :as re-frame]
[status-im.data-store.realm.schemas.account.core :as account]
[status-im.data-store.realm.schemas.base.core :as base]
[status-im.ethereum.core :as ethereum]
[status-im.js-dependencies :as js-dependencies]
[status-im.react-native.js-dependencies :as rn-dependencies]
@ -62,9 +61,6 @@
(defn- realm-management-file? [n]
(re-matches #".*(\.management|\.lock|\.note)$" n))
(def old-base-realm-path
(.-defaultPath rn-dependencies/realm))
(defn realm-dir []
"This has to be a fn because otherwise re-frame app-db is not
initialized yet"
@ -78,15 +74,9 @@
utils.platform/desktop?
(str "/")))))
(def old-realm-dir
(string/replace old-base-realm-path #"default\.realm$" ""))
(defn accounts-realm-dir []
(str (realm-dir) "accounts/"))
(defn base-realm-path []
(str (realm-dir) "default.realm"))
(defn get-account-db-path
[address]
(str (accounts-realm-dir) (ethereum/sha3 address)))
@ -109,25 +99,6 @@
(fs/mkdir (realm-dir))
(then #(fs/mkdir (accounts-realm-dir)))))
(defn- move-realm-to-library [path]
(let [filename (last (string/split path "/"))
new-path (if (is-account-file? path)
(get-account-db-path filename)
(str (realm-dir) filename))]
(log/debug "realm: moving " path " to " new-path)
(if (realm-management-file? path)
(fs/unlink path)
(fs/move-file path new-path))))
(defn move-realms []
(log/info "realm: moving all realms")
(..
(fs/read-dir old-realm-dir)
(then #(->> (js->clj % :keywordize-keys true)
(map :path)
(filter is-realm-file?)))
(then #(js/Promise.all (clj->js (map move-realm-to-library %))))))
(defn- close [realm]
(when realm
(.close realm)))
@ -182,11 +153,9 @@
(defn- index-entity-schemas [all-schemas]
(into {} (map (juxt :name identity)) (-> all-schemas last :schema)))
(defonce base-realm (atom nil))
(defonce account-realm (atom nil))
(def entity->schemas (merge (index-entity-schemas base/schemas)
(index-entity-schemas account/schemas)))
(def entity->schemas (index-entity-schemas account/schemas))
(def realm-queue (utils.async/task-queue 2000))
@ -195,13 +164,6 @@
(close @account-realm)
(reset! account-realm nil))
(defn open-base-realm [encryption-key]
(log/debug "Opening base realm... (first run)")
(when @base-realm
(close @base-realm))
(reset! base-realm (migrate-realm (base-realm-path) base/schemas encryption-key))
(log/debug "Created @base-realm"))
(defn re-encrypt-realm
[file-name old-key new-key on-success on-error]
(let [old-file-name (str file-name "old")]

View File

@ -1,258 +0,0 @@
(ns status-im.data-store.realm.schemas.base.account)
(def v1 {: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}
: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}
: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}}})
(def v2 {: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}
: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}}})
(def v3 {: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}
: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}}})
(def v4 {: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}}})
(def v6 {: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}
:mainnet-warning-shown? {:type :bool
:default false}}})
(def v7 {: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}
:dev-mode? {:type :bool :default false}
:seed-backed-up? {:type :bool :default false}
:wallet-set-up-passed? {:type :bool
:default false}
:mainnet-warning-shown? {:type :bool
:default false}}})
;;NOTE(yenda): this was a mistake made because of the previous
;;way realm migrations were specified
(def v8 v4)
(def v10 {: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}
:dev-mode? {:type :bool :default false}
:seed-backed-up? {:type :bool :default false}
:wallet-set-up-passed? {:type :bool
:default false}
:mainnet-warning-shown? {:type :bool
:default false}}})
(def v11 (assoc-in v10
[:properties :installation-id]
{:type :string}))
(def v12 (assoc-in v11
[:properties :extensions]
{:type :list
:objectType :extension}))
(def v13 (assoc-in v12
[:properties :desktop-notifications?]
{:type :bool :default false}))
(def v14 (assoc-in v13
[:properties :desktop-alpha-release-warning-shown?]
{:type :bool :default false}))
(def v15 (update v14 :properties dissoc :email))
(def v16 (assoc-in v15
[:properties :keycard-instance-uid]
{:type :string :optional true}))
(def v17 (update v16 :properties merge {:keycard-pairing
{:type :string :optional true}
:keycard-paired-on
{:type :int :optional true}}))
(def v18 (assoc-in v17
[:properties :installation-name]
{:type :string :optional true}))
(def v19 (update v18 :properties merge {:stickers
{:type "string[]" :optional true}
:recent-stickers
{:type "string[]" :optional true}}))
(def v20 (assoc-in v19
[:properties :last-published-contact-code]
{:type :int :default 0}))
(def v21 (update v20 :properties merge
{:syncing-on-mobile-network? {:type :bool :default false}
:remember-syncing-choice? {:type :bool :default false}}))
(def v22 (update (update v21 :properties dissoc :mainnet-warning-shown?)
:properties merge
{:mainnet-warning-shown-version {:type :string :optional true}}))
(def v23 (assoc-in v22
[:properties :keycard-key-uid]
{:type :string :optional true}))
(def v24 (update v23 :properties merge {:usernames {:type "string[]" :optional true}}))
(def v25 (update v24 :properties merge {:preferred-name {:type :string :optional true}
:show-name? {:type :bool :optional true}}))
(def v26 (update v25 :properties merge {:root-address {:type :string :optional true}
:accounts {:type :string :optional true}}))
(def v27 (update v26 :properties merge {:latest-derived-path {:type :int :optional true}}))

View File

@ -1,8 +0,0 @@
(ns status-im.data-store.realm.schemas.base.bootnode)
(def v4 {:name :bootnode
:primaryKey :id
:properties {:id :string
:name {:type :string}
:chain {:type :string}
:address {:type :string}}})

View File

@ -1,232 +0,0 @@
(ns status-im.data-store.realm.schemas.base.core
(:require [status-im.data-store.realm.schemas.base.network :as network]
[status-im.data-store.realm.schemas.base.account :as account]
[status-im.data-store.realm.schemas.base.bootnode :as bootnode]
[status-im.data-store.realm.schemas.base.extension :as extension]
[status-im.data-store.realm.schemas.base.migrations :as migrations]))
(def v1 [network/v1
account/v1])
(def v2 [network/v1
account/v2])
(def v3 [network/v1
account/v3])
(def v4 [network/v1
bootnode/v4
account/v4])
(def v5 v4)
(def v6 [network/v1
bootnode/v4
account/v6])
(def v7 [network/v1
bootnode/v4
account/v7])
(def v8 [network/v1
bootnode/v4
account/v8])
(def v9 v8)
(def v10 [network/v1
bootnode/v4
account/v10])
(def v11 [network/v1
bootnode/v4
account/v11])
(def v12 [network/v1
bootnode/v4
extension/v12
account/v12])
(def v13 [network/v1
bootnode/v4
extension/v12
account/v13])
(def v14 v13)
(def v15 [network/v1
bootnode/v4
extension/v12
account/v14])
(def v16 [network/v1
bootnode/v4
extension/v12
account/v15])
(def v17 v16)
;; should go through migration of Infura project IDs from old format to new
(def v18 v17)
(def v19 [network/v1
bootnode/v4
extension/v12
account/v16])
(def v20 v19)
(def v21 [network/v1
bootnode/v4
extension/v12
account/v17])
(def v22 [network/v1
bootnode/v4
extension/v12
account/v18])
(def v23 [network/v1
bootnode/v4
extension/v12
account/v19])
(def v24 v23)
(def v25 [network/v1
bootnode/v4
extension/v12
account/v20])
(def v26 [network/v1
bootnode/v4
extension/v12
account/v21])
(def v27 [network/v1
bootnode/v4
extension/v12
account/v22])
(def v28 [network/v1
bootnode/v4
extension/v12
account/v23])
(def v29 [network/v1
bootnode/v4
extension/v12
account/v24])
(def v30 [network/v1
bootnode/v4
extension/v12
account/v25])
(def v31 [network/v1
bootnode/v4
extension/v12
account/v26])
(def v32 [network/v1
bootnode/v4
extension/v12
account/v27])
;; put schemas ordered by version
(def schemas [{:schema v1
:schemaVersion 1
:migration migrations/v1}
{:schema v2
:schemaVersion 2
:migration migrations/v2}
{:schema v3
:schemaVersion 3
:migration migrations/v3}
{:schema v4
:schemaVersion 4
:migration migrations/v4}
{:schema v5
:schemaVersion 5
:migration migrations/v5}
{:schema v6
:schemaVersion 6
:migration migrations/v6}
{:schema v7
:schemaVersion 7
:migration migrations/v7}
{:schema v8
:schemaVersion 8
:migration migrations/v8}
{:schema v9
:schemaVersion 9
:migration migrations/v9}
{:schema v10
:schemaVersion 10
:migration migrations/v10}
{:schema v11
:schemaVersion 11
:migration migrations/v11}
{:schema v12
:schemaVersion 12
:migration migrations/v12}
{:schema v13
:schemaVersion 13
:migration migrations/v13}
{:schema v14
:schemaVersion 14
:migration migrations/v14}
{:schema v15
:schemaVersion 15
:migration migrations/v15}
{:schema v16
:schemaVersion 16
:migration migrations/v16}
{:schema v17
:schemaVersion 17
:migration migrations/v17}
{:schema v18
:schemaVersion 18
:migration migrations/v18}
{:schema v19
:schemaVersion 19
:migration migrations/v19}
{:schema v20
:schemaVersion 20
:migration migrations/v20}
{:schema v21
:schemaVersion 21
:migration migrations/v21}
{:schema v22
:schemaVersion 22
:migration (constantly nil)}
{:schema v23
:schemaVersion 23
:migration (constantly nil)}
{:schema v24
:schemaVersion 24
:migration migrations/v24}
{:schema v25
:schemaVersion 25
:migration (constantly nil)}
{:schema v26
:schemaVersion 26
:migration (constantly nil)}
{:schema v27
:schemaVersion 27
:migration (constantly nil)}
{:schema v28
:schemaVersion 28
:migration (constantly nil)}
{:schema v29
:schemaVersion 29
:migration (constantly nil)}
{:schema v30
:schemaVersion 30
:migration (constantly nil)}
{:schema v31
:schemaVersion 31
:migration (constantly nil)}
{:schema v32
:schemaVersion 32
:migration (constantly nil)}])

View File

@ -1,11 +0,0 @@
(ns status-im.data-store.realm.schemas.base.extension)
(def v12 {:name :extension
:primaryKey :id
:properties {:id :string
:name {:type :string}
:url {:type :string}
:active? {:type :bool
:default true}
:data {:type :string
:optional true}}})

View File

@ -1,230 +0,0 @@
(ns status-im.data-store.realm.schemas.base.migrations
(:require [taoensso.timbre :as log]
[cognitect.transit :as transit]
[clojure.set :as set]
[clojure.string :as string]
[status-im.constants :as constants]
[status-im.utils.random :as random]))
(def reader (transit/reader :json))
(def writer (transit/writer :json))
(defn serialize [o] (transit/write writer o))
(defn deserialize [o] (try (transit/read reader o) (catch :default e nil)))
(defn v1 [old-realm new-realm]
(log/debug "migrating base database v1: " old-realm new-realm))
(defn v2 [old-realm new-realm]
(log/debug "migrating base database v2: " old-realm new-realm))
(defn v3 [old-realm new-realm]
(log/debug "migrating base database v3: " old-realm new-realm))
(defn v4 [old-realm new-realm]
(log/debug "migrating base database v4: " old-realm new-realm))
(def removed-tokens-v5
#{:ATMChain :Centra :ROL})
(def removed-fiat-currencies
#{:bmd :bzd :gmd :gyd :kyd :lak :lrd :ltl :mkd :mnt :nio :sos :srd :yer})
(defn v5 [old-realm new-realm]
(log/debug "migrating accounts schema v4")
(let [accounts (.objects new-realm "account")]
(dotimes [i (.-length accounts)]
(let [account (aget accounts i)
old-settings (deserialize (aget account "settings"))
new-settings (-> old-settings
(update-in [:wallet :visible-tokens :mainnet]
#(set/difference % removed-tokens-v5))
(update-in [:wallet :currency]
#(if (removed-fiat-currencies %) :usd %)))
updated (serialize new-settings)]
(aset account "settings" updated)))))
(defn v6 [old-realm new-realm]
(log/debug "migrating base database v6: " old-realm new-realm))
(defn v7 [old-realm new-realm]
(log/debug "migrating base database v7: " old-realm new-realm))
(def removed-tokens-v8
#{:ATT})
(defn v8 [old-realm new-realm]
(log/debug "migrating accounts schema v8")
(let [accounts (.objects new-realm "account")]
(dotimes [i (.-length accounts)]
(let [account (aget accounts i)
old-settings (deserialize (aget account "settings"))
new-settings (-> old-settings
(update-in [:wallet :visible-tokens :testnet]
#(set/difference % removed-tokens-v8)))
updated (serialize new-settings)]
(aset account "settings" updated)))))
(defn v9 [old-realm new-realm]
(log/debug "migrating accounts schema v9")
(let [accounts (.objects new-realm "account")]
(dotimes [i (.-length accounts)]
(let [account (aget accounts i)
old-settings (deserialize (aget account "settings"))
new-settings (-> old-settings
(dissoc :wnode))
updated (serialize new-settings)]
(aset account "settings" updated)))))
(defn v10 [old-realm new-realm]
(log/debug "migrating base database v10: " old-realm new-realm))
(defn v11 [old-realm new-realm]
(log/debug "migrating accounts schema v11")
(let [accounts (.objects new-realm "account")]
(dotimes [i (.-length accounts)]
(let [account (aget accounts i)
old-installation-id (aget account "installation-id")
installation-id (random/guid)]
(when (string/blank? old-installation-id)
(aset account "installation-id" installation-id))))))
(defn v12 [old-realm new-realm]
(log/debug "migrating base database v12: " old-realm new-realm))
(defn v13 [old-realm new-realm]
(log/debug "migrating base database v13: " old-realm new-realm))
(defn v14
"Rename wnode to mailserver in account settings"
[old-realm new-realm]
(log/debug "migrating accounts schema v14")
(let [accounts (.objects new-realm "account")]
(dotimes [i (.-length accounts)]
(let [account (aget accounts i)
{:keys [wnode] :as old-settings} (deserialize (aget account "settings"))
new-settings (when wnode
(-> old-settings
(dissoc :wnode)
(assoc :mailserver wnode)))
updated (serialize new-settings)]
(aset account "settings" updated)))))
(defn v15 [old-realm new-realm]
(log/debug "migrating base database v15: " old-realm new-realm))
(defn v16 [old-realm new-realm]
(log/debug "migrating base database v16: " old-realm new-realm))
(defn v17 [old-realm new-realm]
(log/debug "migrating accounts schema v17")
(let [accounts (.objects new-realm "account")]
(dotimes [i (.-length accounts)]
(let [account (aget accounts i)
old-settings (deserialize (aget account "settings"))
new-settings (update-in old-settings [:wallet :visible-tokens :mainnet]
#(cond-> %
true (disj :BQX)
(contains? % :BQX) (conj :ETHOS)))
updated (serialize new-settings)]
(aset account "settings" updated)))))
;; transform inactive legacy network values into the current ones
(defn transition-rpc-url [rpc-url]
(case rpc-url
"https://mainnet.infura.io/z6GCTmjdP3FETEJmMBI4"
(get-in constants/mainnet-networks ["mainnet_rpc" :config :UpstreamConfig :URL])
"https://ropsten.infura.io/z6GCTmjdP3FETEJmMBI4"
(get-in constants/testnet-networks ["testnet_rpc" :config :UpstreamConfig :URL])
"https://rinkeby.infura.io/z6GCTmjdP3FETEJmMBI4"
(get-in constants/testnet-networks ["rinkeby_rpc" :config :UpstreamConfig :URL])
rpc-url))
(defn transition-poa-rpc-url [rpc-url]
(if (= "https://poa.infura.io" rpc-url)
(get-in constants/sidechain-networks ["poa_rpc" :config :UpstreamConfig :URL])
rpc-url))
(defn- update-rpc-url [network-js transition-func]
(let [old-config (js->clj
(.parse js/JSON
(aget network-js "config")))]
;; we only transition rpc networks
(when (get-in old-config ["UpstreamConfig" "Enabled"])
(let [new-config (update-in
old-config
["UpstreamConfig" "URL"]
transition-func)]
(aset network-js
"config"
(.stringify js/JSON (clj->js new-config)))))))
(defn- update-rpc-urls! [networks-js update-func]
(dotimes [i (.-length networks-js)]
(let [network-js (aget networks-js i)]
(update-func network-js))))
(defn- migrate-rpc-urls! [realm-js migrate-func]
(let [accounts (.objects realm-js "account")]
(dotimes [i (.-length accounts)]
(let [account (aget accounts i)
networks (aget account "networks")]
(migrate-func networks)
(aset account "networks" networks)))))
;; infura project id update
(defn- update-infura-project-id! [network-js]
(update-rpc-url network-js transition-rpc-url))
(defn- update-infura-project-ids! [networks-js]
(update-rpc-urls! networks-js update-infura-project-id!))
(defn- migrate-infura-project-ids! [realm-js]
(migrate-rpc-urls! realm-js update-infura-project-ids!))
;; poa network url update
(defn- update-poa-network-url! [network-js]
(update-rpc-url network-js transition-poa-rpc-url))
(defn- update-poa-network-urls! [networks-js]
(update-rpc-urls! networks-js update-poa-network-url!))
(defn- migrate-poa-network-urls! [realm-js]
(migrate-rpc-urls! realm-js update-poa-network-urls!))
(defn v18 [old-realm new-realm]
(log/debug "migrating accounts database v18: " old-realm new-realm)
(migrate-infura-project-ids! new-realm))
;; used to be v18 migration
(defn v19 [old-realm new-realm]
(log/debug "migrating base database v19: " old-realm new-realm))
(defn v20 [old-realm new-realm]
(log/debug "migrating accounts database v20: " old-realm new-realm)
;; Why is this function called twice?
;; We had to release a hotfix that didn't have v18 migration while we had nightlies
;; that already have it. so this `migrate-infura-project-ids!` went as
;; migration no. 18 in the release.
;;
;; Hence, we ended up with 2 branches where migration v18 meant different things:
;; - release 0.9.32-infura-hotfix: v18 means migration of Infura project IDs
;; - nightlies: v18 means empty migration but schema change
;;
;; To be able to migrate from both of these, we
;; (1) swapped migration v18 and v19 in the nigtlies (`develop` branch).
;; (2) create a migration v20 that applies Infura migration again.
;;
;; That way we can upgrade both of the paths:
;; - 0.9.32 that had v18 with Infura transition will apply both v19 and v20, where
;; v20 will be a no-op.
;; - nightlies that had v18 as an empty transition will apply the empty transition
;; v19 again, and migrate Infura IDs as v20.
(migrate-infura-project-ids! new-realm))
(defn v21 [old-realm new-realm]
(log/debug "migrating base database v21: " old-realm new-realm))
(defn v24 [old-realm new-realm]
(log/debug "migrating base database v24: " old-realm new-realm)
(migrate-poa-network-urls! new-realm))

View File

@ -1,11 +0,0 @@
(ns status-im.data-store.realm.schemas.base.network)
(def v1 {:name :network
:primaryKey :id
:properties {:id :string
:name {:type :string
:optional true}
:config {:type :string
:optional true}
:rpc-url {:type :string
:optional true}}})

View File

@ -62,7 +62,7 @@
normalized-address))
(defn get-default-account [accounts]
(some #(when (:default? %) %) accounts))
(some #(when (:wallet %) %) accounts))
(defn default-address [db]
(-> (get-in db [:multiaccount :accounts])
@ -99,7 +99,7 @@
(defn chain-keyword
[db]
(let [network-id (get-in db [:multiaccount :network])
network (get-in db [:multiaccount :networks network-id])]
network (get-in db [:multiaccount :networks/networks network-id])]
(network->chain-keyword network)))
(defn snt-symbol [db]

View File

@ -25,6 +25,7 @@
"eth_newFilter" {:subscription? true}
"eth_syncing" {}
"net_version" {}
"web3_clientVersion" {}
"shhext_enableInstallation" {}
"shhext_disableInstallation" {}
"shhext_getOurInstallations" {}
@ -57,7 +58,10 @@
"browsers_deleteBrowser" {}
"permissions_addDappPermissions" {}
"permissions_getDappPermissions" {}
"permissions_deleteDappPermissions" {}})
"permissions_deleteDappPermissions" {}
"settings_saveConfig" {}
"settings_getConfig" {}
"settings_saveNodeConfig" {}})
(defn call
[{:keys [method params on-success on-error] :as p}]

View File

@ -119,10 +119,14 @@
watched-transactions))))
(fx/defn add-transfer
"We determine a unique id for the transfer before adding it because some
transaction can contain multiple transfers and they would overwrite each other
in the transfer map if identified by hash"
[{:keys [db] :as cofx} {:keys [hash id] :as transfer} address]
(let [transfer-by-hash (get-in db [:wallet :accounts address :transactions hash])]
;;transfer-by-id (get-in db [:wallet :transaction id]) ;; TODO didn't found any usage of this
(when-let [unique-id (when (not= transfer transfer-by-hash) ;(or transfer-by-id)
(let [transfer-by-hash (get-in db [:wallet :accounts address :transactions hash])
transfer-by-id (get-in db [:wallet :accounts address :transactions id])]
(when-let [unique-id (when-not (or transfer-by-id
(= transfer transfer-by-hash))
(if (and transfer-by-hash
(not (= :pending
(:type transfer-by-hash))))

View File

@ -72,78 +72,16 @@
status-im.popover.core))
;; init module
(handlers/register-handler-fx
:init.ui/data-reset-accepted
(fn [cofx _]
{:init/reset-data nil}))
(handlers/register-handler-fx
:init.ui/multiaccount-data-reset-accepted
(fn [_ [_ address]]
{:init/reset-multiaccount-data address}))
(handlers/register-handler-fx
:init.ui/data-reset-cancelled
(fn [cofx [_ encryption-key]]
(init/initialize-app cofx encryption-key)))
(handlers/register-handler-fx
:init/app-started
(fn [cofx _]
(init/start-app cofx)))
(handlers/register-handler-fx
:init.callback/get-encryption-key-success
(fn [cofx [_ encryption-key]]
(init/initialize-app cofx encryption-key)))
(handlers/register-handler-fx
:init.callback/get-device-UUID-success
(fn [cofx [_ device-uuid]]
(init/set-device-uuid cofx device-uuid)))
(handlers/register-handler-fx
:init.callback/init-store-success
[(re-frame/inject-cofx :data-store/get-all-multiaccounts)]
(fn [cofx _]
(init/load-multiaccounts-and-initialize-views cofx)))
(handlers/register-handler-fx
:init.callback/init-store-error
(fn [cofx [_ encryption-key error]]
(init/handle-init-store-error cofx encryption-key)))
(defn multiaccount-change-success
[{:keys [db] :as cofx} [_ address nodes]]
(let [{:node/keys [status]} db]
(fx/merge
cofx
(when nodes
(fleet/set-nodes :eth.contract nodes))
(if (= status :started)
(multiaccounts.login/login)
(node/initialize (get-in db [:multiaccounts/login :address])))
(init/initialize-multiaccount address)
(mailserver/initialize-ranges))))
(handlers/register-handler-fx
:init.callback/multiaccount-change-success
[(re-frame/inject-cofx :web3/get-web3)
(re-frame/inject-cofx :data-store/get-all-installations)
(re-frame/inject-cofx :data-store/all-chat-requests-ranges)]
multiaccount-change-success)
(handlers/register-handler-fx
:init.callback/keychain-reset
(fn [cofx _]
(init/initialize-keychain cofx)))
(handlers/register-handler-fx
:init.callback/multiaccount-db-removed
(fn [{:keys [db]} _]
{:db (assoc-in db [:multiaccounts/login :processing] false)}))
;; home screen
(handlers/register-handler-fx
@ -182,7 +120,7 @@
(handlers/register-handler-fx
:multiaccounts.ui/chaos-mode-switched
(fn [{:keys [db] :as cofx} [_ chaos-mode?]]
(let [old-chaos-mode? (get-in db [:multiaccount :settings :chaos-mode?])]
(let [old-chaos-mode? (get-in db [:multiaccount :chaos-mode?])]
(fx/merge
cofx
(when (and chaos-mode?
@ -244,35 +182,6 @@
(fn [cofx _]
(multiaccounts/confirm-wallet-set-up cofx)))
;; multiaccounts create module
(handlers/register-handler-fx
:multiaccounts.create.ui/next-step-pressed
[(re-frame/inject-cofx :random-guid-generator)]
(fn [cofx [_ step password password-confirm]]
(multiaccounts.create/next-step cofx step password password-confirm)))
(handlers/register-handler-fx
:multiaccounts.create.ui/step-back-pressed
(fn [cofx [_ step password password-confirm]]
(multiaccounts.create/step-back cofx step)))
(handlers/register-handler-fx
:multiaccounts.create.ui/input-text-changed
(fn [cofx [_ input-key text]]
(multiaccounts.create/multiaccount-set-input-text cofx input-key text)))
(defn get-selected-multiaccount [{:keys [db]}]
(let [{:keys [selected-id multiaccounts]} (:intro-wizard db)]
(some #(when (= selected-id (:id %)) %) multiaccounts)))
(handlers/register-handler-fx
:multiaccounts.create.callback/create-multiaccount-success
[(re-frame/inject-cofx :random-guid-generator)
(re-frame/inject-cofx :multiaccounts.create/get-signing-phrase)]
(fn [cofx [_ password]]
(multiaccounts.create/on-multiaccount-created cofx (get-selected-multiaccount cofx) password {:seed-backed-up? false})))
;; multiaccounts recover module
(handlers/register-handler-fx
@ -308,21 +217,10 @@
(multiaccounts.recover/recover-multiaccount cofx)))
;; multiaccounts login module
(handlers/register-handler-fx
:multiaccounts.login.callback/verify-success
(fn [cofx [_ verify-result realm-error]]
(multiaccounts.login/verify-callback cofx verify-result realm-error)))
(handlers/register-handler-fx
:init.callback/multiaccount-change-error
(fn [cofx [_ error]]
(multiaccounts.login/handle-change-multiaccount-error cofx error)))
(handlers/register-handler-fx
:multiaccounts.login.ui/multiaccount-selected
(fn [cofx [_ address photo-path name public-key accounts]]
(multiaccounts.login/open-login cofx address photo-path name public-key accounts)))
(fn [cofx [_ address photo-path name public-key]]
(multiaccounts.login/open-login cofx address photo-path name public-key)))
(handlers/register-handler-fx
:multiaccounts.login.callback/get-user-password-success
@ -344,12 +242,6 @@
(fn [cofx _]
(multiaccounts.logout/logout cofx)))
(handlers/register-handler-fx
:multiaccounts.logout/filters-removed
[(re-frame/inject-cofx :data-store/get-all-multiaccounts)]
(fn [cofx]
(multiaccounts.logout/leave-multiaccount cofx)))
;; multiaccounts update module
(handlers/register-handler-fx
@ -803,7 +695,9 @@
(fn [{{:keys [current-chat-id multiaccount]} :db :as cofx} [_ {:keys [hash] :as sticker}]]
(fx/merge
cofx
(multiaccounts/update-recent-stickers (conj (remove #(= hash %) (:recent-stickers multiaccount)) hash))
(multiaccounts.update/multiaccount-update
{:stickers/recent-stickers (conj (remove #(= hash %) (:recent-stickers multiaccount)) hash)}
{})
(chat.input/send-sticker-fx sticker current-chat-id))))
(handlers/register-handler-fx
@ -958,7 +852,7 @@
(handlers/register-handler-fx
:hardwallet.callback/on-generate-and-load-key-success
[(re-frame/inject-cofx :random-guid-generator)
(re-frame/inject-cofx :multiaccounts.create/get-signing-phrase)]
(re-frame/inject-cofx ::multiaccounts.create/get-signing-phrase)]
(fn [cofx [_ data]]
(hardwallet/on-generate-and-load-key-success cofx data)))

View File

@ -9,13 +9,8 @@
(:require-macros [status-im.utils.slurp :refer [slurp]]))
(defn current-fleet
([db]
(current-fleet db nil))
([db address]
(keyword (or (if address
(get-in db [:multiaccounts/multiaccounts address :settings :fleet])
(get-in db [:multiaccount :settings :fleet]))
config/fleet))))
[db]
(keyword (get-in db [:multiaccount :settings :fleet] config/fleet)))
(defn current-fleet-sub [settings]
(keyword (or (get settings :fleet)

View File

@ -5,7 +5,6 @@
[status-im.multiaccounts.login.core :as multiaccounts.login]
[status-im.multiaccounts.logout.core :as multiaccounts.logout]
[status-im.multiaccounts.recover.core :as multiaccounts.recover]
[status-im.data-store.multiaccounts :as multiaccounts-store]
[status-im.ethereum.core :as ethereum]
[status-im.ethereum.mnemonic :as mnemonic]
[status-im.i18n :as i18n]
@ -20,7 +19,8 @@
[taoensso.timbre :as log]
status-im.hardwallet.fx
[status-im.ui.components.react :as react]
[status-im.constants :as constants]))
[status-im.constants :as constants]
[status-im.multiaccounts.update.core :as multiaccounts.update]))
(def default-pin "000000")
@ -79,15 +79,12 @@
(navigation/navigate-back))))))
(fx/defn remove-pairing-from-multiaccount
[{:keys [db]} {:keys [remove-instance-uid?]}]
(let [multiaccount (cond-> (:multiaccount db)
true (assoc :keycard-pairing nil
:keycard-paired-on nil)
remove-instance-uid? (assoc :keycard-instance-uid nil))]
{:db (-> db
(assoc :multiaccount multiaccount)
(assoc-in [:multiaccounts/multiaccounts (:address multiaccount)] multiaccount))
:data-store/base-tx [(multiaccounts-store/save-multiaccount-tx multiaccount)]}))
[cofx {:keys [remove-instance-uid?]}]
(multiaccounts.update/multiaccount-update cofx
(cond-> {:keycard-pairing nil
:keycard-paired-on nil}
remove-instance-uid? (assoc :keycard-instance-uid nil))
{}))
(defn hardwallet-supported? [{:keys [db]}]
(and config/hardwallet-enabled?
@ -429,7 +426,7 @@
(fx/defn password-option-pressed
[{:keys [db] :as cofx}]
(if (= (get-in db [:hardwallet :flow]) :create)
(multiaccounts.create/navigate-to-create-multiaccount-screen cofx)
#() ;;TODO with v1 flow
(multiaccounts.recover/navigate-to-recover-multiaccount-screen cofx)))
(defn settings-screen-did-load
@ -794,7 +791,7 @@
(assoc-in [:hardwallet :pin] {:status nil
:error-label nil
:on-verified nil}))
:data-store/base-tx [(multiaccounts-store/delete-multiaccount-tx multiaccount-address)]
;;FIXME delete multiaccount
:utils/show-popup {:title ""
:content (i18n/label :t/card-reseted)}}
(multiaccounts.logout/logout))))
@ -826,7 +823,7 @@
(assoc-in [:hardwallet :pin] {:status nil
:error-label nil
:on-verified nil}))
:data-store/base-tx [(multiaccounts-store/delete-multiaccount-tx multiaccount-address)]
;;FIXME delete multiaccount
:utils/show-popup {:title ""
:content (i18n/label :t/card-reseted)}}
@ -1417,13 +1414,11 @@
(def on-init-card-error on-install-applet-and-init-card-error)
(fx/defn set-multiaccount-pairing
[{:keys [db]} {:keys [address] :as multiaccount} pairing paired-on]
(let [multiaccount (assoc multiaccount :keycard-pairing pairing
:keycard-paired-on paired-on)]
{:db (-> db
(assoc :multiaccount multiaccount)
(assoc-in [:multiaccounts/multiaccounts address] multiaccount))
:data-store/base-tx [(multiaccounts-store/save-multiaccount-tx multiaccount)]}))
[{:keys [db] :as cofx} {:keys [address] :as multiaccount} pairing paired-on]
(multiaccounts.update/multiaccount-update cofx
{:keycard-pairing pairing
:keycard-paired-on paired-on}
{}))
(fx/defn on-pair-success
[{:keys [db] :as cofx} pairing]
@ -1575,8 +1570,7 @@
instance-uid
key-uid]} multiaccount
{:keys [pairing paired-on]} secrets]
(fx/merge (-> cofx
(multiaccounts.create/get-signing-phrase))
(fx/merge cofx
{:db (assoc-in db [:hardwallet :setup-step] nil)}
(multiaccounts.create/on-multiaccount-created
{:derived {constants/path-whisper-keyword {:publicKey whisper-public-key
@ -1612,14 +1606,10 @@
(assoc-in [:hardwallet :on-card-connected] nil)
(update :hardwallet dissoc :recovery-phrase)
(update-in [:hardwallet :secrets] dissoc :pin :puk :password)
(assoc :node/on-ready :create-keycard-multiaccount)
(assoc :multiaccounts/new-installation-id (random-guid-generator))
(update-in [:hardwallet :secrets] dissoc :mnemonic))}
(if node-started?
(create-keycard-multiaccount)
(node/initialize nil))
(when (and (not node-started?)
(not= flow :import))
(create-keycard-multiaccount)
(when-not (= flow :import)
(navigation/navigate-to-cofx :keycard-welcome nil)))))
(fx/defn on-generate-and-load-key-error
@ -1633,9 +1623,8 @@
(fx/defn on-get-keys-success
[{:keys [db] :as cofx} data]
(let [{:keys [wallet-address whisper-address encryption-public-key] :as account-data} (js->clj data :keywordize-keys true)
address whisper-address
{:keys [photo-path name]} (get-in db [:multiaccounts/multiaccounts address])
(let [{:keys [wallet-address whisper-address encryption-public-key whisper-private-key] :as account-data} (js->clj data :keywordize-keys true)
{:keys [photo-path name]} (get-in db [:multiaccounts/multiaccounts whisper-address])
instance-uid (get-in db [:hardwallet :application-info :instance-uid])]
(fx/merge cofx
{:db (-> db
@ -1645,11 +1634,13 @@
(assoc-in [:hardwallet :flow] nil)
(update :multiaccounts/login assoc
:password encryption-public-key
:address address
:address whisper-address
:photo-path photo-path
:name name))
:hardwallet/get-application-info {:pairing (get-pairing db instance-uid)}}
(multiaccounts.login/user-login true))))
:hardwallet/get-application-info {:pairing (get-pairing db instance-uid)}
:hardwallet/login-with-keycard {:whisper-private-key whisper-private-key
:encryption-public-key encryption-public-key
:on-result #(re-frame/dispatch [:multiaccounts.login.callback/login-success %])}})))
(fx/defn on-get-keys-error
[{:keys [db] :as cofx} error]

View File

@ -1,90 +1,34 @@
(ns status-im.init.core
(:require [re-frame.core :as re-frame]
[status-im.multiaccounts.login.core :as multiaccounts.login]
[status-im.multiaccounts.update.core :as multiaccounts.update]
[status-im.browser.core :as browser]
[status-im.chat.models :as chat-model]
[status-im.contact.core :as contact]
[status-im.biometric-auth.core :as biometric-auth]
[status-im.data-store.core :as data-store]
[status-im.data-store.realm.core :as realm]
[status-im.ethereum.core :as ethereum]
[status-im.extensions.module :as extensions.module]
[status-im.i18n :as i18n]
[status-im.models.dev-server :as models.dev-server]
[status-im.multiaccounts.login.core :as multiaccounts.login]
[status-im.native-module.core :as status]
[status-im.notifications.core :as notifications]
[status-im.pairing.core :as pairing]
[status-im.react-native.js-dependencies :as rn-dependencies]
[status-im.stickers.core :as stickers]
[status-im.ui.screens.db :refer [app-db]]
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.fx :as fx]
[status-im.utils.keychain.core :as keychain]
[status-im.utils.platform :as platform]
[status-im.biometric-auth.core :as biometric-auth]
[taoensso.timbre :as log]))
(defn init-store!
"Try to decrypt the database, move on if successful otherwise go back to
initial state"
[encryption-key]
(.. (data-store/init encryption-key)
(then #(re-frame/dispatch [:init.callback/init-store-success]))
(catch (fn [error]
(log/warn "Could not decrypt database" error)
(re-frame/dispatch [:init.callback/init-store-error encryption-key])))))
[status-im.utils.platform :as platform]))
(defn restore-native-settings! []
(when platform/desktop?
(.getValue rn-dependencies/desktop-config "logging_enabled"
#(re-frame/dispatch [:set-in [:desktop/desktop :logging-enabled]
(if (boolean? %1)
%1 (cljs.reader/read-string %1))]))))
;; TODO (yenda) move keychain functions to dedicated namespace
(defn reset-keychain! []
(.. (keychain/reset)
(then
#(re-frame/dispatch [:init.callback/keychain-reset]))))
(defn reset-data! []
(.. (realm/delete-realms)
(then reset-keychain!)
(catch reset-keychain!)))
(defn reset-multiaccount-data! [address]
(let [callback #(re-frame/dispatch [:init.callback/multiaccount-db-removed])]
(.. (realm/delete-multiaccount-realm address)
(then callback)
(catch callback))))
(fx/defn initialize-keychain
"Entrypoint, fetches the key from the keychain and initialize the app"
[cofx]
{:keychain/get-encryption-key [:init.callback/get-encryption-key-success]})
(fx/defn start-app [cofx]
(fx/merge cofx
{:init/get-device-UUID nil
:init/get-supported-biometric-auth nil
:init/init-keystore nil
:init/restore-native-settings nil
:ui/listen-to-window-dimensions-change nil
:notifications/init nil
:network/listen-to-network-status nil
:network/listen-to-connection-status nil
:hardwallet/register-card-events nil}
(initialize-keychain)))
(if (boolean? %)
%
(cljs.reader/read-string %))]))))
(fx/defn initialize-app-db
"Initialize db to initial state"
[{{:keys [view-id hardwallet
[{{:keys [view-id hardwallet :multiaccounts/multiaccounts
initial-props desktop/desktop
network-status network peers-count peers-summary device-UUID
supported-biometric-auth push-notifications/stored network/type]
:node/keys [status]
:or {network (get app-db :network)}} :db}]
{:db (assoc app-db
:multiaccounts/multiaccounts multiaccounts
:contacts/contacts {}
:initial-props initial-props
:desktop/desktop (merge desktop (:desktop/desktop app-db))
@ -100,14 +44,6 @@
:view-id view-id
:push-notifications/stored stored)})
(fx/defn initialize-app
[cofx encryption-key]
(fx/merge cofx
{:init/init-store encryption-key
:hardwallet/check-nfc-support nil
:hardwallet/check-nfc-enabled nil}
(initialize-app-db)))
(fx/defn set-device-uuid
[{:keys [db]} device-uuid]
{:db (assoc db :device-UUID device-uuid)})
@ -117,24 +53,6 @@
[{:keys [db]} supported-biometric-auth]
{:db (assoc db :supported-biometric-auth supported-biometric-auth)})
(fx/defn handle-init-store-error
[encryption-key cofx]
{:ui/show-confirmation
{:title (i18n/label :decryption-failed-title)
:content (i18n/label :decryption-failed-content)
:confirm-button-text (i18n/label :decryption-failed-confirm)
;; On cancel we initialize the app with the same key, in case the error was
;; not related/fs error
:on-cancel #(re-frame/dispatch [:init.ui/data-reset-cancelled encryption-key])
:on-accept #(re-frame/dispatch [:init.ui/data-reset-accepted])}})
(fx/defn load-multiaccounts [{:keys [db all-multiaccounts]}]
(let [multiaccounts (->> all-multiaccounts
(map (fn [{:keys [address] :as multiaccount}]
[address multiaccount]))
(into {}))]
{:db (assoc db :multiaccounts/multiaccounts multiaccounts)}))
(fx/defn initialize-views
[cofx]
(let [{{:multiaccounts/keys [multiaccounts] :as db} :db} cofx]
@ -152,131 +70,57 @@
(:public-key multiaccount)))
%)
#(sort-by :last-sign-in > %))
{:keys [address public-key photo-path name accounts]} (first (selection-fn (vals multiaccounts)))]
(multiaccounts.login/open-login cofx address photo-path name public-key accounts)))))
{:keys [address public-key photo-path name]} (first (selection-fn (vals multiaccounts)))]
(multiaccounts.login/open-login cofx address photo-path name public-key)))))
(fx/defn load-multiaccounts-and-initialize-views
"DB has been decrypted, load multiaccounts and initialize-view"
[cofx]
(fx/merge cofx
(load-multiaccounts)
(initialize-views)))
(fx/defn initialize-multiaccount-db [{:keys [db web3]} address]
(let [{:universal-links/keys [url]
:keys [multiaccounts/multiaccounts multiaccounts/create networks/networks network
network-status peers-count peers-summary view-id navigation-stack
mailserver/mailservers
intro-wizard
desktop/desktop hardwallet custom-fleets supported-biometric-auth
device-UUID semaphores multiaccounts/login]
:node/keys [status on-ready]
:or {network (get app-db :network)}} db
current-multiaccount (get multiaccounts address)
multiaccount-network-id (get current-multiaccount :network network)
multiaccount-network (get-in current-multiaccount [:networks multiaccount-network-id])]
{:db (cond-> (assoc app-db
:view-id view-id
:navigation-stack navigation-stack
:node/status status
:intro-wizard intro-wizard
:node/on-ready on-ready
:multiaccounts/create create
:desktop/desktop (merge desktop (:desktop/desktop app-db))
:networks/networks networks
:multiaccount current-multiaccount
:multiaccounts/login login
:multiaccounts/multiaccounts multiaccounts
:mailserver/mailservers mailservers
:network-status network-status
:network multiaccount-network-id
:network/type (:network/type db)
:chain (ethereum/network->chain-name multiaccount-network)
:universal-links/url url
:custom-fleets custom-fleets
:peers-summary peers-summary
:peers-count peers-count
:device-UUID device-UUID
:supported-biometric-auth supported-biometric-auth
:semaphores semaphores
:hardwallet hardwallet
:web3 web3)
(= view-id :create-multiaccount)
(assoc-in [:multiaccounts/create :step] :enter-name))}))
(defn login-only-events [{:keys [db] :as cofx} address stored-pns]
(fx/merge cofx
(when-not (:intro-wizard db)
(cond-> {:notifications/request-notifications-permissions nil}
platform/ios?
;; on ios navigation state might be not initialized yet when
;; navigate-to call happens.
;; That's why it should be delayed a bit.
;; TODO(rasom): revisit this later and find better solution
(assoc :dispatch-later
[{:ms 1
:dispatch [:navigate-to :home]}])))
(when-not (or (:intro-wizard db) platform/ios?)
(navigation/navigate-to-cofx :home nil))
(notifications/process-stored-event address stored-pns)
(when platform/desktop?
(chat-model/update-dock-badge-label))))
(defn dev-mode? [cofx]
(get-in cofx [:db :multiaccount :dev-mode?]))
(defn creating-multiaccount? [cofx]
(= (get-in cofx [:db :view-id])
:create-multiaccount))
(defn recovering-multiaccount? [cofx]
(boolean (get-in cofx [:db :multiaccounts/recover])))
(defn- keycard-setup? [cofx]
(boolean (get-in cofx [:db :hardwallet :flow])))
(fx/defn initialize-multiaccount [{:keys [db] :as cofx} address]
(let [stored-pns (:push-notifications/stored db)]
(fx/defn initialize-multiaccounts
{:events [::initialize-multiaccounts]}
[{:keys [db] :as cofx} all-multiaccounts]
(let [multiaccounts (reduce (fn [acc {:keys [address] :as multiaccount}]
(assoc acc address multiaccount))
{}
all-multiaccounts)]
(fx/merge cofx
{:notifications/get-fcm-token nil}
(initialize-multiaccount-db address)
#(when (dev-mode? %)
(models.dev-server/start))
(extensions.module/initialize)
(stickers/init-stickers-packs)
(multiaccounts.update/update-sign-in-time)
#(when-not (or (creating-multiaccount? %)
(recovering-multiaccount? %)
(keycard-setup? %))
(login-only-events % address stored-pns)))))
{:db (assoc db :multiaccounts/multiaccounts multiaccounts)}
(initialize-views))))
(fx/defn start-app [cofx]
(fx/merge cofx
{::get-device-UUID nil
::get-supported-biometric-auth nil
::init-keystore nil
::restore-native-settings nil
::open-multiaccounts #(re-frame/dispatch [::initialize-multiaccounts %])
::data-store/init-store nil
:ui/listen-to-window-dimensions-change nil
:notifications/init nil
:network/listen-to-network-status nil
:network/listen-to-connection-status nil
:hardwallet/register-card-events nil
:hardwallet/check-nfc-support nil
:hardwallet/check-nfc-enabled nil}
(initialize-app-db)))
(re-frame/reg-fx
:init/init-store
init-store!)
(re-frame/reg-fx
:init/restore-native-settings
::restore-native-settings
restore-native-settings!)
(re-frame/reg-fx
:init/init-keystore
::open-multiaccounts
(fn [callback]
(status/open-accounts callback)))
(re-frame/reg-fx
::init-keystore
(fn []
(status/init-keystore)))
(re-frame/reg-fx
:init/get-device-UUID
::get-device-UUID
(fn []
(status/get-device-UUID #(re-frame/dispatch [:init.callback/get-device-UUID-success %]))))
(re-frame/reg-fx
:init/get-supported-biometric-auth
::get-supported-biometric-auth
(fn []
(biometric-auth/get-supported #(re-frame/dispatch [:init.callback/get-supported-biometric-auth-success %]))))
(re-frame/reg-fx
:init/reset-data
reset-data!)
(re-frame/reg-fx
:init/reset-multiaccount-data
reset-multiaccount-data!)

View File

@ -1069,10 +1069,15 @@
(fx/merge cofx
(multiaccounts.update/update-settings (assoc-in settings [:mailserver current-fleet] mailserver-id)
{}))))
(fx/defn ranges-loaded
{:events [::ranges-loaded]}
[{:keys [db]} ranges]
{:db (assoc db :mailserver/ranges ranges)})
(fx/defn initialize-ranges
[{:keys [:data-store/all-chat-requests-ranges db]}]
{:db (assoc db :mailserver/ranges all-chat-requests-ranges)})
[{:keys [db]}]
{::data-store.mailservers/all-chat-requests-ranges
#(re-frame/dispatch [::ranges-loaded %])})
(fx/defn load-gaps
[{:keys [db now :data-store/all-gaps]} chat-id]

View File

@ -8,10 +8,10 @@
[status-im.utils.build :as build]
[status-im.utils.config :as config]
[status-im.utils.fx :as fx]
[status-im.utils.handlers]
[status-im.utils.gfycat.core :as gfycat]
[status-im.utils.platform :as platform]
[status-im.utils.utils :as utils]
[status-im.utils.handlers :as handlers]))
[status-im.utils.utils :as utils]))
(defn displayed-name [account]
(let [name (or (:preferred-name account) (:name account))]
@ -48,7 +48,8 @@
(fx/defn confirm-wallet-set-up
[cofx]
(multiaccounts.update/multiaccount-update cofx {:wallet-set-up-passed? true} {}))
(multiaccounts.update/multiaccount-update cofx
{:wallet-set-up-passed? true} {}))
(fx/defn update-dev-server-state
[_ dev-mode?]
@ -75,12 +76,10 @@
(fx/defn switch-chaos-mode
[{:keys [db] :as cofx} chaos-mode?]
(when (:multiaccount db)
(let [settings (get-in db [:multiaccount :settings])]
(fx/merge cofx
{::chaos-mode-changed chaos-mode?}
(multiaccounts.update/update-settings
(assoc settings :chaos-mode? chaos-mode?)
{})))))
(fx/merge cofx
{::chaos-mode-changed chaos-mode?}
(multiaccounts.update/multiaccount-update {:chaos-mode? chaos-mode?}
{}))))
(fx/defn switch-biometric-auth
{:events [:multiaccounts.ui/switch-biometric-auth]}
@ -144,13 +143,3 @@
(multiaccounts.update/update-settings
(assoc settings :preview-privacy? private?)
{}))))
(fx/defn update-recent-stickers [cofx stickers]
(multiaccounts.update/multiaccount-update cofx
{:recent-stickers stickers}
{}))
(fx/defn update-stickers [cofx stickers]
(multiaccounts.update/multiaccount-update cofx
{:stickers stickers}
{}))

View File

@ -1,30 +1,25 @@
(ns status-im.multiaccounts.create.core
(:require [clojure.string :as string]
(:require [clojure.set :refer [map-invert]]
[clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.multiaccounts.core :as multiaccounts.core]
[status-im.multiaccounts.login.core :as multiaccounts.login]
[status-im.multiaccounts.update.core :as multiaccounts.update]
[status-im.constants :as constants]
[status-im.data-store.multiaccounts :as multiaccounts-store]
[status-im.i18n :as i18n]
[status-im.multiaccounts.update.core :as multiaccounts.update]
[status-im.native-module.core :as status]
[status-im.node.core :as node]
[status-im.ui.components.colors :as colors]
[status-im.ui.screens.mobile-network-settings.events :as mobile-network]
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.config :as config]
[status-im.utils.random :as random]
[status-im.utils.fx :as fx]
[status-im.utils.gfycat.core :as gfycat]
[status-im.utils.hex :as utils.hex]
[status-im.utils.identicon :as identicon]
[status-im.utils.platform :as platform]
[status-im.utils.random :as random]
[status-im.utils.security :as security]
[status-im.utils.signing-phrase.core :as signing-phrase]
[status-im.utils.types :as types]
[status-im.utils.utils :as utils]
[clojure.set :refer [map-invert]]
[status-im.utils.fx :as fx]
[status-im.node.core :as node]
[status-im.ui.screens.mobile-network-settings.events :as mobile-network]
[status-im.utils.platform :as platform]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.ui.components.colors :as colors]
[status-im.ethereum.core :as ethereum]))
[taoensso.timbre :as log]))
(defn get-signing-phrase [cofx]
(assoc cofx :signing-phrase (signing-phrase/generate)))
@ -46,95 +41,16 @@
(let [inverted (map-invert step-kw-to-num)]
(inverted (inc (step-kw-to-num step)))))
(defn create-multiaccount! [{:keys [id password]}]
(if id
(do
;(status/multiaccount-store-account id password #()) ;; TODO if i add this, i'm unable to login after
(status/multiaccount-store-derived
id
[constants/path-whisper constants/path-default-wallet]
password
#(re-frame/dispatch [:multiaccounts.create.callback/create-multiaccount-success password])))
(status/create-multiaccount
password
#(re-frame/dispatch [:multiaccounts.create.callback/create-multiaccount-success (types/json->clj %) password]))))
;; multiaccounts create module
(defn get-selected-multiaccount [{:keys [db]}]
(let [{:keys [selected-id multiaccounts]} (:intro-wizard db)]
(some #(when (= selected-id (:id %)) %) multiaccounts)))
(defn create-multiaccount
[{:keys [db] :as cofx}]
(if (:intro-wizard db)
(let [{:keys [selected-id key-code]} (:intro-wizard db)]
(fx/merge
cofx
{:multiaccounts.create/create-multiaccount {:id selected-id
:password (get-in db [:multiaccounts/create :password] key-code)}}))
(fx/merge
cofx
{:db (-> db
(update :multiaccounts/create assoc
:id (get-in db [:intro-wizard :selected-id])
:password (or (get-in db [:multiaccounts/create :password])
(get-in db [:intro-wizard :key-code]))
:step :multiaccount-creating
:error nil)
(assoc :node/on-ready :create-multiaccount
:multiaccounts/new-installation-id (random/guid)))}
(node/initialize nil))))
(fx/defn add-multiaccount
"Takes db and new multiaccount, creates map of effects describing adding multiaccount to database and realm"
[cofx {:keys [address] :as multiaccount}]
(let [db (:db cofx)]
{:db (assoc-in db [:multiaccounts/multiaccounts address] multiaccount)
:data-store/base-tx [(multiaccounts-store/save-multiaccount-tx multiaccount)]}))
(defn reset-multiaccount-creation [{db :db}]
{:db (update db :multiaccounts/create assoc
:step :enter-password
:password nil
:password-confirm nil
:error nil)})
(fx/defn multiaccount-set-input-text
[{db :db} input-key text]
{:db (update db :multiaccounts/create merge {input-key text :error nil})})
(defn multiaccount-set-name
[{{:multiaccounts/keys [create] :as db} :db now :now :as cofx}]
(fx/merge cofx
{:db db
:notifications/request-notifications-permissions nil
:dispatch-n [[:navigate-to :home]
(when-not platform/desktop?
[:navigate-to :welcome])]}
;; We set last updated as we are actually changing a field,
;; unlike on recovery where the name is not set
(multiaccounts.update/multiaccount-update {:last-updated now
:name (:name create)} {})
(mobile-network/on-network-status-change)))
(fx/defn next-step
[{:keys [db] :as cofx} step password password-confirm]
(case step
:enter-password {:db (assoc-in db [:multiaccounts/create :step] :confirm-password)}
:confirm-password (if (= password password-confirm)
(create-multiaccount cofx)
{:db (assoc-in db [:multiaccounts/create :error] (i18n/label :t/password_error1))})
:enter-name (multiaccount-set-name cofx)))
(fx/defn step-back
[cofx step]
(case step
:enter-password (navigation/navigate-back cofx)
:confirm-password (reset-multiaccount-creation cofx)))
(fx/defn navigate-to-create-multiaccount-screen
(fx/defn create-multiaccount
[{:keys [db] :as cofx}]
(fx/merge cofx
{:db (update db :multiaccounts/create
#(-> %
(assoc :step :enter-password)
(dissoc :password :password-confirm :name :error)))}
(navigation/navigate-to-cofx :create-multiaccount nil)))
(let [{:keys [selected-id address key-code]} (:intro-wizard db)
{:keys [address]} (get-selected-multiaccount cofx)]
{::store-multiaccount [selected-id address key-code]}))
(fx/defn intro-wizard
{:events [:multiaccounts.create.ui/intro-wizard]}
@ -142,8 +58,7 @@
(fx/merge {:db (assoc db :intro-wizard {:step :generate-key
:weak-password? true
:encrypt-with-password? true
:first-time-setup? first-time-setup?}
:multiaccounts/new-installation-id (random/guid))}
:first-time-setup? first-time-setup?})}
(navigation/navigate-to-cofx :intro-wizard nil)))
(fx/defn intro-step-back
@ -222,62 +137,62 @@
:else {:db (assoc-in db [:intro-wizard :step]
(inc-step step))})))
(defn prepare-default-account [{:keys [publicKey address]}]
{:public-key publicKey
:address address
:color colors/blue
:default? true
:name "Status account"})
(defn prepare-subaccounts-data
[multiaccount]
[(let [{:keys [publicKey address]}
(get-in multiaccount [:derived constants/path-default-wallet-keyword])]
{:public-key publicKey
:address address
:color colors/blue
:wallet true
:path constants/path-default-wallet
:name "Status account"})
(let [{:keys [publicKey address]}
(get-in multiaccount [:derived constants/path-whisper-keyword])]
{:public-key publicKey
:address address
:path constants/path-whisper
:chat true})])
(fx/defn on-multiaccount-created
[{:keys [signing-phrase db] :as cofx}
{:keys [keycard-instance-uid keycard-key-uid keycard-pairing keycard-paired-on mnemonic] :as multiaccount}
[{:keys [signing-phrase random-guid-generator db] :as cofx}
{:keys [address publicKey keycard-instance-uid keycard-key-uid keycard-pairing keycard-paired-on mnemonic] :as multiaccount}
password
{:keys [seed-backed-up? login?] :or {login? true}}]
(let [{:keys [publicKey address]} (get-in multiaccount [:derived constants/path-whisper-keyword])
default-wallet-account (get-in multiaccount [:derived constants/path-default-wallet-keyword])
{:networks/keys [networks]} db
new-multiaccount {;;multiaccount
:root-address (:address multiaccount)
:public-key publicKey
:latest-derived-path 0
:installation-id (get-in db [:multiaccounts/new-installation-id]) ;;TODO why can't we generate it here?
:address address
:name (gfycat/generate-gfy publicKey)
:photo-path (identicon/identicon publicKey)
:network config/default-network
:networks networks
:accounts [(prepare-default-account
(get-in multiaccount [:derived constants/path-default-wallet-keyword]))]
;;multiaccount-settings
:signed-up? true ;; how account can be not signed?
:seed-backed-up? seed-backed-up?
:desktop-notifications? false
:signing-phrase signing-phrase
:mnemonic mnemonic
:settings (constants/default-multiaccount-settings)
:syncing-on-mobile-network? false
:remember-syncing-choice? false
;;keycard
:keycard-instance-uid keycard-instance-uid
:keycard-key-uid keycard-key-uid
:keycard-pairing keycard-pairing
:keycard-paired-on keycard-paired-on}]
(when-not (string/blank? publicKey)
(fx/merge cofx
{:db (assoc db :multiaccounts/login {:address address
:main-account (:address default-wallet-account)
:password password
:processing true})}
(add-multiaccount new-multiaccount)
(when login?
(multiaccounts.login/user-login true))
(when (and (:intro-wizard db)
(nil? keycard-key-uid))
(intro-step-forward {}))))))
(let [[wallet-account {:keys [public-key]} :as subaccounts-data] (prepare-subaccounts-data multiaccount)
name (gfycat/generate-gfy public-key)
photo-path (identicon/identicon public-key)
account-data {:name name :address address :photo-path photo-path}
new-multiaccount {:address address
:name name
:public-key public-key
:photo-path photo-path
:latest-derived-path 0
:accounts [wallet-account]
:installation-id (random-guid-generator)
:signing-phrase signing-phrase
:mnemonic mnemonic
:settings constants/default-multiaccount-settings
:network constants/default-network
:networks/networks constants/default-networks}
db (-> db
(assoc :multiaccounts/login {:address address
:name name
:photo-path photo-path
:password password
:creating? true
:processing true}
:multiaccount new-multiaccount))]
(fx/merge cofx
{:db (cond-> db
seed-backed-up?
(assoc-in [:multiaccount :seed-backed-up?] true))
::save-account-and-login [(types/clj->json account-data)
password
(node/get-new-config db)
(types/clj->json subaccounts-data)]}
(when (:intro-wizard db)
(intro-step-forward {})))))
(re-frame/reg-fx
:intro-wizard/start-onboarding
@ -340,10 +255,39 @@
:weak-password? (< (count new-key-code) 6))}))
(re-frame/reg-cofx
:multiaccounts.create/get-signing-phrase
::get-signing-phrase
(fn [cofx _]
(get-signing-phrase cofx)))
(fx/defn create-multiaccount-success
{:events [::store-multiaccount-success]
:interceptors [(re-frame/inject-cofx :random-guid-generator)
(re-frame/inject-cofx ::get-signing-phrase)]}
[cofx password]
(on-multiaccount-created cofx (get-selected-multiaccount cofx) password {:seed-backed-up? false}))
(re-frame/reg-fx
:multiaccounts.create/create-multiaccount
create-multiaccount!)
::store-multiaccount
(fn [[id address password]]
(status/multiaccount-store-account
id
(security/safe-unmask-data password)
(fn []
(status/multiaccount-load-account
address
password
(fn [value]
(let [{:keys [id]} (types/json->clj value)]
(status/multiaccount-store-derived
id
[constants/path-whisper constants/path-default-wallet]
password
#(re-frame/dispatch [::store-multiaccount-success password])))))))))
(re-frame/reg-fx
::save-account-and-login
(fn [[account-data password config subaccounts-data]]
(status/save-account-and-login account-data
(security/safe-unmask-data password)
config
subaccounts-data)))

View File

@ -20,9 +20,11 @@
(spec/def :multiaccount/signed-up? (spec/nilable boolean?))
(spec/def :multiaccount/last-updated (spec/nilable int?))
(spec/def :multiaccount/last-sign-in (spec/nilable int?))
(spec/def :multiaccount/timestamp (spec/nilable int?))
(spec/def :multiaccount/last-request (spec/nilable int?))
(spec/def :multiaccount/photo-path (spec/nilable string?))
(spec/def :multiaccount/debug? (spec/nilable boolean?))
(spec/def :multiaccount/chaos-mode? (spec/nilable boolean?))
(spec/def :multiaccount/network (spec/nilable string?))
(spec/def :multiaccount/networks (spec/nilable :networks/networks))
(spec/def :multiaccount/bootnodes (spec/nilable :bootnodes/bootnodes))
@ -44,32 +46,32 @@
(spec/def :multiaccount/keycard-pairing (spec/nilable string?))
(spec/def :multiaccount/keycard-paired-on (spec/nilable int?))
(spec/def :multiaccounts/multiaccount (spec/keys :req-un [:multiaccount/name :multiaccount/address :multiaccount/public-key
:multiaccount/photo-path :multiaccount/signing-phrase
:multiaccount/installation-id]
:opt-un [:multiaccount/debug? :multiaccount/last-updated
:multiaccount/email :multiaccount/signed-up? :multiaccount/network
:multiaccount/networks :multiaccount/settings :multiaccount/mailserver
:multiaccount/last-sign-in :multiaccount/sharing-usage-data? :multiaccount/dev-mode?
:multiaccount/seed-backed-up? :multiaccount/mnemonic :multiaccount/desktop-notifications?
:multiaccount/wallet-set-up-passed? :multiaccount/last-request
:multiaccount/bootnodes :multiaccount/extensions
:multiaccount/mainnet-warning-shown-version
:multiaccount/desktop-alpha-release-warning-shown?
:multiaccount/keycard-instance-uid
:multiaccount/keycard-key-uid
:multiaccount/keycard-pairing
:multiaccount/keycard-paired-on
:multiaccount/root-address
:multiaccount/accounts]))
(spec/def :multiaccount/multiaccount (spec/keys :opt-un [:multiaccount/name :multiaccount/address
:multiaccount/photo-path
:multiaccount/signing-phrase
:multiaccount/installation-id
:multiaccount/debug? :multiaccount/last-updated :multiaccount/public-key
:multiaccount/email :multiaccount/signed-up? :multiaccount/network
:multiaccount/networks :multiaccount/settings :multiaccount/mailserver
:multiaccount/last-sign-in :multiaccount/sharing-usage-data? :multiaccount/dev-mode?
:multiaccount/seed-backed-up? :multiaccount/mnemonic :multiaccount/desktop-notifications?
:multiaccount/chaos-mode?
:multiaccount/wallet-set-up-passed? :multiaccount/last-request
:multiaccount/bootnodes :multiaccount/extensions
:multiaccount/mainnet-warning-shown-version
:multiaccount/desktop-alpha-release-warning-shown?
:multiaccount/keycard-instance-uid
:multiaccount/keycard-key-uid
:multiaccount/keycard-pairing
:multiaccount/keycard-paired-on
:multiaccount/root-address
:multiaccount/accounts]))
(spec/def :multiaccounts/multiaccounts (spec/nilable (spec/map-of :multiaccount/address :multiaccounts/multiaccount)))
;;used during creating multiaccount
(spec/def :multiaccounts/create (spec/nilable map?))
;;used during recovering multiaccount
(spec/def :multiaccounts/recover (spec/nilable map?))
;;used during logging
(spec/def :multiaccounts/login (spec/nilable map?))
;;logged in multiaccount
(spec/def :multiaccount/multiaccount (spec/nilable :multiaccounts/multiaccount))
;;before login
(spec/def :multiaccounts/multiaccount (spec/keys :req-un [:multiaccount/name :multiaccount/address]
:opt-un [:multiaccount/timestamp]))
(spec/def :multiaccounts/multiaccounts (spec/nilable (spec/map-of :multiaccount/address :multiaccounts/multiaccount)))

View File

@ -1,19 +1,22 @@
(ns status-im.multiaccounts.login.core
(:require [re-frame.core :as re-frame]
[status-im.multiaccounts.model :as multiaccounts.model]
[status-im.biometric-auth.core :as biometric-auth]
[status-im.chaos-mode.core :as chaos-mode]
[status-im.data-store.core :as data-store]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.ethereum.subscriptions :as ethereum.subscriptions]
[status-im.chat.models :as chat-model]
[status-im.chat.models.loading :as chat.loading]
[status-im.constants :as constants]
[status-im.contact.core :as contact]
[status-im.ethereum.core :as ethereum]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.ethereum.transactions.core :as transactions]
[status-im.extensions.module :as extensions.module]
[status-im.fleet.core :as fleet]
[status-im.i18n :as i18n]
[status-im.native-module.core :as status]
[status-im.node.core :as node]
[status-im.protocol.core :as protocol]
[status-im.tribute-to-talk.core :as tribute-to-talk]
[status-im.notifications.core :as notifications]
[status-im.stickers.core :as stickers]
[status-im.ui.screens.db :refer [app-db]]
[status-im.ui.screens.mobile-network-settings.events :as mobile-network]
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.config :as config]
@ -22,12 +25,11 @@
[status-im.utils.keychain.core :as keychain]
[status-im.utils.platform :as platform]
[status-im.utils.security :as security]
[status-im.biometric-auth.core :as biometric-auth]
[status-im.utils.types :as types]
[status-im.utils.universal-links.core :as universal-links]
[status-im.wallet.core :as wallet]
[taoensso.timbre :as log]
[status-im.ethereum.core :as ethereum]))
[status-im.web3.core :as web3]
[taoensso.timbre :as log]))
(def rpc-endpoint "https://goerli.infura.io/v3/f315575765b14720b32382a61a89341a")
(def contract-address "0xfbf4c8e2B41fAfF8c616a0E49Fb4365a5355Ffaf")
@ -49,44 +51,7 @@
(resolve default-nodes)))))
(resolve default-nodes))))
(defn login! [address main-account password]
(status/login address password main-account [] #(re-frame/dispatch [:multiaccounts.login.callback/login-success %])))
(defn verify! [address password realm-error]
(status/verify address password
#(re-frame/dispatch
[:multiaccounts.login.callback/verify-success % realm-error])))
(defn clear-web-data! []
(status/clear-web-data))
(defn change-multiaccount! [address
password
create-database-if-not-exist?
current-fleet]
;; No matter what is the keychain we use, as checks are done on decrypting base
(.. (keychain/safe-get-encryption-key)
(then #(data-store/change-multiaccount address password % create-database-if-not-exist?))
(then #(js/Promise. (fn [resolve reject]
(if (contract-fleet? current-fleet)
(fetch-nodes current-fleet resolve reject)
(resolve)))))
(then (fn [nodes] (re-frame/dispatch [:init.callback/multiaccount-change-success address nodes])))
(catch (fn [error]
(log/warn "Could not change multiaccount" error)
;; If all else fails we fallback to showing initial error
(re-frame/dispatch [:init.callback/multiaccount-change-error error])))))
;;;; Handlers
(fx/defn login [cofx]
(if (get-in cofx [:db :hardwallet :multiaccount :whisper-private-key])
{:hardwallet/login-with-keycard (-> cofx
(get-in [:db :hardwallet :multiaccount])
(select-keys [:whisper-private-key :encryption-public-key])
(assoc :on-result #(re-frame/dispatch [:multiaccounts.login.callback/login-success %])))}
(let [{:keys [address password main-account]} (get-in cofx [:db :multiaccounts/login])]
{:multiaccounts.login/login [address main-account password]})))
(fx/defn initialize-wallet [cofx]
(fx/merge cofx
(wallet/initialize-tokens)
@ -94,51 +59,13 @@
(wallet/update-prices)
(transactions/initialize)))
(fx/defn user-login-without-creating-db
(fx/defn login
{:events [:multiaccounts.login.ui/password-input-submitted]}
[{:keys [db] :as cofx}]
(let [{:keys [address password]} (multiaccounts.model/credentials cofx)]
(fx/merge
cofx
{:db (-> db
(assoc-in [:multiaccounts/login :processing] true)
(assoc :node/on-ready :login))
:multiaccounts.login/clear-web-data nil
:data-store/change-multiaccount [address
password
false
(get-in db [:multiaccounts/multiaccounts address :settings :fleet])]})))
(fx/defn user-login
[{:keys [db] :as cofx} create-database?]
(let [{:keys [address password]} (multiaccounts.model/credentials cofx)]
(fx/merge
cofx
{:db (-> db
(assoc-in [:multiaccounts/login :processing] true)
(assoc :node/on-ready :login))
:multiaccounts.login/clear-web-data nil
:data-store/change-multiaccount [address
password
create-database?
(get-in db [:multiaccounts/multiaccounts address :settings :fleet])]})))
(fx/defn multiaccount-and-db-password-do-not-match
[{:keys [db] :as cofx} error]
(log/error "failed to login" error)
(fx/merge
cofx
{:db
(update db :multiaccounts/login assoc
:save-password? false
:error error
:processing false)
:utils/show-popup
{:title (i18n/label :multiaccount-and-db-password-mismatch-title)
:content (i18n/label :multiaccount-and-db-password-mismatch-content)}
:dispatch [:multiaccounts.logout.ui/logout-confirmed]}))
(let [{:keys [address password name photo-path]} (:multiaccounts/login db)]
{:db (assoc-in db [:multiaccounts/login :processing] true)
::login [(types/clj->json {:name name :address address :photo-path photo-path})
password]}))
(fx/defn finish-keycard-setup
[{:keys [db] :as cofx}]
@ -168,175 +95,150 @@
all-stored-browsers)]
{:db (assoc db :browser/browsers browsers)}))
(fx/defn user-login-callback
{:events [:multiaccounts.login.callback/login-success]
:interceptors [(re-frame/inject-cofx :web3/get-web3)
(re-frame/inject-cofx :data-store/get-all-mailservers)
(re-frame/inject-cofx :data-store/get-all-installations)
(re-frame/inject-cofx :data-store/transport)
(re-frame/inject-cofx :data-store/mailserver-topics)]}
[{:keys [db web3] :as cofx} login-result]
(let [data (types/json->clj login-result)
error (:error data)
success (empty? error)
{:keys [address password save-password?]}
(multiaccounts.model/credentials cofx)
network-type (:network/type db)]
;; check if logged into multiaccount
(when address
(if success
(fx/merge
cofx
{:db (-> db
(dissoc :multiaccounts/login)
(update :hardwallet dissoc
:on-card-read
:card-read-in-progress?
:pin
:multiaccount))
::json-rpc/call
[{:method "browsers_getBrowsers"
:on-success #(re-frame/dispatch [::initialize-browsers %])}
{:method "permissions_getDappPermissions"
:on-success #(re-frame/dispatch [::initialize-dapp-permissions %])}]
:web3/set-default-account [web3 address]
:web3/fetch-node-version [web3
#(re-frame/dispatch
[:web3/fetch-node-version-callback %])]}
(fn [_]
(when save-password?
{:keychain/save-user-password [address password]}))
(tribute-to-talk/init)
(mobile-network/on-network-status-change)
(protocol/initialize-protocol)
(chat.loading/initialize-chats {:to -1})
(contact/initialize-contacts)
(universal-links/process-stored-event)
(chaos-mode/check-chaos-mode)
(finish-keycard-setup)
(when-not platform/desktop?
(initialize-wallet)))
(multiaccount-and-db-password-do-not-match cofx error)))))
(fx/defn show-migration-error-dialog
[{:keys [db]} realm-error]
(let [{:keys [message]} realm-error
address (get-in db [:multiaccounts/login :address])
erase-button (i18n/label :migrations-erase-multiaccounts-data-button)]
{:ui/show-confirmation
{:title (i18n/label :invalid-key-title)
:content (i18n/label
:invalid-key-content
{:message message
:erase-multiaccounts-data-button-text erase-button})
:confirm-button-text (i18n/label :invalid-key-confirm)
:on-cancel #(re-frame/dispatch
[:init.ui/data-reset-cancelled ""])
:on-accept #(re-frame/dispatch
[:init.ui/multiaccount-data-reset-accepted address])}}))
(fx/defn verify-callback
[cofx verify-result realm-error]
(let [data (types/json->clj verify-result)
error (:error data)
success (empty? error)]
(fx/merge
cofx
{:node/stop nil}
(fn [{:keys [db] :as cofx}]
(if success
(case (:error realm-error)
:decryption-failed
(show-migration-error-dialog cofx realm-error)
:database-does-not-exist
(let [{:keys [address password]} (multiaccounts.model/credentials cofx)]
{:data-store/change-multiaccount [address
password
true
(get-in cofx
[:db
:multiaccounts/multiaccounts
address
:settings
:fleet])]}))
{:db (update db :multiaccounts/login assoc
:error error
:processing false)})))))
(fx/defn migrations-failed
[{:keys [db]} {:keys [realm-error erase-button]}]
(let [{:keys [message details]} realm-error
address (get-in db [:multiaccounts/login :address])]
{:ui/show-confirmation
{:title (i18n/label :migrations-failed-title)
:content (i18n/label
:migrations-failed-content
(merge
{:message message
:erase-multiaccounts-data-button-text erase-button}
details))
:confirm-button-text erase-button
:on-cancel #(re-frame/dispatch
[:init.ui/data-reset-cancelled ""])
:on-accept #(re-frame/dispatch
[:init.ui/multiaccount-data-reset-accepted address])}}))
(fx/defn verify-multiaccount
[{:keys [db] :as cofx} {:keys [realm-error]}]
(if (get-in db [:multiaccounts/recover])
(fx/defn get-config-callback
{:events [::get-config-callback]}
[{:keys [db] :as cofx} config stored-pns]
(let [{:keys [network networks/networks address] :as multiaccount} (types/deserialize config)]
(fx/merge cofx
{:db (-> db
(update :multiaccounts/recover assoc
:processing? false
:password ""
:password-confirmation ""
:password-error :recover-password-invalid)
(update :multiaccounts/recover dissoc
:password-valid?))
:node/stop nil}
(navigation/navigate-to-cofx :recover-multiaccount-enter-password nil))
{:db (assoc db
:network network
:networks/networks networks
:chain (ethereum/network->chain-name network)
:multiaccount multiaccount)
;;NOTE there is a callback that shows a mainnet alert after
;;this effect, and we need multiaccount data to know if it has
;;been shown already
:notifications/request-notifications-permissions nil}
(stickers/init-stickers-packs)
(mobile-network/on-network-status-change)
(chaos-mode/check-chaos-mode)
(when-not platform/desktop?
(initialize-wallet))
(when stored-pns
(notifications/process-stored-event address stored-pns)))))
(fx/defn initialize-multiaccount-db
[{:keys [db]} address]
(let [{:universal-links/keys [url]
:keys [network-status peers-count peers-summary view-id multiaccount
desktop/desktop hardwallet custom-fleets supported-biometric-auth
device-UUID semaphores intro-wizard]} db]
{:db (cond-> (assoc app-db
:view-id view-id
:node/status (:node/status db)
:desktop/desktop (merge desktop (:desktop/desktop app-db))
:network-status network-status
:network/type (:network/type db)
:universal-links/url url
:custom-fleets custom-fleets
:peers-summary peers-summary
:peers-count peers-count
:device-UUID device-UUID
:intro-wizard {:step (:step intro-wizard)}
:supported-biometric-auth supported-biometric-auth
:semaphores semaphores
:hardwallet hardwallet)
multiaccount (assoc :multiaccount multiaccount))}))
(fx/defn initialize-web3-client-version
{:events [::initialize-web3-client-version]}
[{:keys [db]} resp]
(if-let [node-version (second (re-find #"StatusIM/v(.*)/.*/.*" resp))]
{:db (assoc db :web3-node-version node-version)}
(log/warn (str "unexpected web3 version format: " "'" resp "'"))))
(fx/defn save-user-password
[cofx address password]
{:keychain/save-user-password [address password]})
(fx/defn login-only-events
[{:keys [db] :as cofx} address password save-password?]
(let [stored-pns (:push-notifications/stored db)]
(fx/merge cofx
{:db (assoc db :chats/loading? true)
::json-rpc/call
[{:method "browsers_getBrowsers"
:on-success #(re-frame/dispatch [::initialize-browsers %])}
{:method "permissions_getDappPermissions"
:on-success #(re-frame/dispatch [::initialize-dapp-permissions %])}
{:method "settings_getConfig"
:params ["multiaccount"]
:on-success #(re-frame/dispatch [::get-config-callback % stored-pns])}]}
(when save-password?
(save-user-password address password))
(navigation/navigate-to-cofx :home nil)
(stickers/init-stickers-packs)
(chat.loading/initialize-chats)
(contact/initialize-contacts)
(universal-links/process-stored-event)
(when platform/desktop?
(chat-model/update-dock-badge-label)))))
(defn- recovering-multiaccount? [cofx]
(boolean (get-in cofx [:db :multiaccounts/recover])))
(fx/defn create-only-events
[{:keys [db] :as cofx}]
(let [{:keys [multiaccount]} db]
(fx/merge cofx
{:db (assoc db
;;NOTE when login the filters are initialized twice
;;once for contacts and once for chats
;;when creating an account we do it only once by calling
;;load-filters directly because we don't have chats and contacts
;;later on there is a check that filters have been initialized twice
;;so here we set it at 1 already so that it passes the check once it has
;;been initialized
:filters/initialized 1
:network constants/default-network
:networks/networks constants/default-networks)
:filters/load-filters []
::json-rpc/call
[{:method "settings_saveConfig"
:params ["multiaccount" (types/serialize multiaccount)]
:on-success #()}]}
(finish-keycard-setup)
(mobile-network/on-network-status-change)
(chaos-mode/check-chaos-mode)
(when-not platform/desktop?
(initialize-wallet)))))
(defn- keycard-setup? [cofx]
(boolean (get-in cofx [:db :hardwallet :flow])))
(fx/defn multiaccount-login-success
[{:keys [db] :as cofx}]
(let [{:keys [address password save-password? name photo-path creating?]} (:multiaccounts/login db)
step (get-in db [:intro-wizard :step])
recovering? (recovering-multiaccount? cofx)
login-only? (not (or creating?
recovering?
(keycard-setup? cofx)))
nodes nil]
(fx/merge cofx
{:db (-> db
(assoc :node/on-ready :verify-multiaccount)
(assoc :realm-error realm-error))}
(node/initialize nil))))
(fx/defn unknown-realm-error
[cofx {:keys [realm-error erase-button]}]
(let [{:keys [message]} realm-error
{:keys [address]} (multiaccounts.model/credentials cofx)]
{:ui/show-confirmation
{:title (i18n/label :unknown-realm-error)
:content (i18n/label
:unknown-realm-error-content
{:message message
:erase-multiaccounts-data-button-text erase-button})
:confirm-button-text (i18n/label :invalid-key-confirm)
:on-cancel #(re-frame/dispatch
[:init.ui/data-reset-cancelled ""])
:on-accept #(re-frame/dispatch
[:init.ui/multiaccount-data-reset-accepted address])}}))
(fx/defn handle-change-multiaccount-error
[{:keys [db] :as cofx} error]
(let [{:keys [error] :as realm-error}
(if (map? error)
error
{:message (str error)})
erase-button (i18n/label :migrations-erase-multiaccounts-data-button)]
(fx/merge
cofx
{:db (assoc-in db [:multiaccounts/login :save-password?] false)}
(case error
:migrations-failed
(migrations-failed {:realm-error realm-error
:erase-button erase-button})
(:database-does-not-exist :decryption-failed)
(verify-multiaccount {:realm-error realm-error})
(unknown-realm-error {:realm-error realm-error
:erase-button erase-button})))))
(dissoc :multiaccounts/login)
(update :hardwallet dissoc
:on-card-read
:card-read-in-progress?
:pin
:multiaccount))
;;TODO remove once web3 has been replaced by json-rpc in protocol
;; after this call realm and the protocol are initialized as a callback
::web3/initialize [address password login-only?]
::json-rpc/call
[{:method "web3_clientVersion"
:on-success #(re-frame/dispatch [::initialize-web3-client-version %])}]
:notifications/get-fcm-token nil}
;;FIXME
(when nodes
(fleet/set-nodes :eth.contract nodes))
(initialize-multiaccount-db address)
(if login-only?
(login-only-events address password save-password?)
(create-only-events))
(when recovering?
(navigation/navigate-to-cofx :home nil)))))
(fx/defn open-keycard-login
[{:keys [db] :as cofx}]
@ -356,14 +258,14 @@
:keychain/get-user-password [address
#(re-frame/dispatch [:multiaccounts.login.callback/get-user-password-success % address])]})
(fx/defn open-login [{:keys [db] :as cofx} address photo-path name public-key accounts]
(fx/defn open-login
[{:keys [db] :as cofx} address photo-path name public-key]
(let [keycard-multiaccount? (get-in db [:multiaccounts/multiaccounts address :keycard-instance-uid])]
(fx/merge cofx
{:db (-> db
(update :multiaccounts/login assoc
:public-key public-key
:address address
:main-account (:address (ethereum/get-default-account accounts))
:photo-path photo-path
:name name)
(update :multiaccounts/login dissoc
@ -374,14 +276,14 @@
(get-user-password address)))))
(fx/defn open-login-callback
{:events [:multiaccounts.login.callback/biometric-auth-done]}
{:events [::biometric-auth-done]}
[{:keys [db] :as cofx} password {:keys [bioauth-success bioauth-notrequired bioauth-message]}]
(if (and password
(or bioauth-success bioauth-notrequired))
(fx/merge cofx
{:db (assoc-in db [:multiaccounts/login :password] password)}
(navigation/navigate-to-cofx :progress nil)
(user-login false))
login)
(fx/merge cofx
(when bioauth-message
{:utils/show-popup {:title (i18n/label :t/biometric-auth-login-error-title) :content bioauth-message}})
@ -390,28 +292,12 @@
(fx/defn do-biometric-auth
[{:keys [db] :as cofx} password]
(biometric-auth/authenticate-fx cofx
#(re-frame/dispatch [:multiaccounts.login.callback/biometric-auth-done password %])
#(re-frame/dispatch [::biometric-auth-done password %])
{:reason (i18n/label :t/biometric-auth-reason-login)
:ios-fallback-label (i18n/label :t/biometric-auth-login-ios-fallback-label)}))
(re-frame/reg-fx
:multiaccounts.login/login
(fn [[address main-account password]]
(login! address main-account (security/safe-unmask-data password))))
(re-frame/reg-fx
:multiaccounts.login/verify
(fn [[address password realm-error]]
(verify! address (security/safe-unmask-data password) realm-error)))
(re-frame/reg-fx
:multiaccounts.login/clear-web-data
clear-web-data!)
(re-frame/reg-fx
:data-store/change-multiaccount
(fn [[address password create-database-if-not-exist? current-fleet]]
(change-multiaccount! address
(security/safe-unmask-data password)
create-database-if-not-exist?
current-fleet)))
::login
(fn [[account-data password]]
(status/login account-data
(security/safe-unmask-data password))))

View File

@ -3,26 +3,23 @@
[status-im.chaos-mode.core :as chaos-mode]
[status-im.i18n :as i18n]
[status-im.init.core :as init]
[status-im.node.core :as node]
[status-im.native-module.core :as status]
[status-im.transport.core :as transport]
[status-im.utils.fx :as fx]))
[status-im.utils.fx :as fx]
[clojure.string :as string]))
(fx/defn logout
{:events [:logout]}
[{:keys [db] :as cofx}]
(fx/merge cofx
{:keychain/clear-user-password (get-in db [:multiaccount :address])
:dispatch [:multiaccounts.logout/filters-removed]
:dev-server/stop nil}
{::logout nil
:dev-server/stop nil
;;TODO sort out this mess with lower case addresses
:keychain/clear-user-password (string/lower-case (get-in db [:multiaccount :address]))
::init/open-multiaccounts #(re-frame/dispatch [::init/initialize-multiaccounts %])}
(transport/stop-whisper)
(chaos-mode/stop-checking)))
(fx/defn leave-multiaccount
[cofx]
(fx/merge
cofx
(init/initialize-app-db)
(init/load-multiaccounts-and-initialize-views)
(node/stop)))
(chaos-mode/stop-checking)
(init/initialize-app-db)))
(fx/defn show-logout-confirmation [_]
{:ui/show-confirmation
@ -31,3 +28,8 @@
:confirm-button-text (i18n/label :t/logout)
:on-accept #(re-frame/dispatch [:multiaccounts.logout.ui/logout-confirmed])
:on-cancel nil}})
(re-frame/reg-fx
::logout
(fn []
(status/logout)))

View File

@ -1,7 +1,4 @@
(ns status-im.multiaccounts.model
(:require [status-im.utils.security :as security]
[cljs.spec.alpha :as spec]
[clojure.string :as string]))
(ns status-im.multiaccounts.model)
(defn logged-in? [cofx]
(boolean
@ -10,17 +7,6 @@
(defn credentials [cofx]
(select-keys (get-in cofx [:db :multiaccounts/login]) [:address :password :save-password?]))
(defn multiaccount-creation-next-enabled?
[{:keys [step password password-confirm name]}]
(or (and password (= :enter-password step)
(spec/valid? :status-im.multiaccounts.db/password
(security/safe-unmask-data password)))
(and password-confirm
(= :confirm-password step)
(spec/valid? :status-im.multiaccounts.db/password
password-confirm))
(and name (= :enter-name step) (not (string/blank? name)))))
(defn current-public-key
[cofx]
(get-in cofx [:db :multiaccount :public-key]))

View File

@ -1,18 +1,16 @@
(ns status-im.multiaccounts.recover.core
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.multiaccounts.create.core :as multiaccounts.create]
[status-im.multiaccounts.db :as db]
[status-im.constants :as constants]
[status-im.ethereum.mnemonic :as mnemonic]
[status-im.i18n :as i18n]
[status-im.multiaccounts.create.core :as multiaccounts.create]
[status-im.multiaccounts.db :as db]
[status-im.native-module.core :as status]
[status-im.node.core :as node]
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.fx :as fx]
[status-im.utils.identicon :as identicon]
[status-im.utils.security :as security]
[status-im.utils.types :as types]
[status-im.constants :as constants]))
[status-im.utils.types :as types]))
(defn check-password-errors [password]
(cond (string/blank? password) :required-field
@ -91,16 +89,17 @@
:processing? false
:passphrase-error :recover-keycard-multiaccount-not-supported)
(update :multiaccounts/recover dissoc
:passphrase-valid?))
:node/stop nil}
:passphrase-valid?))}
(let [multiaccount' (assoc multiaccount :derived (get-in db [:multiaccounts/recover :derived]))]
(multiaccounts.create/on-multiaccount-created
cofx multiaccount' password {:seed-backed-up? true})))))
(multiaccounts.create/on-multiaccount-created cofx
multiaccount'
password
{:seed-backed-up? true})))))
(fx/defn on-multiaccount-recovered
{:events [:multiaccounts.recover.callback/recover-multiaccount-success]
:interceptors [(re-frame/inject-cofx :random-guid-generator)
(re-frame/inject-cofx :multiaccounts.create/get-signing-phrase)]}
(re-frame/inject-cofx ::multiaccounts.create/get-signing-phrase)]}
[cofx password]
(validate-recover-result cofx password))
@ -117,12 +116,10 @@
(fx/defn recover-multiaccount
[{:keys [db random-guid-generator] :as cofx}]
(let [{:keys [password passphrase]} (:multiaccounts/recover db)]
(fx/merge cofx
{:db (-> db
(assoc-in [:multiaccounts/recover :processing?] true)
(assoc :multiaccounts/new-installation-id (random-guid-generator)))
:multiaccounts.recover/recover-multiaccount
[(security/mask-data passphrase) password]})))
{:db (-> db
(assoc-in [:multiaccounts/recover :processing?] true)
(assoc :multiaccounts/new-installation-id (random-guid-generator)))
:multiaccounts.recover/recover-multiaccount [(security/mask-data passphrase) password]}))
(fx/defn recover-multiaccount-with-checks [{:keys [db] :as cofx}]
(let [{:keys [passphrase processing?]} (:multiaccounts/recover db)]
@ -195,37 +192,21 @@
:dispatch [:bottom-sheet/hide-sheet]}
(navigation/navigate-to-cofx :recover-multiaccount-enter-phrase nil)))
(fx/defn prepare-to-recover
[{:keys [db random-guid-generator] :as cofx}]
(fx/merge cofx
{:db (-> db
(assoc :node/on-ready :import-mnemonic)
(assoc :multiaccounts/new-installation-id (random-guid-generator)))}
(node/initialize nil)))
(fx/defn import-mnemonic
[{:keys [db]}]
(let [{:keys [password passphrase]} (:multiaccounts/recover db)]
{:multiaccounts.recover/import-mnemonic
{:passphrase passphrase
:password password}}))
(fx/defn proceed-to-import-mnemonic
[{:keys [db] :as cofx}]
(let [{:keys [passphrase]} (:multiaccounts/recover db)
node-started? (= :started (:node/status db))]
[{:keys [db random-guid-generator] :as cofx}]
(let [{:keys [password passphrase]} (:multiaccounts/recover db)]
(when (mnemonic/valid-length? passphrase)
(if node-started?
(import-mnemonic cofx)
(prepare-to-recover cofx)))))
(fx/merge cofx
{:db (assoc db :multiaccounts/new-installation-id (random-guid-generator))
:multiaccounts.recover/import-mnemonic {:passphrase passphrase
:password password}}))))
(fx/defn enter-phrase-next-button-pressed
{:events [:recover.enter-passphrase.ui/input-submitted
:recover.enter-passphrase.ui/next-pressed]
:interceptors [(re-frame/inject-cofx :random-guid-generator)]}
[{:keys [db] :as cofx}]
(fx/merge cofx
(proceed-to-import-mnemonic)))
(proceed-to-import-mnemonic cofx))
(fx/defn cancel-pressed
{:events [:recover.ui/cancel-pressed]}

View File

@ -1,12 +1,12 @@
(ns status-im.multiaccounts.update.core
(:require
[status-im.contact.db :as contact.db]
[status-im.contact.device-info :as device-info]
[status-im.data-store.multiaccounts :as multiaccounts-store]
[status-im.data-store.transport :as transport-store]
[status-im.transport.message.protocol :as protocol]
[status-im.transport.message.contact :as message.contact]
[status-im.utils.fx :as fx]))
(:require [status-im.contact.db :as contact.db]
[status-im.contact.device-info :as device-info]
[status-im.data-store.transport :as transport-store]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.transport.message.contact :as message.contact]
[status-im.transport.message.protocol :as protocol]
[status-im.utils.fx :as fx]
[status-im.utils.types :as types]))
(fx/defn multiaccount-update-message [{:keys [db] :as cofx}]
(let [multiaccount (:multiaccount db)
@ -52,17 +52,21 @@
(fx/defn multiaccount-update
"Takes effects (containing :db) + new multiaccount fields, adds all effects necessary for multiaccount update.
Optionally, one can specify a success-event to be dispatched after fields are persisted."
[{:keys [db] :as cofx} new-multiaccount-fields {:keys [success-event]}]
[{:keys [db] :as cofx}
new-multiaccount-fields
{:keys [on-success] :or {on-success #()}}]
(let [current-multiaccount (:multiaccount db)
new-multiaccount (merge current-multiaccount new-multiaccount-fields)
fx {:db (assoc db :multiaccount new-multiaccount)
:data-store/base-tx [{:transaction (multiaccounts-store/save-multiaccount-tx new-multiaccount)
:success-event success-event}]}
fx {:db (assoc db :multiaccount new-multiaccount)
::json-rpc/call
[{:method "settings_saveConfig"
:params ["multiaccount" (types/serialize new-multiaccount)]
:on-success on-success}]}
{:keys [name photo-path]} new-multiaccount-fields]
(if (or name photo-path)
(fx/merge cofx
fx
#(send-multiaccount-update %))
(send-multiaccount-update))
fx)))
(fx/defn clean-seed-phrase
@ -73,13 +77,13 @@
:mnemonic nil}
{}))
(fx/defn update-sign-in-time
[{db :db now :now :as cofx}]
(multiaccount-update cofx {:last-sign-in now} {}))
(fx/defn update-settings
[{{:keys [multiaccount] :as db} :db :as cofx} settings {:keys [success-event]}]
[{{:keys [multiaccount] :as db} :db :as cofx}
settings
{:keys [on-success] :or {on-success #()}}]
(let [new-multiaccount (assoc multiaccount :settings settings)]
{:db (assoc db :multiaccount new-multiaccount)
:data-store/base-tx [{:transaction (multiaccounts-store/save-multiaccount-tx new-multiaccount)
:success-event success-event}]}))
{:db (assoc db :multiaccount new-multiaccount)
::json-rpc/call
[{:method "settings_saveConfig"
:params ["multiaccount" (types/serialize new-multiaccount)]
:on-success on-success}]}))

View File

@ -2,9 +2,7 @@
(:require [status-im.constants :as constants]
[status-im.multiaccounts.update.core :as multiaccounts]
[status-im.pairing.core :as pairing]
[status-im.data-store.multiaccounts :as multiaccounts-store]
[status-im.transport.shh :as shh]
[status-im.utils.fx :as fx]))
[status-im.transport.shh :as shh]))
;; Publish updates every 48 hours
(def publish-updates-interval (* 48 60 60 1000))

View File

@ -6,25 +6,29 @@
(defn init-keystore []
(native-module/init-keystore))
(defn start-node [config]
(native-module/start-node config))
(defn open-accounts [callback]
(native-module/open-accounts callback))
(def node-started (atom false))
(defn prepare-dir-and-update-config [config callback]
(native-module/prepare-dir-and-update-config config callback))
(defn node-ready []
(reset! node-started true)
(native-module/node-ready))
(defn save-account-and-login
[account-data password config subaccounts-data]
(native-module/save-account-and-login account-data password config subaccounts-data))
(defn stop-node []
(reset! node-started false)
(native-module/stop-node))
(defn login
[account-data password]
(native-module/login account-data password))
(defn logout
[]
(native-module/logout))
(defn node-ready [])
(defn create-multiaccount [password callback]
(native-module/create-account password callback))
(defn multiaccount-store-account [account-id password callback]
(native-module/multiaccount-store-account account-id password callback))
(defn multiaccount-load-account [address password callback]
(native-module/multiaccount-load-account address password callback))
@ -37,6 +41,9 @@
(defn recover-multiaccount [passphrase password callback]
(native-module/recover-account passphrase password callback))
(defn multiaccount-store-account [account-id password callback]
(native-module/multiaccount-store-account account-id password callback))
(defn multiaccount-store-derived [account-id paths password callback]
(native-module/multiaccount-store-derived account-id paths password callback))
@ -46,9 +53,6 @@
(defn multiaccount-import-mnemonic [mnemonic password callback]
(native-module/multiaccount-import-mnemonic mnemonic password callback))
(defn login [address password main-account watch-addresses callback]
(native-module/login address password main-account watch-addresses callback))
(defn verify [address password callback]
(native-module/verify address password callback))
@ -59,16 +63,11 @@
(defn set-soft-input-mode [mode]
(native-module/set-soft-input-mode mode))
(defn clear-web-data []
(native-module/clear-web-data))
(defn call-rpc [payload callback]
(when @node-started
(native-module/call-rpc payload callback)))
(native-module/call-rpc payload callback))
(defn call-private-rpc [payload callback]
(when @node-started
(native-module/call-private-rpc payload callback)))
(native-module/call-private-rpc payload callback))
(defn sign-message [rpcParams callback]
(native-module/sign-message rpcParams callback))

View File

@ -10,9 +10,36 @@
(when (exists? (.-NativeModules rn-dependencies/react-native))
(.-Status (.-NativeModules rn-dependencies/react-native))))
(defn clear-web-data []
(when (status)
(.clearCookies (status))
(.clearStorageAPIs (status))))
(defn init-keystore []
(.initKeystore (status)))
(defn open-accounts [callback]
(.openAccounts (status) #(callback (types/json->clj %))))
(defn prepare-dir-and-update-config [config callback]
(.prepareDirAndUpdateConfig (status)
config
#(callback (types/json->clj %))))
(defn save-account-and-login
[account-data password config subaccounts-data]
(clear-web-data)
(.saveAccountAndLogin (status) account-data password config subaccounts-data))
(defn login
[account-data password]
(clear-web-data)
(.login (status) account-data password))
(defn logout []
(clear-web-data)
(.logout (status)))
(defonce listener-initialized (atom false))
(when-not @listener-initialized
@ -20,19 +47,7 @@
(.addListener r/device-event-emitter "gethEvent"
#(re-frame/dispatch [:signals/signal-received (.-jsonEvent %)])))
(defonce node-started (atom false))
(defn stop-node []
(reset! node-started false)
(when (status)
(.stopNode (status))))
(defn node-ready []
(reset! node-started true))
(defn start-node [config]
(when (status)
(.startNode (status) config)))
(defn node-ready [])
(defonce account-creation? (atom false))
@ -58,11 +73,11 @@
(.sendLogs (status) dbJson js-logs callback)))
(defn add-peer [enode on-result]
(when (and @node-started (status))
(when (status)
(.addPeer (status) enode on-result)))
(defn recover-account [passphrase password on-result]
(when (and @node-started (status))
(when (status)
(.recoverAccount (status) passphrase password on-result)))
(defn multiaccount-generate-and-derive-addresses [n mnemonic-length paths on-result]
@ -74,32 +89,33 @@
on-result))
(defn multiaccount-derive-addresses [account-id paths on-result]
(when (and @node-started (status))
(when (status)
(.multiAccountDeriveAddresses (status)
(types/clj->json {:accountID account-id
:paths paths})
on-result)))
(defn multiaccount-store-account [account-id password on-result]
(when (and @node-started (status))
(when (status)
(.multiAccountStoreAccount (status)
(types/clj->json {:accountID account-id
:password password})
on-result)))
(defn multiaccount-load-account [address password on-result]
(when (and @node-started (status))
(when (status)
(.multiAccountLoadAccount (status)
(types/clj->json {:address address
:password password})
on-result)))
(defn multiaccount-reset [on-result]
(when (and @node-started (status))
(when (status)
(.multiAccountReset (status)
on-result)))
(defn multiaccount-store-derived [account-id paths password on-result]
(defn multiaccount-store-derived
[account-id paths password on-result]
(.multiAccountStoreDerived (status)
(types/clj->json {:accountID account-id
:paths paths
@ -108,72 +124,50 @@
on-result))
(defn multiaccount-import-mnemonic [mnemonic password on-result]
(when (and @node-started (status))
(when (status)
(.multiAccountImportMnemonic (status)
(types/clj->json {:mnemonicPhrase mnemonic
:Bip39Passphrase password})
on-result)))
(defn login [address password main-account watch-addresses on-result]
(when (and @node-started (status))
(.login (status)
(types/clj->json {:chatAddress address :password password
:mainAccount main-account :watch-addresses watch-addresses})
on-result)))
(defn verify [address password on-result]
(when (and @node-started (status))
(.verify (status) address password on-result)))
(.verify (status) address password on-result))
(defn login-with-keycard [whisper-private-key encryption-public-key on-result]
(when (and @node-started (status))
(.loginWithKeycard (status) whisper-private-key encryption-public-key on-result)))
(clear-web-data)
(.loginWithKeycard (status) whisper-private-key encryption-public-key on-result))
(defn set-soft-input-mode [mode]
(when (status)
(.setSoftInputMode (status) mode)))
(defn clear-web-data []
(when (status)
(.clearCookies (status))
(.clearStorageAPIs (status))))
(defn call-rpc [payload callback]
(when (and @node-started (status))
(.callRPC (status) payload callback)))
(.callRPC (status) payload callback))
(defn call-private-rpc [payload callback]
(when (and @node-started (status))
(.callPrivateRPC (status) payload callback)))
(.callPrivateRPC (status) payload callback))
(defn sign-message [rpcParams callback]
(when (and @node-started (status))
(.signMessage (status) rpcParams callback)))
(.signMessage (status) rpcParams callback))
(defn hash-transaction [rpcParams callback]
(when (and @node-started (status))
(.hashTransaction (status) rpcParams callback)))
(.hashTransaction (status) rpcParams callback))
(defn hash-message [message callback]
(when (and @node-started (status))
(.hashMessage (status) message callback)))
(.hashMessage (status) message callback))
(defn hash-typed-data [data callback]
(when (and @node-started (status))
(.hashTypedData (status) data callback)))
(.hashTypedData (status) data callback))
(defn sign-typed-data [data account password callback]
(when (and @node-started (status))
(.signTypedData (status) data account password callback)))
(.signTypedData (status) data account password callback))
(defn send-transaction [rpcParams password callback]
(when (and @node-started (status))
(.sendTransaction (status) rpcParams password callback)))
(.sendTransaction (status) rpcParams password callback))
(defn send-transaction-with-signature [rpcParams sig callback]
(when (and @node-started (status))
(.sendTransactionWithSignature (status) rpcParams sig callback)))
(.sendTransactionWithSignature (status) rpcParams sig callback))
(defn close-application []
(.closeApplication (status)))

View File

@ -14,7 +14,9 @@
[status-im.utils.handlers :as handlers]
[status-im.utils.http :as http]
[status-im.utils.types :as types]
status-im.network.subs))
status-im.network.subs
[status-im.node.core :as node]
[taoensso.timbre :as log]))
(def url-regex
#"https?://(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}(\.[a-z]{2,6})?\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)")
@ -54,7 +56,7 @@
(not-any? identity)))
(defn get-network-id-for-chain-id [{:keys [db]} chain-id]
(let [networks (get-in db [:multiaccount :networks])
(let [networks (get-in db [:multiaccount :networks/networks])
filtered (filter #(= chain-id (get-in % [1 :config :NetworkId])) networks)]
(first (keys filtered))))
@ -74,7 +76,7 @@
:config config}))
(defn get-network [{:keys [db]} network-id]
(get-in db [:multiaccount :networks network-id]))
(get-in db [:multiaccount :networks/networks network-id]))
(fx/defn set-input
[{:keys [db]} input-key value]
@ -103,7 +105,7 @@
(:value url)
(:value chain)
(:value chain-id))
current-networks (:networks multiaccount)
current-networks (:networks/networks multiaccount)
new-networks (merge {(:id network) network} current-networks)]
(if (or (not chain-id-unique?)
(chain-id-available? current-networks network))
@ -111,7 +113,7 @@
{:db (dissoc db :networks/manage)}
#(action-handler on-success (:id network) %)
(multiaccounts.update/multiaccount-update
{:networks new-networks}
{:networks/networks new-networks}
{:success-event success-event}))
(action-handler on-failure "chain-id already defined" nil)))
(action-handler on-failure "invalid network parameters" nil))))
@ -124,22 +126,14 @@
(fx/defn connect-success [{:keys [db] :as cofx}
{:keys [network-id on-success client-version]}]
(let [current-network (get-in db [:multiaccount :networks (:network db)])
network-with-upstream-rpc? (ethereum/network-with-upstream-rpc?
current-network)]
(let [current-network (get-in db [:multiaccount :networks/networks (:network db)])]
(fx/merge
cofx
{:ui/show-confirmation
{:title (i18n/label :t/close-app-title)
:content (if network-with-upstream-rpc?
(i18n/label :t/logout-app-content)
(i18n/label :t/close-app-content))
:content (i18n/label :t/logout-app-content)
:confirm-button-text (i18n/label :t/close-app-button)
:on-accept #(re-frame/dispatch
[(if network-with-upstream-rpc?
:network.ui/save-rpc-network-pressed
:network.ui/save-non-rpc-network-pressed)
network-id])
:on-accept #(re-frame/dispatch [::save-network-settings-pressed network-id])
:on-cancel nil}}
#(action-handler on-success {:network-id network-id
:client-version client-version} %))))
@ -150,7 +144,7 @@
nil))
(fx/defn connect [{:keys [db] :as cofx} {:keys [network-id on-success on-failure]}]
(if-let [config (get-in db [:multiaccount :networks network-id :config])]
(if-let [config (get-in db [:multiaccount :networks/networks network-id :config])]
(if-let [upstream-url (get-in config [:UpstreamConfig :URL])]
{:http-post {:url upstream-url
:data (types/clj->json [{:jsonrpc "2.0"
@ -204,7 +198,7 @@
[{{:keys [multiaccount]} :db :as cofx} {:keys [network on-success on-failure]}]
(let [current-network? (= (:network multiaccount) network)]
(if (or current-network?
(not (get-in multiaccount [:networks network])))
(not (get-in multiaccount [:networks/networks network])))
(fx/merge cofx
{:ui/show-error (i18n/label :t/delete-network-error)}
#(action-handler on-failure network %))
@ -216,26 +210,18 @@
:on-cancel nil}}
#(action-handler on-success network %)))))
(fx/defn save-non-rpc-network
[{:keys [db now] :as cofx} network]
(multiaccounts.update/multiaccount-update cofx
{:network network
:last-updated now}
{:success-event [:network.callback/non-rpc-network-saved]}))
(fx/defn save-rpc-network
(fx/defn save-network-settings
{:events [::save-network-settings-pressed]}
[{:keys [now] :as cofx} network]
(multiaccounts.update/multiaccount-update
cofx
{:network network
:last-updated now}
{:success-event [:multiaccounts.update.callback/save-settings-success]}))
(fx/merge cofx
(multiaccounts.update/multiaccount-update {:network network :last-updated now} {})
(node/prepare-new-config {:on-success #(re-frame/dispatch [:logout])})))
(fx/defn remove-network
[{:keys [db now] :as cofx} network success-event]
(let [networks (dissoc (get-in db [:multiaccount :networks]) network)]
(let [networks (dissoc (get-in db [:multiaccount :networks/networks]) network)]
(multiaccounts.update/multiaccount-update cofx
{:networks networks
{:networks/networks networks
:last-updated now}
{:success-event success-event})))
@ -262,10 +248,10 @@
[cofx network]
(let [db (:db cofx)
rpc-network? (get-in network [:config :UpstreamConfig :Enabled] false)
fleet (fleet-core/current-fleet db nil)
fleet (fleet-core/current-fleet db)
fleet-supports-les? (fleet-core/fleet-supports-les? fleet)]
(if (or rpc-network? fleet-supports-les?)
(navigate-to-network-details cofx network (not rpc-network?))
;; Otherwise, we show an explanation dialog to a user if the current fleet does not suport LES
;; Otherwise, we show an explanation dialog to a user if the current fleet does not suport LES
{:utils/show-popup {:title "LES not supported"
:content (not-supported-warning fleet)}})))

View File

@ -20,21 +20,6 @@
(fn [cofx]
(network/edit cofx)))
(handlers/register-handler-fx
:network.callback/non-rpc-network-saved
(fn [_ _]
{:ui/close-application nil}))
(handlers/register-handler-fx
:network.ui/save-non-rpc-network-pressed
(fn [cofx [_ network]]
(network/save-non-rpc-network cofx network)))
(handlers/register-handler-fx
:network.ui/save-rpc-network-pressed
(fn [cofx [_ network]]
(network/save-rpc-network cofx network)))
(handlers/register-handler-fx
:network.ui/remove-network-confirmed
(fn [cofx [_ network]]

View File

@ -21,7 +21,7 @@
:get-networks
:<- [:multiaccount]
:<- [:networks/networks]
(fn [[{:keys [networks]} default-networks]]
(fn [[{:keys [:networks/networks]} default-networks]]
(let [networks (map (label-networks default-networks) (sort-by :name (vals networks)))
types [:mainnet :testnet :custom]]
(zipmap

View File

@ -1,14 +1,15 @@
(ns status-im.node.core
(:require [re-frame.core :as re-frame]
[status-im.constants :as constants]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.fleet.core :as fleet]
[status-im.native-module.core :as status]
[status-im.utils.config :as config]
[status-im.utils.types :as types]
[status-im.utils.fx :as fx]
[status-im.utils.handlers :as utils.handlers]
[status-im.utils.platform :as utils.platform]
[status-im.utils.utils :as utils]
[taoensso.timbre :as log]
[status-im.utils.fx :as fx]))
[status-im.utils.types :as types]
[status-im.utils.utils :as utils]))
(defn- add-custom-bootnodes [config network all-bootnodes]
(let [bootnodes (as-> all-bootnodes $
@ -87,18 +88,15 @@
(assoc-in [:LightEthConfig :MinTrustedFraction] 50))
config))
(defn- get-multiaccount-node-config [db address]
(let [multiaccounts (get db :multiaccounts/multiaccounts)
current-fleet-key (fleet/current-fleet db address)
(defn- get-multiaccount-node-config [db]
(let [multiaccount (:multiaccount db)
current-fleet-key (fleet/current-fleet db)
current-fleet (get (fleet/fleets db) current-fleet-key)
rendezvous-nodes (pick-nodes 3 (vals (:rendezvous current-fleet)))
{:keys [network installation-id settings bootnodes networks]}
(merge
{:network config/default-network
:networks (:networks/networks db)
:settings (constants/default-multiaccount-settings)
:installation-id (get db :multiaccounts/new-installation-id)}
(get multiaccounts address))
{:keys [network installation-id settings bootnodes :networks/networks]
:or {network config/default-network
networks (:networks/networks db)
settings constants/default-multiaccount-settings}} multiaccount
use-custom-bootnodes (get-in settings [:bootnodes network])
log-level (get-log-level settings)
datasync? (:datasync? settings)
@ -167,50 +165,32 @@
{:error error}
(when sync-state (js->clj sync-state :keywordize-keys true))))})
(fx/defn start
[{:keys [db]} address]
(let [network (if address
(get-multiaccount-network db address)
(:network db))
node-config (if (= (:node/on-ready db) :verify-multiaccount)
(get-verify-multiaccount-config db network)
(get-multiaccount-node-config db address))
node-config-json (types/clj->json node-config)]
(log/info "Node config: " node-config-json)
{:db (assoc db
:network network
:node/status :starting)
:node/start node-config-json}))
(defn get-new-config
[db]
(types/clj->json (get-multiaccount-node-config db)))
(fx/defn stop
[{:keys [db]}]
{:db (assoc db :node/status :stopping)
:node/stop nil})
(fx/defn save-new-config
{:events [::save-new-config]}
[{:keys [db]} config {:keys [on-success]}]
{::json-rpc/call [{:method "settings_saveNodeConfig"
:params [config]
:on-success on-success}]})
(fx/defn initialize
[{{:node/keys [status] :as db} :db :as cofx} address]
(let [restart {:db (assoc db :node/restart? true :node/address address)}]
(case status
:started nil
:starting restart
:stopping restart
(start cofx address))))
(fx/defn prepare-new-config
[{:keys [db]} {:keys [on-success]}]
{::prepare-new-config [(get-new-config db)
#(re-frame/dispatch [::save-new-config % {:on-success on-success}])]})
(re-frame/reg-fx
:node/start
(fn [config]
(status/start-node config)))
::prepare-new-config
(fn [[config callback]]
(status/prepare-dir-and-update-config config callback)))
(re-frame/reg-fx
:node/ready
(fn [config]
(status/node-ready)))
(re-frame/reg-fx
:node/stop
(fn []
(status/stop-node)))
(re-frame/reg-fx
:node/les-show-debug-info
(fn [[web3 multiaccount chain-sync-state]]

View File

@ -337,7 +337,8 @@
(create-notification-channel))
(handle-initial-push-notification)))
(fx/defn process-stored-event [{:keys [db] :as cofx} address stored-pns]
(fx/defn process-stored-event
[{:keys [db] :as cofx} address stored-pns]
(when-not platform/desktop?
(if (multiaccounts.model/logged-in? cofx)
(let [current-multiaccount (:multiaccount db)

View File

@ -1,25 +1,22 @@
(ns status-im.pairing.core
(:require [re-frame.core :as re-frame]
[clojure.string :as string]
[status-im.i18n :as i18n]
[status-im.utils.fx :as fx]
[status-im.utils.pairing :as pairing.utils]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.contact.device-info :as device-info]
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.chat.models :as models.chat]
[status-im.contact.core :as contact]
[status-im.contact.db :as contact.db]
[status-im.contact.device-info :as device-info]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.i18n :as i18n]
[status-im.multiaccounts.model :as multiaccounts.model]
[status-im.transport.message.pairing :as transport.pairing]
[status-im.transport.message.protocol :as protocol]
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.config :as config]
[status-im.utils.platform :as utils.platform]
[status-im.chat.models :as models.chat]
[status-im.multiaccounts.model :as multiaccounts.model]
[status-im.transport.message.protocol :as protocol]
[status-im.data-store.installations :as data-store.installations]
[status-im.utils.fx :as fx]
[status-im.utils.identicon :as identicon]
[status-im.contact.core :as contact]
[status-im.transport.filters.core :as transport.filters]
[status-im.data-store.contacts :as data-store.contacts]
[status-im.data-store.multiaccounts :as data-store.multiaccounts]
[status-im.transport.message.pairing :as transport.pairing]))
[status-im.utils.pairing :as pairing.utils]
[status-im.utils.platform :as utils.platform]
[status-im.utils.types :as types]))
(defn enable-installation-rpc [installation-id on-success on-failure]
(json-rpc/call {:method "shhext_enableInstallation"
@ -134,29 +131,8 @@
:deviceType utils.platform/os
:fcmToken fcm-token}]]}))
(fx/defn migrate-installations
"Take the realm installations and move them to status-go, also move installation-name
to status-go, clean up after so it is run only once"
[{:keys [db] :as cofx} installations]
(let [installation-name (get-in db [:multiaccount :installation-name])]
(fx/merge cofx
{:pairing/set-installation-metadata
(map (fn [{:keys [installation-id name device-type fcm-token]}]
[installation-id {:name name
:deviceType device-type
:fcmToken fcm-token}])
installations)}
#(when-not (string/blank? installation-name)
(set-name % installation-name))
#(when-not (string/blank? installation-name)
(let [new-multiaccount (dissoc (:multiaccount (:db %)) :installation-name)]
{:db (assoc (:db %) :multiaccount new-multiaccount)
:data-store/base-tx [(data-store.multiaccounts/save-multiaccount-tx new-multiaccount)]})))))
(fx/defn init [cofx old-installations]
(fx/merge cofx
{:pairing/get-our-installations []}
(migrate-installations old-installations)))
(fx/defn init [cofx]
{:pairing/get-our-installations nil})
(defn handle-bundles-added [{:keys [db] :as cofx} bundle]
(let [installation-id (:installationID bundle)]
@ -165,7 +141,7 @@
(multiaccounts.model/current-public-key cofx))
(not= (get-in db [:multiaccount :installation-id]) installation-id))
(fx/merge cofx
(init [])
(init)
#(when-not (or (:pairing/prompt-user-pop-up db)
(= :installations (:view-id db)))
(prompt-user-on-new-installation %))))))
@ -351,10 +327,11 @@
{}
contacts))
(defn handle-sync-installation [{:keys [db] :as cofx} {:keys [contacts multiaccount chat]} sender]
(defn handle-sync-installation
[{:keys [db] :as cofx} {:keys [contacts multiaccount chat]} sender]
(let [confirmation (:metadata cofx)]
(if (= sender (multiaccounts.model/current-public-key cofx))
(let [success-event [:message/messages-persisted [confirmation]]
(let [on-success #(re-frame/dispatch [:message/messages-persisted [confirmation]])
new-contacts (when (seq contacts)
(vals (merge-contacts (:contacts/contacts db)
((comp ensure-photo-path
@ -365,17 +342,20 @@
cofx
(concat
[{:db (assoc db :multiaccount new-multiaccount)
:data-store/base-tx [{:transaction (data-store.multiaccounts/save-multiaccount-tx new-multiaccount)
:success-event success-event}]}
::json-rpc/call
[{:method "settings_saveConfig"
:params ["multiaccount" (types/serialize new-multiaccount)]
:on-success on-success}]}
#(when (:public? chat)
(models.chat/start-public-chat % (:chat-id chat) {:dont-navigate? true}))]
contacts-fx)))
(confirm-message-processed cofx confirmation))))
(defn handle-pair-installation [{:keys [db] :as cofx} {:keys [name
fcm-token
installation-id
device-type]} timestamp sender]
(defn handle-pair-installation
[{:keys [db] :as cofx} {:keys [name
fcm-token
installation-id
device-type]} timestamp sender]
(if (and (= sender (multiaccounts.model/current-public-key cofx))
(not= (get-in db [:multiaccount :installation-id]) installation-id))
{:pairing/set-installation-metadata [[installation-id {:name name
@ -389,9 +369,7 @@
:installation-id installation-id
:name (:name metadata)
:device-type (:deviceType metadata)
:fcmToken (:fcmToken metadata))
;; we count it as migrated, and delete it from realm
:data-store/tx [(data-store.installations/delete installation-id)]})
:fcmToken (:fcmToken metadata))})
(fx/defn load-installations [{:keys [db]} installations]
{:db (assoc db :pairing/installations (reduce

View File

@ -7,6 +7,7 @@
[status-im.mailserver.core :as mailserver]
[status-im.node.core :as node]
[status-im.transport.core :as transport]
[status-im.tribute-to-talk.core :as tribute-to-talk]
[status-im.utils.fx :as fx]
[status-im.utils.semaphores :as semaphores]
[status-im.utils.utils :as utils]))
@ -57,7 +58,7 @@
[{{:keys [network multiaccount] :as db} :db :as cofx}]
(when (and (not (semaphores/locked? cofx :check-sync-state?))
(not (ethereum/network-with-upstream-rpc?
(get-in multiaccount [:networks network]))))
(get-in multiaccount [:networks/networks network]))))
(fx/merge cofx
(check-sync-state)
(semaphores/lock :check-sync-state?))))
@ -66,7 +67,7 @@
[{:data-store/keys [transport mailserver-topics mailservers]
:keys [db] :as cofx}]
(let [network (get-in db [:multiaccount :network])
network-id (str (get-in db [:multiaccount :networks network :config :NetworkId]))]
network-id (str (get-in db [:multiaccount :networks/networks network :config :NetworkId]))]
(fx/merge cofx
{:db (assoc db
:rpc-url constants/ethereum-rpc-url
@ -76,14 +77,17 @@
[{:method "net_version"
:on-success
(fn [fetched-network-id]
(when (not= network-id fetched-network-id)
(utils/show-popup
(i18n/label :t/ethereum-node-started-incorrectly-title)
(i18n/label :t/ethereum-node-started-incorrectly-description
{:network-id network-id
:fetched-network-id fetched-network-id})
#(re-frame/dispatch [:protocol.ui/close-app-confirmed]))))}]}
;;FIXME
#_(when (not= network-id fetched-network-id) 3
(utils/show-popup
(i18n/label :t/ethereum-node-started-incorrectly-title)
(i18n/label :t/ethereum-node-started-incorrectly-description
{:network-id network-id
:fetched-network-id fetched-network-id})
#(re-frame/dispatch [:protocol.ui/close-app-confirmed]))))}]}
(tribute-to-talk/init)
(start-check-sync-state)
(mailserver/initialize-ranges)
(mailserver/initialize-mailserver mailservers)
(transport/init-whisper))))

View File

@ -1,48 +1,21 @@
(ns status-im.signals.core
(:require [status-im.multiaccounts.model :as multiaccounts.model]
[status-im.multiaccounts.login.core :as multiaccounts.login]
[status-im.chat.models.loading :as chat.loading]
(:require [status-im.chat.models.loading :as chat.loading]
[status-im.contact-recovery.core :as contact-recovery]
[status-im.ethereum.subscriptions :as ethereum.subscriptions]
[status-im.hardwallet.core :as hardwallet]
[status-im.mailserver.core :as mailserver]
[status-im.multiaccounts.model :as multiaccounts.model]
[status-im.node.core :as node]
[status-im.pairing.core :as pairing]
[status-im.transport.message.core :as transport.message]
[status-im.transport.filters.core :as transport.filters]
[status-im.transport.message.core :as transport.message]
[status-im.utils.fx :as fx]
[status-im.utils.security :as security]
[status-im.utils.types :as types]
[taoensso.timbre :as log]
[status-im.multiaccounts.recover.core :as multiaccounts.recover]))
[status-im.multiaccounts.login.core :as login]))
(fx/defn status-node-started
[{db :db :as cofx}]
(let [{:node/keys [restart? address on-ready]
:multiaccounts/keys [create]} db]
(fx/merge cofx
{:db (-> db
(assoc :node/status :started)
(dissoc :node/restart? :node/address))
:node/ready nil}
(when restart?
(node/initialize address))
(case on-ready
:login
(multiaccounts.login/login)
:verify-multiaccount
(let [{:keys [address password]} (multiaccounts.model/credentials cofx)]
(fn [_]
{:multiaccounts.login/verify
[address password (:realm-error db)]}))
:create-multiaccount
(fn [_]
{:multiaccounts.create/create-multiaccount (select-keys create [:id :password])})
:import-mnemonic
(multiaccounts.recover/import-mnemonic)
:create-keycard-multiaccount
(hardwallet/create-keycard-multiaccount)))))
[{db :db :as cofx} event]
(login/multiaccount-login-success cofx))
(fx/defn status-node-stopped
[{db :db}]
@ -63,7 +36,7 @@
[cofx event-str]
(let [{:keys [type event]} (types/json->clj event-str)]
(case type
"node.ready" (status-node-started cofx)
"node.login" (status-node-started cofx event)
"node.stopped" (status-node-stopped cofx)
"envelope.sent" (transport.message/update-envelopes-status cofx (:ids event) :sent)
"envelope.expired" (transport.message/update-envelopes-status cofx (:ids event) :not-sent)

View File

@ -3,6 +3,7 @@
[status-im.utils.fx :as fx]
[status-im.native-module.core :as status]
[status-im.utils.types :as types]
[status-im.utils.handlers :as utils.handlers]
[status-im.ethereum.abi-spec :as abi-spec]
[status-im.ethereum.core :as ethereum]))
@ -73,4 +74,4 @@
(assoc-in [:signing/sign :type] :keycard))}
(if message
(hash-message message)
(hash-transaction)))))
(hash-transaction)))))

View File

@ -10,7 +10,8 @@
[status-im.utils.fx :as fx]
[status-im.utils.utils :as utils]
[status-im.signing.core :as signing]
[status-im.utils.contenthash :as contenthash]))
[status-im.utils.contenthash :as contenthash]
[status-im.multiaccounts.update.core :as multiaccounts.update]))
(defn pack-data-callback
[id open?]
@ -85,9 +86,7 @@
(fx/defn init-stickers-packs
[{:keys [db]}]
(let [sticker-packs (into {} (map #(let [pack (edn/read-string %)]
(vector (:id pack) pack))
(get-in db [:multiaccount :stickers])))]
(let [sticker-packs (get-in db [:multiaccount :stickers/packs-installed])]
{:db (assoc db
:stickers/packs-installed sticker-packs
:stickers/packs sticker-packs)}))
@ -99,8 +98,10 @@
cofx
{:db (-> db
(assoc-in [:stickers/packs-installed id] pack))}
;;(assoc :stickers/selected-pack id))} TODO it doesn't scroll to selected pack on Android
(multiaccounts/update-stickers (conj (:stickers multiaccount) (pr-str pack))))))
;;(assoc :stickers/selected-pack id))} TODO it doesn't scroll to selected pack on Android
(multiaccounts.update/multiaccount-update
{:stickers/packs-installed (assoc (:stickers/packs-installed multiaccount) id pack)}
{}))))
(defn valid-sticker? [sticker]
(contains? sticker :hash))

View File

@ -66,7 +66,6 @@
(reg-root-key-sub :bottom-sheet/options :bottom-sheet/options)
;;general
(reg-root-key-sub :network-name :chain)
(reg-root-key-sub :sync-state :sync-state)
(reg-root-key-sub :network-status :network-status)
(reg-root-key-sub :peers-count :peers-count)
@ -111,7 +110,6 @@
(reg-root-key-sub :multiaccounts/multiaccounts :multiaccounts/multiaccounts)
(reg-root-key-sub :multiaccounts/login :multiaccounts/login)
(reg-root-key-sub :multiaccount :multiaccount)
(reg-root-key-sub :multiaccounts/create :multiaccounts/create)
(reg-root-key-sub :get-recover-multiaccount :multiaccounts/recover)
;;chat
(reg-root-key-sub ::cooldown-enabled? :chat/cooldown-enabled?)
@ -202,7 +200,13 @@
:network
:<- [:multiaccount]
(fn [current-multiaccount]
(get (:networks current-multiaccount) (:network current-multiaccount))))
(get (:networks/networks current-multiaccount) (:network current-multiaccount))))
(re-frame/reg-sub
:network-name
:<- [:network]
(fn [network]
(ethereum/network->chain-keyword network)))
(re-frame/reg-sub
:disconnected?
@ -352,12 +356,6 @@
(fn [sett]
(fleet/current-fleet-sub sett)))
(re-frame/reg-sub
:get-multiaccount-creation-next-enabled?
:<- [:multiaccounts/create]
(fn [create]
(multiaccounts.model/multiaccount-creation-next-enabled? create)))
(re-frame/reg-sub
:multiaccount-settings
:<- [:multiaccount]
@ -370,7 +368,7 @@
:<- [:multiaccount]
:<- [:get-network]
(fn [[multiaccount network]]
(get-in multiaccount [:networks network])))
(get-in multiaccount [:networks/networks network])))
(re-frame/reg-sub
:current-network-initialized?
@ -897,7 +895,7 @@
:stickers/recent
:<- [:multiaccount]
:<- [:stickers/installed-packs-vals]
(fn [[{:keys [recent-stickers]} packs]]
(fn [[{:keys [:stickers/recent-stickers]} packs]]
(map (fn [hash] {:hash hash :pack (find-pack-id-for-hash hash packs)}) recent-stickers)))
;;EXTENSIONS ===========================================================================================================

View File

@ -37,10 +37,10 @@
(fx/defn init-whisper
"Initialises whisper protocol by:
- (optionally) initializing mailserver"
[{:keys [db web3 all-installations] :as cofx}]
[{:keys [db web3] :as cofx}]
(fx/merge cofx
(fetch-node-info-fx)
(pairing/init all-installations)
(pairing/init)
(publisher/start-fx)
(mailserver/connect-to-mailserver)
(message/resend-contact-messages [])))

View File

@ -5,7 +5,6 @@
[re-frame.core :as re-frame]
[clojure.string :as string]
[status-im.contact.db :as contact.db]
[status-im.data-store.multiaccounts :as data-store.multiaccounts]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.utils.fx :as fx]
[status-im.utils.handlers :as handlers]
@ -350,4 +349,3 @@
filters
#(filters-added! (map responses->filters %))
#(log/error "load-filters: failed error" %))))

View File

@ -68,7 +68,6 @@
:current []
:puk []
:enter-step :original}}
:chats/loading? true
:two-pane-ui-enabled? (dimensions/fit-two-pane?)})
;;;;GLOBAL
@ -226,7 +225,6 @@
:commands/stored-command
:group/selected-contacts
:multiaccounts/multiaccounts
:multiaccounts/create
:multiaccounts/recover
:multiaccounts/login
:my-profile/profile
@ -243,8 +241,6 @@
:extensions/staged-extension
:extensions/manage
:node/status
:node/restart?
:node/address
:node/chain-sync-state
:universal-links/url
:push-notifications/stored

View File

@ -7,7 +7,6 @@
new-group
add-participants-toggle-list]]
[status-im.ui.screens.profile.group-chat.views :refer [group-chat-profile]]
[status-im.ui.screens.multiaccounts.create.views :as create.views]
[status-im.ui.screens.multiaccounts.login.views :as login.views]
[status-im.ui.screens.multiaccounts.recover.views :as recover.views]
[status-im.ui.screens.multiaccounts.views :as multiaccounts.views]
@ -33,7 +32,6 @@
:intro intro.views/intro
:multiaccounts multiaccounts.views/multiaccounts
:recover recover.views/recover
:create-multiaccount create.views/create-multiaccount
:new-group new-group
:contact-toggle-list contact-toggle-list
:group-chat-profile group-chat-profile

View File

@ -6,7 +6,6 @@
status-im.ui.screens.group.chat-settings.events
status-im.ui.screens.group.events
status-im.utils.universal-links.events
status-im.web3.events
status-im.ui.screens.add-new.new-chat.navigation
status-im.ui.screens.profile.events
status-im.ui.screens.wallet.navigation

View File

@ -1,41 +0,0 @@
(ns status-im.ui.screens.multiaccounts.create.styles
(:require-macros [status-im.utils.styles :refer [defstyle]])
(:require [status-im.ui.components.colors :as colors]))
(def create-multiaccount-view
{:flex 1})
(def multiaccount-creating-view
{:flex 1})
(def multiaccount-creating-indicatior
{:flex 1
:align-items :center
:justify-content :center
:margin-bottom 100})
(def multiaccount-creating-text
{:font-size 14
:text-align :center
:margin-top 16})
(def logo-container
{:margin-top 16
:align-items :center})
(def logo
{:size 82
:icon-size 34})
(defstyle input-container
{:margin-horizontal 16
:margin-top 16})
(def input-description
{:font-size 14
:color colors/gray})
(def bottom-container
{:flex-direction :row
:margin-horizontal 12
:margin-vertical 15})

View File

@ -1,77 +0,0 @@
(ns status-im.ui.screens.multiaccounts.create.views
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [status-im.ui.components.react :as react]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.components.status-bar.view :as status-bar]
[status-im.i18n :as i18n]
[re-frame.core :as re-frame]
[status-im.ui.components.styles :as components.styles]
[status-im.ui.components.toolbar.actions :as actions]
[status-im.ui.components.react :as components]
[status-im.ui.components.common.common :as components.common]
[status-im.ui.components.text-input.view :as text-input]
[status-im.ui.screens.multiaccounts.create.styles :as styles]))
(def steps
{:enter-password {:input-key :password
:input-label (i18n/label :t/password)
:input-placeholder (i18n/label :t/password-placeholder)
:input-description (i18n/label :t/password-description)}
:confirm-password {:input-key :password-confirm
:input-label (i18n/label :t/confirm)
:input-placeholder (i18n/label :t/password-placeholder2)
:input-description (i18n/label :t/password-description)}
:multiaccount-creating nil
:enter-name {:input-key :name
:input-label (i18n/label :t/name)
:input-placeholder (i18n/label :t/name-placeholder)
:input-description (i18n/label :t/name-description)}})
(defview input [next-enabled? {:keys [step error password password-confirm]}]
[text-input/text-input-with-label
(cond-> {:label (get-in steps [step :input-label])
:placeholder (get-in steps [step :input-placeholder])
:on-change-text #(re-frame/dispatch [:multiaccounts.create.ui/input-text-changed (get-in steps [step :input-key]) %])
:secure-text-entry (boolean (#{:enter-password :confirm-password} step))
:auto-focus true
:error error}
next-enabled? (assoc :on-submit-editing #(re-frame/dispatch [:multiaccounts.create.ui/next-step-pressed step password password-confirm])))])
(defview create-multiaccount []
(letsubs [{:keys [step error password password-confirm]} [:multiaccounts/create]
next-enabled? [:get-multiaccount-creation-next-enabled?]]
[react/keyboard-avoiding-view {:style styles/create-multiaccount-view}
[status-bar/status-bar {:flat? true}]
[toolbar/toolbar nil
(when (#{:enter-password :confirm-password} step)
(toolbar/nav-button (actions/back #(re-frame/dispatch [:multiaccounts.create.ui/step-back-pressed step])))) nil]
(when (= :multiaccount-creating step)
[react/view styles/multiaccount-creating-view
[react/view styles/logo-container
[components.common/logo styles/logo]]
[react/view {:style styles/multiaccount-creating-indicatior}
[components/activity-indicator {:animating true}]
[react/text {:style styles/multiaccount-creating-text}
(i18n/label :t/creating-your-multiaccount)]]])
(when (#{:enter-password :confirm-password :enter-name} step)
[react/scroll-view {:flex 1}
[react/view {:style styles/logo-container}
[components.common/logo styles/logo]]
^{:key (str "step" step)}
[react/view components.styles/flex
[react/view {:style styles/input-container
:important-for-accessibility :no-hide-descendants}
[input next-enabled?
{:step step
:error error
:password password
:password-confirm password-confirm}]
[react/text {:style styles/input-description}
(get-in steps [step :input-description])]]]])
(when (#{:enter-password :confirm-password :enter-name} step)
[react/view {:style styles/bottom-container}
[react/view {:style components.styles/flex}]
[components.common/bottom-button
{:forward? true
:disabled? (not next-enabled?)
:on-press #(re-frame/dispatch [:multiaccounts.create.ui/next-step-pressed step password password-confirm])}]])]))

View File

@ -16,8 +16,8 @@
[status-im.ui.screens.privacy-policy.views :as privacy-policy]
[status-im.react-native.resources :as resources]))
(defn multiaccount-view [{:keys [address photo-path name public-key keycard-instance-uid accounts]}]
[react/touchable-highlight {:on-press #(re-frame/dispatch [:multiaccounts.login.ui/multiaccount-selected address photo-path name public-key accounts])}
(defn multiaccount-view [{:keys [address photo-path name public-key keycard-instance-uid]}]
[react/touchable-highlight {:on-press #(re-frame/dispatch [:multiaccounts.login.ui/multiaccount-selected address photo-path name public-key])}
[react/view styles/multiaccount-view
[photos/photo photo-path {:size styles/multiaccount-image-size}]
[react/view styles/multiaccount-badge-text-view

View File

@ -137,7 +137,8 @@
:active? logged-in?
:action-fn #(re-frame/dispatch [:multiaccounts.logout.ui/logout-pressed])}]]]]))
(defview advanced-settings [{:keys [network networks dev-mode? settings]} on-show supported-biometric-auth]
(defview advanced-settings
[{:keys [network :networks/networks chaos-mode? dev-mode? settings]} on-show supported-biometric-auth]
{:component-did-mount on-show}
[react/view
(when (and config/extensions-enabled? dev-mode?)
@ -209,7 +210,7 @@
[profile.components/settings-item-separator]
[profile.components/settings-switch-item
{:label-kw :t/chaos-mode
:value (:chaos-mode? settings)
:value chaos-mode?
:action-fn #(re-frame/dispatch [:multiaccounts.ui/chaos-mode-switched %])}]
(when dev-mode?
[profile.components/settings-item-separator]

View File

@ -1,7 +1,6 @@
(ns status-im.ui.screens.routing.screens
(:require [status-im.extensions.module :as extensions.module]
[status-im.ui.screens.about-app.views :as about-app]
[status-im.ui.screens.multiaccounts.create.views :as multiaccounts.create]
[status-im.ui.screens.multiaccounts.login.views :as login]
[status-im.ui.screens.multiaccounts.recover.views :as multiaccounts.recover]
[status-im.ui.screens.multiaccounts.views :as multiaccounts]
@ -70,7 +69,6 @@
(def all-screens
{:login login/login
:progress progress/progress
:create-multiaccount multiaccounts.create/create-multiaccount
:recover-multiaccount multiaccounts.recover/recover
:recover-multiaccount-enter-phrase multiaccounts.recover/enter-phrase
:recover-multiaccount-select-storage multiaccounts.recover/select-storage

View File

@ -11,7 +11,7 @@
cofx))
(def ^:private mergable-keys
#{:data-store/tx :data-store/base-tx :chat-received-message/add-fx
#{:data-store/tx :chat-received-message/add-fx
:shh/post :filters/load-filters
:pairing/set-installation-metadata
:status-im.data-store.messages/save-message
@ -39,8 +39,8 @@
The next forms are functions applying effects and returning a map of effects.
The fn ensures that updates to db are passed from function to function within the cofx :db key and
that only a :merging-fx-with-common-keys effect is returned if some functions are trying
to produce the same effects (excepted :db, :data-source/tx and :data-source/base-tx effects).
:data-source/tx and :data-source/base-tx effects are handled specially and their results
to produce the same effects (excepted :db, :data-source/tx effects).
:data-source/tx and effects are handled specially and their results
(list of transactions) are compacted to one transactions list (for each effect). "
[{:keys [db] :as cofx} & args]
(let [[first-arg & rest-args] args

View File

@ -1,4 +1,5 @@
(ns status-im.utils.types)
(ns status-im.utils.types
(:require [cognitect.transit :as transit]))
(defn to-string [s]
(if (keyword? s)
@ -13,3 +14,9 @@
(try
(js->clj (.parse js/JSON json) :keywordize-keys true)
(catch js/Error _ (when (string? json) json)))))
(def reader (transit/reader :json))
(def writer (transit/writer :json))
(defn serialize [o] (transit/write writer o))
(defn deserialize [o] (try (transit/read reader o) (catch :default e nil)))

View File

@ -67,4 +67,4 @@
(multiaccounts.update/multiaccount-update {:accounts (conj accounts new-account)
:latest-derived-path (inc latest-derived-path)} nil)
(wallet/update-balances nil)
(navigation/navigate-to-cofx :wallet nil))))
(navigation/navigate-to-cofx :wallet nil))))

View File

@ -211,7 +211,7 @@
(fx/defn update-prices
[{{:keys [network-status :wallet/all-tokens]
{:keys [address settings]} :multiaccount :as db} :db}]
{:keys [address chaos-mode? settings]} :multiaccount :as db} :db}]
(let [chain (ethereum/chain-keyword db)
mainnet? (= :mainnet chain)
assets (get-in settings [:wallet :visible-tokens chain])
@ -228,7 +228,7 @@
:mainnet? mainnet?
:success-event :wallet.callback/update-prices-success
:error-event :wallet.callback/update-prices-fail
:chaos-mode? (:chaos-mode? settings)}
:chaos-mode? chaos-mode?}
:db
(-> db
@ -313,7 +313,9 @@
{:events [:wallet.ui/sign-transaction-button-clicked]}
[{:keys [db] :as cofx}]
(let [{:keys [to symbol amount from]} (get-in cofx [:db :wallet :send-transaction])
{:keys [symbol address]} (tokens/asset-for (:wallet/all-tokens db) (keyword (:chain db)) symbol)
{:keys [symbol address]} (tokens/asset-for (:wallet/all-tokens db)
(ethereum/chain-keyword db)
symbol)
amount-hex (str "0x" (abi-spec/number-to-hex amount))
to-norm (ethereum/normalized-address to)]
(signing/sign cofx {:tx-obj (if (= symbol :ETH)

View File

@ -2,7 +2,11 @@
(:require [status-im.ethereum.core :as ethereum]
[status-im.js-dependencies :as dependencies]
[status-im.native-module.core :as status]
[taoensso.timbre :as log]))
[taoensso.timbre :as log]
[status-im.data-store.core :as data-store]
[re-frame.core :as re-frame]
[status-im.utils.handlers :as handlers]
[status-im.utils.fx :as fx]))
(defn make-internal-web3
"This Web3 object will allow access to private RPC calls
@ -19,28 +23,18 @@
(log/warn :web3-response-error)
(callback nil (.parse js/JSON response))))))})))
(defn get-web3 [cofx]
(let [web3 (make-internal-web3)]
(assoc cofx :web3 web3)))
(fx/defn initialization-success
{:events [::initialization-success]}
[{:keys [db]} web3 address password login?]
{:db (assoc db :web3 web3)
(if login?
::data-store/change-multiaccount
::data-store/create-multiaccount) [address password]})
;;; FX
(defn set-default-account
[web3 address]
(set! (.-defaultAccount (.-eth web3))
(ethereum/normalized-address address)))
(defn fetch-node-version
[web3 cb]
(.. web3
-version
(getNode
(fn [err resp]
(if-not err
(cb resp)
(log/warn (str "unable to obtain web3 version:" err)))))))
(defn fetch-node-version-callback
[resp {:keys [db]}]
(if-let [node-version (second (re-find #"StatusIM/v(.*)/.*/.*" resp))]
{:db (assoc db :web3-node-version node-version)}
(log/warn (str "unexpected web3 version format: " "'" resp "'"))))
(re-frame/reg-fx
::initialize
(fn [[address password login?]]
(let [web3 (make-internal-web3)]
(set! (.-defaultAccount (.-eth web3))
(ethereum/normalized-address address))
(re-frame/dispatch [::initialization-success web3 address password login?]))))

View File

@ -1,26 +0,0 @@
(ns status-im.web3.events
(:require [re-frame.core :as re-frame]
[status-im.utils.handlers :as handlers]
[status-im.web3.core :as web3]))
;;;; COFX
(re-frame/reg-cofx
:web3/get-web3
web3/get-web3)
;;;; FX
(re-frame/reg-fx
:web3/set-default-account
(fn [[web3 address]]
(web3/set-default-account web3 address)))
(re-frame/reg-fx
:web3/fetch-node-version
(fn [[web3 cb]]
(web3/fetch-node-version web3 cb)))
;;;; Events
(handlers/register-handler-fx
:web3/fetch-node-version-callback
(fn [cofx [_ resp]]
(web3/fetch-node-version-callback resp cofx)))

View File

@ -97,7 +97,7 @@
(testing "it adds the relevant rpc calls"
(let [actual (chat/clear-history cofx chat-id)]
(is (::json-rpc/call actual))
(is (= 1 (count (::json-rpc/call actual))))))))
(is (= 2 (count (::json-rpc/call actual))))))))
(deftest remove-chat-test
(let [chat-id "1"

View File

@ -2,70 +2,71 @@
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.hardwallet.core :as hardwallet]))
(deftest process-pin-input
(testing "start entering PIN"
(is (= {:db {:hardwallet {:pin {:original [1]
:confirmation []
:status nil
:enter-step :original}}}}
(hardwallet/process-pin-input {:db {:hardwallet {:pin {:original [1]
:confirmation []
:enter-step :original}}}}))))
(testing "first 6 numbers entered"
(is (= {:db {:hardwallet {:pin {:original [1 2 3 4 5 6]
:confirmation []
:status nil
:enter-step :confirmation}}}}
(hardwallet/process-pin-input {:db {:hardwallet {:pin {:original [1 2 3 4 5 6]
:confirmation []
:enter-step :original}}}}))))
(testing "confirmation entered"
(is (= {:db {:hardwallet {:pin {:original [1 2 3 4 5 6]
:confirmation [1 2 3 4 5 6]
:current [1 1 1 1 1 1]
:enter-step :confirmation
:status :verifying}
:card-connected? true}}
:hardwallet/change-pin {:new-pin "123456"
:current-pin "111111"
:pairing nil}}
(hardwallet/process-pin-input {:db {:hardwallet {:pin {:original [1 2 3 4 5 6]
:confirmation [1 2 3 4 5 6]
:current [1 1 1 1 1 1]
:enter-step :confirmation}
:card-connected? true}}}))))
;;TODO re-enable after fixing hardwallet flow
#_(deftest process-pin-input
(testing "start entering PIN"
(is (= {:db {:hardwallet {:pin {:original [1]
:confirmation []
:status nil
:enter-step :original}}}}
(hardwallet/process-pin-input {:db {:hardwallet {:pin {:original [1]
:confirmation []
:enter-step :original}}}}))))
(testing "first 6 numbers entered"
(is (= {:db {:hardwallet {:pin {:original [1 2 3 4 5 6]
:confirmation []
:status nil
:enter-step :confirmation}}}}
(hardwallet/process-pin-input {:db {:hardwallet {:pin {:original [1 2 3 4 5 6]
:confirmation []
:enter-step :original}}}}))))
(testing "confirmation entered"
(is (= {:db {:hardwallet {:pin {:original [1 2 3 4 5 6]
:confirmation [1 2 3 4 5 6]
:current [1 1 1 1 1 1]
:enter-step :confirmation
:status :verifying}
:card-connected? true}}
:hardwallet/change-pin {:new-pin "123456"
:current-pin "111111"
:pairing nil}}
(hardwallet/process-pin-input {:db {:hardwallet {:pin {:original [1 2 3 4 5 6]
:confirmation [1 2 3 4 5 6]
:current [1 1 1 1 1 1]
:enter-step :confirmation}
:card-connected? true}}}))))
(testing "confirmation doesn't match"
(is (= {:db {:hardwallet {:pin {:original []
:confirmation []
:enter-step :original
:error-label :t/pin-mismatch
:status :error}}}}
(hardwallet/process-pin-input {:db {:hardwallet {:pin {:original [1 2 3 4 5 6]
:confirmation [1 2 3 4 5 7]
:enter-step :confirmation}}}})))))
(testing "confirmation doesn't match"
(is (= {:db {:hardwallet {:pin {:original []
:confirmation []
:enter-step :original
:error-label :t/pin-mismatch
:status :error}}}}
(hardwallet/process-pin-input {:db {:hardwallet {:pin {:original [1 2 3 4 5 6]
:confirmation [1 2 3 4 5 7]
:enter-step :confirmation}}}})))))
(deftest on-generate-and-load-key-success
(is (= (select-keys
(get-in
(hardwallet/on-generate-and-load-key-success
{:random-guid-generator (constantly "")
:signing-phrase ""
:status ""
:db {}}
#js {"whisper-private-key" "f342f3ef17ce86abfa92b912b3a108a4546cfc687fd8e0f02fedf87a60ee4c0f"
"whisper-public-key" "04de2e21f1642ebee03b9aa4bf1936066124cc89967eaf269544c9b90c539fd5c980166a897d06dd4d3732b38116239f63c89395a8d73eac72881fab802010cb56"
"encryption-public-key" "04f2a432677a1b7c4f1bb22078135821d1d10fce23422297b5c808a545f2b61cdba38ee7394762172fc6ff5e9e28db7535e555efe2812905ffd4e0c25e82a98ae8"
"whisper-address" "87df2285f90b71221fab6267b7cb37532fedbb1f"
"wallet-address" "7e92236392a850980d00d0cd2a4b92886bd7fe7b"})
[:db :hardwallet :multiaccount])
[:whisper-private-key
:whisper-public-key
:encryption-public-key
:wallet-address
:whisper-address]))
{:whisper-private-key "f342f3ef17ce86abfa92b912b3a108a4546cfc687fd8e0f02fedf87a60ee4c0f"
:whisper-public-key "0x04de2e21f1642ebee03b9aa4bf1936066124cc89967eaf269544c9b90c539fd5c980166a897d06dd4d3732b38116239f63c89395a8d73eac72881fab802010cb56"
:encryption-public-key "04f2a432677a1b7c4f1bb22078135821d1d10fce23422297b5c808a545f2b61cdba38ee7394762172fc6ff5e9e28db7535e555efe2812905ffd4e0c25e82a98ae8"
:whisper-address "87df2285f90b71221fab6267b7cb37532fedbb1f"
:wallet-address "7e92236392a850980d00d0cd2a4b92886bd7fe7b"}))
#_(deftest on-generate-and-load-key-success
(is (= (select-keys
(get-in
(hardwallet/on-generate-and-load-key-success
{:random-guid-generator (constantly "")
:signing-phrase ""
:status ""
:db {}}
#js {"whisper-private-key" "f342f3ef17ce86abfa92b912b3a108a4546cfc687fd8e0f02fedf87a60ee4c0f"
"whisper-public-key" "04de2e21f1642ebee03b9aa4bf1936066124cc89967eaf269544c9b90c539fd5c980166a897d06dd4d3732b38116239f63c89395a8d73eac72881fab802010cb56"
"encryption-public-key" "04f2a432677a1b7c4f1bb22078135821d1d10fce23422297b5c808a545f2b61cdba38ee7394762172fc6ff5e9e28db7535e555efe2812905ffd4e0c25e82a98ae8"
"whisper-address" "87df2285f90b71221fab6267b7cb37532fedbb1f"
"wallet-address" "7e92236392a850980d00d0cd2a4b92886bd7fe7b"})
[:db :hardwallet :multiaccount])
[:whisper-private-key
:whisper-public-key
:encryption-public-key
:wallet-address
:whisper-address]))
{:whisper-private-key "f342f3ef17ce86abfa92b912b3a108a4546cfc687fd8e0f02fedf87a60ee4c0f"
:whisper-public-key "0x04de2e21f1642ebee03b9aa4bf1936066124cc89967eaf269544c9b90c539fd5c980166a897d06dd4d3732b38116239f63c89395a8d73eac72881fab802010cb56"
:encryption-public-key "04f2a432677a1b7c4f1bb22078135821d1d10fce23422297b5c808a545f2b61cdba38ee7394762172fc6ff5e9e28db7535e555efe2812905ffd4e0c25e82a98ae8"
:whisper-address "87df2285f90b71221fab6267b7cb37532fedbb1f"
:wallet-address "7e92236392a850980d00d0cd2a4b92886bd7fe7b"}))

View File

@ -170,6 +170,4 @@
actual (model/delete cofx "a")]
(testing "it removes the bootnode"
(is (not (model/fetch actual "a"))))
(testing "it updates the db"
(is (= 1 (count (:data-store/base-tx actual))))))))
(is (not (model/fetch actual "a")))))))

View File

@ -122,13 +122,13 @@
:db {:networks/manage {:url {:value "http://valid.com"}
:chain {:value :mainnet}
:name {:value "valid"}}
:multiaccount {:networks {"randomid"
{:id "randomid"
:name "network-name"
:config {:NetworkId 1
:DataDir "/ethereum/mainnet_rpc"
:UpstreamConfig {:Enabled true
:URL "upstream-url"}}}}}}}
:multiaccount {:networks/networks {"randomid"
{:id "randomid"
:name "network-name"
:config {:NetworkId 1
:DataDir "/ethereum/mainnet_rpc"
:UpstreamConfig {:Enabled true
:URL "upstream-url"}}}}}}}
{:chain-id-unique? true
:on-failure #(reset! failure true)})
(is @failure)))))
@ -139,13 +139,13 @@
:db {:networks/manage {:url {:value "http://valid.com"}
:chain {:value :mainnet}
:name {:value "valid"}}
:multiaccount {:networks {"randomid"
{:id "randomid"
:name "network-name"
:config {:NetworkId 3
:DataDir "/ethereum/mainnet_rpc"
:UpstreamConfig {:Enabled true
:URL "upstream-url"}}}}}}}
:multiaccount {:networks/networks {"randomid"
{:id "randomid"
:name "network-name"
:config {:NetworkId 3
:DataDir "/ethereum/mainnet_rpc"
:UpstreamConfig {:Enabled true
:URL "upstream-url"}}}}}}}
{:chain-id-unique? true})))))
(deftest save-with-id-override
@ -156,15 +156,15 @@
:name {:value "valid"}}
:multiaccount {}}}
{:network-id "override"})]
(is (some? (get-in result [:db :multiaccount :networks "override"]))))))
(is (some? (get-in result [:db :multiaccount :networks/networks "override"]))))))
(deftest get-network-id-for-chain-id
(testing "get the first network id for the given chain-id"
(is (= "randomid" (model/get-network-id-for-chain-id {:db {:multiaccount {:networks {"randomid"
{:id "randomid"
:name "network-name"
:config {:NetworkId 1
:DataDir "/ethereum/mainnet_rpc"
:UpstreamConfig {:Enabled true
:URL "upstream-url"}}}}}}}
(is (= "randomid" (model/get-network-id-for-chain-id {:db {:multiaccount {:networks/networks {"randomid"
{:id "randomid"
:name "network-name"
:config {:NetworkId 1
:DataDir "/ethereum/mainnet_rpc"
:UpstreamConfig {:Enabled true
:URL "upstream-url"}}}}}}}
1)))))

View File

@ -1,10 +1,11 @@
(ns status-im.test.init.core
(ns status-im.test.multiaccounts.login.core
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.init.core :as init]))
[status-im.multiaccounts.login.core :as login]
[clojure.string :as string]))
(deftest initialize-multiaccount-db
(testing "it preserves universal-links/url"
(is (= "some-url" (get-in (init/initialize-multiaccount-db
(is (= "some-url" (get-in (login/initialize-multiaccount-db
{:db {:universal-links/url "some-url"}}
"address")
[:db :universal-links/url])))))

View File

@ -1,13 +1,16 @@
(ns status-im.test.multiaccounts.update.core
(:require [clojure.test :refer-macros [deftest is]]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.multiaccounts.update.core :as multiaccounts.update]))
(deftest test-multiaccount-update
(is (= (multiaccounts.update/multiaccount-update {} nil)
{:db {:multiaccount {}},
:data-store/save-multiaccount {}})))
(let [efx (multiaccounts.update/multiaccount-update {:db {:multiaccount {}}} nil {})
json-rpc (into #{} (map :method (::json-rpc/call efx)))]
(is (json-rpc "settings_saveConfig"))
(is (= (get-in efx [:db :multiaccount]) {}))))
(deftest test-clean-seed-phrase
(is (= (multiaccounts.update/clean-seed-phrase nil)
{:db {:multiaccount {:seed-backed-up? true, :mnemonic nil}},
:data-store/save-multiaccount {:seed-backed-up? true, :mnemonic nil}})))
(let [efx (multiaccounts.update/clean-seed-phrase {:db {:multiaccount {:mnemonic "lalalala"}}})
json-rpc (into #{} (map :method (::json-rpc/call efx)))]
(is (json-rpc "settings_saveConfig"))
(is (= (get-in efx [:db :multiaccount]) {:seed-backed-up? true, :mnemonic nil}))))

View File

@ -1,18 +0,0 @@
(ns status-im.test.node.core
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.utils.config :as config]
[status-im.node.core :as node]))
(defn- parse-node-config [config]
(-> config
:node/start
(js/JSON.parse)
(js->clj :keywordize-keys true)
:ShhextConfig))
(deftest start-test
(let [address "a"
cofx {:db {:multiaccounts/multiaccounts {address {:installation-id "id"}}}}]
(testing "installation-id"
(let [actual (parse-node-config (node/start cofx address))]
(is (= "id" (:InstallationID actual)))))))

View File

@ -33,7 +33,7 @@
:multiaccount {:public-key nil}
:push-notifications/stored {"0x04d2e59a7501a7bc5bc8bf973a0ab95d06225e2b0f53d5f6be719d857c579bdc1b809bfbe0e8393343f9a5b63a9a90a1a58329c6d1c286d6929f01aaa5472ca9c2"
"0x045db1fdb16c4721ddf32e892c5156d9c7a7445482b84ccd41131eb7970f9d623629d86763c5c2a542ae372815125c27eb73535d583d3285bdbfa16ba37f42e2de"}}
:dispatch [:ui/open-login "bd36cd64e2621b054a3b7464ff1b3c4c304880e7" "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAADAFBMVEX" "Bob" nil]}
:dispatch [:ui/open-login "bd36cd64e2621b054a3b7464ff1b3c4c304880e7" "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAADAFBMVEX" "Bob"]}
(notifications/handle-push-notification-open {:db {:multiaccounts/multiaccounts {"bd36cd64e2621b054a3b7464ff1b3c4c304880e7" {:address "bd36cd64e2621b054a3b7464ff1b3c4c304880e7"
:photo-path "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAADAFBMVEX"
:name "Bob"

View File

@ -302,7 +302,8 @@
expected {"installation-1" installation-1
"installation-2" {:has-bundle? true
:installation-id "installation-2"}}]
(is (:pairing/get-our-installations (pairing/handle-bundles-added cofx new-installation)))))
(is ((into #{} (keys (pairing/handle-bundles-added cofx new-installation)))
:pairing/get-our-installations))))
(testing "not from us"
(let [new-installation {:identity "not-us" :installationID "does-not-matter"}]
(is (not (pairing/handle-bundles-added cofx new-installation)))))))
@ -340,4 +341,3 @@
:timestamp 9
:enabled? false}]]
(is (= expected (pairing/sort-installations id (shuffle expected))))))

View File

@ -33,16 +33,15 @@
[status-im.test.group-chats.core]
[status-im.test.hardwallet.core]
[status-im.test.i18n]
[status-im.test.init.core]
[status-im.test.mailserver.core]
[status-im.test.mailserver.topics]
[status-im.test.models.bootnode]
[status-im.test.models.contact]
[status-im.test.models.network]
[status-im.test.multiaccounts.model]
[status-im.test.multiaccounts.login.core]
[status-im.test.multiaccounts.recover.core]
[status-im.test.multiaccounts.update.core]
[status-im.test.node.core]
[status-im.test.pairing.core]
[status-im.test.search.core]
[status-im.test.sign-in.flow]
@ -120,7 +119,6 @@
'status-im.test.group-chats.core
'status-im.test.hardwallet.core
'status-im.test.i18n
'status-im.test.init.core
'status-im.test.mailserver.core
'status-im.test.mailserver.topics
'status-im.test.models.bootnode
@ -128,7 +126,8 @@
'status-im.test.models.network
'status-im.test.multiaccounts.model
'status-im.test.multiaccounts.recover.core
'status-im.test.node.core
'status-im.test.multiaccounts.login.core
'status-im.test.multiaccounts.update.core
'status-im.test.pairing.core
'status-im.test.search.core
'status-im.test.sign-in.flow

View File

@ -101,8 +101,7 @@
:KDO}
:xdai #{}
:poa #{}}}}
:dev-mode? false
:networks {"testnet" {:id "testnet"
:networks/networks {"testnet" {:id "testnet"
:name "Ropsten"
:config {:NetworkId 3
:DataDir "/ethereum/testnet"

View File

@ -5,199 +5,28 @@
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.events :as events]
[status-im.data-store.core :as data-store]
[status-im.multiaccounts.login.core :as login.core]
[status-im.web3.core :as web3]
[status-im.signals.core :as signals]
[status-im.test.sign-in.data :as data]))
(deftest on-password-input-submitted
(testing
"handling :multiaccounts.login.ui/password-input-submitted event"
(let [cofx {:db {:multiaccounts/multiaccounts {"address" {:settings {:fleet "fleet"}}}
:multiaccounts/login {:address "address"
:password "password"}}}
create-database? false
efx (login.core/user-login cofx create-database?)]
(testing "Web data cleared."
(is (contains? efx :multiaccounts.login/clear-web-data)))
(let [cofx {:db {:multiaccounts/login {:address "address"
:password "password"
:name "user"
:photo-path "photo"}}}
efx (login.core/login cofx)]
(testing "Change multiaccount."
(is (= (:data-store/change-multiaccount efx)
["address" "password" false "fleet"])))
(testing "set `node/on-ready` handler"
(is (= (get-in efx [:db :node/on-ready]) :login)))
(is (= (::login.core/login efx)
["{\"name\":\"user\",\"address\":\"address\",\"photo-path\":\"photo\"}" "password"])))
(testing "start activity indicator"
(is (= (get-in efx [:db :multiaccounts/login :processing]) true))))))
(deftest on-successful-multiaccount-change
(testing
"Multiaccount changed successfully: :init.callback/multiaccount-change-success
event is handled."
(let [db {:multiaccounts/login {:address "address"
:password "password"}
:node/on-ready :login
:multiaccounts/multiaccounts data/multiaccounts}
cofx {:db db
:web3 :web3
:all-installations []}
efx (events/multiaccount-change-success cofx [nil "address"])
new-db (:db efx)]
(testing "Starting node."
(is (contains? efx :node/start)))
(testing "Get fcm token."
(is (contains? efx :notifications/get-fcm-token)))
(testing "Request notifications permissions."
(is (contains? efx :notifications/request-notifications-permissions)))
(testing "Navigate to :home."
(is (= [:home nil] (efx :status-im.ui.screens.navigation/navigate-to))))
(testing "Multiaccount selected."
(is (contains? new-db :multiaccount))))))
(deftest decryption-failure-on-multiaccount-change
(testing ":init.callback/multiaccount-change-error event received."
(let [cofx {:db {}}
error {:error :decryption-failed}
efx (login.core/handle-change-multiaccount-error cofx error)
new-db (:db efx)]
(testing "Init multiaccount's password verification"
(is (= :verify-multiaccount (new-db :node/on-ready))))
(testing "Init multiaccount's password verification"
(is (= :decryption-failed (get-in new-db [:realm-error :error]))))
(testing "Start node."
(is (contains? efx :node/start))))))
(deftest database-does-not-exist-on-multiaccount-change
(testing ":init.callback/multiaccount-change-error event received."
(let [cofx {:db {}}
error {:error :database-does-not-exist}
efx (login.core/handle-change-multiaccount-error cofx error)
new-db (:db efx)]
(testing "Init multiaccount's password verification"
(is (= :verify-multiaccount (new-db :node/on-ready))))
(testing "Init multiaccount's password verification"
(is (= :database-does-not-exist (get-in new-db [:realm-error :error]))))
(testing "Start node."
(is (contains? efx :node/start))))))
(deftest migrations-failed-on-multiaccount-change
(testing ":init.callback/multiaccount-change-error event received."
(let [cofx {:db {}}
error {:error :migrations-failed}
efx (login.core/handle-change-multiaccount-error cofx error)]
(testing "Show migrations dialog."
(is (contains? efx :ui/show-confirmation))))))
(deftest unknown-realm-error-on-multiaccount-change
(testing ":init.callback/multiaccount-change-error event received."
(let [cofx {:db {}}
error {:error :unknown-error}
efx (login.core/handle-change-multiaccount-error cofx error)]
(testing "Show unknown error dialog."
(is (contains? efx :ui/show-confirmation))))))
(deftest on-node-started
(testing "node.ready signal received"
(let [cofx {:db {:multiaccounts/login {:address "address"
:password "password"}
:node/on-ready :login
:multiaccounts/multiaccounts data/multiaccounts
:multiaccount data/multiaccounts}}
efx (signals/status-node-started cofx)]
(testing "Change node's status to started."
(is (= :started (get-in efx [:db :node/status])))))))
(deftest on-node-started-for-verification
(testing "node.ready signal received"
(let [cofx {:db {:multiaccounts/login {:address "address"
:password "password"}
:node/on-ready :verify-multiaccount
:multiaccounts/multiaccounts data/multiaccounts
:multiaccount data/multiaccounts
:realm-error {:error :database-does-not-exist}}}
efx (signals/status-node-started cofx)]
(testing "Init VerifyAccountPassword call."
(is (= ["address" "password" {:error :database-does-not-exist}]
(:multiaccounts.login/verify efx))))
(testing "Change node's status to started."
(is (= :started (get-in efx [:db :node/status])))))))
(deftest on-verify-multiaccount-success-after-decryption-failure
(testing ":multiaccounts.login.callback/verify-success event received."
(let [cofx {:db {}}
verify-result "{\"error\":\"\"}"
realm-error {:error :decryption-failed}
efx (login.core/verify-callback cofx verify-result realm-error)]
(testing "Show dialog."
(is (contains? efx :ui/show-confirmation)))
(testing "Stop node."
(is (contains? efx :node/stop))))))
(deftest on-verify-multiaccount-success-after-database-does-not-exist
(testing ":multiaccounts.login.callback/verify-success event received."
(let [cofx {:db {:multiaccounts/multiaccounts {"address" {:settings {:fleet "fleet"}}}
:multiaccounts/login {:address "address"
:password "password"}}}
verify-result "{\"error\":\"\"}"
realm-error {:error :database-does-not-exist}
efx (login.core/verify-callback
cofx verify-result realm-error)]
(testing "Change multiaccount."
(is (= ["address" "password" true "fleet"]
(:data-store/change-multiaccount efx))))
(testing "Stop node."
(is (contains? efx :node/stop))))))
(deftest on-verify-multiaccount-failed
(testing ":multiaccounts.login.callback/verify-success event received."
(let [cofx {:db {:multiaccounts/login {:address "address"
:password "password"}}}
verify-result "{\"error\":\"some error\"}"
realm-error {:error :database-does-not-exist}
efx (login.core/verify-callback
cofx verify-result realm-error)
new-db (:db efx)]
(testing "Show error in sign in form."
(is (= "some error" (get-in new-db [:multiaccounts/login :error]))))
(testing "Hide activity indicator."
(is (= false (get-in new-db [:multiaccounts/login :processing]))))
(testing "Stop node."
(is (contains? efx :node/stop))))))
#_(deftest login-success
(testing ":accounts.login.callback/login-success event received."
(let [db {:accounts/login {:address "address"
:password "password"}
:account/account data/account
:semaphores #{}}
cofx {:db db
:data-store/mailservers []
:data-store/transport data/transport
:data-store/mailserver-topics data/topics}
login-result "{\"error\":\"\"}"
efx (login.core/user-login-callback cofx login-result)
new-db (:db efx)
json-rpc (into #{} (map :method (:json-rpc/call efx)))]
(testing ":accounts/login cleared."
(is (not (contains? new-db :accounts/login))))
(testing "Check messaging related effects."
(is (contains? efx :filters/load-filters))
(is (contains? efx :mailserver/add-peer))
(is (contains? efx :mailserver/update-mailservers))
(is (= #{{:ms 10000
:dispatch [:mailserver/check-connection-timeout]}
{:ms 10000
:dispatch [:protocol/state-sync-timed-out]}}
(set (:utils/dispatch-later efx)))))
(testing "Check the rest of effects."
(is (contains? efx :web3/set-default-account))
(is (contains? efx :web3/fetch-node-version))
(is (json-rpc "net_version"))
(is (json-rpc "eth_syncing"))
(is (contains? efx :wallet/get-balance))
(is (contains? efx :wallet/get-tokens-balance))
(is (contains? efx :wallet/get-prices))))))
(deftest login-failed
(testing
":multiaccounts.login.callback/login-success event received with error."
(deftest login-success
(testing ":accounts.login.callback/login-success event received."
(let [db {:multiaccounts/login {:address "address"
:password "password"}
:multiaccount data/multiaccount
@ -206,34 +35,29 @@
:data-store/mailservers []
:data-store/transport data/transport
:data-store/mailserver-topics data/topics}
login-result "{\"error\":\"Something went wrong!\"}"
efx (login.core/user-login-callback cofx login-result)
new-db (:db efx)]
(testing "Prevent saving of the password."
(is (= false (get-in new-db [:multiaccounts/login :save-password?]))))
(testing "Show error in sign in form."
(is (contains? (:multiaccounts/login new-db) :error)))
(testing "Stop activity indicator."
(is (= false (get-in new-db [:multiaccounts/login :processing]))))
(testing "Show error in sign in form."
(is (contains? (:multiaccounts/login new-db) :error)))
(testing "Show error popup."
(is (contains? efx :utils/show-popup)))
(testing "Logout."
(is (= [:multiaccounts.logout.ui/logout-confirmed] (:dispatch efx)))))))
login-result "{\"error\":\"\"}"
efx (login.core/multiaccount-login-success cofx)
new-db (:db efx)
json-rpc (into #{} (map :method (::json-rpc/call efx)))]
(testing ":accounts/login cleared."
(is (not (contains? new-db :multiaccounts/login))))
(testing "Check the rest of effects."
(is (contains? efx ::web3/initialize))
(is (json-rpc "web3_clientVersion"))))))
(deftest login
(testing "login with keycard"
(let [wpk "c56c7ac797c27b3790ce02c2459e9957c5d20d7a2c55320535526ce9e4dcbbef"
epk "04f43da85ff1c333f3e7277b9ac4df92c9120fbb251f1dede7d41286e8c055acfeb845f6d2654821afca25da119daff9043530b296ee0e28e202ba92ec5842d617"
db {:hardwallet {:multiaccount {:encryption-public-key epk
:whisper-private-key wpk
:wallet-address "83278851e290d2488b6add2a257259f5741a3b7d"
:whisper-public-key "0x04491c1272149d7fa668afa45968c9914c0661641ace7dbcbc585c15070257840a0b4b1f71ce66c2147e281e1a44d6231b4731a26f6cc0a49e9616bbc7fc2f1a93"
:whisper-address "b8bec30855ff20c2ddab32282e2b2c8c8baca70d"}}}
result (login.core/login {:db db})]
(is (= (-> result (get :hardwallet/login-with-keycard) keys count)
3))
(is (= (get-in result [:hardwallet/login-with-keycard :whisper-private-key wpk])))
(is (= (get-in result [:hardwallet/login-with-keycard :encryption-public-key epk])))
(is (fn? (get-in result [:hardwallet/login-with-keycard :on-result]))))))
;;TODO re-enable when keycard is fixed
#_(deftest login
(testing "login with keycard"
(let [wpk "c56c7ac797c27b3790ce02c2459e9957c5d20d7a2c55320535526ce9e4dcbbef"
epk "04f43da85ff1c333f3e7277b9ac4df92c9120fbb251f1dede7d41286e8c055acfeb845f6d2654821afca25da119daff9043530b296ee0e28e202ba92ec5842d617"
db {:hardwallet {:multiaccount {:encryption-public-key epk
:whisper-private-key wpk
:wallet-address "83278851e290d2488b6add2a257259f5741a3b7d"
:whisper-public-key "0x04491c1272149d7fa668afa45968c9914c0661641ace7dbcbc585c15070257840a0b4b1f71ce66c2147e281e1a44d6231b4731a26f6cc0a49e9616bbc7fc2f1a93"
:whisper-address "b8bec30855ff20c2ddab32282e2b2c8c8baca70d"}}}
result (login.core/login {:db db})]
(is (= (-> result (get :hardwallet/login-with-keycard) keys count)
3))
(is (= (get-in result [:hardwallet/login-with-keycard :whisper-private-key wpk])))
(is (= (get-in result [:hardwallet/login-with-keycard :encryption-public-key epk])))
(is (fn? (get-in result [:hardwallet/login-with-keycard :on-result]))))))

View File

@ -52,7 +52,7 @@
{:db {:multiaccount
{:address "954d4393515747ea75808a0301fb73317ae1e460"
:network "testnet_rpc"
:networks {"testnet_rpc" {:config {:NetworkId 3}}}
:networks/networks {"testnet_rpc" {:config {:NetworkId 3}}}
:settings {:tribute-to-talk {:testnet {:snt-amount "1000000000000000000"}}}}
:contacts/contacts
{recipient-pk {:name "bob"
@ -87,10 +87,10 @@
:multiaccount
{:public-key my-public-key
:network "mainnet_rpc"
:networks {"mainnet_rpc" {:id "mainnet_rpc"
:config {:NetworkId 1}}
"testnet_rpc" {:id "testnet_rpc"
:config {:NetworkId 3}}}}})
:networks/networks {"mainnet_rpc" {:id "mainnet_rpc"
:config {:NetworkId 1}}
"testnet_rpc" {:id "testnet_rpc"
:config {:NetworkId 3}}}}})
(deftest check-tribute
(testing "No contract in network, own public key"

View File

@ -69,7 +69,7 @@
(def ttt-enabled-multiaccount
{:db {:multiaccount {:network "testnet_rpc"
:networks {"testnet_rpc" {:config {:NetworkId 3}}}
:networks/networks {"testnet_rpc" {:config {:NetworkId 3}}}
:settings {:tribute-to-talk {:testnet {:snt-amount "1000000000000000000"}}}}
:contacts/contacts user-contacts
:wallet {:transactions
@ -81,7 +81,7 @@
(def ttt-disabled-multiaccount
{:db {:multiaccount {:network "testnet_rpc"
:networks {"testnet_rpc" {:config {:NetworkId 3}}}
:networks/networks {"testnet_rpc" {:config {:NetworkId 3}}}
:settings {:tribute-to-talk {}}}
:contacts/contacts user-contacts}})

View File

@ -11,7 +11,6 @@
(deftest set-currency
(let [cofx (models/set-currency {:db {:multiaccount {:settings {:wallet {}}}}} :usd)]
(is (= [:db :wallet/get-prices :data-store/base-tx] (keys cofx)))
(is (= :usd (get-in cofx [:db :multiaccount :settings :wallet :currency]))))
(is (= :jpy (get-in (models/set-currency {:db {:multiaccount {:settings {:wallet {}}}}} :jpy)
[:db :multiaccount :settings :wallet :currency]))))