Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: store metadata in IPLD CBOR format #50

Closed
wants to merge 1 commit into from
Closed

Conversation

alanshaw
Copy link
Contributor

@alanshaw alanshaw commented Mar 30, 2021

This PR adds a storeMetadata method that allows for storing NFT metadata encoded using IPLD CBOR.

It takes an Object - the metadata to persist. It recursively inspects the object to see if there are any Files or Blobs and when it find them it calls storeBlob/storeDirectory and replaces them with a CID.

The result is an object that we can pass to js-dag-cbor for encoding.

I need to figure out how to store the encoded data. I've just passed it to storeBlob, which gives us back a CID with the RAW codec (since it's small enough and we specify v1 CIDs, giving us raw leaves). In the code I'm taking this RAW CID and re-encoding it to be CBOR. I thought this would work but it looks like the blockstore is still keyed on CID not multihash...

The plan was to then be able to view this on the gateway: ipfs/kubo#8037

I'm using this code to test (runnable in Node.js):

import fs from 'fs'
import { NFTStorage, File } from '../../src/lib.js'

const endpoint = 'https://staging.nft.storage'
const token = 'xxx'

async function main() {
  const store = new NFTStorage({ endpoint, token })
  const data = await fs.promises.readFile('lost-dog.jpg')
  const cid = await store.storeMetadata({
    name: 'My NFT',
    image: new File([data], 'lost-dog.jpg')
  })
  console.log({ cid })
}
main()

@alanshaw alanshaw requested a review from Gozala March 30, 2021 11:43
const cid = await NFTStorage.storeBlob(service, new Blob([cbor.encode(metadata)]))
console.log(cid)
const mh = CID.parse(cid).multihash
return CID.createV1(cbor.code, mh).toString()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is cool! I was thinking of doing something slightly different that is:

  1. Create a content bundle like a car file so that
  2. It would inline all the files
  3. A JSON serialization written as metadata.json
  4. A dag-cbor with pointers to all of the above (kind of like you do here)

Then we could turn return value into:

{
   cid: CIDString // CID to the cbor with links to everything
   jsonURL: URL // ipfs://${cid} URL to a metadata.json
   data: JSON // JSON that written as `metadata.json`
}

That way:

  1. Single NFT will correspond to single dag-cbor with links to all the relevant files and encoding al data.
  2. We don't force IPLD, JSON representation of it is still there.
  3. We do also proactively make things IPLD native, and lay the upgrade path to folks that want to.
  4. Since we have all the data locally anyway, we include that in data so that URLs for all the files can be pulled out without another roundtrip.

@alanshaw
Copy link
Contributor Author

alanshaw commented Apr 6, 2021

closing in favour of #56

@alanshaw alanshaw closed this Apr 6, 2021
@alanshaw alanshaw deleted the feat/storeMetadata branch April 6, 2021 08:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants