chia_sdk_driver/layers/mips/
singleton_member_layer.rs1use chia_protocol::Bytes32;
2use chia_puzzles::{SINGLETON_LAUNCHER_HASH, SINGLETON_MEMBER_HASH, SINGLETON_TOP_LAYER_V1_1_HASH};
3use chia_sdk_types::puzzles::{SingletonMember, SingletonMemberSolution};
4use clvm_traits::FromClvm;
5use clvmr::{Allocator, NodePtr};
6
7use crate::{DriverError, Layer, Puzzle, SpendContext};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub struct SingletonMemberLayer {
11 pub launcher_id: Bytes32,
12}
13
14impl SingletonMemberLayer {
15 pub fn new(launcher_id: Bytes32) -> Self {
16 Self { launcher_id }
17 }
18}
19
20impl Layer for SingletonMemberLayer {
21 type Solution = SingletonMemberSolution;
22
23 fn construct_puzzle(&self, ctx: &mut SpendContext) -> Result<NodePtr, DriverError> {
24 ctx.curry(SingletonMember::new(self.launcher_id))
25 }
26
27 fn construct_solution(
28 &self,
29 ctx: &mut SpendContext,
30 solution: Self::Solution,
31 ) -> Result<NodePtr, DriverError> {
32 ctx.alloc(&solution)
33 }
34
35 fn parse_puzzle(allocator: &Allocator, puzzle: Puzzle) -> Result<Option<Self>, DriverError>
36 where
37 Self: Sized,
38 {
39 let Some(curried) = puzzle.as_curried() else {
40 return Ok(None);
41 };
42
43 if curried.mod_hash != SINGLETON_MEMBER_HASH.into() {
44 return Ok(None);
45 }
46
47 let args = SingletonMember::from_clvm(allocator, curried.args)?;
48
49 if args.singleton_struct.mod_hash != SINGLETON_TOP_LAYER_V1_1_HASH.into()
50 || args.singleton_struct.launcher_puzzle_hash != SINGLETON_LAUNCHER_HASH.into()
51 {
52 return Err(DriverError::InvalidSingletonStruct);
53 }
54
55 Ok(Some(Self::new(args.singleton_struct.launcher_id)))
56 }
57
58 fn parse_solution(
59 allocator: &Allocator,
60 solution: NodePtr,
61 ) -> Result<Self::Solution, DriverError> {
62 Ok(SingletonMemberSolution::from_clvm(allocator, solution)?)
63 }
64}