solforge 0.2.5 → 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 (73) hide show
  1. package/package.json +1 -1
  2. package/scripts/postinstall.cjs +3 -3
  3. package/server/lib/base58.ts +1 -1
  4. package/server/methods/account/get-account-info.ts +3 -7
  5. package/server/methods/account/get-balance.ts +3 -7
  6. package/server/methods/account/get-multiple-accounts.ts +2 -1
  7. package/server/methods/account/get-parsed-account-info.ts +3 -7
  8. package/server/methods/account/parsers/index.ts +2 -2
  9. package/server/methods/account/parsers/loader-upgradeable.ts +14 -1
  10. package/server/methods/account/parsers/spl-token.ts +29 -10
  11. package/server/methods/account/request-airdrop.ts +44 -31
  12. package/server/methods/block/get-block.ts +3 -7
  13. package/server/methods/block/get-blocks-with-limit.ts +3 -7
  14. package/server/methods/block/is-blockhash-valid.ts +3 -7
  15. package/server/methods/get-address-lookup-table.ts +3 -7
  16. package/server/methods/program/get-program-accounts.ts +9 -9
  17. package/server/methods/program/get-token-account-balance.ts +3 -7
  18. package/server/methods/program/get-token-accounts-by-delegate.ts +4 -3
  19. package/server/methods/program/get-token-accounts-by-owner.ts +54 -33
  20. package/server/methods/program/get-token-largest-accounts.ts +3 -2
  21. package/server/methods/program/get-token-supply.ts +3 -2
  22. package/server/methods/solforge/index.ts +9 -6
  23. package/server/methods/transaction/get-parsed-transaction.ts +3 -7
  24. package/server/methods/transaction/get-signature-statuses.ts +14 -7
  25. package/server/methods/transaction/get-signatures-for-address.ts +3 -7
  26. package/server/methods/transaction/get-transaction.ts +167 -81
  27. package/server/methods/transaction/send-transaction.ts +29 -16
  28. package/server/methods/transaction/simulate-transaction.ts +3 -2
  29. package/server/rpc-server.ts +47 -34
  30. package/server/types.ts +9 -6
  31. package/server/ws-server.ts +11 -7
  32. package/src/api-server-entry.ts +5 -5
  33. package/src/cli/commands/airdrop.ts +2 -2
  34. package/src/cli/commands/config.ts +2 -2
  35. package/src/cli/commands/mint.ts +3 -3
  36. package/src/cli/commands/program-clone.ts +9 -11
  37. package/src/cli/commands/program-load.ts +3 -3
  38. package/src/cli/commands/rpc-start.ts +7 -7
  39. package/src/cli/commands/token-adopt-authority.ts +1 -1
  40. package/src/cli/commands/token-clone.ts +5 -6
  41. package/src/cli/commands/token-create.ts +5 -5
  42. package/src/cli/main.ts +33 -36
  43. package/src/cli/run-solforge.ts +3 -3
  44. package/src/cli/setup-wizard.ts +8 -6
  45. package/src/commands/add-program.ts +1 -1
  46. package/src/commands/init.ts +2 -2
  47. package/src/commands/mint.ts +5 -6
  48. package/src/commands/start.ts +10 -9
  49. package/src/commands/status.ts +1 -1
  50. package/src/commands/stop.ts +1 -1
  51. package/src/config/index.ts +33 -17
  52. package/src/config/manager.ts +3 -3
  53. package/src/db/index.ts +2 -2
  54. package/src/db/tx-store.ts +12 -8
  55. package/src/gui/public/app.css +13 -13
  56. package/src/gui/server.ts +1 -1
  57. package/src/gui/src/api.ts +1 -1
  58. package/src/gui/src/app.tsx +49 -17
  59. package/src/gui/src/components/airdrop-mint-form.tsx +32 -8
  60. package/src/gui/src/components/clone-program-modal.tsx +25 -6
  61. package/src/gui/src/components/clone-token-modal.tsx +25 -6
  62. package/src/gui/src/components/modal.tsx +6 -1
  63. package/src/gui/src/components/status-panel.tsx +1 -1
  64. package/src/index.ts +19 -6
  65. package/src/services/api-server.ts +41 -19
  66. package/src/services/port-manager.ts +7 -10
  67. package/src/services/process-registry.ts +4 -5
  68. package/src/services/program-cloner.ts +4 -4
  69. package/src/services/token-cloner.ts +4 -4
  70. package/src/services/validator.ts +2 -4
  71. package/src/types/config.ts +2 -2
  72. package/src/utils/shell.ts +1 -1
  73. package/src/utils/token-loader.ts +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "solforge",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "module": "index.ts",
5
5
  "type": "module",
6
6
  "private": false,
@@ -4,9 +4,9 @@
4
4
  - Skips if SOLFORGE_SKIP_DOWNLOAD=true
5
5
  - Falls back silently on errors (CLI will still work via Bun if installed)
6
6
  */
7
- const fs = require("fs");
8
- const path = require("path");
9
- const https = require("https");
7
+ const fs = require("node:fs");
8
+ const path = require("node:path");
9
+ const https = require("node:https");
10
10
 
11
11
  function log(msg) {
12
12
  console.log(`[solforge] ${msg}`);
@@ -12,7 +12,7 @@ export function encodeBase58(bytes: Uint8Array): string {
12
12
  encoded = ALPHABET[Number(remainder)] + encoded;
13
13
  }
14
14
  for (let i = 0; i < bytes.length && bytes[i] === 0; i++)
15
- encoded = "1" + encoded;
15
+ encoded = `1${encoded}`;
16
16
  return encoded || "1";
17
17
  }
18
18
 
@@ -79,12 +79,8 @@ export const getAccountInfo: RpcMethodHandler = async (id, params, context) => {
79
79
  context: { slot: Number(context.slot) },
80
80
  value: accountInfo,
81
81
  });
82
- } catch (error: any) {
83
- return context.createErrorResponse(
84
- id,
85
- -32602,
86
- "Invalid params",
87
- error.message,
88
- );
82
+ } catch (error: unknown) {
83
+ const message = error instanceof Error ? error.message : String(error);
84
+ return context.createErrorResponse(id, -32602, "Invalid params", message);
89
85
  }
90
86
  };
@@ -16,12 +16,8 @@ export const getBalance: RpcMethodHandler = (id, params, context) => {
16
16
  context: { slot: Number(context.slot) },
17
17
  value: Number(balance || 0n),
18
18
  });
19
- } catch (error: any) {
20
- return context.createErrorResponse(
21
- id,
22
- -32602,
23
- "Invalid params",
24
- error.message,
25
- );
19
+ } catch (error: unknown) {
20
+ const message = error instanceof Error ? error.message : String(error);
21
+ return context.createErrorResponse(id, -32602, "Invalid params", message);
26
22
  }
27
23
  };
@@ -1,5 +1,6 @@
1
1
  import { PublicKey } from "@solana/web3.js";
2
2
  import type { RpcMethodHandler } from "../../types";
3
+ import type { AccountSnapshot } from "../../../src/db/tx-store";
3
4
 
4
5
  /**
5
6
  * Implements the getMultipleAccounts RPC method
@@ -54,7 +55,7 @@ export const getMultipleAccounts: RpcMethodHandler = async (
54
55
 
55
56
  // Opportunistic index update
56
57
  try {
57
- const snaps: any[] = [];
58
+ const snaps: AccountSnapshot[] = [];
58
59
  for (const pubkeyStr of pubkeys) {
59
60
  try {
60
61
  const pubkey = new PublicKey(pubkeyStr);
@@ -10,12 +10,8 @@ export const getParsedAccountInfo: RpcMethodHandler = async (
10
10
  const cfg = { ...(config || {}), encoding: "jsonParsed" };
11
11
  try {
12
12
  return await getAccountInfo(id, [pubkey, 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
  };
@@ -6,7 +6,7 @@ import { parseSystemAccount } from "./system";
6
6
 
7
7
  export type ParsedAccountData = {
8
8
  program: string;
9
- parsed: any; // match Solana RPC jsonParsed payloads
9
+ parsed: unknown; // match Solana RPC jsonParsed payloads
10
10
  space: number;
11
11
  } | null;
12
12
 
@@ -32,7 +32,7 @@ export function parseAccountJson(
32
32
  const dataBytes =
33
33
  account.data instanceof Uint8Array
34
34
  ? account.data
35
- : Buffer.from(account.data as any);
35
+ : Buffer.from(account.data as ReadonlyArray<number>);
36
36
  const space = dataBytes.length;
37
37
 
38
38
  // 1) System program
@@ -12,7 +12,20 @@ export function parseUpgradeableLoader(
12
12
  const bytes = data;
13
13
  const dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
14
14
  const space = bytes.length;
15
- let parsed: any = null;
15
+ type UpgradeableParsed =
16
+ | { type: "program"; info: { programData: string } }
17
+ | {
18
+ type: "programData";
19
+ info: {
20
+ slot: number;
21
+ upgradeAuthority: string | null;
22
+ authority: string | null;
23
+ data: [string, "base64"];
24
+ };
25
+ }
26
+ | { type: "buffer"; info: { authority: string | null } }
27
+ | null;
28
+ let parsed: UpgradeableParsed = null;
16
29
  try {
17
30
  if (bytes.length >= 4) {
18
31
  const tag = dv.getUint32(0, true);
@@ -51,10 +51,17 @@ export function parseSplTokenAccountOrMint(
51
51
  try {
52
52
  const mintAcc = context.svm.getAccount(dec.mint);
53
53
  if (mintAcc) {
54
- const mintOwner =
55
- typeof (mintAcc as any).owner?.toBase58 === "function"
56
- ? ((mintAcc as any).owner as PublicKey)
57
- : new PublicKey(mintAcc.owner);
54
+ const rawOwner = (mintAcc as { owner?: unknown }).owner;
55
+ const mintOwner = ((): PublicKey => {
56
+ if (
57
+ rawOwner &&
58
+ typeof (rawOwner as { toBase58?: unknown }).toBase58 ===
59
+ "function"
60
+ ) {
61
+ return rawOwner as PublicKey;
62
+ }
63
+ return new PublicKey(String(rawOwner));
64
+ })();
58
65
  const mintProg = mintOwner.equals(TOKEN_2022_PROGRAM_ID)
59
66
  ? TOKEN_2022_PROGRAM_ID
60
67
  : TOKEN_PROGRAM_ID;
@@ -176,18 +183,18 @@ function buildAccountExtensions(account: {
176
183
 
177
184
  function buildMintExtensions(mint: {
178
185
  tlvData: Buffer;
179
- }): Array<Record<string, any>> | undefined {
186
+ }): Array<Record<string, unknown>> | undefined {
180
187
  if (!mint.tlvData || mint.tlvData.length === 0) return undefined;
181
188
  const types = getExtensionTypes(mint.tlvData);
182
189
  if (!types.length) return undefined;
183
- const out: Array<Record<string, any>> = [];
190
+ const out: Array<Record<string, unknown>> = [];
184
191
  for (const ext of types) {
185
- const entry: Record<string, any> = {
192
+ const entry: Record<string, unknown> = {
186
193
  type: ExtensionType[ext] ?? String(ext),
187
194
  };
188
195
  try {
189
196
  if (ext === ExtensionType.MetadataPointer) {
190
- const state = getMetadataPointerState(mint as any);
197
+ const state = getMetadataPointerState(mint as { tlvData: Buffer });
191
198
  if (state) {
192
199
  entry.info = {
193
200
  authority: state.authority ? state.authority.toBase58() : null,
@@ -222,9 +229,21 @@ function buildMintExtensions(mint: {
222
229
  return out.length ? out : undefined;
223
230
  }
224
231
 
225
- function toAccountInfo(raw: any, owner: PublicKey): AccountInfo<Buffer> {
232
+ function toAccountInfo(
233
+ raw: {
234
+ data?: Buffer | Uint8Array | number[];
235
+ lamports?: number | bigint;
236
+ executable?: boolean;
237
+ rentEpoch?: number | bigint;
238
+ },
239
+ owner: PublicKey,
240
+ ): AccountInfo<Buffer> {
226
241
  const data =
227
- raw.data instanceof Buffer ? raw.data : Buffer.from(raw.data ?? []);
242
+ raw.data instanceof Buffer
243
+ ? raw.data
244
+ : raw.data instanceof Uint8Array
245
+ ? Buffer.from(raw.data)
246
+ : Buffer.from((raw.data ?? []) as number[]);
228
247
  return {
229
248
  data,
230
249
  executable: !!raw.executable,
@@ -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
@@ -364,7 +389,7 @@ export const getTokenAccountsByOwner: RpcMethodHandler = async (
364
389
  (v) => typeof v === "number" && v >= 0,
365
390
  ),
366
391
  );
367
- const filtered: any[] = [];
392
+ const filtered: unknown[] = [];
368
393
  for (let i = 0; i < out.length; i++) {
369
394
  const e = out[i];
370
395
  const info = e.account?.data?.parsed?.info;
@@ -381,15 +406,11 @@ export const getTokenAccountsByOwner: RpcMethodHandler = async (
381
406
  context: { slot: Number(context.slot) },
382
407
  value: out,
383
408
  });
384
- } catch (e: any) {
409
+ } catch (e: unknown) {
385
410
  try {
386
411
  console.error("[rpc] getTokenAccountsByOwner error", e);
387
412
  } catch {}
388
- return context.createErrorResponse(
389
- id,
390
- -32603,
391
- "Internal error",
392
- e?.message || String(e),
393
- );
413
+ const message = e instanceof Error ? e.message : String(e);
414
+ return context.createErrorResponse(id, -32603, "Internal error", message);
394
415
  }
395
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
  };