tonlib_core/wallet/
version_helper.rs1use super::wallet_code::WALLET_VERSION_BY_CODE;
2use crate::cell::{ArcCell, Cell, CellBuilder, TonCellError};
3use crate::tlb_types::tlb::TLB;
4use crate::wallet::mnemonic::KeyPair;
5use crate::wallet::versioned::highload_v2::WalletDataHighloadV2R2;
6use crate::wallet::versioned::v1_v2::{WalletDataV1V2, WalletExtMsgBodyV2};
7use crate::wallet::versioned::v3::{WalletDataV3, WalletExtMsgBodyV3};
8use crate::wallet::versioned::v4::{WalletDataV4, WalletExtMsgBodyV4};
9use crate::wallet::versioned::v5::{WalletDataV5, WalletExtMsgBodyV5};
10use crate::wallet::wallet_code::WALLET_CODE_BY_VERSION;
11use crate::wallet::wallet_version::WalletVersion;
12use crate::TonHash;
13
14pub struct VersionHelper;
15
16impl VersionHelper {
17 pub fn get_data(
18 version: WalletVersion,
19 key_pair: &KeyPair,
20 wallet_id: i32,
21 ) -> Result<Cell, TonCellError> {
22 let public_key = TonHash::try_from(key_pair.public_key.as_slice())?;
23 let data_cell = match version {
24 WalletVersion::V1R1
25 | WalletVersion::V1R2
26 | WalletVersion::V1R3
27 | WalletVersion::V2R1
28 | WalletVersion::V2R2 => WalletDataV1V2::new(public_key).to_cell()?,
29 WalletVersion::V3R1 | WalletVersion::V3R2 => {
30 WalletDataV3::new(wallet_id, public_key).to_cell()?
31 }
32 WalletVersion::V4R1 | WalletVersion::V4R2 => {
33 WalletDataV4::new(wallet_id, public_key).to_cell()?
34 }
35 WalletVersion::V5R1 => WalletDataV5::new(wallet_id, public_key).to_cell()?,
36 WalletVersion::HighloadV2R2 => {
37 WalletDataHighloadV2R2::new(wallet_id, public_key).to_cell()?
38 }
39 WalletVersion::HighloadV1R1
40 | WalletVersion::HighloadV1R2
41 | WalletVersion::HighloadV2
42 | WalletVersion::HighloadV2R1 => {
43 let err_str = format!("initial_data for {version:?} is unsupported");
44 return Err(TonCellError::InternalError(err_str));
45 }
46 };
47 Ok(data_cell)
48 }
49
50 pub fn get_code(version: WalletVersion) -> Result<&'static ArcCell, TonCellError> {
51 WALLET_CODE_BY_VERSION.get(&version).ok_or_else(|| {
52 let err_str = format!("No code found for {version:?}");
53 TonCellError::InternalError(err_str)
54 })
55 }
56
57 pub fn get_version(code_hash: &TonHash) -> Result<&WalletVersion, TonCellError> {
58 WALLET_VERSION_BY_CODE
59 .get(code_hash)
60 .ok_or_else(|| TonCellError::InternalError("No wallet version found".to_string()))
61 }
62
63 pub fn build_ext_msg<T: AsRef<[ArcCell]>>(
64 version: WalletVersion,
65 valid_until: u32,
66 msg_seqno: u32,
67 wallet_id: i32,
68 msgs_refs: T,
69 ) -> Result<Cell, TonCellError> {
70 let msgs: Vec<ArcCell> = msgs_refs.as_ref().to_vec();
71
72 match version {
73 WalletVersion::V2R1 | WalletVersion::V2R2 => WalletExtMsgBodyV2 {
74 msg_seqno,
75 valid_until,
76 msgs_modes: vec![3u8; msgs.len()],
77 msgs,
78 }
79 .to_cell(),
80 WalletVersion::V3R1 | WalletVersion::V3R2 => WalletExtMsgBodyV3 {
81 subwallet_id: wallet_id,
82 msg_seqno,
83 valid_until,
84 msgs_modes: vec![3u8; msgs.len()],
85 msgs,
86 }
87 .to_cell(),
88 WalletVersion::V4R1 | WalletVersion::V4R2 => WalletExtMsgBodyV4 {
89 subwallet_id: wallet_id,
90 valid_until,
91 msg_seqno,
92 opcode: 0,
93 msgs_modes: vec![3u8; msgs.len()],
94 msgs,
95 }
96 .to_cell(),
97 WalletVersion::V5R1 => WalletExtMsgBodyV5 {
98 wallet_id,
99 valid_until,
100 msg_seqno,
101 msgs_modes: vec![3u8; msgs.len()],
102 msgs,
103 }
104 .to_cell(),
105 _ => {
106 let err_str = format!("build_ext_msg for {version:?} is unsupported");
107 Err(TonCellError::InternalError(err_str))
108 }
109 }
110 }
111
112 pub fn sign_msg(
113 version: WalletVersion,
114 msg_cell: &Cell,
115 sign: &[u8],
116 ) -> Result<Cell, TonCellError> {
117 let signed_cell = match version {
118 WalletVersion::V5R1 => {
120 let mut builder = CellBuilder::new();
121 builder.store_cell(msg_cell)?;
122 builder.store_slice(sign)?;
123 builder.build()?
124 }
125 _ => {
126 let mut builder = CellBuilder::new();
127 builder.store_slice(sign)?;
128 builder.store_cell(msg_cell)?;
129 builder.build()?
130 }
131 };
132 Ok(signed_cell)
133 }
134}