Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/iota-graphql-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ repository = "https://github.com/iotaledger/iota-rust-sdk/"
description = "GraphQL RPC Client for the IOTA Blockchain"

[dependencies]
anyhow = "1.0.71"
base64ct = { version = "1.6.0", features = ["alloc", "std"] }
bcs = "0.1.4"
chrono = "0.4.26"
cynic = "3.7.3"
derive_more = { version = "2.0", features = ["from"] }
eyre = "0.6"
futures = "0.3.29"
iota-types = { package = "iota-sdk-types", path = "../iota-sdk-types", features = ["serde"] }
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "json"] }
Expand Down
8 changes: 4 additions & 4 deletions crates/iota-graphql-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Instantiate a client with [`Client::new(server: &str)`] or use one of the predef

```rust, no_run
use iota_graphql_client::Client;
use anyhow::Result;
use eyre::Result;

#[tokio::main]
async fn main() -> Result<()> {
Expand All @@ -47,7 +47,7 @@ The client provides an API to request gas from the faucet. The `request_and_wait
use iota_graphql_client::faucet::FaucetClient;
use iota_types::Address;

use anyhow::Result;
use eyre::Result;
use std::str::FromStr;

#[tokio::main]
Expand Down Expand Up @@ -77,7 +77,7 @@ Note that this `FaucetClient` is explicitly designed to work with two endpoints:
use iota_graphql_client::faucet::FaucetClient;
use iota_types::Address;

use anyhow::Result;
use eyre::Result;
use std::str::FromStr;

#[tokio::main]
Expand Down Expand Up @@ -157,7 +157,7 @@ pub struct BigInt(pub String);
The complete example is shown below:

```rust, ignore
use anyhow::Result;
use eyre::Result;
use cynic::QueryBuilder;

use iota_graphql_client::{
Expand Down
2 changes: 1 addition & 1 deletion crates/iota-graphql-client/examples/custom_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// Modifications Copyright (c) 2025 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use anyhow::Result;
use cynic::QueryBuilder;
use eyre::Result;
use iota_graphql_client::{
Client,
query_types::{BigInt, schema},
Expand Down
2 changes: 1 addition & 1 deletion crates/iota-graphql-client/examples/dynamic_fields.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) 2025 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use anyhow::Result;
use eyre::Result;
use iota_graphql_client::Client;

#[tokio::main]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use core::str::FromStr;

use anyhow::{Context, Result};
use eyre::{OptionExt, Result};
use iota_graphql_client::Client;
use iota_transaction_builder::{Function, TransactionBuilder, unresolved::Input};
use iota_types::{Address, Identifier, TypeTag};
Expand All @@ -20,7 +20,7 @@ async fn main() -> Result<()> {
None,
)
.await?
.context("missing gas coin")?;
.ok_or_eyre("missing gas coin")?;

let mut builder = TransactionBuilder::new();

Expand Down Expand Up @@ -55,15 +55,15 @@ async fn main() -> Result<()> {
client
.reference_gas_price(None)
.await?
.context("missing gas price")?,
.ok_or_eyre("missing gas price")?,
);
builder.add_gas_objects([Input::from(&gas_coin).with_owned_kind()]);

let txn = builder.finish()?;
let res = client.dry_run_tx(&txn, false).await?;

if let Some(err) = res.error {
anyhow::bail!("Failed to call generic Move function: {err}");
eyre::bail!("Failed to call generic Move function: {err}");
}

println!("Successfully called generic Move function!");
Expand Down
4 changes: 2 additions & 2 deletions crates/iota-graphql-client/examples/get_object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use std::str::FromStr;

use anyhow::{Context, Result};
use eyre::{OptionExt, Result};
use iota_graphql_client::Client;
use iota_types::ObjectId;

Expand All @@ -17,7 +17,7 @@ async fn main() -> Result<()> {
let obj = client
.object(object_id, None)
.await?
.context("missing object")?;
.ok_or_eyre("missing object")?;

println!("Object ID: {}", obj.object_id());
println!("Version: {}", obj.version());
Expand Down
6 changes: 3 additions & 3 deletions crates/iota-graphql-client/examples/move_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use std::str::FromStr;

use anyhow::Result;
use eyre::Result;
use iota_graphql_client::Client;
use iota_types::Address;

Expand All @@ -14,7 +14,7 @@ async fn main() -> Result<()> {
let package_address =
Address::from_str("0x3ec4826f1d6e0d9f00680b2e9a7a41f03788ee610b3d11c24f41ab0ae71da39f")?;
let Some(package) = client.package(package_address, None).await? else {
anyhow::bail!("no package found")
eyre::bail!("no package found")
};

for (module_id, _) in package.modules {
Expand All @@ -30,7 +30,7 @@ async fn main() -> Result<()> {
)
.await?
else {
anyhow::bail!("module `{module_id}` not found")
eyre::bail!("module `{module_id}` not found")
};
if let Some(funs) = module.functions {
println!("Module: {module_id}");
Expand Down
2 changes: 1 addition & 1 deletion crates/iota-graphql-client/examples/owned_objects.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) 2025 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use anyhow::Result;
use eyre::Result;
use iota_graphql_client::{Client, pagination::PaginationFilter, query_types::ObjectFilter};
use iota_types::Address;

Expand Down
2 changes: 1 addition & 1 deletion crates/iota-graphql-client/examples/pagination.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) 2025 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use anyhow::Result;
use eyre::Result;
use iota_graphql_client::{Client, pagination::PaginationFilter, query_types::ObjectFilter};
use iota_types::Address;

Expand Down
4 changes: 2 additions & 2 deletions crates/iota-graphql-client/examples/prepare_send_iota.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

use std::str::FromStr;

use anyhow::Result;
use base64ct::Encoding;
use eyre::Result;
use iota_graphql_client::Client;
use iota_transaction_builder::{TransactionBuilder, unresolved::Input};
use iota_types::{Address, ObjectId};
Expand Down Expand Up @@ -63,7 +63,7 @@ async fn main() -> Result<()> {
let res = client.dry_run_tx(&txn, false).await?;

if let Some(err) = res.error {
anyhow::bail!("Failed to send IOTA: {err}");
eyre::bail!("Failed to send IOTA: {err}");
}

println!("Send IOTA dry run was successful!");
Expand Down
10 changes: 5 additions & 5 deletions crates/iota-graphql-client/examples/prepare_send_iota_multi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

use std::str::FromStr;

use anyhow::{Context, Result};
use base64ct::Encoding;
use eyre::{OptionExt, Result};
use iota_graphql_client::Client;
use iota_transaction_builder::{TransactionBuilder, unresolved::Input};
use iota_types::{Address, Argument, ObjectId};
Expand All @@ -24,7 +24,7 @@ async fn main() -> Result<()> {
None,
)
.await?
.context("missing gas coin")?;
.ok_or_eyre("missing gas coin")?;

// Recipients and amounts
let recipients = [
Expand Down Expand Up @@ -61,7 +61,7 @@ async fn main() -> Result<()> {
// Transfer each split coin to its corresponding recipient
for (i, recipient_input) in recipient_inputs.into_iter().enumerate() {
let coin_arg = Argument::get_nested_result(&split_coins_result, i as u16)
.ok_or_else(|| anyhow::anyhow!("Failed to get split coin result at index {i}"))?;
.ok_or_else(|| eyre::eyre!("Failed to get split coin result at index {i}"))?;
builder.transfer_objects(vec![coin_arg], recipient_input);
}

Expand All @@ -71,7 +71,7 @@ async fn main() -> Result<()> {
client
.reference_gas_price(None)
.await?
.context("missing ref gas price")?,
.ok_or_eyre("missing ref gas price")?,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like context much more :(

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could actually be used with an additional trait import

NOTE: However, to help with porting we do provide a ContextCompat trait which implements context for options which you can import to make existing .context calls compile.

https://crates.io/crates/eyre

);
builder.add_gas_objects([Input::from(&gas_coin).with_owned_kind()]);
let txn = builder.finish()?;
Expand All @@ -85,7 +85,7 @@ async fn main() -> Result<()> {
let res = client.dry_run_tx(&txn, false).await?;

if let Some(err) = res.error {
anyhow::bail!("Failed to send IOTA: {err}");
eyre::bail!("Failed to send IOTA: {err}");
}

println!("Send IOTA dry run was successful!");
Expand Down
12 changes: 6 additions & 6 deletions crates/iota-graphql-client/examples/stake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use std::str::FromStr;

use anyhow::{Context, Result};
use eyre::{OptionExt, Result};
use iota_graphql_client::Client;
use iota_transaction_builder::{Function, TransactionBuilder, unresolved::Input};
use iota_types::{Address, Identifier, ObjectId};
Expand All @@ -21,7 +21,7 @@ async fn main() -> Result<()> {
.data
.into_iter()
.next()
.context("no validators found")?;
.ok_or_eyre("no validators found")?;

println!(
"Staking to validator {}",
Expand All @@ -36,7 +36,7 @@ async fn main() -> Result<()> {
None,
)
.await?
.context("missing object")?;
.ok_or_eyre("missing object")?;
let gas_coin = client
.object(
ObjectId::from_str(
Expand All @@ -45,7 +45,7 @@ async fn main() -> Result<()> {
None,
)
.await?
.context("missing gas coin")?;
.ok_or_eyre("missing gas coin")?;

let mut builder = TransactionBuilder::new();
let inputs = vec![
Expand All @@ -68,14 +68,14 @@ async fn main() -> Result<()> {
client
.reference_gas_price(None)
.await?
.context("missing ref gas price")?,
.ok_or_eyre("missing ref gas price")?,
);
builder.add_gas_objects([Input::from(&gas_coin).with_owned_kind()]);
let txn = builder.finish()?;
let res = client.dry_run_tx(&txn, false).await?;

if let Some(err) = res.error {
anyhow::bail!("Failed to stake: {err}");
eyre::bail!("Failed to stake: {err}");
}

println!("Stake dry run was successful!");
Expand Down
8 changes: 4 additions & 4 deletions crates/iota-graphql-client/examples/unstake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use std::str::FromStr;

use anyhow::{Context, Result};
use eyre::{OptionExt, Result};
use iota_graphql_client::{Client, query_types::ObjectFilter};
use iota_transaction_builder::{Function, TransactionBuilder, unresolved::Input};
use iota_types::{Address, Identifier, ObjectId, StructTag};
Expand All @@ -24,7 +24,7 @@ async fn main() -> Result<()> {
.data
.into_iter()
.next()
.context("no staked iota found")?;
.ok_or_eyre("no staked iota found")?;

// Get a valid gas coin
let gas_coin = client
Expand All @@ -40,7 +40,7 @@ async fn main() -> Result<()> {
.data
.into_iter()
.next()
.context("no gas coin found")?;
.ok_or_eyre("no gas coin found")?;

let mut builder = TransactionBuilder::new();
let inputs = vec![
Expand Down Expand Up @@ -69,7 +69,7 @@ async fn main() -> Result<()> {
let res = client.dry_run_tx(&txn, false).await?;

if let Some(err) = res.error {
anyhow::bail!("Failed to unstake: {err}");
eyre::bail!("Failed to unstake: {err}");
}

println!("Unstake dry run was successful!");
Expand Down
19 changes: 8 additions & 11 deletions crates/iota-graphql-client/src/faucet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use std::time::Duration;

use anyhow::{anyhow, bail};
use eyre::{bail, eyre};
use iota_types::{Address, Digest, ObjectId};
use reqwest::{StatusCode, Url};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -95,13 +95,13 @@ impl FaucetClient {
/// Request gas from the faucet. Note that this will return the UUID of the
/// request and not wait until the token is received. Use
/// `request_and_wait` to wait for the token.
pub async fn request(&self, address: Address) -> anyhow::Result<Option<String>> {
pub async fn request(&self, address: Address) -> eyre::Result<Option<String>> {
self.request_impl(address).await
}

/// Internal implementation of a faucet request. It returns the task Uuid as
/// a String.
async fn request_impl(&self, address: Address) -> anyhow::Result<Option<String>> {
async fn request_impl(&self, address: Address) -> eyre::Result<Option<String>> {
let address = address.to_string();
let json_body = json![{
"FixedAmountRequest": {
Expand Down Expand Up @@ -158,10 +158,7 @@ impl FaucetClient {
///
/// Note that the faucet is heavily rate-limited, so calling repeatedly the
/// faucet would likely result in a 429 code or 502 code.
pub async fn request_and_wait(
&self,
address: Address,
) -> anyhow::Result<Option<FaucetReceipt>> {
pub async fn request_and_wait(&self, address: Address) -> eyre::Result<Option<FaucetReceipt>> {
let request_id = self.request(address).await?;
if let Some(request_id) = request_id {
let poll_response = tokio::time::timeout(FAUCET_REQUEST_TIMEOUT, async {
Expand Down Expand Up @@ -189,7 +186,7 @@ impl FaucetClient {
}
} else if let Some(err) = req.err() {
error!("Faucet request {request_id} failed. Error: {:?}", err);
break Err(anyhow!(
break Err(eyre!(
"Faucet request {request_id} failed. Error: {:?}",
err
));
Expand All @@ -202,7 +199,7 @@ impl FaucetClient {
"Faucet request {request_id} timed out. Timeout set to {} seconds",
FAUCET_REQUEST_TIMEOUT.as_secs()
);
anyhow!("Faucet request timed out")
eyre!("Faucet request timed out")
})??;
Ok(poll_response.transferred_gas_objects)
} else {
Expand All @@ -213,7 +210,7 @@ impl FaucetClient {
/// Check the faucet request status.
///
/// Possible statuses are defined in: [`BatchSendStatusType`]
pub async fn request_status(&self, id: String) -> anyhow::Result<Option<BatchSendStatus>> {
pub async fn request_status(&self, id: String) -> eyre::Result<Option<BatchSendStatus>> {
let status_url = format!("{}v1/status/{}", self.faucet_url, id);
info!("Checking status of faucet request: {status_url}");
let response = self.inner.get(&status_url).send().await?;
Expand All @@ -227,7 +224,7 @@ impl FaucetClient {
.await
.map_err(|e| {
error!("Failed to parse faucet response: {:?}", e);
anyhow!("Failed to parse faucet response: {:?}", e)
eyre!("Failed to parse faucet response: {:?}", e)
})?;
Ok(json.status)
}
Expand Down
Loading