diff --git a/ucan/src/chain.rs b/ucan/src/chain.rs index 4eb0e67a..c26e63d5 100644 --- a/ucan/src/chain.rs +++ b/ucan/src/chain.rs @@ -46,6 +46,7 @@ pub struct ProofChain { } impl ProofChain { + /// Instantiate a [ProofChain] from a [Ucan], given a [UcanJwtStore] and [DidParser] #[cfg_attr(target_arch = "wasm32", async_recursion(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_recursion)] pub async fn from_ucan( @@ -102,10 +103,16 @@ impl ProofChain { }) } - pub async fn from_cid<'a>(_cid: &str, _did_parser: &mut DidParser) -> Result { - todo!("Resolving a proof from a CID not yet implemented") + /// Instantiate a [ProofChain] from a [Cid], given a [UcanJwtStore] and [DidParser] + /// The [Cid] must resolve to a JWT token string + pub async fn from_cid(cid: &Cid, did_parser: &mut DidParser, store: &S) -> Result + where + S: UcanJwtStore, + { + Self::try_from_token_string(&store.require_token(cid).await?, did_parser, store).await } + /// Instantiate a [ProofChain] from a JWT token string, given a [UcanJwtStore] and [DidParser] pub async fn try_from_token_string<'a, S>( ucan_token_string: &str, did_parser: &mut DidParser, diff --git a/ucan/src/tests/chain.rs b/ucan/src/tests/chain.rs index 55e8c069..ddb616d6 100644 --- a/ucan/src/tests/chain.rs +++ b/ucan/src/tests/chain.rs @@ -100,6 +100,55 @@ pub async fn it_fails_with_incorrect_chaining() { assert!(parse_token_result.is_err()); } +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr(not(target_arch = "wasm32"), tokio::test)] +pub async fn it_can_be_instantiated_by_cid() { + let identities = Identities::new().await; + let mut did_parser = DidParser::new(SUPPORTED_KEYS); + + let leaf_ucan = UcanBuilder::default() + .issued_by(&identities.alice_key) + .for_audience(identities.bob_did.as_str()) + .with_lifetime(60) + .build() + .unwrap() + .sign() + .await + .unwrap(); + + let delegated_token = UcanBuilder::default() + .issued_by(&identities.bob_key) + .for_audience(identities.mallory_did.as_str()) + .with_lifetime(50) + .witnessed_by(&leaf_ucan) + .build() + .unwrap() + .sign() + .await + .unwrap() + .encode() + .unwrap(); + + let mut store = MemoryStore::default(); + + store + .write_token(&leaf_ucan.encode().unwrap()) + .await + .unwrap(); + + let cid = store.write_token(&delegated_token).await.unwrap(); + + let chain = ProofChain::from_cid(&cid, &mut did_parser, &store) + .await + .unwrap(); + + assert_eq!(chain.ucan().audience(), &identities.mallory_did); + assert_eq!( + chain.proofs().get(0).unwrap().ucan().issuer(), + &identities.alice_did + ); +} + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] #[cfg_attr(not(target_arch = "wasm32"), tokio::test)] pub async fn it_can_handle_multiple_leaves() {