Skip to main content

chia_sdk_driver/layers/mips/
delegated_puzzle_feeder_layer.rs

1use chia_puzzles::DELEGATED_PUZZLE_FEEDER_HASH;
2use chia_sdk_types::puzzles::{DelegatedPuzzleFeederArgs, DelegatedPuzzleFeederSolution};
3use clvm_traits::FromClvm;
4use clvmr::{Allocator, NodePtr};
5
6use crate::{DriverError, Layer, Puzzle, SpendContext};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub struct DelegatedPuzzleFeederLayer<I> {
10    pub inner_puzzle: I,
11}
12
13impl<I> DelegatedPuzzleFeederLayer<I> {
14    pub fn new(inner_puzzle: I) -> Self {
15        Self { inner_puzzle }
16    }
17}
18
19impl<I> Layer for DelegatedPuzzleFeederLayer<I>
20where
21    I: Layer,
22{
23    type Solution = DelegatedPuzzleFeederSolution<NodePtr, NodePtr, I::Solution>;
24
25    fn construct_puzzle(&self, ctx: &mut SpendContext) -> Result<NodePtr, DriverError> {
26        let inner_puzzle = self.inner_puzzle.construct_puzzle(ctx)?;
27        ctx.curry(DelegatedPuzzleFeederArgs::new(inner_puzzle))
28    }
29
30    fn construct_solution(
31        &self,
32        ctx: &mut SpendContext,
33        solution: Self::Solution,
34    ) -> Result<NodePtr, DriverError> {
35        let inner_solution = self
36            .inner_puzzle
37            .construct_solution(ctx, solution.inner_solution)?;
38        ctx.alloc(&DelegatedPuzzleFeederSolution::new(
39            solution.delegated_puzzle,
40            solution.delegated_solution,
41            inner_solution,
42        ))
43    }
44
45    fn parse_puzzle(allocator: &Allocator, puzzle: Puzzle) -> Result<Option<Self>, DriverError>
46    where
47        Self: Sized,
48    {
49        let Some(curried) = puzzle.as_curried() else {
50            return Ok(None);
51        };
52
53        if curried.mod_hash != DELEGATED_PUZZLE_FEEDER_HASH.into() {
54            return Ok(None);
55        }
56
57        let args = DelegatedPuzzleFeederArgs::<Puzzle>::from_clvm(allocator, curried.args)?;
58
59        let Some(inner_puzzle) = I::parse_puzzle(allocator, args.inner_puzzle)? else {
60            return Ok(None);
61        };
62
63        Ok(Some(Self::new(inner_puzzle)))
64    }
65
66    fn parse_solution(
67        allocator: &Allocator,
68        solution: NodePtr,
69    ) -> Result<Self::Solution, DriverError> {
70        let solution = DelegatedPuzzleFeederSolution::<NodePtr, NodePtr, NodePtr>::from_clvm(
71            allocator, solution,
72        )?;
73
74        let inner_solution = I::parse_solution(allocator, solution.inner_solution)?;
75
76        Ok(DelegatedPuzzleFeederSolution::new(
77            solution.delegated_puzzle,
78            solution.delegated_solution,
79            inner_solution,
80        ))
81    }
82}