solforge 0.2.6 → 0.2.7

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.
@@ -1,51 +1,76 @@
1
1
  import { VersionedTransaction } from "@solana/web3.js";
2
2
  import type { RpcMethodHandler } from "../../types";
3
+ import { parseInstruction } from "../../lib/instruction-parser";
3
4
 
4
5
  export const getTransaction: RpcMethodHandler = async (id, params, context) => {
5
- const [signature, config] = params || [];
6
- const encoding = config?.encoding ?? "json";
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) console.debug(`[tx-capture] getTransaction request: sig=${signature} enc=${encoding}`);
11
+ } catch {}
7
12
 
8
13
  try {
9
14
  const rec = context.getRecordedTransaction(signature);
10
- if (rec) {
11
- const tx = rec.tx;
12
- if (encoding === "base64") {
13
- const raw = Buffer.from(tx.serialize()).toString("base64");
14
- // Top-level version is required by some clients
15
- const isV0 = (() => {
16
- const m = tx.message as unknown as { version?: number };
17
- return typeof m?.version === "number" ? m.version === 0 : true;
18
- })();
19
- return context.createSuccessResponse(id, {
20
- slot: rec.slot,
21
- transaction: [raw, "base64"],
22
- version: isV0 ? 0 : "legacy",
23
- meta: {
24
- status: rec.err ? { Err: rec.err } : { Ok: null },
25
- err: rec.err ?? null,
26
- fee: rec.fee,
27
- loadedAddresses: { writable: [], readonly: [] },
28
- preBalances: Array.isArray(rec.preBalances) ? rec.preBalances : [],
29
- postBalances: Array.isArray(rec.postBalances)
30
- ? rec.postBalances
31
- : [],
32
- innerInstructions: [],
33
- logMessages: rec.logs || [],
34
- preTokenBalances: (() => {
35
- const arr = (rec as unknown as { preTokenBalances?: unknown[] })
36
- .preTokenBalances;
37
- return Array.isArray(arr) ? arr : [];
38
- })(),
39
- postTokenBalances: (() => {
40
- const arr = (rec as unknown as { postTokenBalances?: unknown[] })
41
- .postTokenBalances;
42
- return Array.isArray(arr) ? arr : [];
43
- })(),
44
- rewards: [],
45
- },
46
- blockTime: rec.blockTime,
47
- });
48
- }
15
+ if (rec) {
16
+ try {
17
+ if (DBG)
18
+ console.debug(
19
+ `[tx-capture] getTransaction hit memory: logs=${rec.logs?.length || 0} inner=${Array.isArray((rec as any).innerInstructions) ? (rec as any).innerInstructions.length : 0}`,
20
+ );
21
+ } catch {}
22
+ const tx = rec.tx;
23
+ if (encoding === "base64") {
24
+ const raw = Buffer.from(tx.serialize()).toString("base64");
25
+ // Top-level version is required by some clients
26
+ const isV0 = (() => {
27
+ const m = tx.message as unknown as { version?: number };
28
+ return typeof m?.version === "number" ? m.version === 0 : true;
29
+ })();
30
+ return context.createSuccessResponse(id, {
31
+ slot: rec.slot,
32
+ transaction: [raw, "base64"],
33
+ version: isV0 ? 0 : "legacy",
34
+ meta: {
35
+ status: rec.err ? { Err: rec.err } : { Ok: null },
36
+ err: rec.err ?? null,
37
+ fee: rec.fee,
38
+ loadedAddresses: { writable: [], readonly: [] },
39
+ preBalances: Array.isArray(rec.preBalances) ? rec.preBalances : [],
40
+ postBalances: Array.isArray(rec.postBalances)
41
+ ? rec.postBalances
42
+ : [],
43
+ innerInstructions: Array.isArray((rec as any).innerInstructions)
44
+ ? (rec as any).innerInstructions
45
+ : [],
46
+ logMessages: rec.logs || [],
47
+ preTokenBalances: (() => {
48
+ const arr = (rec as unknown as { preTokenBalances?: unknown[] })
49
+ .preTokenBalances;
50
+ return Array.isArray(arr) ? arr : [];
51
+ })(),
52
+ postTokenBalances: (() => {
53
+ const arr = (rec as unknown as { postTokenBalances?: unknown[] })
54
+ .postTokenBalances;
55
+ return Array.isArray(arr) ? arr : [];
56
+ })(),
57
+ computeUnitsConsumed:
58
+ typeof (rec as any).computeUnits === "number"
59
+ ? (rec as any).computeUnits
60
+ : null,
61
+ returnData: (() => {
62
+ const rd = (rec as any).returnData as
63
+ | { programId: string; dataBase64: string }
64
+ | null
65
+ | undefined;
66
+ if (!rd) return null;
67
+ return { programId: rd.programId, data: [rd.dataBase64, "base64"] };
68
+ })(),
69
+ rewards: [],
70
+ },
71
+ blockTime: rec.blockTime,
72
+ });
73
+ }
49
74
 
50
75
  const msg = tx.message as unknown as {
51
76
  staticAccountKeys?: unknown[];
@@ -132,94 +157,102 @@ export const getTransaction: RpcMethodHandler = async (id, params, context) => {
132
157
  },
133
158
  },
134
159
  version: isV0 ? 0 : "legacy",
135
- meta: {
136
- status: rec.err ? { Err: rec.err } : { Ok: null },
137
- err: rec.err ?? null,
138
- fee: rec.fee,
139
- loadedAddresses: { writable: [], readonly: [] },
140
- preBalances: Array.isArray(rec.preBalances) ? rec.preBalances : [],
141
- postBalances: Array.isArray(rec.postBalances) ? rec.postBalances : [],
142
- innerInstructions: [],
143
- logMessages: rec.logs || [],
144
- preTokenBalances: (() => {
145
- const arr = (rec as unknown as { preTokenBalances?: unknown[] })
146
- .preTokenBalances;
147
- return Array.isArray(arr) ? arr : [];
148
- })(),
149
- postTokenBalances: (() => {
150
- const arr = (rec as unknown as { postTokenBalances?: unknown[] })
151
- .postTokenBalances;
152
- return Array.isArray(arr) ? arr : [];
153
- })(),
154
- rewards: [],
155
- },
156
- blockTime: rec.blockTime,
157
- };
160
+ meta: {
161
+ status: rec.err ? { Err: rec.err } : { Ok: null },
162
+ err: rec.err ?? null,
163
+ fee: rec.fee,
164
+ loadedAddresses: { writable: [], readonly: [] },
165
+ preBalances: Array.isArray(rec.preBalances) ? rec.preBalances : [],
166
+ postBalances: Array.isArray(rec.postBalances) ? rec.postBalances : [],
167
+ innerInstructions: Array.isArray((rec as any).innerInstructions)
168
+ ? (rec as any).innerInstructions
169
+ : [],
170
+ logMessages: rec.logs || [],
171
+ preTokenBalances: (() => {
172
+ const arr = (rec as unknown as { preTokenBalances?: unknown[] })
173
+ .preTokenBalances;
174
+ return Array.isArray(arr) ? arr : [];
175
+ })(),
176
+ postTokenBalances: (() => {
177
+ const arr = (rec as unknown as { postTokenBalances?: unknown[] })
178
+ .postTokenBalances;
179
+ return Array.isArray(arr) ? arr : [];
180
+ })(),
181
+ computeUnitsConsumed:
182
+ typeof (rec as any).computeUnits === "number"
183
+ ? (rec as any).computeUnits
184
+ : null,
185
+ returnData: (() => {
186
+ const rd = (rec as any).returnData as
187
+ | { programId: string; dataBase64: string }
188
+ | null
189
+ | undefined;
190
+ if (!rd) return null;
191
+ return { programId: rd.programId, data: [rd.dataBase64, "base64"] };
192
+ })(),
193
+ rewards: [],
194
+ },
195
+ blockTime: rec.blockTime,
196
+ };
158
197
 
159
- if (encoding === "jsonParsed") {
160
- const SYSTEM_PROGRAM_ID = "11111111111111111111111111111111";
161
- const accountKeysParsed = accountKeys.map((pk: string, i: number) => ({
162
- pubkey: pk,
163
- signer:
164
- typeof msg.isAccountSigner === "function"
165
- ? !!msg.isAccountSigner(i)
166
- : i < (header?.numRequiredSignatures ?? 0),
167
- writable:
168
- typeof msg.isAccountWritable === "function"
169
- ? !!msg.isAccountWritable(i)
170
- : i < (header?.numRequiredSignatures ?? 0),
171
- }));
172
- const parsedInstructions = compiled.map((ci) => {
173
- const c = ci as {
174
- programIdIndex: number;
175
- accountKeyIndexes?: number[];
176
- accounts?: number[];
177
- data: Uint8Array | number[];
178
- };
179
- const programId = accountKeys[c.programIdIndex];
180
- let parsed: unknown;
181
- try {
182
- const data: Uint8Array =
183
- c.data instanceof Uint8Array ? c.data : Buffer.from(c.data);
184
- if (programId === SYSTEM_PROGRAM_ID && data.length >= 12) {
185
- const dv = new DataView(
186
- data.buffer,
187
- data.byteOffset,
188
- data.byteLength,
189
- );
190
- const discriminator = dv.getUint32(0, true);
191
- if (
192
- discriminator === 2 &&
193
- (ci.accountKeyIndexes?.length ?? 0) >= 2
194
- ) {
195
- const lamports = Number(dv.getBigUint64(4, true));
196
- const source = accountKeys[c.accountKeyIndexes?.[0] as number];
197
- const destination =
198
- accountKeys[c.accountKeyIndexes?.[1] as number];
199
- parsed = {
200
- type: "transfer",
201
- info: { source, destination, lamports },
202
- };
203
- }
204
- }
205
- } catch {}
206
- if (parsed) return { program: "system", programId, parsed };
207
- return {
208
- programId,
209
- accounts: (c.accountKeyIndexes || []).map(
210
- (ix: number) => accountKeys[ix],
211
- ),
212
- data: context.encodeBase58(
213
- c.data instanceof Uint8Array ? c.data : Buffer.from(c.data),
214
- ),
215
- };
216
- });
217
- (result.transaction.message as { accountKeys: unknown[] }).accountKeys =
218
- accountKeysParsed;
219
- (
220
- result.transaction.message as { instructions: unknown[] }
221
- ).instructions = parsedInstructions as unknown[];
222
- }
198
+ if (encoding === "jsonParsed") {
199
+ const accountKeysParsed = accountKeys.map((pk: string, i: number) => ({
200
+ pubkey: pk,
201
+ signer:
202
+ typeof msg.isAccountSigner === "function"
203
+ ? !!msg.isAccountSigner(i)
204
+ : i < (header?.numRequiredSignatures ?? 0),
205
+ writable:
206
+ typeof msg.isAccountWritable === "function"
207
+ ? !!msg.isAccountWritable(i)
208
+ : i < (header?.numRequiredSignatures ?? 0),
209
+ }));
210
+ const parsedInstructions = compiled.map((ci) => {
211
+ const c = ci as {
212
+ programIdIndex: number;
213
+ accountKeyIndexes?: number[];
214
+ accounts?: number[];
215
+ data: Uint8Array | number[];
216
+ };
217
+ const dataBytes: Uint8Array =
218
+ c.data instanceof Uint8Array ? c.data : Buffer.from(c.data);
219
+ const accountsIdx = Array.from(
220
+ c.accountKeyIndexes || c.accounts || [],
221
+ );
222
+ const programId = accountKeys[c.programIdIndex];
223
+ return parseInstruction(
224
+ programId,
225
+ accountsIdx,
226
+ context.encodeBase58(dataBytes),
227
+ accountKeys,
228
+ );
229
+ });
230
+ (result.transaction.message as { accountKeys: unknown[] }).accountKeys =
231
+ accountKeysParsed;
232
+ (
233
+ result.transaction.message as { instructions: unknown[] }
234
+ ).instructions = parsedInstructions as unknown[];
235
+ // Parse inner instructions using the same parser
236
+ try {
237
+ const inner = (result.meta as any)?.innerInstructions as
238
+ | Array<{ index: number; instructions: any[] }>
239
+ | undefined;
240
+ if (Array.isArray(inner)) {
241
+ const parsedInner = inner.map((group) => ({
242
+ index: group.index,
243
+ instructions: (group.instructions || []).map((ii) => {
244
+ const accountsIdx = Array.isArray(ii.accounts)
245
+ ? ii.accounts
246
+ : [];
247
+ const dataB58 = typeof ii.data === "string" ? ii.data : String(ii.data ?? "");
248
+ const pid = accountKeys[ii.programIdIndex ?? 0] || accountKeys[0];
249
+ return parseInstruction(pid, accountsIdx, dataB58, accountKeys);
250
+ }),
251
+ }));
252
+ (result.meta as any).innerInstructions = parsedInner;
253
+ }
254
+ } catch {}
255
+ }
223
256
 
224
257
  return context.createSuccessResponse(id, result);
225
258
  }
@@ -227,37 +260,54 @@ export const getTransaction: RpcMethodHandler = async (id, params, context) => {
227
260
  // Fallback: persistent store
228
261
  try {
229
262
  const row = await context.store?.getTransaction(signature);
230
- if (row) {
231
- const errVal = row.errJson ? JSON.parse(row.errJson) : null;
232
- const preBalances = JSON.parse(row.preBalancesJson || "[]");
233
- const postBalances = JSON.parse(row.postBalancesJson || "[]");
234
- const logs = JSON.parse(row.logsJson || "[]");
235
- const versionVal =
236
- row.version === "0" || row.version === 0 ? 0 : row.version;
237
- if (encoding === "base64") {
238
- return context.createSuccessResponse(id, {
239
- slot: Number(row.slot),
240
- transaction: [row.rawBase64, "base64"],
241
- version: versionVal,
242
- meta: {
243
- status: errVal ? { Err: errVal } : { Ok: null },
244
- err: errVal,
245
- fee: Number(row.fee),
246
- loadedAddresses: { writable: [], readonly: [] },
247
- preBalances,
248
- postBalances,
249
- innerInstructions: [],
250
- logMessages: logs,
251
- preTokenBalances: JSON.parse(row.preTokenBalancesJson || "[]"),
252
- postTokenBalances: JSON.parse(row.postTokenBalancesJson || "[]"),
253
- rewards: [],
254
- },
255
- blockTime: row.blockTime ? Number(row.blockTime) : null,
256
- });
257
- } else if (encoding === "jsonParsed") {
258
- // Build jsonParsed similar to in-memory path
259
- const raw = Buffer.from(row.rawBase64, "base64");
260
- const tx = VersionedTransaction.deserialize(raw);
263
+ if (row) {
264
+ try {
265
+ if (DBG)
266
+ console.debug(
267
+ `[tx-capture] getTransaction hit sqlite: slot=${row.slot} logs=${JSON.parse(row.logsJson || '[]').length} inner=${JSON.parse(row.innerInstructionsJson || '[]').length}`,
268
+ );
269
+ } catch {}
270
+ const errVal = row.errJson ? JSON.parse(row.errJson) : null;
271
+ const preBalances = JSON.parse(row.preBalancesJson || "[]");
272
+ const postBalances = JSON.parse(row.postBalancesJson || "[]");
273
+ const logs = JSON.parse(row.logsJson || "[]");
274
+ const inner = JSON.parse(row.innerInstructionsJson || "[]");
275
+ const versionVal =
276
+ row.version === "0" || row.version === 0 ? 0 : row.version;
277
+ if (encoding === "base64") {
278
+ return context.createSuccessResponse(id, {
279
+ slot: Number(row.slot),
280
+ transaction: [row.rawBase64, "base64"],
281
+ version: versionVal,
282
+ meta: {
283
+ status: errVal ? { Err: errVal } : { Ok: null },
284
+ err: errVal,
285
+ fee: Number(row.fee),
286
+ loadedAddresses: { writable: [], readonly: [] },
287
+ preBalances,
288
+ postBalances,
289
+ innerInstructions: Array.isArray(inner) ? inner : [],
290
+ logMessages: logs,
291
+ preTokenBalances: JSON.parse(row.preTokenBalancesJson || "[]"),
292
+ postTokenBalances: JSON.parse(row.postTokenBalancesJson || "[]"),
293
+ computeUnitsConsumed:
294
+ row.computeUnits != null ? Number(row.computeUnits) : null,
295
+ returnData: (() => {
296
+ if (row.returnDataProgramId && row.returnDataBase64)
297
+ return {
298
+ programId: row.returnDataProgramId,
299
+ data: [row.returnDataBase64, "base64"],
300
+ };
301
+ return null;
302
+ })(),
303
+ rewards: [],
304
+ },
305
+ blockTime: row.blockTime ? Number(row.blockTime) : null,
306
+ });
307
+ } else if (encoding === "jsonParsed") {
308
+ // Build jsonParsed similar to in-memory path
309
+ const raw = Buffer.from(row.rawBase64, "base64");
310
+ const tx = VersionedTransaction.deserialize(raw);
261
311
  const msg = tx.message as unknown as {
262
312
  staticAccountKeys?: unknown[];
263
313
  accountKeys?: unknown[];
@@ -293,54 +343,26 @@ export const getTransaction: RpcMethodHandler = async (id, params, context) => {
293
343
  : Array.isArray(msg.instructions)
294
344
  ? msg.instructions
295
345
  : [];
296
- const parsedInstructions = compiled.map((ci) => {
297
- const c = ci as {
298
- programIdIndex: number;
299
- accountKeyIndexes?: number[];
300
- accounts?: number[];
301
- data: Uint8Array | number[];
302
- };
303
- const programId = accountKeys[c.programIdIndex];
304
- let parsed: unknown;
305
- try {
306
- const data: Uint8Array =
307
- c.data instanceof Uint8Array ? c.data : Buffer.from(c.data);
308
- // Minimal system transfer parser
309
- if (
310
- programId === "11111111111111111111111111111111" &&
311
- data.length >= 12
312
- ) {
313
- const dv = new DataView(
314
- data.buffer,
315
- data.byteOffset,
316
- data.byteLength,
317
- );
318
- const discriminator = dv.getUint32(0, true);
319
- if (
320
- discriminator === 2 &&
321
- (ci.accountKeyIndexes?.length ?? 0) >= 2
322
- ) {
323
- const lamports = Number(dv.getBigUint64(4, true));
324
- const source = accountKeys[c.accountKeyIndexes?.[0]];
325
- const destination = accountKeys[c.accountKeyIndexes?.[1]];
326
- parsed = {
327
- type: "transfer",
328
- info: { source, destination, lamports },
329
- };
330
- }
331
- }
332
- } catch {}
333
- if (parsed) return { program: "system", programId, parsed };
334
- return {
335
- programId,
336
- accounts: (c.accountKeyIndexes || []).map(
337
- (ix: number) => accountKeys[ix],
338
- ),
339
- data: context.encodeBase58(
340
- c.data instanceof Uint8Array ? c.data : Buffer.from(c.data),
341
- ),
342
- };
343
- });
346
+ const parsedInstructions = compiled.map((ci) => {
347
+ const c = ci as {
348
+ programIdIndex: number;
349
+ accountKeyIndexes?: number[];
350
+ accounts?: number[];
351
+ data: Uint8Array | number[];
352
+ };
353
+ const dataBytes: Uint8Array =
354
+ c.data instanceof Uint8Array ? c.data : Buffer.from(c.data);
355
+ const accountsIdx = Array.from(
356
+ c.accountKeyIndexes || c.accounts || [],
357
+ );
358
+ const programId = accountKeys[c.programIdIndex];
359
+ return parseInstruction(
360
+ programId,
361
+ accountsIdx,
362
+ context.encodeBase58(dataBytes),
363
+ accountKeys,
364
+ );
365
+ });
344
366
  const accountKeysParsed = accountKeys.map(
345
367
  (pk: string, i: number) => ({
346
368
  pubkey: pk,
@@ -354,36 +376,65 @@ export const getTransaction: RpcMethodHandler = async (id, params, context) => {
354
376
  : i < (header?.numRequiredSignatures ?? 0),
355
377
  }),
356
378
  );
357
- const result = {
358
- slot: Number(row.slot),
359
- transaction: {
360
- signatures: [signature],
361
- message: {
362
- accountKeys: accountKeysParsed,
363
- header,
364
- recentBlockhash: msg.recentBlockhash || "",
365
- instructions: parsedInstructions,
366
- addressTableLookups: msg.addressTableLookups || [],
367
- },
368
- },
369
- version: row.version === "0" || row.version === 0 ? 0 : row.version,
370
- meta: {
371
- status: errVal ? { Err: errVal } : { Ok: null },
372
- err: errVal,
373
- fee: Number(row.fee),
374
- loadedAddresses: { writable: [], readonly: [] },
375
- preBalances,
376
- postBalances,
377
- innerInstructions: [],
378
- logMessages: logs,
379
- preTokenBalances: JSON.parse(row.preTokenBalancesJson || "[]"),
380
- postTokenBalances: JSON.parse(row.postTokenBalancesJson || "[]"),
381
- rewards: [],
382
- },
383
- blockTime: row.blockTime ? Number(row.blockTime) : null,
384
- };
385
- return context.createSuccessResponse(id, result);
386
- } else {
379
+ const result = {
380
+ slot: Number(row.slot),
381
+ transaction: {
382
+ signatures: [signature],
383
+ message: {
384
+ accountKeys: accountKeysParsed,
385
+ header,
386
+ recentBlockhash: msg.recentBlockhash || "",
387
+ instructions: parsedInstructions,
388
+ addressTableLookups: msg.addressTableLookups || [],
389
+ },
390
+ },
391
+ version: row.version === "0" || row.version === 0 ? 0 : row.version,
392
+ meta: {
393
+ status: errVal ? { Err: errVal } : { Ok: null },
394
+ err: errVal,
395
+ fee: Number(row.fee),
396
+ loadedAddresses: { writable: [], readonly: [] },
397
+ preBalances,
398
+ postBalances,
399
+ innerInstructions: Array.isArray(inner) ? inner : [],
400
+ logMessages: logs,
401
+ preTokenBalances: JSON.parse(row.preTokenBalancesJson || "[]"),
402
+ postTokenBalances: JSON.parse(row.postTokenBalancesJson || "[]"),
403
+ computeUnitsConsumed:
404
+ row.computeUnits != null ? Number(row.computeUnits) : null,
405
+ returnData: (() => {
406
+ if (row.returnDataProgramId && row.returnDataBase64)
407
+ return {
408
+ programId: row.returnDataProgramId,
409
+ data: [row.returnDataBase64, "base64"],
410
+ };
411
+ return null;
412
+ })(),
413
+ rewards: [],
414
+ },
415
+ blockTime: row.blockTime ? Number(row.blockTime) : null,
416
+ };
417
+ // Also parse inner instructions from DB row
418
+ try {
419
+ const innerSrc = JSON.parse(row.innerInstructionsJson || "[]");
420
+ const innerParsed = (innerSrc as any[]).map((group) => ({
421
+ index: Number(group.index || 0),
422
+ instructions: Array.isArray(group.instructions)
423
+ ? group.instructions.map((ii: any) =>
424
+ parseInstruction(
425
+ accountKeys[ii.programIdIndex ?? 0] || accountKeys[0],
426
+ Array.isArray(ii.accounts) ? ii.accounts : [],
427
+ typeof ii.data === "string" ? ii.data : String(ii.data ?? ""),
428
+ accountKeys,
429
+ ),
430
+ )
431
+ : [],
432
+ }));
433
+ (result as any).meta.innerInstructions = innerParsed;
434
+ } catch {}
435
+
436
+ return context.createSuccessResponse(id, result);
437
+ } else {
387
438
  const raw = Buffer.from(row.rawBase64, "base64");
388
439
  const tx = VersionedTransaction.deserialize(raw);
389
440
  const msg = tx.message as unknown as {
@@ -434,36 +485,46 @@ export const getTransaction: RpcMethodHandler = async (id, params, context) => {
434
485
  ),
435
486
  };
436
487
  });
437
- const result = {
438
- slot: Number(row.slot),
439
- transaction: {
440
- signatures: [signature],
441
- message: {
442
- accountKeys,
443
- header,
444
- recentBlockhash: msg.recentBlockhash || "",
445
- instructions,
446
- addressTableLookups: msg.addressTableLookups || [],
447
- },
448
- },
449
- version: versionVal,
450
- meta: {
451
- status: errVal ? { Err: errVal } : { Ok: null },
452
- err: errVal,
453
- fee: Number(row.fee),
454
- loadedAddresses: { writable: [], readonly: [] },
455
- preBalances,
456
- postBalances,
457
- innerInstructions: [],
458
- logMessages: logs,
459
- preTokenBalances: JSON.parse(row.preTokenBalancesJson || "[]"),
460
- postTokenBalances: JSON.parse(row.postTokenBalancesJson || "[]"),
461
- rewards: [],
462
- },
463
- blockTime: row.blockTime ? Number(row.blockTime) : null,
464
- };
465
- return context.createSuccessResponse(id, result);
466
- }
488
+ const result = {
489
+ slot: Number(row.slot),
490
+ transaction: {
491
+ signatures: [signature],
492
+ message: {
493
+ accountKeys,
494
+ header,
495
+ recentBlockhash: msg.recentBlockhash || "",
496
+ instructions,
497
+ addressTableLookups: msg.addressTableLookups || [],
498
+ },
499
+ },
500
+ version: versionVal,
501
+ meta: {
502
+ status: errVal ? { Err: errVal } : { Ok: null },
503
+ err: errVal,
504
+ fee: Number(row.fee),
505
+ loadedAddresses: { writable: [], readonly: [] },
506
+ preBalances,
507
+ postBalances,
508
+ innerInstructions: Array.isArray(inner) ? inner : [],
509
+ logMessages: logs,
510
+ preTokenBalances: JSON.parse(row.preTokenBalancesJson || "[]"),
511
+ postTokenBalances: JSON.parse(row.postTokenBalancesJson || "[]"),
512
+ computeUnitsConsumed:
513
+ row.computeUnits != null ? Number(row.computeUnits) : null,
514
+ returnData: (() => {
515
+ if (row.returnDataProgramId && row.returnDataBase64)
516
+ return {
517
+ programId: row.returnDataProgramId,
518
+ data: [row.returnDataBase64, "base64"],
519
+ };
520
+ return null;
521
+ })(),
522
+ rewards: [],
523
+ },
524
+ blockTime: row.blockTime ? Number(row.blockTime) : null,
525
+ };
526
+ return context.createSuccessResponse(id, result);
527
+ }
467
528
  }
468
529
  } catch {}
469
530