@@ -22,7 +22,7 @@ use std::iter::repeat;
22
22
23
23
use clap:: Parser ;
24
24
use hedera:: {
25
- AccountBalanceQuery , AccountCreateTransaction , AccountId , Client , Hbar , PrivateKey , TokenAirdropTransaction , TokenAssociateTransaction , TokenCreateTransaction , TokenDeleteTransaction , TokenGrantKycTransaction , TokenMintTransaction , TokenWipeTransaction , TransferTransaction
25
+ AccountBalanceQuery , AccountCreateTransaction , AccountId , Client , Hbar , PrivateKey , TokenAirdropTransaction , TokenCancelAirdropTransaction , TokenClaimAirdropTransaction , TokenCreateTransaction , TokenMintTransaction , TokenRejectTransaction
26
26
} ;
27
27
use time:: { Duration , OffsetDateTime } ;
28
28
@@ -50,8 +50,8 @@ async fn main() -> anyhow::Result<()> {
50
50
let client = Client :: for_name ( & hedera_network) ?;
51
51
52
52
client. set_operator ( operator_account_id, operator_key. clone ( ) ) ;
53
- let private_key_1 = PrivateKey :: generate_ed25519 ( ) ;
54
- let alice = AccountCreateTransaction :: new ( )
53
+ let private_key_1 = PrivateKey :: generate_ecdsa ( ) ;
54
+ let alice_id = AccountCreateTransaction :: new ( )
55
55
. key ( private_key_1. public_key ( ) )
56
56
. initial_balance ( Hbar :: new ( 10 ) )
57
57
. max_automatic_token_associations ( -1 )
@@ -62,8 +62,8 @@ async fn main() -> anyhow::Result<()> {
62
62
. account_id
63
63
. unwrap ( ) ;
64
64
65
- let private_key_2 = PrivateKey :: generate_ed25519 ( ) ;
66
- let bob = AccountCreateTransaction :: new ( )
65
+ let private_key_2 = PrivateKey :: generate_ecdsa ( ) ;
66
+ let bob_id = AccountCreateTransaction :: new ( )
67
67
. key ( private_key_2. public_key ( ) )
68
68
. max_automatic_token_associations ( 1 )
69
69
. execute ( & client)
@@ -73,8 +73,8 @@ async fn main() -> anyhow::Result<()> {
73
73
. account_id
74
74
. unwrap ( ) ;
75
75
76
- let private_key_3 = PrivateKey :: generate_ed25519 ( ) ;
77
- let carol = AccountCreateTransaction :: new ( )
76
+ let private_key_3 = PrivateKey :: generate_ecdsa ( ) ;
77
+ let carol_id = AccountCreateTransaction :: new ( )
78
78
. key ( private_key_3. public_key ( ) )
79
79
. max_automatic_token_associations ( 0 )
80
80
. execute ( & client)
@@ -84,7 +84,7 @@ async fn main() -> anyhow::Result<()> {
84
84
. account_id
85
85
. unwrap ( ) ;
86
86
87
- let treasury_key = PrivateKey :: generate_ed25519 ( ) ;
87
+ let treasury_key = PrivateKey :: generate_ecdsa ( ) ;
88
88
let treasury_account_id = AccountCreateTransaction :: new ( )
89
89
. key ( treasury_key. public_key ( ) )
90
90
. initial_balance ( Hbar :: new ( 10 ) )
@@ -124,7 +124,6 @@ async fn main() -> anyhow::Result<()> {
124
124
let nft_id = TokenCreateTransaction :: new ( )
125
125
. name ( "example NFT" )
126
126
. symbol ( "F" )
127
- . decimals ( 3 )
128
127
. max_supply ( 10 )
129
128
. treasury_account_id ( treasury_account_id)
130
129
. token_supply_type ( hedera:: TokenSupplyType :: Finite )
@@ -135,7 +134,7 @@ async fn main() -> anyhow::Result<()> {
135
134
. pause_key ( operator_key. clone ( ) . public_key ( ) )
136
135
. expiration_time ( OffsetDateTime :: now_utc ( ) + Duration :: hours ( 2 ) )
137
136
. freeze_with ( & client) ?
138
- . sign ( treasury_key)
137
+ . sign ( treasury_key. clone ( ) )
139
138
. execute ( & client)
140
139
. await ?
141
140
. get_receipt ( & client)
@@ -157,13 +156,15 @@ async fn main() -> anyhow::Result<()> {
157
156
*/
158
157
println ! ( "Airdropping tokens to all accounts" ) ;
159
158
160
- let airdrop_record = TokenAirdropTransaction :: new ( )
161
- . token_transfer ( token_id, alice , 10 )
159
+ let tx_record = TokenAirdropTransaction :: new ( )
160
+ . token_transfer ( token_id, alice_id , 10 )
162
161
. token_transfer ( token_id, treasury_account_id, -10 )
163
- . token_transfer ( token_id, bob , 10 )
162
+ . token_transfer ( token_id, bob_id , 10 )
164
163
. token_transfer ( token_id, treasury_account_id, -10 )
165
- . token_transfer ( token_id, carol , 10 )
164
+ . token_transfer ( token_id, carol_id , 10 )
166
165
. token_transfer ( token_id, treasury_account_id, -10 )
166
+ . freeze_with ( & client) ?
167
+ . sign ( treasury_key. clone ( ) )
167
168
. execute ( & client)
168
169
. await ?
169
170
. get_record ( & client)
@@ -175,29 +176,29 @@ async fn main() -> anyhow::Result<()> {
175
176
*/
176
177
println ! (
177
178
"Pending airdrop length: {}" ,
178
- airdrop_record . pending_airdrop_records. len( )
179
+ tx_record . pending_airdrop_records. len( )
179
180
) ;
180
181
println ! (
181
182
"Pending airdrops: {:?}" ,
182
- airdrop_record . pending_airdrop_records. get( 0 )
183
+ tx_record . pending_airdrop_records. get( 0 )
183
184
) ;
184
185
185
186
/*
186
187
* Step 5:
187
188
* Query to verify alice and bob received the airdrops and carol did not
188
189
*/
189
190
let alice_balance = AccountBalanceQuery :: new ( )
190
- . account_id ( alice )
191
+ . account_id ( alice_id )
191
192
. execute ( & client)
192
193
. await ?;
193
194
194
195
let bob_balance = AccountBalanceQuery :: new ( )
195
- . account_id ( bob )
196
+ . account_id ( bob_id )
196
197
. execute ( & client)
197
198
. await ?;
198
199
199
200
let carol_balance = AccountBalanceQuery :: new ( )
200
- . account_id ( carol )
201
+ . account_id ( carol_id )
201
202
. execute ( & client)
202
203
. await ?;
203
204
@@ -209,10 +210,258 @@ async fn main() -> anyhow::Result<()> {
209
210
"Bob ft balance after airdrop: {}" ,
210
211
bob_balance. tokens. get( & token_id) . unwrap( )
211
212
) ;
213
+ println ! (
214
+ "Carol ft balance after airdrop: {:?}" ,
215
+ carol_balance. tokens. get( & token_id)
216
+ ) ;
217
+
218
+ /*
219
+ * Step 6:
220
+ * Claim the airdrop for carol
221
+ */
222
+ println ! ( "Claiming ft with Carol" ) ;
223
+
224
+ _ = TokenClaimAirdropTransaction :: new ( )
225
+ . add_pending_airdrop_id (
226
+ tx_record
227
+ . pending_airdrop_records
228
+ . get ( 0 )
229
+ . unwrap ( )
230
+ . pending_airdrop_id ,
231
+ )
232
+ . freeze_with ( & client) ?
233
+ . sign ( private_key_3. clone ( ) )
234
+ . execute ( & client)
235
+ . await ?
236
+ . get_receipt ( & client)
237
+ . await ?;
238
+
239
+ let carol_balance = AccountBalanceQuery :: new ( )
240
+ . account_id ( carol_id)
241
+ . execute ( & client)
242
+ . await ?;
243
+
212
244
println ! (
213
245
"Carol ft balance after airdrop: {}" ,
214
246
carol_balance. tokens. get( & token_id) . unwrap( )
215
247
) ;
216
248
249
+ /*
250
+ * Step 7:
251
+ * Airdrop the NFTs to all three accounts
252
+ */
253
+ println ! ( "Airdropping nfts" ) ;
254
+ let tx_record = TokenAirdropTransaction :: new ( )
255
+ . nft_transfer ( nft_id. nft ( 1 ) , treasury_account_id, alice_id)
256
+ . nft_transfer ( nft_id. nft ( 2 ) , treasury_account_id, bob_id)
257
+ . nft_transfer ( nft_id. nft ( 3 ) , treasury_account_id, carol_id)
258
+ . freeze_with ( & client) ?
259
+ . sign ( treasury_key. clone ( ) )
260
+ . execute ( & client)
261
+ . await ?
262
+ . get_record ( & client)
263
+ . await ?;
264
+
265
+ /*
266
+ * Step 8:
267
+ * Get the transaction record and verify two pending airdrops (for bob & carol)
268
+ */
269
+ println ! (
270
+ "Pending airdrops length: {}" ,
271
+ tx_record. pending_airdrop_records. len( )
272
+ ) ;
273
+ println ! (
274
+ "Pending airdrops for Bob: {}" ,
275
+ tx_record. pending_airdrop_records. get( 0 ) . unwrap( )
276
+ ) ;
277
+ println ! (
278
+ "Pending airdrops for Carol: {}" ,
279
+ tx_record. pending_airdrop_records. get( 1 ) . unwrap( )
280
+ ) ;
281
+
282
+ /*
283
+ * Step 9:
284
+ * Query to verify alice received the airdrop and bob and carol did not
285
+ */
286
+ let alice_balance = AccountBalanceQuery :: new ( )
287
+ . account_id ( alice_id)
288
+ . execute ( & client)
289
+ . await ?;
290
+
291
+ let bob_balance = AccountBalanceQuery :: new ( )
292
+ . account_id ( bob_id)
293
+ . execute ( & client)
294
+ . await ?;
295
+
296
+ let carol_balance = AccountBalanceQuery :: new ( )
297
+ . account_id ( carol_id)
298
+ . execute ( & client)
299
+ . await ?;
300
+
301
+ println ! (
302
+ "Alice nft balance after airdrop: {}" ,
303
+ alice_balance. tokens. get( & nft_id) . unwrap( )
304
+ ) ;
305
+
306
+ println ! (
307
+ "Bob nft balance after airdrop: {:?}" ,
308
+ bob_balance. tokens. get( & nft_id)
309
+ ) ;
310
+
311
+ println ! (
312
+ "Carol nft balance after airdrop: {:?}" ,
313
+ carol_balance. tokens. get( & nft_id)
314
+ ) ;
315
+
316
+ /*
317
+ * Step 10:
318
+ * Claim the airdrop for bob
319
+ */
320
+ println ! ( "Claiming nft with Bob" ) ;
321
+ _ = TokenClaimAirdropTransaction :: new ( )
322
+ . add_pending_airdrop_id (
323
+ tx_record
324
+ . pending_airdrop_records
325
+ . get ( 0 )
326
+ . unwrap ( )
327
+ . pending_airdrop_id ,
328
+ )
329
+ . freeze_with ( & client) ?
330
+ . sign ( private_key_2. clone ( ) )
331
+ . execute ( & client)
332
+ . await ?
333
+ . get_receipt ( & client)
334
+ . await ?;
335
+
336
+ let bob_balance = AccountBalanceQuery :: new ( )
337
+ . account_id ( bob_id)
338
+ . execute ( & client)
339
+ . await ?;
340
+
341
+ println ! (
342
+ "Bob nft balance after claim: {}" ,
343
+ bob_balance. tokens. get( & nft_id) . unwrap( )
344
+ ) ;
345
+
346
+ /*
347
+ * Step 11:
348
+ * Cancel the airdrop for carol
349
+ */
350
+ println ! ( "Cancelling nft for Carol" ) ;
351
+
352
+ _ = TokenCancelAirdropTransaction :: new ( )
353
+ . add_pending_airdrop_id (
354
+ tx_record
355
+ . pending_airdrop_records
356
+ . get ( 1 )
357
+ . unwrap ( )
358
+ . pending_airdrop_id ,
359
+ )
360
+ . freeze_with ( & client) ?
361
+ . sign ( treasury_key. clone ( ) )
362
+ . execute ( & client)
363
+ . await ?
364
+ . get_receipt ( & client)
365
+ . await ?;
366
+
367
+ let carol_balance = AccountBalanceQuery :: new ( )
368
+ . account_id ( carol_id)
369
+ . execute ( & client)
370
+ . await ?;
371
+
372
+ println ! (
373
+ "Carol nft balance after cancel: {:?}" ,
374
+ carol_balance. tokens. get( & nft_id)
375
+ ) ;
376
+
377
+ /*
378
+ * Step 12:
379
+ * Reject the NFT for bob
380
+ */
381
+ println ! ( "Rejecting nft with Bob" ) ;
382
+
383
+ _ = TokenRejectTransaction :: new ( )
384
+ . owner ( bob_id)
385
+ . add_nft_id ( nft_id. nft ( 2 ) )
386
+ . freeze_with ( & client) ?
387
+ . sign ( private_key_2)
388
+ . execute ( & client)
389
+ . await ?
390
+ . get_receipt ( & client)
391
+ . await ?;
392
+
393
+ /*
394
+ * Step 13:
395
+ * Query to verify bob no longer has the NFT
396
+ */
397
+ let bob_balance = AccountBalanceQuery :: new ( )
398
+ . account_id ( bob_id)
399
+ . execute ( & client)
400
+ . await ?;
401
+
402
+ println ! (
403
+ "Bob nft balance after reject: {}" ,
404
+ bob_balance. tokens. get( & nft_id) . unwrap( )
405
+ ) ;
406
+
407
+ /*
408
+ * Step 13:
409
+ * Query to verify the NFT was returned to the Treasury
410
+ */
411
+ let treasury_balance = AccountBalanceQuery :: new ( )
412
+ . account_id ( treasury_account_id)
413
+ . execute ( & client)
414
+ . await ?;
415
+
416
+ println ! (
417
+ "Treasury nft balance after reject: {}" ,
418
+ treasury_balance. tokens. get( & nft_id) . unwrap( )
419
+ ) ;
420
+
421
+ /*
422
+ * Step 14:
423
+ * Reject the Fungible token for carol
424
+ */
425
+ println ! ( "Rejecting ft with Carol" ) ;
426
+
427
+ _ = TokenRejectTransaction :: new ( )
428
+ . owner ( carol_id)
429
+ . add_token_id ( token_id)
430
+ . freeze_with ( & client) ?
431
+ . sign ( private_key_3. clone ( ) )
432
+ . execute ( & client)
433
+ . await ?
434
+ . get_receipt ( & client)
435
+ . await ?;
436
+
437
+ /*
438
+ * Step 14:
439
+ * Query to verify Carol no longer has the fungible tokens
440
+ */
441
+ let carol_balance = AccountBalanceQuery :: new ( )
442
+ . account_id ( carol_id)
443
+ . execute ( & client)
444
+ . await ?;
445
+
446
+ println ! (
447
+ "Carol ft balance after reject: {}" ,
448
+ carol_balance. tokens. get( & token_id) . unwrap( )
449
+ ) ;
450
+
451
+ /*
452
+ * Step 15:
453
+ * Query to verify Treasury received the rejected fungible tokens
454
+ */
455
+ let treasury_balance = AccountBalanceQuery :: new ( )
456
+ . account_id ( treasury_account_id)
457
+ . execute ( & client)
458
+ . await ?;
459
+
460
+ println ! (
461
+ "Treasury ft balance after reject: {}" ,
462
+ treasury_balance. tokens. get( & token_id) . unwrap( )
463
+ ) ;
464
+
465
+ println ! ( "Token airdrop example completed successfully" ) ;
217
466
Ok ( ( ) )
218
467
}
0 commit comments