-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathton_transfer.rs
More file actions
121 lines (106 loc) · 4.95 KB
/
ton_transfer.rs
File metadata and controls
121 lines (106 loc) · 4.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use anyhow::Ok;
#[cfg(feature = "tonlibjson")]
mod example {
use log::LevelFilter;
use log4rs::Config;
use log4rs::append::console::{ConsoleAppender, Target};
use log4rs::config::{Appender, Root};
use std::sync::Once;
use std::time::Duration;
use ton::block_tlb::{CommonMsgInfo, CurrencyCollection};
use ton::block_tlb::{CommonMsgInfoInt, Msg};
use ton::contracts::TonWalletMethods;
use ton::contracts::tl_provider::TLProvider;
use ton::contracts::{ContractClient, TonContract, TonWalletContract};
use ton::net_config::TonNetConfig;
use ton::sys_utils::sys_tonlib_set_verbosity_level;
use ton::tl_client::{LiteNodeFilter, RetryStrategy, TLClient, TLClientTrait};
use ton::ton_wallet::TonWallet;
use ton::ton_wallet::WalletVersion;
use ton_core::cell::TonCell;
use ton_core::traits::tlb::TLB;
use ton_core::types::tlb_core::TLBCoins;
use ton_core::types::tlb_core::{MsgAddress, TLBEitherRef};
// Transaction: https://testnet.tonviewer.com/transaction/3771a86dd5c5238ac93e7f125817379c7a9d1321c79b27ac5e6b2b2d34749af1
// How external and internal messages work: https://docs.ton.org/v3/guidelines/smart-contracts/howto/wallet#-external-and-internal-messages
/* Plan:
- Ton transfer (We will use ton_wallet v4)
- make an internal message with empty sell. It will signal that it is transfer
- make an correct external message, and put there an internal message
- send message to ton blockchain
*/
static LOG: Once = Once::new();
fn init_logging() {
LOG.call_once(|| {
let stderr = ConsoleAppender::builder()
.target(Target::Stderr)
.encoder(Box::new(log4rs::encode::pattern::PatternEncoder::new(
"{d(%Y-%m-%d %H:%M:%S%.6f)} {T:>15.15} {h({l:>5.5})} {t}:{L} - {m}{n}",
)))
.build();
let config = Config::builder()
.appender(Appender::builder().build("stderr", Box::new(stderr)))
.build(Root::builder().appender("stderr").build(LevelFilter::Info))
.unwrap();
log4rs::init_config(config).unwrap();
})
}
async fn make_tl_client(mainnet: bool, archive_only: bool) -> anyhow::Result<TLClient> {
init_logging();
log::info!("Initializing tl_client with mainnet={mainnet}, archive_only={archive_only}...");
let client = TLClient::builder()?
.with_net_config(&TonNetConfig::new_default(mainnet)?)?
.with_connection_check(LiteNodeFilter::Archive)
.with_connections_count(10)
.with_retry_strategy(RetryStrategy {
retry_count: 10,
retry_waiting: Duration::from_millis(200),
})
.build()
.await?;
sys_tonlib_set_verbosity_level(0);
Ok(client)
}
pub async fn real_main() -> anyhow::Result<()> {
// ---------- Wallet initialization ----------
let mnemonic = std::env::var("MNEMONIC_STR")?;
// To create w5 ton_wallet for testnet, use TonWallet::new_with_params with WALLET_V5R1_DEFAULT_ID_TESTNET wallet_id
let wallet = TonWallet::new_with_creds(WalletVersion::V4R2, &mnemonic, None)?;
// Make testnet contract_client
let tl_client = make_tl_client(false, false).await?;
let provider = TLProvider::new(tl_client.clone());
let ctr_cli = ContractClient::builder(provider)?.build()?;
// ---------- Building transfer_msg ----------
let transfer_msg = Msg {
info: CommonMsgInfo::Int(CommonMsgInfoInt {
ihr_disabled: false,
bounce: false,
bounced: false,
src: MsgAddress::NONE,
dst: wallet.address.to_msg_address(),
value: CurrencyCollection::from_num(&50010u128)?,
ihr_fee: TLBCoins::ZERO,
fwd_fee: TLBCoins::ZERO,
created_lt: 0,
created_at: 0,
}),
init: None,
body: TLBEitherRef::new(TonCell::empty().to_owned()),
};
let expired_at_time = std::time::SystemTime::now() + Duration::from_secs(600);
let expire_at = expired_at_time.duration_since(std::time::UNIX_EPOCH)?.as_secs() as u32;
// Get current ton_wallet seqno
let wallet_ctr = TonWalletContract::new(&ctr_cli, &wallet.address, None).await?;
let seqno = wallet_ctr.seqno().await?;
let ext_in_msg = wallet.create_ext_in_msg(vec![transfer_msg.to_cell()?], seqno, expire_at, false)?;
// Transaction: https://testnet.tonviewer.com/transaction/3771a86dd5c5238ac93e7f125817379c7a9d1321c79b27ac5e6b2b2d34749af1
let _msg_hash = tl_client.send_msg(ext_in_msg.to_boc()?).await?;
Ok(())
}
}
#[tokio::main(flavor = "current_thread")]
async fn main() -> anyhow::Result<()> {
#[cfg(feature = "tonlibjson")]
example::real_main().await?;
Ok(())
}