2
2
using Microsoft . Extensions . Hosting ;
3
3
using Microsoft . Extensions . Logging ;
4
4
using TonLibDotNet . Types ;
5
+ using TonLibDotNet . Types . Wallet ;
5
6
6
7
namespace TonLibDotNet
7
8
{
8
9
public static class Program
9
10
{
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
+
10
22
public static async Task Main ( string [ ] args )
11
23
{
12
24
var builder = Host . CreateDefaultBuilder ( args ) ;
13
25
14
- ////builder.ConfigureLogging(o => o.AddSystemdConsole());
15
26
builder . UseConsoleLifetime ( ) ;
16
27
builder . ConfigureServices ( ( context , services ) =>
17
28
{
18
29
services . Configure < TonOptions > ( o =>
19
30
{
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
22
33
o . VerbosityLevel = 0 ;
23
- o . Options . KeystoreType = new KeyStoreTypeDirectory ( "D:/Temp/keys" ) ;
34
+ o . Options . KeystoreType = new KeyStoreTypeDirectory ( DirectoryForKeys ) ;
24
35
} ) ;
25
36
services . AddSingleton < ITonClient , TonClient > ( ) ;
26
37
} ) ;
@@ -39,6 +50,21 @@ public static async Task Main(string[] args)
39
50
var mi = await tonClient . GetMasterchainInfo ( ) ;
40
51
logger . LogInformation ( "Last block: shard = {Shard}, seqno = {Seqno}" , mi . Last . Shard , mi . Last . Seqno ) ;
41
52
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
+ {
42
68
var account = "EQCJTkhd1W2wztkVNp_dsKBpv2SIoUWoIyzI7mQrbSrj_NSh" ; // TON Diamonds
43
69
44
70
var uaa = await tonClient . UnpackAccountAddress ( account ) ;
@@ -62,17 +88,12 @@ public static async Task Main(string[] args)
62
88
logger . LogInformation ( "TX {Id}: {Value} to {Address}" , item . TransactionId . Hash , item . OutMsgs [ 0 ] . Value , item . OutMsgs [ 0 ] . Destination . Value ) ;
63
89
}
64
90
}
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 ) ) ;
72
91
}
73
92
74
93
private static async Task RunKeyDemo ( ITonClient tonClient )
75
94
{
95
+ var hints = await tonClient . GetBip39Hints ( "zo" ) ;
96
+
76
97
// some "random" bytes
77
98
var localPass = Convert . ToBase64String ( new byte [ ] { 1 , 2 , 3 , 4 , 5 } ) ;
78
99
var mnemonicPass = Convert . ToBase64String ( new byte [ ] { 19 , 42 , 148 } ) ;
@@ -104,5 +125,50 @@ private static async Task RunKeyDemo(ITonClient tonClient)
104
125
105
126
await tonClient . DeleteAllKeys ( ) ;
106
127
}
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
+ }
107
173
}
108
174
}
0 commit comments