s0racle-sdk 0.0.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/README.md +139 -0
- package/dist/index.d.mts +182 -0
- package/dist/index.d.ts +182 -0
- package/dist/index.js +2192 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2147 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +55 -0
package/README.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# s0racle-sdk
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="https://avatars.githubusercontent.com/u/288873784?s=200&v=4" alt="s0racle" width="120" />
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
TypeScript SDK for reading live Solana network health from the s0racle oracle.
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT License" />
|
|
13
|
+
<img src="https://img.shields.io/badge/Solana-devnet-9945FF?logo=solana" alt="Solana devnet" />
|
|
14
|
+
<img src="https://img.shields.io/badge/npm-0.1.0-CB3837?logo=npm" alt="npm 0.1.0" />
|
|
15
|
+
<img src="https://img.shields.io/badge/TypeScript-5.x-3178C6?logo=typescript" alt="TypeScript" />
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Overview
|
|
21
|
+
|
|
22
|
+
s0racle publishes live Solana network health on-chain — validator reachability, slot latency, client diversity, and stake-weighted reach — aggregated from distributed observer nodes across multiple regions.
|
|
23
|
+
|
|
24
|
+
This SDK gives you a clean TypeScript interface to read that data. One function call, typed response, no Anchor boilerplate, no manual PDA derivation.
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install s0racle-sdk @solana/web3.js
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Quick Start
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { Connection } from "@solana/web3.js";
|
|
36
|
+
import { createS0racleClient } from "s0racle-sdk";
|
|
37
|
+
|
|
38
|
+
const connection = new Connection("https://api.devnet.solana.com");
|
|
39
|
+
const client = createS0racleClient({ connection });
|
|
40
|
+
|
|
41
|
+
const health = await client.getNetworkHealth();
|
|
42
|
+
|
|
43
|
+
console.log(health.healthScore); // 0–100
|
|
44
|
+
console.log(health.tpuReachabilityPct); // % validators reachable right now
|
|
45
|
+
console.log(health.avgSlotLatencyMs); // how far behind is the network
|
|
46
|
+
console.log(health.agaveCount, health.firedancerCount, health.jitoCount);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Stake-Weighted Reach & Client Diversity
|
|
50
|
+
|
|
51
|
+
Raw validator counts don't tell the full story. s0racle weights reachability by stake and tracks which clients are running — so you know if the network can actually finalize, not just respond.
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { isConsensusCritical, stakeReachStatus, clientDiversityIndex } from "s0racle-sdk";
|
|
55
|
+
|
|
56
|
+
for (const region of health.regionScores) {
|
|
57
|
+
if (region.observerCount === 0) continue;
|
|
58
|
+
|
|
59
|
+
console.log(stakeReachStatus(region.reachableStakePct)); // healthy | degraded | critical
|
|
60
|
+
console.log(clientDiversityIndex(region)); // 0 = monoculture, 100 = perfectly even
|
|
61
|
+
|
|
62
|
+
if (isConsensusCritical(region.reachableStakePct)) {
|
|
63
|
+
// under 67% stake reachable — network cannot finalize
|
|
64
|
+
// pause writes, widen spreads, or alert users
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Thresholds: `>= 80%` healthy · `>= 67%` degraded · `< 67%` critical
|
|
70
|
+
|
|
71
|
+
## Health Score
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
healthScore = (reachabilityPct × 70%) + (latencyScore × 30%)
|
|
75
|
+
latencyScore = max(0, (400 - slotLatencyMs) × 100 / 400)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Reachability is weighted higher because a degraded but reachable network can still process transactions — an unreachable one cannot.
|
|
79
|
+
|
|
80
|
+
## API
|
|
81
|
+
|
|
82
|
+
### `createS0racleClient(options)`
|
|
83
|
+
|
|
84
|
+
| Option | Type | Default |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| `connection` | `Connection` | required |
|
|
87
|
+
| `programId` | `PublicKey` | s0racle devnet address |
|
|
88
|
+
| `wallet` | `Wallet` | read-only by default |
|
|
89
|
+
|
|
90
|
+
### Read methods
|
|
91
|
+
|
|
92
|
+
| Method | Returns |
|
|
93
|
+
|---|---|
|
|
94
|
+
| `getNetworkHealth()` | `Promise<NetworkHealth>` |
|
|
95
|
+
| `getRegistry()` | `Promise<Registry>` |
|
|
96
|
+
| `getObserver(pubkey)` | `Promise<Observer>` |
|
|
97
|
+
| `getAllObservers()` | `Promise<Observer[]>` |
|
|
98
|
+
| `getObserversByRegion(region)` | `Promise<Observer[]>` |
|
|
99
|
+
|
|
100
|
+
### Utility helpers
|
|
101
|
+
|
|
102
|
+
| Function | What it does |
|
|
103
|
+
|---|---|
|
|
104
|
+
| `healthStatus(health)` | `"healthy"` · `"degraded"` · `"critical"` |
|
|
105
|
+
| `isStale(health, slot)` | True if data is older than 150 slots |
|
|
106
|
+
| `isDegraded(health)` | True if score below 70 |
|
|
107
|
+
| `isConsensusCritical(pct)` | True if stake reach below 67% |
|
|
108
|
+
| `stakeReachStatus(pct)` | Threshold label for stake reach |
|
|
109
|
+
| `dominantClient(region)` | Which client runs most validators here |
|
|
110
|
+
| `clientDiversityIndex(region)` | 0–100 diversity score |
|
|
111
|
+
| `regionLabel(region)` | Human readable region name |
|
|
112
|
+
|
|
113
|
+
### Regions
|
|
114
|
+
|
|
115
|
+
`Asia` · `US` · `EU` · `SouthAmerica` · `Africa` · `Oceania` · `Other`
|
|
116
|
+
|
|
117
|
+
## Examples
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
cd examples
|
|
121
|
+
npm install
|
|
122
|
+
npm run read # fetch and print NetworkHealth
|
|
123
|
+
npm run observers # list observers by region
|
|
124
|
+
npm run diversity # stake-weighted consensus check
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Status
|
|
128
|
+
|
|
129
|
+
Early development — API may change before `1.0.0`.
|
|
130
|
+
|
|
131
|
+
Program ID (devnet): `2paXpX8Ze3tvYezviSwQJSSihG3LbrDiD7SNsaFwgTow`
|
|
132
|
+
|
|
133
|
+
## Links
|
|
134
|
+
|
|
135
|
+
GitHub: [github.com/s0racle](https://github.com/s0racle)
|
|
136
|
+
|
|
137
|
+
## License
|
|
138
|
+
|
|
139
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { PublicKey, Connection, TransactionInstruction } from '@solana/web3.js';
|
|
2
|
+
import { Wallet } from '@coral-xyz/anchor';
|
|
3
|
+
|
|
4
|
+
declare enum Region {
|
|
5
|
+
Asia = "Asia",
|
|
6
|
+
US = "US",
|
|
7
|
+
EU = "EU",
|
|
8
|
+
SouthAmerica = "SouthAmerica",
|
|
9
|
+
Africa = "Africa",
|
|
10
|
+
Oceania = "Oceania",
|
|
11
|
+
Other = "Other"
|
|
12
|
+
}
|
|
13
|
+
interface Attestation {
|
|
14
|
+
slot: bigint;
|
|
15
|
+
timestamp: bigint;
|
|
16
|
+
avgRttUs: number;
|
|
17
|
+
p95RttUs: number;
|
|
18
|
+
slotLatencyMs: number;
|
|
19
|
+
tpuReachable: number;
|
|
20
|
+
tpuProbed: number;
|
|
21
|
+
agaveCount: number;
|
|
22
|
+
firedancerCount: number;
|
|
23
|
+
jitoCount: number;
|
|
24
|
+
solanaLabsCount: number;
|
|
25
|
+
otherCount: number;
|
|
26
|
+
reachableStakePct: number;
|
|
27
|
+
}
|
|
28
|
+
interface RegionScore {
|
|
29
|
+
region: Region;
|
|
30
|
+
observerCount: number;
|
|
31
|
+
healthScore: number;
|
|
32
|
+
reachabilityPct: number;
|
|
33
|
+
avgRttUs: number;
|
|
34
|
+
slotLatencyMs: number;
|
|
35
|
+
lastUpdatedSlot: bigint;
|
|
36
|
+
agaveCount: number;
|
|
37
|
+
firedancerCount: number;
|
|
38
|
+
jitoCount: number;
|
|
39
|
+
solanaLabsCount: number;
|
|
40
|
+
otherCount: number;
|
|
41
|
+
reachableStakePct: number;
|
|
42
|
+
}
|
|
43
|
+
interface NetworkHealth {
|
|
44
|
+
healthScore: number;
|
|
45
|
+
tpuReachabilityPct: number;
|
|
46
|
+
avgSlotLatencyMs: number;
|
|
47
|
+
activeObserverCount: number;
|
|
48
|
+
activeRegionCount: number;
|
|
49
|
+
lastUpdatedSlot: bigint;
|
|
50
|
+
lastUpdatedTs: bigint;
|
|
51
|
+
minHealthEver: number | null;
|
|
52
|
+
maxHealthEver: number;
|
|
53
|
+
totalAttestations: bigint;
|
|
54
|
+
regionScores: RegionScore[];
|
|
55
|
+
agaveCount: number;
|
|
56
|
+
firedancerCount: number;
|
|
57
|
+
jitoCount: number;
|
|
58
|
+
solanaLabsCount: number;
|
|
59
|
+
otherCount: number;
|
|
60
|
+
}
|
|
61
|
+
interface Observer {
|
|
62
|
+
publicKey: PublicKey;
|
|
63
|
+
authority: PublicKey;
|
|
64
|
+
region: Region;
|
|
65
|
+
stakeLamports: bigint;
|
|
66
|
+
registeredAt: bigint;
|
|
67
|
+
lastAttestationSlot: bigint;
|
|
68
|
+
attestationCount: bigint;
|
|
69
|
+
latestAttestation: Attestation;
|
|
70
|
+
isActive: boolean;
|
|
71
|
+
}
|
|
72
|
+
interface Registry {
|
|
73
|
+
authority: PublicKey;
|
|
74
|
+
pendingAuthority: PublicKey | null;
|
|
75
|
+
minStakeLamports: bigint;
|
|
76
|
+
observerCount: number;
|
|
77
|
+
activeCount: number;
|
|
78
|
+
maxObservers: number;
|
|
79
|
+
paused: boolean;
|
|
80
|
+
version: number;
|
|
81
|
+
}
|
|
82
|
+
interface AttestationSubmittedEvent {
|
|
83
|
+
observer: PublicKey;
|
|
84
|
+
region: Region;
|
|
85
|
+
score: number;
|
|
86
|
+
reachabilityPct: number;
|
|
87
|
+
slotLatencyMs: number;
|
|
88
|
+
slot: bigint;
|
|
89
|
+
agaveCount: number;
|
|
90
|
+
firedancerCount: number;
|
|
91
|
+
jitoCount: number;
|
|
92
|
+
solanaLabsCount: number;
|
|
93
|
+
otherCount: number;
|
|
94
|
+
reachableStakePct: number;
|
|
95
|
+
}
|
|
96
|
+
interface ObserverRegisteredEvent {
|
|
97
|
+
observer: PublicKey;
|
|
98
|
+
region: Region;
|
|
99
|
+
stakeLamports: bigint;
|
|
100
|
+
}
|
|
101
|
+
interface ObserverDeregisteredEvent {
|
|
102
|
+
observer: PublicKey;
|
|
103
|
+
}
|
|
104
|
+
interface ObserverSlashedEvent {
|
|
105
|
+
observer: PublicKey;
|
|
106
|
+
slashBps: number;
|
|
107
|
+
amountSlashed: bigint;
|
|
108
|
+
}
|
|
109
|
+
interface ConfigUpdatedEvent {
|
|
110
|
+
minStakeLamports: bigint | null;
|
|
111
|
+
maxObservers: number | null;
|
|
112
|
+
paused: boolean | null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
declare const PROGRAM_ID: PublicKey;
|
|
116
|
+
declare function getRegistryPDA(programId?: PublicKey): [PublicKey, number];
|
|
117
|
+
declare function getNetworkHealthPDA(programId?: PublicKey): [PublicKey, number];
|
|
118
|
+
declare function getObserverPDA(observer: PublicKey, programId?: PublicKey): [PublicKey, number];
|
|
119
|
+
|
|
120
|
+
interface SubmitAttestationParams {
|
|
121
|
+
tpuReachable: number;
|
|
122
|
+
tpuProbed: number;
|
|
123
|
+
avgRttUs: number;
|
|
124
|
+
p95RttUs: number;
|
|
125
|
+
slotLatencyMs: number;
|
|
126
|
+
agaveCount: number;
|
|
127
|
+
firedancerCount: number;
|
|
128
|
+
jitoCount: number;
|
|
129
|
+
solanaLabsCount: number;
|
|
130
|
+
otherCount: number;
|
|
131
|
+
reachableStakePct: number;
|
|
132
|
+
}
|
|
133
|
+
interface UpdateConfigParams {
|
|
134
|
+
minStakeLamports: bigint | null;
|
|
135
|
+
maxObservers: number | null;
|
|
136
|
+
paused: boolean | null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
interface S0racleClientOptions {
|
|
140
|
+
connection: Connection;
|
|
141
|
+
programId?: PublicKey;
|
|
142
|
+
wallet?: Wallet;
|
|
143
|
+
}
|
|
144
|
+
interface S0racleClient {
|
|
145
|
+
readonly programId: PublicKey;
|
|
146
|
+
readonly connection: Connection;
|
|
147
|
+
getNetworkHealth(): Promise<NetworkHealth>;
|
|
148
|
+
getRegistry(): Promise<Registry>;
|
|
149
|
+
getObserver(observerPubkey: PublicKey): Promise<Observer>;
|
|
150
|
+
getAllObservers(): Promise<Observer[]>;
|
|
151
|
+
getObserversByRegion(region: Region): Promise<Observer[]>;
|
|
152
|
+
registerObserver(observer: PublicKey, region: Region): Promise<TransactionInstruction>;
|
|
153
|
+
submitAttestation(authority: PublicKey, params: SubmitAttestationParams): Promise<TransactionInstruction>;
|
|
154
|
+
deregisterObserver(caller: PublicKey, observerWallet: PublicKey): Promise<TransactionInstruction>;
|
|
155
|
+
crankAggregation(cranker: PublicKey, observerAccounts: PublicKey[]): Promise<TransactionInstruction>;
|
|
156
|
+
initialize(authority: PublicKey, minStakeLamports: bigint, maxObservers: number): Promise<TransactionInstruction>;
|
|
157
|
+
slashObserver(authority: PublicKey, observerWallet: PublicKey, treasury: PublicKey, slashBps: number): Promise<TransactionInstruction>;
|
|
158
|
+
updateConfig(authority: PublicKey, params: UpdateConfigParams): Promise<TransactionInstruction>;
|
|
159
|
+
proposeAuthority(authority: PublicKey, newAuthority: PublicKey): Promise<TransactionInstruction>;
|
|
160
|
+
acceptAuthority(newAuthority: PublicKey): Promise<TransactionInstruction>;
|
|
161
|
+
onAttestationSubmitted(callback: (event: AttestationSubmittedEvent, slot: number) => void): number;
|
|
162
|
+
onObserverRegistered(callback: (event: ObserverRegisteredEvent, slot: number) => void): number;
|
|
163
|
+
onObserverDeregistered(callback: (event: ObserverDeregisteredEvent, slot: number) => void): number;
|
|
164
|
+
onObserverSlashed(callback: (event: ObserverSlashedEvent, slot: number) => void): number;
|
|
165
|
+
onConfigUpdated(callback: (event: ConfigUpdatedEvent, slot: number) => void): number;
|
|
166
|
+
removeEventListener(listenerId: number): Promise<void>;
|
|
167
|
+
}
|
|
168
|
+
declare function createS0racleClient(opts: S0racleClientOptions): S0racleClient;
|
|
169
|
+
|
|
170
|
+
declare function isStale(networkHealth: NetworkHealth, currentSlot: bigint): boolean;
|
|
171
|
+
declare function isObserverStale(observer: Observer, currentSlot: bigint): boolean;
|
|
172
|
+
declare function isDegraded(networkHealth: NetworkHealth, threshold?: number): boolean;
|
|
173
|
+
declare function healthStatus(networkHealth: NetworkHealth, currentSlot?: bigint): "healthy" | "degraded" | "critical" | "stale";
|
|
174
|
+
declare function regionLabel(region: Region): string;
|
|
175
|
+
declare function lamportsToSol(lamports: bigint): number;
|
|
176
|
+
declare function latencyScore(slotLatencyMs: number): number;
|
|
177
|
+
declare function isConsensusCritical(reachableStakePct: number): boolean;
|
|
178
|
+
declare function stakeReachStatus(reachableStakePct: number): "healthy" | "degraded" | "critical";
|
|
179
|
+
declare function dominantClient(region: RegionScore): "agave" | "firedancer" | "jito" | "other";
|
|
180
|
+
declare function clientDiversityIndex(region: RegionScore): number;
|
|
181
|
+
|
|
182
|
+
export { type Attestation, type AttestationSubmittedEvent, type ConfigUpdatedEvent, type NetworkHealth, type Observer, type ObserverDeregisteredEvent, type ObserverRegisteredEvent, type ObserverSlashedEvent, PROGRAM_ID, Region, type RegionScore, type Registry, type S0racleClient, type S0racleClientOptions, type SubmitAttestationParams, type UpdateConfigParams, clientDiversityIndex, createS0racleClient, dominantClient, getNetworkHealthPDA, getObserverPDA, getRegistryPDA, healthStatus, isConsensusCritical, isDegraded, isObserverStale, isStale, lamportsToSol, latencyScore, regionLabel, stakeReachStatus };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { PublicKey, Connection, TransactionInstruction } from '@solana/web3.js';
|
|
2
|
+
import { Wallet } from '@coral-xyz/anchor';
|
|
3
|
+
|
|
4
|
+
declare enum Region {
|
|
5
|
+
Asia = "Asia",
|
|
6
|
+
US = "US",
|
|
7
|
+
EU = "EU",
|
|
8
|
+
SouthAmerica = "SouthAmerica",
|
|
9
|
+
Africa = "Africa",
|
|
10
|
+
Oceania = "Oceania",
|
|
11
|
+
Other = "Other"
|
|
12
|
+
}
|
|
13
|
+
interface Attestation {
|
|
14
|
+
slot: bigint;
|
|
15
|
+
timestamp: bigint;
|
|
16
|
+
avgRttUs: number;
|
|
17
|
+
p95RttUs: number;
|
|
18
|
+
slotLatencyMs: number;
|
|
19
|
+
tpuReachable: number;
|
|
20
|
+
tpuProbed: number;
|
|
21
|
+
agaveCount: number;
|
|
22
|
+
firedancerCount: number;
|
|
23
|
+
jitoCount: number;
|
|
24
|
+
solanaLabsCount: number;
|
|
25
|
+
otherCount: number;
|
|
26
|
+
reachableStakePct: number;
|
|
27
|
+
}
|
|
28
|
+
interface RegionScore {
|
|
29
|
+
region: Region;
|
|
30
|
+
observerCount: number;
|
|
31
|
+
healthScore: number;
|
|
32
|
+
reachabilityPct: number;
|
|
33
|
+
avgRttUs: number;
|
|
34
|
+
slotLatencyMs: number;
|
|
35
|
+
lastUpdatedSlot: bigint;
|
|
36
|
+
agaveCount: number;
|
|
37
|
+
firedancerCount: number;
|
|
38
|
+
jitoCount: number;
|
|
39
|
+
solanaLabsCount: number;
|
|
40
|
+
otherCount: number;
|
|
41
|
+
reachableStakePct: number;
|
|
42
|
+
}
|
|
43
|
+
interface NetworkHealth {
|
|
44
|
+
healthScore: number;
|
|
45
|
+
tpuReachabilityPct: number;
|
|
46
|
+
avgSlotLatencyMs: number;
|
|
47
|
+
activeObserverCount: number;
|
|
48
|
+
activeRegionCount: number;
|
|
49
|
+
lastUpdatedSlot: bigint;
|
|
50
|
+
lastUpdatedTs: bigint;
|
|
51
|
+
minHealthEver: number | null;
|
|
52
|
+
maxHealthEver: number;
|
|
53
|
+
totalAttestations: bigint;
|
|
54
|
+
regionScores: RegionScore[];
|
|
55
|
+
agaveCount: number;
|
|
56
|
+
firedancerCount: number;
|
|
57
|
+
jitoCount: number;
|
|
58
|
+
solanaLabsCount: number;
|
|
59
|
+
otherCount: number;
|
|
60
|
+
}
|
|
61
|
+
interface Observer {
|
|
62
|
+
publicKey: PublicKey;
|
|
63
|
+
authority: PublicKey;
|
|
64
|
+
region: Region;
|
|
65
|
+
stakeLamports: bigint;
|
|
66
|
+
registeredAt: bigint;
|
|
67
|
+
lastAttestationSlot: bigint;
|
|
68
|
+
attestationCount: bigint;
|
|
69
|
+
latestAttestation: Attestation;
|
|
70
|
+
isActive: boolean;
|
|
71
|
+
}
|
|
72
|
+
interface Registry {
|
|
73
|
+
authority: PublicKey;
|
|
74
|
+
pendingAuthority: PublicKey | null;
|
|
75
|
+
minStakeLamports: bigint;
|
|
76
|
+
observerCount: number;
|
|
77
|
+
activeCount: number;
|
|
78
|
+
maxObservers: number;
|
|
79
|
+
paused: boolean;
|
|
80
|
+
version: number;
|
|
81
|
+
}
|
|
82
|
+
interface AttestationSubmittedEvent {
|
|
83
|
+
observer: PublicKey;
|
|
84
|
+
region: Region;
|
|
85
|
+
score: number;
|
|
86
|
+
reachabilityPct: number;
|
|
87
|
+
slotLatencyMs: number;
|
|
88
|
+
slot: bigint;
|
|
89
|
+
agaveCount: number;
|
|
90
|
+
firedancerCount: number;
|
|
91
|
+
jitoCount: number;
|
|
92
|
+
solanaLabsCount: number;
|
|
93
|
+
otherCount: number;
|
|
94
|
+
reachableStakePct: number;
|
|
95
|
+
}
|
|
96
|
+
interface ObserverRegisteredEvent {
|
|
97
|
+
observer: PublicKey;
|
|
98
|
+
region: Region;
|
|
99
|
+
stakeLamports: bigint;
|
|
100
|
+
}
|
|
101
|
+
interface ObserverDeregisteredEvent {
|
|
102
|
+
observer: PublicKey;
|
|
103
|
+
}
|
|
104
|
+
interface ObserverSlashedEvent {
|
|
105
|
+
observer: PublicKey;
|
|
106
|
+
slashBps: number;
|
|
107
|
+
amountSlashed: bigint;
|
|
108
|
+
}
|
|
109
|
+
interface ConfigUpdatedEvent {
|
|
110
|
+
minStakeLamports: bigint | null;
|
|
111
|
+
maxObservers: number | null;
|
|
112
|
+
paused: boolean | null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
declare const PROGRAM_ID: PublicKey;
|
|
116
|
+
declare function getRegistryPDA(programId?: PublicKey): [PublicKey, number];
|
|
117
|
+
declare function getNetworkHealthPDA(programId?: PublicKey): [PublicKey, number];
|
|
118
|
+
declare function getObserverPDA(observer: PublicKey, programId?: PublicKey): [PublicKey, number];
|
|
119
|
+
|
|
120
|
+
interface SubmitAttestationParams {
|
|
121
|
+
tpuReachable: number;
|
|
122
|
+
tpuProbed: number;
|
|
123
|
+
avgRttUs: number;
|
|
124
|
+
p95RttUs: number;
|
|
125
|
+
slotLatencyMs: number;
|
|
126
|
+
agaveCount: number;
|
|
127
|
+
firedancerCount: number;
|
|
128
|
+
jitoCount: number;
|
|
129
|
+
solanaLabsCount: number;
|
|
130
|
+
otherCount: number;
|
|
131
|
+
reachableStakePct: number;
|
|
132
|
+
}
|
|
133
|
+
interface UpdateConfigParams {
|
|
134
|
+
minStakeLamports: bigint | null;
|
|
135
|
+
maxObservers: number | null;
|
|
136
|
+
paused: boolean | null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
interface S0racleClientOptions {
|
|
140
|
+
connection: Connection;
|
|
141
|
+
programId?: PublicKey;
|
|
142
|
+
wallet?: Wallet;
|
|
143
|
+
}
|
|
144
|
+
interface S0racleClient {
|
|
145
|
+
readonly programId: PublicKey;
|
|
146
|
+
readonly connection: Connection;
|
|
147
|
+
getNetworkHealth(): Promise<NetworkHealth>;
|
|
148
|
+
getRegistry(): Promise<Registry>;
|
|
149
|
+
getObserver(observerPubkey: PublicKey): Promise<Observer>;
|
|
150
|
+
getAllObservers(): Promise<Observer[]>;
|
|
151
|
+
getObserversByRegion(region: Region): Promise<Observer[]>;
|
|
152
|
+
registerObserver(observer: PublicKey, region: Region): Promise<TransactionInstruction>;
|
|
153
|
+
submitAttestation(authority: PublicKey, params: SubmitAttestationParams): Promise<TransactionInstruction>;
|
|
154
|
+
deregisterObserver(caller: PublicKey, observerWallet: PublicKey): Promise<TransactionInstruction>;
|
|
155
|
+
crankAggregation(cranker: PublicKey, observerAccounts: PublicKey[]): Promise<TransactionInstruction>;
|
|
156
|
+
initialize(authority: PublicKey, minStakeLamports: bigint, maxObservers: number): Promise<TransactionInstruction>;
|
|
157
|
+
slashObserver(authority: PublicKey, observerWallet: PublicKey, treasury: PublicKey, slashBps: number): Promise<TransactionInstruction>;
|
|
158
|
+
updateConfig(authority: PublicKey, params: UpdateConfigParams): Promise<TransactionInstruction>;
|
|
159
|
+
proposeAuthority(authority: PublicKey, newAuthority: PublicKey): Promise<TransactionInstruction>;
|
|
160
|
+
acceptAuthority(newAuthority: PublicKey): Promise<TransactionInstruction>;
|
|
161
|
+
onAttestationSubmitted(callback: (event: AttestationSubmittedEvent, slot: number) => void): number;
|
|
162
|
+
onObserverRegistered(callback: (event: ObserverRegisteredEvent, slot: number) => void): number;
|
|
163
|
+
onObserverDeregistered(callback: (event: ObserverDeregisteredEvent, slot: number) => void): number;
|
|
164
|
+
onObserverSlashed(callback: (event: ObserverSlashedEvent, slot: number) => void): number;
|
|
165
|
+
onConfigUpdated(callback: (event: ConfigUpdatedEvent, slot: number) => void): number;
|
|
166
|
+
removeEventListener(listenerId: number): Promise<void>;
|
|
167
|
+
}
|
|
168
|
+
declare function createS0racleClient(opts: S0racleClientOptions): S0racleClient;
|
|
169
|
+
|
|
170
|
+
declare function isStale(networkHealth: NetworkHealth, currentSlot: bigint): boolean;
|
|
171
|
+
declare function isObserverStale(observer: Observer, currentSlot: bigint): boolean;
|
|
172
|
+
declare function isDegraded(networkHealth: NetworkHealth, threshold?: number): boolean;
|
|
173
|
+
declare function healthStatus(networkHealth: NetworkHealth, currentSlot?: bigint): "healthy" | "degraded" | "critical" | "stale";
|
|
174
|
+
declare function regionLabel(region: Region): string;
|
|
175
|
+
declare function lamportsToSol(lamports: bigint): number;
|
|
176
|
+
declare function latencyScore(slotLatencyMs: number): number;
|
|
177
|
+
declare function isConsensusCritical(reachableStakePct: number): boolean;
|
|
178
|
+
declare function stakeReachStatus(reachableStakePct: number): "healthy" | "degraded" | "critical";
|
|
179
|
+
declare function dominantClient(region: RegionScore): "agave" | "firedancer" | "jito" | "other";
|
|
180
|
+
declare function clientDiversityIndex(region: RegionScore): number;
|
|
181
|
+
|
|
182
|
+
export { type Attestation, type AttestationSubmittedEvent, type ConfigUpdatedEvent, type NetworkHealth, type Observer, type ObserverDeregisteredEvent, type ObserverRegisteredEvent, type ObserverSlashedEvent, PROGRAM_ID, Region, type RegionScore, type Registry, type S0racleClient, type S0racleClientOptions, type SubmitAttestationParams, type UpdateConfigParams, clientDiversityIndex, createS0racleClient, dominantClient, getNetworkHealthPDA, getObserverPDA, getRegistryPDA, healthStatus, isConsensusCritical, isDegraded, isObserverStale, isStale, lamportsToSol, latencyScore, regionLabel, stakeReachStatus };
|