solana-resilience-kit 1.0.2 → 1.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/README.md +60 -2
- package/package.json +12 -2
package/README.md
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/solana-resilience-kit)
|
|
4
4
|
[](https://www.npmjs.com/package/solana-resilience-kit)
|
|
5
5
|
[](https://www.npmjs.com/package/solana-resilience-kit)
|
|
6
|
+
[](./.github/workflows/ci.yml)
|
|
6
7
|
[](./LICENSE)
|
|
7
8
|
|
|
8
9
|
A vendor-neutral, **client-side resilience and observability layer for Solana dApps**, built on `@solana/kit` (web3.js v2). It unifies the reliability work that is today either left as a do-it-yourself recipe by the official SDK or locked inside a single provider: health-aware multi-RPC failover, a correct transaction send/confirm state machine, simulate-based fee/CU estimation, Jito/MEV routing with automatic RPC fallback, and standardized OpenTelemetry/Datadog telemetry — behind one clean API that works on top of any set of providers.
|
|
@@ -99,7 +100,7 @@ The pool exposes a real `@solana/kit` `RpcTransport`, so callers build a normal
|
|
|
99
100
|
npm install solana-resilience-kit @solana/kit
|
|
100
101
|
```
|
|
101
102
|
|
|
102
|
-
Requires Node ≥ 20. The package is ESM-only and ships compiled JS with type declarations.
|
|
103
|
+
Requires Node ≥ 20. The package is ESM-only and ships compiled JS with type declarations. **`@solana/kit` is a required peer dependency** (`^6.9.0`): install it alongside so your app and the SDK resolve to a *single* kit instance — this keeps kit's branded types (`Address`, `Signature`, `Base64EncodedWireTransaction`, …) compatible across the boundary. `@opentelemetry/api` is an **optional** peer, needed only if you use `OtelMetrics` (and is already pulled in transitively by the OpenTelemetry SDK packages — see [Wiring observability to OpenTelemetry / Datadog](#wiring-observability-to-opentelemetry--datadog)).
|
|
103
104
|
|
|
104
105
|
## Quickstart
|
|
105
106
|
|
|
@@ -193,6 +194,63 @@ expired transaction) · `2` a usage error. Run with no command, `help`, or
|
|
|
193
194
|
`--help` to print usage. The argv parser is a pure, network-free function and is
|
|
194
195
|
unit-tested in isolation (`test/cli/argv.test.ts`).
|
|
195
196
|
|
|
197
|
+
## Wiring observability to OpenTelemetry / Datadog
|
|
198
|
+
|
|
199
|
+
The library depends on **only `@opentelemetry/api`** — `OtelMetrics` writes to the
|
|
200
|
+
*global* OpenTelemetry meter, which is a **no-op until your app registers a real
|
|
201
|
+
`MeterProvider`** with a reader + exporter. The OTel SDK and OTLP exporter are
|
|
202
|
+
your application's dependencies, not the SDK's, so you choose the backend. The
|
|
203
|
+
~10 lines that make exports real:
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
import { metrics } from "@opentelemetry/api";
|
|
207
|
+
import { MeterProvider, PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
|
|
208
|
+
import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
|
|
209
|
+
import { OtelMetrics, ResilientRpcPool } from "solana-resilience-kit";
|
|
210
|
+
|
|
211
|
+
// 1. Register a working MeterProvider — without this, OtelMetrics is inert.
|
|
212
|
+
metrics.setGlobalMeterProvider(
|
|
213
|
+
new MeterProvider({
|
|
214
|
+
readers: [
|
|
215
|
+
new PeriodicExportingMetricReader({
|
|
216
|
+
// Reads OTEL_EXPORTER_OTLP_ENDPOINT, e.g. an OTel Collector or the
|
|
217
|
+
// Datadog Agent's OTLP intake (http://localhost:4318).
|
|
218
|
+
exporter: new OTLPMetricExporter(),
|
|
219
|
+
exportIntervalMillis: 10_000,
|
|
220
|
+
}),
|
|
221
|
+
],
|
|
222
|
+
}),
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
// 2. Hand OtelMetrics to the SDK — now every signal below is exported.
|
|
226
|
+
const pool = new ResilientRpcPool({ endpoints, metrics: new OtelMetrics({ serviceName: "my-dapp" }) });
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Install the exporter side in your app (devtime/runtime, not in this library):
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
npm install @opentelemetry/sdk-metrics @opentelemetry/exporter-metrics-otlp-http
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**For Datadog**, point `OTEL_EXPORTER_OTLP_ENDPOINT` at the Datadog Agent's OTLP
|
|
236
|
+
endpoint (enable OTLP ingestion in the Agent); no separate Collector needed.
|
|
237
|
+
|
|
238
|
+
The SDK emits a small, fixed set of client-side instruments:
|
|
239
|
+
|
|
240
|
+
| Instrument | Type | Attributes | Emitted when |
|
|
241
|
+
|---|---|---|---|
|
|
242
|
+
| `rpc.request.latency_ms` | histogram | `endpoint`, `method`, `ok` | every RPC request attempt (per endpoint) |
|
|
243
|
+
| `rpc.request.failures` | counter | `endpoint`, `method` | a request attempt fails |
|
|
244
|
+
| `rpc.rate_limited` | counter | `endpoint` | an attempt is rejected with HTTP 429 |
|
|
245
|
+
| `tx.rebroadcasts` | counter | `signature` | the sender rebroadcasts the signed transaction |
|
|
246
|
+
| `tx.landings` | counter | `signature`, `outcome`, `slots` | a transaction reaches a terminal outcome (`confirmed` / `expired`) |
|
|
247
|
+
| `rpc.endpoint.slot` | gauge | `endpoint` | a `getSlot` response is observed (slot-lag dashboards) |
|
|
248
|
+
|
|
249
|
+
A runnable end-to-end demo is in [`examples/otel-setup.ts`](./examples/otel-setup.ts):
|
|
250
|
+
`npm run example:otel` wires `OtelMetrics` into a pool + sender, drives simulated
|
|
251
|
+
sends against the harness, and exports all six instruments — with a console
|
|
252
|
+
exporter attached so you see every data point even without a collector running.
|
|
253
|
+
|
|
196
254
|
## Testing your own code against the fault harness
|
|
197
255
|
|
|
198
256
|
The deterministic Solana cluster simulator the SDK is tested with is shipped as a
|
|
@@ -239,7 +297,7 @@ npm run test:cov # coverage with the thresholds enforced
|
|
|
239
297
|
npm run typecheck # tsc --noEmit
|
|
240
298
|
```
|
|
241
299
|
|
|
242
|
-
Coverage thresholds (`vitest.config.ts`) are **lines 90 / functions 90 / branches 85 / statements 90**, and the suite passes them. A fully reproducible Docker environment is available via the [`Makefile`](./Makefile):
|
|
300
|
+
Coverage thresholds (`vitest.config.ts`) are **lines 90 / functions 90 / branches 85 / statements 90**, and the suite passes them. **CI enforces this gate on every push and PR** — the `docker compose run --rm cov` step in [`ci.yml`](./.github/workflows/ci.yml) runs `npm run test:cov`, which exits non-zero (failing the build) if coverage drops below those thresholds. A fully reproducible Docker environment is available via the [`Makefile`](./Makefile):
|
|
243
301
|
|
|
244
302
|
```bash
|
|
245
303
|
make verify # typecheck + always-green harness/metrics tests, in Docker
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "solana-resilience-kit",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Vendor-neutral, client-side resilience and observability layer for Solana dApps, built on @solana/kit (web3.js v2).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -58,14 +58,24 @@
|
|
|
58
58
|
"test:cov": "vitest run --coverage",
|
|
59
59
|
"typecheck": "tsc --noEmit",
|
|
60
60
|
"docs:api": "typedoc",
|
|
61
|
+
"example:otel": "tsx examples/otel-setup.ts",
|
|
61
62
|
"prepublishOnly": "npm run typecheck && npm test && npm run build"
|
|
62
63
|
},
|
|
63
|
-
"
|
|
64
|
+
"peerDependencies": {
|
|
64
65
|
"@opentelemetry/api": "^1.9.0",
|
|
65
66
|
"@solana/kit": "^6.9.0"
|
|
66
67
|
},
|
|
68
|
+
"peerDependenciesMeta": {
|
|
69
|
+
"@opentelemetry/api": {
|
|
70
|
+
"optional": true
|
|
71
|
+
}
|
|
72
|
+
},
|
|
67
73
|
"devDependencies": {
|
|
74
|
+
"@opentelemetry/api": "^1.9.0",
|
|
75
|
+
"@opentelemetry/exporter-metrics-otlp-http": "^0.219.0",
|
|
76
|
+
"@opentelemetry/sdk-metrics": "^2.8.0",
|
|
68
77
|
"@solana-program/system": "^0.12.2",
|
|
78
|
+
"@solana/kit": "^6.9.0",
|
|
69
79
|
"@types/node": "^22.19.21",
|
|
70
80
|
"@vitest/coverage-v8": "^4.1.9",
|
|
71
81
|
"tsx": "^4.22.4",
|