chia_sdk_driver/action_system/
spend_kind.rs1use chia_protocol::Bytes32;
2use chia_puzzle_types::offer::{NotarizedPayment, Payment};
3use chia_sdk_types::{
4 conditions::{AssertPuzzleAnnouncement, CreateCoin},
5 payment_assertion, tree_hash_notarized_payment, Conditions,
6};
7use clvmr::{Allocator, NodePtr};
8
9use crate::{Output, OutputConstraints, OutputSet};
10
11mod conditions_spend;
12mod settlement_spend;
13
14pub use conditions_spend::*;
15pub use settlement_spend::*;
16
17#[derive(Debug, Clone)]
18pub enum SpendKind {
19 Conditions(ConditionsSpend),
20 Settlement(SettlementSpend),
21}
22
23impl SpendKind {
24 pub fn conditions() -> Self {
25 Self::Conditions(ConditionsSpend::new())
26 }
27
28 pub fn settlement() -> Self {
29 Self::Settlement(SettlementSpend::new())
30 }
31
32 pub fn is_conditions(&self) -> bool {
33 matches!(self, Self::Conditions(_))
34 }
35
36 pub fn is_settlement(&self) -> bool {
37 matches!(self, Self::Settlement(_))
38 }
39
40 pub fn create_coin_with_assertion(
41 &mut self,
42 allocator: &Allocator,
43 parent_puzzle_hash: Bytes32,
44 payment_assertions: &mut Vec<AssertPuzzleAnnouncement>,
45 create_coin: CreateCoin<NodePtr>,
46 ) {
47 match self {
48 SpendKind::Conditions(spend) => {
49 spend.add_conditions(Conditions::new().with(create_coin));
50 }
51 SpendKind::Settlement(spend) => {
52 let notarized_payment = NotarizedPayment::new(
54 Bytes32::default(),
55 vec![Payment::new(
56 create_coin.puzzle_hash,
57 create_coin.amount,
58 create_coin.memos,
59 )],
60 );
61 payment_assertions.push(payment_assertion(
62 parent_puzzle_hash,
63 tree_hash_notarized_payment(allocator, ¬arized_payment),
64 ));
65 spend.add_notarized_payment(notarized_payment);
66 }
67 }
68 }
69
70 pub fn create_intermediate_coin(&mut self, create_coin: CreateCoin<NodePtr>) {
71 match self {
72 Self::Conditions(spend) => {
73 spend.add_conditions(Conditions::new().with(create_coin));
74 }
75 Self::Settlement(spend) => {
76 spend.add_notarized_payment(NotarizedPayment {
78 nonce: Bytes32::default(),
79 payments: vec![Payment::new(
80 create_coin.puzzle_hash,
81 create_coin.amount,
82 create_coin.memos,
83 )],
84 });
85 }
86 }
87 }
88
89 #[must_use]
90 pub fn empty_copy(&self) -> Self {
91 match self {
92 Self::Conditions(_) => Self::conditions(),
93 Self::Settlement(_) => Self::settlement(),
94 }
95 }
96}
97
98impl OutputSet for SpendKind {
99 fn has_output(&self, output: &Output) -> bool {
100 match self {
101 Self::Conditions(spend) => spend.has_output(output),
102 Self::Settlement(spend) => spend.has_output(output),
103 }
104 }
105
106 fn can_run_cat_tail(&self) -> bool {
107 match self {
108 Self::Conditions(spend) => spend.can_run_cat_tail(),
109 Self::Settlement(spend) => spend.can_run_cat_tail(),
110 }
111 }
112
113 fn missing_singleton_output(&self) -> bool {
114 match self {
115 Self::Conditions(spend) => spend.missing_singleton_output(),
116 Self::Settlement(spend) => spend.missing_singleton_output(),
117 }
118 }
119
120 fn is_allowed(&self, output: &Output, output_constraints: &OutputConstraints) -> bool {
121 match self {
122 Self::Conditions(spend) => spend.is_allowed(output, output_constraints),
123 Self::Settlement(spend) => spend.is_allowed(output, output_constraints),
124 }
125 }
126}