Wesh App with Persistent Storage
Tags: web3, p2p, protocol, opensource
Published: 2023-09-01 13:03:18

In the previous blog post, we made an example “Hello world” app using the Wesh API. But it used in-memory storage for the keys and messages, which are lost when the app closes. It's possible to export the data to a file before closing, and re-import it when the in-memory app stars again. But in this blog post we will make an example app to use a persistent storage on disk. We'll also use this to explain some details of what is in the key store and libp2p node.

As before, we write an app similar to the [Go tutorial](https://go.dev/doc/tutorial/getting-started). In a terminal enter:

```
cd
mkdir persistent
cd persistent
go mod init example/persistent

```
As in the previous blog post, paste the following code into your persistent.go file.

```
package main

import (
	"context"
	"fmt"

	"berty.tech/weshnet"
	"berty.tech/weshnet/pkg/protocoltypes"
)
```
(See the previous blog post for explanation.) To complete the example, paste the following main function and save the file.

```
func main() {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	path := "data"
        client, err := weshnet.NewPersistentServiceClient(path)
	if err != nil {
		panic(err)
	}
	defer client.Close()

	config, err := client.ServiceGetConfiguration(ctx,
            &protocoltypes.ServiceGetConfiguration_Request{})
	if err != nil {
		panic(err)
	}

	fmt.Println("Hello, world! My peer ID is", config.PeerID)
}
```

This is similar to the previous example, except that we change **NewInMemoryServiceClient() to NewPersistentServiceClient(path)** , where path is the directory for the persistent storage. When we run for the first time, Wesh will create the directory and the storage files for a new peer identity. To run, in a terminal enter:

```
go mod tidy
go run . 
```
(You only need to do go mod tidy the first time.) It should print something like **“Hello, world! My peer ID is 12D3KooWJeVb4rbDisCgmUQQxtzNRikgcQxXzSodoy2AyNCdTEWr”** . Now, enter the run command again:

```
go run .
```
This time, **NewPersistentServiceClient(path)** uses the storage files that we created the first time. It should print exactly the same peer ID, meaning that the same identity is persistent on disk. To see the storage files, enter:

```
ls data
```

You should see something like:

```
000000.vlog	000002.sst	MANIFEST	config		datastore_spec	repo.lock
000001.sst	KEYREGISTRY	blocks		datastore	keystore	      version

```
Much of the content of these files is encrypted. They are only meant to be accessed through the Wesh API. We aren't going to look at all of these files or describe their format, but seeing them gives us a chance to discuss the basic types of information in Wesh.

The most important to discuss are the three types of information associated with your identity:

- [The libp2p host Peer ID](https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md#peer-ids) is what the example prints. It identifies your computer as a node in libp2p communication.

- [The Account key pair](https://berty.tech/docs/protocol/#account-creation
) holds the primary identity that you use to connect to other Wesh users and to join a group.

- [A Device key pair](https://berty.tech/docs/protocol/#linking-devices) is created on each computer or mobile device where you use Wesh, and is connected cryptographically to your Account key pair.

In Wesh, communication is based on the “group” where messages are secure between group members. For each new group, the Wesh service generates a Metadata log (with info like members joining), a Message log (which we'll explore in a future blog post), and cryptographic secrets (your own secrets and secrets received from other group members). There are three types of groups:

- Your [Account group](https://berty.tech/docs/protocol/#account-group) stores all the secrets and metadata of your account and allows the devices linked to it to sync with each other, as explained above. So, when the example first calls **`NewPersistentServiceClient`**, Wesh creates one Account key pair, one Device key pair for your computer, and the Account group for it.

- When [you add another Wesh user as a contact](https://berty.tech/docs/protocol/#adding-contacts), you are both in a [Contact group](https://berty.tech/docs/protocol/#contact-group) where just the two of you can communicate securely. No other users can join this group.

- Finally, you can create or join a [Multi-member group](https://berty.tech/docs/protocol/#multi-member-group). This is what people normally think of when they hear about Wesh, but it's useful to mention the other types of groups and their purpose.

Among other maintenance files, the persistent storage has a Network config file with info on how libp2p makes connections. And there is a block store which is part of the peer-to-peer network and stores information you have received or may be useful to other users that your device connects to.

That's enough for now! For more details, see the links in the text above. Now that we see how to create an account, in the next blog post we'll look at how to use Wesh to add a contact and send a message.