Skip to content

Latest commit

 

History

History
170 lines (132 loc) · 4.48 KB

0001.md

File metadata and controls

170 lines (132 loc) · 4.48 KB

PLIP-1

Comments

draft mandatory

Posts and replies are both considered plebbit "comments". They are signed by a plebbit author and published to a subplebbit.

For example:

{
  "title": "Why did the banana go to the doctor?",
  "content": "It wasn't peeling well.",
  "subplebbitAddress": "jokes.eth",
  "author": {"address": "john.eth"},
  "timestamp": 1728174027,
  "signature": {
    "signature": <base64>,
    "publicKey": <base64>,
    "type": "ed25519",
    "signedPropertyNames": ["title", "content", "subplebbitAddress", "author", "timestamp"]
  }
}

Required fields are:

  • subplebbitAddress
  • author
  • timestamp
  • signature

Optional fields are:

  • title
  • content
  • link
  • parentCid

Reserved subplebbit fields:

  • depth
  • previousCid
  • postCid

Fetching

Comments can be fetched by their IPFS CID (content ID), for example by going to https://ipfsgateway.xyz/ipfs/ or https://ipfsgateway.xyz/ipfs/QmTFuY58c2w9WofMM9KshjUqNncX7EwDK7pV9TMf7aeg1G

Authors

Signature

Unsigned fields (not included in comment.signature.signedPropertyNames) must be ignored since they could be maliciously added by someone other than the author.

Fields included in comment.signature.signedPropertyNames must not be undefined or null so signature is easier to verify with CBOR.

Subplebbits may add some unsigned fields like comment.depth, comment.previousCid, comment.postCid, etc. these fields must be ignored until validated through commentUpdate.signature and commentUpdate.cid.

Reserved subplebbit fields must not be signed by the comment author or they would cause a collision when the subplebbit tries to overwrite them. The comment author signature would become invalid.

The comment.signature.type "ed25519" algorithm is:

const propertiesToSign = {}
for (const propertyName of comment.signature.signedPropertyNames) {
  if (comment[propertyName] === undefined || comment[propertyName] === null) {
    throw Error('invalid signature')
  }
  propertiesToSign[propertyName] = comment[propertyName]
}
ed25519.verify(
  base64.decode(comment.signature.signature), // signature
  cbor.encode(propertiesToSign), // CBOR encoded data to sign
  base64.decode(comment.signature.publicKey) // public key
)

Uses

Post

A post is like a tweet, a blog post, a reddit post, a facebook post, etc. It may contain comment.title and/or comment.content. It should not contain comment.parentCid.

For example:

{
  "title": "Why did the banana go to the doctor?",
  "content": "It wasn't peeling well.",
  "subplebbitAddress": "jokes.eth",
  "author": {"address": "john.eth"},
  "timestamp": 1728174027,
  "signature": {
    "signature": <base64>,
    "publicKey": <base64>,
    "type": "ed25519",
    "signedPropertyNames": ["title", "content", "subplebbitAddress", "author", "timestamp"]
  }
}

Link post

A link post should contain post.link, which should be an HTTPS link. It may contain comment.title and/or comment.content.

For example:

{
  "title": "Breaking: The Sky Is Falling!",
  "link": "https://cnn.com/the-sky-is-falling.html",
  "subplebbitAddress": "news.eth",
  "author": {"address": "john.eth"},
  "timestamp": 1728174027,
  "signature": {
    "signature": <base64>,
    "publicKey": <base64>,
    "type": "ed25519",
    "signedPropertyNames": ["title", "link", "subplebbitAddress", "author", "timestamp"]
  }
}

Media post

A media post should contain post.link, which should be an HTTPS link to an image file or video file. It may contain comment.title and/or comment.content.

For example:

{
  "title": "This is funny!",
  "link": "https://funny.com/funny-meme.png",
  "subplebbitAddress": "memes.eth",
  "author": {"address": "john.eth"},
  "timestamp": 1728174027,
  "signature": {
    "signature": <base64>,
    "publicKey": <base64>,
    "type": "ed25519",
    "signedPropertyNames": ["title", "link", "subplebbitAddress", "author", "timestamp"]
  }
}

Reply

A reply to a post. It should contain comment.parentCid. It may contain comment.title and/or comment.content.

For example:

{
  "parentCid": "QmXnEICVkZBHKgjtj7Vt63HWq3ZfPjcGTSPs79oXtfEZxc",
  "content": "Very funny.",
  "subplebbitAddress": "jokes.eth",
  "author": {"address": "john.eth"},
  "timestamp": 1728174027,
  "signature": {
    "signature": <base64>,
    "publicKey": <base64>,
    "type": "ed25519",
    "signedPropertyNames": ["parentCid", "content", "subplebbitAddress", "author", "timestamp"]
  }
}