chia_sdk_driver/layers/
royalty_transfer_layer.rs1use std::convert::Infallible;
2
3use chia_protocol::Bytes32;
4use chia_puzzle_types::{nft::NftRoyaltyTransferPuzzleArgs, singleton::SingletonStruct};
5use chia_puzzles::{
6 NFT_OWNERSHIP_TRANSFER_PROGRAM_ONE_WAY_CLAIM_WITH_ROYALTIES_HASH, SINGLETON_LAUNCHER_HASH,
7 SINGLETON_TOP_LAYER_V1_1_HASH,
8};
9use clvm_traits::FromClvm;
10use clvm_utils::{ToTreeHash, TreeHash};
11use clvmr::{Allocator, NodePtr};
12
13use crate::{DriverError, Layer, Puzzle, SpendContext};
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19pub struct RoyaltyTransferLayer {
20 pub launcher_id: Bytes32,
22 pub royalty_puzzle_hash: Bytes32,
24 pub royalty_basis_points: u16,
27}
28
29impl RoyaltyTransferLayer {
30 pub fn new(
31 launcher_id: Bytes32,
32 royalty_puzzle_hash: Bytes32,
33 royalty_basis_points: u16,
34 ) -> Self {
35 Self {
36 launcher_id,
37 royalty_puzzle_hash,
38 royalty_basis_points,
39 }
40 }
41}
42
43impl Layer for RoyaltyTransferLayer {
44 type Solution = Infallible;
45
46 fn construct_puzzle(&self, ctx: &mut SpendContext) -> Result<NodePtr, DriverError> {
47 ctx.curry(NftRoyaltyTransferPuzzleArgs {
48 singleton_struct: SingletonStruct::new(self.launcher_id),
49 royalty_puzzle_hash: self.royalty_puzzle_hash,
50 royalty_ten_thousandths: self.royalty_basis_points,
51 })
52 }
53
54 fn parse_puzzle(allocator: &Allocator, puzzle: Puzzle) -> Result<Option<Self>, DriverError> {
55 let Some(puzzle) = puzzle.as_curried() else {
56 return Ok(None);
57 };
58
59 if puzzle.mod_hash
60 != NFT_OWNERSHIP_TRANSFER_PROGRAM_ONE_WAY_CLAIM_WITH_ROYALTIES_HASH.into()
61 {
62 return Ok(None);
63 }
64
65 let args = NftRoyaltyTransferPuzzleArgs::from_clvm(allocator, puzzle.args)?;
66
67 if args.singleton_struct.mod_hash != SINGLETON_TOP_LAYER_V1_1_HASH.into()
68 || args.singleton_struct.launcher_puzzle_hash != SINGLETON_LAUNCHER_HASH.into()
69 {
70 return Err(DriverError::InvalidSingletonStruct);
71 }
72
73 Ok(Some(Self {
74 launcher_id: args.singleton_struct.launcher_id,
75 royalty_puzzle_hash: args.royalty_puzzle_hash,
76 royalty_basis_points: args.royalty_ten_thousandths,
77 }))
78 }
79
80 fn construct_solution(
81 &self,
82 _ctx: &mut SpendContext,
83 _solution: Self::Solution,
84 ) -> Result<NodePtr, DriverError> {
85 panic!("RoyaltyTransferLayer does not have a solution");
86 }
87
88 fn parse_solution(
89 _allocator: &clvmr::Allocator,
90 _solution: NodePtr,
91 ) -> Result<Self::Solution, DriverError> {
92 panic!("RoyaltyTransferLayer does not have a solution");
93 }
94}
95
96impl ToTreeHash for RoyaltyTransferLayer {
97 fn tree_hash(&self) -> TreeHash {
98 NftRoyaltyTransferPuzzleArgs::curry_tree_hash(
99 self.launcher_id,
100 self.royalty_puzzle_hash,
101 self.royalty_basis_points,
102 )
103 }
104}