ckb_sdk/transaction/handler/
sudt.rs

1use ckb_types::{
2    core::DepType,
3    h256,
4    packed::{CellDep, OutPoint},
5    prelude::*,
6};
7
8use crate::{
9    core::TransactionBuilder, tx_builder::TxBuilderError, NetworkInfo, NetworkType, ScriptGroup,
10    ScriptId,
11};
12
13use super::{HandlerContext, ScriptHandler};
14
15/// sUDT script handler, it will setup the [Simple UDT](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0025-simple-udt/0025-simple-udt.md) related data automatically.
16pub struct SudtHandler {
17    cell_deps: Vec<CellDep>,
18    sudt_script_id: ScriptId,
19}
20
21pub struct SudtContext;
22
23impl HandlerContext for SudtContext {}
24
25impl SudtHandler {
26    pub fn new_with_network(network: &NetworkInfo) -> Result<Self, TxBuilderError> {
27        let (out_point, sudt_script_id) = if network.network_type == NetworkType::Mainnet {
28            (
29                OutPoint::new_builder()
30                    .tx_hash(
31                        h256!("0xc7813f6a415144643970c2e88e0bb6ca6a8edc5dd7c1022746f628284a9936d5")
32                            .pack(),
33                    )
34                    .index(0u32)
35                    .build(),
36                ScriptId::new_type(h256!(
37                    "0x5e7a36a77e68eecc013dfa2fe6a23f3b6c344b04005808694ae6dd45eea4cfd5"
38                )),
39            )
40        } else if network.network_type == NetworkType::Testnet {
41            (
42                OutPoint::new_builder()
43                    .tx_hash(
44                        h256!("0xe12877ebd2c3c364dc46c5c992bcfaf4fee33fa13eebdf82c591fc9825aab769")
45                            .pack(),
46                    )
47                    .index(0u32)
48                    .build(),
49                ScriptId::new_type(h256!(
50                    "0xc5e5dcf215925f7ef4dfaf5f4b4f105bc321c02776d6e7d52a1db3fcd9d011a4"
51                )),
52            )
53        } else {
54            return Err(TxBuilderError::UnsupportedNetworkType(network.network_type));
55        };
56
57        let cell_dep = CellDep::new_builder()
58            .out_point(out_point)
59            .dep_type(DepType::Code)
60            .build();
61
62        Ok(Self {
63            cell_deps: vec![cell_dep],
64            sudt_script_id,
65        })
66    }
67
68    pub fn new_with_customize(cell_deps: Vec<CellDep>, sudt_script_id: ScriptId) -> Self {
69        Self {
70            cell_deps,
71            sudt_script_id,
72        }
73    }
74}
75#[cfg_attr(target_arch="wasm32", async_trait::async_trait(?Send))]
76#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
77impl ScriptHandler for SudtHandler {
78    fn build_transaction(
79        &self,
80        tx_builder: &mut TransactionBuilder,
81        script_group: &mut ScriptGroup,
82        context: &dyn HandlerContext,
83    ) -> Result<bool, TxBuilderError> {
84        if context.as_any().is::<SudtContext>()
85            && ScriptId::from(&script_group.script) == self.sudt_script_id
86        {
87            tx_builder.dedup_cell_deps(self.cell_deps.clone());
88            if script_group.input_indices.is_empty() {
89                // issue sudt, do nothing
90                return Ok(true);
91            }
92        }
93        Ok(false)
94    }
95    #[cfg(not(target_arch = "wasm32"))]
96    fn init(&mut self, _network: &NetworkInfo) -> Result<(), TxBuilderError> {
97        Ok(())
98    }
99    async fn init_async(&mut self, _network: &NetworkInfo) -> Result<(), TxBuilderError> {
100        Ok(())
101    }
102}