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(context-client): generalize implementation #903

Merged
merged 16 commits into from
Nov 2, 2024
1 change: 0 additions & 1 deletion Cargo.lock

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

1 change: 0 additions & 1 deletion crates/context/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ license.workspace = true

[dependencies]
camino = { workspace = true, features = ["serde1"] }
clap.workspace = true
ed25519-dalek.workspace = true
eyre.workspace = true
futures-util.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion crates/context/config/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ impl<'a, T: Transport> CallClient<'a, T> {
protocol: self.protocol,
network_id: Cow::Borrowed(&self.network_id),
contract_id: Cow::Borrowed(&self.contract_id),
operation: Operation::Read {
operation: Operation::Write {
method: Cow::Borrowed(M::METHOD),
},
};
Expand Down
161 changes: 114 additions & 47 deletions crates/context/config/src/client/env/config.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::ptr;

use query::appilcation_revision::{ApplicationRevision, Revision};
use mutate::context::Mutate;
use query::application::ApplicationRequest;
use query::application_revision::{ApplicationRevision, Revision};
use query::members::Members;
use query::members_revision::MembersRevision;
use query::privileges::IdentitiyPrivileges;

mod mutate;
mod query;

use crate::client::protocol::near::Near;
use crate::client::protocol::starknet::Starknet;
use crate::client::protocol::Method;
use crate::client::{CallClient, ConfigError, Environment, Protocol, Transport};
use crate::repr::Repr;
use crate::types::{Application, Capability, ContextIdentity, SignerId};
use crate::types::{Application, Capability, ContextId, ContextIdentity, SignerId};
use crate::{ContextRequest, ContextRequestKind, RequestKind};
pub enum ContextConfig {}

pub struct ContextConfigQuery<'a, T> {
Expand Down Expand Up @@ -118,76 +122,139 @@ impl<'a, T: Transport> ContextConfigQuery<'a, T> {
}
}

#[derive(Debug)]
pub struct ContextConfigMutateRequest<'a, T> {
client: CallClient<'a, T>,
kind: RequestKind<'a>,
}

impl<'a, T: Transport> ContextConfigMutate<'a, T> {
pub fn add_context(self, context_id: String) -> ContextConfigMutateRequest<'a, T> {
pub fn add_context(
self,
context_id: ContextId,
author_id: ContextIdentity,
application: Application<'a>,
) -> ContextConfigMutateRequest<'a, T> {
ContextConfigMutateRequest {
client: self.client,
kind: RequestKind::AddContext { context_id },
kind: RequestKind::Context(ContextRequest {
context_id: Repr::new(context_id),
kind: ContextRequestKind::Add {
author_id: Repr::new(author_id),
application,
},
}),
}
}
}

enum RequestKind {
AddContext { context_id: String },
}

pub struct ContextConfigMutateRequest<'a, T> {
client: CallClient<'a, T>,
kind: RequestKind,
}

struct Mutate {
signer_id: String,
nonce: u64,
kind: RequestKind,
}

impl Method<Mutate> for Near {
const METHOD: &'static str = "mutate";
pub fn update_application(
self,
context_id: ContextId,
application: Application<'a>,
) -> ContextConfigMutateRequest<'a, T> {
ContextConfigMutateRequest {
client: self.client,
kind: RequestKind::Context(ContextRequest {
context_id: Repr::new(context_id),
kind: ContextRequestKind::UpdateApplication { application },
}),
}
}

type Returns = ();
pub fn add_members(
self,
context_id: ContextId,
members: &[ContextIdentity],
) -> ContextConfigMutateRequest<'a, T> {
let members = unsafe {
&*(ptr::from_ref::<[ContextIdentity]>(members) as *const [Repr<ContextIdentity>])
};

fn encode(params: &Mutate) -> eyre::Result<Vec<u8>> {
// sign the params, encode it and return
todo!()
ContextConfigMutateRequest {
client: self.client,
kind: RequestKind::Context(ContextRequest {
context_id: Repr::new(context_id),
kind: ContextRequestKind::AddMembers {
members: Cow::Borrowed(members),
},
}),
}
}

fn decode(response: &[u8]) -> eyre::Result<Self::Returns> {
todo!()
}
}
pub fn remove_members(
self,
context_id: ContextId,
members: &[ContextIdentity],
) -> ContextConfigMutateRequest<'a, T> {
let members = unsafe {
&*(ptr::from_ref::<[ContextIdentity]>(members) as *const [Repr<ContextIdentity>])
};

impl Method<Mutate> for Starknet {
type Returns = ();
ContextConfigMutateRequest {
client: self.client,
kind: RequestKind::Context(ContextRequest {
context_id: Repr::new(context_id),
kind: ContextRequestKind::RemoveMembers {
members: Cow::Borrowed(members),
},
}),
}
}

const METHOD: &'static str = "mutate";
pub fn grant(
self,
context_id: ContextId,
capabilities: &[(ContextIdentity, Capability)],
) -> ContextConfigMutateRequest<'a, T> {
let capabilities = unsafe {
&*(ptr::from_ref::<[(ContextIdentity, Capability)]>(capabilities)
as *const [(Repr<ContextIdentity>, Capability)])
};

fn encode(params: &Mutate) -> eyre::Result<Vec<u8>> {
// sign the params, encode it and return
// since you will have a `Vec<Felt>` here, you can
// `Vec::with_capacity(32 * calldata.len())` and then
// extend the `Vec` with each `Felt::to_bytes_le()`
// when this `Vec<u8>` makes it to `StarknetTransport`,
// reconstruct the `Vec<Felt>` from it
todo!()
ContextConfigMutateRequest {
client: self.client,
kind: RequestKind::Context(ContextRequest {
context_id: Repr::new(context_id),
kind: ContextRequestKind::Grant {
capabilities: Cow::Borrowed(capabilities),
},
}),
}
}

fn decode(response: &[u8]) -> eyre::Result<Self::Returns> {
todo!()
pub fn revoke(
self,
context_id: ContextId,
capabilities: &[(ContextIdentity, Capability)],
) -> ContextConfigMutateRequest<'a, T> {
let capabilities = unsafe {
&*(ptr::from_ref::<[(ContextIdentity, Capability)]>(capabilities)
as *const [(Repr<ContextIdentity>, Capability)])
};

ContextConfigMutateRequest {
client: self.client,
kind: RequestKind::Context(ContextRequest {
context_id: Repr::new(context_id),
kind: ContextRequestKind::Revoke {
capabilities: Cow::Borrowed(capabilities),
},
}),
}
}
}

impl<'a, T: Transport> ContextConfigMutateRequest<'a, T> {
pub async fn send(self, signing_key: [u8; 32]) -> Result<(), ConfigError<T>> {
let request = Mutate {
signer_id: todo!(),
signer_id: signing_key,
nonce: 0,
kind: self.kind,
};

match self.client.protocol {
Protocol::Near => self.client.mutate::<Near, _>(request).await?,
Protocol::Starknet => self.client.mutate::<Starknet, _>(request).await?,
Protocol::Near => self.client.mutate::<Near, Mutate<'_>>(request).await?,
Protocol::Starknet => self.client.mutate::<Starknet, Mutate<'_>>(request).await?,
}

Ok(())
Expand Down
55 changes: 55 additions & 0 deletions crates/context/config/src/client/env/config/mutate/context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use ed25519_dalek::ed25519::signature::SignerMut;
use ed25519_dalek::SigningKey;

use crate::client::protocol::near::Near;
use crate::client::protocol::starknet::Starknet;
use crate::client::protocol::Method;
use crate::types::Signed;
use crate::{Request, RequestKind};

#[derive(Debug)]
pub struct Mutate<'a> {
pub(crate) signer_id: [u8; 32],
pub(crate) nonce: u64,
pub(crate) kind: RequestKind<'a>,
}

impl<'a> Method<Mutate<'a>> for Near {
const METHOD: &'static str = "mutate";

type Returns = ();

fn encode(params: &Mutate) -> eyre::Result<Vec<u8>> {
let signed = Signed::new(&Request::new(todo!(), params.kind), |b| {
miraclx marked this conversation as resolved.
Show resolved Hide resolved
SigningKey::from_bytes(&params.signer_id).sign(b)
})?;

let encoded = serde_json::to_vec(&signed)?;

Ok(encoded)
}

fn decode(response: &[u8]) -> eyre::Result<Self::Returns> {
Ok(())
}
}

impl<'a> Method<Mutate<'a>> for Starknet {
type Returns = ();

const METHOD: &'static str = "mutate";

fn encode(params: &Mutate) -> eyre::Result<Vec<u8>> {
// sign the params, encode it and return
// since you will have a `Vec<Felt>` here, you can
// `Vec::with_capacity(32 * calldata.len())` and then
// extend the `Vec` with each `Felt::to_bytes_le()`
// when this `Vec<u8>` makes it to `StarknetTransport`,
// reconstruct the `Vec<Felt>` from it
todo!()
}

fn decode(response: &[u8]) -> eyre::Result<Self::Returns> {
todo!()
}
}
1 change: 1 addition & 0 deletions crates/context/config/src/client/env/config/mutate/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod context;
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::client::protocol::near::Near;
use crate::client::protocol::starknet::Starknet;
use crate::client::protocol::Method;
use crate::repr::Repr;
use crate::types::ContextIdentity;
use crate::types::{ContextId, ContextIdentity};

#[derive(Serialize, Deserialize, Debug)]
pub struct Members {
Expand Down
2 changes: 1 addition & 1 deletion crates/context/config/src/client/env/config/query/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub mod appilcation_revision;
pub mod application;
pub mod application_revision;
pub mod members;
pub mod members_revision;
pub mod privileges;
4 changes: 2 additions & 2 deletions crates/context/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ impl ContextManager {
ApplicationMetadataConfig(Repr::new(application.metadata.into())),
),
)
.send(SigningKey::from_bytes(&context_secret).sign(b))
.send(context.id.rt().expect("infallible conversion"))
.await?;

Ok((context.id, identity_secret.public_key()))
Expand Down Expand Up @@ -413,7 +413,7 @@ impl ContextManager {
context_id.rt().expect("infallible conversion"),
&[invitee_id.rt().expect("infallible conversion")],
)
.send(|b| SigningKey::from_bytes(&requester_secret).sign(b))
.send(requester_secret)
.await?;

let invitation_payload = ContextInvitationPayload::new(
Expand Down
Loading