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

104 lines
2.5 KiB
JavaScript

// @flow
import {struct} from 'superstruct';
import * as Layout from './layout';
import * as shortvec from './util/shortvec-encoding';
import {PublicKey} from './publickey';
export const VALIDATOR_INFO_KEY = new PublicKey(
'Va1idator1nfo111111111111111111111111111111',
);
/**
* @private
*/
type ConfigKey = {|
publicKey: PublicKey,
isSigner: boolean,
|};
/**
* Info used to identity validators.
*
* @typedef {Object} Info
* @property {string} name validator name
* @property {?string} website optional, validator website
* @property {?string} details optional, extra information the validator chose to share
* @property {?string} keybaseUsername optional, used to identify validators on keybase.io
*/
export type Info = {|
name: string,
website?: string,
details?: string,
keybaseUsername?: string,
|};
const InfoString = struct({
name: 'string',
website: 'string?',
details: 'string?',
keybaseUsername: '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
*/
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 = Layout.rustString().decode(Buffer.from(byteArray));
const info = InfoString(JSON.parse(rawInfo));
return new ValidatorInfo(configKeys[1].publicKey, info);
}
}
return null;
}
}