chia_sdk_driver/layers/
augmented_condition_layer.rs

1use chia_puzzles::AUGMENTED_CONDITION_HASH;
2use chia_sdk_types::{
3    puzzles::{AugmentedConditionArgs, AugmentedConditionSolution},
4    Condition,
5};
6use clvm_traits::{FromClvm, ToClvm};
7use clvmr::{Allocator, NodePtr};
8
9use crate::{DriverError, Layer, Puzzle, SpendContext};
10
11/// The augmented condition [`Layer`] allows for adding a condition to a puzzle's output.
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub struct AugmentedConditionLayer<T, I> {
14    pub condition: Condition<T>,
15    pub inner_puzzle: I,
16}
17
18impl<T, I> Layer for AugmentedConditionLayer<T, I>
19where
20    T: ToClvm<Allocator> + FromClvm<Allocator> + Clone,
21    I: Layer,
22{
23    type Solution = AugmentedConditionSolution<NodePtr>;
24
25    fn parse_puzzle(allocator: &Allocator, puzzle: Puzzle) -> Result<Option<Self>, DriverError> {
26        let Some(puzzle) = puzzle.as_curried() else {
27            return Ok(None);
28        };
29
30        if puzzle.mod_hash != AUGMENTED_CONDITION_HASH.into() {
31            return Ok(None);
32        }
33
34        let args = AugmentedConditionArgs::<T, Puzzle>::from_clvm(allocator, puzzle.args)?;
35        let Some(inner_layer) = I::parse_puzzle(allocator, args.inner_puzzle)? else {
36            return Ok(None);
37        };
38
39        Ok(Some(Self {
40            condition: args.condition,
41            inner_puzzle: inner_layer,
42        }))
43    }
44
45    fn parse_solution(
46        allocator: &Allocator,
47        solution: NodePtr,
48    ) -> Result<Self::Solution, DriverError> {
49        Ok(AugmentedConditionSolution::<NodePtr>::from_clvm(
50            allocator, solution,
51        )?)
52    }
53
54    fn construct_puzzle(&self, ctx: &mut SpendContext) -> Result<NodePtr, DriverError> {
55        let inner_puzzle = self.inner_puzzle.construct_puzzle(ctx)?;
56        let curried = ctx.curry(AugmentedConditionArgs {
57            condition: self.condition.clone(),
58            inner_puzzle,
59        })?;
60        ctx.alloc(&curried)
61    }
62
63    fn construct_solution(
64        &self,
65        ctx: &mut SpendContext,
66        solution: Self::Solution,
67    ) -> Result<NodePtr, DriverError> {
68        ctx.alloc(&solution)
69    }
70}