tonlib_core/message/sbt/
request_owner.rs

1use num_bigint::BigUint;
2
3use super::SBT_REQUEST_OWNER;
4use crate::cell::{ArcCell, Cell, CellBuilder, EMPTY_ARC_CELL};
5use crate::message::{HasOpcode, TonMessage, TonMessageError, WithForwardPayload};
6use crate::TonAddress;
7
8/// Creates a body for sbt request owner according to TL-B schema:
9///
10/// ```raw
11/// request_owner#d0c3bfea
12///   query_id:uint64
13///   dest:MsgAddress
14///   forward_payload:^Cell
15///   with_content:Bool
16/// = InternalMsgBody;
17/// ```
18#[derive(Clone, Debug, PartialEq)]
19pub struct RequestOwnerMessage {
20    /// arbitrary request number.
21    pub query_id: u64,
22    /// address of the contract to which the ownership of SBT should be proven.    pub dest: TonAddress,
23    pub dest: TonAddress,
24    /// arbitrary data required by target contract.
25    pub forward_payload: ArcCell,
26    /// if true, SBT's content cell will be included in message to contract.
27    pub with_content: bool,
28}
29
30impl RequestOwnerMessage {
31    pub fn new(dest: &TonAddress, with_content: bool) -> Self {
32        RequestOwnerMessage {
33            query_id: 0,
34            dest: dest.clone(),
35            forward_payload: EMPTY_ARC_CELL.clone(),
36            with_content,
37        }
38    }
39}
40
41impl TonMessage for RequestOwnerMessage {
42    fn build(&self) -> Result<Cell, TonMessageError> {
43        let mut builder = CellBuilder::new();
44        builder.store_u32(32, Self::opcode())?;
45        builder.store_u64(64, self.query_id)?;
46        builder.store_address(&self.dest)?;
47        builder.store_reference(&self.forward_payload)?;
48        builder.store_bit(self.with_content)?;
49        Ok(builder.build()?)
50    }
51
52    fn parse(cell: &Cell) -> Result<Self, TonMessageError> {
53        let mut parser = cell.parser();
54
55        let opcode: u32 = parser.load_u32(32)?;
56        let query_id = parser.load_u64(64)?;
57        let dest = parser.load_address()?;
58        let forward_payload = parser.next_reference()?;
59        let with_content = parser.load_bit()?;
60        parser.ensure_empty()?;
61
62        let result = RequestOwnerMessage {
63            query_id,
64            dest,
65            forward_payload,
66            with_content,
67        };
68        result.verify_opcode(opcode)?;
69        Ok(result)
70    }
71}
72
73impl WithForwardPayload for RequestOwnerMessage {
74    fn set_forward_payload(&mut self, forward_payload: ArcCell, _forward_ton_amount: BigUint) {
75        self.forward_payload = forward_payload;
76    }
77}
78
79impl HasOpcode for RequestOwnerMessage {
80    fn set_query_id(&mut self, query_id: u64) {
81        self.query_id = query_id;
82    }
83
84    fn query_id(&self) -> u64 {
85        self.query_id
86    }
87
88    fn opcode() -> u32 {
89        SBT_REQUEST_OWNER
90    }
91}
92
93#[cfg(test)]
94mod tests {
95
96    use std::sync::Arc;
97
98    use num_bigint::BigUint;
99    use num_traits::Zero;
100
101    use crate::cell::{ArcCell, CellBuilder};
102    use crate::message::{HasOpcode, RequestOwnerMessage, TonMessage, WithForwardPayload};
103    use crate::TonAddress;
104
105    #[test]
106    fn sbt_request_ownership_msg_test() {
107        let query_id = 1234567890;
108
109        let dest = &TonAddress::from_base64_url("EQAW42HutyDem98Be1f27PoXobghh81umTQ-cGgaKVmRLS7-")
110            .unwrap();
111
112        let forward_payload: ArcCell = Arc::new(
113            CellBuilder::new()
114                .store_u32(12, 123)
115                .unwrap()
116                .build()
117                .unwrap(),
118        );
119
120        let expected = RequestOwnerMessage {
121            query_id,
122            dest: dest.clone(),
123            forward_payload: forward_payload.clone(),
124            with_content: true,
125        };
126
127        let build_result = RequestOwnerMessage::new(dest, true)
128            .with_forward_payload(BigUint::zero(), forward_payload)
129            .with_query_id(query_id)
130            .build();
131        assert!(build_result.is_ok());
132
133        let cell = build_result.unwrap();
134        let parse_result = RequestOwnerMessage::parse(&cell);
135        assert!(parse_result.is_ok());
136
137        let parsed_msg = parse_result.unwrap();
138        assert_eq!(expected, parsed_msg);
139    }
140}