diff --git a/Cargo.lock b/Cargo.lock index 800be22..de4c904 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,7 +5,7 @@ version = 3 [[package]] name = "account_sdk" version = "0.1.0" -source = "git+https://github.com/cartridge-gg/controller?rev=fea57f1#fea57f16ba2c52e89311787aaaea8875b35e38f4" +source = "git+https://github.com/cartridge-gg/controller#61d2fd0cd856daa01b2da52b762368542c03da6f" dependencies = [ "anyhow", "async-trait", @@ -27,6 +27,7 @@ dependencies = [ "primitive-types", "reqwest 0.11.27", "serde", + "serde-wasm-bindgen", "serde_cbor_2", "serde_json", "serde_with 3.9.0", @@ -37,6 +38,7 @@ dependencies = [ "thiserror", "tokio", "toml", + "tsify-next", "u256-literal", "url", "urlencoding", @@ -515,7 +517,7 @@ dependencies = [ [[package]] name = "cainome" version = "0.2.3" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.1#db76fb849d1b7f3e9a2e943868bcd8616cf72e90" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.2#4e3924fb82b7299d56d3619aa5d7b9863f581e0a" dependencies = [ "anyhow", "async-trait", @@ -540,7 +542,7 @@ dependencies = [ [[package]] name = "cainome-cairo-serde" version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.1#db76fb849d1b7f3e9a2e943868bcd8616cf72e90" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.2#4e3924fb82b7299d56d3619aa5d7b9863f581e0a" dependencies = [ "serde", "starknet 0.12.0", @@ -550,7 +552,7 @@ dependencies = [ [[package]] name = "cainome-parser" version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.1#db76fb849d1b7f3e9a2e943868bcd8616cf72e90" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.2#4e3924fb82b7299d56d3619aa5d7b9863f581e0a" dependencies = [ "convert_case 0.6.0", "quote", @@ -563,7 +565,7 @@ dependencies = [ [[package]] name = "cainome-rs" version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.1#db76fb849d1b7f3e9a2e943868bcd8616cf72e90" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.2#4e3924fb82b7299d56d3619aa5d7b9863f581e0a" dependencies = [ "anyhow", "cainome-cairo-serde", @@ -581,7 +583,7 @@ dependencies = [ [[package]] name = "cainome-rs-macro" version = "0.1.0" -source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.1#db76fb849d1b7f3e9a2e943868bcd8616cf72e90" +source = "git+https://github.com/cartridge-gg/cainome?tag=v0.4.2#4e3924fb82b7299d56d3619aa5d7b9863f581e0a" dependencies = [ "anyhow", "cainome-cairo-serde", @@ -4042,6 +4044,17 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-wasm-bindgen" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + [[package]] name = "serde_cbor_2" version = "0.12.0-dev" @@ -4713,9 +4726,9 @@ dependencies = [ [[package]] name = "starknet-types-core" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6bacf0ba19bc721e518bc4bf389ff13daa8a7c5db5fd320600473b8aa9fcbd" +checksum = "9b889ee5734db8b3c8a6551135c16764bf4ce1ab4955fffbb2ac5b6706542b64" dependencies = [ "lambdaworks-crypto", "lambdaworks-math", @@ -5271,6 +5284,31 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "tsify-next" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f4a645dca4ee0800f5ab60ce166deba2db6a0315de795a2691e138a3d55d756" +dependencies = [ + "gloo-utils", + "serde", + "serde_json", + "tsify-next-macros", + "wasm-bindgen", +] + +[[package]] +name = "tsify-next-macros" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d5c06f8a51d759bb58129e30b2631739e7e1e4579fad1f30ac09a6c88e488a6" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.66", +] + [[package]] name = "typenum" version = "1.17.0" diff --git a/slot/Cargo.toml b/slot/Cargo.toml index b5895f8..2da8ff7 100644 --- a/slot/Cargo.toml +++ b/slot/Cargo.toml @@ -28,6 +28,5 @@ tempfile = "3.10.1" hyper.workspace = true serde_with = "3.9.0" -# Must be synced across Dojo -account_sdk = { git = "https://github.com/cartridge-gg/controller", rev = "fea57f1" } +account_sdk = { git = "https://github.com/cartridge-gg/controller" } base64 = "0.22.1" diff --git a/slot/src/session.rs b/slot/src/session.rs index 88337ee..80a1f90 100644 --- a/slot/src/session.rs +++ b/slot/src/session.rs @@ -1,10 +1,10 @@ use std::path::Path; use std::{fs, path::PathBuf}; -use account_sdk::account::session::hash::{AllowedMethod, Session}; +use account_sdk::account::session::hash::{Policy, Session}; use account_sdk::account::session::SessionAccount; use account_sdk::signers::{HashSigner, Signer}; -use anyhow::Context; +use anyhow::{anyhow, Context}; use axum::response::{IntoResponse, Response}; use axum::{extract::State, routing::post, Router}; use hyper::StatusCode; @@ -29,8 +29,6 @@ use crate::{browser, server::LocalServer, vars}; const GUARDIAN: Felt = short_string!("CARTRIDGE_GUARDIAN"); pub const SESSION_GUARDIAN_SIGNING_KEY: SigningKey = SigningKey::from_secret_scalar(GUARDIAN); -// Taken from: https://github.com/cartridge-gg/controller/blob/b2c6ed8fcbabdc2e40176ce9955e155c662a9f1c/packages/keychain/src/const.ts#L2C1-L2C47 -const DEFAULT_SESSION_EXPIRES_AT: u64 = 1727776800; const SESSION_CREATION_PATH: &str = "/session"; const SESSION_FILE_BASE_NAME: &str = "session.json"; @@ -62,13 +60,11 @@ impl FullSessionInfo { where P: Provider + Send, { - let session_guardian = Signer::Starknet(SESSION_GUARDIAN_SIGNING_KEY); let session_signer = Signer::Starknet(SigningKey::from_secret_scalar(self.auth.signer)); SessionAccount::new_as_registered( provider, session_signer, - session_guardian, self.auth.address, self.chain_id, self.auth.owner_guid, @@ -137,11 +133,12 @@ pub async fn create(rpc_url: Url, policies: &[PolicyMethod]) -> Result, _>>() .map_err(Error::InvalidMethodName)?; - let session = Session::new(methods, DEFAULT_SESSION_EXPIRES_AT, &signer.signer())?; + let expires_at = response.expires_at.parse::().map_err(|e| anyhow!(e))?; + let session = Session::new(methods, expires_at, &signer.signer())?; let chain_id = get_network_chain_id(rpc_url).await?; Ok(FullSessionInfo { @@ -199,7 +196,7 @@ fn store_at( /// The response object to the session creation request. // -// A reflection of https://github.com/cartridge-gg/controller/blob/90b767bcc6478f0e02973f7237bc2a974f745adf/packages/keychain/src/pages/session.tsx#L15-L21 +// A reflection of https://github.com/cartridge-gg/controller/blob/1ac2995e4d430e9d3b88e3a62f4d3eb21a2496c3/packages/keychain/src/pages/session.tsx#L15-L22 #[cfg_attr(test, derive(PartialEq, Serialize))] #[derive(Debug, Clone, Default, Deserialize)] #[serde(rename_all = "camelCase")] @@ -208,6 +205,8 @@ pub struct SessionCreationResponse { pub username: String, /// The address of the Controller account associated with the username. pub address: Felt, + /// The session's expiration date. + pub expires_at: String, pub owner_guid: Felt, /// The hash of the session creation transaction. `None` is the session @@ -233,6 +232,18 @@ impl SessionCreationResponse { Ok(serde_json::from_str(&decoded)?) } + + #[cfg(test)] + pub fn to_encoded(&self) -> anyhow::Result { + use base64::{engine::general_purpose, Engine as _}; + + // Serialize the struct to JSON + let json = serde_json::to_string(self)?; + + // Encode the JSON string to Base64 + let encoded = general_purpose::STANDARD_NO_PAD.encode(json.as_bytes()); + Ok(encoded) + } } // TODO(kariy): this function should probably be put in a more generic `controller` rust sdk. @@ -380,7 +391,7 @@ async fn get_network_chain_id(url: Url) -> anyhow::Result { Ok(provider.chain_id().await?) } -impl TryFrom for AllowedMethod { +impl TryFrom for account_sdk::account::session::hash::Policy { type Error = NonAsciiNameError; fn try_from(value: PolicyMethod) -> Result { @@ -391,7 +402,7 @@ impl TryFrom for AllowedMethod { } } -impl TryFrom<&PolicyMethod> for AllowedMethod { +impl TryFrom<&PolicyMethod> for account_sdk::account::session::hash::Policy { type Error = NonAsciiNameError; fn try_from(value: &PolicyMethod) -> Result { @@ -529,24 +540,25 @@ mod tests { #[test] fn deserialize_backend_encoded_response() { - let encoded_response = "eyJ1c2VybmFtZSI6ImpvaG5zbWl0aCIsImFkZHJlc3MiOiIweDM5NzMzM2U5OTNhZTE2MmI0NzY2OTBlMTQwMTU0OGFlOTdhODgxOTk1NTUwNmI4YmM5MThlMDY3YmRhZmMzIiwib3duZXJHdWlkIjoiMHg1ZDc3MDliMGE0ODVlNjRhNTQ5YWRhOWJkMTRkMzA0MTkzNjQxMjdkZmQzNTFlMDFmMzg4NzFjODI1MDBjZDciLCJ0cmFuc2FjdGlvbkhhc2giOiIweDRlOTY4ZWRkODFiYTQ2MjI0Zjc2MjNmNDA5NWQ3NTRkYzgwZjZjYmQ1NTU4M2NkZTBlZDJhMTQzYWViNzMyMSJ9"; - let response = SessionCreationResponse::from_encoded(encoded_response).unwrap(); - - assert_eq!(response.username, "johnsmith"); - assert_eq!( - response.address, - felt!("0x397333e993ae162b476690e1401548ae97a8819955506b8bc918e067bdafc3") - ); - assert_eq!( - response.owner_guid, - felt!("0x5d7709b0a485e64a549ada9bd14d30419364127dfd351e01f38871c82500cd7") - ); - assert_eq!( - response.transaction_hash, - Some(felt!( + let original = SessionCreationResponse { + username: "johnsmith".to_string(), + address: felt!("0x397333e993ae162b476690e1401548ae97a8819955506b8bc918e067bdafc3"), + owner_guid: felt!("0x5d7709b0a485e64a549ada9bd14d30419364127dfd351e01f38871c82500cd7"), + transaction_hash: Some(felt!( "0x4e968edd81ba46224f7623f4095d754dc80f6cbd55583cde0ed2a143aeb7321" - )) - ); - assert!(!response.already_registered); + )), + expires_at: "2023-12-31T23:59:59Z".to_string(), + already_registered: false, + }; + + let encoded = original.to_encoded().unwrap(); + let decoded = SessionCreationResponse::from_encoded(&encoded).unwrap(); + + assert_eq!(decoded.username, original.username); + assert_eq!(decoded.address, original.address); + assert_eq!(decoded.owner_guid, original.owner_guid); + assert_eq!(decoded.transaction_hash, original.transaction_hash); + assert_eq!(decoded.expires_at, original.expires_at); + assert_eq!(decoded.already_registered, original.already_registered); } }