# Schema

[Reference Implementation](https://github.com/autism-org/ui/blob/main/src/util/message.ts)<br>

Every activity performed by a user can be described as a message with the follow schema:

**Message**

```json
{  
    id: STRING[255],  
    type: STRING[15],  
    subtype: STRING[15],  
    creator: STRING[65535],  
    createdAt: UINT64,  
    payload: OBJECT, // Depends on message type  
}  
```

| Name      |       Type      |                                                                           Description |
| --------- | :-------------: | ------------------------------------------------------------------------------------: |
| id        |  `STRING[255]`  | Unique message ID based on the content hash of the message. See “Message ID” section. |
| type      |   `STRING[15]`  |                               Main type describing the primary purpose of the message |
| subtype   |   `STRING[15]`  |                              Sub type describing the secondary purpose of the message |
| creator   | `STRING[65535]` |                         Domain names of the creator (e.g. bob.eth, alice.crypto, etc) |
| createdAt |     `UINT64`    |                             Unix timestamp in seconds of when the message was created |
| payload   |     `OBJECT`    |                                   Schema containing data of a message depends on type |

**Message ID**

We should hex-encode the message based on the following pseudo code in order to create a deterministic SHA256 hash.

```js
const type = hexString(message.type.toUpperCase()); // e.g. "POST" -> 504f5354  
const subtype = hexString(message.subtype.toUpperCase());  
const creator = hexString(message.creator); // ETH address
const createdAt = hexUint32(message.createdAt); // e.g. 1624773198 -> 60D8124E  
const payload = hex(message.payload); // hex order based on message types  
const encode = [  
  uint8len(hash), hash, // "POST" -> 504f5354 -> 8504f5354  
  uint8len(subtype), subtype, // "" -> "" -> 0  
  uint16len(creator), creator, // "bob.eth" -> 626f622e657468 -> 000e626f622e657468  
  createdAt, // 1624780498 -> 0000000060d82ed2  
  payload  
].join('');  
  
const messageHash = crypto.createHash('sha256').update(encode).digest('hex');  
const messageId = creator + '/' + messageHash; // e.g. 0x1234...7890/42740f20aed483b69701a55ab295a2ed  
```

A message can be used to described user activities such as a post, comment, likes, and follow.

**Profile Message**

The PROFILE type is used to support adding profile data to a name.

```json
{  
	type: "PROFILE",  
	subtype: "NICKNAME" | "BIO" | "PROFILE_IMAGE",  
	payload: { 
		value: STRING[255],
	}  
}  
```

| Name  |      Type     |               Description |
| ----- | :-----------: | ------------------------: |
| value | `STRING[255]` | value of the profile data |

```json
{  
	type: "PROFILE",  
	subtype: "CUSTOM",  
	payload: {  
		key: STRING[255],  
		value: STRING[16777215]  
	}  
}  
```

| Name  |        Type        |                  Description |
| ----- | :----------------: | ---------------------------: |
| key   |    `STRING[255]`   |   Custom key of profile data |
| value | `STRING[16777215]` | Custom value of profile data |

**Post Message**

The POST type is used to support posts (similar to tweets, status update, etc), comments, and reposts.

```json
{  
	type: "POST",  
	subtype: "" | "REPLY" | "REPOST",  
	payload: {  
		topic: STRING[255],  
		title: STRING[255],  
		content: STRING[16777215],  
		reference: STRING[255],  
		attachment: STRING[255]  
	}  
}  
```

| Name       |        Type        |                                                  Description |
| ---------- | :----------------: | -----------------------------------------------------------: |
| topic      |    `STRING[255]`   | Topic of the post for ease of discovery. (e.g. sports, news) |
| title      |    `STRING[255]`   |                  Plain text containing the title of the Post |
| content    | `STRING[16777215]` |                 Markdown text containing content of the Post |
| attachment |    `STRING[255]`   |       url or file message hash being attached to the message |
| reference  |    `STRING[255]`   |                                         post being reference |

**File Message**

The File type is used to support adding file to a name

```json
{  
	type: "FILE",  
	subtype: "TORRENT",  
	payload: {  
		name: STRING[255],  
		mimeType: STRING[255],  
		data: STRING[16777215]  
	}  
}
```

| Name     |        Type        |               Description |
| -------- | :----------------: | ------------------------: |
| name     |    `STRING[255]`   |                 File name |
| mimeType |    `STRING[255]`   |    Mime types of the file |
| data     | `STRING[16777215]` | magnetURI for the torrent |

```json
{  
	type: "FILE",  
	subtype: "IPFS",  
	payload: {  
		name: STRING[255],  
		mimeType: STRING[255],  
		data: STRING[16777215]  
	}  
}
```

| Name     |        Type        |            Description |
| -------- | :----------------: | ---------------------: |
| name     |    `STRING[255]`   |              File name |
| mimeType |    `STRING[255]`   | Mime types of the file |
| data     | `STRING[16777215]` | ipfs hash for the file |

**Moderation Message**

The MODERATION type is used to support moderation activities, such as a LIKE, UPVOTE, DOWNVOTE, BAN, etc.

```json
{  
	type: "MODERATION",  
	subtype: "LIKE" | "BLOCK",  
	payload: {  
		reference: STRING[255]  
	}  
}  
```

<table><thead><tr><th>Name</th><th align="center">Type</th><th align="right">Description</th></tr></thead><tbody><tr><td><pre><code>reference
</code></pre></td><td align="center"><code>STRING[255]</code></td><td align="right">hash of the message receiving the moderation</td></tr></tbody></table>

**Connection Message**

The CONNECTION type is used to support follows and other types of links between names.

```json
{  
	type: "CONNECTION",  
	subtype: "FOLLOW" | "BLOCK",  
	payload: {  
		name: STRING[65535]  
	}  
}  
```

| Name |       Type      |                                                              Description |
| ---- | :-------------: | -----------------------------------------------------------------------: |
| name | `STRING[65535]` | Domain names of the one being followed (e.g. bob.eth, alice.crypto, etc) |
