Skip to content

[CHIA-3598] Port easy wallet endpoints to @marshal #19941

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 33 additions & 19 deletions chia/_tests/cmds/cmd_test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from pathlib import Path
from typing import Any, Optional, cast

from chia_rs import BlockRecord, Coin, G2Element
from chia_rs import BlockRecord, Coin, G1Element, G2Element
from chia_rs.sized_bytes import bytes32
from chia_rs.sized_ints import uint8, uint16, uint32, uint64

Expand Down Expand Up @@ -44,6 +44,10 @@
NFTGetInfo,
NFTGetInfoResponse,
SendTransactionMultiResponse,
SignMessageByAddress,
SignMessageByAddressResponse,
SignMessageByID,
SignMessageByIDResponse,
WalletInfoResponse,
)
from chia.wallet.wallet_rpc_client import WalletRpcClient
Expand Down Expand Up @@ -147,19 +151,37 @@ async def get_cat_name(self, wallet_id: int) -> str:
self.add_to_log("get_cat_name", (wallet_id,))
return "test" + str(wallet_id)

async def sign_message_by_address(self, address: str, message: str) -> tuple[str, str, str]:
self.add_to_log("sign_message_by_address", (address, message))
pubkey = bytes([3] * 48).hex()
signature = bytes([6] * 576).hex()
async def sign_message_by_address(self, request: SignMessageByAddress) -> SignMessageByAddressResponse:
self.add_to_log("sign_message_by_address", (request.address, request.message))
pubkey = G1Element.from_bytes(
bytes.fromhex(
"b5acf3599bc5fa5da1c00f6cc3d5bcf1560def67778b7f50a8c373a83f78761505b6250ab776e38a292e26628009aec4"
)
)
signature = G2Element.from_bytes(
bytes.fromhex(
"c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
)
)
signing_mode = SigningMode.CHIP_0002.value
return pubkey, signature, signing_mode
return SignMessageByAddressResponse(pubkey, signature, signing_mode)

async def sign_message_by_id(self, id: str, message: str) -> tuple[str, str, str]:
self.add_to_log("sign_message_by_id", (id, message))
pubkey = bytes([4] * 48).hex()
signature = bytes([7] * 576).hex()
async def sign_message_by_id(self, request: SignMessageByID) -> SignMessageByIDResponse:
self.add_to_log("sign_message_by_id", (request.id, request.message))
pubkey = G1Element.from_bytes(
bytes.fromhex(
"a9e652cb551d5978a9ee4b7aa52a4e826078a54b08a3d903c38611cb8a804a9a29c926e4f8549314a079e04ecde10cc1"
)
)
signature = G2Element.from_bytes(
bytes.fromhex(
"c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
)
)
signing_mode = SigningMode.CHIP_0002.value
return pubkey, signature, signing_mode
return SignMessageByIDResponse(pubkey, signature, bytes32.zeros, signing_mode)

async def cat_asset_id_to_name(self, asset_id: bytes32) -> Optional[tuple[Optional[uint32], str]]:
"""
Expand Down Expand Up @@ -250,14 +272,6 @@ async def get_spendable_coins(
unconfirmed_additions = [Coin(bytes32([7] * 32), bytes32([8] * 32), uint64(1234580000))]
return confirmed_records, unconfirmed_removals, unconfirmed_additions

async def get_next_address(self, wallet_id: int, new_address: bool) -> str:
self.add_to_log("get_next_address", (wallet_id, new_address))
addr = encode_puzzle_hash(bytes32([self.wallet_index] * 32), "xch")
self.wallet_index += 1
if self.wallet_index > 254:
self.wallet_index = 1
return addr

async def send_transaction_multi(
self,
wallet_id: int,
Expand Down
4 changes: 2 additions & 2 deletions chia/_tests/cmds/wallet/test_did.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ def test_did_sign_message(capsys: object, get_test_cli_clients: tuple[TestRpcCli
# these are various things that should be in the output
assert_list = [
f"Message: {message.hex()}",
f"Public Key: {bytes([4] * 48).hex()}",
f"Signature: {bytes([7] * 576).hex()}",
"Public Key: a9e652cb551d5978a9ee4b7aa52a4e826078a54b08a3d903c38611cb8a804a9a29c926e4f8549314a079e04ecde10cc1",
"Signature: c0" + "00" * (42 - 1),
f"Signing Mode: {SigningMode.CHIP_0002.value}",
]
run_cli_command_and_assert(capsys, root_dir, [*command_args, f"-i{did_id}"], assert_list)
Expand Down
12 changes: 6 additions & 6 deletions chia/_tests/cmds/wallet/test_nft.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,19 +64,19 @@ def test_nft_sign_message(capsys: object, get_test_cli_clients: tuple[TestRpcCli

inst_rpc_client = TestWalletRpcClient()
test_rpc_clients.wallet_rpc_client = inst_rpc_client
did_id = encode_puzzle_hash(get_bytes32(1), "nft")
nft_id = encode_puzzle_hash(get_bytes32(1), "nft")
message = b"hello nft world!!"
command_args = ["wallet", "did", "sign_message", FINGERPRINT_ARG, f"-m{message.hex()}"]
command_args = ["wallet", "nft", "sign_message", FINGERPRINT_ARG, f"-m{message.hex()}"]
# these are various things that should be in the output
assert_list = [
f"Message: {message.hex()}",
f"Public Key: {bytes([4] * 48).hex()}",
f"Signature: {bytes([7] * 576).hex()}",
"Public Key: a9e652cb551d5978a9ee4b7aa52a4e826078a54b08a3d903c38611cb8a804a9a29c926e4f8549314a079e04ecde10cc1",
"Signature: c0" + "00" * (42 - 1),
f"Signing Mode: {SigningMode.CHIP_0002.value}",
]
run_cli_command_and_assert(capsys, root_dir, [*command_args, f"-i{did_id}"], assert_list)
run_cli_command_and_assert(capsys, root_dir, [*command_args, f"-i{nft_id}"], assert_list)
expected_calls: logType = {
"sign_message_by_id": [(did_id, message.hex())], # xch std
"sign_message_by_id": [(nft_id, message.hex())], # xch std
}
test_rpc_clients.wallet_rpc_client.check_log(expected_calls)

Expand Down
28 changes: 22 additions & 6 deletions chia/_tests/cmds/wallet/test_notifications.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from pathlib import Path
from typing import Optional, cast
from typing import cast

from chia_rs.sized_bytes import bytes32
from chia_rs.sized_ints import uint32, uint64
Expand All @@ -12,7 +12,7 @@
from chia.wallet.conditions import ConditionValidTimes
from chia.wallet.notification_store import Notification
from chia.wallet.transaction_record import TransactionRecord
from chia.wallet.wallet_request_types import GetNotifications, GetNotificationsResponse
from chia.wallet.wallet_request_types import DeleteNotifications, GetNotifications, GetNotificationsResponse

test_condition_valid_times: ConditionValidTimes = ConditionValidTimes(min_time=uint64(100), max_time=uint64(150))

Expand Down Expand Up @@ -111,15 +111,31 @@ def test_notifications_delete(capsys: object, get_test_cli_clients: tuple[TestRp

# set RPC Client
class NotificationsDeleteRpcClient(TestWalletRpcClient):
async def delete_notifications(self, ids: Optional[list[bytes32]] = None) -> bool:
self.add_to_log("delete_notifications", (ids,))
return True
async def delete_notifications(self, request: DeleteNotifications) -> None:
self.add_to_log("delete_notifications", (request.ids,))

inst_rpc_client = NotificationsDeleteRpcClient()
test_rpc_clients.wallet_rpc_client = inst_rpc_client
# Try all first
command_args = ["wallet", "notifications", "delete", FINGERPRINT_ARG, "--all"]
# these are various things that should be in the output
assert_list = ["Success: True"]
assert_list = ["Success!"]
run_cli_command_and_assert(capsys, root_dir, command_args, assert_list)
expected_calls: logType = {"delete_notifications": [(None,)]}
test_rpc_clients.wallet_rpc_client.check_log(expected_calls)
# Next try specifying IDs
command_args = [
"wallet",
"notifications",
"delete",
FINGERPRINT_ARG,
"--id",
bytes32.zeros.hex(),
"--id",
bytes32.zeros.hex(),
]
# these are various things that should be in the output
assert_list = ["Success!"]
run_cli_command_and_assert(capsys, root_dir, command_args, assert_list)
expected_calls = {"delete_notifications": [([bytes32.zeros, bytes32.zeros],)]}
test_rpc_clients.wallet_rpc_client.check_log(expected_calls)
35 changes: 21 additions & 14 deletions chia/_tests/cmds/wallet/test_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,14 @@
CancelOfferResponse,
CATSpendResponse,
CreateOfferForIDsResponse,
DeleteUnconfirmedTransactions,
ExtendDerivationIndex,
ExtendDerivationIndexResponse,
FungibleAsset,
GetCurrentDerivationIndexResponse,
GetHeightInfoResponse,
GetNextAddress,
GetNextAddressResponse,
GetTransaction,
GetTransactions,
GetTransactionsResponse,
Expand Down Expand Up @@ -493,11 +499,11 @@ def test_get_address(capsys: object, get_test_cli_clients: tuple[TestRpcClients,

# set RPC Client
class GetAddressWalletRpcClient(TestWalletRpcClient):
async def get_next_address(self, wallet_id: int, new_address: bool) -> str:
self.add_to_log("get_next_address", (wallet_id, new_address))
if new_address:
return encode_puzzle_hash(get_bytes32(3), "xch")
return encode_puzzle_hash(get_bytes32(4), "xch")
async def get_next_address(self, request: GetNextAddress) -> GetNextAddressResponse:
self.add_to_log("get_next_address", (request.wallet_id, request.new_address))
if request.new_address:
return GetNextAddressResponse(request.wallet_id, encode_puzzle_hash(get_bytes32(3), "xch"))
return GetNextAddressResponse(request.wallet_id, encode_puzzle_hash(get_bytes32(4), "xch"))

inst_rpc_client = GetAddressWalletRpcClient()
test_rpc_clients.wallet_rpc_client = inst_rpc_client
Expand Down Expand Up @@ -569,8 +575,8 @@ def test_del_unconfirmed_tx(capsys: object, get_test_cli_clients: tuple[TestRpcC

# set RPC Client
class UnconfirmedTxRpcClient(TestWalletRpcClient):
async def delete_unconfirmed_transactions(self, wallet_id: int) -> None:
self.add_to_log("delete_unconfirmed_transactions", (wallet_id,))
async def delete_unconfirmed_transactions(self, request: DeleteUnconfirmedTransactions) -> None:
self.add_to_log("delete_unconfirmed_transactions", (request.wallet_id,))

inst_rpc_client = UnconfirmedTxRpcClient()
test_rpc_clients.wallet_rpc_client = inst_rpc_client
Expand All @@ -594,9 +600,9 @@ def test_get_derivation_index(capsys: object, get_test_cli_clients: tuple[TestRp

# set RPC Client
class GetDerivationIndexRpcClient(TestWalletRpcClient):
async def get_current_derivation_index(self) -> str:
async def get_current_derivation_index(self) -> GetCurrentDerivationIndexResponse:
self.add_to_log("get_current_derivation_index", ())
return str(520)
return GetCurrentDerivationIndexResponse(uint32(520))

inst_rpc_client = GetDerivationIndexRpcClient()
test_rpc_clients.wallet_rpc_client = inst_rpc_client
Expand Down Expand Up @@ -625,8 +631,9 @@ def test_sign_message(capsys: object, get_test_cli_clients: tuple[TestRpcClients
# these are various things that should be in the output
assert_list = [
f"Message: {message.hex()}",
f"Public Key: {bytes([3] * 48).hex()}",
f"Signature: {bytes([6] * 576).hex()}",
"Public Key: b5acf3599bc5fa5da1c00f6cc3d5bcf1560def67778b7f50a8c373a83f78761505b6250ab776e38a292e26628009aec4",
"Signature: c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
f"Signing Mode: {SigningMode.CHIP_0002.value}",
]
run_cli_command_and_assert(capsys, root_dir, [*command_args, f"-a{xch_addr}"], assert_list)
Expand All @@ -641,9 +648,9 @@ def test_update_derivation_index(capsys: object, get_test_cli_clients: tuple[Tes

# set RPC Client
class UpdateDerivationIndexRpcClient(TestWalletRpcClient):
async def extend_derivation_index(self, index: int) -> str:
self.add_to_log("extend_derivation_index", (index,))
return str(index)
async def extend_derivation_index(self, request: ExtendDerivationIndex) -> ExtendDerivationIndexResponse:
self.add_to_log("extend_derivation_index", (request.index,))
return ExtendDerivationIndexResponse(request.index)

inst_rpc_client = UpdateDerivationIndexRpcClient()
test_rpc_clients.wallet_rpc_client = inst_rpc_client
Expand Down
3 changes: 2 additions & 1 deletion chia/_tests/pools/test_pool_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from chia.wallet.util.wallet_types import WalletType
from chia.wallet.wallet_node import WalletNode
from chia.wallet.wallet_request_types import (
DeleteUnconfirmedTransactions,
GetTransactions,
GetWalletBalance,
GetWallets,
Expand Down Expand Up @@ -463,7 +464,7 @@ async def pw_created(check_wallet_id: int) -> bool:
def mempool_empty() -> bool:
return full_node_api.full_node.mempool_manager.mempool.size() == 0

await client.delete_unconfirmed_transactions(1)
await client.delete_unconfirmed_transactions(DeleteUnconfirmedTransactions(uint32(1)))
await full_node_api.process_all_wallet_transactions(wallet=wallet)
await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, timeout=20)

Expand Down
23 changes: 12 additions & 11 deletions chia/_tests/wallet/did_wallet/test_did.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from chia.types.peer_info import PeerInfo
from chia.types.signing_mode import CHIP_0002_SIGN_MESSAGE_PREFIX
from chia.util.bech32m import decode_puzzle_hash, encode_puzzle_hash
from chia.util.byte_types import hexstr_to_bytes
from chia.wallet.did_wallet.did_wallet import DIDWallet
from chia.wallet.singleton import (
create_singleton_puzzle,
Expand Down Expand Up @@ -1091,9 +1092,9 @@ async def test_did_sign_message(wallet_environments: WalletTestFramework):
)
puzzle: Program = Program.to((CHIP_0002_SIGN_MESSAGE_PREFIX, message))
assert AugSchemeMPL.verify(
G1Element.from_bytes(bytes.fromhex(response["pubkey"])),
G1Element.from_bytes(hexstr_to_bytes(response["pubkey"])),
puzzle.get_tree_hash(),
G2Element.from_bytes(bytes.fromhex(response["signature"])),
G2Element.from_bytes(hexstr_to_bytes(response["signature"])),
)
# Test hex string
message = "0123456789ABCDEF"
Expand All @@ -1107,9 +1108,9 @@ async def test_did_sign_message(wallet_environments: WalletTestFramework):
puzzle = Program.to((CHIP_0002_SIGN_MESSAGE_PREFIX, bytes.fromhex(message)))

assert AugSchemeMPL.verify(
G1Element.from_bytes(bytes.fromhex(response["pubkey"])),
G1Element.from_bytes(hexstr_to_bytes(response["pubkey"])),
puzzle.get_tree_hash(),
G2Element.from_bytes(bytes.fromhex(response["signature"])),
G2Element.from_bytes(hexstr_to_bytes(response["signature"])),
)

# Test BLS sign string
Expand All @@ -1119,15 +1120,15 @@ async def test_did_sign_message(wallet_environments: WalletTestFramework):
{
"id": encode_puzzle_hash(did_wallet_1.did_info.origin_coin.name(), AddressType.DID.value),
"message": message,
"is_hex": "False",
"safe_mode": "False",
"is_hex": False,
"safe_mode": False,
}
)

assert AugSchemeMPL.verify(
G1Element.from_bytes(bytes.fromhex(response["pubkey"])),
G1Element.from_bytes(hexstr_to_bytes(response["pubkey"])),
bytes(message, "utf-8"),
G2Element.from_bytes(bytes.fromhex(response["signature"])),
G2Element.from_bytes(hexstr_to_bytes(response["signature"])),
)
# Test BLS sign hex
message = "0123456789ABCDEF"
Expand All @@ -1142,9 +1143,9 @@ async def test_did_sign_message(wallet_environments: WalletTestFramework):
)

assert AugSchemeMPL.verify(
G1Element.from_bytes(bytes.fromhex(response["pubkey"])),
bytes.fromhex(message),
G2Element.from_bytes(bytes.fromhex(response["signature"])),
G1Element.from_bytes(hexstr_to_bytes(response["pubkey"])),
hexstr_to_bytes(message),
G2Element.from_bytes(hexstr_to_bytes(response["signature"])),
)


Expand Down
Loading
Loading