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 30 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
41 changes: 24 additions & 17 deletions Cargo.lock

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

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ members = [
"./crates/primitives",
"./crates/runtime",
"./crates/sdk",
"./crates/sdk/libs/near",
"./crates/sdk/macros",
"./crates/server",
"./crates/server-primitives",
Expand Down Expand Up @@ -46,11 +47,13 @@ futures-util = "0.3.30"
hex = "0.4.3"
libp2p = "0.53.2"
libp2p-stream = "0.1.0-alpha.1"
libp2p-identity = "0.2.9"
multiaddr = "0.18.1"
# multibase = "0.9.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 All @@ -67,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 apps/only-peers/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ crate-type = ["cdylib"]

[dependencies]
calimero-sdk = { path = "../../crates/sdk" }
calimero-sdk-near = { path = "../../crates/sdk/libs/near" }
its-saeed marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 1 addition & 1 deletion crates/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ license.workspace = true
[dependencies]
bs58.workspace = true
ed25519-dalek.workspace = true
libp2p = { workspace = true, features = ["serde"] }
libp2p-identity = { workspace = true, features = ["peerid", "serde"] }
semver = { workspace = true, features = ["serde"] }
serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true
Expand Down
20 changes: 20 additions & 0 deletions crates/primitives/src/common.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
use serde::{Deserialize, Serialize};

pub const fn bool_true() -> bool {
true
}

#[derive(Serialize, Deserialize)]
#[serde(remote = "Result")]
pub enum ResultAlt<T, E> {
#[serde(rename = "result")]
Ok(T),
#[serde(rename = "error")]
Err(E),
}

impl<T, E> From<ResultAlt<T, E>> for Result<T, E> {
fn from(result: ResultAlt<T, E>) -> Self {
match result {
ResultAlt::Ok(value) => Ok(value),
ResultAlt::Err(err) => Err(err),
}
}
}
2 changes: 1 addition & 1 deletion crates/primitives/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub struct ExecutedTransactionPayload {
#[derive(Clone, Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct PeerJoinedPayload {
pub peer_id: libp2p::PeerId,
pub peer_id: libp2p_identity::PeerId,
}

#[derive(Clone, Serialize, Deserialize, Debug)]
Expand Down
2 changes: 1 addition & 1 deletion crates/primitives/src/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ pub mod serde_signing_key {
pub mod serde_identity {
use std::fmt;

use libp2p::identity::Keypair;
use libp2p_identity::Keypair;
use serde::de::{self, MapAccess};
use serde::ser::{self, SerializeMap};
use serde::{Deserializer, Serializer};
Expand Down
4 changes: 3 additions & 1 deletion crates/runtime/src/logic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,9 @@ impl<'a> VMHostFunctions<'a> {
let url = self.get_string(url_ptr, url_len)?;
let method = self.get_string(method_ptr, method_len)?;
let headers = self.read_guest_memory(headers_ptr, headers_len)?;
let headers: Vec<(String, String)> = borsh::from_slice(&headers).unwrap(); // safety: headers are coming from an inner source. Safe to deserialize.

// safety: It's not possible to call `fetch` directly by apps. So headers is generated by our code. Safe to deserialize.
its-saeed marked this conversation as resolved.
Show resolved Hide resolved
its-saeed marked this conversation as resolved.
Show resolved Hide resolved
let headers: Vec<(String, String)> = borsh::from_slice(&headers).unwrap();
let body = self.read_guest_memory(body_ptr, body_len)?;
let mut request = ureq::request(&method, &url);

Expand Down
17 changes: 17 additions & 0 deletions crates/sdk/libs/near/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "calimero-sdk-near"
version = "0.1.0"
authors.workspace = true
edition.workspace = true
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),
}
64 changes: 64 additions & 0 deletions crates/sdk/libs/near/src/jsonrpc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
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
}

impl Client {
pub fn new(url: String) -> Self {
fbozic marked this conversation as resolved.
Show resolved Hide resolved
Self {
url,
id: std::cell::RefCell::new(0),
}
}

pub fn call<T: DeserializeOwned, E: DeserializeOwned, P: Serialize>(
&self,
method: &str,
params: P,
) -> 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(),
its-saeed marked this conversation as resolved.
Show resolved Hide resolved
method,
params,
})?;

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)]
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,
}

#[derive(Debug, Clone, Deserialize)]
pub struct Response<T: DeserializeOwned, E: DeserializeOwned> {
pub jsonrpc: Option<String>,
pub id: String,

#[serde(with = "calimero_primitives::common::ResultAlt", flatten)]
pub data: Result<T, RpcError<E>>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct RpcError<E> {
pub code: i32,
pub message: String,
pub data: Option<E>,
}
40 changes: 40 additions & 0 deletions crates/sdk/libs/near/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use error::NearLibError;
use jsonrpc::Response;

pub mod error;
its-saeed marked this conversation as resolved.
Show resolved Hide resolved
mod jsonrpc;
pub mod query;
pub mod types;
pub mod views;

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 {
client: jsonrpc::Client::new("https://rpc.testnet.near.org/".to_string()),
}
}

pub fn mainnet() -> Self {
Self {
client: jsonrpc::Client::new("https://rpc.mainnet.near.org/".to_string()),
}
}

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
}
}
Loading