diff --git a/clients/js/test/revokeCollectionV1.test.ts b/clients/js/test/revokeCollectionV1.test.ts index 5060c33d..7e7ba7d1 100644 --- a/clients/js/test/revokeCollectionV1.test.ts +++ b/clients/js/test/revokeCollectionV1.test.ts @@ -49,3 +49,41 @@ NON_EDITION_TOKEN_STANDARDS.forEach((tokenStandard) => { t.false(await umi.rpc.accountExists(metadataDelegateRecord)); }); }); + +NON_EDITION_TOKEN_STANDARDS.forEach((tokenStandard) => { + test(`it can self-revoke a collection delegate for a ${tokenStandard}`, async (t) => { + // Given an asset with an approved collection delegate. + const umi = await createUmi(); + const updateAuthority = generateSigner(umi); + const { publicKey: mint } = await createDigitalAssetWithToken(umi, { + authority: updateAuthority, + tokenStandard: TokenStandard[tokenStandard], + }); + const collectionDelegate = generateSigner(umi); + await delegateCollectionV1(umi, { + mint, + authority: updateAuthority, + delegate: collectionDelegate.publicKey, + tokenStandard: TokenStandard[tokenStandard], + }).sendAndConfirm(umi); + const [metadataDelegateRecord] = findMetadataDelegateRecordPda(umi, { + mint, + delegateRole: MetadataDelegateRole.Collection, + delegate: collectionDelegate.publicKey, + updateAuthority: updateAuthority.publicKey, + }); + t.true(await umi.rpc.accountExists(metadataDelegateRecord)); + + // When we revoke the collection delegate. + await revokeCollectionV1(umi, { + mint, + authority: collectionDelegate, + updateAuthority: updateAuthority.publicKey, + delegate: collectionDelegate.publicKey, + tokenStandard: TokenStandard[tokenStandard], + }).sendAndConfirm(umi); + + // Then the metadata delegate record was deleted. + t.false(await umi.rpc.accountExists(metadataDelegateRecord)); + }); +}); diff --git a/programs/token-metadata/program/src/processor/delegate/revoke.rs b/programs/token-metadata/program/src/processor/delegate/revoke.rs index c2fa5973..454c1ba0 100644 --- a/programs/token-metadata/program/src/processor/delegate/revoke.rs +++ b/programs/token-metadata/program/src/processor/delegate/revoke.rs @@ -195,21 +195,21 @@ fn get_delegate_record_update_authority( delegate_record_info: &AccountInfo, authority: &Pubkey, ) -> Result { - let delegate_record_update_authority = match delegate_scenario { + let (delegate, delegate_record_update_authority) = match delegate_scenario { DelegateScenario::Metadata(_) => { - MetadataDelegateRecord::from_account_info(delegate_record_info) - .map_err(|_| MetadataError::DelegateNotFound)? - .update_authority + let record = MetadataDelegateRecord::from_account_info(delegate_record_info) + .map_err(|_| MetadataError::DelegateNotFound)?; + (record.delegate, record.update_authority) } DelegateScenario::Holder(_) => { - HolderDelegateRecord::from_account_info(delegate_record_info) - .map_err(|_| MetadataError::DelegateNotFound)? - .update_authority + let record = HolderDelegateRecord::from_account_info(delegate_record_info) + .map_err(|_| MetadataError::DelegateNotFound)?; + (record.delegate, record.update_authority) } _ => return Err(MetadataError::InvalidDelegateRole.into()), }; - if cmp_pubkeys(&delegate_record_update_authority, authority) { + if cmp_pubkeys(&delegate, authority) { Ok(delegate_record_update_authority) } else { Err(MetadataError::InvalidDelegate.into())