chia_sdk_driver/clear_signing/
issuance.rs1use 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}