Skip to content

Commit df8dc26

Browse files
committed
Demo for sending coins scenario
1 parent 50b3ede commit df8dc26

File tree

1 file changed

+77
-11
lines changed

1 file changed

+77
-11
lines changed

TonLibDotNet.Demo/Program.cs

Lines changed: 77 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,36 @@
22
using Microsoft.Extensions.Hosting;
33
using Microsoft.Extensions.Logging;
44
using TonLibDotNet.Types;
5+
using TonLibDotNet.Types.Wallet;
56

67
namespace TonLibDotNet
78
{
89
public static class Program
910
{
11+
private const string DirectoryForKeys = "D:/Temp/keys";
12+
13+
// You need mnemonic and address for actual account with some coins to test sending.
14+
// Double check that you are using testnet!!!
15+
private const string TestnetAccountToSendFromAddress = "EQAkEWzRLi1sw9AlaGDDzPvk2_F20hjpTjlvsjQqYawVmdT0";
16+
private static readonly string[] TestnetAccountToSendFromMnemonic = new[]
17+
{
18+
"word1", "word2", "word3", "word4", "word5", "word6", "word7", "word8", "word9", "word10", "word11", "word12",
19+
"word13", "word14", "word15", "word16", "word17", "word18", "word19", "word20", "word21", "word22", "word23", "word24",
20+
};
21+
1022
public static async Task Main(string[] args)
1123
{
1224
var builder = Host.CreateDefaultBuilder(args);
1325

14-
////builder.ConfigureLogging(o => o.AddSystemdConsole());
1526
builder.UseConsoleLifetime();
1627
builder.ConfigureServices((context, services) =>
1728
{
1829
services.Configure<TonOptions>(o =>
1930
{
20-
o.UseMainnet = true;
21-
o.LogTextLimit = 0;
31+
o.UseMainnet = false; // also replace tonlibjson.dll !
32+
o.LogTextLimit = 500; // Set to 0 to see full requests/responses
2233
o.VerbosityLevel = 0;
23-
o.Options.KeystoreType = new KeyStoreTypeDirectory("D:/Temp/keys");
34+
o.Options.KeystoreType = new KeyStoreTypeDirectory(DirectoryForKeys);
2435
});
2536
services.AddSingleton<ITonClient, TonClient>();
2637
});
@@ -39,6 +50,21 @@ public static async Task Main(string[] args)
3950
var mi = await tonClient.GetMasterchainInfo();
4051
logger.LogInformation("Last block: shard = {Shard}, seqno = {Seqno}", mi.Last.Shard, mi.Last.Seqno);
4152

53+
await RunAssortDemo(tonClient, logger);
54+
55+
await RunKeyDemo(tonClient);
56+
57+
if (TestnetAccountToSendFromMnemonic[0] != "word1")
58+
{
59+
await RunSendDemo(tonClient, logger, TestnetAccountToSendFromAddress, TestnetAccountToSendFromMnemonic);
60+
}
61+
62+
// Loggers need some time to flush data to screen/console.
63+
await Task.Delay(TimeSpan.FromSeconds(1));
64+
}
65+
66+
private static async Task RunAssortDemo(ITonClient tonClient, ILogger logger)
67+
{
4268
var account = "EQCJTkhd1W2wztkVNp_dsKBpv2SIoUWoIyzI7mQrbSrj_NSh"; // TON Diamonds
4369

4470
var uaa = await tonClient.UnpackAccountAddress(account);
@@ -62,17 +88,12 @@ public static async Task Main(string[] args)
6288
logger.LogInformation("TX {Id}: {Value} to {Address}", item.TransactionId.Hash, item.OutMsgs[0].Value, item.OutMsgs[0].Destination.Value);
6389
}
6490
}
65-
66-
var hints = await tonClient.GetBip39Hints("zo");
67-
68-
await RunKeyDemo(tonClient);
69-
70-
// Loggers need some time to flush data to screen/console.
71-
await Task.Delay(TimeSpan.FromSeconds(1));
7291
}
7392

7493
private static async Task RunKeyDemo(ITonClient tonClient)
7594
{
95+
var hints = await tonClient.GetBip39Hints("zo");
96+
7697
// some "random" bytes
7798
var localPass = Convert.ToBase64String(new byte[] { 1, 2, 3, 4, 5 });
7899
var mnemonicPass = Convert.ToBase64String(new byte[] { 19, 42, 148 });
@@ -104,5 +125,50 @@ private static async Task RunKeyDemo(ITonClient tonClient)
104125

105126
await tonClient.DeleteAllKeys();
106127
}
128+
129+
private static async Task RunSendDemo(ITonClient tonClient, ILogger logger, string validAddress, string[] mnemonic)
130+
{
131+
/*
132+
* See https://ton.org/docs/develop/dapps/asset-processing/#deploying-wallet
133+
* and https://ton.org/docs/develop/dapps/asset-processing/#sending-payments
134+
*/
135+
136+
// Step 1: Import key and find your address
137+
138+
// Docs says you should use value from network config.
139+
var walletId = tonClient.OptionsInfo.ConfigInfo.DefaultWalletId;
140+
141+
// Surprise! Even for testnet, wallet.ton.org uses mainnet value :(
142+
walletId = 698983191;
143+
144+
var inputKey = await tonClient.ImportKey(new ExportedKey(mnemonic.ToList()));
145+
var initialAccountState = new V3InitialAccountState() { PublicKey = inputKey.PublicKey, WalletId = walletId };
146+
var address = await tonClient.GetAccountAddress(initialAccountState, 0, 0);
147+
logger.LogDebug("Verifying addresses: expected '{Valid}', got '{Actual}'", validAddress, address.Value);
148+
if (validAddress != address.Value)
149+
{
150+
logger.LogError("Address mismatch. Aborting.");
151+
return;
152+
}
153+
154+
// Step 2: Build message and action
155+
var msg = new Types.Msg.Message(new AccountAddress(validAddress))
156+
{
157+
Data = new Types.Msg.DataText(tonClient.EncodeStringAsBase64("Sent using https://github.com/justdmitry/TonLib.NET")),
158+
Amount = tonClient.ConvertToNanoTon(0.01M),
159+
SendMode = 1,
160+
};
161+
162+
var action = new Types.ActionMsg(new List<Types.Msg.Message>() { msg }) { AllowSendToUninited = true };
163+
164+
// Step 3: create query and send it
165+
var query = await tonClient.CreateQuery(new InputKeyRegular(inputKey), address, action, TimeSpan.FromMinutes(1), initialAccountState: initialAccountState);
166+
167+
// wanna know fees before sending?
168+
var fees = await tonClient.QueryEstimateFees(query.Id);
169+
170+
// Send it to network. You dont have TX id or something in respnse - just poll getTransactions() for your account and wait for new TX.
171+
_ = await tonClient.QuerySend(query.Id);
172+
}
107173
}
108174
}

0 commit comments

Comments
 (0)