chia_sdk_driver/layers/
p2_delegated_conditions_layer.rs

1use chia_bls::PublicKey;
2use chia_puzzles::P2_DELEGATED_CONDITIONS_HASH;
3use chia_sdk_types::{
4    puzzles::{P2DelegatedConditionsArgs, P2DelegatedConditionsSolution},
5    Mod,
6};
7use clvm_traits::FromClvm;
8use clvm_utils::{ToTreeHash, TreeHash};
9use clvmr::{Allocator, NodePtr};
10
11use crate::{DriverError, Layer, Puzzle, SpendContext};
12
13/// The p2 delegated conditions [`Layer`] allows a certain key to spend the coin.
14/// To do so, a list of additional conditions is signed and passed in the solution.
15/// Typically, the [`StandardLayer`](crate::StandardLayer) is used instead, since it adds more flexibility.
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub struct P2DelegatedConditionsLayer {
18    /// The public key that has the ability to spend the coin.
19    pub public_key: PublicKey,
20}
21
22impl P2DelegatedConditionsLayer {
23    pub fn new(public_key: PublicKey) -> Self {
24        Self { public_key }
25    }
26}
27
28impl Layer for P2DelegatedConditionsLayer {
29    type Solution = P2DelegatedConditionsSolution;
30
31    fn construct_puzzle(&self, ctx: &mut SpendContext) -> Result<NodePtr, DriverError> {
32        ctx.curry(P2DelegatedConditionsArgs::new(self.public_key))
33    }
34
35    fn construct_solution(
36        &self,
37        ctx: &mut SpendContext,
38        solution: Self::Solution,
39    ) -> Result<NodePtr, DriverError> {
40        ctx.alloc(&solution)
41    }
42
43    fn parse_puzzle(allocator: &Allocator, puzzle: Puzzle) -> Result<Option<Self>, DriverError> {
44        let Some(puzzle) = puzzle.as_curried() else {
45            return Ok(None);
46        };
47
48        if puzzle.mod_hash != P2_DELEGATED_CONDITIONS_HASH.into() {
49            return Ok(None);
50        }
51
52        let args = P2DelegatedConditionsArgs::from_clvm(allocator, puzzle.args)?;
53
54        Ok(Some(Self {
55            public_key: args.public_key,
56        }))
57    }
58
59    fn parse_solution(
60        allocator: &Allocator,
61        solution: NodePtr,
62    ) -> Result<Self::Solution, DriverError> {
63        Ok(P2DelegatedConditionsSolution::from_clvm(
64            allocator, solution,
65        )?)
66    }
67}
68
69impl ToTreeHash for P2DelegatedConditionsLayer {
70    fn tree_hash(&self) -> TreeHash {
71        P2DelegatedConditionsArgs::new(self.public_key).curry_tree_hash()
72    }
73}