whisper: detail the internals of the JS example (#19481)
This commit is contained in:
		@@ -4,7 +4,63 @@ title: Whisper JavaScript example
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[This link](https://github.com/gballet/whisper-chat-example) contains a full-fledged example of how to use Whisper in a small chat application.
 | 
					[This link](https://github.com/gballet/whisper-chat-example) contains a full-fledged example of how to use Whisper in a small chat application.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Let's now have a look at the `sendMessage` function:
 | 
					The app is a simple Vue single page application that works in several steps. In the first step, the user configures the RPC service that they wish to connect to. Typically, this would be a `geth` client with the `--shh` option enabled.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Then one can install the application locally by typing:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					$ git clone https://github.com/gballet/whisper-chat-example
 | 
				
			||||||
 | 
					$ cd whisper-chat-example
 | 
				
			||||||
 | 
					$ npm install
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The application is then started by typing:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					$ npm run dev
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The application will then be available at `http://localhost:8080` (Note the http here, which is because it's a **demo application** and should not be used in production)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## User workflow
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The app starts by asking the user for their user name and whether they want a symmetric or asymmetric connection. If it's asymmetric, the geth server will propose a public key. If it's symmetric, a key has to be provided.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Then the user presses "Start" and the conversation begins.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## The app's state
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```javascript
 | 
				
			||||||
 | 
					                let data = {
 | 
				
			||||||
 | 
					                        msgs: [],
 | 
				
			||||||
 | 
					                        text: "",
 | 
				
			||||||
 | 
					                        symKeyId: null,
 | 
				
			||||||
 | 
					                        name: "",
 | 
				
			||||||
 | 
					                        asymKeyId: null,
 | 
				
			||||||
 | 
					                        sympw: "",
 | 
				
			||||||
 | 
					                        asym: true,
 | 
				
			||||||
 | 
					                        configured: false,
 | 
				
			||||||
 | 
					                        topic: defaultTopic,
 | 
				
			||||||
 | 
					                        recipientPubKey: defaultRecipientPubKey,
 | 
				
			||||||
 | 
					                        asymPubKey: ""
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This is how the current, transient, state of the application is represented:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * `msgs` is the list of messages in the current conversation
 | 
				
			||||||
 | 
					  * `text` contains the text that the current user is typing
 | 
				
			||||||
 | 
					  * `name` is the name of the current user, which is used to identify them in conversations
 | 
				
			||||||
 | 
					  * `asymKeyId` and `symKeyId` represent handles to the corresponding keys in `geth`'s memory
 | 
				
			||||||
 | 
					  * `recipientPubKey` is a hex string representing the public key that an asymmetric message is sent to
 | 
				
			||||||
 | 
					  * `topic` is a hex string representing the message's topic
 | 
				
			||||||
 | 
					  * `asymPubKey` is a hex string representing the user's own public key
 | 
				
			||||||
 | 
					  * `configured` is a flag that is set to true when the user has choosen either a public key or a symmetric key, and a user name
 | 
				
			||||||
 | 
					  * `sympw` contains the symmetric password
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## The `sendMessage` callback
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The `sendMessage` callback is called every time the user clicks on "Send" or presses the return key. It is responsible for creating the RPC request that instructs the `geth` node to encrypt and send the message.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```javascript
 | 
					```javascript
 | 
				
			||||||
sendMessage() {
 | 
					sendMessage() {
 | 
				
			||||||
@@ -17,6 +73,7 @@ sendMessage() {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // (code elided for clarity)
 | 
					    // (code elided for clarity)
 | 
				
			||||||
 | 
					    // ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Create the data object that will be sent to the RPC endpoint.
 | 
					    // Create the data object that will be sent to the RPC endpoint.
 | 
				
			||||||
    let postData = {
 | 
					    let postData = {
 | 
				
			||||||
@@ -39,5 +96,14 @@ sendMessage() {
 | 
				
			|||||||
    this.shh.post(postData);
 | 
					    this.shh.post(postData);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // (code elided for clarity)
 | 
					    // (code elided for clarity)
 | 
				
			||||||
 | 
					    // ...
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The `msg` object is created. The format chosen for the object is specific to this demo application. It just contains a text and the name of the sender. This is obviously not secure enough for a real-world application.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					That object is converted to a string and then encoded as a hexadecimal string, in the `payload` member of the request's `POST` data object. Other fields include the `topic` of the message, how much work the sending server should do and other parameters.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Next, depending whether the "asymmetric" checkbox has been ticked, the value of `this.asym` will be true or false. Based on this, the system will update the request object with the relevant information.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Finally, the request is being sent with `this.shh.post(postData)`, which calls Web3's `shh.post` function to send the message.
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user