chia_sdk_parser/puzzles/
singleton.rs1use chia_protocol::{Bytes32, Coin};
2use chia_puzzles::{
3 singleton::{SingletonArgs, SINGLETON_LAUNCHER_PUZZLE_HASH, SINGLETON_TOP_LAYER_PUZZLE_HASH},
4 LineageProof,
5};
6use clvm_traits::FromClvm;
7use clvmr::{Allocator, NodePtr};
8
9use crate::{ParseError, Puzzle};
10
11#[derive(Debug, Clone, Copy)]
12pub struct SingletonPuzzle {
13 pub launcher_id: Bytes32,
14 pub inner_puzzle: Puzzle,
15}
16
17impl SingletonPuzzle {
18 pub fn parse(
19 allocator: &Allocator,
20 puzzle: &Puzzle,
21 ) -> Result<Option<SingletonPuzzle>, ParseError> {
22 let Some(puzzle) = puzzle.as_curried() else {
23 return Ok(None);
24 };
25
26 if puzzle.mod_hash != SINGLETON_TOP_LAYER_PUZZLE_HASH {
27 return Ok(None);
28 }
29
30 let args = SingletonArgs::<NodePtr>::from_clvm(allocator, puzzle.args)?;
31
32 if args.singleton_struct.mod_hash != SINGLETON_TOP_LAYER_PUZZLE_HASH.into()
33 || args.singleton_struct.launcher_puzzle_hash != SINGLETON_LAUNCHER_PUZZLE_HASH.into()
34 {
35 return Err(ParseError::InvalidSingletonStruct);
36 }
37
38 Ok(Some(SingletonPuzzle {
39 launcher_id: args.singleton_struct.launcher_id,
40 inner_puzzle: Puzzle::parse(allocator, args.inner_puzzle),
41 }))
42 }
43
44 pub fn lineage_proof(&self, parent_coin: Coin) -> LineageProof {
45 LineageProof {
46 parent_parent_coin_id: parent_coin.parent_coin_info,
47 parent_inner_puzzle_hash: self.inner_puzzle.curried_puzzle_hash().into(),
48 parent_amount: parent_coin.amount,
49 }
50 }
51}