1use anyhow::{Context, Result};
2use colored::Colorize;
3use ed25519_dalek::{SigningKey, VerifyingKey};
4use serde::{Deserialize, Serialize};
5use sha2::{Digest, Sha256};
6use std::fs;
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct Wallet {
10 pub address: String,
11 pub private_key: String,
12 pub network: String,
13 pub seed_phrase: String,
14}
15
16impl Wallet {
17 pub async fn create(network: &str) -> Result<Self> {
18 println!("{}", "Creating wallet...".cyan());
19
20 let seed_phrase = Self::generate_seed_phrase();
21 let (private_key, address) = Self::derive_keys(&seed_phrase);
22
23 let wallet = Wallet {
24 address,
25 private_key,
26 network: network.to_string(),
27 seed_phrase,
28 };
29
30 println!("{}", "✓ Wallet created successfully".green().bold());
31
32 Ok(wallet)
33 }
34
35 pub fn save_to_file(&self) -> Result<()> {
36 let mut wallets_dir = dirs::home_dir().context("Failed to determine home directory")?;
37
38 wallets_dir.push(".x402");
39 wallets_dir.push("wallets");
40
41 fs::create_dir_all(&wallets_dir)
42 .with_context(|| format!("Failed to create wallets directory"))?;
43
44 let wallet_file = wallets_dir.join(format!("{}.json", self.address));
45
46 let wallet_data =
47 serde_json::to_string_pretty(self).context("Failed to serialize wallet data")?;
48
49 fs::write(&wallet_file, wallet_data)
50 .with_context(|| format!("Failed to save wallet file: {}", wallet_file.display()))?;
51
52 let display = wallet_file.display();
53 println!(
54 "{}",
55 format!(" ✓ Wallet saved to {}", display).cyan().dimmed()
56 );
57
58 Ok(())
59 }
60
61 pub fn import(private_key: &str, network: &str) -> Result<Self> {
62 println!("{}", "Importing wallet from private key...".cyan());
63
64 let private_key_clean = private_key.trim_start_matches("0x");
65 let private_key_bytes = hex::decode(private_key_clean)
66 .map_err(|e| anyhow::anyhow!("Failed to decode private key hex: {}", e))?;
67
68 if private_key_bytes.len() < 32 {
69 return Err(anyhow::anyhow!("Private key must be at least 32 bytes"));
70 }
71
72 let mut key_bytes = [0u8; 32];
73 key_bytes.copy_from_slice(&private_key_bytes[..32]);
74
75 let signing_key = SigningKey::from_bytes(&key_bytes);
76 let public_key = signing_key.verifying_key();
77 let public_key_bytes = public_key.as_bytes();
78 let address = hex::encode(&public_key_bytes[1..]);
79 let address = format!("0x{}", address);
80
81 let wallet = Wallet {
82 address,
83 private_key: private_key_clean.to_string(),
84 network: network.to_string(),
85 seed_phrase: String::new(),
86 };
87
88 println!("{}", "✓ Wallet imported successfully".green().bold());
89
90 Ok(wallet)
91 }
92
93 pub async fn fund_from_faucet(&self) -> Result<()> {
94 if self.network != "testnet" {
95 println!(
96 "{}",
97 " ℹ Skipping faucet funding (not on testnet)"
98 .yellow()
99 .dimmed()
100 );
101 return Ok(());
102 }
103
104 let faucet_url = "https://faucet.testnet.aptoslabs.com";
105
106 let client = reqwest::Client::new();
107 let request_body = serde_json::json!({
108 "address": self.address,
109 "amount": 100_000_000
110 });
111
112 let response = client
113 .post(faucet_url)
114 .header("Content-Type", "application/json")
115 .json(&request_body)
116 .send()
117 .await
118 .context("Failed to contact faucet")?;
119
120 if response.status().is_success() {
121 let _output = response.text().await.unwrap_or_default();
122 println!(
123 "{}",
124 format!(" ✓ Funded with 1 APT from faucet")
125 .green()
126 .dimmed()
127 );
128 } else {
129 let status = response.status();
130 let error = response.text().await.unwrap_or_default();
131 println!(
132 "{}",
133 format!(" ⚠ Faucet request failed: {} - {}", status, error)
134 .yellow()
135 .dimmed()
136 );
137 }
138
139 Ok(())
140 }
141
142 fn generate_seed_phrase() -> String {
143 const WORDS: &[&str] = &[
144 "abandon",
145 "ability",
146 "able",
147 "about",
148 "above",
149 "absent",
150 "absorb",
151 "abstract",
152 "absurd",
153 "abuse",
154 "access",
155 "accident",
156 "account",
157 "accuse",
158 "achieve",
159 "acid",
160 "acoustic",
161 "acquire",
162 "across",
163 "act",
164 "action",
165 "actor",
166 "actress",
167 "actual",
168 "adapt",
169 "add",
170 "addict",
171 "address",
172 "adjust",
173 "admit",
174 "adult",
175 "advance",
176 "advice",
177 "aerobic",
178 "affair",
179 "afford",
180 "afraid",
181 "again",
182 "age",
183 "agent",
184 "agree",
185 "ahead",
186 "aim",
187 "air",
188 "airport",
189 "aisle",
190 "alarm",
191 "album",
192 "alcohol",
193 "alert",
194 "alien",
195 "all",
196 "alley",
197 "allow",
198 "almost",
199 "alone",
200 "alpha",
201 "already",
202 "also",
203 "alter",
204 "always",
205 "amateur",
206 "amazing",
207 "among",
208 "amount",
209 "amused",
210 "analyst",
211 "anchor",
212 "ancient",
213 "anger",
214 "angle",
215 "angry",
216 "animal",
217 "ankle",
218 "announce",
219 "annual",
220 "another",
221 "answer",
222 "antenna",
223 "antique",
224 "anxiety",
225 "any",
226 "apart",
227 "apology",
228 "appear",
229 "apple",
230 "approve",
231 "april",
232 "arch",
233 "arctic",
234 "area",
235 "arena",
236 "argue",
237 "arm",
238 "armed",
239 "armor",
240 "army",
241 "around",
242 "arrange",
243 "arrest",
244 "arrive",
245 "arrow",
246 "art",
247 "artist",
248 "artwork",
249 "ask",
250 "aspect",
251 "assault",
252 "asset",
253 "assist",
254 "assume",
255 "asthma",
256 "athlete",
257 "atom",
258 "attack",
259 "attend",
260 "attract",
261 "auction",
262 "audit",
263 "august",
264 "aunt",
265 "author",
266 "auto",
267 "autumn",
268 "average",
269 "avocado",
270 "avoid",
271 "awake",
272 "aware",
273 "away",
274 "awesome",
275 "awful",
276 "awkward",
277 "axis",
278 "baby",
279 "bachelor",
280 "bacon",
281 "badge",
282 "bag",
283 "balance",
284 "balcony",
285 "ball",
286 "bamboo",
287 "banana",
288 "banner",
289 "bar",
290 "barely",
291 "bargain",
292 "barrel",
293 "base",
294 "basic",
295 "basket",
296 "battle",
297 "beach",
298 "bean",
299 "beauty",
300 "become",
301 "beef",
302 "before",
303 "begin",
304 "behave",
305 "behind",
306 "believe",
307 "below",
308 "belt",
309 "bench",
310 "benefit",
311 "best",
312 "betray",
313 "better",
314 "between",
315 "beyond",
316 "bicycle",
317 "bid",
318 "bike",
319 "bind",
320 "biology",
321 "bird",
322 "birth",
323 "bitter",
324 "black",
325 "blade",
326 "blame",
327 "blanket",
328 "blast",
329 "bleak",
330 "bless",
331 "blind",
332 "blood",
333 "blossom",
334 "blouse",
335 "blue",
336 "blur",
337 "blush",
338 "board",
339 "boat",
340 "body",
341 "boil",
342 "bomb",
343 "bone",
344 "bonus",
345 "book",
346 "boost",
347 "border",
348 "bored",
349 "borrow",
350 "boss",
351 "bottom",
352 "bounce",
353 "box",
354 "boy",
355 "bracket",
356 "brain",
357 "brand",
358 "brass",
359 "brave",
360 "bread",
361 "breeze",
362 "brick",
363 "bridge",
364 "brief",
365 "bright",
366 "bring",
367 "brisk",
368 "broken",
369 "bronze",
370 "broom",
371 "brother",
372 "brown",
373 "brush",
374 "bubble",
375 "buddy",
376 "budget",
377 "buffalo",
378 "build",
379 "bulb",
380 "bulk",
381 "bullet",
382 "bundle",
383 "bunker",
384 "burden",
385 "burger",
386 "burst",
387 "bus",
388 "business",
389 "busy",
390 "butter",
391 "buyer",
392 "buzz",
393 "cabbage",
394 "cabin",
395 "cable",
396 "cactus",
397 "cage",
398 "cake",
399 "call",
400 "calm",
401 "camera",
402 "camp",
403 "can",
404 "canal",
405 "cancel",
406 "candy",
407 "cannon",
408 "canoe",
409 "canvas",
410 "canyon",
411 "capable",
412 "capital",
413 "captain",
414 "car",
415 "carbon",
416 "card",
417 "cargo",
418 "carpet",
419 "carry",
420 "cart",
421 "case",
422 "cash",
423 "casino",
424 "castle",
425 "casual",
426 "cat",
427 "catalog",
428 "catch",
429 "category",
430 "cattle",
431 "caught",
432 "cause",
433 "caution",
434 "cave",
435 "ceiling",
436 "celery",
437 "cement",
438 "census",
439 "century",
440 "cereal",
441 "certain",
442 "chair",
443 "chalk",
444 "champion",
445 "change",
446 "chaos",
447 "chapter",
448 "charge",
449 "chase",
450 "chat",
451 "cheap",
452 "check",
453 "cheese",
454 "chef",
455 "cherry",
456 "chest",
457 "chicken",
458 "chief",
459 "child",
460 "chimney",
461 "choice",
462 "choose",
463 "chronic",
464 "chuckle",
465 "chunk",
466 "churn",
467 "cigar",
468 "cinnamon",
469 "circle",
470 "citizen",
471 "city",
472 "civil",
473 "claim",
474 "clap",
475 "clarify",
476 "claw",
477 "clay",
478 "clean",
479 "clerk",
480 "clever",
481 "click",
482 "client",
483 "cliff",
484 "climb",
485 "clinic",
486 "clip",
487 "clock",
488 "clog",
489 "close",
490 "cloth",
491 "cloud",
492 "clown",
493 "club",
494 "clump",
495 "cluster",
496 "clutch",
497 "coach",
498 "coast",
499 "coconut",
500 "code",
501 "coffee",
502 "coil",
503 "coin",
504 "collect",
505 "color",
506 "column",
507 "combine",
508 "come",
509 "comfort",
510 "comic",
511 "common",
512 "company",
513 "concert",
514 "conduct",
515 "confirm",
516 "congress",
517 "connect",
518 "consider",
519 "control",
520 "convince",
521 "cook",
522 "cool",
523 "copper",
524 "copy",
525 "coral",
526 "core",
527 "corn",
528 "corner",
529 "correct",
530 "cost",
531 "cotton",
532 "couch",
533 "country",
534 "couple",
535 "course",
536 "cousin",
537 "cover",
538 "coyote",
539 "crack",
540 "cradle",
541 "craft",
542 "cram",
543 "crane",
544 "crash",
545 "crater",
546 "crawl",
547 "crazy",
548 "cream",
549 "credit",
550 "creek",
551 "crew",
552 "cricket",
553 "crime",
554 "crisp",
555 "critic",
556 "crop",
557 "cross",
558 "crouch",
559 "crowd",
560 "crucial",
561 "cruel",
562 "cruise",
563 "crumble",
564 "crunch",
565 "crush",
566 "cry",
567 "crystal",
568 "cube",
569 "culture",
570 "cup",
571 "cupboard",
572 "curious",
573 "current",
574 "curtain",
575 "curve",
576 "cushion",
577 "custom",
578 "cute",
579 "cycle",
580 "dad",
581 "damage",
582 "damp",
583 "dance",
584 "danger",
585 "daring",
586 "dash",
587 "daughter",
588 "dawn",
589 "day",
590 "deal",
591 "debate",
592 "debris",
593 "decade",
594 "december",
595 "decide",
596 "decline",
597 "decorate",
598 "decrease",
599 "deer",
600 "defense",
601 "define",
602 "defy",
603 "degree",
604 "delay",
605 "deliver",
606 "demand",
607 "demise",
608 "denial",
609 "dentist",
610 "deny",
611 "depart",
612 "depend",
613 "deposit",
614 "depth",
615 "deputy",
616 "derive",
617 "describe",
618 "desert",
619 "design",
620 "desk",
621 "despair",
622 "destroy",
623 "detail",
624 "detect",
625 "develop",
626 "device",
627 "devote",
628 "diagram",
629 "dial",
630 "diamond",
631 "diary",
632 "dice",
633 "diesel",
634 "diet",
635 "differ",
636 "digital",
637 "dignity",
638 "dilemma",
639 "dinner",
640 "dinosaur",
641 "direct",
642 "dirt",
643 "disagree",
644 "discover",
645 "disease",
646 "dish",
647 "dismiss",
648 "disorder",
649 "display",
650 "distance",
651 "divert",
652 "divide",
653 "divorce",
654 "dizzy",
655 "doctor",
656 "document",
657 "dog",
658 "doll",
659 "dolphin",
660 "domain",
661 "donate",
662 "donkey",
663 "donor",
664 "door",
665 "dose",
666 "double",
667 "dove",
668 "draft",
669 "dragon",
670 "drama",
671 "draw",
672 "dream",
673 "dress",
674 "drift",
675 "drill",
676 "drink",
677 "drip",
678 "drive",
679 "drop",
680 "drum",
681 "dry",
682 "duck",
683 "dumb",
684 "dune",
685 "during",
686 "dust",
687 "dutch",
688 "duty",
689 "dwarf",
690 "dynamic",
691 "eager",
692 "eagle",
693 "early",
694 "earn",
695 "earth",
696 "easily",
697 "east",
698 "easy",
699 "echo",
700 "ecology",
701 "economy",
702 "edge",
703 "edit",
704 "educate",
705 "effort",
706 "egg",
707 "eight",
708 "elbow",
709 "elder",
710 "electric",
711 "elegant",
712 "element",
713 "elephant",
714 "elevator",
715 "elite",
716 "else",
717 "embark",
718 "embody",
719 "embrace",
720 "emerge",
721 "emotion",
722 "employ",
723 "empower",
724 "empty",
725 "enable",
726 "enact",
727 "end",
728 "endless",
729 "endorse",
730 "enemy",
731 "energy",
732 "enforce",
733 "engage",
734 "engine",
735 "enhance",
736 "enjoy",
737 "enlist",
738 "enough",
739 "enrich",
740 "enroll",
741 "ensure",
742 "enter",
743 "entire",
744 "entry",
745 "envelope",
746 "episode",
747 "equal",
748 "equip",
749 "era",
750 "erase",
751 "erode",
752 "erosion",
753 "error",
754 "erupt",
755 "escape",
756 "essay",
757 "essence",
758 "estate",
759 "eternal",
760 "ethics",
761 "evidence",
762 "evil",
763 "evoke",
764 "evolve",
765 "exact",
766 "example",
767 "excess",
768 "exchange",
769 "excite",
770 "exclude",
771 "excuse",
772 "execute",
773 "exercise",
774 "exhaust",
775 "exhibit",
776 "exile",
777 "exist",
778 "exit",
779 "exotic",
780 "expand",
781 "expect",
782 "expire",
783 "explain",
784 "expose",
785 "express",
786 "extend",
787 "extra",
788 "eye",
789 "eyebrow",
790 "fabric",
791 "face",
792 "faculty",
793 "fade",
794 "faint",
795 "faith",
796 "fall",
797 "false",
798 "fame",
799 "family",
800 "famous",
801 "fan",
802 "fancy",
803 "fantasy",
804 "farm",
805 "fashion",
806 "fat",
807 "fatal",
808 "father",
809 "fatigue",
810 "fault",
811 "favorite",
812 "feature",
813 "february",
814 "federal",
815 "fee",
816 "feed",
817 "feel",
818 "female",
819 "fence",
820 "festival",
821 "fetch",
822 "fever",
823 "few",
824 "fiber",
825 "fiction",
826 "field",
827 "figure",
828 "file",
829 "film",
830 "filter",
831 "final",
832 "find",
833 "fine",
834 "finger",
835 "finish",
836 "fire",
837 "firm",
838 "first",
839 "fiscal",
840 "fish",
841 "fit",
842 "fitness",
843 "fix",
844 "flag",
845 "flame",
846 "flash",
847 "flat",
848 "flavor",
849 "flee",
850 "flight",
851 "flip",
852 "float",
853 "flock",
854 "floor",
855 "flower",
856 "fluid",
857 "flush",
858 "fly",
859 "foam",
860 "focus",
861 "fog",
862 "foil",
863 "fold",
864 "follow",
865 "food",
866 "foot",
867 "force",
868 "forest",
869 "forget",
870 "fork",
871 "fortune",
872 "forum",
873 "forward",
874 "fossil",
875 "foster",
876 "found",
877 "fox",
878 "fragile",
879 "frame",
880 "frequent",
881 "fresh",
882 "friend",
883 "fringe",
884 "frog",
885 "front",
886 "frost",
887 "frown",
888 "frozen",
889 "fruit",
890 "fuel",
891 "fun",
892 "funny",
893 "furnace",
894 "fury",
895 "future",
896 "gadget",
897 "gain",
898 "galaxy",
899 "gallery",
900 "game",
901 "gap",
902 "garage",
903 "garbage",
904 "garden",
905 "garlic",
906 "garment",
907 "gas",
908 "gasp",
909 "gate",
910 "gather",
911 "gauge",
912 "gaze",
913 "general",
914 "genius",
915 "genre",
916 "gentle",
917 "genuine",
918 "gesture",
919 "ghost",
920 "giant",
921 "gift",
922 "giggle",
923 "ginger",
924 "giraffe",
925 "girl",
926 "give",
927 "glad",
928 "glance",
929 "glare",
930 "glass",
931 "glide",
932 "glimpse",
933 "globe",
934 "gloom",
935 "glory",
936 "glove",
937 "glow",
938 "glue",
939 "goat",
940 "goddess",
941 "gold",
942 "good",
943 "goose",
944 "gorilla",
945 "gospel",
946 "gossip",
947 "govern",
948 "gown",
949 "grab",
950 "grace",
951 "grain",
952 "grant",
953 "grape",
954 "grass",
955 "gravity",
956 "great",
957 "green",
958 "grid",
959 "grief",
960 "grit",
961 "grocery",
962 "group",
963 "grow",
964 "grunt",
965 "guard",
966 "guess",
967 "guide",
968 "guilt",
969 "guitar",
970 "gun",
971 "gym",
972 "habit",
973 "hair",
974 "half",
975 "hammer",
976 "hamster",
977 "hand",
978 "handle",
979 "harbor",
980 "hard",
981 "harsh",
982 "harvest",
983 "hat",
984 "have",
985 "hawk",
986 "hazard",
987 "head",
988 "health",
989 "heart",
990 "heavy",
991 "hedgehog",
992 "height",
993 "hello",
994 "helmet",
995 "help",
996 "hen",
997 "hero",
998 "hidden",
999 "high",
1000 "hill",
1001 "hint",
1002 "hip",
1003 "hire",
1004 "history",
1005 "hobby",
1006 "hockey",
1007 "hold",
1008 "hole",
1009 "holiday",
1010 "hollow",
1011 "home",
1012 "honey",
1013 "hood",
1014 "hope",
1015 "horn",
1016 "horror",
1017 "horse",
1018 "hospital",
1019 "host",
1020 "hotel",
1021 "hour",
1022 "hover",
1023 "hub",
1024 "huge",
1025 "human",
1026 "humble",
1027 "humor",
1028 "hundred",
1029 "hungry",
1030 "hunt",
1031 "hurdle",
1032 "hurry",
1033 "hurt",
1034 "husband",
1035 "hybrid",
1036 "ice",
1037 "icon",
1038 "idea",
1039 "identify",
1040 "idle",
1041 "ignore",
1042 "ill",
1043 "illegal",
1044 "illness",
1045 "image",
1046 "imitate",
1047 "immense",
1048 "immune",
1049 "impact",
1050 "impose",
1051 "improve",
1052 "impulse",
1053 "inch",
1054 "include",
1055 "income",
1056 "increase",
1057 "index",
1058 "indicate",
1059 "indoor",
1060 "industry",
1061 "infant",
1062 "inflict",
1063 "inform",
1064 "inhale",
1065 "inherit",
1066 "initial",
1067 "inject",
1068 "injury",
1069 "inmate",
1070 "inner",
1071 "innocent",
1072 "input",
1073 "inquiry",
1074 "insane",
1075 "insect",
1076 "inside",
1077 "inspire",
1078 "install",
1079 "intact",
1080 "interest",
1081 "into",
1082 "invest",
1083 "invite",
1084 "involve",
1085 "iron",
1086 "island",
1087 "isolate",
1088 "issue",
1089 "item",
1090 "ivory",
1091 "jacket",
1092 "jaguar",
1093 "jar",
1094 "jazz",
1095 "jealous",
1096 "jeans",
1097 "jelly",
1098 "jewel",
1099 "job",
1100 "join",
1101 "joke",
1102 "journey",
1103 "joy",
1104 "judge",
1105 "juggle",
1106 "juice",
1107 "jump",
1108 "jungle",
1109 "junior",
1110 "junk",
1111 "just",
1112 "kangaroo",
1113 "keen",
1114 "keep",
1115 "ketchup",
1116 "key",
1117 "kick",
1118 "kid",
1119 "kidney",
1120 "kind",
1121 "kingdom",
1122 "kiss",
1123 "kit",
1124 "kitchen",
1125 "kite",
1126 "kitten",
1127 "kiwi",
1128 "knee",
1129 "knife",
1130 "knock",
1131 "know",
1132 "lab",
1133 "label",
1134 "labor",
1135 "ladder",
1136 "lady",
1137 "lake",
1138 "lamp",
1139 "language",
1140 "laptop",
1141 "large",
1142 "later",
1143 "latin",
1144 "laugh",
1145 "laundry",
1146 "lava",
1147 "law",
1148 "lawn",
1149 "lawsuit",
1150 "layer",
1151 "lazy",
1152 "leader",
1153 "leaf",
1154 "learn",
1155 "leave",
1156 "lecture",
1157 "left",
1158 "leg",
1159 "legal",
1160 "legend",
1161 "leisure",
1162 "lemon",
1163 "lend",
1164 "length",
1165 "lens",
1166 "leopard",
1167 "lesson",
1168 "letter",
1169 "level",
1170 "liar",
1171 "liberty",
1172 "library",
1173 "license",
1174 "life",
1175 "lift",
1176 "light",
1177 "like",
1178 "limb",
1179 "limit",
1180 "link",
1181 "lion",
1182 "liquid",
1183 "list",
1184 "little",
1185 "live",
1186 "lizard",
1187 "load",
1188 "loan",
1189 "lobster",
1190 "local",
1191 "lock",
1192 "logic",
1193 "lonely",
1194 "long",
1195 "loop",
1196 "lottery",
1197 "loud",
1198 "lounge",
1199 "love",
1200 "loyal",
1201 "lucky",
1202 "luggage",
1203 "lumber",
1204 "lunar",
1205 "lunch",
1206 "luxury",
1207 "lyrics",
1208 "machine",
1209 "mad",
1210 "magic",
1211 "magnet",
1212 "maid",
1213 "mail",
1214 "main",
1215 "major",
1216 "make",
1217 "mammal",
1218 "man",
1219 "manage",
1220 "mandate",
1221 "mango",
1222 "mansion",
1223 "manual",
1224 "maple",
1225 "marble",
1226 "march",
1227 "margin",
1228 "marine",
1229 "market",
1230 "marriage",
1231 "mask",
1232 "mass",
1233 "master",
1234 "match",
1235 "material",
1236 "math",
1237 "matrix",
1238 "matter",
1239 "maximum",
1240 "maze",
1241 "meadow",
1242 "mean",
1243 "measure",
1244 "meat",
1245 "mechanic",
1246 "medal",
1247 "media",
1248 "melody",
1249 "melt",
1250 "member",
1251 "memory",
1252 "mention",
1253 "menu",
1254 "mercy",
1255 "merge",
1256 "merit",
1257 "merry",
1258 "mesh",
1259 "message",
1260 "metal",
1261 "method",
1262 "middle",
1263 "midnight",
1264 "milk",
1265 "million",
1266 "mimic",
1267 "mind",
1268 "minimum",
1269 "minor",
1270 "minute",
1271 "miracle",
1272 "mirror",
1273 "misery",
1274 "miss",
1275 "mistake",
1276 "mix",
1277 "mixed",
1278 "mixture",
1279 "mobile",
1280 "model",
1281 "modify",
1282 "mom",
1283 "moment",
1284 "monitor",
1285 "monkey",
1286 "monster",
1287 "month",
1288 "moon",
1289 "moral",
1290 "more",
1291 "morning",
1292 "mosquito",
1293 "mother",
1294 "motion",
1295 "motor",
1296 "mountain",
1297 "mouse",
1298 "move",
1299 "movie",
1300 "much",
1301 "muffin",
1302 "mule",
1303 "multiply",
1304 "muscle",
1305 "museum",
1306 "mushroom",
1307 "music",
1308 "must",
1309 "mutual",
1310 "myself",
1311 "mystery",
1312 "myth",
1313 "naive",
1314 "name",
1315 "napkin",
1316 "narrow",
1317 "nasty",
1318 "nation",
1319 "nature",
1320 "near",
1321 "neck",
1322 "need",
1323 "negative",
1324 "neglect",
1325 "neither",
1326 "nephew",
1327 "nerve",
1328 "nest",
1329 "net",
1330 "network",
1331 "neutral",
1332 "never",
1333 "news",
1334 "next",
1335 "nice",
1336 "night",
1337 "noble",
1338 "noise",
1339 "nominee",
1340 "noodle",
1341 "normal",
1342 "north",
1343 "nose",
1344 "notable",
1345 "note",
1346 "nothing",
1347 "notice",
1348 "novel",
1349 "now",
1350 "nuclear",
1351 "number",
1352 "nurse",
1353 "nut",
1354 "oak",
1355 "obey",
1356 "object",
1357 "oblige",
1358 "obscure",
1359 "observe",
1360 "obtain",
1361 "obvious",
1362 "occur",
1363 "ocean",
1364 "october",
1365 "odor",
1366 "off",
1367 "offer",
1368 "office",
1369 "often",
1370 "oil",
1371 "okay",
1372 "old",
1373 "olive",
1374 "olympic",
1375 "omit",
1376 "once",
1377 "one",
1378 "onion",
1379 "online",
1380 "only",
1381 "open",
1382 "opera",
1383 "opinion",
1384 "oppose",
1385 "option",
1386 "orange",
1387 "orbit",
1388 "orchard",
1389 "order",
1390 "ordinary",
1391 "organ",
1392 "orient",
1393 "original",
1394 "orphan",
1395 "ostrich",
1396 "other",
1397 "outdoor",
1398 "outer",
1399 "output",
1400 "outside",
1401 "oval",
1402 "oven",
1403 "over",
1404 "own",
1405 "owner",
1406 "oxygen",
1407 "oyster",
1408 "ozone",
1409 "pact",
1410 "paddle",
1411 "page",
1412 "pair",
1413 "palace",
1414 "palm",
1415 "panda",
1416 "panel",
1417 "panic",
1418 "panther",
1419 "paper",
1420 "parade",
1421 "parent",
1422 "park",
1423 "parrot",
1424 "party",
1425 "pass",
1426 "patch",
1427 "path",
1428 "patient",
1429 "patrol",
1430 "pattern",
1431 "pause",
1432 "pave",
1433 "payment",
1434 "peace",
1435 "peanut",
1436 "pear",
1437 "peasant",
1438 "pelican",
1439 "pen",
1440 "penalty",
1441 "pencil",
1442 "people",
1443 "pepper",
1444 "perfect",
1445 "permit",
1446 "person",
1447 "pet",
1448 "phone",
1449 "photo",
1450 "phrase",
1451 "physical",
1452 "piano",
1453 "picnic",
1454 "picture",
1455 "piece",
1456 "pig",
1457 "pigeon",
1458 "pill",
1459 "pilot",
1460 "pink",
1461 "pioneer",
1462 "pipe",
1463 "pistol",
1464 "pitch",
1465 "pizza",
1466 "place",
1467 "planet",
1468 "plastic",
1469 "plate",
1470 "play",
1471 "please",
1472 "pledge",
1473 "pluck",
1474 "plug",
1475 "plunge",
1476 "poem",
1477 "poet",
1478 "point",
1479 "polar",
1480 "pole",
1481 "police",
1482 "pond",
1483 "pony",
1484 "pool",
1485 "popular",
1486 "portion",
1487 "position",
1488 "possible",
1489 "post",
1490 "potato",
1491 "pottery",
1492 "poverty",
1493 "powder",
1494 "power",
1495 "practice",
1496 "praise",
1497 "predict",
1498 "prefer",
1499 "prepare",
1500 "present",
1501 "pretty",
1502 "prevent",
1503 "price",
1504 "pride",
1505 "primary",
1506 "print",
1507 "priority",
1508 "prison",
1509 "private",
1510 "prize",
1511 "problem",
1512 "process",
1513 "produce",
1514 "profit",
1515 "program",
1516 "project",
1517 "promote",
1518 "proof",
1519 "property",
1520 "prosper",
1521 "protect",
1522 "proud",
1523 "provide",
1524 "public",
1525 "pudding",
1526 "pull",
1527 "pulp",
1528 "pulse",
1529 "pumpkin",
1530 "punch",
1531 "pupil",
1532 "puppy",
1533 "purchase",
1534 "purity",
1535 "purpose",
1536 "purse",
1537 "push",
1538 "put",
1539 "puzzle",
1540 "pyramid",
1541 "quality",
1542 "quantum",
1543 "quarter",
1544 "question",
1545 "quick",
1546 "quit",
1547 "quiz",
1548 "quote",
1549 "rabbit",
1550 "raccoon",
1551 "race",
1552 "rack",
1553 "radar",
1554 "radio",
1555 "rail",
1556 "rain",
1557 "raise",
1558 "rally",
1559 "ramp",
1560 "ranch",
1561 "random",
1562 "range",
1563 "rapid",
1564 "rare",
1565 "rate",
1566 "rather",
1567 "raven",
1568 "raw",
1569 "reach",
1570 "react",
1571 "read",
1572 "real",
1573 "realm",
1574 "reason",
1575 "rebel",
1576 "rebuild",
1577 "receipt",
1578 "receive",
1579 "recipe",
1580 "record",
1581 "recycle",
1582 "red",
1583 "reduce",
1584 "reflect",
1585 "reform",
1586 "refuge",
1587 "refuse",
1588 "region",
1589 "regret",
1590 "regular",
1591 "reject",
1592 "relax",
1593 "release",
1594 "relief",
1595 "rely",
1596 "remain",
1597 "remember",
1598 "remind",
1599 "remote",
1600 "remove",
1601 "render",
1602 "renew",
1603 "rent",
1604 "reopen",
1605 "repair",
1606 "repeat",
1607 "replace",
1608 "reply",
1609 "report",
1610 "represent",
1611 "reptile",
1612 "require",
1613 "rescue",
1614 "resemble",
1615 "resist",
1616 "resource",
1617 "response",
1618 "result",
1619 "retire",
1620 "retreat",
1621 "return",
1622 "reunion",
1623 "reveal",
1624 "review",
1625 "reward",
1626 "rhythm",
1627 "rib",
1628 "ribbon",
1629 "rice",
1630 "rich",
1631 "ride",
1632 "ridge",
1633 "rifle",
1634 "right",
1635 "rigid",
1636 "ring",
1637 "riot",
1638 "ripple",
1639 "risk",
1640 "ritual",
1641 "rival",
1642 "river",
1643 "road",
1644 "roast",
1645 "robot",
1646 "robust",
1647 "rocket",
1648 "romance",
1649 "roof",
1650 "rookie",
1651 "room",
1652 "rose",
1653 "rotate",
1654 "rough",
1655 "round",
1656 "route",
1657 "royal",
1658 "rubber",
1659 "rude",
1660 "rug",
1661 "rule",
1662 "run",
1663 "runway",
1664 "rural",
1665 "sad",
1666 "saddle",
1667 "sadness",
1668 "safe",
1669 "sail",
1670 "salad",
1671 "salmon",
1672 "salon",
1673 "salt",
1674 "salute",
1675 "same",
1676 "sample",
1677 "sand",
1678 "satisfy",
1679 "satoshi",
1680 "sauce",
1681 "sausage",
1682 "save",
1683 "say",
1684 "scale",
1685 "scan",
1686 "scare",
1687 "scatter",
1688 "scene",
1689 "scheme",
1690 "school",
1691 "science",
1692 "scissors",
1693 "scorpion",
1694 "scout",
1695 "scrap",
1696 "screen",
1697 "script",
1698 "scrub",
1699 "sea",
1700 "search",
1701 "season",
1702 "seat",
1703 "second",
1704 "secret",
1705 "section",
1706 "security",
1707 "seed",
1708 "seek",
1709 "segment",
1710 "select",
1711 "sell",
1712 "seminar",
1713 "senior",
1714 "sense",
1715 "sentence",
1716 "series",
1717 "service",
1718 "session",
1719 "settle",
1720 "setup",
1721 "seven",
1722 "shadow",
1723 "shaft",
1724 "shallow",
1725 "share",
1726 "shed",
1727 "shell",
1728 "sheriff",
1729 "shield",
1730 "shift",
1731 "shine",
1732 "ship",
1733 "shiver",
1734 "shock",
1735 "shoe",
1736 "shoot",
1737 "shop",
1738 "short",
1739 "shoulder",
1740 "shove",
1741 "shrimp",
1742 "shrug",
1743 "shuffle",
1744 "shy",
1745 "sibling",
1746 "sick",
1747 "side",
1748 "siege",
1749 "sight",
1750 "sign",
1751 "silent",
1752 "silk",
1753 "silly",
1754 "silver",
1755 "similar",
1756 "simple",
1757 "since",
1758 "sing",
1759 "siren",
1760 "sister",
1761 "sit",
1762 "situation",
1763 "six",
1764 "size",
1765 "skate",
1766 " sketch",
1767 "ski",
1768 "skill",
1769 "skin",
1770 "skirt",
1771 "skull",
1772 "slab",
1773 "slam",
1774 "sleep",
1775 "slender",
1776 "slice",
1777 "slide",
1778 "slight",
1779 "slim",
1780 "slogan",
1781 "slot",
1782 "slow",
1783 "slush",
1784 "small",
1785 "smart",
1786 "smile",
1787 "smoke",
1788 "smooth",
1789 "snack",
1790 "snake",
1791 "snap",
1792 "sniff",
1793 "snow",
1794 "soap",
1795 "soccer",
1796 "social",
1797 "sock",
1798 "soda",
1799 "soft",
1800 "solar",
1801 "soldier",
1802 "solid",
1803 "solution",
1804 "solve",
1805 "someone",
1806 "song",
1807 "soon",
1808 "sorry",
1809 "sort",
1810 "soul",
1811 "sound",
1812 "soup",
1813 "source",
1814 "south",
1815 "space",
1816 "spare",
1817 "spatial",
1818 "spawn",
1819 "speak",
1820 "special",
1821 "speed",
1822 "spell",
1823 "spend",
1824 "sphere",
1825 "spice",
1826 "spider",
1827 "spike",
1828 "spin",
1829 "spirit",
1830 "split",
1831 "spoil",
1832 "sponsor",
1833 "spoon",
1834 "sport",
1835 "spot",
1836 "spray",
1837 "spread",
1838 "spring",
1839 "spy",
1840 "square",
1841 "squeeze",
1842 "squirrel",
1843 "stable",
1844 "stadium",
1845 "staff",
1846 "stage",
1847 "stairs",
1848 "stamp",
1849 "stand",
1850 "start",
1851 "state",
1852 "stay",
1853 "steak",
1854 "steel",
1855 "stem",
1856 "step",
1857 "stereo",
1858 "stick",
1859 "still",
1860 "sting",
1861 "stock",
1862 "stomach",
1863 "stone",
1864 "stool",
1865 "story",
1866 "stove",
1867 "strategy",
1868 "street",
1869 "strike",
1870 "strong",
1871 "struggle",
1872 "student",
1873 "stuff",
1874 "stumble",
1875 "style",
1876 "subject",
1877 "submit",
1878 "subway",
1879 "success",
1880 "such",
1881 "sudden",
1882 "suffer",
1883 "sugar",
1884 "suggest",
1885 "suit",
1886 "summer",
1887 "sun",
1888 "sunny",
1889 "sunset",
1890 "super",
1891 "supply",
1892 "supreme",
1893 "sure",
1894 "surface",
1895 "surge",
1896 "surprise",
1897 "surround",
1898 "survey",
1899 "suspect",
1900 "sustain",
1901 "swallow",
1902 "swamp",
1903 "swap",
1904 "swarm",
1905 "swear",
1906 "sweet",
1907 "swift",
1908 "swim",
1909 "swing",
1910 "switch",
1911 "sword",
1912 "symbol",
1913 "symptom",
1914 "syrup",
1915 "system",
1916 "table",
1917 "tackle",
1918 "tag",
1919 "tail",
1920 "talent",
1921 "talk",
1922 "tank",
1923 "tape",
1924 "target",
1925 "task",
1926 "taste",
1927 "tattoo",
1928 "taxi",
1929 "teach",
1930 "team",
1931 "tell",
1932 "ten",
1933 "tenant",
1934 "tennis",
1935 "tent",
1936 "term",
1937 "test",
1938 "text",
1939 "thank",
1940 "that",
1941 "theme",
1942 "then",
1943 "theory",
1944 "there",
1945 "they",
1946 "thing",
1947 "this",
1948 "thought",
1949 "three",
1950 "thrive",
1951 "throw",
1952 "thumb",
1953 "thunder",
1954 "ticket",
1955 "tide",
1956 "tiger",
1957 "tilt",
1958 "timber",
1959 "time",
1960 "tiny",
1961 "tip",
1962 "tired",
1963 "tissue",
1964 "title",
1965 "toast",
1966 "tobacco",
1967 "today",
1968 "toddler",
1969 "toe",
1970 "together",
1971 "toilet",
1972 "token",
1973 "tomato",
1974 "tomorrow",
1975 "tone",
1976 "tongue",
1977 "tonight",
1978 "tool",
1979 "tooth",
1980 "top",
1981 "topic",
1982 "topple",
1983 "torch",
1984 "tornado",
1985 "tortoise",
1986 "toss",
1987 "total",
1988 "tourist",
1989 "toward",
1990 "tower",
1991 "town",
1992 "toy",
1993 "track",
1994 "trade",
1995 "traffic",
1996 "tragic",
1997 "train",
1998 "transfer",
1999 "trap",
2000 "trash",
2001 "travel",
2002 "tray",
2003 "treat",
2004 "tree",
2005 "trend",
2006 "trial",
2007 "tribe",
2008 "trick",
2009 "trigger",
2010 "trim",
2011 "trip",
2012 "trophy",
2013 "trouble",
2014 "truck",
2015 "true",
2016 "truly",
2017 "trumpet",
2018 "trust",
2019 "truth",
2020 "try",
2021 "tube",
2022 "tuition",
2023 "tumble",
2024 "tuna",
2025 "tunnel",
2026 "turkey",
2027 "turn",
2028 "turtle",
2029 "twelve",
2030 "twenty",
2031 "twice",
2032 "twin",
2033 "twist",
2034 "two",
2035 "type",
2036 "typical",
2037 "ugly",
2038 "umbrella",
2039 "unable",
2040 "unaware",
2041 "uncle",
2042 "uncover",
2043 "under",
2044 "undo",
2045 "unfair",
2046 "unfold",
2047 "unhappy",
2048 "uniform",
2049 "unique",
2050 "unit",
2051 "universe",
2052 "unknown",
2053 "unlock",
2054 "until",
2055 "unusual",
2056 "unveil",
2057 "update",
2058 "upgrade",
2059 "uphold",
2060 "upon",
2061 "upper",
2062 "upset",
2063 "urban",
2064 "urge",
2065 "usage",
2066 "use",
2067 "used",
2068 "useful",
2069 "useless",
2070 "user",
2071 "utility",
2072 "vacant",
2073 "vacuum",
2074 "vague",
2075 "valid",
2076 "valley",
2077 "valve",
2078 "van",
2079 "vanish",
2080 "vapor",
2081 "various",
2082 "vegan",
2083 "velvet",
2084 "vendor",
2085 "venture",
2086 "venue",
2087 "verb",
2088 "verify",
2089 "version",
2090 "very",
2091 "vessel",
2092 "veteran",
2093 "viable",
2094 "vibrant",
2095 "vicious",
2096 "victory",
2097 "video",
2098 "view",
2099 "village",
2100 "vintage",
2101 "violin",
2102 "virtual",
2103 "virus",
2104 "visa",
2105 "visit",
2106 "visual",
2107 "vital",
2108 "vivid",
2109 "vocal",
2110 "voice",
2111 "void",
2112 "volcano",
2113 "volume",
2114 "vote",
2115 "voyage",
2116 "wage",
2117 "wagon",
2118 "wait",
2119 "walk",
2120 "wall",
2121 "walnut",
2122 "want",
2123 "warfare",
2124 "warm",
2125 "warrior",
2126 "wash",
2127 "wasp",
2128 "waste",
2129 "water",
2130 "wave",
2131 "way",
2132 "wealth",
2133 "weapon",
2134 "wear",
2135 "weasel",
2136 "weather",
2137 "web",
2138 "wedding",
2139 "weekend",
2140 "weird",
2141 "welcome",
2142 "west",
2143 "wet",
2144 "whale",
2145 "what",
2146 "wheat",
2147 "wheel",
2148 "when",
2149 "where",
2150 "whip",
2151 "whisper",
2152 "wide",
2153 "width",
2154 "wife",
2155 "wild",
2156 "will",
2157 "win",
2158 "window",
2159 "wine",
2160 "wing",
2161 "wink",
2162 "winner",
2163 "winter",
2164 "wire",
2165 "wisdom",
2166 "wise",
2167 "wish",
2168 "witness",
2169 "wolf",
2170 "woman",
2171 "wonder",
2172 "wood",
2173 "wool",
2174 "word",
2175 "work",
2176 "world",
2177 "worry",
2178 "worth",
2179 "wrap",
2180 "wreck",
2181 "wrestle",
2182 "wrist",
2183 "write",
2184 "wrong",
2185 "yard",
2186 "year",
2187 "yellow",
2188 "you",
2189 "young",
2190 "youth",
2191 "zebra",
2192 "zero",
2193 "zone",
2194 "zoo",
2195 ];
2196
2197 use rand::Rng;
2198 let mut rng = rand::thread_rng();
2199 let mut phrase = Vec::new();
2200 for _ in 0..12 {
2201 phrase.push(WORDS[rng.gen_range(0..WORDS.len())]);
2202 }
2203 phrase.join(" ")
2204 }
2205
2206 fn derive_keys(seed: &str) -> (String, String) {
2207 let mut hasher = Sha256::new();
2208 hasher.update(seed.as_bytes());
2209 let hash_result = hasher.finalize();
2210
2211 let mut key_bytes = [0u8; 32];
2212 key_bytes.copy_from_slice(&hash_result[..32]);
2213
2214 let signing_key = SigningKey::from_bytes(&key_bytes);
2215 let verifying_key: VerifyingKey = signing_key.verifying_key();
2216
2217 let private_key_hex = hex::encode(signing_key.to_bytes());
2218 let address = hex::encode(&verifying_key.as_bytes()[1..]);
2219
2220 let formatted_address = format!("0x{}", address);
2221 let formatted_private_key = format!("0x{}", private_key_hex);
2222
2223 (formatted_private_key, formatted_address)
2224 }
2225
2226 fn derive_address_from_public_key(public_key_bytes: &[u8]) -> String {
2227 let address = hex::encode(&public_key_bytes[1..]);
2228 format!("0x{}", address)
2229 }
2230}
2231
2232impl Default for Wallet {
2233 fn default() -> Self {
2234 Wallet {
2235 address: "0x0000000000000000000000000000000000000000000000000000000000000000"
2236 .to_string(),
2237 private_key: "0x0000000000000000000000000000000000000000000000000000000000000000"
2238 .to_string(),
2239 network: "testnet".to_string(),
2240 seed_phrase: String::new(),
2241 }
2242 }
2243}