solana/web3.js/src/validator-info.ts

107 lines
2.5 KiB
TypeScript
Raw Normal View History

import {Buffer} from 'buffer';
import {
assert as assertType,
optional,
string,
type as pick,
} from 'superstruct';
import * as Layout from './layout';
import * as shortvec from './util/shortvec-encoding';
import {PublicKey} from './publickey';
2019-07-24 16:01:07 -07:00
export const VALIDATOR_INFO_KEY = new PublicKey(
'Va1idator1nfo111111111111111111111111111111',
);
/**
2021-03-14 20:01:35 -07:00
* @internal
*/
2021-03-14 20:01:35 -07:00
type ConfigKey = {
publicKey: PublicKey;
isSigner: boolean;
};
/**
* Info used to identity validators.
*/
2021-03-14 20:01:35 -07:00
export type Info = {
2021-03-31 03:48:41 -07:00
/** validator name */
2021-03-14 20:01:35 -07:00
name: string;
2021-03-31 03:48:41 -07:00
/** optional, validator website */
2021-03-14 20:01:35 -07:00
website?: string;
2021-03-31 03:48:41 -07:00
/** optional, extra information the validator chose to share */
2021-03-14 20:01:35 -07:00
details?: string;
2021-03-31 03:48:41 -07:00
/** optional, used to identify validators on keybase.io */
2021-03-14 20:01:35 -07:00
keybaseUsername?: string;
};
const InfoString = pick({
name: string(),
website: optional(string()),
details: optional(string()),
keybaseUsername: optional(string()),
});
/**
* ValidatorInfo class
*/
export class ValidatorInfo {
/**
* validator public key
*/
key: PublicKey;
/**
* validator information
*/
info: Info;
/**
* Construct a valid ValidatorInfo
*
* @param key validator public key
* @param info validator information
*/
constructor(key: PublicKey, info: Info) {
this.key = key;
this.info = info;
}
/**
* Deserialize ValidatorInfo from the config account data. Exactly two config
* keys are required in the data.
*
* @param buffer config account data
* @return null if info was not found
*/
2020-02-14 06:33:11 -08:00
static fromConfigData(
buffer: Buffer | Uint8Array | Array<number>,
): ValidatorInfo | null {
const PUBKEY_LENGTH = 32;
let byteArray = [...buffer];
const configKeyCount = shortvec.decodeLength(byteArray);
if (configKeyCount !== 2) return null;
const configKeys: Array<ConfigKey> = [];
for (let i = 0; i < 2; i++) {
const publicKey = new PublicKey(byteArray.slice(0, PUBKEY_LENGTH));
byteArray = byteArray.slice(PUBKEY_LENGTH);
const isSigner = byteArray.slice(0, 1)[0] === 1;
byteArray = byteArray.slice(1);
configKeys.push({publicKey, isSigner});
}
if (configKeys[0].publicKey.equals(VALIDATOR_INFO_KEY)) {
if (configKeys[1].isSigner) {
const rawInfo: any = Layout.rustString().decode(Buffer.from(byteArray));
const info = JSON.parse(rawInfo as string);
assertType(info, InfoString);
return new ValidatorInfo(configKeys[1].publicKey, info);
}
}
return null;
}
}