diff --git a/cadence/contracts/bridge/FlowEVMBridgeResolver.cdc b/cadence/contracts/bridge/FlowEVMBridgeResolver.cdc index 8e99e6e0..fc1ee851 100644 --- a/cadence/contracts/bridge/FlowEVMBridgeResolver.cdc +++ b/cadence/contracts/bridge/FlowEVMBridgeResolver.cdc @@ -113,6 +113,42 @@ access(all) contract FlowEVMBridgeResolver { return nil } + /// Builds a thumbnail file based on the provided thumbnail file type identifier and optional IPFS file path + /// + /// @param thumbnailURI: The URI of the thumbnail file + /// @param thumbnailFileTypeIdentifier: The type identifier of the thumbnail file + /// @param ipfsFilePath: The optional IPFS file path if the thumbnail file is an IPFS file and has a path + /// + /// @returns The built thumbnail file + /// + access(all) + view fun buildFile(uri: String, fileType: Type, ipfsFilePath: String?): {MetadataViews.File}? { + switch fileType { + case Type(): + return MetadataViews.HTTPFile(url: uri) + case Type(): + return MetadataViews.IPFSFile(cid: uri, path: ipfsFilePath) + default: + return nil + } + } + + /// Builds a dictionary of ExternalURL views from a dictionary of URLs, helpful for creating a socials dictionary + /// + /// @param fromDict: The dictionary of URLs to convert + /// + /// @returns The dictionary of ExternalURL views + /// + access(all) + view fun buildExternalURLMapping(fromDict: {String: String}): {String: MetadataViews.ExternalURL} { + let res: {String: MetadataViews.ExternalURL} = {} + for key in fromDict.keys { + res[key] = MetadataViews.ExternalURL(fromDict[key]!) + } + return res + } + + /***************** Constructs *****************/ diff --git a/cadence/transactions/bridge/admin/metadata/set_bridged_ft_display_view.cdc b/cadence/transactions/bridge/admin/metadata/set_bridged_ft_display_view.cdc index cf61bd48..ab5cf06b 100644 --- a/cadence/transactions/bridge/admin/metadata/set_bridged_ft_display_view.cdc +++ b/cadence/transactions/bridge/admin/metadata/set_bridged_ft_display_view.cdc @@ -3,34 +3,6 @@ import "FungibleTokenMetadataViews" import "FlowEVMBridgeResolver" -/// Builds a thumbnail file based on the provided thumbnail file type identifier and optional IPFS file path -/// -access(all) -fun buildFile(_ uri: String, _ fileTypeIdentifier: String, _ ipfsFilePath: String?): {MetadataViews.File} { - // Determine the inteded File type based on the provided file type identifier - let thumbnailFileType = CompositeType(fileTypeIdentifier) - ?? panic("Invalid file type identifier=".concat(fileTypeIdentifier)) - - // Build the thumbnail file based on the determined file type - if thumbnailFileType == Type() { - return MetadataViews.HTTPFile(url: uri) - } else if thumbnailFileType == Type() { - return MetadataViews.IPFSFile(cid: uri, path: ipfsFilePath) - } else { - panic("Unsupported file type=".concat(fileTypeIdentifier)) - } -} - -access(all) -fun buildSocials(_ socials: {String: String}): {String: MetadataViews.ExternalURL} { - let res: {String: MetadataViews.ExternalURL} = {} - socials.forEachKey(fun (key: String): Bool { - res[key] = MetadataViews.ExternalURL(socials[key]!) - return true - }) - return res -} - /// This transaction sets the bridged FTDisplay view for all fungible tokens bridged from Flow EVM /// transaction( @@ -46,12 +18,20 @@ transaction( let admin: auth(FlowEVMBridgeResolver.Metadata) &FlowEVMBridgeResolver.Admin prepare(signer: auth(BorrowValue) &Account) { + // Determine the inteded File type based on the provided file type identifier + let fileType = CompositeType(logoFileTypeIdentifier) + ?? panic("Invalid file type identifier=".concat(logoFileTypeIdentifier)) + let file = FlowEVMBridgeResolver.buildFile( + uri: logoURI, + fileType: fileType, + ipfsFilePath: logoIPFSFilePath + ) ?? panic("Failed to build file") let logo = MetadataViews.Media( - file: buildFile(logoURI, logoFileTypeIdentifier, logoIPFSFilePath), + file: file, mediaType: logoMediaType ) let logos = MetadataViews.Medias([logo]) - let socials = buildSocials(socialsDict) + let socials = FlowEVMBridgeResolver.buildExternalURLMapping(fromDict: socialsDict) self.ftDisplay = FungibleTokenMetadataViews.FTDisplay( name: "This name is replaced by a bridged token's name", symbol: "This symbol is replaced by a bridged token's symbol", diff --git a/cadence/transactions/bridge/admin/metadata/set_bridged_nft_collection_display_view.cdc b/cadence/transactions/bridge/admin/metadata/set_bridged_nft_collection_display_view.cdc index 42cead5c..66c160af 100644 --- a/cadence/transactions/bridge/admin/metadata/set_bridged_nft_collection_display_view.cdc +++ b/cadence/transactions/bridge/admin/metadata/set_bridged_nft_collection_display_view.cdc @@ -2,36 +2,6 @@ import "MetadataViews" import "FlowEVMBridgeResolver" -/// Builds a thumbnail file based on the provided thumbnail file type identifier and optional IPFS file path -/// -access(all) -fun buildFile(_ uri: String, _ fileTypeIdentifier: String, _ ipfsFilePath: String?): {MetadataViews.File} { - // Determine the inteded File type based on the provided file type identifier - let thumbnailFileType = CompositeType(fileTypeIdentifier) - ?? panic("Invalid file type identifier=".concat(fileTypeIdentifier)) - - // Build the thumbnail file based on the determined file type - if thumbnailFileType == Type() { - return MetadataViews.HTTPFile(url: uri) - } else if thumbnailFileType == Type() { - return MetadataViews.IPFSFile(cid: uri, path: ipfsFilePath) - } else { - panic("Unsupported file type=".concat(fileTypeIdentifier)) - } -} - -/// Builds a socials dictionary based on the provided socials dictionary as a string to string mapping -/// -access(all) -fun buildSocials(_ socials: {String: String}): {String: MetadataViews.ExternalURL} { - let res: {String: MetadataViews.ExternalURL} = {} - socials.forEachKey(fun (key: String): Bool { - res[key] = MetadataViews.ExternalURL(socials[key]!) - return true - }) - return res -} - /// This transaction sets the bridged NFTCollectionDisplay view for all NFTs bridged from Flow EVM /// transaction( @@ -51,24 +21,34 @@ transaction( let admin: auth(FlowEVMBridgeResolver.Metadata) &FlowEVMBridgeResolver.Admin prepare(signer: auth(BorrowValue) &Account) { - let squareImage = MetadataViews.Media( - file: buildFile(squareImageURI, squareImageFileTypeIdentifier, squareImageIPFSFilePath), - mediaType: squareImageMediaType - ) - let bannerImage = MetadataViews.Media( - file: buildFile(bannerImageURI, bannerImageFileTypeIdentifier, bannerImageIPFSFilePath), - mediaType: bannerImageMediaType - ) - let socials = buildSocials(socialsDict) + // Build the square and banner image files + let squareImageileType = CompositeType(squareImageFileTypeIdentifier) + ?? panic("Invalid file type identifier=".concat(squareImageFileTypeIdentifier)) + let bannerImageFileType = CompositeType(bannerImageFileTypeIdentifier) + ?? panic("Invalid file type identifier=".concat(bannerImageFileTypeIdentifier)) + let squareImageFile = FlowEVMBridgeResolver.buildFile( + uri: squareImageURI, + fileType: squareImageileType, + ipfsFilePath: squareImageIPFSFilePath + ) ?? panic("Failed to build square image file") + let bannerImageFile = FlowEVMBridgeResolver.buildFile( + uri: bannerImageURI, + fileType: bannerImageFileType, + ipfsFilePath: bannerImageIPFSFilePath + ) ?? panic("Failed to build banner image file") + // Build the socials dictionary + let socials = FlowEVMBridgeResolver.buildExternalURLMapping(fromDict: socialsDict) + // Build the NFTCollectionDisplay view self.nftCollectionDisplay = MetadataViews.NFTCollectionDisplay( name: "This name is replaced by a bridged NFT's collection name", description: "This description is replaced by a bridged NFT's collection description", externalURL: MetadataViews.ExternalURL(externalURL), - squareImage: squareImage, - bannerImage: bannerImage, + squareImage: MetadataViews.Media(file: squareImageFile, mediaType: squareImageMediaType), + bannerImage: MetadataViews.Media(file: bannerImageFile, mediaType: squareImageMediaType), socials: socials ) + // Borrow the Admin resource self.admin = signer.storage.borrow( from: FlowEVMBridgeResolver.AdminStoragePath ) ?? panic("Missing or mis-typed Admin resource")