···99};
1010use crate::utils::at_uri_is_by;
1111use deadpool_postgres::{Object, Pool, Transaction};
1212-use did_resolver::Resolver;
1312use foldhash::quality::RandomState;
1413use futures::StreamExt;
1514use ipld_core::cid::Cid;
1515+use jacquard_common::types::string::Handle;
1616+use jacquard_identity::JacquardResolver;
1617use metrics::counter;
1718use parakeet_db::types::{ActorStatus, ActorSyncState};
1819use parakeet_index::AggregateType;
···2021use redis::AsyncCommands;
2122use std::collections::HashMap;
2223use std::hash::BuildHasher;
2323-use std::sync::Arc;
2424use tokio::sync::mpsc::{channel, Sender};
2525use tokio::sync::watch::Receiver as WatchReceiver;
2626use tracing::instrument;
···3737#[derive(Clone)]
3838struct RelayIndexerState {
3939 idxc_tx: Sender<parakeet_index::AggregateDeltaReq>,
4040- resolver: Arc<Resolver>,
4040+ resolver: JacquardResolver,
4141 do_backfill: bool,
4242 do_handle_res: bool,
4343 req_backfill: bool,
···5757 pool: Pool,
5858 redis: MultiplexedConnection,
5959 idxc_tx: Sender<parakeet_index::AggregateDeltaReq>,
6060- resolver: Arc<Resolver>,
6060+ resolver: JacquardResolver,
6161 firehose: FirehoseConsumer,
6262 resume: sled::Db,
6363 opts: RelayIndexerOpts,
···253253 did: &str,
254254 expected_handle: Option<String>,
255255) -> eyre::Result<Option<String>> {
256256- // Resolve the did doc
257257- let Some(did_doc) = state.resolver.resolve_did(did).await? else {
258258- eyre::bail!("missing did doc");
256256+ let Some(handle) = expected_handle else {
257257+ return Ok(None);
259258 };
260259261261- // if there's no handles in aka or the expected is none, set to none in DB.
262262- if did_doc.also_known_as.as_ref().is_none_or(|v| v.is_empty()) || expected_handle.is_none() {
263263- return Ok(None);
264264- }
265265-266266- let expected = expected_handle.unwrap();
267267-268268- // check if the handle from the event is in the did doc
269269- let expected_in_doc = did_doc.also_known_as.is_some_and(|v| {
270270- v.iter()
271271- .filter_map(|v| v.strip_prefix("at://"))
272272- .any(|v| v == expected)
273273- });
274274-275275- // if it isn't, set to invalid.
276276- if !expected_in_doc {
277277- tracing::warn!("Handle not in DID doc");
278278- return Ok(None);
279279- }
280280-281281- // in theory, we can use com.atproto.identity.resolveHandle against a PDS, but that seems
282282- // like a way to end up with really sus handles.
283283- let Some(handle_did) = state.resolver.resolve_handle(&expected).await? else {
284284- return Ok(None);
285285- };
260260+ // this verifies that the handle and the did it resolves to match.
261261+ let (handle_did, _did_doc, _warnings) = state
262262+ .resolver
263263+ .resolve_handle_and_doc(&Handle::raw(&handle))
264264+ .await?;
286265287266 // finally, check if the event did matches the handle, if not, set invalid, otherwise set the handle.
288288- if handle_did != did {
289289- Ok(None)
267267+ if did == &*handle_did {
268268+ return Ok(Some(handle));
290269 } else {
291291- Ok(Some(expected))
270270+ return Ok(None);
292271 }
293272}
294273