ckb_sdk/transaction/handler/
mod.rs

1use std::any::Any;
2
3use crate::{
4    core::TransactionBuilder, tx_builder::TxBuilderError, unlock::MultisigConfig, NetworkInfo,
5    ScriptGroup,
6};
7
8use self::{
9    sighash::Secp256k1Blake160SighashAllScriptContext, sudt::SudtContext, typeid::TypeIdContext,
10};
11
12pub mod multisig;
13pub mod sighash;
14pub mod sudt;
15pub mod typeid;
16
17#[cfg_attr(target_arch="wasm32", async_trait::async_trait(?Send))]
18#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
19pub trait ScriptHandler: Send + Sync {
20    /// Try to build transaction with the given script_group and context.
21    ///
22    /// Return true if script_group and context are matched, otherwise return false.
23    fn build_transaction(
24        &self,
25        tx_builder: &mut TransactionBuilder,
26        script_group: &mut ScriptGroup,
27        context: &dyn HandlerContext,
28    ) -> Result<bool, TxBuilderError>;
29    #[cfg(not(target_arch = "wasm32"))]
30    fn init(&mut self, network: &NetworkInfo) -> Result<(), TxBuilderError>;
31    async fn init_async(&mut self, network: &NetworkInfo) -> Result<(), TxBuilderError>;
32}
33
34pub trait Type2Any: 'static {
35    fn as_any(&self) -> &dyn Any;
36}
37
38impl<T: 'static> Type2Any for T {
39    fn as_any(&self) -> &dyn Any {
40        self
41    }
42}
43
44pub trait HandlerContext: Type2Any + Send + Sync {}
45
46pub struct HandlerContexts {
47    pub contexts: Vec<Box<dyn HandlerContext>>,
48}
49
50impl Default for HandlerContexts {
51    fn default() -> Self {
52        Self {
53            contexts: vec![
54                Box::new(Secp256k1Blake160SighashAllScriptContext),
55                Box::new(SudtContext),
56                Box::new(TypeIdContext),
57            ],
58        }
59    }
60}
61
62impl HandlerContexts {
63    pub fn new_sighash() -> Self {
64        Self {
65            contexts: vec![Box::new(Secp256k1Blake160SighashAllScriptContext)],
66        }
67    }
68
69    pub fn new_multisig(config: MultisigConfig) -> Self {
70        Self {
71            contexts: vec![Box::new(
72                multisig::Secp256k1Blake160MultisigAllScriptContext::new(config),
73            )],
74        }
75    }
76
77    pub fn add_context(&mut self, context: Box<dyn HandlerContext>) {
78        self.contexts.push(context);
79    }
80}