tonlib_core_anychain/message/
transfer.rs

1use std::sync::Arc;
2
3use super::{
4    CommonMsgInfo, ExternalIncomingMessage, ExternalOutgoingMessage, InternalMessage, TonMessage,
5    TonMessageError,
6};
7use crate::cell::{ArcCell, Cell, CellBuilder};
8
9#[derive(Clone, Debug, PartialEq)]
10pub struct TransferMessage {
11    pub common_msg_info: CommonMsgInfo,
12    pub state_init: Option<ArcCell>,
13    pub data: Option<ArcCell>,
14}
15
16impl TransferMessage {
17    pub fn new(common_msg_info: CommonMsgInfo) -> Self {
18        TransferMessage {
19            common_msg_info,
20            state_init: None,
21            data: None,
22        }
23    }
24
25    pub fn with_state_init(&mut self, state_init: Cell) -> &mut Self {
26        self.with_state_init_ref(&Arc::new(state_init))
27    }
28
29    pub fn with_state_init_ref(&mut self, state_init: &ArcCell) -> &mut Self {
30        self.state_init = Some(state_init.clone());
31        self
32    }
33
34    pub fn with_data(&mut self, data: ArcCell) -> &mut Self {
35        self.data = Some(data);
36        self
37    }
38}
39
40impl TonMessage for TransferMessage {
41    fn build(&self) -> Result<Cell, TonMessageError> {
42        let mut builder = CellBuilder::new();
43
44        match &self.common_msg_info {
45            CommonMsgInfo::InternalMessage(m) => {
46                builder.store_bit(false)?; // bit0 (is_external)
47                builder.store_bit(m.ihr_disabled)?; // ihr_disabled
48                builder.store_bit(m.bounce)?; // bounce
49                builder.store_bit(m.bounced)?; // bounced
50                builder.store_address(&m.src)?; // src_addr
51                builder.store_address(&m.dest)?; // dest_addr
52                builder.store_coins(&m.value)?; // value
53                builder.store_bit(false)?; // currency_coll
54                builder.store_coins(&m.ihr_fee)?; // ihr_fees
55                builder.store_coins(&m.fwd_fee)?; // fwd_fees
56                builder.store_u64(64, m.created_lt)?; // created_lt
57                builder.store_u32(32, m.created_at)?; // created_at
58            }
59            CommonMsgInfo::ExternalIncomingMessage(m) => {
60                builder.store_bit(true)?; // bit0 (is_external)
61                builder.store_bit(false)?; // bit0 (is_outgoing)
62                builder.store_address(&m.src)?;
63                builder.store_address(&m.dest)?;
64                builder.store_coins(&m.import_fee)?;
65            }
66            CommonMsgInfo::ExternalOutgoingMessage(m) => {
67                builder.store_bit(true)?; // bit0 (is_external)
68                builder.store_bit(true)?; // bit0 (is_outgoing)
69                builder.store_address(&m.src)?;
70                builder.store_address(&m.dest)?;
71                builder.store_u64(64, m.created_lt)?; // created_lt
72                builder.store_u32(32, m.created_at)?; // created_at
73            }
74        }
75        builder.store_maybe_cell_ref(&self.state_init)?;
76
77        builder.store_maybe_cell_ref(&self.data)?;
78
79        Ok(builder.build()?)
80    }
81
82    fn parse(cell: &Cell) -> Result<Self, TonMessageError> {
83        let mut parser = cell.parser();
84        //   TODO: Review structure of transfer message
85        let bit0 = parser.load_bit()?;
86
87        // internal message
88        let common_msg_info = if !bit0 {
89            let ihr_disabled = parser.load_bit()?;
90            let bounce = parser.load_bit()?;
91            let bounced = parser.load_bit()?;
92            let src = parser.load_address()?;
93            let dest = parser.load_address()?;
94            let value = parser.load_coins()?;
95            let ihr_fee = parser.load_coins()?;
96            let fwd_fee = parser.load_coins()?;
97            let created_lt = parser.load_u64(64)?;
98            let created_at = parser.load_u32(32)?;
99
100            CommonMsgInfo::InternalMessage(InternalMessage {
101                ihr_disabled,
102                bounce,
103                bounced,
104                src,
105                dest,
106                value,
107                ihr_fee,
108                fwd_fee,
109                created_lt,
110                created_at,
111            })
112        } else {
113            let bit1 = parser.load_bit()?;
114
115            if !bit1 {
116                let src = parser.load_address()?;
117                let dest = parser.load_address()?;
118                let import_fee = parser.load_coins()?;
119
120                CommonMsgInfo::ExternalIncomingMessage(ExternalIncomingMessage {
121                    src,
122                    dest,
123                    import_fee,
124                })
125            } else {
126                let src = parser.load_address()?;
127                let dest = parser.load_address()?;
128
129                let created_lt = parser.load_u64(64)?;
130                let created_at = parser.load_u32(32)?;
131
132                CommonMsgInfo::ExternalOutgoingMessage(ExternalOutgoingMessage {
133                    src,
134                    dest,
135                    created_lt,
136                    created_at,
137                })
138            }
139        };
140        let state_init = parser.load_maybe_cell_ref()?;
141        let data = parser.load_maybe_cell_ref()?;
142
143        parser.ensure_empty()?;
144
145        Ok(TransferMessage {
146            common_msg_info,
147            state_init,
148            data,
149        })
150    }
151}