solforge 0.1.7 → 0.2.1

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 (151) hide show
  1. package/README.md +367 -393
  2. package/docs/API.md +379 -0
  3. package/docs/CONFIGURATION.md +407 -0
  4. package/docs/bun-single-file-executable.md +585 -0
  5. package/docs/cli-plan.md +154 -0
  6. package/docs/data-indexing-plan.md +214 -0
  7. package/docs/gui-roadmap.md +202 -0
  8. package/package.json +38 -51
  9. package/server/index.ts +5 -0
  10. package/server/lib/base58.ts +33 -0
  11. package/server/lib/faucet.ts +110 -0
  12. package/server/lib/spl-token.ts +57 -0
  13. package/server/methods/TEMPLATE.md +117 -0
  14. package/server/methods/account/get-account-info.ts +90 -0
  15. package/server/methods/account/get-balance.ts +27 -0
  16. package/server/methods/account/get-multiple-accounts.ts +83 -0
  17. package/server/methods/account/get-parsed-account-info.ts +21 -0
  18. package/server/methods/account/index.ts +12 -0
  19. package/server/methods/account/parsers/index.ts +52 -0
  20. package/server/methods/account/parsers/loader-upgradeable.ts +66 -0
  21. package/server/methods/account/parsers/spl-token.ts +237 -0
  22. package/server/methods/account/parsers/system.ts +4 -0
  23. package/server/methods/account/request-airdrop.ts +219 -0
  24. package/server/methods/admin/adopt-mint-authority.ts +94 -0
  25. package/server/methods/admin/clone-program-accounts.ts +55 -0
  26. package/server/methods/admin/clone-program.ts +152 -0
  27. package/server/methods/admin/clone-token-accounts.ts +117 -0
  28. package/server/methods/admin/clone-token-mint.ts +82 -0
  29. package/server/methods/admin/create-mint.ts +114 -0
  30. package/server/methods/admin/create-token-account.ts +137 -0
  31. package/server/methods/admin/helpers.ts +70 -0
  32. package/server/methods/admin/index.ts +10 -0
  33. package/server/methods/admin/list-mints.ts +21 -0
  34. package/server/methods/admin/load-program.ts +52 -0
  35. package/server/methods/admin/mint-to.ts +278 -0
  36. package/server/methods/block/get-block-height.ts +5 -0
  37. package/server/methods/block/get-block.ts +35 -0
  38. package/server/methods/block/get-blocks-with-limit.ts +23 -0
  39. package/server/methods/block/get-latest-blockhash.ts +12 -0
  40. package/server/methods/block/get-slot.ts +5 -0
  41. package/server/methods/block/index.ts +6 -0
  42. package/server/methods/block/is-blockhash-valid.ts +23 -0
  43. package/server/methods/epoch/get-cluster-nodes.ts +17 -0
  44. package/server/methods/epoch/get-epoch-info.ts +16 -0
  45. package/server/methods/epoch/get-epoch-schedule.ts +15 -0
  46. package/server/methods/epoch/get-highest-snapshot-slot.ts +9 -0
  47. package/server/methods/epoch/get-leader-schedule.ts +8 -0
  48. package/server/methods/epoch/get-max-retransmit-slot.ts +9 -0
  49. package/server/methods/epoch/get-max-shred-insert-slot.ts +9 -0
  50. package/server/methods/epoch/get-slot-leader.ts +6 -0
  51. package/server/methods/epoch/get-slot-leaders.ts +9 -0
  52. package/server/methods/epoch/get-stake-activation.ts +9 -0
  53. package/server/methods/epoch/get-stake-minimum-delegation.ts +9 -0
  54. package/server/methods/epoch/get-vote-accounts.ts +19 -0
  55. package/server/methods/epoch/index.ts +13 -0
  56. package/server/methods/epoch/minimum-ledger-slot.ts +5 -0
  57. package/server/methods/fee/get-fee-calculator-for-blockhash.ts +12 -0
  58. package/server/methods/fee/get-fee-for-message.ts +8 -0
  59. package/server/methods/fee/get-fee-rate-governor.ts +16 -0
  60. package/server/methods/fee/get-fees.ts +14 -0
  61. package/server/methods/fee/get-recent-prioritization-fees.ts +22 -0
  62. package/server/methods/fee/index.ts +5 -0
  63. package/server/methods/get-address-lookup-table.ts +31 -0
  64. package/server/methods/index.ts +265 -0
  65. package/server/methods/performance/get-recent-performance-samples.ts +25 -0
  66. package/server/methods/performance/get-transaction-count.ts +5 -0
  67. package/server/methods/performance/index.ts +2 -0
  68. package/server/methods/program/get-block-commitment.ts +9 -0
  69. package/server/methods/program/get-block-production.ts +14 -0
  70. package/server/methods/program/get-block-time.ts +21 -0
  71. package/server/methods/program/get-blocks.ts +11 -0
  72. package/server/methods/program/get-first-available-block.ts +9 -0
  73. package/server/methods/program/get-genesis-hash.ts +6 -0
  74. package/server/methods/program/get-identity.ts +6 -0
  75. package/server/methods/program/get-inflation-governor.ts +15 -0
  76. package/server/methods/program/get-inflation-rate.ts +10 -0
  77. package/server/methods/program/get-inflation-reward.ts +12 -0
  78. package/server/methods/program/get-largest-accounts.ts +8 -0
  79. package/server/methods/program/get-parsed-program-accounts.ts +12 -0
  80. package/server/methods/program/get-parsed-token-accounts-by-delegate.ts +12 -0
  81. package/server/methods/program/get-parsed-token-accounts-by-owner.ts +12 -0
  82. package/server/methods/program/get-program-accounts.ts +221 -0
  83. package/server/methods/program/get-supply.ts +13 -0
  84. package/server/methods/program/get-token-account-balance.ts +64 -0
  85. package/server/methods/program/get-token-accounts-by-delegate.ts +81 -0
  86. package/server/methods/program/get-token-accounts-by-owner.ts +390 -0
  87. package/server/methods/program/get-token-largest-accounts.ts +80 -0
  88. package/server/methods/program/get-token-supply.ts +38 -0
  89. package/server/methods/program/index.ts +21 -0
  90. package/server/methods/solforge/index.ts +155 -0
  91. package/server/methods/system/get-health.ts +5 -0
  92. package/server/methods/system/get-minimum-balance-for-rent-exemption.ts +13 -0
  93. package/server/methods/system/get-version.ts +9 -0
  94. package/server/methods/system/index.ts +3 -0
  95. package/server/methods/transaction/get-confirmed-transaction.ts +11 -0
  96. package/server/methods/transaction/get-parsed-transaction.ts +21 -0
  97. package/server/methods/transaction/get-signature-statuses.ts +72 -0
  98. package/server/methods/transaction/get-signatures-for-address.ts +45 -0
  99. package/server/methods/transaction/get-transaction.ts +428 -0
  100. package/server/methods/transaction/index.ts +7 -0
  101. package/server/methods/transaction/send-transaction.ts +232 -0
  102. package/server/methods/transaction/simulate-transaction.ts +56 -0
  103. package/server/rpc-server.ts +474 -0
  104. package/server/types.ts +74 -0
  105. package/server/ws-server.ts +171 -0
  106. package/src/cli/bootstrap.ts +67 -0
  107. package/src/cli/commands/airdrop.ts +37 -0
  108. package/src/cli/commands/config.ts +39 -0
  109. package/src/cli/commands/mint.ts +187 -0
  110. package/src/cli/commands/program-clone.ts +124 -0
  111. package/src/cli/commands/program-load.ts +64 -0
  112. package/src/cli/commands/rpc-start.ts +46 -0
  113. package/src/cli/commands/token-adopt-authority.ts +37 -0
  114. package/src/cli/commands/token-clone.ts +113 -0
  115. package/src/cli/commands/token-create.ts +81 -0
  116. package/src/cli/main.ts +130 -0
  117. package/src/cli/run-solforge.ts +98 -0
  118. package/src/cli/setup-utils.ts +54 -0
  119. package/src/cli/setup-wizard.ts +256 -0
  120. package/src/cli/utils/args.ts +15 -0
  121. package/src/config/index.ts +130 -0
  122. package/src/db/index.ts +83 -0
  123. package/src/db/schema/accounts.ts +23 -0
  124. package/src/db/schema/address-signatures.ts +31 -0
  125. package/src/db/schema/index.ts +5 -0
  126. package/src/db/schema/meta-kv.ts +9 -0
  127. package/src/db/schema/transactions.ts +29 -0
  128. package/src/db/schema/tx-accounts.ts +33 -0
  129. package/src/db/tx-store.ts +229 -0
  130. package/src/gui/public/app.css +1 -0
  131. package/src/gui/public/build/main.css +1 -0
  132. package/src/gui/public/build/main.js +303 -0
  133. package/src/gui/public/build/main.js.txt +231 -0
  134. package/src/gui/public/index.html +19 -0
  135. package/src/gui/server.ts +297 -0
  136. package/src/gui/src/api.ts +127 -0
  137. package/src/gui/src/app.tsx +390 -0
  138. package/src/gui/src/components/airdrop-mint-form.tsx +216 -0
  139. package/src/gui/src/components/clone-program-modal.tsx +183 -0
  140. package/src/gui/src/components/clone-token-modal.tsx +211 -0
  141. package/src/gui/src/components/modal.tsx +127 -0
  142. package/src/gui/src/components/programs-panel.tsx +112 -0
  143. package/src/gui/src/components/status-panel.tsx +122 -0
  144. package/src/gui/src/components/tokens-panel.tsx +116 -0
  145. package/src/gui/src/hooks/use-interval.ts +17 -0
  146. package/src/gui/src/index.css +529 -0
  147. package/src/gui/src/main.tsx +17 -0
  148. package/src/migrations-bundled.ts +17 -0
  149. package/src/rpc/start.ts +44 -0
  150. package/scripts/postinstall.cjs +0 -103
  151. package/tsconfig.json +0 -28
@@ -0,0 +1,529 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ :root {
6
+ color-scheme: dark;
7
+
8
+ /* Professional Color Palette */
9
+ --color-bg-base: #0a0a0f;
10
+ --color-bg-surface: #12121a;
11
+ --color-bg-elevated: #1a1a24;
12
+ --color-bg-hover: #22222e;
13
+ --color-bg-active: #2a2a38;
14
+
15
+ /* Accent Colors - Purple/Violet gradient */
16
+ --color-accent-primary: #8b5cf6;
17
+ --color-accent-secondary: #a78bfa;
18
+ --color-accent-tertiary: #c4b5fd;
19
+ --color-accent-glow: rgba(139, 92, 246, 0.4);
20
+
21
+ /* Status Colors */
22
+ --color-success: #10b981;
23
+ --color-warning: #f59e0b;
24
+ --color-error: #ef4444;
25
+ --color-info: #3b82f6;
26
+
27
+ /* Text Colors */
28
+ --color-text-primary: #f3f4f6;
29
+ --color-text-secondary: #9ca3af;
30
+ --color-text-tertiary: #6b7280;
31
+ --color-text-muted: #4b5563;
32
+
33
+ /* Borders */
34
+ --color-border-subtle: rgba(255, 255, 255, 0.06);
35
+ --color-border-default: rgba(255, 255, 255, 0.1);
36
+ --color-border-strong: rgba(255, 255, 255, 0.15);
37
+
38
+ /* Shadows */
39
+ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
40
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
41
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
42
+ --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
43
+ --shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / 0.25);
44
+ --shadow-glow: 0 0 50px rgba(139, 92, 246, 0.3);
45
+
46
+ /* Animations */
47
+ --transition-base: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
48
+ --transition-smooth: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
49
+ --transition-spring: all 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
50
+ }
51
+
52
+ * {
53
+ box-sizing: border-box;
54
+ margin: 0;
55
+ padding: 0;
56
+ }
57
+
58
+ html {
59
+ font-family: 'Inter', system-ui, -apple-system, sans-serif;
60
+ font-feature-settings: 'cv11', 'ss01';
61
+ font-variation-settings: 'opsz' 32;
62
+ scroll-behavior: smooth;
63
+ }
64
+
65
+ body {
66
+ @apply antialiased;
67
+ background: var(--color-bg-base);
68
+ color: var(--color-text-primary);
69
+ min-height: 100vh;
70
+ position: relative;
71
+ overflow-x: hidden;
72
+ }
73
+
74
+ /* Background gradient effect */
75
+ body::before {
76
+ content: '';
77
+ position: fixed;
78
+ top: 0;
79
+ left: 0;
80
+ right: 0;
81
+ bottom: 0;
82
+ background: radial-gradient(
83
+ ellipse at top left,
84
+ rgba(139, 92, 246, 0.15) 0%,
85
+ transparent 50%
86
+ ),
87
+ radial-gradient(
88
+ ellipse at bottom right,
89
+ rgba(167, 139, 250, 0.1) 0%,
90
+ transparent 50%
91
+ );
92
+ pointer-events: none;
93
+ z-index: 0;
94
+ }
95
+
96
+ #root {
97
+ position: relative;
98
+ z-index: 1;
99
+ }
100
+
101
+ /* Custom Scrollbar */
102
+ ::-webkit-scrollbar {
103
+ width: 12px;
104
+ height: 12px;
105
+ }
106
+
107
+ ::-webkit-scrollbar-track {
108
+ background: var(--color-bg-surface);
109
+ border-radius: 6px;
110
+ }
111
+
112
+ ::-webkit-scrollbar-thumb {
113
+ background: linear-gradient(180deg, var(--color-accent-primary), var(--color-accent-secondary));
114
+ border-radius: 6px;
115
+ border: 2px solid var(--color-bg-surface);
116
+ }
117
+
118
+ ::-webkit-scrollbar-thumb:hover {
119
+ background: linear-gradient(180deg, var(--color-accent-secondary), var(--color-accent-tertiary));
120
+ }
121
+
122
+ /* Animations */
123
+ @keyframes fadeIn {
124
+ from {
125
+ opacity: 0;
126
+ transform: translateY(10px);
127
+ }
128
+ to {
129
+ opacity: 1;
130
+ transform: translateY(0);
131
+ }
132
+ }
133
+
134
+ @keyframes slideIn {
135
+ from {
136
+ opacity: 0;
137
+ transform: translateX(-20px);
138
+ }
139
+ to {
140
+ opacity: 1;
141
+ transform: translateX(0);
142
+ }
143
+ }
144
+
145
+ @keyframes pulse {
146
+ 0%, 100% {
147
+ opacity: 1;
148
+ }
149
+ 50% {
150
+ opacity: 0.5;
151
+ }
152
+ }
153
+
154
+ @keyframes shimmer {
155
+ 0% {
156
+ background-position: -1000px 0;
157
+ }
158
+ 100% {
159
+ background-position: 1000px 0;
160
+ }
161
+ }
162
+
163
+ @keyframes glow {
164
+ 0%, 100% {
165
+ box-shadow: 0 0 20px rgba(139, 92, 246, 0.5),
166
+ inset 0 0 20px rgba(139, 92, 246, 0.1);
167
+ }
168
+ 50% {
169
+ box-shadow: 0 0 40px rgba(139, 92, 246, 0.8),
170
+ inset 0 0 30px rgba(139, 92, 246, 0.2);
171
+ }
172
+ }
173
+
174
+ /* Component Classes */
175
+ @layer components {
176
+ /* Glass Morphism Panel */
177
+ .glass-panel {
178
+ @apply rounded-2xl border;
179
+ background: linear-gradient(
180
+ 135deg,
181
+ rgba(255, 255, 255, 0.03) 0%,
182
+ rgba(255, 255, 255, 0.01) 100%
183
+ );
184
+ border-color: var(--color-border-default);
185
+ backdrop-filter: blur(20px);
186
+ box-shadow: var(--shadow-xl), inset 0 1px 0 0 rgba(255, 255, 255, 0.05);
187
+ transition: var(--transition-base);
188
+ }
189
+
190
+ .glass-panel:hover {
191
+ border-color: var(--color-border-strong);
192
+ box-shadow: var(--shadow-2xl), var(--shadow-glow), inset 0 1px 0 0 rgba(255, 255, 255, 0.08);
193
+ }
194
+
195
+ /* Card Styles */
196
+ .card {
197
+ @apply rounded-xl p-6;
198
+ background: var(--color-bg-surface);
199
+ border: 1px solid var(--color-border-subtle);
200
+ transition: var(--transition-smooth);
201
+ animation: fadeIn 0.5s ease-out;
202
+ }
203
+
204
+ .card:hover {
205
+ background: var(--color-bg-elevated);
206
+ border-color: var(--color-border-default);
207
+ transform: translateY(-2px);
208
+ box-shadow: var(--shadow-lg);
209
+ }
210
+
211
+ .card-interactive {
212
+ @apply card cursor-pointer;
213
+ }
214
+
215
+ .card-interactive:active {
216
+ transform: scale(0.98);
217
+ }
218
+
219
+ /* Modern Buttons */
220
+ .btn {
221
+ @apply inline-flex items-center justify-center gap-2 rounded-xl px-5 py-2.5 font-medium;
222
+ transition: var(--transition-base);
223
+ position: relative;
224
+ overflow: hidden;
225
+ text-transform: none;
226
+ letter-spacing: 0.01em;
227
+ }
228
+
229
+ .btn-primary {
230
+ @apply btn;
231
+ background: linear-gradient(135deg, var(--color-accent-primary), var(--color-accent-secondary));
232
+ color: white;
233
+ box-shadow: 0 4px 15px rgba(139, 92, 246, 0.3);
234
+ }
235
+
236
+ .btn-primary:hover {
237
+ box-shadow: 0 6px 25px rgba(139, 92, 246, 0.5);
238
+ transform: translateY(-2px);
239
+ }
240
+
241
+ .btn-primary:active {
242
+ transform: translateY(0);
243
+ }
244
+
245
+ .btn-secondary {
246
+ @apply btn;
247
+ background: var(--color-bg-elevated);
248
+ color: var(--color-text-primary);
249
+ border: 1px solid var(--color-border-default);
250
+ }
251
+
252
+ .btn-secondary:hover {
253
+ background: var(--color-bg-hover);
254
+ border-color: var(--color-accent-primary);
255
+ box-shadow: inset 0 0 0 1px var(--color-accent-primary);
256
+ }
257
+
258
+ .btn-ghost {
259
+ @apply btn;
260
+ background: transparent;
261
+ color: var(--color-text-secondary);
262
+ }
263
+
264
+ .btn-ghost:hover {
265
+ background: var(--color-bg-elevated);
266
+ color: var(--color-text-primary);
267
+ }
268
+
269
+ .btn-icon {
270
+ @apply inline-flex items-center justify-center;
271
+ width: 40px;
272
+ height: 40px;
273
+ border-radius: 12px;
274
+ background: var(--color-bg-elevated);
275
+ border: 1px solid var(--color-border-subtle);
276
+ color: var(--color-text-secondary);
277
+ transition: var(--transition-base);
278
+ }
279
+
280
+ .btn-icon:hover {
281
+ background: var(--color-bg-hover);
282
+ color: var(--color-accent-primary);
283
+ border-color: var(--color-accent-primary);
284
+ transform: scale(1.05);
285
+ }
286
+
287
+ /* Modern Input Fields */
288
+ .input {
289
+ @apply w-full rounded-xl px-4 py-3 text-sm;
290
+ background: var(--color-bg-surface);
291
+ border: 1px solid var(--color-border-subtle);
292
+ color: var(--color-text-primary);
293
+ transition: var(--transition-base);
294
+ font-family: 'Inter', sans-serif;
295
+ }
296
+
297
+ .input:hover {
298
+ background: var(--color-bg-elevated);
299
+ border-color: var(--color-border-default);
300
+ }
301
+
302
+ .input:focus {
303
+ outline: none;
304
+ border-color: var(--color-accent-primary);
305
+ box-shadow: 0 0 0 3px var(--color-accent-glow);
306
+ background: var(--color-bg-elevated);
307
+ }
308
+
309
+ .input::placeholder {
310
+ color: var(--color-text-muted);
311
+ }
312
+
313
+ /* Select */
314
+ .select {
315
+ @apply input cursor-pointer;
316
+ padding-right: 40px;
317
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%239ca3af'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M19 9l-7 7-7-7'/%3E%3C/svg%3E");
318
+ background-repeat: no-repeat;
319
+ background-position: right 12px center;
320
+ background-size: 20px;
321
+ }
322
+
323
+ /* Checkbox */
324
+ .checkbox {
325
+ @apply h-5 w-5 rounded-md;
326
+ background: var(--color-bg-surface);
327
+ border: 1px solid var(--color-border-default);
328
+ cursor: pointer;
329
+ transition: var(--transition-base);
330
+ }
331
+
332
+ .checkbox:checked {
333
+ background: linear-gradient(135deg, var(--color-accent-primary), var(--color-accent-secondary));
334
+ border-color: var(--color-accent-primary);
335
+ }
336
+
337
+ .checkbox:focus {
338
+ outline: none;
339
+ box-shadow: 0 0 0 3px var(--color-accent-glow);
340
+ }
341
+
342
+ /* Tables */
343
+ .table-modern {
344
+ @apply w-full;
345
+ border-collapse: separate;
346
+ border-spacing: 0;
347
+ }
348
+
349
+ .table-modern thead {
350
+ background: var(--color-bg-surface);
351
+ }
352
+
353
+ .table-modern th {
354
+ @apply px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider;
355
+ color: var(--color-text-tertiary);
356
+ border-bottom: 1px solid var(--color-border-subtle);
357
+ }
358
+
359
+ .table-modern td {
360
+ @apply px-4 py-3 text-sm;
361
+ color: var(--color-text-primary);
362
+ border-bottom: 1px solid var(--color-border-subtle);
363
+ }
364
+
365
+ .table-modern tbody tr {
366
+ transition: var(--transition-base);
367
+ }
368
+
369
+ .table-modern tbody tr:hover {
370
+ background: var(--color-bg-elevated);
371
+ }
372
+
373
+ /* Badges */
374
+ .badge {
375
+ @apply inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-medium;
376
+ background: var(--color-bg-elevated);
377
+ color: var(--color-text-secondary);
378
+ border: 1px solid var(--color-border-subtle);
379
+ }
380
+
381
+ .badge-success {
382
+ background: rgba(16, 185, 129, 0.1);
383
+ color: #10b981;
384
+ border-color: rgba(16, 185, 129, 0.2);
385
+ }
386
+
387
+ .badge-warning {
388
+ background: rgba(245, 158, 11, 0.1);
389
+ color: #f59e0b;
390
+ border-color: rgba(245, 158, 11, 0.2);
391
+ }
392
+
393
+ .badge-error {
394
+ background: rgba(239, 68, 68, 0.1);
395
+ color: #ef4444;
396
+ border-color: rgba(239, 68, 68, 0.2);
397
+ }
398
+
399
+ .badge-info {
400
+ background: rgba(59, 130, 246, 0.1);
401
+ color: #3b82f6;
402
+ border-color: rgba(59, 130, 246, 0.2);
403
+ }
404
+
405
+ /* Loading States */
406
+ .skeleton {
407
+ @apply rounded-lg;
408
+ background: linear-gradient(
409
+ 90deg,
410
+ var(--color-bg-surface) 25%,
411
+ var(--color-bg-elevated) 50%,
412
+ var(--color-bg-surface) 75%
413
+ );
414
+ background-size: 1000px 100%;
415
+ animation: shimmer 2s infinite;
416
+ }
417
+
418
+ .spinner {
419
+ border: 3px solid var(--color-border-subtle);
420
+ border-top-color: var(--color-accent-primary);
421
+ border-radius: 50%;
422
+ width: 20px;
423
+ height: 20px;
424
+ animation: spin 1s linear infinite;
425
+ }
426
+
427
+ @keyframes spin {
428
+ to {
429
+ transform: rotate(360deg);
430
+ }
431
+ }
432
+
433
+ /* Tooltips */
434
+ .tooltip {
435
+ @apply absolute z-50 rounded-lg px-3 py-2 text-xs font-medium;
436
+ background: var(--color-bg-elevated);
437
+ color: var(--color-text-primary);
438
+ border: 1px solid var(--color-border-default);
439
+ box-shadow: var(--shadow-xl);
440
+ pointer-events: none;
441
+ opacity: 0;
442
+ transition: opacity 0.2s;
443
+ }
444
+
445
+ .tooltip.show {
446
+ opacity: 1;
447
+ }
448
+
449
+ /* Dividers */
450
+ .divider {
451
+ @apply my-6;
452
+ height: 1px;
453
+ background: linear-gradient(
454
+ 90deg,
455
+ transparent,
456
+ var(--color-border-default) 50%,
457
+ transparent
458
+ );
459
+ }
460
+
461
+ /* Status Indicators */
462
+ .status-dot {
463
+ @apply inline-block h-2 w-2 rounded-full;
464
+ animation: pulse 2s infinite;
465
+ }
466
+
467
+ .status-dot.online {
468
+ background: var(--color-success);
469
+ box-shadow: 0 0 8px var(--color-success);
470
+ }
471
+
472
+ .status-dot.offline {
473
+ background: var(--color-text-muted);
474
+ }
475
+
476
+ .status-dot.error {
477
+ background: var(--color-error);
478
+ box-shadow: 0 0 8px var(--color-error);
479
+ }
480
+
481
+ /* Code blocks */
482
+ .code-block {
483
+ @apply rounded-xl p-4;
484
+ background: var(--color-bg-base);
485
+ border: 1px solid var(--color-border-subtle);
486
+ font-family: 'JetBrains Mono', monospace;
487
+ font-size: 0.875rem;
488
+ line-height: 1.5;
489
+ overflow-x: auto;
490
+ }
491
+
492
+ .code-inline {
493
+ @apply rounded px-1.5 py-0.5;
494
+ background: var(--color-bg-elevated);
495
+ border: 1px solid var(--color-border-subtle);
496
+ font-family: 'JetBrains Mono', monospace;
497
+ font-size: 0.875em;
498
+ }
499
+
500
+ /* Responsive utilities */
501
+ @media (max-width: 640px) {
502
+ .hide-mobile {
503
+ display: none;
504
+ }
505
+ }
506
+
507
+ @media (min-width: 641px) {
508
+ .show-mobile {
509
+ display: none;
510
+ }
511
+ }
512
+ }
513
+
514
+ /* Tailwind overrides for consistency */
515
+ .text-mono {
516
+ font-family: 'JetBrains Mono', monospace;
517
+ }
518
+
519
+ /* Focus visible styles */
520
+ *:focus-visible {
521
+ outline: 2px solid var(--color-accent-primary);
522
+ outline-offset: 2px;
523
+ }
524
+
525
+ /* Selection styles */
526
+ ::selection {
527
+ background: var(--color-accent-primary);
528
+ color: white;
529
+ }
@@ -0,0 +1,17 @@
1
+ import { createRoot } from "react-dom/client";
2
+ import "../public/app.css";
3
+ import { App } from "./app";
4
+
5
+ function render() {
6
+ const el = document.getElementById("root");
7
+ if (!el) return;
8
+ const root = createRoot(el);
9
+ root.render(<App />);
10
+ }
11
+
12
+ // Ensure we render whether or not DOMContentLoaded has already fired
13
+ if (document.readyState === "loading") {
14
+ document.addEventListener("DOMContentLoaded", render);
15
+ } else {
16
+ render();
17
+ }
@@ -0,0 +1,17 @@
1
+ // Bundled Drizzle migrations for single-binary builds
2
+ // These imports ensure Bun embeds the SQL files into the executable.
3
+ // Order matters: keep in incremental order.
4
+
5
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
6
+ // @ts-expect-error - Bun import attributes
7
+ import mig0000 from "../drizzle/0000_friendly_millenium_guard.sql" with {
8
+ type: "file",
9
+ };
10
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
11
+ // @ts-expect-error - Bun import attributes
12
+ import mig0001 from "../drizzle/0001_stale_sentinels.sql" with { type: "file" };
13
+
14
+ export const bundledMigrations: Array<{ name: string; path: string }> = [
15
+ { name: "0000_friendly_millenium_guard.sql", path: mig0000 },
16
+ { name: "0001_stale_sentinels.sql", path: mig0001 },
17
+ ];
@@ -0,0 +1,44 @@
1
+ import {
2
+ createLiteSVMRpcServer,
3
+ createLiteSVMWebSocketServer,
4
+ } from "../../server";
5
+ import { startGuiServer } from "../gui/server";
6
+
7
+ export interface RpcStartOptions {
8
+ rpcPort?: number;
9
+ wsPort?: number;
10
+ dbMode?: "ephemeral" | "persistent";
11
+ dbPath?: string;
12
+ host?: string;
13
+ guiEnabled?: boolean;
14
+ guiPort?: number;
15
+ }
16
+
17
+ export function startRpcServers(opts: RpcStartOptions = {}) {
18
+ const rpcPort = Number(opts.rpcPort ?? (process.env.RPC_PORT || 8899));
19
+ const wsPort = Number(opts.wsPort ?? rpcPort + 1);
20
+ const host = String(opts.host ?? process.env.RPC_HOST ?? "127.0.0.1");
21
+ const guiEnabled = opts.guiEnabled !== false;
22
+ const guiPort = Number(
23
+ opts.guiPort ?? process.env.SOLFORGE_GUI_PORT ?? 42069,
24
+ );
25
+
26
+ if (opts.dbMode) process.env.SOLFORGE_DB_MODE = opts.dbMode;
27
+ if (opts.dbPath) process.env.SOLFORGE_DB_PATH = opts.dbPath;
28
+
29
+ const { httpServer, rpcServer } = createLiteSVMRpcServer(rpcPort, host);
30
+ const { wsServer } = createLiteSVMWebSocketServer(rpcServer, wsPort);
31
+ const guiServer = guiEnabled
32
+ ? startGuiServer({ port: guiPort, host, rpcPort, rpcServer })
33
+ : null;
34
+
35
+ return {
36
+ httpServer,
37
+ rpcServer,
38
+ wsServer,
39
+ rpcPort,
40
+ wsPort,
41
+ guiPort: guiServer ? guiServer.port : null,
42
+ guiServer,
43
+ };
44
+ }
@@ -1,103 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const fs = require("fs");
4
- const path = require("path");
5
- const https = require("https");
6
- const { execSync } = require("child_process");
7
-
8
- const PACKAGE_NAME = "solforge";
9
- const VERSION = require("../package.json").version;
10
-
11
- // Platform mapping
12
- const PLATFORM_MAP = {
13
- "darwin-x64": "darwin-x64",
14
- "darwin-arm64": "darwin-arm64",
15
- "linux-x64": "linux-x64",
16
- "linux-arm64": "linux-arm64",
17
- "win32-x64": "win32-x64.exe",
18
- };
19
-
20
- function getPlatform() {
21
- const platform = process.platform;
22
- const arch = process.arch;
23
- const key = `${platform}-${arch}`;
24
-
25
- if (!PLATFORM_MAP[key]) {
26
- console.error(`Unsupported platform: ${platform}-${arch}`);
27
- console.error("Supported platforms:", Object.keys(PLATFORM_MAP).join(", "));
28
- process.exit(1);
29
- }
30
-
31
- return PLATFORM_MAP[key];
32
- }
33
-
34
- function downloadBinary(url, destination) {
35
- return new Promise((resolve, reject) => {
36
- const file = fs.createWriteStream(destination);
37
-
38
- https
39
- .get(url, (response) => {
40
- if (response.statusCode === 200) {
41
- response.pipe(file);
42
- file.on("finish", () => {
43
- file.close();
44
- fs.chmodSync(destination, 0o755); // Make executable
45
- resolve();
46
- });
47
- } else if (response.statusCode === 302 || response.statusCode === 301) {
48
- // Handle redirects
49
- downloadBinary(response.headers.location, destination)
50
- .then(resolve)
51
- .catch(reject);
52
- } else {
53
- reject(new Error(`Failed to download: ${response.statusCode}`));
54
- }
55
- })
56
- .on("error", reject);
57
- });
58
- }
59
-
60
- async function install() {
61
- try {
62
- const platform = getPlatform();
63
- const binDir = path.join(__dirname, "..", "bin");
64
- const binaryName =
65
- process.platform === "win32" ? "solforge.exe" : "solforge";
66
- const binaryPath = path.join(binDir, binaryName);
67
-
68
- // Create bin directory
69
- if (!fs.existsSync(binDir)) {
70
- fs.mkdirSync(binDir, { recursive: true });
71
- }
72
-
73
- // Try to build locally first (if Bun is available)
74
- try {
75
- console.log("Attempting to build locally with Bun...");
76
- execSync(`bun build src/index.ts --compile --outfile ${binaryPath}`, {
77
- cwd: path.join(__dirname, ".."),
78
- stdio: "pipe",
79
- });
80
- console.log("✅ Built successfully with local Bun");
81
- return;
82
- } catch (e) {
83
- console.log("Local Bun build failed, downloading pre-built binary...");
84
- }
85
-
86
- // Download pre-built binary from GitHub releases
87
- const downloadUrl = `https://github.com/nitishxyz/solforge/releases/download/v${VERSION}/solforge-${platform}`;
88
-
89
- console.log(`Downloading ${PACKAGE_NAME} binary for ${platform}...`);
90
- console.log(`URL: ${downloadUrl}`);
91
-
92
- await downloadBinary(downloadUrl, binaryPath);
93
- console.log("✅ Binary downloaded and installed successfully");
94
- } catch (error) {
95
- console.error("❌ Installation failed:", error.message);
96
- console.error("\nFallback options:");
97
- console.error("1. Install Bun and run: bun install -g solforge");
98
- console.error("2. Clone the repo and build manually");
99
- process.exit(1);
100
- }
101
- }
102
-
103
- install();