tonlib_core/wallet/versioned/
v4.rs1use crate::cell::{ArcCell, CellBuilder, CellParser, TonCellError};
2use crate::tlb_types::primitives::reference::Ref;
3use crate::tlb_types::tlb::TLB;
4use crate::types::TonHash;
5use crate::wallet::versioned::utils::write_up_to_4_msgs;
6
7#[derive(Debug, PartialEq, Clone)]
9pub struct WalletDataV4 {
10 pub seqno: u32,
11 pub wallet_id: i32,
12 pub public_key: TonHash,
13 pub plugins: Option<Ref<ArcCell>>,
14}
15
16#[derive(Debug, PartialEq, Clone)]
19pub struct WalletExtMsgBodyV4 {
20 pub subwallet_id: i32,
21 pub valid_until: u32,
22 pub msg_seqno: u32,
23 pub opcode: u32,
24 pub msgs_modes: Vec<u8>,
25 pub msgs: Vec<ArcCell>,
26}
27
28impl WalletDataV4 {
29 pub fn new(wallet_id: i32, public_key: TonHash) -> Self {
30 Self {
31 seqno: 0,
32 wallet_id,
33 public_key,
34 plugins: None,
35 }
36 }
37}
38
39impl TLB for WalletDataV4 {
40 fn read_definition(parser: &mut CellParser) -> Result<Self, TonCellError> {
41 Ok(Self {
42 seqno: parser.load_u32(32)?,
43 wallet_id: parser.load_i32(32)?,
44 public_key: parser.load_tonhash()?,
45 plugins: TLB::read(parser)?,
46 })
47 }
48
49 fn write_definition(&self, dst: &mut CellBuilder) -> Result<(), TonCellError> {
50 dst.store_u32(32, self.seqno)?;
51 dst.store_i32(32, self.wallet_id)?;
52 dst.store_tonhash(&self.public_key)?;
53 self.plugins.write(dst)?;
54 Ok(())
55 }
56}
57
58impl TLB for WalletExtMsgBodyV4 {
59 fn read_definition(parser: &mut CellParser) -> Result<Self, TonCellError> {
60 let subwallet_id = parser.load_i32(32)?;
61 let valid_until = parser.load_u32(32)?;
62 let msg_seqno = parser.load_u32(32)?;
63 let opcode = parser.load_u32(8)?;
64 if opcode != 0 {
65 let err_str = format!("Unsupported opcode: {opcode}");
66 return Err(TonCellError::InternalError(err_str));
67 }
68
69 let msgs_cnt = parser.cell.references().len();
70 let mut msgs_modes = Vec::with_capacity(msgs_cnt);
71 let mut msgs = Vec::with_capacity(msgs_cnt);
72 for _ in 0..msgs_cnt {
73 msgs_modes.push(parser.load_u8(8)?);
74 msgs.push(parser.next_reference()?);
75 }
76 Ok(Self {
77 subwallet_id,
78 valid_until,
79 msg_seqno,
80 opcode,
81 msgs_modes,
82 msgs,
83 })
84 }
85
86 fn write_definition(&self, dst: &mut CellBuilder) -> Result<(), TonCellError> {
87 if self.opcode != 0 {
88 let err_str = format!("Unsupported opcode: {}", self.opcode);
89 return Err(TonCellError::InternalError(err_str));
90 }
91 dst.store_i32(32, self.subwallet_id)?;
92 dst.store_u32(32, self.valid_until)?;
93 dst.store_u32(32, self.msg_seqno)?;
94 dst.store_u32(8, self.opcode)?;
95 write_up_to_4_msgs(dst, &self.msgs, &self.msgs_modes)?;
96 Ok(())
97 }
98}
99
100#[cfg(test)]
101mod test {
102 use super::*;
103 use crate::cell::Cell;
104 use crate::tlb_types::tlb::TLB;
105 use crate::wallet::versioned::DEFAULT_WALLET_ID;
106
107 #[test]
108 fn test_wallet_data_v4() -> anyhow::Result<()> {
109 let src_boc_hex = "b5ee9c7241010101002b0000510000001429a9a317cbf377c9b73604c70bf73488ddceba14f763baef2ac70f68d1d6032a120149f440a6c9f37d";
111 let wallet_data = WalletDataV4::from_boc_hex(src_boc_hex)?;
112 assert_eq!(wallet_data.seqno, 20);
113 assert_eq!(wallet_data.wallet_id, DEFAULT_WALLET_ID);
114 assert_eq!(
115 wallet_data.public_key,
116 TonHash::from_hex("cbf377c9b73604c70bf73488ddceba14f763baef2ac70f68d1d6032a120149f4")?
117 );
118 assert_eq!(wallet_data.plugins, None);
119
120 let serial_boc_hex = wallet_data.to_boc_hex(false)?;
121 let restored = WalletDataV4::from_boc_hex(&serial_boc_hex)?;
122 assert_eq!(wallet_data, restored);
123 Ok(())
124 }
125
126 #[test]
127 fn test_wallet_ext_msg_body_v4() -> anyhow::Result<()> {
128 let body_signed_cell = Cell::from_boc_hex("b5ee9c7201010201008700019c9dcd3a68926ad6fb9d094c5b72901bfc359ada50f22b648c6c2223c767135d397c7489c121071e45a5316a94a533d80c41450049ebeed406c419fea99117f40629a9a31767ad328900000013000301006842007847b4630eb08d9f486fe846d5496878556dfd5a084f82a9a3fb01224e67c84c200989680000000000000000000000000000")?;
130 let mut parser = body_signed_cell.parser();
131 parser.load_bytes(64)?; let body_cell = Cell::read(&mut parser)?;
133
134 let body = WalletExtMsgBodyV4::from_cell(&body_cell)?;
135 assert_eq!(body.subwallet_id, DEFAULT_WALLET_ID);
136 assert_eq!(body.valid_until, 1739403913);
137 assert_eq!(body.msg_seqno, 19);
138 assert_eq!(body.opcode, 0);
139 assert_eq!(body.msgs_modes, vec![3]);
140 assert_eq!(body.msgs.len(), 1);
141
142 let serial_cell = body.to_cell()?;
143 assert_eq!(body_cell, serial_cell);
144 Ok(())
145 }
146}