1#![allow(unused)]
2
3use binky::Result;
4use chik_bls::PublicKey;
5use chik_consensus::opcodes::{
6 CREATE_COIN_ANNOUNCEMENT, CREATE_PUZZLE_ANNOUNCEMENT, RECEIVE_MESSAGE, SEND_MESSAGE,
7};
8use chik_protocol::Bytes32;
9use chik_sdk_driver as sdk;
10
11use crate::{K1PublicKey, Klvm, Program, R1PublicKey};
12
13#[derive(Clone)]
14pub struct MipsMemo {
15 pub inner_puzzle: InnerPuzzleMemo,
16}
17
18impl From<MipsMemo> for sdk::MipsMemo {
19 fn from(value: MipsMemo) -> Self {
20 Self::new(value.inner_puzzle.into())
21 }
22}
23
24#[derive(Clone)]
25pub struct InnerPuzzleMemo {
26 pub nonce: u32,
27 pub restrictions: Vec<RestrictionMemo>,
28 pub kind: MemoKind,
29}
30
31impl From<InnerPuzzleMemo> for sdk::InnerPuzzleMemo {
32 fn from(value: InnerPuzzleMemo) -> Self {
33 Self::new(
34 value.nonce.try_into().unwrap(),
35 value.restrictions.into_iter().map(Into::into).collect(),
36 value.kind.into(),
37 )
38 }
39}
40
41#[derive(Clone)]
42pub struct RestrictionMemo {
43 pub member_condition_validator: bool,
44 pub puzzle_hash: Bytes32,
45 pub memo: Program,
46}
47
48impl RestrictionMemo {
49 pub fn force_1_of_2_restricted_variable(
50 klvm: Klvm,
51 left_side_subtree_hash: Bytes32,
52 nonce: u32,
53 member_validator_list_hash: Bytes32,
54 delegated_puzzle_validator_list_hash: Bytes32,
55 ) -> Result<Self> {
56 let mut ctx = klvm.0.lock().unwrap();
57 let restriction = sdk::RestrictionMemo::force_1_of_2_restricted_variable(
58 &mut ctx,
59 left_side_subtree_hash,
60 nonce.try_into().unwrap(),
61 member_validator_list_hash,
62 delegated_puzzle_validator_list_hash,
63 )?;
64 Ok(Self {
65 member_condition_validator: restriction.member_condition_validator,
66 puzzle_hash: restriction.puzzle_hash,
67 memo: Program(klvm.0.clone(), restriction.memo),
68 })
69 }
70
71 pub fn enforce_delegated_puzzle_wrappers(
72 klvm: Klvm,
73 wrapper_memos: Vec<WrapperMemo>,
74 ) -> Result<Self> {
75 let mut ctx = klvm.0.lock().unwrap();
76 let restriction = sdk::RestrictionMemo::enforce_delegated_puzzle_wrappers(
77 &mut ctx,
78 &wrapper_memos
79 .into_iter()
80 .map(Into::into)
81 .collect::<Vec<_>>(),
82 )?;
83 Ok(Self {
84 member_condition_validator: restriction.member_condition_validator,
85 puzzle_hash: restriction.puzzle_hash,
86 memo: Program(klvm.0.clone(), restriction.memo),
87 })
88 }
89
90 pub fn timelock(klvm: Klvm, seconds: u64, reveal: bool) -> Result<Self> {
91 let mut ctx = klvm.0.lock().unwrap();
92 let restriction = sdk::RestrictionMemo::timelock(&mut ctx, seconds, reveal)?;
93 Ok(Self {
94 member_condition_validator: restriction.member_condition_validator,
95 puzzle_hash: restriction.puzzle_hash,
96 memo: Program(klvm.0.clone(), restriction.memo),
97 })
98 }
99}
100
101impl From<RestrictionMemo> for sdk::RestrictionMemo {
102 fn from(value: RestrictionMemo) -> Self {
103 Self::new(
104 value.member_condition_validator,
105 value.puzzle_hash,
106 value.memo.1,
107 )
108 }
109}
110
111#[derive(Clone)]
112pub struct WrapperMemo {
113 pub puzzle_hash: Bytes32,
114 pub memo: Program,
115}
116
117impl WrapperMemo {
118 pub fn prevent_vault_side_effects(klvm: Klvm, reveal: bool) -> Result<Vec<Self>> {
119 Ok(vec![
120 Self::prevent_condition_opcode(klvm.clone(), CREATE_COIN_ANNOUNCEMENT, reveal)?,
121 Self::prevent_condition_opcode(klvm.clone(), CREATE_PUZZLE_ANNOUNCEMENT, reveal)?,
122 Self::prevent_condition_opcode(klvm.clone(), SEND_MESSAGE, reveal)?,
123 Self::prevent_condition_opcode(klvm.clone(), RECEIVE_MESSAGE, reveal)?,
124 Self::prevent_multiple_create_coins(klvm)?,
125 ])
126 }
127
128 pub fn force_coin_announcement(klvm: Klvm) -> Result<Self> {
129 let wrapper = sdk::WrapperMemo::force_coin_message();
130 Ok(Self {
131 puzzle_hash: wrapper.puzzle_hash,
132 memo: Program(klvm.0.clone(), wrapper.memo),
133 })
134 }
135
136 pub fn force_coin_message(klvm: Klvm) -> Result<Self> {
137 let wrapper = sdk::WrapperMemo::force_coin_message();
138 Ok(Self {
139 puzzle_hash: wrapper.puzzle_hash,
140 memo: Program(klvm.0.clone(), wrapper.memo),
141 })
142 }
143
144 pub fn prevent_multiple_create_coins(klvm: Klvm) -> Result<Self> {
145 let wrapper = sdk::WrapperMemo::prevent_multiple_create_coins();
146 Ok(Self {
147 puzzle_hash: wrapper.puzzle_hash,
148 memo: Program(klvm.0.clone(), wrapper.memo),
149 })
150 }
151
152 pub fn timelock(klvm: Klvm, seconds: u64, reveal: bool) -> Result<Self> {
153 let mut ctx = klvm.0.lock().unwrap();
154 let wrapper = sdk::WrapperMemo::timelock(&mut ctx, seconds, reveal)?;
155 Ok(Self {
156 puzzle_hash: wrapper.puzzle_hash,
157 memo: Program(klvm.0.clone(), wrapper.memo),
158 })
159 }
160
161 pub fn prevent_condition_opcode(klvm: Klvm, opcode: u16, reveal: bool) -> Result<Self> {
162 let mut ctx = klvm.0.lock().unwrap();
163 let wrapper = sdk::WrapperMemo::prevent_condition_opcode(&mut ctx, opcode, reveal)?;
164 Ok(Self {
165 puzzle_hash: wrapper.puzzle_hash,
166 memo: Program(klvm.0.clone(), wrapper.memo),
167 })
168 }
169}
170
171impl From<WrapperMemo> for sdk::WrapperMemo {
172 fn from(value: WrapperMemo) -> Self {
173 Self::new(value.puzzle_hash, value.memo.1)
174 }
175}
176
177#[derive(Clone)]
178pub struct Force1of2RestrictedVariableMemo {
179 pub left_side_subtree_hash: Bytes32,
180 pub nonce: u32,
181 pub member_validator_list_hash: Bytes32,
182 pub delegated_puzzle_validator_list_hash: Bytes32,
183}
184
185impl From<Force1of2RestrictedVariableMemo> for sdk::Force1of2RestrictedVariableMemo {
186 fn from(value: Force1of2RestrictedVariableMemo) -> Self {
187 Self::new(
188 value.left_side_subtree_hash,
189 value.nonce.try_into().unwrap(),
190 value.member_validator_list_hash,
191 value.delegated_puzzle_validator_list_hash,
192 )
193 }
194}
195#[derive(Clone)]
196pub enum MemoKind {
197 Member(MemberMemo),
198 MofN(MofNMemo),
199}
200
201impl MemoKind {
202 pub fn member(member: MemberMemo) -> Result<Self> {
203 Ok(Self::Member(member))
204 }
205
206 pub fn m_of_n(m_of_n: MofNMemo) -> Result<Self> {
207 Ok(Self::MofN(m_of_n))
208 }
209
210 pub fn as_member(&self) -> Result<Option<MemberMemo>> {
211 if let Self::Member(member) = self {
212 Ok(Some(member.clone()))
213 } else {
214 Ok(None)
215 }
216 }
217
218 pub fn as_m_of_n(&self) -> Result<Option<MofNMemo>> {
219 if let Self::MofN(m_of_n) = self {
220 Ok(Some(m_of_n.clone()))
221 } else {
222 Ok(None)
223 }
224 }
225}
226
227impl From<MemoKind> for sdk::MemoKind {
228 fn from(value: MemoKind) -> Self {
229 match value {
230 MemoKind::Member(member) => sdk::MemoKind::Member(member.into()),
231 MemoKind::MofN(m_of_n) => sdk::MemoKind::MofN(m_of_n.into()),
232 }
233 }
234}
235
236#[derive(Clone)]
237pub struct MemberMemo {
238 pub puzzle_hash: Bytes32,
239 pub memo: Program,
240}
241
242impl MemberMemo {
243 pub fn k1(
244 klvm: Klvm,
245 public_key: K1PublicKey,
246 fast_forward: bool,
247 reveal: bool,
248 ) -> Result<Self> {
249 let mut ctx = klvm.0.lock().unwrap();
250 let memo = sdk::MemberMemo::k1(&mut ctx, public_key.0, fast_forward, reveal)?;
251 Ok(Self {
252 puzzle_hash: memo.puzzle_hash,
253 memo: Program(klvm.0.clone(), memo.memo),
254 })
255 }
256
257 pub fn r1(
258 klvm: Klvm,
259 public_key: R1PublicKey,
260 fast_forward: bool,
261 reveal: bool,
262 ) -> Result<Self> {
263 let mut ctx = klvm.0.lock().unwrap();
264 let memo = sdk::MemberMemo::r1(&mut ctx, public_key.0, fast_forward, reveal)?;
265 Ok(Self {
266 puzzle_hash: memo.puzzle_hash,
267 memo: Program(klvm.0.clone(), memo.memo),
268 })
269 }
270
271 pub fn bls(klvm: Klvm, public_key: PublicKey, taproot: bool, reveal: bool) -> Result<Self> {
272 let mut ctx = klvm.0.lock().unwrap();
273 let memo = sdk::MemberMemo::bls(&mut ctx, public_key, taproot, reveal)?;
274 Ok(Self {
275 puzzle_hash: memo.puzzle_hash,
276 memo: Program(klvm.0.clone(), memo.memo),
277 })
278 }
279
280 pub fn passkey(
281 klvm: Klvm,
282 public_key: R1PublicKey,
283 fast_forward: bool,
284 reveal: bool,
285 ) -> Result<Self> {
286 let mut ctx = klvm.0.lock().unwrap();
287 let memo = sdk::MemberMemo::passkey(&mut ctx, public_key.0, fast_forward, reveal)?;
288 Ok(Self {
289 puzzle_hash: memo.puzzle_hash,
290 memo: Program(klvm.0.clone(), memo.memo),
291 })
292 }
293
294 pub fn singleton(klvm: Klvm, launcher_id: Bytes32, reveal: bool) -> Result<Self> {
295 let mut ctx = klvm.0.lock().unwrap();
296 let memo = sdk::MemberMemo::singleton(&mut ctx, launcher_id, reveal)?;
297 Ok(Self {
298 puzzle_hash: memo.puzzle_hash,
299 memo: Program(klvm.0.clone(), memo.memo),
300 })
301 }
302
303 pub fn fixed_puzzle(klvm: Klvm, puzzle_hash: Bytes32, reveal: bool) -> Result<Self> {
304 let mut ctx = klvm.0.lock().unwrap();
305 let memo = sdk::MemberMemo::fixed_puzzle(&mut ctx, puzzle_hash, reveal)?;
306 Ok(Self {
307 puzzle_hash: memo.puzzle_hash,
308 memo: Program(klvm.0.clone(), memo.memo),
309 })
310 }
311}
312
313impl From<MemberMemo> for sdk::MemberMemo {
314 fn from(value: MemberMemo) -> Self {
315 Self::new(value.puzzle_hash, value.memo.1)
316 }
317}
318
319#[derive(Clone)]
320pub struct MofNMemo {
321 pub required: u32,
322 pub items: Vec<InnerPuzzleMemo>,
323}
324
325impl From<MofNMemo> for sdk::MofNMemo {
326 fn from(value: MofNMemo) -> Self {
327 Self::new(
328 value.required.try_into().unwrap(),
329 value.items.into_iter().map(Into::into).collect(),
330 )
331 }
332}