-
Notifications
You must be signed in to change notification settings - Fork 5
feat: algokit_utils (Rust impl only) #166
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
Merged
+1,743
−527
Merged
Changes from all commits
Commits
Show all changes
55 commits
Select commit
Hold shift + click to select a range
8b891fe
wip: utils crate with composer
joe-p 37608d4
wip: working utils py (with some modifications)
joe-p 5552911
wip: working utils ts
joe-p 326ed8e
wip: get uniffi compiling again
joe-p a7f3776
wip: use Mutex for WASM, toString, and transactions getter
joe-p 5f1a167
wip: valueOf and proper toString via JSON.stringify
joe-p bbe4e6e
wip: toJSON
joe-p 84f8e5e
wip: test error
joe-p 4fca1ae
wip: fetch
joe-p ba89749
wip: blocking HTTPClient
joe-p 6b30bc6
async http client
joe-p 726c301
wip: AlgodClient
joe-p 8f261ed
wip: so close
joe-p 2cf84d9
wip: AlgodClient class and async extern, still same error
joe-p 00b784e
wip: working
joe-p 44e9f34
wip: split out wasm mod
joe-p 2f5eb2e
wip: almost working, just need to split out httpclient trait
joe-p 44b9bf4
wip: split out http trait
joe-p 07a666f
wip: working utils py without http test
joe-p 84e2f01
wip: passing pytest w/ http call!
joe-p 249d275
wip: working TS!
joe-p e011f45
wip: unified wasm and uniffi
joe-p 7ffb4a9
wip: split out wasm file
joe-p 874a6b4
wip: move wasm externs into http crate
joe-p b900e3d
wip: split out unified mutex
joe-p bff57fe
wip: rename FfiMutex
joe-p a1c1f53
wip: HTTP -> Http
joe-p b7a6641
wip: add some comments
joe-p 2b2eba2
wip: add default client to http crate
joe-p aaff444
change main to node.cjs
joe-p fc8f7bc
wip: add_payment in rust utils
joe-p cdf4c91
wip: algod_api crate
joe-p 21d516a
wip: proper transactions/params deserialization
joe-p 13a69c7
wip: build() function
joe-p 5bd2a2d
Merge branch 'main' into spike/utils_crate
joe-p d5214d8
wip: assign group
joe-p 4ee2034
wip: return an already build group
joe-p a17eb49
wip: gather signatures
joe-p 0c40e9c
wip: use traits for signer/signer getter
joe-p 10a7aa6
wip: rm utils_ffi
joe-p c97d362
wip: fix __init__.py
joe-p 4e70e67
wip: rm unused variables
joe-p 7e3b7fb
wip: fix http trait wasm feat
joe-p b1da130
wip: rm utils packages
joe-p d4c330a
wip: make signer traits async
joe-p fcfa5b5
chore: fix typo
joe-p c9b26d9
Merge branch 'main' into feat/rust_utils
joe-p 9d4e137
feat(ffi_mutex): set ffi_uniffi as the default trait
joe-p 9db75dd
chore: fmt/clippy
joe-p d8ee065
fix(utils): http client trait with ffi_wasm
joe-p e4b3b2c
chore: fix typo
joe-p cc8526a
chore: rename algokit_http_client crate
joe-p 4324c93
fix(utils): use appropriate error types
joe-p 380e44e
fix(http_client): avoid unwrap
joe-p afb55ca
chore: add docstring
joe-p File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or 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 hidden or 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,14 @@ | ||
[package] | ||
name = "algod_api" | ||
version = "0.1.0" | ||
edition = "2024" | ||
|
||
[features] | ||
default = ["default_http_client"] | ||
default_http_client = ["algokit_http_client/default_client"] | ||
|
||
|
||
[dependencies] | ||
algokit_http_client = { version = "0.1.0", path = "../algokit_http_client" } | ||
serde = { version = "1.0.219", features = ["derive"] } | ||
serde_json = "1.0.140" |
This file contains hidden or 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,47 @@ | ||
use std::sync::Arc; | ||
|
||
use algokit_http_client::{HttpClient, HttpError}; | ||
|
||
#[cfg(feature = "default_http_client")] | ||
use algokit_http_client::DefaultHttpClient; | ||
|
||
use serde::{Deserialize, Serialize}; | ||
|
||
pub struct AlgodClient { | ||
http_client: Arc<dyn HttpClient>, | ||
} | ||
|
||
#[derive(Serialize, Deserialize)] | ||
#[serde(rename_all = "kebab-case")] | ||
pub struct TransactionParams { | ||
pub consensus_version: String, | ||
pub fee: u64, | ||
pub last_round: u64, | ||
pub genesis_id: String, | ||
pub genesis_hash: String, | ||
pub min_fee: u64, | ||
} | ||
|
||
/// A temporary AlgodClient until the proper client is generated. | ||
/// The exepectation is that this client will use a HttpClient to make requests to the Algorand API | ||
impl AlgodClient { | ||
joe-p marked this conversation as resolved.
Show resolved
Hide resolved
|
||
pub fn new(http_client: Arc<dyn HttpClient>) -> Self { | ||
AlgodClient { http_client } | ||
} | ||
|
||
#[cfg(feature = "default_http_client")] | ||
pub fn testnet() -> Self { | ||
AlgodClient { | ||
http_client: Arc::new(DefaultHttpClient::new( | ||
"https://testnet-api.4160.nodely.dev", | ||
)), | ||
} | ||
} | ||
|
||
pub async fn transaction_params(&self) -> Result<TransactionParams, HttpError> { | ||
let path = "/v2/transactions/params".to_string(); | ||
let response = self.http_client.get(path).await?; | ||
|
||
serde_json::from_slice(&response).map_err(|e| HttpError::HttpError(e.to_string())) | ||
} | ||
} |
This file contains hidden or 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,19 @@ | ||
[package] | ||
name = "algokit_http_client" | ||
version = "0.1.0" | ||
edition = "2024" | ||
|
||
[features] | ||
default = ["default_client"] | ||
ffi_uniffi = ["dep:uniffi"] | ||
ffi_wasm = ["dep:wasm-bindgen", "dep:js-sys"] | ||
default_client = ["dep:reqwest"] | ||
|
||
[dependencies] | ||
async-trait = "0.1.88" | ||
js-sys = { workspace = true, optional = true } | ||
reqwest = { version = "0.12.19", optional = true } | ||
thiserror.workspace = true | ||
uniffi = { workspace = true, optional = true } | ||
wasm-bindgen = { workspace = true, optional = true } | ||
wasm-bindgen-futures = "0.4.50" |
This file contains hidden or 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,98 @@ | ||||||
use async_trait::async_trait; | ||||||
|
||||||
#[cfg(feature = "ffi_uniffi")] | ||||||
uniffi::setup_scaffolding!(); | ||||||
|
||||||
#[derive(Debug, thiserror::Error)] | ||||||
#[cfg_attr(feature = "ffi_uniffi", derive(uniffi::Error))] | ||||||
pub enum HttpError { | ||||||
#[error("HttpError: {0}")] | ||||||
HttpError(String), | ||||||
} | ||||||
|
||||||
#[cfg(not(feature = "ffi_wasm"))] | ||||||
#[cfg_attr(feature = "ffi_uniffi", uniffi::export(with_foreign))] | ||||||
#[async_trait] | ||||||
/// This trait must be implemented by any HTTP client that is used by our Rust crates. | ||||||
/// It is assumed the implementing type will provide the hostname, port, headers, etc. as needed for each request. | ||||||
/// | ||||||
/// By default, this trait requires the implementing type to be `Send + Sync`. | ||||||
/// For WASM targets, enable the `ffi_wasm` feature to use a different implementation that is compatible with WASM. | ||||||
/// | ||||||
/// With the `ffi_uniffi` feature enabled, this is exported as a foreign trait, meaning it is implemented natively in the foreign language. | ||||||
/// | ||||||
pub trait HttpClient: Send + Sync { | ||||||
async fn get(&self, path: String) -> Result<Vec<u8>, HttpError>; | ||||||
} | ||||||
|
||||||
#[cfg(feature = "default_client")] | ||||||
pub struct DefaultHttpClient { | ||||||
host: String, | ||||||
} | ||||||
|
||||||
#[cfg(feature = "default_client")] | ||||||
impl DefaultHttpClient { | ||||||
pub fn new(host: &str) -> Self { | ||||||
DefaultHttpClient { | ||||||
host: host.to_string(), | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
#[cfg(feature = "default_client")] | ||||||
#[cfg_attr(feature = "ffi_wasm", async_trait(?Send))] | ||||||
#[cfg_attr(not(feature = "ffi_wasm"), async_trait)] | ||||||
impl HttpClient for DefaultHttpClient { | ||||||
async fn get(&self, path: String) -> Result<Vec<u8>, HttpError> { | ||||||
let response = reqwest::get(self.host.clone() + &path) | ||||||
.await | ||||||
.map_err(|e| HttpError::HttpError(e.to_string()))? | ||||||
.bytes() | ||||||
.await | ||||||
.map_err(|e| HttpError::HttpError(e.to_string()))? | ||||||
.to_vec(); | ||||||
|
||||||
Ok(response) | ||||||
} | ||||||
} | ||||||
|
||||||
#[cfg(feature = "ffi_wasm")] | ||||||
use wasm_bindgen::prelude::*; | ||||||
|
||||||
#[cfg(feature = "ffi_wasm")] | ||||||
use js_sys::Uint8Array; | ||||||
|
||||||
#[cfg(feature = "ffi_wasm")] | ||||||
#[async_trait(?Send)] | ||||||
pub trait HttpClient { | ||||||
async fn get(&self, path: String) -> Result<Vec<u8>, HttpError>; | ||||||
} | ||||||
|
||||||
#[wasm_bindgen] | ||||||
#[cfg(feature = "ffi_wasm")] | ||||||
extern "C" { | ||||||
/// The interface for the JavaScript-based HTTP client that will be used in WASM environments. | ||||||
/// | ||||||
/// This mirrors the `HttpClient` trait, but wasm-bindgen doesn't support foreign traits so we define it separately. | ||||||
pub type WasmHttpClient; | ||||||
|
||||||
#[wasm_bindgen(method, catch)] | ||||||
async fn get(this: &WasmHttpClient, path: &str) -> Result<Uint8Array, JsValue>; | ||||||
} | ||||||
|
||||||
#[cfg(feature = "ffi_wasm")] | ||||||
#[async_trait(?Send)] | ||||||
impl HttpClient for WasmHttpClient { | ||||||
async fn get(&self, path: String) -> Result<Vec<u8>, HttpError> { | ||||||
let result = self.get(&path).await.map_err(|e| { | ||||||
HttpError::HttpError( | ||||||
e.as_string().unwrap_or( | ||||||
"A HTTP error ocurred in JavaScript, but it cannot be converted to a string" | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix spelling: change "ocurred" to "occurred" in the error message.
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||||||
.to_string(), | ||||||
), | ||||||
) | ||||||
})?; | ||||||
|
||||||
Ok(result.to_vec()) | ||||||
} | ||||||
} |
This file contains hidden or 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 hidden or 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,21 @@ | ||
[package] | ||
name = "algokit_utils" | ||
version = "0.1.0" | ||
edition = "2024" | ||
|
||
[features] | ||
default = ["default_http_client"] | ||
default_http_client = ["dep:reqwest", "algokit_http_client/default_client"] | ||
|
||
[dependencies] | ||
algod_api = { version = "0.1.0", path = "../algod_api" } | ||
algokit_http_client = { version = "0.1.0", path = "../algokit_http_client", default-features = false } | ||
algokit_transact = { version = "0.1.0", path = "../algokit_transact", features = ["test_utils"] } | ||
async-trait = { version = "0.1.88" } | ||
base64 = "0.22.1" | ||
derive_more = { version = "2.0.1", features = ["full"] } | ||
reqwest = { version = "0.12.19", features = ["blocking"], optional = true } | ||
thiserror.workspace = true | ||
|
||
[dev-dependencies] | ||
tokio = { version = "1.45.1", features = ["full", "test-util"] } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix spelling: change "exepectation" to "expectation" in the documentation comment.
Copilot uses AI. Check for mistakes.