diff --git a/crates/context/config/src/client/env/config/query/proxy_contract.rs b/crates/context/config/src/client/env/config/query/proxy_contract.rs index a76317359..0d549f187 100644 --- a/crates/context/config/src/client/env/config/query/proxy_contract.rs +++ b/crates/context/config/src/client/env/config/query/proxy_contract.rs @@ -1,5 +1,11 @@ +use std::io::Cursor; + +use base64::engine::general_purpose::STANDARD as BASE64; +use base64::Engine as _; use candid::{Decode, Encode, Principal}; use serde::Serialize; +use soroban_sdk::xdr::{Limited, Limits, ReadXdr, ScVal}; +use soroban_sdk::{Address, Env, TryFromVal}; use starknet::core::codec::Encode as StarknetEncode; use starknet_crypto::Felt; @@ -90,8 +96,24 @@ impl Method for ProxyContractRequest { } fn decode(response: Vec) -> eyre::Result { - let value = String::from_utf8(response) - .map_err(|e| eyre::eyre!("Failed to decode proxy contract address: {}", e))?; - Ok(value) + let base64_str = BASE64.encode(&response); + + let xdr_bytes = BASE64 + .decode(base64_str) + .map_err(|e| format!("Failed to decode base64: {}", e)) + .unwrap(); + + let cursor = Cursor::new(xdr_bytes); + let mut limited = Limited::new(cursor, Limits::none()); + + let sc_val = ScVal::read_xdr(&mut limited) + .map_err(|e| format!("Failed to read XDR: {}", e)) + .unwrap(); + + let env = Env::default(); + match Address::try_from_val(&env, &sc_val) { + Ok(address) => Ok(address.to_string().to_string()), + Err(e) => return Err(eyre::eyre!("failed to convert to address: {:?}", e)), + } } } diff --git a/crates/context/config/src/client/protocol/stellar.rs b/crates/context/config/src/client/protocol/stellar.rs index dea7b350b..542ee97de 100644 --- a/crates/context/config/src/client/protocol/stellar.rs +++ b/crates/context/config/src/client/protocol/stellar.rs @@ -188,37 +188,12 @@ impl ProtocolTransport for StellarTransport<'_> { )); }; - let mut args = None; - - if !payload.is_empty() { - let env = Env::default(); - let env_bytes = Bytes::from_slice(&env, &payload); - let signed_request = - StellarSignedRequest::from_xdr(&env, &env_bytes).map_err(|_| { - StellarError::Custom { - operation: ErrorOperation::Query, - reason: "Failed to deserialize signed request".to_owned(), - } - })?; - let val: Val = signed_request - .try_into_val(&env) - .map_err(|_| StellarError::Custom { - operation: ErrorOperation::Query, - reason: "Failed to convert to Val".to_owned(), - })?; - let sc_val: ScVal = val.try_into_val(&env).map_err(|_| StellarError::Custom { - operation: ErrorOperation::Query, - reason: "Failed to convert to ScVal".to_owned(), - })?; - args = Some(vec![sc_val]); - } - let contract: Contracts = Contracts::new(&request.contract_id) .map_err(|_| StellarError::InvalidContractId(request.contract_id.into_owned()))?; match request.operation { - Operation::Read { method } => network.query(&contract, &method, args).await, - Operation::Write { method } => network.mutate(&contract, &method, args).await, + Operation::Read { method } => network.query(&contract, &method, payload).await, + Operation::Write { method } => network.mutate(&contract, &method, payload).await, } } } @@ -228,7 +203,7 @@ impl Network { &self, contract: &Contracts, method: &str, - args: Option>, + args: Vec, ) -> Result, StellarError> { let account = self .client @@ -241,9 +216,27 @@ impl Network { let source_account = Rc::new(RefCell::new(account)); + let mut encoded_args = None; + + if !args.is_empty() { + let env = Env::default(); + let env_bytes = Bytes::from_slice(&env, &args); + let val: Val = env_bytes + .try_into_val(&env) + .map_err(|_| StellarError::Custom { + operation: ErrorOperation::Query, + reason: "Failed to convert to Val".to_owned(), + })?; + let sc_val: ScVal = val.try_into_val(&env).map_err(|_| StellarError::Custom { + operation: ErrorOperation::Query, + reason: "Failed to convert to ScVal".to_owned(), + })?; + encoded_args = Some(vec![sc_val]); + } + let transaction = TransactionBuilder::new(source_account, self.network.as_str(), None) .fee(10000u32) - .add_operation(contract.call(method, args)) + .add_operation(contract.call(method, encoded_args)) .set_timeout(15) .expect("Transaction timeout") .build(); @@ -288,7 +281,7 @@ impl Network { &self, contract: &Contracts, method: &str, - args: Option>, + args: Vec, ) -> Result, StellarError> { let account = self .client @@ -301,9 +294,34 @@ impl Network { let source_account = Rc::new(RefCell::new(account)); + let mut encoded_args = None; + + if !args.is_empty() { + let env = Env::default(); + let env_bytes = Bytes::from_slice(&env, &args); + let signed_request = + StellarSignedRequest::from_xdr(&env, &env_bytes).map_err(|_| { + StellarError::Custom { + operation: ErrorOperation::Query, + reason: "Failed to deserialize signed request".to_owned(), + } + })?; + let val: Val = signed_request + .try_into_val(&env) + .map_err(|_| StellarError::Custom { + operation: ErrorOperation::Query, + reason: "Failed to convert to Val".to_owned(), + })?; + let sc_val: ScVal = val.try_into_val(&env).map_err(|_| StellarError::Custom { + operation: ErrorOperation::Query, + reason: "Failed to convert to ScVal".to_owned(), + })?; + encoded_args = Some(vec![sc_val]); + } + let transaction = TransactionBuilder::new(source_account, self.network.as_str(), None) .fee(10000u32) - .add_operation(contract.call(method, args)) + .add_operation(contract.call(method, encoded_args)) .set_timeout(15) .expect("Transaction timeout") .build();