chia_sdk_driver/layers/action_layer/actions/xchandles/
oracle.rs1use chia_protocol::Bytes32;
2use chia_sdk_types::{
3 Conditions, Mod, announcement_id,
4 puzzles::{XchandlesOracleActionArgs, XchandlesSlotValue},
5};
6use clvm_utils::{ToTreeHash, TreeHash};
7use clvmr::NodePtr;
8
9use crate::{
10 DriverError, SingletonAction, Slot, Spend, SpendContext, XchandlesConstants, XchandlesRegistry,
11};
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub struct XchandlesOracleAction {
15 pub launcher_id: Bytes32,
16}
17
18impl ToTreeHash for XchandlesOracleAction {
19 fn tree_hash(&self) -> TreeHash {
20 Self::new_args(self.launcher_id).curry_tree_hash()
21 }
22}
23
24impl SingletonAction<XchandlesRegistry> for XchandlesOracleAction {
25 fn from_constants(constants: &XchandlesConstants) -> Self {
26 Self {
27 launcher_id: constants.launcher_id,
28 }
29 }
30}
31
32impl XchandlesOracleAction {
33 pub fn new_args(launcher_id: Bytes32) -> XchandlesOracleActionArgs {
34 XchandlesOracleActionArgs {
35 slot_1st_curry_hash: Slot::<()>::first_curry_hash(launcher_id, 0).into(),
36 }
37 }
38
39 fn construct_puzzle(&self, ctx: &mut SpendContext) -> Result<NodePtr, DriverError> {
40 ctx.curry(Self::new_args(self.launcher_id))
41 }
42
43 pub fn spent_slot_value(
44 ctx: &SpendContext,
45 solution: NodePtr,
46 ) -> Result<XchandlesSlotValue, DriverError> {
47 let slot_value = ctx.extract::<XchandlesSlotValue>(solution)?;
48
49 Ok(slot_value)
50 }
51
52 pub fn created_slot_value(spent_slot_value: XchandlesSlotValue) -> XchandlesSlotValue {
53 spent_slot_value
54 }
55
56 pub fn spend(
57 self,
58 ctx: &mut SpendContext,
59 registry: &mut XchandlesRegistry,
60 slot: Slot<XchandlesSlotValue>,
61 ) -> Result<Conditions, DriverError> {
62 let slot = registry.actual_slot(slot);
64 let action_solution = ctx.alloc(&slot.info.value)?;
65 let action_puzzle = self.construct_puzzle(ctx)?;
66
67 registry.insert_action_spend(ctx, Spend::new(action_puzzle, action_solution))?;
68
69 let new_slot = Self::created_slot_value(slot.info.value.clone());
70
71 slot.spend(ctx, registry.info.inner_puzzle_hash().into())?;
73
74 let mut oracle_ann = new_slot.tree_hash().to_vec();
75 oracle_ann.insert(0, b'o');
76 Ok(Conditions::new()
77 .assert_puzzle_announcement(announcement_id(registry.coin.puzzle_hash, oracle_ann)))
78 }
79}