Skip to content

Commit

Permalink
Demo for sending coins scenario
Browse files Browse the repository at this point in the history
  • Loading branch information
justdmitry committed Mar 7, 2023
1 parent 50b3ede commit df8dc26
Showing 1 changed file with 77 additions and 11 deletions.
88 changes: 77 additions & 11 deletions TonLibDotNet.Demo/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,36 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using TonLibDotNet.Types;
using TonLibDotNet.Types.Wallet;

namespace TonLibDotNet
{
public static class Program
{
private const string DirectoryForKeys = "D:/Temp/keys";

// You need mnemonic and address for actual account with some coins to test sending.
// Double check that you are using testnet!!!
private const string TestnetAccountToSendFromAddress = "EQAkEWzRLi1sw9AlaGDDzPvk2_F20hjpTjlvsjQqYawVmdT0";
private static readonly string[] TestnetAccountToSendFromMnemonic = new[]
{
"word1", "word2", "word3", "word4", "word5", "word6", "word7", "word8", "word9", "word10", "word11", "word12",
"word13", "word14", "word15", "word16", "word17", "word18", "word19", "word20", "word21", "word22", "word23", "word24",
};

public static async Task Main(string[] args)
{
var builder = Host.CreateDefaultBuilder(args);

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

await RunAssortDemo(tonClient, logger);

await RunKeyDemo(tonClient);

if (TestnetAccountToSendFromMnemonic[0] != "word1")
{
await RunSendDemo(tonClient, logger, TestnetAccountToSendFromAddress, TestnetAccountToSendFromMnemonic);
}

// Loggers need some time to flush data to screen/console.
await Task.Delay(TimeSpan.FromSeconds(1));
}

private static async Task RunAssortDemo(ITonClient tonClient, ILogger logger)
{
var account = "EQCJTkhd1W2wztkVNp_dsKBpv2SIoUWoIyzI7mQrbSrj_NSh"; // TON Diamonds

var uaa = await tonClient.UnpackAccountAddress(account);
Expand All @@ -62,17 +88,12 @@ public static async Task Main(string[] args)
logger.LogInformation("TX {Id}: {Value} to {Address}", item.TransactionId.Hash, item.OutMsgs[0].Value, item.OutMsgs[0].Destination.Value);
}
}

var hints = await tonClient.GetBip39Hints("zo");

await RunKeyDemo(tonClient);

// Loggers need some time to flush data to screen/console.
await Task.Delay(TimeSpan.FromSeconds(1));
}

private static async Task RunKeyDemo(ITonClient tonClient)
{
var hints = await tonClient.GetBip39Hints("zo");

// some "random" bytes
var localPass = Convert.ToBase64String(new byte[] { 1, 2, 3, 4, 5 });
var mnemonicPass = Convert.ToBase64String(new byte[] { 19, 42, 148 });
Expand Down Expand Up @@ -104,5 +125,50 @@ private static async Task RunKeyDemo(ITonClient tonClient)

await tonClient.DeleteAllKeys();
}

private static async Task RunSendDemo(ITonClient tonClient, ILogger logger, string validAddress, string[] mnemonic)
{
/*
* See https://ton.org/docs/develop/dapps/asset-processing/#deploying-wallet
* and https://ton.org/docs/develop/dapps/asset-processing/#sending-payments
*/

// Step 1: Import key and find your address

// Docs says you should use value from network config.
var walletId = tonClient.OptionsInfo.ConfigInfo.DefaultWalletId;

// Surprise! Even for testnet, wallet.ton.org uses mainnet value :(
walletId = 698983191;

var inputKey = await tonClient.ImportKey(new ExportedKey(mnemonic.ToList()));
var initialAccountState = new V3InitialAccountState() { PublicKey = inputKey.PublicKey, WalletId = walletId };
var address = await tonClient.GetAccountAddress(initialAccountState, 0, 0);
logger.LogDebug("Verifying addresses: expected '{Valid}', got '{Actual}'", validAddress, address.Value);
if (validAddress != address.Value)
{
logger.LogError("Address mismatch. Aborting.");
return;
}

// Step 2: Build message and action
var msg = new Types.Msg.Message(new AccountAddress(validAddress))
{
Data = new Types.Msg.DataText(tonClient.EncodeStringAsBase64("Sent using https://github.com/justdmitry/TonLib.NET")),
Amount = tonClient.ConvertToNanoTon(0.01M),
SendMode = 1,
};

var action = new Types.ActionMsg(new List<Types.Msg.Message>() { msg }) { AllowSendToUninited = true };

// Step 3: create query and send it
var query = await tonClient.CreateQuery(new InputKeyRegular(inputKey), address, action, TimeSpan.FromMinutes(1), initialAccountState: initialAccountState);

// wanna know fees before sending?
var fees = await tonClient.QueryEstimateFees(query.Id);

// Send it to network. You dont have TX id or something in respnse - just poll getTransactions() for your account and wait for new TX.
_ = await tonClient.QuerySend(query.Id);
}
}
}

0 comments on commit df8dc26

Please sign in to comment.