@thesight/sdk 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Rick Dsida
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,123 @@
1
+ # @thesight/sdk
2
+
3
+ **See the truth of your Solana program.**
4
+
5
+ [Sight](https://thesight.dev) is the first OpenTelemetry-native
6
+ observability SDK for Solana. One package install, one `initSight()`
7
+ call, and every transaction becomes a span with per-CPI compute-unit
8
+ attribution, decoded Anchor errors, and full wallet↔RPC↔program
9
+ correlation — consumable by the Sight dashboard or any APM backend
10
+ (Datadog, Grafana, Honeycomb, Tempo).
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ pnpm add @thesight/sdk
16
+ ```
17
+
18
+ All OpenTelemetry dependencies are bundled transitively — you do **not**
19
+ need to `pnpm add @opentelemetry/*` separately.
20
+
21
+ ## Quickstart
22
+
23
+ ```ts
24
+ import { initSight, InstrumentedConnection } from '@thesight/sdk';
25
+ import { clusterApiUrl } from '@solana/web3.js';
26
+
27
+ // Call once near the top of your process entry point
28
+ initSight({
29
+ apiKey: process.env.SIGHT_API_KEY!,
30
+ serviceName: 'my-service',
31
+ });
32
+
33
+ // Drop-in replacement for @solana/web3.js Connection
34
+ const connection = new InstrumentedConnection(clusterApiUrl('mainnet'));
35
+
36
+ // Every confirmed transaction becomes an OTel span routed to Sight ingest
37
+ const { signature, cpiTree } = await connection.sendAndConfirmInstrumented(tx);
38
+ ```
39
+
40
+ `initSight` registers a `NodeTracerProvider` as the global OpenTelemetry
41
+ tracer, installs a batch span processor, and wires a Sight-specific
42
+ exporter that POSTs to ingest in the expected format. Any tracer
43
+ obtained via `trace.getTracer(...)` (including the one
44
+ `InstrumentedConnection` uses internally) routes through the same
45
+ exporter — so if you add OTel instrumentation elsewhere in your app,
46
+ those spans get Sight-correlated for free.
47
+
48
+ ## Anchor IDL registration
49
+
50
+ Sight never guesses program names from chain. Tell it what you know:
51
+
52
+ ```ts
53
+ import { Program } from '@coral-xyz/anchor';
54
+
55
+ const program = new Program(idl, programId, provider);
56
+ connection.registerIdl(program.programId.toBase58(), program.idl);
57
+ ```
58
+
59
+ Or pass a map at init:
60
+
61
+ ```ts
62
+ const connection = new InstrumentedConnection(rpcUrl, {
63
+ idls: {
64
+ [swapProgramId]: swapIdl,
65
+ [lendingProgramId]: lendingIdl,
66
+ },
67
+ });
68
+ ```
69
+
70
+ Unknown programs surface as short-ids in the dashboard rather than
71
+ being fabricated.
72
+
73
+ ## Self-host the ingest
74
+
75
+ By default spans export to `https://ingest.thesight.dev/ingest`.
76
+ Override via `ingestUrl` to point at a self-hosted Sight ingest:
77
+
78
+ ```ts
79
+ initSight({
80
+ apiKey: 'sk_live_...',
81
+ serviceName: 'my-service',
82
+ ingestUrl: 'http://localhost:3001/ingest', // local compose stack
83
+ });
84
+ ```
85
+
86
+ ## What's on the span
87
+
88
+ Every `sendAndConfirmInstrumented` call produces an OTel span with the
89
+ following attributes when they're available:
90
+
91
+ - `solana.tx.signature` — base58 signature
92
+ - `solana.tx.status` — `confirmed` / `failed` / `timeout`
93
+ - `solana.tx.slot`
94
+ - `solana.tx.cu_used` / `solana.tx.cu_budget` / `solana.tx.cu_utilization`
95
+ - `solana.tx.program` — root program name (from registered IDL or
96
+ curated known-programs list)
97
+ - `solana.tx.instruction` — extracted from `Program log: Instruction: …`
98
+ - `solana.tx.error` / `solana.tx.error_code` / `solana.tx.error_program`
99
+ — decoded from on-chain return data via the registered IDL's error
100
+ table or the hardcoded native-error tables
101
+ - `solana.tx.fee_lamports`
102
+ - `solana.tx.submit_ms` / `solana.tx.confirmation_ms` /
103
+ `solana.tx.enrichment_ms` — client-observed latencies
104
+ - Per-CPI `cpi.invoke` events on the span: program, instruction, depth,
105
+ CU consumed, CU self, percentage
106
+
107
+ ## Shutdown
108
+
109
+ Call `shutdown()` on the handle returned by `initSight` at graceful
110
+ shutdown time so pending spans flush before the process exits:
111
+
112
+ ```ts
113
+ const sight = initSight({ apiKey, serviceName });
114
+
115
+ process.on('SIGTERM', async () => {
116
+ await sight.shutdown();
117
+ process.exit(0);
118
+ });
119
+ ```
120
+
121
+ ## License
122
+
123
+ MIT — see `LICENSE`.
@@ -0,0 +1,43 @@
1
+ import type { SpanExporter, ReadableSpan } from '@opentelemetry/sdk-trace-base';
2
+ import { type ExportResult } from '@opentelemetry/core';
3
+ export interface SightExporterConfig {
4
+ /** Project API key (`sk_live_...`). Sent as Bearer auth on every POST. */
5
+ apiKey: string;
6
+ /**
7
+ * Full ingest URL including the path (e.g. `https://ingest.thesight.dev/ingest`
8
+ * or `http://localhost:3001/ingest` for local dev).
9
+ */
10
+ ingestUrl: string;
11
+ /** Inject a fake fetch in tests. Defaults to `globalThis.fetch`. */
12
+ fetchImpl?: typeof fetch;
13
+ /** Max spans per POST. Ingest enforces an upper bound of 100. */
14
+ maxBatchSize?: number;
15
+ }
16
+ /**
17
+ * An OTel `SpanExporter` that translates OTel spans to Sight's custom
18
+ * ingest payload shape and POSTs them to `/ingest`.
19
+ *
20
+ * Each span becomes one object in the `spans` array. Solana-specific
21
+ * attributes flow through as-is (the set that `InstrumentedConnection`
22
+ * already populates — `solana.tx.signature`, `solana.tx.cu_used`,
23
+ * `solana.tx.program`, etc). The exporter intentionally does not attempt
24
+ * to translate span events or links — the ingest schema doesn't have
25
+ * slots for those, and we prefer dropping silently over guessing.
26
+ *
27
+ * The BatchSpanProcessor upstream handles retries, timeouts, and batching;
28
+ * this exporter stays a thin wire-format translator.
29
+ */
30
+ export declare class SightSpanExporter implements SpanExporter {
31
+ private readonly apiKey;
32
+ private readonly ingestUrl;
33
+ private readonly fetchImpl;
34
+ private readonly maxBatchSize;
35
+ private shuttingDown;
36
+ constructor(config: SightExporterConfig);
37
+ export(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): Promise<void>;
38
+ shutdown(): Promise<void>;
39
+ forceFlush(): Promise<void>;
40
+ private sendChunk;
41
+ private convertSpan;
42
+ }
43
+ //# sourceMappingURL=exporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exporter.d.ts","sourceRoot":"","sources":["../src/exporter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,qBAAqB,CAAC;AAI7B,MAAM,WAAW,mBAAmB;IAClC,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAID;;;;;;;;;;;;;GAaG;AACH,qBAAa,iBAAkB,YAAW,YAAY;IACpD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkB;IAC5C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,YAAY,CAAS;gBAEjB,MAAM,EAAE,mBAAmB;IAiBjC,MAAM,CACV,KAAK,EAAW,YAAY,EAAE,EAC9B,cAAc,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GAC7C,OAAO,CAAC,IAAI,CAAC;IA2BV,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAIzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAOnB,SAAS;IAsBvB,OAAO,CAAC,WAAW;CAuCpB"}
@@ -0,0 +1,151 @@
1
+ import { hrTimeToMilliseconds, ExportResultCode, } from '@opentelemetry/core';
2
+ // ─── Exporter ────────────────────────────────────────────────────────────────
3
+ /**
4
+ * An OTel `SpanExporter` that translates OTel spans to Sight's custom
5
+ * ingest payload shape and POSTs them to `/ingest`.
6
+ *
7
+ * Each span becomes one object in the `spans` array. Solana-specific
8
+ * attributes flow through as-is (the set that `InstrumentedConnection`
9
+ * already populates — `solana.tx.signature`, `solana.tx.cu_used`,
10
+ * `solana.tx.program`, etc). The exporter intentionally does not attempt
11
+ * to translate span events or links — the ingest schema doesn't have
12
+ * slots for those, and we prefer dropping silently over guessing.
13
+ *
14
+ * The BatchSpanProcessor upstream handles retries, timeouts, and batching;
15
+ * this exporter stays a thin wire-format translator.
16
+ */
17
+ export class SightSpanExporter {
18
+ apiKey;
19
+ ingestUrl;
20
+ fetchImpl;
21
+ maxBatchSize;
22
+ shuttingDown = false;
23
+ constructor(config) {
24
+ this.apiKey = config.apiKey;
25
+ this.ingestUrl = config.ingestUrl;
26
+ this.fetchImpl = config.fetchImpl ?? globalThis.fetch;
27
+ // Ingest's IngestPayload schema caps at 100 spans per POST. Allow
28
+ // operators to lower the batch size for tighter latency, but never
29
+ // raise it above the server's limit.
30
+ this.maxBatchSize = Math.min(100, config.maxBatchSize ?? 100);
31
+ if (!this.fetchImpl) {
32
+ throw new Error('SightSpanExporter: globalThis.fetch is not available. Node >= 18 ships ' +
33
+ 'with fetch built in, or pass `fetchImpl` explicitly.');
34
+ }
35
+ }
36
+ async export(spans, resultCallback) {
37
+ if (this.shuttingDown) {
38
+ resultCallback({ code: ExportResultCode.FAILED, error: new Error('Exporter is shut down') });
39
+ return;
40
+ }
41
+ // Split into chunks if the upstream processor handed us a larger
42
+ // batch than ingest will accept. Uncommon with a well-configured
43
+ // BatchSpanProcessor but cheap to handle defensively.
44
+ const chunks = [];
45
+ for (let i = 0; i < spans.length; i += this.maxBatchSize) {
46
+ chunks.push(spans.slice(i, i + this.maxBatchSize));
47
+ }
48
+ try {
49
+ for (const chunk of chunks) {
50
+ await this.sendChunk(chunk);
51
+ }
52
+ resultCallback({ code: ExportResultCode.SUCCESS });
53
+ }
54
+ catch (err) {
55
+ resultCallback({
56
+ code: ExportResultCode.FAILED,
57
+ error: err instanceof Error ? err : new Error(String(err)),
58
+ });
59
+ }
60
+ }
61
+ async shutdown() {
62
+ this.shuttingDown = true;
63
+ }
64
+ async forceFlush() {
65
+ // The exporter is stateless — BatchSpanProcessor's own forceFlush
66
+ // drains the queue before calling export(). Nothing to do here.
67
+ }
68
+ // ─── Internal ──────────────────────────────────────────────────────────────
69
+ async sendChunk(spans) {
70
+ const payload = {
71
+ spans: spans.map((span) => this.convertSpan(span)),
72
+ };
73
+ const response = await this.fetchImpl(this.ingestUrl, {
74
+ method: 'POST',
75
+ headers: {
76
+ 'Content-Type': 'application/json',
77
+ 'Authorization': `Bearer ${this.apiKey}`,
78
+ },
79
+ body: JSON.stringify(payload),
80
+ });
81
+ if (!response.ok) {
82
+ const body = await safeReadText(response);
83
+ throw new Error(`Sight ingest returned ${response.status} ${response.statusText}: ${body}`);
84
+ }
85
+ }
86
+ convertSpan(span) {
87
+ const attr = span.attributes;
88
+ const resource = span.resource.attributes;
89
+ const serviceName = typeof resource['service.name'] === 'string'
90
+ ? resource['service.name']
91
+ : undefined;
92
+ const startTimeMs = hrTimeToMilliseconds(span.startTime);
93
+ const endTimeMs = hrTimeToMilliseconds(span.endTime);
94
+ const durationMs = Math.max(0, endTimeMs - startTimeMs);
95
+ const out = {
96
+ traceId: span.spanContext().traceId,
97
+ spanId: span.spanContext().spanId,
98
+ spanName: span.name,
99
+ startTimeMs,
100
+ durationMs,
101
+ };
102
+ const parentSpanId = span.parentSpanId;
103
+ if (parentSpanId)
104
+ out.parentSpanId = parentSpanId;
105
+ if (serviceName)
106
+ out.serviceName = serviceName;
107
+ copyIfString(attr, 'solana.tx.signature', out);
108
+ copyIfEnum(attr, 'solana.tx.status', out, ['confirmed', 'failed', 'timeout']);
109
+ copyIfNumber(attr, 'solana.tx.slot', out);
110
+ copyIfNumber(attr, 'solana.tx.cu_used', out);
111
+ copyIfNumber(attr, 'solana.tx.cu_budget', out);
112
+ copyIfNumber(attr, 'solana.tx.cu_utilization', out);
113
+ copyIfString(attr, 'solana.tx.program', out);
114
+ copyIfString(attr, 'solana.tx.instruction', out);
115
+ copyIfString(attr, 'solana.tx.error', out);
116
+ copyIfNumber(attr, 'solana.tx.error_code', out);
117
+ copyIfString(attr, 'solana.tx.error_program', out);
118
+ copyIfNumber(attr, 'solana.tx.submit_ms', out);
119
+ copyIfNumber(attr, 'solana.tx.confirmation_ms', out);
120
+ copyIfNumber(attr, 'solana.tx.fee_lamports', out);
121
+ return out;
122
+ }
123
+ }
124
+ // ─── Helpers ────────────────────────────────────────────────────────────────
125
+ function copyIfString(attr, key, out) {
126
+ const v = attr[key];
127
+ if (typeof v === 'string') {
128
+ out[key] = v;
129
+ }
130
+ }
131
+ function copyIfNumber(attr, key, out) {
132
+ const v = attr[key];
133
+ if (typeof v === 'number' && Number.isFinite(v)) {
134
+ out[key] = v;
135
+ }
136
+ }
137
+ function copyIfEnum(attr, key, out, allowed) {
138
+ const v = attr[key];
139
+ if (typeof v === 'string' && allowed.includes(v)) {
140
+ out[key] = v;
141
+ }
142
+ }
143
+ async function safeReadText(res) {
144
+ try {
145
+ return (await res.text()).slice(0, 500);
146
+ }
147
+ catch {
148
+ return '<no body>';
149
+ }
150
+ }
151
+ //# sourceMappingURL=exporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exporter.js","sourceRoot":"","sources":["../src/exporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ import { Connection, type ConnectionConfig, type Transaction, type VersionedTransaction, type SendOptions, type Commitment } from '@solana/web3.js';
2
+ import { type Tracer } from '@opentelemetry/api';
3
+ import type { AnchorIdl, DecodedError, CpiTree } from '@thesight/core';
4
+ export interface SightConfig {
5
+ /** OTel tracer. Get via trace.getTracer('your-service') */
6
+ tracer?: Tracer;
7
+ /** Override RPC endpoint for IDL fetching (defaults to same as connection) */
8
+ idlRpcEndpoint?: string;
9
+ /** Commitment to use when fetching confirmed tx details */
10
+ commitment?: Commitment;
11
+ /** Skip IDL resolution (faster, no program names or error decoding) */
12
+ skipIdlResolution?: boolean;
13
+ /**
14
+ * Pre-register IDLs at construction time. Keys are program IDs, values are
15
+ * full Anchor IDL objects. Anchor users can pass `program.idl` directly off
16
+ * their `Program` instance — zero setup friction.
17
+ */
18
+ idls?: Record<string, AnchorIdl>;
19
+ /**
20
+ * Opt into reading Anchor IDL accounts from the on-chain PDA as a fallback
21
+ * when a program is not explicitly registered. Defaults to **false** —
22
+ * Sight's model is that IDLs are explicitly provided by the application
23
+ * (via this option or `registerIdl`), not silently guessed from chain.
24
+ */
25
+ allowOnChainIdlFetch?: boolean;
26
+ }
27
+ export interface SightSpanAttributes {
28
+ 'solana.tx.signature': string;
29
+ 'solana.tx.status': 'confirmed' | 'failed' | 'timeout';
30
+ 'solana.tx.slot'?: number;
31
+ 'solana.tx.fee_lamports'?: number;
32
+ 'solana.tx.submit_ms': number;
33
+ 'solana.tx.confirmation_ms'?: number;
34
+ 'solana.tx.enrichment_ms'?: number;
35
+ 'solana.tx.cu_used'?: number;
36
+ 'solana.tx.cu_budget'?: number;
37
+ 'solana.tx.cu_utilization'?: number;
38
+ 'solana.tx.program'?: string;
39
+ 'solana.tx.instruction'?: string;
40
+ 'solana.tx.error'?: string;
41
+ 'solana.tx.error_code'?: number;
42
+ 'solana.tx.error_program'?: string;
43
+ 'solana.tx.error_msg'?: string;
44
+ }
45
+ /**
46
+ * Drop-in replacement for @solana/web3.js Connection that instruments
47
+ * every transaction with OpenTelemetry spans.
48
+ *
49
+ * Usage:
50
+ * const connection = new InstrumentedConnection(rpcUrl, {
51
+ * tracer: trace.getTracer('my-service'),
52
+ * });
53
+ *
54
+ * The Solana transaction becomes a child span of whatever OTel context
55
+ * is active when sendAndConfirmTransaction is called — so it automatically
56
+ * nests inside your HTTP handler or background job span.
57
+ */
58
+ export declare class InstrumentedConnection extends Connection {
59
+ private sightConfig;
60
+ private idlResolver;
61
+ private tracer;
62
+ constructor(endpoint: string, config?: ConnectionConfig & SightConfig);
63
+ /**
64
+ * Register an IDL for a single program. Convenience forwarder for the
65
+ * underlying resolver. Anchor users typically call this right after
66
+ * constructing a `Program`:
67
+ *
68
+ * const program = new Program(idl, programId, provider);
69
+ * connection.registerIdl(program.programId.toBase58(), program.idl);
70
+ */
71
+ registerIdl(programId: string, idl: AnchorIdl): void;
72
+ /** Bulk-register multiple IDLs. */
73
+ registerIdls(idls: Record<string, AnchorIdl>): void;
74
+ /**
75
+ * Sends and confirms a transaction, wrapped in an OTel span.
76
+ * The span is a child of the current active context.
77
+ */
78
+ sendAndConfirmInstrumented(transaction: Transaction | VersionedTransaction, options?: SendOptions & {
79
+ commitment?: Commitment;
80
+ }): Promise<{
81
+ signature: string;
82
+ cpiTree?: CpiTree;
83
+ error?: DecodedError;
84
+ }>;
85
+ }
86
+ export { IdlResolver } from '@thesight/core';
87
+ export type { CpiTree, CuAttribution, FlamegraphItem, DecodedError, AnchorIdl } from '@thesight/core';
88
+ export { initSight } from './init.js';
89
+ export type { InitSightConfig, SightTracerHandle } from './init.js';
90
+ export { SightSpanExporter } from './exporter.js';
91
+ export type { SightExporterConfig } from './exporter.js';
92
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,175 @@
1
+ import { Connection, } from '@solana/web3.js';
2
+ import { trace, context, SpanStatusCode } from '@opentelemetry/api';
3
+ import { parseLogs, IdlResolver, enrichTree, flatAttributions } from '@thesight/core';
4
+ /**
5
+ * Drop-in replacement for @solana/web3.js Connection that instruments
6
+ * every transaction with OpenTelemetry spans.
7
+ *
8
+ * Usage:
9
+ * const connection = new InstrumentedConnection(rpcUrl, {
10
+ * tracer: trace.getTracer('my-service'),
11
+ * });
12
+ *
13
+ * The Solana transaction becomes a child span of whatever OTel context
14
+ * is active when sendAndConfirmTransaction is called — so it automatically
15
+ * nests inside your HTTP handler or background job span.
16
+ */
17
+ export class InstrumentedConnection extends Connection {
18
+ sightConfig;
19
+ idlResolver;
20
+ tracer;
21
+ constructor(endpoint, config) {
22
+ const { tracer, idlRpcEndpoint, skipIdlResolution, idls, allowOnChainIdlFetch, ...connectionConfig } = config ?? {};
23
+ super(endpoint, connectionConfig);
24
+ this.sightConfig = { tracer, idlRpcEndpoint, skipIdlResolution, allowOnChainIdlFetch };
25
+ this.idlResolver = new IdlResolver({
26
+ rpcEndpoint: idlRpcEndpoint ?? endpoint,
27
+ allowOnChainFetch: allowOnChainIdlFetch ?? false,
28
+ });
29
+ if (idls)
30
+ this.idlResolver.registerMany(idls);
31
+ this.tracer = tracer ?? trace.getTracer('@thesight/sdk');
32
+ }
33
+ /**
34
+ * Register an IDL for a single program. Convenience forwarder for the
35
+ * underlying resolver. Anchor users typically call this right after
36
+ * constructing a `Program`:
37
+ *
38
+ * const program = new Program(idl, programId, provider);
39
+ * connection.registerIdl(program.programId.toBase58(), program.idl);
40
+ */
41
+ registerIdl(programId, idl) {
42
+ this.idlResolver.register(programId, idl);
43
+ }
44
+ /** Bulk-register multiple IDLs. */
45
+ registerIdls(idls) {
46
+ this.idlResolver.registerMany(idls);
47
+ }
48
+ /**
49
+ * Sends and confirms a transaction, wrapped in an OTel span.
50
+ * The span is a child of the current active context.
51
+ */
52
+ async sendAndConfirmInstrumented(transaction, options) {
53
+ const commitment = options?.commitment ?? this.sightConfig.commitment ?? 'confirmed';
54
+ const finality = commitment === 'processed' ? 'confirmed' : commitment;
55
+ const span = this.tracer.startSpan('solana.sendAndConfirmTransaction', {}, context.active());
56
+ const submitStart = Date.now();
57
+ try {
58
+ // Submit the transaction
59
+ const signature = await this.sendRawTransaction('serialize' in transaction
60
+ ? transaction.serialize()
61
+ : transaction.serialize(), { skipPreflight: false, ...options });
62
+ span.setAttribute('solana.tx.signature', signature);
63
+ const submitMs = Date.now() - submitStart;
64
+ span.setAttribute('solana.tx.submit_ms', submitMs);
65
+ // Await confirmation
66
+ const confirmStart = Date.now();
67
+ const { value: result } = await this.confirmTransaction({ signature, ...(await this.getLatestBlockhash(commitment)) }, commitment);
68
+ const confirmMs = Date.now() - confirmStart;
69
+ span.setAttribute('solana.tx.confirmation_ms', confirmMs);
70
+ if (result.err) {
71
+ span.setAttribute('solana.tx.status', 'failed');
72
+ span.setStatus({ code: SpanStatusCode.ERROR });
73
+ if (!this.sightConfig.skipIdlResolution) {
74
+ // Enrich error with IDL decoding
75
+ const txDetails = await this.getParsedTransaction(signature, {
76
+ commitment: finality,
77
+ maxSupportedTransactionVersion: 0,
78
+ });
79
+ const accountKeys = txDetails?.transaction.message.accountKeys.map((k) => k.pubkey ? k.pubkey.toBase58() : k.toBase58()) ?? [];
80
+ const programIds = txDetails?.transaction.message.instructions.map((ix) => ix.programId ? ix.programId.toBase58() : accountKeys[ix.programIdIndex] ?? '') ?? [];
81
+ const decoded = await this.idlResolver.decodeError(result.err, accountKeys, programIds);
82
+ if (decoded.errorName) {
83
+ span.setAttribute('solana.tx.error', decoded.errorName);
84
+ }
85
+ if (decoded.errorCode !== undefined) {
86
+ span.setAttribute('solana.tx.error_code', decoded.errorCode);
87
+ }
88
+ if (decoded.programName) {
89
+ span.setAttribute('solana.tx.error_program', decoded.programName);
90
+ }
91
+ if (decoded.errorMsg) {
92
+ span.setAttribute('solana.tx.error_msg', decoded.errorMsg);
93
+ }
94
+ span.end();
95
+ return { signature, error: decoded };
96
+ }
97
+ span.end();
98
+ return { signature };
99
+ }
100
+ span.setAttribute('solana.tx.status', 'confirmed');
101
+ // Enrich with on-chain details
102
+ if (!this.sightConfig.skipIdlResolution) {
103
+ const enrichStart = Date.now();
104
+ const txDetails = await this.getTransaction(signature, {
105
+ commitment: finality,
106
+ maxSupportedTransactionVersion: 0,
107
+ });
108
+ if (txDetails) {
109
+ const slot = txDetails.slot;
110
+ const fee = txDetails.meta?.fee;
111
+ const logs = txDetails.meta?.logMessages ?? [];
112
+ const cuUsed = txDetails.meta?.computeUnitsConsumed;
113
+ span.setAttribute('solana.tx.slot', slot);
114
+ if (fee !== undefined)
115
+ span.setAttribute('solana.tx.fee_lamports', fee);
116
+ if (cuUsed !== undefined) {
117
+ span.setAttribute('solana.tx.cu_used', cuUsed);
118
+ span.setAttribute('solana.tx.cu_budget', 200_000);
119
+ span.setAttribute('solana.tx.cu_utilization', parseFloat((cuUsed / 200_000 * 100).toFixed(1)));
120
+ }
121
+ // Parse logs into CPI tree
122
+ const { cpiTree } = parseLogs({ logs });
123
+ if (!this.sightConfig.skipIdlResolution) {
124
+ await enrichTree(cpiTree, this.idlResolver);
125
+ }
126
+ // Emit one span event per CPI invocation
127
+ const attributions = flatAttributions(cpiTree);
128
+ for (const attr of attributions) {
129
+ span.addEvent('cpi.invoke', {
130
+ 'cpi.program': attr.programName ?? attr.programId,
131
+ 'cpi.instruction': attr.instructionName ?? 'unknown',
132
+ 'cpi.depth': attr.depth,
133
+ 'cpi.cu_consumed': attr.cuConsumed,
134
+ 'cpi.cu_self': attr.cuSelf,
135
+ 'cpi.percentage': parseFloat(attr.percentage.toFixed(2)),
136
+ });
137
+ }
138
+ // Top-level instruction info
139
+ const root = cpiTree.roots[0];
140
+ if (root) {
141
+ if (root.programName)
142
+ span.setAttribute('solana.tx.program', root.programName);
143
+ if (root.instructionName)
144
+ span.setAttribute('solana.tx.instruction', root.instructionName);
145
+ }
146
+ span.setAttribute('solana.tx.enrichment_ms', Date.now() - enrichStart);
147
+ span.setStatus({ code: SpanStatusCode.OK });
148
+ span.end();
149
+ return { signature, cpiTree };
150
+ }
151
+ }
152
+ span.setStatus({ code: SpanStatusCode.OK });
153
+ span.end();
154
+ return { signature };
155
+ }
156
+ catch (err) {
157
+ span.setAttribute('solana.tx.status', 'failed');
158
+ span.setAttribute('solana.tx.submit_ms', Date.now() - submitStart);
159
+ span.setStatus({
160
+ code: SpanStatusCode.ERROR,
161
+ message: err instanceof Error ? err.message : String(err),
162
+ });
163
+ span.end();
164
+ throw err;
165
+ }
166
+ }
167
+ }
168
+ export { IdlResolver } from '@thesight/core';
169
+ // ─── Tracing initialization ──────────────────────────────────────────────────
170
+ // One-call setup that wires a NodeTracerProvider + SightSpanExporter as the
171
+ // global OTel tracer. After calling initSight, every InstrumentedConnection
172
+ // span routes to Sight ingest automatically — no separate OTel setup needed.
173
+ export { initSight } from './init.js';
174
+ export { SightSpanExporter } from './exporter.js';
175
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/init.d.ts ADDED
@@ -0,0 +1,62 @@
1
+ import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
2
+ export interface InitSightConfig {
3
+ /** Project API key (`sk_live_...`) from the Sight dashboard. */
4
+ apiKey: string;
5
+ /**
6
+ * Human-readable service name that shows up on every span. Pick something
7
+ * that identifies this process — `'swap-bot'`, `'market-maker'`,
8
+ * `'trade-settler'`, etc.
9
+ */
10
+ serviceName: string;
11
+ /** Optional version string for the service. Useful for correlating spans with a deploy. */
12
+ serviceVersion?: string;
13
+ /**
14
+ * Full ingest URL. Defaults to the hosted Sight ingest. Override for
15
+ * local development (e.g. `http://localhost:3001/ingest`) or self-hosted
16
+ * deployments.
17
+ */
18
+ ingestUrl?: string;
19
+ /** BatchSpanProcessor flush interval, in ms. Defaults to 5s. */
20
+ batchDelayMs?: number;
21
+ /** Max spans per HTTP POST. Clamped to 100 by the exporter. */
22
+ maxBatchSize?: number;
23
+ /** Inject a fetch implementation for tests. Defaults to global fetch. */
24
+ fetchImpl?: typeof fetch;
25
+ }
26
+ export interface SightTracerHandle {
27
+ provider: NodeTracerProvider;
28
+ /** Flush any pending spans and release the batch processor. */
29
+ shutdown: () => Promise<void>;
30
+ }
31
+ /**
32
+ * Initialize Sight tracing. Call this **once** near the top of your
33
+ * process entry point — typically in the same file that boots your
34
+ * HTTP server or worker.
35
+ *
36
+ * import { initSight, InstrumentedConnection } from '@thesight/sdk';
37
+ *
38
+ * initSight({
39
+ * apiKey: process.env.SIGHT_API_KEY!,
40
+ * serviceName: 'swap-bot',
41
+ * ingestUrl: process.env.SIGHT_INGEST_URL, // optional, defaults to prod
42
+ * });
43
+ *
44
+ * const connection = new InstrumentedConnection(process.env.RPC_URL!);
45
+ * const { signature } = await connection.sendAndConfirmInstrumented(tx);
46
+ *
47
+ * Registers a NodeTracerProvider as the global OTel tracer, so any call to
48
+ * `trace.getTracer(...)` (including the ones inside `InstrumentedConnection`)
49
+ * routes spans through the Sight exporter. Context propagation uses the
50
+ * Node async hooks manager so spans nest correctly across await boundaries.
51
+ *
52
+ * Returns a handle with a `shutdown()` method. Call it at graceful shutdown
53
+ * time so pending spans are flushed before the process exits:
54
+ *
55
+ * const sight = initSight({ ... });
56
+ * process.on('SIGTERM', async () => {
57
+ * await sight.shutdown();
58
+ * process.exit(0);
59
+ * });
60
+ */
61
+ export declare function initSight(config: InitSightConfig): SightTracerHandle;
62
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAQnE,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB,2FAA2F;IAC3F,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,yEAAyE;IACzE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,iBAAiB,CA8CpE"}
package/dist/init.js ADDED
@@ -0,0 +1,78 @@
1
+ import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
2
+ import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
3
+ import { Resource } from '@opentelemetry/resources';
4
+ import { SEMRESATTRS_SERVICE_NAME, SEMRESATTRS_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';
5
+ import { SightSpanExporter } from './exporter.js';
6
+ // ─── Entry point ────────────────────────────────────────────────────────────
7
+ const DEFAULT_INGEST_URL = 'https://ingest.thesight.dev/ingest';
8
+ /**
9
+ * Initialize Sight tracing. Call this **once** near the top of your
10
+ * process entry point — typically in the same file that boots your
11
+ * HTTP server or worker.
12
+ *
13
+ * import { initSight, InstrumentedConnection } from '@thesight/sdk';
14
+ *
15
+ * initSight({
16
+ * apiKey: process.env.SIGHT_API_KEY!,
17
+ * serviceName: 'swap-bot',
18
+ * ingestUrl: process.env.SIGHT_INGEST_URL, // optional, defaults to prod
19
+ * });
20
+ *
21
+ * const connection = new InstrumentedConnection(process.env.RPC_URL!);
22
+ * const { signature } = await connection.sendAndConfirmInstrumented(tx);
23
+ *
24
+ * Registers a NodeTracerProvider as the global OTel tracer, so any call to
25
+ * `trace.getTracer(...)` (including the ones inside `InstrumentedConnection`)
26
+ * routes spans through the Sight exporter. Context propagation uses the
27
+ * Node async hooks manager so spans nest correctly across await boundaries.
28
+ *
29
+ * Returns a handle with a `shutdown()` method. Call it at graceful shutdown
30
+ * time so pending spans are flushed before the process exits:
31
+ *
32
+ * const sight = initSight({ ... });
33
+ * process.on('SIGTERM', async () => {
34
+ * await sight.shutdown();
35
+ * process.exit(0);
36
+ * });
37
+ */
38
+ export function initSight(config) {
39
+ if (!config.apiKey) {
40
+ throw new Error('initSight: `apiKey` is required');
41
+ }
42
+ if (!config.serviceName) {
43
+ throw new Error('initSight: `serviceName` is required');
44
+ }
45
+ const resource = new Resource({
46
+ [SEMRESATTRS_SERVICE_NAME]: config.serviceName,
47
+ ...(config.serviceVersion
48
+ ? { [SEMRESATTRS_SERVICE_VERSION]: config.serviceVersion }
49
+ : {}),
50
+ });
51
+ const provider = new NodeTracerProvider({ resource });
52
+ const exporter = new SightSpanExporter({
53
+ apiKey: config.apiKey,
54
+ ingestUrl: config.ingestUrl ?? DEFAULT_INGEST_URL,
55
+ fetchImpl: config.fetchImpl,
56
+ maxBatchSize: config.maxBatchSize,
57
+ });
58
+ // BatchSpanProcessor buffers spans and flushes on an interval. This is the
59
+ // right default for production — simple span processor is one HTTP round
60
+ // trip per span, which is fine for tests and dev but nasty at scale.
61
+ const processor = new BatchSpanProcessor(exporter, {
62
+ scheduledDelayMillis: config.batchDelayMs ?? 5_000,
63
+ maxExportBatchSize: config.maxBatchSize ?? 100,
64
+ maxQueueSize: 2048,
65
+ });
66
+ provider.addSpanProcessor(processor);
67
+ // Register as the global OTel tracer provider. After this call,
68
+ // `trace.getTracer('anything')` returns a tracer from our provider,
69
+ // which routes spans to SightSpanExporter.
70
+ provider.register();
71
+ return {
72
+ provider,
73
+ shutdown: async () => {
74
+ await provider.shutdown();
75
+ },
76
+ };
77
+ }
78
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,wBAAwB,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAC5G,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAyClD,+EAA+E;AAE/E,MAAM,kBAAkB,GAAG,oCAAoC,CAAC;AAEhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,UAAU,SAAS,CAAC,MAAuB;IAC/C,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC;QAC5B,CAAC,wBAAwB,CAAC,EAAE,MAAM,CAAC,WAAW;QAC9C,GAAG,CAAC,MAAM,CAAC,cAAc;YACvB,CAAC,CAAC,EAAE,CAAC,2BAA2B,CAAC,EAAE,MAAM,CAAC,cAAc,EAAE;YAC1D,CAAC,CAAC,EAAE,CAAC;KACR,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,IAAI,kBAAkB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IAEtD,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC;QACrC,MAAM,EAAQ,MAAM,CAAC,MAAM;QAC3B,SAAS,EAAK,MAAM,CAAC,SAAS,IAAI,kBAAkB;QACpD,SAAS,EAAK,MAAM,CAAC,SAAS;QAC9B,YAAY,EAAE,MAAM,CAAC,YAAY;KAClC,CAAC,CAAC;IAEH,2EAA2E;IAC3E,yEAAyE;IACzE,qEAAqE;IACrE,MAAM,SAAS,GAAG,IAAI,kBAAkB,CAAC,QAAQ,EAAE;QACjD,oBAAoB,EAAE,MAAM,CAAC,YAAY,IAAI,KAAK;QAClD,kBAAkB,EAAI,MAAM,CAAC,YAAY,IAAI,GAAG;QAChD,YAAY,EAAU,IAAI;KAC3B,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAErC,gEAAgE;IAChE,oEAAoE;IACpE,2CAA2C;IAC3C,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAEpB,OAAO;QACL,QAAQ;QACR,QAAQ,EAAE,KAAK,IAAI,EAAE;YACnB,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC;KACF,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@thesight/sdk",
3
+ "version": "0.1.0",
4
+ "description": "Sight SDK — OpenTelemetry-native observability for Solana. One call (initSight) wires a NodeTracerProvider + Sight exporter, then InstrumentedConnection turns every transaction into a span with per-CPI compute-unit attribution, decoded Anchor errors, and wallet-to-program correlation.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
19
+ "author": "Rick Dsida <rick@dsida.us>",
20
+ "license": "MIT",
21
+ "homepage": "https://thesight.dev",
22
+ "keywords": [
23
+ "solana",
24
+ "opentelemetry",
25
+ "otel",
26
+ "observability",
27
+ "distributed-tracing",
28
+ "compute-units",
29
+ "cpi",
30
+ "anchor",
31
+ "apm",
32
+ "sight",
33
+ "thesight"
34
+ ],
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "dependencies": {
39
+ "@thesight/core": "^0.1.0",
40
+ "@solana/web3.js": "^1.95.0",
41
+ "@opentelemetry/api": "^1.8.0",
42
+ "@opentelemetry/core": "^1.24.0",
43
+ "@opentelemetry/resources": "^1.24.0",
44
+ "@opentelemetry/sdk-trace-base": "^1.24.0",
45
+ "@opentelemetry/sdk-trace-node": "^1.24.0",
46
+ "@opentelemetry/semantic-conventions": "^1.24.0"
47
+ },
48
+ "scripts": {
49
+ "build": "tsc -p tsconfig.json",
50
+ "test": "vitest run",
51
+ "dev": "tsc -p tsconfig.json --watch"
52
+ }
53
+ }