import { assertAccountExists, decodeAccount, type FetchAccountConfig } from '@solana/accounts'; import { combineCodec, type FixedSizeCodec, type FixedSizeDecoder, type FixedSizeEncoder } from '@solana/codecs-core'; import { getStructDecoder, getStructEncoder } from '@solana/codecs-data-structures'; import { getI64Decoder, getI64Encoder, getU64Decoder, getU64Encoder } from '@solana/codecs-numbers'; import type { GetAccountInfoApi } from '@solana/rpc-api'; import type { Rpc } from '@solana/rpc-spec'; import type { Epoch, Slot, UnixTimestamp } from '@solana/rpc-types'; import { fetchEncodedSysvarAccount, SYSVAR_CLOCK_ADDRESS } from './sysvar'; type SysvarClockSize = 40; /** * Contains data on cluster time, including the current slot, epoch, and estimated wall-clock Unix * timestamp. It is updated every slot. */ export type SysvarClock = Readonly<{ /** The current epoch */ epoch: Epoch; /** * The Unix timestamp of the first slot in this epoch. * * In the first slot of an epoch, this timestamp is identical to the `unixTimestamp`. */ epochStartTimestamp: UnixTimestamp; /** The most recent epoch for which the leader schedule has already been generated */ leaderScheduleEpoch: Epoch; /** The current slot */ slot: Slot; /** The Unix timestamp of this slot */ unixTimestamp: UnixTimestamp; }>; /** * Returns an encoder that you can use to encode a {@link SysvarClock} to a byte array representing * the `Clock` sysvar's account data. */ export function getSysvarClockEncoder(): FixedSizeEncoder { return getStructEncoder([ ['slot', getU64Encoder()], ['epochStartTimestamp', getI64Encoder()], ['epoch', getU64Encoder()], ['leaderScheduleEpoch', getU64Encoder()], ['unixTimestamp', getI64Encoder()], ]) as FixedSizeEncoder; } /** * Returns a decoder that you can use to decode a byte array representing the `Clock` sysvar's * account data to a {@link SysvarClock}. */ export function getSysvarClockDecoder(): FixedSizeDecoder { return getStructDecoder([ ['slot', getU64Decoder()], ['epochStartTimestamp', getI64Decoder()], ['epoch', getU64Decoder()], ['leaderScheduleEpoch', getU64Decoder()], ['unixTimestamp', getI64Decoder()], ]) as FixedSizeDecoder; } /** * Returns a codec that you can use to encode from or decode to {@link SysvarClock} * * @see {@link getSysvarClockDecoder} * @see {@link getSysvarClockEncoder} */ export function getSysvarClockCodec(): FixedSizeCodec { return combineCodec(getSysvarClockEncoder(), getSysvarClockDecoder()); } /** * Fetches the `Clock` sysvar account using any RPC that supports the {@link GetAccountInfoApi}. */ export async function fetchSysvarClock(rpc: Rpc, config?: FetchAccountConfig): Promise { const account = await fetchEncodedSysvarAccount(rpc, SYSVAR_CLOCK_ADDRESS, config); assertAccountExists(account); const decoded = decodeAccount(account, getSysvarClockDecoder()); return decoded.data; }