RSS3 v0.3.0

Latest editor's draft:

Editors:

Reviewers

Participate:

1. Abstract

Derived from the best out of RSS, RSS3 is an open protocol designed for all our cyber existence in the era ofโ€‚Web 3.0.

This document describes the interfaces of RSS3 files.

2. Status of This Document

The proposal is being incubated in the NaturalSelectionLabsopen in new window.

GitHubopen in new window issuesopen in new window and discussionsopen in new window are preferred for discussion of this specification.

3. Future Compatibility

This version is a beta version, so it is not guaranteed to be compatible with subsequent versions, but breaking updates will be kept to a minimum.

4. Concepts

  • Persona - a user, either as an individual or as a group
  • Item - An item published or experienced by a persona
  • Link - One type of relationship to other personas/item from current persona/item
  • Backlink - A link from other personas/items to current persona/item
  • Assets - Objects currently owned by the persona

5. Interfaces

5.1 Interfaces in TypeScript

// File ids
type RSS3ID = string; // A 42-character hexadecimal address with 0x appended in front.
type RSS3ItemsID = string; // `${RSS3ID}-items-${index}`
type RSS3ListID = string; // `${RSS3ID}-list-links.${links.type}-${index}`, `${RSS3ID}-list-backlinks.${backlinks.type}-${index}`, `${RSS3ID}-list-assets-${index}`, `${RSS3ID}-list-backlinks.item.${item.index}.${backlinks.type}-${index}`

type RSS3FileID = RSS3ID | RSS3ItemsID | RSS3ListID; // Unique indicate for current file

type RSS3ItemID = string; // `${RSS3ID}-item-${index}`

type ThirdPartyAddress = string[]; // A series of url or ipfs hash that link to an identical file

// Common attributes for each files
interface RSS3Base {
    version: 'rss3.io/version/v0.3.0'; // Proposal version for current file. It should be like `rss3.io/version/v1.0.0`
    id: RSS3FileID;
    date_created: string; // Specifies the created date in RFC 3339 format
    date_updated: string; // Specifies the updated date in RFC 3339 format
}

// Entrance, RSS3 file, indicating a persona
interface RSS3 extends RSS3Base {
    id: RSS3ID;
    signature: string; // Signed by persona's private key; The signature content is the Keccak-256 hash of the array of object sorted by alphabetical and excluding objects containing `auto: true` field and the `signature` field itself(for example {a: "1", c: "2", b: {d: "3"}, e: {auto: true}} -> [["a", "1"], ["b", ["d", "3"]], ["c", "2"]]) or the string `Hi, RSS3. I'm your agent ${agent_id}` if using agent signature; Used for the object integration verification for both server side and persona side
    agent_id?: string; // A random ed25519 public key generated by the client
    agent_signature?: string; // A signature signed by `agent_id`'s private key, its content is the same as `signature`
    controller?: string; // A contract address indicating ownership of the file

    profile?: {
        name?: string;
        avatar?: ThirdPartyAddress;
        bio?: string;

        accounts?: {
            tags?: string[];
            platform: string; // Platform name, for example: EVM+ or Twitter
            identity: string; // Platform identity, for example: 0x1234567890123456789012345678901234567890 or @username
            signature?: string; // Signature of [["address": id], ["identity": account.identity], ["platform", account.platform]], optional for no public-key cryptography platform
        }[];
    };

    items?: RSS3ItemsID;

    links?: {
        tags?: string[];
        type: string; // Link type, for example: follow superfollow
        list?: RSS3ListID; // Personas who belong to this link
    }[];
    backlinks?: { // Backlinks for this persona, for example: follow type of backlink means followers.
        auto: true;
        type: string; // The same as links.type
        list: RSS3ListID; // File ID of backlink list that belong to this type. See **RSS3List** for more details
    }[];

    assets?: RSS3ListID;
}

// RSS3Items file, used for pagination of RSS3 files
interface RSS3Items extends RSS3Base {
    id: RSS3ItemsID;
    signature: string;
    agent_id?: string;
    agent_signature?: string;

    items: RSS3Item[]; // List of items
    items_next?: RSS3ItemsID; // Next page of items
}

// RSS3List file, used for pagination of links and contexts
interface RSS3List extends RSS3Base {
    id: RSS3ListID;

    list?: RSS3ID[] | RSS3ItemID[] | RSS3Asset[];
    list_next?: RSS3ListID;
}

// Asset
type RSS3Asset = RSS3UserAsset | RSS3NodeAsset;

interface RSS3NodeAsset {
    auto: true;
    platform: string; // Corresponding to profile.accounts.platform
    identity: string; // Corresponding to profile.accounts.identity
    id: string; // Unique asset ID
    type: string; // Asset type, for example: Ethereum-NFT xDai-POAP
}

interface RSS3UserAsset {
    tags?: string[];
    platform: 'custom'; // Corresponding to profile.accounts.platform
    identity: string; // Corresponding to profile.accounts.identity
    id: string; // Unique asset ID
    type: string; // Asset type, for example: Ethereum-NFT xDai-POAP
}

// Item
type RSS3Item = RSS3UserItem | RSS3NodeItem;

interface RSS3ItemBase {
    id: RSS3ItemID;
    date_published: string; // Specifies the published date in RFC 3339 format
    date_modified: string; // Specifies the modified date in RFC 3339 format

    backlinks?: { // Interactive items from other personas.
        auto: true;
        type: string;
        list: RSS3ListID; // File ID of items list that belong to this context. See **RSS3List** for more details
    }[];
}

// A type of content posted by persona itself
interface RSS3UserItem extends RSS3ItemBase {
    tags?: string[];
    authors?: RSS3ID[];
    title?: string;
    summary?: string;

    link?: {
        type: string; // Link type for the non-original item, for example: comment like
        target: RSS3ItemID; // Target of the non-original item
    }

    contents?: { // Contents of current item, possibly multiple different types of content
        tags?: string[];
        address: ThirdPartyAddress;
        mime_type: string; // [MIME type](https://en.wikipedia.org/wiki/Media_type) of current content
        name?: string;
        size_in_bytes?: string;
        duration_in_seconds?: string;
    }[];
}

// A type of content that is automatically generated by a node to represent a change of an asset
interface RSS3NodeItem extends RSS3ItemBase {
    auto: true;
    account_platform: string; // Corresponding to profile.accounts.platform
    account_identity: string; // Corresponding to profile.accounts.identity
    asset_id: string; // Corresponding to asset.id
    asset_type: string; // Corresponding to asset.type
    asset_action: {
        type: string;
        target?: string;
    };
}

5.2 Fields

Objects with this auto field

  • Entirely the responsibility of the hosting program
  • May be modified by the hosting program at any time
  • Not allowed to be modified by the persona
  • Excluded when calculating signatures

Extensions

Custom objects can be used in RSS3. Names must start with an _ character. Custom objects can appear anywhere in RSS3.

Empty contents

It is strongly recommended to delete fields with empty contents, including empty strings, empty arrays, empty objects

5.3 Examples

A persona 0x1234567890123456789012345678901234567890 with a published item Hello World and a comment to it

# Index file
{
    "version": "rss3.io/version/v0.3.0",
    "id": "0x1234567890123456789012345678901234567890",
    "date_created": "2021-01-01T00:00:00.000Z",
    "date_updated": "2021-01-01T00:00:00.000Z",
    "signature": "0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",

    "profile": {
        "name": "RSS3",
        "avatar": ["https://example.com/rss3.jpg", "QmT1zZNHvXxdTzHesfEdvFjMPvw536Ltbup7B4ijGVib7t"],
        "bio": "RSS3 is an open protocol designed for all our cyber existence in the era ofโ€‚Web 3.0.",

        "accounts": [{
            "platform": "EVM+",
            "identity": "0x1111111111111111111111111111111111111111",
            "signature": "0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
        }]
    },

    "items": "0x1234567890123456789012345678901234567890-items-0",

    "links": [{
        "type": "follow",
        "list": "0x1234567890123456789012345678901234567890-list-links.follow-0",
    }],
    "backlinks": [{
        "auto": true,
        "type": "follow",
        "list": "0x1234567890123456789012345678901234567890-list-backlinks.follow-0",
    }],

    "assets": "0x1234567890123456789012345678901234567890-list-assets-0"
}

# Items file
{
    "version": "rss3.io/version/v0.3.0",
    "id": "0x1234567890123456789012345678901234567890-items-0",
    "date_created": "2021-01-01T00:00:00.000Z",
    "date_updated": "2021-01-01T00:00:00.000Z",
    "signature": "0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",

    "items": [{
        "auto": true,
        "id": "0x1234567890123456789012345678901234567890-item-2",
        "date_published": "2021-01-01T00:00:00.000Z",
        "date_modified": "2021-01-01T00:00:00.000Z",

        "account_platform": "EVM+",
        "account_identity": "0x1111111111111111111111111111111111111111",
        "asset_id": "id0",
        "asset_type": "Ethereum-NFT",
        "asset_action": {
            "type": "transfer-to",
            "target": "0x2222222222222222222222222222222222222222"
        },

        "backlinks": [{
            "auto": true,
            "type": "comment",
            "list": "0x1234567890123456789012345678901234567890-list-backlinks.item.2.comment-0"
        }]
    }, {
        "id": "0x1234567890123456789012345678901234567890-item-1",
        "summary": "Yes!!",
        "date_published": "2021-01-01T00:00:00.000Z",
        "date_modified": "2021-01-01T00:00:00.000Z",

        "link": {
            "type": "comment",
            "target": "0x1234567890123456789012345678901234567890-item-0"
        },
    }, {
        "id": "0x1234567890123456789012345678901234567890-item-0",
        "title": "Hello World",
        "summary": "Hello, this is the first item of RSS3.",
        "date_published": "2021-01-01T00:00:00.000Z",
        "date_modified": "2021-01-01T00:00:00.000Z",

        "contents": [{
            "address": ["https://example.com/rss3.jpg"],
            "mime_type": "image/jpeg"
        }],

        "backlinks": [{
            "auto": true,
            "type": "comment",
            "list": "0x1234567890123456789012345678901234567890-list-backlinks.item.0.comment-0"
        }]
    }]
}

# Link list file
{
    "version": "rss3.io/version/v0.3.0",
    "id": "0x1234567890123456789012345678901234567890-list-links.follow-0",
    "date_created": "2021-01-01T00:00:00.000Z",
    "date_updated": "2021-01-01T00:00:00.000Z",

    "list": ["0x1111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222"]
}

# Assets list file
{
    "version": "rss3.io/version/v0.3.0",
    "id": "0x1234567890123456789012345678901234567890-list-assets-0",
    "date_created": "2021-01-01T00:00:00.000Z",
    "date_updated": "2021-01-01T00:00:00.000Z",

    "list": [{
        "platform": "EVM+",
        "identity": "0x1234567890123456789012345678901234567890",
        "id": "0xacbe98efe2d4d103e221e04c76d7c55db15c8e89-5",
        "type": "Ethereum-NFT"
    }]
}