diff --git a/Cargo.lock b/Cargo.lock index b80f9d77..145f02e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -459,6 +459,7 @@ dependencies = [ "chia-sdk-signer", "chia-sdk-test", "chia-sdk-types", + "chia-secp", "chia-traits 0.17.0", "clvm-traits", "clvm-utils", @@ -535,6 +536,7 @@ dependencies = [ "chia-protocol", "chia-puzzles", "chia-sdk-derive", + "chia-secp", "clvm-traits", "clvm-utils", "clvmr", diff --git a/Cargo.toml b/Cargo.toml index ecd005f9..47ad44cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,7 +62,10 @@ workspace = true [features] chip-0035 = ["chia-sdk-driver/chip-0035", "chia-sdk-types/chip-0035"] -vault = ["chia-sdk-driver/vault", "chia-sdk-types/vault"] +experimental-vaults = [ + "chia-sdk-driver/experimental-vaults", + "chia-sdk-types/experimental-vaults", +] offers = ["chia-sdk-driver/offers"] native-tls = ["chia-sdk-client/native-tls"] rustls = ["chia-sdk-client/rustls"] diff --git a/crates/chia-sdk-driver/Cargo.toml b/crates/chia-sdk-driver/Cargo.toml index 327eeadc..15f847a7 100644 --- a/crates/chia-sdk-driver/Cargo.toml +++ b/crates/chia-sdk-driver/Cargo.toml @@ -19,7 +19,7 @@ workspace = true [features] chip-0035 = ["chia-sdk-types/chip-0035"] -vault = ["chia-sdk-types/vault"] +experimental-vaults = ["chia-sdk-types/experimental-vaults"] offers = [ "dep:bech32", "dep:chia-traits", @@ -30,6 +30,7 @@ offers = [ [dependencies] chia-bls = { workspace = true } +chia-secp = { workspace = true } chia-protocol = { workspace = true } chia-puzzles = { workspace = true } clvm-traits = { workspace = true } diff --git a/crates/chia-sdk-driver/src/primitives.rs b/crates/chia-sdk-driver/src/primitives.rs index 8f6e283b..22afeb14 100644 --- a/crates/chia-sdk-driver/src/primitives.rs +++ b/crates/chia-sdk-driver/src/primitives.rs @@ -18,8 +18,8 @@ mod datalayer; #[cfg(feature = "chip-0035")] pub use datalayer::*; -#[cfg(feature = "vault")] +#[cfg(feature = "experimental-vaults")] mod vault; -#[cfg(feature = "vault")] +#[cfg(feature = "experimental-vaults")] pub use vault::*; diff --git a/crates/chia-sdk-driver/src/primitives/vault/member.rs b/crates/chia-sdk-driver/src/primitives/vault/member.rs index a8e5a1f4..7306f0ba 100644 --- a/crates/chia-sdk-driver/src/primitives/vault/member.rs +++ b/crates/chia-sdk-driver/src/primitives/vault/member.rs @@ -1,5 +1,11 @@ use chia_bls::PublicKey; -use chia_sdk_types::{BlsMember, Mod}; +use chia_protocol::Bytes32; +use chia_sdk_types::{ + BlsMember, BlsTaprootMember, FixedPuzzleMember, Mod, PasskeyMember, PasskeyMemberPuzzleAssert, + Secp256k1Member, Secp256k1MemberPuzzleAssert, Secp256r1Member, Secp256r1MemberPuzzleAssert, + SingletonMember, +}; +use chia_secp::{K1PublicKey, R1PublicKey}; use clvm_utils::TreeHash; use clvmr::NodePtr; @@ -16,6 +22,15 @@ pub struct Member { #[derive(Debug, Clone)] pub enum MemberKind { Bls(BlsMember), + BlsTaproot(BlsTaprootMember), + FixedPuzzle(FixedPuzzleMember), + Passkey(PasskeyMember), + PasskeyPuzzleAssert(PasskeyMemberPuzzleAssert), + Secp256k1(Secp256k1Member), + Secp256k1PuzzleAssert(Secp256k1MemberPuzzleAssert), + Secp256r1(Secp256r1Member), + Secp256r1PuzzleAssert(Secp256r1MemberPuzzleAssert), + Singleton(SingletonMember), MofN(MofN), Unknown, } @@ -29,6 +44,78 @@ impl Member { } } + pub fn bls_taproot(synthetic_key: PublicKey) -> Self { + let member = BlsTaprootMember::new(synthetic_key); + Self { + puzzle_hash: member.curry_tree_hash(), + kind: MemberKind::BlsTaproot(member), + } + } + + pub fn fixed_puzzle(fixed_puzzle_hash: Bytes32) -> Self { + let member = FixedPuzzleMember::new(fixed_puzzle_hash); + Self { + puzzle_hash: member.curry_tree_hash(), + kind: MemberKind::FixedPuzzle(member), + } + } + + pub fn passkey(genesis_challenge: Bytes32, public_key: R1PublicKey) -> Self { + let member = PasskeyMember::new(genesis_challenge, public_key); + Self { + puzzle_hash: member.curry_tree_hash(), + kind: MemberKind::Passkey(member), + } + } + + pub fn passkey_puzzle_assert(genesis_challenge: Bytes32, public_key: R1PublicKey) -> Self { + let member = PasskeyMemberPuzzleAssert::new(genesis_challenge, public_key); + Self { + puzzle_hash: member.curry_tree_hash(), + kind: MemberKind::PasskeyPuzzleAssert(member), + } + } + + pub fn secp256k1(public_key: K1PublicKey) -> Self { + let member = Secp256k1Member::new(public_key); + Self { + puzzle_hash: member.curry_tree_hash(), + kind: MemberKind::Secp256k1(member), + } + } + + pub fn secp256k1_puzzle_assert(public_key: K1PublicKey) -> Self { + let member = Secp256k1MemberPuzzleAssert::new(public_key); + Self { + puzzle_hash: member.curry_tree_hash(), + kind: MemberKind::Secp256k1PuzzleAssert(member), + } + } + + pub fn secp256r1(public_key: R1PublicKey) -> Self { + let member = Secp256r1Member::new(public_key); + Self { + puzzle_hash: member.curry_tree_hash(), + kind: MemberKind::Secp256r1(member), + } + } + + pub fn secp256r1_puzzle_assert(public_key: R1PublicKey) -> Self { + let member = Secp256r1MemberPuzzleAssert::new(public_key); + Self { + puzzle_hash: member.curry_tree_hash(), + kind: MemberKind::Secp256r1PuzzleAssert(member), + } + } + + pub fn singleton(launcher_id: Bytes32) -> Self { + let member = SingletonMember::new(launcher_id); + Self { + puzzle_hash: member.curry_tree_hash(), + kind: MemberKind::Singleton(member), + } + } + pub fn m_of_n(required: usize, members: Vec>) -> Self { let m_of_n = MofN::new(required, members).expect("invalid m_of_n"); Self { @@ -57,6 +144,21 @@ impl VaultLayer for Member { fn puzzle(&self, ctx: &mut SpendContext) -> Result { match &self.kind { MemberKind::Bls(bls) => ctx.curry(bls), + MemberKind::BlsTaproot(bls_taproot) => ctx.curry(bls_taproot), + MemberKind::FixedPuzzle(fixed_puzzle) => ctx.curry(fixed_puzzle), + MemberKind::Passkey(passkey) => ctx.curry(passkey), + MemberKind::PasskeyPuzzleAssert(passkey_puzzle_assert) => { + ctx.curry(passkey_puzzle_assert) + } + MemberKind::Secp256k1(secp256k1) => ctx.curry(secp256k1), + MemberKind::Secp256k1PuzzleAssert(secp256k1_puzzle_assert) => { + ctx.curry(secp256k1_puzzle_assert) + } + MemberKind::Secp256r1(secp256r1) => ctx.curry(secp256r1), + MemberKind::Secp256r1PuzzleAssert(secp256r1_puzzle_assert) => { + ctx.curry(secp256r1_puzzle_assert) + } + MemberKind::Singleton(singleton) => ctx.curry(singleton), MemberKind::MofN(m_of_n) => m_of_n.puzzle(ctx), MemberKind::Unknown => Err(DriverError::UnknownPuzzle), } @@ -70,7 +172,17 @@ impl VaultLayer for Member { .unwrap_or(self.kind); let kind = match kind { - MemberKind::Bls(..) | MemberKind::Unknown => kind, + MemberKind::Bls(..) + | MemberKind::BlsTaproot(..) + | MemberKind::FixedPuzzle(..) + | MemberKind::Passkey(..) + | MemberKind::PasskeyPuzzleAssert(..) + | MemberKind::Secp256k1(..) + | MemberKind::Secp256k1PuzzleAssert(..) + | MemberKind::Secp256r1(..) + | MemberKind::Secp256r1PuzzleAssert(..) + | MemberKind::Singleton(..) + | MemberKind::Unknown => kind, MemberKind::MofN(m_of_n) => MemberKind::MofN(m_of_n.replace(known_puzzles)), }; diff --git a/crates/chia-sdk-driver/src/primitives/vault/restriction.rs b/crates/chia-sdk-driver/src/primitives/vault/restriction.rs index a2b76593..8327d432 100644 --- a/crates/chia-sdk-driver/src/primitives/vault/restriction.rs +++ b/crates/chia-sdk-driver/src/primitives/vault/restriction.rs @@ -1,4 +1,4 @@ -use chia_sdk_types::Timelock; +use chia_sdk_types::{Force1of2RestrictedVariable, Timelock}; use clvm_utils::TreeHash; use clvmr::NodePtr; @@ -16,6 +16,9 @@ pub struct Restriction { #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum RestrictionKind { Timelock(Timelock), + ForceCoinMessage, + ForceAssertCoinAnnouncement, + Force1of2RestrictedVariable(Force1of2RestrictedVariable), Unknown, } @@ -49,6 +52,11 @@ impl VaultLayer for Restriction { fn puzzle(&self, ctx: &mut SpendContext) -> Result { match &self.kind { RestrictionKind::Timelock(timelock) => ctx.curry(timelock), + RestrictionKind::ForceCoinMessage => ctx.force_coin_message_puzzle(), + RestrictionKind::ForceAssertCoinAnnouncement => { + ctx.force_assert_coin_announcement_puzzle() + } + RestrictionKind::Force1of2RestrictedVariable(restriction) => ctx.curry(restriction), RestrictionKind::Unknown => Err(DriverError::UnknownPuzzle), } } diff --git a/crates/chia-sdk-driver/src/spend_context.rs b/crates/chia-sdk-driver/src/spend_context.rs index f1b85938..52bfa73c 100644 --- a/crates/chia-sdk-driver/src/spend_context.rs +++ b/crates/chia-sdk-driver/src/spend_context.rs @@ -11,6 +11,12 @@ use clvm_traits::{FromClvm, ToClvm}; use clvm_utils::{tree_hash, CurriedProgram, TreeHash}; use clvmr::{serde::node_from_bytes, Allocator, NodePtr}; +#[cfg(feature = "experimental-vaults")] +use chia_sdk_types::{ + FORCE_ASSERT_COIN_ANNOUNCEMENT_PUZZLE, FORCE_ASSERT_COIN_ANNOUNCEMENT_PUZZLE_HASH, + FORCE_COIN_MESSAGE_PUZZLE, FORCE_COIN_MESSAGE_PUZZLE_HASH, +}; + use crate::{DriverError, Spend}; /// A wrapper around [`Allocator`] that caches puzzles and keeps track of a list of [`CoinSpend`]. @@ -128,6 +134,19 @@ impl SpendContext { self.puzzle(SETTLEMENT_PAYMENTS_PUZZLE_HASH, &SETTLEMENT_PAYMENTS_PUZZLE) } + #[cfg(feature = "experimental-vaults")] + pub fn force_coin_message_puzzle(&mut self) -> Result { + self.puzzle(FORCE_COIN_MESSAGE_PUZZLE_HASH, &FORCE_COIN_MESSAGE_PUZZLE) + } + + #[cfg(feature = "experimental-vaults")] + pub fn force_assert_coin_announcement_puzzle(&mut self) -> Result { + self.puzzle( + FORCE_ASSERT_COIN_ANNOUNCEMENT_PUZZLE_HASH, + &FORCE_ASSERT_COIN_ANNOUNCEMENT_PUZZLE, + ) + } + /// Preload a puzzle into the cache. pub fn preload(&mut self, puzzle_hash: TreeHash, ptr: NodePtr) { self.puzzles.insert(puzzle_hash, ptr); diff --git a/crates/chia-sdk-types/Cargo.toml b/crates/chia-sdk-types/Cargo.toml index 7ee801ff..8f912df9 100644 --- a/crates/chia-sdk-types/Cargo.toml +++ b/crates/chia-sdk-types/Cargo.toml @@ -16,11 +16,12 @@ workspace = true [features] chip-0035 = [] -vault = [] +experimental-vaults = [] [dependencies] chia-sdk-derive = { workspace = true } chia-bls = { workspace = true } +chia-secp = { workspace = true } chia-protocol = { workspace = true } chia-consensus = { workspace = true } chia-puzzles = { workspace = true } diff --git a/crates/chia-sdk-types/src/puzzles.rs b/crates/chia-sdk-types/src/puzzles.rs index ae321e27..2a9866cc 100644 --- a/crates/chia-sdk-types/src/puzzles.rs +++ b/crates/chia-sdk-types/src/puzzles.rs @@ -18,10 +18,10 @@ mod datalayer; #[cfg(feature = "chip-0035")] pub use datalayer::*; -#[cfg(feature = "vault")] +#[cfg(feature = "experimental-vaults")] mod vault; -#[cfg(feature = "vault")] +#[cfg(feature = "experimental-vaults")] pub use vault::*; #[cfg(test)] diff --git a/crates/chia-sdk-types/src/puzzles/vault/members.rs b/crates/chia-sdk-types/src/puzzles/vault/members.rs index f0c02cf0..5f202fb8 100644 --- a/crates/chia-sdk-types/src/puzzles/vault/members.rs +++ b/crates/chia-sdk-types/src/puzzles/vault/members.rs @@ -1,3 +1,21 @@ mod bls_member; +mod bls_taproot_member; +mod fixed_puzzle_member; +mod passkey_member; +mod passkey_member_puzzle_assert; +mod secp256k1_member; +mod secp256k1_member_puzzle_assert; +mod secp256r1_member; +mod secp256r1_member_puzzle_assert; +mod singleton_member; pub use bls_member::*; +pub use bls_taproot_member::*; +pub use fixed_puzzle_member::*; +pub use passkey_member::*; +pub use passkey_member_puzzle_assert::*; +pub use secp256k1_member::*; +pub use secp256k1_member_puzzle_assert::*; +pub use secp256r1_member::*; +pub use secp256r1_member_puzzle_assert::*; +pub use singleton_member::*; diff --git a/crates/chia-sdk-types/src/puzzles/vault/members/bls_taproot_member.rs b/crates/chia-sdk-types/src/puzzles/vault/members/bls_taproot_member.rs new file mode 100644 index 00000000..a878ff25 --- /dev/null +++ b/crates/chia-sdk-types/src/puzzles/vault/members/bls_taproot_member.rs @@ -0,0 +1,50 @@ +use chia_bls::PublicKey; +use clvm_traits::{FromClvm, ToClvm}; +use clvm_utils::TreeHash; +use hex_literal::hex; + +use crate::Mod; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(curry)] +pub struct BlsTaprootMember { + pub synthetic_key: PublicKey, +} + +impl BlsTaprootMember { + pub fn new(synthetic_key: PublicKey) -> Self { + Self { synthetic_key } + } +} + +impl Mod for BlsTaprootMember { + const MOD_REVEAL: &[u8] = &BLS_TAPROOT_MEMBER; + const MOD_HASH: TreeHash = BLS_TAPROOT_MEMBER_HASH; +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(solution)] +pub struct BlsTaprootMemberSolution { + pub original_public_key: Option, +} + +impl BlsTaprootMemberSolution { + pub fn new(original_public_key: Option) -> Self { + Self { + original_public_key, + } + } +} + +pub const BLS_TAPROOT_MEMBER: [u8; 99] = hex!( + " + ff02ffff01ff02ffff03ff17ffff01ff02ffff03ffff09ff05ffff1dff17ffff + 1effff0bff17ff0b80808080ff80ffff01ff088080ff0180ffff01ff04ffff04 + ff02ffff04ff05ffff04ff0bff80808080ff808080ff0180ffff04ffff0132ff + 018080 + " +); + +pub const BLS_TAPROOT_MEMBER_HASH: TreeHash = TreeHash::new(hex!( + "35d2ad31aaf0df91c965909e5112294c57a18354ee4a5aae80572080ec3b6842" +)); diff --git a/crates/chia-sdk-types/src/puzzles/vault/members/fixed_puzzle_member.rs b/crates/chia-sdk-types/src/puzzles/vault/members/fixed_puzzle_member.rs new file mode 100644 index 00000000..77d214d3 --- /dev/null +++ b/crates/chia-sdk-types/src/puzzles/vault/members/fixed_puzzle_member.rs @@ -0,0 +1,30 @@ +use chia_protocol::Bytes32; +use clvm_traits::{FromClvm, ToClvm}; +use clvm_utils::TreeHash; +use hex_literal::hex; + +use crate::Mod; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(curry)] +pub struct FixedPuzzleMember { + pub fixed_puzzle_hash: Bytes32, +} + +impl FixedPuzzleMember { + pub fn new(fixed_puzzle_hash: Bytes32) -> Self { + Self { fixed_puzzle_hash } + } +} + +impl Mod for FixedPuzzleMember { + const MOD_REVEAL: &[u8] = &FIXED_PUZZLE_MEMBER; + const MOD_HASH: TreeHash = FIXED_PUZZLE_MEMBER_HASH; +} + +pub const FIXED_PUZZLE_MEMBER: [u8; 25] = + hex!("ff02ffff03ffff09ff02ff0580ff80ffff01ff088080ff0180"); + +pub const FIXED_PUZZLE_MEMBER_HASH: TreeHash = TreeHash::new(hex!( + "34ede3eadc52ed750e405f2b9dea9891506547f651290bb606356d997c64f219" +)); diff --git a/crates/chia-sdk-types/src/puzzles/vault/members/passkey_member.rs b/crates/chia-sdk-types/src/puzzles/vault/members/passkey_member.rs new file mode 100644 index 00000000..a3d7f2cf --- /dev/null +++ b/crates/chia-sdk-types/src/puzzles/vault/members/passkey_member.rs @@ -0,0 +1,92 @@ +use chia_protocol::{Bytes, Bytes32}; +use chia_secp::{R1PublicKey, R1Signature}; +use clvm_traits::{FromClvm, ToClvm}; +use clvm_utils::TreeHash; +use hex_literal::hex; + +use crate::Mod; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(curry)] +pub struct PasskeyMember { + pub genesis_challenge: Bytes32, + pub public_key: R1PublicKey, +} + +impl PasskeyMember { + pub fn new(genesis_challenge: Bytes32, public_key: R1PublicKey) -> Self { + Self { + genesis_challenge, + public_key, + } + } +} + +impl Mod for PasskeyMember { + const MOD_REVEAL: &[u8] = &PASSKEY_MEMBER; + const MOD_HASH: TreeHash = PASSKEY_MEMBER_HASH; +} + +#[derive(Debug, Clone, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(solution)] +pub struct PasskeyMemberSolution { + pub authenticator_data: Bytes, + pub client_data_json: Bytes, + pub challenge_index: usize, + pub signature: R1Signature, + pub coin_id: Bytes32, +} + +pub const PASSKEY_MEMBER: [u8; 1424] = hex!( + " + ff02ffff01ff02ff3effff04ff02ffff04ff03ffff04ffff02ff2cffff04ff02 + ffff04ffff0bff17ff8202ffff0580ff80808080ff8080808080ffff04ffff01 + ffffffff02ffff03ffff21ffff09ff0bffff0dff178080ffff15ff0bffff0dff + 17808080ffff01ff0180ffff01ff04ffff02ff05ffff04ffff0cff17ff0bffff + 10ff0bffff01038080ff808080ffff02ff10ffff04ff02ffff04ff05ffff04ff + ff10ff0bffff010380ffff04ff17ff8080808080808080ff0180ff02ffff03ff + 0bffff01ff02ffff03ff13ffff01ff04ffff02ff05ffff04ff23ff808080ffff + 02ff18ffff04ff02ffff04ff05ffff04ffff04ff33ff1b80ff808080808080ff + ff01ff02ff18ffff04ff02ffff04ff05ffff04ff1bff808080808080ff0180ff + ff01ff018080ff0180ffff0cffff01c0404142434445464748494a4b4c4d4e4f + 505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475 + 767778797a303132333435363738392d5fff05ffff10ff05ffff01018080ffff + 02ff3cffff04ff02ffff04ff03ffff04ffff06ffff14ffff0dff0580ffff0103 + 8080ff8080808080ff02ff12ffff04ff02ffff04ff03ffff04ffff02ffff03ff + 0bffff01ff11ffff0103ff0b80ffff01ff018080ff0180ff8080808080ffffff + 02ff2affff04ff02ffff04ff03ffff04ffff0eff11ffff0cffff0183000000ff + 80ff0b8080ff8080808080ffff02ff2effff04ff02ffff04ff03ffff04ffff02 + ff10ffff04ff02ffff04ffff04ffff0102ffff04ffff04ffff0101ffff04ffff + 0102ffff04ffff04ffff0101ff1680ffff04ffff04ffff0104ffff04ffff04ff + ff0101ff0280ffff04ffff0101ff80808080ff8080808080ffff04ffff04ffff + 0104ffff04ffff04ffff0101ffff04ff15ff808080ffff04ffff0101ff808080 + 80ff80808080ffff04ff80ffff04ff0bff808080808080ff8080808080ff04ff + 4fffff04ffff19ffff16ff6fffff010480ff2780ffff04ffff19ffff16ff37ff + ff010280ff1380ffff04ff1bff8080808080ffff02ff3affff04ff02ffff04ff + ff04ffff04ff09ff8080ffff04ff0bff808080ffff04ffff14ffff02ffff03ff + ff15ffff0cff0bffff0102ffff010380ffff0181ff80ffff01ff0cff0bffff01 + 02ffff010380ffff01ff10ffff0cff0bffff0102ffff010380ffff0182010080 + 80ff0180ffff014080ffff04ffff14ffff02ffff03ffff15ffff0cff0bffff01 + 01ffff010280ffff0181ff80ffff01ff0cff0bffff0101ffff010280ffff01ff + 10ffff0cff0bffff0101ffff010280ffff018201008080ff0180ffff011080ff + ff04ffff14ffff02ffff03ffff15ffff0cff0bff80ffff010180ffff0181ff80 + ffff01ff0cff0bff80ffff010180ffff01ff10ffff0cff0bff80ffff010180ff + ff018201008080ff0180ffff010480ff80808080808080ffff0cffff02ffff04 + ffff04ffff010eff8080ffff02ff18ffff04ff02ffff04ffff04ffff0102ffff + 04ffff04ffff0101ff1480ffff04ffff04ffff0104ffff04ffff04ffff0101ff + 0280ffff04ffff0101ff80808080ff80808080ffff04ff0bff808080808080ff + 8080ff80ffff11ffff0dffff02ffff04ffff04ffff010eff8080ffff02ff18ff + ff04ff02ffff04ffff04ffff0102ffff04ffff04ffff0101ff1480ffff04ffff + 04ffff0104ffff04ffff04ffff0101ff0280ffff04ffff0101ff80808080ff80 + 808080ffff04ff0bff808080808080ff808080ff298080ff02ffff03ffff09ff + ff0cff8200bdff82017dffff10ff82017dffff0dffff0effff018d226368616c + 6c656e6765223a22ff0bffff012280808080ffff0effff018d226368616c6c65 + 6e6765223a22ff0bffff01228080ffff01ff04ffff04ffff0146ffff04ff8205 + fdff808080ffff841c3a8f00ff15ffff0bff5dffff0bff8200bd8080ff8202fd + 8080ffff01ff088080ff0180ff018080 + " +); + +pub const PASSKEY_MEMBER_HASH: TreeHash = TreeHash::new(hex!( + "2877c080c18a408111ec86b108da56dd667f968ce38f87623ca084934127059c" +)); diff --git a/crates/chia-sdk-types/src/puzzles/vault/members/passkey_member_puzzle_assert.rs b/crates/chia-sdk-types/src/puzzles/vault/members/passkey_member_puzzle_assert.rs new file mode 100644 index 00000000..9a7d2ff2 --- /dev/null +++ b/crates/chia-sdk-types/src/puzzles/vault/members/passkey_member_puzzle_assert.rs @@ -0,0 +1,92 @@ +use chia_protocol::{Bytes, Bytes32}; +use chia_secp::{R1PublicKey, R1Signature}; +use clvm_traits::{FromClvm, ToClvm}; +use clvm_utils::TreeHash; +use hex_literal::hex; + +use crate::Mod; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(curry)] +pub struct PasskeyMemberPuzzleAssert { + pub genesis_challenge: Bytes32, + pub public_key: R1PublicKey, +} + +impl PasskeyMemberPuzzleAssert { + pub fn new(genesis_challenge: Bytes32, public_key: R1PublicKey) -> Self { + Self { + genesis_challenge, + public_key, + } + } +} + +impl Mod for PasskeyMemberPuzzleAssert { + const MOD_REVEAL: &[u8] = &PASSKEY_MEMBER_PUZZLE_ASSERT; + const MOD_HASH: TreeHash = PASSKEY_MEMBER_PUZZLE_ASSERT_HASH; +} + +#[derive(Debug, Clone, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(solution)] +pub struct PasskeyMemberPuzzleAssertSolution { + pub authenticator_data: Bytes, + pub client_data_json: Bytes, + pub challenge_index: usize, + pub signature: R1Signature, + pub puzzle_hash: Bytes32, +} + +pub const PASSKEY_MEMBER_PUZZLE_ASSERT: [u8; 1424] = hex!( + " + ff02ffff01ff02ff3effff04ff02ffff04ff03ffff04ffff02ff2cffff04ff02 + ffff04ffff0bff17ff8202ffff0580ff80808080ff8080808080ffff04ffff01 + ffffffff02ffff03ffff21ffff09ff0bffff0dff178080ffff15ff0bffff0dff + 17808080ffff01ff0180ffff01ff04ffff02ff05ffff04ffff0cff17ff0bffff + 10ff0bffff01038080ff808080ffff02ff10ffff04ff02ffff04ff05ffff04ff + ff10ff0bffff010380ffff04ff17ff8080808080808080ff0180ff02ffff03ff + 0bffff01ff02ffff03ff13ffff01ff04ffff02ff05ffff04ff23ff808080ffff + 02ff18ffff04ff02ffff04ff05ffff04ffff04ff33ff1b80ff808080808080ff + ff01ff02ff18ffff04ff02ffff04ff05ffff04ff1bff808080808080ff0180ff + ff01ff018080ff0180ffff0cffff01c0404142434445464748494a4b4c4d4e4f + 505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475 + 767778797a303132333435363738392d5fff05ffff10ff05ffff01018080ffff + 02ff3cffff04ff02ffff04ff03ffff04ffff06ffff14ffff0dff0580ffff0103 + 8080ff8080808080ff02ff12ffff04ff02ffff04ff03ffff04ffff02ffff03ff + 0bffff01ff11ffff0103ff0b80ffff01ff018080ff0180ff8080808080ffffff + 02ff2affff04ff02ffff04ff03ffff04ffff0eff11ffff0cffff0183000000ff + 80ff0b8080ff8080808080ffff02ff2effff04ff02ffff04ff03ffff04ffff02 + ff10ffff04ff02ffff04ffff04ffff0102ffff04ffff04ffff0101ffff04ffff + 0102ffff04ffff04ffff0101ff1680ffff04ffff04ffff0104ffff04ffff04ff + ff0101ff0280ffff04ffff0101ff80808080ff8080808080ffff04ffff04ffff + 0104ffff04ffff04ffff0101ffff04ff15ff808080ffff04ffff0101ff808080 + 80ff80808080ffff04ff80ffff04ff0bff808080808080ff8080808080ff04ff + 4fffff04ffff19ffff16ff6fffff010480ff2780ffff04ffff19ffff16ff37ff + ff010280ff1380ffff04ff1bff8080808080ffff02ff3affff04ff02ffff04ff + ff04ffff04ff09ff8080ffff04ff0bff808080ffff04ffff14ffff02ffff03ff + ff15ffff0cff0bffff0102ffff010380ffff0181ff80ffff01ff0cff0bffff01 + 02ffff010380ffff01ff10ffff0cff0bffff0102ffff010380ffff0182010080 + 80ff0180ffff014080ffff04ffff14ffff02ffff03ffff15ffff0cff0bffff01 + 01ffff010280ffff0181ff80ffff01ff0cff0bffff0101ffff010280ffff01ff + 10ffff0cff0bffff0101ffff010280ffff018201008080ff0180ffff011080ff + ff04ffff14ffff02ffff03ffff15ffff0cff0bff80ffff010180ffff0181ff80 + ffff01ff0cff0bff80ffff010180ffff01ff10ffff0cff0bff80ffff010180ff + ff018201008080ff0180ffff010480ff80808080808080ffff0cffff02ffff04 + ffff04ffff010eff8080ffff02ff18ffff04ff02ffff04ffff04ffff0102ffff + 04ffff04ffff0101ff1480ffff04ffff04ffff0104ffff04ffff04ffff0101ff + 0280ffff04ffff0101ff80808080ff80808080ffff04ff0bff808080808080ff + 8080ff80ffff11ffff0dffff02ffff04ffff04ffff010eff8080ffff02ff18ff + ff04ff02ffff04ffff04ffff0102ffff04ffff04ffff0101ff1480ffff04ffff + 04ffff0104ffff04ffff04ffff0101ff0280ffff04ffff0101ff80808080ff80 + 808080ffff04ff0bff808080808080ff808080ff298080ff02ffff03ffff09ff + ff0cff8200bdff82017dffff10ff82017dffff0dffff0effff018d226368616c + 6c656e6765223a22ff0bffff012280808080ffff0effff018d226368616c6c65 + 6e6765223a22ff0bffff01228080ffff01ff04ffff04ffff0148ffff04ff8205 + fdff808080ffff841c3a8f00ff15ffff0bff5dffff0bff8200bd8080ff8202fd + 8080ffff01ff088080ff0180ff018080 + " +); + +pub const PASSKEY_MEMBER_PUZZLE_ASSERT_HASH: TreeHash = TreeHash::new(hex!( + "0bf2d91cf0442a139b2cb9f9c2a68a3ac3b497093fc66595b3c4c398ae94d206" +)); diff --git a/crates/chia-sdk-types/src/puzzles/vault/members/secp256k1_member.rs b/crates/chia-sdk-types/src/puzzles/vault/members/secp256k1_member.rs new file mode 100644 index 00000000..ce1d6cc8 --- /dev/null +++ b/crates/chia-sdk-types/src/puzzles/vault/members/secp256k1_member.rs @@ -0,0 +1,42 @@ +use chia_protocol::Bytes32; +use chia_secp::{K1PublicKey, K1Signature}; +use clvm_traits::{FromClvm, ToClvm}; +use clvm_utils::TreeHash; +use hex_literal::hex; + +use crate::Mod; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(curry)] +pub struct Secp256k1Member { + pub public_key: K1PublicKey, +} + +impl Secp256k1Member { + pub fn new(public_key: K1PublicKey) -> Self { + Self { public_key } + } +} + +impl Mod for Secp256k1Member { + const MOD_REVEAL: &[u8] = &SECP256K1_MEMBER; + const MOD_HASH: TreeHash = SECP256K1_MEMBER_HASH; +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(solution)] +pub struct Secp256k1MemberSolution { + pub coin_id: Bytes32, + pub signature: K1Signature, +} + +pub const SECP256K1_MEMBER: [u8; 53] = hex!( + " + ff02ffff01ff04ffff04ff02ffff04ff17ff808080ffff8413d61f00ff05ffff + 0bff0bff1780ff2f8080ffff04ffff0146ff018080 + " +); + +pub const SECP256K1_MEMBER_HASH: TreeHash = TreeHash::new(hex!( + "2b05daf134c9163acc8f2ac05b61f7d8328fca3dcc963154a28e89bcfc4dbfca" +)); diff --git a/crates/chia-sdk-types/src/puzzles/vault/members/secp256k1_member_puzzle_assert.rs b/crates/chia-sdk-types/src/puzzles/vault/members/secp256k1_member_puzzle_assert.rs new file mode 100644 index 00000000..020c1436 --- /dev/null +++ b/crates/chia-sdk-types/src/puzzles/vault/members/secp256k1_member_puzzle_assert.rs @@ -0,0 +1,42 @@ +use chia_protocol::Bytes32; +use chia_secp::{K1PublicKey, K1Signature}; +use clvm_traits::{FromClvm, ToClvm}; +use clvm_utils::TreeHash; +use hex_literal::hex; + +use crate::Mod; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(curry)] +pub struct Secp256k1MemberPuzzleAssert { + pub public_key: K1PublicKey, +} + +impl Secp256k1MemberPuzzleAssert { + pub fn new(public_key: K1PublicKey) -> Self { + Self { public_key } + } +} + +impl Mod for Secp256k1MemberPuzzleAssert { + const MOD_REVEAL: &[u8] = &SECP256K1_MEMBER_PUZZLE_ASSERT; + const MOD_HASH: TreeHash = SECP256K1_MEMBER_PUZZLE_ASSERT_HASH; +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(solution)] +pub struct Secp256k1MemberPuzzleAssertSolution { + pub puzzle_hash: Bytes32, + pub signature: K1Signature, +} + +pub const SECP256K1_MEMBER_PUZZLE_ASSERT: [u8; 53] = hex!( + " + ff02ffff01ff04ffff04ff02ffff04ff17ff808080ffff8413d61f00ff05ffff + 0bff0bff1780ff2f8080ffff04ffff0148ff018080 + " +); + +pub const SECP256K1_MEMBER_PUZZLE_ASSERT_HASH: TreeHash = TreeHash::new(hex!( + "67d591ffeb00571269d401f41a6a43ceb927b5087074ad4446ff22400a010e87" +)); diff --git a/crates/chia-sdk-types/src/puzzles/vault/members/secp256r1_member.rs b/crates/chia-sdk-types/src/puzzles/vault/members/secp256r1_member.rs new file mode 100644 index 00000000..06dcf076 --- /dev/null +++ b/crates/chia-sdk-types/src/puzzles/vault/members/secp256r1_member.rs @@ -0,0 +1,42 @@ +use chia_protocol::Bytes32; +use chia_secp::{R1PublicKey, R1Signature}; +use clvm_traits::{FromClvm, ToClvm}; +use clvm_utils::TreeHash; +use hex_literal::hex; + +use crate::Mod; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(curry)] +pub struct Secp256r1Member { + pub public_key: R1PublicKey, +} + +impl Secp256r1Member { + pub fn new(public_key: R1PublicKey) -> Self { + Self { public_key } + } +} + +impl Mod for Secp256r1Member { + const MOD_REVEAL: &[u8] = &SECP256R1_MEMBER; + const MOD_HASH: TreeHash = SECP256R1_MEMBER_HASH; +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(solution)] +pub struct Secp256r1MemberSolution { + pub coin_id: Bytes32, + pub signature: R1Signature, +} + +pub const SECP256R1_MEMBER: [u8; 53] = hex!( + " + ff02ffff01ff04ffff04ff02ffff04ff17ff808080ffff841c3a8f00ff05ffff + 0bff0bff1780ff2f8080ffff04ffff0146ff018080 + " +); + +pub const SECP256R1_MEMBER_HASH: TreeHash = TreeHash::new(hex!( + "05aaa1f2fb6c48b5bce952b09f3da99afa4241989878a9919aafb7d74b70ac54" +)); diff --git a/crates/chia-sdk-types/src/puzzles/vault/members/secp256r1_member_puzzle_assert.rs b/crates/chia-sdk-types/src/puzzles/vault/members/secp256r1_member_puzzle_assert.rs new file mode 100644 index 00000000..aee703ae --- /dev/null +++ b/crates/chia-sdk-types/src/puzzles/vault/members/secp256r1_member_puzzle_assert.rs @@ -0,0 +1,42 @@ +use chia_protocol::Bytes32; +use chia_secp::{R1PublicKey, R1Signature}; +use clvm_traits::{FromClvm, ToClvm}; +use clvm_utils::TreeHash; +use hex_literal::hex; + +use crate::Mod; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(curry)] +pub struct Secp256r1MemberPuzzleAssert { + pub public_key: R1PublicKey, +} + +impl Secp256r1MemberPuzzleAssert { + pub fn new(public_key: R1PublicKey) -> Self { + Self { public_key } + } +} + +impl Mod for Secp256r1MemberPuzzleAssert { + const MOD_REVEAL: &[u8] = &SECP256R1_MEMBER_PUZZLE_ASSERT; + const MOD_HASH: TreeHash = SECP256R1_MEMBER_PUZZLE_ASSERT_HASH; +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(solution)] +pub struct Secp256r1MemberPuzzleAssertSolution { + pub puzzle_hash: Bytes32, + pub signature: R1Signature, +} + +pub const SECP256R1_MEMBER_PUZZLE_ASSERT: [u8; 53] = hex!( + " + ff02ffff01ff04ffff04ff02ffff04ff17ff808080ffff841c3a8f00ff05ffff + 0bff0bff1780ff2f8080ffff04ffff0148ff018080 + " +); + +pub const SECP256R1_MEMBER_PUZZLE_ASSERT_HASH: TreeHash = TreeHash::new(hex!( + "d77bbc050bff8dfe4eb4544fa2bf0d0fd0463b96801bf6445687bd35985e71db" +)); diff --git a/crates/chia-sdk-types/src/puzzles/vault/members/singleton_member.rs b/crates/chia-sdk-types/src/puzzles/vault/members/singleton_member.rs new file mode 100644 index 00000000..099f4944 --- /dev/null +++ b/crates/chia-sdk-types/src/puzzles/vault/members/singleton_member.rs @@ -0,0 +1,54 @@ +use chia_protocol::Bytes32; +use chia_puzzles::singleton::SingletonStruct; +use clvm_traits::{FromClvm, ToClvm}; +use clvm_utils::TreeHash; +use hex_literal::hex; + +use crate::Mod; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(curry)] +pub struct SingletonMember { + pub singleton_struct: SingletonStruct, +} + +impl SingletonMember { + pub fn new(launcher_id: Bytes32) -> Self { + Self { + singleton_struct: SingletonStruct::new(launcher_id), + } + } +} + +impl Mod for SingletonMember { + const MOD_REVEAL: &[u8] = &SINGLETON_MEMBER; + const MOD_HASH: TreeHash = SINGLETON_MEMBER_HASH; +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(solution)] +pub struct SingletonMemberSolution { + pub singleton_inner_puzzle_hash: Bytes32, + pub singleton_amount: u64, +} + +pub const SINGLETON_MEMBER: [u8; 361] = hex!( + " + ff02ffff01ff04ffff04ff12ffff04ffff0117ffff04ff0bffff04ffff02ff2e + ffff04ff02ffff04ff09ffff04ff17ffff04ffff02ff3effff04ff02ffff04ff + 05ff80808080ff808080808080ff8080808080ff8080ffff04ffff01ffffff02 + 04ff0101ffff4302ffff02ffff03ff05ffff01ff02ff16ffff04ff02ffff04ff + 0dffff04ffff0bff1affff0bff14ff1880ffff0bff1affff0bff1affff0bff14 + ff1c80ff0980ffff0bff1aff0bffff0bff14ff8080808080ff8080808080ffff + 010b80ff0180ffff0bff1affff0bff14ff1080ffff0bff1affff0bff1affff0b + ff14ff1c80ff0580ffff0bff1affff02ff16ffff04ff02ffff04ff07ffff04ff + ff0bff14ff1480ff8080808080ffff0bff14ff8080808080ff02ffff03ffff07 + ff0580ffff01ff0bffff0102ffff02ff3effff04ff02ffff04ff09ff80808080 + ffff02ff3effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff05 + 8080ff0180ff018080 + " +); + +pub const SINGLETON_MEMBER_HASH: TreeHash = TreeHash::new(hex!( + "6f1cebc5a6d3661ad87d3558146259ca580729b244b7662757f8d1c34a6a9ad9" +)); diff --git a/crates/chia-sdk-types/src/puzzles/vault/restrictions.rs b/crates/chia-sdk-types/src/puzzles/vault/restrictions.rs index 313a40df..bb1f800a 100644 --- a/crates/chia-sdk-types/src/puzzles/vault/restrictions.rs +++ b/crates/chia-sdk-types/src/puzzles/vault/restrictions.rs @@ -1,5 +1,11 @@ +mod force_1_of_2_restricted_variable; +mod force_assert_coin_announcement; +mod force_coin_message; mod timelock; +pub use force_1_of_2_restricted_variable::*; +pub use force_assert_coin_announcement::*; +pub use force_coin_message::*; pub use timelock::*; use clvm_traits::{FromClvm, ToClvm}; diff --git a/crates/chia-sdk-types/src/puzzles/vault/restrictions/force_1_of_2_restricted_variable.rs b/crates/chia-sdk-types/src/puzzles/vault/restrictions/force_1_of_2_restricted_variable.rs new file mode 100644 index 00000000..ec84f545 --- /dev/null +++ b/crates/chia-sdk-types/src/puzzles/vault/restrictions/force_1_of_2_restricted_variable.rs @@ -0,0 +1,74 @@ +use chia_protocol::Bytes32; +use clvm_traits::{FromClvm, ToClvm}; +use clvm_utils::TreeHash; +use hex_literal::hex; + +use crate::{Mod, DELEGATED_FEEDER_PUZZLE_HASH, VAULT_1_OF_N_PUZZLE_HASH}; + +use super::RESTRICTIONS_PUZZLE_HASH; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(curry)] +pub struct Force1of2RestrictedVariable { + pub delegated_puzzle_feeder_mod_hash: Bytes32, + pub one_of_n_mod_hash: Bytes32, + pub left_side_subtree_hash: Bytes32, + pub nonce: usize, + pub restriction_mod_hash: Bytes32, + pub member_validator_list_hash: Bytes32, + pub delegated_puzzle_validator_list_hash: Bytes32, +} + +impl Force1of2RestrictedVariable { + pub fn new( + left_side_subtree_hash: Bytes32, + nonce: usize, + member_validator_list_hash: Bytes32, + delegated_puzzle_validator_list_hash: Bytes32, + ) -> Self { + Self { + delegated_puzzle_feeder_mod_hash: DELEGATED_FEEDER_PUZZLE_HASH.into(), + one_of_n_mod_hash: VAULT_1_OF_N_PUZZLE_HASH.into(), + left_side_subtree_hash, + nonce, + restriction_mod_hash: RESTRICTIONS_PUZZLE_HASH.into(), + member_validator_list_hash, + delegated_puzzle_validator_list_hash, + } + } +} + +impl Mod for Force1of2RestrictedVariable { + const MOD_REVEAL: &[u8] = &FORCE_1_OF_2_RESTRICTED_VARIABLE_PUZZLE; + const MOD_HASH: TreeHash = FORCE_1_OF_2_RESTRICTED_VARIABLE_PUZZLE_HASH; +} + +pub const FORCE_1_OF_2_RESTRICTED_VARIABLE_PUZZLE: [u8; 650] = hex!( + " + ff02ffff01ff02ffff03ffff02ff12ffff04ff02ffff04ff8205ffffff04ffff + 02ff16ffff04ff02ffff04ff2fffff04ffff0bff18ff5f80ffff04ffff02ff16 + ffff04ff02ffff04ff05ffff04ffff02ff16ffff04ff02ffff04ff0bffff04ff + ff0bff18ffff0bff14ff17ffff0bff18ffff02ff16ffff04ff02ffff04ff2fff + ff04ffff0bff18ff5f80ffff04ffff02ff16ffff04ff02ffff04ff81bfffff04 + ff82017fffff04ff8202ffffff04ff820bffff80808080808080ff8080808080 + 80808080ff8080808080ff8080808080ff808080808080ff8080808080ffff01 + 8205ffffff01ff088080ff0180ffff04ffff01ffffff3301ff02ff02ffff03ff + 05ffff01ff0bff7affff02ff1effff04ff02ffff04ff09ffff04ffff02ff1cff + ff04ff02ffff04ff0dff80808080ff808080808080ffff016a80ff0180ffffff + 02ffff03ff05ffff01ff02ffff03ffff02ffff03ffff09ff11ff1080ffff01ff + 02ffff03ffff20ffff09ff29ff0b8080ffff01ff0101ff8080ff0180ff8080ff + 0180ffff01ff0880ffff01ff02ff12ffff04ff02ffff04ff0dffff04ff0bff80 + 8080808080ff0180ffff01ff010180ff0180ffffa04bf5122f344554c53bde2e + bb8cd2b7e3d1600ad631c385a5d7cce23c7785459aa09dcf97a184f32623d11a + 73124ceb99a5709b083721e878a16d78f596718ba7b2ffa102a12871fee210fb + 8619291eaea194581cbd2531e4b23759d225f6806923f63222a102a8d5dd63fb + a471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5ffff0bff5a + ffff02ff1effff04ff02ffff04ff05ffff04ffff02ff1cffff04ff02ffff04ff + 07ff80808080ff808080808080ff0bff14ffff0bff14ff6aff0580ffff0bff14 + ff0bff4a8080ff018080 + " +); + +pub const FORCE_1_OF_2_RESTRICTED_VARIABLE_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( + "4f7bc8f30deb6dad75a1e29ceacb67fd0fe0eda79173e45295ff2cfbb8de53c6" +)); diff --git a/crates/chia-sdk-types/src/puzzles/vault/restrictions/force_assert_coin_announcement.rs b/crates/chia-sdk-types/src/puzzles/vault/restrictions/force_assert_coin_announcement.rs new file mode 100644 index 00000000..8ec1e38d --- /dev/null +++ b/crates/chia-sdk-types/src/puzzles/vault/restrictions/force_assert_coin_announcement.rs @@ -0,0 +1,14 @@ +use clvm_utils::TreeHash; +use hex_literal::hex; + +pub const FORCE_ASSERT_COIN_ANNOUNCEMENT_PUZZLE: [u8; 85] = hex!( + " + ff02ffff01ff02ff06ffff04ff02ffff04ff05ff80808080ffff04ffff01ff3d + ff02ffff03ffff09ff11ff0480ffff0105ffff01ff04ff09ffff02ff06ffff04 + ff02ffff04ff0dff808080808080ff0180ff018080 + " +); + +pub const FORCE_ASSERT_COIN_ANNOUNCEMENT_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( + "ca0daca027e5ebd4a61fad7e32cfe1e984ad5b561c2fc08dea30accf3a191fab" +)); diff --git a/crates/chia-sdk-types/src/puzzles/vault/restrictions/force_coin_message.rs b/crates/chia-sdk-types/src/puzzles/vault/restrictions/force_coin_message.rs new file mode 100644 index 00000000..3ef29d5c --- /dev/null +++ b/crates/chia-sdk-types/src/puzzles/vault/restrictions/force_coin_message.rs @@ -0,0 +1,15 @@ +use clvm_utils::TreeHash; +use hex_literal::hex; + +pub const FORCE_COIN_MESSAGE_PUZZLE: [u8; 127] = hex!( + " + ff02ffff01ff02ff06ffff04ff02ffff04ff05ff80808080ffff04ffff01ff42 + ff02ffff03ffff02ffff03ffff09ff11ff0480ffff01ff02ffff03ffff18ff29 + ffff010780ffff01ff0101ff8080ff0180ff8080ff0180ffff0105ffff01ff04 + ff09ffff02ff06ffff04ff02ffff04ff0dff808080808080ff0180ff018080 + " +); + +pub const FORCE_COIN_MESSAGE_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( + "9618c96b30b96362f6c01716a11f76c630a786697d5bac92345f5ff90b882268" +));