add file necryption
This commit is contained in:
parent
8ee1ebb266
commit
94e4afc652
|
@ -288,30 +288,40 @@ export const login_action = fingerprint => {
|
|||
};
|
||||
};
|
||||
|
||||
export const get_backup_info = file_path => {
|
||||
export const get_backup_info = (file_path, fingerprint, words) => {
|
||||
var action = walletMessage();
|
||||
action.message.command = "get_backup_info";
|
||||
action.message.data = {
|
||||
file_path: file_path
|
||||
};
|
||||
if (fingerprint === null) {
|
||||
action.message.data = {
|
||||
file_path: file_path,
|
||||
words: words
|
||||
};
|
||||
} else if (words === null) {
|
||||
action.message.data = {
|
||||
file_path: file_path,
|
||||
fingerprint: fingerprint
|
||||
};
|
||||
}
|
||||
return action;
|
||||
};
|
||||
|
||||
export const get_backup_info_action = file_path => {
|
||||
export const get_backup_info_action = (file_path, fingerprint, words) => {
|
||||
return dispatch => {
|
||||
dispatch(selectFilePath(file_path));
|
||||
return async_api(dispatch, get_backup_info(file_path), true).then(
|
||||
response => {
|
||||
dispatch(closeProgress());
|
||||
if (response.data.success) {
|
||||
dispatch(setBackupInfo(response.data.backup_info));
|
||||
dispatch(changeBackupView(presentBackupInfo));
|
||||
} else {
|
||||
const error = response.data.error;
|
||||
dispatch(openDialog("Error", error));
|
||||
}
|
||||
return async_api(
|
||||
dispatch,
|
||||
get_backup_info(file_path, fingerprint, words),
|
||||
true
|
||||
).then(response => {
|
||||
dispatch(closeProgress());
|
||||
if (response.data.success) {
|
||||
dispatch(setBackupInfo(response.data.backup_info));
|
||||
dispatch(changeBackupView(presentBackupInfo));
|
||||
} else {
|
||||
const error = response.data.error;
|
||||
dispatch(openDialog("Error", error));
|
||||
}
|
||||
);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -45,8 +45,6 @@ const UIPart = props => {
|
|||
}
|
||||
|
||||
function skip() {
|
||||
dispatch(get_backup_info_action("/Users/yostra/Desktop/tri"));
|
||||
return;
|
||||
if (fingerprint !== null) {
|
||||
dispatch(login_and_skip_action(fingerprint));
|
||||
} else if (words !== null) {
|
||||
|
@ -72,7 +70,11 @@ const UIPart = props => {
|
|||
|
||||
const file_path = e.dataTransfer.files[0].path;
|
||||
debugger;
|
||||
dispatch(get_backup_info_action(file_path));
|
||||
if (fingerprint !== null) {
|
||||
dispatch(get_backup_info_action(file_path, fingerprint, null));
|
||||
} else if (words !== null) {
|
||||
dispatch(get_backup_info_action(file_path, null, words));
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
@ -5,6 +5,8 @@ from pathlib import Path
|
|||
|
||||
from typing import List, Optional, Tuple, Dict, Callable
|
||||
|
||||
from blspy import PrivateKey
|
||||
|
||||
from src.util.byte_types import hexstr_to_bytes
|
||||
from src.util.keychain import (
|
||||
generate_mnemonic,
|
||||
|
@ -439,7 +441,7 @@ class WalletRpcApi:
|
|||
async def cc_get_colour(self, request):
|
||||
wallet_id = int(request["wallet_id"])
|
||||
wallet: CCWallet = self.service.wallet_state_manager.wallets[wallet_id]
|
||||
colour: str = await wallet.get_colour()
|
||||
colour: str = wallet.get_colour()
|
||||
response = {"colour": colour, "wallet_id": wallet_id}
|
||||
return response
|
||||
|
||||
|
@ -453,7 +455,7 @@ class WalletRpcApi:
|
|||
type = wallet.wallet_info.type
|
||||
if type == WalletType.COLOURED_COIN.value:
|
||||
name = wallet.cc_info.my_colour_name
|
||||
colour = await wallet.get_colour()
|
||||
colour = wallet.get_colour()
|
||||
response[wallet_id] = {
|
||||
"type": type,
|
||||
"balance": balance,
|
||||
|
@ -510,7 +512,34 @@ class WalletRpcApi:
|
|||
|
||||
async def get_backup_info(self, request: Dict):
|
||||
file_path = Path(request["file_path"])
|
||||
backup_info = get_backup_info(file_path)
|
||||
sk = None
|
||||
if "words" in request:
|
||||
mnemonic = request["words"]
|
||||
passphrase = ""
|
||||
try:
|
||||
sk = self.service.keychain.add_private_key(
|
||||
" ".join(mnemonic), passphrase
|
||||
)
|
||||
except KeyError as e:
|
||||
return {
|
||||
"success": False,
|
||||
"error": f"The word '{e.args[0]}' is incorrect.'",
|
||||
"word": e.args[0],
|
||||
}
|
||||
except ValueError as e:
|
||||
return {
|
||||
"success": False,
|
||||
"error": e.args[0],
|
||||
}
|
||||
elif "fingerprint" in request:
|
||||
sk, seed = await self._get_private_key(request["fingerprint"])
|
||||
|
||||
if sk is None:
|
||||
return {
|
||||
"success": False,
|
||||
"error": "Unable to decrypt the backup file, no such key."
|
||||
}
|
||||
backup_info = get_backup_info(file_path, sk)
|
||||
response = {"success": True, "backup_info": backup_info}
|
||||
return response
|
||||
|
||||
|
@ -537,20 +566,26 @@ class WalletRpcApi:
|
|||
response = {"success": True, "public_key_fingerprints": fingerprints}
|
||||
return response
|
||||
|
||||
async def get_private_key(self, request):
|
||||
fingerprint = request["fingerprint"]
|
||||
async def _get_private_key(self, fingerprint) -> Tuple[Optional[PrivateKey], Optional[bytes]]:
|
||||
for sk, seed in self.service.keychain.get_all_private_keys():
|
||||
if sk.get_g1().get_fingerprint() == fingerprint:
|
||||
s = bytes_to_mnemonic(seed) if seed is not None else None
|
||||
return {
|
||||
"success": True,
|
||||
"private_key": {
|
||||
"fingerprint": fingerprint,
|
||||
"sk": bytes(sk).hex(),
|
||||
"pk": bytes(sk.get_g1()).hex(),
|
||||
"seed": s,
|
||||
},
|
||||
}
|
||||
return sk, seed
|
||||
return None, None
|
||||
|
||||
async def get_private_key(self, request):
|
||||
fingerprint = request["fingerprint"]
|
||||
sk, seed = await self._get_private_key(fingerprint)
|
||||
if sk is not None:
|
||||
s = bytes_to_mnemonic(seed) if seed is not None else None
|
||||
return {
|
||||
"success": True,
|
||||
"private_key": {
|
||||
"fingerprint": fingerprint,
|
||||
"sk": bytes(sk).hex(),
|
||||
"pk": bytes(sk.get_g1()).hex(),
|
||||
"seed": s,
|
||||
},
|
||||
}
|
||||
return {"success": False, "private_key": {"fingerprint": fingerprint}}
|
||||
|
||||
async def log_in(self, request):
|
||||
|
|
|
@ -228,7 +228,7 @@ class CCWallet:
|
|||
self.wallet_info = new_info
|
||||
await self.wallet_state_manager.user_store.update_wallet(self.wallet_info)
|
||||
|
||||
async def get_colour(self):
|
||||
def get_colour(self):
|
||||
return self.cc_info.my_colour_name
|
||||
|
||||
async def coin_added(
|
||||
|
@ -516,7 +516,7 @@ class CCWallet:
|
|||
our_spend = False
|
||||
for coin in record.removals:
|
||||
# Don't count eve spend as change
|
||||
if coin.parent_coin_info.hex() == await self.get_colour():
|
||||
if coin.parent_coin_info.hex() == self.get_colour():
|
||||
continue
|
||||
if await self.wallet_state_manager.does_coin_belong_to_wallet(
|
||||
coin, self.wallet_info.id
|
||||
|
|
|
@ -5,7 +5,7 @@ from src.util.ints import uint32
|
|||
# https://eips.ethereum.org/EIPS/eip-2334
|
||||
# 12381 = bls spec number
|
||||
# 8444 = Chia blockchain number and port number
|
||||
# 0, 1, 2, 3, farmer, pool, wallet, local key numbers
|
||||
# 0, 1, 2, 3, 4, farmer, pool, wallet, local, backup key numbers
|
||||
|
||||
|
||||
def master_sk_to_farmer_sk(master: PrivateKey) -> PrivateKey:
|
||||
|
@ -27,3 +27,7 @@ def master_sk_to_wallet_sk(master: PrivateKey, index: uint32) -> PrivateKey:
|
|||
|
||||
def master_sk_to_local_sk(master: PrivateKey) -> PrivateKey:
|
||||
return master.derive_child(12381).derive_child(8444).derive_child(3).derive_child(0)
|
||||
|
||||
|
||||
def master_sk_to_backup_sk(master: PrivateKey) -> PrivateKey:
|
||||
return master.derive_child(12381).derive_child(8444).derive_child(4).derive_child(0)
|
||||
|
|
|
@ -1,13 +1,23 @@
|
|||
import base64
|
||||
import json
|
||||
|
||||
from cryptography.fernet import Fernet
|
||||
|
||||
from src.wallet.derive_keys import master_sk_to_backup_sk
|
||||
from src.wallet.util.wallet_types import WalletType
|
||||
|
||||
|
||||
def get_backup_info(file_path):
|
||||
def get_backup_info(file_path, private_key):
|
||||
info_dict = {}
|
||||
wallets = []
|
||||
|
||||
backup_text = file_path.read_text()
|
||||
encrypted_backup_text = file_path.read_text()
|
||||
backup_pk = master_sk_to_backup_sk(private_key)
|
||||
key_base_64 = base64.b64encode(bytes(backup_pk))
|
||||
f = Fernet(key_base_64)
|
||||
backup_text_data = f.decrypt(encrypted_backup_text.encode())
|
||||
|
||||
backup_text = backup_text_data.decode()
|
||||
json_dict = json.loads(backup_text)
|
||||
|
||||
wallet_list_json = json_dict["wallet_list"]
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import base64
|
||||
import json
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
@ -9,6 +10,7 @@ import asyncio
|
|||
import aiosqlite
|
||||
from chiabip158 import PyBIP158
|
||||
from blspy import PrivateKey, G1Element
|
||||
from cryptography.fernet import Fernet
|
||||
|
||||
from src.consensus.constants import ConsensusConstants
|
||||
from src.types.coin import Coin
|
||||
|
@ -45,7 +47,7 @@ from src.types.program import Program
|
|||
from src.wallet.derivation_record import DerivationRecord
|
||||
from src.wallet.util.wallet_types import WalletType
|
||||
from src.consensus.find_fork_point import find_fork_point_in_chain
|
||||
from src.wallet.derive_keys import master_sk_to_wallet_sk
|
||||
from src.wallet.derive_keys import master_sk_to_wallet_sk, master_sk_to_backup_sk
|
||||
from src import __version__
|
||||
|
||||
|
||||
|
@ -1331,10 +1333,23 @@ class WalletStateManager:
|
|||
json_dict["version"] = __version__
|
||||
json_dict["fingerprint"] = self.private_key.get_g1().get_fingerprint()
|
||||
json_dict["timestamp"] = uint64(int(time.time()))
|
||||
file_path.write_text(json.dumps(json_dict))
|
||||
|
||||
backup_pk = master_sk_to_backup_sk(self.private_key)
|
||||
key_base_64 = base64.b64encode(bytes(backup_pk))
|
||||
f = Fernet(key_base_64)
|
||||
|
||||
backup_data = json.dumps(json_dict).encode()
|
||||
encrypted = f.encrypt(backup_data)
|
||||
file_path.write_text(encrypted.decode())
|
||||
|
||||
async def import_backup_info(self, file_path):
|
||||
backup_text = file_path.read_text()
|
||||
encrypted_backup_text = file_path.read_text()
|
||||
backup_pk = master_sk_to_backup_sk(self.private_key)
|
||||
key_base_64 = base64.b64encode(bytes(backup_pk))
|
||||
f = Fernet(key_base_64)
|
||||
backup_text_data = f.decrypt(encrypted_backup_text.encode())
|
||||
backup_text = backup_text_data.decode()
|
||||
|
||||
json_dict = json.loads(backup_text)
|
||||
wallet_list_json = json_dict["wallet_list"]
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ class TestCCWallet:
|
|||
for i in range(1, num_blocks):
|
||||
await full_node_1.farm_new_block(FarmNewBlockProtocol(ph))
|
||||
|
||||
colour = await cc_wallet.get_colour()
|
||||
colour = cc_wallet.get_colour()
|
||||
assert (
|
||||
await wallet_node.wallet_state_manager.get_wallet_for_colour(colour)
|
||||
== cc_wallet
|
||||
|
|
|
@ -215,8 +215,8 @@ class TestCCTrades:
|
|||
assert offer is not None
|
||||
assert offer["chia"] == -1000
|
||||
|
||||
colour_2 = await cc_a_2.get_colour()
|
||||
colour_3 = await cc_a_3.get_colour()
|
||||
colour_2 = cc_a_2.get_colour()
|
||||
colour_3 = cc_a_3.get_colour()
|
||||
|
||||
assert offer[colour_2] == 20
|
||||
assert offer[colour_3] == 50
|
||||
|
@ -265,7 +265,7 @@ class TestCCTrades:
|
|||
|
||||
await time_out_assert(15, cc_a_4.get_confirmed_balance, 100)
|
||||
|
||||
colour = await cc_a_4.get_colour()
|
||||
colour = cc_a_4.get_colour()
|
||||
|
||||
cc_b_4: CCWallet = await CCWallet.create_wallet_for_cc(
|
||||
wallet_node_b.wallet_state_manager, wallet_b, colour
|
||||
|
|
Loading…
Reference in New Issue