chia_sdk_driver/primitives/
intermediate_launcher.rs1use chia_protocol::{Bytes32, Coin, CoinSpend};
2use chia_puzzle_types::{Memos, nft::NftIntermediateLauncherArgs};
3use chia_puzzles::SINGLETON_LAUNCHER_HASH;
4use chia_sdk_types::{Conditions, announcement_id};
5use chia_sha2::Sha256;
6use clvmr::Allocator;
7
8use crate::{DriverError, SpendContext};
9
10use super::Launcher;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18#[must_use]
19pub struct IntermediateLauncher {
20 mint_number: usize,
21 mint_total: usize,
22 intermediate_coin: Coin,
23 launcher_coin: Coin,
24}
25
26impl IntermediateLauncher {
27 pub fn new(parent_coin_id: Bytes32, mint_number: usize, mint_total: usize) -> Self {
29 let intermediate_puzzle_hash =
30 NftIntermediateLauncherArgs::curry_tree_hash(mint_number, mint_total).into();
31
32 let intermediate_coin = Coin::new(parent_coin_id, intermediate_puzzle_hash, 0);
33
34 let launcher_coin = Coin::new(
35 intermediate_coin.coin_id(),
36 SINGLETON_LAUNCHER_HASH.into(),
37 1,
38 );
39
40 Self {
41 mint_number,
42 mint_total,
43 intermediate_coin,
44 launcher_coin,
45 }
46 }
47
48 pub fn intermediate_coin(&self) -> Coin {
50 self.intermediate_coin
51 }
52
53 pub fn launcher_coin(&self) -> Coin {
55 self.launcher_coin
56 }
57
58 pub fn create(self, ctx: &mut SpendContext) -> Result<Launcher, DriverError> {
60 let mut parent = Conditions::new();
61
62 let puzzle = ctx.curry(NftIntermediateLauncherArgs::new(
63 self.mint_number,
64 self.mint_total,
65 ))?;
66
67 parent = parent.create_coin(self.intermediate_coin.puzzle_hash, 0, Memos::None);
68
69 let puzzle_reveal = ctx.serialize(&puzzle)?;
70 let solution = ctx.serialize(&())?;
71
72 ctx.insert(CoinSpend::new(
73 self.intermediate_coin,
74 puzzle_reveal,
75 solution,
76 ));
77
78 let mut index_message = Sha256::new();
79 index_message.update(usize_to_bytes(self.mint_number));
80 index_message.update(usize_to_bytes(self.mint_total));
81
82 Ok(Launcher::from_coin(
83 self.launcher_coin,
84 parent.assert_coin_announcement(announcement_id(
85 self.intermediate_coin.coin_id(),
86 index_message.finalize(),
87 )),
88 ))
89 }
90}
91
92fn usize_to_bytes(value: usize) -> Vec<u8> {
93 let mut allocator = Allocator::new();
94 let atom = allocator.new_number(value.into()).unwrap();
95 allocator.atom(atom).as_ref().to_vec()
96}