Skip to content

Commit

Permalink
Make minting possible
Browse files Browse the repository at this point in the history
  • Loading branch information
Rigidity committed Dec 10, 2024
1 parent 2f25b5f commit 5cbf5f8
Show file tree
Hide file tree
Showing 15 changed files with 402 additions and 95 deletions.
18 changes: 9 additions & 9 deletions crates/chia-sdk-driver/src/primitives/vault.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
mod known_puzzles;
mod m_of_n;
mod member;
mod puzzle_with_restrictions;
mod restriction;
mod vault_info;
mod vault_launcher;
mod vault_layer;
mod vault_primitive;

pub use known_puzzles::*;
pub use m_of_n::*;
pub use member::*;
pub use puzzle_with_restrictions::*;
pub use restriction::*;
pub use vault_info::*;

use chia_protocol::Coin;

#[derive(Debug, Clone)]
pub struct Vault {
pub coin: Coin,
}
pub use vault_layer::*;
pub use vault_primitive::*;
17 changes: 17 additions & 0 deletions crates/chia-sdk-driver/src/primitives/vault/known_puzzles.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use std::collections::HashMap;

use clvm_utils::TreeHash;

use super::{MemberKind, RestrictionKind};

#[derive(Debug, Default, Clone)]
pub struct KnownPuzzles {
pub restrictions: HashMap<TreeHash, RestrictionKind>,
pub members: HashMap<TreeHash, MemberKind>,
}

impl KnownPuzzles {
pub fn new() -> Self {
Self::default()
}
}
73 changes: 40 additions & 33 deletions crates/chia-sdk-driver/src/primitives/vault/m_of_n.rs
Original file line number Diff line number Diff line change
@@ -1,55 +1,62 @@
use clvm_traits::{FromClvm, ToClvm};
use clvmr::{Allocator, NodePtr};
use chia_protocol::Bytes32;
use chia_sdk_types::{MerkleTree, Mod, Vault1ofNArgs, VaultMofNArgs, VaultNofNArgs};
use clvm_utils::TreeHash;

use crate::DriverError;

use super::Member;

#[derive(Debug, Clone, PartialEq, Eq, ToClvm, FromClvm)]
#[clvm(list)]
pub struct MofNMemo<T> {
pub required: usize,
pub members: Vec<T>,
}
use super::{KnownPuzzles, Member, PuzzleWithRestrictions, VaultLayer};

#[derive(Debug, Clone)]
pub struct MofN {
required: usize,
members: Vec<Member>,
members: Vec<PuzzleWithRestrictions<Member>>,
}

impl MofN {
pub fn new(required: usize, members: Vec<Member>) -> Option<Self> {
pub fn new(required: usize, members: Vec<PuzzleWithRestrictions<Member>>) -> Option<Self> {
if members.len() < required {
return None;
}
Some(Self { required, members })
}

pub fn from_memo(allocator: &Allocator, memo: NodePtr) -> Result<Self, DriverError> {
let memo = MofNMemo::from_clvm(allocator, memo)?;

if memo.members.len() < memo.required {
return Err(DriverError::InvalidMemo);
}

let mut members = Vec::with_capacity(memo.members.len());
pub fn required(&self) -> usize {
self.required
}

for member_memo in memo.members {
members.push(Member::from_memo(allocator, member_memo)?);
}
pub fn members(&self) -> &[PuzzleWithRestrictions<Member>] {
&self.members
}

Ok(Self {
required: memo.required,
members,
})
fn merkle_tree(&self) -> MerkleTree {
let leaves: Vec<Bytes32> = self
.members
.iter()
.map(|member| member.puzzle_hash().into())
.collect();
MerkleTree::new(&leaves)
}
}

pub fn required(&self) -> usize {
self.required
impl VaultLayer for MofN {
fn puzzle_hash(&self) -> TreeHash {
if self.required == 1 {
let merkle_tree = self.merkle_tree();
Vault1ofNArgs::new(merkle_tree.root()).curry_tree_hash()
} else if self.required == self.members.len() {
let members = self.members.iter().map(VaultLayer::puzzle_hash).collect();
VaultNofNArgs::new(members).curry_tree_hash()
} else {
let merkle_tree = self.merkle_tree();
VaultMofNArgs::new(self.required, merkle_tree.root()).curry_tree_hash()
}
}

pub fn members(&self) -> &[Member] {
&self.members
fn replace(self, known_puzzles: &KnownPuzzles) -> Self {
let required = self.required;
let members = self
.members
.into_iter()
.map(|member| member.replace(known_puzzles))
.collect();
Self { required, members }
}
}
79 changes: 57 additions & 22 deletions crates/chia-sdk-driver/src/primitives/vault/member.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,70 @@
use chia_bls::PublicKey;
use chia_protocol::Bytes32;
use chia_sdk_types::BlsMember;
use clvm_traits::{FromClvm, ToClvm};
use clvmr::{Allocator, NodePtr};
use chia_sdk_types::{BlsMember, Mod};
use clvm_utils::TreeHash;

use crate::DriverError;
use super::{KnownPuzzles, MofN, VaultLayer};

use super::MofN;

#[derive(Debug, Clone, PartialEq, Eq, ToClvm, FromClvm)]
#[clvm(list)]
pub struct MemberMemo<T> {
pub curried_puzzle_hash: Bytes32,
pub member: T,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)]
#[clvm(list)]
pub struct BlsMemberMemo {
pub public_key: PublicKey,
#[derive(Debug, Clone)]
pub struct Member {
puzzle_hash: TreeHash,
kind: MemberKind,
}

#[derive(Debug, Clone)]
pub enum Member {
pub enum MemberKind {
Bls(BlsMember),
// do this last
MofN(MofN),
Unknown,
}

impl Member {
pub fn from_memo(allocator: &Allocator, memo: NodePtr) -> Result<Self, DriverError> {
todo!()
pub fn bls(public_key: PublicKey) -> Self {
let member = BlsMember::new(public_key);
Self {
puzzle_hash: member.curry_tree_hash(),
kind: MemberKind::Bls(member),
}
}

pub fn m_of_n(m_of_n: MofN) -> Self {
Self {
puzzle_hash: m_of_n.puzzle_hash(),
kind: MemberKind::MofN(m_of_n),
}
}

pub fn unknown(puzzle_hash: TreeHash) -> Self {
Self {
puzzle_hash,
kind: MemberKind::Unknown,
}
}

pub fn kind(&self) -> &MemberKind {
&self.kind
}
}

impl VaultLayer for Member {
fn puzzle_hash(&self) -> TreeHash {
self.puzzle_hash
}

fn replace(self, known_puzzles: &KnownPuzzles) -> Self {
let kind = known_puzzles
.members
.get(&self.puzzle_hash)
.cloned()
.unwrap_or(self.kind);

let kind = match kind {
MemberKind::Bls(..) | MemberKind::Unknown => kind,
MemberKind::MofN(m_of_n) => MemberKind::MofN(m_of_n.replace(known_puzzles)),
};

Self {
puzzle_hash: self.puzzle_hash,
kind,
}
}
}
52 changes: 52 additions & 0 deletions crates/chia-sdk-driver/src/primitives/vault/memos.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#[derive(Debug, Clone, PartialEq, Eq, ToClvm, FromClvm)]
#[clvm(list)]
pub struct RestrictionMemo<T> {
pub is_morpher: bool,
pub curried_puzzle_hash: Bytes32,
pub restriction: T,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)]
#[clvm(list)]
pub struct TimelockMemo {
pub seconds: u64,
}

#[derive(Debug, Clone, PartialEq, Eq, ToClvm, FromClvm)]
#[clvm(list)]
pub struct MemberMemo<T> {
pub curried_puzzle_hash: Bytes32,
pub member: T,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)]
#[clvm(list)]
pub struct BlsMemberMemo {
pub public_key: PublicKey,
}

#[derive(Debug, Clone, PartialEq, Eq, ToClvm, FromClvm)]
#[clvm(list)]
pub struct MofNMemo<T> {
pub required: usize,
pub members: Vec<T>,
}

pub fn from_memo(allocator: &Allocator, memo: NodePtr) -> Result<Self, DriverError> {
let memo = MofNMemo::from_clvm(allocator, memo)?;

if memo.members.len() < memo.required {
return Err(DriverError::InvalidMemo);
}

let mut members = Vec::with_capacity(memo.members.len());

for member_memo in memo.members {
members.push(Member::from_memo(allocator, member_memo)?);
}

Ok(Self {
required: memo.required,
members,
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use chia_sdk_types::{DelegatedFeederArgs, IndexWrapperArgs, Mod, RestrictionsArgs};
use clvm_utils::TreeHash;

use super::{KnownPuzzles, Restriction, VaultLayer};

#[derive(Debug, Clone)]
pub struct PuzzleWithRestrictions<T> {
nonce: usize,
restrictions: Vec<Restriction>,
puzzle: T,
has_delegated_feeder: bool,
}

impl<T> PuzzleWithRestrictions<T> {
pub fn top_level(nonce: usize, restrictions: Vec<Restriction>, puzzle: T) -> Self {

Check warning on line 15 in crates/chia-sdk-driver/src/primitives/vault/puzzle_with_restrictions.rs

View check run for this annotation

Codecov / codecov/patch

crates/chia-sdk-driver/src/primitives/vault/puzzle_with_restrictions.rs#L15

Added line #L15 was not covered by tests
Self {
nonce,
restrictions,
puzzle,
has_delegated_feeder: true,
}
}

pub fn inner(nonce: usize, restrictions: Vec<Restriction>, puzzle: T) -> Self {

Check warning on line 24 in crates/chia-sdk-driver/src/primitives/vault/puzzle_with_restrictions.rs

View check run for this annotation

Codecov / codecov/patch

crates/chia-sdk-driver/src/primitives/vault/puzzle_with_restrictions.rs#L24

Added line #L24 was not covered by tests
Self {
nonce,
restrictions,
puzzle,
has_delegated_feeder: false,
}
}
}

impl<T> VaultLayer for PuzzleWithRestrictions<T>
where
T: VaultLayer,
{
fn puzzle_hash(&self) -> TreeHash {
let mut puzzle_hash = self.puzzle.puzzle_hash();

Check warning on line 39 in crates/chia-sdk-driver/src/primitives/vault/puzzle_with_restrictions.rs

View check run for this annotation

Codecov / codecov/patch

crates/chia-sdk-driver/src/primitives/vault/puzzle_with_restrictions.rs#L38-L39

Added lines #L38 - L39 were not covered by tests

if !self.restrictions.is_empty() {
let mut member_validators = Vec::new();
let mut delegated_puzzle_validators = Vec::new();

Check warning on line 43 in crates/chia-sdk-driver/src/primitives/vault/puzzle_with_restrictions.rs

View check run for this annotation

Codecov / codecov/patch

crates/chia-sdk-driver/src/primitives/vault/puzzle_with_restrictions.rs#L42-L43

Added lines #L42 - L43 were not covered by tests

for restriction in &self.restrictions {
if restriction.is_member_condition_validator() {
member_validators.push(restriction.puzzle_hash());

Check warning on line 47 in crates/chia-sdk-driver/src/primitives/vault/puzzle_with_restrictions.rs

View check run for this annotation

Codecov / codecov/patch

crates/chia-sdk-driver/src/primitives/vault/puzzle_with_restrictions.rs#L45-L47

Added lines #L45 - L47 were not covered by tests
} else {
delegated_puzzle_validators.push(restriction.puzzle_hash());

Check warning on line 49 in crates/chia-sdk-driver/src/primitives/vault/puzzle_with_restrictions.rs

View check run for this annotation

Codecov / codecov/patch

crates/chia-sdk-driver/src/primitives/vault/puzzle_with_restrictions.rs#L49

Added line #L49 was not covered by tests
}
}

puzzle_hash =
RestrictionsArgs::new(member_validators, delegated_puzzle_validators, puzzle_hash)
.curry_tree_hash();

Check warning on line 55 in crates/chia-sdk-driver/src/primitives/vault/puzzle_with_restrictions.rs

View check run for this annotation

Codecov / codecov/patch

crates/chia-sdk-driver/src/primitives/vault/puzzle_with_restrictions.rs#L53-L55

Added lines #L53 - L55 were not covered by tests
}

if self.has_delegated_feeder {
puzzle_hash = DelegatedFeederArgs::new(puzzle_hash).curry_tree_hash();
}

IndexWrapperArgs::new(self.nonce, puzzle_hash).curry_tree_hash()
}

fn replace(mut self, known_puzzles: &KnownPuzzles) -> Self {
let mut restrictions = Vec::with_capacity(self.restrictions.len());
for restriction in self.restrictions {
restrictions.push(restriction.replace(known_puzzles));

Check warning on line 68 in crates/chia-sdk-driver/src/primitives/vault/puzzle_with_restrictions.rs

View check run for this annotation

Codecov / codecov/patch

crates/chia-sdk-driver/src/primitives/vault/puzzle_with_restrictions.rs#L65-L68

Added lines #L65 - L68 were not covered by tests
}
self.restrictions = restrictions;
self.puzzle = self.puzzle.replace(known_puzzles);
self

Check warning on line 72 in crates/chia-sdk-driver/src/primitives/vault/puzzle_with_restrictions.rs

View check run for this annotation

Codecov / codecov/patch

crates/chia-sdk-driver/src/primitives/vault/puzzle_with_restrictions.rs#L70-L72

Added lines #L70 - L72 were not covered by tests
}
}
Loading

0 comments on commit 5cbf5f8

Please sign in to comment.