this.me 2.9.4 → 2.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,132 +1,258 @@
1
- <img src="https://suign.github.io/assets/imgs/Cleaker-removebg-preview.png" alt="Cleak Me Please." width="244">
1
+ <img src="https://docs.neurons.me/media/all-this/webP/this.me.webp" alt="SVG Image" width="250" height="250">
2
2
 
3
3
  # THIS.ME
4
- **This.Me** is a data-structured identity.
5
- <img src="https://suign.github.io/assets/imgs/point.png" alt="Me" width="144"> Consider **.me** as a point.
4
+ > **This.Me** is a data-structured identity designed to generate and manage identities, attributes, properties and more. It combines privacy, user control, and secure interoperability.
6
5
 
7
- this.me is designed to generate and manage identities. It's responsible for creating a user’s identity, handling attributes, and generating hashes.
6
+ **.me** is a local, encrypted identity object designed to return ownership of identity back to the user. Its core philosophy is **user sovereignty**: your identity lives on your machine, under your control, not in someone else’s cloud. It holds attributes, relationships, and keys that define who you are—and crucially, **how you relate to others**.
8
7
 
9
- Use Case: Suppose you're building an app where users need to create profiles or identities. You can install this.me locally in that project to manage user identities.
8
+ Each **.me** instance can pair with other authorities or identities using its **cryptographic keys**, establishing **trust through signatures and endorsements** rather than centralized verification. Instead of logging in through third-party services, you can validate your identity or vouch for someone else’s using these key exchanges. This enables a decentralized trust model where relationships are verifiable, persistent, and portable—empowering systems to recognize who you are based on real, user-generated signals, not institutional permissions.
10
9
 
11
- 1. ### **Install `this.me`:**
10
+ # Getting Started:
11
+ 1. ##### **Install `this.me`:**
12
12
  Open your terminal and run the following command to install the `this.me` package:
13
13
  ```js
14
- npm install this.me
14
+ npm i -g this.me
15
15
  ```
16
-
17
- 2. ### **Import `Me` in Your Project:**
18
- In the JavaScript file where you want to use `this.me`, import the `Me` class.
19
- ```js
20
- import Me from 'this.me';
21
- ```
22
-
23
- **Explanation**
24
- ​ • The **be** method in the **Me** class accepts an object of **key-value pairs** and **adds these to the identity object**.
25
- ​ • You can call **me.be()** multiple times with different attributes to dynamically update the identity object.
26
-
27
- ```javascript
28
- // Create a new Me instance
29
- let me = new Me("xyxyxy");
30
-
31
- // Add attributes to the identity
32
- me.be({ a: "XXX", b: "YYY" });
33
- me.be({ c: "z" });
16
+
17
+ 2. **Run this command on your terminal:**
18
+
19
+ ```bash
20
+ me
34
21
  ```
35
22
 
36
- **A less abstract example:**
23
+ The **Me** class represents a **persistent identity**, stored as an encrypted file (username.me) in ~/.this/me. This file contains:
37
24
 
38
- ```js
39
- // Add attributes to the identity
40
- me.be({ name: "Alice", phone: "33550000" });
41
- ```
25
+ - An identifier (username)
26
+ - Keys (private/public currently placeholders)
27
+ - User-defined attributes
28
+ - Relationships and other social elements (reactions, attributies, properties, endorsements...)
42
29
 
43
- **1. Registry as a Service:**
30
+ It can be **created**, **read** (if you have the correct hash), **modified in memory**, and then **saved again** in encrypted form.
44
31
 
45
- The registry becomes a centralized service hosted by an authority (e.g., neurons.me).
32
+ # Command Line Options:
46
33
 
47
- This service would handle the verification and management of all Me instances across the network.
34
+ ### **me create**
48
35
 
49
- **Example Flow:**
36
+ - **Description**: Creates a new .me identity.
37
+ - **Flow**: Prompts for username and hash (secret key), then saves an encrypted file at ~/.this/me/username.me.
50
38
 
51
- 1. **Setup**: A developer installs this.me and configures it to connect to neurons.me.
39
+ ------
52
40
 
53
- 2. **User Registration**: Users register their Me identity through the service, and the library connects to the neurons.me registry for verification.
41
+ ### **me show [username]**
54
42
 
55
- 3. **Service Interaction**: When a user interacts with a service that uses this.me, the service can trust the identity by querying the selected registry.
43
+ - **Description**: Shows the decrypted contents of an identity.
44
+ - **Flow**:
45
+ - If [username] is not provided, it prompts for it.
46
+ - Always prompts for the hash to unlock the identity.
47
+ - If successful, prints the identity as JSON.
56
48
 
57
- **Implementation:**
49
+ ------
50
+
51
+ ### **me list**
52
+
53
+ - **Description**: Lists all local .me identities.
54
+ - **Flow**: Reads the ~/.this/me directory and prints all .me files (usernames).
55
+
56
+ ------
57
+
58
+ # **Me Class Constructor**
58
59
 
59
- ```js
60
- import Me from 'this.me';
61
- const config = {
62
- registryURL: 'https://registry.neurons.me', // Registry authority URL
63
- };
64
- let me = new Me('alice', config);
65
- me.register({ password: 'securePass123', email: 'alice@example.com' });
66
- // Verify and interact with services using the connected registry
60
+ ```
61
+ constructor(username)
67
62
  ```
68
63
 
64
+ Initializes:
69
65
 
66
+ - this.username: the username
67
+ - this.filePath: path to the encrypted file (/Users/youruser/.this/me/username.me)
68
+ - this.unlocked: whether the identity is unlocked in memory (RAM)
69
+ - this.data: decrypted content (attributes, keys, relationships)
70
70
 
71
- --------
72
- <img src="https://suign.github.io/assets/imgs/monads.png" alt="Cleak Me Please" width="244">Hello, I am **.me**
71
+ > It doesn’t load anything yet—just defines the path and initial state.
73
72
 
74
- ### ❯ add.me
75
- ----
73
+ ------
76
74
 
77
- ###### Using the CLI and this.me globally to manage user sessions.
75
+ ### **save(hash)**
78
76
 
79
- ```bash
80
- npm i -g this.me
77
+ ```
78
+ save(hash)
81
79
  ```
82
80
 
81
+ - Encrypts this.data using AES-256-CBC.
82
+ - Uses a random iv and a key derived from the hash (acting like a passphrase).
83
+ - Saves the file as: iv + encryptedBuffer.
83
84
 
84
- ### Neural Networks - **One-Hot Encoding**
85
- --------
86
- To represent the combinations of **“me, you, him, her, it, us, them”** in a neural network, we need to convert the elements into a suitable format for neural network processing, such as one-hot encoding, and design a neural network architecture that can process these inputs.
85
+ > ⚠️ Throws an error if this.data is not set.
87
86
 
88
- Here’s a step-by-step approach to achieve this:
89
- 1. **One-Hot Encoding:** Convert each element (“me”, “you”, “him”, “her”, “it”, “us”, “them”) into a one-hot encoded vector.
90
- 2. **Combination Representation:** Create input vectors for each combination by combining the one-hot encoded vectors.
91
- 3. **Neural Network Design:** Design a simple neural network to process these input vectors.
87
+ ------
92
88
 
93
- #### Step 1: One-Hot Encoding
94
- One-hot encoding represents each element as a binary vector with a single high (1) value and the rest low (0). For the elements “me”, “you”, “him”, “her”, “it”, “us”, “them”, we can assign the following one-hot encoded vectors:
89
+ ### **.unlock(hash)**
95
90
 
96
- ```js
97
- // Create Me instances
98
- const meInstance = new Me('me');
99
- const youInstance = new Me('you');
100
- const himInstance = new Me('him');
101
- const herInstance = new Me('her');
102
- const itInstance = new Me('it');
103
- const usInstance = new Me('us');
104
- const themInstance = new Me('them');
105
-
106
- // One-hot encoding representation
107
- const subjects = {
108
- 'me': [1, 0, 0, 0, 0, 0, 0],
109
- 'you': [0, 1, 0, 0, 0, 0, 0],
110
- 'him': [0, 0, 1, 0, 0, 0, 0],
111
- 'her': [0, 0, 0, 1, 0, 0, 0],
112
- 'it': [0, 0, 0, 0, 1, 0, 0],
113
- 'us': [0, 0, 0, 0, 0, 1, 0],
114
- 'them': [0, 0, 0, 0, 0, 0, 1]
115
- };
91
+ ```javascript
92
+ unlock(hash)
116
93
  ```
117
94
 
118
- #### Step 2: Combination Representation
119
- For each combination, we can create an input vector by combining the one-hot encoded vectors of its elements. For example:
120
- Combination “me, you” would be represented as the sum of the one-hot vectors for “me” and “you”:
95
+ - Loads the .me file from disk.
96
+ - Uses the first 16 bytes as the IV.
97
+ - Attempts to decrypt the rest using the key derived from the hash.
98
+ - If successful, stores the content in this.data and marks .unlocked = true.
121
99
 
100
+ > 🔒 If it fails, returns false (likely due to a wrong hash or a corrupted file).
101
+
102
+ ------
103
+
104
+ ### **.lock()**
105
+
106
+ ```javascript
107
+ lock()
108
+ ```
109
+
110
+ Clears this.data from memory and sets .unlocked = false.
111
+
112
+ ------
113
+
114
+ ### **.create(username, hash) (static)**
115
+
116
+ ```javascript
117
+ static create(username, hash)
118
+ ```
119
+
120
+ - If the file already exists, throws an error.
121
+ - Creates a new Me object with the structure:
122
+
123
+ ```javascript
124
+ {
125
+ identity: { username, publicKey, privateKey },
126
+ attributes: {},
127
+ relationships: [],
128
+ reactions: [],
129
+ endorsements: []
130
+ }
122
131
  ```
123
- [1, 0, 0, 0, 0, 0, 0] + [0, 1, 0, 0, 0, 0, 0] = [1, 1, 0, 0, 0, 0, 0]
132
+
133
+ - Then calls .save(hash) to store the encrypted identity.
134
+
135
+ ------
136
+
137
+ ### **.load(username, hash) (static)**
138
+
139
+ ```javascript
140
+ static load(username, hash)
141
+ ```
142
+
143
+ - Creates a new Me instance.
144
+ - Calls .unlock(hash) to try decrypting it.
145
+ - If successful, returns the instance.
146
+ - If not, throws an error.
147
+
148
+ ---
149
+
150
+ ### **Social Methods**
151
+
152
+ #### **.addEndorsement(endorsement)**
153
+
154
+ Agrega una firma externa (ej: Alice confía en Bob) a la identidad desbloqueada.
155
+
156
+ #### **.be(key, value)**
157
+
158
+ The **be** method in the **Me** class accepts an object of **key-value pairs** and **adds these to the identity object**.
159
+ ​•You can call **me.be()** multiple times with different attributes to dynamically update the identity object.
160
+
161
+ ```javascript
162
+ // Create a new Me instance
163
+ let me = new Me("xyxyxy");
164
+ // Add attributes to the identity
165
+ me.be({ a: "XXX", b: "YYY" });
166
+ me.be({ c: "z" });
167
+ ```
168
+
169
+ **A less abstract example:**
170
+
171
+ ```js
172
+ // Add attributes to the identity
173
+ me.be({ name: "Alice", phone: "33550000" });
124
174
  ```
175
+
176
+ ------
177
+
178
+ ## 🔍 Core Principles
179
+
180
+ 1. **Freedom to Declare**
181
+ Anyone can generate a `.me` identity locally without external approval.
182
+ 2. **Trusted Endorsements**
183
+ Authorities (e.g., Cleaker) can endorse `.me` identities without controlling them.
184
+ 3. **Local Ownership**
185
+ All sensitive data (including private keys) stays on the user's machine.
186
+
125
187
  ---
126
- ### Me Deviation Formula
127
- **How Spread Out the data Points are around the .me?**
188
+ ## 📁 File Structure
189
+ * `~/.this/me/username.me.json` Encrypted identity file
190
+ * `.me` includes:
191
+
192
+ * `username`
193
+ * `publicKey`, `privateKey` (encrypted)
194
+ * `attributes`, `relationships`, `reactions`, `properties`, `relationships`
195
+ * `endorsements`
196
+
197
+ ---
198
+ ## 🔐 Cryptographic Model
199
+ * Identity is unlocked using a user-defined `hash` (password).
200
+ * This hash decrypts the local `.me` file.
201
+ * The identity includes:
202
+
203
+ * A **key pair** (public/private) for signing and verification.
204
+ * Optional **endorsements** signed by Cleaker or other authorities.
205
+
206
+ ---
207
+ ## 🛡️ Security Model
208
+ * No private key ever leaves the local `.me` file.
209
+ * Endorsements are public and verifiable using the public key.
210
+ * If compromised, user can rotate keys and notify authorities.
211
+
212
+ ---
213
+ ## 🌐 Multi-Device Support
214
+ * `.me` can be restored using a seed phrase or backup.
215
+ * New devices can be authorized using signatures from old devices.
216
+
217
+ ---
218
+ ## ⚖️ Responsibilities
219
+ * **this.me**
220
+ * Local file management, encryption, signing.
221
+ * CLI + API for usage.
222
+
223
+ * **Cleaker / Authorities**
224
+
225
+ * Store trusted records of `username` + `publicKey`
226
+ * Provide validation/endorsement services.
227
+
228
+ ---
229
+ ## 🌍 Use Cases
230
+ * Digital signature of documents
231
+ * Smart contract interaction
232
+ * Federated profiles with trust anchors
233
+ * Group identity and shared contexts (`me && you && them in context/friends`)
234
+
235
+ ---
236
+ By default, **this.me** uses the **local file system (~/.this/me/)** to store and manage identity data.
237
+ No external service is required.
238
+
239
+ ​<img src="https://suign.github.io/assets/imgs/monads.png" alt="Cleak Me Please" width="244">Hello, I am **.me**
240
+
241
+ ### ❯ add.me
242
+ ----
243
+
244
+ # What is All.This?
245
+ ###### Modular Data Structures:
246
+ **Each module** in **[all.this](https://neurons.me/all-this)** represents a specific **datastructure**. These **classes** encapsulate the functionalities and **data specific to their domain.**
128
247
 
248
+ **[this.me](https://docs.neurons.me/this.me/index.html) - [this.audio](https://docs.neurons.me/this.audio/index.html) - [this.text](https://docs.neurons.me/this.text/index.html) - [this.wallet](https://docs.neurons.me/this.wallet/index.html) - [this.img](https://docs.neurons.me/this.img/index.html) - [this.pixel](https://docs.neurons.me/this.pixel/index.html) - [be.this](https://docs.neurons.me/be.this/index.html) - [this.DOM](https://docs.neurons.me/this.DOM/index.html) - [this.env](https://docs.neurons.me/this.env/index.html) - [this.GUI](https://docs.neurons.me/this.GUI/index.html) - [this.be](https://docs.neurons.me/this.be/index.html) - [this.video](https://docs.neurons.me/this.video/index.html) - [this.dictionaries](https://docs.neurons.me/this.dictionaries/index.html)**
129
249
 
130
- ----------
250
+ #### Contribution
251
+ If you are interested in collaborating or wish to share your insights, please feel free to reach out or contribute to the project.
131
252
 
253
+ #### License & Policies
254
+ - **License**: MIT License.
255
+ - **Learn more** at **https://neurons.me**
256
+ [Terms](https://docs.neurons.me/terms-and-conditions) | [Privacy](https://docs.neurons.me/privacy-policy)
132
257
 
258
+ <img src="https://docs.neurons.me/neurons.me.webp" alt="neurons.me logo" width="123" height="123">
package/bin/me.cli.js ADDED
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env node
2
+ // ./bin/me.cli.js
3
+ import { Command } from 'commander';
4
+ import inquirer from 'inquirer';
5
+ import chalk from 'chalk';
6
+ import { existsSync } from 'fs';
7
+ import path from 'path';
8
+ import os from 'os';
9
+ import Me from '../src/me.js';
10
+ import { validateSetup } from '../src/scripts/setup_validation.js';
11
+ validateSetup(); // Asegura que ~/.this y ~/.this/me existen antes de usar el CLI
12
+ const program = new Command();
13
+ const ME_DIR = path.join(os.homedir(), '.this', 'me');
14
+ // Utilidad para obtener ruta de archivo `.me`
15
+ const getMeFilePath = (username) => path.join(ME_DIR, `${username}.me`);
16
+ program
17
+ .name('me')
18
+ .description('CLI to manage this.me identities')
19
+ .version('1.0.0');
20
+ // Comando: crear una identidad .me
21
+ program
22
+ .command('create')
23
+ .description('Create new .me identity')
24
+ .action(async () => {
25
+ const { username, hash } = await inquirer.prompt([
26
+ {
27
+ type: 'input',
28
+ name: 'username',
29
+ message: 'Enter a username:',
30
+ },
31
+ {
32
+ type: 'password',
33
+ name: 'hash',
34
+ message: 'Define your hash (secret key):',
35
+ mask: '*',
36
+ }
37
+ ]);
38
+ const mePath = getMeFilePath(username);
39
+ if (existsSync(mePath)) {
40
+ console.log(chalk.red(`❌ Identity '${username}' already exists.`));
41
+ return;
42
+ }
43
+ const me = await Me.create(username, hash);
44
+ console.log(chalk.green(`✅ Identity '${me.username}' created and saved as ${mePath}`));
45
+ });
46
+
47
+ // Command: show identity contents
48
+ program
49
+ .command('show')
50
+ .description('Show contents of a .me identity')
51
+ .argument('[username]', 'Username of the identity to show')
52
+ .action(async (usernameArg) => {
53
+ const { username, hash } = await inquirer.prompt([
54
+ {
55
+ type: 'input',
56
+ name: 'username',
57
+ message: 'Enter username to view:',
58
+ when: () => !usernameArg,
59
+ },
60
+ {
61
+ type: 'password',
62
+ name: 'hash',
63
+ message: 'Enter your hash to unlock:',
64
+ mask: '*',
65
+ }
66
+ ]);
67
+
68
+ const finalUsername = usernameArg || username;
69
+
70
+ try {
71
+ const me = await Me.load(finalUsername, hash);
72
+ console.log(chalk.cyan(`\n📂 Identity '${finalUsername}':\n`));
73
+ console.log(JSON.stringify(me, null, 2));
74
+ } catch (err) {
75
+ console.log(chalk.red(`Error: ${err.message}`));
76
+ }
77
+ });
78
+
79
+ // Comando: listar identidades locales
80
+ program
81
+ .command('list')
82
+ .description('List available local .me identities')
83
+ .action(async () => {
84
+ const fs = await import('fs/promises');
85
+ fs.readdir(ME_DIR)
86
+ .then(files => {
87
+ const meFiles = files.filter(file => file.endsWith('.me'));
88
+ if (meFiles.length === 0) {
89
+ console.log(chalk.yellow('⚠️ No registered identities found.'));
90
+ } else {
91
+ console.log(chalk.cyan('📇 Available identities:'));
92
+ meFiles.forEach(file => console.log('•', file.replace('.me', '')));
93
+ console.log(chalk.gray('\nTip: Use `me show` or `me show <username>` to view identity contents.'));
94
+ }
95
+ })
96
+ .catch(err => console.log(chalk.red(`Error: ${err.message}`)));
97
+ });
98
+
99
+ program.parse(process.argv);
package/index.js CHANGED
@@ -1,12 +1,12 @@
1
- //index.js
1
+ // index.js
2
2
  /**
3
3
  * @module This.Me
4
4
  * @description
5
5
  * This.Me is a data-structured identity...
6
- * */
6
+ */
7
7
 
8
+ import { validateSetup } from './src/scripts/setup_validation.js';
9
+ validateSetup(); // Asegura que ~/.this y ~/.this/me existen antes de continuar
8
10
  import Me from './src/me.js';
9
- //when a user declares "I am %.me," their digital existence is affirmed and recorded in the system.
10
- export default Me;
11
-
12
- console.log("this.me is loaded!!");
11
+ // when a user declares "I am %.me," their digital existence is affirmed and recorded in the system.
12
+ export default Me;
package/jsdoc.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "source": {
3
+ "include": ["./src", "./index.js", "./README.md"]
4
+ },
5
+ "opts": {
6
+ "destination": "/mnt/neuroverse/https-neurons/subDomains/docs/public/this.me",
7
+ "template": "../../../suign.github.io/Sandbox/better-docs/",
8
+ "readme": "./README.md"
9
+ },
10
+ "templates": {
11
+ "cleverLinks": false,
12
+ "monospaceLinks": false,
13
+ "search": true,
14
+ "default": {
15
+ "staticFiles": {
16
+ "include": ["./README.md"]
17
+ }
18
+ },
19
+ "better-docs": {
20
+ "name": "this.me",
21
+ "title": "this.me Docs",
22
+ "css": "style.css",
23
+ "trackingCode": "...",
24
+ "hideGenerator": false,
25
+ "navLinks": [
26
+ {
27
+ "label": "All.This",
28
+ "href": "https://docs.neurons.me/all.this/"
29
+ },
30
+ {
31
+ "label": "Neurons.me",
32
+ "href": "https://neurons.me"
33
+ },
34
+ {
35
+ "label": "Github",
36
+ "href": "https://github.com/neurons-me/this.me"
37
+ }
38
+ ]
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,9 @@
1
+ 👤 Entonces, ¿qué es .me?
2
+
3
+ .me es el sujeto.
4
+ Es quien dice “yo”.
5
+ Es la llave privada, la biografía, la voluntad.
6
+
7
+ .me es local, silencioso, estático.
8
+ No “vive”, no escucha.
9
+ Solo es consultado y afirma.
@@ -0,0 +1,154 @@
1
+ ### **Index of `this.me` Structure**
2
+ Here’s a comprehensive list of the components and their purposes within the `this.me` class:
3
+
4
+ #### **1. Identity**
5
+ - **Description:** Immutable attributes defining the core identity of the user.
6
+ - Incluye claves criptográficas necesarias para autenticación, firma y encriptación.
7
+ #### **2. Attributes**
8
+ - **Description:** Flexible traits and descriptive properties of the user.
9
+ #### **3. Relationships**
10
+ - **Description:** Connections and associations with others.
11
+ #### **4. Reactions**
12
+ - **Description:** User’s interactions and engagements with the world.
13
+ #### **5. Properties**
14
+ - **Description:** Items owned or managed by the user.
15
+
16
+ ------
17
+
18
+ ### **1. The Me Structure Overview**
19
+
20
+ #### **Core Components**
21
+ - **Identity:** The foundation of the `this.me` object.
22
+
23
+ - Immutable attributes: `username`, `DID`, `publicKey`, `privateKey`.
24
+ - Core methods for validation, key generation, and secure signing.
25
+
26
+ - Example key storage:
27
+ ```json
28
+ {
29
+ "username": "jabellae",
30
+ "DID": "did:cleaker:xyz123",
31
+ "publicKey": "abc123...",
32
+ "privateKey": "<encrypted or local-only>"
33
+ }
34
+ ```
35
+
36
+ - Example method:
37
+ ```js
38
+ jabellae.sign("message to sign"); // Returns signature using stored private key
39
+ ```
40
+
41
+ ---
42
+
43
+ - **Attributes:** Fundamental identity traits.
44
+ Store and manage user traits dynamically:
45
+ - Examples: Name, age, location, pronouns, bio.
46
+ **Use `.be()` to add or update attributes.**
47
+ Example:
48
+ ```json
49
+ { name: 'John Doe', age: 30, location: 'Earth' }
50
+ ```
51
+ Implement `be()` as a flexible key-value store.
52
+ Add validation for specific attributes (if required).
53
+
54
+ --------
55
+
56
+ - **Relationships:** Connections with others.
57
+ - Examples: Friends, groups, networks, organizations.
58
+ **Contacts:** Individual connections.
59
+ **Groups:** Collections of users with shared context.
60
+
61
+ ```js
62
+ .relationships.addContact({ username: 'alice', status: 'friend' });
63
+ .relationships.createGroup({ name: 'Family', members: ['alice', 'bob'] });
64
+ ```
65
+
66
+ Define `addContact` and `createGroup` methods.
67
+ Enable nested relationship structures (e.g., groups of groups).
68
+
69
+ ---------
70
+
71
+ - **Reactions:** How a user interacts with the world.
72
+ Streamline all user engagements under `.react()`
73
+ - Examples: Likes, comments, shares, emotions.
74
+ - Categorization Rationale:
75
+ - Keeps all engagements unified.
76
+ - Expands easily (adding emojis, advanced reactions).
77
+
78
+ ```js
79
+ .react.add({ type: 'like', target: 'PostID' });
80
+ .react.add({ type: 'comment', target: 'PhotoID', content: 'Great pic!' });
81
+ ```
82
+
83
+ Design a structure to store and retrieve reactions efficiently.
84
+ Define a `log` system for reaction history.
85
+
86
+ -----
87
+
88
+ - **Properties:** Things the user owns or manages.
89
+ Attach external, modular objects as user-owned assets:
90
+ - Use `this.me.properties` as a unified interface for ownership.
91
+ - Modular objects like `Wallet`, `Device`, `File`.
92
+ - Examples: Wallets, devices, digital files, accounts.
93
+ - **Sub-Methods:** Add, Share, Transfer Ownership, Revoke Access.
94
+
95
+ ```js
96
+ const jabellae = new Me('jabellae'); // Create a new Me instance
97
+ const wallet = new Wallet({ type: 'ETH', address: '0x123...' }); // Create a wallet object
98
+ jabellae.addProperty(wallet); // Add wallet as a property to Me
99
+ ```
100
+
101
+ ​ Implement `add`, `share`, `transferOwnership`, and `revokeAccess` methods for properties. Define modular objects (`Wallet`, `Device`) independently.
102
+
103
+ 1. **Creating a Wallet**
104
+ The wallet is created independently and then added to the `Me` instance's properties.
105
+
106
+ ```javascript
107
+ const jabellae = new Me('jabellae'); // Create a new Me instance
108
+ const wallet = new Wallet({ type: 'ETH', address: '0x123...' }); // Create a wallet object
109
+ jabellae.addProperty(wallet); // Add wallet as a property to Me
110
+ ```
111
+
112
+ 2. **Sharing the Wallet**
113
+ Sharing logic is handled by the `Me` instance, not the property itself.
114
+
115
+ ```javascript
116
+ jabellae.shareProperty(wallet, 'otherMe', { permissions: 'view' });
117
+ ```
118
+
119
+ 3. **Transferring Ownership**
120
+ Ownership transfer is also managed by the `Me` instance.
121
+
122
+ ```javascript
123
+ jabellae.transferOwnership(wallet, 'otherMe');
124
+ ```
125
+
126
+ ------
127
+
128
+ ### **2. Why Independent Objects?**
129
+
130
+ #### **Modularity**
131
+ - Keeps the `this.me` instance *agnostic* of specifics.
132
+ - Allows new property types to integrate seamlessly.
133
+
134
+ #### **Reusability**
135
+ - Each property (e.g., `this.wallet`, `this.device`) operates independently.
136
+ - Can be ported across `this.me` instances without coupling.
137
+
138
+ #### **Transferability**
139
+ - Ownership is a property-level concern.
140
+ - Example:
141
+
142
+ ```javascript
143
+ const wallet = new Wallet(owner = "me");
144
+ wallet.transferOwnership("otherMeInstance");
145
+ ```
146
+
147
+ #### **Separation of Concerns**
148
+ - Identity (`this.me`) manages relationships, attributes, and higher-level user interactions.
149
+ - Objects like `Wallet` or `Device` manage their specific functionality.
150
+
151
+ #### **Scalability**
152
+ - Adding a new property type is as simple as:
153
+ 1. Defining the object (e.g., `Vehicle`).
154
+ 2. Registering it with `this.me`.