forked from lthn/blockchain
Merge branch 'develop' of github.com:hyle-team/zano into develop
This commit is contained in:
commit
dc74da0ae6
22 changed files with 486 additions and 254 deletions
32
README.md
32
README.md
|
|
@ -30,7 +30,21 @@ Recommended OS version: Ubuntu 17.04 LTS.
|
|||
For GUI version:\
|
||||
`$ sudo apt-get install -y build-essential g++ python-dev autotools-dev libicu-dev libbz2-dev cmake git libboost-all-dev screen mesa-common-dev libglu1-mesa-dev qt5-default qtwebengine5-dev`
|
||||
|
||||
2. `$ cd zano/ && make -j$(nproc) gui`
|
||||
2. Building binaries \
|
||||
2.1. Building daemon and simplewallet: \
|
||||
`$ cd zano/ && make -j` \
|
||||
or \
|
||||
`$ cd zano && mkdir build && cd build `\
|
||||
`$ cmake .. `\
|
||||
`$ make -j daemon simplewallet` \
|
||||
2.2. Building GUI: \
|
||||
`$ cd zano/ && make -j gui ` \
|
||||
or \
|
||||
`$ cd zano && mkdir build && cd build `\
|
||||
`$ cmake -D BUILD_GUI=ON .. `\
|
||||
`$ make -j Zano` \
|
||||
`$ rsync -haP ~/zano/src/gui/qt-daemon/html ~/zano/build/src` \
|
||||
NOTICE: If you are building on machine with relatively small anount of RAM(small VPS for example, less then 16GB) and without proper setting of virtual memory, then be careful with setting `-j` option, this may cause compiller crashes.
|
||||
3. Look for the binaries, including the `Zano` GUI, in the build directory
|
||||
|
||||
### Windows
|
||||
|
|
@ -54,14 +68,14 @@ Recommended OS version: macOS Sierra 10.12.6 x64.
|
|||
|
||||
To build GUI application:
|
||||
|
||||
1. Create self-signing certificate via Keychain Access:
|
||||
a. Run Keychain Access.
|
||||
b. Choose Keychain Access > Certificate Assistant > Create a Certificate.
|
||||
c. Use “Zano” (without quotes) as certificate name.
|
||||
d. Choose “Code Signing” in “Certificate Type” field.
|
||||
e. Press “Create”, then “Done”.
|
||||
f. Make sure the certificate was added to keychain "System". If not—move it to "System".
|
||||
g. Double click the certificate you've just added, enter the trust section and under "When using this certificate" select "Always trust".
|
||||
1. Create self-signing certificate via Keychain Access:\
|
||||
a. Run Keychain Access.\
|
||||
b. Choose Keychain Access > Certificate Assistant > Create a Certificate.\
|
||||
c. Use “Zano” (without quotes) as certificate name.\
|
||||
d. Choose “Code Signing” in “Certificate Type” field.\
|
||||
e. Press “Create”, then “Done”.\
|
||||
f. Make sure the certificate was added to keychain "System". If not—move it to "System".\
|
||||
g. Double click the certificate you've just added, enter the trust section and under "When using this certificate" select "Always trust".\
|
||||
h. Unfold the certificate in Keychain Access window and double click underlying private key "Zano". Select "Access Control" tab, then select "Allow all applications to access this item". Click "Save Changes".
|
||||
2. Revise building script, comment out unwanted steps and run it: `utils/build_script_mac_osx.sh`
|
||||
3. The application should be here: `/buid_mac_osx_64/release/src`
|
||||
|
|
|
|||
|
|
@ -28,16 +28,21 @@ namespace currency
|
|||
|
||||
//-----------------------------------------------------------------
|
||||
account_base::account_base()
|
||||
:m_keys{}
|
||||
,m_creation_timestamp{}
|
||||
,m_seed{}
|
||||
{
|
||||
set_null();
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
void account_base::set_null()
|
||||
{
|
||||
// fill sensitive data with random bytes
|
||||
crypto::generate_random_bytes(sizeof m_keys.m_spend_secret_key, &m_keys.m_spend_secret_key);
|
||||
crypto::generate_random_bytes(sizeof m_keys.m_view_secret_key, &m_keys.m_view_secret_key);
|
||||
crypto::generate_random_bytes(m_seed.size(), &m_seed[0]);
|
||||
|
||||
// clear
|
||||
m_keys = account_keys();
|
||||
m_creation_timestamp = 0;
|
||||
m_seed.clear();
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
void account_base::generate()
|
||||
|
|
@ -65,6 +70,8 @@ namespace currency
|
|||
std::string account_base::get_restore_braindata() const
|
||||
{
|
||||
std::string restore_buff = get_restore_data();
|
||||
if (restore_buff.empty())
|
||||
return "";
|
||||
std::vector<unsigned char> v;
|
||||
v.assign((unsigned char*)restore_buff.data(), (unsigned char*)restore_buff.data() + restore_buff.size());
|
||||
std::string seed_brain_data = tools::mnemonic_encoding::binary2text(v);
|
||||
|
|
@ -124,7 +131,23 @@ namespace currency
|
|||
//-----------------------------------------------------------------
|
||||
void account_base::make_account_watch_only()
|
||||
{
|
||||
m_keys.m_spend_secret_key = currency::null_skey;
|
||||
// keep only:
|
||||
// timestamp
|
||||
// view pub & spend pub (public address)
|
||||
// view sec
|
||||
|
||||
// store to local tmp
|
||||
uint64_t local_ts = m_creation_timestamp;
|
||||
account_public_address local_addr = m_keys.m_account_address;
|
||||
crypto::secret_key local_view_sec = m_keys.m_view_secret_key;
|
||||
|
||||
// clear
|
||||
set_null();
|
||||
|
||||
// restore
|
||||
m_creation_timestamp = local_ts;
|
||||
m_keys.m_account_address = local_addr;
|
||||
m_keys.m_view_secret_key = local_view_sec;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
std::string transform_addr_to_str(const account_public_address& addr)
|
||||
|
|
|
|||
|
|
@ -676,7 +676,9 @@ std::string daemon_backend::open_wallet(const std::wstring& path, const std::str
|
|||
{
|
||||
try
|
||||
{
|
||||
w->load(path, password);
|
||||
w->load(path, password);
|
||||
if (w->is_watch_only())
|
||||
return API_RETURN_CODE_WALLET_WATCH_ONLY_NOT_SUPPORTED;
|
||||
w->get_recent_transfers_history(owr.recent_history.history, 0, txs_to_return, owr.recent_history.total_history_items);
|
||||
//w->get_unconfirmed_transfers(owr.recent_history.unconfirmed);
|
||||
w->get_unconfirmed_transfers(owr.recent_history.history);
|
||||
|
|
|
|||
|
|
@ -304,7 +304,9 @@ bool MainWindow::store_app_config()
|
|||
{
|
||||
TRY_ENTRY();
|
||||
std::string conf_path = m_backend.get_config_folder() + "/" + GUI_INTERNAL_CONFIG;
|
||||
return tools::serialize_obj_to_file(m_config, conf_path);
|
||||
LOG_PRINT_L0("storing gui internal config from " << conf_path);
|
||||
CHECK_AND_ASSERT_MES(tools::serialize_obj_to_file(m_config, conf_path), false, "failed to store gui internal config");
|
||||
return true;
|
||||
CATCH_ENTRY2(false);
|
||||
}
|
||||
|
||||
|
|
@ -312,7 +314,10 @@ bool MainWindow::load_app_config()
|
|||
{
|
||||
TRY_ENTRY();
|
||||
std::string conf_path = m_backend.get_config_folder() + "/" + GUI_INTERNAL_CONFIG;
|
||||
return tools::unserialize_obj_from_file(m_config, conf_path);
|
||||
LOG_PRINT_L0("loading gui internal config from " << conf_path);
|
||||
bool r = tools::unserialize_obj_from_file(m_config, conf_path);
|
||||
LOG_PRINT_L0("gui internal config " << (r ? "loaded ok" : "was not loaded"));
|
||||
return r;
|
||||
CATCH_ENTRY2(false);
|
||||
}
|
||||
|
||||
|
|
@ -1060,13 +1065,13 @@ QString MainWindow::get_secure_app_data(const QString& param)
|
|||
bool r = file_io_utils::load_file_to_string(filename, app_data_buff);
|
||||
if (!r)
|
||||
{
|
||||
LOG_PRINT_L1("config file was not loaded: " << m_backend.get_config_folder() + "/" + GUI_SECURE_CONFIG_FILENAME);
|
||||
LOG_PRINT_L1("gui secure config was not loaded from " << filename);
|
||||
return "";
|
||||
}
|
||||
|
||||
if (app_data_buff.size() < sizeof(app_data_file_binary_header))
|
||||
{
|
||||
LOG_ERROR("app_data_buff.size() < sizeof(app_data_file_binary_header) check failed");
|
||||
LOG_ERROR("app_data_buff.size() < sizeof(app_data_file_binary_header) check failed while loading from " << filename);
|
||||
view::api_response ar;
|
||||
ar.error_code = API_RETURN_CODE_FAIL;
|
||||
return MAKE_RESPONSE(ar);
|
||||
|
|
@ -1077,7 +1082,7 @@ QString MainWindow::get_secure_app_data(const QString& param)
|
|||
const app_data_file_binary_header* phdr = reinterpret_cast<const app_data_file_binary_header*>(app_data_buff.data());
|
||||
if (phdr->m_signature != APP_DATA_FILE_BINARY_SIGNATURE)
|
||||
{
|
||||
LOG_ERROR("password missmatch");
|
||||
LOG_ERROR("gui secure config: password missmatch while loading from " << filename);
|
||||
view::api_response ar;
|
||||
ar.error_code = API_RETURN_CODE_WRONG_PASSWORD;
|
||||
return MAKE_RESPONSE(ar);
|
||||
|
|
@ -1087,7 +1092,7 @@ QString MainWindow::get_secure_app_data(const QString& param)
|
|||
|
||||
crypto::hash master_password_pre_hash = crypto::cn_fast_hash(m_master_password.c_str(), m_master_password.length());
|
||||
crypto::hash master_password_hash = crypto::cn_fast_hash(&master_password_pre_hash, sizeof master_password_pre_hash);
|
||||
LOG_PRINT_L0("get_secure_app_data, pass hash: " << master_password_hash);
|
||||
LOG_PRINT_L0("gui secure config loaded ok from " << filename << ", pass hash: " << master_password_hash);
|
||||
|
||||
return app_data_buff.substr(sizeof(app_data_file_binary_header)).c_str();
|
||||
CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR);
|
||||
|
|
@ -1161,10 +1166,6 @@ QString MainWindow::store_app_data(const QString& param)
|
|||
return MAKE_RESPONSE(ar);
|
||||
}
|
||||
|
||||
crypto::hash master_password_pre_hash = crypto::cn_fast_hash(m_master_password.c_str(), m_master_password.length());
|
||||
crypto::hash master_password_hash = crypto::cn_fast_hash(&master_password_pre_hash, sizeof master_password_pre_hash);
|
||||
LOG_PRINT_L0("store_app_data, pass hash: " << master_password_hash);
|
||||
|
||||
std::string filename = m_backend.get_config_folder() + "/" + GUI_CONFIG_FILENAME;
|
||||
bool r = file_io_utils::save_string_to_file(filename, param.toStdString());
|
||||
if (r)
|
||||
|
|
@ -1313,6 +1314,8 @@ QString MainWindow::have_secure_app_data()
|
|||
else
|
||||
ar.error_code = API_RETURN_CODE_FALSE;
|
||||
|
||||
LOG_PRINT_L0("have_secure_app_data, r = " << ar.error_code);
|
||||
|
||||
return MAKE_RESPONSE(ar);
|
||||
CATCH_ENTRY_FAIL_API_RESPONCE();
|
||||
}
|
||||
|
|
@ -1328,6 +1331,9 @@ QString MainWindow::drop_secure_app_data()
|
|||
ar.error_code = API_RETURN_CODE_TRUE;
|
||||
else
|
||||
ar.error_code = API_RETURN_CODE_FALSE;
|
||||
|
||||
LOG_PRINT_L0("drop_secure_app_data, r = " << ar.error_code);
|
||||
|
||||
return MAKE_RESPONSE(ar);
|
||||
CATCH_ENTRY_FAIL_API_RESPONCE();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -736,6 +736,7 @@ public:
|
|||
#define API_RETURN_CODE_BAD_ARG_WRONG_PAYMENT_ID "BAD_ARG_WRONG_PAYMENT_ID"
|
||||
#define API_RETURN_CODE_WRONG_PASSWORD "WRONG_PASSWORD"
|
||||
#define API_RETURN_CODE_WALLET_WRONG_ID "WALLET_WRONG_ID"
|
||||
#define API_RETURN_CODE_WALLET_WATCH_ONLY_NOT_SUPPORTED "WALLET_WATCH_ONLY_NOT_SUPPORTED"
|
||||
#define API_RETURN_CODE_FILE_NOT_FOUND "FILE_NOT_FOUND"
|
||||
#define API_RETURN_CODE_ALREADY_EXISTS "ALREADY_EXISTS"
|
||||
#define API_RETURN_CODE_CANCELED "CANCELED"
|
||||
|
|
|
|||
|
|
@ -581,6 +581,7 @@
|
|||
"TRANSACTION_ERROR": "Error. Transaction not completed.",
|
||||
"BAD_ARG": "Invalid argument",
|
||||
"WALLET_WRONG_ID": "Invalid wallet ID",
|
||||
"WALLET_WATCH_ONLY_NOT_SUPPORTED": "Watch-only wallets can only be opened by simplewallet",
|
||||
"WRONG_PASSWORD": "Invalid password",
|
||||
"FILE_RESTORED": "The wallet file was corrupted. We have recovered the keys and the wallet from the blockchain",
|
||||
"FILE_NOT_FOUND": "File not found",
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -649,7 +649,7 @@ module.exports = function (NAME, wrapper, methods, common, IS_MAP, IS_WEAK) {
|
|||
/*! no static exports found */
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
var core = module.exports = { version: '2.6.10' };
|
||||
var core = module.exports = { version: '2.6.11' };
|
||||
if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -8,6 +8,7 @@
|
|||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(255, 255, 255, 0.25);
|
||||
z-index: 5;
|
||||
}
|
||||
.modal {
|
||||
position: relative;
|
||||
|
|
|
|||
|
|
@ -109,6 +109,9 @@ export class BackendService {
|
|||
case 'WALLET_WRONG_ID':
|
||||
error_translate = 'ERRORS.WALLET_WRONG_ID';
|
||||
break;
|
||||
case 'WALLET_WATCH_ONLY_NOT_SUPPORTED':
|
||||
error_translate = 'ERRORS.WALLET_WATCH_ONLY_NOT_SUPPORTED';
|
||||
break;
|
||||
case 'WRONG_PASSWORD':
|
||||
case 'WRONG_PASSWORD:invalid password':
|
||||
params = JSON.parse(params);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@
|
|||
<div class="sidebar-account-row account-title-balance">
|
||||
<span class="title" tooltip="{{ wallet.name }}" placement="top-left" tooltipClass="table-tooltip account-tooltip" [delay]="500" [showWhenNoOverflow]="false">{{wallet.name}}</span>
|
||||
<span class="balance">{{wallet.balance | intToMoney : '3' }} {{variablesService.defaultCurrency}}</span>
|
||||
<button type="button" (click)="showDialog(wallet.wallet_id)" tooltip="{{ 'WALLET.TOOLTIPS.CLOSE' | translate }}" placement="top-left" tooltipClass="table-tooltip account-tooltip" [delay]="500" [timeDelay]="500">
|
||||
<i class="icon close-wallet"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="sidebar-account-row account-alias">
|
||||
<div class="name">
|
||||
|
|
@ -155,3 +158,4 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<app-confirm-modal *ngIf="isModalDialogVisible" [title]=" 'WALLET.CONFIRM.TITLE' | translate " [message]=" 'WALLET.CONFIRM.MESSAGE' | translate " (confirmed)="confirmed($event)"></app-confirm-modal>
|
||||
|
|
|
|||
|
|
@ -179,6 +179,31 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-weight: 400;
|
||||
outline: none;
|
||||
padding: 0;
|
||||
padding-bottom: 5rem;
|
||||
position: absolute;
|
||||
left: 105%;
|
||||
|
||||
.icon {
|
||||
margin-right: 1.2rem;
|
||||
width: 1.3rem;
|
||||
height: 1.3rem;
|
||||
|
||||
&.close-wallet {
|
||||
mask: url(../../assets/icons/close-wallet.svg) no-repeat center;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@ export class SidebarComponent implements OnInit, OnDestroy {
|
|||
settings = icons.settings;
|
||||
exit = icons.exit;
|
||||
|
||||
isModalDialogVisible = false;
|
||||
closeWalletId: number;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
|
|
@ -68,6 +71,39 @@ export class SidebarComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
}
|
||||
|
||||
showDialog(wallet_id) {
|
||||
this.isModalDialogVisible = true;
|
||||
this.closeWalletId = wallet_id;
|
||||
}
|
||||
|
||||
confirmed(confirmed: boolean) {
|
||||
if (confirmed) {
|
||||
this.closeWallet(this.closeWalletId);
|
||||
}
|
||||
this.isModalDialogVisible = false;
|
||||
}
|
||||
|
||||
closeWallet(wallet_id) {
|
||||
this.backend.closeWallet(wallet_id, () => {
|
||||
for (let i = this.variablesService.wallets.length - 1; i >= 0; i--) {
|
||||
if (this.variablesService.wallets[i].wallet_id === this.variablesService.currentWallet.wallet_id) {
|
||||
this.variablesService.wallets.splice(i, 1);
|
||||
}
|
||||
}
|
||||
this.ngZone.run(() => {
|
||||
if (this.variablesService.wallets.length) {
|
||||
this.variablesService.currentWallet = this.variablesService.wallets[0];
|
||||
this.router.navigate(['/wallet/' + this.variablesService.currentWallet.wallet_id]);
|
||||
} else {
|
||||
this.router.navigate(['/']);
|
||||
}
|
||||
});
|
||||
if (this.variablesService.appPass) {
|
||||
this.backend.storeSecureAppData();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getUpdate() {
|
||||
this.backend.openUrlInBrowser('zano.org/downloads.html');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,9 +17,6 @@
|
|||
<button [routerLink]="['/details']" routerLinkActive="active" tooltip="{{ 'WALLET.TOOLTIPS.SETTINGS' | translate }}" placement="left" tooltipClass="table-tooltip account-tooltip" [delay]="500" [timeDelay]="500">
|
||||
<i class="icon details"></i>
|
||||
</button>
|
||||
<button type="button" (click)="showDialog()" tooltip="{{ 'WALLET.TOOLTIPS.CLOSE' | translate }}" placement="bottom-right" tooltipClass="table-tooltip account-tooltip" [delay]="500" [timeDelay]="500">
|
||||
<i class="icon close-wallet"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="address">
|
||||
|
|
@ -57,5 +54,3 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<app-confirm-modal *ngIf="isModalDialogVisible" [title]=" 'WALLET.CONFIRM.TITLE' | translate " [message]=" 'WALLET.CONFIRM.MESSAGE' | translate " (confirmed)="confirmed($event)"></app-confirm-modal>
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ export class WalletComponent implements OnInit, OnDestroy {
|
|||
copyAnimation = false;
|
||||
copyAnimationTimeout;
|
||||
balanceTooltip;
|
||||
isModalDialogVisible = false;
|
||||
activeTab = 'history';
|
||||
|
||||
public currentPage = 1;
|
||||
|
|
@ -189,38 +188,6 @@ export class WalletComponent implements OnInit, OnDestroy {
|
|||
this.backend.openUrlInBrowser(link);
|
||||
}
|
||||
|
||||
showDialog() {
|
||||
this.isModalDialogVisible = true;
|
||||
}
|
||||
|
||||
confirmed(confirmed: boolean) {
|
||||
if (confirmed) {
|
||||
this.closeWallet();
|
||||
}
|
||||
this.isModalDialogVisible = false;
|
||||
}
|
||||
|
||||
closeWallet() {
|
||||
this.backend.closeWallet(this.variablesService.currentWallet.wallet_id, () => {
|
||||
for (let i = this.variablesService.wallets.length - 1; i >= 0; i--) {
|
||||
if (this.variablesService.wallets[i].wallet_id === this.variablesService.currentWallet.wallet_id) {
|
||||
this.variablesService.wallets.splice(i, 1);
|
||||
}
|
||||
}
|
||||
this.ngZone.run(() => {
|
||||
if (this.variablesService.wallets.length) {
|
||||
this.variablesService.currentWallet = this.variablesService.wallets[0];
|
||||
this.router.navigate(['/wallet/' + this.variablesService.currentWallet.wallet_id]);
|
||||
} else {
|
||||
this.router.navigate(['/']);
|
||||
}
|
||||
});
|
||||
if (this.variablesService.appPass) {
|
||||
this.backend.storeSecureAppData();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public setPage(pageNumber: number) {
|
||||
if (pageNumber === this.variablesService.currentWallet.currentPage) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -581,6 +581,7 @@
|
|||
"TRANSACTION_ERROR": "Error. Transaction not completed.",
|
||||
"BAD_ARG": "Invalid argument",
|
||||
"WALLET_WRONG_ID": "Invalid wallet ID",
|
||||
"WALLET_WATCH_ONLY_NOT_SUPPORTED": "Watch-only wallets can only be opened by simplewallet",
|
||||
"WRONG_PASSWORD": "Invalid password",
|
||||
"FILE_RESTORED": "The wallet file was corrupted. We have recovered the keys and the wallet from the blockchain",
|
||||
"FILE_NOT_FOUND": "File not found",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@
|
|||
#define PROJECT_REVISION "4"
|
||||
#define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION
|
||||
|
||||
#define PROJECT_VERSION_BUILD_NO 76
|
||||
#define PROJECT_VERSION_BUILD_NO 77
|
||||
#define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO)
|
||||
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"
|
||||
|
|
|
|||
|
|
@ -2097,7 +2097,7 @@ void wallet2::store(const std::wstring& path_to_save, const std::string& passwor
|
|||
|
||||
//prepare data
|
||||
std::string keys_buff;
|
||||
bool r = store_keys(keys_buff, password);
|
||||
bool r = store_keys(keys_buff, password, m_watch_only);
|
||||
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(r, "failed to store_keys for wallet " << ascii_path_to_save);
|
||||
|
||||
//store data
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue