@bug-fix/drand-client
Version:
A client to the drand randomness beacon network.
70 lines (59 loc) • 2.1 kB
text/typescript
import {ChainInfo} from './index'
// this is generated by the `precompile` npm script
// using the package.json version itself messes with the generated javascript, so it must be known
// at compile time
import {LIB_VERSION} from './version'
export function sleep(timeMs: number): Promise<void> {
return new Promise(resolve => {
if (timeMs <= 0) {
resolve()
}
setTimeout(resolve, timeMs)
})
}
export function roundAt(time: number, chain: ChainInfo) {
if (!Number.isFinite(time)) {
throw new Error('Cannot use Infinity or NaN as a beacon time')
}
if (time < chain.genesis_time * 1000) {
throw Error('Cannot request a round before the genesis time')
}
return Math.floor((time - (chain.genesis_time * 1000)) / (chain.period * 1000)) + 1
}
export function roundTime(chain: ChainInfo, round: number) {
if (!Number.isFinite(round)) {
throw new Error('Cannot use Infinity or NaN as a round number')
}
round = round < 0 ? 0 : round
return (chain.genesis_time + (round - 1) * chain.period) * 1000
}
export type HttpOptions = {
userAgent?: string
headers?: Record<string, string>
}
// taking a separate `userAgent` param for backwards compatibility
export const defaultHttpOptions: HttpOptions = {
userAgent: `drand-client-${LIB_VERSION}`,
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export async function jsonOrError(url: string, options: HttpOptions = defaultHttpOptions): Promise<any> {
const headers = {...options.headers}
if (options.userAgent) {
headers['User-Agent'] = options.userAgent
}
const response = await fetch(url, {headers})
if (!response.ok) {
throw Error(`Error response fetching ${url} - got ${response.status}`)
}
return await response.json()
}
export async function retryOnError<T>(fn: () => Promise<T>, times: number): Promise<T> {
try {
return await fn()
} catch (err) {
if (times === 0) {
throw err
}
return retryOnError(fn, times - 1)
}
}