Appearance
TypeScript SDK
@verity-vrf/sdk, built on viem.
ts
import { createPublicClient, createWalletClient, custom, http, parseEther } from 'viem'
import { VerityCoordinator, deployments, pulsechainTestnet, waitForFulfillment, getActivity } from '@verity-vrf/sdk'
const { coordinator, startBlock, keyHashes } = deployments[943]!
const publicClient = createPublicClient({ chain: pulsechainTestnet, transport: http() })
const verity = new VerityCoordinator(coordinator, publicClient, walletClient)verity.createSubscription({ fund? }) | Returns the subscription id |
verity.fundSubscription(id, amount), addConsumer, removeConsumer, cancelSubscription, owner transfer | Wait for the receipt; throw if the transaction reverted |
verity.getSubscription(id) | balance, reserved, available, pending requests, owner, consumers |
verity.getConfig(), verity.getLanes(), verity.estimateRequestCost(keyHash, gas) | |
listSubscriptions(client, { coordinator, owner, fromBlock }) | Live subscriptions owned by an address |
getRequestStatus(client, { coordinator, requestId, fromBlock }) | pending / fulfilled (words, payment, callbackSuccess) / cancelled / unknown |
waitForFulfillment(client, opts) | Resolves on fulfilment; rejects on cancellation or timeout |
getActivity(client, { coordinator, fromBlock }) | Every request with its fulfilment, delay percentiles and totals |
computeRequestId, computePreSeed, deriveWords, keyHashOf | Pure helpers, identical to the contract |
pulsechain, pulsechainTestnet, deployments | Chains and official addresses |
When reading logs yourself with viem, call getBlockNumber({ cacheTime: 0 }). The default cache can hide events from the last few seconds.
Indexer API and fallback
VerityApi is a typed client for the verity-indexer HTTP API (subscriptions, requests, stats and time series, gas lanes, operators, governance, search) and its live stream. VerityData is what apps should read through: it uses the API when it is reachable and up to date, and otherwise reads the chain directly with the functions above. Every answer says where it came from.
ts
import { VerityApi, VerityData, deployments } from '@verity-vrf/sdk'
const d = deployments[943]!
const api = new VerityApi({ baseUrl: 'https://<indexer>/v1', chainId: 943 })
const data = new VerityData({ publicClient, coordinator: d.coordinator, fromBlock: d.startBlock, api })
const { data: sub, source } = await data.getSubscription(1n) // source: 'api' | 'chain'
sub.details?.lowBalance // extra fields only the API has (history counters, low-balance hint, ...)
await data.getRequestStatus(requestId)
await data.listSubscriptions(owner)
await data.getActivity({ limit: 25 })
// live updates; onDisabled fires if the server switched the stream off (then poll)
const s = api.subscribe({ subId: 1n, onMessage: (m) => console.log(m.kind, m.data), onDisabled: startPolling })
s.close()Falls back to the chain on network errors, timeouts, 429, 5xx, an index more than maxLagBlocks (default 20) behind, and 404s for things the index may not have seen yet. Bad input (400) is not retried.