solforge 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +471 -79
  2. package/cli.cjs +106 -78
  3. package/package.json +1 -1
  4. package/scripts/install.sh +1 -1
  5. package/scripts/postinstall.cjs +66 -58
  6. package/server/methods/program/get-token-accounts-by-owner.ts +7 -2
  7. package/server/ws-server.ts +4 -1
  8. package/src/api-server-entry.ts +91 -91
  9. package/src/cli/commands/rpc-start.ts +4 -1
  10. package/src/cli/main.ts +7 -3
  11. package/src/cli/run-solforge.ts +20 -6
  12. package/src/commands/add-program.ts +324 -328
  13. package/src/commands/init.ts +106 -106
  14. package/src/commands/list.ts +125 -125
  15. package/src/commands/mint.ts +246 -246
  16. package/src/commands/start.ts +834 -831
  17. package/src/commands/status.ts +80 -80
  18. package/src/commands/stop.ts +381 -382
  19. package/src/config/manager.ts +149 -149
  20. package/src/gui/public/app.css +1556 -1
  21. package/src/gui/public/build/main.css +1569 -1
  22. package/src/gui/server.ts +20 -21
  23. package/src/gui/src/app.tsx +56 -37
  24. package/src/gui/src/components/airdrop-mint-form.tsx +17 -11
  25. package/src/gui/src/components/clone-program-modal.tsx +6 -6
  26. package/src/gui/src/components/clone-token-modal.tsx +7 -7
  27. package/src/gui/src/components/modal.tsx +13 -11
  28. package/src/gui/src/components/programs-panel.tsx +27 -15
  29. package/src/gui/src/components/status-panel.tsx +31 -17
  30. package/src/gui/src/components/tokens-panel.tsx +25 -19
  31. package/src/gui/src/index.css +491 -463
  32. package/src/index.ts +161 -146
  33. package/src/rpc/start.ts +1 -1
  34. package/src/services/api-server.ts +470 -473
  35. package/src/services/port-manager.ts +167 -167
  36. package/src/services/process-registry.ts +143 -143
  37. package/src/services/program-cloner.ts +312 -312
  38. package/src/services/token-cloner.ts +799 -797
  39. package/src/services/validator.ts +288 -288
  40. package/src/types/config.ts +71 -71
  41. package/src/utils/shell.ts +75 -75
  42. package/src/utils/token-loader.ts +77 -77
@@ -18,20 +18,22 @@ export function StatusPanel({ status, loading, onRefresh }: Props) {
18
18
  </div>
19
19
  <div>
20
20
  <h2 className="text-xl font-bold text-white">Network Status</h2>
21
- <p className="text-xs text-gray-500">Real-time blockchain metrics</p>
21
+ <p className="text-xs text-gray-500">
22
+ Real-time blockchain metrics
23
+ </p>
22
24
  </div>
23
25
  </div>
24
26
  <button
25
27
  type="button"
26
28
  onClick={onRefresh}
27
29
  disabled={loading}
28
- className={`btn-secondary ${loading ? 'opacity-50 cursor-not-allowed' : ''}`}
30
+ className={`btn-secondary ${loading ? "opacity-50 cursor-not-allowed" : ""}`}
29
31
  >
30
- <i className={`fas fa-sync-alt ${loading ? 'animate-spin' : ''}`}></i>
32
+ <i className={`fas fa-sync-alt ${loading ? "animate-spin" : ""}`}></i>
31
33
  <span>{loading ? "Refreshing" : "Refresh"}</span>
32
34
  </button>
33
35
  </div>
34
-
36
+
35
37
  {status ? (
36
38
  <>
37
39
  <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
@@ -64,14 +66,18 @@ export function StatusPanel({ status, loading, onRefresh }: Props) {
64
66
  color="green"
65
67
  />
66
68
  </div>
67
-
69
+
68
70
  {status.latestBlockhash && (
69
71
  <div className="mt-6 p-4 rounded-xl bg-white/5 border border-white/10">
70
72
  <div className="flex items-center gap-2 mb-2">
71
73
  <i className="fas fa-fingerprint text-violet-400 text-xs"></i>
72
- <span className="text-xs font-semibold text-gray-400 uppercase tracking-wider">Latest Blockhash</span>
74
+ <span className="text-xs font-semibold text-gray-400 uppercase tracking-wider">
75
+ Latest Blockhash
76
+ </span>
73
77
  </div>
74
- <p className="text-sm font-mono text-violet-300 break-all">{status.latestBlockhash}</p>
78
+ <p className="text-sm font-mono text-violet-300 break-all">
79
+ {status.latestBlockhash}
80
+ </p>
75
81
  </div>
76
82
  )}
77
83
  </>
@@ -81,7 +87,9 @@ export function StatusPanel({ status, loading, onRefresh }: Props) {
81
87
  <i className="fas fa-server text-gray-500 text-2xl"></i>
82
88
  </div>
83
89
  <p className="text-gray-400 mb-2">No connection to RPC</p>
84
- <p className="text-sm text-gray-500">Start the RPC server to see network status</p>
90
+ <p className="text-sm text-gray-500">
91
+ Start the RPC server to see network status
92
+ </p>
85
93
  </div>
86
94
  )}
87
95
  </section>
@@ -93,30 +101,36 @@ interface StatusCardProps {
93
101
  value: string;
94
102
  subtitle?: string;
95
103
  icon: string;
96
- color: 'purple' | 'blue' | 'amber' | 'green';
104
+ color: "purple" | "blue" | "amber" | "green";
97
105
  }
98
106
 
99
107
  const colorClasses = {
100
- purple: 'from-purple-500/20 to-violet-500/20 text-purple-400',
101
- blue: 'from-blue-500/20 to-cyan-500/20 text-blue-400',
102
- amber: 'from-amber-500/20 to-orange-500/20 text-amber-400',
103
- green: 'from-green-500/20 to-emerald-500/20 text-green-400',
108
+ purple: "from-purple-500/20 to-violet-500/20 text-purple-400",
109
+ blue: "from-blue-500/20 to-cyan-500/20 text-blue-400",
110
+ amber: "from-amber-500/20 to-orange-500/20 text-amber-400",
111
+ green: "from-green-500/20 to-emerald-500/20 text-green-400",
104
112
  };
105
113
 
106
114
  function StatusCard({ title, value, subtitle, icon, color }: StatusCardProps) {
107
115
  return (
108
116
  <div className="card group hover:scale-[1.02] transition-all duration-200">
109
117
  <div className="flex items-start justify-between mb-3">
110
- <div className={`w-10 h-10 rounded-xl bg-gradient-to-br ${colorClasses[color]} flex items-center justify-center group-hover:scale-110 transition-transform`}>
118
+ <div
119
+ className={`w-10 h-10 rounded-xl bg-gradient-to-br ${colorClasses[color]} flex items-center justify-center group-hover:scale-110 transition-transform`}
120
+ >
111
121
  <i className={`fas ${icon} text-sm`}></i>
112
122
  </div>
113
123
  <span className="status-dot online"></span>
114
124
  </div>
115
- <p className="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-1">{title}</p>
125
+ <p className="text-xs font-semibold text-gray-500 uppercase tracking-wider mb-1">
126
+ {title}
127
+ </p>
116
128
  <p className="text-2xl font-bold text-white">{value}</p>
117
129
  {subtitle && (
118
- <p className="mt-2 text-xs text-gray-500 font-mono truncate">{subtitle}</p>
130
+ <p className="mt-2 text-xs text-gray-500 font-mono truncate">
131
+ {subtitle}
132
+ </p>
119
133
  )}
120
134
  </div>
121
135
  );
122
- }
136
+ }
@@ -17,9 +17,7 @@ export function TokensPanel({ tokens, loading, onRefresh, onAdd }: Props) {
17
17
  </div>
18
18
  <div>
19
19
  <h2 className="text-xl font-bold text-white">Tokens</h2>
20
- <p className="text-xs text-gray-500">
21
- {tokens.length} SPL tokens
22
- </p>
20
+ <p className="text-xs text-gray-500">{tokens.length} SPL tokens</p>
23
21
  </div>
24
22
  </div>
25
23
  <div className="flex items-center gap-2">
@@ -27,22 +25,20 @@ export function TokensPanel({ tokens, loading, onRefresh, onAdd }: Props) {
27
25
  type="button"
28
26
  onClick={onRefresh}
29
27
  disabled={loading}
30
- className={`btn-secondary text-sm ${loading ? 'opacity-50 cursor-not-allowed' : ''}`}
28
+ className={`btn-secondary text-sm ${loading ? "opacity-50 cursor-not-allowed" : ""}`}
31
29
  >
32
- <i className={`fas fa-sync-alt ${loading ? 'animate-spin' : ''}`}></i>
30
+ <i
31
+ className={`fas fa-sync-alt ${loading ? "animate-spin" : ""}`}
32
+ ></i>
33
33
  <span>{loading ? "Refreshing" : "Refresh"}</span>
34
34
  </button>
35
- <button
36
- type="button"
37
- onClick={onAdd}
38
- className="btn-primary text-sm"
39
- >
35
+ <button type="button" onClick={onAdd} className="btn-primary text-sm">
40
36
  <i className="fas fa-plus"></i>
41
37
  <span>Add Token</span>
42
38
  </button>
43
39
  </div>
44
40
  </header>
45
-
41
+
46
42
  <div className="overflow-x-auto rounded-xl">
47
43
  {tokens.length === 0 ? (
48
44
  <div className="flex flex-col items-center justify-center py-12 text-center">
@@ -50,7 +46,9 @@ export function TokensPanel({ tokens, loading, onRefresh, onAdd }: Props) {
50
46
  <i className="fas fa-coins text-amber-500 text-2xl"></i>
51
47
  </div>
52
48
  <p className="text-gray-400 mb-2">No tokens created</p>
53
- <p className="text-sm text-gray-500">Click "Add Token" to clone from mainnet</p>
49
+ <p className="text-sm text-gray-500">
50
+ Click "Add Token" to clone from mainnet
51
+ </p>
54
52
  </div>
55
53
  ) : (
56
54
  <table className="table-modern">
@@ -65,7 +63,11 @@ export function TokensPanel({ tokens, loading, onRefresh, onAdd }: Props) {
65
63
  </thead>
66
64
  <tbody>
67
65
  {tokens.map((token, index) => (
68
- <tr key={token.mint} style={{animationDelay: `${index * 50}ms`}} className="animate-fadeIn">
66
+ <tr
67
+ key={token.mint}
68
+ style={{ animationDelay: `${index * 50}ms` }}
69
+ className="animate-fadeIn"
70
+ >
69
71
  <td>
70
72
  <div className="flex items-center gap-2">
71
73
  <i className="fas fa-coin text-amber-400 text-xs"></i>
@@ -83,9 +85,7 @@ export function TokensPanel({ tokens, loading, onRefresh, onAdd }: Props) {
83
85
  </div>
84
86
  </td>
85
87
  <td>
86
- <span className="badge">
87
- {token.decimals}
88
- </span>
88
+ <span className="badge">{token.decimals}</span>
89
89
  </td>
90
90
  <td>
91
91
  {token.mintAuthority ? (
@@ -96,12 +96,18 @@ export function TokensPanel({ tokens, loading, onRefresh, onAdd }: Props) {
96
96
  </span>
97
97
  </div>
98
98
  ) : (
99
- <span className="text-gray-500 text-sm">No authority</span>
99
+ <span className="text-gray-500 text-sm">
100
+ No authority
101
+ </span>
100
102
  )}
101
103
  </td>
102
104
  <td>
103
- <span className={`badge ${token.isInitialized ? 'badge-success' : 'badge-warning'}`}>
104
- <i className={`fas fa-${token.isInitialized ? 'check-circle' : 'clock'} text-xs`}></i>
105
+ <span
106
+ className={`badge ${token.isInitialized ? "badge-success" : "badge-warning"}`}
107
+ >
108
+ <i
109
+ className={`fas fa-${token.isInitialized ? "check-circle" : "clock"} text-xs`}
110
+ ></i>
105
111
  <span>{token.isInitialized ? "Active" : "Pending"}</span>
106
112
  </span>
107
113
  </td>