chia-sdk-bindings 0.34.0

Underlying implementation of chia-wallet-sdk bindings.
Documentation
use bindy::Result;
use chia_protocol::{Bytes32, Coin};
use chia_sdk_driver::{
    OptionContract as SdkOptionContract, OptionInfo, OptionMetadata, OptionType, OptionUnderlying,
    SingletonInfo,
};
use clvm_utils::{ToTreeHash, TreeHash};

use crate::{Clvm, Program, Proof, Spend};

use super::Puzzle;

#[derive(Clone)]
pub struct OptionContract {
    pub coin: Coin,
    pub proof: Proof,
    pub info: OptionInfo,
}

pub trait OptionContractExt: Sized {
    fn child_proof(&self) -> Result<Proof>;
    fn child(&self, p2_puzzle_hash: Bytes32) -> Result<Self>;
    fn child_with(&self, info: OptionInfo) -> Result<Self>;
}

impl OptionContractExt for OptionContract {
    fn child_proof(&self) -> Result<Proof> {
        Ok(SdkOptionContract::from(self.clone())
            .child_lineage_proof()
            .into())
    }

    fn child(&self, p2_puzzle_hash: Bytes32) -> Result<Self> {
        Ok(SdkOptionContract::from(self.clone())
            .child(p2_puzzle_hash, self.coin.amount)
            .into())
    }

    fn child_with(&self, info: OptionInfo) -> Result<Self> {
        Ok(SdkOptionContract::from(self.clone())
            .child_with(info, self.coin.amount)
            .into())
    }
}

impl From<SdkOptionContract> for OptionContract {
    fn from(value: SdkOptionContract) -> Self {
        OptionContract {
            coin: value.coin,
            proof: value.proof.into(),
            info: value.info,
        }
    }
}

impl From<OptionContract> for SdkOptionContract {
    fn from(value: OptionContract) -> Self {
        SdkOptionContract {
            coin: value.coin,
            proof: value.proof.into(),
            info: value.info,
        }
    }
}

pub trait OptionInfoExt {
    fn inner_puzzle_hash(&self) -> Result<TreeHash>;
    fn puzzle_hash(&self) -> Result<TreeHash>;
}

impl OptionInfoExt for OptionInfo {
    fn inner_puzzle_hash(&self) -> Result<TreeHash> {
        Ok(SingletonInfo::inner_puzzle_hash(self))
    }

    fn puzzle_hash(&self) -> Result<TreeHash> {
        Ok(SingletonInfo::puzzle_hash(self))
    }
}

#[derive(Clone)]
pub struct ParsedOptionInfo {
    pub info: OptionInfo,
    pub p2_puzzle: Puzzle,
}

#[derive(Clone)]
pub struct ParsedOption {
    pub option: OptionContract,
    pub p2_puzzle: Puzzle,
    pub p2_solution: Program,
}

pub trait OptionUnderlyingExt: Sized {
    fn exercise_spend(
        &self,
        clvm: Clvm,
        singleton_inner_puzzle_hash: Bytes32,
        singleton_amount: u64,
    ) -> Result<Spend>;
    fn clawback_spend(&self, spend: Spend) -> Result<Spend>;
    fn puzzle_hash(&self) -> Result<TreeHash>;
    fn delegated_puzzle_hash(&self) -> Result<TreeHash>;
}

impl OptionUnderlyingExt for OptionUnderlying {
    fn exercise_spend(
        &self,
        clvm: Clvm,
        singleton_inner_puzzle_hash: Bytes32,
        singleton_amount: u64,
    ) -> Result<Spend> {
        let mut ctx = clvm.0.lock().unwrap();
        let spend = self.exercise_spend(&mut ctx, singleton_inner_puzzle_hash, singleton_amount)?;
        Ok(Spend {
            puzzle: Program(clvm.0.clone(), spend.puzzle),
            solution: Program(clvm.0.clone(), spend.solution),
        })
    }

    fn clawback_spend(&self, spend: Spend) -> Result<Spend> {
        let ctx_clone = spend.puzzle.0.clone();
        let mut ctx = ctx_clone.lock().unwrap();
        let spend = self.clawback_spend(&mut ctx, spend.into())?;
        Ok(Spend {
            puzzle: Program(ctx_clone.clone(), spend.puzzle),
            solution: Program(ctx_clone.clone(), spend.solution),
        })
    }

    fn puzzle_hash(&self) -> Result<TreeHash> {
        Ok(self.tree_hash())
    }

    fn delegated_puzzle_hash(&self) -> Result<TreeHash> {
        Ok(self.delegated_puzzle().tree_hash())
    }
}

pub trait OptionTypeExt: Sized {
    fn xch(amount: u64) -> Result<Self>;
    fn cat(asset_id: Bytes32, amount: u64) -> Result<Self>;
    fn revocable_cat(asset_id: Bytes32, hidden_puzzle_hash: Bytes32, amount: u64) -> Result<Self>;
    fn nft(launcher_id: Bytes32, settlement_puzzle_hash: Bytes32, amount: u64) -> Result<Self>;

    fn to_xch(&self) -> Result<Option<OptionTypeXch>>;
    fn to_cat(&self) -> Result<Option<OptionTypeCat>>;
    fn to_revocable_cat(&self) -> Result<Option<OptionTypeRevocableCat>>;
    fn to_nft(&self) -> Result<Option<OptionTypeNft>>;
}

impl OptionTypeExt for OptionType {
    fn xch(amount: u64) -> Result<Self> {
        Ok(Self::Xch { amount })
    }

    fn cat(asset_id: Bytes32, amount: u64) -> Result<Self> {
        Ok(Self::Cat { asset_id, amount })
    }

    fn revocable_cat(asset_id: Bytes32, hidden_puzzle_hash: Bytes32, amount: u64) -> Result<Self> {
        Ok(Self::RevocableCat {
            asset_id,
            hidden_puzzle_hash,
            amount,
        })
    }

    fn nft(launcher_id: Bytes32, settlement_puzzle_hash: Bytes32, amount: u64) -> Result<Self> {
        Ok(Self::Nft {
            launcher_id,
            settlement_puzzle_hash,
            amount,
        })
    }

    fn to_xch(&self) -> Result<Option<OptionTypeXch>> {
        match *self {
            Self::Xch { amount } => Ok(Some(OptionTypeXch { amount })),
            _ => Ok(None),
        }
    }

    fn to_cat(&self) -> Result<Option<OptionTypeCat>> {
        match *self {
            Self::Cat { asset_id, amount } => Ok(Some(OptionTypeCat { asset_id, amount })),
            _ => Ok(None),
        }
    }

    fn to_revocable_cat(&self) -> Result<Option<OptionTypeRevocableCat>> {
        match *self {
            Self::RevocableCat {
                asset_id,
                hidden_puzzle_hash,
                amount,
            } => Ok(Some(OptionTypeRevocableCat {
                asset_id,
                hidden_puzzle_hash,
                amount,
            })),
            _ => Ok(None),
        }
    }

    fn to_nft(&self) -> Result<Option<OptionTypeNft>> {
        match *self {
            Self::Nft {
                launcher_id,
                settlement_puzzle_hash,
                amount,
            } => Ok(Some(OptionTypeNft {
                launcher_id,
                settlement_puzzle_hash,
                amount,
            })),
            _ => Ok(None),
        }
    }
}
#[derive(Clone)]
pub struct OptionTypeXch {
    pub amount: u64,
}

#[derive(Clone)]
pub struct OptionTypeCat {
    pub asset_id: Bytes32,
    pub amount: u64,
}

#[derive(Clone)]
pub struct OptionTypeRevocableCat {
    pub asset_id: Bytes32,
    pub hidden_puzzle_hash: Bytes32,
    pub amount: u64,
}

#[derive(Clone)]
pub struct OptionTypeNft {
    pub launcher_id: Bytes32,
    pub settlement_puzzle_hash: Bytes32,
    pub amount: u64,
}

pub trait OptionMetadataExt {}

impl OptionMetadataExt for OptionMetadata {}