# 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) |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.zkitter.com/developers/data/schema.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
