@thesight/sdk 0.3.7 → 0.4.0
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.
- package/dist/index.cjs +139 -171
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -17
- package/dist/index.d.ts +2 -17
- package/dist/index.js +125 -157
- package/dist/index.js.map +1 -1
- package/package.json +5 -10
package/dist/index.cjs
CHANGED
|
@@ -20,7 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
-
IdlResolver: () =>
|
|
23
|
+
IdlResolver: () => import_core5.IdlResolver,
|
|
24
24
|
InstrumentedConnection: () => InstrumentedConnection,
|
|
25
25
|
SightSpanExporter: () => SightSpanExporter,
|
|
26
26
|
buildDsn: () => buildDsn,
|
|
@@ -30,15 +30,93 @@ __export(index_exports, {
|
|
|
30
30
|
});
|
|
31
31
|
module.exports = __toCommonJS(index_exports);
|
|
32
32
|
var import_web3 = require("@solana/web3.js");
|
|
33
|
-
var
|
|
34
|
-
var import_core3 = require("@thesight/core");
|
|
33
|
+
var import_api4 = require("@opentelemetry/api");
|
|
35
34
|
var import_core4 = require("@thesight/core");
|
|
36
35
|
|
|
37
|
-
// src/
|
|
36
|
+
// src/enrichment.ts
|
|
38
37
|
var import_api = require("@opentelemetry/api");
|
|
38
|
+
var import_core = require("@thesight/core");
|
|
39
|
+
var SOLANA_CU_BUDGET = 2e5;
|
|
40
|
+
var DEFAULT_ENRICHMENT_TIMEOUT_MS = 3e4;
|
|
41
|
+
var DEFAULT_ENRICHMENT_POLL_MS = 500;
|
|
42
|
+
async function pollForTransaction(getTransaction, signature, commitment, deadline, basePollMs) {
|
|
43
|
+
let attempt = 0;
|
|
44
|
+
while (Date.now() < deadline) {
|
|
45
|
+
try {
|
|
46
|
+
const tx = await getTransaction(signature, {
|
|
47
|
+
commitment,
|
|
48
|
+
maxSupportedTransactionVersion: 0
|
|
49
|
+
});
|
|
50
|
+
if (tx) return tx;
|
|
51
|
+
} catch {
|
|
52
|
+
}
|
|
53
|
+
attempt++;
|
|
54
|
+
const waitMs = Math.min(basePollMs * Math.pow(1.5, attempt - 1), 2e3);
|
|
55
|
+
await sleep(waitMs);
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
function attachTxDetailsToSpan(span, txDetails) {
|
|
60
|
+
span.setAttribute("solana.tx.status", txDetails.meta?.err ? "failed" : "confirmed");
|
|
61
|
+
span.setAttribute("solana.tx.slot", txDetails.slot);
|
|
62
|
+
const fee = txDetails.meta?.fee;
|
|
63
|
+
if (fee !== void 0) span.setAttribute("solana.tx.fee_lamports", fee);
|
|
64
|
+
const cuUsed = txDetails.meta?.computeUnitsConsumed;
|
|
65
|
+
if (cuUsed !== void 0 && cuUsed !== null) {
|
|
66
|
+
span.setAttribute("solana.tx.cu_used", Number(cuUsed));
|
|
67
|
+
span.setAttribute("solana.tx.cu_budget", SOLANA_CU_BUDGET);
|
|
68
|
+
span.setAttribute(
|
|
69
|
+
"solana.tx.cu_utilization",
|
|
70
|
+
parseFloat((Number(cuUsed) / SOLANA_CU_BUDGET * 100).toFixed(1))
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async function attachParsedLogsToSpan(span, logs, resolver) {
|
|
75
|
+
const { cpiTree } = (0, import_core.parseLogs)({ logs });
|
|
76
|
+
await (0, import_core.enrichTree)(cpiTree, resolver);
|
|
77
|
+
const attributions = (0, import_core.flatAttributions)(cpiTree);
|
|
78
|
+
for (const attr of attributions) {
|
|
79
|
+
span.addEvent("cpi.invoke", {
|
|
80
|
+
"cpi.program": attr.programName ?? attr.programId,
|
|
81
|
+
"cpi.instruction": attr.instructionName ?? "unknown",
|
|
82
|
+
"cpi.depth": attr.depth,
|
|
83
|
+
"cpi.cu_consumed": attr.cuConsumed,
|
|
84
|
+
"cpi.cu_self": attr.cuSelf,
|
|
85
|
+
"cpi.percentage": parseFloat(attr.percentage.toFixed(2))
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
const root = cpiTree.roots[0];
|
|
89
|
+
if (root) {
|
|
90
|
+
if (root.programName) span.setAttribute("solana.tx.program", root.programName);
|
|
91
|
+
if (root.instructionName) span.setAttribute("solana.tx.instruction", root.instructionName);
|
|
92
|
+
}
|
|
93
|
+
return cpiTree;
|
|
94
|
+
}
|
|
95
|
+
function finalizeSpan(span, txDetails, startTime) {
|
|
96
|
+
if (!txDetails) {
|
|
97
|
+
span.setAttribute("solana.tx.status", "timeout");
|
|
98
|
+
span.setAttribute("solana.tx.enrichment_ms", Date.now() - startTime);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
span.setAttribute("solana.tx.enrichment_ms", Date.now() - startTime);
|
|
102
|
+
if (txDetails.meta?.err) {
|
|
103
|
+
span.setStatus({ code: import_api.SpanStatusCode.ERROR });
|
|
104
|
+
} else {
|
|
105
|
+
span.setStatus({ code: import_api.SpanStatusCode.OK });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function sleep(ms) {
|
|
109
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// src/index.ts
|
|
113
|
+
var import_core5 = require("@thesight/core");
|
|
114
|
+
|
|
115
|
+
// src/init.ts
|
|
116
|
+
var import_api2 = require("@opentelemetry/api");
|
|
39
117
|
|
|
40
118
|
// src/exporter.ts
|
|
41
|
-
var
|
|
119
|
+
var import_core2 = require("@opentelemetry/core");
|
|
42
120
|
|
|
43
121
|
// src/dsn.ts
|
|
44
122
|
function parseDsn(dsn) {
|
|
@@ -91,7 +169,7 @@ var SightSpanExporter = class {
|
|
|
91
169
|
}
|
|
92
170
|
async export(spans, resultCallback) {
|
|
93
171
|
if (this.shuttingDown) {
|
|
94
|
-
resultCallback({ code:
|
|
172
|
+
resultCallback({ code: import_core2.ExportResultCode.FAILED, error: new Error("Exporter is shut down") });
|
|
95
173
|
return;
|
|
96
174
|
}
|
|
97
175
|
const chunks = [];
|
|
@@ -102,10 +180,10 @@ var SightSpanExporter = class {
|
|
|
102
180
|
for (const chunk of chunks) {
|
|
103
181
|
await this.sendChunk(chunk);
|
|
104
182
|
}
|
|
105
|
-
resultCallback({ code:
|
|
183
|
+
resultCallback({ code: import_core2.ExportResultCode.SUCCESS });
|
|
106
184
|
} catch (err) {
|
|
107
185
|
resultCallback({
|
|
108
|
-
code:
|
|
186
|
+
code: import_core2.ExportResultCode.FAILED,
|
|
109
187
|
error: err instanceof Error ? err : new Error(String(err))
|
|
110
188
|
});
|
|
111
189
|
}
|
|
@@ -139,8 +217,8 @@ var SightSpanExporter = class {
|
|
|
139
217
|
const attr = span.attributes;
|
|
140
218
|
const resource2 = span.resource.attributes;
|
|
141
219
|
const serviceName = typeof resource2["service.name"] === "string" ? resource2["service.name"] : void 0;
|
|
142
|
-
const startTimeMs = (0,
|
|
143
|
-
const endTimeMs = (0,
|
|
220
|
+
const startTimeMs = (0, import_core2.hrTimeToMilliseconds)(span.startTime);
|
|
221
|
+
const endTimeMs = (0, import_core2.hrTimeToMilliseconds)(span.endTime);
|
|
144
222
|
const durationMs = Math.max(0, endTimeMs - startTimeMs);
|
|
145
223
|
const out = {
|
|
146
224
|
traceId: span.spanContext().traceId,
|
|
@@ -214,8 +292,9 @@ function initSight(config) {
|
|
|
214
292
|
});
|
|
215
293
|
try {
|
|
216
294
|
const _require = eval("require");
|
|
217
|
-
const
|
|
218
|
-
const
|
|
295
|
+
const traceBase = _require("@opentelemetry/sdk-trace-base");
|
|
296
|
+
const TracerProvider = traceBase.TracerProvider ?? traceBase.BasicTracerProvider;
|
|
297
|
+
const BatchSpanProcessor = traceBase.BatchSpanProcessor;
|
|
219
298
|
const otelResources = _require("@opentelemetry/resources");
|
|
220
299
|
const processor = new BatchSpanProcessor(exporter, {
|
|
221
300
|
scheduledDelayMillis: config.batchDelayMs ?? 5e3,
|
|
@@ -228,11 +307,11 @@ function initSight(config) {
|
|
|
228
307
|
};
|
|
229
308
|
const resource = typeof otelResources.resourceFromAttributes === "function" ? otelResources.resourceFromAttributes(resourceAttrs) : new otelResources.Resource(resourceAttrs);
|
|
230
309
|
let provider;
|
|
231
|
-
if (typeof
|
|
232
|
-
provider = new
|
|
310
|
+
if (typeof TracerProvider.prototype.addSpanProcessor === "function") {
|
|
311
|
+
provider = new TracerProvider({ resource });
|
|
233
312
|
provider.addSpanProcessor(processor);
|
|
234
313
|
} else {
|
|
235
|
-
provider = new
|
|
314
|
+
provider = new TracerProvider({ resource, spanProcessors: [processor] });
|
|
236
315
|
}
|
|
237
316
|
try {
|
|
238
317
|
provider.register();
|
|
@@ -249,7 +328,7 @@ function initSight(config) {
|
|
|
249
328
|
_lastTier1Error = tier1Err;
|
|
250
329
|
}
|
|
251
330
|
try {
|
|
252
|
-
const proxy =
|
|
331
|
+
const proxy = import_api2.trace.getTracerProvider();
|
|
253
332
|
const delegate = proxy?.getDelegate?.() ?? proxy;
|
|
254
333
|
if (delegate && typeof delegate.addSpanProcessor === "function") {
|
|
255
334
|
const processor2 = new SightInlineProcessor(
|
|
@@ -259,7 +338,7 @@ function initSight(config) {
|
|
|
259
338
|
);
|
|
260
339
|
delegate.addSpanProcessor(processor2);
|
|
261
340
|
return {
|
|
262
|
-
tracer:
|
|
341
|
+
tracer: import_api2.trace.getTracer("@thesight/sdk"),
|
|
263
342
|
mode: "piggyback",
|
|
264
343
|
shutdown: async () => {
|
|
265
344
|
await processor2.shutdown();
|
|
@@ -281,7 +360,7 @@ function initSight(config) {
|
|
|
281
360
|
}
|
|
282
361
|
}
|
|
283
362
|
return {
|
|
284
|
-
tracer:
|
|
363
|
+
tracer: import_api2.trace.getTracer("@thesight/sdk"),
|
|
285
364
|
mode: "api_only",
|
|
286
365
|
shutdown: async () => {
|
|
287
366
|
}
|
|
@@ -331,68 +410,40 @@ var SightInlineProcessor = class {
|
|
|
331
410
|
};
|
|
332
411
|
|
|
333
412
|
// src/track.ts
|
|
334
|
-
var
|
|
335
|
-
var
|
|
413
|
+
var import_api3 = require("@opentelemetry/api");
|
|
414
|
+
var import_core3 = require("@thesight/core");
|
|
336
415
|
async function trackSolanaTransaction(opts) {
|
|
337
416
|
const tracerName = opts.serviceName ?? "@thesight/sdk";
|
|
338
|
-
const tracer = opts.tracer ??
|
|
339
|
-
const span = tracer.startSpan("solana.trackTransaction", {},
|
|
417
|
+
const tracer = opts.tracer ?? import_api3.trace.getTracer(tracerName);
|
|
418
|
+
const span = tracer.startSpan("solana.trackTransaction", {}, import_api3.context.active());
|
|
340
419
|
span.setAttribute("solana.tx.signature", opts.signature);
|
|
341
420
|
const start = Date.now();
|
|
342
|
-
const deadline = start + (opts.timeoutMs ??
|
|
421
|
+
const deadline = start + (opts.timeoutMs ?? DEFAULT_ENRICHMENT_TIMEOUT_MS);
|
|
343
422
|
const commitment = opts.commitment ?? "confirmed";
|
|
344
|
-
const basePoll = opts.pollIntervalMs ??
|
|
423
|
+
const basePoll = opts.pollIntervalMs ?? DEFAULT_ENRICHMENT_POLL_MS;
|
|
345
424
|
const resolver = opts.idlResolver ?? buildResolverFromIdls(opts.idls);
|
|
346
425
|
try {
|
|
347
|
-
const txDetails = await
|
|
426
|
+
const txDetails = await pollForTransaction(
|
|
427
|
+
(sig, pollOpts) => opts.connection.getTransaction(sig, pollOpts),
|
|
428
|
+
opts.signature,
|
|
429
|
+
commitment,
|
|
430
|
+
deadline,
|
|
431
|
+
basePoll
|
|
432
|
+
);
|
|
348
433
|
if (!txDetails) {
|
|
349
|
-
span
|
|
350
|
-
span.setAttribute("solana.tx.enrichment_ms", Date.now() - start);
|
|
434
|
+
finalizeSpan(span, null, start);
|
|
351
435
|
return;
|
|
352
436
|
}
|
|
353
|
-
span
|
|
354
|
-
span.setAttribute("solana.tx.slot", txDetails.slot);
|
|
355
|
-
const fee = txDetails.meta?.fee;
|
|
356
|
-
if (fee !== void 0) span.setAttribute("solana.tx.fee_lamports", fee);
|
|
357
|
-
const cuUsed = txDetails.meta?.computeUnitsConsumed;
|
|
358
|
-
if (cuUsed !== void 0 && cuUsed !== null) {
|
|
359
|
-
span.setAttribute("solana.tx.cu_used", Number(cuUsed));
|
|
360
|
-
span.setAttribute("solana.tx.cu_budget", 2e5);
|
|
361
|
-
span.setAttribute(
|
|
362
|
-
"solana.tx.cu_utilization",
|
|
363
|
-
parseFloat((Number(cuUsed) / 2e5 * 100).toFixed(1))
|
|
364
|
-
);
|
|
365
|
-
}
|
|
437
|
+
attachTxDetailsToSpan(span, txDetails);
|
|
366
438
|
const logs = txDetails.meta?.logMessages ?? [];
|
|
367
439
|
if (logs.length > 0) {
|
|
368
|
-
|
|
369
|
-
await (0, import_core2.enrichTree)(cpiTree, resolver);
|
|
370
|
-
for (const attr of (0, import_core2.flatAttributions)(cpiTree)) {
|
|
371
|
-
span.addEvent("cpi.invoke", {
|
|
372
|
-
"cpi.program": attr.programName ?? attr.programId,
|
|
373
|
-
"cpi.instruction": attr.instructionName ?? "unknown",
|
|
374
|
-
"cpi.depth": attr.depth,
|
|
375
|
-
"cpi.cu_consumed": attr.cuConsumed,
|
|
376
|
-
"cpi.cu_self": attr.cuSelf,
|
|
377
|
-
"cpi.percentage": parseFloat(attr.percentage.toFixed(2))
|
|
378
|
-
});
|
|
379
|
-
}
|
|
380
|
-
const root = cpiTree.roots[0];
|
|
381
|
-
if (root) {
|
|
382
|
-
if (root.programName) span.setAttribute("solana.tx.program", root.programName);
|
|
383
|
-
if (root.instructionName) span.setAttribute("solana.tx.instruction", root.instructionName);
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
span.setAttribute("solana.tx.enrichment_ms", Date.now() - start);
|
|
387
|
-
if (txDetails.meta?.err) {
|
|
388
|
-
span.setStatus({ code: import_api2.SpanStatusCode.ERROR });
|
|
389
|
-
} else {
|
|
390
|
-
span.setStatus({ code: import_api2.SpanStatusCode.OK });
|
|
440
|
+
await attachParsedLogsToSpan(span, logs, resolver);
|
|
391
441
|
}
|
|
442
|
+
finalizeSpan(span, txDetails, start);
|
|
392
443
|
} catch (err) {
|
|
393
444
|
span.recordException(err instanceof Error ? err : new Error(String(err)));
|
|
394
445
|
span.setStatus({
|
|
395
|
-
code:
|
|
446
|
+
code: import_api3.SpanStatusCode.ERROR,
|
|
396
447
|
message: err instanceof Error ? err.message : String(err)
|
|
397
448
|
});
|
|
398
449
|
} finally {
|
|
@@ -400,27 +451,10 @@ async function trackSolanaTransaction(opts) {
|
|
|
400
451
|
}
|
|
401
452
|
}
|
|
402
453
|
function buildResolverFromIdls(idls) {
|
|
403
|
-
const resolver = new
|
|
454
|
+
const resolver = new import_core3.IdlResolver();
|
|
404
455
|
if (idls) resolver.registerMany(idls);
|
|
405
456
|
return resolver;
|
|
406
457
|
}
|
|
407
|
-
async function pollGetTransaction(connection, signature, commitment, deadline, basePollMs) {
|
|
408
|
-
let attempt = 0;
|
|
409
|
-
while (Date.now() < deadline) {
|
|
410
|
-
try {
|
|
411
|
-
const tx = await connection.getTransaction(signature, {
|
|
412
|
-
commitment,
|
|
413
|
-
maxSupportedTransactionVersion: 0
|
|
414
|
-
});
|
|
415
|
-
if (tx) return tx;
|
|
416
|
-
} catch {
|
|
417
|
-
}
|
|
418
|
-
attempt++;
|
|
419
|
-
const waitMs = Math.min(basePollMs * Math.pow(1.5, attempt - 1), 2e3);
|
|
420
|
-
await new Promise((resolve) => setTimeout(resolve, waitMs));
|
|
421
|
-
}
|
|
422
|
-
return null;
|
|
423
|
-
}
|
|
424
458
|
|
|
425
459
|
// src/index.ts
|
|
426
460
|
var InstrumentedConnection = class extends import_web3.Connection {
|
|
@@ -437,7 +471,9 @@ var InstrumentedConnection = class extends import_web3.Connection {
|
|
|
437
471
|
enrichmentTimeoutMs,
|
|
438
472
|
enrichmentPollIntervalMs,
|
|
439
473
|
disableAutoSpan,
|
|
440
|
-
commitment
|
|
474
|
+
// Note: commitment is intentionally NOT destructured out. It must
|
|
475
|
+
// pass through to super() via connectionConfig so the parent
|
|
476
|
+
// Connection uses it for RPC calls (preflight, blockhash, etc.).
|
|
441
477
|
...connectionConfig
|
|
442
478
|
} = config2 ?? {};
|
|
443
479
|
super(endpoint, connectionConfig);
|
|
@@ -446,17 +482,17 @@ var InstrumentedConnection = class extends import_web3.Connection {
|
|
|
446
482
|
idlRpcEndpoint,
|
|
447
483
|
skipIdlResolution,
|
|
448
484
|
allowOnChainIdlFetch,
|
|
449
|
-
enrichmentTimeoutMs: enrichmentTimeoutMs ??
|
|
450
|
-
enrichmentPollIntervalMs: enrichmentPollIntervalMs ??
|
|
485
|
+
enrichmentTimeoutMs: enrichmentTimeoutMs ?? DEFAULT_ENRICHMENT_TIMEOUT_MS,
|
|
486
|
+
enrichmentPollIntervalMs: enrichmentPollIntervalMs ?? DEFAULT_ENRICHMENT_POLL_MS,
|
|
451
487
|
disableAutoSpan,
|
|
452
|
-
commitment
|
|
488
|
+
commitment: config2?.commitment
|
|
453
489
|
};
|
|
454
|
-
this.idlResolver = new
|
|
490
|
+
this.idlResolver = new import_core4.IdlResolver({
|
|
455
491
|
rpcEndpoint: idlRpcEndpoint ?? endpoint,
|
|
456
492
|
allowOnChainFetch: allowOnChainIdlFetch ?? false
|
|
457
493
|
});
|
|
458
494
|
if (idls) this.idlResolver.registerMany(idls);
|
|
459
|
-
this.tracer = tracer ??
|
|
495
|
+
this.tracer = tracer ?? import_api4.trace.getTracer("@thesight/sdk");
|
|
460
496
|
}
|
|
461
497
|
/**
|
|
462
498
|
* Register an IDL for a single program. Convenience forwarder for the
|
|
@@ -488,7 +524,7 @@ var InstrumentedConnection = class extends import_web3.Connection {
|
|
|
488
524
|
if (this.sightConfig.disableAutoSpan) {
|
|
489
525
|
return super.sendRawTransaction(rawTransaction, options);
|
|
490
526
|
}
|
|
491
|
-
const span = this.tracer.startSpan("solana.sendRawTransaction", {},
|
|
527
|
+
const span = this.tracer.startSpan("solana.sendRawTransaction", {}, import_api4.context.active());
|
|
492
528
|
const submitStart = Date.now();
|
|
493
529
|
let signature;
|
|
494
530
|
try {
|
|
@@ -499,7 +535,7 @@ var InstrumentedConnection = class extends import_web3.Connection {
|
|
|
499
535
|
span.setAttribute("solana.tx.status", "failed");
|
|
500
536
|
span.recordException(err instanceof Error ? err : new Error(String(err)));
|
|
501
537
|
span.setStatus({
|
|
502
|
-
code:
|
|
538
|
+
code: import_api4.SpanStatusCode.ERROR,
|
|
503
539
|
message: err instanceof Error ? err.message : String(err)
|
|
504
540
|
});
|
|
505
541
|
span.end();
|
|
@@ -523,30 +559,30 @@ var InstrumentedConnection = class extends import_web3.Connection {
|
|
|
523
559
|
*/
|
|
524
560
|
async enrichSpanInBackground(span, signature, submitStart) {
|
|
525
561
|
const enrichStart = Date.now();
|
|
526
|
-
const deadline = enrichStart + (this.sightConfig.enrichmentTimeoutMs ??
|
|
562
|
+
const deadline = enrichStart + (this.sightConfig.enrichmentTimeoutMs ?? DEFAULT_ENRICHMENT_TIMEOUT_MS);
|
|
527
563
|
const commitment = this.sightConfig.commitment ?? "confirmed";
|
|
528
|
-
const basePollMs = this.sightConfig.enrichmentPollIntervalMs ??
|
|
564
|
+
const basePollMs = this.sightConfig.enrichmentPollIntervalMs ?? DEFAULT_ENRICHMENT_POLL_MS;
|
|
529
565
|
try {
|
|
530
|
-
const txDetails = await
|
|
566
|
+
const txDetails = await pollForTransaction(
|
|
567
|
+
(sig, opts) => super.getTransaction(sig, opts),
|
|
568
|
+
signature,
|
|
569
|
+
commitment,
|
|
570
|
+
deadline,
|
|
571
|
+
basePollMs
|
|
572
|
+
);
|
|
531
573
|
if (!txDetails) {
|
|
532
|
-
span
|
|
533
|
-
span.setAttribute("solana.tx.enrichment_ms", Date.now() - submitStart);
|
|
574
|
+
finalizeSpan(span, null, submitStart);
|
|
534
575
|
span.end();
|
|
535
576
|
return;
|
|
536
577
|
}
|
|
537
|
-
|
|
578
|
+
attachTxDetailsToSpan(span, txDetails);
|
|
538
579
|
if (!this.sightConfig.skipIdlResolution) {
|
|
539
580
|
const logs = txDetails.meta?.logMessages ?? [];
|
|
540
581
|
if (logs.length > 0) {
|
|
541
|
-
await
|
|
582
|
+
await attachParsedLogsToSpan(span, logs, this.idlResolver);
|
|
542
583
|
}
|
|
543
584
|
}
|
|
544
|
-
span
|
|
545
|
-
if (txDetails.meta?.err) {
|
|
546
|
-
span.setStatus({ code: import_api3.SpanStatusCode.ERROR });
|
|
547
|
-
} else {
|
|
548
|
-
span.setStatus({ code: import_api3.SpanStatusCode.OK });
|
|
549
|
-
}
|
|
585
|
+
finalizeSpan(span, txDetails, submitStart);
|
|
550
586
|
} catch (err) {
|
|
551
587
|
span.recordException(err instanceof Error ? err : new Error(String(err)));
|
|
552
588
|
span.setAttribute(
|
|
@@ -557,75 +593,7 @@ var InstrumentedConnection = class extends import_web3.Connection {
|
|
|
557
593
|
span.end();
|
|
558
594
|
}
|
|
559
595
|
}
|
|
560
|
-
/**
|
|
561
|
-
* Poll `getTransaction(signature)` until either the on-chain record is
|
|
562
|
-
* returned or the deadline passes. Exponential backoff (1.5x) capped at
|
|
563
|
-
* 2 seconds to balance responsiveness against RPC load.
|
|
564
|
-
*/
|
|
565
|
-
async pollForTransaction(signature, commitment, deadline, basePollMs) {
|
|
566
|
-
let attempt = 0;
|
|
567
|
-
while (Date.now() < deadline) {
|
|
568
|
-
try {
|
|
569
|
-
const tx = await super.getTransaction(signature, {
|
|
570
|
-
commitment,
|
|
571
|
-
maxSupportedTransactionVersion: 0
|
|
572
|
-
});
|
|
573
|
-
if (tx) return tx;
|
|
574
|
-
} catch {
|
|
575
|
-
}
|
|
576
|
-
attempt++;
|
|
577
|
-
const waitMs = Math.min(basePollMs * Math.pow(1.5, attempt - 1), 2e3);
|
|
578
|
-
await sleep(waitMs);
|
|
579
|
-
}
|
|
580
|
-
return null;
|
|
581
|
-
}
|
|
582
|
-
/** Attach the flat fields (slot, fee, CU, status) from a tx response to a span. */
|
|
583
|
-
attachTxDetailsToSpan(span, txDetails) {
|
|
584
|
-
span.setAttribute("solana.tx.status", txDetails.meta?.err ? "failed" : "confirmed");
|
|
585
|
-
span.setAttribute("solana.tx.slot", txDetails.slot);
|
|
586
|
-
const fee = txDetails.meta?.fee;
|
|
587
|
-
if (fee !== void 0) span.setAttribute("solana.tx.fee_lamports", fee);
|
|
588
|
-
const cuUsed = txDetails.meta?.computeUnitsConsumed;
|
|
589
|
-
if (cuUsed !== void 0 && cuUsed !== null) {
|
|
590
|
-
span.setAttribute("solana.tx.cu_used", Number(cuUsed));
|
|
591
|
-
span.setAttribute("solana.tx.cu_budget", 2e5);
|
|
592
|
-
span.setAttribute(
|
|
593
|
-
"solana.tx.cu_utilization",
|
|
594
|
-
parseFloat((Number(cuUsed) / 2e5 * 100).toFixed(1))
|
|
595
|
-
);
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
/**
|
|
599
|
-
* Parse program logs into a CPI tree, enrich with registered IDLs, and
|
|
600
|
-
* emit one `cpi.invoke` event per invocation onto the span. Root
|
|
601
|
-
* program/instruction names are copied onto span attributes so dashboards
|
|
602
|
-
* can filter by them without walking events.
|
|
603
|
-
*/
|
|
604
|
-
async attachParsedLogsToSpan(span, logs) {
|
|
605
|
-
const { cpiTree } = (0, import_core3.parseLogs)({ logs });
|
|
606
|
-
await (0, import_core3.enrichTree)(cpiTree, this.idlResolver);
|
|
607
|
-
const attributions = (0, import_core3.flatAttributions)(cpiTree);
|
|
608
|
-
for (const attr of attributions) {
|
|
609
|
-
span.addEvent("cpi.invoke", {
|
|
610
|
-
"cpi.program": attr.programName ?? attr.programId,
|
|
611
|
-
"cpi.instruction": attr.instructionName ?? "unknown",
|
|
612
|
-
"cpi.depth": attr.depth,
|
|
613
|
-
"cpi.cu_consumed": attr.cuConsumed,
|
|
614
|
-
"cpi.cu_self": attr.cuSelf,
|
|
615
|
-
"cpi.percentage": parseFloat(attr.percentage.toFixed(2))
|
|
616
|
-
});
|
|
617
|
-
}
|
|
618
|
-
const root = cpiTree.roots[0];
|
|
619
|
-
if (root) {
|
|
620
|
-
if (root.programName) span.setAttribute("solana.tx.program", root.programName);
|
|
621
|
-
if (root.instructionName) span.setAttribute("solana.tx.instruction", root.instructionName);
|
|
622
|
-
}
|
|
623
|
-
return cpiTree;
|
|
624
|
-
}
|
|
625
596
|
};
|
|
626
|
-
function sleep(ms) {
|
|
627
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
628
|
-
}
|
|
629
597
|
// Annotate the CommonJS export names for ESM import in node:
|
|
630
598
|
0 && (module.exports = {
|
|
631
599
|
IdlResolver,
|