chia-blockchain/chia/wallet/outer_puzzles.py
Kyle Altendorf 3b084a165b
configure isort to add the future annotations import (#13327)
* configure isort to add the future annotations import

* apply the new isort setting

* remove type ignores for new mypy (#13539)

https://pypi.org/project/mypy/0.981/

* another
2022-09-30 03:40:22 -05:00

82 lines
3.9 KiB
Python

from __future__ import annotations
from enum import Enum
from typing import Dict, Optional
from chia.types.blockchain_format.program import Program
from chia.types.blockchain_format.sized_bytes import bytes32
from chia.wallet.cat_wallet.cat_outer_puzzle import CATOuterPuzzle
from chia.wallet.driver_protocol import DriverProtocol
from chia.wallet.nft_wallet.metadata_outer_puzzle import MetadataOuterPuzzle
from chia.wallet.nft_wallet.ownership_outer_puzzle import OwnershipOuterPuzzle
from chia.wallet.nft_wallet.singleton_outer_puzzle import SingletonOuterPuzzle
from chia.wallet.nft_wallet.transfer_program_puzzle import TransferProgramPuzzle
from chia.wallet.puzzle_drivers import PuzzleInfo, Solver
from chia.wallet.uncurried_puzzle import UncurriedPuzzle
"""
This file provides a central location for acquiring drivers for outer puzzles like CATs, NFTs, etc.
A driver for a puzzle must include the following functions:
- match(self, puzzle: UncurriedPuzzle) -> Optional[PuzzleInfo]
- Given a puzzle reveal, return a PuzzleInfo object that can be used to reconstruct it later
- get_inner_puzzle(self, constructor: PuzzleInfo, puzzle_reveal: UncurriedPuzzle) -> Optional[Program]:
- Given a PuzzleInfo object and a puzzle reveal, pull out this outer puzzle's inner puzzle
- asset_id(self, constructor: PuzzleInfo) -> Optional[bytes32]
- Given a PuzzleInfo object, generate a 32 byte ID for use in dictionaries, etc.
- construct(self, constructor: PuzzleInfo, inner_puzzle: Program) -> Program
- Given a PuzzleInfo object and an innermost puzzle, construct a puzzle reveal for a coin spend
- solve(self, constructor: PuzzleInfo, solver: Solver, inner_puzzle: Program, inner_solution: Program) -> Program
- Given a PuzzleInfo object, a Solver object, and an innermost puzzle and its solution return a solution for a spend
- The "Solver" object can contain any dictionary, it's up to the driver to enforce the needed elements of the API
- Some classes that wish to integrate with a driver may not have access to all of the info it needs so the driver
needs to raise errors appropriately
"""
class AssetType(Enum):
CAT = "CAT"
SINGLETON = "singleton"
METADATA = "metadata"
OWNERSHIP = "ownership"
ROYALTY_TRANSFER_PROGRAM = "royalty transfer program"
def match_puzzle(puzzle: UncurriedPuzzle) -> Optional[PuzzleInfo]:
for driver in driver_lookup.values():
potential_info: Optional[PuzzleInfo] = driver.match(puzzle)
if potential_info is not None:
return potential_info
return None
def construct_puzzle(constructor: PuzzleInfo, inner_puzzle: Program) -> Program:
return driver_lookup[AssetType(constructor.type())].construct(constructor, inner_puzzle)
def solve_puzzle(constructor: PuzzleInfo, solver: Solver, inner_puzzle: Program, inner_solution: Program) -> Program:
return driver_lookup[AssetType(constructor.type())].solve(constructor, solver, inner_puzzle, inner_solution)
def get_inner_puzzle(constructor: PuzzleInfo, puzzle_reveal: UncurriedPuzzle) -> Optional[Program]:
return driver_lookup[AssetType(constructor.type())].get_inner_puzzle(constructor, puzzle_reveal)
def get_inner_solution(constructor: PuzzleInfo, solution: Program) -> Optional[Program]:
return driver_lookup[AssetType(constructor.type())].get_inner_solution(constructor, solution)
def create_asset_id(constructor: PuzzleInfo) -> Optional[bytes32]:
return driver_lookup[AssetType(constructor.type())].asset_id(constructor)
function_args = (match_puzzle, construct_puzzle, solve_puzzle, get_inner_puzzle, get_inner_solution)
driver_lookup: Dict[AssetType, DriverProtocol] = {
AssetType.CAT: CATOuterPuzzle(*function_args),
AssetType.SINGLETON: SingletonOuterPuzzle(*function_args),
AssetType.METADATA: MetadataOuterPuzzle(*function_args),
AssetType.OWNERSHIP: OwnershipOuterPuzzle(*function_args),
AssetType.ROYALTY_TRANSFER_PROGRAM: TransferProgramPuzzle(*function_args),
}