Skip to main content

chia_sdk_driver/clear_signing/
issuance.rs

1use chia_protocol::{Bytes, Bytes32};
2use chia_sdk_types::{Condition, Mod, puzzles::EverythingWithSingletonTailArgs};
3use clvm_traits::{FromClvm, ToClvm};
4use clvm_utils::tree_hash;
5use clvmr::{Allocator, NodePtr};
6
7use crate::{CurriedPuzzle, DriverError};
8
9#[derive(Debug, Clone)]
10pub struct Issuance {
11    pub coin_id: Bytes32,
12    pub asset_id: Bytes32,
13    pub extra_delta: i64,
14    pub kind: IssuanceKind,
15}
16
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub enum IssuanceKind {
19    EverythingWithSingleton {
20        singleton_struct_hash: Bytes32,
21        nonce: Bytes,
22    },
23    Unknown,
24}
25
26#[derive(Debug, Clone)]
27pub struct RunCatTailInvocation {
28    pub asset_id: Bytes32,
29    pub kind: IssuanceKind,
30}
31
32pub fn parse_run_cat_tail(
33    allocator: &Allocator,
34    conditions: &[Condition],
35) -> Result<Option<RunCatTailInvocation>, DriverError> {
36    for condition in conditions {
37        let Some(run_cat_tail) = condition.as_run_cat_tail() else {
38            continue;
39        };
40
41        let asset_id = tree_hash(allocator, run_cat_tail.program).into();
42        let kind = classify_tail(allocator, run_cat_tail.program)?;
43
44        return Ok(Some(RunCatTailInvocation { asset_id, kind }));
45    }
46
47    Ok(None)
48}
49
50fn classify_tail(allocator: &Allocator, tail: NodePtr) -> Result<IssuanceKind, DriverError> {
51    let Some(curried) = CurriedPuzzle::parse(allocator, tail) else {
52        return Ok(IssuanceKind::Unknown);
53    };
54
55    if curried.mod_hash != EverythingWithSingletonTailArgs::mod_hash() {
56        return Ok(IssuanceKind::Unknown);
57    }
58
59    let args = EverythingWithSingletonTailArgs::from_clvm(allocator, curried.args)?;
60
61    Ok(IssuanceKind::EverythingWithSingleton {
62        singleton_struct_hash: args.singleton_struct_hash,
63        nonce: args.nonce,
64    })
65}
66
67pub fn get_extra_delta_message(extra_delta: i64) -> Bytes {
68    let mut allocator = Allocator::new();
69    let ptr = extra_delta.to_clvm(&mut allocator).unwrap();
70    allocator.atom(ptr).as_ref().to_vec().into()
71}