Reading From Indexes/External Tables

Learn how Zephyr programs can access publicly indexed data.

Zephyr tables are by default shareable across programs.

Note that when pricing kicks off creators of certain tables will be able to manage how their tables are accessed with custom rules.

This functionality allows any program or Custom Dashboardsto access already indexer + live-updated data on Mercury!

Let's make things practical and jump straight to an example. This code returns all indexed Blend Mainnet borrowed operations for a given pool:

use serde::{Deserialize, Serialize};
use zephyr_sdk::{prelude::*, EnvClient, DatabaseDerive};

// importing the public table
#[derive(DatabaseDerive, Clone)]
#[with_name("borrowed")]
#[external("8")]    // notice that! Below you have the full explanation
pub struct Borrowed {
    pub id: i64,
    pub timestamp: u64,
    pub ledger: u32,
    pub pool: String,
    pub asset: String,
    pub borrowed: i128,
    pub delta: i128,
    pub source: String,
}

#[derive(Deserialize)]
pub struct Request {
    pool: String,
}

#[derive(Serialize)]
pub struct ResponseObject {
    pub timestamp: u64,
    pub ledger: u32,
    pub asset: String,
    pub borrowed: String,
    pub delta: String,
    pub source: String,
}

#[no_mangle]
pub extern "C" fn get_borrowed_by_pool() {
    let env = EnvClient::empty();
    let request: Request = env.read_request_body();
    // starting from the publicly indexed "borrowed" table we filter through the Borrowed objects
    // for the ones whose ".pool" field matches our request body. 
    let borrowed: Vec<Borrowed> = env.read_filter().column_equal_to("pool", request.pool).read().unwrap();
    // return those as a Vec of objects of type "ResponseObject"
    let borrowed: Vec<ResponseObject> = borrowed.iter().map(|obj| {
        ResponseObject {
            timestamp: obj.timestamp,
            ledger: obj.ledger,
            asset: obj.asset.clone(),
            borrowed: (obj.borrowed as i64).to_string(),
            delta: (obj.delta as i64).to_string(),
            source: obj.source.clone()
        }
    }).collect();

    env.conclude(&borrowed)
}

The key here is the attribute

#[external("8")]

Which tells the compiler (and then the ZephyrVM) that you're reading from the borrowed table created by id 8 (in this case, blend's Mainnet deployment).

This function can be easily called through:

curl -X POST https://mainnet.mercurydata.app/zephyr/execute -H "Authorization: Bearer $MERCURY_JWT" -H 'Content-Type: application/json' -d '{"mode":{"Function": {"fname": "get_borrowed_by_pool", "arguments": "{\"pool\":\"CDVQVKOY2YSXS2IC7KN6MNASSHPAO7UN2UR2ON4OI2SKMFJNVAMDX6DP\"}"}}}'

To access public tables you need to get the name of the table as well as the id of the user who created it. These data as a general rule are made available by the creator itself.

As you can see here, we are accessing some data that we have not indexed ourselves quite easily, and this can be done from every point of your Zephyr program.

Last updated