chia_sdk_driver/layers/action_layer/actions/
delegated_state.rs

1use chia_protocol::{Bytes32, Coin};
2use chia_sdk_types::{
3    Conditions,
4    puzzles::{DelegatedStateActionArgs, DelegatedStateActionSolution},
5};
6use clvm_traits::ToClvm;
7use clvm_utils::{ToTreeHash, TreeHash};
8use clvmr::{Allocator, NodePtr};
9
10use crate::{
11    CatalogRegistry, CatalogRegistryConstants, DriverError, SingletonAction, Spend, SpendContext,
12    XchandlesConstants, XchandlesRegistry,
13};
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub struct DelegatedStateAction {
17    pub other_launcher_id: Bytes32,
18}
19
20impl ToTreeHash for DelegatedStateAction {
21    fn tree_hash(&self) -> TreeHash {
22        DelegatedStateActionArgs::curry_tree_hash(self.other_launcher_id)
23    }
24}
25
26impl SingletonAction<CatalogRegistry> for DelegatedStateAction {
27    fn from_constants(constants: &CatalogRegistryConstants) -> Self {
28        Self {
29            other_launcher_id: constants.price_singleton_launcher_id,
30        }
31    }
32}
33
34impl SingletonAction<XchandlesRegistry> for DelegatedStateAction {
35    fn from_constants(constants: &XchandlesConstants) -> Self {
36        Self {
37            other_launcher_id: constants.price_singleton_launcher_id,
38        }
39    }
40}
41
42impl DelegatedStateAction {
43    pub fn curry_tree_hash(price_singleton_launcher_id: Bytes32) -> TreeHash {
44        DelegatedStateActionArgs::curry_tree_hash(price_singleton_launcher_id)
45    }
46
47    pub fn construct_puzzle(&self, ctx: &mut SpendContext) -> Result<NodePtr, DriverError> {
48        ctx.curry(DelegatedStateActionArgs::new(self.other_launcher_id))
49    }
50
51    pub fn spend<S>(
52        self,
53        ctx: &mut SpendContext,
54        my_coin: Coin,
55        new_state: S,
56        other_singleton_inner_puzzle_hash: Bytes32,
57    ) -> Result<(Conditions, Spend), DriverError>
58    where
59        S: ToClvm<Allocator>,
60    {
61        let state = new_state.to_clvm(ctx)?;
62        let my_solution = DelegatedStateActionSolution::<NodePtr> {
63            new_state: state,
64            other_singleton_inner_puzzle_hash,
65        }
66        .to_clvm(ctx)?;
67        let my_puzzle = self.construct_puzzle(ctx)?;
68
69        let message: Bytes32 = ctx.tree_hash(state).into();
70        let conds = Conditions::new().send_message(
71            18,
72            message.into(),
73            vec![ctx.alloc(&my_coin.puzzle_hash)?],
74        );
75        Ok((conds, Spend::new(my_puzzle, my_solution)))
76    }
77}