chia_sdk_driver/primitives/option/
option_info.rs

1use chia_protocol::Bytes32;
2use chia_puzzle_types::singleton::SingletonArgs;
3use chia_sdk_types::{puzzles::OptionContractArgs, Mod};
4use clvm_utils::{ToTreeHash, TreeHash};
5use clvmr::Allocator;
6
7use crate::{DriverError, Layer, OptionContractLayer, Puzzle, SingletonLayer};
8
9pub type OptionContractLayers<I> = SingletonLayer<OptionContractLayer<I>>;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
12pub struct OptionInfo {
13    pub launcher_id: Bytes32,
14    pub underlying_coin_id: Bytes32,
15    pub underlying_delegated_puzzle_hash: Bytes32,
16    pub p2_puzzle_hash: Bytes32,
17}
18
19impl OptionInfo {
20    pub fn new(
21        launcher_id: Bytes32,
22        underlying_coin_id: Bytes32,
23        underlying_delegated_puzzle_hash: Bytes32,
24        p2_puzzle_hash: Bytes32,
25    ) -> Self {
26        Self {
27            launcher_id,
28            underlying_coin_id,
29            underlying_delegated_puzzle_hash,
30            p2_puzzle_hash,
31        }
32    }
33
34    pub fn parse(
35        allocator: &Allocator,
36        puzzle: Puzzle,
37    ) -> Result<Option<(Self, Puzzle)>, DriverError> {
38        let Some(layers) = OptionContractLayers::parse_puzzle(allocator, puzzle)? else {
39            return Ok(None);
40        };
41
42        let p2_puzzle = layers.inner_puzzle.inner_puzzle;
43
44        Ok(Some((Self::from_layers(&layers), p2_puzzle)))
45    }
46
47    pub fn from_layers<I>(layers: &OptionContractLayers<I>) -> Self
48    where
49        I: ToTreeHash,
50    {
51        Self {
52            launcher_id: layers.launcher_id,
53            underlying_coin_id: layers.inner_puzzle.underlying_coin_id,
54            underlying_delegated_puzzle_hash: layers.inner_puzzle.underlying_delegated_puzzle_hash,
55            p2_puzzle_hash: layers.inner_puzzle.inner_puzzle.tree_hash().into(),
56        }
57    }
58
59    #[must_use]
60    pub fn into_layers<I>(self, p2_puzzle: I) -> OptionContractLayers<I> {
61        SingletonLayer::new(
62            self.launcher_id,
63            OptionContractLayer::new(
64                self.underlying_coin_id,
65                self.underlying_delegated_puzzle_hash,
66                p2_puzzle,
67            ),
68        )
69    }
70
71    pub fn puzzle_hash(&self) -> TreeHash {
72        SingletonArgs::curry_tree_hash(self.launcher_id, self.inner_puzzle_hash())
73    }
74
75    pub fn inner_puzzle_hash(&self) -> TreeHash {
76        OptionContractArgs::new(
77            self.underlying_coin_id,
78            self.underlying_delegated_puzzle_hash,
79            TreeHash::from(self.p2_puzzle_hash),
80        )
81        .curry_tree_hash()
82    }
83
84    #[must_use]
85    pub fn with_p2_puzzle_hash(self, p2_puzzle_hash: Bytes32) -> Self {
86        Self {
87            launcher_id: self.launcher_id,
88            underlying_coin_id: self.underlying_coin_id,
89            underlying_delegated_puzzle_hash: self.underlying_delegated_puzzle_hash,
90            p2_puzzle_hash,
91        }
92    }
93}