2020-09-14 15:06:41 +03:00
|
|
|
from pathlib import Path
|
2021-03-10 05:27:27 +03:00
|
|
|
from typing import Dict, List
|
|
|
|
|
2020-07-25 06:46:18 +03:00
|
|
|
from src.rpc.rpc_client import RpcClient
|
2021-02-16 12:15:24 +03:00
|
|
|
from src.types.blockchain_format.sized_bytes import bytes32
|
2021-01-14 18:29:51 +03:00
|
|
|
from src.util.bech32m import decode_puzzle_hash
|
2021-03-10 05:27:27 +03:00
|
|
|
from src.util.ints import uint32, uint64
|
|
|
|
from src.wallet.transaction_record import TransactionRecord
|
2020-07-25 06:46:18 +03:00
|
|
|
|
|
|
|
|
|
|
|
class WalletRpcClient(RpcClient):
|
|
|
|
"""
|
|
|
|
Client to Chia RPC, connects to a local wallet. Uses HTTP/JSON, and converts back from
|
|
|
|
JSON into native python objects before returning. All api calls use POST requests.
|
|
|
|
Note that this is not the same as the peer protocol, or wallet protocol (which run Chia's
|
|
|
|
protocol on top of TCP), it's a separate protocol on top of HTTP thats provides easy access
|
|
|
|
to the full node.
|
|
|
|
"""
|
|
|
|
|
2020-09-14 15:06:41 +03:00
|
|
|
# Key Management APIs
|
|
|
|
async def log_in(self, fingerprint: int) -> Dict:
|
2020-09-14 17:59:27 +03:00
|
|
|
try:
|
|
|
|
return await self.fetch(
|
|
|
|
"log_in",
|
2021-01-06 07:13:39 +03:00
|
|
|
{"host": "https://backup.chia.net", "fingerprint": fingerprint, "type": "start"},
|
2020-09-14 17:59:27 +03:00
|
|
|
)
|
2021-01-06 07:13:39 +03:00
|
|
|
|
2020-09-14 17:59:27 +03:00
|
|
|
except ValueError as e:
|
|
|
|
return e.args[0]
|
2020-09-09 08:13:24 +03:00
|
|
|
|
2020-09-14 15:06:41 +03:00
|
|
|
async def log_in_and_restore(self, fingerprint: int, file_path) -> Dict:
|
2020-09-14 17:59:27 +03:00
|
|
|
try:
|
|
|
|
return await self.fetch(
|
|
|
|
"log_in",
|
|
|
|
{
|
|
|
|
"host": "https://backup.chia.net",
|
|
|
|
"fingerprint": fingerprint,
|
|
|
|
"type": "restore_backup",
|
|
|
|
"file_path": file_path,
|
|
|
|
},
|
|
|
|
)
|
|
|
|
except ValueError as e:
|
|
|
|
return e.args[0]
|
2020-09-11 06:03:06 +03:00
|
|
|
|
2020-09-14 15:06:41 +03:00
|
|
|
async def log_in_and_skip(self, fingerprint: int) -> Dict:
|
2020-09-14 17:59:27 +03:00
|
|
|
try:
|
|
|
|
return await self.fetch(
|
|
|
|
"log_in",
|
2021-01-06 07:13:39 +03:00
|
|
|
{"host": "https://backup.chia.net", "fingerprint": fingerprint, "type": "skip"},
|
2020-09-14 17:59:27 +03:00
|
|
|
)
|
|
|
|
except ValueError as e:
|
|
|
|
return e.args[0]
|
2020-09-11 06:03:06 +03:00
|
|
|
|
2020-09-14 15:06:41 +03:00
|
|
|
async def get_public_keys(self) -> List[int]:
|
|
|
|
return (await self.fetch("get_public_keys", {}))["public_key_fingerprints"]
|
|
|
|
|
|
|
|
async def get_private_key(self, fingerprint: int) -> Dict:
|
2020-12-10 08:46:43 +03:00
|
|
|
return (await self.fetch("get_private_key", {"fingerprint": fingerprint}))["private_key"]
|
2020-09-14 15:06:41 +03:00
|
|
|
|
|
|
|
async def generate_mnemonic(self) -> List[str]:
|
|
|
|
return (await self.fetch("generate_mnemonic", {}))["mnemonic"]
|
|
|
|
|
2020-12-10 08:46:43 +03:00
|
|
|
async def add_key(self, mnemonic: List[str], request_type: str = "new_wallet") -> None:
|
2020-09-14 15:06:41 +03:00
|
|
|
return await self.fetch("add_key", {"mnemonic": mnemonic, "type": request_type})
|
|
|
|
|
|
|
|
async def delete_key(self, fingerprint: int) -> None:
|
|
|
|
return await self.fetch("delete_key", {"fingerprint": fingerprint})
|
|
|
|
|
|
|
|
async def delete_all_keys(self) -> None:
|
|
|
|
return await self.fetch("delete_all_keys", {})
|
2020-09-11 11:26:25 +03:00
|
|
|
|
2020-09-14 15:06:41 +03:00
|
|
|
# Wallet Node APIs
|
|
|
|
async def get_sync_status(self) -> bool:
|
|
|
|
return (await self.fetch("get_sync_status", {}))["syncing"]
|
2020-09-11 06:03:06 +03:00
|
|
|
|
2020-09-14 15:06:41 +03:00
|
|
|
async def get_height_info(self) -> uint32:
|
|
|
|
return (await self.fetch("get_height_info", {}))["height"]
|
|
|
|
|
|
|
|
async def farm_block(self, address: str) -> None:
|
|
|
|
return await self.fetch("farm_block", {"address": address})
|
|
|
|
|
|
|
|
# Wallet Management APIs
|
|
|
|
async def get_wallets(self) -> Dict:
|
|
|
|
return (await self.fetch("get_wallets", {}))["wallets"]
|
|
|
|
|
|
|
|
# Wallet APIs
|
|
|
|
async def get_wallet_balance(self, wallet_id: str) -> Dict:
|
2020-12-10 08:46:43 +03:00
|
|
|
return (await self.fetch("get_wallet_balance", {"wallet_id": wallet_id}))["wallet_balance"]
|
2020-09-14 15:06:41 +03:00
|
|
|
|
2020-12-10 08:46:43 +03:00
|
|
|
async def get_transaction(self, wallet_id: str, transaction_id: bytes32) -> TransactionRecord:
|
2020-09-14 07:38:08 +03:00
|
|
|
res = await self.fetch(
|
2020-09-11 06:03:06 +03:00
|
|
|
"get_transaction",
|
|
|
|
{"walled_id": wallet_id, "transaction_id": transaction_id.hex()},
|
|
|
|
)
|
2020-09-14 12:29:03 +03:00
|
|
|
return TransactionRecord.from_json_dict(res["transaction"])
|
|
|
|
|
2020-09-15 19:56:04 +03:00
|
|
|
async def get_transactions(
|
|
|
|
self,
|
|
|
|
wallet_id: str,
|
|
|
|
) -> List[TransactionRecord]:
|
|
|
|
res = await self.fetch(
|
|
|
|
"get_transactions",
|
|
|
|
{"wallet_id": wallet_id},
|
|
|
|
)
|
2020-09-14 12:29:03 +03:00
|
|
|
reverted_tx: List[TransactionRecord] = []
|
|
|
|
for modified_tx in res["transactions"]:
|
|
|
|
# Server returns address instead of ph, but TransactionRecord requires ph
|
2020-12-10 08:46:43 +03:00
|
|
|
modified_tx["to_puzzle_hash"] = decode_puzzle_hash(modified_tx["to_address"]).hex()
|
2020-09-14 12:29:03 +03:00
|
|
|
del modified_tx["to_address"]
|
|
|
|
reverted_tx.append(TransactionRecord.from_json_dict(modified_tx))
|
|
|
|
return reverted_tx
|
2020-09-11 06:03:06 +03:00
|
|
|
|
2021-03-12 06:36:28 +03:00
|
|
|
async def get_next_address(self, wallet_id: str, new_address: bool) -> str:
|
|
|
|
return (await self.fetch("get_next_address", {"wallet_id": wallet_id, "new_address": new_address}))["address"]
|
2020-09-09 08:13:24 +03:00
|
|
|
|
2020-09-14 15:06:41 +03:00
|
|
|
async def send_transaction(
|
|
|
|
self, wallet_id: str, amount: uint64, address: str, fee: uint64 = uint64(0)
|
|
|
|
) -> TransactionRecord:
|
|
|
|
|
|
|
|
res = await self.fetch(
|
|
|
|
"send_transaction",
|
2020-09-14 17:53:34 +03:00
|
|
|
{"wallet_id": wallet_id, "amount": amount, "address": address, "fee": fee},
|
2020-09-09 08:13:24 +03:00
|
|
|
)
|
2020-09-14 15:06:41 +03:00
|
|
|
return TransactionRecord.from_json_dict(res["transaction"])
|
2020-09-09 08:13:24 +03:00
|
|
|
|
2020-09-14 15:06:41 +03:00
|
|
|
async def create_backup(self, file_path: Path) -> None:
|
2020-12-10 08:46:43 +03:00
|
|
|
return await self.fetch("create_backup", {"file_path": str(file_path.resolve())})
|
2020-09-09 08:13:24 +03:00
|
|
|
|
2021-03-11 19:52:29 +03:00
|
|
|
async def get_farmed_amount(self) -> Dict:
|
|
|
|
return await self.fetch("get_farmed_amount", {})
|
|
|
|
|
2020-09-14 15:06:41 +03:00
|
|
|
|
|
|
|
# TODO: add APIs for coloured coins and RL wallet
|