@thesight/sdk 0.1.0 → 0.1.1
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 +366 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +194 -0
- package/dist/index.d.ts +115 -13
- package/dist/index.js +335 -167
- package/dist/index.js.map +1 -1
- package/package.json +8 -6
- package/dist/exporter.d.ts +0 -43
- package/dist/exporter.d.ts.map +0 -1
- package/dist/exporter.js +0 -151
- package/dist/exporter.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/init.d.ts +0 -62
- package/dist/init.d.ts.map +0 -1
- package/dist/init.js +0 -78
- package/dist/init.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,175 +1,343 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import {
|
|
3
|
+
Connection
|
|
4
|
+
} from "@solana/web3.js";
|
|
5
|
+
import { trace, context, SpanStatusCode } from "@opentelemetry/api";
|
|
6
|
+
import { parseLogs, IdlResolver, enrichTree, flatAttributions } from "@thesight/core";
|
|
7
|
+
import { IdlResolver as IdlResolver2 } from "@thesight/core";
|
|
8
|
+
|
|
9
|
+
// src/init.ts
|
|
10
|
+
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
|
|
11
|
+
import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
12
|
+
import { Resource } from "@opentelemetry/resources";
|
|
13
|
+
import { SEMRESATTRS_SERVICE_NAME, SEMRESATTRS_SERVICE_VERSION } from "@opentelemetry/semantic-conventions";
|
|
14
|
+
|
|
15
|
+
// src/exporter.ts
|
|
16
|
+
import {
|
|
17
|
+
hrTimeToMilliseconds,
|
|
18
|
+
ExportResultCode
|
|
19
|
+
} from "@opentelemetry/core";
|
|
20
|
+
var SightSpanExporter = class {
|
|
21
|
+
apiKey;
|
|
22
|
+
ingestUrl;
|
|
23
|
+
fetchImpl;
|
|
24
|
+
maxBatchSize;
|
|
25
|
+
shuttingDown = false;
|
|
26
|
+
constructor(config) {
|
|
27
|
+
this.apiKey = config.apiKey;
|
|
28
|
+
this.ingestUrl = config.ingestUrl;
|
|
29
|
+
this.fetchImpl = config.fetchImpl ?? globalThis.fetch;
|
|
30
|
+
this.maxBatchSize = Math.min(100, config.maxBatchSize ?? 100);
|
|
31
|
+
if (!this.fetchImpl) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
"SightSpanExporter: globalThis.fetch is not available. Node >= 18 ships with fetch built in, or pass `fetchImpl` explicitly."
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async export(spans, resultCallback) {
|
|
38
|
+
if (this.shuttingDown) {
|
|
39
|
+
resultCallback({ code: ExportResultCode.FAILED, error: new Error("Exporter is shut down") });
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const chunks = [];
|
|
43
|
+
for (let i = 0; i < spans.length; i += this.maxBatchSize) {
|
|
44
|
+
chunks.push(spans.slice(i, i + this.maxBatchSize));
|
|
32
45
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
46
|
+
try {
|
|
47
|
+
for (const chunk of chunks) {
|
|
48
|
+
await this.sendChunk(chunk);
|
|
49
|
+
}
|
|
50
|
+
resultCallback({ code: ExportResultCode.SUCCESS });
|
|
51
|
+
} catch (err) {
|
|
52
|
+
resultCallback({
|
|
53
|
+
code: ExportResultCode.FAILED,
|
|
54
|
+
error: err instanceof Error ? err : new Error(String(err))
|
|
55
|
+
});
|
|
43
56
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
57
|
+
}
|
|
58
|
+
async shutdown() {
|
|
59
|
+
this.shuttingDown = true;
|
|
60
|
+
}
|
|
61
|
+
async forceFlush() {
|
|
62
|
+
}
|
|
63
|
+
// ─── Internal ──────────────────────────────────────────────────────────────
|
|
64
|
+
async sendChunk(spans) {
|
|
65
|
+
const payload = {
|
|
66
|
+
spans: spans.map((span) => this.convertSpan(span))
|
|
67
|
+
};
|
|
68
|
+
const response = await this.fetchImpl(this.ingestUrl, {
|
|
69
|
+
method: "POST",
|
|
70
|
+
headers: {
|
|
71
|
+
"Content-Type": "application/json",
|
|
72
|
+
"Authorization": `Bearer ${this.apiKey}`
|
|
73
|
+
},
|
|
74
|
+
body: JSON.stringify(payload)
|
|
75
|
+
});
|
|
76
|
+
if (!response.ok) {
|
|
77
|
+
const body = await safeReadText(response);
|
|
78
|
+
throw new Error(
|
|
79
|
+
`Sight ingest returned ${response.status} ${response.statusText}: ${body}`
|
|
80
|
+
);
|
|
47
81
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
82
|
+
}
|
|
83
|
+
convertSpan(span) {
|
|
84
|
+
const attr = span.attributes;
|
|
85
|
+
const resource = span.resource.attributes;
|
|
86
|
+
const serviceName = typeof resource["service.name"] === "string" ? resource["service.name"] : void 0;
|
|
87
|
+
const startTimeMs = hrTimeToMilliseconds(span.startTime);
|
|
88
|
+
const endTimeMs = hrTimeToMilliseconds(span.endTime);
|
|
89
|
+
const durationMs = Math.max(0, endTimeMs - startTimeMs);
|
|
90
|
+
const out = {
|
|
91
|
+
traceId: span.spanContext().traceId,
|
|
92
|
+
spanId: span.spanContext().spanId,
|
|
93
|
+
spanName: span.name,
|
|
94
|
+
startTimeMs,
|
|
95
|
+
durationMs
|
|
96
|
+
};
|
|
97
|
+
const parentSpanId = span.parentSpanId;
|
|
98
|
+
if (parentSpanId) out.parentSpanId = parentSpanId;
|
|
99
|
+
if (serviceName) out.serviceName = serviceName;
|
|
100
|
+
copyIfString(attr, "solana.tx.signature", out);
|
|
101
|
+
copyIfEnum(attr, "solana.tx.status", out, ["confirmed", "failed", "timeout"]);
|
|
102
|
+
copyIfNumber(attr, "solana.tx.slot", out);
|
|
103
|
+
copyIfNumber(attr, "solana.tx.cu_used", out);
|
|
104
|
+
copyIfNumber(attr, "solana.tx.cu_budget", out);
|
|
105
|
+
copyIfNumber(attr, "solana.tx.cu_utilization", out);
|
|
106
|
+
copyIfString(attr, "solana.tx.program", out);
|
|
107
|
+
copyIfString(attr, "solana.tx.instruction", out);
|
|
108
|
+
copyIfString(attr, "solana.tx.error", out);
|
|
109
|
+
copyIfNumber(attr, "solana.tx.error_code", out);
|
|
110
|
+
copyIfString(attr, "solana.tx.error_program", out);
|
|
111
|
+
copyIfNumber(attr, "solana.tx.submit_ms", out);
|
|
112
|
+
copyIfNumber(attr, "solana.tx.confirmation_ms", out);
|
|
113
|
+
copyIfNumber(attr, "solana.tx.fee_lamports", out);
|
|
114
|
+
return out;
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
function copyIfString(attr, key, out) {
|
|
118
|
+
const v = attr[key];
|
|
119
|
+
if (typeof v === "string") {
|
|
120
|
+
out[key] = v;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function copyIfNumber(attr, key, out) {
|
|
124
|
+
const v = attr[key];
|
|
125
|
+
if (typeof v === "number" && Number.isFinite(v)) {
|
|
126
|
+
out[key] = v;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function copyIfEnum(attr, key, out, allowed) {
|
|
130
|
+
const v = attr[key];
|
|
131
|
+
if (typeof v === "string" && allowed.includes(v)) {
|
|
132
|
+
out[key] = v;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async function safeReadText(res) {
|
|
136
|
+
try {
|
|
137
|
+
return (await res.text()).slice(0, 500);
|
|
138
|
+
} catch {
|
|
139
|
+
return "<no body>";
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// src/init.ts
|
|
144
|
+
var DEFAULT_INGEST_URL = "https://ingest.thesight.dev/ingest";
|
|
145
|
+
function initSight(config) {
|
|
146
|
+
if (!config.apiKey) {
|
|
147
|
+
throw new Error("initSight: `apiKey` is required");
|
|
148
|
+
}
|
|
149
|
+
if (!config.serviceName) {
|
|
150
|
+
throw new Error("initSight: `serviceName` is required");
|
|
151
|
+
}
|
|
152
|
+
const resource = new Resource({
|
|
153
|
+
[SEMRESATTRS_SERVICE_NAME]: config.serviceName,
|
|
154
|
+
...config.serviceVersion ? { [SEMRESATTRS_SERVICE_VERSION]: config.serviceVersion } : {}
|
|
155
|
+
});
|
|
156
|
+
const provider = new NodeTracerProvider({ resource });
|
|
157
|
+
const exporter = new SightSpanExporter({
|
|
158
|
+
apiKey: config.apiKey,
|
|
159
|
+
ingestUrl: config.ingestUrl ?? DEFAULT_INGEST_URL,
|
|
160
|
+
fetchImpl: config.fetchImpl,
|
|
161
|
+
maxBatchSize: config.maxBatchSize
|
|
162
|
+
});
|
|
163
|
+
const processor = new BatchSpanProcessor(exporter, {
|
|
164
|
+
scheduledDelayMillis: config.batchDelayMs ?? 5e3,
|
|
165
|
+
maxExportBatchSize: config.maxBatchSize ?? 100,
|
|
166
|
+
maxQueueSize: 2048
|
|
167
|
+
});
|
|
168
|
+
provider.addSpanProcessor(processor);
|
|
169
|
+
provider.register();
|
|
170
|
+
return {
|
|
171
|
+
provider,
|
|
172
|
+
shutdown: async () => {
|
|
173
|
+
await provider.shutdown();
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// src/index.ts
|
|
179
|
+
var InstrumentedConnection = class extends Connection {
|
|
180
|
+
sightConfig;
|
|
181
|
+
idlResolver;
|
|
182
|
+
tracer;
|
|
183
|
+
constructor(endpoint, config) {
|
|
184
|
+
const {
|
|
185
|
+
tracer,
|
|
186
|
+
idlRpcEndpoint,
|
|
187
|
+
skipIdlResolution,
|
|
188
|
+
idls,
|
|
189
|
+
allowOnChainIdlFetch,
|
|
190
|
+
...connectionConfig
|
|
191
|
+
} = config ?? {};
|
|
192
|
+
super(endpoint, connectionConfig);
|
|
193
|
+
this.sightConfig = { tracer, idlRpcEndpoint, skipIdlResolution, allowOnChainIdlFetch };
|
|
194
|
+
this.idlResolver = new IdlResolver({
|
|
195
|
+
rpcEndpoint: idlRpcEndpoint ?? endpoint,
|
|
196
|
+
allowOnChainFetch: allowOnChainIdlFetch ?? false
|
|
197
|
+
});
|
|
198
|
+
if (idls) this.idlResolver.registerMany(idls);
|
|
199
|
+
this.tracer = tracer ?? trace.getTracer("@thesight/sdk");
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Register an IDL for a single program. Convenience forwarder for the
|
|
203
|
+
* underlying resolver. Anchor users typically call this right after
|
|
204
|
+
* constructing a `Program`:
|
|
205
|
+
*
|
|
206
|
+
* const program = new Program(idl, programId, provider);
|
|
207
|
+
* connection.registerIdl(program.programId.toBase58(), program.idl);
|
|
208
|
+
*/
|
|
209
|
+
registerIdl(programId, idl) {
|
|
210
|
+
this.idlResolver.register(programId, idl);
|
|
211
|
+
}
|
|
212
|
+
/** Bulk-register multiple IDLs. */
|
|
213
|
+
registerIdls(idls) {
|
|
214
|
+
this.idlResolver.registerMany(idls);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Sends and confirms a transaction, wrapped in an OTel span.
|
|
218
|
+
* The span is a child of the current active context.
|
|
219
|
+
*/
|
|
220
|
+
async sendAndConfirmInstrumented(transaction, options) {
|
|
221
|
+
const commitment = options?.commitment ?? this.sightConfig.commitment ?? "confirmed";
|
|
222
|
+
const finality = commitment === "processed" ? "confirmed" : commitment;
|
|
223
|
+
const span = this.tracer.startSpan("solana.sendAndConfirmTransaction", {}, context.active());
|
|
224
|
+
const submitStart = Date.now();
|
|
225
|
+
try {
|
|
226
|
+
const signature = await this.sendRawTransaction(
|
|
227
|
+
"serialize" in transaction ? transaction.serialize() : transaction.serialize(),
|
|
228
|
+
{ skipPreflight: false, ...options }
|
|
229
|
+
);
|
|
230
|
+
span.setAttribute("solana.tx.signature", signature);
|
|
231
|
+
const submitMs = Date.now() - submitStart;
|
|
232
|
+
span.setAttribute("solana.tx.submit_ms", submitMs);
|
|
233
|
+
const confirmStart = Date.now();
|
|
234
|
+
const { value: result } = await this.confirmTransaction(
|
|
235
|
+
{ signature, ...await this.getLatestBlockhash(commitment) },
|
|
236
|
+
commitment
|
|
237
|
+
);
|
|
238
|
+
const confirmMs = Date.now() - confirmStart;
|
|
239
|
+
span.setAttribute("solana.tx.confirmation_ms", confirmMs);
|
|
240
|
+
if (result.err) {
|
|
241
|
+
span.setAttribute("solana.tx.status", "failed");
|
|
242
|
+
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
243
|
+
if (!this.sightConfig.skipIdlResolution) {
|
|
244
|
+
const txDetails = await this.getParsedTransaction(signature, {
|
|
245
|
+
commitment: finality,
|
|
246
|
+
maxSupportedTransactionVersion: 0
|
|
247
|
+
});
|
|
248
|
+
const accountKeys = txDetails?.transaction.message.accountKeys.map(
|
|
249
|
+
(k) => k.pubkey ? k.pubkey.toBase58() : k.toBase58()
|
|
250
|
+
) ?? [];
|
|
251
|
+
const programIds = txDetails?.transaction.message.instructions.map(
|
|
252
|
+
(ix) => ix.programId ? ix.programId.toBase58() : accountKeys[ix.programIdIndex] ?? ""
|
|
253
|
+
) ?? [];
|
|
254
|
+
const decoded = await this.idlResolver.decodeError(
|
|
255
|
+
result.err,
|
|
256
|
+
accountKeys,
|
|
257
|
+
programIds
|
|
258
|
+
);
|
|
259
|
+
if (decoded.errorName) {
|
|
260
|
+
span.setAttribute("solana.tx.error", decoded.errorName);
|
|
261
|
+
}
|
|
262
|
+
if (decoded.errorCode !== void 0) {
|
|
263
|
+
span.setAttribute("solana.tx.error_code", decoded.errorCode);
|
|
264
|
+
}
|
|
265
|
+
if (decoded.programName) {
|
|
266
|
+
span.setAttribute("solana.tx.error_program", decoded.programName);
|
|
267
|
+
}
|
|
268
|
+
if (decoded.errorMsg) {
|
|
269
|
+
span.setAttribute("solana.tx.error_msg", decoded.errorMsg);
|
|
270
|
+
}
|
|
271
|
+
span.end();
|
|
272
|
+
return { signature, error: decoded };
|
|
155
273
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
274
|
+
span.end();
|
|
275
|
+
return { signature };
|
|
276
|
+
}
|
|
277
|
+
span.setAttribute("solana.tx.status", "confirmed");
|
|
278
|
+
if (!this.sightConfig.skipIdlResolution) {
|
|
279
|
+
const enrichStart = Date.now();
|
|
280
|
+
const txDetails = await this.getTransaction(signature, {
|
|
281
|
+
commitment: finality,
|
|
282
|
+
maxSupportedTransactionVersion: 0
|
|
283
|
+
});
|
|
284
|
+
if (txDetails) {
|
|
285
|
+
const slot = txDetails.slot;
|
|
286
|
+
const fee = txDetails.meta?.fee;
|
|
287
|
+
const logs = txDetails.meta?.logMessages ?? [];
|
|
288
|
+
const cuUsed = txDetails.meta?.computeUnitsConsumed;
|
|
289
|
+
span.setAttribute("solana.tx.slot", slot);
|
|
290
|
+
if (fee !== void 0) span.setAttribute("solana.tx.fee_lamports", fee);
|
|
291
|
+
if (cuUsed !== void 0) {
|
|
292
|
+
span.setAttribute("solana.tx.cu_used", cuUsed);
|
|
293
|
+
span.setAttribute("solana.tx.cu_budget", 2e5);
|
|
294
|
+
span.setAttribute("solana.tx.cu_utilization", parseFloat((cuUsed / 2e5 * 100).toFixed(1)));
|
|
295
|
+
}
|
|
296
|
+
const { cpiTree } = parseLogs({ logs });
|
|
297
|
+
if (!this.sightConfig.skipIdlResolution) {
|
|
298
|
+
await enrichTree(cpiTree, this.idlResolver);
|
|
299
|
+
}
|
|
300
|
+
const attributions = flatAttributions(cpiTree);
|
|
301
|
+
for (const attr of attributions) {
|
|
302
|
+
span.addEvent("cpi.invoke", {
|
|
303
|
+
"cpi.program": attr.programName ?? attr.programId,
|
|
304
|
+
"cpi.instruction": attr.instructionName ?? "unknown",
|
|
305
|
+
"cpi.depth": attr.depth,
|
|
306
|
+
"cpi.cu_consumed": attr.cuConsumed,
|
|
307
|
+
"cpi.cu_self": attr.cuSelf,
|
|
308
|
+
"cpi.percentage": parseFloat(attr.percentage.toFixed(2))
|
|
162
309
|
});
|
|
163
|
-
|
|
164
|
-
|
|
310
|
+
}
|
|
311
|
+
const root = cpiTree.roots[0];
|
|
312
|
+
if (root) {
|
|
313
|
+
if (root.programName) span.setAttribute("solana.tx.program", root.programName);
|
|
314
|
+
if (root.instructionName) span.setAttribute("solana.tx.instruction", root.instructionName);
|
|
315
|
+
}
|
|
316
|
+
span.setAttribute("solana.tx.enrichment_ms", Date.now() - enrichStart);
|
|
317
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
318
|
+
span.end();
|
|
319
|
+
return { signature, cpiTree };
|
|
165
320
|
}
|
|
321
|
+
}
|
|
322
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
323
|
+
span.end();
|
|
324
|
+
return { signature };
|
|
325
|
+
} catch (err) {
|
|
326
|
+
span.setAttribute("solana.tx.status", "failed");
|
|
327
|
+
span.setAttribute("solana.tx.submit_ms", Date.now() - submitStart);
|
|
328
|
+
span.setStatus({
|
|
329
|
+
code: SpanStatusCode.ERROR,
|
|
330
|
+
message: err instanceof Error ? err.message : String(err)
|
|
331
|
+
});
|
|
332
|
+
span.end();
|
|
333
|
+
throw err;
|
|
166
334
|
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
export {
|
|
338
|
+
IdlResolver2 as IdlResolver,
|
|
339
|
+
InstrumentedConnection,
|
|
340
|
+
SightSpanExporter,
|
|
341
|
+
initSight
|
|
342
|
+
};
|
|
175
343
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/init.ts","../src/exporter.ts"],"sourcesContent":["import {\n Connection,\n type ConnectionConfig,\n type Transaction,\n type VersionedTransaction,\n type SendOptions,\n type Commitment,\n type Finality,\n type RpcResponseAndContext,\n type SignatureResult,\n} from '@solana/web3.js';\nimport { trace, context, SpanStatusCode, type Tracer } from '@opentelemetry/api';\nimport { parseLogs, IdlResolver, enrichTree, flatAttributions } from '@thesight/core';\nimport type { AnchorIdl, DecodedError, CpiTree } from '@thesight/core';\n\nexport interface SightConfig {\n /** OTel tracer. Get via trace.getTracer('your-service') */\n tracer?: Tracer;\n /** Override RPC endpoint for IDL fetching (defaults to same as connection) */\n idlRpcEndpoint?: string;\n /** Commitment to use when fetching confirmed tx details */\n commitment?: Commitment;\n /** Skip IDL resolution (faster, no program names or error decoding) */\n skipIdlResolution?: boolean;\n /**\n * Pre-register IDLs at construction time. Keys are program IDs, values are\n * full Anchor IDL objects. Anchor users can pass `program.idl` directly off\n * their `Program` instance — zero setup friction.\n */\n idls?: Record<string, AnchorIdl>;\n /**\n * Opt into reading Anchor IDL accounts from the on-chain PDA as a fallback\n * when a program is not explicitly registered. Defaults to **false** —\n * Sight's model is that IDLs are explicitly provided by the application\n * (via this option or `registerIdl`), not silently guessed from chain.\n */\n allowOnChainIdlFetch?: boolean;\n}\n\nexport interface SightSpanAttributes {\n 'solana.tx.signature': string;\n 'solana.tx.status': 'confirmed' | 'failed' | 'timeout';\n 'solana.tx.slot'?: number;\n 'solana.tx.fee_lamports'?: number;\n 'solana.tx.submit_ms': number;\n 'solana.tx.confirmation_ms'?: number;\n 'solana.tx.enrichment_ms'?: number;\n 'solana.tx.cu_used'?: number;\n 'solana.tx.cu_budget'?: number;\n 'solana.tx.cu_utilization'?: number;\n 'solana.tx.program'?: string;\n 'solana.tx.instruction'?: string;\n 'solana.tx.error'?: string;\n 'solana.tx.error_code'?: number;\n 'solana.tx.error_program'?: string;\n 'solana.tx.error_msg'?: string;\n}\n\n/**\n * Drop-in replacement for @solana/web3.js Connection that instruments\n * every transaction with OpenTelemetry spans.\n *\n * Usage:\n * const connection = new InstrumentedConnection(rpcUrl, {\n * tracer: trace.getTracer('my-service'),\n * });\n *\n * The Solana transaction becomes a child span of whatever OTel context\n * is active when sendAndConfirmTransaction is called — so it automatically\n * nests inside your HTTP handler or background job span.\n */\nexport class InstrumentedConnection extends Connection {\n private sightConfig: SightConfig;\n private idlResolver: IdlResolver;\n private tracer: Tracer;\n\n constructor(endpoint: string, config?: ConnectionConfig & SightConfig) {\n const {\n tracer,\n idlRpcEndpoint,\n skipIdlResolution,\n idls,\n allowOnChainIdlFetch,\n ...connectionConfig\n } = config ?? {};\n super(endpoint, connectionConfig);\n this.sightConfig = { tracer, idlRpcEndpoint, skipIdlResolution, allowOnChainIdlFetch };\n this.idlResolver = new IdlResolver({\n rpcEndpoint: idlRpcEndpoint ?? endpoint,\n allowOnChainFetch: allowOnChainIdlFetch ?? false,\n });\n if (idls) this.idlResolver.registerMany(idls);\n this.tracer = tracer ?? trace.getTracer('@thesight/sdk');\n }\n\n /**\n * Register an IDL for a single program. Convenience forwarder for the\n * underlying resolver. Anchor users typically call this right after\n * constructing a `Program`:\n *\n * const program = new Program(idl, programId, provider);\n * connection.registerIdl(program.programId.toBase58(), program.idl);\n */\n registerIdl(programId: string, idl: AnchorIdl): void {\n this.idlResolver.register(programId, idl);\n }\n\n /** Bulk-register multiple IDLs. */\n registerIdls(idls: Record<string, AnchorIdl>): void {\n this.idlResolver.registerMany(idls);\n }\n\n /**\n * Sends and confirms a transaction, wrapped in an OTel span.\n * The span is a child of the current active context.\n */\n async sendAndConfirmInstrumented(\n transaction: Transaction | VersionedTransaction,\n options?: SendOptions & { commitment?: Commitment },\n ): Promise<{ signature: string; cpiTree?: CpiTree; error?: DecodedError }> {\n const commitment = options?.commitment ?? this.sightConfig.commitment ?? 'confirmed';\n const finality: Finality = commitment === 'processed' ? 'confirmed' : commitment as Finality;\n const span = this.tracer.startSpan('solana.sendAndConfirmTransaction', {}, context.active());\n\n const submitStart = Date.now();\n\n try {\n // Submit the transaction\n const signature = await this.sendRawTransaction(\n 'serialize' in transaction\n ? transaction.serialize()\n : (transaction as VersionedTransaction).serialize(),\n { skipPreflight: false, ...options },\n );\n\n span.setAttribute('solana.tx.signature', signature);\n const submitMs = Date.now() - submitStart;\n span.setAttribute('solana.tx.submit_ms', submitMs);\n\n // Await confirmation\n const confirmStart = Date.now();\n const { value: result } = await this.confirmTransaction(\n { signature, ...(await this.getLatestBlockhash(commitment)) },\n commitment,\n ) as RpcResponseAndContext<SignatureResult>;\n\n const confirmMs = Date.now() - confirmStart;\n span.setAttribute('solana.tx.confirmation_ms', confirmMs);\n\n if (result.err) {\n span.setAttribute('solana.tx.status', 'failed');\n span.setStatus({ code: SpanStatusCode.ERROR });\n\n if (!this.sightConfig.skipIdlResolution) {\n // Enrich error with IDL decoding\n const txDetails = await this.getParsedTransaction(signature, {\n commitment: finality,\n maxSupportedTransactionVersion: 0,\n });\n const accountKeys = txDetails?.transaction.message.accountKeys.map(\n (k: { pubkey?: { toBase58(): string }; toBase58?(): string }) =>\n k.pubkey ? k.pubkey.toBase58() : k.toBase58!()\n ) ?? [];\n const programIds = txDetails?.transaction.message.instructions.map(\n (ix: { programId?: { toBase58(): string }; programIdIndex?: number }) =>\n ix.programId ? ix.programId.toBase58() : accountKeys[ix.programIdIndex!] ?? ''\n ) ?? [];\n\n const decoded = await this.idlResolver.decodeError(\n result.err as never,\n accountKeys,\n programIds,\n );\n\n if (decoded.errorName) {\n span.setAttribute('solana.tx.error', decoded.errorName);\n }\n if (decoded.errorCode !== undefined) {\n span.setAttribute('solana.tx.error_code', decoded.errorCode);\n }\n if (decoded.programName) {\n span.setAttribute('solana.tx.error_program', decoded.programName);\n }\n if (decoded.errorMsg) {\n span.setAttribute('solana.tx.error_msg', decoded.errorMsg);\n }\n\n span.end();\n return { signature, error: decoded };\n }\n\n span.end();\n return { signature };\n }\n\n span.setAttribute('solana.tx.status', 'confirmed');\n\n // Enrich with on-chain details\n if (!this.sightConfig.skipIdlResolution) {\n const enrichStart = Date.now();\n const txDetails = await this.getTransaction(signature, {\n commitment: finality,\n maxSupportedTransactionVersion: 0,\n });\n\n if (txDetails) {\n const slot = txDetails.slot;\n const fee = txDetails.meta?.fee;\n const logs = txDetails.meta?.logMessages ?? [];\n const cuUsed = txDetails.meta?.computeUnitsConsumed;\n\n span.setAttribute('solana.tx.slot', slot);\n if (fee !== undefined) span.setAttribute('solana.tx.fee_lamports', fee);\n if (cuUsed !== undefined) {\n span.setAttribute('solana.tx.cu_used', cuUsed);\n span.setAttribute('solana.tx.cu_budget', 200_000);\n span.setAttribute('solana.tx.cu_utilization', parseFloat((cuUsed / 200_000 * 100).toFixed(1)));\n }\n\n // Parse logs into CPI tree\n const { cpiTree } = parseLogs({ logs });\n\n if (!this.sightConfig.skipIdlResolution) {\n await enrichTree(cpiTree, this.idlResolver);\n }\n\n // Emit one span event per CPI invocation\n const attributions = flatAttributions(cpiTree);\n for (const attr of attributions) {\n span.addEvent('cpi.invoke', {\n 'cpi.program': attr.programName ?? attr.programId,\n 'cpi.instruction': attr.instructionName ?? 'unknown',\n 'cpi.depth': attr.depth,\n 'cpi.cu_consumed': attr.cuConsumed,\n 'cpi.cu_self': attr.cuSelf,\n 'cpi.percentage': parseFloat(attr.percentage.toFixed(2)),\n });\n }\n\n // Top-level instruction info\n const root = cpiTree.roots[0];\n if (root) {\n if (root.programName) span.setAttribute('solana.tx.program', root.programName);\n if (root.instructionName) span.setAttribute('solana.tx.instruction', root.instructionName);\n }\n\n span.setAttribute('solana.tx.enrichment_ms', Date.now() - enrichStart);\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n\n return { signature, cpiTree };\n }\n }\n\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n return { signature };\n\n } catch (err) {\n span.setAttribute('solana.tx.status', 'failed');\n span.setAttribute('solana.tx.submit_ms', Date.now() - submitStart);\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: err instanceof Error ? err.message : String(err),\n });\n span.end();\n throw err;\n }\n }\n}\n\nexport { IdlResolver } from '@thesight/core';\nexport type { CpiTree, CuAttribution, FlamegraphItem, DecodedError, AnchorIdl } from '@thesight/core';\n\n// ─── Tracing initialization ──────────────────────────────────────────────────\n// One-call setup that wires a NodeTracerProvider + SightSpanExporter as the\n// global OTel tracer. After calling initSight, every InstrumentedConnection\n// span routes to Sight ingest automatically — no separate OTel setup needed.\n\nexport { initSight } from './init.js';\nexport type { InitSightConfig, SightTracerHandle } from './init.js';\nexport { SightSpanExporter } from './exporter.js';\nexport type { SightExporterConfig } from './exporter.js';\n","import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';\nimport { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';\nimport { Resource } from '@opentelemetry/resources';\nimport { SEMRESATTRS_SERVICE_NAME, SEMRESATTRS_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';\nimport { SightSpanExporter } from './exporter.js';\n\n// ─── Config ──────────────────────────────────────────────────────────────────\n\nexport interface InitSightConfig {\n /** Project API key (`sk_live_...`) from the Sight dashboard. */\n apiKey: string;\n\n /**\n * Human-readable service name that shows up on every span. Pick something\n * that identifies this process — `'swap-bot'`, `'market-maker'`,\n * `'trade-settler'`, etc.\n */\n serviceName: string;\n\n /** Optional version string for the service. Useful for correlating spans with a deploy. */\n serviceVersion?: string;\n\n /**\n * Full ingest URL. Defaults to the hosted Sight ingest. Override for\n * local development (e.g. `http://localhost:3001/ingest`) or self-hosted\n * deployments.\n */\n ingestUrl?: string;\n\n /** BatchSpanProcessor flush interval, in ms. Defaults to 5s. */\n batchDelayMs?: number;\n\n /** Max spans per HTTP POST. Clamped to 100 by the exporter. */\n maxBatchSize?: number;\n\n /** Inject a fetch implementation for tests. Defaults to global fetch. */\n fetchImpl?: typeof fetch;\n}\n\nexport interface SightTracerHandle {\n provider: NodeTracerProvider;\n /** Flush any pending spans and release the batch processor. */\n shutdown: () => Promise<void>;\n}\n\n// ─── Entry point ────────────────────────────────────────────────────────────\n\nconst DEFAULT_INGEST_URL = 'https://ingest.thesight.dev/ingest';\n\n/**\n * Initialize Sight tracing. Call this **once** near the top of your\n * process entry point — typically in the same file that boots your\n * HTTP server or worker.\n *\n * import { initSight, InstrumentedConnection } from '@thesight/sdk';\n *\n * initSight({\n * apiKey: process.env.SIGHT_API_KEY!,\n * serviceName: 'swap-bot',\n * ingestUrl: process.env.SIGHT_INGEST_URL, // optional, defaults to prod\n * });\n *\n * const connection = new InstrumentedConnection(process.env.RPC_URL!);\n * const { signature } = await connection.sendAndConfirmInstrumented(tx);\n *\n * Registers a NodeTracerProvider as the global OTel tracer, so any call to\n * `trace.getTracer(...)` (including the ones inside `InstrumentedConnection`)\n * routes spans through the Sight exporter. Context propagation uses the\n * Node async hooks manager so spans nest correctly across await boundaries.\n *\n * Returns a handle with a `shutdown()` method. Call it at graceful shutdown\n * time so pending spans are flushed before the process exits:\n *\n * const sight = initSight({ ... });\n * process.on('SIGTERM', async () => {\n * await sight.shutdown();\n * process.exit(0);\n * });\n */\nexport function initSight(config: InitSightConfig): SightTracerHandle {\n if (!config.apiKey) {\n throw new Error('initSight: `apiKey` is required');\n }\n if (!config.serviceName) {\n throw new Error('initSight: `serviceName` is required');\n }\n\n const resource = new Resource({\n [SEMRESATTRS_SERVICE_NAME]: config.serviceName,\n ...(config.serviceVersion\n ? { [SEMRESATTRS_SERVICE_VERSION]: config.serviceVersion }\n : {}),\n });\n\n const provider = new NodeTracerProvider({ resource });\n\n const exporter = new SightSpanExporter({\n apiKey: config.apiKey,\n ingestUrl: config.ingestUrl ?? DEFAULT_INGEST_URL,\n fetchImpl: config.fetchImpl,\n maxBatchSize: config.maxBatchSize,\n });\n\n // BatchSpanProcessor buffers spans and flushes on an interval. This is the\n // right default for production — simple span processor is one HTTP round\n // trip per span, which is fine for tests and dev but nasty at scale.\n const processor = new BatchSpanProcessor(exporter, {\n scheduledDelayMillis: config.batchDelayMs ?? 5_000,\n maxExportBatchSize: config.maxBatchSize ?? 100,\n maxQueueSize: 2048,\n });\n\n provider.addSpanProcessor(processor);\n\n // Register as the global OTel tracer provider. After this call,\n // `trace.getTracer('anything')` returns a tracer from our provider,\n // which routes spans to SightSpanExporter.\n provider.register();\n\n return {\n provider,\n shutdown: async () => {\n await provider.shutdown();\n },\n };\n}\n","import type { SpanAttributes } from '@opentelemetry/api';\nimport type { SpanExporter, ReadableSpan } from '@opentelemetry/sdk-trace-base';\nimport {\n hrTimeToMilliseconds,\n ExportResultCode,\n type ExportResult,\n} from '@opentelemetry/core';\n\n// ─── Config ──────────────────────────────────────────────────────────────────\n\nexport interface SightExporterConfig {\n /** Project API key (`sk_live_...`). Sent as Bearer auth on every POST. */\n apiKey: string;\n /**\n * Full ingest URL including the path (e.g. `https://ingest.thesight.dev/ingest`\n * or `http://localhost:3001/ingest` for local dev).\n */\n ingestUrl: string;\n /** Inject a fake fetch in tests. Defaults to `globalThis.fetch`. */\n fetchImpl?: typeof fetch;\n /** Max spans per POST. Ingest enforces an upper bound of 100. */\n maxBatchSize?: number;\n}\n\n// ─── Exporter ────────────────────────────────────────────────────────────────\n\n/**\n * An OTel `SpanExporter` that translates OTel spans to Sight's custom\n * ingest payload shape and POSTs them to `/ingest`.\n *\n * Each span becomes one object in the `spans` array. Solana-specific\n * attributes flow through as-is (the set that `InstrumentedConnection`\n * already populates — `solana.tx.signature`, `solana.tx.cu_used`,\n * `solana.tx.program`, etc). The exporter intentionally does not attempt\n * to translate span events or links — the ingest schema doesn't have\n * slots for those, and we prefer dropping silently over guessing.\n *\n * The BatchSpanProcessor upstream handles retries, timeouts, and batching;\n * this exporter stays a thin wire-format translator.\n */\nexport class SightSpanExporter implements SpanExporter {\n private readonly apiKey: string;\n private readonly ingestUrl: string;\n private readonly fetchImpl: typeof fetch;\n private readonly maxBatchSize: number;\n private shuttingDown = false;\n\n constructor(config: SightExporterConfig) {\n this.apiKey = config.apiKey;\n this.ingestUrl = config.ingestUrl;\n this.fetchImpl = config.fetchImpl ?? (globalThis.fetch as typeof fetch);\n // Ingest's IngestPayload schema caps at 100 spans per POST. Allow\n // operators to lower the batch size for tighter latency, but never\n // raise it above the server's limit.\n this.maxBatchSize = Math.min(100, config.maxBatchSize ?? 100);\n\n if (!this.fetchImpl) {\n throw new Error(\n 'SightSpanExporter: globalThis.fetch is not available. Node >= 18 ships ' +\n 'with fetch built in, or pass `fetchImpl` explicitly.',\n );\n }\n }\n\n async export(\n spans: ReadableSpan[],\n resultCallback: (result: ExportResult) => void,\n ): Promise<void> {\n if (this.shuttingDown) {\n resultCallback({ code: ExportResultCode.FAILED, error: new Error('Exporter is shut down') });\n return;\n }\n\n // Split into chunks if the upstream processor handed us a larger\n // batch than ingest will accept. Uncommon with a well-configured\n // BatchSpanProcessor but cheap to handle defensively.\n const chunks: ReadableSpan[][] = [];\n for (let i = 0; i < spans.length; i += this.maxBatchSize) {\n chunks.push(spans.slice(i, i + this.maxBatchSize));\n }\n\n try {\n for (const chunk of chunks) {\n await this.sendChunk(chunk);\n }\n resultCallback({ code: ExportResultCode.SUCCESS });\n } catch (err) {\n resultCallback({\n code: ExportResultCode.FAILED,\n error: err instanceof Error ? err : new Error(String(err)),\n });\n }\n }\n\n async shutdown(): Promise<void> {\n this.shuttingDown = true;\n }\n\n async forceFlush(): Promise<void> {\n // The exporter is stateless — BatchSpanProcessor's own forceFlush\n // drains the queue before calling export(). Nothing to do here.\n }\n\n // ─── Internal ──────────────────────────────────────────────────────────────\n\n private async sendChunk(spans: ReadableSpan[]): Promise<void> {\n const payload = {\n spans: spans.map((span) => this.convertSpan(span)),\n };\n\n const response = await this.fetchImpl(this.ingestUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n const body = await safeReadText(response);\n throw new Error(\n `Sight ingest returned ${response.status} ${response.statusText}: ${body}`,\n );\n }\n }\n\n private convertSpan(span: ReadableSpan): IngestSpan {\n const attr = span.attributes;\n const resource = span.resource.attributes;\n const serviceName = typeof resource['service.name'] === 'string'\n ? resource['service.name']\n : undefined;\n const startTimeMs = hrTimeToMilliseconds(span.startTime);\n const endTimeMs = hrTimeToMilliseconds(span.endTime);\n const durationMs = Math.max(0, endTimeMs - startTimeMs);\n\n const out: IngestSpan = {\n traceId: span.spanContext().traceId,\n spanId: span.spanContext().spanId,\n spanName: span.name,\n startTimeMs,\n durationMs,\n };\n\n const parentSpanId = (span as { parentSpanId?: string }).parentSpanId;\n if (parentSpanId) out.parentSpanId = parentSpanId;\n if (serviceName) out.serviceName = serviceName;\n\n copyIfString(attr, 'solana.tx.signature', out);\n copyIfEnum(attr, 'solana.tx.status', out, ['confirmed', 'failed', 'timeout']);\n copyIfNumber(attr, 'solana.tx.slot', out);\n copyIfNumber(attr, 'solana.tx.cu_used', out);\n copyIfNumber(attr, 'solana.tx.cu_budget', out);\n copyIfNumber(attr, 'solana.tx.cu_utilization', out);\n copyIfString(attr, 'solana.tx.program', out);\n copyIfString(attr, 'solana.tx.instruction', out);\n copyIfString(attr, 'solana.tx.error', out);\n copyIfNumber(attr, 'solana.tx.error_code', out);\n copyIfString(attr, 'solana.tx.error_program', out);\n copyIfNumber(attr, 'solana.tx.submit_ms', out);\n copyIfNumber(attr, 'solana.tx.confirmation_ms', out);\n copyIfNumber(attr, 'solana.tx.fee_lamports', out);\n\n return out;\n }\n}\n\n// ─── Wire format (narrow, matches ingest's zod schema) ──────────────────────\n\ninterface IngestSpan {\n traceId: string;\n spanId: string;\n parentSpanId?: string;\n serviceName?: string;\n spanName: string;\n startTimeMs: number;\n durationMs: number;\n\n 'solana.tx.signature'?: string;\n 'solana.tx.status'?: 'confirmed' | 'failed' | 'timeout';\n 'solana.tx.slot'?: number;\n 'solana.tx.cu_used'?: number;\n 'solana.tx.cu_budget'?: number;\n 'solana.tx.cu_utilization'?: number;\n 'solana.tx.program'?: string;\n 'solana.tx.instruction'?: string;\n 'solana.tx.error'?: string;\n 'solana.tx.error_code'?: number;\n 'solana.tx.error_program'?: string;\n 'solana.tx.submit_ms'?: number;\n 'solana.tx.confirmation_ms'?: number;\n 'solana.tx.fee_lamports'?: number;\n}\n\n// ─── Helpers ────────────────────────────────────────────────────────────────\n\nfunction copyIfString(\n attr: SpanAttributes,\n key: keyof IngestSpan & string,\n out: IngestSpan,\n): void {\n const v = attr[key];\n if (typeof v === 'string') {\n (out as unknown as Record<string, unknown>)[key] = v;\n }\n}\n\nfunction copyIfNumber(\n attr: SpanAttributes,\n key: keyof IngestSpan & string,\n out: IngestSpan,\n): void {\n const v = attr[key];\n if (typeof v === 'number' && Number.isFinite(v)) {\n (out as unknown as Record<string, unknown>)[key] = v;\n }\n}\n\nfunction copyIfEnum<T extends string>(\n attr: SpanAttributes,\n key: keyof IngestSpan & string,\n out: IngestSpan,\n allowed: readonly T[],\n): void {\n const v = attr[key];\n if (typeof v === 'string' && (allowed as readonly string[]).includes(v)) {\n (out as unknown as Record<string, unknown>)[key] = v;\n }\n}\n\nasync function safeReadText(res: Response): Promise<string> {\n try {\n return (await res.text()).slice(0, 500);\n } catch {\n return '<no body>';\n }\n}\n"],"mappings":"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","names":["IdlResolver"]}
|