Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ext): add app-side library for NEAR #374

Merged
merged 43 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
a851290
feat: add a fetch function inside the runtime host environment
saeed-zil Jun 12, 2024
052f4ed
Add headers
saeed-zil Jun 12, 2024
ad06f97
Add method
saeed-zil Jun 12, 2024
5279d24
Add body
saeed-zil Jun 12, 2024
16b37ae
feat: Add app-side library for NEAR
saeed-zil Jun 13, 2024
a6fbc46
Merge branch 'master' of github.com:calimero-network/core into 370-ad…
saeed-zil Jun 18, 2024
7bef965
code review fixes
saeed-zil Jun 18, 2024
a63bc2b
Fix serde deserializer
saeed-zil Jun 18, 2024
854b6fe
Remove unwrap
saeed-zil Jun 18, 2024
22741e2
Merge branch 'master' of github.com:calimero-network/core into 370-ad…
saeed-zil Jun 18, 2024
893c6c6
Merge branch 'master' of github.com:calimero-network/core into 370-ad…
saeed-zil Jun 18, 2024
3d38742
Add methods
saeed-zil Jun 18, 2024
66d3042
Merge branch 'master' of github.com:calimero-network/core into 370-ad…
saeed-zil Jun 19, 2024
96e6c6a
Move AltResult to primitives.
saeed-zil Jun 19, 2024
6bd911d
Make id incremental
saeed-zil Jun 19, 2024
222ae8d
Make view account more restricted.
saeed-zil Jun 19, 2024
792de59
Fix code style
saeed-zil Jun 19, 2024
4ed7b77
Add more query functions
saeed-zil Jun 20, 2024
b13f56f
add function call.
saeed-zil Jun 21, 2024
93d3144
change comment
saeed-zil Jun 21, 2024
9f9cf2d
Update style
saeed-zil Jun 21, 2024
a587f32
fix code style
saeed-zil Jun 21, 2024
c1c0f72
Merge branch 'master' of github.com:calimero-network/core into 370-ad…
saeed-zil Jun 24, 2024
034a9eb
update cargo.lock
saeed-zil Jun 24, 2024
cd4b7d2
Code review fixes
saeed-zil Jun 24, 2024
c16ac26
Add error type for rpc calls.
saeed-zil Jun 24, 2024
3901d33
Change the design
saeed-zil Jun 24, 2024
17c0563
minor changes
saeed-zil Jun 24, 2024
4455f4b
unwanted change
saeed-zil Jun 24, 2024
364fc0d
remove useless code
saeed-zil Jun 24, 2024
6202fe1
Merge branch 'master' of github.com:calimero-network/core into 370-ad…
saeed-zil Jun 24, 2024
38d146f
tiny fixes
saeed-zil Jun 24, 2024
93070fd
rename error.
saeed-zil Jun 24, 2024
961cf9f
Merge client and jsonrpcclient
saeed-zil Jun 24, 2024
8ffddab
make id a number.
saeed-zil Jun 24, 2024
aa2cfa2
fix error
saeed-zil Jun 24, 2024
424555e
Merge branch 'master' of github.com:calimero-network/core into 370-ad…
saeed-zil Jun 26, 2024
1b4474e
Add more error types.
saeed-zil Jun 26, 2024
104cb64
Merge branch 'master' into 370-add-near-app-side-library
its-saeed Jun 26, 2024
fd718f7
move code to better mods
saeed-zil Jun 26, 2024
5559c99
Update crates/runtime/src/logic.rs
its-saeed Jun 26, 2024
885a36f
Add an example for near library
saeed-zil Jun 26, 2024
3722fd6
Merge branch '370-add-near-app-side-library' of github.com:calimero-n…
saeed-zil Jun 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ multiaddr = "0.18.1"
near-jsonrpc-client = "0.8.0"
near-jsonrpc-primitives = "0.20.0"
near-primitives = "0.20.0"
near-account-id = "1.0.0"
its-saeed marked this conversation as resolved.
Show resolved Hide resolved
near-sdk = "5.0.0"
near-workspaces = "0.10.0"
ouroboros = "0.18.3"
Expand Down
11 changes: 0 additions & 11 deletions apps/only-peers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,6 @@ pub enum Event<'a> {

#[app::logic]
impl OnlyPeers {
pub fn foo(&mut self) -> String {
let client = calimero_sdk_near::Client::testnet();
match client.view_account(
"nearkat.testnet",
calimero_sdk_near::types::BlockId::Height(166710735),
) {
Ok(r) => format!("{}", r.amount),
Err(e) => e,
}
}

pub fn post(&self, id: usize) -> Option<&Post> {
env::log(&format!("Getting post with id: {:?}", id));

Expand Down
2 changes: 1 addition & 1 deletion crates/runtime/examples/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fn main() -> eyre::Result<()> {
let cx = logic::VMContext {
input: serde_json::to_vec(&json!({}))?,
};
let get_outcome = run(file, "foo", cx, &mut storage, &limits)?;
let get_outcome = run(file, "fetch", cx, &mut storage, &limits)?;
let returns = String::from_utf8(get_outcome.returns.unwrap().unwrap()).unwrap();
println!("{returns}");

Expand Down
2 changes: 0 additions & 2 deletions crates/runtime/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,6 @@ pub enum HostError {
EventKindSizeOverflow,
#[error("event data size overflow")]
EventDataSizeOverflow,
#[error("failed to fetch data from {url} with error: {error}")]
FetchError { url: String, error: String },
}

#[derive(Debug, Serialize)]
Expand Down
2 changes: 2 additions & 0 deletions crates/sdk/libs/near/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ repository.workspace = true
license.workspace = true

[dependencies]
near-account-id = { workspace = true, features = ["serde"]}
serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true
serde_with = {workspace = true, features = ["base64"]}
thiserror.workspace = true

calimero-sdk = { path = "../../" }
calimero-primitives = { path = "../../../primitives" }
13 changes: 13 additions & 0 deletions crates/sdk/libs/near/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use thiserror::Error;

#[derive(Debug, Error)]
pub enum NearLibError {
its-saeed marked this conversation as resolved.
Show resolved Hide resolved
#[error(transparent)]
JsonError(#[from] serde_json::Error),

#[error(transparent)]
IoError(#[from] std::io::Error),
its-saeed marked this conversation as resolved.
Show resolved Hide resolved

#[error("Failed to fetch: {0}")]
FetchError(String),
}
25 changes: 13 additions & 12 deletions crates/sdk/libs/near/src/jsonrpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use calimero_sdk::env;
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};

use crate::error::NearLibError;

pub(crate) struct Client {
its-saeed marked this conversation as resolved.
Show resolved Hide resolved
url: String,
id: std::cell::RefCell<u64>,
fbozic marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -19,29 +21,28 @@ impl Client {
&self,
method: &str,
params: P,
) -> Result<Response<T, E>, String> {
) -> Result<Response<T, E>, NearLibError> {
let headers = [("Content-Type", "application/json")];

*self.id.borrow_mut() += 1;
let body = serde_json::to_vec(&Request {
jsonrpc: "2.0",
id: self.id.borrow().to_string(),
method: method.to_string(),
id: &*self.id.borrow().to_string(),
its-saeed marked this conversation as resolved.
Show resolved Hide resolved
method,
params,
})
.map_err(|err| format!("Cannot serialize request: {:?}", err))?;
})?;

let response = unsafe { env::ext::fetch(&self.url, "POST", &headers, &body) }?;
serde_json::from_slice::<Response<T, E>>(&response)
.map_err(|e| format!("Failed to parse response: {}", e.to_string(),))
let response = unsafe { env::ext::fetch(&self.url, "POST", &headers, &body) }
.map_err(NearLibError::FetchError)?;
Ok(serde_json::from_slice::<Response<T, E>>(&response)?)
}
}

#[derive(Debug, Clone, Serialize)]
pub struct Request<P: Serialize> {
pub jsonrpc: &'static str,
pub id: String,
pub method: String,
struct Request<'a, P: Serialize> {
pub jsonrpc: &'a str,
its-saeed marked this conversation as resolved.
Show resolved Hide resolved
pub id: &'a str,
its-saeed marked this conversation as resolved.
Show resolved Hide resolved
pub method: &'a str,

pub params: P,
}
Expand Down
154 changes: 14 additions & 140 deletions crates/sdk/libs/near/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use error::NearLibError;
use jsonrpc::Response;
use query::{QueryResponseKind, RpcQueryRequest};
use types::{BlockId, FunctionArgs, StoreKey};
use views::QueryRequest;

pub mod error;
its-saeed marked this conversation as resolved.
Show resolved Hide resolved
mod jsonrpc;
pub mod query;
pub mod types;
Expand All @@ -12,6 +11,13 @@ pub struct Client {
client: jsonrpc::Client,
}

pub trait RpcMethod {
type Response: serde::de::DeserializeOwned;

fn method_name(&self) -> &str;
fn params(&self) -> Result<serde_json::Value, std::io::Error>;
}

impl Client {
pub fn testnet() -> Self {
Self {
Expand All @@ -25,142 +31,10 @@ impl Client {
}
}

pub fn view_account(
&self,
account_id: &str,
block_id: BlockId,
) -> Result<views::AccountView, String> {
let request = RpcQueryRequest {
block_id,
request: QueryRequest::ViewAccount {
account_id: account_id.to_string(),
},
};
let response: Response<query::RpcQueryResponse, String> =
self.client.call("query", request)?;

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

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) => {
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,)),
}
}

pub fn call_function(
&self,
account_id: &str,
method_name: &str,
args: FunctionArgs,
block_id: BlockId,
) -> Result<views::CallResult, String> {
let request = RpcQueryRequest {
block_id,
request: QueryRequest::CallFunction {
account_id: account_id.to_string(),
method_name: method_name.to_string(),
args,
},
};

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

match response.data {
Ok(r) => {
if let QueryResponseKind::CallResult(cr) = r.kind {
return Ok(cr);
}
return Err("Unexpected response returned.".to_string());
}
Err(e) => Err(format!("Error: {}, Code: {}", e.message, e.code,)),
}
pub fn call<M>(&self, method: M) -> Result<Response<M::Response, String>, NearLibError>
its-saeed marked this conversation as resolved.
Show resolved Hide resolved
where
M: RpcMethod,
{
self.client.call(method.method_name(), &method.params()?)
its-saeed marked this conversation as resolved.
Show resolved Hide resolved
}
}
15 changes: 15 additions & 0 deletions crates/sdk/libs/near/src/query.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use serde_json::json;

use crate::types::{BlockHash, BlockHeight, BlockId};
use crate::views::{
AccessKeyList, AccessKeyView, AccountView, CallResult, ContractCodeView, QueryRequest,
ViewStateResult,
};
use crate::RpcMethod;

#[derive(serde::Serialize, Debug)]
pub struct RpcQueryRequest {
Expand All @@ -29,3 +32,15 @@ pub enum QueryResponseKind {
AccessKeyList(AccessKeyList),
CallResult(CallResult),
}

impl RpcMethod for RpcQueryRequest {
type Response = RpcQueryResponse;

fn method_name(&self) -> &str {
"query"
}

fn params(&self) -> Result<serde_json::Value, std::io::Error> {
Ok(json!(self))
its-saeed marked this conversation as resolved.
Show resolved Hide resolved
}
}
5 changes: 3 additions & 2 deletions crates/sdk/libs/near/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ use serde_with::base64::Base64;
use serde_with::serde_as;

pub type BlockHeight = u64;
pub type BlockHash = String;
pub type AccountId = String;
pub type BlockHash = calimero_primitives::hash::Hash;
pub type AccountId = near_account_id::AccountId;
pub type StorageUsage = u64;
pub type Nonce = u64;
pub type Balance = u128;

#[derive(Debug, Clone, serde::Serialize)]
#[serde(untagged)]
Expand Down
Loading