#import "RCTStatus.h" #import "ReactNativeConfig.h" #import "React/RCTBridge.h" #import "React/RCTEventDispatcher.h" #import "Statusgo.h" #import "SSZipArchive.h" @interface NSDictionary (BVJSONString) -(NSString*) bv_jsonStringWithPrettyPrint:(BOOL) prettyPrint; @end @implementation NSDictionary (BVJSONString) -(NSString*) bv_jsonStringWithPrettyPrint:(BOOL) prettyPrint { NSError *error; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self options:(NSJSONWritingOptions) (prettyPrint ? NSJSONWritingPrettyPrinted : 0) error:&error]; if (! jsonData) { NSLog(@"bv_jsonStringWithPrettyPrint: error: %@", error.localizedDescription); return @"{}"; } else { return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; } } @end @interface NSArray (BVJSONString) - (NSString *)bv_jsonStringWithPrettyPrint:(BOOL)prettyPrint; @end @implementation NSArray (BVJSONString) -(NSString*) bv_jsonStringWithPrettyPrint:(BOOL) prettyPrint { NSError *error; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self options:(NSJSONWritingOptions) (prettyPrint ? NSJSONWritingPrettyPrinted : 0) error:&error]; if (! jsonData) { NSLog(@"bv_jsonStringWithPrettyPrint: error: %@", error.localizedDescription); return @"[]"; } else { return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; } } @end static RCTBridge *bridge; @implementation Status - (instancetype)init { self = [super init]; if (!self) { return nil; } // Subscribing to the signals from Status-Go StatusgoSetMobileSignalHandler(self); return self; } -(RCTBridge *)bridge { return bridge; } -(void)setBridge:(RCTBridge *)newBridge { bridge = newBridge; } - (void)handleSignal:(NSString *)signal { if(!signal){ #if DEBUG NSLog(@"SignalEvent nil"); #endif return; } #if DEBUG NSLog(@"[handleSignal] Received an event from Status-Go: %@", signal); #endif [bridge.eventDispatcher sendAppEventWithName:@"gethEvent" body:@{@"jsonEvent": signal}]; return; } RCT_EXPORT_MODULE(); //////////////////////////////////////////////////////////////////// #pragma mark - shouldMoveToInternalStorage //////////////////////////////////////////////////////////////////// shouldMoveToInternalStorage RCT_EXPORT_METHOD(shouldMoveToInternalStorage:(RCTResponseSenderBlock)onResultCallback) { // Android only onResultCallback(@[[NSNull null]]); } //////////////////////////////////////////////////////////////////// #pragma mark - moveToInternalStorage //////////////////////////////////////////////////////////////////// moveToInternalStorage RCT_EXPORT_METHOD(moveToInternalStorage:(RCTResponseSenderBlock)onResultCallback) { // Android only onResultCallback(@[[NSNull null]]); } //////////////////////////////////////////////////////////////////// #pragma mark - InitKeystore method //////////////////////////////////////////////////////////////////// StopNode RCT_EXPORT_METHOD(initKeystore:(NSString *)keyUID callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"initKeystore() method called"); #endif NSFileManager *fileManager = [NSFileManager defaultManager]; NSURL *rootUrl =[[fileManager URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject]; NSURL *commonKeystoreDir = [rootUrl URLByAppendingPathComponent:@"keystore"]; NSURL *keystoreDir = [commonKeystoreDir URLByAppendingPathComponent:keyUID]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { NSString *res = StatusgoInitKeystore(keystoreDir.path); NSLog(@"InitKeyStore result %@", res); callback(@[]); }); } //////////////////////////////////////////////////////////////////// #pragma mark - SendLogs method //////////////////////////////////////////////////////////////////// sendLogs RCT_EXPORT_METHOD(sendLogs:(NSString *)dbJson jsLogs:(NSString *)jsLogs callback:(RCTResponseSenderBlock)callback) { // TODO: Implement SendLogs for iOS #if DEBUG NSLog(@"SendLogs() method called, not implemented"); #endif NSFileManager *fileManager = [NSFileManager defaultManager]; NSError *error = nil; NSURL *rootUrl =[[fileManager URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject]; NSURL *zipFile = [rootUrl URLByAppendingPathComponent:@"logs.zip"]; [fileManager removeItemAtPath:zipFile.path error:nil]; NSURL *logsFolderName = [rootUrl URLByAppendingPathComponent:@"logs"]; if (![fileManager fileExistsAtPath:logsFolderName.path]) [fileManager createDirectoryAtPath:logsFolderName.path withIntermediateDirectories:YES attributes:nil error:&error]; NSURL *dbFile = [logsFolderName URLByAppendingPathComponent:@"db.json"]; NSURL *jsLogsFile = [logsFolderName URLByAppendingPathComponent:@"Status.log"]; #if DEBUG NSString *networkDirPath = @"ethereum/mainnet_rpc_dev"; #else NSString *networkDirPath = @"ethereum/mainnet_rpc"; #endif NSURL *networkDir = [rootUrl URLByAppendingPathComponent:networkDirPath]; NSURL *originalGethLogsFile = [networkDir URLByAppendingPathComponent:@"geth.log"]; NSURL *gethLogsFile = [logsFolderName URLByAppendingPathComponent:@"geth.log"]; [dbJson writeToFile:dbFile.path atomically:YES encoding:NSUTF8StringEncoding error:nil]; [jsLogs writeToFile:jsLogsFile.path atomically:YES encoding:NSUTF8StringEncoding error:nil]; //NSString* gethLogs = StatusgoExportNodeLogs(); //[gethLogs writeToFile:gethLogsFile.path atomically:YES encoding:NSUTF8StringEncoding error:nil]; [fileManager copyItemAtPath:originalGethLogsFile.path toPath:gethLogsFile.path error:nil]; [SSZipArchive createZipFileAtPath:zipFile.path withContentsOfDirectory:logsFolderName.path]; [fileManager removeItemAtPath:logsFolderName.path error:nil]; callback(@[zipFile.path]); } //////////////////////////////////////////////////////////////////// addPeer RCT_EXPORT_METHOD(exportLogs:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"exportLogs() method called"); #endif NSString *result = StatusgoExportNodeLogs(); callback(@[result]); } //////////////////////////////////////////////////////////////////// addPeer RCT_EXPORT_METHOD(addPeer:(NSString *)enode callback:(RCTResponseSenderBlock)callback) { NSString *result = StatusgoAddPeer(enode); callback(@[result]); #if DEBUG NSLog(@"AddPeer() method called"); #endif } //////////////////////////////////////////////////////////////////// getNodesFromContract RCT_EXPORT_METHOD(getNodesFromContract:(NSString *)url address:(NSString *) address callback:(RCTResponseSenderBlock)callback) { NSString* result = StatusgoGetNodesFromContract(url, address); callback(@[result]); #if DEBUG NSLog(@"GetNodesFromContract() method called"); #endif } //////////////////////////////////////////////////////////////////// chaosModeUpdate RCT_EXPORT_METHOD(chaosModeUpdate:(BOOL)on callback:(RCTResponseSenderBlock)callback) { NSString* result = StatusgoChaosModeUpdate(on); callback(@[result]); #if DEBUG NSLog(@"ChaosModeUpdate() method called"); #endif } //////////////////////////////////////////////////////////////////// multiAccountImportPrivateKey RCT_EXPORT_METHOD(deleteMultiaccount:(NSString *)keyUID callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"MultiAccountImportPrivateKey() method called"); #endif NSURL *multiaccountKeystoreDir = [self getKeyStoreDir:keyUID]; NSString *result = StatusgoDeleteMultiaccount(keyUID, multiaccountKeystoreDir.path); callback(@[result]); } //////////////////////////////////////////////////////////////////// multiAccountGenerateAndDeriveAddresses RCT_EXPORT_METHOD(multiAccountGenerateAndDeriveAddresses:(NSString *)json callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"MultiAccountGenerateAndDeriveAddresses() method called"); #endif NSString *result = StatusgoMultiAccountGenerateAndDeriveAddresses(json); callback(@[result]); } //////////////////////////////////////////////////////////////////// MultiAccountStoreAccount RCT_EXPORT_METHOD(multiAccountStoreAccount:(NSString *)json callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"MultiAccountStoreAccount() method called"); #endif NSString *result = StatusgoMultiAccountStoreAccount(json); callback(@[result]); } //////////////////////////////////////////////////////////////////// MultiAccountLoadAccount RCT_EXPORT_METHOD(multiAccountLoadAccount:(NSString *)json callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"MultiAccountLoadAccount() method called"); #endif NSString *result = StatusgoMultiAccountLoadAccount(json); callback(@[result]); } //////////////////////////////////////////////////////////////////// MultiAccountReset RCT_EXPORT_METHOD(multiAccountReset:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"MultiAccountReset() method called"); #endif NSString *result = StatusgoMultiAccountReset(); callback(@[result]); } //////////////////////////////////////////////////////////////////// multiAccountStoreDerived RCT_EXPORT_METHOD(multiAccountStoreDerived:(NSString *)json callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"MultiAccountStoreDerived() method called"); #endif NSString *result = StatusgoMultiAccountStoreDerivedAccounts(json); callback(@[result]); } //////////////////////////////////////////////////////////////////// multiAccountImportPrivateKey RCT_EXPORT_METHOD(multiAccountImportPrivateKey:(NSString *)json callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"MultiAccountImportPrivateKey() method called"); #endif NSString *result = StatusgoMultiAccountImportPrivateKey(json); callback(@[result]); } //////////////////////////////////////////////////////////////////// hashTransaction RCT_EXPORT_METHOD(hashTransaction:(NSString *)txArgsJSON callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"HashTransaction() method called"); #endif NSString *result = StatusgoHashTransaction(txArgsJSON); callback(@[result]); } //////////////////////////////////////////////////////////////////// hashMessage RCT_EXPORT_METHOD(hashMessage:(NSString *)message callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"hashMessage() method called"); #endif NSString *result = StatusgoHashMessage(message); callback(@[result]); } //////////////////////////////////////////////////////////////////// hashTypedData RCT_EXPORT_METHOD(hashTypedData:(NSString *)data callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"hashTypedData() method called"); #endif NSString *result = StatusgoHashTypedData(data); callback(@[result]); } //////////////////////////////////////////////////////////////////// hashTypedDataV4 RCT_EXPORT_METHOD(hashTypedDataV4:(NSString *)data callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"hashTypedDataV4() method called"); #endif NSString *result = StatusgoHashTypedDataV4(data); callback(@[result]); } //////////////////////////////////////////////////////////////////// sendTransactionWithSignature RCT_EXPORT_METHOD(sendTransactionWithSignature:(NSString *)txArgsJSON signature:(NSString *)signature callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"sendTransactionWithSignature() method called"); #endif NSString *result = StatusgoSendTransactionWithSignature(txArgsJSON, signature); callback(@[result]); } //////////////////////////////////////////////////////////////////// multiAccountImportMnemonic RCT_EXPORT_METHOD(multiAccountImportMnemonic:(NSString *)json callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"MultiAccountImportMnemonic() method called"); #endif NSString *result = StatusgoMultiAccountImportMnemonic(json); callback(@[result]); } //////////////////////////////////////////////////////////////////// multiAccountDeriveAddresses RCT_EXPORT_METHOD(multiAccountDeriveAddresses:(NSString *)json callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"MultiAccountDeriveAddresses() method called"); #endif NSString *result = StatusgoMultiAccountDeriveAddresses(json); callback(@[result]); } -(NSString *) getKeyUID:(NSString *)jsonString { NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; return [json valueForKey:@"key-uid"]; } //////////////////////////////////////////////////////////////////// prepareDirAndUpdateConfig -(NSString *) prepareDirAndUpdateConfig:(NSString *)config withKeyUID:(NSString *)keyUID { NSFileManager *fileManager = [NSFileManager defaultManager]; NSError *error = nil; NSURL *rootUrl =[[fileManager URLsForDirectory:NSLibraryDirectory 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"); NSString *keystore = @"keystore"; 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 *dataDirUrl = [NSURL fileURLWithPath:relativeDataDir]; NSURL *logUrl = [dataDirUrl URLByAppendingPathComponent:@"geth.log"]; NSString *keystoreDir = [@"/keystore/" stringByAppendingString:keyUID]; [configJSON setValue:keystoreDir forKey:@"KeyStoreDir"]; [configJSON setValue:@"" forKey:@"LogDir"]; [configJSON setValue:logUrl.path forKey:@"LogFile"]; NSString *resultingConfig = [configJSON bv_jsonStringWithPrettyPrint:NO]; NSLog(@"node config %@", resultingConfig); if(![fileManager fileExistsAtPath:absDataDir]) { [fileManager createDirectoryAtPath:absDataDir withIntermediateDirectories:YES attributes:nil error:nil]; } NSLog(@"logUrlPath %@ rootDir %@", logUrl.path, rootUrl.path); NSURL *absLogUrl = [absDataDirUrl URLByAppendingPathComponent:@"geth.log"]; 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 *)keyUID config:(NSString *)config callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"PrepareDirAndUpdateConfig() method called"); #endif NSString *updatedConfig = [self prepareDirAndUpdateConfig:config withKeyUID:keyUID]; callback(@[updatedConfig]); } //////////////////////////////////////////////////////////////////// saveAccountAndLogin RCT_EXPORT_METHOD(saveAccountAndLogin:(NSString *)multiaccountData password:(NSString *)password settings:(NSString *)settings config:(NSString *)config accountsData:(NSString *)accountsData) { #if DEBUG NSLog(@"SaveAccountAndLogin() method called"); #endif NSString *keyUID = [self getKeyUID:multiaccountData]; NSString *finalConfig = [self prepareDirAndUpdateConfig:config withKeyUID:keyUID]; NSString *result = StatusgoSaveAccountAndLogin(multiaccountData, password, settings, finalConfig, accountsData); NSLog(@"%@", result); } //////////////////////////////////////////////////////////////////// saveAccountAndLoginWithKeycard RCT_EXPORT_METHOD(saveAccountAndLoginWithKeycard:(NSString *)multiaccountData password:(NSString *)password settings:(NSString *)settings config:(NSString *)config accountsData:(NSString *)accountsData chatKey:(NSString *)chatKey) { #if DEBUG NSLog(@"SaveAccountAndLoginWithKeycard() method called"); #endif NSString *keyUID = [self getKeyUID:multiaccountData]; NSString *finalConfig = [self prepareDirAndUpdateConfig:config withKeyUID:keyUID]; NSString *result = StatusgoSaveAccountAndLoginWithKeycard(multiaccountData, password, settings, finalConfig, accountsData, chatKey); NSLog(@"%@", result); } - (NSURL *) getKeyStoreDir:(NSString *)keyUID { NSFileManager *fileManager = [NSFileManager defaultManager]; NSURL *rootUrl =[[fileManager URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject]; NSURL *oldKeystoreDir = [rootUrl URLByAppendingPathComponent:@"keystore"]; NSURL *multiaccountKeystoreDir = [oldKeystoreDir URLByAppendingPathComponent:keyUID]; return multiaccountKeystoreDir; } - (void) migrateKeystore:(NSString *)accountData password:(NSString *)password { NSFileManager *fileManager = [NSFileManager defaultManager]; NSURL *rootUrl =[[fileManager URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject]; NSString *keyUID = [self getKeyUID:accountData]; NSURL *oldKeystoreDir = [rootUrl URLByAppendingPathComponent:@"keystore"]; NSURL *multiaccountKeystoreDir = [self getKeyStoreDir:keyUID]; NSArray *keys = [fileManager contentsOfDirectoryAtPath:multiaccountKeystoreDir.path error:nil]; if (keys.count == 0) { NSString *migrationResult = StatusgoMigrateKeyStoreDir(accountData, password, oldKeystoreDir.path, multiaccountKeystoreDir.path); NSLog(@"keystore migration result %@", migrationResult); NSString *initKeystoreResult = StatusgoInitKeystore(multiaccountKeystoreDir.path); NSLog(@"InitKeyStore result %@", initKeystoreResult); } } //////////////////////////////////////////////////////////////////// login RCT_EXPORT_METHOD(login:(NSString *)accountData password:(NSString *)password) { #if DEBUG NSLog(@"Login() method called"); #endif [self migrateKeystore:accountData password:password]; NSString *result = StatusgoLogin(accountData, password); NSLog(@"%@", result); } //////////////////////////////////////////////////////////////////// loginWithKeycard RCT_EXPORT_METHOD(loginWithKeycard:(NSString *)accountData password:(NSString *)password chatKey:(NSString *)chatKey) { #if DEBUG NSLog(@"LoginWithKeycard() method called"); #endif [self migrateKeystore:accountData password:password]; NSString *result = StatusgoLoginWithKeycard(accountData, password, chatKey); 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:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject]; NSString *result = StatusgoOpenAccounts(rootUrl.path); callback(@[result]); } //////////////////////////////////////////////////////////////////// verityAccountPassword RCT_EXPORT_METHOD(verify:(NSString *)address password:(NSString *)password callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"VerifyAccountPassword() method called"); #endif NSFileManager *fileManager = [NSFileManager defaultManager]; NSURL *rootUrl =[[fileManager URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject]; NSURL *absKeystoreUrl = [rootUrl URLByAppendingPathComponent:@"keystore"]; NSString *result = StatusgoVerifyAccountPassword(absKeystoreUrl.path, address, password); callback(@[result]); } //////////////////////////////////////////////////////////////////// changeDatabasePassword RCT_EXPORT_METHOD(reEncryptDbAndKeystore:(NSString *)keyUID currentPassword:(NSString *)currentPassword newPassword:(NSString *)newPassword callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"reEncryptDbAndKeystore() method called"); #endif // changes password and re-encrypts keystore NSString *result = StatusgoChangeDatabasePassword(keyUID, currentPassword, newPassword); callback(@[result]); } //////////////////////////////////////////////////////////////////// #pragma mark - SendTransaction //////////////////////////////////////////////////////////////////// sendTransaction RCT_EXPORT_METHOD(sendTransaction:(NSString *)txArgsJSON password:(NSString *)password callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"SendTransaction() method called"); #endif NSString *result = StatusgoSendTransaction(txArgsJSON, password); callback(@[result]); } //////////////////////////////////////////////////////////////////// #pragma mark - SignMessage //////////////////////////////////////////////////////////////////// signMessage RCT_EXPORT_METHOD(signMessage:(NSString *)message callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"SignMessage() method called"); #endif NSString *result = StatusgoSignMessage(message); callback(@[result]); } //////////////////////////////////////////////////////////////////// #pragma mark - SignTypedData //////////////////////////////////////////////////////////////////// signTypedData RCT_EXPORT_METHOD(signTypedData:(NSString *)data account:(NSString *)account password:(NSString *)password callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"SignTypedData() method called"); #endif NSString *result = StatusgoSignTypedData(data, account, password); callback(@[result]); } //////////////////////////////////////////////////////////////////// #pragma mark - SignTypedDataV4 //////////////////////////////////////////////////////////////////// signTypedDataV4 RCT_EXPORT_METHOD(signTypedDataV4:(NSString *)data account:(NSString *)account password:(NSString *)password callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"SignTypedDataV4() method called"); #endif NSString *result = StatusgoSignTypedDataV4(data, account, password); callback(@[result]); } //////////////////////////////////////////////////////////////////// #pragma mark - SignGroupMembership //////////////////////////////////////////////////////////////////// signGroupMembership RCT_EXPORT_METHOD(signGroupMembership:(NSString *)content callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"SignGroupMembership() method called"); #endif NSString *result = StatusgoSignGroupMembership(content); callback(@[result]); } //////////////////////////////////////////////////////////////////// #pragma mark - ExtractGroupMembershipSignatures //////////////////////////////////////////////////////////////////// extractGroupMembershipSignatures RCT_EXPORT_METHOD(extractGroupMembershipSignatures:(NSString *)content callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"ExtractGroupMembershipSignatures() method called"); #endif NSString *result = StatusgoExtractGroupMembershipSignatures(content); callback(@[result]); } //////////////////////////////////////////////////////////////////// #pragma mark - GetNodeConfig //////////////////////////////////////////////////////////////////// getNodeConfig RCT_EXPORT_METHOD(getNodeConfig:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"GetNodeConfig() method called"); #endif NSString *result = StatusgoGetNodeConfig(); callback(@[result]); } //////////////////////////////////////////////////////////////////// #pragma mark - only android methods //////////////////////////////////////////////////////////////////// RCT_EXPORT_METHOD(setAdjustResize) { #if DEBUG NSLog(@"setAdjustResize() works only on Android"); #endif } RCT_EXPORT_METHOD(setAdjustPan) { #if DEBUG NSLog(@"setAdjustPan() works only on Android"); #endif } RCT_EXPORT_METHOD(setSoftInputMode: (NSInteger) i) { #if DEBUG NSLog(@"setSoftInputMode() works only on Android"); #endif } RCT_EXPORT_METHOD(clearCookies) { NSHTTPCookie *cookie; NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; for (cookie in [storage cookies]) { [storage deleteCookie:cookie]; } } RCT_EXPORT_METHOD(clearStorageAPIs) { [[NSURLCache sharedURLCache] removeAllCachedResponses]; NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil]; for (NSString *string in array) { NSLog(@"Removing %@", [path stringByAppendingPathComponent:string]); if ([[string pathExtension] isEqualToString:@"localstorage"]) [[NSFileManager defaultManager] removeItemAtPath:[path stringByAppendingPathComponent:string] error:nil]; } } RCT_EXPORT_METHOD(callRPC:(NSString *)payload callback:(RCTResponseSenderBlock)callback) { dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSString *result = StatusgoCallRPC(payload); dispatch_async(dispatch_get_main_queue(), ^{ callback(@[result]); }); }); } RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(generateAlias:(NSString *)publicKey) { return StatusgoGenerateAlias(publicKey); } RCT_EXPORT_METHOD(generateAliasAsync:(NSString *)publicKey callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"generateAliasAsync() method called"); #endif NSString *result = StatusgoGenerateAlias(publicKey); callback(@[result]); } RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(identicon:(NSString *)publicKey) { return StatusgoIdenticon(publicKey); } RCT_EXPORT_METHOD(validateMnemonic:(NSString *)seed callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"validateMnemonic() method called"); #endif NSString *result = StatusgoValidateMnemonic(seed); callback(@[result]); } RCT_EXPORT_METHOD(identiconAsync:(NSString *)publicKey callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"identiconAsync() method called"); #endif NSString *result = StatusgoIdenticon(publicKey); callback(@[result]); } RCT_EXPORT_METHOD(generateAliasAndIdenticonAsync:(NSString *)publicKey callback:(RCTResponseSenderBlock)callback) { #if DEBUG NSLog(@"generateAliasAndIdenticonAsync() method called"); #endif NSString *identiconResult = StatusgoIdenticon(publicKey); NSString *aliasResult = StatusgoGenerateAlias(publicKey); callback(@[aliasResult, identiconResult]); } RCT_EXPORT_METHOD(callPrivateRPC:(NSString *)payload callback:(RCTResponseSenderBlock)callback) { dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSString *result = StatusgoCallPrivateRPC(payload); dispatch_async(dispatch_get_main_queue(), ^{ callback(@[result]); }); }); } RCT_EXPORT_METHOD(closeApplication) { exit(0); } RCT_EXPORT_METHOD(connectionChange:(NSString *)type isExpensive:(BOOL)isExpensive) { #if DEBUG NSLog(@"ConnectionChange() method called"); #endif StatusgoConnectionChange(type, isExpensive ? 1 : 0); } RCT_EXPORT_METHOD(appStateChange:(NSString *)type) { #if DEBUG NSLog(@"AppStateChange() method called"); #endif StatusgoAppStateChange(type); } RCT_EXPORT_METHOD(stopLocalNotifications) { #if DEBUG NSLog(@"StopLocalNotifications() method called"); #endif StatusgoStopLocalNotifications(); } RCT_EXPORT_METHOD(startLocalNotifications) { #if DEBUG NSLog(@"StartLocalNotifications() method called"); #endif StatusgoStartLocalNotifications(); } RCT_EXPORT_METHOD(exportUnencryptedDatabase:(NSString *)accountData password:(NSString *)password) { #if DEBUG NSLog(@"exportUnencryptedDatabase() method called"); #endif ""; } RCT_EXPORT_METHOD(importUnencryptedDatabase:(NSString *)accountData password:(NSString *)password) { #if DEBUG NSLog(@"importUnencryptedDatabase() method called"); #endif ""; } RCT_EXPORT_METHOD(setBlankPreviewFlag:(BOOL *)newValue) { NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; [userDefaults setBool:newValue forKey:@"BLANK_PREVIEW"]; [userDefaults synchronize]; } RCT_EXPORT_METHOD(activateKeepAwake) { dispatch_async(dispatch_get_main_queue(), ^{ [[UIApplication sharedApplication] setIdleTimerDisabled:YES]; }); } RCT_EXPORT_METHOD(deactivateKeepAwake) { dispatch_async(dispatch_get_main_queue(), ^{ [[UIApplication sharedApplication] setIdleTimerDisabled:NO]; }); } //// deviceinfo - (bool) is24Hour { NSString *format = [NSDateFormatter dateFormatFromTemplate:@"j" options:0 locale:[NSLocale currentLocale]]; return ([format rangeOfString:@"a"].location == NSNotFound); } - (NSString *)getBuildId { return @"not available"; } - (NSString*) deviceId { struct utsname systemInfo; uname(&systemInfo); NSString* deviceId = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; if ([deviceId isEqualToString:@"i386"] || [deviceId isEqualToString:@"x86_64"] ) { deviceId = [NSString stringWithFormat:@"%s", getenv("SIMULATOR_MODEL_IDENTIFIER")]; } return deviceId; } - (NSString*) deviceName { NSString* deviceName = nil; if ([self.deviceId rangeOfString:@"iPod"].location != NSNotFound) { deviceName = @"iPod Touch"; } else if([self.deviceId rangeOfString:@"iPad"].location != NSNotFound) { deviceName = @"iPad"; } else if([self.deviceId rangeOfString:@"iPhone"].location != NSNotFound){ deviceName = @"iPhone"; } else if([self.deviceId rangeOfString:@"AppleTV"].location != NSNotFound){ deviceName = @"Apple TV"; } return deviceName; } - (NSDictionary *)constantsToExport { return @{ @"is24Hour": @(self.is24Hour), @"model": self.deviceName ?: [NSNull null], @"brand": @"Apple", @"buildId": [self getBuildId], @"deviceId": self.deviceId ?: [NSNull null], }; } + (BOOL)requiresMainQueueSetup { return NO; } @end