mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2024-09-11 10:56:14 +03:00
get backup client
This commit is contained in:
parent
43cdbb90b9
commit
cb0897ba36
@ -1,5 +1,6 @@
|
||||
const config = {
|
||||
local_test: false
|
||||
local_test: false,
|
||||
backup_host: "https://backup.chia.net",
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
|
@ -3,14 +3,14 @@ import {
|
||||
registerService,
|
||||
startService,
|
||||
isServiceRunning,
|
||||
startServiceTest
|
||||
startServiceTest,
|
||||
} from "../modules/daemon_messages";
|
||||
import { handle_message } from "./middleware_api";
|
||||
import {
|
||||
service_wallet,
|
||||
service_full_node,
|
||||
service_simulator,
|
||||
service_plotter
|
||||
service_plotter,
|
||||
} from "../util/service_names";
|
||||
const config = require("../config");
|
||||
|
||||
@ -24,14 +24,14 @@ const outgoing_message = (command, data, destination) => ({
|
||||
ack: false,
|
||||
origin: "wallet_ui",
|
||||
destination: destination,
|
||||
request_id: crypto.randomBytes(32).toString("hex")
|
||||
request_id: crypto.randomBytes(32).toString("hex"),
|
||||
});
|
||||
|
||||
const socketMiddleware = () => {
|
||||
let socket = null;
|
||||
let connected = false;
|
||||
|
||||
const onOpen = store => event => {
|
||||
const onOpen = (store) => (event) => {
|
||||
connected = true;
|
||||
store.dispatch(actions.wsConnected(event.target.url));
|
||||
var register_action = registerService();
|
||||
@ -50,12 +50,12 @@ const socketMiddleware = () => {
|
||||
store.dispatch(start_node);
|
||||
};
|
||||
|
||||
const onClose = store => () => {
|
||||
const onClose = (store) => () => {
|
||||
connected = false;
|
||||
store.dispatch(actions.wsDisconnected());
|
||||
};
|
||||
|
||||
const onMessage = store => event => {
|
||||
const onMessage = (store) => (event) => {
|
||||
const payload = JSON.parse(event.data);
|
||||
const request_id = payload["request_id"];
|
||||
if (callback_map[request_id] != null) {
|
||||
@ -67,7 +67,7 @@ const socketMiddleware = () => {
|
||||
handle_message(store, payload);
|
||||
};
|
||||
|
||||
return store => next => action => {
|
||||
return (store) => (next) => (action) => {
|
||||
switch (action.type) {
|
||||
case "WS_CONNECT":
|
||||
if (socket !== null) {
|
||||
|
@ -1,21 +1,21 @@
|
||||
export const presentBackupInfo = "BACKUP_INFO";
|
||||
export const presentMain = "MAIN";
|
||||
|
||||
export const changeBackupView = view => ({ type: "BACKUP_VIEW", view: view });
|
||||
export const setBackupInfo = backup_info => ({
|
||||
export const changeBackupView = (view) => ({ type: "BACKUP_VIEW", view: view });
|
||||
export const setBackupInfo = (backup_info) => ({
|
||||
type: "BACKUP_INFO",
|
||||
backup_info: backup_info
|
||||
backup_info: backup_info,
|
||||
});
|
||||
|
||||
export const selectFilePath = file_path => ({
|
||||
export const selectFilePath = (file_path) => ({
|
||||
type: "SELECT_FILEPATH",
|
||||
file_path: file_path
|
||||
file_path: file_path,
|
||||
});
|
||||
|
||||
const initial_state = {
|
||||
view: presentMain,
|
||||
backup_info: {},
|
||||
selected_file_path: null
|
||||
selected_file_path: null,
|
||||
};
|
||||
|
||||
export const backupReducer = (state = { ...initial_state }, action) => {
|
||||
|
@ -5,7 +5,7 @@ import { setIncorrectWord, resetMnemonic } from "./mnemonic_input";
|
||||
import {
|
||||
changeEntranceMenu,
|
||||
presentRestoreBackup,
|
||||
presentOldWallet
|
||||
presentOldWallet,
|
||||
} from "./entranceMenu";
|
||||
import { openDialog } from "./dialogReducer";
|
||||
import { createState } from "./createWalletReducer";
|
||||
@ -14,25 +14,27 @@ import {
|
||||
getPlotDirectories,
|
||||
removePlotDirectory,
|
||||
getPlots,
|
||||
refreshPlots
|
||||
refreshPlots,
|
||||
} from "./harvesterMessages";
|
||||
import {
|
||||
setBackupInfo,
|
||||
changeBackupView,
|
||||
presentBackupInfo,
|
||||
selectFilePath
|
||||
selectFilePath,
|
||||
} from "./backup_state";
|
||||
import { exitDaemon } from "./daemon_messages";
|
||||
import { wsDisconnect } from "./websocket";
|
||||
import {
|
||||
changeCreateWallet,
|
||||
ALL_OPTIONS
|
||||
ALL_OPTIONS,
|
||||
} from "../modules/createWalletReducer";
|
||||
const config = require("../config");
|
||||
const backup_host = config.backup_host;
|
||||
|
||||
export const clearSend = () => {
|
||||
var action = {
|
||||
type: "CLEAR_SEND",
|
||||
mesasge: ""
|
||||
mesasge: "",
|
||||
};
|
||||
return action;
|
||||
};
|
||||
@ -40,27 +42,27 @@ export const clearSend = () => {
|
||||
export const walletMessage = () => ({
|
||||
type: "OUTGOING_MESSAGE",
|
||||
message: {
|
||||
destination: service_wallet
|
||||
}
|
||||
destination: service_wallet,
|
||||
},
|
||||
});
|
||||
|
||||
export const selectFingerprint = fingerprint => ({
|
||||
export const selectFingerprint = (fingerprint) => ({
|
||||
type: "SELECT_FINGERPRINT",
|
||||
fingerprint: fingerprint
|
||||
fingerprint: fingerprint,
|
||||
});
|
||||
|
||||
export const unselectFingerprint = () => ({
|
||||
type: "UNSELECT_FINGERPRINT"
|
||||
type: "UNSELECT_FINGERPRINT",
|
||||
});
|
||||
|
||||
export const selectMnemonic = mnemonic => ({
|
||||
export const selectMnemonic = (mnemonic) => ({
|
||||
type: "SELECT_MNEMONIC",
|
||||
mnemonic: mnemonic
|
||||
mnemonic: mnemonic,
|
||||
});
|
||||
|
||||
export const showCreateBackup = show => ({
|
||||
export const showCreateBackup = (show) => ({
|
||||
type: "SHOW_CREATE_BACKUP",
|
||||
show: show
|
||||
show: show,
|
||||
});
|
||||
|
||||
export const async_api = (dispatch, action, open_spinner) => {
|
||||
@ -93,7 +95,7 @@ export const pingWallet = () => {
|
||||
return action;
|
||||
};
|
||||
|
||||
export const get_balance_for_wallet = id => {
|
||||
export const get_balance_for_wallet = (id) => {
|
||||
var action = walletMessage();
|
||||
action.message.command = "get_wallet_balance";
|
||||
action.message.data = { wallet_id: id };
|
||||
@ -107,7 +109,7 @@ export const send_transaction = (wallet_id, amount, fee, puzzle_hash) => {
|
||||
wallet_id: wallet_id,
|
||||
amount: amount,
|
||||
fee: fee,
|
||||
puzzle_hash: puzzle_hash
|
||||
puzzle_hash: puzzle_hash,
|
||||
};
|
||||
return action;
|
||||
};
|
||||
@ -125,18 +127,18 @@ export const add_key = (mnemonic, type, file_path) => {
|
||||
action.message.data = {
|
||||
mnemonic: mnemonic,
|
||||
type: type,
|
||||
file_path: file_path
|
||||
file_path: file_path,
|
||||
};
|
||||
return action;
|
||||
};
|
||||
|
||||
export const add_new_key_action = mnemonic => {
|
||||
return dispatch => {
|
||||
export const add_new_key_action = (mnemonic) => {
|
||||
return (dispatch) => {
|
||||
return async_api(
|
||||
dispatch,
|
||||
add_key(mnemonic, "new_wallet", null),
|
||||
true
|
||||
).then(response => {
|
||||
).then((response) => {
|
||||
dispatch(closeProgress());
|
||||
if (response.data.success) {
|
||||
// Go to wallet
|
||||
@ -157,10 +159,10 @@ export const add_new_key_action = mnemonic => {
|
||||
};
|
||||
};
|
||||
|
||||
export const add_and_skip_backup = mnemonic => {
|
||||
return dispatch => {
|
||||
export const add_and_skip_backup = (mnemonic) => {
|
||||
return (dispatch) => {
|
||||
return async_api(dispatch, add_key(mnemonic, "skip", null), true).then(
|
||||
response => {
|
||||
(response) => {
|
||||
dispatch(closeProgress());
|
||||
if (response.data.success) {
|
||||
// Go to wallet
|
||||
@ -185,17 +187,16 @@ export const add_and_skip_backup = mnemonic => {
|
||||
};
|
||||
|
||||
export const add_and_restore_from_backup = (mnemonic, file_path) => {
|
||||
return dispatch => {
|
||||
return (dispatch) => {
|
||||
return async_api(
|
||||
dispatch,
|
||||
add_key(mnemonic, "restore_backup", file_path),
|
||||
true
|
||||
).then(response => {
|
||||
).then((response) => {
|
||||
dispatch(closeProgress());
|
||||
if (response.data.success) {
|
||||
// Go to wallet
|
||||
dispatch(resetMnemonic());
|
||||
dispatch(format_message("get_public_keys", {}));
|
||||
refreshAllState(dispatch);
|
||||
} else {
|
||||
if (response.data.word) {
|
||||
@ -211,7 +212,7 @@ export const add_and_restore_from_backup = (mnemonic, file_path) => {
|
||||
};
|
||||
};
|
||||
|
||||
export const delete_key = fingerprint => {
|
||||
export const delete_key = (fingerprint) => {
|
||||
var action = walletMessage();
|
||||
action.message.command = "delete_key";
|
||||
action.message.data = { fingerprint: fingerprint };
|
||||
@ -225,17 +226,25 @@ export const delete_all_keys = () => {
|
||||
return action;
|
||||
};
|
||||
|
||||
export const log_in = fingerprint => {
|
||||
export const log_in = (fingerprint) => {
|
||||
var action = walletMessage();
|
||||
action.message.command = "log_in";
|
||||
action.message.data = { fingerprint: fingerprint, type: "normal" };
|
||||
action.message.data = {
|
||||
fingerprint: fingerprint,
|
||||
host: backup_host,
|
||||
type: "normal",
|
||||
};
|
||||
return action;
|
||||
};
|
||||
|
||||
export const log_in_and_skip_import = fingerprint => {
|
||||
export const log_in_and_skip_import = (fingerprint) => {
|
||||
var action = walletMessage();
|
||||
action.message.command = "log_in";
|
||||
action.message.data = { fingerprint: fingerprint, type: "skip" };
|
||||
action.message.data = {
|
||||
fingerprint: fingerprint,
|
||||
host: backup_host,
|
||||
type: "skip",
|
||||
};
|
||||
return action;
|
||||
};
|
||||
|
||||
@ -245,16 +254,17 @@ export const log_in_and_import_backup = (fingerprint, file_path) => {
|
||||
action.message.data = {
|
||||
fingerprint: fingerprint,
|
||||
type: "restore_backup",
|
||||
file_path: file_path
|
||||
file_path: file_path,
|
||||
host: backup_host,
|
||||
};
|
||||
return action;
|
||||
};
|
||||
|
||||
export const login_and_skip_action = fingerprint => {
|
||||
return dispatch => {
|
||||
export const login_and_skip_action = (fingerprint) => {
|
||||
return (dispatch) => {
|
||||
dispatch(selectFingerprint(fingerprint));
|
||||
return async_api(dispatch, log_in_and_skip_import(fingerprint), true).then(
|
||||
response => {
|
||||
(response) => {
|
||||
dispatch(closeProgress());
|
||||
if (response.data.success) {
|
||||
// Go to wallet
|
||||
@ -273,10 +283,10 @@ export const login_and_skip_action = fingerprint => {
|
||||
};
|
||||
};
|
||||
|
||||
export const login_action = fingerprint => {
|
||||
return dispatch => {
|
||||
export const login_action = (fingerprint) => {
|
||||
return (dispatch) => {
|
||||
dispatch(selectFingerprint(fingerprint));
|
||||
return async_api(dispatch, log_in(fingerprint), true).then(response => {
|
||||
return async_api(dispatch, log_in(fingerprint), true).then((response) => {
|
||||
dispatch(closeProgress());
|
||||
if (response.data.success) {
|
||||
// Go to wallet
|
||||
@ -284,7 +294,14 @@ export const login_action = fingerprint => {
|
||||
} else {
|
||||
const error = response.data.error;
|
||||
if (error === "not_initialized") {
|
||||
const backup_info = response.data.backup_info;
|
||||
const backup_path = response.data.backup_path;
|
||||
dispatch(changeEntranceMenu(presentRestoreBackup));
|
||||
if (backup_info && backup_path) {
|
||||
dispatch(setBackupInfo(backup_info));
|
||||
dispatch(selectFilePath(backup_path));
|
||||
dispatch(changeBackupView(presentBackupInfo));
|
||||
}
|
||||
// Go to restore from backup screen
|
||||
} else {
|
||||
dispatch(openDialog("Error", error));
|
||||
@ -300,27 +317,28 @@ export const get_backup_info = (file_path, fingerprint, words) => {
|
||||
if (fingerprint === null) {
|
||||
action.message.data = {
|
||||
file_path: file_path,
|
||||
words: words
|
||||
words: words,
|
||||
};
|
||||
} else if (words === null) {
|
||||
action.message.data = {
|
||||
file_path: file_path,
|
||||
fingerprint: fingerprint
|
||||
fingerprint: fingerprint,
|
||||
};
|
||||
}
|
||||
return action;
|
||||
};
|
||||
|
||||
export const get_backup_info_action = (file_path, fingerprint, words) => {
|
||||
return dispatch => {
|
||||
return (dispatch) => {
|
||||
dispatch(selectFilePath(file_path));
|
||||
return async_api(
|
||||
dispatch,
|
||||
get_backup_info(file_path, fingerprint, words),
|
||||
true
|
||||
).then(response => {
|
||||
).then((response) => {
|
||||
dispatch(closeProgress());
|
||||
if (response.data.success) {
|
||||
response.data.backup_info.downloaded = false;
|
||||
dispatch(setBackupInfo(response.data.backup_info));
|
||||
dispatch(changeBackupView(presentBackupInfo));
|
||||
} else {
|
||||
@ -331,28 +349,28 @@ export const get_backup_info_action = (file_path, fingerprint, words) => {
|
||||
};
|
||||
};
|
||||
|
||||
export const get_private_key = fingerprint => {
|
||||
export const get_private_key = (fingerprint) => {
|
||||
var action = walletMessage();
|
||||
action.message.command = "get_private_key";
|
||||
action.message.data = { fingerprint: fingerprint };
|
||||
return action;
|
||||
};
|
||||
|
||||
export const get_transactions = wallet_id => {
|
||||
export const get_transactions = (wallet_id) => {
|
||||
var action = walletMessage();
|
||||
action.message.command = "get_transactions";
|
||||
action.message.data = { wallet_id: wallet_id };
|
||||
return action;
|
||||
};
|
||||
|
||||
export const get_puzzle_hash = wallet_id => {
|
||||
export const get_puzzle_hash = (wallet_id) => {
|
||||
var action = walletMessage();
|
||||
action.message.command = "get_next_puzzle_hash";
|
||||
action.message.data = { wallet_id: wallet_id };
|
||||
return action;
|
||||
};
|
||||
|
||||
export const farm_block = puzzle_hash => {
|
||||
export const farm_block = (puzzle_hash) => {
|
||||
var action = walletMessage();
|
||||
action.message.command = "farm_block";
|
||||
action.message.data = { puzzle_hash: puzzle_hash };
|
||||
@ -387,7 +405,8 @@ export const create_coloured_coin = (amount, fee) => {
|
||||
wallet_type: "cc_wallet",
|
||||
mode: "new",
|
||||
amount: amount,
|
||||
fee: fee
|
||||
fee: fee,
|
||||
host: backup_host,
|
||||
};
|
||||
return action;
|
||||
};
|
||||
@ -399,24 +418,25 @@ export const create_cc_for_colour = (colour, fee) => {
|
||||
wallet_type: "cc_wallet",
|
||||
mode: "existing",
|
||||
colour: colour,
|
||||
fee: fee
|
||||
fee: fee,
|
||||
host: backup_host,
|
||||
};
|
||||
return action;
|
||||
};
|
||||
|
||||
export const create_backup = file_path => {
|
||||
export const create_backup = (file_path) => {
|
||||
var action = walletMessage();
|
||||
action.message.command = "create_backup";
|
||||
action.message.data = {
|
||||
file_path: file_path
|
||||
file_path: file_path,
|
||||
};
|
||||
return action;
|
||||
};
|
||||
|
||||
export const create_backup_action = file_path => {
|
||||
return dispatch => {
|
||||
export const create_backup_action = (file_path) => {
|
||||
return (dispatch) => {
|
||||
return async_api(dispatch, create_backup(file_path), true).then(
|
||||
response => {
|
||||
(response) => {
|
||||
dispatch(closeProgress());
|
||||
if (response.data.success) {
|
||||
dispatch(showCreateBackup(false));
|
||||
@ -430,9 +450,9 @@ export const create_backup_action = file_path => {
|
||||
};
|
||||
|
||||
export const create_cc_action = (amount, fee) => {
|
||||
return dispatch => {
|
||||
return (dispatch) => {
|
||||
return async_api(dispatch, create_coloured_coin(amount, fee), true).then(
|
||||
response => {
|
||||
(response) => {
|
||||
dispatch(closeProgress());
|
||||
dispatch(createState(true, false));
|
||||
if (response.data.success) {
|
||||
@ -440,7 +460,7 @@ export const create_cc_action = (amount, fee) => {
|
||||
dispatch(format_message("get_wallets", {}));
|
||||
dispatch(showCreateBackup(true));
|
||||
dispatch(createState(true, false));
|
||||
dispatch(changeCreateWallet(ALL_OPTIONS))
|
||||
dispatch(changeCreateWallet(ALL_OPTIONS));
|
||||
} else {
|
||||
const error = response.data.error;
|
||||
dispatch(openDialog("Error", error));
|
||||
@ -451,16 +471,16 @@ export const create_cc_action = (amount, fee) => {
|
||||
};
|
||||
|
||||
export const create_cc_for_colour_action = (colour, fee) => {
|
||||
return dispatch => {
|
||||
return (dispatch) => {
|
||||
return async_api(dispatch, create_cc_for_colour(colour, fee), true).then(
|
||||
response => {
|
||||
(response) => {
|
||||
dispatch(closeProgress());
|
||||
dispatch(createState(true, false));
|
||||
if (response.data.success) {
|
||||
// Go to wallet
|
||||
dispatch(showCreateBackup(true));
|
||||
dispatch(format_message("get_wallets", {}));
|
||||
dispatch(changeCreateWallet(ALL_OPTIONS))
|
||||
dispatch(changeCreateWallet(ALL_OPTIONS));
|
||||
} else {
|
||||
const error = response.data.error;
|
||||
dispatch(openDialog("Error", error));
|
||||
@ -470,14 +490,14 @@ export const create_cc_for_colour_action = (colour, fee) => {
|
||||
};
|
||||
};
|
||||
|
||||
export const get_colour_info = wallet_id => {
|
||||
export const get_colour_info = (wallet_id) => {
|
||||
var action = walletMessage();
|
||||
action.message.command = "cc_get_colour";
|
||||
action.message.data = { wallet_id: wallet_id };
|
||||
return action;
|
||||
};
|
||||
|
||||
export const get_colour_name = wallet_id => {
|
||||
export const get_colour_name = (wallet_id) => {
|
||||
var action = walletMessage();
|
||||
action.message.command = "cc_get_name";
|
||||
action.message.data = { wallet_id: wallet_id };
|
||||
@ -498,16 +518,16 @@ export const cc_spend = (wallet_id, puzzle_hash, amount, fee) => {
|
||||
wallet_id: wallet_id,
|
||||
innerpuzhash: puzzle_hash,
|
||||
amount: amount,
|
||||
fee: fee
|
||||
fee: fee,
|
||||
};
|
||||
return action;
|
||||
};
|
||||
|
||||
export const logOut = (command, data) => ({ type: "LOG_OUT", command, data });
|
||||
|
||||
export const incomingMessage = message => ({
|
||||
export const incomingMessage = (message) => ({
|
||||
type: "INCOMING_MESSAGE",
|
||||
message: message
|
||||
message: message,
|
||||
});
|
||||
|
||||
export const create_rl_admin = (interval, limit, pubkey, amount) => {
|
||||
@ -519,18 +539,19 @@ export const create_rl_admin = (interval, limit, pubkey, amount) => {
|
||||
interval: interval,
|
||||
limit: limit,
|
||||
pubkey: pubkey,
|
||||
amount: amount
|
||||
amount: amount,
|
||||
host: backup_host,
|
||||
};
|
||||
return action;
|
||||
};
|
||||
|
||||
export const create_rl_admin_action = (interval, limit, pubkey, amount) => {
|
||||
return dispatch => {
|
||||
return (dispatch) => {
|
||||
return async_api(
|
||||
dispatch,
|
||||
create_rl_admin(interval, limit, pubkey, amount),
|
||||
true
|
||||
).then(response => {
|
||||
).then((response) => {
|
||||
dispatch(closeProgress());
|
||||
dispatch(createState(true, false));
|
||||
if (response.data.success) {
|
||||
@ -552,14 +573,15 @@ export const create_rl_user = () => {
|
||||
action.message.command = "create_new_wallet";
|
||||
action.message.data = {
|
||||
wallet_type: "rl_wallet",
|
||||
rl_type: "user"
|
||||
rl_type: "user",
|
||||
host: backup_host,
|
||||
};
|
||||
return action;
|
||||
};
|
||||
|
||||
export const create_rl_user_action = () => {
|
||||
return dispatch => {
|
||||
return async_api(dispatch, create_rl_user(), true).then(response => {
|
||||
return (dispatch) => {
|
||||
return async_api(dispatch, create_rl_user(), true).then((response) => {
|
||||
dispatch(closeProgress());
|
||||
dispatch(createState(true, false));
|
||||
if (response.data.success) {
|
||||
@ -575,12 +597,12 @@ export const create_rl_user_action = () => {
|
||||
};
|
||||
};
|
||||
|
||||
export const add_plot_directory_and_refresh = dir => {
|
||||
return dispatch => {
|
||||
return async_api(dispatch, addPlotDirectory(dir), true).then(response => {
|
||||
export const add_plot_directory_and_refresh = (dir) => {
|
||||
return (dispatch) => {
|
||||
return async_api(dispatch, addPlotDirectory(dir), true).then((response) => {
|
||||
if (response.data.success) {
|
||||
dispatch(getPlotDirectories());
|
||||
return async_api(dispatch, refreshPlots(), false).then(response => {
|
||||
return async_api(dispatch, refreshPlots(), false).then((response) => {
|
||||
dispatch(closeProgress());
|
||||
dispatch(getPlots());
|
||||
});
|
||||
@ -592,13 +614,13 @@ export const add_plot_directory_and_refresh = dir => {
|
||||
};
|
||||
};
|
||||
|
||||
export const remove_plot_directory_and_refresh = dir => {
|
||||
return dispatch => {
|
||||
export const remove_plot_directory_and_refresh = (dir) => {
|
||||
return (dispatch) => {
|
||||
return async_api(dispatch, removePlotDirectory(dir), true).then(
|
||||
response => {
|
||||
(response) => {
|
||||
if (response.data.success) {
|
||||
dispatch(getPlotDirectories());
|
||||
return async_api(dispatch, refreshPlots(), false).then(response => {
|
||||
return async_api(dispatch, refreshPlots(), false).then((response) => {
|
||||
dispatch(closeProgress());
|
||||
dispatch(getPlots());
|
||||
});
|
||||
@ -625,7 +647,7 @@ export const rl_set_user_info = (
|
||||
interval: interval,
|
||||
limit: limit,
|
||||
origin: origin,
|
||||
admin_pubkey: admin_pubkey
|
||||
admin_pubkey: admin_pubkey,
|
||||
};
|
||||
return action;
|
||||
};
|
||||
@ -637,12 +659,12 @@ export const rl_set_user_info_action = (
|
||||
origin,
|
||||
admin_pubkey
|
||||
) => {
|
||||
return dispatch => {
|
||||
return (dispatch) => {
|
||||
return async_api(
|
||||
dispatch,
|
||||
rl_set_user_info(wallet_id, interval, limit, origin, admin_pubkey),
|
||||
true
|
||||
).then(response => {
|
||||
).then((response) => {
|
||||
dispatch(closeProgress());
|
||||
dispatch(createState(true, false));
|
||||
if (response.data.success) {
|
||||
@ -658,13 +680,13 @@ export const rl_set_user_info_action = (
|
||||
};
|
||||
};
|
||||
|
||||
export const clawback_rl_coin = wallet_id => {
|
||||
export const clawback_rl_coin = (wallet_id) => {
|
||||
// THIS IS A PLACEHOLDER FOR RL CLAWBACK FUNCTIONALITY
|
||||
};
|
||||
|
||||
export const exit_and_close = event => {
|
||||
return dispatch => {
|
||||
return async_api(dispatch, exitDaemon(), false).then(response => {
|
||||
export const exit_and_close = (event) => {
|
||||
return (dispatch) => {
|
||||
return async_api(dispatch, exitDaemon(), false).then((response) => {
|
||||
console.log("GOT RESPONSE", response);
|
||||
dispatch(wsDisconnect());
|
||||
event.sender.send("daemon-exited");
|
||||
|
@ -8,30 +8,32 @@ import { useSelector, useDispatch } from "react-redux";
|
||||
import myStyle from "../style";
|
||||
import {
|
||||
changeEntranceMenu,
|
||||
presentSelectKeys
|
||||
presentSelectKeys,
|
||||
} from "../../modules/entranceMenu";
|
||||
import {
|
||||
add_new_key_action,
|
||||
log_in_and_import_backup,
|
||||
add_and_restore_from_backup,
|
||||
login_and_skip_action,
|
||||
get_backup_info_action
|
||||
get_backup_info_action,
|
||||
} from "../../modules/message";
|
||||
import { Paper, Grid } from "@material-ui/core";
|
||||
import {
|
||||
changeBackupView,
|
||||
presentMain,
|
||||
presentBackupInfo
|
||||
presentBackupInfo,
|
||||
setBackupInfo,
|
||||
selectFilePath,
|
||||
} from "../../modules/backup_state";
|
||||
import { unix_to_short_date } from "../../util/utils";
|
||||
import { Box } from "@material-ui/core";
|
||||
|
||||
const UIPart = props => {
|
||||
const UIPart = (props) => {
|
||||
const dispatch = useDispatch();
|
||||
const classes = myStyle();
|
||||
var words = useSelector(state => state.mnemonic_state.mnemonic_input);
|
||||
var words = useSelector((state) => state.mnemonic_state.mnemonic_input);
|
||||
var fingerprint = useSelector(
|
||||
state => state.wallet_state.selected_fingerprint
|
||||
(state) => state.wallet_state.selected_fingerprint
|
||||
);
|
||||
|
||||
for (let word of words) {
|
||||
@ -52,24 +54,23 @@ const UIPart = props => {
|
||||
}
|
||||
}
|
||||
|
||||
const handleDragEnter = e => {
|
||||
const handleDragEnter = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
};
|
||||
const handleDragLeave = e => {
|
||||
const handleDragLeave = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
};
|
||||
const handleDragOver = e => {
|
||||
const handleDragOver = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
};
|
||||
const handleDrop = e => {
|
||||
const handleDrop = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const file_path = e.dataTransfer.files[0].path;
|
||||
debugger;
|
||||
if (fingerprint !== null) {
|
||||
dispatch(get_backup_info_action(file_path, fingerprint, null));
|
||||
} else if (words !== null) {
|
||||
@ -90,10 +91,10 @@ const UIPart = props => {
|
||||
</Container>
|
||||
</div>
|
||||
<div
|
||||
onDrop={e => handleDrop(e)}
|
||||
onDragOver={e => handleDragOver(e)}
|
||||
onDragEnter={e => handleDragEnter(e)}
|
||||
onDragLeave={e => handleDragLeave(e)}
|
||||
onDrop={(e) => handleDrop(e)}
|
||||
onDragOver={(e) => handleDragOver(e)}
|
||||
onDragEnter={(e) => handleDragEnter(e)}
|
||||
onDragLeave={(e) => handleDragLeave(e)}
|
||||
className={classes.dragContainer}
|
||||
>
|
||||
<Paper
|
||||
@ -125,16 +126,23 @@ const UIPart = props => {
|
||||
const BackupDetails = () => {
|
||||
const classes = myStyle();
|
||||
const dispatch = useDispatch();
|
||||
const file_path = useSelector(state => state.backup_state.selected_file_path);
|
||||
const backup_info = useSelector(state => state.backup_state.backup_info);
|
||||
const file_path = useSelector(
|
||||
(state) => state.backup_state.selected_file_path
|
||||
);
|
||||
const backup_info = useSelector((state) => state.backup_state.backup_info);
|
||||
const selected_file_path = useSelector(
|
||||
(state) => state.backup_state.selected_file_path
|
||||
);
|
||||
const date = unix_to_short_date(backup_info["timestamp"]);
|
||||
const backup_fingerprint = backup_info["fingerprint"];
|
||||
const version = backup_info["version"];
|
||||
const wallets = backup_info["wallets"];
|
||||
const downloaded = backup_info["downloaded"];
|
||||
const host = backup_info["backup_host"];
|
||||
|
||||
var words = useSelector(state => state.mnemonic_state.mnemonic_input);
|
||||
var words = useSelector((state) => state.mnemonic_state.mnemonic_input);
|
||||
var fingerprint = useSelector(
|
||||
state => state.wallet_state.selected_fingerprint
|
||||
(state) => state.wallet_state.selected_fingerprint
|
||||
);
|
||||
|
||||
for (let word of words) {
|
||||
@ -148,6 +156,12 @@ const BackupDetails = () => {
|
||||
dispatch(changeEntranceMenu(presentSelectKeys));
|
||||
}
|
||||
|
||||
function goBackBackup() {
|
||||
dispatch(changeBackupView(presentMain));
|
||||
dispatch(setBackupInfo({}));
|
||||
dispatch(selectFilePath(null));
|
||||
}
|
||||
|
||||
function next() {
|
||||
if (fingerprint !== null) {
|
||||
dispatch(log_in_and_import_backup(fingerprint, file_path));
|
||||
@ -175,10 +189,16 @@ const BackupDetails = () => {
|
||||
position: "relative",
|
||||
width: "80%",
|
||||
margin: "auto",
|
||||
padding: "20px"
|
||||
padding: "20px",
|
||||
}}
|
||||
>
|
||||
<Grid container spacing={0} style={{ marginBottom: 10 }}>
|
||||
<ArrowBackIosIcon
|
||||
style={{ cursor: "pointer" }}
|
||||
onClick={goBackBackup}
|
||||
>
|
||||
{" "}
|
||||
</ArrowBackIosIcon>
|
||||
<Grid container spacing={3} style={{ marginBottom: 10 }}>
|
||||
<Grid item xs={6}>
|
||||
<Typography variant="subtitle1">Backup info:</Typography>
|
||||
<Box display="flex" style={{ minWidth: "100%" }}>
|
||||
@ -200,10 +220,26 @@ const BackupDetails = () => {
|
||||
</Box>
|
||||
</Box>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Box display="flex" style={{ minWidth: "100%" }}>
|
||||
<Box flexGrow={1}>Downloaded: </Box>
|
||||
<Box className={classes.align_right} flexGrow={1}>
|
||||
{downloaded + ""}
|
||||
</Box>
|
||||
</Box>
|
||||
<Box display="flex" style={{ minWidth: "100%" }}>
|
||||
<Box flexGrow={1}>
|
||||
{downloaded ? "Backup Host:" : "File Path"}
|
||||
</Box>
|
||||
<Box className={classes.align_right} flexGrow={1}>
|
||||
{downloaded ? host : selected_file_path}
|
||||
</Box>
|
||||
</Box>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Typography variant="subtitle1">Smart wallets</Typography>
|
||||
<WalletHeader></WalletHeader>
|
||||
{wallets.map(wallet => (
|
||||
{wallets.map((wallet) => (
|
||||
<WalletRow wallet={wallet}></WalletRow>
|
||||
))}
|
||||
</Paper>
|
||||
@ -227,7 +263,7 @@ const BackupDetails = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const WalletRow = props => {
|
||||
const WalletRow = (props) => {
|
||||
const wallet = props.wallet;
|
||||
const id = wallet.id;
|
||||
const name = wallet.name;
|
||||
@ -274,7 +310,7 @@ const WalletHeader = () => {
|
||||
};
|
||||
|
||||
export const RestoreBackup = () => {
|
||||
const view = useSelector(state => state.backup_state.view);
|
||||
const view = useSelector((state) => state.backup_state.view);
|
||||
if (view === presentBackupInfo) {
|
||||
return <BackupDetails></BackupDetails>;
|
||||
} else {
|
||||
|
@ -1,40 +1,40 @@
|
||||
import { makeStyles } from "@material-ui/styles";
|
||||
|
||||
const myStyle = makeStyles(theme => ({
|
||||
const myStyle = makeStyles((theme) => ({
|
||||
root: {
|
||||
background: "linear-gradient(45deg, #181818 30%, #333333 90%)",
|
||||
height: "100%"
|
||||
height: "100%",
|
||||
},
|
||||
paper: {
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
padding: theme.spacing(0)
|
||||
padding: theme.spacing(0),
|
||||
},
|
||||
avatar: {
|
||||
marginTop: theme.spacing(8),
|
||||
backgroundColor: theme.palette.secondary.main
|
||||
backgroundColor: theme.palette.secondary.main,
|
||||
},
|
||||
form: {
|
||||
width: "100%", // Fix IE 11 issue.
|
||||
marginTop: theme.spacing(5)
|
||||
marginTop: theme.spacing(5),
|
||||
},
|
||||
textField: {
|
||||
borderColor: "#ffffff"
|
||||
borderColor: "#ffffff",
|
||||
},
|
||||
submit: {
|
||||
marginTop: theme.spacing(8),
|
||||
marginBottom: theme.spacing(3)
|
||||
marginBottom: theme.spacing(3),
|
||||
},
|
||||
grid_wrap: {
|
||||
paddingLeft: theme.spacing(10),
|
||||
paddingRight: theme.spacing(10),
|
||||
textAlign: "center"
|
||||
textAlign: "center",
|
||||
},
|
||||
grid: {
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center"
|
||||
alignItems: "center",
|
||||
},
|
||||
grid_item: {
|
||||
padding: theme.spacing(1),
|
||||
@ -44,17 +44,17 @@ const myStyle = makeStyles(theme => ({
|
||||
alignItems: "center",
|
||||
backgroundColor: "#444444",
|
||||
color: "#ffffff",
|
||||
height: 60
|
||||
height: 60,
|
||||
},
|
||||
title: {
|
||||
color: "#ffffff",
|
||||
marginTop: theme.spacing(4),
|
||||
marginBottom: theme.spacing(8)
|
||||
marginBottom: theme.spacing(8),
|
||||
},
|
||||
titleSmallMargin: {
|
||||
color: "#ffffff",
|
||||
marginTop: theme.spacing(4),
|
||||
marginBottom: theme.spacing(2)
|
||||
marginBottom: theme.spacing(2),
|
||||
},
|
||||
navigator: {
|
||||
color: "#ffffff",
|
||||
@ -62,55 +62,56 @@ const myStyle = makeStyles(theme => ({
|
||||
marginLeft: theme.spacing(4),
|
||||
fontSize: 35,
|
||||
flex: 1,
|
||||
align: "right"
|
||||
align: "right",
|
||||
cursor: "pointer",
|
||||
},
|
||||
instructions: {
|
||||
color: "#ffffff",
|
||||
fontSize: 18
|
||||
fontSize: 18,
|
||||
},
|
||||
dragContainer: {
|
||||
paddingLeft: 20,
|
||||
paddingRight: 20,
|
||||
paddingBottom: 20
|
||||
paddingBottom: 20,
|
||||
},
|
||||
drag: {
|
||||
backgroundColor: "#aaaaaa",
|
||||
height: 300,
|
||||
width: "100%"
|
||||
width: "100%",
|
||||
},
|
||||
dragText: {
|
||||
margin: 0,
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)"
|
||||
transform: "translate(-50%, -50%)",
|
||||
},
|
||||
circle: {
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center"
|
||||
justifyContent: "center",
|
||||
},
|
||||
logo: {
|
||||
marginTop: theme.spacing(0),
|
||||
marginBottom: theme.spacing(1)
|
||||
marginBottom: theme.spacing(1),
|
||||
},
|
||||
whiteP: {
|
||||
color: "white",
|
||||
fontSize: "18px"
|
||||
fontSize: "18px",
|
||||
},
|
||||
column_three: {
|
||||
width: "33%"
|
||||
width: "33%",
|
||||
},
|
||||
align_right: {
|
||||
textAlign: "right"
|
||||
textAlign: "right",
|
||||
},
|
||||
align_left: {
|
||||
textAlign: "left"
|
||||
textAlign: "left",
|
||||
},
|
||||
align_center: {
|
||||
textAlign: "center"
|
||||
}
|
||||
textAlign: "center",
|
||||
},
|
||||
}));
|
||||
|
||||
export default myStyle;
|
||||
|
@ -21,8 +21,8 @@ from src.server.outbound_message import NodeType, OutboundMessage, Message, Deli
|
||||
from src.simulator.simulator_protocol import FarmNewBlockProtocol
|
||||
from src.util.ints import uint64, uint32
|
||||
from src.wallet.trade_record import TradeRecord
|
||||
from src.wallet.util.backup_utils import get_backup_info
|
||||
from src.wallet.util.trade_utils import trade_record_to_dict
|
||||
from src.wallet.util.backup_utils import get_backup_info, download_backup, upload_backup
|
||||
from src.wallet.util.cc_utils import trade_record_to_dict
|
||||
from src.wallet.util.wallet_types import WalletType
|
||||
from src.wallet.rl_wallet.rl_wallet import RLWallet
|
||||
from src.wallet.cc_wallet.cc_wallet import CCWallet
|
||||
@ -335,9 +335,25 @@ class WalletRpcApi:
|
||||
|
||||
return response
|
||||
|
||||
async def create_backup_and_upload(self, host):
|
||||
try:
|
||||
now = time.time()
|
||||
file_name = f"backup_{now}"
|
||||
path = path_from_root(self.service.root_path, file_name)
|
||||
await self.service.wallet_state_manager.create_wallet_backup(path)
|
||||
backup_text = path.read_text()
|
||||
response = await upload_backup(host, backup_text)
|
||||
success = response["success"]
|
||||
if success is False:
|
||||
log.error("Failed to upload backup to wallet backup service")
|
||||
elif success is True:
|
||||
log.info("Finished upload of the backup file")
|
||||
except BaseException as e:
|
||||
log.error(f"Exception in upload backup. Error: {e}")
|
||||
|
||||
async def create_new_wallet(self, request):
|
||||
config, wallet_state_manager, main_wallet = self.get_wallet_config()
|
||||
|
||||
host = request["host"]
|
||||
if request["wallet_type"] == "cc_wallet":
|
||||
if request["mode"] == "new":
|
||||
try:
|
||||
@ -345,6 +361,7 @@ class WalletRpcApi:
|
||||
wallet_state_manager, main_wallet, request["amount"]
|
||||
)
|
||||
colour = cc_wallet.get_colour()
|
||||
asyncio.ensure_future(self.create_backup_and_upload(host))
|
||||
return {
|
||||
"success": True,
|
||||
"type": cc_wallet.wallet_info.type,
|
||||
@ -359,6 +376,7 @@ class WalletRpcApi:
|
||||
cc_wallet = await CCWallet.create_wallet_for_cc(
|
||||
wallet_state_manager, main_wallet, request["colour"]
|
||||
)
|
||||
asyncio.ensure_future(self.create_backup_and_upload(host))
|
||||
return {"success": True, "type": cc_wallet.wallet_info.type}
|
||||
except Exception as e:
|
||||
log.error("FAILED2 {e}")
|
||||
@ -376,6 +394,7 @@ class WalletRpcApi:
|
||||
request["pubkey"],
|
||||
uint64(int(request["amount"])),
|
||||
)
|
||||
asyncio.ensure_future(self.create_backup_and_upload(host))
|
||||
return {
|
||||
"success": success,
|
||||
"id": rl_admin.wallet_info.id,
|
||||
@ -392,7 +411,7 @@ class WalletRpcApi:
|
||||
rl_user: RLWallet = await RLWallet.create_rl_user(
|
||||
wallet_state_manager
|
||||
)
|
||||
|
||||
asyncio.ensure_future(self.create_backup_and_upload(host))
|
||||
return {
|
||||
"success": True,
|
||||
"id": rl_user.wallet_info.id,
|
||||
@ -657,6 +676,7 @@ class WalletRpcApi:
|
||||
await self.stop_wallet()
|
||||
fingerprint = request["fingerprint"]
|
||||
type = request["type"]
|
||||
recovery_host = request["host"]
|
||||
|
||||
if type == "skip":
|
||||
started = await self.service._start(
|
||||
@ -672,9 +692,26 @@ class WalletRpcApi:
|
||||
|
||||
if started is True:
|
||||
return {"success": True}
|
||||
else:
|
||||
if self.service.backup_initialized is False:
|
||||
return {"success": False, "error": "not_initialized"}
|
||||
elif self.service.backup_initialized is False:
|
||||
backup_info = None
|
||||
backup_path = None
|
||||
try:
|
||||
private_key = self.service.get_key_for_fingerprint(fingerprint)
|
||||
last_recovery = await download_backup(recovery_host, private_key)
|
||||
backup_path = path_from_root(self.service.root_path, "last_recovery")
|
||||
if backup_path.exists():
|
||||
backup_path.unlink()
|
||||
backup_path.write_text(last_recovery)
|
||||
backup_info = get_backup_info(backup_path, private_key)
|
||||
backup_info["backup_host"] = recovery_host
|
||||
backup_info["downloaded"] = True
|
||||
except BaseException as e:
|
||||
log.error(f"error {e}")
|
||||
response = {"success": False, "error": "not_initialized"}
|
||||
if backup_info is not None:
|
||||
response["backup_info"] = backup_info
|
||||
response["backup_path"] = f"{backup_path}"
|
||||
return response
|
||||
|
||||
return {"success": False, "error": "Unknown Error"}
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
import base64
|
||||
import json
|
||||
from typing import Any
|
||||
|
||||
from blspy import PublicKeyMPL, SignatureMPL, AugSchemeMPL
|
||||
import aiohttp
|
||||
from blspy import PublicKeyMPL, SignatureMPL, AugSchemeMPL, PrivateKey
|
||||
from cryptography.fernet import Fernet
|
||||
|
||||
from src.util.byte_types import hexstr_to_bytes
|
||||
@ -65,3 +67,49 @@ def get_backup_info(file_path, private_key):
|
||||
info_dict["wallets"] = wallets
|
||||
|
||||
return info_dict
|
||||
|
||||
|
||||
async def post(session: aiohttp.ClientSession, url: str, data: Any):
|
||||
response = await session.post(url, json=data)
|
||||
return await response.json()
|
||||
|
||||
|
||||
async def get(session: aiohttp.ClientSession, url: str):
|
||||
response = await session.get(url)
|
||||
return await response.text()
|
||||
|
||||
|
||||
async def upload_backup(host: str, backup_text: str):
|
||||
request = {"backup": backup_text}
|
||||
session = aiohttp.ClientSession()
|
||||
nonce_url = f"{host}/upload_backup"
|
||||
upload_response = await post(session, nonce_url, request)
|
||||
return upload_response
|
||||
|
||||
|
||||
async def download_backup(host: str, private_key: PrivateKey):
|
||||
session = aiohttp.ClientSession()
|
||||
backup_privkey = master_sk_to_backup_sk(private_key)
|
||||
backup_pubkey = bytes(backup_privkey.get_g1()).hex()
|
||||
|
||||
# Get nonce
|
||||
nonce_request = {"pubkey": backup_pubkey}
|
||||
nonce_url = f"{host}/get_download_nonce"
|
||||
nonce_response = await post(session, nonce_url, nonce_request)
|
||||
nonce = nonce_response["nonce"]
|
||||
|
||||
# Sign nonce
|
||||
signature = bytes(
|
||||
AugSchemeMPL.sign(backup_privkey, std_hash(hexstr_to_bytes(nonce)))
|
||||
).hex()
|
||||
# Request backup url
|
||||
get_backup_url = f"{host}/download_backup"
|
||||
backup_request = {"pubkey": backup_pubkey, "signature": signature}
|
||||
backup_response = await post(session, get_backup_url, backup_request)
|
||||
|
||||
# Download from s3
|
||||
assert backup_response["success"] is True
|
||||
backup_url = backup_response["url"]
|
||||
backup_text = await get(session, backup_url)
|
||||
|
||||
return backup_text
|
||||
|
@ -115,19 +115,13 @@ class WalletNode:
|
||||
self.sync_generator_task = None
|
||||
self.server = None
|
||||
|
||||
async def _start(
|
||||
self,
|
||||
fingerprint: Optional[int] = None,
|
||||
new_wallet: bool = False,
|
||||
backup_file: Optional[Path] = None,
|
||||
skip_backup_import: bool = False,
|
||||
) -> bool:
|
||||
def get_key_for_fingerprint(self, fingerprint):
|
||||
private_keys = self.keychain.get_all_private_keys()
|
||||
if len(private_keys) == 0:
|
||||
self.log.warning(
|
||||
"No keys present. Create keys with the UI, or with the 'chia keys' program."
|
||||
)
|
||||
return False
|
||||
return None
|
||||
|
||||
private_key: Optional[PrivateKey] = None
|
||||
if fingerprint is not None:
|
||||
@ -137,7 +131,16 @@ class WalletNode:
|
||||
break
|
||||
else:
|
||||
private_key = private_keys[0][0]
|
||||
return private_key
|
||||
|
||||
async def _start(
|
||||
self,
|
||||
fingerprint: Optional[int] = None,
|
||||
new_wallet: bool = False,
|
||||
backup_file: Optional[Path] = None,
|
||||
skip_backup_import: bool = False,
|
||||
) -> bool:
|
||||
private_key = self.get_key_for_fingerprint(fingerprint)
|
||||
if private_key is None:
|
||||
raise RuntimeError("Invalid fingerprint {public_key_fingerprint}")
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user