solforge 0.2.0 → 0.2.2

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 (56) hide show
  1. package/LICENSE +21 -0
  2. package/docs/API.md +379 -0
  3. package/docs/CONFIGURATION.md +407 -0
  4. package/package.json +67 -45
  5. package/src/api-server-entry.ts +109 -0
  6. package/src/commands/add-program.ts +337 -0
  7. package/src/commands/init.ts +122 -0
  8. package/src/commands/list.ts +136 -0
  9. package/src/commands/mint.ts +288 -0
  10. package/src/commands/start.ts +877 -0
  11. package/src/commands/status.ts +99 -0
  12. package/src/commands/stop.ts +406 -0
  13. package/src/config/manager.ts +157 -0
  14. package/src/gui/public/build/main.css +1 -0
  15. package/src/gui/public/build/main.js +303 -0
  16. package/src/gui/public/build/main.js.txt +231 -0
  17. package/src/index.ts +188 -0
  18. package/src/services/api-server.ts +485 -0
  19. package/src/services/port-manager.ts +177 -0
  20. package/src/services/process-registry.ts +154 -0
  21. package/src/services/program-cloner.ts +317 -0
  22. package/src/services/token-cloner.ts +809 -0
  23. package/src/services/validator.ts +295 -0
  24. package/src/types/config.ts +110 -0
  25. package/src/utils/shell.ts +110 -0
  26. package/src/utils/token-loader.ts +115 -0
  27. package/.agi/agi.sqlite +0 -0
  28. package/.claude/settings.local.json +0 -9
  29. package/.github/workflows/release-binaries.yml +0 -133
  30. package/.tmp/.787ebcdbf7b8fde8-00000000.hm +0 -0
  31. package/.tmp/.bffe6efebdf8aedc-00000000.hm +0 -0
  32. package/AGENTS.md +0 -271
  33. package/CLAUDE.md +0 -106
  34. package/PROJECT_STRUCTURE.md +0 -124
  35. package/SOLANA_KIT_GUIDE.md +0 -251
  36. package/SOLFORGE.md +0 -119
  37. package/biome.json +0 -34
  38. package/bun.lock +0 -743
  39. package/drizzle/0000_friendly_millenium_guard.sql +0 -53
  40. package/drizzle/0001_stale_sentinels.sql +0 -2
  41. package/drizzle/meta/0000_snapshot.json +0 -329
  42. package/drizzle/meta/0001_snapshot.json +0 -345
  43. package/drizzle/meta/_journal.json +0 -20
  44. package/drizzle.config.ts +0 -12
  45. package/index.ts +0 -21
  46. package/mint.sh +0 -47
  47. package/postcss.config.js +0 -6
  48. package/rpc-server.ts.backup +0 -519
  49. package/sf.config.json +0 -38
  50. package/tailwind.config.js +0 -27
  51. package/test-client.ts +0 -120
  52. package/tmp/inspect-html.ts +0 -4
  53. package/tmp/response-test.ts +0 -5
  54. package/tmp/test-html.ts +0 -5
  55. package/tmp/test-server.ts +0 -13
  56. package/tsconfig.json +0 -29
@@ -1,519 +0,0 @@
1
- import { LiteSVM } from "litesvm";
2
- import {
3
- PublicKey,
4
- VersionedTransaction
5
- } from "@solana/web3.js";
6
-
7
- interface JsonRpcRequest {
8
- jsonrpc: "2.0";
9
- id: string | number;
10
- method: string;
11
- params?: any;
12
- }
13
-
14
- interface JsonRpcResponse {
15
- jsonrpc: "2.0";
16
- id: string | number;
17
- result?: any;
18
- error?: {
19
- code: number;
20
- message: string;
21
- data?: any;
22
- };
23
- }
24
-
25
- class LiteSVMRpcServer {
26
- private svm: LiteSVM;
27
- private slot: bigint = 1n;
28
- private blockHeight: bigint = 1n;
29
-
30
- constructor() {
31
- this.svm = new LiteSVM()
32
- .withSysvars()
33
- .withBuiltins()
34
- .withDefaultPrograms()
35
- .withLamports(1000000000000n)
36
- .withBlockhashCheck(false)
37
- .withTransactionHistory(0n)
38
- .withSigverify(false);
39
- }
40
-
41
- private encodeBase58(bytes: Uint8Array): string {
42
- const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
43
- const base = BigInt(ALPHABET.length);
44
-
45
- let num = 0n;
46
- for (let i = 0; i < bytes.length; i++) {
47
- num = num * 256n + BigInt(bytes[i] || 0);
48
- }
49
-
50
- let encoded = "";
51
- while (num > 0n) {
52
- const remainder = num % base;
53
- num = num / base;
54
- encoded = ALPHABET[Number(remainder)] + encoded;
55
- }
56
-
57
- for (let i = 0; i < bytes.length && bytes[i] === 0; i++) {
58
- encoded = "1" + encoded;
59
- }
60
-
61
- return encoded || "1";
62
- }
63
-
64
- private decodeBase58(str: string): Uint8Array {
65
- const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
66
- const base = BigInt(ALPHABET.length);
67
-
68
- let num = 0n;
69
- for (const char of str) {
70
- const index = ALPHABET.indexOf(char);
71
- if (index === -1) throw new Error("Invalid base58 character");
72
- num = num * base + BigInt(index);
73
- }
74
-
75
- const bytes = [];
76
- while (num > 0n) {
77
- bytes.unshift(Number(num % 256n));
78
- num = num / 256n;
79
- }
80
-
81
- for (let i = 0; i < str.length && str[i] === "1"; i++) {
82
- bytes.unshift(0);
83
- }
84
-
85
- return new Uint8Array(bytes.length > 0 ? bytes : [0]);
86
- }
87
-
88
- private createSuccessResponse(id: string | number, result: any): JsonRpcResponse {
89
- return {
90
- jsonrpc: "2.0",
91
- id,
92
- result
93
- };
94
- }
95
-
96
- private createErrorResponse(
97
- id: string | number,
98
- code: number,
99
- message: string,
100
- data?: any
101
- ): JsonRpcResponse {
102
- return {
103
- jsonrpc: "2.0",
104
- id,
105
- error: { code, message, data }
106
- };
107
- }
108
-
109
- async handleRequest(request: JsonRpcRequest): Promise<JsonRpcResponse> {
110
- const { method, params, id } = request;
111
-
112
- try {
113
- switch (method) {
114
- case "getAccountInfo":
115
- return this.handleGetAccountInfo(id, params);
116
-
117
- case "getBalance":
118
- return this.handleGetBalance(id, params);
119
-
120
- case "getLatestBlockhash":
121
- return this.handleGetLatestBlockhash(id, params);
122
-
123
- case "sendTransaction":
124
- return this.handleSendTransaction(id, params);
125
-
126
- case "simulateTransaction":
127
- return this.handleSimulateTransaction(id, params);
128
-
129
- case "requestAirdrop":
130
- return this.handleRequestAirdrop(id, params);
131
-
132
- case "getSlot":
133
- return this.handleGetSlot(id, params);
134
-
135
- case "getBlockHeight":
136
- return this.handleGetBlockHeight(id, params);
137
-
138
- case "getTransaction":
139
- return this.handleGetTransaction(id, params);
140
-
141
- case "getSignatureStatuses":
142
- return this.handleGetSignatureStatuses(id, params);
143
-
144
- case "getMinimumBalanceForRentExemption":
145
- return this.handleGetMinimumBalanceForRentExemption(id, params);
146
-
147
- case "getMultipleAccounts":
148
- return this.handleGetMultipleAccounts(id, params);
149
-
150
- case "getHealth":
151
- return this.createSuccessResponse(id, "ok");
152
-
153
- case "getVersion":
154
- return this.createSuccessResponse(id, {
155
- "solana-core": "1.18.0",
156
- "feature-set": 1
157
- });
158
-
159
- default:
160
- return this.createErrorResponse(
161
- id,
162
- -32601,
163
- `Method not found: ${method}`
164
- );
165
- }
166
- } catch (error: any) {
167
- return this.createErrorResponse(
168
- id,
169
- -32603,
170
- "Internal error",
171
- error.message
172
- );
173
- }
174
- }
175
-
176
- private handleGetAccountInfo(id: string | number, params: any): JsonRpcResponse {
177
- const [pubkeyStr, config] = params;
178
- const encoding = config?.encoding || "base64";
179
-
180
- try {
181
- const pubkey = new PublicKey(pubkeyStr);
182
- const account = this.svm.getAccount(pubkey);
183
-
184
- if (!account) {
185
- return this.createSuccessResponse(id, {
186
- context: { slot: Number(this.slot) },
187
- value: null
188
- });
189
- }
190
-
191
- const accountInfo = {
192
- lamports: Number(account.lamports),
193
- owner: new PublicKey(account.owner).toBase58(),
194
- data: encoding === "base64"
195
- ? [Buffer.from(account.data).toString("base64"), encoding]
196
- : Array.from(account.data),
197
- executable: account.executable,
198
- rentEpoch: Number(account.rentEpoch || 0)
199
- };
200
-
201
- return this.createSuccessResponse(id, {
202
- context: { slot: Number(this.slot) },
203
- value: accountInfo
204
- });
205
- } catch (error: any) {
206
- return this.createErrorResponse(id, -32602, "Invalid params", error.message);
207
- }
208
- }
209
-
210
- private handleGetBalance(id: string | number, params: any): JsonRpcResponse {
211
- const [pubkeyStr] = params;
212
-
213
- try {
214
- const pubkey = new PublicKey(pubkeyStr);
215
- const balance = this.svm.getBalance(pubkey);
216
-
217
- return this.createSuccessResponse(id, {
218
- context: { slot: Number(this.slot) },
219
- value: Number(balance || 0n)
220
- });
221
- } catch (error: any) {
222
- return this.createErrorResponse(id, -32602, "Invalid params", error.message);
223
- }
224
- }
225
-
226
- private handleGetLatestBlockhash(id: string | number, params: any): JsonRpcResponse {
227
- const blockhash = this.svm.latestBlockhash();
228
-
229
- return this.createSuccessResponse(id, {
230
- context: { slot: Number(this.slot) },
231
- value: {
232
- blockhash,
233
- lastValidBlockHeight: Number(this.blockHeight + 150n)
234
- }
235
- });
236
- }
237
-
238
- private handleSendTransaction(id: string | number, params: any): JsonRpcResponse {
239
- const [encodedTx, config] = params;
240
-
241
- try {
242
- const txData = Buffer.from(encodedTx, "base64");
243
- const tx = VersionedTransaction.deserialize(txData);
244
-
245
- const result = this.svm.sendTransaction(tx);
246
-
247
- if ("err" in result) {
248
- return this.createErrorResponse(
249
- id,
250
- -32002,
251
- "Transaction simulation failed",
252
- result.err
253
- );
254
- }
255
-
256
- const signature = tx.signatures[0] ? this.encodeBase58(tx.signatures[0]) : this.encodeBase58(new Uint8Array(64).fill(0));
257
-
258
- this.slot += 1n;
259
- this.blockHeight += 1n;
260
-
261
- return this.createSuccessResponse(id, signature);
262
- } catch (error: any) {
263
- return this.createErrorResponse(
264
- id,
265
- -32003,
266
- "Transaction failed",
267
- error.message
268
- );
269
- }
270
- }
271
-
272
- private handleSimulateTransaction(id: string | number, params: any): JsonRpcResponse {
273
- const [encodedTx, config] = params;
274
-
275
- try {
276
- const txData = Buffer.from(encodedTx, "base64");
277
- const tx = VersionedTransaction.deserialize(txData);
278
-
279
- const result = this.svm.simulateTransaction(tx);
280
-
281
- if ("err" in result) {
282
- const errorMeta = result.meta();
283
- return this.createSuccessResponse(id, {
284
- context: { slot: Number(this.slot) },
285
- value: {
286
- err: result.err(),
287
- logs: errorMeta.logs(),
288
- accounts: null,
289
- unitsConsumed: Number(errorMeta.computeUnitsConsumed()),
290
- returnData: null
291
- }
292
- });
293
- }
294
-
295
- const meta = result.meta();
296
- const returnData = meta.returnData();
297
-
298
- return this.createSuccessResponse(id, {
299
- context: { slot: Number(this.slot) },
300
- value: {
301
- err: null,
302
- logs: meta.logs(),
303
- accounts: null,
304
- unitsConsumed: Number(meta.computeUnitsConsumed()),
305
- returnData: returnData ? {
306
- programId: this.encodeBase58(returnData.programId()),
307
- data: [Buffer.from(returnData.data()).toString("base64"), "base64"]
308
- } : null
309
- }
310
- });
311
- } catch (error: any) {
312
- return this.createErrorResponse(
313
- id,
314
- -32003,
315
- "Simulation failed",
316
- error.message
317
- );
318
- }
319
- }
320
-
321
- private handleRequestAirdrop(id: string | number, params: any): JsonRpcResponse {
322
- const [pubkeyStr, lamports] = params;
323
-
324
- try {
325
- const pubkey = new PublicKey(pubkeyStr);
326
- const result = this.svm.airdrop(pubkey, BigInt(lamports));
327
-
328
- if (!result || "err" in result) {
329
- return this.createErrorResponse(
330
- id,
331
- -32003,
332
- "Airdrop failed",
333
- result?.err || "Unknown error"
334
- );
335
- }
336
-
337
- const signature = this.encodeBase58(new Uint8Array(64).fill(1));
338
-
339
- this.slot += 1n;
340
- this.blockHeight += 1n;
341
-
342
- return this.createSuccessResponse(id, signature);
343
- } catch (error: any) {
344
- return this.createErrorResponse(id, -32602, "Invalid params", error.message);
345
- }
346
- }
347
-
348
- private handleGetSlot(id: string | number, params: any): JsonRpcResponse {
349
- return this.createSuccessResponse(id, Number(this.slot));
350
- }
351
-
352
- private handleGetBlockHeight(id: string | number, params: any): JsonRpcResponse {
353
- return this.createSuccessResponse(id, Number(this.blockHeight));
354
- }
355
-
356
- private handleGetTransaction(id: string | number, params: any): JsonRpcResponse {
357
- const [signature] = params;
358
-
359
- try {
360
- const sigBytes = this.decodeBase58(signature);
361
- const tx = this.svm.getTransaction(sigBytes);
362
-
363
- if (!tx) {
364
- return this.createSuccessResponse(id, null);
365
- }
366
-
367
- const isError = "err" in tx;
368
- const logs = isError ? tx.meta().logs() : tx.logs();
369
-
370
- return this.createSuccessResponse(id, {
371
- slot: Number(this.slot),
372
- transaction: {
373
- signatures: [signature]
374
- },
375
- meta: {
376
- err: isError ? tx.err() : null,
377
- fee: 5000,
378
- preBalances: [],
379
- postBalances: [],
380
- innerInstructions: [],
381
- logMessages: logs,
382
- preTokenBalances: [],
383
- postTokenBalances: [],
384
- rewards: []
385
- }
386
- });
387
- } catch (error: any) {
388
- return this.createErrorResponse(id, -32602, "Invalid params", error.message);
389
- }
390
- }
391
-
392
- private handleGetSignatureStatuses(id: string | number, params: any): JsonRpcResponse {
393
- const [signatures, config] = params;
394
-
395
- const statuses = signatures.map((sig: string) => {
396
- try {
397
- const sigBytes = this.decodeBase58(sig);
398
- const tx = this.svm.getTransaction(sigBytes);
399
-
400
- if (!tx) {
401
- return null;
402
- }
403
-
404
- return {
405
- slot: Number(this.slot),
406
- confirmations: 0,
407
- err: "err" in tx ? tx.err : null,
408
- confirmationStatus: "finalized"
409
- };
410
- } catch {
411
- return null;
412
- }
413
- });
414
-
415
- return this.createSuccessResponse(id, {
416
- context: { slot: Number(this.slot) },
417
- value: statuses
418
- });
419
- }
420
-
421
- private handleGetMinimumBalanceForRentExemption(
422
- id: string | number,
423
- params: any
424
- ): JsonRpcResponse {
425
- const [dataLength] = params;
426
- const minBalance = this.svm.minimumBalanceForRentExemption(BigInt(dataLength));
427
-
428
- return this.createSuccessResponse(id, Number(minBalance));
429
- }
430
-
431
- private handleGetMultipleAccounts(id: string | number, params: any): JsonRpcResponse {
432
- const [pubkeys, config] = params;
433
- const encoding = config?.encoding || "base64";
434
-
435
- const accounts = pubkeys.map((pubkeyStr: string) => {
436
- try {
437
- const pubkey = new PublicKey(pubkeyStr);
438
- const account = this.svm.getAccount(pubkey);
439
-
440
- if (!account) {
441
- return null;
442
- }
443
-
444
- return {
445
- lamports: Number(account.lamports),
446
- owner: new PublicKey(account.owner).toBase58(),
447
- data: encoding === "base64"
448
- ? [Buffer.from(account.data).toString("base64"), encoding]
449
- : Array.from(account.data),
450
- executable: account.executable,
451
- rentEpoch: Number(account.rentEpoch || 0)
452
- };
453
- } catch {
454
- return null;
455
- }
456
- });
457
-
458
- return this.createSuccessResponse(id, {
459
- context: { slot: Number(this.slot) },
460
- value: accounts
461
- });
462
- }
463
- }
464
-
465
- export function createLiteSVMRpcServer(port: number = 8899) {
466
- const server = new LiteSVMRpcServer();
467
-
468
- const bunServer = Bun.serve({
469
- port,
470
- async fetch(req) {
471
- if (req.method === "POST") {
472
- try {
473
- const body = await req.json();
474
-
475
- if (Array.isArray(body)) {
476
- const responses = await Promise.all(
477
- body.map(request => server.handleRequest(request))
478
- );
479
- return Response.json(responses);
480
- } else {
481
- const response = await server.handleRequest(body as JsonRpcRequest);
482
- return Response.json(response);
483
- }
484
- } catch (error) {
485
- return Response.json({
486
- jsonrpc: "2.0",
487
- id: null,
488
- error: {
489
- code: -32700,
490
- message: "Parse error"
491
- }
492
- });
493
- }
494
- }
495
-
496
- if (req.method === "OPTIONS") {
497
- return new Response(null, {
498
- headers: {
499
- "Access-Control-Allow-Origin": "*",
500
- "Access-Control-Allow-Methods": "POST, OPTIONS",
501
- "Access-Control-Allow-Headers": "Content-Type"
502
- }
503
- });
504
- }
505
-
506
- return new Response("Method not allowed", { status: 405 });
507
- },
508
- error(error) {
509
- console.error("Server error:", error);
510
- return new Response("Internal Server Error", { status: 500 });
511
- }
512
- });
513
-
514
- console.log(`🚀 LiteSVM RPC Server running on http://localhost:${port}`);
515
- console.log(` Compatible with Solana RPC API`);
516
- console.log(` Use with: solana config set -u http://localhost:${port}`);
517
-
518
- return bunServer;
519
- }
package/sf.config.json DELETED
@@ -1,38 +0,0 @@
1
- {
2
- "server": {
3
- "rpcPort": 8899,
4
- "wsPort": 8900,
5
- "db": {
6
- "mode": "ephemeral",
7
- "path": ".solforge/db.db"
8
- }
9
- },
10
- "svm": {
11
- "initialLamports": "1000000000000000",
12
- "faucetSOL": 1000
13
- },
14
- "clone": {
15
- "endpoint": "https://api.mainnet-beta.solana.com",
16
- "programs": [
17
- "JARSq9S9RgyynuAwcdWh2yEG6MbhfntWq7zjXjAo87uQ"
18
- ],
19
- "tokens": [
20
- "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
21
- "XsDoVfqeBukxuZHWhdvWHBhgEHjGNst4MLodqsJHzoB",
22
- "pumpCmXqMfrsAkQ5r49WcJnRayYRqmXz6ae8H7H9Dfn"
23
- ],
24
- "programAccounts": []
25
- },
26
- "gui": {
27
- "enabled": true,
28
- "port": 42069
29
- },
30
- "bootstrap": {
31
- "airdrops": [
32
- {
33
- "address": "JARSnsWXAxUAp6Ny3Td9H1i4wNpesqkcfL1wf82t5tKi",
34
- "amountSol": 100
35
- }
36
- ]
37
- }
38
- }
@@ -1,27 +0,0 @@
1
- /** @type {import('tailwindcss').Config} */
2
- export default {
3
- darkMode: "class",
4
- content: [
5
- "./src/gui/public/index.html",
6
- "./src/gui/src/**/*.{ts,tsx,js,jsx}",
7
- ],
8
- theme: {
9
- extend: {
10
- colors: {
11
- bg: {
12
- primary: "#0f172a",
13
- surface: "#111827",
14
- elevated: "#1f2937",
15
- },
16
- accent: {
17
- primary: "#22d3ee",
18
- hover: "#67e8f9",
19
- },
20
- },
21
- boxShadow: {
22
- soft: "0 10px 25px -15px rgba(15, 23, 42, 0.9)",
23
- },
24
- },
25
- },
26
- plugins: [],
27
- };
package/test-client.ts DELETED
@@ -1,120 +0,0 @@
1
- import {
2
- appendTransactionMessageInstructions,
3
- createSolanaRpc,
4
- createTransactionMessage,
5
- generateKeyPairSigner,
6
- getBase64EncodedWireTransaction,
7
- getSignatureFromTransaction,
8
- lamports,
9
- pipe,
10
- setTransactionMessageFeePayerSigner,
11
- setTransactionMessageLifetimeUsingBlockhash,
12
- signTransactionMessageWithSigners,
13
- } from "@solana/kit";
14
- import { getTransferSolInstruction } from "@solana-program/system";
15
-
16
- async function testLiteSVMRpc() {
17
- console.log("🧪 Testing LiteSVM RPC Server...\n");
18
-
19
- const rpc = createSolanaRpc("http://localhost:8899");
20
-
21
- try {
22
- console.log("1️⃣ Testing getHealth...");
23
- const health = await rpc.getHealth().send();
24
- console.log(" Health:", health, "\n");
25
-
26
- console.log("2️⃣ Testing getVersion...");
27
- const version = await rpc.getVersion().send();
28
- console.log(" Version:", version, "\n");
29
-
30
- console.log("3️⃣ Creating test wallets...");
31
- const payer = await generateKeyPairSigner();
32
- const recipient = await generateKeyPairSigner();
33
- console.log(" Payer:", payer.address);
34
- console.log(" Recipient:", recipient.address, "\n");
35
-
36
- console.log("4️⃣ Requesting airdrop to payer...");
37
- const airdropAmount = lamports(2_000_000_000n);
38
- const airdropSig = await rpc
39
- .requestAirdrop(payer.address, airdropAmount, { commitment: "confirmed" })
40
- .send();
41
- console.log(" Airdrop signature:", airdropSig, "\n");
42
-
43
- console.log("5️⃣ Checking payer balance...");
44
- const { value: payerBalance } = await rpc
45
- .getBalance(payer.address, { commitment: "confirmed" })
46
- .send();
47
- console.log(
48
- " Payer balance:",
49
- Number(payerBalance) / 1_000_000_000,
50
- "SOL\n",
51
- );
52
-
53
- console.log("6️⃣ Getting latest blockhash...");
54
- const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
55
- console.log(" Blockhash:", latestBlockhash.blockhash, "\n");
56
-
57
- console.log("7️⃣ Creating transfer transaction...");
58
- const transferAmount = lamports(500_000_000n);
59
- const transferInstruction = getTransferSolInstruction({
60
- source: payer,
61
- destination: recipient.address,
62
- amount: transferAmount,
63
- });
64
-
65
- const transactionMessage = pipe(
66
- createTransactionMessage({ version: 0 }),
67
- (tx) => setTransactionMessageFeePayerSigner(payer, tx),
68
- (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
69
- (tx) => appendTransactionMessageInstructions([transferInstruction], tx),
70
- );
71
-
72
- console.log("8️⃣ Signing transaction...");
73
- const signedTransaction =
74
- await signTransactionMessageWithSigners(transactionMessage);
75
- const signature = getSignatureFromTransaction(signedTransaction);
76
- console.log(" Transaction signature:", signature, "\n");
77
-
78
- console.log("9️⃣ Simulating transaction...");
79
- const base64Tx = getBase64EncodedWireTransaction(signedTransaction);
80
- const { value: simulation } = await rpc
81
- .simulateTransaction(base64Tx, { encoding: "base64" })
82
- .send();
83
- console.log(" Simulation result:", simulation.err ? "Failed" : "Success");
84
- if (simulation.logs) {
85
- console.log(
86
- " Logs:",
87
- simulation.logs.slice(0, 3).join("\n "),
88
- "\n",
89
- );
90
- }
91
-
92
- console.log("🔟 Sending transaction...");
93
- const txSig = await rpc
94
- .sendTransaction(base64Tx, { encoding: "base64" })
95
- .send();
96
- console.log(" Transaction sent:", txSig, "\n");
97
-
98
- console.log("1️⃣1️⃣ Checking recipient balance...");
99
- const { value: recipientBalance } = await rpc
100
- .getBalance(recipient.address, { commitment: "confirmed" })
101
- .send();
102
- console.log(
103
- " Recipient balance:",
104
- Number(recipientBalance) / 1_000_000_000,
105
- "SOL\n",
106
- );
107
-
108
- console.log("1️⃣2️⃣ Getting transaction status...");
109
- const { value: statuses } = await rpc.getSignatureStatuses([txSig]).send();
110
- console.log(" Transaction status:", statuses[0], "\n");
111
-
112
- console.log("✅ All tests passed!");
113
- } catch (error) {
114
- console.error("❌ Test failed:", error);
115
- }
116
- }
117
-
118
- if (import.meta.main) {
119
- testLiteSVMRpc();
120
- }
@@ -1,4 +0,0 @@
1
- import indexHtml from "../src/gui/public/index.html";
2
-
3
- console.log("fetch" in indexHtml, typeof (indexHtml as any).fetch);
4
- console.log("serve" in indexHtml, typeof (indexHtml as any).serve);
@@ -1,5 +0,0 @@
1
- import indexHtml from "../src/gui/public/index.html";
2
-
3
- const res = new Response(indexHtml);
4
- const text = await res.text();
5
- console.log(text.slice(0, 60));