Skip to content

Commit

Permalink
Fix memos & minter did (#13604)
Browse files Browse the repository at this point in the history
* Fix memos & minter did

* Fix pre-commit
  • Loading branch information
ytx1991 authored Oct 6, 2022
1 parent eb6aeb6 commit e4d4c8f
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 40 deletions.
22 changes: 5 additions & 17 deletions chia/rpc/wallet_rpc_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
from chia.wallet.did_wallet.did_wallet import DIDWallet
from chia.wallet.nft_wallet import nft_puzzles
from chia.wallet.nft_wallet.nft_info import NFTInfo, NFTCoinInfo
from chia.wallet.nft_wallet.nft_puzzles import get_metadata_and_phs, get_new_owner_did
from chia.wallet.nft_wallet.nft_puzzles import get_metadata_and_phs
from chia.wallet.nft_wallet.nft_wallet import NFTWallet
from chia.wallet.nft_wallet.uncurry_nft import UncurriedNFT
from chia.wallet.notification_store import Notification
Expand Down Expand Up @@ -1888,22 +1888,8 @@ async def nft_get_info(self, request: Dict) -> EndpointResult:
"success": False,
"error": f"Launcher coin record 0x{uncurried_nft.singleton_launcher_id.hex()} not found",
}
# Get minter DID
eve_coin = (
await self.service.wallet_state_manager.wallet_node.fetch_children(launcher_coin[0].coin.name(), peer=peer)
)[0]
eve_coin_spend: CoinSpend = await self.service.wallet_state_manager.wallet_node.fetch_puzzle_solution(
eve_coin.spent_height, eve_coin.coin, peer
)
eve_full_puzzle: Program = Program.from_bytes(bytes(eve_coin_spend.puzzle_reveal))
eve_uncurried_nft: Optional[UncurriedNFT] = UncurriedNFT.uncurry(*eve_full_puzzle.uncurry())
if eve_uncurried_nft is None:
return {"success": False, "error": "The coin is not a NFT."}
minter_did = None
if eve_uncurried_nft.supports_did:
minter_did = get_new_owner_did(eve_uncurried_nft, eve_coin_spend.solution.to_program())
if minter_did == b"":
minter_did = None
minter_did = await self.service.wallet_state_manager.get_minter_did(launcher_coin[0].coin, peer)

nft_info: NFTInfo = await nft_puzzles.get_nft_info_from_puzzle(
NFTCoinInfo(
uncurried_nft.singleton_launcher_id,
Expand Down Expand Up @@ -2018,6 +2004,7 @@ async def nft_mint_bulk(self, request) -> EndpointResult:
else:
xch_change_ph = None
new_innerpuzhash = request.get("new_innerpuzhash", None)
new_p2_puzhash = request.get("new_p2_puzhash", None)
did_coin_dict = request.get("did_coin", None)
if did_coin_dict:
did_coin = Coin.from_json_dict(did_coin_dict)
Expand All @@ -2039,6 +2026,7 @@ async def nft_mint_bulk(self, request) -> EndpointResult:
xch_coins=xch_coins,
xch_change_ph=xch_change_ph,
new_innerpuzhash=new_innerpuzhash,
new_p2_puzhash=new_p2_puzhash,
did_coin=did_coin,
did_lineage_parent=did_lineage_parent,
fee=fee,
Expand Down
34 changes: 11 additions & 23 deletions chia/wallet/nft_wallet/nft_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,7 @@
from chia.wallet.nft_wallet import nft_puzzles
from chia.wallet.nft_wallet.nft_info import NFTCoinInfo, NFTWalletInfo
from chia.wallet.nft_wallet.nft_off_chain import delete_off_chain_metadata, get_off_chain_metadata
from chia.wallet.nft_wallet.nft_puzzles import (
NFT_METADATA_UPDATER,
create_ownership_layer_puzzle,
get_metadata_and_phs,
get_new_owner_did,
)
from chia.wallet.nft_wallet.nft_puzzles import NFT_METADATA_UPDATER, create_ownership_layer_puzzle, get_metadata_and_phs
from chia.wallet.nft_wallet.uncurry_nft import UncurriedNFT
from chia.wallet.outer_puzzles import AssetType, construct_puzzle, match_puzzle, solve_puzzle
from chia.wallet.payment import Payment
Expand Down Expand Up @@ -213,22 +208,7 @@ async def puzzle_solution_received(self, coin_spend: CoinSpend, peer: WSChiaConn
minter_did = None
if uncurried_nft.supports_did:
inner_puzzle = nft_puzzles.recurry_nft_puzzle(uncurried_nft, coin_spend.solution.to_program(), p2_puzzle)
# Get minter DID
eve_coin = (
await self.wallet_state_manager.wallet_node.fetch_children(
launcher_coin_states[0].coin.name(), peer=peer
)
)[0]
eve_coin_spend: CoinSpend = await self.wallet_state_manager.wallet_node.fetch_puzzle_solution(
eve_coin.spent_height, eve_coin.coin, peer
)
eve_full_puzzle: Program = Program.from_bytes(bytes(eve_coin_spend.puzzle_reveal))
eve_uncurried_nft: Optional[UncurriedNFT] = UncurriedNFT.uncurry(*eve_full_puzzle.uncurry())
if eve_uncurried_nft is None:
raise ValueError("Couldn't get minter DID for NFT")
minter_did = get_new_owner_did(eve_uncurried_nft, eve_coin_spend.solution.to_program())
if minter_did == b"":
minter_did = None
minter_did = await self.wallet_state_manager.get_minter_did(launcher_coin_states[0].coin, peer)
else:
inner_puzzle = p2_puzzle
child_puzzle: Program = nft_puzzles.create_full_puzzle(
Expand Down Expand Up @@ -1041,6 +1021,7 @@ async def mint_from_did(
xch_coins: Optional[Set[Coin]] = None,
xch_change_ph: Optional[bytes32] = None,
new_innerpuzhash: Optional[bytes32] = None,
new_p2_puzhash: Optional[bytes32] = None,
did_coin: Optional[Coin] = None,
did_lineage_parent: Optional[bytes32] = None,
fee: Optional[uint64] = uint64(0),
Expand All @@ -1067,6 +1048,8 @@ async def mint_from_did(
from the funding transaction goes to.
:param new_innerpuzhash: [Optional] The new inner puzzle hash for the DID once it is spent. For bulk minting we
generally don't provide this as the default behaviour is to re-use the existing inner puzzle hash
:param new_p2_puzhash: [Optional] The new p2 puzzle hash for the DID once it is spent. For bulk minting we
generally don't provide this as the default behaviour is to re-use the existing inner puzzle hash
:param did_coin: [Optional] The did coin to use for minting. Required for bulk minting when the DID coin will
be created in the future
:param did_lineage_parent: [Optional] The parent coin to use for the lineage proof in the DID spend. Needed
Expand Down Expand Up @@ -1100,10 +1083,15 @@ async def mint_from_did(
innerpuz: Program = did_wallet.did_info.current_inner
if new_innerpuzhash is None:
new_innerpuzhash = innerpuz.get_tree_hash()
uncurried_did = did_wallet_puzzles.uncurry_innerpuz(innerpuz)
assert uncurried_did is not None
p2_puzzle = uncurried_did[0]
new_p2_puzhash = p2_puzzle.get_tree_hash()
assert new_p2_puzhash is not None
# make the primaries for the DID spend
primaries = [
AmountWithPuzzlehash(
{"puzzlehash": new_innerpuzhash, "amount": uint64(did_coin.amount), "memos": [new_innerpuzhash]}
{"puzzlehash": new_innerpuzhash, "amount": uint64(did_coin.amount), "memos": [bytes(new_p2_puzhash)]}
)
]

Expand Down
40 changes: 40 additions & 0 deletions chia/wallet/wallet_state_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,46 @@ async def handle_did(
self.state_changed("wallet_created", wallet_id, {"did_id": did_wallet.get_my_DID()})
return wallet_id, wallet_type

async def get_minter_did(self, launcher_coin: Coin, peer: WSChiaConnection) -> Optional[bytes32]:
# Get minter DID
eve_coin = (await self.wallet_node.fetch_children(launcher_coin.name(), peer=peer))[0]
eve_coin_spend: CoinSpend = await self.wallet_node.fetch_puzzle_solution(
eve_coin.spent_height, eve_coin.coin, peer
)
eve_full_puzzle: Program = Program.from_bytes(bytes(eve_coin_spend.puzzle_reveal))
eve_uncurried_nft: Optional[UncurriedNFT] = UncurriedNFT.uncurry(*eve_full_puzzle.uncurry())
if eve_uncurried_nft is None:
raise ValueError("Couldn't get minter DID for NFT")
if not eve_uncurried_nft.supports_did:
return None
minter_did = get_new_owner_did(eve_uncurried_nft, eve_coin_spend.solution.to_program())
if minter_did == b"":
minter_did = None
if minter_did is None:
# Check if the NFT is a bulk minting
launcher_parent: List[CoinState] = await self.wallet_node.get_coin_state(
[launcher_coin.parent_coin_info], peer=peer
)
assert (
launcher_parent is not None
and len(launcher_parent) == 1
and launcher_parent[0].spent_height is not None
)
did_coin: List[CoinState] = await self.wallet_node.get_coin_state(
[launcher_parent[0].coin.parent_coin_info], peer=peer
)
assert did_coin is not None and len(did_coin) == 1 and did_coin[0].spent_height is not None
did_spend: CoinSpend = await self.wallet_node.fetch_puzzle_solution(
did_coin[0].spent_height, did_coin[0].coin, peer
)
puzzle = Program.from_bytes(bytes(did_spend.puzzle_reveal))
uncurried = uncurry_puzzle(puzzle)
did_curried_args = match_did_puzzle(uncurried.mod, uncurried.args)
if did_curried_args is not None:
p2_puzzle, recovery_list_hash, num_verification, singleton_struct, metadata = did_curried_args
minter_did = bytes32(bytes(singleton_struct.rest().first())[1:])
return minter_did

async def handle_nft(
self, coin_spend: CoinSpend, uncurried_nft: UncurriedNFT, parent_coin_state: CoinState
) -> Tuple[Optional[uint32], Optional[WalletType]]:
Expand Down
1 change: 1 addition & 0 deletions tests/wallet/nft_wallet/test_nft_bulk_mint.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ async def test_nft_mint_from_did(two_wallet_nodes: Any, trusted: Any) -> None:

expected_xch_bal = funds - fee - mint_total - 1
await time_out_assert(30, wallet_0.get_confirmed_balance, expected_xch_bal)
assert (await nft_wallet_taker.get_current_nfts())[0].minter_did == did_id


@pytest.mark.parametrize(
Expand Down

0 comments on commit e4d4c8f

Please sign in to comment.