chia_sdk_bindings/puzzle/
option.rs1use bindy::Result;
2use chia_protocol::{Bytes32, Coin};
3use chia_sdk_driver::{
4 OptionContract as SdkOptionContract, OptionInfo, OptionMetadata, OptionType, OptionUnderlying,
5 SingletonInfo,
6};
7use clvm_utils::{ToTreeHash, TreeHash};
8
9use crate::{Clvm, Program, Proof, Spend};
10
11use super::Puzzle;
12
13#[derive(Clone)]
14pub struct OptionContract {
15 pub coin: Coin,
16 pub proof: Proof,
17 pub info: OptionInfo,
18}
19
20pub trait OptionContractExt: Sized {
21 fn child_proof(&self) -> Result<Proof>;
22 fn child(&self, p2_puzzle_hash: Bytes32) -> Result<Self>;
23 fn child_with(&self, info: OptionInfo) -> Result<Self>;
24}
25
26impl OptionContractExt for OptionContract {
27 fn child_proof(&self) -> Result<Proof> {
28 Ok(SdkOptionContract::from(self.clone())
29 .child_lineage_proof()
30 .into())
31 }
32
33 fn child(&self, p2_puzzle_hash: Bytes32) -> Result<Self> {
34 Ok(SdkOptionContract::from(self.clone())
35 .child(p2_puzzle_hash, self.coin.amount)
36 .into())
37 }
38
39 fn child_with(&self, info: OptionInfo) -> Result<Self> {
40 Ok(SdkOptionContract::from(self.clone())
41 .child_with(info, self.coin.amount)
42 .into())
43 }
44}
45
46impl From<SdkOptionContract> for OptionContract {
47 fn from(value: SdkOptionContract) -> Self {
48 OptionContract {
49 coin: value.coin,
50 proof: value.proof.into(),
51 info: value.info,
52 }
53 }
54}
55
56impl From<OptionContract> for SdkOptionContract {
57 fn from(value: OptionContract) -> Self {
58 SdkOptionContract {
59 coin: value.coin,
60 proof: value.proof.into(),
61 info: value.info,
62 }
63 }
64}
65
66pub trait OptionInfoExt {
67 fn inner_puzzle_hash(&self) -> Result<TreeHash>;
68 fn puzzle_hash(&self) -> Result<TreeHash>;
69}
70
71impl OptionInfoExt for OptionInfo {
72 fn inner_puzzle_hash(&self) -> Result<TreeHash> {
73 Ok(SingletonInfo::inner_puzzle_hash(self))
74 }
75
76 fn puzzle_hash(&self) -> Result<TreeHash> {
77 Ok(SingletonInfo::puzzle_hash(self))
78 }
79}
80
81#[derive(Clone)]
82pub struct ParsedOptionInfo {
83 pub info: OptionInfo,
84 pub p2_puzzle: Puzzle,
85}
86
87#[derive(Clone)]
88pub struct ParsedOption {
89 pub option: OptionContract,
90 pub p2_puzzle: Puzzle,
91 pub p2_solution: Program,
92}
93
94pub trait OptionUnderlyingExt: Sized {
95 fn exercise_spend(
96 &self,
97 clvm: Clvm,
98 singleton_inner_puzzle_hash: Bytes32,
99 singleton_amount: u64,
100 ) -> Result<Spend>;
101 fn clawback_spend(&self, spend: Spend) -> Result<Spend>;
102 fn puzzle_hash(&self) -> Result<TreeHash>;
103 fn delegated_puzzle_hash(&self) -> Result<TreeHash>;
104}
105
106impl OptionUnderlyingExt for OptionUnderlying {
107 fn exercise_spend(
108 &self,
109 clvm: Clvm,
110 singleton_inner_puzzle_hash: Bytes32,
111 singleton_amount: u64,
112 ) -> Result<Spend> {
113 let mut ctx = clvm.0.lock().unwrap();
114 let spend = self.exercise_spend(&mut ctx, singleton_inner_puzzle_hash, singleton_amount)?;
115 Ok(Spend {
116 puzzle: Program(clvm.0.clone(), spend.puzzle),
117 solution: Program(clvm.0.clone(), spend.solution),
118 })
119 }
120
121 fn clawback_spend(&self, spend: Spend) -> Result<Spend> {
122 let ctx_clone = spend.puzzle.0.clone();
123 let mut ctx = ctx_clone.lock().unwrap();
124 let spend = self.clawback_spend(&mut ctx, spend.into())?;
125 Ok(Spend {
126 puzzle: Program(ctx_clone.clone(), spend.puzzle),
127 solution: Program(ctx_clone.clone(), spend.solution),
128 })
129 }
130
131 fn puzzle_hash(&self) -> Result<TreeHash> {
132 Ok(self.tree_hash())
133 }
134
135 fn delegated_puzzle_hash(&self) -> Result<TreeHash> {
136 Ok(self.delegated_puzzle().tree_hash())
137 }
138}
139
140pub trait OptionTypeExt: Sized {
141 fn xch(amount: u64) -> Result<Self>;
142 fn cat(asset_id: Bytes32, amount: u64) -> Result<Self>;
143 fn revocable_cat(asset_id: Bytes32, hidden_puzzle_hash: Bytes32, amount: u64) -> Result<Self>;
144 fn nft(launcher_id: Bytes32, settlement_puzzle_hash: Bytes32, amount: u64) -> Result<Self>;
145
146 fn to_xch(&self) -> Result<Option<OptionTypeXch>>;
147 fn to_cat(&self) -> Result<Option<OptionTypeCat>>;
148 fn to_revocable_cat(&self) -> Result<Option<OptionTypeRevocableCat>>;
149 fn to_nft(&self) -> Result<Option<OptionTypeNft>>;
150}
151
152impl OptionTypeExt for OptionType {
153 fn xch(amount: u64) -> Result<Self> {
154 Ok(Self::Xch { amount })
155 }
156
157 fn cat(asset_id: Bytes32, amount: u64) -> Result<Self> {
158 Ok(Self::Cat { asset_id, amount })
159 }
160
161 fn revocable_cat(asset_id: Bytes32, hidden_puzzle_hash: Bytes32, amount: u64) -> Result<Self> {
162 Ok(Self::RevocableCat {
163 asset_id,
164 hidden_puzzle_hash,
165 amount,
166 })
167 }
168
169 fn nft(launcher_id: Bytes32, settlement_puzzle_hash: Bytes32, amount: u64) -> Result<Self> {
170 Ok(Self::Nft {
171 launcher_id,
172 settlement_puzzle_hash,
173 amount,
174 })
175 }
176
177 fn to_xch(&self) -> Result<Option<OptionTypeXch>> {
178 match *self {
179 Self::Xch { amount } => Ok(Some(OptionTypeXch { amount })),
180 _ => Ok(None),
181 }
182 }
183
184 fn to_cat(&self) -> Result<Option<OptionTypeCat>> {
185 match *self {
186 Self::Cat { asset_id, amount } => Ok(Some(OptionTypeCat { asset_id, amount })),
187 _ => Ok(None),
188 }
189 }
190
191 fn to_revocable_cat(&self) -> Result<Option<OptionTypeRevocableCat>> {
192 match *self {
193 Self::RevocableCat {
194 asset_id,
195 hidden_puzzle_hash,
196 amount,
197 } => Ok(Some(OptionTypeRevocableCat {
198 asset_id,
199 hidden_puzzle_hash,
200 amount,
201 })),
202 _ => Ok(None),
203 }
204 }
205
206 fn to_nft(&self) -> Result<Option<OptionTypeNft>> {
207 match *self {
208 Self::Nft {
209 launcher_id,
210 settlement_puzzle_hash,
211 amount,
212 } => Ok(Some(OptionTypeNft {
213 launcher_id,
214 settlement_puzzle_hash,
215 amount,
216 })),
217 _ => Ok(None),
218 }
219 }
220}
221#[derive(Clone)]
222pub struct OptionTypeXch {
223 pub amount: u64,
224}
225
226#[derive(Clone)]
227pub struct OptionTypeCat {
228 pub asset_id: Bytes32,
229 pub amount: u64,
230}
231
232#[derive(Clone)]
233pub struct OptionTypeRevocableCat {
234 pub asset_id: Bytes32,
235 pub hidden_puzzle_hash: Bytes32,
236 pub amount: u64,
237}
238
239#[derive(Clone)]
240pub struct OptionTypeNft {
241 pub launcher_id: Bytes32,
242 pub settlement_puzzle_hash: Bytes32,
243 pub amount: u64,
244}
245
246pub trait OptionMetadataExt {}
247
248impl OptionMetadataExt for OptionMetadata {}