solforge 0.2.4 → 0.2.6

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 (82) 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 +69 -61
  6. package/server/lib/base58.ts +1 -1
  7. package/server/methods/account/get-account-info.ts +3 -7
  8. package/server/methods/account/get-balance.ts +3 -7
  9. package/server/methods/account/get-multiple-accounts.ts +2 -1
  10. package/server/methods/account/get-parsed-account-info.ts +3 -7
  11. package/server/methods/account/parsers/index.ts +2 -2
  12. package/server/methods/account/parsers/loader-upgradeable.ts +14 -1
  13. package/server/methods/account/parsers/spl-token.ts +29 -10
  14. package/server/methods/account/request-airdrop.ts +44 -31
  15. package/server/methods/block/get-block.ts +3 -7
  16. package/server/methods/block/get-blocks-with-limit.ts +3 -7
  17. package/server/methods/block/is-blockhash-valid.ts +3 -7
  18. package/server/methods/get-address-lookup-table.ts +3 -7
  19. package/server/methods/program/get-program-accounts.ts +9 -9
  20. package/server/methods/program/get-token-account-balance.ts +3 -7
  21. package/server/methods/program/get-token-accounts-by-delegate.ts +4 -3
  22. package/server/methods/program/get-token-accounts-by-owner.ts +61 -35
  23. package/server/methods/program/get-token-largest-accounts.ts +3 -2
  24. package/server/methods/program/get-token-supply.ts +3 -2
  25. package/server/methods/solforge/index.ts +9 -6
  26. package/server/methods/transaction/get-parsed-transaction.ts +3 -7
  27. package/server/methods/transaction/get-signature-statuses.ts +14 -7
  28. package/server/methods/transaction/get-signatures-for-address.ts +3 -7
  29. package/server/methods/transaction/get-transaction.ts +167 -81
  30. package/server/methods/transaction/send-transaction.ts +29 -16
  31. package/server/methods/transaction/simulate-transaction.ts +3 -2
  32. package/server/rpc-server.ts +47 -34
  33. package/server/types.ts +9 -6
  34. package/server/ws-server.ts +15 -8
  35. package/src/api-server-entry.ts +91 -91
  36. package/src/cli/commands/airdrop.ts +2 -2
  37. package/src/cli/commands/config.ts +2 -2
  38. package/src/cli/commands/mint.ts +3 -3
  39. package/src/cli/commands/program-clone.ts +9 -11
  40. package/src/cli/commands/program-load.ts +3 -3
  41. package/src/cli/commands/rpc-start.ts +8 -5
  42. package/src/cli/commands/token-adopt-authority.ts +1 -1
  43. package/src/cli/commands/token-clone.ts +5 -6
  44. package/src/cli/commands/token-create.ts +5 -5
  45. package/src/cli/main.ts +38 -37
  46. package/src/cli/run-solforge.ts +20 -6
  47. package/src/cli/setup-wizard.ts +8 -6
  48. package/src/commands/add-program.ts +324 -328
  49. package/src/commands/init.ts +106 -106
  50. package/src/commands/list.ts +125 -125
  51. package/src/commands/mint.ts +247 -248
  52. package/src/commands/start.ts +837 -833
  53. package/src/commands/status.ts +80 -80
  54. package/src/commands/stop.ts +381 -382
  55. package/src/config/index.ts +33 -17
  56. package/src/config/manager.ts +150 -150
  57. package/src/db/index.ts +2 -2
  58. package/src/db/tx-store.ts +12 -8
  59. package/src/gui/public/app.css +1556 -1
  60. package/src/gui/public/build/main.css +1569 -1
  61. package/src/gui/server.ts +21 -22
  62. package/src/gui/src/api.ts +1 -1
  63. package/src/gui/src/app.tsx +96 -45
  64. package/src/gui/src/components/airdrop-mint-form.tsx +49 -19
  65. package/src/gui/src/components/clone-program-modal.tsx +31 -12
  66. package/src/gui/src/components/clone-token-modal.tsx +32 -13
  67. package/src/gui/src/components/modal.tsx +18 -11
  68. package/src/gui/src/components/programs-panel.tsx +27 -15
  69. package/src/gui/src/components/status-panel.tsx +32 -18
  70. package/src/gui/src/components/tokens-panel.tsx +25 -19
  71. package/src/gui/src/index.css +491 -463
  72. package/src/index.ts +177 -149
  73. package/src/rpc/start.ts +1 -1
  74. package/src/services/api-server.ts +494 -475
  75. package/src/services/port-manager.ts +164 -167
  76. package/src/services/process-registry.ts +144 -145
  77. package/src/services/program-cloner.ts +312 -312
  78. package/src/services/token-cloner.ts +799 -797
  79. package/src/services/validator.ts +288 -290
  80. package/src/types/config.ts +72 -72
  81. package/src/utils/shell.ts +75 -75
  82. package/src/utils/token-loader.ts +78 -78
@@ -12,7 +12,7 @@ import type { RpcMethodHandler } from "../../types";
12
12
  * @see https://docs.solana.com/api/http#requestairdrop
13
13
  */
14
14
  export const requestAirdrop: RpcMethodHandler = (id, params, context) => {
15
- const [pubkeyStr, lamports, config] = params || [];
15
+ const [pubkeyStr, lamports, _config] = params || [];
16
16
 
17
17
  try {
18
18
  const toPubkey = new PublicKey(pubkeyStr);
@@ -59,13 +59,16 @@ export const requestAirdrop: RpcMethodHandler = (id, params, context) => {
59
59
  tx.sign([faucet]);
60
60
 
61
61
  // Compute pre balances for all static account keys
62
- const txMsg: any = tx.message as any;
63
- const rawKeys: any[] = Array.isArray(txMsg.staticAccountKeys)
64
- ? txMsg.staticAccountKeys
65
- : Array.isArray(txMsg.accountKeys)
66
- ? txMsg.accountKeys
62
+ const msg = tx.message as unknown as {
63
+ staticAccountKeys?: unknown;
64
+ accountKeys?: unknown;
65
+ };
66
+ const rawKeys = Array.isArray(msg.staticAccountKeys)
67
+ ? (msg.staticAccountKeys as unknown[])
68
+ : Array.isArray(msg.accountKeys)
69
+ ? (msg.accountKeys as unknown[])
67
70
  : [];
68
- const staticKeys = rawKeys.map((k: any) => {
71
+ const staticKeys = rawKeys.map((k) => {
69
72
  try {
70
73
  return typeof k === "string" ? new PublicKey(k) : (k as PublicKey);
71
74
  } catch {
@@ -94,18 +97,22 @@ export const requestAirdrop: RpcMethodHandler = (id, params, context) => {
94
97
  const sendResult = context.svm.sendTransaction(tx);
95
98
  // Surface errors to aid debugging
96
99
  try {
97
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
98
- const rawErrFun = (sendResult as any).err;
100
+ const rawErr = (sendResult as { err?: unknown }).err;
99
101
  const maybeErr =
100
- typeof rawErrFun === "function" ? rawErrFun() : rawErrFun;
102
+ typeof rawErr === "function" ? (rawErr as () => unknown)() : rawErr;
101
103
  if (maybeErr) {
102
104
  let logsForErr: string[] = [];
103
105
  try {
104
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
105
- const anyRes: any = sendResult;
106
- if (typeof anyRes?.logs === "function") logsForErr = anyRes.logs();
107
- else if (typeof anyRes?.meta === "function")
108
- logsForErr = anyRes.meta()?.logs?.() ?? [];
106
+ const sr = sendResult as {
107
+ logs?: () => string[];
108
+ meta?: () => { logs?: () => string[] } | undefined;
109
+ };
110
+ if (typeof sr?.logs === "function") logsForErr = sr.logs();
111
+ else if (typeof sr?.meta === "function") {
112
+ const m = sr.meta();
113
+ const lg = m?.logs;
114
+ if (typeof lg === "function") logsForErr = lg();
115
+ }
109
116
  } catch {}
110
117
  console.warn(
111
118
  "[requestAirdrop] transfer failed. err=",
@@ -130,11 +137,16 @@ export const requestAirdrop: RpcMethodHandler = (id, params, context) => {
130
137
  });
131
138
  let logs: string[] = [];
132
139
  try {
133
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
134
- const anyRes: any = sendResult;
135
- if (typeof anyRes?.logs === "function") logs = anyRes.logs();
136
- else if (typeof anyRes?.meta === "function")
137
- logs = anyRes.meta()?.logs?.() ?? [];
140
+ const sr = sendResult as {
141
+ logs?: () => string[];
142
+ meta?: () => { logs?: () => string[] } | undefined;
143
+ };
144
+ if (typeof sr?.logs === "function") logs = sr.logs();
145
+ else if (typeof sr?.meta === "function") {
146
+ const m = sr.meta();
147
+ const lg = m?.logs;
148
+ if (typeof lg === "function") logs = lg();
149
+ }
138
150
  } catch {}
139
151
  // Verify recipient received lamports; retry once if not
140
152
  const afterTo =
@@ -175,7 +187,9 @@ export const requestAirdrop: RpcMethodHandler = (id, params, context) => {
175
187
  tx2.sign([faucet]);
176
188
  const res2 = context.svm.sendTransaction(tx2);
177
189
  try {
178
- const e2 = (res2 as any).err?.() ?? (res2 as any).err;
190
+ const e2Raw = (res2 as { err?: unknown }).err;
191
+ const e2 =
192
+ typeof e2Raw === "function" ? (e2Raw as () => unknown)() : e2Raw;
179
193
  if (e2) console.warn("[requestAirdrop] retry failed:", e2);
180
194
  } catch {}
181
195
  signature = tx2.signatures[0]
@@ -193,10 +207,13 @@ export const requestAirdrop: RpcMethodHandler = (id, params, context) => {
193
207
  }
194
208
 
195
209
  // Try to capture error again for accurate status reporting
196
- let recErr: any = null;
210
+ let recErr: unknown = null;
197
211
  try {
198
- const rawErrFun = (sendResult as any).err;
199
- recErr = typeof rawErrFun === "function" ? rawErrFun() : rawErrFun;
212
+ const rawErrFun = (sendResult as { err?: unknown }).err;
213
+ recErr =
214
+ typeof rawErrFun === "function"
215
+ ? (rawErrFun as () => unknown)()
216
+ : rawErrFun;
200
217
  } catch {}
201
218
  context.recordTransaction(signature, tx, {
202
219
  logs,
@@ -208,12 +225,8 @@ export const requestAirdrop: RpcMethodHandler = (id, params, context) => {
208
225
  });
209
226
 
210
227
  return context.createSuccessResponse(id, signature);
211
- } catch (error: any) {
212
- return context.createErrorResponse(
213
- id,
214
- -32602,
215
- "Invalid params",
216
- error.message,
217
- );
228
+ } catch (error: unknown) {
229
+ const message = error instanceof Error ? error.message : String(error);
230
+ return context.createErrorResponse(id, -32602, "Invalid params", message);
218
231
  }
219
232
  };
@@ -24,12 +24,8 @@ export const getBlock: RpcMethodHandler = (id, params, context) => {
24
24
  rewards: [],
25
25
  blockTime,
26
26
  });
27
- } catch (error: any) {
28
- return context.createErrorResponse(
29
- id,
30
- -32602,
31
- "Invalid params",
32
- error.message,
33
- );
27
+ } catch (error: unknown) {
28
+ const message = error instanceof Error ? error.message : String(error);
29
+ return context.createErrorResponse(id, -32602, "Invalid params", message);
34
30
  }
35
31
  };
@@ -12,12 +12,8 @@ export const getBlocksWithLimit: RpcMethodHandler = (id, params, context) => {
12
12
  const blocks: number[] = [];
13
13
  for (let s = start; s <= end; s++) blocks.push(s);
14
14
  return context.createSuccessResponse(id, blocks);
15
- } catch (error: any) {
16
- return context.createErrorResponse(
17
- id,
18
- -32602,
19
- "Invalid params",
20
- error.message,
21
- );
15
+ } catch (error: unknown) {
16
+ const message = error instanceof Error ? error.message : String(error);
17
+ return context.createErrorResponse(id, -32602, "Invalid params", message);
22
18
  }
23
19
  };
@@ -12,12 +12,8 @@ export const isBlockhashValid: RpcMethodHandler = (id, params, context) => {
12
12
  context: { slot: Number(context.slot) },
13
13
  value: isValid,
14
14
  });
15
- } catch (error: any) {
16
- return context.createErrorResponse(
17
- id,
18
- -32602,
19
- "Invalid params",
20
- error.message,
21
- );
15
+ } catch (error: unknown) {
16
+ const message = error instanceof Error ? error.message : String(error);
17
+ return context.createErrorResponse(id, -32602, "Invalid params", message);
22
18
  }
23
19
  };
@@ -20,12 +20,8 @@ export const getAddressLookupTable: RpcMethodHandler = (
20
20
  context: { slot: Number(context.slot) },
21
21
  value: null,
22
22
  });
23
- } catch (error: any) {
24
- return context.createErrorResponse(
25
- id,
26
- -32602,
27
- "Invalid params",
28
- error.message,
29
- );
23
+ } catch (error: unknown) {
24
+ const message = error instanceof Error ? error.message : String(error);
25
+ return context.createErrorResponse(id, -32602, "Invalid params", message);
30
26
  }
31
27
  };
@@ -21,7 +21,11 @@ export const getProgramAccounts: RpcMethodHandler = async (
21
21
  const dataSlice = cfg?.dataSlice as
22
22
  | { offset: number; length: number }
23
23
  | undefined;
24
- const filters = (cfg?.filters || []) as Array<any>;
24
+ type GpaFilter = {
25
+ dataSize?: number;
26
+ memcmp?: { offset?: number; bytes?: string };
27
+ };
28
+ const filters: GpaFilter[] = (cfg?.filters as unknown as GpaFilter[]) || [];
25
29
  const limit = Math.max(1, Math.min(Number(cfg?.limit ?? 10000), 50000));
26
30
 
27
31
  let rows: Array<{ address: string }> = [];
@@ -29,7 +33,7 @@ export const getProgramAccounts: RpcMethodHandler = async (
29
33
  rows = (await context.store?.getAccountsByOwner(programStr, limit)) || [];
30
34
  } catch {}
31
35
 
32
- const out: any[] = [];
36
+ const out: unknown[] = [];
33
37
  for (const r of rows) {
34
38
  try {
35
39
  const pk = new PublicKey(r.address);
@@ -210,12 +214,8 @@ export const getProgramAccounts: RpcMethodHandler = async (
210
214
  }
211
215
 
212
216
  return context.createSuccessResponse(id, out);
213
- } catch (error: any) {
214
- return context.createErrorResponse(
215
- id,
216
- -32602,
217
- "Invalid params",
218
- error.message,
219
- );
217
+ } catch (error: unknown) {
218
+ const message = error instanceof Error ? error.message : String(error);
219
+ return context.createErrorResponse(id, -32602, "Invalid params", message);
220
220
  }
221
221
  };
@@ -53,12 +53,8 @@ export const getTokenAccountBalance: RpcMethodHandler = (
53
53
  uiAmountString: ui.toString(),
54
54
  },
55
55
  });
56
- } catch (error: any) {
57
- return context.createErrorResponse(
58
- id,
59
- -32602,
60
- "Invalid params",
61
- error.message,
62
- );
56
+ } catch (error: unknown) {
57
+ const message = error instanceof Error ? error.message : String(error);
58
+ return context.createErrorResponse(id, -32602, "Invalid params", message);
63
59
  }
64
60
  };
@@ -23,7 +23,7 @@ export const getTokenAccountsByDelegate: RpcMethodHandler = async (
23
23
  requestedProgramId === token2022Id ? token2022Id : classicId;
24
24
  const rows =
25
25
  (await context.store?.getAccountsByOwner(programFilter, 50_000)) || [];
26
- const out: any[] = [];
26
+ const out: unknown[] = [];
27
27
  for (const r of rows) {
28
28
  try {
29
29
  const acc = context.svm.getAccount(new PublicKey(r.address));
@@ -75,7 +75,8 @@ export const getTokenAccountsByDelegate: RpcMethodHandler = async (
75
75
  context: { slot: Number(context.slot) },
76
76
  value: out,
77
77
  });
78
- } catch (e: any) {
79
- return context.createErrorResponse(id, -32602, "Invalid params", e.message);
78
+ } catch (e: unknown) {
79
+ const message = e instanceof Error ? e.message : String(e);
80
+ return context.createErrorResponse(id, -32602, "Invalid params", message);
80
81
  }
81
82
  };
@@ -30,7 +30,7 @@ export const getTokenAccountsByOwner: RpcMethodHandler = async (
30
30
  : [classicId, token2022Id];
31
31
 
32
32
  // Query DB for accounts owned by both SPL Token programs (classic + 2022)
33
- const rows: Array<{ address: string; lastSlot: number } & any> = [];
33
+ const rows: Array<{ address: string; lastSlot: number }> = [];
34
34
  for (const programId of programIds) {
35
35
  try {
36
36
  const found =
@@ -43,7 +43,7 @@ export const getTokenAccountsByOwner: RpcMethodHandler = async (
43
43
  }
44
44
  }
45
45
 
46
- const out: any[] = [];
46
+ const out: unknown[] = [];
47
47
  const seen = new Set<string>();
48
48
  for (const r of rows) {
49
49
  if (seen.has(r.address)) continue;
@@ -55,11 +55,12 @@ export const getTokenAccountsByOwner: RpcMethodHandler = async (
55
55
  let ownerPk: PublicKey;
56
56
  try {
57
57
  // acc.owner may already be a PublicKey in LiteSVM
58
- const anyOwner: any = (acc as any).owner;
58
+ const rawOwner = (acc as { owner?: unknown }).owner;
59
59
  ownerPk =
60
- typeof anyOwner?.toBase58 === "function"
61
- ? (anyOwner as PublicKey)
62
- : new PublicKey(anyOwner);
60
+ rawOwner &&
61
+ typeof (rawOwner as { toBase58?: unknown }).toBase58 === "function"
62
+ ? (rawOwner as PublicKey)
63
+ : new PublicKey(String(rawOwner));
63
64
  } catch {
64
65
  ownerPk = TOKEN_PROGRAM_ID; // fallback avoids throw; unpackAccount will fail if wrong and be skipped
65
66
  }
@@ -80,9 +81,14 @@ export const getTokenAccountsByOwner: RpcMethodHandler = async (
80
81
  try {
81
82
  const mintAcc = context.svm.getAccount(dec.mint);
82
83
  const mintOwnerPk = mintAcc
83
- ? typeof (mintAcc as any).owner?.toBase58 === "function"
84
- ? (mintAcc as any).owner
85
- : new PublicKey(mintAcc.owner)
84
+ ? ((): PublicKey => {
85
+ const ro = (mintAcc as { owner?: unknown }).owner;
86
+ return ro &&
87
+ typeof (ro as { toBase58?: unknown }).toBase58 ===
88
+ "function"
89
+ ? (ro as PublicKey)
90
+ : new PublicKey(String(ro));
91
+ })()
86
92
  : programPk;
87
93
  const info = mintAcc
88
94
  ? unpackMint(
@@ -122,7 +128,12 @@ export const getTokenAccountsByOwner: RpcMethodHandler = async (
122
128
  uiAmountString: (delegatedUiAmount ?? 0).toString(),
123
129
  };
124
130
  // rentExemptReserve only for native (wrapped SOL) accounts; value in lamports (9 decimals)
125
- let rentExemptReserve = null as any;
131
+ let rentExemptReserve: {
132
+ amount: string;
133
+ decimals: number;
134
+ uiAmount: number | null;
135
+ uiAmountString: string;
136
+ } | null = null;
126
137
  if (dec.isNative) {
127
138
  const lamports = BigInt(
128
139
  dec.rentExemptReserve?.toString?.() ??
@@ -196,9 +207,13 @@ export const getTokenAccountsByOwner: RpcMethodHandler = async (
196
207
  const mintPk = new PublicKey(m);
197
208
  const mintAcc = context.svm.getAccount(mintPk);
198
209
  const mintOwnerPk = mintAcc
199
- ? typeof (mintAcc as any).owner?.toBase58 === "function"
200
- ? (mintAcc as any).owner
201
- : new PublicKey(mintAcc.owner)
210
+ ? ((): PublicKey => {
211
+ const ro = (mintAcc as { owner?: unknown }).owner;
212
+ return ro &&
213
+ typeof (ro as { toBase58?: unknown }).toBase58 === "function"
214
+ ? (ro as PublicKey)
215
+ : new PublicKey(String(ro));
216
+ })()
202
217
  : TOKEN_PROGRAM_ID;
203
218
  // Determine which token program this mint belongs to
204
219
  const programForMint = mintOwnerPk.equals(TOKEN_2022_PROGRAM_ID)
@@ -221,12 +236,12 @@ export const getTokenAccountsByOwner: RpcMethodHandler = async (
221
236
  const acc = context.svm.getAccount(ata);
222
237
  if (!acc || (acc.data?.length ?? 0) < ACCOUNT_SIZE) continue;
223
238
  if (seen.has(ata.toBase58())) continue;
224
- let ownerPk: PublicKey;
225
- const anyOwner: any = (acc as any).owner;
226
- ownerPk =
227
- typeof anyOwner?.toBase58 === "function"
228
- ? (anyOwner as PublicKey)
229
- : new PublicKey(anyOwner);
239
+ const rawOwner = (acc as { owner?: unknown }).owner;
240
+ const ownerPk: PublicKey =
241
+ rawOwner &&
242
+ typeof (rawOwner as { toBase58?: unknown }).toBase58 === "function"
243
+ ? (rawOwner as PublicKey)
244
+ : new PublicKey(String(rawOwner));
230
245
  const programPk = ownerPk.equals(TOKEN_2022_PROGRAM_ID)
231
246
  ? TOKEN_2022_PROGRAM_ID
232
247
  : TOKEN_PROGRAM_ID;
@@ -249,9 +264,14 @@ export const getTokenAccountsByOwner: RpcMethodHandler = async (
249
264
  try {
250
265
  const mintAcc = context.svm.getAccount(dec.mint);
251
266
  const mintOwnerPk = mintAcc
252
- ? typeof (mintAcc as any).owner?.toBase58 === "function"
253
- ? (mintAcc as any).owner
254
- : new PublicKey(mintAcc.owner)
267
+ ? ((): PublicKey => {
268
+ const ro = (mintAcc as { owner?: unknown }).owner;
269
+ return ro &&
270
+ typeof (ro as { toBase58?: unknown }).toBase58 ===
271
+ "function"
272
+ ? (ro as PublicKey)
273
+ : new PublicKey(String(ro));
274
+ })()
255
275
  : programPk;
256
276
  const info = mintAcc
257
277
  ? unpackMint(
@@ -326,9 +346,14 @@ export const getTokenAccountsByOwner: RpcMethodHandler = async (
326
346
  const ownerPk = new PublicKey(ownerStr);
327
347
  const mintAcc = context.svm.getAccount(mintPk);
328
348
  const mintOwnerPk = mintAcc
329
- ? typeof (mintAcc as any).owner?.toBase58 === "function"
330
- ? (mintAcc as any).owner
331
- : new PublicKey(mintAcc.owner)
349
+ ? ((): PublicKey => {
350
+ const ro = (mintAcc as { owner?: unknown }).owner;
351
+ return ro &&
352
+ typeof (ro as { toBase58?: unknown }).toBase58 ===
353
+ "function"
354
+ ? (ro as PublicKey)
355
+ : new PublicKey(String(ro));
356
+ })()
332
357
  : TOKEN_PROGRAM_ID;
333
358
  const programForMint = mintOwnerPk.equals(TOKEN_2022_PROGRAM_ID)
334
359
  ? TOKEN_2022_PROGRAM_ID
@@ -359,12 +384,17 @@ export const getTokenAccountsByOwner: RpcMethodHandler = async (
359
384
  }
360
385
 
361
386
  // Build filtered list keeping only chosen indices
362
- const keep = new Set<number>(Array.from(pick.values()).filter((v) => typeof v === "number" && v >= 0));
363
- const filtered: any[] = [];
387
+ const keep = new Set<number>(
388
+ Array.from(pick.values()).filter(
389
+ (v) => typeof v === "number" && v >= 0,
390
+ ),
391
+ );
392
+ const filtered: unknown[] = [];
364
393
  for (let i = 0; i < out.length; i++) {
365
394
  const e = out[i];
366
395
  const info = e.account?.data?.parsed?.info;
367
- const key = info?.owner && info?.mint ? `${info.owner}:${info.mint}` : null;
396
+ const key =
397
+ info?.owner && info?.mint ? `${info.owner}:${info.mint}` : null;
368
398
  if (key && keep.has(i)) filtered.push(e);
369
399
  else if (!key) filtered.push(e); // non-parsed or unexpected shape
370
400
  }
@@ -376,15 +406,11 @@ export const getTokenAccountsByOwner: RpcMethodHandler = async (
376
406
  context: { slot: Number(context.slot) },
377
407
  value: out,
378
408
  });
379
- } catch (e: any) {
409
+ } catch (e: unknown) {
380
410
  try {
381
411
  console.error("[rpc] getTokenAccountsByOwner error", e);
382
412
  } catch {}
383
- return context.createErrorResponse(
384
- id,
385
- -32603,
386
- "Internal error",
387
- e?.message || String(e),
388
- );
413
+ const message = e instanceof Error ? e.message : String(e);
414
+ return context.createErrorResponse(id, -32603, "Internal error", message);
389
415
  }
390
416
  };
@@ -74,7 +74,8 @@ export const getTokenLargestAccounts: RpcMethodHandler = async (
74
74
  context: { slot: Number(context.slot) },
75
75
  value: top,
76
76
  });
77
- } catch (e: any) {
78
- return context.createErrorResponse(id, -32602, "Invalid params", e.message);
77
+ } catch (e: unknown) {
78
+ const message = e instanceof Error ? e.message : String(e);
79
+ return context.createErrorResponse(id, -32602, "Invalid params", message);
79
80
  }
80
81
  };
@@ -32,7 +32,8 @@ export const getTokenSupply: RpcMethodHandler = (id, params, context) => {
32
32
  uiAmountString: ui.toString(),
33
33
  },
34
34
  });
35
- } catch (e: any) {
36
- return context.createErrorResponse(id, -32602, "Invalid params", e.message);
35
+ } catch (e: unknown) {
36
+ const message = e instanceof Error ? e.message : String(e);
37
+ return context.createErrorResponse(id, -32602, "Invalid params", message);
37
38
  }
38
39
  };
@@ -46,12 +46,13 @@ export const solforgeGetStatus: RpcMethodHandler = async (
46
46
  ...formatLamports(faucetLamports),
47
47
  },
48
48
  });
49
- } catch (error: any) {
49
+ } catch (error: unknown) {
50
+ const message = error instanceof Error ? error.message : String(error);
50
51
  return context.createErrorResponse(
51
52
  id,
52
53
  -32603,
53
54
  "Status unavailable",
54
- error?.message || String(error),
55
+ message,
55
56
  );
56
57
  }
57
58
  };
@@ -90,12 +91,13 @@ export const solforgeListPrograms: RpcMethodHandler = async (
90
91
  .filter(Boolean);
91
92
 
92
93
  return context.createSuccessResponse(id, detailed);
93
- } catch (error: any) {
94
+ } catch (error: unknown) {
95
+ const message = error instanceof Error ? error.message : String(error);
94
96
  return context.createErrorResponse(
95
97
  id,
96
98
  -32603,
97
99
  "List programs failed",
98
- error?.message || String(error),
100
+ message,
99
101
  );
100
102
  }
101
103
  };
@@ -144,12 +146,13 @@ export const solforgeListTokensDetailed: RpcMethodHandler = async (
144
146
  .filter(Boolean);
145
147
 
146
148
  return context.createSuccessResponse(id, detailed);
147
- } catch (error: any) {
149
+ } catch (error: unknown) {
150
+ const message = error instanceof Error ? error.message : String(error);
148
151
  return context.createErrorResponse(
149
152
  id,
150
153
  -32603,
151
154
  "List tokens failed",
152
- error?.message || String(error),
155
+ message,
153
156
  );
154
157
  }
155
158
  };
@@ -10,12 +10,8 @@ export const getParsedTransaction: RpcMethodHandler = async (
10
10
  const cfg = { ...(config || {}), encoding: "jsonParsed" };
11
11
  try {
12
12
  return await getTransaction(id, [signature, cfg], context);
13
- } catch (error: any) {
14
- return context.createErrorResponse(
15
- id,
16
- -32603,
17
- "Internal error",
18
- error.message,
19
- );
13
+ } catch (error: unknown) {
14
+ const message = error instanceof Error ? error.message : String(error);
15
+ return context.createErrorResponse(id, -32603, "Internal error", message);
20
16
  }
21
17
  };
@@ -7,7 +7,7 @@ export const getSignatureStatuses: RpcMethodHandler = async (
7
7
  ) => {
8
8
  const [signatures] = params;
9
9
 
10
- let persisted: Map<string, { slot: number; err: any | null }> = new Map();
10
+ let persisted: Map<string, { slot: number; err: unknown | null }> = new Map();
11
11
  try {
12
12
  persisted = (await context.store?.getStatuses(signatures)) || new Map();
13
13
  } catch {}
@@ -17,7 +17,7 @@ export const getSignatureStatuses: RpcMethodHandler = async (
17
17
  // Prefer locally recorded transactions for reliability with CLI tooling
18
18
  const rec = context.getRecordedTransaction(sig);
19
19
  if (rec) {
20
- const errVal: any = rec.err ?? null;
20
+ const errVal: unknown = rec.err ?? null;
21
21
  const status = errVal ? { Err: errVal } : { Ok: null };
22
22
  return {
23
23
  slot: rec.slot,
@@ -29,7 +29,7 @@ export const getSignatureStatuses: RpcMethodHandler = async (
29
29
  }
30
30
  const db = persisted.get(sig);
31
31
  if (db) {
32
- const errVal: any = db.err ?? null;
32
+ const errVal: unknown = db.err ?? null;
33
33
  const status = errVal ? { Err: errVal } : { Ok: null };
34
34
  return {
35
35
  slot: db.slot,
@@ -41,13 +41,20 @@ export const getSignatureStatuses: RpcMethodHandler = async (
41
41
  }
42
42
 
43
43
  const sigBytes = context.decodeBase58(sig);
44
- const tx = (context.svm as any).getTransaction(sigBytes);
44
+ const txGetter = (
45
+ context.svm as unknown as {
46
+ getTransaction?: (sig: Uint8Array) => { err?: unknown } | undefined;
47
+ }
48
+ ).getTransaction;
49
+ const tx =
50
+ typeof txGetter === "function" ? txGetter(sigBytes) : undefined;
45
51
  if (!tx) return null;
46
52
 
47
- let errVal: any = null;
53
+ let errVal: unknown = null;
48
54
  try {
49
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
- errVal = "err" in tx ? (tx as any).err() : null;
55
+ const rawErr = (tx as { err?: unknown }).err;
56
+ errVal =
57
+ typeof rawErr === "function" ? (rawErr as () => unknown)() : rawErr;
51
58
  } catch {
52
59
  errVal = null;
53
60
  }
@@ -31,15 +31,11 @@ export const getSignaturesForAddress: RpcMethodHandler = async (
31
31
  // Graceful fallback: return empty list instead of error
32
32
  return context.createSuccessResponse(id, []);
33
33
  }
34
- } catch (error: any) {
34
+ } catch (error: unknown) {
35
35
  try {
36
36
  console.error("[rpc] getSignaturesForAddress error", error);
37
37
  } catch {}
38
- return context.createErrorResponse(
39
- id,
40
- -32603,
41
- "Internal error",
42
- error.message,
43
- );
38
+ const message = error instanceof Error ? error.message : String(error);
39
+ return context.createErrorResponse(id, -32603, "Internal error", message);
44
40
  }
45
41
  };