Skip to main content

x402_cli/x402/
wallet.rs

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}