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/dist/index.js
ADDED
|
@@ -0,0 +1,2192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
PROGRAM_ID: () => PROGRAM_ID,
|
|
34
|
+
Region: () => Region,
|
|
35
|
+
clientDiversityIndex: () => clientDiversityIndex,
|
|
36
|
+
createS0racleClient: () => createS0racleClient,
|
|
37
|
+
dominantClient: () => dominantClient,
|
|
38
|
+
getNetworkHealthPDA: () => getNetworkHealthPDA,
|
|
39
|
+
getObserverPDA: () => getObserverPDA,
|
|
40
|
+
getRegistryPDA: () => getRegistryPDA,
|
|
41
|
+
healthStatus: () => healthStatus,
|
|
42
|
+
isConsensusCritical: () => isConsensusCritical,
|
|
43
|
+
isDegraded: () => isDegraded,
|
|
44
|
+
isObserverStale: () => isObserverStale,
|
|
45
|
+
isStale: () => isStale,
|
|
46
|
+
lamportsToSol: () => lamportsToSol,
|
|
47
|
+
latencyScore: () => latencyScore,
|
|
48
|
+
regionLabel: () => regionLabel,
|
|
49
|
+
stakeReachStatus: () => stakeReachStatus
|
|
50
|
+
});
|
|
51
|
+
module.exports = __toCommonJS(index_exports);
|
|
52
|
+
|
|
53
|
+
// src/types.ts
|
|
54
|
+
var import_web3 = require("@solana/web3.js");
|
|
55
|
+
var Region = /* @__PURE__ */ ((Region2) => {
|
|
56
|
+
Region2["Asia"] = "Asia";
|
|
57
|
+
Region2["US"] = "US";
|
|
58
|
+
Region2["EU"] = "EU";
|
|
59
|
+
Region2["SouthAmerica"] = "SouthAmerica";
|
|
60
|
+
Region2["Africa"] = "Africa";
|
|
61
|
+
Region2["Oceania"] = "Oceania";
|
|
62
|
+
Region2["Other"] = "Other";
|
|
63
|
+
return Region2;
|
|
64
|
+
})(Region || {});
|
|
65
|
+
|
|
66
|
+
// src/accounts.ts
|
|
67
|
+
var import_web32 = require("@solana/web3.js");
|
|
68
|
+
var import_bn = require("bn.js");
|
|
69
|
+
var PROGRAM_ID = new import_web32.PublicKey(
|
|
70
|
+
"2paXpX8Ze3tvYezviSwQJSSihG3LbrDiD7SNsaFwgTow"
|
|
71
|
+
);
|
|
72
|
+
var STALE_SLOTS = 150n;
|
|
73
|
+
var SUPPORTED_REGISTRY_VERSION = 1;
|
|
74
|
+
function getRegistryPDA(programId = PROGRAM_ID) {
|
|
75
|
+
return import_web32.PublicKey.findProgramAddressSync([Buffer.from("registry")], programId);
|
|
76
|
+
}
|
|
77
|
+
function getNetworkHealthPDA(programId = PROGRAM_ID) {
|
|
78
|
+
return import_web32.PublicKey.findProgramAddressSync(
|
|
79
|
+
[Buffer.from("network_health")],
|
|
80
|
+
programId
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
function getObserverPDA(observer, programId = PROGRAM_ID) {
|
|
84
|
+
return import_web32.PublicKey.findProgramAddressSync(
|
|
85
|
+
[Buffer.from("observer"), observer.toBuffer()],
|
|
86
|
+
programId
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
function toBigInt(val) {
|
|
90
|
+
if (typeof val === "bigint") return val;
|
|
91
|
+
if (typeof val === "number") return BigInt(val);
|
|
92
|
+
return BigInt(val.toString());
|
|
93
|
+
}
|
|
94
|
+
function toRegion(val) {
|
|
95
|
+
const key = typeof val === "string" ? val : Object.keys(val)[0] ?? "other";
|
|
96
|
+
const normalized = key.charAt(0).toUpperCase() + key.slice(1).toLowerCase();
|
|
97
|
+
const map = {
|
|
98
|
+
Asia: "Asia",
|
|
99
|
+
Us: "US",
|
|
100
|
+
Eu: "EU",
|
|
101
|
+
Southamerica: "SouthAmerica",
|
|
102
|
+
Africa: "Africa",
|
|
103
|
+
Oceania: "Oceania",
|
|
104
|
+
Other: "Other"
|
|
105
|
+
};
|
|
106
|
+
return map[normalized] ?? "Other";
|
|
107
|
+
}
|
|
108
|
+
function decodeAttestation(raw) {
|
|
109
|
+
return {
|
|
110
|
+
slot: toBigInt(raw["slot"]),
|
|
111
|
+
timestamp: toBigInt(raw["timestamp"]),
|
|
112
|
+
avgRttUs: raw["avgRttUs"],
|
|
113
|
+
p95RttUs: raw["p95RttUs"],
|
|
114
|
+
slotLatencyMs: raw["slotLatencyMs"],
|
|
115
|
+
tpuReachable: raw["tpuReachable"],
|
|
116
|
+
tpuProbed: raw["tpuProbed"],
|
|
117
|
+
agaveCount: raw["agaveCount"],
|
|
118
|
+
firedancerCount: raw["firedancerCount"],
|
|
119
|
+
jitoCount: raw["jitoCount"],
|
|
120
|
+
solanaLabsCount: raw["solanaLabsCount"],
|
|
121
|
+
otherCount: raw["otherCount"],
|
|
122
|
+
reachableStakePct: raw["reachableStakePct"]
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function decodeRegionScore(raw) {
|
|
126
|
+
return {
|
|
127
|
+
region: toRegion(raw["region"]),
|
|
128
|
+
observerCount: raw["observerCount"],
|
|
129
|
+
healthScore: raw["healthScore"],
|
|
130
|
+
reachabilityPct: raw["reachabilityPct"],
|
|
131
|
+
avgRttUs: raw["avgRttUs"],
|
|
132
|
+
slotLatencyMs: raw["slotLatencyMs"],
|
|
133
|
+
lastUpdatedSlot: toBigInt(raw["lastUpdatedSlot"]),
|
|
134
|
+
agaveCount: raw["agaveCount"],
|
|
135
|
+
firedancerCount: raw["firedancerCount"],
|
|
136
|
+
jitoCount: raw["jitoCount"],
|
|
137
|
+
solanaLabsCount: raw["solanaLabsCount"],
|
|
138
|
+
otherCount: raw["otherCount"],
|
|
139
|
+
reachableStakePct: raw["reachableStakePct"]
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function decodeNetworkHealth(raw) {
|
|
143
|
+
const minRaw = raw["minHealthEver"];
|
|
144
|
+
return {
|
|
145
|
+
healthScore: raw["healthScore"],
|
|
146
|
+
tpuReachabilityPct: raw["tpuReachabilityPct"],
|
|
147
|
+
avgSlotLatencyMs: raw["avgSlotLatencyMs"],
|
|
148
|
+
activeObserverCount: raw["activeObserverCount"],
|
|
149
|
+
activeRegionCount: raw["activeRegionCount"],
|
|
150
|
+
lastUpdatedSlot: toBigInt(raw["lastUpdatedSlot"]),
|
|
151
|
+
lastUpdatedTs: toBigInt(raw["lastUpdatedTs"]),
|
|
152
|
+
minHealthEver: minRaw === 255 ? null : minRaw,
|
|
153
|
+
maxHealthEver: raw["maxHealthEver"],
|
|
154
|
+
totalAttestations: toBigInt(raw["totalAttestations"]),
|
|
155
|
+
regionScores: raw["regionScores"].map(
|
|
156
|
+
decodeRegionScore
|
|
157
|
+
),
|
|
158
|
+
agaveCount: raw["agaveCount"],
|
|
159
|
+
firedancerCount: raw["firedancerCount"],
|
|
160
|
+
jitoCount: raw["jitoCount"],
|
|
161
|
+
solanaLabsCount: raw["solanaLabsCount"],
|
|
162
|
+
otherCount: raw["otherCount"]
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function decodeObserver(raw, publicKey) {
|
|
166
|
+
return {
|
|
167
|
+
publicKey,
|
|
168
|
+
authority: raw["authority"],
|
|
169
|
+
region: toRegion(raw["region"]),
|
|
170
|
+
stakeLamports: toBigInt(raw["stakeLamports"]),
|
|
171
|
+
registeredAt: toBigInt(raw["registeredAt"]),
|
|
172
|
+
lastAttestationSlot: toBigInt(raw["lastAttestationSlot"]),
|
|
173
|
+
attestationCount: toBigInt(raw["attestationCount"]),
|
|
174
|
+
latestAttestation: decodeAttestation(
|
|
175
|
+
raw["latestAttestation"]
|
|
176
|
+
),
|
|
177
|
+
isActive: raw["isActive"]
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function decodeRegistry(raw) {
|
|
181
|
+
const version = raw["version"];
|
|
182
|
+
if (version !== SUPPORTED_REGISTRY_VERSION) {
|
|
183
|
+
console.warn(
|
|
184
|
+
`s0racle-sdk: registry version ${version} is not supported by this SDK (expected ${SUPPORTED_REGISTRY_VERSION}). Upgrade s0racle-sdk to a compatible version.`
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
const pending = raw["pendingAuthority"];
|
|
188
|
+
return {
|
|
189
|
+
authority: raw["authority"],
|
|
190
|
+
pendingAuthority: pending ?? null,
|
|
191
|
+
minStakeLamports: toBigInt(raw["minStakeLamports"]),
|
|
192
|
+
observerCount: raw["observerCount"],
|
|
193
|
+
activeCount: raw["activeCount"],
|
|
194
|
+
maxObservers: raw["maxObservers"],
|
|
195
|
+
paused: raw["paused"],
|
|
196
|
+
version: raw["version"]
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// src/client.ts
|
|
201
|
+
var import_anchor2 = require("@coral-xyz/anchor");
|
|
202
|
+
var import_web35 = require("@solana/web3.js");
|
|
203
|
+
|
|
204
|
+
// src/idl/s0racle_program.json
|
|
205
|
+
var s0racle_program_default = {
|
|
206
|
+
address: "2paXpX8Ze3tvYezviSwQJSSihG3LbrDiD7SNsaFwgTow",
|
|
207
|
+
metadata: {
|
|
208
|
+
name: "s0racle_program",
|
|
209
|
+
version: "0.1.0",
|
|
210
|
+
spec: "0.1.0",
|
|
211
|
+
description: "Created with Anchor"
|
|
212
|
+
},
|
|
213
|
+
instructions: [
|
|
214
|
+
{
|
|
215
|
+
name: "accept_authority",
|
|
216
|
+
discriminator: [
|
|
217
|
+
107,
|
|
218
|
+
86,
|
|
219
|
+
198,
|
|
220
|
+
91,
|
|
221
|
+
33,
|
|
222
|
+
12,
|
|
223
|
+
107,
|
|
224
|
+
160
|
|
225
|
+
],
|
|
226
|
+
accounts: [
|
|
227
|
+
{
|
|
228
|
+
name: "registry",
|
|
229
|
+
writable: true
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
name: "new_authority",
|
|
233
|
+
signer: true
|
|
234
|
+
}
|
|
235
|
+
],
|
|
236
|
+
args: []
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
name: "crank_aggregation",
|
|
240
|
+
discriminator: [
|
|
241
|
+
37,
|
|
242
|
+
116,
|
|
243
|
+
43,
|
|
244
|
+
137,
|
|
245
|
+
4,
|
|
246
|
+
13,
|
|
247
|
+
88,
|
|
248
|
+
26
|
|
249
|
+
],
|
|
250
|
+
accounts: [
|
|
251
|
+
{
|
|
252
|
+
name: "cranker",
|
|
253
|
+
signer: true
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
name: "network_health",
|
|
257
|
+
writable: true,
|
|
258
|
+
pda: {
|
|
259
|
+
seeds: [
|
|
260
|
+
{
|
|
261
|
+
kind: "const",
|
|
262
|
+
value: [
|
|
263
|
+
110,
|
|
264
|
+
101,
|
|
265
|
+
116,
|
|
266
|
+
119,
|
|
267
|
+
111,
|
|
268
|
+
114,
|
|
269
|
+
107,
|
|
270
|
+
95,
|
|
271
|
+
104,
|
|
272
|
+
101,
|
|
273
|
+
97,
|
|
274
|
+
108,
|
|
275
|
+
116,
|
|
276
|
+
104
|
|
277
|
+
]
|
|
278
|
+
}
|
|
279
|
+
]
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
name: "registry_account",
|
|
284
|
+
pda: {
|
|
285
|
+
seeds: [
|
|
286
|
+
{
|
|
287
|
+
kind: "const",
|
|
288
|
+
value: [
|
|
289
|
+
114,
|
|
290
|
+
101,
|
|
291
|
+
103,
|
|
292
|
+
105,
|
|
293
|
+
115,
|
|
294
|
+
116,
|
|
295
|
+
114,
|
|
296
|
+
121
|
|
297
|
+
]
|
|
298
|
+
}
|
|
299
|
+
]
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
name: "clock",
|
|
304
|
+
address: "SysvarC1ock11111111111111111111111111111111"
|
|
305
|
+
}
|
|
306
|
+
],
|
|
307
|
+
args: []
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
name: "deregister_observer",
|
|
311
|
+
discriminator: [
|
|
312
|
+
16,
|
|
313
|
+
4,
|
|
314
|
+
225,
|
|
315
|
+
8,
|
|
316
|
+
113,
|
|
317
|
+
188,
|
|
318
|
+
135,
|
|
319
|
+
196
|
|
320
|
+
],
|
|
321
|
+
accounts: [
|
|
322
|
+
{
|
|
323
|
+
name: "caller",
|
|
324
|
+
writable: true,
|
|
325
|
+
signer: true
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
name: "observer_wallet",
|
|
329
|
+
docs: [
|
|
330
|
+
"Recipient of returned stake lamports on deregistration."
|
|
331
|
+
],
|
|
332
|
+
writable: true
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
name: "observer_account",
|
|
336
|
+
writable: true,
|
|
337
|
+
pda: {
|
|
338
|
+
seeds: [
|
|
339
|
+
{
|
|
340
|
+
kind: "const",
|
|
341
|
+
value: [
|
|
342
|
+
111,
|
|
343
|
+
98,
|
|
344
|
+
115,
|
|
345
|
+
101,
|
|
346
|
+
114,
|
|
347
|
+
118,
|
|
348
|
+
101,
|
|
349
|
+
114
|
|
350
|
+
]
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
kind: "account",
|
|
354
|
+
path: "observer_wallet"
|
|
355
|
+
}
|
|
356
|
+
]
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
name: "registry",
|
|
361
|
+
writable: true,
|
|
362
|
+
pda: {
|
|
363
|
+
seeds: [
|
|
364
|
+
{
|
|
365
|
+
kind: "const",
|
|
366
|
+
value: [
|
|
367
|
+
114,
|
|
368
|
+
101,
|
|
369
|
+
103,
|
|
370
|
+
105,
|
|
371
|
+
115,
|
|
372
|
+
116,
|
|
373
|
+
114,
|
|
374
|
+
121
|
|
375
|
+
]
|
|
376
|
+
}
|
|
377
|
+
]
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
name: "system_program",
|
|
382
|
+
address: "11111111111111111111111111111111"
|
|
383
|
+
}
|
|
384
|
+
],
|
|
385
|
+
args: []
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
name: "initialize",
|
|
389
|
+
discriminator: [
|
|
390
|
+
175,
|
|
391
|
+
175,
|
|
392
|
+
109,
|
|
393
|
+
31,
|
|
394
|
+
13,
|
|
395
|
+
152,
|
|
396
|
+
155,
|
|
397
|
+
237
|
|
398
|
+
],
|
|
399
|
+
accounts: [
|
|
400
|
+
{
|
|
401
|
+
name: "authority",
|
|
402
|
+
writable: true,
|
|
403
|
+
signer: true
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
name: "registry",
|
|
407
|
+
writable: true,
|
|
408
|
+
pda: {
|
|
409
|
+
seeds: [
|
|
410
|
+
{
|
|
411
|
+
kind: "const",
|
|
412
|
+
value: [
|
|
413
|
+
114,
|
|
414
|
+
101,
|
|
415
|
+
103,
|
|
416
|
+
105,
|
|
417
|
+
115,
|
|
418
|
+
116,
|
|
419
|
+
114,
|
|
420
|
+
121
|
|
421
|
+
]
|
|
422
|
+
}
|
|
423
|
+
]
|
|
424
|
+
}
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
name: "network_health",
|
|
428
|
+
writable: true,
|
|
429
|
+
pda: {
|
|
430
|
+
seeds: [
|
|
431
|
+
{
|
|
432
|
+
kind: "const",
|
|
433
|
+
value: [
|
|
434
|
+
110,
|
|
435
|
+
101,
|
|
436
|
+
116,
|
|
437
|
+
119,
|
|
438
|
+
111,
|
|
439
|
+
114,
|
|
440
|
+
107,
|
|
441
|
+
95,
|
|
442
|
+
104,
|
|
443
|
+
101,
|
|
444
|
+
97,
|
|
445
|
+
108,
|
|
446
|
+
116,
|
|
447
|
+
104
|
|
448
|
+
]
|
|
449
|
+
}
|
|
450
|
+
]
|
|
451
|
+
}
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
name: "system_program",
|
|
455
|
+
address: "11111111111111111111111111111111"
|
|
456
|
+
}
|
|
457
|
+
],
|
|
458
|
+
args: [
|
|
459
|
+
{
|
|
460
|
+
name: "min_stake_lamports",
|
|
461
|
+
type: "u64"
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
name: "max_observers",
|
|
465
|
+
type: "u16"
|
|
466
|
+
}
|
|
467
|
+
]
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
name: "propose_authority",
|
|
471
|
+
discriminator: [
|
|
472
|
+
20,
|
|
473
|
+
148,
|
|
474
|
+
236,
|
|
475
|
+
198,
|
|
476
|
+
76,
|
|
477
|
+
119,
|
|
478
|
+
99,
|
|
479
|
+
142
|
|
480
|
+
],
|
|
481
|
+
accounts: [
|
|
482
|
+
{
|
|
483
|
+
name: "registry",
|
|
484
|
+
writable: true,
|
|
485
|
+
pda: {
|
|
486
|
+
seeds: [
|
|
487
|
+
{
|
|
488
|
+
kind: "const",
|
|
489
|
+
value: [
|
|
490
|
+
114,
|
|
491
|
+
101,
|
|
492
|
+
103,
|
|
493
|
+
105,
|
|
494
|
+
115,
|
|
495
|
+
116,
|
|
496
|
+
114,
|
|
497
|
+
121
|
|
498
|
+
]
|
|
499
|
+
}
|
|
500
|
+
]
|
|
501
|
+
}
|
|
502
|
+
},
|
|
503
|
+
{
|
|
504
|
+
name: "authority",
|
|
505
|
+
signer: true,
|
|
506
|
+
relations: [
|
|
507
|
+
"registry"
|
|
508
|
+
]
|
|
509
|
+
}
|
|
510
|
+
],
|
|
511
|
+
args: [
|
|
512
|
+
{
|
|
513
|
+
name: "new_authority",
|
|
514
|
+
type: "pubkey"
|
|
515
|
+
}
|
|
516
|
+
]
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
name: "register_observer",
|
|
520
|
+
discriminator: [
|
|
521
|
+
95,
|
|
522
|
+
238,
|
|
523
|
+
80,
|
|
524
|
+
77,
|
|
525
|
+
247,
|
|
526
|
+
96,
|
|
527
|
+
2,
|
|
528
|
+
225
|
|
529
|
+
],
|
|
530
|
+
accounts: [
|
|
531
|
+
{
|
|
532
|
+
name: "observer",
|
|
533
|
+
writable: true,
|
|
534
|
+
signer: true
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
name: "observer_account",
|
|
538
|
+
writable: true,
|
|
539
|
+
pda: {
|
|
540
|
+
seeds: [
|
|
541
|
+
{
|
|
542
|
+
kind: "const",
|
|
543
|
+
value: [
|
|
544
|
+
111,
|
|
545
|
+
98,
|
|
546
|
+
115,
|
|
547
|
+
101,
|
|
548
|
+
114,
|
|
549
|
+
118,
|
|
550
|
+
101,
|
|
551
|
+
114
|
|
552
|
+
]
|
|
553
|
+
},
|
|
554
|
+
{
|
|
555
|
+
kind: "account",
|
|
556
|
+
path: "observer"
|
|
557
|
+
}
|
|
558
|
+
]
|
|
559
|
+
}
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
name: "registry",
|
|
563
|
+
writable: true,
|
|
564
|
+
pda: {
|
|
565
|
+
seeds: [
|
|
566
|
+
{
|
|
567
|
+
kind: "const",
|
|
568
|
+
value: [
|
|
569
|
+
114,
|
|
570
|
+
101,
|
|
571
|
+
103,
|
|
572
|
+
105,
|
|
573
|
+
115,
|
|
574
|
+
116,
|
|
575
|
+
114,
|
|
576
|
+
121
|
|
577
|
+
]
|
|
578
|
+
}
|
|
579
|
+
]
|
|
580
|
+
}
|
|
581
|
+
},
|
|
582
|
+
{
|
|
583
|
+
name: "system_program",
|
|
584
|
+
address: "11111111111111111111111111111111"
|
|
585
|
+
}
|
|
586
|
+
],
|
|
587
|
+
args: [
|
|
588
|
+
{
|
|
589
|
+
name: "region",
|
|
590
|
+
type: {
|
|
591
|
+
defined: {
|
|
592
|
+
name: "Region"
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
]
|
|
597
|
+
},
|
|
598
|
+
{
|
|
599
|
+
name: "slash_observer",
|
|
600
|
+
discriminator: [
|
|
601
|
+
203,
|
|
602
|
+
50,
|
|
603
|
+
98,
|
|
604
|
+
246,
|
|
605
|
+
173,
|
|
606
|
+
53,
|
|
607
|
+
118,
|
|
608
|
+
177
|
|
609
|
+
],
|
|
610
|
+
accounts: [
|
|
611
|
+
{
|
|
612
|
+
name: "authority",
|
|
613
|
+
signer: true,
|
|
614
|
+
relations: [
|
|
615
|
+
"registry"
|
|
616
|
+
]
|
|
617
|
+
},
|
|
618
|
+
{
|
|
619
|
+
name: "observer_wallet"
|
|
620
|
+
},
|
|
621
|
+
{
|
|
622
|
+
name: "observer_account",
|
|
623
|
+
writable: true,
|
|
624
|
+
pda: {
|
|
625
|
+
seeds: [
|
|
626
|
+
{
|
|
627
|
+
kind: "const",
|
|
628
|
+
value: [
|
|
629
|
+
111,
|
|
630
|
+
98,
|
|
631
|
+
115,
|
|
632
|
+
101,
|
|
633
|
+
114,
|
|
634
|
+
118,
|
|
635
|
+
101,
|
|
636
|
+
114
|
|
637
|
+
]
|
|
638
|
+
},
|
|
639
|
+
{
|
|
640
|
+
kind: "account",
|
|
641
|
+
path: "observer_wallet"
|
|
642
|
+
}
|
|
643
|
+
]
|
|
644
|
+
}
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
name: "registry",
|
|
648
|
+
writable: true,
|
|
649
|
+
pda: {
|
|
650
|
+
seeds: [
|
|
651
|
+
{
|
|
652
|
+
kind: "const",
|
|
653
|
+
value: [
|
|
654
|
+
114,
|
|
655
|
+
101,
|
|
656
|
+
103,
|
|
657
|
+
105,
|
|
658
|
+
115,
|
|
659
|
+
116,
|
|
660
|
+
114,
|
|
661
|
+
121
|
|
662
|
+
]
|
|
663
|
+
}
|
|
664
|
+
]
|
|
665
|
+
}
|
|
666
|
+
},
|
|
667
|
+
{
|
|
668
|
+
name: "treasury",
|
|
669
|
+
writable: true
|
|
670
|
+
}
|
|
671
|
+
],
|
|
672
|
+
args: [
|
|
673
|
+
{
|
|
674
|
+
name: "slash_bps",
|
|
675
|
+
type: "u16"
|
|
676
|
+
}
|
|
677
|
+
]
|
|
678
|
+
},
|
|
679
|
+
{
|
|
680
|
+
name: "submit_attestation",
|
|
681
|
+
discriminator: [
|
|
682
|
+
238,
|
|
683
|
+
220,
|
|
684
|
+
255,
|
|
685
|
+
105,
|
|
686
|
+
183,
|
|
687
|
+
211,
|
|
688
|
+
40,
|
|
689
|
+
83
|
|
690
|
+
],
|
|
691
|
+
accounts: [
|
|
692
|
+
{
|
|
693
|
+
name: "authority",
|
|
694
|
+
writable: true,
|
|
695
|
+
signer: true,
|
|
696
|
+
relations: [
|
|
697
|
+
"observer_account"
|
|
698
|
+
]
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
name: "observer_account",
|
|
702
|
+
writable: true,
|
|
703
|
+
pda: {
|
|
704
|
+
seeds: [
|
|
705
|
+
{
|
|
706
|
+
kind: "const",
|
|
707
|
+
value: [
|
|
708
|
+
111,
|
|
709
|
+
98,
|
|
710
|
+
115,
|
|
711
|
+
101,
|
|
712
|
+
114,
|
|
713
|
+
118,
|
|
714
|
+
101,
|
|
715
|
+
114
|
|
716
|
+
]
|
|
717
|
+
},
|
|
718
|
+
{
|
|
719
|
+
kind: "account",
|
|
720
|
+
path: "authority"
|
|
721
|
+
}
|
|
722
|
+
]
|
|
723
|
+
}
|
|
724
|
+
},
|
|
725
|
+
{
|
|
726
|
+
name: "network_health",
|
|
727
|
+
writable: true,
|
|
728
|
+
pda: {
|
|
729
|
+
seeds: [
|
|
730
|
+
{
|
|
731
|
+
kind: "const",
|
|
732
|
+
value: [
|
|
733
|
+
110,
|
|
734
|
+
101,
|
|
735
|
+
116,
|
|
736
|
+
119,
|
|
737
|
+
111,
|
|
738
|
+
114,
|
|
739
|
+
107,
|
|
740
|
+
95,
|
|
741
|
+
104,
|
|
742
|
+
101,
|
|
743
|
+
97,
|
|
744
|
+
108,
|
|
745
|
+
116,
|
|
746
|
+
104
|
|
747
|
+
]
|
|
748
|
+
}
|
|
749
|
+
]
|
|
750
|
+
}
|
|
751
|
+
},
|
|
752
|
+
{
|
|
753
|
+
name: "registry",
|
|
754
|
+
pda: {
|
|
755
|
+
seeds: [
|
|
756
|
+
{
|
|
757
|
+
kind: "const",
|
|
758
|
+
value: [
|
|
759
|
+
114,
|
|
760
|
+
101,
|
|
761
|
+
103,
|
|
762
|
+
105,
|
|
763
|
+
115,
|
|
764
|
+
116,
|
|
765
|
+
114,
|
|
766
|
+
121
|
|
767
|
+
]
|
|
768
|
+
}
|
|
769
|
+
]
|
|
770
|
+
}
|
|
771
|
+
},
|
|
772
|
+
{
|
|
773
|
+
name: "clock",
|
|
774
|
+
address: "SysvarC1ock11111111111111111111111111111111"
|
|
775
|
+
}
|
|
776
|
+
],
|
|
777
|
+
args: [
|
|
778
|
+
{
|
|
779
|
+
name: "tpu_reachable",
|
|
780
|
+
type: "u16"
|
|
781
|
+
},
|
|
782
|
+
{
|
|
783
|
+
name: "tpu_probed",
|
|
784
|
+
type: "u16"
|
|
785
|
+
},
|
|
786
|
+
{
|
|
787
|
+
name: "avg_rtt_us",
|
|
788
|
+
type: "u32"
|
|
789
|
+
},
|
|
790
|
+
{
|
|
791
|
+
name: "p95_rtt_us",
|
|
792
|
+
type: "u32"
|
|
793
|
+
},
|
|
794
|
+
{
|
|
795
|
+
name: "slot_latency_ms",
|
|
796
|
+
type: "u32"
|
|
797
|
+
},
|
|
798
|
+
{
|
|
799
|
+
name: "agave_count",
|
|
800
|
+
type: "u16"
|
|
801
|
+
},
|
|
802
|
+
{
|
|
803
|
+
name: "firedancer_count",
|
|
804
|
+
type: "u16"
|
|
805
|
+
},
|
|
806
|
+
{
|
|
807
|
+
name: "jito_count",
|
|
808
|
+
type: "u16"
|
|
809
|
+
},
|
|
810
|
+
{
|
|
811
|
+
name: "solana_labs_count",
|
|
812
|
+
type: "u16"
|
|
813
|
+
},
|
|
814
|
+
{
|
|
815
|
+
name: "other_count",
|
|
816
|
+
type: "u16"
|
|
817
|
+
},
|
|
818
|
+
{
|
|
819
|
+
name: "reachable_stake_pct",
|
|
820
|
+
type: "u8"
|
|
821
|
+
}
|
|
822
|
+
]
|
|
823
|
+
},
|
|
824
|
+
{
|
|
825
|
+
name: "update_config",
|
|
826
|
+
discriminator: [
|
|
827
|
+
29,
|
|
828
|
+
158,
|
|
829
|
+
252,
|
|
830
|
+
191,
|
|
831
|
+
10,
|
|
832
|
+
83,
|
|
833
|
+
219,
|
|
834
|
+
99
|
|
835
|
+
],
|
|
836
|
+
accounts: [
|
|
837
|
+
{
|
|
838
|
+
name: "authority",
|
|
839
|
+
signer: true,
|
|
840
|
+
relations: [
|
|
841
|
+
"registry"
|
|
842
|
+
]
|
|
843
|
+
},
|
|
844
|
+
{
|
|
845
|
+
name: "registry",
|
|
846
|
+
writable: true,
|
|
847
|
+
pda: {
|
|
848
|
+
seeds: [
|
|
849
|
+
{
|
|
850
|
+
kind: "const",
|
|
851
|
+
value: [
|
|
852
|
+
114,
|
|
853
|
+
101,
|
|
854
|
+
103,
|
|
855
|
+
105,
|
|
856
|
+
115,
|
|
857
|
+
116,
|
|
858
|
+
114,
|
|
859
|
+
121
|
|
860
|
+
]
|
|
861
|
+
}
|
|
862
|
+
]
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
],
|
|
866
|
+
args: [
|
|
867
|
+
{
|
|
868
|
+
name: "min_stake_lamports",
|
|
869
|
+
type: {
|
|
870
|
+
option: "u64"
|
|
871
|
+
}
|
|
872
|
+
},
|
|
873
|
+
{
|
|
874
|
+
name: "max_observers",
|
|
875
|
+
type: {
|
|
876
|
+
option: "u16"
|
|
877
|
+
}
|
|
878
|
+
},
|
|
879
|
+
{
|
|
880
|
+
name: "paused",
|
|
881
|
+
type: {
|
|
882
|
+
option: "bool"
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
]
|
|
886
|
+
}
|
|
887
|
+
],
|
|
888
|
+
accounts: [
|
|
889
|
+
{
|
|
890
|
+
name: "NetworkHealthAccount",
|
|
891
|
+
discriminator: [
|
|
892
|
+
90,
|
|
893
|
+
218,
|
|
894
|
+
55,
|
|
895
|
+
105,
|
|
896
|
+
239,
|
|
897
|
+
131,
|
|
898
|
+
43,
|
|
899
|
+
68
|
|
900
|
+
]
|
|
901
|
+
},
|
|
902
|
+
{
|
|
903
|
+
name: "ObserverAccount",
|
|
904
|
+
discriminator: [
|
|
905
|
+
119,
|
|
906
|
+
24,
|
|
907
|
+
204,
|
|
908
|
+
152,
|
|
909
|
+
164,
|
|
910
|
+
169,
|
|
911
|
+
5,
|
|
912
|
+
101
|
|
913
|
+
]
|
|
914
|
+
},
|
|
915
|
+
{
|
|
916
|
+
name: "RegistryAccount",
|
|
917
|
+
discriminator: [
|
|
918
|
+
113,
|
|
919
|
+
93,
|
|
920
|
+
106,
|
|
921
|
+
201,
|
|
922
|
+
100,
|
|
923
|
+
166,
|
|
924
|
+
146,
|
|
925
|
+
98
|
|
926
|
+
]
|
|
927
|
+
}
|
|
928
|
+
],
|
|
929
|
+
events: [
|
|
930
|
+
{
|
|
931
|
+
name: "AttestationSubmitted",
|
|
932
|
+
discriminator: [
|
|
933
|
+
177,
|
|
934
|
+
213,
|
|
935
|
+
117,
|
|
936
|
+
225,
|
|
937
|
+
166,
|
|
938
|
+
11,
|
|
939
|
+
54,
|
|
940
|
+
218
|
|
941
|
+
]
|
|
942
|
+
},
|
|
943
|
+
{
|
|
944
|
+
name: "ConfigUpdated",
|
|
945
|
+
discriminator: [
|
|
946
|
+
40,
|
|
947
|
+
241,
|
|
948
|
+
230,
|
|
949
|
+
122,
|
|
950
|
+
11,
|
|
951
|
+
19,
|
|
952
|
+
198,
|
|
953
|
+
194
|
|
954
|
+
]
|
|
955
|
+
},
|
|
956
|
+
{
|
|
957
|
+
name: "ObserverDeregistered",
|
|
958
|
+
discriminator: [
|
|
959
|
+
78,
|
|
960
|
+
251,
|
|
961
|
+
104,
|
|
962
|
+
71,
|
|
963
|
+
5,
|
|
964
|
+
145,
|
|
965
|
+
253,
|
|
966
|
+
95
|
|
967
|
+
]
|
|
968
|
+
},
|
|
969
|
+
{
|
|
970
|
+
name: "ObserverRegistered",
|
|
971
|
+
discriminator: [
|
|
972
|
+
33,
|
|
973
|
+
248,
|
|
974
|
+
190,
|
|
975
|
+
137,
|
|
976
|
+
191,
|
|
977
|
+
38,
|
|
978
|
+
49,
|
|
979
|
+
56
|
|
980
|
+
]
|
|
981
|
+
},
|
|
982
|
+
{
|
|
983
|
+
name: "ObserverSlashed",
|
|
984
|
+
discriminator: [
|
|
985
|
+
132,
|
|
986
|
+
0,
|
|
987
|
+
84,
|
|
988
|
+
231,
|
|
989
|
+
39,
|
|
990
|
+
179,
|
|
991
|
+
32,
|
|
992
|
+
211
|
|
993
|
+
]
|
|
994
|
+
}
|
|
995
|
+
],
|
|
996
|
+
errors: [
|
|
997
|
+
{
|
|
998
|
+
code: 6e3,
|
|
999
|
+
name: "ValueCannotBeZero",
|
|
1000
|
+
msg: "Value cannot be zero"
|
|
1001
|
+
},
|
|
1002
|
+
{
|
|
1003
|
+
code: 6001,
|
|
1004
|
+
name: "RegistryPaused",
|
|
1005
|
+
msg: "Registry is currently paused"
|
|
1006
|
+
},
|
|
1007
|
+
{
|
|
1008
|
+
code: 6002,
|
|
1009
|
+
name: "MaxObserversReached",
|
|
1010
|
+
msg: "Maximum number of observers has been reached"
|
|
1011
|
+
},
|
|
1012
|
+
{
|
|
1013
|
+
code: 6003,
|
|
1014
|
+
name: "InsufficientLamports",
|
|
1015
|
+
msg: "Insufficient Lamports"
|
|
1016
|
+
},
|
|
1017
|
+
{
|
|
1018
|
+
code: 6004,
|
|
1019
|
+
name: "UnauthorizedObserver",
|
|
1020
|
+
msg: "Unauthorized Observer"
|
|
1021
|
+
},
|
|
1022
|
+
{
|
|
1023
|
+
code: 6005,
|
|
1024
|
+
name: "ObserverNotActive",
|
|
1025
|
+
msg: "Observer is not active"
|
|
1026
|
+
},
|
|
1027
|
+
{
|
|
1028
|
+
code: 6006,
|
|
1029
|
+
name: "ZeroValidatorsProbed",
|
|
1030
|
+
msg: "Zero validators probed"
|
|
1031
|
+
},
|
|
1032
|
+
{
|
|
1033
|
+
code: 6007,
|
|
1034
|
+
name: "InsufficientValidatorsProbed",
|
|
1035
|
+
msg: "Insufficient validators probed"
|
|
1036
|
+
},
|
|
1037
|
+
{
|
|
1038
|
+
code: 6008,
|
|
1039
|
+
name: "InvalidReachabilityCount",
|
|
1040
|
+
msg: "Invalid reachability count"
|
|
1041
|
+
},
|
|
1042
|
+
{
|
|
1043
|
+
code: 6009,
|
|
1044
|
+
name: "InvalidLatencyValue",
|
|
1045
|
+
msg: "Invalid latency submitted"
|
|
1046
|
+
},
|
|
1047
|
+
{
|
|
1048
|
+
code: 6010,
|
|
1049
|
+
name: "StaleAttestation",
|
|
1050
|
+
msg: "Stale attestation"
|
|
1051
|
+
},
|
|
1052
|
+
{
|
|
1053
|
+
code: 6011,
|
|
1054
|
+
name: "NoActiveObservers",
|
|
1055
|
+
msg: "No active observers"
|
|
1056
|
+
},
|
|
1057
|
+
{
|
|
1058
|
+
code: 6012,
|
|
1059
|
+
name: "ObserverAlreadyInActive",
|
|
1060
|
+
msg: "Observer already inactive"
|
|
1061
|
+
},
|
|
1062
|
+
{
|
|
1063
|
+
code: 6013,
|
|
1064
|
+
name: "UnAuthorizedCaller",
|
|
1065
|
+
msg: "Unauthorized caller"
|
|
1066
|
+
},
|
|
1067
|
+
{
|
|
1068
|
+
code: 6014,
|
|
1069
|
+
name: "InsufficientBalanceForRefund",
|
|
1070
|
+
msg: "Insufficient balance in PDA for stake refund"
|
|
1071
|
+
},
|
|
1072
|
+
{
|
|
1073
|
+
code: 6015,
|
|
1074
|
+
name: "InvalidSlashBps",
|
|
1075
|
+
msg: "Invalid slash basis points - must be <= 10000"
|
|
1076
|
+
},
|
|
1077
|
+
{
|
|
1078
|
+
code: 6016,
|
|
1079
|
+
name: "ObserverNotFound",
|
|
1080
|
+
msg: "Observer not found"
|
|
1081
|
+
},
|
|
1082
|
+
{
|
|
1083
|
+
code: 6017,
|
|
1084
|
+
name: "InsufficientBalanceForSlash",
|
|
1085
|
+
msg: "Insufficient balance in PDA for slash"
|
|
1086
|
+
},
|
|
1087
|
+
{
|
|
1088
|
+
code: 6018,
|
|
1089
|
+
name: "InvalidPendingAuthority",
|
|
1090
|
+
msg: "Invalid or no pending authority for registry"
|
|
1091
|
+
},
|
|
1092
|
+
{
|
|
1093
|
+
code: 6019,
|
|
1094
|
+
name: "MaxObserversCannotBeLessThanActiveObservers",
|
|
1095
|
+
msg: "Max observers cannot be less than active observers"
|
|
1096
|
+
}
|
|
1097
|
+
],
|
|
1098
|
+
types: [
|
|
1099
|
+
{
|
|
1100
|
+
name: "Attestation",
|
|
1101
|
+
docs: [
|
|
1102
|
+
"Single 10-second measurement from one observer node"
|
|
1103
|
+
],
|
|
1104
|
+
type: {
|
|
1105
|
+
kind: "struct",
|
|
1106
|
+
fields: [
|
|
1107
|
+
{
|
|
1108
|
+
name: "slot",
|
|
1109
|
+
docs: [
|
|
1110
|
+
"Solana slot this measurement covers"
|
|
1111
|
+
],
|
|
1112
|
+
type: "u64"
|
|
1113
|
+
},
|
|
1114
|
+
{
|
|
1115
|
+
name: "timestamp",
|
|
1116
|
+
docs: [
|
|
1117
|
+
"Timestamp of the measurement"
|
|
1118
|
+
],
|
|
1119
|
+
type: "i64"
|
|
1120
|
+
},
|
|
1121
|
+
{
|
|
1122
|
+
name: "avg_rtt_us",
|
|
1123
|
+
docs: [
|
|
1124
|
+
"Average RTT of the QUIC probe"
|
|
1125
|
+
],
|
|
1126
|
+
type: "u32"
|
|
1127
|
+
},
|
|
1128
|
+
{
|
|
1129
|
+
name: "p95_rtt_us",
|
|
1130
|
+
docs: [
|
|
1131
|
+
"P95 RTT of the QUIC probe"
|
|
1132
|
+
],
|
|
1133
|
+
type: "u32"
|
|
1134
|
+
},
|
|
1135
|
+
{
|
|
1136
|
+
name: "slot_latency_ms",
|
|
1137
|
+
docs: [
|
|
1138
|
+
"Slot latency of the QUIC probe"
|
|
1139
|
+
],
|
|
1140
|
+
type: "u32"
|
|
1141
|
+
},
|
|
1142
|
+
{
|
|
1143
|
+
name: "tpu_reachable",
|
|
1144
|
+
docs: [
|
|
1145
|
+
"Validators reachable via QUIC probe"
|
|
1146
|
+
],
|
|
1147
|
+
type: "u16"
|
|
1148
|
+
},
|
|
1149
|
+
{
|
|
1150
|
+
name: "tpu_probed",
|
|
1151
|
+
docs: [
|
|
1152
|
+
"Total validators probed this round"
|
|
1153
|
+
],
|
|
1154
|
+
type: "u16"
|
|
1155
|
+
},
|
|
1156
|
+
{
|
|
1157
|
+
name: "agave_count",
|
|
1158
|
+
docs: [
|
|
1159
|
+
"Client distributions"
|
|
1160
|
+
],
|
|
1161
|
+
type: "u16"
|
|
1162
|
+
},
|
|
1163
|
+
{
|
|
1164
|
+
name: "firedancer_count",
|
|
1165
|
+
type: "u16"
|
|
1166
|
+
},
|
|
1167
|
+
{
|
|
1168
|
+
name: "jito_count",
|
|
1169
|
+
type: "u16"
|
|
1170
|
+
},
|
|
1171
|
+
{
|
|
1172
|
+
name: "solana_labs_count",
|
|
1173
|
+
type: "u16"
|
|
1174
|
+
},
|
|
1175
|
+
{
|
|
1176
|
+
name: "other_count",
|
|
1177
|
+
type: "u16"
|
|
1178
|
+
},
|
|
1179
|
+
{
|
|
1180
|
+
name: "reachable_stake_pct",
|
|
1181
|
+
docs: [
|
|
1182
|
+
"% of total stake (by lamports) reachable via QUIC probe"
|
|
1183
|
+
],
|
|
1184
|
+
type: "u8"
|
|
1185
|
+
}
|
|
1186
|
+
]
|
|
1187
|
+
}
|
|
1188
|
+
},
|
|
1189
|
+
{
|
|
1190
|
+
name: "AttestationSubmitted",
|
|
1191
|
+
type: {
|
|
1192
|
+
kind: "struct",
|
|
1193
|
+
fields: [
|
|
1194
|
+
{
|
|
1195
|
+
name: "observer",
|
|
1196
|
+
type: "pubkey"
|
|
1197
|
+
},
|
|
1198
|
+
{
|
|
1199
|
+
name: "region",
|
|
1200
|
+
type: {
|
|
1201
|
+
defined: {
|
|
1202
|
+
name: "Region"
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
},
|
|
1206
|
+
{
|
|
1207
|
+
name: "score",
|
|
1208
|
+
type: "u8"
|
|
1209
|
+
},
|
|
1210
|
+
{
|
|
1211
|
+
name: "reachability_pct",
|
|
1212
|
+
type: "u8"
|
|
1213
|
+
},
|
|
1214
|
+
{
|
|
1215
|
+
name: "slot_latency_ms",
|
|
1216
|
+
type: "u32"
|
|
1217
|
+
},
|
|
1218
|
+
{
|
|
1219
|
+
name: "slot",
|
|
1220
|
+
type: "u64"
|
|
1221
|
+
},
|
|
1222
|
+
{
|
|
1223
|
+
name: "agave_count",
|
|
1224
|
+
type: "u16"
|
|
1225
|
+
},
|
|
1226
|
+
{
|
|
1227
|
+
name: "firedancer_count",
|
|
1228
|
+
type: "u16"
|
|
1229
|
+
},
|
|
1230
|
+
{
|
|
1231
|
+
name: "jito_count",
|
|
1232
|
+
type: "u16"
|
|
1233
|
+
},
|
|
1234
|
+
{
|
|
1235
|
+
name: "solana_labs_count",
|
|
1236
|
+
type: "u16"
|
|
1237
|
+
},
|
|
1238
|
+
{
|
|
1239
|
+
name: "other_count",
|
|
1240
|
+
type: "u16"
|
|
1241
|
+
},
|
|
1242
|
+
{
|
|
1243
|
+
name: "reachable_stake_pct",
|
|
1244
|
+
type: "u8"
|
|
1245
|
+
}
|
|
1246
|
+
]
|
|
1247
|
+
}
|
|
1248
|
+
},
|
|
1249
|
+
{
|
|
1250
|
+
name: "ConfigUpdated",
|
|
1251
|
+
type: {
|
|
1252
|
+
kind: "struct",
|
|
1253
|
+
fields: [
|
|
1254
|
+
{
|
|
1255
|
+
name: "min_stake_lamports",
|
|
1256
|
+
type: {
|
|
1257
|
+
option: "u64"
|
|
1258
|
+
}
|
|
1259
|
+
},
|
|
1260
|
+
{
|
|
1261
|
+
name: "max_observers",
|
|
1262
|
+
type: {
|
|
1263
|
+
option: "u16"
|
|
1264
|
+
}
|
|
1265
|
+
},
|
|
1266
|
+
{
|
|
1267
|
+
name: "paused",
|
|
1268
|
+
type: {
|
|
1269
|
+
option: "bool"
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
]
|
|
1273
|
+
}
|
|
1274
|
+
},
|
|
1275
|
+
{
|
|
1276
|
+
name: "NetworkHealthAccount",
|
|
1277
|
+
docs: [
|
|
1278
|
+
"Global oracle account - the single source of truth for dApps and UI reads"
|
|
1279
|
+
],
|
|
1280
|
+
type: {
|
|
1281
|
+
kind: "struct",
|
|
1282
|
+
fields: [
|
|
1283
|
+
{
|
|
1284
|
+
name: "health_score",
|
|
1285
|
+
docs: [
|
|
1286
|
+
"The health score of the network"
|
|
1287
|
+
],
|
|
1288
|
+
type: "u8"
|
|
1289
|
+
},
|
|
1290
|
+
{
|
|
1291
|
+
name: "tpu_reachability_pct",
|
|
1292
|
+
docs: [
|
|
1293
|
+
"TPU reachability % averaged across all regions"
|
|
1294
|
+
],
|
|
1295
|
+
type: "u8"
|
|
1296
|
+
},
|
|
1297
|
+
{
|
|
1298
|
+
name: "avg_slot_latency_ms",
|
|
1299
|
+
docs: [
|
|
1300
|
+
"Average slot latency in milliseconds"
|
|
1301
|
+
],
|
|
1302
|
+
type: "u32"
|
|
1303
|
+
},
|
|
1304
|
+
{
|
|
1305
|
+
name: "active_observer_count",
|
|
1306
|
+
docs: [
|
|
1307
|
+
"Number of active observers that contributed to this score"
|
|
1308
|
+
],
|
|
1309
|
+
type: "u16"
|
|
1310
|
+
},
|
|
1311
|
+
{
|
|
1312
|
+
name: "active_region_count",
|
|
1313
|
+
docs: [
|
|
1314
|
+
"Number of regions with fresh attestations"
|
|
1315
|
+
],
|
|
1316
|
+
type: "u16"
|
|
1317
|
+
},
|
|
1318
|
+
{
|
|
1319
|
+
name: "last_updated_slot",
|
|
1320
|
+
docs: [
|
|
1321
|
+
"Slot of last aggregation \u2014 dApps check this for staleness"
|
|
1322
|
+
],
|
|
1323
|
+
type: "u64"
|
|
1324
|
+
},
|
|
1325
|
+
{
|
|
1326
|
+
name: "last_updated_ts",
|
|
1327
|
+
docs: [
|
|
1328
|
+
"Unix timestamp of last update"
|
|
1329
|
+
],
|
|
1330
|
+
type: "i64"
|
|
1331
|
+
},
|
|
1332
|
+
{
|
|
1333
|
+
name: "min_health_ever",
|
|
1334
|
+
docs: [
|
|
1335
|
+
"Lowest health score ever recorded",
|
|
1336
|
+
'Note: Initialized to 255 (u8::MAX) which represents "no data yet".'
|
|
1337
|
+
],
|
|
1338
|
+
type: "u8"
|
|
1339
|
+
},
|
|
1340
|
+
{
|
|
1341
|
+
name: "max_health_ever",
|
|
1342
|
+
docs: [
|
|
1343
|
+
"Highest health score ever recorded"
|
|
1344
|
+
],
|
|
1345
|
+
type: "u8"
|
|
1346
|
+
},
|
|
1347
|
+
{
|
|
1348
|
+
name: "total_attestations",
|
|
1349
|
+
docs: [
|
|
1350
|
+
"Total attestations ever submitted across all observers"
|
|
1351
|
+
],
|
|
1352
|
+
type: "u64"
|
|
1353
|
+
},
|
|
1354
|
+
{
|
|
1355
|
+
name: "region_scores",
|
|
1356
|
+
docs: [
|
|
1357
|
+
"One entry per region"
|
|
1358
|
+
],
|
|
1359
|
+
type: {
|
|
1360
|
+
array: [
|
|
1361
|
+
{
|
|
1362
|
+
defined: {
|
|
1363
|
+
name: "RegionScore"
|
|
1364
|
+
}
|
|
1365
|
+
},
|
|
1366
|
+
7
|
|
1367
|
+
]
|
|
1368
|
+
}
|
|
1369
|
+
},
|
|
1370
|
+
{
|
|
1371
|
+
name: "agave_count",
|
|
1372
|
+
type: "u8"
|
|
1373
|
+
},
|
|
1374
|
+
{
|
|
1375
|
+
name: "firedancer_count",
|
|
1376
|
+
type: "u8"
|
|
1377
|
+
},
|
|
1378
|
+
{
|
|
1379
|
+
name: "jito_count",
|
|
1380
|
+
type: "u8"
|
|
1381
|
+
},
|
|
1382
|
+
{
|
|
1383
|
+
name: "solana_labs_count",
|
|
1384
|
+
type: "u8"
|
|
1385
|
+
},
|
|
1386
|
+
{
|
|
1387
|
+
name: "other_count",
|
|
1388
|
+
type: "u8"
|
|
1389
|
+
},
|
|
1390
|
+
{
|
|
1391
|
+
name: "bump",
|
|
1392
|
+
docs: [
|
|
1393
|
+
"PDA bump seed"
|
|
1394
|
+
],
|
|
1395
|
+
type: "u8"
|
|
1396
|
+
}
|
|
1397
|
+
]
|
|
1398
|
+
}
|
|
1399
|
+
},
|
|
1400
|
+
{
|
|
1401
|
+
name: "ObserverAccount",
|
|
1402
|
+
docs: [
|
|
1403
|
+
"Per-observer state - stores identity, region, stake and latest measurement"
|
|
1404
|
+
],
|
|
1405
|
+
type: {
|
|
1406
|
+
kind: "struct",
|
|
1407
|
+
fields: [
|
|
1408
|
+
{
|
|
1409
|
+
name: "authority",
|
|
1410
|
+
docs: [
|
|
1411
|
+
"The authority of the observer"
|
|
1412
|
+
],
|
|
1413
|
+
type: "pubkey"
|
|
1414
|
+
},
|
|
1415
|
+
{
|
|
1416
|
+
name: "region",
|
|
1417
|
+
docs: [
|
|
1418
|
+
"The region of the observer"
|
|
1419
|
+
],
|
|
1420
|
+
type: {
|
|
1421
|
+
defined: {
|
|
1422
|
+
name: "Region"
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
},
|
|
1426
|
+
{
|
|
1427
|
+
name: "stake_lamports",
|
|
1428
|
+
docs: [
|
|
1429
|
+
"The stake of the observer"
|
|
1430
|
+
],
|
|
1431
|
+
type: "u64"
|
|
1432
|
+
},
|
|
1433
|
+
{
|
|
1434
|
+
name: "registered_at",
|
|
1435
|
+
docs: [
|
|
1436
|
+
"The timestamp when the observer was registered"
|
|
1437
|
+
],
|
|
1438
|
+
type: "i64"
|
|
1439
|
+
},
|
|
1440
|
+
{
|
|
1441
|
+
name: "last_attestation_slot",
|
|
1442
|
+
docs: [
|
|
1443
|
+
"Solana slot of the most recent attestation submitted",
|
|
1444
|
+
"Used for staleness check in crank_aggregation"
|
|
1445
|
+
],
|
|
1446
|
+
type: "u64"
|
|
1447
|
+
},
|
|
1448
|
+
{
|
|
1449
|
+
name: "attestation_count",
|
|
1450
|
+
docs: [
|
|
1451
|
+
"The number of attestations submitted by the observer"
|
|
1452
|
+
],
|
|
1453
|
+
type: "u64"
|
|
1454
|
+
},
|
|
1455
|
+
{
|
|
1456
|
+
name: "latest_attestation",
|
|
1457
|
+
docs: [
|
|
1458
|
+
"The latest attestation submitted by the observer"
|
|
1459
|
+
],
|
|
1460
|
+
type: {
|
|
1461
|
+
defined: {
|
|
1462
|
+
name: "Attestation"
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
},
|
|
1466
|
+
{
|
|
1467
|
+
name: "is_active",
|
|
1468
|
+
docs: [
|
|
1469
|
+
"Whether the observer is active"
|
|
1470
|
+
],
|
|
1471
|
+
type: "bool"
|
|
1472
|
+
},
|
|
1473
|
+
{
|
|
1474
|
+
name: "bump",
|
|
1475
|
+
docs: [
|
|
1476
|
+
"The bump seed for the PDA"
|
|
1477
|
+
],
|
|
1478
|
+
type: "u8"
|
|
1479
|
+
}
|
|
1480
|
+
]
|
|
1481
|
+
}
|
|
1482
|
+
},
|
|
1483
|
+
{
|
|
1484
|
+
name: "ObserverDeregistered",
|
|
1485
|
+
type: {
|
|
1486
|
+
kind: "struct",
|
|
1487
|
+
fields: [
|
|
1488
|
+
{
|
|
1489
|
+
name: "observer",
|
|
1490
|
+
type: "pubkey"
|
|
1491
|
+
}
|
|
1492
|
+
]
|
|
1493
|
+
}
|
|
1494
|
+
},
|
|
1495
|
+
{
|
|
1496
|
+
name: "ObserverRegistered",
|
|
1497
|
+
type: {
|
|
1498
|
+
kind: "struct",
|
|
1499
|
+
fields: [
|
|
1500
|
+
{
|
|
1501
|
+
name: "observer",
|
|
1502
|
+
type: "pubkey"
|
|
1503
|
+
},
|
|
1504
|
+
{
|
|
1505
|
+
name: "region",
|
|
1506
|
+
type: {
|
|
1507
|
+
defined: {
|
|
1508
|
+
name: "Region"
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
},
|
|
1512
|
+
{
|
|
1513
|
+
name: "stake_lamports",
|
|
1514
|
+
type: "u64"
|
|
1515
|
+
}
|
|
1516
|
+
]
|
|
1517
|
+
}
|
|
1518
|
+
},
|
|
1519
|
+
{
|
|
1520
|
+
name: "ObserverSlashed",
|
|
1521
|
+
type: {
|
|
1522
|
+
kind: "struct",
|
|
1523
|
+
fields: [
|
|
1524
|
+
{
|
|
1525
|
+
name: "observer",
|
|
1526
|
+
type: "pubkey"
|
|
1527
|
+
},
|
|
1528
|
+
{
|
|
1529
|
+
name: "slash_bps",
|
|
1530
|
+
type: "u16"
|
|
1531
|
+
},
|
|
1532
|
+
{
|
|
1533
|
+
name: "amount_slashed",
|
|
1534
|
+
type: "u64"
|
|
1535
|
+
}
|
|
1536
|
+
]
|
|
1537
|
+
}
|
|
1538
|
+
},
|
|
1539
|
+
{
|
|
1540
|
+
name: "Region",
|
|
1541
|
+
docs: [
|
|
1542
|
+
"Geographic region of an observer node - serializes as u8 on-chain"
|
|
1543
|
+
],
|
|
1544
|
+
type: {
|
|
1545
|
+
kind: "enum",
|
|
1546
|
+
variants: [
|
|
1547
|
+
{
|
|
1548
|
+
name: "Asia"
|
|
1549
|
+
},
|
|
1550
|
+
{
|
|
1551
|
+
name: "US"
|
|
1552
|
+
},
|
|
1553
|
+
{
|
|
1554
|
+
name: "EU"
|
|
1555
|
+
},
|
|
1556
|
+
{
|
|
1557
|
+
name: "SouthAmerica"
|
|
1558
|
+
},
|
|
1559
|
+
{
|
|
1560
|
+
name: "Africa"
|
|
1561
|
+
},
|
|
1562
|
+
{
|
|
1563
|
+
name: "Oceania"
|
|
1564
|
+
},
|
|
1565
|
+
{
|
|
1566
|
+
name: "Other"
|
|
1567
|
+
}
|
|
1568
|
+
]
|
|
1569
|
+
}
|
|
1570
|
+
},
|
|
1571
|
+
{
|
|
1572
|
+
name: "RegionScore",
|
|
1573
|
+
docs: [
|
|
1574
|
+
"Health snapshot for one geographic region - embedded in NetworkHealthAccount"
|
|
1575
|
+
],
|
|
1576
|
+
type: {
|
|
1577
|
+
kind: "struct",
|
|
1578
|
+
fields: [
|
|
1579
|
+
{
|
|
1580
|
+
name: "region",
|
|
1581
|
+
docs: [
|
|
1582
|
+
"Which region this entry represents"
|
|
1583
|
+
],
|
|
1584
|
+
type: {
|
|
1585
|
+
defined: {
|
|
1586
|
+
name: "Region"
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
},
|
|
1590
|
+
{
|
|
1591
|
+
name: "observer_count",
|
|
1592
|
+
docs: [
|
|
1593
|
+
"Number of observer contributions currently represented in this region aggregate"
|
|
1594
|
+
],
|
|
1595
|
+
type: "u16"
|
|
1596
|
+
},
|
|
1597
|
+
{
|
|
1598
|
+
name: "health_score",
|
|
1599
|
+
docs: [
|
|
1600
|
+
"Health score from this region"
|
|
1601
|
+
],
|
|
1602
|
+
type: "u8"
|
|
1603
|
+
},
|
|
1604
|
+
{
|
|
1605
|
+
name: "reachability_pct",
|
|
1606
|
+
docs: [
|
|
1607
|
+
"TPU reachability % from this region"
|
|
1608
|
+
],
|
|
1609
|
+
type: "u8"
|
|
1610
|
+
},
|
|
1611
|
+
{
|
|
1612
|
+
name: "avg_rtt_us",
|
|
1613
|
+
docs: [
|
|
1614
|
+
"Average RTT from this region in microseconds"
|
|
1615
|
+
],
|
|
1616
|
+
type: "u32"
|
|
1617
|
+
},
|
|
1618
|
+
{
|
|
1619
|
+
name: "slot_latency_ms",
|
|
1620
|
+
docs: [
|
|
1621
|
+
"Slot propagation latency from this region (ms)"
|
|
1622
|
+
],
|
|
1623
|
+
type: "u32"
|
|
1624
|
+
},
|
|
1625
|
+
{
|
|
1626
|
+
name: "last_updated_slot",
|
|
1627
|
+
docs: [
|
|
1628
|
+
"Slot when this region last reported"
|
|
1629
|
+
],
|
|
1630
|
+
type: "u64"
|
|
1631
|
+
},
|
|
1632
|
+
{
|
|
1633
|
+
name: "total_health_score",
|
|
1634
|
+
docs: [
|
|
1635
|
+
"Running total of health scores for observers in this region"
|
|
1636
|
+
],
|
|
1637
|
+
type: "u32"
|
|
1638
|
+
},
|
|
1639
|
+
{
|
|
1640
|
+
name: "total_reachability_pct",
|
|
1641
|
+
docs: [
|
|
1642
|
+
"Running total of reachability percentages for observers in this region"
|
|
1643
|
+
],
|
|
1644
|
+
type: "u32"
|
|
1645
|
+
},
|
|
1646
|
+
{
|
|
1647
|
+
name: "total_avg_rtt_us",
|
|
1648
|
+
docs: [
|
|
1649
|
+
"Running total of RTT values for observers in this region"
|
|
1650
|
+
],
|
|
1651
|
+
type: "u64"
|
|
1652
|
+
},
|
|
1653
|
+
{
|
|
1654
|
+
name: "total_slot_latency_ms",
|
|
1655
|
+
docs: [
|
|
1656
|
+
"Running total of slot latency values for observers in this region"
|
|
1657
|
+
],
|
|
1658
|
+
type: "u64"
|
|
1659
|
+
},
|
|
1660
|
+
{
|
|
1661
|
+
name: "agave_count",
|
|
1662
|
+
docs: [
|
|
1663
|
+
"Client distribution counts for this region"
|
|
1664
|
+
],
|
|
1665
|
+
type: "u16"
|
|
1666
|
+
},
|
|
1667
|
+
{
|
|
1668
|
+
name: "firedancer_count",
|
|
1669
|
+
type: "u16"
|
|
1670
|
+
},
|
|
1671
|
+
{
|
|
1672
|
+
name: "jito_count",
|
|
1673
|
+
type: "u16"
|
|
1674
|
+
},
|
|
1675
|
+
{
|
|
1676
|
+
name: "solana_labs_count",
|
|
1677
|
+
type: "u16"
|
|
1678
|
+
},
|
|
1679
|
+
{
|
|
1680
|
+
name: "other_count",
|
|
1681
|
+
type: "u16"
|
|
1682
|
+
},
|
|
1683
|
+
{
|
|
1684
|
+
name: "total_agave_count",
|
|
1685
|
+
docs: [
|
|
1686
|
+
"Running totals"
|
|
1687
|
+
],
|
|
1688
|
+
type: "u32"
|
|
1689
|
+
},
|
|
1690
|
+
{
|
|
1691
|
+
name: "total_firedancer_count",
|
|
1692
|
+
type: "u32"
|
|
1693
|
+
},
|
|
1694
|
+
{
|
|
1695
|
+
name: "total_jito_count",
|
|
1696
|
+
type: "u32"
|
|
1697
|
+
},
|
|
1698
|
+
{
|
|
1699
|
+
name: "total_solana_labs_count",
|
|
1700
|
+
type: "u32"
|
|
1701
|
+
},
|
|
1702
|
+
{
|
|
1703
|
+
name: "total_other_count",
|
|
1704
|
+
type: "u32"
|
|
1705
|
+
},
|
|
1706
|
+
{
|
|
1707
|
+
name: "reachable_stake_pct",
|
|
1708
|
+
docs: [
|
|
1709
|
+
"Stake-weighted reachability for this region"
|
|
1710
|
+
],
|
|
1711
|
+
type: "u8"
|
|
1712
|
+
},
|
|
1713
|
+
{
|
|
1714
|
+
name: "total_reachable_stake_pct",
|
|
1715
|
+
type: "u32"
|
|
1716
|
+
}
|
|
1717
|
+
]
|
|
1718
|
+
}
|
|
1719
|
+
},
|
|
1720
|
+
{
|
|
1721
|
+
name: "RegistryAccount",
|
|
1722
|
+
docs: [
|
|
1723
|
+
"Global registry - tracks all observer nodes and program config"
|
|
1724
|
+
],
|
|
1725
|
+
type: {
|
|
1726
|
+
kind: "struct",
|
|
1727
|
+
fields: [
|
|
1728
|
+
{
|
|
1729
|
+
name: "authority",
|
|
1730
|
+
docs: [
|
|
1731
|
+
"Admin key"
|
|
1732
|
+
],
|
|
1733
|
+
type: "pubkey"
|
|
1734
|
+
},
|
|
1735
|
+
{
|
|
1736
|
+
name: "pending_authority",
|
|
1737
|
+
docs: [
|
|
1738
|
+
"Pending authority for handoff"
|
|
1739
|
+
],
|
|
1740
|
+
type: {
|
|
1741
|
+
option: "pubkey"
|
|
1742
|
+
}
|
|
1743
|
+
},
|
|
1744
|
+
{
|
|
1745
|
+
name: "min_stake_lamports",
|
|
1746
|
+
docs: [
|
|
1747
|
+
"Minimum stake required to observe"
|
|
1748
|
+
],
|
|
1749
|
+
type: "u64"
|
|
1750
|
+
},
|
|
1751
|
+
{
|
|
1752
|
+
name: "observer_count",
|
|
1753
|
+
docs: [
|
|
1754
|
+
"Number of observers"
|
|
1755
|
+
],
|
|
1756
|
+
type: "u16"
|
|
1757
|
+
},
|
|
1758
|
+
{
|
|
1759
|
+
name: "active_count",
|
|
1760
|
+
docs: [
|
|
1761
|
+
"Currently active accounts"
|
|
1762
|
+
],
|
|
1763
|
+
type: "u16"
|
|
1764
|
+
},
|
|
1765
|
+
{
|
|
1766
|
+
name: "max_observers",
|
|
1767
|
+
docs: [
|
|
1768
|
+
"Maximum number of observers"
|
|
1769
|
+
],
|
|
1770
|
+
type: "u16"
|
|
1771
|
+
},
|
|
1772
|
+
{
|
|
1773
|
+
name: "paused",
|
|
1774
|
+
docs: [
|
|
1775
|
+
"Paused flag"
|
|
1776
|
+
],
|
|
1777
|
+
type: "bool"
|
|
1778
|
+
},
|
|
1779
|
+
{
|
|
1780
|
+
name: "version",
|
|
1781
|
+
docs: [
|
|
1782
|
+
"Version of the registry"
|
|
1783
|
+
],
|
|
1784
|
+
type: "u8"
|
|
1785
|
+
},
|
|
1786
|
+
{
|
|
1787
|
+
name: "bump",
|
|
1788
|
+
docs: [
|
|
1789
|
+
"Bump seed for the PDA"
|
|
1790
|
+
],
|
|
1791
|
+
type: "u8"
|
|
1792
|
+
}
|
|
1793
|
+
]
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
],
|
|
1797
|
+
constants: [
|
|
1798
|
+
{
|
|
1799
|
+
name: "SEED",
|
|
1800
|
+
type: "string",
|
|
1801
|
+
value: '"anchor"'
|
|
1802
|
+
}
|
|
1803
|
+
]
|
|
1804
|
+
};
|
|
1805
|
+
|
|
1806
|
+
// src/instructions.ts
|
|
1807
|
+
var import_anchor = require("@coral-xyz/anchor");
|
|
1808
|
+
var import_bn2 = __toESM(require("bn.js"));
|
|
1809
|
+
var import_web33 = require("@solana/web3.js");
|
|
1810
|
+
var CLOCK_SYSVAR = new import_web33.PublicKey(
|
|
1811
|
+
"SysvarC1ock11111111111111111111111111111111"
|
|
1812
|
+
);
|
|
1813
|
+
function toAnchorRegion(region) {
|
|
1814
|
+
const map = {
|
|
1815
|
+
["Asia" /* Asia */]: "asia",
|
|
1816
|
+
["US" /* US */]: "us",
|
|
1817
|
+
["EU" /* EU */]: "eu",
|
|
1818
|
+
["SouthAmerica" /* SouthAmerica */]: "southAmerica",
|
|
1819
|
+
["Africa" /* Africa */]: "africa",
|
|
1820
|
+
["Oceania" /* Oceania */]: "oceania",
|
|
1821
|
+
["Other" /* Other */]: "other"
|
|
1822
|
+
};
|
|
1823
|
+
return { [map[region]]: {} };
|
|
1824
|
+
}
|
|
1825
|
+
async function buildRegisterObserver(program, observer, region) {
|
|
1826
|
+
const programId = program.programId;
|
|
1827
|
+
const [observerAccount] = getObserverPDA(observer, programId);
|
|
1828
|
+
const [registry] = getRegistryPDA(programId);
|
|
1829
|
+
return program.methods["registerObserver"](
|
|
1830
|
+
toAnchorRegion(region)
|
|
1831
|
+
).accounts({ observer, observerAccount, registry }).instruction();
|
|
1832
|
+
}
|
|
1833
|
+
async function buildSubmitAttestation(program, authority, params) {
|
|
1834
|
+
const programId = program.programId;
|
|
1835
|
+
const [observerAccount] = getObserverPDA(authority, programId);
|
|
1836
|
+
const [networkHealth] = getNetworkHealthPDA(programId);
|
|
1837
|
+
const [registry] = getRegistryPDA(programId);
|
|
1838
|
+
return program.methods["submitAttestation"](
|
|
1839
|
+
params.tpuReachable,
|
|
1840
|
+
params.tpuProbed,
|
|
1841
|
+
params.avgRttUs,
|
|
1842
|
+
params.p95RttUs,
|
|
1843
|
+
params.slotLatencyMs,
|
|
1844
|
+
params.agaveCount,
|
|
1845
|
+
params.firedancerCount,
|
|
1846
|
+
params.jitoCount,
|
|
1847
|
+
params.solanaLabsCount,
|
|
1848
|
+
params.otherCount,
|
|
1849
|
+
params.reachableStakePct
|
|
1850
|
+
).accounts({
|
|
1851
|
+
authority,
|
|
1852
|
+
observerAccount,
|
|
1853
|
+
networkHealth,
|
|
1854
|
+
registry,
|
|
1855
|
+
clock: CLOCK_SYSVAR
|
|
1856
|
+
}).instruction();
|
|
1857
|
+
}
|
|
1858
|
+
async function buildDeregisterObserver(program, caller, observerWallet) {
|
|
1859
|
+
const programId = program.programId;
|
|
1860
|
+
const [observerAccount] = getObserverPDA(observerWallet, programId);
|
|
1861
|
+
const [registry] = getRegistryPDA(programId);
|
|
1862
|
+
return program.methods["deregisterObserver"]().accounts({ caller, observerWallet, observerAccount, registry }).instruction();
|
|
1863
|
+
}
|
|
1864
|
+
async function buildCrankAggregation(program, cranker, observerAccounts) {
|
|
1865
|
+
const programId = program.programId;
|
|
1866
|
+
const [networkHealth] = getNetworkHealthPDA(programId);
|
|
1867
|
+
const [registryAccount] = getRegistryPDA(programId);
|
|
1868
|
+
const remaining = observerAccounts.map((pubkey) => ({
|
|
1869
|
+
pubkey,
|
|
1870
|
+
isSigner: false,
|
|
1871
|
+
isWritable: false
|
|
1872
|
+
}));
|
|
1873
|
+
return program.methods["crankAggregation"]().accounts({
|
|
1874
|
+
cranker,
|
|
1875
|
+
networkHealth,
|
|
1876
|
+
registryAccount,
|
|
1877
|
+
clock: CLOCK_SYSVAR
|
|
1878
|
+
}).remainingAccounts(remaining).instruction();
|
|
1879
|
+
}
|
|
1880
|
+
async function buildInitialize(program, authority, minStakeLamports, maxObservers) {
|
|
1881
|
+
const programId = program.programId;
|
|
1882
|
+
const [registry] = getRegistryPDA(programId);
|
|
1883
|
+
const [networkHealth] = getNetworkHealthPDA(programId);
|
|
1884
|
+
return program.methods["initialize"](
|
|
1885
|
+
new import_bn2.default(minStakeLamports.toString()),
|
|
1886
|
+
maxObservers
|
|
1887
|
+
).accounts({ authority, registry, networkHealth }).instruction();
|
|
1888
|
+
}
|
|
1889
|
+
async function buildSlashObserver(program, authority, observerWallet, treasury, slashBps) {
|
|
1890
|
+
const programId = program.programId;
|
|
1891
|
+
const [observerAccount] = getObserverPDA(observerWallet, programId);
|
|
1892
|
+
const [registry] = getRegistryPDA(programId);
|
|
1893
|
+
return program.methods["slashObserver"](
|
|
1894
|
+
slashBps
|
|
1895
|
+
).accounts({
|
|
1896
|
+
authority,
|
|
1897
|
+
observerWallet,
|
|
1898
|
+
observerAccount,
|
|
1899
|
+
registry,
|
|
1900
|
+
treasury
|
|
1901
|
+
}).instruction();
|
|
1902
|
+
}
|
|
1903
|
+
async function buildUpdateConfig(program, authority, params) {
|
|
1904
|
+
const programId = program.programId;
|
|
1905
|
+
const [registry] = getRegistryPDA(programId);
|
|
1906
|
+
const minStake = params.minStakeLamports != null ? new import_bn2.default(params.minStakeLamports.toString()) : null;
|
|
1907
|
+
return program.methods["updateConfig"](
|
|
1908
|
+
minStake,
|
|
1909
|
+
params.maxObservers,
|
|
1910
|
+
params.paused
|
|
1911
|
+
).accounts({ authority, registry }).instruction();
|
|
1912
|
+
}
|
|
1913
|
+
async function buildProposeAuthority(program, authority, newAuthority) {
|
|
1914
|
+
const programId = program.programId;
|
|
1915
|
+
const [registry] = getRegistryPDA(programId);
|
|
1916
|
+
return program.methods["proposeAuthority"](
|
|
1917
|
+
newAuthority
|
|
1918
|
+
).accounts({ authority, registry }).instruction();
|
|
1919
|
+
}
|
|
1920
|
+
async function buildAcceptAuthority(program, newAuthority) {
|
|
1921
|
+
const programId = program.programId;
|
|
1922
|
+
const [registry] = getRegistryPDA(programId);
|
|
1923
|
+
return program.methods["acceptAuthority"]().accounts({ newAuthority, registry }).instruction();
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
// src/events.ts
|
|
1927
|
+
var import_web34 = require("@solana/web3.js");
|
|
1928
|
+
var import_bn3 = require("bn.js");
|
|
1929
|
+
function toBigInt2(val) {
|
|
1930
|
+
if (typeof val === "bigint") return val;
|
|
1931
|
+
if (typeof val === "number") return BigInt(val);
|
|
1932
|
+
return BigInt(val.toString());
|
|
1933
|
+
}
|
|
1934
|
+
function toRegion2(val) {
|
|
1935
|
+
const key = typeof val === "string" ? val : Object.keys(val)[0] ?? "other";
|
|
1936
|
+
const normalized = key.charAt(0).toUpperCase() + key.slice(1).toLowerCase();
|
|
1937
|
+
const map = {
|
|
1938
|
+
Asia: "Asia",
|
|
1939
|
+
Us: "US",
|
|
1940
|
+
Eu: "EU",
|
|
1941
|
+
Southamerica: "SouthAmerica",
|
|
1942
|
+
Africa: "Africa",
|
|
1943
|
+
Oceania: "Oceania",
|
|
1944
|
+
Other: "Other"
|
|
1945
|
+
};
|
|
1946
|
+
return map[normalized] ?? "Other";
|
|
1947
|
+
}
|
|
1948
|
+
function decodeAttestationSubmitted(raw) {
|
|
1949
|
+
return {
|
|
1950
|
+
observer: raw["observer"],
|
|
1951
|
+
region: toRegion2(raw["region"]),
|
|
1952
|
+
score: raw["score"],
|
|
1953
|
+
reachabilityPct: raw["reachabilityPct"],
|
|
1954
|
+
slotLatencyMs: raw["slotLatencyMs"],
|
|
1955
|
+
slot: toBigInt2(raw["slot"]),
|
|
1956
|
+
agaveCount: raw["agaveCount"],
|
|
1957
|
+
firedancerCount: raw["firedancerCount"],
|
|
1958
|
+
jitoCount: raw["jitoCount"],
|
|
1959
|
+
solanaLabsCount: raw["solanaLabsCount"],
|
|
1960
|
+
otherCount: raw["otherCount"],
|
|
1961
|
+
reachableStakePct: raw["reachableStakePct"]
|
|
1962
|
+
};
|
|
1963
|
+
}
|
|
1964
|
+
function decodeObserverRegistered(raw) {
|
|
1965
|
+
return {
|
|
1966
|
+
observer: raw["observer"],
|
|
1967
|
+
region: toRegion2(raw["region"]),
|
|
1968
|
+
stakeLamports: toBigInt2(raw["stakeLamports"])
|
|
1969
|
+
};
|
|
1970
|
+
}
|
|
1971
|
+
function decodeObserverDeregistered(raw) {
|
|
1972
|
+
return {
|
|
1973
|
+
observer: raw["observer"]
|
|
1974
|
+
};
|
|
1975
|
+
}
|
|
1976
|
+
function decodeObserverSlashed(raw) {
|
|
1977
|
+
return {
|
|
1978
|
+
observer: raw["observer"],
|
|
1979
|
+
slashBps: raw["slashBps"],
|
|
1980
|
+
amountSlashed: toBigInt2(raw["amountSlashed"])
|
|
1981
|
+
};
|
|
1982
|
+
}
|
|
1983
|
+
function decodeConfigUpdated(raw) {
|
|
1984
|
+
const minStake = raw["minStakeLamports"];
|
|
1985
|
+
const maxObs = raw["maxObservers"];
|
|
1986
|
+
const paused = raw["paused"];
|
|
1987
|
+
return {
|
|
1988
|
+
minStakeLamports: minStake != null ? toBigInt2(minStake) : null,
|
|
1989
|
+
maxObservers: maxObs != null ? maxObs : null,
|
|
1990
|
+
paused: paused != null ? paused : null
|
|
1991
|
+
};
|
|
1992
|
+
}
|
|
1993
|
+
|
|
1994
|
+
// src/client.ts
|
|
1995
|
+
var READ_ONLY_PUBKEY = new import_web35.PublicKey("11111111111111111111111111111111");
|
|
1996
|
+
function createReadOnlyWallet() {
|
|
1997
|
+
return {
|
|
1998
|
+
publicKey: READ_ONLY_PUBKEY,
|
|
1999
|
+
payer: import_web35.Keypair.generate(),
|
|
2000
|
+
signTransaction: async (tx) => tx,
|
|
2001
|
+
signAllTransactions: async (txs) => txs
|
|
2002
|
+
};
|
|
2003
|
+
}
|
|
2004
|
+
function createS0racleClient(opts) {
|
|
2005
|
+
const { connection } = opts;
|
|
2006
|
+
const programId = opts.programId ?? PROGRAM_ID;
|
|
2007
|
+
const wallet = opts.wallet ?? createReadOnlyWallet();
|
|
2008
|
+
const provider = new import_anchor2.AnchorProvider(connection, wallet, {
|
|
2009
|
+
commitment: "confirmed"
|
|
2010
|
+
});
|
|
2011
|
+
const idl = { ...s0racle_program_default, address: programId.toBase58() };
|
|
2012
|
+
const program = new import_anchor2.Program(idl, provider);
|
|
2013
|
+
async function getNetworkHealth() {
|
|
2014
|
+
const [pda] = getNetworkHealthPDA(programId);
|
|
2015
|
+
const raw = await program.account["networkHealthAccount"].fetch(pda);
|
|
2016
|
+
return decodeNetworkHealth(raw);
|
|
2017
|
+
}
|
|
2018
|
+
async function getRegistry() {
|
|
2019
|
+
const [pda] = getRegistryPDA(programId);
|
|
2020
|
+
const raw = await program.account["registryAccount"].fetch(pda);
|
|
2021
|
+
return decodeRegistry(raw);
|
|
2022
|
+
}
|
|
2023
|
+
async function getObserver(observerPubkey) {
|
|
2024
|
+
const [pda] = getObserverPDA(observerPubkey, programId);
|
|
2025
|
+
const raw = await program.account["observerAccount"].fetch(pda);
|
|
2026
|
+
return decodeObserver(raw, pda);
|
|
2027
|
+
}
|
|
2028
|
+
async function getAllObservers() {
|
|
2029
|
+
const all = await program.account["observerAccount"].all();
|
|
2030
|
+
return all.map(
|
|
2031
|
+
(entry) => decodeObserver(entry.account, entry.publicKey)
|
|
2032
|
+
);
|
|
2033
|
+
}
|
|
2034
|
+
async function getObserversByRegion(region) {
|
|
2035
|
+
const all = await getAllObservers();
|
|
2036
|
+
return all.filter((o) => o.region === region);
|
|
2037
|
+
}
|
|
2038
|
+
return {
|
|
2039
|
+
programId,
|
|
2040
|
+
connection,
|
|
2041
|
+
// Reads
|
|
2042
|
+
getNetworkHealth,
|
|
2043
|
+
getRegistry,
|
|
2044
|
+
getObserver,
|
|
2045
|
+
getAllObservers,
|
|
2046
|
+
getObserversByRegion,
|
|
2047
|
+
// Instruction builders
|
|
2048
|
+
registerObserver: (observer, region) => buildRegisterObserver(program, observer, region),
|
|
2049
|
+
submitAttestation: (authority, params) => buildSubmitAttestation(program, authority, params),
|
|
2050
|
+
deregisterObserver: (caller, observerWallet) => buildDeregisterObserver(program, caller, observerWallet),
|
|
2051
|
+
crankAggregation: (cranker, observerAccounts) => buildCrankAggregation(program, cranker, observerAccounts),
|
|
2052
|
+
initialize: (authority, minStakeLamports, maxObservers) => buildInitialize(program, authority, minStakeLamports, maxObservers),
|
|
2053
|
+
slashObserver: (authority, observerWallet, treasury, slashBps) => buildSlashObserver(
|
|
2054
|
+
program,
|
|
2055
|
+
authority,
|
|
2056
|
+
observerWallet,
|
|
2057
|
+
treasury,
|
|
2058
|
+
slashBps
|
|
2059
|
+
),
|
|
2060
|
+
updateConfig: (authority, params) => buildUpdateConfig(program, authority, params),
|
|
2061
|
+
proposeAuthority: (authority, newAuthority) => buildProposeAuthority(program, authority, newAuthority),
|
|
2062
|
+
acceptAuthority: (newAuthority) => buildAcceptAuthority(program, newAuthority),
|
|
2063
|
+
// Event subscriptions
|
|
2064
|
+
onAttestationSubmitted: (callback) => program.addEventListener(
|
|
2065
|
+
"attestationSubmitted",
|
|
2066
|
+
(raw, slot) => callback(
|
|
2067
|
+
decodeAttestationSubmitted(raw),
|
|
2068
|
+
slot
|
|
2069
|
+
)
|
|
2070
|
+
),
|
|
2071
|
+
onObserverRegistered: (callback) => program.addEventListener(
|
|
2072
|
+
"observerRegistered",
|
|
2073
|
+
(raw, slot) => callback(
|
|
2074
|
+
decodeObserverRegistered(raw),
|
|
2075
|
+
slot
|
|
2076
|
+
)
|
|
2077
|
+
),
|
|
2078
|
+
onObserverDeregistered: (callback) => program.addEventListener(
|
|
2079
|
+
"observerDeregistered",
|
|
2080
|
+
(raw, slot) => callback(
|
|
2081
|
+
decodeObserverDeregistered(raw),
|
|
2082
|
+
slot
|
|
2083
|
+
)
|
|
2084
|
+
),
|
|
2085
|
+
onObserverSlashed: (callback) => program.addEventListener(
|
|
2086
|
+
"observerSlashed",
|
|
2087
|
+
(raw, slot) => callback(decodeObserverSlashed(raw), slot)
|
|
2088
|
+
),
|
|
2089
|
+
onConfigUpdated: (callback) => program.addEventListener(
|
|
2090
|
+
"configUpdated",
|
|
2091
|
+
(raw, slot) => callback(decodeConfigUpdated(raw), slot)
|
|
2092
|
+
),
|
|
2093
|
+
removeEventListener: (listenerId) => program.removeEventListener(listenerId)
|
|
2094
|
+
};
|
|
2095
|
+
}
|
|
2096
|
+
|
|
2097
|
+
// src/utils.ts
|
|
2098
|
+
var DEFAULT_DEGRADED_THRESHOLD = 70;
|
|
2099
|
+
var DEFAULT_CRITICAL_THRESHOLD = 40;
|
|
2100
|
+
function isStale(networkHealth, currentSlot) {
|
|
2101
|
+
return currentSlot - networkHealth.lastUpdatedSlot > STALE_SLOTS;
|
|
2102
|
+
}
|
|
2103
|
+
function isObserverStale(observer, currentSlot) {
|
|
2104
|
+
return currentSlot - observer.lastAttestationSlot > STALE_SLOTS;
|
|
2105
|
+
}
|
|
2106
|
+
function isDegraded(networkHealth, threshold = DEFAULT_DEGRADED_THRESHOLD) {
|
|
2107
|
+
return networkHealth.healthScore < threshold;
|
|
2108
|
+
}
|
|
2109
|
+
function healthStatus(networkHealth, currentSlot) {
|
|
2110
|
+
if (currentSlot !== void 0 && isStale(networkHealth, currentSlot)) {
|
|
2111
|
+
return "stale";
|
|
2112
|
+
}
|
|
2113
|
+
if (networkHealth.healthScore < DEFAULT_CRITICAL_THRESHOLD) return "critical";
|
|
2114
|
+
if (networkHealth.healthScore < DEFAULT_DEGRADED_THRESHOLD) return "degraded";
|
|
2115
|
+
return "healthy";
|
|
2116
|
+
}
|
|
2117
|
+
function regionLabel(region) {
|
|
2118
|
+
switch (region) {
|
|
2119
|
+
case "Asia" /* Asia */:
|
|
2120
|
+
return "Asia";
|
|
2121
|
+
case "US" /* US */:
|
|
2122
|
+
return "United States";
|
|
2123
|
+
case "EU" /* EU */:
|
|
2124
|
+
return "Europe";
|
|
2125
|
+
case "SouthAmerica" /* SouthAmerica */:
|
|
2126
|
+
return "South America";
|
|
2127
|
+
case "Africa" /* Africa */:
|
|
2128
|
+
return "Africa";
|
|
2129
|
+
case "Oceania" /* Oceania */:
|
|
2130
|
+
return "Oceania";
|
|
2131
|
+
case "Other" /* Other */:
|
|
2132
|
+
return "Other";
|
|
2133
|
+
}
|
|
2134
|
+
}
|
|
2135
|
+
function lamportsToSol(lamports) {
|
|
2136
|
+
return Number(lamports) / 1e9;
|
|
2137
|
+
}
|
|
2138
|
+
function latencyScore(slotLatencyMs) {
|
|
2139
|
+
if (slotLatencyMs >= 400) return 0;
|
|
2140
|
+
return Math.floor((400 - slotLatencyMs) * 100 / 400);
|
|
2141
|
+
}
|
|
2142
|
+
function isConsensusCritical(reachableStakePct) {
|
|
2143
|
+
return reachableStakePct < 67;
|
|
2144
|
+
}
|
|
2145
|
+
function stakeReachStatus(reachableStakePct) {
|
|
2146
|
+
if (reachableStakePct >= 80) return "healthy";
|
|
2147
|
+
if (reachableStakePct >= 67) return "degraded";
|
|
2148
|
+
return "critical";
|
|
2149
|
+
}
|
|
2150
|
+
function dominantClient(region) {
|
|
2151
|
+
const counts = {
|
|
2152
|
+
agave: region.agaveCount,
|
|
2153
|
+
firedancer: region.firedancerCount,
|
|
2154
|
+
jito: region.jitoCount,
|
|
2155
|
+
other: region.otherCount + region.solanaLabsCount
|
|
2156
|
+
};
|
|
2157
|
+
return Object.entries(counts).sort((a, b) => b[1] - a[1])[0][0];
|
|
2158
|
+
}
|
|
2159
|
+
function clientDiversityIndex(region) {
|
|
2160
|
+
const total = region.agaveCount + region.firedancerCount + region.jitoCount + region.solanaLabsCount + region.otherCount;
|
|
2161
|
+
if (total === 0) return 0;
|
|
2162
|
+
const shares = [
|
|
2163
|
+
region.agaveCount,
|
|
2164
|
+
region.firedancerCount,
|
|
2165
|
+
region.jitoCount,
|
|
2166
|
+
region.solanaLabsCount,
|
|
2167
|
+
region.otherCount
|
|
2168
|
+
].map((c) => c / total);
|
|
2169
|
+
const hhi = shares.reduce((sum, s) => sum + s * s, 0);
|
|
2170
|
+
return Math.round((1 - hhi) * 125);
|
|
2171
|
+
}
|
|
2172
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
2173
|
+
0 && (module.exports = {
|
|
2174
|
+
PROGRAM_ID,
|
|
2175
|
+
Region,
|
|
2176
|
+
clientDiversityIndex,
|
|
2177
|
+
createS0racleClient,
|
|
2178
|
+
dominantClient,
|
|
2179
|
+
getNetworkHealthPDA,
|
|
2180
|
+
getObserverPDA,
|
|
2181
|
+
getRegistryPDA,
|
|
2182
|
+
healthStatus,
|
|
2183
|
+
isConsensusCritical,
|
|
2184
|
+
isDegraded,
|
|
2185
|
+
isObserverStale,
|
|
2186
|
+
isStale,
|
|
2187
|
+
lamportsToSol,
|
|
2188
|
+
latencyScore,
|
|
2189
|
+
regionLabel,
|
|
2190
|
+
stakeReachStatus
|
|
2191
|
+
});
|
|
2192
|
+
//# sourceMappingURL=index.js.map
|