Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
revoxhere
GitHub Repository: revoxhere/duino-coin
Path: blob/master/Legacy codes/CLI_Wallet.py
922 views
1
#!/usr/bin/env python3
2
##########################################
3
# Duino-Coin CLI Wallet (v2.7.1)
4
# https://github.com/revoxhere/duino-coin
5
# Distributed under MIT license
6
# © Duino-Coin Community 2022
7
##########################################
8
import configparser
9
import datetime
10
import getpass
11
import json
12
import os
13
from os import _exit, execl, mkdir
14
from os import path
15
import platform
16
import socket
17
import sys
18
import time
19
from pathlib import Path
20
from signal import SIGINT, signal
21
from base64 import b64decode, b64encode
22
from platform import system as plsystem
23
from locale import LC_ALL, getdefaultlocale, getlocale, setlocale
24
from json import load as jsonload
25
26
try:
27
import requests
28
except:
29
now = datetime.datetime.now()
30
print(now.strftime("%H:%M:%S ") +
31
"Requests is not installed. "
32
+ "Please install it using: python3 -m pip install requests."
33
+ "\nExiting in 15s.")
34
time.sleep(15)
35
os._exit(1)
36
37
wrong_passphrase = False
38
iterations = 100_000
39
timeout = 30 # Socket timeout
40
VER = 2.71
41
RESOURCES_DIR = 'CLI_Wallet_' + str(VER) + '_resources'
42
use_wrapper = False
43
WS_URI = "ws://server.duinocoin.com:15808"
44
config = configparser.ConfigParser()
45
46
# Check if the resources folder exists, and makes one if not
47
if not path.exists(RESOURCES_DIR):
48
mkdir(RESOURCES_DIR)
49
50
# Check if commands file exists
51
if not Path(RESOURCES_DIR + "/cli_wallet_commands.json").is_file():
52
url = ("https://raw.githubusercontent.com/"
53
+ "revoxhere/"
54
+ "duino-coin/master/Resources/"
55
+ "cli_wallet_commands.json")
56
r = requests.get(url)
57
with open(RESOURCES_DIR + "/cli_wallet_commands.json", "wb") as f:
58
f.write(r.content)
59
60
# Check if languages file exists
61
if not Path(RESOURCES_DIR + "/langs.json").is_file():
62
url = ("https://raw.githubusercontent.com/"
63
+ "revoxhere/"
64
+ "duino-coin/master/Resources/"
65
+ "CLI_Wallet_langs.json")
66
r = requests.get(url)
67
with open(RESOURCES_DIR + "/langs.json", "wb") as f:
68
f.write(r.content)
69
70
# Load language file
71
with open(RESOURCES_DIR + "/langs.json", "r", encoding="utf8") as lang_file:
72
lang_file = jsonload(lang_file)
73
74
# OS X invalid locale hack
75
if plsystem() == "Darwin":
76
if getlocale()[0] is None:
77
setlocale(LC_ALL, "en_US.UTF-8")
78
79
# Check if wallet is configured, if it isn't, autodetect language
80
try:
81
if not Path(RESOURCES_DIR + "/CLIWallet_config.cfg").is_file():
82
locale = getdefaultlocale()[0]
83
if locale.startswith("nl"):
84
lang = "dutch"
85
elif locale.startswith("th"):
86
lang = "thai"
87
elif locale.startswith("sk"):
88
lang = "slovak"
89
elif locale.startswith("ko"):
90
lang = "korean"
91
else:
92
lang = "english"
93
else:
94
# Read language variable from configfile
95
try:
96
config.read(RESOURCES_DIR + "/CLIWallet_config.cfg")
97
lang = config["wallet"]["language"]
98
except Exception:
99
# If it fails, fallback to english
100
lang = "english"
101
except Exception as error:
102
lang = "english"
103
104
105
def getString(string_name):
106
# Get string form language file
107
if string_name in lang_file[lang]:
108
return lang_file[lang][string_name]
109
elif string_name in lang_file["english"]:
110
return lang_file["english"][string_name]
111
else:
112
return "String not found: " + string_name
113
114
115
try:
116
from base64 import urlsafe_b64decode as b64d
117
from base64 import urlsafe_b64encode as b64e
118
except ModuleNotFoundError:
119
print(getString("base64_not_installed"))
120
time.sleep(15)
121
_exit(1)
122
123
try:
124
from cryptography.fernet import Fernet, InvalidToken
125
from cryptography.hazmat.backends import default_backend
126
from cryptography.hazmat.primitives import hashes
127
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
128
except:
129
now = datetime.datetime.now()
130
print(now.strftime("%H:%M:%S ") + getString("cryptography_not_installed"))
131
time.sleep(15)
132
os._exit(1)
133
134
try:
135
import secrets
136
except:
137
now = datetime.datetime.now()
138
print(now.strftime("%H:%M:%S ") + getString("secrets_not_installed"))
139
time.sleep(15)
140
os._exit(1)
141
142
try:
143
import websocket
144
except:
145
now = datetime.datetime.now()
146
print(now.strftime("%H:%M:%S ") + getString("websocket_not_installed"))
147
time.sleep(15)
148
os._exit(1)
149
150
try: # Check if colorama is installed
151
from colorama import Back, Fore, Style, init
152
except:
153
now = datetime.datetime.now()
154
print(now.strftime("%H:%M:%S ") + getString("colorama_not_installed"))
155
time.sleep(15)
156
os._exit(1)
157
158
try:
159
import tronpy
160
from tronpy.keys import PrivateKey
161
tronpy_installed = True
162
except:
163
tronpy_installed = False
164
now = datetime.datetime.now()
165
print(now.strftime("%H:%M:%S ") + getString("tronpy_not_installed"))
166
167
backend = default_backend()
168
169
170
def title(title):
171
if os.name == 'nt':
172
os.system(
173
"title "
174
+ title)
175
else:
176
print(
177
'\33]0;'
178
+ title
179
+ '\a',
180
end='')
181
sys.stdout.flush()
182
183
184
def _derive_key(
185
password: bytes,
186
salt: bytes,
187
iterations: int = iterations) -> bytes:
188
kdf = PBKDF2HMAC(
189
algorithm=hashes.SHA256(),
190
length=32,
191
salt=salt,
192
iterations=iterations,
193
backend=backend)
194
return b64e(kdf.derive(password))
195
196
197
def print_command(name, desc):
198
print(" " + Style.RESET_ALL + Fore.WHITE +
199
Style.BRIGHT + name + Style.RESET_ALL + desc)
200
201
202
# Print the command names and description using a json file
203
def print_commands_norm():
204
with open(RESOURCES_DIR + '/cli_wallet_commands.json') as f:
205
data = json.load(f)
206
for key, value in data.items():
207
if key == "wrapper_commands":
208
break
209
print_command(key, value)
210
211
212
def print_commands_wrapper():
213
with open(RESOURCES_DIR + '/cli_wallet_commands.json') as f:
214
data = json.load(f)
215
for key in data["wrapper_commands"]:
216
print_command(key, data["wrapper_commands"][key])
217
218
219
def password_encrypt(
220
message: bytes,
221
password: str,
222
iterations: int = iterations) -> bytes:
223
salt = secrets.token_bytes(16)
224
key = _derive_key(
225
password.encode(),
226
salt,
227
iterations)
228
return b64e(
229
b'%b%b%b' % (
230
salt,
231
iterations.to_bytes(4, 'big'),
232
b64d(Fernet(key).encrypt(message))))
233
234
235
def password_decrypt(
236
token: bytes,
237
password: str) -> bytes:
238
decoded = b64d(token)
239
salt, iterations, token = decoded[:16], decoded[16:20], b64e(decoded[20:])
240
iterations = int.from_bytes(iterations, 'big')
241
key = _derive_key(
242
password.encode(),
243
salt,
244
iterations)
245
return Fernet(key).decrypt(token)
246
247
248
def handler(signal_received, frame):
249
print(Style.RESET_ALL
250
+ Style.BRIGHT
251
+ Fore.YELLOW
252
+ getString("see_you_soon"))
253
try:
254
wss_conn.send(bytes("CLOSE", encoding="utf8"))
255
except:
256
pass
257
os._exit(0)
258
259
260
signal(SIGINT, handler) # Enable signal handler
261
262
263
while True:
264
print(("Warning: CLI and GUI wallets are being deprecated "
265
+ "in favor of the Web Wallet. "
266
+ "This app may not run properly."))
267
try:
268
wss_conn = websocket.create_connection(WS_URI)
269
SERVER_VER = wss_conn.recv().decode()
270
271
jsonapi = requests.get(
272
"https://raw.githubusercontent.com/"
273
+ "revoxhere/"
274
+ "duco-statistics/master/api.json",
275
data=None)
276
if jsonapi.status_code == 200:
277
content = jsonapi.content.decode()
278
contentjson = json.loads(content)
279
ducofiat = float(contentjson["Duco price"])
280
else:
281
ducofiat = 0.0025
282
break
283
284
except Exception as e:
285
print(e)
286
print(Style.RESET_ALL
287
+ Fore.RED
288
+ getString("cant_connect_to_server"))
289
time.sleep(15)
290
os._exit(1)
291
292
except:
293
print(Style.RESET_ALL
294
+ Fore.RED
295
+ getString("cant_recieve_pool_ip_and_port"))
296
time.sleep(15)
297
os._exit(1)
298
299
300
def reconnect():
301
while True:
302
try:
303
# Try to connect
304
wss_conn = websocket.create_connection(WS_URI)
305
wss_conn.settimeout(timeout)
306
SERVER_VER = wss_conn.recv().decode().rstrip("\n")
307
308
jsonapi = requests.get(
309
"https://raw.githubusercontent.com/"
310
+ "revoxhere/"
311
+ "duco-statistics/master/api.json",
312
data=None)
313
if jsonapi.status_code == 200:
314
content = jsonapi.content.decode()
315
contentjson = json.loads(content)
316
ducofiat = float(contentjson["Duco price"])
317
else:
318
ducofiat = 0.0025
319
320
except:
321
print(Style.RESET_ALL + Fore.RED
322
+ getString("cant_connect_to_server"))
323
time.sleep(15)
324
os.system("python " + __file__)
325
else:
326
return wss_conn
327
328
329
while True:
330
title("Duino-Coin CLI Wallet")
331
if not Path(RESOURCES_DIR + "/CLIWallet_config.cfg").is_file():
332
# Initial configuration section
333
print(Style.RESET_ALL
334
+ Style.BRIGHT
335
+ Fore.YELLOW
336
+ getString("first_run"))
337
print(Style.RESET_ALL + getString("select_option"))
338
339
choice = input(getString("choice_input"))
340
try:
341
int(choice)
342
except ValueError:
343
print(getString("value_not_numeric"))
344
345
if int(choice) <= 1:
346
username = input(
347
Style.RESET_ALL
348
+ Fore.YELLOW
349
+ getString("enter_username")
350
+ Style.BRIGHT)
351
352
password = getpass.getpass(prompt=Style.RESET_ALL
353
+ Fore.YELLOW
354
+ getString("enter_password")
355
+ Style.BRIGHT,
356
stream=None)
357
358
server_timeout = True
359
while server_timeout:
360
try:
361
wss_conn.send(bytes(
362
"LOGI,"
363
+ str(username)
364
+ ","
365
+ str(password)
366
+ str(",placeholder"),
367
encoding="utf8"))
368
loginFeedback = wss_conn.recv().decode()
369
loginFeedback = loginFeedback.rstrip("\n").split(",")
370
server_timeout = False
371
372
if loginFeedback[0] == "OK":
373
print(Style.RESET_ALL
374
+ Fore.YELLOW
375
+ getString("login_success"))
376
377
config['wallet'] = {
378
"username": username,
379
"password": b64encode(
380
bytes(password, encoding="utf8")
381
).decode("utf-8"),
382
"language": lang}
383
config['wrapper'] = {"use_wrapper": "false"}
384
385
# Write data to file
386
with open(RESOURCES_DIR
387
+ "/CLIWallet_config.cfg",
388
"w") as configfile:
389
config.write(configfile)
390
else:
391
print(Style.RESET_ALL
392
+ Fore.RED
393
+ getString("login_failed")
394
+ Style.BRIGHT
395
+ str(loginFeedback[1]))
396
time.sleep(15)
397
os._exit(1)
398
except socket.timeout:
399
server_timeout = True
400
401
if int(choice) == 2:
402
print(Style.RESET_ALL
403
+ Fore.YELLOW
404
+ getString("agree_requirments")
405
+ Fore.WHITE
406
+ "https://github.com/revoxhere/duino-coin#terms-of-usage"
407
+ Fore.YELLOW)
408
409
username = input(
410
Style.RESET_ALL
411
+ Fore.YELLOW
412
+ getString("enter_username")
413
+ Style.BRIGHT)
414
415
password = getpass.getpass(prompt=Style.RESET_ALL
416
+ Fore.YELLOW
417
+ getString("enter_password")
418
+ Style.BRIGHT,
419
stream=None)
420
421
pconfirm = getpass.getpass(prompt=Style.RESET_ALL
422
+ Fore.YELLOW
423
+ getString("confirm_password")
424
+ Style.BRIGHT,
425
stream=None)
426
427
email = input(
428
Style.RESET_ALL
429
+ Fore.YELLOW
430
+ getString("enter_email")
431
+ Style.BRIGHT)
432
433
if password == pconfirm:
434
while True:
435
wss_conn.send(bytes(
436
"REGI,"
437
+ str(username)
438
+ ","
439
+ str(password)
440
+ ","
441
+ str(email),
442
encoding="utf8"))
443
444
regiFeedback = wss_conn.recv().decode()
445
regiFeedback = regiFeedback.rstrip("\n").split(",")
446
447
if regiFeedback[0] == "OK":
448
print(Style.RESET_ALL
449
+ Fore.YELLOW
450
+ Style.BRIGHT
451
+ getString("register_success"))
452
break
453
454
elif regiFeedback[0] == "NO":
455
print(Style.RESET_ALL
456
+ Fore.RED
457
+ getString("register_failed")
458
+ Style.BRIGHT
459
+ str(regiFeedback[1]))
460
time.sleep(15)
461
os._exit(1)
462
463
if int(choice) >= 3:
464
os._exit(0)
465
466
else:
467
config.read(RESOURCES_DIR + "/CLIWallet_config.cfg")
468
if config["wrapper"]["use_wrapper"] == "true" and tronpy_installed:
469
use_wrapper = True
470
471
if config["wrapper"]["use_custom_passphrase"] == "true":
472
passphrase = getpass.getpass(
473
prompt=Style.RESET_ALL
474
+ Fore.YELLOW
475
+ getString("decrypt_private_key")
476
+ Style.BRIGHT,
477
stream=None)
478
479
try:
480
priv_key = password_decrypt(
481
config["wrapper"]["priv_key"],
482
passphrase).decode("utf8")
483
except InvalidToken:
484
print(getString("invalid_passphrase_wrapper"))
485
use_wrapper = False
486
wrong_passphrase = True
487
else:
488
try:
489
priv_key = password_decrypt(
490
config["wrapper"]["priv_key"],
491
b64decode(
492
config["wallet"]["password"]
493
).decode("utf8")
494
).decode("utf8")
495
except InvalidToken:
496
print(getString("invalid_passphrase_wrapper"))
497
use_wrapper = False
498
wrong_passphrase = True
499
500
pub_key = config["wrapper"]["pub_key"]
501
502
while True:
503
try:
504
tron = tronpy.Tron()
505
# wDUCO contract
506
wduco = tron.get_contract(
507
"TWYaXdxA12JywrUdou3PFD1fvx2PWjqK9U"
508
)
509
break
510
except:
511
print("Retrying wDUCO contract fetch")
512
pass
513
514
while True:
515
try:
516
wbalance = wduco.functions.balanceOf(
517
config["wrapper"]["pub_key"])
518
break
519
except:
520
print("Retrying wDUCO balance fetch")
521
522
try:
523
trx_balance = tron.get_account_balance(
524
config["wrapper"]["pub_key"]
525
)
526
except:
527
trx_balance = 0
528
529
while True:
530
config.read(RESOURCES_DIR + "/CLIWallet_config.cfg")
531
username = config["wallet"]["username"]
532
password = b64decode(config["wallet"]["password"]).decode("utf8")
533
534
print("Authenticating...")
535
wss_conn.send(bytes(
536
"LOGI,"
537
+ str(username)
538
+ ","
539
+ str(password)
540
+ str(",placeholder"),
541
encoding="utf8"))
542
543
loginFeedback = wss_conn.recv().decode().rstrip("\n").split(",")
544
if loginFeedback[0] == "OK":
545
break
546
else:
547
print(Style.RESET_ALL
548
+ Fore.RED
549
+ getString("login_failed")
550
+ Style.BRIGHT
551
+ str(loginFeedback[1]))
552
time.sleep(15)
553
os._exit(1)
554
555
while True:
556
while True:
557
try:
558
wss_conn.send(bytes(
559
"BALA",
560
encoding="utf8"))
561
except:
562
wss_conn = reconnect()
563
try:
564
balance = round(
565
float(wss_conn.recv().decode().rstrip("\n")), 8)
566
balanceusd = round(
567
float(balance) * float(ducofiat), 6)
568
break
569
except:
570
pass
571
572
if use_wrapper:
573
while True:
574
try:
575
wbalance = float(
576
wduco.functions.balanceOf(pub_key)
577
)/10**6
578
break
579
except:
580
pass
581
582
try:
583
trx_balance = tron.get_account_balance(pub_key)
584
except:
585
trx_balance = 0
586
587
print(Style.RESET_ALL
588
+ Style.BRIGHT
589
+ Fore.YELLOW
590
+ getString("cli_wallet_text"))
591
592
print(Style.RESET_ALL
593
+ Fore.YELLOW
594
+ getString("you_have")
595
+ Style.BRIGHT
596
+ str(balance)
597
+ " DUCO")
598
599
print(Style.RESET_ALL
600
+ Fore.YELLOW
601
+ getString("which_is_about")
602
+ Style.BRIGHT
603
+ str(balanceusd)
604
+ " USD")
605
606
print(Style.RESET_ALL
607
+ Fore.YELLOW
608
+ getString("duco_price")
609
+ Style.BRIGHT
610
+ str(ducofiat)
611
+ " USD")
612
613
if use_wrapper:
614
print(Style.RESET_ALL
615
+ Fore.YELLOW
616
+ getString("you_have")
617
+ Style.BRIGHT
618
+ str(wbalance)
619
+ " wDUCO")
620
621
while True:
622
try:
623
pendingbalance = float(
624
wduco.functions.pendingWithdrawals(
625
pub_key,
626
username)
627
)/(10**6)
628
break
629
except:
630
pass
631
632
if pendingbalance > 0:
633
print(Style.RESET_ALL
634
+ Fore.YELLOW
635
+ getString("pending_unwraps")
636
+ Style.BRIGHT
637
+ str(pendingbalance)
638
+ " wDUCO")
639
640
print(Style.RESET_ALL
641
+ Fore.YELLOW
642
+ getString("tron_address")
643
+ Style.BRIGHT
644
+ str(pub_key))
645
646
print(Style.RESET_ALL
647
+ Fore.YELLOW
648
+ getString("trx_balance")
649
+ Style.BRIGHT
650
+ str(trx_balance))
651
652
print(Style.RESET_ALL
653
+ Fore.YELLOW
654
+ getString("help_list_command"))
655
656
command = input(Style.RESET_ALL
657
+ Fore.WHITE
658
+ getString("duco_console")
659
+ Style.BRIGHT)
660
661
if command == "refresh":
662
continue
663
664
elif command == "clear":
665
if os.name == "nt":
666
os.system("cls")
667
continue
668
else:
669
os.system("clear")
670
continue
671
672
elif command == "send":
673
recipient = input(Style.RESET_ALL
674
+ Fore.WHITE
675
+ getString("enter_recipients_name")
676
+ Style.BRIGHT)
677
try:
678
amount = float(input(
679
Style.RESET_ALL
680
+ Fore.WHITE
681
+ getString("enter_amount_transfer")
682
+ Style.BRIGHT))
683
except ValueError:
684
print(getString("amount_numeric"))
685
continue
686
687
wss_conn.send(bytes(
688
"SEND,-,"
689
+ str(recipient)
690
+ ","
691
+ str(amount),
692
encoding="utf8"))
693
while True:
694
message = wss_conn.recv().decode().rstrip("\n")
695
print(Style.RESET_ALL
696
+ Fore.BLUE
697
+ getString("server_message")
698
+ Style.BRIGHT
699
+ str(message))
700
break
701
702
elif command == "changepass":
703
oldpassword = input(
704
Style.RESET_ALL
705
+ Fore.WHITE
706
+ getString("enter_current_password")
707
+ Style.BRIGHT)
708
709
newpassword = input(
710
Style.RESET_ALL
711
+ Fore.WHITE
712
+ getString("enter_new_password")
713
+ Style.BRIGHT)
714
715
wss_conn.send(bytes(
716
"CHGP,"
717
+ str(oldpassword)
718
+ ","
719
+ str(newpassword),
720
encoding="utf8"))
721
722
while True:
723
message = wss_conn.recv().decode().rstrip("\n")
724
print(Style.RESET_ALL
725
+ Fore.BLUE
726
+ getString("server_message")
727
+ Style.BRIGHT
728
+ str(message))
729
break
730
731
elif command == "exit":
732
print(Style.RESET_ALL
733
+ Style.BRIGHT
734
+ Fore.YELLOW
735
+ getString("sigint_detected")
736
+ Style.NORMAL
737
+ getString("see_you_soon")
738
+ Style.RESET_ALL)
739
try:
740
wss_conn.send(bytes("CLOSE", encoding="utf8"))
741
except:
742
pass
743
os._exit(0)
744
745
elif command == "wrapperconf": # wrapper config
746
config.read(RESOURCES_DIR + "/CLIWallet_config.cfg")
747
if (not config["wrapper"]["use_wrapper"] == "true"
748
and tronpy_installed):
749
print(Style.RESET_ALL
750
+ Fore.WHITE
751
+ getString("select_option"))
752
try:
753
choice = int(
754
input(getString("choice_input_wrapper")))
755
756
if choice <= 1:
757
priv_key = str(PrivateKey.random())
758
pub_key = PrivateKey(bytes.fromhex(
759
priv_key)).public_key.to_base58check_address()
760
print(getString("how_encrypt_private_key"))
761
762
incorrect_value = True
763
while incorrect_value:
764
try:
765
encryption_choice = int(
766
input(getString("encryption_choice")))
767
incorrect_value = False
768
except ValueError:
769
print(getString("value_not_numeric"))
770
incorrect_value = True
771
772
if encryption_choice <= 1:
773
config['wrapper'] = {
774
"use_wrapper": "true",
775
"priv_key": str(password_encrypt(
776
priv_key.encode(),
777
password).decode()),
778
"pub_key": pub_key,
779
"use_custom_passphrase": "false"}
780
781
# Write data to file
782
with open(RESOURCES_DIR
783
+ "/CLIWallet_config.cfg",
784
"w") as configfile:
785
config.write(configfile)
786
print(getString("success"))
787
788
elif encryption_choice >= 2:
789
passphrase = input(
790
getString("encrypt_private_key"))
791
config['wrapper'] = {
792
"use_wrapper": "true",
793
"priv_key": str(password_encrypt(
794
priv_key.encode(),
795
passphrase).decode()),
796
"pub_key": pub_key,
797
"use_custom_passphrase": "true"}
798
799
# Write data to file
800
with open(RESOURCES_DIR
801
+ "/CLIWallet_config.cfg",
802
"w") as configfile:
803
config.write(configfile)
804
print(getString("success"))
805
806
print("Restart the wallet to use the wrapper")
807
808
elif choice == 2:
809
priv_key = input(getString("input_private_key"))
810
try:
811
pub_key = PrivateKey(
812
bytes.fromhex(
813
priv_key)
814
).public_key.to_base58check_address()
815
print(getString("how_encrypt_private_key"))
816
817
incorrect_value = True
818
while incorrect_value:
819
try:
820
encryption_choice = int(
821
input(
822
getString("encryption_choice")
823
)
824
)
825
incorrect_value = False
826
except ValueError:
827
print(getString("value_not_numeric"))
828
incorrect_value = True
829
830
if encryption_choice <= 1:
831
config['wrapper'] = {
832
"use_wrapper": "true",
833
"priv_key": str(password_encrypt(
834
priv_key.encode(),
835
password).decode()),
836
"pub_key": pub_key,
837
"use_custom_passphrase": "false"}
838
839
# Write data to file
840
with open(RESOURCES_DIR
841
+ "/CLIWallet_config.cfg",
842
"w") as configfile:
843
config.write(configfile)
844
print(getString("success"))
845
846
elif encryption_choice >= 2:
847
passphrase = input(
848
getString("encrypt_private_key"))
849
config['wrapper'] = {
850
"use_wrapper": "true",
851
"priv_key": str(password_encrypt(
852
priv_key.encode(),
853
passphrase).decode()),
854
"pub_key": pub_key,
855
"use_custom_passphrase": "true"}
856
857
# Write data to file
858
with open(RESOURCES_DIR
859
+ "/CLIWallet_config.cfg",
860
"w") as configfile:
861
config.write(configfile)
862
print(getString("success"))
863
except ValueError:
864
print(getString("incorrect_key"))
865
else:
866
print(getString("cancelled"))
867
868
except ValueError:
869
print(Style.RESET_ALL
870
+ Fore.WHITE
871
+ getString("incorrect_value")
872
+ Style.BRIGHT)
873
874
elif not tronpy_installed:
875
print(now.strftime(
876
"%H:%M:%S ")
877
+ getString("tronpy_not_installed_2"))
878
879
elif command == "wrap":
880
if use_wrapper:
881
try:
882
amount = float(input(
883
Style.RESET_ALL
884
+ Fore.WHITE
885
+ getString("amount_to_wrap")
886
+ Style.BRIGHT))
887
except ValueError:
888
print(getString("no_amount_numeric"))
889
continue
890
891
try:
892
wss_conn.send(bytes("BALA", encoding="utf8"))
893
balance = round(
894
float(wss_conn.recv().decode().rstrip("\n")), 8)
895
except:
896
wss_conn = reconnect()
897
if float(amount) >= 10 and float(amount) <= balance:
898
tron_address = input(
899
Style.RESET_ALL
900
+ Fore.WHITE
901
+ getString("enter_tron_address_or_local")
902
+ Style.BRIGHT)
903
if tron_address == "":
904
tron_address = pub_key
905
906
wss_conn.send(bytes(
907
"WRAP,"
908
+ str(amount)
909
+ ","
910
+ str(tron_address)
911
+ str(",placeholder"),
912
encoding='utf8'))
913
914
elif float(amount) < 10 and not float(amount) > balance:
915
print(getString("error_min_10_duco"))
916
else:
917
print(getString("error_unsufficient_balance"))
918
elif wrong_passphrase:
919
print(getString("error_wrong_passphrase"))
920
else:
921
print(getString("error_configure_wrapperconf"))
922
923
elif command == "unwrap":
924
if use_wrapper:
925
pendingvalues = wduco.functions.pendingWithdrawals(
926
pub_key, username
927
)
928
# Transaction wasn't initiated
929
# but variable should be declared
930
txn_success = False
931
try:
932
amount = float(
933
input(Style.RESET_ALL
934
+ Fore.WHITE
935
+ getString("enter_amount_unwrap")
936
+ Style.BRIGHT))
937
except ValueError:
938
print(getString("value_not_numeric"))
939
continue
940
if int(float(amount)*10**6) >= pendingvalues:
941
toInit = int(float(amount)*10**6)-pendingvalues
942
else:
943
toInit = amount*10**6
944
if toInit > 0:
945
txn = wduco.functions.initiateWithdraw(
946
username, toInit
947
).with_owner(
948
pub_key
949
).fee_limit(
950
5_000_000
951
).build().sign(
952
PrivateKey(
953
bytes.fromhex(priv_key)
954
)
955
)
956
print(getString("initiating_unwrap"), txn.txid)
957
txn = txn.broadcast()
958
txnfeedback = txn.result()
959
if txnfeedback:
960
txn_success = True
961
else:
962
txn_success = False
963
964
if amount <= pendingvalues:
965
print(getString("amount_over_pending_values"))
966
967
if txn_success or amount <= pendingvalues:
968
wss_conn.send(bytes(
969
"UNWRAP,"
970
+ str(amount)
971
+ ","
972
+ str(pub_key),
973
encoding='utf8'))
974
else:
975
print(getString("error_initiating_unwrap"))
976
977
elif wrong_passphrase:
978
print(getString("error_wrong_passphrase"))
979
else:
980
print(getString("error_configure_wrapperconf"))
981
982
elif command == "cancelunwraps":
983
if use_wrapper:
984
txn = wduco.functions.cancelWithdrawals(
985
pub_key, username
986
).with_owner(
987
pub_key
988
).fee_limit(
989
5_000_000
990
).build().sign(
991
PrivateKey(
992
bytes.fromhex(priv_key)
993
)
994
)
995
print(getString("transaction_send_txid"), txn.txid)
996
txn = txn.broadcast()
997
if txn.result():
998
print(getString("success"))
999
else:
1000
print(getString("error_not_enough_energy_or_trx"))
1001
elif wrong_passphrase:
1002
print(getString("error_wrong_passphrase"))
1003
else:
1004
print(getString("error_configure_wrapperconf"))
1005
1006
elif command == "finishunwraps":
1007
if use_wrapper:
1008
pendingvalues = float(
1009
wduco.functions.pendingWithdrawals(
1010
pub_key,
1011
username))/(10**6)
1012
wss_conn.send(bytes(
1013
"UNWRAP,"
1014
+ str(pendingvalues)
1015
+ ","
1016
+ str(pub_key)
1017
+ str(",placeholder"),
1018
encoding='utf8'))
1019
print(getString("finished_unwrapping"),
1020
str(pendingvalues), "DUCO")
1021
elif wrong_passphrase:
1022
print(getString("error_wrong_passphrase"))
1023
else:
1024
print(getString("error_configure_wrapperconf"))
1025
1026
elif command == "exportwrapkey":
1027
if use_wrapper:
1028
confirmation = input(
1029
getString("confirm_export_private_key"))
1030
if confirmation == "YES":
1031
print(getString("private_key"), priv_key)
1032
else:
1033
print(getString("cancelled_invalid_confirmation"))
1034
elif wrong_passphrase:
1035
print(getString("error_wrong_passphrase"))
1036
else:
1037
print(getString("error_configure_wrapperconf"))
1038
1039
elif command == "wsend":
1040
if use_wrapper:
1041
recipient = input(
1042
Style.RESET_ALL
1043
+ Fore.WHITE
1044
+ getString("enter_tron_recipients_name")
1045
+ Style.BRIGHT)
1046
try:
1047
amount = float(input(
1048
Style.RESET_ALL
1049
+ Fore.WHITE
1050
+ getString("enter_amount_transfer")
1051
+ Style.BRIGHT))
1052
except ValueError:
1053
print(getString("amount_numeric"))
1054
continue
1055
wbalance = float(wduco.functions.balanceOf(pub_key))/10**6
1056
if float(amount) <= wbalance:
1057
txn = wduco.functions.transfer(
1058
recipient,
1059
int(float(amount)*10**6)
1060
).with_owner(
1061
pub_key
1062
).fee_limit(
1063
5_000_000
1064
).build().sign(
1065
PrivateKey(
1066
bytes.fromhex(priv_key)
1067
)
1068
)
1069
txn = txn.broadcast()
1070
print(getString("tron_transaction_submitted"),
1071
txn.txid)
1072
trontxresult = txn.wait()
1073
if trontxresult:
1074
print(getString("tron_successful_transaction"))
1075
else:
1076
print(getString("tron_error_transaction"))
1077
elif wrong_passphrase:
1078
print(getString("error_wrong_passphrase"))
1079
else:
1080
print(getString("error_configure_wrapperconf"))
1081
1082
elif command == "about":
1083
print(Style.RESET_ALL
1084
+ Fore.WHITE
1085
+ getString("about_1"))
1086
print(Style.RESET_ALL
1087
+ Fore.WHITE
1088
+ getString("about_2")
1089
+ str(VER))
1090
print(Style.RESET_ALL
1091
+ Fore.WHITE
1092
+ getString("about_3"))
1093
print(Style.RESET_ALL
1094
+ Fore.WHITE
1095
+ Style.BRIGHT
1096
+ "https://duinocoin.com")
1097
print(Style.RESET_ALL
1098
+ Fore.WHITE
1099
+ getString("about_4")
1100
+ Style.BRIGHT
1101
+ str(SERVER_VER)
1102
+ Style.RESET_ALL)
1103
if float(SERVER_VER) > VER:
1104
print(Style.RESET_ALL
1105
+ Fore.YELLOW
1106
+ getString("about_5")
1107
+ Fore.WHITE
1108
+ Style.BRIGHT
1109
+ SERVER_VER
1110
+ Fore.YELLOW
1111
+ Style.RESET_ALL
1112
+ getString("about_6")
1113
+ Style.BRIGHT
1114
+ Fore.WHITE
1115
+ str(VER)
1116
+ Style.RESET_ALL
1117
+ Fore.YELLOW
1118
+ getString("about_7"))
1119
else:
1120
print(Style.RESET_ALL
1121
+ Fore.WHITE
1122
+ getString("about_8"))
1123
1124
elif command == "logout":
1125
os.remove(RESOURCES_DIR + "/CLIWallet_config.cfg")
1126
os.system("python " + __file__)
1127
1128
elif command == "donate":
1129
print(Style.RESET_ALL
1130
+ Fore.BLUE
1131
+ Style.BRIGHT
1132
+ getString("donate_1"))
1133
print(Style.RESET_ALL
1134
+ Fore.YELLOW
1135
+ getString("donate_2")
1136
+ Style.RESET_ALL
1137
+ Fore.WHITE
1138
+ Style.BRIGHT
1139
+ "TY5wfM6JsYKEEMfQR3RBQBPKfetTpf7nyM"
1140
+ Style.RESET_ALL
1141
+ Fore.YELLOW
1142
+ getString("donate_3"))
1143
print("Duino-Coin: "
1144
+ Style.RESET_ALL
1145
+ Fore.WHITE
1146
+ Style.BRIGHT
1147
+ "revox"
1148
+ Style.RESET_ALL
1149
+ Fore.YELLOW
1150
+ getString("donate_4"))
1151
print("Duino-Coin: "
1152
+ Style.RESET_ALL
1153
+ Fore.WHITE
1154
+ Style.BRIGHT
1155
+ "Yanis"
1156
+ Style.RESET_ALL
1157
+ Fore.YELLOW
1158
+ getString("donate_5"))
1159
1160
else:
1161
print(Style.RESET_ALL
1162
+ Fore.YELLOW
1163
+ getString("duco_commands"))
1164
print_commands_norm()
1165
1166
print(Style.RESET_ALL
1167
+ Fore.YELLOW
1168
+ getString("wrapper_commands"))
1169
print_commands_wrapper()
1170
1171