@polkadot/types/interfaces#Header TypeScript Examples
The following examples show how to use
@polkadot/types/interfaces#Header.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: base-provider.ts From bodhi.js with Apache License 2.0 | 6 votes |
_getBlockHeader = async (blockTag?: BlockTag | Promise<BlockTag>): Promise<Header> => {
const blockHash = await this._getBlockHash(blockTag);
try {
const header = await this.api.rpc.chain.getHeader(blockHash);
return header;
} catch (error) {
if (
typeof error === 'object' &&
typeof (error as any).message === 'string' &&
(error as any).message.match(/Unable to retrieve header and parent from supplied hash/gi)
) {
//@ts-ignore
return logger.throwError('header not found', PROVIDER_ERRORS.HEADER_NOT_FOUND);
}
throw error;
}
};
Example #2
Source File: index.ts From community-repo with GNU General Public License v3.0 | 6 votes |
(async () => {
const client = new Discord.Client({ intents: [Intents.FLAGS.GUILDS] });
client.once("ready", async () => {
console.log('Discord.js client ready');
Object.values(workingGroups).forEach( async (mappedChannel: string) => {
await client.channels.fetch(mappedChannel);
})
});
await client.login(discordBotToken);
console.log('Bot logged in successfully');
connectUpstream().then( async (api: ApiPromise) => {
api.rpc.chain.subscribeNewHeads(async (header: Header) => {
const id = +header.number;
await processBlock(api, client, id);
})
})
})()
Example #3
Source File: BestHash.tsx From crust-apps with Apache License 2.0 | 6 votes |
function BestHash ({ className = '', label }: Props): React.ReactElement<Props> {
const { api } = useApi();
const newHead = useCall<Header>(api.rpc.chain.subscribeNewHeads);
return (
<div className={className}>
{label || ''}{newHead?.hash.toHex()}
</div>
);
}
Example #4
Source File: Provider.tsx From gear-js with GNU General Public License v3.0 | 6 votes |
useBlocks = () => {
const { api } = useApi();
const [blocks, setBlocks] = useState<Blocks>([]);
const getTime = (timestamp: number) => new Date(timestamp).toLocaleTimeString();
const getBlock = ({ hash, number }: Header, time: string) => ({
hash: hash.toHex(),
number: number.toNumber(),
time,
});
const updateBlocks = (block: Block) => {
setBlocks((prevBlocks) => {
const blocksTail = prevBlocks.length > 9 ? prevBlocks.slice(0, -1) : prevBlocks;
return [block, ...blocksTail];
});
};
const handleSubscription = (header: Header) =>
api.blocks
.getBlockTimestamp(header.hash)
.then((timestamp) => getTime(timestamp.toNumber()))
.then((time) => getBlock(header, time))
.then(updateBlocks);
const subscribeToBlocks = () => api.gearEvents.subscribeToNewBlocks(handleSubscription);
useSubscription(subscribeToBlocks);
return blocks;
}
Example #5
Source File: SubstrateService.ts From squid with GNU General Public License v3.0 | 6 votes |
async subscribeToHeads(): Promise<void> {
debug(`Subscribing to new heads`)
const api = await getApiPromise()
api.rx.rpc.chain.subscribeFinalizedHeads().subscribe({
next: (header: Header) =>
eventEmitter.emit(IndexerEvents.NEW_FINALIZED_HEAD, {
header,
height: header.number.toNumber(),
}),
})
api.rx.rpc.chain.subscribeNewHeads().subscribe({
next: (header: Header) =>
eventEmitter.emit(IndexerEvents.NEW_BEST_HEAD, {
header,
height: header.number.toNumber(),
}),
})
api.rx.rpc.chain.subscribeAllHeads().subscribe({
next: (header: Header) =>
eventEmitter.emit(IndexerEvents.NEW_HEAD, {
header,
height: header.number.toNumber(),
}),
})
}
Example #6
Source File: subscriber.ts From polkadot-watcher-csv-exporter with Apache License 2.0 | 6 votes |
private _writeCSVHandler = async (header: Header): Promise<void> =>{
if(this._isCSVWriteLocked()) return
const deriveSessionProgress = await this.api.derive.session.progress();
if (!this.config.sessionOnly == true && await this._isEndEraBlock(deriveSessionProgress)) {
this.logger.info(`starting the CSV writing for the session ${deriveSessionProgress.currentIndex} and the era ${deriveSessionProgress.currentEra}`)
this._lockCSVWrite()
await this._writeEraCSV(deriveSessionProgress.activeEra, deriveSessionProgress.currentIndex, header.number)
this._setCSVUploadable(true)
}
else if (await this._isEndSessionBlock(deriveSessionProgress)) {
this.logger.info(`starting the CSV writing for the session ${deriveSessionProgress.currentIndex}`)
this._lockCSVWrite()
await this._writeSessionCSV(deriveSessionProgress.currentEra, deriveSessionProgress.currentIndex, header.number);
this._setCSVUploadable(true)
}
}
Example #7
Source File: tests.ts From community-repo with GNU General Public License v3.0 | 5 votes |
main = async () => {
const provider = new WsProvider(wsLocation);
const api = await ApiPromise.create({ provider, types });
await api.isReady;
const [chain, node, version] = await Promise.all([
api.rpc.system.chain(),
api.rpc.system.name(),
api.rpc.system.version(),
]);
log(`Connected to ${chain} on ${node} v${version}`);
let council: Council = { round: 0, last: "" };
let lastBlock: number = 0;
let proposals: Proposals = {
last: 1,
current: 2,
active: [],
executing: [],
};
let categories = [0, 0];
let posts = [0, 0];
let channels = [0, 0];
const unsubscribe = await api.rpc.chain.subscribeNewHeads(
async (block: Header): Promise<void> => {
// council
if (lastBlock > 0) process.exit;
lastBlock = block.number.toNumber();
const currentBlock = block.number.toNumber();
log("current council");
council = await announce.council(api, council, currentBlock, sendMessage);
lastBlock = currentBlock;
log("first proposal");
announce.proposals(api, proposals, lastBlock, sendMessage);
log("last proposal");
proposals.current = await get.proposalCount(api);
proposals.last = proposals.current - 1;
announce.proposals(api, proposals, lastBlock, sendMessage);
log("first category");
announce.categories(api, categories, sendMessage);
log("last category");
categories[1] = await get.currentCategoryId(api);
categories[0] = categories[1] - 1;
announce.categories(api, categories, sendMessage);
log("first post");
announce.posts(api, posts, sendMessage);
log("last post");
posts[1] = await get.currentPostId(api);
posts[0] = posts[1] - 1;
announce.posts(api, posts, sendMessage);
log("first channel");
announce.channels(api, channels, sendMessage);
log("last channel");
channels[1] = await get.currentChannelId(api);
channels[0] = channels[1] - 1;
announce.channels(api, channels, sendMessage);
}
);
}
Example #8
Source File: Parachain.tsx From crust-apps with Apache License 2.0 | 5 votes |
transformHeader = {
transform: (header: Header) => header.number.unwrap()
}
Example #9
Source File: system.ts From interbtc-api with Apache License 2.0 | 5 votes |
async subscribeToFinalizedBlockHeads(callback: (blockHeader: Header) => void): Promise<() => void> {
const unsub = await this.api.rpc.chain.subscribeFinalizedHeads((head) => {
callback(head);
});
return unsub;
}
Example #10
Source File: system.ts From interbtc-api with Apache License 2.0 | 5 votes |
async subscribeToCurrentBlockHeads(callback: (blockHeader: Header) => void): Promise<() => void> {
const unsub = await this.api.rpc.chain.subscribeAllHeads((head) => {
callback(head);
});
return unsub;
}
Example #11
Source File: useBestHash.ts From subscan-multisig-react with Apache License 2.0 | 5 votes |
optCall = {
transform: (header: Header) => header.hash.toHex(),
}
Example #12
Source File: BlockProducer.ts From squid with GNU General Public License v3.0 | 5 votes |
private _headerCache = new FIFOCache<number, Header>(
getConfig().HEADER_CACHE_CAPACITY
)
Example #13
Source File: SubstrateService.ts From squid with GNU General Public License v3.0 | 5 votes |
async getHeader(hash: Hash | Uint8Array | string): Promise<Header> {
return this.apiCall(
(api) => api.rpc.chain.getHeader(hash),
`Getting block header of ${JSON.stringify(hash)}`
)
}
Example #14
Source File: base-provider.ts From bodhi.js with Apache License 2.0 | 4 votes |
startSubscription = async (): Promise<any> => {
this._cache = new BlockCache(this.maxBlockCacheSize);
if (this.maxBlockCacheSize < 1) {
return logger.throwError(
`expect maxBlockCacheSize > 0, but got ${this.maxBlockCacheSize}`,
Logger.errors.INVALID_ARGUMENT
);
} else {
this.maxBlockCacheSize > 9999 && logger.warn(CACHE_SIZE_WARNING);
}
await this.isReady();
const subscriptionMethod = this.safeMode
? this.api.rpc.chain.subscribeFinalizedHeads.bind(this)
: this.api.rpc.chain.subscribeNewHeads.bind(this);
subscriptionMethod(async (header: Header) => {
// cache
const blockNumber = header.number.toNumber();
const blockHash = (await this.api.rpc.chain.getBlockHash(blockNumber)).toHex();
const txHashes = await this._getTxHashesAtBlock(blockHash);
this._cache!.addTxsAtBlock(blockNumber, txHashes);
// eth_subscribe
// TODO: can do some optimizations
if (this._listeners[NEW_HEADS]?.length > 0) {
const block = await this.getBlock(blockNumber);
const response = hexlifyRpcResult(block);
this._listeners[NEW_HEADS].forEach((l) => l.cb(response));
}
if (this._listeners[NEW_LOGS]?.length > 0) {
const block = await this._getBlock(header.number.toHex(), false);
const receipts = await Promise.all(
block.transactions.map((tx) => this.getTransactionReceiptAtBlock(tx as string, header.number.toHex()))
);
const logs = receipts.map((r) => r.logs).flat();
this._listeners[NEW_LOGS]?.forEach(({ cb, filter }) => {
const filteredLogs = logs.filter((l) => filterLog(l, filter));
const response = hexlifyRpcResult(filteredLogs);
response.forEach((log: any) => cb(log));
});
}
}) as unknown as void;
// for getTXhashFromNextBlock
this.api.rpc.chain.subscribeNewHeads((header: Header) => {
this._newBlockListeners.forEach((cb) => {
try {
cb(header);
} catch {
/* swallow */
}
});
this._newBlockListeners = [];
}) as unknown as void;
this.api.rpc.chain.subscribeFinalizedHeads(async (header: Header) => {
const blockNumber = header.number.toNumber();
this.latestFinalizedBlockNumber = blockNumber;
// safe mode only, if useful in the future, can remove this if condition
if (this.safeMode) {
const blockHash = (await this.api.rpc.chain.getBlockHash(blockNumber)).toHex();
this.latestFinalizedBlockHash = blockHash;
}
}) as unknown as void;
this.api.rpc.state.subscribeRuntimeVersion((runtime: RuntimeVersion) => {
const version = runtime.specVersion.toNumber();
this.verbose && logger.info(`runtime version: ${version}`);
if (!this.runtimeVersion || this.runtimeVersion === version) {
this.runtimeVersion = version;
} else {
logger.warn(
`runtime version changed: ${this.runtimeVersion} => ${version}, shutting down myself... good bye ?`
);
process?.exit(1);
}
}) as unknown as void;
};
Example #15
Source File: bot.ts From community-repo with GNU General Public License v3.0 | 4 votes |
main = async () => {
const provider = new WsProvider(wsLocation);
const api = await ApiPromise.create({ provider, types });
await api.isReady;
const [chain, node, version] = await Promise.all([
String(await api.rpc.system.chain()),
api.rpc.system.name(),
api.rpc.system.version(),
]);
log(`Subscribed to ${chain} on ${node} v${version}`);
let council: Council = { round: 0, last: "" };
let blocks: Block[] = [];
let lastEra = 0;
let timestamp = await get.timestamp(api);
let duration = 0;
let lastHeartbeat = timestamp;
let lastBlock: Block = {
id: 0,
duration: 0,
timestamp: 0,
stake: 0,
noms: 0,
vals: 0,
issued: 0,
reward: 0,
};
let issued = 0;
let reward = 0;
let stake = 0;
let vals = 0;
let noms = 0;
let announced: { [key: string]: boolean } = {};
const channels: number[] = [0, 0];
const posts: number[] = [0, 0];
const threads: number[] = [0, 0];
let proposals: Proposals = { last: 0, current: 0, active: [], executing: [] };
let lastProposalUpdate = 0;
if (opts.forum) {
posts[0] = await get.currentPostId(api);
threads[0] = await get.currentThreadId(api);
}
if (opts.proposals) {
proposals.last = await get.proposalCount(api);
proposals.active = await get.activeProposals(api, proposals.last);
}
const getReward = async (era: number) =>
Number(await api.query.staking.erasValidatorReward(era));
api.rpc.chain.subscribeNewHeads(
async (header: Header): Promise<void> => {
// current block
const id = header.number.toNumber();
if (lastBlock.id === id) return;
timestamp = await get.timestamp(api);
duration = lastBlock.timestamp ? timestamp - lastBlock.timestamp : 0;
// update validators and nominators every era
const era = Number(await api.query.staking.currentEra());
if (era > lastEra) {
vals = (await api.query.session.validators()).length;
stake = Number(await api.query.staking.erasTotalStake(era));
issued = Number(await api.query.balances.totalIssuance());
reward = (await getReward(era - 1)) || (await getReward(era - 2));
// nominator count
noms = 0;
const nominators: { [key: string]: number } = {};
const stashes = (await api.derive.staking.stashes())
.map((s) => String(s))
.map(async (v) => {
const stakers = await api.query.staking.erasStakers(era, v);
stakers.others.forEach(
(n: { who: AccountId }) => nominators[String(n.who)]++
);
noms = Object.keys(nominators).length;
});
lastEra = era;
}
const block: Block = {
id,
timestamp,
duration,
stake,
noms,
vals,
reward,
issued,
};
if (duration) blocks = blocks.concat(block);
// heartbeat
if (timestamp > lastHeartbeat + heartbeat) {
const time = passedTime(lastHeartbeat, timestamp);
announce.heartbeat(
api,
blocks,
time,
proposals,
sendMessage,
discordChannels.tokenomics
);
lastHeartbeat = block.timestamp;
blocks = [];
}
// announcements
if (opts.council && block.id > lastBlock.id)
council = await announce.council(
api,
council,
block.id,
sendMessage,
discordChannels.council
);
if (opts.proposals) {
proposals.current = await get.proposalCount(api);
if (
proposals.current > proposals.last &&
!announced[proposals.current]
) {
announced[`proposal${proposals.current}`] = true;
proposals = await announce.proposals(
api,
proposals,
id,
sendMessage,
discordChannels.proposals
);
lastProposalUpdate = timestamp;
}
}
if (opts.forum) {
posts[1] = await get.currentPostId(api);
announce.posts(api, posts, sendMessage, discordChannels.forum);
posts[0] = posts[1];
}
printStatus(opts, { block: id, chain, posts, proposals });
lastBlock = block;
}
);
}
Example #16
Source File: Forks.tsx From crust-apps with Apache License 2.0 | 4 votes |
function Forks ({ className }: Props): React.ReactElement<Props> | null {
const { t } = useTranslation();
const { api } = useApi();
const [tree, setTree] = useState<Link | null>(null);
const childrenRef = useRef<Map<string, string[]>>(new Map([['root', []]]));
const countRef = useRef({ numBlocks: 0, numForks: 0 });
const headersRef = useRef<Map<string, LinkHeader>>(new Map());
const firstNumRef = useRef('');
const _finalize = useCallback(
(hash: string): void => {
const hdr = headersRef.current.get(hash);
if (hdr && !hdr.isFinalized) {
hdr.isFinalized = true;
_finalize(hdr.parent);
}
},
[]
);
// adds children for a specific header, retrieving based on matching parent
const _addChildren = useCallback(
(base: LinkHeader, children: LinkArray): LinkArray => {
// add the children
(childrenRef.current.get(base.hash) || [])
.map((hash): LinkHeader | undefined => headersRef.current.get(hash))
.filter((hdr): hdr is LinkHeader => !!hdr)
.forEach((hdr): void => {
children.push({ arr: _addChildren(hdr, []), hdr });
});
// calculate the max height/width for this entry
base.height = calcHeight(children);
base.width = calcWidth(children);
// place the active (larger, finalized) columns first for the pyramid display
children.sort((a, b): number =>
(a.hdr.width > b.hdr.width || a.hdr.height > b.hdr.height || a.hdr.isFinalized)
? -1
: (a.hdr.width < b.hdr.width || a.hdr.height < b.hdr.height || b.hdr.isFinalized)
? 1
: 0
);
return children;
},
[]
);
// create a tree list from the available headers
const _generateTree = useCallback(
(): Link => {
const root = createLink();
// add all the root entries first, we iterate from these
// We add the root entry explicitly, it exists as per init
(childrenRef.current.get('root') || []).forEach((hash): void => {
const hdr = headersRef.current.get(hash);
// if this fails, well, we have a bigger issue :(
if (hdr) {
root.arr.push({ arr: [], hdr: { ...hdr } });
}
});
// iterate through, adding the children for each of the root nodes
root.arr.forEach(({ arr, hdr }): void => {
_addChildren(hdr, arr);
});
// align the columns with empty spacers - this aids in display
addColumnSpacers(root.arr);
root.hdr.height = calcHeight(root.arr);
root.hdr.width = calcWidth(root.arr);
return root;
},
[_addChildren]
);
// callback when finalized
const _newFinalized = useCallback(
(header: Header): void => {
_finalize(header.hash.toHex());
},
[_finalize]
);
// callback for the subscribe headers sub
const _newHeader = useCallback(
(header: Header): void => {
// formatted block info
const bn = formatNumber(header.number);
const hash = header.hash.toHex();
const parent = header.parentHash.toHex();
let isFork = false;
// if this the first one?
if (!firstNumRef.current) {
firstNumRef.current = bn;
}
if (!headersRef.current.has(hash)) {
// if this is the first, add to the root entry
if (firstNumRef.current === bn) {
(childrenRef.current.get('root') as any[]).push(hash);
}
// add to the header map
// also for HeaderExtended header.author ? header.author.toString() : null
headersRef.current.set(hash, createHdr(bn, hash, parent, null));
// check to see if the children already has a entry
if (childrenRef.current.has(parent)) {
isFork = true;
(childrenRef.current.get(parent) as any[]).push(hash);
} else {
childrenRef.current.set(parent, [hash]);
}
// if we don't have the parent of this one, retrieve it
if (!headersRef.current.has(parent)) {
// just make sure we are not first in the list, we don't want to full chain
if (firstNumRef.current !== bn) {
console.warn(`Retrieving missing header ${header.parentHash.toHex()}`);
api.rpc.chain.getHeader(header.parentHash).then(_newHeader).catch(console.error);
// catch the refresh on the result
return;
}
}
// update our counters
countRef.current.numBlocks++;
if (isFork) {
countRef.current.numForks++;
}
// do the magic, extract the info into something useful and add to state
setTree(_generateTree());
}
},
[api, _generateTree]
);
useEffect((): () => void => {
let _subFinHead: UnsubFn | null = null;
let _subNewHead: UnsubFn | null = null;
(async (): Promise<void> => {
_subFinHead = await api.rpc.chain.subscribeFinalizedHeads(_newFinalized);
_subNewHead = await api.rpc.chain.subscribeNewHeads(_newHeader);
})().catch(console.error);
return (): void => {
_subFinHead && _subFinHead();
_subNewHead && _subNewHead();
};
}, [api, _newFinalized, _newHeader]);
if (!tree) {
return null;
}
return (
<div className={className}>
<SummaryBox>
<section>
<CardSummary label={t<string>('blocks')}>{formatNumber(countRef.current.numBlocks)}</CardSummary>
<CardSummary label={t<string>('forks')}>{formatNumber(countRef.current.numForks)}</CardSummary>
</section>
</SummaryBox>
<table>
<tbody>
{renderRows(createRows(tree.arr))}
</tbody>
</table>
</div>
);
}