chia_sdk_bindings/mips/
members.rs

1use bindy::Result;
2use chia_bls::PublicKey;
3use chia_protocol::Bytes32;
4use chia_sdk_driver::{MofN, mips_puzzle_hash};
5use chia_sdk_types::{
6    Mod,
7    puzzles::{
8        BlsMember, BlsMemberPuzzleAssert, FixedPuzzleMember, K1Member, K1MemberPuzzleAssert,
9        PasskeyMember, PasskeyMemberPuzzleAssert, R1Member, R1MemberPuzzleAssert, SingletonMember,
10        SingletonMemberWithMode,
11    },
12};
13use clvm_utils::TreeHash;
14
15use crate::{K1PublicKey, R1PublicKey};
16
17use super::{Restriction, convert_restrictions};
18
19#[derive(Default, Clone)]
20pub struct MemberConfig {
21    pub top_level: bool,
22    pub nonce: u32,
23    pub restrictions: Vec<Restriction>,
24}
25
26impl MemberConfig {
27    pub fn new() -> Result<Self> {
28        Ok(Self::default())
29    }
30
31    pub fn with_top_level(&self, top_level: bool) -> Result<Self> {
32        Ok(Self {
33            top_level,
34            nonce: self.nonce,
35            restrictions: self.restrictions.clone(),
36        })
37    }
38
39    pub fn with_nonce(&self, nonce: u32) -> Result<Self> {
40        Ok(Self {
41            top_level: self.top_level,
42            nonce,
43            restrictions: self.restrictions.clone(),
44        })
45    }
46
47    pub fn with_restrictions(&self, restrictions: Vec<Restriction>) -> Result<Self> {
48        Ok(Self {
49            top_level: self.top_level,
50            nonce: self.nonce,
51            restrictions,
52        })
53    }
54}
55
56fn member_hash(config: MemberConfig, inner_hash: TreeHash) -> Result<TreeHash> {
57    Ok(mips_puzzle_hash(
58        config.nonce.try_into().unwrap(),
59        convert_restrictions(config.restrictions),
60        inner_hash,
61        config.top_level,
62    ))
63}
64
65pub fn m_of_n_hash(config: MemberConfig, required: u32, items: Vec<TreeHash>) -> Result<TreeHash> {
66    member_hash(
67        config,
68        MofN::new(required.try_into().unwrap(), items).inner_puzzle_hash(),
69    )
70}
71
72pub fn k1_member_hash(
73    config: MemberConfig,
74    public_key: K1PublicKey,
75    fast_forward: bool,
76) -> Result<TreeHash> {
77    member_hash(
78        config,
79        if fast_forward {
80            K1MemberPuzzleAssert::new(public_key.0).curry_tree_hash()
81        } else {
82            K1Member::new(public_key.0).curry_tree_hash()
83        },
84    )
85}
86
87pub fn r1_member_hash(
88    config: MemberConfig,
89    public_key: R1PublicKey,
90    fast_forward: bool,
91) -> Result<TreeHash> {
92    member_hash(
93        config,
94        if fast_forward {
95            R1MemberPuzzleAssert::new(public_key.0).curry_tree_hash()
96        } else {
97            R1Member::new(public_key.0).curry_tree_hash()
98        },
99    )
100}
101
102pub fn bls_member_hash(
103    config: MemberConfig,
104    public_key: PublicKey,
105    fast_forward: bool,
106) -> Result<TreeHash> {
107    member_hash(
108        config,
109        if fast_forward {
110            BlsMemberPuzzleAssert::new(public_key).curry_tree_hash()
111        } else {
112            BlsMember::new(public_key).curry_tree_hash()
113        },
114    )
115}
116
117pub fn passkey_member_hash(
118    config: MemberConfig,
119    public_key: R1PublicKey,
120    fast_forward: bool,
121) -> Result<TreeHash> {
122    member_hash(
123        config,
124        if fast_forward {
125            PasskeyMemberPuzzleAssert::new(public_key.0).curry_tree_hash()
126        } else {
127            PasskeyMember::new(public_key.0).curry_tree_hash()
128        },
129    )
130}
131
132pub fn singleton_member_hash(
133    config: MemberConfig,
134    launcher_id: Bytes32,
135    fast_forward: bool,
136) -> Result<TreeHash> {
137    member_hash(
138        config,
139        if fast_forward {
140            SingletonMemberWithMode::new(launcher_id, 0b010_010).curry_tree_hash()
141        } else {
142            SingletonMember::new(launcher_id).curry_tree_hash()
143        },
144    )
145}
146
147pub fn fixed_member_hash(config: MemberConfig, fixed_puzzle_hash: Bytes32) -> Result<TreeHash> {
148    member_hash(
149        config,
150        FixedPuzzleMember::new(fixed_puzzle_hash).curry_tree_hash(),
151    )
152}
153
154pub fn custom_member_hash(config: MemberConfig, inner_hash: TreeHash) -> Result<TreeHash> {
155    member_hash(config, inner_hash)
156}