Chainsight Hands-on: Collecting Data from Internet Computer
Tags: blockchain, tutorial, oracle, dfinity
Published: 2024-02-19 12:24:53

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.

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.

**Completed Component Definition**

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.

![chainsight_deepdive_into_showcase-handson-snapshot_indexer_icp.png](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1fr37op83998zwy7ma0e.png)

**Prerequisite**

The Chainsight CLI requires several tools and a `csx`  installation. Please refer to the following articles for this preliminary preparation.

https://dev.to/hide_yoshi/step-by-step-creating-an-evm-price-oracle-with-chainsight-469g

**Create a project & add a manifest template**

As before, build from an empty project; use `csx new --no-samples` to create a template.

```bash
% csx new --no-samples sample_icp
Feb 06 02:00:18.697 INFO Start creating new project 'sample_icp'...
Feb 06 02:00:18.698 INFO Project 'sample_icp' created successfully
Feb 06 02:00:18.698 INFO You can add components with:

  cd sample_icp && csx add
```

Then use csx add to add the Snapshot Indexer EVM. snapshot_indexer_icp type should be selected.

```bash
% csx add
✔ Please input Component Name to add · icp_snapshot_indexer
✔ Please select Component Type to add · snapshot_indexer_icp
Feb 06 02:01:11.560 INFO Start creating new component 'icp_snapshot_indexer'...
Feb 06 02:01:11.560 INFO SnapshotIndexerICP component 'icp_snapshot_indexer' added successfully
```

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.

CanisterId: `2ixw4-taaaa-aaaag-qcpdq-cai` 

![handson-snapshot_indexer_icp-1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r9kmzhyengzv2ka0hksv.png)

Source: https://info.icpswap.com/swap/token/details/ryjl3-tyaaa-aaaaa-aaaba-cai

In the `datasource` field, specify the canister and its function to call this time.

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

> Candid is an **interface description language**. Its primary purpose is to describe the public interface of a **service**, usually in the form of a program deployed as a **canister** 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.
> 

Source: https://internetcomputer.org/docs/current/developer-docs/backend/candid/candid-concepts

Internet Computer makes it easy to see the interface of the canister by using the Dashboard.


![handson-snapshot_indexer_icp-2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/77m4nanezhzueqd86zu1.png)

![handson-snapshot_indexer_icp-3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dqix52dht2sgd55rzgri.png)




Source: https://dashboard.internetcomputer.org/canister/2ixw4-taaaa-aaaag-qcpdq-cai

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

Specify a function declaration in `method.identifier` that includes arguments and response information: `get_exchange_rates: () -> (vec ExchangeRate__1)`. 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 `method.interface`. 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 `target_interface.did` under the interfaces folder and paste what you just copied into its contents. The actual folder and file will look like this

```bash
% ls interfaces 
target_interface.did
% cat interfaces/target_interface.did 
type ExchangeRate__1 = 
 record {
   base_class: text;
   base_symbol: text;
   decimals: nat32;
   error: opt Error;
   quote_class: text;
...
```

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

```yaml
datasource:
  location:
    id: 2ixw4-taaaa-aaaag-qcpdq-cai
  method:
    identifier: 'get_exchange_rates: () -> (vec ExchangeRate__1)'
    interface: interfaces/target_interface.did
    args: []
```

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

```yaml
version: v1
metadata:
  label: ICP Snapshot Indexer by handson
  type: snapshot_indexer_icp
  description: 'Collect ICP prices. This is a sample of the components that will be built in the Hands-on article.'
  tags:
  - Price Snapshot Indexer
  - ICP
  - "Hands-on Sample"
datasource:
  location:
    id: 2ixw4-taaaa-aaaag-qcpdq-cai
  method:
    identifier: 'get_exchange_rates: () -> (vec ExchangeRate__1)'
    interface: interfaces/target_interface.did
    args: []
is_target_component: false
lens_targets: null
interval: 3600
cycles: null
```

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.

**Generate a code & build a module**

Let's generate the canister code with csx generate. If you actually run this command, you will get the following output.

```bash
% csx generate
Feb 06 07:22:01.688 INFO Start code generation for project 'sample_icp'
Feb 06 07:22:01.691 INFO [icp_snapshot_indexer] Start processing...
Feb 06 07:22:01.694 INFO [icp_snapshot_indexer] Generate interfaces (.did files) ...
Feb 06 07:22:14.300 INFO [icp_snapshot_indexer] Succeeded: Generate interfaces (.did files)
Feb 06 07:22:14.300 INFO Project 'sample_icp' codes/resources generated successfully
```

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.

You can generate modules from code with csx build. Let's run it.

```bash
% csx build
Feb 07 14:28:14.403 INFO Start building project 'sample_icp'
Feb 07 14:28:14.403 INFO Start code generation for project 'sample_icp'
Feb 07 14:28:14.406 INFO [icp_snapshot_indexer] Start processing...
Feb 07 14:28:14.410 INFO [icp_snapshot_indexer] Skip creating logic project: './src/logics/icp_snapshot_indexer' already exists
Feb 07 14:28:14.411 INFO [icp_snapshot_indexer] Generate interfaces (.did files) ...
Feb 07 14:28:19.094 INFO [icp_snapshot_indexer] Succeeded: Generate interfaces (.did files)
Feb 07 14:28:19.094 INFO Project 'sample_icp' 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 'sample_icp' built successfully
```

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

[Behind Chainsight: How Modules are Created Pt. 2 | by Chainsight | Feb, 2024 | Medium](https://medium.com/@Chainsight_Network/behind-chainsight-how-modules-are-created-pt-2-4cf29234b98b)

Finally, deploy and start the component!

**Deploy a component**

Deploy this component on the Chainsight Platform with csx deploy and csx exec as in previous hands-on sessions.

```bash
csx deploy --network ic --component icp_snapshot_indexer
csx exec --network ic --component icp_snapshot_indexer
```

When you run these, you should get the following logs.

```bash
% csx deploy --network ic --component icp_snapshot_indexer
Feb 07 14:43:27.188 INFO Checking environments...
Feb 07 14:43:27.188 INFO Running command: 'dfx ping ic'
Feb 07 14:43:27.828 INFO Suceeded: dfx ping ic
Feb 07 14:43:27.828 INFO Running command: 'dfx identity whoami --network ic'
Feb 07 14:43:27.910 INFO Suceeded: dfx identity whoami --network ic
Feb 07 14:43:27.910 INFO Running command: 'dfx identity get-principal --network ic'
Feb 07 14:43:27.987 INFO Suceeded: dfx identity get-principal --network ic
Feb 07 14:43:27.987 INFO Running command: 'dfx identity get-wallet --network ic'
Feb 07 14:43:28.063 INFO Suceeded: dfx identity get-wallet --network ic
Feb 07 14:43:28.063 INFO Checking environments finished successfully
Feb 07 14:43:28.063 INFO Start deploying project 'sample_icp'...
Feb 07 14:43:28.063 INFO Running command: 'dfx canister create --network ic icp_snapshot_indexer'
Feb 07 14:43:32.757 INFO Suceeded: dfx canister create --network ic icp_snapshot_indexer
Feb 07 14:43:32.757 INFO Running command: 'dfx build --network ic icp_snapshot_indexer'
Feb 07 14:43:32.945 INFO Suceeded: dfx build --network ic icp_snapshot_indexer
Feb 07 14:43:32.945 INFO Running command: 'dfx canister install --network ic icp_snapshot_indexer'
Feb 07 14:43:43.151 INFO Suceeded: dfx canister install --network ic icp_snapshot_indexer
Feb 07 14:43:43.151 INFO Running command: 'dfx canister update-settings --add-controller xkzfe-fiaaa-aaaal-qcnuq-cai --network ic icp_snapshot_indexer'
Feb 07 14:43:50.150 INFO Suceeded: dfx canister update-settings --add-controller xkzfe-fiaaa-aaaal-qcnuq-cai --network ic icp_snapshot_indexer
Feb 07 14:43:51.507 INFO Current deployed status:
Canister Name: icp_snapshot_indexer
  Canister Id: {"ic": "lqf7x-4yaaa-aaaal-qdg7q-cai"}
  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 exec --network ic --component icp_snapshot_indexer
Feb 07 14:43:59.998 INFO Execute canister processing...
Feb 07 14:43:59.998 INFO Start processing for commands generation...
Feb 07 14:44:00.001 INFO Script for Component "icp_snapshot_indexer" generated successfully
Feb 07 14:44:00.001 INFO Entrypoint Script generated successfully
Feb 07 14:44:00.001 INFO Start processing for commands execution...
Feb 07 14:44:00.001 INFO Run scripts to execute commands for deployed components
Feb 07 14:44:00.001 INFO Selected component is 'icp_snapshot_indexer'
Feb 07 14:44:44.155 INFO Executed './scripts/entrypoint.sh' successfully
Feb 07 14:44:44.155 INFO Project "sample_icp" canisters executed successfully
```

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.

***

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.)


![handson-snapshot_indexer_icp-4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0i9qrans22unjywd6w4j.png)


Source: https://beta.chainsight.network/explore/components/lqf7x-4yaaa-aaaal-qdg7q-cai

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!

Written by [Megared@Chainsight](https://twitter.com/megared05)