Skip to content

Commit

Permalink
Add more query functions
Browse files Browse the repository at this point in the history
  • Loading branch information
saeed-zil committed Jun 20, 2024
1 parent 792de59 commit 4ed7b77
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 28 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ sha3 = "0.10.8"
semver = "1.0.22"
serde = "1.0.196"
serde_json = "1.0.113"
serde_with = "3.8.1"
syn = "2.0"
thiserror = "1.0.56"
tokio = "1.35.1"
Expand Down
1 change: 1 addition & 0 deletions crates/sdk/libs/near/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ license.workspace = true
[dependencies]
serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true
serde_with = {workspace = true, features = ["base64"]}

calimero-sdk = { path = "../../" }
calimero-primitives = { path = "../../../primitives" }
Expand Down
27 changes: 18 additions & 9 deletions crates/sdk/libs/near/src/jsonrpc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use calimero_sdk::env;
use serde::de::DeserializeOwned;
use serde::Deserialize;
use serde::{Deserialize, Serialize};

pub(crate) struct Client {
url: String,
Expand All @@ -15,20 +15,20 @@ impl Client {
}
}

pub fn call<T: DeserializeOwned, E: DeserializeOwned>(
pub fn call<T: DeserializeOwned, E: DeserializeOwned, P: Serialize>(
&self,
method: &str,
params: serde_json::Value,
params: P,
) -> Result<Response<T, E>, String> {
let headers = [("Content-Type", "application/json")];

*self.id.borrow_mut() += 1;
let body = serde_json::to_vec(&serde_json::json!({
"jsonrpc": "2.0",
"id": self.id.borrow().to_string(),
"method": method,
"params": params,
}))
let body = serde_json::to_vec(&Request {
jsonrpc: "2.0",
id: self.id.borrow().to_string(),
method: method.to_string(),
params,
})
.map_err(|err| format!("Cannot serialize request: {:?}", err))?;

let response = unsafe { env::ext::fetch(&self.url, "POST", &headers, &body) }?;
Expand All @@ -37,6 +37,15 @@ impl Client {
}
}

#[derive(Debug, Clone, Serialize)]
pub struct Request<P: Serialize> {
pub jsonrpc: &'static str,
pub id: String,
pub method: String,

pub params: P,
}

#[derive(Debug, Clone, Deserialize)]
pub struct Response<T: DeserializeOwned, E: DeserializeOwned> {
pub jsonrpc: Option<String>,
Expand Down
95 changes: 81 additions & 14 deletions crates/sdk/libs/near/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use jsonrpc::Response;
use query::{QueryResponseKind, RpcQueryRequest};
use types::BlockId;
use types::{BlockId, StoreKey};
use views::QueryRequest;

mod jsonrpc;
Expand Down Expand Up @@ -36,9 +36,8 @@ impl Client {
account_id: account_id.to_string(),
},
};
let response: Response<query::RpcQueryResponse, String> = self
.client
.call("query", serde_json::to_value(&request).unwrap())?;
let response: Response<query::RpcQueryResponse, String> =
self.client.call("query", request)?;

match response.data {
Ok(r) => {
Expand All @@ -51,18 +50,86 @@ impl Client {
}
}

pub fn view_code(&self, account_id: &str) -> Result<views::ContractCodeView, String> {
let response: Response<views::ContractCodeView, String> = self.client.call(
"query",
serde_json::json!({
"request_type": "view_code",
"finality": "final",
"account_id": account_id,
}),
)?;
pub fn view_code(
&self,
account_id: &str,
block_id: BlockId,
) -> Result<views::ContractCodeView, String> {
let request = RpcQueryRequest {
block_id,
request: QueryRequest::ViewCode {
account_id: account_id.to_string(),
},
};

let response: Response<query::RpcQueryResponse, String> =
self.client.call("query", request)?;

match response.data {
Ok(r) => Ok(r),
Ok(r) => {
if let QueryResponseKind::ViewCode(vc) = r.kind {
return Ok(vc);
}
return Err("Unexpected response returned.".to_string());
}
Err(e) => Err(format!("Error: {}, Code: {}", e.message, e.code,)),
}
}

pub fn view_state(
&self,
account_id: &str,
prefix: StoreKey,
include_proof: bool,
block_id: BlockId,
) -> Result<views::ViewStateResult, String> {
let request = RpcQueryRequest {
block_id,
request: QueryRequest::ViewState {
account_id: account_id.to_string(),
prefix,
include_proof,
},
};

let response: Response<query::RpcQueryResponse, String> =
self.client.call("query", request)?;

match response.data {
Ok(r) => {
if let QueryResponseKind::ViewState(vs) = r.kind {
return Ok(vs);
}
return Err("Unexpected response returned.".to_string());
}
Err(e) => Err(format!("Error: {}, Code: {}", e.message, e.code,)),
}
}

pub fn view_access_key(
&self,
account_id: &str,
public_key: &str,
block_id: BlockId,
) -> Result<views::ViewStateResult, String> {
let request = RpcQueryRequest {
block_id,
request: QueryRequest::ViewAccessKey {
account_id: account_id.to_string(),
public_key: public_key.to_string(),
},
};

let response: Response<query::RpcQueryResponse, String> =
self.client.call("query", request)?;

match response.data {
Ok(r) => {
if let QueryResponseKind::ViewState(vs) = r.kind {
return Ok(vs);
}
return Err("Unexpected response returned.".to_string());
}
Err(e) => Err(format!("Error: {}, Code: {}", e.message, e.code,)),
}
}
Expand Down
7 changes: 6 additions & 1 deletion crates/sdk/libs/near/src/query.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::{
types::{BlockHash, BlockHeight, BlockId},
views::{AccountView, ContractCodeView, QueryRequest},
views::{
AccessKeyList, AccessKeyView, AccountView, ContractCodeView, QueryRequest, ViewStateResult,
},
};

#[derive(serde::Serialize, Debug)]
Expand All @@ -23,4 +25,7 @@ pub struct RpcQueryResponse {
pub enum QueryResponseKind {
ViewAccount(AccountView),
ViewCode(ContractCodeView),
ViewState(ViewStateResult),
AccessKey(AccessKeyView),
AccessKeyList(AccessKeyList),
}
14 changes: 14 additions & 0 deletions crates/sdk/libs/near/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
use serde_with::base64::Base64;
use serde_with::serde_as;

pub type BlockHeight = u64;
pub type BlockHash = String;
pub type AccountId = String;
pub type StorageUsage = u64;
pub type Nonce = u64;

#[derive(Debug, Clone, serde::Serialize)]
#[serde(untagged)]
pub enum BlockId {
Height(BlockHeight),
Hash(BlockHash),
}

#[serde_as]
#[derive(serde::Deserialize, Clone, Debug)]
#[serde(transparent)]
pub struct StoreValue(#[serde_as(as = "Base64")] pub Vec<u8>);

#[serde_as]
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
#[serde(transparent)]
pub struct StoreKey(#[serde_as(as = "Base64")] pub Vec<u8>);
75 changes: 71 additions & 4 deletions crates/sdk/libs/near/src/views.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,33 @@
use crate::types::{AccountId, BlockHeight, StorageUsage};
use std::sync::Arc;

use serde_with::base64::Base64;
use serde_with::serde_as;

use crate::types::{AccountId, BlockHeight, Nonce, StorageUsage, StoreKey, StoreValue};

#[derive(serde::Serialize, Debug)]
#[serde(tag = "request_type", rename_all = "snake_case")]
pub enum QueryRequest {
ViewAccount { account_id: AccountId },
ViewCode { account_id: AccountId },
ViewAccount {
account_id: AccountId,
},
ViewCode {
account_id: AccountId,
},
ViewState {
account_id: AccountId,
#[serde(rename = "prefix_base64")]
prefix: StoreKey,
#[serde(default)]
include_proof: bool,
},
ViewAccessKey {
account_id: AccountId,
public_key: String,
},
ViewAccessKeyList {
account_id: AccountId,
},
}

#[derive(serde::Deserialize, Debug, Clone)]
Expand All @@ -16,9 +39,53 @@ pub struct AccountView {
pub storage_paid_at: BlockHeight,
}

#[serde_as]
#[derive(serde::Deserialize, Debug, Clone)]
pub struct ContractCodeView {
#[serde(rename = "code_base64")]
pub code: String,
#[serde_as(as = "Base64")]
pub code: Vec<u8>,
pub hash: String,
}

#[derive(serde::Deserialize, Debug, Clone)]
pub struct StateItem {
pub key: StoreKey,
pub value: StoreValue,
}

#[serde_as]
#[derive(serde::Deserialize, Debug, Clone)]
pub struct ViewStateResult {
pub values: Vec<StateItem>,
#[serde_as(as = "Vec<Base64>")]
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub proof: Vec<Arc<[u8]>>,
}

#[derive(Debug, Clone, serde::Deserialize)]
pub struct AccessKeyView {
pub nonce: Nonce,
pub permission: AccessKeyPermissionView,
}

#[derive(Debug, Clone, serde::Deserialize)]
pub enum AccessKeyPermissionView {
FunctionCall {
allowance: Option<String>,
receiver_id: String,
method_names: Vec<String>,
},
FullAccess,
}

#[derive(serde::Deserialize, Debug, Clone)]
pub struct AccessKeyList {
pub keys: Vec<AccessKeyInfoView>,
}

#[derive(serde::Deserialize, Debug, Clone)]
pub struct AccessKeyInfoView {
pub public_key: String,
pub access_key: AccessKeyView,
}

0 comments on commit 4ed7b77

Please sign in to comment.