'How to call contract's method from crate

I need to call the contract's method from my Indexer. Now I use tokio::process and near-cli written on NodeJs. It looks soundless, and I would like to do that from Rust.



Solution 1:[1]

Recommended way

NEAR JSON-RPC Client RS is the recommended way to interact with NEAR Protocol from within the Rust code.

Example from the README

use near_jsonrpc_client::{methods, JsonRpcClient};
use near_jsonrpc_primitives::types::transactions::TransactionInfo;

let mainnet_client = JsonRpcClient::connect("https://archival-rpc.mainnet.near.org");

let tx_status_request = methods::tx::RpcTransactionStatusRequest {
    transaction_info: TransactionInfo::TransactionId {
        hash: "9FtHUFBQsZ2MG77K3x3MJ9wjX3UT8zE1TczCrhZEcG8U".parse()?,
        account_id: "miraclx.near".parse()?,
    },
};

// call a method on the server via the connected client
let tx_status = mainnet_client.call(tx_status_request).await?;

println!("{:?}", tx_status);

In the examples folder of the repo, you will find different use cases, and hopefully, you'll find yours there as well.

near-jsonrpc-client-rs is the best option.

Alternative way

NB! This way is using non-documented APIs. It is not recommended way, because using these assumes you will dig into the code and find out how to use it by yourself.

If you're using the NEAR Indexer Framework you're literally running a nearcore node which includes:

  • JSON RPC server
  • ClientActor and ViewClient

Based on the kind of call you need to perform to your contract: change method or view method, you can use ClientActor or ViewClient.

ViewClient example

Code is for understanding the concept, not a working example.

let indexer = near_indexer::Indexer::new(indexer_config);

let view_client = indexer.client_actors().0;

let block_response = view_client
        .send(query)
        .await
        .context("Failed to deliver response")?
        .context("Invalid request")?;

You can find the usage in NEAR Indexer for Explorer starting from here

ClientActor example

ClientActor is used to send a transaction. I guess here's a good starting point to look for ClientActor example.

async fn send_tx_async(
    &self,
    request_data: near_jsonrpc_primitives::types::transactions::RpcBroadcastTransactionRequest,
) -> CryptoHash {
    let tx = request_data.signed_transaction;
    let hash = tx.get_hash().clone();
    self.client_addr.do_send(NetworkClientMessages::Transaction {
        transaction: tx,
        is_forwarded: false,
        check_only: false, // if we set true here it will not actually send the transaction
    });
    hash
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 khorolets