Skip to main content

chia_sdk_driver/primitives/vault/
p2_singleton.rs

1use chia_protocol::Bytes32;
2use chia_sdk_types::{
3    Mod,
4    puzzles::{SingletonMember, SingletonMemberSolution},
5};
6use clvm_utils::{ToTreeHash, TreeHash};
7
8use crate::{DriverError, InnerPuzzleSpend, MipsSpend, Spend, SpendContext, mips_puzzle_hash};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
11pub struct P2Singleton {
12    pub launcher_id: Bytes32,
13    pub nonce: usize,
14}
15
16impl P2Singleton {
17    pub fn new(launcher_id: Bytes32, nonce: usize) -> Self {
18        Self { launcher_id, nonce }
19    }
20
21    pub fn spend(
22        &self,
23        ctx: &mut SpendContext,
24        singleton_inner_puzzle_hash: Bytes32,
25        singleton_amount: u64,
26        delegated_spend: Spend,
27    ) -> Result<Spend, DriverError> {
28        let mut mips = MipsSpend::new(delegated_spend);
29
30        let puzzle = ctx.curry(SingletonMember::new(self.launcher_id))?;
31        let solution = ctx.alloc(&SingletonMemberSolution::new(
32            singleton_inner_puzzle_hash,
33            singleton_amount,
34        ))?;
35
36        let custody_hash = self.tree_hash();
37
38        mips.members.insert(
39            custody_hash,
40            InnerPuzzleSpend::new(self.nonce, vec![], Spend::new(puzzle, solution)),
41        );
42
43        mips.spend(ctx, custody_hash)
44    }
45}
46
47impl ToTreeHash for P2Singleton {
48    fn tree_hash(&self) -> TreeHash {
49        mips_puzzle_hash(
50            self.nonce,
51            vec![],
52            SingletonMember::new(self.launcher_id).curry_tree_hash(),
53            true,
54        )
55    }
56}