@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 vote down vote up
_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 vote down vote up
(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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
transformHeader = {
  transform: (header: Header) => header.number.unwrap()
}
Example #9
Source File: system.ts    From interbtc-api with Apache License 2.0 5 votes vote down vote up
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 vote down vote up
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 vote down vote up
optCall = {
  transform: (header: Header) => header.hash.toHex(),
}
Example #12
Source File: BlockProducer.ts    From squid with GNU General Public License v3.0 5 votes vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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>
  );
}