Create > Series > CSV Upload: animation_url is ignored

I am able to mint HTML pages as either a 1 of 1 or Series > Manual Upload via animation_url however, animation_url seems to be ignored when trying to mint via Series > CSV Upload.

Expected Outcome

Please note that I had originally included links to all text in italics below, however, as I am a new user I cannot include more than two links in my post. Would love to share the links as originally intended to make it easier to debug! In place of links, assets can be viewed on OpenSea > Sepolia > Contract 0x9ce0fcc01cb9b04037d8511a0c1db62c903b1c6a. Token numbers for this contract provided below.

Actual Outcome

  • Series > CSV Upload using the CSV below effectively mints the image field (animated GIFs) rather than the animation_url field

    • “snowden-archive” on OpenSea after minting via Series > CSV Upload => token #25
    • “SETUP32.EXE” on OpenSea after minting via Series > CSV Upload => token #26
  • Notice the difference (HTML pages, not animated GIFs):

    • “snowden-archive” on OpenSea after minting via Series > Manual Upload => token #21
    • “SETUP32.EXE” on OpenSea after minting via Series > Manual Upload => token #22
    • “snowden-archive” on OpenSea after minting via 1 of 1 => token #23
    • “SETUP32.EXE” on OpenSea after minting via 1 of 1 => token #24
  • Specifically:

    • “snowden-archive” > tokenUri does not have animation_url key when minted via Series > CSV Upload (token #25)
    • “snowden-archive” > tokenUri does have animation_url key when minted via Series > Manual Upload (token #21)
    • “snowden-archive” > tokenUri does have animation_url key when minted via 1 of 1 (token #23)

To Reproduce

  • Create > Series > CSV Upload
  • Use the following CSV
name,description,created_by,image,animation_url
string,string,string,string,string
"snowden-archive","Testing",Eric Corriel,https://assets.enterthemachine.io/v3/famous-files/thumbnails/square/lg/1.gif,https://arweave.net/Mi9PLAnb4at9Ym8Z_Nm_5QuqAtVRnadOmJz3N0f-uPs
"SETUP32.EXE","Testing",Eric Corriel,https://assets.enterthemachine.io/v3/famous-files/thumbnails/square/lg/2.gif,https://ipfs.io/ipfs/QmUvaeFKus3xsWPFfaxmqyZuYrhM3Y6aFSxd9LVYFSUvGB

In addition…

  • The documentation on creating HTML NFTs says one needs to include animation_details: {"format": "HTML"} however this is no longer necessary as 1 of 1s and Series > Manual Upload HTML NFTs mint just fine without this key. In addition, escaping double quotes in CSV files is tricky (I think it would need to be {"""format""": """HTML"""} which could throw people off. Perhaps consider removing this from the documentation if it’s no longer necessary.

In order for our team to investigate a bug/errors, please provide the following:

  • What is your wallet address? : 0x40132A7Ec3d871c5380003D5BfED2EBb5cc1BCf9
  • A summary of the issue : described above
  • What are you trying to do? : Mint HTML pages via Series > CSV Upload
  • What is the actual outcome? Are you seeing any error messages? : See above, no error messages
  • A screenshot of the issue/error with the console.
  • What browser are you using? : Chrome
  • What wallet are you using? : MetaMask

Thank you!

Found the issue, fix in progress. We were not processing HTML animation_url’s.

Ok, please try again, this should be fixed now

Thanks for the quick response! However, it isn’t quite working. There are a few different issues:

  • animation_url does not come through for CSV entries after the first row
  • animation_url is being transformed on upload. This not how 1 of 1s and Series > Manual Upload work
    • In my CSV I specify animation_url as https://arweave.net/Mi9PLAnb4at9Ym8Z_Nm_5QuqAtVRnadOmJz3N0f-uPs
    • However tokenUri for the minted token returns a completely different Arweave url
  • None of the information (image, title, description) [displays on OpenSea]: testnets[dot]opensea[dot]io/assets/sepolia/0x9ce0fcc01cb9b04037d8511a0c1db62c903b1c6a/30

To reproduce

  • Use the CSV below and check both mints on OpenSea:
name,description,created_by,image,animation_url
string,string,string,string,string
"snowden-archive","Testing","Eric Corriel",https://assets.enterthemachine.io/v3/famous-files/thumbnails/square/lg/1.gif,https://arweave.net/Mi9PLAnb4at9Ym8Z_Nm_5QuqAtVRnadOmJz3N0f-uPs
"SETUP32.EXE","Testing","Eric Corriel",https://assets.enterthemachine.io/v3/famous-files/thumbnails/square/lg/2.gif,https://ipfs.io/ipfs/QmUvaeFKus3xsWPFfaxmqyZuYrhM3Y6aFSxd9LVYFSUvGB

Differences between methods
From what I can tell, there are a few differences between what tokenUri returns depending on how the asset was minted.

  • If minted via Series > CSV Upload there are two additional keys compared to when minted via Series > Manual Upload:
    • animation (in addition to animation_url)
    • animation_details
    • compare this json from generated via CSV upload to this json generated via Series > Manual upload

Happy to help debug further if I can–thank you!

Just wondering whether there’s been any update on this? I recently tested removing animation_url from the CSV above, and in that case, image and description do show up successfully on OpenSea:

name,description,created_by,image
string,string,string,string
"snowden-archive","Testing","Eric Corriel",https://assets.enterthemachine.io/v3/famous-files/thumbnails/square/lg/1.gif
"SETUP32.EXE","Testing","Eric Corriel",https://assets.enterthemachine.io/v3/famous-files/thumbnails/square/lg/2.gif

So it seems something about animation_url alone is changing how the metadata is formed and interpreted by OpenSea…hope that helps and please keep me posted–thx!

Just retested this with the CSV from the original post and now the dialog box has been saying the following for the last hour:

Upload token assets to decentralized storage. Still processing, hold tight…

Note the CSV (from the original post) only contains 2 entries, and animation_url for both of them already store their assets on decentralized storage (Arweave and IPFS). Eventually the request times out and says:

We’re waiting on Arweave to upload your files :hourglass_flowing_sand:

and asks if I want to retry. I click yes and wait another hour or so for the same error message to appear.

Please ignore if this totally misses the mark but if the strategy is to copy all files referenced by animation_url to decentralized storage then I’m not sure this is pragmatic or even possible. Not pragmatic because it’s not uncommon for HTML-based projects created by contemporary web frameworks to create dozens if not hundreds of individual files, like so. Not possible because one could always load files from centralized storage dynamically via JavaScript anyway.

All that said, I’m happy to see some progress is being made! Happy to help debug further or provide more info if I can!

Hi there, we just dug a bit deeper.

We do in fact copy all uploaded file references to arweave. We can’t use the public ipfs node because it blocks us, so we use our own ipfs node provider to access ipfs files for download (in our case, a filebase based node). It appears that filebase is blocking the content you referenced, which is what is ultimately causing the issue. We’re reaching out to the node provider to figure out how to unblock this content and will update the thread once we get a response.

Hey there,

So regarding:

We do in fact copy all uploaded file references to arweave.

I’m not exactly sure what is meant by this and, if I may, have questions about this strategy. Consider the following use cases:


1. Including media files, such as sound

Let’s say my index.html includes audio:

<audio src="my-awesome-audio.mp3"></audio>

Question 1: How would Manifold know to copy my-awesome-audio.mp3? What would be Manifold’s suggestion on how to include audio (or any other standalone media) in one’s web-based NFT project?


2. Contemporary web-based projects

Summary: The vast majority of web developers in 2024 use frameworks that generate dozens of include files that are required for the project to run. How could Manifold possibly know to copy these files?

To illustrate:

  • animation_url normally points to index.html for HTML-based works
  • It is standard these days for index.html to reference dozens include files:
<html>
<head>
	<script src="_nuxt/DK032Xhj.js"></script>
	<script src="_nuxt/B8tSIu8h.js"></script>
	<script src="_nuxt/Cf38bH3o.js"></script>
	<script src="_nuxt/BSHFxmWp.js"></script>
	<script src="_nuxt/D6hqstVr.js"></script>
	<script src="_nuxt/BVC0TJmx.js"></script>
	<script src="_nuxt/DlAUqK2U.js"></script>
	<script src="_nuxt/Dvefj2iM.js"></script>
	<script src="_nuxt/8ka3P6J0.js"></script>
	<script src="_nuxt/DFtmBjkY.js"></script>
	<script src="_nuxt/DV10Np8S.js"></script>
	<script src="_nuxt/S717hTp_.js"></script>
</head>
  • Currently Manifold does not copy these files even though they’re in the same directory (on decentralized storage) as index.html
  • Trying to copy all include files strikes me as potentially highly error prone and unreliable
  • Gone are the days of web-based projects consisting only of index.html. That’s just not how web projects are developed anymore…

Implementation suggestions

OpenSea no longer displays animation_urls that are not stored on decentralized storage. If you supply animation_url: myserver.com/tokens/1/index.html, OS will not render the HTML and will instead show the image field. Here’s an example: testnets[dot]opensea[dot]io[slash]assets[slash]sepolia[slash]0x9ce0fcc01cb9b04037d8511a0c1db62c903b1c6a[slash]1

Suggestion 1
Follow OS’s lead: if animation_url already points to decentralized storage, let it pass through. Only copy animation_url to decentralized storage if it is not already on decentralized storage.

Note: This behavior already exists as Manifold lets animation_url pass through for both Create > 1 of 1 and Create > Series > Manual Upload

Suggestion 2
To allow for the widest range of creative expression in web-based projects, it would seem to me Manifold should take into account the tools contemporary artists in this domain are using (frontend frameworks) and external media files.

To support these tools, Manifold would need to copy every file in manifest.json at animation_url. So if animation_url is:

But that’s a lot of unnecessary copying, especially since the files are on decentralized storage to begin with.

Personally I would opt for Suggestion 1 for ease of implementation, maintainability, and further support of industry standards around NFT asset storage.

Happy to help further in any way I can!

Small note regarding Suggestion 2: in addition copying all files in manifest.json to a new location, Manifold would then need to recreate a new manifest.json in the new location to preserve the relationships between copied files…

FWIW my vote is for letting decentralized animation_urls just pass through…

Will take your notes into consideration. However, our backend makes an assumption that all items are referenced to be copied right now (because many use google drive links, or ipfs links that are not pinned).

We may have a workaround to allow a passthrough if you specify hidden attributes though (which is what we suggest for people who want to inject directly referenced links into the urls)

At the moment, we only copy the top level referenced file to arweave.

Also, our ipfs node provider has unblocked this comment, so you should be able to try again.

wrt ‘hidden attributes’, I am referring to:

This basically overrides the animation_url (or whatever property) with a custom value.

Thanks again for your attention to this issue!

Also, our ipfs node provider has unblocked this comment, so you should be able to try again.

:point_up_2: Confirmed working


Re: the docs, are you referring to the hidden attribute: animation_details: { "format": "HTML" }?

If so, this is very difficult to integrate into CSV files because the double quotes need to be escaped like so:

"value1","value2","{"""format""":"""HTML"""}"

Unfortunately including animation_details in this way via the CSV uploader doesn’t have any effect.

Not wrapping the object in quotes and not escaping the double quotes breaks the uploader AFAIK. The following do not upload:

"value1","value2",{"format":"HTML"}
"value1","value2",{"""format""":"""HTML"""}

I can also confirm (as of 2 wks ago) that both Create > Series > Manual Upload and Create > Series > 1 of 1 do not require animation_details: { "format": "HTML" } in order for animation_url to be “passed through.”

I’m not sure what else to try. Please let me know if I’m missing anything or if there’s anything else I should be looking at. Thank you!

:point_up_2: Just reconfirmed. The other methods let animation_url pass through and do not require animation_details: {"format": "HTML"}.

Is it possible Manifold is applying the “copy top level references” logic to animation_url only for Create > Series > CSV Upload? Maybe this logic is only meant to be applied to image and is mistakingly being applied to animation_url in the CSV workflow?

GM!

Sorry for the delayed in response, we have limited support over the weekend.
We have released a new update which let you format “animation_url” and “format: “HTML”” in the csv.

If you go into the app now, click on “csv upload”. Then choose “Download Template”. Under “Properies”, choose “Hidden” and add your “animation_url”. Do similar thing for “format”.
It will then give you a csv with the proper format and you can fill it in then.

Example csv:

name,description,created_by,image,hidden::animation_url,hidden::animation_details

string,string,string,string,string,string

don dang,daodnawd,qwdqwdqwdqwd,https://photos.onedrive.com/share/A0E809BD1F09982E!183?cid=A0E809BD1F09982E&resId=A0E809BD1F09982E!183&authkey=!ALn_JqMj8sDed2Y&ithint=photo&e=Ai0MfL,https://drive.google.com/file/d/1aZCxnjg6jNkV2a0zkcFlkNKAyDE3RmJx/view,{"format":"HTML"}

don dang,daodnawd,qwdqwdqwdqwd,https://photos.onedrive.com/share/A0E809BD1F09982E!183?cid=A0E809BD1F09982E&resId=A0E809BD1F09982E!183&authkey=!ALn_JqMj8sDed2Y&ithint=photo&e=Ai0MfL,https://drive.google.com/file/d/1aZCxnjg6jNkV2a0zkcFlkNKAyDE3RmJx/view,{"format":"HTML"}

don dang,daodnawd,qwdqwdqwdqwd,https://photos.onedrive.com/share/A0E809BD1F09982E!183?cid=A0E809BD1F09982E&resId=A0E809BD1F09982E!183&authkey=!ALn_JqMj8sDed2Y&ithint=photo&e=Ai0MfL,https://drive.google.com/file/d/1aZCxnjg6jNkV2a0zkcFlkNKAyDE3RmJx/view,{"format":"HTML"}

Please let me know if this works!

:raised_hands: Confirmed working for Arweave and IPFS animation_urls via CSV upload :raised_hands:

Note to anyone who may come across this thread. In my testing, sometimes OpenSea will display image rather than animation_url on initial load. Refreshing the token metadata seems to fix this.

Thanks team!