chia_sdk_driver/layers/action_layer/
p2_delegated_by_singleton_layer.rs

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