solforge 0.2.12 → 0.2.14

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 (175) hide show
  1. package/package.json +1 -5
  2. package/start.cjs +19 -23
  3. package/docs/API.md +0 -379
  4. package/docs/CONFIGURATION.md +0 -407
  5. package/docs/bun-single-file-executable.md +0 -585
  6. package/docs/cli-plan.md +0 -154
  7. package/docs/data-indexing-plan.md +0 -214
  8. package/docs/gui-roadmap.md +0 -202
  9. package/scripts/decode-b58.ts +0 -10
  10. package/scripts/install.sh +0 -112
  11. package/server/index.ts +0 -5
  12. package/server/lib/base58.ts +0 -33
  13. package/server/lib/faucet.ts +0 -110
  14. package/server/lib/instruction-parser.ts +0 -328
  15. package/server/lib/parsers/spl-associated-token-account.ts +0 -50
  16. package/server/lib/parsers/spl-token.ts +0 -340
  17. package/server/lib/spl-token.ts +0 -57
  18. package/server/methods/TEMPLATE.md +0 -117
  19. package/server/methods/account/get-account-info.ts +0 -86
  20. package/server/methods/account/get-balance.ts +0 -23
  21. package/server/methods/account/get-multiple-accounts.ts +0 -84
  22. package/server/methods/account/get-parsed-account-info.ts +0 -17
  23. package/server/methods/account/index.ts +0 -12
  24. package/server/methods/account/parsers/index.ts +0 -52
  25. package/server/methods/account/parsers/loader-upgradeable.ts +0 -79
  26. package/server/methods/account/parsers/spl-token.ts +0 -256
  27. package/server/methods/account/parsers/system.ts +0 -4
  28. package/server/methods/account/request-airdrop.ts +0 -271
  29. package/server/methods/admin/adopt-mint-authority.ts +0 -94
  30. package/server/methods/admin/clone-program-accounts.ts +0 -55
  31. package/server/methods/admin/clone-program.ts +0 -152
  32. package/server/methods/admin/clone-token-accounts.ts +0 -117
  33. package/server/methods/admin/clone-token-mint.ts +0 -82
  34. package/server/methods/admin/create-mint.ts +0 -114
  35. package/server/methods/admin/create-token-account.ts +0 -137
  36. package/server/methods/admin/helpers.ts +0 -70
  37. package/server/methods/admin/index.ts +0 -10
  38. package/server/methods/admin/list-mints.ts +0 -21
  39. package/server/methods/admin/load-program.ts +0 -52
  40. package/server/methods/admin/mint-to.ts +0 -266
  41. package/server/methods/block/get-block-height.ts +0 -5
  42. package/server/methods/block/get-block.ts +0 -31
  43. package/server/methods/block/get-blocks-with-limit.ts +0 -19
  44. package/server/methods/block/get-latest-blockhash.ts +0 -12
  45. package/server/methods/block/get-slot.ts +0 -5
  46. package/server/methods/block/index.ts +0 -6
  47. package/server/methods/block/is-blockhash-valid.ts +0 -19
  48. package/server/methods/epoch/get-cluster-nodes.ts +0 -17
  49. package/server/methods/epoch/get-epoch-info.ts +0 -16
  50. package/server/methods/epoch/get-epoch-schedule.ts +0 -15
  51. package/server/methods/epoch/get-highest-snapshot-slot.ts +0 -9
  52. package/server/methods/epoch/get-leader-schedule.ts +0 -8
  53. package/server/methods/epoch/get-max-retransmit-slot.ts +0 -9
  54. package/server/methods/epoch/get-max-shred-insert-slot.ts +0 -9
  55. package/server/methods/epoch/get-slot-leader.ts +0 -6
  56. package/server/methods/epoch/get-slot-leaders.ts +0 -9
  57. package/server/methods/epoch/get-stake-activation.ts +0 -9
  58. package/server/methods/epoch/get-stake-minimum-delegation.ts +0 -9
  59. package/server/methods/epoch/get-vote-accounts.ts +0 -19
  60. package/server/methods/epoch/index.ts +0 -13
  61. package/server/methods/epoch/minimum-ledger-slot.ts +0 -5
  62. package/server/methods/fee/get-fee-calculator-for-blockhash.ts +0 -12
  63. package/server/methods/fee/get-fee-for-message.ts +0 -8
  64. package/server/methods/fee/get-fee-rate-governor.ts +0 -16
  65. package/server/methods/fee/get-fees.ts +0 -14
  66. package/server/methods/fee/get-recent-prioritization-fees.ts +0 -22
  67. package/server/methods/fee/index.ts +0 -5
  68. package/server/methods/get-address-lookup-table.ts +0 -27
  69. package/server/methods/index.ts +0 -265
  70. package/server/methods/performance/get-recent-performance-samples.ts +0 -25
  71. package/server/methods/performance/get-transaction-count.ts +0 -5
  72. package/server/methods/performance/index.ts +0 -2
  73. package/server/methods/program/get-block-commitment.ts +0 -9
  74. package/server/methods/program/get-block-production.ts +0 -14
  75. package/server/methods/program/get-block-time.ts +0 -21
  76. package/server/methods/program/get-blocks.ts +0 -11
  77. package/server/methods/program/get-first-available-block.ts +0 -9
  78. package/server/methods/program/get-genesis-hash.ts +0 -6
  79. package/server/methods/program/get-identity.ts +0 -6
  80. package/server/methods/program/get-inflation-governor.ts +0 -15
  81. package/server/methods/program/get-inflation-rate.ts +0 -10
  82. package/server/methods/program/get-inflation-reward.ts +0 -12
  83. package/server/methods/program/get-largest-accounts.ts +0 -8
  84. package/server/methods/program/get-parsed-program-accounts.ts +0 -12
  85. package/server/methods/program/get-parsed-token-accounts-by-delegate.ts +0 -12
  86. package/server/methods/program/get-parsed-token-accounts-by-owner.ts +0 -12
  87. package/server/methods/program/get-program-accounts.ts +0 -221
  88. package/server/methods/program/get-supply.ts +0 -13
  89. package/server/methods/program/get-token-account-balance.ts +0 -60
  90. package/server/methods/program/get-token-accounts-by-delegate.ts +0 -82
  91. package/server/methods/program/get-token-accounts-by-owner.ts +0 -416
  92. package/server/methods/program/get-token-largest-accounts.ts +0 -81
  93. package/server/methods/program/get-token-supply.ts +0 -39
  94. package/server/methods/program/index.ts +0 -21
  95. package/server/methods/solforge/index.ts +0 -158
  96. package/server/methods/system/get-health.ts +0 -5
  97. package/server/methods/system/get-minimum-balance-for-rent-exemption.ts +0 -13
  98. package/server/methods/system/get-version.ts +0 -9
  99. package/server/methods/system/index.ts +0 -3
  100. package/server/methods/transaction/get-confirmed-transaction.ts +0 -11
  101. package/server/methods/transaction/get-parsed-transaction.ts +0 -17
  102. package/server/methods/transaction/get-signature-statuses.ts +0 -79
  103. package/server/methods/transaction/get-signatures-for-address.ts +0 -41
  104. package/server/methods/transaction/get-transaction.ts +0 -639
  105. package/server/methods/transaction/index.ts +0 -7
  106. package/server/methods/transaction/inner-instructions.test.ts +0 -104
  107. package/server/methods/transaction/send-transaction.ts +0 -469
  108. package/server/methods/transaction/simulate-transaction.ts +0 -57
  109. package/server/rpc-server.ts +0 -521
  110. package/server/types.ts +0 -109
  111. package/server/ws-server.ts +0 -178
  112. package/src/api-server-entry.ts +0 -109
  113. package/src/cli/bootstrap.ts +0 -67
  114. package/src/cli/commands/airdrop.ts +0 -37
  115. package/src/cli/commands/config.ts +0 -39
  116. package/src/cli/commands/mint.ts +0 -187
  117. package/src/cli/commands/program-clone.ts +0 -122
  118. package/src/cli/commands/program-load.ts +0 -64
  119. package/src/cli/commands/rpc-start.ts +0 -49
  120. package/src/cli/commands/token-adopt-authority.ts +0 -37
  121. package/src/cli/commands/token-clone.ts +0 -112
  122. package/src/cli/commands/token-create.ts +0 -81
  123. package/src/cli/main.ts +0 -158
  124. package/src/cli/run-solforge.ts +0 -112
  125. package/src/cli/setup-utils.ts +0 -54
  126. package/src/cli/setup-wizard.ts +0 -258
  127. package/src/cli/utils/args.ts +0 -15
  128. package/src/commands/add-program.ts +0 -333
  129. package/src/commands/init.ts +0 -122
  130. package/src/commands/list.ts +0 -136
  131. package/src/commands/mint.ts +0 -287
  132. package/src/commands/start.ts +0 -881
  133. package/src/commands/status.ts +0 -99
  134. package/src/commands/stop.ts +0 -405
  135. package/src/config/index.ts +0 -146
  136. package/src/config/manager.ts +0 -157
  137. package/src/db/index.ts +0 -83
  138. package/src/db/schema/accounts.ts +0 -23
  139. package/src/db/schema/address-signatures.ts +0 -31
  140. package/src/db/schema/index.ts +0 -6
  141. package/src/db/schema/meta-kv.ts +0 -9
  142. package/src/db/schema/transactions.ts +0 -36
  143. package/src/db/schema/tx-account-states.ts +0 -23
  144. package/src/db/schema/tx-accounts.ts +0 -33
  145. package/src/db/tx-store.ts +0 -264
  146. package/src/gui/public/app.css +0 -1556
  147. package/src/gui/public/build/main.css +0 -1569
  148. package/src/gui/public/build/main.js +0 -303
  149. package/src/gui/public/build/main.js.txt +0 -231
  150. package/src/gui/public/index.html +0 -19
  151. package/src/gui/server.ts +0 -296
  152. package/src/gui/src/api.ts +0 -127
  153. package/src/gui/src/app.tsx +0 -441
  154. package/src/gui/src/components/airdrop-mint-form.tsx +0 -246
  155. package/src/gui/src/components/clone-program-modal.tsx +0 -202
  156. package/src/gui/src/components/clone-token-modal.tsx +0 -230
  157. package/src/gui/src/components/modal.tsx +0 -134
  158. package/src/gui/src/components/programs-panel.tsx +0 -124
  159. package/src/gui/src/components/status-panel.tsx +0 -136
  160. package/src/gui/src/components/tokens-panel.tsx +0 -122
  161. package/src/gui/src/hooks/use-interval.ts +0 -17
  162. package/src/gui/src/index.css +0 -557
  163. package/src/gui/src/main.tsx +0 -17
  164. package/src/index.ts +0 -216
  165. package/src/migrations-bundled.ts +0 -23
  166. package/src/rpc/start.ts +0 -44
  167. package/src/services/api-server.ts +0 -504
  168. package/src/services/port-manager.ts +0 -174
  169. package/src/services/process-registry.ts +0 -153
  170. package/src/services/program-cloner.ts +0 -317
  171. package/src/services/token-cloner.ts +0 -811
  172. package/src/services/validator.ts +0 -293
  173. package/src/types/config.ts +0 -110
  174. package/src/utils/shell.ts +0 -110
  175. package/src/utils/token-loader.ts +0 -115
@@ -1,639 +0,0 @@
1
- import { VersionedTransaction } from "@solana/web3.js";
2
- import type { RpcMethodHandler } from "../../types";
3
- import { parseInstruction } from "../../lib/instruction-parser";
4
-
5
- export const getTransaction: RpcMethodHandler = async (id, params, context) => {
6
- const [signature, config] = params || [];
7
- const encoding = config?.encoding ?? "json";
8
- const DBG = process.env.DEBUG_TX_CAPTURE === "1";
9
- try {
10
- if (DBG)
11
- console.debug(
12
- `[tx-capture] getTransaction request: sig=${signature} enc=${encoding}`,
13
- );
14
- } catch {}
15
-
16
- try {
17
- const rec = context.getRecordedTransaction(signature);
18
- if (rec) {
19
- try {
20
- if (DBG) {
21
- const innerLen = (() => {
22
- try {
23
- const v = (rec as unknown as { innerInstructions?: unknown })
24
- .innerInstructions;
25
- return Array.isArray(v) ? v.length : 0;
26
- } catch {
27
- return 0;
28
- }
29
- })();
30
- console.debug(
31
- `[tx-capture] getTransaction hit memory: logs=${rec.logs?.length || 0} inner=${innerLen}`,
32
- );
33
- }
34
- } catch {}
35
- const tx = rec.tx;
36
- if (encoding === "base64") {
37
- const raw = Buffer.from(tx.serialize()).toString("base64");
38
- // Top-level version is required by some clients
39
- const isV0 = (() => {
40
- const m = tx.message as unknown as { version?: number };
41
- return typeof m?.version === "number" ? m.version === 0 : true;
42
- })();
43
- return context.createSuccessResponse(id, {
44
- slot: rec.slot,
45
- transaction: [raw, "base64"],
46
- version: isV0 ? 0 : "legacy",
47
- meta: {
48
- status: rec.err ? { Err: rec.err } : { Ok: null },
49
- err: rec.err ?? null,
50
- fee: rec.fee,
51
- loadedAddresses: { writable: [], readonly: [] },
52
- preBalances: Array.isArray(rec.preBalances) ? rec.preBalances : [],
53
- postBalances: Array.isArray(rec.postBalances)
54
- ? rec.postBalances
55
- : [],
56
- innerInstructions: Array.isArray(rec.innerInstructions)
57
- ? rec.innerInstructions
58
- : [],
59
- logMessages: rec.logs || [],
60
- preTokenBalances: (() => {
61
- const arr = (rec as unknown as { preTokenBalances?: unknown[] })
62
- .preTokenBalances;
63
- return Array.isArray(arr) ? arr : [];
64
- })(),
65
- postTokenBalances: (() => {
66
- const arr = (rec as unknown as { postTokenBalances?: unknown[] })
67
- .postTokenBalances;
68
- return Array.isArray(arr) ? arr : [];
69
- })(),
70
- computeUnitsConsumed:
71
- typeof rec.computeUnits === "number" ? rec.computeUnits : null,
72
- returnData: (() => {
73
- const rd = rec.returnData as
74
- | { programId: string; dataBase64: string }
75
- | null
76
- | undefined;
77
- if (!rd) return null;
78
- return {
79
- programId: rd.programId,
80
- data: [rd.dataBase64, "base64"],
81
- };
82
- })(),
83
- rewards: [],
84
- },
85
- blockTime: rec.blockTime,
86
- });
87
- }
88
-
89
- const msg = tx.message as unknown as {
90
- staticAccountKeys?: unknown[];
91
- accountKeys?: unknown[];
92
- compiledInstructions?: unknown[];
93
- instructions?: unknown[];
94
- header?: unknown;
95
- recentBlockhash?: string;
96
- version?: number;
97
- addressTableLookups?: unknown[];
98
- isAccountSigner?: (i: number) => boolean;
99
- isAccountWritable?: (i: number) => boolean;
100
- };
101
- const rawKeys1: unknown[] = Array.isArray(msg.staticAccountKeys)
102
- ? msg.staticAccountKeys
103
- : Array.isArray(msg.accountKeys)
104
- ? msg.accountKeys
105
- : [];
106
- const accountKeys = rawKeys1.map((k) => {
107
- try {
108
- return typeof k === "string"
109
- ? k
110
- : (k as { toBase58: () => string }).toBase58();
111
- } catch {
112
- return String(k);
113
- }
114
- });
115
- const compiled: unknown[] = Array.isArray(msg.compiledInstructions)
116
- ? msg.compiledInstructions
117
- : Array.isArray(msg.instructions)
118
- ? msg.instructions
119
- : [];
120
- const instructions = compiled.map((ci) => {
121
- const c = ci as {
122
- programIdIndex: number;
123
- accountKeyIndexes?: number[];
124
- accounts?: number[];
125
- data: Uint8Array | number[];
126
- };
127
- const dataBytes: Uint8Array =
128
- c.data instanceof Uint8Array ? c.data : Buffer.from(c.data);
129
- return {
130
- programIdIndex: c.programIdIndex,
131
- accounts: Array.from(c.accountKeyIndexes || c.accounts || []),
132
- data: context.encodeBase58(dataBytes),
133
- };
134
- });
135
- const addressTableLookups = (
136
- Array.isArray(msg.addressTableLookups) ? msg.addressTableLookups : []
137
- ).map((l) => {
138
- const a = l as {
139
- accountKey?: { toBase58?: () => string } | string;
140
- writableIndexes?: number[];
141
- readonlyIndexes?: number[];
142
- };
143
- return {
144
- accountKey:
145
- typeof (a.accountKey as { toBase58?: unknown })?.toBase58 ===
146
- "function"
147
- ? (a.accountKey as { toBase58: () => string }).toBase58()
148
- : String(a.accountKey),
149
- writableIndexes: Array.from(a.writableIndexes || []),
150
- readonlyIndexes: Array.from(a.readonlyIndexes || []),
151
- };
152
- });
153
- const header = msg.header || {
154
- numRequiredSignatures: tx.signatures.length,
155
- numReadonlySignedAccounts: 0,
156
- numReadonlyUnsignedAccounts: 0,
157
- };
158
- const recentBlockhash = msg.recentBlockhash || "";
159
-
160
- const isV0 = typeof msg.version === "number" ? msg.version === 0 : true;
161
- const result = {
162
- slot: rec.slot,
163
- transaction: {
164
- signatures: [signature],
165
- message: {
166
- accountKeys,
167
- header,
168
- recentBlockhash,
169
- instructions,
170
- addressTableLookups,
171
- },
172
- },
173
- version: isV0 ? 0 : "legacy",
174
- meta: {
175
- status: rec.err ? { Err: rec.err } : { Ok: null },
176
- err: rec.err ?? null,
177
- fee: rec.fee,
178
- loadedAddresses: { writable: [], readonly: [] },
179
- preBalances: Array.isArray(rec.preBalances) ? rec.preBalances : [],
180
- postBalances: Array.isArray(rec.postBalances) ? rec.postBalances : [],
181
- innerInstructions: Array.isArray(rec.innerInstructions)
182
- ? rec.innerInstructions
183
- : [],
184
- logMessages: rec.logs || [],
185
- preTokenBalances: (() => {
186
- const arr = (rec as unknown as { preTokenBalances?: unknown[] })
187
- .preTokenBalances;
188
- return Array.isArray(arr) ? arr : [];
189
- })(),
190
- postTokenBalances: (() => {
191
- const arr = (rec as unknown as { postTokenBalances?: unknown[] })
192
- .postTokenBalances;
193
- return Array.isArray(arr) ? arr : [];
194
- })(),
195
- computeUnitsConsumed:
196
- typeof rec.computeUnits === "number" ? rec.computeUnits : null,
197
- returnData: (() => {
198
- const rd = rec.returnData as
199
- | { programId: string; dataBase64: string }
200
- | null
201
- | undefined;
202
- if (!rd) return null;
203
- return { programId: rd.programId, data: [rd.dataBase64, "base64"] };
204
- })(),
205
- rewards: [],
206
- },
207
- blockTime: rec.blockTime,
208
- };
209
-
210
- if (encoding === "jsonParsed") {
211
- const accountKeysParsed = accountKeys.map((pk: string, i: number) => ({
212
- pubkey: pk,
213
- signer:
214
- typeof msg.isAccountSigner === "function"
215
- ? !!msg.isAccountSigner(i)
216
- : i < (header?.numRequiredSignatures ?? 0),
217
- writable:
218
- typeof msg.isAccountWritable === "function"
219
- ? !!msg.isAccountWritable(i)
220
- : i < (header?.numRequiredSignatures ?? 0),
221
- }));
222
- // Collect token balance hints: (mint, decimals) pairs to help identify mint when keys are missing
223
- const preTbs = ((result as unknown as { meta?: { preTokenBalances?: unknown[] } })?.meta?.preTokenBalances || []) as Array<{
224
- mint?: string;
225
- uiTokenAmount?: { decimals?: number };
226
- }>;
227
- const postTbs = ((result as unknown as { meta?: { postTokenBalances?: unknown[] } })?.meta?.postTokenBalances || []) as Array<{
228
- mint?: string;
229
- uiTokenAmount?: { decimals?: number };
230
- }>;
231
- const tokenBalanceHints: Array<{ mint: string; decimals: number }> = [];
232
- for (const tb of [...preTbs, ...postTbs]) {
233
- try {
234
- const mint = tb?.mint ? String(tb.mint) : "";
235
- const decimals = Number(tb?.uiTokenAmount?.decimals ?? 0);
236
- if (mint) tokenBalanceHints.push({ mint, decimals });
237
- } catch {}
238
- }
239
- const parsedInstructions = compiled.map((ci) => {
240
- const c = ci as {
241
- programIdIndex: number;
242
- accountKeyIndexes?: number[];
243
- accounts?: number[];
244
- data: Uint8Array | number[];
245
- };
246
- const dataBytes: Uint8Array =
247
- c.data instanceof Uint8Array ? c.data : Buffer.from(c.data);
248
- const accountsIdx = Array.from(
249
- c.accountKeyIndexes || c.accounts || [],
250
- );
251
- const programId = accountKeys[c.programIdIndex];
252
- return parseInstruction(
253
- programId,
254
- accountsIdx,
255
- context.encodeBase58(dataBytes),
256
- accountKeys,
257
- tokenBalanceHints,
258
- );
259
- });
260
- (result.transaction.message as { accountKeys: unknown[] }).accountKeys =
261
- accountKeysParsed;
262
- (
263
- result.transaction.message as { instructions: unknown[] }
264
- ).instructions = parsedInstructions as unknown[];
265
- // Parse inner instructions using the same parser
266
- try {
267
- const inner = (
268
- result.meta as unknown as {
269
- innerInstructions?: unknown;
270
- }
271
- )?.innerInstructions as
272
- | Array<{ index: number; instructions: unknown[] }>
273
- | undefined;
274
- if (Array.isArray(inner)) {
275
- const parsedInner = inner.map((group) => ({
276
- index: group.index,
277
- instructions: (group.instructions || []).map((ii) => {
278
- const accountsIdx = Array.isArray(ii.accounts)
279
- ? ii.accounts
280
- : [];
281
- const dataB58 =
282
- typeof ii.data === "string" ? ii.data : String(ii.data ?? "");
283
- const pid =
284
- accountKeys[ii.programIdIndex ?? 0] || accountKeys[0];
285
- return parseInstruction(
286
- pid,
287
- accountsIdx,
288
- dataB58,
289
- accountKeys,
290
- tokenBalanceHints,
291
- );
292
- }),
293
- }));
294
- (
295
- result as unknown as {
296
- meta: { innerInstructions?: unknown };
297
- }
298
- ).meta.innerInstructions = parsedInner as unknown[];
299
- }
300
- } catch {}
301
- }
302
-
303
- return context.createSuccessResponse(id, result);
304
- }
305
-
306
- // Fallback: persistent store
307
- try {
308
- const row = await context.store?.getTransaction(signature);
309
- if (row) {
310
- try {
311
- if (DBG)
312
- console.debug(
313
- `[tx-capture] getTransaction hit sqlite: slot=${row.slot} logs=${JSON.parse(row.logsJson || "[]").length} inner=${JSON.parse(row.innerInstructionsJson || "[]").length}`,
314
- );
315
- } catch {}
316
- const errVal = row.errJson ? JSON.parse(row.errJson) : null;
317
- const preBalances = JSON.parse(row.preBalancesJson || "[]");
318
- const postBalances = JSON.parse(row.postBalancesJson || "[]");
319
- const logs = JSON.parse(row.logsJson || "[]");
320
- const inner = JSON.parse(row.innerInstructionsJson || "[]");
321
- const versionVal =
322
- row.version === "0" || row.version === 0 ? 0 : row.version;
323
- if (encoding === "base64") {
324
- return context.createSuccessResponse(id, {
325
- slot: Number(row.slot),
326
- transaction: [row.rawBase64, "base64"],
327
- version: versionVal,
328
- meta: {
329
- status: errVal ? { Err: errVal } : { Ok: null },
330
- err: errVal,
331
- fee: Number(row.fee),
332
- loadedAddresses: { writable: [], readonly: [] },
333
- preBalances,
334
- postBalances,
335
- innerInstructions: Array.isArray(inner) ? inner : [],
336
- logMessages: logs,
337
- preTokenBalances: JSON.parse(row.preTokenBalancesJson || "[]"),
338
- postTokenBalances: JSON.parse(row.postTokenBalancesJson || "[]"),
339
- computeUnitsConsumed:
340
- row.computeUnits != null ? Number(row.computeUnits) : null,
341
- returnData: (() => {
342
- if (row.returnDataProgramId && row.returnDataBase64)
343
- return {
344
- programId: row.returnDataProgramId,
345
- data: [row.returnDataBase64, "base64"],
346
- };
347
- return null;
348
- })(),
349
- rewards: [],
350
- },
351
- blockTime: row.blockTime ? Number(row.blockTime) : null,
352
- });
353
- } else if (encoding === "jsonParsed") {
354
- // Build jsonParsed similar to in-memory path
355
- const raw = Buffer.from(row.rawBase64, "base64");
356
- const tx = VersionedTransaction.deserialize(raw);
357
- const msg = tx.message as unknown as {
358
- staticAccountKeys?: unknown[];
359
- accountKeys?: unknown[];
360
- compiledInstructions?: unknown[];
361
- instructions?: unknown[];
362
- header?: unknown;
363
- recentBlockhash?: string;
364
- addressTableLookups?: unknown[];
365
- isAccountSigner?: (i: number) => boolean;
366
- isAccountWritable?: (i: number) => boolean;
367
- };
368
- const rawKeys2: unknown[] = Array.isArray(msg.staticAccountKeys)
369
- ? msg.staticAccountKeys
370
- : Array.isArray(msg.accountKeys)
371
- ? msg.accountKeys
372
- : [];
373
- const accountKeys = rawKeys2.map((k) => {
374
- try {
375
- return typeof k === "string"
376
- ? k
377
- : (k as { toBase58: () => string }).toBase58();
378
- } catch {
379
- return String(k);
380
- }
381
- });
382
- const header = msg.header || {
383
- numRequiredSignatures: tx.signatures.length,
384
- numReadonlySignedAccounts: 0,
385
- numReadonlyUnsignedAccounts: 0,
386
- };
387
- const compiled: unknown[] = Array.isArray(msg.compiledInstructions)
388
- ? msg.compiledInstructions
389
- : Array.isArray(msg.instructions)
390
- ? msg.instructions
391
- : [];
392
- const parsedInstructions = compiled.map((ci) => {
393
- const c = ci as {
394
- programIdIndex: number;
395
- accountKeyIndexes?: number[];
396
- accounts?: number[];
397
- data: Uint8Array | number[];
398
- };
399
- const dataBytes: Uint8Array =
400
- c.data instanceof Uint8Array ? c.data : Buffer.from(c.data);
401
- const accountsIdx = Array.from(
402
- c.accountKeyIndexes || c.accounts || [],
403
- );
404
- const programId = accountKeys[c.programIdIndex];
405
- return parseInstruction(
406
- programId,
407
- accountsIdx,
408
- context.encodeBase58(dataBytes),
409
- accountKeys,
410
- );
411
- });
412
- const accountKeysParsed = accountKeys.map(
413
- (pk: string, i: number) => ({
414
- pubkey: pk,
415
- signer:
416
- typeof msg.isAccountSigner === "function"
417
- ? !!msg.isAccountSigner(i)
418
- : i < (header?.numRequiredSignatures ?? 0),
419
- writable:
420
- typeof msg.isAccountWritable === "function"
421
- ? !!msg.isAccountWritable(i)
422
- : i < (header?.numRequiredSignatures ?? 0),
423
- }),
424
- );
425
- const result = {
426
- slot: Number(row.slot),
427
- transaction: {
428
- signatures: [signature],
429
- message: {
430
- accountKeys: accountKeysParsed,
431
- header,
432
- recentBlockhash: msg.recentBlockhash || "",
433
- instructions: parsedInstructions,
434
- addressTableLookups: msg.addressTableLookups || [],
435
- },
436
- },
437
- version: row.version === "0" || row.version === 0 ? 0 : row.version,
438
- meta: {
439
- status: errVal ? { Err: errVal } : { Ok: null },
440
- err: errVal,
441
- fee: Number(row.fee),
442
- loadedAddresses: { writable: [], readonly: [] },
443
- preBalances,
444
- postBalances,
445
- innerInstructions: Array.isArray(inner) ? inner : [],
446
- logMessages: logs,
447
- preTokenBalances: JSON.parse(row.preTokenBalancesJson || "[]"),
448
- postTokenBalances: JSON.parse(row.postTokenBalancesJson || "[]"),
449
- computeUnitsConsumed:
450
- row.computeUnits != null ? Number(row.computeUnits) : null,
451
- returnData: (() => {
452
- if (row.returnDataProgramId && row.returnDataBase64)
453
- return {
454
- programId: row.returnDataProgramId,
455
- data: [row.returnDataBase64, "base64"],
456
- };
457
- return null;
458
- })(),
459
- rewards: [],
460
- },
461
- blockTime: row.blockTime ? Number(row.blockTime) : null,
462
- };
463
- // Also parse inner instructions from DB row
464
- try {
465
- const innerSrc = JSON.parse(row.innerInstructionsJson || "[]");
466
- const groups: unknown[] = Array.isArray(innerSrc) ? innerSrc : [];
467
- const innerParsed = groups.map((group) => {
468
- const g = group as Record<string, unknown>;
469
- const instrSrc = Array.isArray(g.instructions)
470
- ? (g.instructions as unknown[])
471
- : [];
472
- const instructions = instrSrc.map((ii) => {
473
- const r = ii as Record<string, unknown>;
474
- const pidIdx =
475
- typeof r.programIdIndex === "number" ? r.programIdIndex : 0;
476
- const accountsIdx = Array.isArray(r.accounts)
477
- ? (r.accounts as unknown[]).filter(
478
- (v): v is number => typeof v === "number",
479
- )
480
- : [];
481
- const dataB58 =
482
- typeof r.data === "string" ? r.data : String(r.data ?? "");
483
- return parseInstruction(
484
- accountKeys[pidIdx] || accountKeys[0],
485
- accountsIdx,
486
- dataB58,
487
- accountKeys,
488
- );
489
- });
490
- return {
491
- index: Number(g.index || 0),
492
- instructions,
493
- };
494
- });
495
- (
496
- result as unknown as { meta: { innerInstructions?: unknown } }
497
- ).meta.innerInstructions = innerParsed as unknown[];
498
- } catch {}
499
-
500
- return context.createSuccessResponse(id, result);
501
- } else {
502
- const raw = Buffer.from(row.rawBase64, "base64");
503
- const tx = VersionedTransaction.deserialize(raw);
504
- const msg = tx.message as unknown as {
505
- staticAccountKeys?: unknown[];
506
- accountKeys?: unknown[];
507
- compiledInstructions?: unknown[];
508
- instructions?: unknown[];
509
- header?: unknown;
510
- recentBlockhash?: string;
511
- addressTableLookups?: unknown[];
512
- };
513
- const rawKeys3: unknown[] = Array.isArray(msg.staticAccountKeys)
514
- ? msg.staticAccountKeys
515
- : Array.isArray(msg.accountKeys)
516
- ? msg.accountKeys
517
- : [];
518
- const accountKeys = rawKeys3.map((k) => {
519
- try {
520
- return typeof k === "string"
521
- ? k
522
- : (k as { toBase58: () => string }).toBase58();
523
- } catch {
524
- return String(k);
525
- }
526
- });
527
- const header = msg.header || {
528
- numRequiredSignatures: tx.signatures.length,
529
- numReadonlySignedAccounts: 0,
530
- numReadonlyUnsignedAccounts: 0,
531
- };
532
- const compiled: unknown[] = Array.isArray(msg.compiledInstructions)
533
- ? msg.compiledInstructions
534
- : Array.isArray(msg.instructions)
535
- ? msg.instructions
536
- : [];
537
- const instructions = compiled.map((ci) => {
538
- const c = ci as {
539
- programIdIndex: number;
540
- accountKeyIndexes?: number[];
541
- accounts?: number[];
542
- data: Uint8Array | number[];
543
- };
544
- return {
545
- programIdIndex: c.programIdIndex,
546
- accounts: Array.from(c.accountKeyIndexes || c.accounts || []),
547
- data: context.encodeBase58(
548
- c.data instanceof Uint8Array ? c.data : Buffer.from(c.data),
549
- ),
550
- };
551
- });
552
- const result = {
553
- slot: Number(row.slot),
554
- transaction: {
555
- signatures: [signature],
556
- message: {
557
- accountKeys,
558
- header,
559
- recentBlockhash: msg.recentBlockhash || "",
560
- instructions,
561
- addressTableLookups: msg.addressTableLookups || [],
562
- },
563
- },
564
- version: versionVal,
565
- meta: {
566
- status: errVal ? { Err: errVal } : { Ok: null },
567
- err: errVal,
568
- fee: Number(row.fee),
569
- loadedAddresses: { writable: [], readonly: [] },
570
- preBalances,
571
- postBalances,
572
- innerInstructions: Array.isArray(inner) ? inner : [],
573
- logMessages: logs,
574
- preTokenBalances: JSON.parse(row.preTokenBalancesJson || "[]"),
575
- postTokenBalances: JSON.parse(row.postTokenBalancesJson || "[]"),
576
- computeUnitsConsumed:
577
- row.computeUnits != null ? Number(row.computeUnits) : null,
578
- returnData: (() => {
579
- if (row.returnDataProgramId && row.returnDataBase64)
580
- return {
581
- programId: row.returnDataProgramId,
582
- data: [row.returnDataBase64, "base64"],
583
- };
584
- return null;
585
- })(),
586
- rewards: [],
587
- },
588
- blockTime: row.blockTime ? Number(row.blockTime) : null,
589
- };
590
- return context.createSuccessResponse(id, result);
591
- }
592
- }
593
- } catch {}
594
-
595
- // Fallback to LiteSVM history when no local record exists
596
- const sigBytes = context.decodeBase58(signature);
597
- const getTx = (
598
- context.svm as unknown as {
599
- getTransaction?: (
600
- sig: Uint8Array,
601
- ) =>
602
- | { logs: () => string[]; err: () => unknown }
603
- | { meta: () => { logs: () => string[] }; err: () => unknown };
604
- }
605
- ).getTransaction;
606
- const txh = typeof getTx === "function" ? getTx(sigBytes) : undefined;
607
- if (!txh) return context.createSuccessResponse(id, null);
608
-
609
- const isError = "err" in txh;
610
- const logs = isError ? txh.meta().logs() : txh.logs();
611
- const errVal = isError ? txh.err() : null;
612
- const status = isError ? { Err: errVal } : { Ok: null };
613
- const isV0 = true;
614
- return context.createSuccessResponse(id, {
615
- slot: Number(context.slot),
616
- transaction: {
617
- signatures: [signature],
618
- },
619
- version: isV0 ? 0 : "legacy",
620
- meta: {
621
- status,
622
- err: errVal,
623
- fee: 5000,
624
- loadedAddresses: { writable: [], readonly: [] },
625
- preBalances: [],
626
- postBalances: [],
627
- innerInstructions: [],
628
- logMessages: logs,
629
- preTokenBalances: [],
630
- postTokenBalances: [],
631
- rewards: [],
632
- },
633
- blockTime: Math.floor(Date.now() / 1000),
634
- });
635
- } catch (error: unknown) {
636
- const message = error instanceof Error ? error.message : String(error);
637
- return context.createErrorResponse(id, -32602, "Invalid params", message);
638
- }
639
- };
@@ -1,7 +0,0 @@
1
- export { getConfirmedTransaction } from "./get-confirmed-transaction";
2
- export { getParsedTransaction } from "./get-parsed-transaction";
3
- export { getSignatureStatuses } from "./get-signature-statuses";
4
- export { getSignaturesForAddress } from "./get-signatures-for-address";
5
- export { getTransaction } from "./get-transaction";
6
- export { sendTransaction } from "./send-transaction";
7
- export { simulateTransaction } from "./simulate-transaction";