Skip to content

Commit 3d43c65

Browse files
committed
feat use resolver
1 parent ea67dc7 commit 3d43c65

File tree

3 files changed

+41
-41
lines changed

3 files changed

+41
-41
lines changed

src/lib.rs

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2020-2024 IOTA Stiftung
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use std::collections::{HashMap, HashSet};
4+
use std::collections::HashSet;
55
use std::env;
66
use std::str::FromStr;
77
use std::sync::Arc;
@@ -13,14 +13,16 @@ use axum::routing::get;
1313
use axum::{Json, Router};
1414
use identity_iota::document::CoreDocument;
1515
use identity_iota::iota::{IotaDID, IotaDocumentMetadata};
16+
use identity_iota::prelude::Resolver;
17+
use identity_iota::resolver::ErrorCause;
1618
use identity_iota_core::rebased::client::IdentityClientReadOnly;
17-
use identity_iota_core::rebased::migration::get_identity;
19+
use identity_iota_core::IotaDocument;
1820
use iota_sdk::types::base_types::ObjectID;
1921
use iota_sdk::{IotaClient, IotaClientBuilder};
2022
use serde::{Deserialize, Serialize};
2123
use tokio::net::TcpListener;
2224

23-
type NetworkClients = Arc<HashMap<String, IdentityClientReadOnly>>;
25+
type SharedResolver = Arc<Resolver<IotaDocument>>;
2426

2527
/// Custom endpoint for the IOTA network.
2628
pub const IOTA_CUSTOM_NODE_ENDPOINT: &str = "IOTA_CUSTOM_NODE_ENDPOINT";
@@ -105,21 +107,21 @@ impl Network {
105107
}
106108
#[derive(Default)]
107109
pub struct Server {
108-
clients: Option<NetworkClients>,
110+
resolver: Option<SharedResolver>,
109111
}
110112

111113
impl Server {
112-
pub fn with_clients(mut self, clients: HashMap<String, IdentityClientReadOnly>) -> Self {
113-
self.clients = Some(Arc::new(clients));
114+
pub fn with_resolver(mut self, resolver: Resolver<IotaDocument>) -> Self {
115+
self.resolver = Some(Arc::new(resolver));
114116
self
115117
}
116118

117119
pub async fn run(self, listener: TcpListener) -> anyhow::Result<()> {
118-
let clients = match self.clients {
119-
Some(clients) => clients,
120-
None => init_clients().await?,
120+
let resolver = match self.resolver {
121+
Some(resolver) => resolver,
122+
None => init_resolver().await?,
121123
};
122-
let app = app(clients).await?;
124+
let app = app(resolver).await?;
123125
let addr = listener.local_addr()?;
124126

125127
tracing::debug!("Server is starting at {addr}");
@@ -145,42 +147,34 @@ pub struct ResolutionResponse {
145147
)]
146148
async fn resolve_did(
147149
Path(arg): Path<String>,
148-
State(clients): State<NetworkClients>,
150+
State(resolver): State<SharedResolver>,
149151
) -> Result<Json<ResolutionResponse>, (StatusCode, String)> {
150152
let did = IotaDID::parse(&arg).map_err(|e| (StatusCode::BAD_REQUEST, e.to_string()))?;
151-
let network = did.network_str().to_string();
152153

153-
let object_id = ObjectID::from_str(did.tag_str()).map_err(|e| (StatusCode::BAD_REQUEST, e.to_string()))?;
154+
let identity = resolver.resolve(&did).await.map_err(|e| match e.error_cause() {
155+
ErrorCause::HandlerError { source, .. } if source.to_string().contains("could not find") => (
156+
StatusCode::NOT_FOUND,
157+
"The requested DID document was not found".to_owned(),
158+
),
154159

155-
let client = clients
156-
.get(&network)
157-
.ok_or_else(|| (StatusCode::BAD_REQUEST, format!("Unsupported network: {}", network)))?;
158-
159-
let identity = get_identity(client, object_id)
160-
.await
161-
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?
162-
.ok_or_else(|| {
163-
(
164-
StatusCode::NOT_FOUND,
165-
"The requested DID document was not found".to_owned(),
166-
)
167-
})?;
160+
_ => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()),
161+
})?;
168162

169163
Ok(Json(ResolutionResponse {
170164
did_document: identity.core_document().clone(),
171165
did_resolution_metadata: identity.metadata.clone(),
172166
}))
173167
}
174168

175-
async fn app(clients: NetworkClients) -> anyhow::Result<Router> {
169+
async fn app(resolver: SharedResolver) -> anyhow::Result<Router> {
176170
Ok(Router::new()
177171
.route("/1.0/identifiers/:did", get(resolve_did))
178-
.with_state(clients))
172+
.with_state(resolver))
179173
}
180174

181175
/// Initialize identity clients for all configured networks.
182-
async fn init_clients() -> anyhow::Result<NetworkClients> {
183-
let mut clients = HashMap::new();
176+
async fn init_resolver() -> anyhow::Result<SharedResolver> {
177+
let mut clients = vec![];
184178
let networks = Network::from_env()?;
185179

186180
for network in networks {
@@ -201,13 +195,18 @@ async fn init_clients() -> anyhow::Result<NetworkClients> {
201195

202196
let network_name = identity_client.network().to_string();
203197
tracing::debug!("Initialized client for network: {}", network_name);
204-
205-
if clients.insert(network_name.clone(), identity_client).is_some() {
206-
tracing::warn!("Overwrote existing client for network: {}", network_name);
207-
}
198+
let network_name: &'static str = Box::leak(network_name.into_boxed_str());
199+
clients.push((network_name, identity_client));
208200
}
209201

210-
ensure!(!clients.is_empty(), "No identity clients were created");
202+
ensure!(
203+
!clients.is_empty(),
204+
"No clients were created. Make sure you provide a configuration for at least one network"
205+
);
206+
207+
let mut resolver = Resolver::<IotaDocument>::new();
208+
209+
resolver.attach_multiple_iota_handlers(clients);
211210

212-
Ok(Arc::new(clients))
211+
Ok(Arc::new(resolver))
213212
}

tests/common/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
// Copyright 2020-2023 IOTA Stiftung
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use std::collections::HashMap;
54
use std::net::SocketAddr;
65
use std::sync::{Arc, OnceLock};
76

87
use anyhow::Context;
98
use fastcrypto::ed25519::Ed25519PublicKey;
109
use fastcrypto::traits::ToFromBytes;
1110
use identity_iota::iota::{IotaDocument, NetworkName};
11+
use identity_iota::prelude::Resolver;
1212
use identity_iota::storage::{JwkDocumentExt, Storage, StorageSigner};
1313
use identity_iota::verification::jwk::Jwk;
1414
use identity_iota::verification::jws::JwsAlgorithm;
@@ -57,17 +57,17 @@ impl TestServer {
5757

5858
let client = IdentityClientReadOnly::new(client).await?;
5959

60-
let mut clients = HashMap::new();
60+
let mut resolver = Resolver::<IotaDocument>::new();
6161

62-
clients.insert(client.network().to_string(), client.clone());
62+
resolver.attach_iota_handler(client.clone());
6363

64-
let server = Server::default().with_clients(clients);
64+
let server = Server::default().with_resolver(resolver);
6565

6666
let listener = TcpListener::bind("127.0.0.1:0")
6767
.await
6868
.context("failed to bind to random port")?;
6969
let address = listener.local_addr()?;
70-
70+
println!("Server running on: {}", address);
7171
Ok(Self {
7272
client,
7373
storage,

tests/did_resolution.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use uni_resolver_driver_iota::ResolutionResponse;
1111
// Creates and fetches a DID document using the resolver server.
1212
async fn did_resolution_works() -> anyhow::Result<()> {
1313
let mut server = TestServer::new().await?;
14+
1415
let target_doc = server.create_did().await?;
1516

1617
let client = Client::default();

0 commit comments

Comments
 (0)