chik_sdk_bindings/puzzle/
nft.rs

1use std::sync::{Arc, Mutex};
2
3use binky::Result;
4use chik_protocol::{Bytes32, Coin};
5use chik_puzzle_types::nft::NftMetadata;
6use chik_sdk_driver::{
7    HashedPtr, Nft as SdkNft, NftInfo as SdkNftInfo, NftMint as SdkNftMint, NftOwner, SpendContext,
8};
9use klvm_utils::TreeHash;
10use klvmr::Allocator;
11
12use crate::{AsProgram, AsPtr, Program, Proof};
13
14use super::Puzzle;
15
16#[derive(Clone)]
17pub struct Nft {
18    pub coin: Coin,
19    pub proof: Proof,
20    pub info: NftInfo,
21}
22
23impl Nft {
24    pub fn child_proof(&self) -> Result<Proof> {
25        let ctx = self.info.metadata.0.lock().unwrap();
26        Ok(self.as_ptr(&ctx).child_lineage_proof().into())
27    }
28
29    pub fn child(
30        &self,
31        p2_puzzle_hash: Bytes32,
32        current_owner: Option<Bytes32>,
33        metadata: Program,
34    ) -> Result<Self> {
35        let ctx = metadata.0.lock().unwrap();
36        Ok(self
37            .as_ptr(&ctx)
38            .child(p2_puzzle_hash, current_owner, metadata.as_ptr(&ctx))
39            .as_program(&metadata.0))
40    }
41
42    pub fn child_with(&self, info: NftInfo) -> Result<Self> {
43        let ctx = self.info.metadata.0.lock().unwrap();
44        Ok(self
45            .as_ptr(&ctx)
46            .child_with(info.as_ptr(&ctx))
47            .as_program(&self.info.metadata.0))
48    }
49}
50
51impl AsProgram for SdkNft<HashedPtr> {
52    type AsProgram = Nft;
53
54    fn as_program(&self, klvm: &Arc<Mutex<SpendContext>>) -> Self::AsProgram {
55        Nft {
56            coin: self.coin,
57            proof: self.proof.into(),
58            info: self.info.as_program(klvm),
59        }
60    }
61}
62
63impl AsPtr for Nft {
64    type AsPtr = SdkNft<HashedPtr>;
65
66    fn as_ptr(&self, allocator: &Allocator) -> Self::AsPtr {
67        SdkNft::new(
68            self.coin,
69            self.proof.clone().into(),
70            self.info.as_ptr(allocator),
71        )
72    }
73}
74
75#[derive(Clone)]
76pub struct NftInfo {
77    pub launcher_id: Bytes32,
78    pub metadata: Program,
79    pub metadata_updater_puzzle_hash: Bytes32,
80    pub current_owner: Option<Bytes32>,
81    pub royalty_puzzle_hash: Bytes32,
82    pub royalty_basis_points: u16,
83    pub p2_puzzle_hash: Bytes32,
84}
85
86impl NftInfo {
87    pub fn inner_puzzle_hash(&self) -> Result<TreeHash> {
88        let ctx = self.metadata.0.lock().unwrap();
89        Ok(self.as_ptr(&ctx).inner_puzzle_hash())
90    }
91
92    pub fn puzzle_hash(&self) -> Result<TreeHash> {
93        let ctx = self.metadata.0.lock().unwrap();
94        Ok(self.as_ptr(&ctx).puzzle_hash())
95    }
96}
97
98impl AsProgram for SdkNftInfo<HashedPtr> {
99    type AsProgram = NftInfo;
100
101    fn as_program(&self, klvm: &Arc<Mutex<SpendContext>>) -> Self::AsProgram {
102        NftInfo {
103            launcher_id: self.launcher_id,
104            metadata: self.metadata.as_program(klvm),
105            metadata_updater_puzzle_hash: self.metadata_updater_puzzle_hash,
106            current_owner: self.current_owner,
107            royalty_puzzle_hash: self.royalty_puzzle_hash,
108            royalty_basis_points: self.royalty_basis_points,
109            p2_puzzle_hash: self.p2_puzzle_hash,
110        }
111    }
112}
113
114impl AsPtr for NftInfo {
115    type AsPtr = SdkNftInfo<HashedPtr>;
116
117    fn as_ptr(&self, allocator: &Allocator) -> Self::AsPtr {
118        SdkNftInfo {
119            launcher_id: self.launcher_id,
120            metadata: self.metadata.as_ptr(allocator),
121            metadata_updater_puzzle_hash: self.metadata_updater_puzzle_hash,
122            current_owner: self.current_owner,
123            royalty_puzzle_hash: self.royalty_puzzle_hash,
124            royalty_basis_points: self.royalty_basis_points,
125            p2_puzzle_hash: self.p2_puzzle_hash,
126        }
127    }
128}
129
130#[derive(Clone)]
131pub struct ParsedNft {
132    pub info: NftInfo,
133    pub p2_puzzle: Puzzle,
134}
135
136pub trait NftMetadataExt {}
137
138impl NftMetadataExt for NftMetadata {}
139
140#[derive(Clone)]
141pub struct NftMint {
142    pub metadata: Program,
143    pub metadata_updater_puzzle_hash: Bytes32,
144    pub p2_puzzle_hash: Bytes32,
145    pub royalty_puzzle_hash: Bytes32,
146    pub royalty_basis_points: u16,
147    pub owner: Option<NftOwner>,
148}
149
150impl AsPtr for NftMint {
151    type AsPtr = SdkNftMint<HashedPtr>;
152
153    fn as_ptr(&self, allocator: &Allocator) -> Self::AsPtr {
154        SdkNftMint {
155            metadata: self.metadata.as_ptr(allocator),
156            metadata_updater_puzzle_hash: self.metadata_updater_puzzle_hash,
157            p2_puzzle_hash: self.p2_puzzle_hash,
158            royalty_puzzle_hash: self.royalty_puzzle_hash,
159            royalty_basis_points: self.royalty_basis_points,
160            owner: self.owner,
161        }
162    }
163}
164
165pub trait NftOwnerExt {}
166
167impl NftOwnerExt for NftOwner {}
168
169#[derive(Clone)]
170pub struct MintedNfts {
171    pub nfts: Vec<Nft>,
172    pub parent_conditions: Vec<Program>,
173}