chia-sdk-driver 0.34.0

Driver code for interacting with standard puzzles on the Chia blockchain.
Documentation
use chia_protocol::{Bytes, Bytes32};
use chia_sdk_types::{Condition, Mod, puzzles::EverythingWithSingletonTailArgs};
use clvm_traits::{FromClvm, ToClvm};
use clvm_utils::tree_hash;
use clvmr::{Allocator, NodePtr};

use crate::{CurriedPuzzle, DriverError};

#[derive(Debug, Clone)]
pub struct Issuance {
    pub coin_id: Bytes32,
    pub asset_id: Bytes32,
    pub extra_delta: i64,
    pub kind: IssuanceKind,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum IssuanceKind {
    EverythingWithSingleton {
        singleton_struct_hash: Bytes32,
        nonce: Bytes,
    },
    Unknown,
}

#[derive(Debug, Clone)]
pub struct RunCatTailInvocation {
    pub asset_id: Bytes32,
    pub kind: IssuanceKind,
}

pub fn parse_run_cat_tail(
    allocator: &Allocator,
    conditions: &[Condition],
) -> Result<Option<RunCatTailInvocation>, DriverError> {
    for condition in conditions {
        let Some(run_cat_tail) = condition.as_run_cat_tail() else {
            continue;
        };

        let asset_id = tree_hash(allocator, run_cat_tail.program).into();
        let kind = classify_tail(allocator, run_cat_tail.program)?;

        return Ok(Some(RunCatTailInvocation { asset_id, kind }));
    }

    Ok(None)
}

fn classify_tail(allocator: &Allocator, tail: NodePtr) -> Result<IssuanceKind, DriverError> {
    let Some(curried) = CurriedPuzzle::parse(allocator, tail) else {
        return Ok(IssuanceKind::Unknown);
    };

    if curried.mod_hash != EverythingWithSingletonTailArgs::mod_hash() {
        return Ok(IssuanceKind::Unknown);
    }

    let args = EverythingWithSingletonTailArgs::from_clvm(allocator, curried.args)?;

    Ok(IssuanceKind::EverythingWithSingleton {
        singleton_struct_hash: args.singleton_struct_hash,
        nonce: args.nonce,
    })
}

pub fn get_extra_delta_message(extra_delta: i64) -> Bytes {
    let mut allocator = Allocator::new();
    let ptr = extra_delta.to_clvm(&mut allocator).unwrap();
    allocator.atom(ptr).as_ref().to_vec().into()
}