-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into feat--add-near-calls-nonce
- Loading branch information
Showing
11 changed files
with
602 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
crates/context/config/src/client/env/proxy/query/context_storage_entries.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
use candid::{Decode, Encode}; | ||
use serde::Serialize; | ||
use starknet::core::codec::{Decode as StarknetDecode, Encode as StarknetEncode}; | ||
use starknet_crypto::Felt; | ||
|
||
use crate::client::env::proxy::starknet::{ | ||
CallData, ContextStorageEntriesResponse, StarknetContextStorageEntriesRequest, | ||
}; | ||
use crate::client::env::Method; | ||
use crate::client::protocol::icp::Icp; | ||
use crate::client::protocol::near::Near; | ||
use crate::client::protocol::starknet::Starknet; | ||
use crate::types::ContextStorageEntry; | ||
|
||
#[derive(Clone, Debug, Serialize)] | ||
pub(super) struct ContextStorageEntriesRequest { | ||
pub(super) offset: usize, | ||
pub(super) limit: usize, | ||
} | ||
|
||
impl Method<Near> for ContextStorageEntriesRequest { | ||
const METHOD: &'static str = "context_storage_entries"; | ||
|
||
type Returns = Vec<ContextStorageEntry>; | ||
|
||
fn encode(self) -> eyre::Result<Vec<u8>> { | ||
serde_json::to_vec(&self).map_err(Into::into) | ||
} | ||
|
||
fn decode(response: Vec<u8>) -> eyre::Result<Self::Returns> { | ||
// Decode the response as Vec of tuples with boxed slices | ||
let entries: Vec<(Box<[u8]>, Box<[u8]>)> = serde_json::from_slice(&response) | ||
.map_err(|e| eyre::eyre!("Failed to decode response: {}", e))?; | ||
|
||
// Convert to ContextStorageEntry | ||
Ok(entries | ||
.into_iter() | ||
.map(|(key, value)| ContextStorageEntry { | ||
key: key.into(), | ||
value: value.into(), | ||
}) | ||
.collect()) | ||
} | ||
} | ||
|
||
impl Method<Starknet> for ContextStorageEntriesRequest { | ||
const METHOD: &'static str = "context_storage_entries"; | ||
|
||
type Returns = Vec<ContextStorageEntry>; | ||
|
||
fn encode(self) -> eyre::Result<Vec<u8>> { | ||
let req = StarknetContextStorageEntriesRequest { | ||
offset: Felt::from(self.offset as u64), | ||
length: Felt::from(self.limit as u64), | ||
}; | ||
let mut call_data = CallData::default(); | ||
req.encode(&mut call_data)?; | ||
Ok(call_data.0) | ||
} | ||
|
||
fn decode(response: Vec<u8>) -> eyre::Result<Self::Returns> { | ||
if response.is_empty() { | ||
return Ok(vec![]); | ||
} | ||
|
||
// Convert bytes to Felts | ||
let chunks = response.chunks_exact(32); | ||
let felts: Vec<Felt> = chunks | ||
.map(|chunk| { | ||
let chunk_array: [u8; 32] = chunk | ||
.try_into() | ||
.map_err(|e| eyre::eyre!("Failed to convert chunk to array: {}", e))?; | ||
Ok(Felt::from_bytes_be(&chunk_array)) | ||
}) | ||
.collect::<eyre::Result<Vec<Felt>>>()?; | ||
|
||
let response = ContextStorageEntriesResponse::decode_iter(&mut felts.iter())?; | ||
|
||
Ok(response.entries.into_iter().map(Into::into).collect()) | ||
} | ||
} | ||
|
||
impl Method<Icp> for ContextStorageEntriesRequest { | ||
const METHOD: &'static str = "context_storage_entries"; | ||
|
||
type Returns = Vec<ContextStorageEntry>; | ||
|
||
fn encode(self) -> eyre::Result<Vec<u8>> { | ||
// Encode offset and limit using Candid | ||
Encode!(&self.offset, &self.limit) | ||
.map_err(|e| eyre::eyre!("Failed to encode request: {}", e)) | ||
} | ||
|
||
fn decode(response: Vec<u8>) -> eyre::Result<Self::Returns> { | ||
// Decode the response as Vec of tuples | ||
let entries: Vec<(Vec<u8>, Vec<u8>)> = Decode!(&response, Vec<(Vec<u8>, Vec<u8>)>) | ||
.map_err(|e| eyre::eyre!("Failed to decode response: {}", e))?; | ||
|
||
// Convert to ContextStorageEntry | ||
Ok(entries | ||
.into_iter() | ||
.map(|(key, value)| ContextStorageEntry { key, value }) | ||
.collect()) | ||
} | ||
} |
102 changes: 102 additions & 0 deletions
102
crates/context/config/src/client/env/proxy/query/context_variable.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
use candid::{Decode, Encode}; | ||
use serde::Serialize; | ||
use starknet::core::codec::Encode as StarknetEncode; | ||
use starknet_crypto::Felt; | ||
|
||
use crate::client::env::proxy::starknet::{CallData, ContextVariableKey}; | ||
use crate::client::env::Method; | ||
use crate::client::protocol::icp::Icp; | ||
use crate::client::protocol::near::Near; | ||
use crate::client::protocol::starknet::Starknet; | ||
use crate::icp::repr::ICRepr; | ||
|
||
#[derive(Clone, Debug, Serialize)] | ||
pub(super) struct ContextVariableRequest { | ||
pub(super) key: Vec<u8>, | ||
} | ||
|
||
impl Method<Near> for ContextVariableRequest { | ||
const METHOD: &'static str = "get_context_value"; | ||
|
||
type Returns = Vec<u8>; | ||
|
||
fn encode(self) -> eyre::Result<Vec<u8>> { | ||
serde_json::to_vec(&self).map_err(Into::into) | ||
} | ||
|
||
fn decode(response: Vec<u8>) -> eyre::Result<Self::Returns> { | ||
serde_json::from_slice(&response).map_err(Into::into) | ||
} | ||
} | ||
|
||
impl Method<Starknet> for ContextVariableRequest { | ||
const METHOD: &'static str = "get_context_value"; | ||
|
||
type Returns = Vec<u8>; | ||
|
||
fn encode(self) -> eyre::Result<Vec<u8>> { | ||
let mut call_data = CallData::default(); | ||
let key: ContextVariableKey = self.key.into(); | ||
key.encode(&mut call_data)?; | ||
|
||
Ok(call_data.0) | ||
} | ||
|
||
fn decode(response: Vec<u8>) -> eyre::Result<Self::Returns> { | ||
if response.is_empty() { | ||
return Ok(vec![]); | ||
} | ||
|
||
let chunks = response.chunks_exact(32); | ||
let felts: Vec<Felt> = chunks | ||
.map(|chunk| { | ||
let chunk_array: [u8; 32] = chunk | ||
.try_into() | ||
.map_err(|e| eyre::eyre!("Failed to convert chunk to array: {}", e))?; | ||
Ok(Felt::from_bytes_be(&chunk_array)) | ||
}) | ||
.collect::<eyre::Result<Vec<Felt>>>()?; | ||
|
||
if felts.is_empty() { | ||
return Ok(vec![]); | ||
} | ||
|
||
// First felt is the discriminant (0 for None, 1 for Some) | ||
match felts[0] { | ||
f if f == Felt::ZERO => { | ||
println!( | ||
"First few bytes after discriminant: {:?}", | ||
&response[32..40] | ||
); | ||
|
||
// Skip first 64 bytes (discriminant + length) and filter nulls | ||
Ok(response[64..] | ||
.iter() | ||
.filter(|&&b| b != 0) | ||
.copied() | ||
.collect()) | ||
} | ||
v => Err(eyre::eyre!("Invalid option discriminant: {}", v)), | ||
} | ||
} | ||
} | ||
|
||
impl Method<Icp> for ContextVariableRequest { | ||
const METHOD: &'static str = "get_context_value"; | ||
|
||
type Returns = Vec<u8>; | ||
|
||
fn encode(self) -> eyre::Result<Vec<u8>> { | ||
// Convert the key to ICRepr | ||
let payload = ICRepr::new(self.key); | ||
// Use candid's Encode macro to serialize the data | ||
Encode!(&payload).map_err(Into::into) | ||
} | ||
|
||
fn decode(response: Vec<u8>) -> eyre::Result<Self::Returns> { | ||
// Use candid's Decode macro to deserialize the response | ||
// The response will be an Option<Vec<u8>> | ||
let decoded = Decode!(&response, Vec<u8>)?; | ||
Ok(decoded) | ||
} | ||
} |
Oops, something went wrong.