<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: megared05</title>
    <description>The latest articles on Forem by megared05 (@megared05).</description>
    <link>https://forem.com/megared05</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1275375%2Fd74dd1d6-9c7b-4aad-bc7a-74c467d789ca.png</url>
      <title>Forem: megared05</title>
      <link>https://forem.com/megared05</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/megared05"/>
    <language>en</language>
    <item>
      <title>Chainsight Hands-on: Subscribe to On-Chain Events &amp; Collect</title>
      <dc:creator>megared05</dc:creator>
      <pubDate>Tue, 27 Feb 2024 05:02:09 +0000</pubDate>
      <link>https://forem.com/megared05/chainsight-hands-on-subscribe-to-on-chain-events-collect-4a3k</link>
      <guid>https://forem.com/megared05/chainsight-hands-on-subscribe-to-on-chain-events-collect-4a3k</guid>
      <description>&lt;p&gt;So far we have introduced three components focused on the purpose of "collecting data. The component we present here, Event Indexer, follows the same objective, but with a slightly different means. It subscribes to events issued on-chain and stores the confirmed event information in the component.&lt;/p&gt;

&lt;p&gt;The Event Indexer specifies events issued from EVM-compatible blockchain contracts, and subscribes to and stores those events. It is possible to specify a block number to start subscribing to and collect all events issued in subsequent blocks. This component allows monitoring of the various actions that occur in the contract itself, which is difficult to collect with Snapshot Indexer. To learn more about Events in Ethereum, please see below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ethereum.org/developers/docs/smart-contracts/anatomy#events-and-logs"&gt;https://ethereum.org/developers/docs/smart-contracts/anatomy#events-and-logs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's build an Event Indexer that subscribes to ERC-20's Transfer event, which is typical of smart contracts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://eips.ethereum.org/EIPS/eip-20#events"&gt;https://eips.ethereum.org/EIPS/eip-20#events&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Completed Component Definition&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Target the DAI of ERC20 token, Ethereum's stable coin, and build an Event Indexer that collects DAI transfers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwb7kkt8fjgq150pckm4d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwb7kkt8fjgq150pckm4d.png" alt="chainsight_deepdive_into_showcase-handson-event_indexer.png" width="581" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisite&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Chainsight CLI requires several tools and a &lt;code&gt;csx&lt;/code&gt;  installation. Please refer to the following articles for this preliminary preparation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/hide_yoshi/step-by-step-creating-an-evm-price-oracle-with-chainsight-469g"&gt;https://dev.to/hide_yoshi/step-by-step-creating-an-evm-price-oracle-with-chainsight-469g&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a project &amp;amp; add a manifest template&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As before, build from an empty project; use &lt;code&gt;csx new --no-samples&lt;/code&gt; to create a template.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% csx new &lt;span class="nt"&gt;--no-samples&lt;/span&gt; event_indexer_pj 
Feb 13 12:56:29.488 INFO Start creating new project &lt;span class="s1"&gt;'event_indexer_pj'&lt;/span&gt;...
Feb 13 12:56:29.489 INFO Project &lt;span class="s1"&gt;'event_indexer_pj'&lt;/span&gt; created successfully
Feb 13 12:56:29.489 INFO You can add components with:

  &lt;span class="nb"&gt;cd &lt;/span&gt;event_indexer_pj &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; csx add
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then use &lt;code&gt;csx add&lt;/code&gt; to add the Event Indexer, selecting the event_indexer type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% &lt;span class="nb"&gt;cd &lt;/span&gt;event_indexer_pj
% csx add
✔ Please input Component Name to add · dai_transfer_subscriber
✔ Please &lt;span class="k"&gt;select &lt;/span&gt;Component Type to add · event_indexer
Feb 13 12:57:22.481 INFO Start creating new component &lt;span class="s1"&gt;'dai_transfer_subscriber'&lt;/span&gt;...
Feb 13 12:57:22.484 INFO EventIndexer component &lt;span class="s1"&gt;'dai_transfer_subscriber'&lt;/span&gt; added successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From here, we will update the manifest so that DAI Transfer Events can be collected. The fields to be configured are a bit similar to those in the Snapshot Indexer EVM. The &lt;code&gt;datasource&lt;/code&gt; field is important for setting the events to be subscribed to. Let's take a look at the generated manifest.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;0000000000000000000000000000000000000000'&lt;/span&gt;
  &lt;span class="na"&gt;event&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;EventIdentifier&lt;/span&gt;
    &lt;span class="na"&gt;interface&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
  &lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;rpc_url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://polygon-mumbai.infura.io/v3/${INFURA_MUMBAI_RPC_URL_KEY}&lt;/span&gt;
    &lt;span class="na"&gt;chain_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80001&lt;/span&gt;
  &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;37730337&lt;/span&gt;
  &lt;span class="na"&gt;contract_type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ERC-20&lt;/span&gt;
  &lt;span class="na"&gt;batch_size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The parameters that need to be modified this time are the &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;event&lt;/code&gt;, &lt;code&gt;network&lt;/code&gt; and &lt;code&gt;from&lt;/code&gt; fields. Specify the blockchain network and its contract to be subscribed to in &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;network&lt;/code&gt;, the RPC URL of the Ethereum blockchain, the chain ID, and the contract address of the DAI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;0x6B175474E89094C44Da98b954EedeAC495271d0F&lt;/span&gt;
  &lt;span class="na"&gt;event&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;
  &lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;rpc_url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://polygon-mumbai.infura.io/v3/${INFURA_MUMBAI_RPC_URL_KEY}&lt;/span&gt;
    &lt;span class="na"&gt;chain_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80001&lt;/span&gt;
  &lt;span class="s"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Specify the event to be retrieved in event, the name to identify the event, and the ABI of the contract. Obtain the ABI for ERC20, which will be called this time, from the link below and create &lt;code&gt;interfaces/ERC20.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://etherscan.io/token/0x6b175474e89094c44da98b954eedeac495271d0f#code"&gt;https://etherscan.io/token/0x6b175474e89094c44da98b954eedeac495271d0f#code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then &lt;code&gt;from&lt;/code&gt; specifies the block at the start of the subscription.&lt;/p&gt;

&lt;p&gt;Finally, &lt;code&gt;event&lt;/code&gt; and &lt;code&gt;from&lt;/code&gt; should be specified as follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;
  &lt;span class="na"&gt;event&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Transfer&lt;/span&gt;
    &lt;span class="na"&gt;interface&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ERC20.json&lt;/span&gt;
  &lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;
  &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;17660942&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final manifest is as follows&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Dai Transfer Subscriber by Hands-on&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;event_indexer&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Collect&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Transfer&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Event&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;of&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;DAI&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;token.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;This&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;sample&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;of&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;components&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;that&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;will&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;be&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;built&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;in&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Hands-on&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;article.'&lt;/span&gt;
  &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;0x6B175474E89094C44Da98b954EedeAC495271d0F&lt;/span&gt;
  &lt;span class="na"&gt;event&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Transfer&lt;/span&gt;
    &lt;span class="na"&gt;interface&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ERC20.json&lt;/span&gt;
  &lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;rpc_url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_KEY}&lt;/span&gt;
    &lt;span class="na"&gt;chain_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;17660942&lt;/span&gt;
  &lt;span class="na"&gt;contract_type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ERC-20&lt;/span&gt;
  &lt;span class="na"&gt;batch_size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1800&lt;/span&gt; &lt;span class="c1"&gt;# 30min&lt;/span&gt;
&lt;span class="na"&gt;cycles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Generate a code &amp;amp; build a module&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's generate the canister code with &lt;code&gt;csx generate&lt;/code&gt;. If you actually run this command, you will get the following output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% csx generate
Feb 15 01:24:21.749 INFO Start code generation &lt;span class="k"&gt;for &lt;/span&gt;project &lt;span class="s1"&gt;'event_indexer_pj'&lt;/span&gt;
Feb 15 01:24:21.749 INFO Load &lt;span class="nb"&gt;env &lt;/span&gt;file: &lt;span class="s2"&gt;"./.env"&lt;/span&gt;
Feb 15 01:24:21.752 INFO &lt;span class="o"&gt;[&lt;/span&gt;dai_transfer_subscriber] Start processing...
Feb 15 01:24:21.752 INFO &lt;span class="o"&gt;[&lt;/span&gt;dai_transfer_subscriber] Interface file &lt;span class="s1"&gt;'ERC20.json'&lt;/span&gt; copied from &lt;span class="nb"&gt;builtin &lt;/span&gt;interface
Feb 15 01:24:21.753 INFO &lt;span class="o"&gt;[&lt;/span&gt;dai_transfer_subscriber] Generate interfaces &lt;span class="o"&gt;(&lt;/span&gt;.did files&lt;span class="o"&gt;)&lt;/span&gt; ...
Feb 15 01:24:23.007 INFO &lt;span class="o"&gt;[&lt;/span&gt;dai_transfer_subscriber] Succeeded: Generate interfaces &lt;span class="o"&gt;(&lt;/span&gt;.did files&lt;span class="o"&gt;)&lt;/span&gt;
Feb 15 01:24:23.007 INFO Project &lt;span class="s1"&gt;'event_indexer_pj'&lt;/span&gt; codes/resources generated successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no need to implement any additional logic in Event Indexer. The build process can be executed as is.&lt;/p&gt;

&lt;p&gt;You can generate modules from code with &lt;code&gt;csx build&lt;/code&gt;. Let's run it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% csx build          
Feb 13 13:17:44.320 INFO Start building project &lt;span class="s1"&gt;'event_indexer_pj'&lt;/span&gt;
Feb 13 13:17:44.320 INFO Load &lt;span class="nb"&gt;env &lt;/span&gt;file: &lt;span class="s2"&gt;"./.env"&lt;/span&gt;
Feb 13 13:17:44.321 INFO Start code generation &lt;span class="k"&gt;for &lt;/span&gt;project &lt;span class="s1"&gt;'event_indexer_pj'&lt;/span&gt;
Feb 13 13:17:44.321 INFO Load &lt;span class="nb"&gt;env &lt;/span&gt;file: &lt;span class="s2"&gt;"./.env"&lt;/span&gt;
Feb 13 13:17:44.321 INFO &lt;span class="o"&gt;[&lt;/span&gt;dai_transfer_subscriber] Start processing...
Feb 13 13:17:44.321 INFO &lt;span class="o"&gt;[&lt;/span&gt;dai_transfer_subscriber] Interface file &lt;span class="s1"&gt;'ERC20.json'&lt;/span&gt; copied from &lt;span class="nb"&gt;builtin &lt;/span&gt;interface
Feb 13 13:17:44.389 INFO &lt;span class="o"&gt;[&lt;/span&gt;dai_transfer_subscriber] Generate interfaces &lt;span class="o"&gt;(&lt;/span&gt;.did files&lt;span class="o"&gt;)&lt;/span&gt; ...
Feb 13 13:18:12.780 INFO &lt;span class="o"&gt;[&lt;/span&gt;dai_transfer_subscriber] Succeeded: Generate interfaces &lt;span class="o"&gt;(&lt;/span&gt;.did files&lt;span class="o"&gt;)&lt;/span&gt;
Feb 13 13:18:12.780 INFO Project &lt;span class="s1"&gt;'event_indexer_pj'&lt;/span&gt; codes/resources generated successfully
Feb 13 13:18:12.780 INFO Start building...
Feb 13 13:18:12.781 INFO Compile canisters...
Feb 13 13:18:51.182 INFO Succeeded: Compile canisters
Feb 13 13:18:51.182 INFO Shrink/Optimize modules...
Feb 13 13:18:51.304 INFO Succeeded: Shrink/Optimize modules
Feb 13 13:18:51.304 INFO Add metadata to modules...
Feb 13 13:18:51.416 INFO Succeeded: Add metadata to modules
Feb 13 13:19:14.065 INFO Project &lt;span class="s1"&gt;'event_indexer_pj'&lt;/span&gt; built successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you get logs like the above for this one as well, you are done. Finally, deploy and start the component!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deploy a component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Deploy this component on the Chainsight Platform with csx deploy and csx exec as in previous hands-on sessions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;csx deploy &lt;span class="nt"&gt;--network&lt;/span&gt; ic &lt;span class="nt"&gt;--component&lt;/span&gt; dai_transfer_subscriber
csx &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;--network&lt;/span&gt; ic &lt;span class="nt"&gt;--component&lt;/span&gt; dai_transfer_subscriber
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you run these, you should get the following logs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% csx deploy &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; csx &lt;span class="nb"&gt;exec
&lt;/span&gt;Feb 13 13:19:15.970 INFO Checking environments...
Feb 13 13:19:15.970 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx ping http://127.0.0.1:4943'&lt;/span&gt;
Feb 13 13:19:16.033 INFO Suceeded: dfx ping http://127.0.0.1:4943
Feb 13 13:19:16.033 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx identity whoami'&lt;/span&gt;
Feb 13 13:19:16.093 INFO Suceeded: dfx identity &lt;span class="nb"&gt;whoami
&lt;/span&gt;Feb 13 13:19:16.093 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx identity get-principal'&lt;/span&gt;
Feb 13 13:19:16.167 INFO Suceeded: dfx identity get-principal
Feb 13 13:19:16.167 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx identity get-wallet'&lt;/span&gt;
Feb 13 13:19:20.479 INFO Suceeded: dfx identity get-wallet
Feb 13 13:19:20.479 INFO Checking environments finished successfully
Feb 13 13:19:20.479 INFO Start deploying project &lt;span class="s1"&gt;'event_indexer_pj'&lt;/span&gt;...
Feb 13 13:19:20.480 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx canister create --all'&lt;/span&gt;
Feb 13 13:19:23.138 INFO Suceeded: dfx canister create &lt;span class="nt"&gt;--all&lt;/span&gt;
Feb 13 13:19:23.138 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx build --all'&lt;/span&gt;
Feb 13 13:19:23.402 INFO Suceeded: dfx build &lt;span class="nt"&gt;--all&lt;/span&gt;
Feb 13 13:19:23.402 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx canister install --all'&lt;/span&gt;
Feb 13 13:19:28.884 INFO Suceeded: dfx canister &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--all&lt;/span&gt;
Feb 13 13:19:28.885 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx canister update-settings --add-controller 7fpuj-hqaaa-aaaal-acg7q-cai dai_transfer_subscriber'&lt;/span&gt;
Feb 13 13:19:31.795 INFO Suceeded: dfx canister update-settings &lt;span class="nt"&gt;--add-controller&lt;/span&gt; 7fpuj-hqaaa-aaaal-acg7q-cai dai_transfer_subscriber
Feb 13 13:19:31.981 INFO Current deployed status:
Canister Name: __Candid_UI
  Canister Id: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"local"&lt;/span&gt;: &lt;span class="s2"&gt;"b77ix-eeaaa-aaaaa-qaada-cai"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
  Controllers: k245a-2cvyi-rcnzj-cpq6h-dcy7o-qrg4b-325bv-5c3om-jfceo-ikmjz-aqe
  Module Hash: 0x934756863c010898a24345ce4842d173b3ea7639a8eb394a0d027a9423c70b5c

Canister Name: dai_transfer_subscriber
  Canister Id: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"local"&lt;/span&gt;: &lt;span class="s2"&gt;"bw4dl-smaaa-aaaaa-qaacq-cai"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
  Controllers: 7fpuj-hqaaa-aaaal-acg7q-cai br5f7-7uaaa-aaaaa-qaaca-cai k245a-2cvyi-rcnzj-cpq6h-dcy7o-qrg4b-325bv-5c3om-jfceo-ikmjz-aqe
  Module Hash: 0x80b8cbaa5c666cbd3dce384cf964d883828d78ac2ee2f2ffa1f9287b521499f8

Feb 13 13:19:32.030 INFO Execute canister processing...
Feb 13 13:19:32.030 INFO Load &lt;span class="nb"&gt;env &lt;/span&gt;file: &lt;span class="s2"&gt;"./.env"&lt;/span&gt;
Feb 13 13:19:32.030 INFO Start processing &lt;span class="k"&gt;for &lt;/span&gt;commands generation...
Feb 13 13:19:32.031 INFO Script &lt;span class="k"&gt;for &lt;/span&gt;Component &lt;span class="s2"&gt;"dai_transfer_subscriber"&lt;/span&gt; generated successfully
Feb 13 13:19:32.031 INFO Entrypoint Script generated successfully
Feb 13 13:19:32.031 INFO Start processing &lt;span class="k"&gt;for &lt;/span&gt;commands execution...
Feb 13 13:19:32.031 INFO Run scripts to execute commands &lt;span class="k"&gt;for &lt;/span&gt;deployed components
Feb 13 13:20:02.789 INFO Executed &lt;span class="s1"&gt;'./scripts/entrypoint.sh'&lt;/span&gt; successfully
Feb 13 13:20:02.789 INFO Project &lt;span class="s2"&gt;"event_indexer_pj"&lt;/span&gt; canisters executed successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The deployment and operation start instruction is now complete! Now all you have to do is wait for the interval of the automatic execution and you can refer to the data.&lt;/p&gt;

&lt;p&gt;Event Indexer has the following interface to retrieve data. Try using these to call components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;events_from_to &lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;(nat64, nat64) -&amp;gt; (vec record { nat64; vec Transfer }) query;&lt;/span&gt;
&lt;span class="na"&gt;events_latest_n &lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;(nat64) -&amp;gt; (vec record { nat64; vec Transfer }) query;&lt;/span&gt;
&lt;span class="na"&gt;get_last_indexed &lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;() -&amp;gt; (nat64) query;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;This concludes our hands-on with Event Indexer. We will continue to create and publish new hands-on sessions in the future, so please look forward to them!&lt;/p&gt;

&lt;p&gt;Written by &lt;a href="https://twitter.com/megared05"&gt;Megared@Chainsight&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>tutorial</category>
      <category>oracle</category>
      <category>evm</category>
    </item>
    <item>
      <title>Chainsight Hands-on: Generate original indicators from data in indexers</title>
      <dc:creator>megared05</dc:creator>
      <pubDate>Thu, 22 Feb 2024 06:57:59 +0000</pubDate>
      <link>https://forem.com/megared05/chainsight-hands-on-generate-original-indicators-from-data-in-indexers-23h0</link>
      <guid>https://forem.com/megared05/chainsight-hands-on-generate-original-indicators-from-data-in-indexers-23h0</guid>
      <description>&lt;p&gt;We have released three hands-on sessions so far, all of which involved creating components to "collect data.” By using the Snapshot Indexer in the Chainsight Platform, we were able to retrieve all kinds of data from various locations. In this hands-on session, we will build a component that generates a new index/indicator by performing a unique calculation using the data stored by the Snapshot Indexer as input.&lt;/p&gt;

&lt;p&gt;This project uses Ethereum price data collected by multiple Snapshot Indexers and calculates their average value to calculate a reliable Ethereum price. The component used as the calculator is Algorithm Lens. In this case, we are collecting Ethereum price data from three Snapshot Indexers. By using different locations for each of these data sources, we aim to improve the reliability of the calculation results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Completed Component Definition&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Algorithm Lens, which performs the calculation, obtains the latest Ethereum price data from the three Snapshot Indexers and performs the calculation using those data as input. The configuration diagram is shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe57j3lpbkblbbh6rcfq9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe57j3lpbkblbbh6rcfq9.png" alt="chainsight_deepdive_into_showcase-handson-algorithm_lens.png" width="483" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisite&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Chainsight CLI requires several tools and a &lt;code&gt;csx&lt;/code&gt;  installation. Please refer to the following articles for this preliminary preparation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/hide_yoshi/step-by-step-creating-an-evm-price-oracle-with-chainsight-469g"&gt;https://dev.to/hide_yoshi/step-by-step-creating-an-evm-price-oracle-with-chainsight-469g&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As before, build from an empty project; use &lt;code&gt;csx new --no-samples&lt;/code&gt; to create a template.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% csx new &lt;span class="nt"&gt;--no-samples&lt;/span&gt; lens-project
Feb 06 02:00:18.697 INFO Start creating new project &lt;span class="s1"&gt;'lens-project'&lt;/span&gt;...
Feb 06 02:00:18.698 INFO Project &lt;span class="s1"&gt;'lens-project'&lt;/span&gt; created successfully
Feb 06 02:00:18.698 INFO You can add components with:

  &lt;span class="nb"&gt;cd &lt;/span&gt;lens-project &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; csx add
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Add Snapshot Indexers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This time, we will build three Snapshot Indexers, two of which are Snapshot Indexer EVMs. Two of them are Snapshot Indexer EVMs that use Mainnet's chainlink contract and Arbitrum One's API3 contract as data sources. The last one is Snapshot Indexer HTTPS, which uses coingecko's API as its data source. Please add the following manifest and update &lt;code&gt;project.yaml&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# components/chainlink_eth_indexer.yaml&lt;/span&gt;
&lt;span class="nn"&gt;...&lt;/span&gt;
&lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Chainlink: ETH/USD Price Feed&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5f4eC3Df9cbd43714FE2740f5E3616155c5b8419&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;network_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
      &lt;span class="na"&gt;rpc_url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_MAINNET_KEY}&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;latestRoundData():(uint80,int256,uint256,uint256,uint80)&lt;/span&gt;
    &lt;span class="na"&gt;interface&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;EACAggregator.json&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
&lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${INTERVAL}&lt;/span&gt;
&lt;span class="na"&gt;cycles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# components/api3_eth_indexer.yaml&lt;/span&gt;
&lt;span class="nn"&gt;...&lt;/span&gt;
&lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Api3ServerV1&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;709944a48caf83535e43471680fda4905fb3920a&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;network_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;42161&lt;/span&gt;
      &lt;span class="na"&gt;rpc_url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://arb-mainnet.g.alchemy.com/v2/${ALCHEMY_ARBITRUM_ONE_KEY}&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dataFeeds(bytes32):(int224,uint32)&lt;/span&gt;
    &lt;span class="na"&gt;interface&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Api3ServerV1.json&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;0x4385954e058fbe6b6a744f32a4f89d67aad099f8fb8b23e7ea8dd366ae88151d&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${INTERVAL}&lt;/span&gt;
&lt;span class="na"&gt;cycles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# components/web_eth_indexer.yaml&lt;/span&gt;
&lt;span class="nn"&gt;...&lt;/span&gt;
&lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://api.coingecko.com/api/v3/simple/price&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/json&lt;/span&gt;
  &lt;span class="na"&gt;queries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;static&lt;/span&gt;
    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;ids&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ethereum&lt;/span&gt;
      &lt;span class="na"&gt;vs_currencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;usd&lt;/span&gt;
      &lt;span class="na"&gt;include_market_cap&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;include_24hr_vol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;include_24hr_change&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;include_last_updated_at&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;precision&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;18&lt;/span&gt;
&lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${INTERVAL}&lt;/span&gt;
&lt;span class="na"&gt;cycles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# project.yaml&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;eth-lens-project&lt;/span&gt;
&lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;component_path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;components/chainlink_eth_indexer.yaml&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;component_path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;components/api3_eth_indexer.yaml&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;component_path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;components/web_eth_indexer.yaml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I will add a supplement to the manifest you added.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;chainlink_eth_indexer,&lt;/code&gt; the Price Feed Contract for Mainnet's Chainlink is specified. Since the ABI used in the &lt;code&gt;interface&lt;/code&gt; field declared in the manifest is required, copy the ABI from the link below, create &lt;code&gt;interfaces/EACAggregator.json&lt;/code&gt;, and paste the copied contents directly into the file to create the ABI file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://etherscan.io/address/0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419#code"&gt;https://etherscan.io/address/0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419#code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;api3_eth_indexer&lt;/code&gt; specifies the Contract for API3 of Arbitrum One. The ABI file must be placed here as well. Copy the ABI from the link below and create an ABI file &lt;code&gt;interfaces/Api3ServerV1.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://arbiscan.io/address/0x709944a48caf83535e43471680fda4905fb3920a#code"&gt;https://arbiscan.io/address/0x709944a48caf83535e43471680fda4905fb3920a#code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;web_eth_indexer&lt;/code&gt; specifies Coingecko's API.&lt;/p&gt;

&lt;p&gt;The Snapshot Indexer EVM manifest also sets up an RPC URL to communicate with the blockchain, and in most cases when using RPC, the private RPC endpoint is generated using the Platform associated with Web3 and used. This is accompanied by a special key, which cannot be made public. To enable such RPCs without problems, environment variables are available in the Chainsight manifest. For the above manifest, generate the following &lt;code&gt;.env&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INTERVAL=60
ALCHEMY_MAINNET_KEY=(YOUR_KEY)
ALCHEMY_ARBITRUM_ONE_KEY=(YOUR_KEY)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Variables declared in this &lt;code&gt;.env&lt;/code&gt; file are expanded when the manifest is read.&lt;/p&gt;

&lt;p&gt;You have now completed creating the manifest for Snapshot Indexer! Make sure your folder structure looks like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% &lt;span class="nb"&gt;ls
&lt;/span&gt;artifacts   components  interfaces  project.yaml    src
% &lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; components
api3_eth_indexer.yaml
chainlink_eth_indexer.yaml
web_eth_indexer.yaml
% &lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; interfaces 
Api3ServerV1.json
EACAggregator.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have done this, you can build it by running &lt;code&gt;csx build&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% csx build
Feb 11 01:38:07.827 INFO Start building project &lt;span class="s1"&gt;'lens-project'&lt;/span&gt;
Feb 11 01:38:07.828 INFO Load &lt;span class="nb"&gt;env &lt;/span&gt;file: &lt;span class="s2"&gt;"./.env"&lt;/span&gt;
Feb 11 01:38:07.828 INFO Start code generation &lt;span class="k"&gt;for &lt;/span&gt;project &lt;span class="s1"&gt;'lens-project'&lt;/span&gt;
Feb 11 01:38:07.828 INFO Load &lt;span class="nb"&gt;env &lt;/span&gt;file: &lt;span class="s2"&gt;"./.env"&lt;/span&gt;
Feb 11 01:38:07.832 INFO &lt;span class="o"&gt;[&lt;/span&gt;chainlink_eth_indexer] Start processing...
Feb 11 01:38:07.833 INFO &lt;span class="o"&gt;[&lt;/span&gt;chainlink_eth_indexer] Interface file &lt;span class="s1"&gt;'EACAggregator.json'&lt;/span&gt; copied from user&lt;span class="s1"&gt;'s interface
Feb 11 01:38:08.387 INFO [chainlink_eth_indexer] Generate interfaces (.did files) ...
Feb 11 01:38:09.684 INFO [chainlink_eth_indexer] Succeeded: Generate interfaces (.did files)
Feb 11 01:38:09.684 INFO [api3_eth_indexer] Start processing...
Feb 11 01:38:09.685 INFO [api3_eth_indexer] Interface file '&lt;/span&gt;Api3ServerV1.json&lt;span class="s1"&gt;' copied from user'&lt;/span&gt;s interface
Feb 11 01:38:09.778 INFO &lt;span class="o"&gt;[&lt;/span&gt;api3_eth_indexer] Generate interfaces &lt;span class="o"&gt;(&lt;/span&gt;.did files&lt;span class="o"&gt;)&lt;/span&gt; ...
Feb 11 01:38:10.533 INFO &lt;span class="o"&gt;[&lt;/span&gt;api3_eth_indexer] Succeeded: Generate interfaces &lt;span class="o"&gt;(&lt;/span&gt;.did files&lt;span class="o"&gt;)&lt;/span&gt;
Feb 11 01:38:10.533 INFO &lt;span class="o"&gt;[&lt;/span&gt;web_eth_indexer] Start processing...
Feb 11 01:38:11.203 INFO &lt;span class="o"&gt;[&lt;/span&gt;web_eth_indexer] Generate interfaces &lt;span class="o"&gt;(&lt;/span&gt;.did files&lt;span class="o"&gt;)&lt;/span&gt; ...
Feb 11 01:38:12.087 INFO &lt;span class="o"&gt;[&lt;/span&gt;web_eth_indexer] Succeeded: Generate interfaces &lt;span class="o"&gt;(&lt;/span&gt;.did files&lt;span class="o"&gt;)&lt;/span&gt;
Feb 11 01:38:12.087 INFO Project &lt;span class="s1"&gt;'lens-project'&lt;/span&gt; codes/resources generated successfully
Feb 11 01:38:12.087 INFO Start building...
Feb 11 01:38:12.089 INFO Compile canisters...
Feb 11 01:38:15.098 INFO Succeeded: Compile canisters
Feb 11 01:38:15.098 INFO Shrink/Optimize modules...
Feb 11 01:38:15.389 INFO Succeeded: Shrink/Optimize modules
Feb 11 01:38:15.389 INFO Add metadata to modules...
Feb 11 01:38:15.640 INFO Succeeded: Add metadata to modules
Feb 11 01:38:15.640 INFO Project &lt;span class="s1"&gt;'lens-project'&lt;/span&gt; built successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When "built successfully" is displayed as shown above, it is OK. The implementation of Snapshot Indexer is now complete.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Algorithm Lens: Add a manifest&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's the heart of this hands-on: let's build a component in Algorithm Lens that serves as a calculator to calculate the price of Ethereum by averaging multiple data sources.&lt;/p&gt;

&lt;p&gt;Add the component with &lt;code&gt;csx add&lt;/code&gt;, but this time select the &lt;code&gt;algorithm_lens&lt;/code&gt; type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% csx add
✔ Please input Component Name to add · eth_average_price_calculator
✔ Please &lt;span class="k"&gt;select &lt;/span&gt;Component Type to add · algorithm_lens
Feb 11 06:16:01.723 INFO Start creating new component &lt;span class="s1"&gt;'eth_average_price_calculator'&lt;/span&gt;...
Feb 11 06:16:01.727 INFO AlgorithmLens component &lt;span class="s1"&gt;'eth_average_price_calculator'&lt;/span&gt; added successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this command completes without problems, you will see the following manifest in your project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# components/eth_average_price_calculator.yaml&lt;/span&gt;
&lt;span class="nn"&gt;...&lt;/span&gt;
&lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sample_snapshot_indexer_icp&lt;/span&gt;
    &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;get_last_snapshot&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;()&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(record&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;value&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;text;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;timestamp&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;nat64&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;})'&lt;/span&gt;
    &lt;span class="na"&gt;candid_file_path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;span class="nn"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit this manifest to create a component that can retrieve data from the three Snapshot Indexers built in the previous section. Change the datasource field as follows&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;chainlink_eth_indexer&lt;/span&gt;
    &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;get_last_snapshot_value&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;()&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(record&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;nat;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;text;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;text;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;text;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;nat&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;})'&lt;/span&gt;
    &lt;span class="na"&gt;func_name_alias&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;chainlink_eth_indexer&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;api3_eth_indexer&lt;/span&gt;
    &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;get_last_snapshot_value&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;()&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(record&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;text;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;nat32&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;})'&lt;/span&gt;
    &lt;span class="na"&gt;func_name_alias&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;api3_eth_indexer&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;web_eth_indexer&lt;/span&gt;
    &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;get_last_snapshot_value&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;()&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(SnapshotValue)'&lt;/span&gt;
    &lt;span class="na"&gt;func_name_alias&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;web_eth_indexer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a record for each Snapshot Indexer.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;id&lt;/code&gt; field, enter the id of the Snapshot Indexer. (The id is determined from the filename of the YAML manifest that defines the component.)&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;identifier&lt;/code&gt; is a Candidate for the interface of the function when calling the component. &lt;code&gt;get_last_snapshot_value&lt;/code&gt; is one of several fixed interfaces built into Snapshot Indexer. The type of the return value depends on the data structure managed by the component. For further understanding, please refer to the following articles.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@Chainsight_Network/behind-chainsight-a-look-into-snapshot-indexer-component-d8a6074237e2"&gt;Behind Chainsight: A Look Into Snapshot Indexer Component | by Chainsight | Feb, 2024 | Medium&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;func_name_alias&lt;/code&gt; is an optional parameter, but is set for code clarity in the logic to be implemented later. The value specified here will be used as the automatically generated function name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Algorithm Lens: Generate a template code &amp;amp; make it into your logic&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's generate code with &lt;code&gt;csx generate&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% csx generate
Feb 11 14:02:32.560 INFO Start code generation &lt;span class="k"&gt;for &lt;/span&gt;project &lt;span class="s1"&gt;'lens-project'&lt;/span&gt;
Feb 11 14:02:32.560 INFO Load &lt;span class="nb"&gt;env &lt;/span&gt;file: &lt;span class="s2"&gt;"./.env"&lt;/span&gt;
Feb 11 14:02:32.562 INFO &lt;span class="o"&gt;[&lt;/span&gt;chainlink_eth_indexer] Start processing...
...
Feb 11 14:02:34.298 INFO &lt;span class="o"&gt;[&lt;/span&gt;eth_average_price_calculator] Start processing...
Feb 11 14:02:34.380 INFO &lt;span class="o"&gt;[&lt;/span&gt;eth_average_price_calculator] Generate interfaces &lt;span class="o"&gt;(&lt;/span&gt;.did files&lt;span class="o"&gt;)&lt;/span&gt; ...
Feb 11 14:02:36.470 INFO &lt;span class="o"&gt;[&lt;/span&gt;eth_average_price_calculator] Succeeded: Generate interfaces &lt;span class="o"&gt;(&lt;/span&gt;.did files&lt;span class="o"&gt;)&lt;/span&gt;
Feb 11 14:02:36.470 INFO Project &lt;span class="s1"&gt;'lens-project'&lt;/span&gt; codes/resources generated successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the above generation is complete, the following template code is generated in the &lt;code&gt;eth_average_price_calculator&lt;/code&gt; logic code file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/logics/eth_average_price_calculator/src/lib.rs&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;eth_average_price_calculator_accessors&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;#[derive(Clone,&lt;/span&gt; &lt;span class="nd"&gt;Debug,&lt;/span&gt; &lt;span class="nd"&gt;Default,&lt;/span&gt; &lt;span class="nd"&gt;candid&lt;/span&gt; &lt;span class="nd"&gt;::&lt;/span&gt; &lt;span class="nd"&gt;CandidType,&lt;/span&gt; &lt;span class="nd"&gt;serde&lt;/span&gt; &lt;span class="nd"&gt;::&lt;/span&gt; &lt;span class="nd"&gt;Deserialize,&lt;/span&gt; &lt;span class="nd"&gt;serde&lt;/span&gt; &lt;span class="nd"&gt;::&lt;/span&gt; &lt;span class="nd"&gt;Serialize)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;LensValue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;dummy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;LensValue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_chainlink_eth_indexer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_api3_eth_indexer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_web_eth_indexer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nd"&gt;todo!&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are several module imports, one structure (&lt;code&gt;struct LensValue&lt;/code&gt;) and one function (&lt;code&gt;fn calculate&lt;/code&gt;). You can customize these structs and functions to turn them into your own logic. It may be easier to understand if you think of it as a fixed interface whose contents can be customized.&lt;/p&gt;

&lt;p&gt;The structure &lt;code&gt;LensValue&lt;/code&gt; is the output type of the logic used by the Algortihm Lens. In this case, a scalar value, Float, will be fine since it returns the result of calculating the average value. Modify as follows&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;pub struct LensValue {
&lt;/span&gt;&lt;span class="gd"&gt;-    pub dummy: u64,
&lt;/span&gt;&lt;span class="gi"&gt;+    pub value: f64,
&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will then touch on the main calculation logic. As you can imagine from the function name, the function declared from the beginning is the function to retrieve data from the data source.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_chainlink_eth_indexer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_api3_eth_indexer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_web_eth_indexer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's use the values obtained here as inputs to the calculation to compute the average. After processing each input to &lt;code&gt;f64&lt;/code&gt; (64-bits float), adjust the number of digits in each data and calculate the average value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;str&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;FromStr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;LensValue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_chainlink_eth_indexer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;price_from_chainlink&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="na"&gt;.1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_api3_eth_indexer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;price_from_api3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_web_eth_indexer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;price_from_web&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.ethereum.usd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;prices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nn"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;price_from_chainlink&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;10f64&lt;/span&gt;&lt;span class="nf"&gt;.powi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nn"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;price_from_api3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;10f64&lt;/span&gt;&lt;span class="nf"&gt;.powi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;price_from_web&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;average&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.sum&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;LensValue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;average&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the chainlink price data is adjusted to 8 digits and the API3 data is adjusted to 18 digits, we have set this back to an unscaled value. In order to see the actual values of the input data, you can use explorer for blockchain data or make API calls for web data. If you have already deployed Snapshot Indexer, you can also check the data by calling the implemented reference functions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzi2m3a3vlj13brvdmnet.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzi2m3a3vlj13brvdmnet.png" alt="chainsight-handson-lens-1.png" width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://etherscan.io/address/0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419#readContract"&gt;https://etherscan.io/address/0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419#readContract&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9qhccmyy4grwv0ic45dv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9qhccmyy4grwv0ic45dv.png" alt="chainsight-handson-lens-2.png" width="800" height="187"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://arbiscan.io/address/0x709944a48caf83535e43471680fda4905fb3920a#readContract"&gt;https://arbiscan.io/address/0x709944a48caf83535e43471680fda4905fb3920a#readContract&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This completes the logic construction. The final code should look like this If this is verified locally to you, development is complete!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/logics/eth_average_price_calculator/src/lib.rs&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;eth_average_price_calculator_accessors&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;str&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;FromStr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;#[derive(Clone,&lt;/span&gt; &lt;span class="nd"&gt;Debug,&lt;/span&gt; &lt;span class="nd"&gt;Default,&lt;/span&gt; &lt;span class="nd"&gt;candid&lt;/span&gt; &lt;span class="nd"&gt;::&lt;/span&gt; &lt;span class="nd"&gt;CandidType,&lt;/span&gt; &lt;span class="nd"&gt;serde&lt;/span&gt; &lt;span class="nd"&gt;::&lt;/span&gt; &lt;span class="nd"&gt;Deserialize,&lt;/span&gt; &lt;span class="nd"&gt;serde&lt;/span&gt; &lt;span class="nd"&gt;::&lt;/span&gt; &lt;span class="nd"&gt;Serialize)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;LensValue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;LensValue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_chainlink_eth_indexer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;price_from_chainlink&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="na"&gt;.1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_api3_eth_indexer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;price_from_api3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_web_eth_indexer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;price_from_web&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.ethereum.usd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;prices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nn"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;price_from_chainlink&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;10f64&lt;/span&gt;&lt;span class="nf"&gt;.powi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nn"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;price_from_api3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;10f64&lt;/span&gt;&lt;span class="nf"&gt;.powi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;price_from_web&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nn"&gt;ic_cdk&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;average&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.sum&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;LensValue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;average&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Algorithm Lens: Build &amp;amp; Deploy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now let's build, generate modules, and deploy as before. This time, be careful about the amount of Cycles remaining since there are many canisters to deploy. By default, about 6T Cycles are required per component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;csx build
csx deploy &lt;span class="nt"&gt;--network&lt;/span&gt; ic
csx &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;--network&lt;/span&gt; ic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execute the above command and if the following log is obtained, execution is complete!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% csx build
Feb 11 23:13:55.148 INFO Start building project &lt;span class="s1"&gt;'lens-project'&lt;/span&gt;
Feb 11 23:13:55.148 INFO Load &lt;span class="nb"&gt;env &lt;/span&gt;file: &lt;span class="s2"&gt;"./.env"&lt;/span&gt;
Feb 11 23:13:55.148 INFO Start code generation &lt;span class="k"&gt;for &lt;/span&gt;project &lt;span class="s1"&gt;'lens-project'&lt;/span&gt;
Feb 11 23:13:55.148 INFO Load &lt;span class="nb"&gt;env &lt;/span&gt;file: &lt;span class="s2"&gt;"./.env"&lt;/span&gt;
Feb 11 23:13:55.150 INFO &lt;span class="o"&gt;[&lt;/span&gt;chainlink_eth_indexer] Start processing...
...
Feb 11 23:13:55.758 INFO &lt;span class="o"&gt;[&lt;/span&gt;api3_eth_indexer] Start processing...
...
Feb 11 23:13:56.376 INFO &lt;span class="o"&gt;[&lt;/span&gt;web_eth_indexer] Start processing...
...
Feb 11 23:13:56.973 INFO &lt;span class="o"&gt;[&lt;/span&gt;eth_average_price_calculator] Start processing...
...
Feb 11 23:13:58.084 INFO Project &lt;span class="s1"&gt;'lens-project'&lt;/span&gt; codes/resources generated successfully
Feb 11 23:13:58.084 INFO Start building...
...
Feb 11 23:14:05.212 INFO Project &lt;span class="s1"&gt;'lens-project'&lt;/span&gt; built successfully

% csx deploy &lt;span class="nt"&gt;--network&lt;/span&gt; ic
Feb 11 23:14:09.194 INFO Checking environments...
...
Feb 11 23:14:53.726 INFO Current deployed status:
Canister Name: api3_eth_indexer
  Canister Id: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"local"&lt;/span&gt;: &lt;span class="s2"&gt;"br5f7-7uaaa-aaaaa-qaaca-cai"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
  Controllers: 7fpuj-hqaaa-aaaal-acg7q-cai be2us-64aaa-aaaaa-qaabq-cai k245a-2cvyi-rcnzj-cpq6h-dcy7o-qrg4b-325bv-5c3om-jfceo-ikmjz-aqe
  Module Hash: 0xf11c7d0d3f0cfec06ea1d7d7d6ac2ddc0219f964f65666461d758a9cce46e85f

Canister Name: chainlink_eth_indexer
  Canister Id: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"local"&lt;/span&gt;: &lt;span class="s2"&gt;"bw4dl-smaaa-aaaaa-qaacq-cai"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
  Controllers: 7fpuj-hqaaa-aaaal-acg7q-cai be2us-64aaa-aaaaa-qaabq-cai k245a-2cvyi-rcnzj-cpq6h-dcy7o-qrg4b-325bv-5c3om-jfceo-ikmjz-aqe
  Module Hash: 0x1832aa2b92faa97065146047f87c503bd84a638ebd6073cb1c88606c663526f9

Canister Name: eth_average_price_calculator
  Canister Id: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"local"&lt;/span&gt;: &lt;span class="s2"&gt;"b77ix-eeaaa-aaaaa-qaada-cai"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
  Controllers: 7fpuj-hqaaa-aaaal-acg7q-cai be2us-64aaa-aaaaa-qaabq-cai k245a-2cvyi-rcnzj-cpq6h-dcy7o-qrg4b-325bv-5c3om-jfceo-ikmjz-aqe
  Module Hash: 0xbbd87ce2d215bcc65b130cf13ca21d99dfbb2d9827dd5c8c2f8d10b0f8e8f337

Canister Name: web_eth_indexer
  Canister Id: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"local"&lt;/span&gt;: &lt;span class="s2"&gt;"by6od-j4aaa-aaaaa-qaadq-cai"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
  Controllers: 7fpuj-hqaaa-aaaal-acg7q-cai be2us-64aaa-aaaaa-qaabq-cai k245a-2cvyi-rcnzj-cpq6h-dcy7o-qrg4b-325bv-5c3om-jfceo-ikmjz-aqe
  Module Hash: 0x6feb60c3a47517392b08b06f42a32ed544d00660137a35290ef43de5d589d14d

% csx &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;--network&lt;/span&gt; ic
Feb 11 23:14:53.778 INFO Execute canister processing...
Feb 11 23:14:53.778 INFO Load &lt;span class="nb"&gt;env &lt;/span&gt;file: &lt;span class="s2"&gt;"./.env"&lt;/span&gt;
Feb 11 23:14:53.778 INFO Start processing &lt;span class="k"&gt;for &lt;/span&gt;commands generation...
Feb 11 23:14:53.779 INFO Script &lt;span class="k"&gt;for &lt;/span&gt;Component &lt;span class="s2"&gt;"chainlink_eth_indexer"&lt;/span&gt; generated successfully
Feb 11 23:14:53.779 INFO Script &lt;span class="k"&gt;for &lt;/span&gt;Component &lt;span class="s2"&gt;"api3_eth_indexer"&lt;/span&gt; generated successfully
Feb 11 23:14:53.779 INFO Script &lt;span class="k"&gt;for &lt;/span&gt;Component &lt;span class="s2"&gt;"web_eth_indexer"&lt;/span&gt; generated successfully
Feb 11 23:14:53.779 INFO Script &lt;span class="k"&gt;for &lt;/span&gt;Component &lt;span class="s2"&gt;"eth_average_price_calculator"&lt;/span&gt; generated successfully
Feb 11 23:14:53.780 INFO Entrypoint Script generated successfully
...
Feb 11 23:16:47.932 INFO Project &lt;span class="s2"&gt;"lens-project"&lt;/span&gt; canisters executed successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Calculations in Algotirhm Lens are performed at each call. It is not executed on a regular basis. Therefore, you can check the calculation results with the following command. (You can also use IC Dashboard)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% &lt;span class="nb"&gt;cd &lt;/span&gt;artifacts
% dfx canister call eth_average_price_calculator get_result &lt;span class="s2"&gt;"vec {&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dfx canister &lt;span class="nb"&gt;id &lt;/span&gt;chainlink_eth_indexer&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;; &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dfx canister &lt;span class="nb"&gt;id &lt;/span&gt;api3_eth_indexer&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;; &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;dfx canister &lt;span class="nb"&gt;id &lt;/span&gt;web_eth_indexer&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;record &lt;span class="o"&gt;{&lt;/span&gt; value &lt;span class="o"&gt;=&lt;/span&gt; 2502.2185809524067 : float64 &lt;span class="o"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see this command executed, you have deployed an Algorithm Lens that correctly reflects the original logic you have implemented! Thank you for your patience up to this point.&lt;/p&gt;




&lt;p&gt;This hands-on session was more difficult than previous ones due to the large number of components to be built. We hope that through this hands-on, you will be able to experience how Chainsight can reflect the user's customization. This is the end of the hands-on on Algorithm Lens. We will continue to create and publish new hands-on sessions in the future, so please look forward to them!&lt;/p&gt;

&lt;p&gt;Written by &lt;a href="https://twitter.com/megared05"&gt;Megared@Chainsight&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>tutorial</category>
      <category>oracle</category>
      <category>rust</category>
    </item>
    <item>
      <title>Chainsight Hands-on: Collecting Data from Internet Computer</title>
      <dc:creator>megared05</dc:creator>
      <pubDate>Mon, 19 Feb 2024 12:24:53 +0000</pubDate>
      <link>https://forem.com/megared05/chainsight-hands-on-collecting-data-from-internet-computer-7oa</link>
      <guid>https://forem.com/megared05/chainsight-hands-on-collecting-data-from-internet-computer-7oa</guid>
      <description>&lt;p&gt;Last time we created a hands-on article on creating a component to get Ethereum price data from an Ethereum contract. The Snapshot Indexer EVM uses ABI as its interface to retrieve data from EVM-compatible chains. In this article, we will try to retrieve data from Internet Computer by using Candid, an interface on the Internet Computer where Chainsight is running. In this article, we will try to create a component that collects data in Internet Computer using Snapshot indexer ICP.&lt;/p&gt;

&lt;p&gt;This project is a Price Snapshot Indexer ICP that collects ICP prices using a DEX contract on Internet Computer. As of February 2024, 1 ICP is trading at around $12.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Completed Component Definition&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ICPSwap, one of the well-known DEXes on the Internet Computer, is used to obtain ICP prices. The ICPSwap contract (canister) is called periodically to collect ICP price data. Snapshot Indexer is constructed with a collection interval of 1 hour.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1fr37op83998zwy7ma0e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1fr37op83998zwy7ma0e.png" alt="chainsight_deepdive_into_showcase-handson-snapshot_indexer_icp.png" width="561" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisite&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Chainsight CLI requires several tools and a &lt;code&gt;csx&lt;/code&gt;  installation. Please refer to the following articles for this preliminary preparation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/hide_yoshi/step-by-step-creating-an-evm-price-oracle-with-chainsight-469g"&gt;https://dev.to/hide_yoshi/step-by-step-creating-an-evm-price-oracle-with-chainsight-469g&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a project &amp;amp; add a manifest template&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As before, build from an empty project; use &lt;code&gt;csx new --no-samples&lt;/code&gt; to create a template.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% csx new &lt;span class="nt"&gt;--no-samples&lt;/span&gt; sample_icp
Feb 06 02:00:18.697 INFO Start creating new project &lt;span class="s1"&gt;'sample_icp'&lt;/span&gt;...
Feb 06 02:00:18.698 INFO Project &lt;span class="s1"&gt;'sample_icp'&lt;/span&gt; created successfully
Feb 06 02:00:18.698 INFO You can add components with:

  &lt;span class="nb"&gt;cd &lt;/span&gt;sample_icp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; csx add
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then use csx add to add the Snapshot Indexer EVM. snapshot_indexer_icp type should be selected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% csx add
✔ Please input Component Name to add · icp_snapshot_indexer
✔ Please &lt;span class="k"&gt;select &lt;/span&gt;Component Type to add · snapshot_indexer_icp
Feb 06 02:01:11.560 INFO Start creating new component &lt;span class="s1"&gt;'icp_snapshot_indexer'&lt;/span&gt;...
Feb 06 02:01:11.560 INFO SnapshotIndexerICP component &lt;span class="s1"&gt;'icp_snapshot_indexer'&lt;/span&gt; added successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's update this manifest that we have added so that we can call Canister already deployed on Internet Computer. In this case, we will use the Canister used in ICPSwap.&lt;/p&gt;

&lt;p&gt;CanisterId: &lt;code&gt;2ixw4-taaaa-aaaag-qcpdq-cai&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr9kmzhyengzv2ka0hksv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr9kmzhyengzv2ka0hksv.png" alt="handson-snapshot_indexer_icp-1" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://info.icpswap.com/swap/token/details/ryjl3-tyaaa-aaaaa-aaaba-cai"&gt;https://info.icpswap.com/swap/token/details/ryjl3-tyaaa-aaaaa-aaaba-cai&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;datasource&lt;/code&gt; field, specify the canister and its function to call this time.&lt;/p&gt;

&lt;p&gt;Specify the ID of the canister to call in the &lt;code&gt;location.id&lt;/code&gt; field. In this case, set &lt;code&gt;2ixw4-taaaa-aaaag-qcpdq-cai&lt;/code&gt;. Next, in &lt;code&gt;datasource.method&lt;/code&gt;, specify the canister function to call. In &lt;code&gt;method.identifier&lt;/code&gt;, specify the function in Candid format, which is the interface notation of Internet Computer.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Candid is an &lt;strong&gt;interface description language&lt;/strong&gt;. Its primary purpose is to describe the public interface of a &lt;strong&gt;service&lt;/strong&gt;, usually in the form of a program deployed as a &lt;strong&gt;canister&lt;/strong&gt; that runs on the Internet Computer. One of the key benefits of Candid is that it is language-agnostic, and allows inter-operation between services and frontends written in different programming languages, including Motoko, Rust, and JavaScript.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Source: &lt;a href="https://internetcomputer.org/docs/current/developer-docs/backend/candid/candid-concepts"&gt;https://internetcomputer.org/docs/current/developer-docs/backend/candid/candid-concepts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Internet Computer makes it easy to see the interface of the canister by using the Dashboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F77m4nanezhzueqd86zu1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F77m4nanezhzueqd86zu1.png" alt="handson-snapshot_indexer_icp-2" width="800" height="781"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdqix52dht2sgd55rzgri.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdqix52dht2sgd55rzgri.png" alt="handson-snapshot_indexer_icp-3" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://dashboard.internetcomputer.org/canister/2ixw4-taaaa-aaaag-qcpdq-cai"&gt;https://dashboard.internetcomputer.org/canister/2ixw4-taaaa-aaaag-qcpdq-cai&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the canister's Candid Interface that we will call. The declarations in the &lt;code&gt;service&lt;/code&gt; section are the interfaces provided by the canister, and in this case we will use the &lt;code&gt;get_exchange_rates&lt;/code&gt; function described here. There are two things we need to do to specify this function.&lt;/p&gt;

&lt;p&gt;Specify a function declaration in &lt;code&gt;method.identifier&lt;/code&gt; that includes arguments and response information: &lt;code&gt;get_exchange_rates: () -&amp;gt; (vec ExchangeRate__1)&lt;/code&gt;. Since this declaration uses a custom type that is not a Candid builtin, create a .did file that includes the Candid Interface so that it can be referenced, and specify that file in &lt;code&gt;method.interface&lt;/code&gt;. With Candid selected in the Canister Interface of the Dashboard screen mentioned earlier, click "Copy" in the upper right corner to copy the declaration with the interface. Then, create &lt;code&gt;target_interface.did&lt;/code&gt; under the interfaces folder and paste what you just copied into its contents. The actual folder and file will look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% &lt;span class="nb"&gt;ls &lt;/span&gt;interfaces 
target_interface.did
% &lt;span class="nb"&gt;cat &lt;/span&gt;interfaces/target_interface.did 
&lt;span class="nb"&gt;type &lt;/span&gt;ExchangeRate__1 &lt;span class="o"&gt;=&lt;/span&gt; 
 record &lt;span class="o"&gt;{&lt;/span&gt;
   base_class: text&lt;span class="p"&gt;;&lt;/span&gt;
   base_symbol: text&lt;span class="p"&gt;;&lt;/span&gt;
   decimals: nat32&lt;span class="p"&gt;;&lt;/span&gt;
   error: opt Error&lt;span class="p"&gt;;&lt;/span&gt;
   quote_class: text&lt;span class="p"&gt;;&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the file is created, specify interfaces/target_interface.did in method.interface. At this point, the datasource field should look like the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2ixw4-taaaa-aaaag-qcpdq-cai&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;get_exchange_rates:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;()&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(vec&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ExchangeRate__1)'&lt;/span&gt;
    &lt;span class="na"&gt;interface&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;interfaces/target_interface.did&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, add a setting for this component to call canisters outside of Chainsight Platform. is_target_component should be set to false. If this flag is not set and is true, the component is to call a component within Chainsight Platform. This completes the update of the manifest. The completed manifest is as follows&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ICP Snapshot Indexer by handson&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;snapshot_indexer_icp&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Collect&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ICP&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;prices.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;This&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;sample&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;of&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;components&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;that&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;will&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;be&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;built&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;in&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Hands-on&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;article.'&lt;/span&gt;
  &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Price Snapshot Indexer&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ICP&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hands-on&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Sample"&lt;/span&gt;
&lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2ixw4-taaaa-aaaag-qcpdq-cai&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;get_exchange_rates:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;()&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(vec&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ExchangeRate__1)'&lt;/span&gt;
    &lt;span class="na"&gt;interface&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;interfaces/target_interface.did&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
&lt;span class="na"&gt;is_target_component&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="na"&gt;lens_targets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3600&lt;/span&gt;
&lt;span class="na"&gt;cycles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For metadata, any arbitrary setting is fine. Check the datasource field and is_target_component again. If you have successfully modified the code up to this point, let's generate the code immediately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generate a code &amp;amp; build a module&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's generate the canister code with csx generate. If you actually run this command, you will get the following output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% csx generate
Feb 06 07:22:01.688 INFO Start code generation &lt;span class="k"&gt;for &lt;/span&gt;project &lt;span class="s1"&gt;'sample_icp'&lt;/span&gt;
Feb 06 07:22:01.691 INFO &lt;span class="o"&gt;[&lt;/span&gt;icp_snapshot_indexer] Start processing...
Feb 06 07:22:01.694 INFO &lt;span class="o"&gt;[&lt;/span&gt;icp_snapshot_indexer] Generate interfaces &lt;span class="o"&gt;(&lt;/span&gt;.did files&lt;span class="o"&gt;)&lt;/span&gt; ...
Feb 06 07:22:14.300 INFO &lt;span class="o"&gt;[&lt;/span&gt;icp_snapshot_indexer] Succeeded: Generate interfaces &lt;span class="o"&gt;(&lt;/span&gt;.did files&lt;span class="o"&gt;)&lt;/span&gt;
Feb 06 07:22:14.300 INFO Project &lt;span class="s1"&gt;'sample_icp'&lt;/span&gt; codes/resources generated successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As with the Snapshot Indexer EVM, no additional customization is required for this interface in the Snapshot Indexer ICP. The build process can begin without any additional customization.&lt;/p&gt;

&lt;p&gt;You can generate modules from code with csx build. Let's run it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% csx build
Feb 07 14:28:14.403 INFO Start building project &lt;span class="s1"&gt;'sample_icp'&lt;/span&gt;
Feb 07 14:28:14.403 INFO Start code generation &lt;span class="k"&gt;for &lt;/span&gt;project &lt;span class="s1"&gt;'sample_icp'&lt;/span&gt;
Feb 07 14:28:14.406 INFO &lt;span class="o"&gt;[&lt;/span&gt;icp_snapshot_indexer] Start processing...
Feb 07 14:28:14.410 INFO &lt;span class="o"&gt;[&lt;/span&gt;icp_snapshot_indexer] Skip creating logic project: &lt;span class="s1"&gt;'./src/logics/icp_snapshot_indexer'&lt;/span&gt; already exists
Feb 07 14:28:14.411 INFO &lt;span class="o"&gt;[&lt;/span&gt;icp_snapshot_indexer] Generate interfaces &lt;span class="o"&gt;(&lt;/span&gt;.did files&lt;span class="o"&gt;)&lt;/span&gt; ...
Feb 07 14:28:19.094 INFO &lt;span class="o"&gt;[&lt;/span&gt;icp_snapshot_indexer] Succeeded: Generate interfaces &lt;span class="o"&gt;(&lt;/span&gt;.did files&lt;span class="o"&gt;)&lt;/span&gt;
Feb 07 14:28:19.094 INFO Project &lt;span class="s1"&gt;'sample_icp'&lt;/span&gt; codes/resources generated successfully
Feb 07 14:28:19.094 INFO Start building...
Feb 07 14:28:19.099 INFO Compile canisters...
Feb 07 14:28:25.620 INFO Succeeded: Compile canisters
Feb 07 14:28:25.620 INFO Shrink/Optimize modules...
Feb 07 14:28:25.693 INFO Succeeded: Shrink/Optimize modules
Feb 07 14:28:25.693 INFO Add metadata to modules...
Feb 07 14:28:25.755 INFO Succeeded: Add metadata to modules
Feb 07 14:28:25.755 INFO Project &lt;span class="s1"&gt;'sample_icp'&lt;/span&gt; built successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The build will be completed in less than a few minutes. This command generates the WASM module and candid interface. For a more in-depth understanding of these behaviors, please refer to the following articles&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@Chainsight_Network/behind-chainsight-how-modules-are-created-pt-2-4cf29234b98b"&gt;Behind Chainsight: How Modules are Created Pt. 2 | by Chainsight | Feb, 2024 | Medium&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, deploy and start the component!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deploy a component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Deploy this component on the Chainsight Platform with csx deploy and csx exec as in previous hands-on sessions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;csx deploy &lt;span class="nt"&gt;--network&lt;/span&gt; ic &lt;span class="nt"&gt;--component&lt;/span&gt; icp_snapshot_indexer
csx &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;--network&lt;/span&gt; ic &lt;span class="nt"&gt;--component&lt;/span&gt; icp_snapshot_indexer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you run these, you should get the following logs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% csx deploy &lt;span class="nt"&gt;--network&lt;/span&gt; ic &lt;span class="nt"&gt;--component&lt;/span&gt; icp_snapshot_indexer
Feb 07 14:43:27.188 INFO Checking environments...
Feb 07 14:43:27.188 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx ping ic'&lt;/span&gt;
Feb 07 14:43:27.828 INFO Suceeded: dfx ping ic
Feb 07 14:43:27.828 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx identity whoami --network ic'&lt;/span&gt;
Feb 07 14:43:27.910 INFO Suceeded: dfx identity &lt;span class="nb"&gt;whoami&lt;/span&gt; &lt;span class="nt"&gt;--network&lt;/span&gt; ic
Feb 07 14:43:27.910 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx identity get-principal --network ic'&lt;/span&gt;
Feb 07 14:43:27.987 INFO Suceeded: dfx identity get-principal &lt;span class="nt"&gt;--network&lt;/span&gt; ic
Feb 07 14:43:27.987 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx identity get-wallet --network ic'&lt;/span&gt;
Feb 07 14:43:28.063 INFO Suceeded: dfx identity get-wallet &lt;span class="nt"&gt;--network&lt;/span&gt; ic
Feb 07 14:43:28.063 INFO Checking environments finished successfully
Feb 07 14:43:28.063 INFO Start deploying project &lt;span class="s1"&gt;'sample_icp'&lt;/span&gt;...
Feb 07 14:43:28.063 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx canister create --network ic icp_snapshot_indexer'&lt;/span&gt;
Feb 07 14:43:32.757 INFO Suceeded: dfx canister create &lt;span class="nt"&gt;--network&lt;/span&gt; ic icp_snapshot_indexer
Feb 07 14:43:32.757 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx build --network ic icp_snapshot_indexer'&lt;/span&gt;
Feb 07 14:43:32.945 INFO Suceeded: dfx build &lt;span class="nt"&gt;--network&lt;/span&gt; ic icp_snapshot_indexer
Feb 07 14:43:32.945 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx canister install --network ic icp_snapshot_indexer'&lt;/span&gt;
Feb 07 14:43:43.151 INFO Suceeded: dfx canister &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--network&lt;/span&gt; ic icp_snapshot_indexer
Feb 07 14:43:43.151 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx canister update-settings --add-controller xkzfe-fiaaa-aaaal-qcnuq-cai --network ic icp_snapshot_indexer'&lt;/span&gt;
Feb 07 14:43:50.150 INFO Suceeded: dfx canister update-settings &lt;span class="nt"&gt;--add-controller&lt;/span&gt; xkzfe-fiaaa-aaaal-qcnuq-cai &lt;span class="nt"&gt;--network&lt;/span&gt; ic icp_snapshot_indexer
Feb 07 14:43:51.507 INFO Current deployed status:
Canister Name: icp_snapshot_indexer
  Canister Id: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"ic"&lt;/span&gt;: &lt;span class="s2"&gt;"lqf7x-4yaaa-aaaal-qdg7q-cai"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
  Controllers: 5naws-oiaaa-aaaal-qbxuq-cai k245a-2cvyi-rcnzj-cpq6h-dcy7o-qrg4b-325bv-5c3om-jfceo-ikmjz-aqe xkzfe-fiaaa-aaaal-qcnuq-cai
  Module Hash: 0xfa98d0d929e40968a31f9da12485805b512ed538ae6b74ec41364057546d1ce3

% csx &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;--network&lt;/span&gt; ic &lt;span class="nt"&gt;--component&lt;/span&gt; icp_snapshot_indexer
Feb 07 14:43:59.998 INFO Execute canister processing...
Feb 07 14:43:59.998 INFO Start processing &lt;span class="k"&gt;for &lt;/span&gt;commands generation...
Feb 07 14:44:00.001 INFO Script &lt;span class="k"&gt;for &lt;/span&gt;Component &lt;span class="s2"&gt;"icp_snapshot_indexer"&lt;/span&gt; generated successfully
Feb 07 14:44:00.001 INFO Entrypoint Script generated successfully
Feb 07 14:44:00.001 INFO Start processing &lt;span class="k"&gt;for &lt;/span&gt;commands execution...
Feb 07 14:44:00.001 INFO Run scripts to execute commands &lt;span class="k"&gt;for &lt;/span&gt;deployed components
Feb 07 14:44:00.001 INFO Selected component is &lt;span class="s1"&gt;'icp_snapshot_indexer'&lt;/span&gt;
Feb 07 14:44:44.155 INFO Executed &lt;span class="s1"&gt;'./scripts/entrypoint.sh'&lt;/span&gt; successfully
Feb 07 14:44:44.155 INFO Project &lt;span class="s2"&gt;"sample_icp"&lt;/span&gt; canisters executed successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The deployment and operation start instruction is now complete! Now all you have to do is wait for the interval of the automatic execution and you can refer to the data.&lt;/p&gt;




&lt;p&gt;The components that can be created in this hands-on session are also actually running! (We have changed the description and execution interval a bit.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0i9qrans22unjywd6w4j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0i9qrans22unjywd6w4j.png" alt="handson-snapshot_indexer_icp-4" width="800" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://beta.chainsight.network/explore/components/lqf7x-4yaaa-aaaal-qdg7q-cai"&gt;https://beta.chainsight.network/explore/components/lqf7x-4yaaa-aaaal-qdg7q-cai&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This concludes our hands-on with the Snapshot Indexer EVM. We will continue to create and publish new hands-on sessions in the future, so please look forward to them!&lt;/p&gt;

&lt;p&gt;Written by &lt;a href="https://twitter.com/megared05"&gt;Megared@Chainsight&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>tutorial</category>
      <category>oracle</category>
      <category>dfinity</category>
    </item>
    <item>
      <title>Chainsight Hands-on: Collecting Data from Onchain</title>
      <dc:creator>megared05</dc:creator>
      <pubDate>Mon, 12 Feb 2024 06:40:36 +0000</pubDate>
      <link>https://forem.com/megared05/chainsight-hands-on-collecting-data-from-onchain-1d31</link>
      <guid>https://forem.com/megared05/chainsight-hands-on-collecting-data-from-onchain-1d31</guid>
      <description>&lt;p&gt;Previously we created a hands-on article on creating a component to collect bitcoin price data from the web. We have built Snapshot Indexer HTTPS to collect data from the web with reliability, but now let's try to get data on-chain. In this article, we will create a component that collects data from Ethereum using the Snapshot Indexer EVM.&lt;/p&gt;

&lt;p&gt;In this project, let's create a Price Snapshot Indexer EVM that can get the price of a specified currency using the Price Aggregator Contract on Ethereum.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Completed Component Definition&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's create a Snapshot Indexer EVM that collects Ethereum prices. In order to get the Ethereum price, we will use the ETH/USD Aggregator Contract in the Ethereum Blockchain to collect the price data. This component is constructed with a collection interval of 1 hour.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqtks02a2r9j2hhjdy1zw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqtks02a2r9j2hhjdy1zw.png" alt="chainsight_deepdive_into_showcase-handson-snapshot_indexer_evm.png" width="581" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisite&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Chainsight CLI requires several tools and this CLI installation. Please refer to the following article for this preliminary preparation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/hide_yoshi/step-by-step-creating-an-evm-price-oracle-with-chainsight-469g"&gt;Step-by-step creating an EVM Price Oracle with Chainsight - DEV Community&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a project &amp;amp; add a manifest template&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As before, build from an empty project; use &lt;code&gt;csx new --no-samples&lt;/code&gt; to create a template.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% csx new &lt;span class="nt"&gt;--no-samples&lt;/span&gt; sample_evm
Jan 30 13:24:51.690 INFO Start creating new project &lt;span class="s1"&gt;'sample_evm'&lt;/span&gt;...
Jan 30 13:24:51.691 INFO Project &lt;span class="s1"&gt;'sample_evm'&lt;/span&gt; created successfully
Jan 30 13:24:51.691 INFO You can add components with:

  &lt;span class="nb"&gt;cd &lt;/span&gt;sample_evm &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; csx add
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then use &lt;code&gt;csx add&lt;/code&gt; to add the Snapshot Indexer EVM. &lt;code&gt;snapshot_indexer_evm&lt;/code&gt; type should be selected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% &lt;span class="nb"&gt;cd &lt;/span&gt;sample_evm 
% csx add
✔ Please input Component Name to add · sample_component
✔ Please &lt;span class="k"&gt;select &lt;/span&gt;Component Type to add · snapshot_indexer_evm
Jan 30 13:25:38.714 INFO Start creating new component &lt;span class="s1"&gt;'sample_component'&lt;/span&gt;...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's update this manifest that we have added and generate a contract that retrieves data from the Aggregator Contract. The contract to be called this time is as follows. Use the Aggregator Contract that Chainlink deploys on Ethereum.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7lpo776wojlfw88etnb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7lpo776wojlfw88etnb.png" alt="chainsight-handson-evm-1.png" width="797" height="183"&gt;&lt;/a&gt;&lt;br&gt;
Source: &lt;a href="https://docs.chain.link/data-feeds/price-feeds/addresses?network=ethereum&amp;amp;page=1#ethereum-mainnet"&gt;https://docs.chain.link/data-feeds/price-feeds/addresses?network=ethereum&amp;amp;page=1#ethereum-mainnet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the datasource field, specify the contract and its function to be called this time, setting &lt;code&gt;location.id&lt;/code&gt; to &lt;code&gt;5f4eC3Df9cbd43714FE2740f5E3616155c5b8419&lt;/code&gt;  without prefix and &lt;code&gt;method.identifier&lt;/code&gt; to &lt;code&gt;latestAnswer():(int256)&lt;/code&gt; to get the latest price data from this contract. Finally, an ABI file in JSON format must be obtained, placed in the &lt;code&gt;interface&lt;/code&gt; folder, and specified in &lt;code&gt;method.interface&lt;/code&gt;. The contents of the ABI can be getted from the following url.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://etherscan.io/address/0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419#code"&gt;https://etherscan.io/address/0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419#code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The final modified datasource field will look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5f4eC3Df9cbd43714FE2740f5E3616155c5b8419&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;network_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
      &lt;span class="na"&gt;rpc_url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://mainnet.infura.io/v3/${INFURA_MAINNET_RPC_URL_KEY}&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;latestAnswer():(int256)&lt;/span&gt;
    &lt;span class="na"&gt;interface&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Aggregator.json&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have the above modifications at hand, let's get started with the code generation!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generate a code &amp;amp; build a module&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;csx generate&lt;/code&gt;  will generate canister code with the manifest in your project as input. Now let's run it to generate the code for the Snapshot Indexer EVM we mentioned earlier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% csx generate
Feb 02 13:24:12.258 INFO Start code generation &lt;span class="k"&gt;for &lt;/span&gt;project &lt;span class="s1"&gt;'sample_evm'&lt;/span&gt;
Feb 02 13:24:12.259 INFO &lt;span class="o"&gt;[&lt;/span&gt;sample_component] Start processing...
Feb 02 13:24:12.259 INFO &lt;span class="o"&gt;[&lt;/span&gt;sample_component] Interface file &lt;span class="s1"&gt;'Aggregator.json'&lt;/span&gt; copied from user&lt;span class="s1"&gt;'s interface
Feb 02 13:24:12.411 INFO [sample_component] Generate interfaces (.did files) ...
Feb 02 13:24:13.039 INFO [sample_component] Succeeded: Generate interfaces (.did files)
Feb 02 13:24:13.039 INFO Project '&lt;/span&gt;sample_evm&lt;span class="s1"&gt;' codes/resources generated successfully
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the log is displayed like this, the command has successfully completed. Depending on some Component and its parameters, it is possible to make customizations and adjustments to this generated canister code, but in the case of this Snapshot Indexer EVM, this is not necessary. This is the completed canister code. Therefore, this is all that is needed to begin the build process.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;csx build&lt;/code&gt;  builds the generated code into modules and generates what is needed to deploy them as components of Chainsight Platform. Let's run it immediately.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% csx build
Feb 02 13:28:31.518 INFO Start building project &lt;span class="s1"&gt;'sample_evm'&lt;/span&gt;
Feb 02 13:28:31.518 INFO Start code generation &lt;span class="k"&gt;for &lt;/span&gt;project &lt;span class="s1"&gt;'sample_evm'&lt;/span&gt;
Feb 02 13:28:31.519 INFO &lt;span class="o"&gt;[&lt;/span&gt;sample_component] Start processing...
Feb 02 13:28:31.519 INFO &lt;span class="o"&gt;[&lt;/span&gt;sample_component] Interface file &lt;span class="s1"&gt;'Aggregator.json'&lt;/span&gt; copied from user&lt;span class="s1"&gt;'s interface
Feb 02 13:28:31.524 INFO [sample_component] Skip creating logic project: '&lt;/span&gt;./src/logics/sample_component&lt;span class="s1"&gt;' already exists
Feb 02 13:28:31.524 INFO [sample_component] Generate interfaces (.did files) ...
Feb 02 13:28:32.443 INFO [sample_component] Succeeded: Generate interfaces (.did files)
Feb 02 13:28:32.443 INFO Project '&lt;/span&gt;sample_evm&lt;span class="s1"&gt;' codes/resources generated successfully
Feb 02 13:28:32.443 INFO Start building...
Feb 02 13:28:32.443 INFO Compile canisters...
Feb 02 13:29:10.484 INFO Succeeded: Compile canisters
Feb 02 13:29:10.484 INFO Shrink/Optimize modules...
Feb 02 13:29:10.590 INFO Succeeded: Shrink/Optimize modules
Feb 02 13:29:10.590 INFO Add metadata to modules...
Feb 02 13:29:10.685 INFO Succeeded: Add metadata to modules
Feb 02 13:29:10.685 INFO Project '&lt;/span&gt;sample_evm&lt;span class="s1"&gt;' built successfully
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The build process takes less than a few minutes and the artifacts generated by the csx build are placed in the artifacts folder. If you look in that folder, you will see WASM modules and candid interface files that actually have component names as their file names. For a more in-depth understanding, please refer to the following article.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@Chainsight_Network/behind-chainsight-how-modules-are-created-pt-2-4cf29234b98b"&gt;Behind Chainsight: How Modules are Created Pt. 2 | by Chainsight | Feb, 2024 | Medium&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, deploy and start the component!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deploy a component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you can deploy this module as a component of the Chainsight Platform, all is done.&lt;/p&gt;

&lt;p&gt;With csx deploy we can actually deploy to the Chainsight Platform on Internet Computer, and with csx exec we can send the commands to start working. Let's run the command with some parameters to specify the component and execution network.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;csx deploy &lt;span class="nt"&gt;--network&lt;/span&gt; ic &lt;span class="nt"&gt;--component&lt;/span&gt; sample_component
csx &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;--network&lt;/span&gt; ic &lt;span class="nt"&gt;--component&lt;/span&gt; sample_component
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you run these commands and they complete without problems, you should see the following output! The log here has slightly changed the names of the components, so just read and check that point.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% csx deploy &lt;span class="nt"&gt;--network&lt;/span&gt; ic &lt;span class="nt"&gt;--component&lt;/span&gt; eth_snapshot_indexer
Feb 02 13:35:53.077 INFO Checking environments...
Feb 02 13:35:53.077 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx ping ic'&lt;/span&gt;
Feb 02 13:35:54.957 INFO Suceeded: dfx ping ic
Feb 02 13:35:54.957 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx identity whoami --network ic'&lt;/span&gt;
Feb 02 13:35:55.044 INFO Suceeded: dfx identity &lt;span class="nb"&gt;whoami&lt;/span&gt; &lt;span class="nt"&gt;--network&lt;/span&gt; ic
Feb 02 13:35:55.044 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx identity get-principal --network ic'&lt;/span&gt;
Feb 02 13:35:55.121 INFO Suceeded: dfx identity get-principal &lt;span class="nt"&gt;--network&lt;/span&gt; ic
Feb 02 13:35:55.121 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx identity get-wallet --network ic'&lt;/span&gt;
Feb 02 13:35:55.201 INFO Suceeded: dfx identity get-wallet &lt;span class="nt"&gt;--network&lt;/span&gt; ic
Feb 02 13:35:55.201 INFO Checking environments finished successfully
Feb 02 13:35:55.201 INFO Start deploying project &lt;span class="s1"&gt;'sample_evm'&lt;/span&gt;...
Feb 02 13:35:55.201 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx canister create --network ic eth_snapshot_indexer'&lt;/span&gt;
Feb 02 13:36:02.966 INFO Suceeded: dfx canister create &lt;span class="nt"&gt;--network&lt;/span&gt; ic eth_snapshot_indexer
Feb 02 13:36:02.966 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx build --network ic eth_snapshot_indexer'&lt;/span&gt;
Feb 02 13:36:03.218 INFO Suceeded: dfx build &lt;span class="nt"&gt;--network&lt;/span&gt; ic eth_snapshot_indexer
Feb 02 13:36:03.218 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx canister install --network ic eth_snapshot_indexer'&lt;/span&gt;
Feb 02 13:36:17.031 INFO Suceeded: dfx canister &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--network&lt;/span&gt; ic eth_snapshot_indexer
Feb 02 13:36:17.031 INFO Running &lt;span class="nb"&gt;command&lt;/span&gt;: &lt;span class="s1"&gt;'dfx canister update-settings --add-controller xkzfe-fiaaa-aaaal-qcnuq-cai --network ic eth_snapshot_indexer'&lt;/span&gt;
Feb 02 13:36:22.852 INFO Suceeded: dfx canister update-settings &lt;span class="nt"&gt;--add-controller&lt;/span&gt; xkzfe-fiaaa-aaaal-qcnuq-cai &lt;span class="nt"&gt;--network&lt;/span&gt; ic eth_snapshot_indexer
Feb 02 13:36:24.305 INFO Current deployed status:
Canister Name: eth_snapshot_indexer
  Canister Id: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"ic"&lt;/span&gt;: &lt;span class="s2"&gt;"5saj5-jqaaa-aaaal-qdfea-cai"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
  Controllers: 5naws-oiaaa-aaaal-qbxuq-cai k245a-2cvyi-rcnzj-cpq6h-dcy7o-qrg4b-325bv-5c3om-jfceo-ikmjz-aqe xkzfe-fiaaa-aaaal-qcnuq-cai
  Module Hash: 0x6c5ee5bdde96e2ef3c49d635d44086538bc38caf43e878a0651cdbbd0584c4ba
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;% csx &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;--network&lt;/span&gt; ic &lt;span class="nt"&gt;--component&lt;/span&gt; eth_snapshot_indexer
Feb 02 13:36:34.713 INFO Execute canister processing...
Feb 02 13:36:34.713 INFO Start processing &lt;span class="k"&gt;for &lt;/span&gt;commands generation...
Feb 02 13:36:34.713 INFO Script &lt;span class="k"&gt;for &lt;/span&gt;Component &lt;span class="s2"&gt;"eth_snapshot_indexer"&lt;/span&gt; generated successfully
Feb 02 13:36:34.713 INFO Entrypoint Script generated successfully
Feb 02 13:36:34.713 INFO Start processing &lt;span class="k"&gt;for &lt;/span&gt;commands execution...
Feb 02 13:36:34.713 INFO Run scripts to execute commands &lt;span class="k"&gt;for &lt;/span&gt;deployed components
Feb 02 13:36:34.713 INFO Selected component is &lt;span class="s1"&gt;'eth_snapshot_indexer'&lt;/span&gt;
Feb 02 13:37:15.705 INFO Executed &lt;span class="s1"&gt;'./scripts/entrypoint.sh'&lt;/span&gt; successfully
Feb 02 13:37:15.705 INFO Project &lt;span class="s2"&gt;"sample_evm"&lt;/span&gt; canisters executed successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The deployment and operation start instruction is now complete! Now all you have to do is wait for the interval of the automatic execution and you can refer to the data.&lt;/p&gt;




&lt;p&gt;The components that can be created in this hands-on session are also actually running! (We have changed the description and execution interval a bit.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnacb69ryd7p6qvjrj154.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnacb69ryd7p6qvjrj154.png" alt="chainsight-handson-evm-2" width="800" height="278"&gt;&lt;/a&gt;&lt;br&gt;
Source: &lt;a href="https://beta.chainsight.network/explore/components/lcdio-qiaaa-aaaal-qdg4q-cai"&gt;Detail lcdio-qiaaa-aaaal-qdg4q-cai| Chainsight&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This concludes our hands-on with the Snapshot Indexer EVM. We will continue to create and publish new hands-on sessions in the future, so please look forward to them!&lt;/p&gt;

&lt;p&gt;Written by &lt;a href="https://twitter.com/megared05"&gt;Megared@Chainsight&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>tutorial</category>
      <category>ethereum</category>
      <category>oracle</category>
    </item>
    <item>
      <title>Chainsight Hands-on: Collecting Data from Web</title>
      <dc:creator>megared05</dc:creator>
      <pubDate>Thu, 08 Feb 2024 07:31:47 +0000</pubDate>
      <link>https://forem.com/megared05/chainsight-hands-on-collecting-data-from-web-1o00</link>
      <guid>https://forem.com/megared05/chainsight-hands-on-collecting-data-from-web-1o00</guid>
      <description>&lt;p&gt;So far, in &lt;a href="https://medium.com/@Chainsight_Network"&gt;medium.com&lt;/a&gt; we have delved deeply into the behind-the-scenes of components and SDKs, as well as showcases that combine various components. This time, we will actually go hands-on to create our own component. In this article, we will try to create a component that actually collects data from the Web using Snapshot Indexer HTTPS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Completed Component Definition&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Completed Component DefinitionThis time, let's create a Snapshot Indexer HTTPS that collects bitcoin prices. There are several APIs that provide bitcoin prices, but we will use coingecho's API to collect the current price. Let's construct Snapshot Indexer with a collection interval of one hour.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fri4u3jsnq7xq3imdxslq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fri4u3jsnq7xq3imdxslq.png" alt="chainsight_deepdive_into_showcase-handson-snapshot_indexer_https.png" width="511" height="179"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisite&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Chainsight CLI requires several tools and this CLI installation. Please refer to the following article for this preliminary preparation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/hide_yoshi/step-by-step-creating-an-evm-price-oracle-with-chainsight-469g"&gt;Step-by-step creating an EVM Price Oracle with Chainsight - DEV Community&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first step is to build a project template. In this case, we only need one manifest, so let's proceed by adding a manifest of the type we want to create from an empty project. The command to create a project is &lt;code&gt;csx new&lt;/code&gt;.  Give the &lt;code&gt;-no-sample&lt;/code&gt; option to make the project empty.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv8ftpht5hy0wbawenwkq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv8ftpht5hy0wbawenwkq.png" alt="chainsight-handson-web-1" width="503" height="84"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looking at the created project, the manifest folder, components, is empty.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp8m5u7pawy7uh8pm74yb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp8m5u7pawy7uh8pm74yb.png" alt="chainsight-handson-web-2" width="762" height="70"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's run csx add to add the manifest as instructed in the log.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add a manifest&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can use &lt;code&gt;csx add&lt;/code&gt; to interactively add a manifest of the type you wish to add. Let's actually run &lt;code&gt;csx add&lt;/code&gt; with the name &lt;code&gt;btc_snapshot_indexer&lt;/code&gt; and the type &lt;code&gt;snapshot_indexer_https&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fklcnzp20et44kzbb3rxq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fklcnzp20et44kzbb3rxq.png" alt="chainsight-handson-web-3" width="695" height="70"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will generate a manifest (.yaml) for &lt;code&gt;btc_snapshot_indexer&lt;/code&gt; and update &lt;code&gt;project.yaml&lt;/code&gt; to include &lt;code&gt;btc_snapshot_indexer&lt;/code&gt; in the project itself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3dm2pxho4pfrmsyk6fl8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3dm2pxho4pfrmsyk6fl8.png" alt="chainsight-handson-web-4" width="409" height="101"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then update this generated manifest so that the bitcoin price can be retrieved. Get the bitcoin price by calling the /simple/price endpoint of the coingecko API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.coingecko.com/api/documentation"&gt;Crypto API Documentation | CoinGecko&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The parameters for actually taking this data are as follows. The id to retrieve bitcoin data is &lt;code&gt;bitcoin&lt;/code&gt;. Let's also specify some parameters to extend the data available at this endpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://api.coingecko.com/api/v3/simple/price
  ?ids=bitcoin
  &amp;amp;vs_currencies=usd,eur,btc,eth
  &amp;amp;include_market_cap=true
  &amp;amp;include_24hr_vol=true
  &amp;amp;include_24hr_change=true
  &amp;amp;include_last_updated_at=true
  &amp;amp;precision=18
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify &lt;code&gt;datasource&lt;/code&gt; field to specify this parameter in the &lt;code&gt;snapshot_indexer_https&lt;/code&gt; manifest. Specify the endpoint in the &lt;code&gt;url&lt;/code&gt; field. Since the query parameters are static and immutable this time, set &lt;code&gt;queries&lt;/code&gt; type to &lt;code&gt;static&lt;/code&gt; and &lt;code&gt;value&lt;/code&gt; field to the respective key and value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://api.coingecko.com/api/v3/simple/price&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/json&lt;/span&gt;
  &lt;span class="na"&gt;queries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;static&lt;/span&gt;
    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;ids&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bitcoin&lt;/span&gt;
      &lt;span class="na"&gt;vs_currencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;usd,eur,btc,eth&lt;/span&gt;
      &lt;span class="na"&gt;include_market_cap&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;include_24hr_vol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;include_24hr_change&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;include_last_updated_at&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;precision&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;18&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference between the template generated by &lt;code&gt;csx add&lt;/code&gt; and the updated manifest is as follows&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;9,10c9,11
&amp;lt;   - DAI
&amp;lt;   - USD
&lt;span class="nt"&gt;---&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;   - BTC
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;   - bitcoin
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;   - &lt;span class="s2"&gt;"Hands-on Sample"&lt;/span&gt;
18,19c19,25
&amp;lt;       ids: dai
&amp;lt;       vs_currencies: usd
&lt;span class="nt"&gt;---&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;       ids: bitcoin
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;       vs_currencies: usd,eur,btc,eth
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;       include_market_cap: &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;       include_24hr_vol: &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;       include_24hr_change: &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;       include_last_updated_at: &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;       precision: 18
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use this manifest to move on to the next step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generate a code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To generate the canister code for a component from its manifest, run &lt;code&gt;csx generate&lt;/code&gt; with the &lt;code&gt;project.yaml&lt;/code&gt; declaring the path to its manifest.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffhfloy6qeakb8z9m05cb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffhfloy6qeakb8z9m05cb.png" alt="chainsight-handson-web-5" width="659" height="88"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;csx generate&lt;/code&gt; generates a project to generate the canister module under the src folder. If no customization is required, module generation can be performed immediately by running &lt;code&gt;csx build&lt;/code&gt; in this state.&lt;/p&gt;

&lt;p&gt;Since this Snapshot Indexer is intended to collect only bitcoin prices, not all data that can be retrieved from the API is required. Also, the more data content, the more expensive it is to retain, and the higher the probability of consensus generation failure when retrieving data via HTTPS outcalls. For more information, please refer to the following article.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@Chainsight_Network/behind-chainsight-a-look-into-snapshot-indexer-component-d8a6074237e2"&gt;Behind Chainsight: How Modules are Created Pt. 1 | by Chainsight | Jan, 2024 | Medium&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Therefore, in order to avoid storing unnecessary data, modifications are made to narrow down the data to be collected.&lt;br&gt;
To make customizations to the generated code, modify &lt;code&gt;logics/(canister-name)/src/lib.rs&lt;/code&gt; in the &lt;code&gt;src&lt;/code&gt; directory. For any type of canister, you can add your own customizations by modifying the file replacing &lt;code&gt;canister-name&lt;/code&gt; with the name of the component of interest. If you want to know more about the project generated by &lt;code&gt;csx generate&lt;/code&gt;, please refer to this article.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@Chainsight_Network/behind-chainsight-how-modules-are-created-pt-1-32b13aa7f696"&gt;Behind Chainsight: How Modules are Created Pt. 1 | by Chainsight | Jan, 2024 | Medium&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's get back to the main issue. Let's open &lt;code&gt;logics/btc_snapshot_indexer/src/lib.rs&lt;/code&gt; in your project. The code should look something like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Auto-generated code from manifest.&lt;/span&gt;
&lt;span class="c1"&gt;// You update the structure as needed.&lt;/span&gt;
&lt;span class="c1"&gt;// The existence of the SnapshotValue structure must be maintained.&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;candid&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Decode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Encode&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nd"&gt;#[derive(Debug,&lt;/span&gt; &lt;span class="nd"&gt;Clone,&lt;/span&gt; &lt;span class="nd"&gt;candid::CandidType,&lt;/span&gt; &lt;span class="nd"&gt;candid::Deserialize,&lt;/span&gt; &lt;span class="nd"&gt;serde::Serialize,&lt;/span&gt; &lt;span class="nd"&gt;chainsight_cdk_macros::StableMemoryStorable)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;SnapshotValue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;bitcoin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Bitcoin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Debug,&lt;/span&gt; &lt;span class="nd"&gt;Clone,&lt;/span&gt; &lt;span class="nd"&gt;candid::CandidType,&lt;/span&gt; &lt;span class="nd"&gt;candid::Deserialize,&lt;/span&gt; &lt;span class="nd"&gt;serde::Serialize,&lt;/span&gt; &lt;span class="nd"&gt;chainsight_cdk_macros::StableMemoryStorable)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Bitcoin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;usd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;usd_market_cap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;usd_24h_vol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;usd_24h_change&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;eur&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;eur_market_cap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;eur_24h_vol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;eur_24h_change&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;btc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;btc_market_cap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;btc_24h_vol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;btc_24h_change&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;eth_market_cap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;eth_24h_vol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;eth_24h_change&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;last_updated_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an implementation for mapping the data obtained by calling the endpoints you specify. The trait you are using has the necessary functionality for the structure, so understand that that is the way it is and don't worry about it. The point of concern is the fields of the structure. Fields for a number of elements have already been declared. Where this code, which is implemented from the beginning, comes from is that the CLI automatically generates an implementation that matches the response from the endpoint you have set up. The actual response data will give you a sense of the implementation for mapping.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"bitcoin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"usd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;42451.59160065723&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"usd_market_cap"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;832331572531.3098&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"usd_24h_vol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;12740914009.764158&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"usd_24h_change"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.7450874696750942&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"btc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"btc_market_cap"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;19611887.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"btc_24h_vol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;300160.8233960758&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"btc_24h_change"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"eth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;18.650627839906598&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"eth_market_cap"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;365799851.323311&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"eth_24h_vol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;5597576.829903464&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"eth_24h_change"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.9213166048247731&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"last_updated_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1706500074&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, we only need to collect bitcoin price information. In other words, only &lt;code&gt;bitcoin.usd&lt;/code&gt; data needs to be collected. Let's remove all but the &lt;code&gt;usd&lt;/code&gt; field of the Bitcoin structure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;pub struct Bitcoin {
&lt;/span&gt;    pub usd: f64,
&lt;span class="gd"&gt;-    pub usd_market_cap: f64,
-    pub usd_24h_vol: f64,
-    pub usd_24h_change: f64,
-    pub eur: f64,
-    pub eur_market_cap: f64,
-    pub eur_24h_vol: f64,
-    pub eur_24h_change: f64,
-    pub btc: f64,
-    pub btc_market_cap: f64,
-    pub btc_24h_vol: f64,
-    pub btc_24h_change: f64,
-    pub eth: f64,
-    pub eth_market_cap: f64,
-    pub eth_24h_vol: f64,
-    pub eth_24h_change: f64,
-    pub last_updated_at: i64,
&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's update the logic in this way and run csx generate again. You have the template logic generated once you run generate, and you have placed code that modifies it. Therefore, if you run &lt;code&gt;csx generate&lt;/code&gt; again, you will see the log output that the execution has completed, skipping the logic generation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnobp1o2x3a4nd0tvzkuy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnobp1o2x3a4nd0tvzkuy.png" alt="chainsight-handson-web-6" width="800" height="89"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build a module&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Generate a module from the code created in the previous processes. Let's run &lt;code&gt;csx build&lt;/code&gt; immediately.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7pvx7bf4qzjj6wd4yjgu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7pvx7bf4qzjj6wd4yjgu.png" alt="chainsight-handson-web-7" width="800" height="198"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's all it took to generate a module for Chainsight from your code! Let's actually check out the artifact.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvycw2lm4zvo4a4fjyk9y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvycw2lm4zvo4a4fjyk9y.png" alt="chainsight-handson-web-8" width="532" height="28"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The artifacts generated by &lt;code&gt;csx build&lt;/code&gt; are placed in the &lt;code&gt;artifacts&lt;/code&gt; folder. If you look in that folder, you will see WASM modules and candid interface files with the actual component names as their file names. For a more in-depth understanding, please refer to the following articles&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@Chainsight_Network/behind-chainsight-how-modules-are-created-pt-2-4cf29234b98b"&gt;Behind Chainsight: How Modules are Created Pt. 2 | by Chainsight | Feb, 2024 | Medium&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's all there is to the build. Now all you have to do is deploy and get the component up and running.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deploy a component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's actually deploy the generated module in Chainsight. Components are deployed with &lt;code&gt;csx deploy&lt;/code&gt;, and after deployment is complete, &lt;code&gt;csx exec&lt;/code&gt; is executed to send a command to the component to start execution. Let's run through some options. Let's deploy to Internet Computer using &lt;code&gt;--component&lt;/code&gt; to explicitly specify the component to process and &lt;code&gt;--network&lt;/code&gt; to specify the network to run on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;csx deploy &lt;span class="nt"&gt;--network&lt;/span&gt; ic &lt;span class="nt"&gt;--component&lt;/span&gt; btc_snapshot_indexer
csx &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;--network&lt;/span&gt; ic &lt;span class="nt"&gt;--component&lt;/span&gt; btc_snapshot_indexer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb1vuownqf4pcppz5sigl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb1vuownqf4pcppz5sigl.png" alt="chainsight-handson-web-9" width="800" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3dypqr3cq1aapbsu5ck0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3dypqr3cq1aapbsu5ck0.png" alt="chainsight-handson-web-10" width="657" height="142"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The deployment and operation start instruction is now complete! Now all you have to do is wait for the interval of the automatic execution and you can refer to the data.&lt;/p&gt;




&lt;p&gt;Please take a look at the component that can be created in this hands-on session, which is actually running as a sample. (The description and execution interval have been slightly changed.)&lt;br&gt;
Using the Chainsight UI, you can check the acquired data, the execution cycle, and the state of the cycles that fuel it!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frarnu8ohsdpsg32727st.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frarnu8ohsdpsg32727st.png" alt="chainsight-handson-web-11" width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://beta.chainsight.network/explore/components/wqsbs-fyaaa-aaaal-qdezq-cai"&gt;https://beta.chainsight.network/explore/components/wqsbs-fyaaa-aaaal-qdezq-cai&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This concludes our hands-on with Snapshot Indexer HTTPS. We will continue to create and publish new hands-on sessions in the future, so please look forward to them!&lt;/p&gt;

&lt;p&gt;Written by &lt;a href="https://twitter.com/megared05"&gt;Megared@Chainsight&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>smartcontract</category>
      <category>tutorial</category>
      <category>oracle</category>
    </item>
  </channel>
</rss>
