Keep the Monero wallet out of iCloud backups
This commit is contained in:
@@ -14,7 +14,22 @@ static std::string walletPath(NSString *name) {
|
|||||||
return std::string([dir stringByAppendingPathComponent:name].UTF8String);
|
return std::string([dir stringByAppendingPathComponent:name].UTF8String);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keep wallet files out of iCloud/iTunes backups: the seed in the Keychain is
|
||||||
|
// device-only and the file is rebuildable from it, so backing it up would only
|
||||||
|
// consume the user's quota (it peaks near 120 MB while a wallet restored from
|
||||||
|
// genesis scans). Must run after every write, since wallet2 rewrites these
|
||||||
|
// files on each save.
|
||||||
|
static void excludeWalletFilesFromBackup(const std::string &walletPathString) {
|
||||||
|
NSString *base = [NSString stringWithUTF8String:walletPathString.c_str()];
|
||||||
|
if (base.length == 0) return;
|
||||||
|
for (NSString *suffix in @[ @"", @".keys", @".address.txt", @".mms" ]) {
|
||||||
|
NSURL *url = [NSURL fileURLWithPath:[base stringByAppendingString:suffix]];
|
||||||
|
[url setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static monero_wallet_full *g_wallet = nullptr;
|
static monero_wallet_full *g_wallet = nullptr;
|
||||||
|
static std::string g_walletPath;
|
||||||
static NSString *g_daemonURL = @"xmr-node.cakewallet.com:18081";
|
static NSString *g_daemonURL = @"xmr-node.cakewallet.com:18081";
|
||||||
static NSArray<NSString *> *g_fallbackDaemons = nil;
|
static NSArray<NSString *> *g_fallbackDaemons = nil;
|
||||||
static std::atomic<bool> s_cachedConnected(false);
|
static std::atomic<bool> s_cachedConnected(false);
|
||||||
@@ -82,6 +97,8 @@ static void connectDaemon(monero_wallet_full *w) {
|
|||||||
connectDaemon(g_wallet);
|
connectDaemon(g_wallet);
|
||||||
resp[@"address"] = [NSString stringWithUTF8String:g_wallet->get_address(0, 0).c_str()];
|
resp[@"address"] = [NSString stringWithUTF8String:g_wallet->get_address(0, 0).c_str()];
|
||||||
try { resp[@"mnemonic"] = [NSString stringWithUTF8String:g_wallet->get_seed().c_str()]; } catch (...) {}
|
try { resp[@"mnemonic"] = [NSString stringWithUTF8String:g_wallet->get_seed().c_str()]; } catch (...) {}
|
||||||
|
g_walletPath = path;
|
||||||
|
excludeWalletFilesFromBackup(g_walletPath);
|
||||||
} else {
|
} else {
|
||||||
monero_wallet_config config;
|
monero_wallet_config config;
|
||||||
config.m_path = path;
|
config.m_path = path;
|
||||||
@@ -94,6 +111,8 @@ static void connectDaemon(monero_wallet_full *w) {
|
|||||||
connectDaemon(w);
|
connectDaemon(w);
|
||||||
resp[@"address"] = [NSString stringWithUTF8String:w->get_address(0, 0).c_str()];
|
resp[@"address"] = [NSString stringWithUTF8String:w->get_address(0, 0).c_str()];
|
||||||
resp[@"mnemonic"] = [NSString stringWithUTF8String:w->get_seed().c_str()];
|
resp[@"mnemonic"] = [NSString stringWithUTF8String:w->get_seed().c_str()];
|
||||||
|
g_walletPath = path;
|
||||||
|
excludeWalletFilesFromBackup(g_walletPath);
|
||||||
}
|
}
|
||||||
} else if ([op isEqualToString:@"openWallet"] || [op isEqualToString:@"restoreWallet"]) {
|
} else if ([op isEqualToString:@"openWallet"] || [op isEqualToString:@"restoreWallet"]) {
|
||||||
if (g_wallet) {
|
if (g_wallet) {
|
||||||
@@ -118,6 +137,8 @@ static void connectDaemon(monero_wallet_full *w) {
|
|||||||
g_wallet = monero_wallet_full::create_wallet(config, nullptr);
|
g_wallet = monero_wallet_full::create_wallet(config, nullptr);
|
||||||
}
|
}
|
||||||
connectDaemon(g_wallet);
|
connectDaemon(g_wallet);
|
||||||
|
g_walletPath = walletPath(req[@"name"]);
|
||||||
|
excludeWalletFilesFromBackup(g_walletPath);
|
||||||
resp[@"address"] = [NSString stringWithUTF8String:g_wallet->get_address(0, 0).c_str()];
|
resp[@"address"] = [NSString stringWithUTF8String:g_wallet->get_address(0, 0).c_str()];
|
||||||
} else if ([op isEqualToString:@"getSeed"]) {
|
} else if ([op isEqualToString:@"getSeed"]) {
|
||||||
if (g_wallet) {
|
if (g_wallet) {
|
||||||
@@ -145,12 +166,14 @@ static void connectDaemon(monero_wallet_full *w) {
|
|||||||
delete g_wallet;
|
delete g_wallet;
|
||||||
g_wallet = nullptr;
|
g_wallet = nullptr;
|
||||||
}
|
}
|
||||||
|
g_walletPath.clear();
|
||||||
} else if ([op isEqualToString:@"saveWallet"]) {
|
} else if ([op isEqualToString:@"saveWallet"]) {
|
||||||
// monero-cpp never persists while syncing, so scan progress survives a
|
// monero-cpp never persists while syncing, so scan progress survives a
|
||||||
// restart only if this is called explicitly. save() pauses the sync
|
// restart only if this is called explicitly. save() pauses the sync
|
||||||
// thread while it writes.
|
// thread while it writes.
|
||||||
if (g_wallet) {
|
if (g_wallet) {
|
||||||
g_wallet->save();
|
g_wallet->save();
|
||||||
|
excludeWalletFilesFromBackup(g_walletPath);
|
||||||
resp[@"saved"] = @YES;
|
resp[@"saved"] = @YES;
|
||||||
} else {
|
} else {
|
||||||
resp[@"error"] = @"No wallet open";
|
resp[@"error"] = @"No wallet open";
|
||||||
|
|||||||
Reference in New Issue
Block a user