I'm happy to do so - I just assume everyone else knows more than I do...
Here's what I've found, using Rarible and OpenSeas on Rinkeby for testing:
- The metadata URL in the constructor for ERC721PresetMinterPauserAutoId is accessed by Rarible/OpenSeas, and your implementation would return the following:
- A single JSON object starting with { and ending with }. (not an array of objects)
- An HTTP header with Content-Type: application/json; which in php is achieved with this:
header('Content-Type: application/json;');
Is this only way it can work? I'm not sure, but this does work.
-
Rarible and OpenSeas save the result of hitting that metadata URL, so it will only re-load if you explicitly click on a "refresh metadata" option at their site. It is actually interesting (to me) that the refresh exists at all, but was the key element for me in debugging this... Note that Rarible refresh is synchronous and OpenSeas is asynchronous, so Rarible is easier to use. BTW, the same is true of the asset itself (usually an image), so you can expect Rarible an OpenSeas to have N copies of your original.
-
Note my metadata URL ends in ".......?nftid=" . The token id created by ERC721PresetMinterPauserAutoId (that's the auto part!) is appended to this URL before it is used, so you can distinguish between different tokens, like "....?nftid=99" I use php, and a .php URL works fine.
-
And... this is the most useful thing I learned. You can deploy your contract (it is called ERC721PresetMinterPauserAutoId in the example code, see 2_deploy.js) only once, and then mint as many tokens as you want without deploying again!
At this point, the ERC721PresetMinterPauserAutoId was not useful anymore to me. The autoid function is convienent, but I created my own contract (from the AutoId code) that allows explicit assignment of tokenIds. the AutoId contract has
mint("0x.......")
and my contract adds:
mintWithTokenID("0x......", 774). which has explicit tokenID 774
At that point I could do this with my contract:
truffle(rinkeby)>deploy [uses the same 2_deploy.js, but with my complied contract]
truffle(rinkeby)>nft = await ERC721enclayveItem.deployed()
truffle(rinkeby)>await nft.mintWithTokenID("0x....", 77)
truffle(rinkeby)>await nft.mintWithTokenID("0x....", 78)
truffle(rinkeby)>await nft.mintWithTokenID("0x....", 79)
Which puts three different assets into Rarible and OpenSeas. And... at those systems, all of these assets appear under the same "Collection" in Rarbile/OpenSeas. The "Collection" name comes from the "name" field used in the constructor for the contract in 2_deploy.js
To me, managing my own Token IDs is preferred because I can then assign them in advance (and I can make them distinct easily), so my server-side database of assets can have an nftid field I control. The metadata URL uses the nftid=XXXX, which is a simple lookup in our asset database and returns proper JSON reference to the asset itself.
It's also a little more secure, since the IDs are big long numbers and someone who spams our web site with random IDs (in the metadata URL. "https://.........?nftid=X" where they try every X won't likely find anything. I think the autoid design starts with 0 and counts up, which is pretty exposed. This can be eased with replacing the counter in AutoID contract with a random number, but you still don't know the tokenIDs in advance which (to me) makes everything harder to code in the overall system.
That is, the example code wants you to do this:
truffle(rinkeby)>nft = await ERC721PresetMinterPauserAutoId.deployed()
truffle(rinkeby)>await nft.mint("0x....")
truffle(rinkeby)>await nft.mint("0x....")
truffle(rinkeby)>await nft.mint("0x....")
And I've now minted 3 assets, but I don't know what their tokenIDs are, and then of course I don't know how to look them up in my server's database to generate the actual assert URL, etc. etc, I think you can see where I'm going with this. This minting sequence just doesn't work unless you have a-priori information about the tokenIds (it's a chicken-and-egg problem....)