codama_nodes/contextual_value_nodes/
pda_value_node.rs

1use crate::{AccountValueNode, ArgumentValueNode, PdaLinkNode, PdaNode, PdaSeedValueNode};
2use codama_nodes_derive::{node, node_union};
3
4#[node]
5pub struct PdaValueNode {
6    // Children.
7    pub pda: PdaValue,
8    pub seeds: Vec<PdaSeedValueNode>,
9    #[serde(skip_serializing_if = "crate::is_default")]
10    pub program_id: Box<Option<PdaProgramIdValueNode>>,
11}
12
13#[node_union]
14pub enum PdaProgramIdValueNode {
15    Account(AccountValueNode),
16    Argument(ArgumentValueNode),
17}
18
19impl From<PdaValueNode> for crate::Node {
20    fn from(val: PdaValueNode) -> Self {
21        crate::Node::ContextualValue(val.into())
22    }
23}
24
25impl PdaValueNode {
26    pub fn new<T>(pda: T, seeds: Vec<PdaSeedValueNode>) -> Self
27    where
28        T: Into<PdaValue>,
29    {
30        Self {
31            pda: pda.into(),
32            seeds,
33            program_id: Box::new(None),
34        }
35    }
36
37    pub fn new_with_program_id<T, U>(pda: T, seeds: Vec<PdaSeedValueNode>, program_id: U) -> Self
38    where
39        T: Into<PdaValue>,
40        U: Into<PdaProgramIdValueNode>,
41    {
42        Self {
43            pda: pda.into(),
44            seeds,
45            program_id: Box::new(Some(program_id.into())),
46        }
47    }
48}
49
50#[node_union]
51pub enum PdaValue {
52    Linked(PdaLinkNode),
53    Nested(PdaNode),
54}
55
56#[cfg(test)]
57mod tests {
58    use crate::{NumberTypeNode, NumberValueNode, PublicKeyValueNode, VariablePdaSeedNode, U32};
59
60    use super::*;
61
62    #[test]
63    fn new_linked() {
64        let node = PdaValueNode::new(
65            PdaLinkNode::new("masterEdition"),
66            vec![
67                PdaSeedValueNode::new(
68                    "mint",
69                    PublicKeyValueNode::new("33QJ9VtGKRS7wstQiwuigk1cBVYEPp3XBCC1g9WkDFEE"),
70                ),
71                PdaSeedValueNode::new("edition", NumberValueNode::new(42)),
72            ],
73        );
74        assert_eq!(
75            node.pda,
76            PdaValue::Linked(PdaLinkNode::new("masterEdition"))
77        );
78        assert_eq!(
79            node.seeds,
80            vec![
81                PdaSeedValueNode::new(
82                    "mint",
83                    PublicKeyValueNode::new("33QJ9VtGKRS7wstQiwuigk1cBVYEPp3XBCC1g9WkDFEE")
84                ),
85                PdaSeedValueNode::new("edition", NumberValueNode::new(42)),
86            ]
87        );
88    }
89
90    #[test]
91    fn new_nested() {
92        let node = PdaValueNode::new(
93            PdaNode::new(
94                "counter",
95                vec![VariablePdaSeedNode::new("value", NumberTypeNode::le(U32)).into()],
96            ),
97            vec![PdaSeedValueNode::new("value", NumberValueNode::new(42))],
98        );
99        assert_eq!(
100            node.pda,
101            PdaValue::Nested(PdaNode::new(
102                "counter",
103                vec![VariablePdaSeedNode::new("value", NumberTypeNode::le(U32)).into()],
104            ))
105        );
106        assert_eq!(
107            node.seeds,
108            vec![PdaSeedValueNode::new("value", NumberValueNode::new(42)),]
109        );
110    }
111
112    #[test]
113    fn to_json() {
114        let node = PdaValueNode::new(PdaLinkNode::new("myPda"), vec![]);
115        let json = serde_json::to_string(&node).unwrap();
116        assert_eq!(
117            json,
118            r#"{"kind":"pdaValueNode","pda":{"kind":"pdaLinkNode","name":"myPda"},"seeds":[]}"#
119        );
120    }
121
122    #[test]
123    fn from_json() {
124        let json: &str =
125            r#"{"kind":"pdaValueNode","pda":{"kind":"pdaLinkNode","name":"myPda"},"seeds":[]}"#;
126        let node: PdaValueNode = serde_json::from_str(json).unwrap();
127        assert_eq!(node, PdaValueNode::new(PdaLinkNode::new("myPda"), vec![]));
128    }
129
130    #[test]
131    fn to_json_with_program_id() {
132        let node = PdaValueNode::new_with_program_id(
133            PdaValue::Linked(PdaLinkNode::new("myPda")),
134            vec![],
135            AccountValueNode::new("myProgramAccount"),
136        );
137        let json = serde_json::to_string(&node).unwrap();
138        assert_eq!(
139            json,
140            r#"{"kind":"pdaValueNode","pda":{"kind":"pdaLinkNode","name":"myPda"},"seeds":[],"programId":{"kind":"accountValueNode","name":"myProgramAccount"}}"#
141        );
142    }
143}