Skip to content
Snippets Groups Projects
Commit 2cfdb8bf authored by Jake Taylor's avatar Jake Taylor :lips:
Browse files

Merge branch 'jono/updateREADME' into 'release'

Update README

See merge request !270
parents 8912ec20 1f39467e
No related branches found
No related tags found
2 merge requests!510Release,!270Update README
# xx network Client # xx network Client
[![pipeline status](https://gitlab.com/elixxir/client/badges/master/pipeline.svg)](https://gitlab.com/elixxir/client/commits/master) [Repository](https://git.xx.network/elixxir/client) | [Go Doc](https://pkg.go.dev/gitlab.com/elixxir/client/xxdk) | [Examples](https://git.xx.network/elixxir/xxdk-examples/-/tree/master)
[![coverage report](https://gitlab.com/elixxir/client/badges/master/coverage.svg)](https://gitlab.com/elixxir/client/commits/master)
The client is a library and related command-line tool The client is a library and related command-line tool that facilitates making full-featured xx clients for all
that facilitates making full-featured xx clients for all platforms. It interfaces with the cMix system, enabling access platforms. It interfaces with the cMix system, enabling access to all xx network messaging features, including
to all xx network messaging features, including end-to-end encryption and metadata protection. end-to-end encryption and metadata protection.
This repository contains everything necessary to implement all of the This repository contains everything necessary to implement the xx network messaging features. In addition, it also
xx network messaging features. It also contains features to extend the base contains features to extend the base messaging protocols.
messaging protocols.
The command-line tool accompanying the client library can be built for any platform supported by The command-line tool accompanying the client library can be built for any platform supported by Go. The libraries are
golang. The libraries are built for iOS and Android using built for iOS and Android using [gomobile](https://pkg.go.dev/golang.org/x/mobile/cmd/gomobile).
[gomobile](https://godoc.org/golang.org/x/mobile/cmd/gomobile).
For library writers, the client requires a writable folder to store For library writers, the client requires a writable folder to store data, functions for receiving and approving requests
data, functions for receiving and approving requests for creating for creating secure end-to-end messaging channels, discovering users, and receiving different types of messages.
secure end-to-end messaging channels, for discovering users, and for
receiving different types of messages. Details for implementing these
features are in the [Library Overview section](#library-overview) below.
The client is open-source software released under the simplified BSD License. The client is open-source software released under the simplified BSD License.
## Command Line Usage ## Command Line Usage
The command-line tool is intended for testing xx network functionality and not The command-line tool is intended for testing xx network functionality and not for regular user use.
for regular user use.
These instructions assume that you have [Go 1.17.X installed](https://go.dev/doc/install), and GCC installed for Cgo (such as `build-essential` on Debian or Ubuntu). These instructions assume that you have [Go 1.17.X](https://go.dev/doc/install) installed and GCC installed for
[cgo](https://pkg.go.dev/cmd/cgo) (such as `build-essential` on Debian or Ubuntu).
Compilation steps: Compilation steps:
``` ```shell
git clone https://gitlab.com/elixxir/client.git client $ git clone https://gitlab.com/elixxir/client.git client
cd client $ cd client
go mod vendor -v $ go mod vendor
go mod tidy $ go mod tidy
go test ./...
# Linux 64 bit binary # Linux 64-bit binary
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags '-w -s' -o client.linux64 main.go $ GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags '-w -s' -o client.linux64 main.go
# Windows 64 bit binary
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -ldflags '-w -s' -o client.win64 main.go # Windows 64-bit binary
# Windows 32 big binary $ GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -ldflags '-w -s' -o client.win64 main.go
GOOS=windows GOARCH=386 CGO_ENABLED=0 go build -ldflags '-w -s' -o release/client.win32 main.go
# Mac OSX 64 bit binary (intel) # Windows 32-bit binary
GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build -ldflags '-w -s' -o release/client.darwin64 main.go $ GOOS=windows GOARCH=386 CGO_ENABLED=0 go build -ldflags '-w -s' -o client.win32 main.go
# Mac OSX 64-bit binary (Intel)
$ GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build -ldflags '-w -s' -o client.darwin64 main.go
``` ```
#### Fetching an NDF ### Fetching an NDF
All actions performed with the client require a All actions performed with the client require a current
current [NDF](https://xxdk-dev.xx.network/technical-glossary#network-definition-file-ndf). The NDF is downloadable from [network definition file (NDF)](https://xxdk-dev.xx.network/technical-glossary/#network-definition-file-ndf). The NDF is
the command line downloadable from the command line or
or [via an access point](https://xxdk-dev.xx.network/quick-reference#func-downloadandverifysignedndfwithurl) in the [via an access point](https://xxdk-dev.xx.network/quick-reference#func-downloadandverifysignedndfwithurl) in the Client
Client API. API.
Use the `getndf` command to fetch the NDF via the command line. `getndf` enables command-line users to poll the NDF from Use the `getndf` command to fetch the NDF via the command line. `getndf` enables command-line users to poll the NDF from
a network gateway without any pre-established client connection. a network gateway without any pre-established client connection.
First, you'll want to download an SSL certificate: First, you'll want to download an SSL certificate:
``` ```shell
// Assumes you are running a gateway locally # Assumes you are running a gateway locally
openssl s_client -showcerts -connect localhost:8440 < /dev/null 2>&1 | openssl x509 -outform PEM > certfile.pem $ openssl s_client -showcerts -connect localhost:8440 < /dev/null 2>&1 | openssl x509 -outform PEM > certfile.pem
``` ```
Now you can fetch the NDF: Now you can fetch the NDF.
``` ```shell
// Example usage for Gateways, assumes you are running a gateway locally # Example usage for gateways, assumes you are running a gateway locally
$ go run main.go getndf --gwhost localhost:8440 --cert certfile.pem | jq . >ndf.json $ ./client getndf --gwhost localhost:8440 --cert certfile.pem | jq . > ndf.json
``` ```
You can also download an NDF directly for different environments by using the `--env` flag: You can also download an NDF directly for different environments by using the `--env` flag.
```go ```shell
$ go run main.go getndf --env mainnet | jq . >ndf.json $ ./client getndf --env mainnet | jq . > ndf.json
// Or, run via the binary (assuming 64-bit Windows):
$ ./client.win64 getndf --env mainnet | jq . >ndf.json
``` ```
Sample content of `ndf.json`: Sample content of `ndf.json`:
``` ```json
{ {
"Timestamp": "2021-01-29T01:19:49.227246827Z", "Timestamp": "2021-01-29T01:19:49.227246827Z",
"Gateways": [ "Gateways": [
...@@ -91,31 +86,36 @@ Sample content of `ndf.json`: ...@@ -91,31 +86,36 @@ Sample content of `ndf.json`:
"Id": "BRM+Iotl6ujIGhjRddZMBdauapS7Z6jL0FJGq7IkUdYB", "Id": "BRM+Iotl6ujIGhjRddZMBdauapS7Z6jL0FJGq7IkUdYB",
"Address": ":8440", "Address": ":8440",
"Tls_certificate": "-----BEGIN CERTIFICATE-----\nMIIDbDCCAlSgAwIBAgIJAOUNtZneIYECMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNV\nBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQx\nGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJp\ncDAeFw0xOTAzMDUxODM1NDNaFw0yOTAzMDIxODM1NDNaMGgxCzAJBgNVBAYTAlVT\nMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNV\nBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPP0WyVkfZA/CEd2DgKpcudn0oDh\nDwsjmx8LBDWsUgQzyLrFiVigfUmUefknUH3dTJjmiJtGqLsayCnWdqWLHPJYvFfs\nWYW0IGF93UG/4N5UAWO4okC3CYgKSi4ekpfw2zgZq0gmbzTnXcHF9gfmQ7jJUKSE\ntJPSNzXq+PZeJTC9zJAb4Lj8QzH18rDM8DaL2y1ns0Y2Hu0edBFn/OqavBJKb/uA\nm3AEjqeOhC7EQUjVamWlTBPt40+B/6aFJX5BYm2JFkRsGBIyBVL46MvC02MgzTT9\nbJIJfwqmBaTruwemNgzGu7Jk03hqqS1TUEvSI6/x8bVoba3orcKkf9HsDjECAwEA\nAaMZMBcwFQYDVR0RBA4wDIIKKi5jbWl4LnJpcDANBgkqhkiG9w0BAQUFAAOCAQEA\nneUocN4AbcQAC1+b3To8u5UGdaGxhcGyZBlAoenRVdjXK3lTjsMdMWb4QctgNfIf\nU/zuUn2mxTmF/ekP0gCCgtleZr9+DYKU5hlXk8K10uKxGD6EvoiXZzlfeUuotgp2\nqvI3ysOm/hvCfyEkqhfHtbxjV7j7v7eQFPbvNaXbLa0yr4C4vMK/Z09Ui9JrZ/Z4\ncyIkxfC6/rOqAirSdIp09EGiw7GM8guHyggE4IiZrDslT8V3xIl985cbCxSxeW1R\ntgH4rdEXuVe9+31oJhmXOE9ux2jCop9tEJMgWg7HStrJ5plPbb+HmjoX3nBO04E5\n6m52PyzMNV+2N21IPppKwA==\n-----END CERTIFICATE-----\n" "Tls_certificate": "-----BEGIN CERTIFICATE-----\nMIIDbDCCAlSgAwIBAgIJAOUNtZneIYECMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNV\nBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQx\nGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJp\ncDAeFw0xOTAzMDUxODM1NDNaFw0yOTAzMDIxODM1NDNaMGgxCzAJBgNVBAYTAlVT\nMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQxGzAZBgNV\nBAoMElByaXZhdGVncml0eSBDb3JwLjETMBEGA1UEAwwKKi5jbWl4LnJpcDCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPP0WyVkfZA/CEd2DgKpcudn0oDh\nDwsjmx8LBDWsUgQzyLrFiVigfUmUefknUH3dTJjmiJtGqLsayCnWdqWLHPJYvFfs\nWYW0IGF93UG/4N5UAWO4okC3CYgKSi4ekpfw2zgZq0gmbzTnXcHF9gfmQ7jJUKSE\ntJPSNzXq+PZeJTC9zJAb4Lj8QzH18rDM8DaL2y1ns0Y2Hu0edBFn/OqavBJKb/uA\nm3AEjqeOhC7EQUjVamWlTBPt40+B/6aFJX5BYm2JFkRsGBIyBVL46MvC02MgzTT9\nbJIJfwqmBaTruwemNgzGu7Jk03hqqS1TUEvSI6/x8bVoba3orcKkf9HsDjECAwEA\nAaMZMBcwFQYDVR0RBA4wDIIKKi5jbWl4LnJpcDANBgkqhkiG9w0BAQUFAAOCAQEA\nneUocN4AbcQAC1+b3To8u5UGdaGxhcGyZBlAoenRVdjXK3lTjsMdMWb4QctgNfIf\nU/zuUn2mxTmF/ekP0gCCgtleZr9+DYKU5hlXk8K10uKxGD6EvoiXZzlfeUuotgp2\nqvI3ysOm/hvCfyEkqhfHtbxjV7j7v7eQFPbvNaXbLa0yr4C4vMK/Z09Ui9JrZ/Z4\ncyIkxfC6/rOqAirSdIp09EGiw7GM8guHyggE4IiZrDslT8V3xIl985cbCxSxeW1R\ntgH4rdEXuVe9+31oJhmXOE9ux2jCop9tEJMgWg7HStrJ5plPbb+HmjoX3nBO04E5\n6m52PyzMNV+2N21IPppKwA==\n-----END CERTIFICATE-----\n"
}, }
{ ]
"Id": "JCBd9mAQb2BW8hc8H9avy1ubcjUAa7MHrPp0dBU/VqQB", }
.....
``` ```
#### Sending Safe Messages Between Two (2) Users Use the `--help` command with `getndf` to view all options.
```shell
$ ./client getndf --help
```
**Note:** For information on receiving messages and troubleshooting authenticated channel requests, ### Sending Safe Messages Between Two (2) Users
see [Receiving Messages](#receiving-messages)
and [Confirming authenticated channel requests](#confirming-authenticated-channel-requests). > 💡 **Note:** For information on receiving messages and troubleshooting authenticated channel requests,
see [Receiving Messages](#receiving-messages) and
> [Confirming authenticated channel requests](#confirming-authenticated-channel-requests).
To send messages with end-to-end encryption, you must first establish a connection To send messages with end-to-end encryption, you must first establish a connection
or [authenticated channel](https://xxdk-dev.xx.network/technical-glossary#authenticated-channel) with the other user. or [authenticated channel](https://xxdk-dev.xx.network/technical-glossary#authenticated-channel) with the other user.
See below for example commands for sending or confirming authenticated channel requests, as well as for sending E2E See below for example commands for sending or confirming authenticated channel requests, as well as for sending E2E
messages: messages.
``` ```shell
# Get user contact jsons for each client # Get user contact files for each client
$ client --password user1-password --ndf ndf.json -l client1.log -s user1session --writeContact user1-contact.json --unsafe -m "Hi to me, without E2E Encryption" $ ./client --password user1-password --ndf ndf.json -l client1.log -s user1session --writeContact user1-contact.json --unsafe -m "Hi to me, without E2E Encryption"
$ client --password user2-password --ndf ndf.json -l client2.log -s user2session --writeContact user2-contact.json --unsafe -m "Hi to me, without E2E Encryption" $ ./client --password user2-password --ndf ndf.json -l client2.log -s user2session --writeContact user2-contact.json --unsafe -m "Hi to me, without E2E Encryption"
# Request authenticated channel from another client. Note that the receiving client # Request authenticated channel from another client. Note that the receiving client
# is expected to confirm the request before any specified timeout (default 120s) # is expected to confirm the request before any specified timeout (default 120s)
$ client --password password --ndf ndf.json -l client.log -s session-directory --destfile user2-contact.json --waitTimeout 360 --unsafe-channel-creation --send-auth-request $ ./client --password password --ndf ndf.json -l client.log -s session-directory --destfile user2-contact.json --waitTimeout 360 --unsafe-channel-creation --send-auth-request
WARNING: unsafe channel creation enabled WARNING: unsafe channel creation enabled
Adding authenticated channel for: Qm40C5hRUm7uhp5aATVWhSL6Mt+Z4JVBQrsEDvMORh4D Adding authenticated channel for: Qm40C5hRUm7uhp5aATVWhSL6Mt+Z4JVBQrsEDvMORh4D
Message received: Message received:
...@@ -124,19 +124,19 @@ Received 1 ...@@ -124,19 +124,19 @@ Received 1
# Accept/Confirm an authenticated channel request implicitly # Accept/Confirm an authenticated channel request implicitly
# (should be within the timeout window of requesting client, or the request will need to be re-sent): # (should be within the timeout window of requesting client, or the request will need to be re-sent):
$ client --password "password" --ndf ndf.json -l client.log -s session-directory --destfile user2-contact.json --unsafe-channel-creation --waitTimeout 200 $ ./client --password "password" --ndf ndf.json -l client.log -s session-directory --destfile user2-contact.json --unsafe-channel-creation --waitTimeout 200
Authentication channel request from: o+QpswTmnsuZve/QRz0j0RYNWqjgx4R5pACfO00Pe0cD Authentication channel request from: o+QpswTmnsuZve/QRz0j0RYNWqjgx4R5pACfO00Pe0cD
Sending to o+QpswTmnsuZve/QRz0j0RYNWqjgx4R5pACfO00Pe0cD: Sending to o+QpswTmnsuZve/QRz0j0RYNWqjgx4R5pACfO00Pe0cD:
Message received: Message received:
Received 1 Received 1
# Send E2E Messages # Send E2E Messages
$ client --password user1-password --ndf ndf.json -l client1.log -s user1session --destfile user2-contact.json -m "Hi User 2, from User 1 with E2E Encryption" $ ./client --password user1-password --ndf ndf.json -l client1.log -s user1session --destfile user2-contact.json -m "Hi User 2, from User 1 with E2E Encryption"
Sending to Qm40C5hRUm7uhp5aATVWhSL6Mt+Z4JVBQrsEDvMORh4D: Hi User 2, from User 1 with E2E Encryption Sending to Qm40C5hRUm7uhp5aATVWhSL6Mt+Z4JVBQrsEDvMORh4D: Hi User 2, from User 1 with E2E Encryption
Timed out! Timed out!
Received 0 Received 0
$ client --password user2-password --ndf ndf.json -l client1.log -s user2session --destfile user1-contact.json -m "Hi User 1, from User 2 with E2E Encryption" $ ./client --password user2-password --ndf ndf.json -l client1.log -s user2session --destfile user1-contact.json -m "Hi User 1, from User 2 with E2E Encryption"
Sending to o+QpswTmnsuZve/QRz0j0RYNWqjgx4R5pACfO00Pe0cD: Hi User 1, from User 2 with E2E Encryption Sending to o+QpswTmnsuZve/QRz0j0RYNWqjgx4R5pACfO00Pe0cD: Hi User 1, from User 2 with E2E Encryption
Timed out! Timed out!
Received 0 Received 0
...@@ -147,57 +147,55 @@ Received 0 ...@@ -147,57 +147,55 @@ Received 0
* `-l`: The file to write logs (user messages are still printed to stdout). * `-l`: The file to write logs (user messages are still printed to stdout).
* `-s`: The storage directory for client session data. * `-s`: The storage directory for client session data.
* `--writeContact`: Output the user's contact information to this file. * `--writeContact`: Output the user's contact information to this file.
* `--destfile` is used to specify the recipient. You can also use * `--destfile` is used to specify the recipient. You can also use `--destid b64:...` using the user's base64 ID, which
`--destid b64:...` using the user's base64 id, which is printed in the logs. is printed in the logs.
* `--unsafe`: Send message without encryption (necessary whenever you have not * `--unsafe`: Send message without encryption (necessary whenever you have not already established an e2e channel).
already established an e2e channel).
* `--unsafe-channel-creation` Auto-create and auto-accept channel requests. * `--unsafe-channel-creation` Auto-create and auto-accept channel requests.
* `-m`: The message to send. * `-m`: The message to send.
Note that the client defaults to sending to itself when a destination is not supplied. Note that the client defaults to sending to itself when a destination is not supplied.
This is why we've used the `--unsafe` flag when creating the user contact jsons. This is why we've used the `--unsafe` flag when creating the user contact files.
However, when sending between users, it is dropped in exchange for `--unsafe-channel-creation`. However, when sending between users, the flag is dropped in exchange for `--unsafe-channel-creation`.
For the authenticated channel creation to be considered "safe", the user should be prompted. You can do this by For the authenticated channel creation to be considered "safe", the user should be prompted. You can do this by
explicitly accepting the channel creation explicitly accepting the channel creation when sending a request with `--send-auth-request` (while excluding the
when sending a request with `--send-auth-request` (while excluding the `--unsafe-channel-creation` flag) or explicitly `--unsafe-channel-creation` flag) or explicitly accepting a request with `--accept-channel`:
accepting a request with `--accept-channel`:
``` ```shell
$ client --password user-password --ndf ndf.json -l client.log -s session-directory --destfile user-contact.json --accept-channel $ ./client --password user-password --ndf ndf.json -l client.log -s session-directory --destfile user-contact.json --accept-channel
Authentication channel request from: yYAztmoCoAH2VIr00zPxnj/ZRvdiDdURjdDWys0KYI4D Authentication channel request from: yYAztmoCoAH2VIr00zPxnj/ZRvdiDdURjdDWys0KYI4D
Sending to yYAztmoCoAH2VIr00zPxnj/ZRvdiDdURjdDWys0KYI4D: Sending to yYAztmoCoAH2VIr00zPxnj/ZRvdiDdURjdDWys0KYI4D:
Message received: Message received:
Received 1 Received 1
``` ```
#### Receiving Messages ### Receiving Messages
There is no explicit command for receiving messages. Instead, the client will attempt to fetch pending messages on each There is no explicit command for receiving messages. Instead, the client will attempt to fetch pending messages on each
run. run.
You can use the `--receiveCount` flag to limit the number of messages the client waits for before a timeout occurs: You can use the `--receiveCount` flag to limit the number of messages the client waits for before a timeout occurs:
``` ```shell
$ client --password <password> --ndf <NDF JSON file> -l client.log -s <session directory> --destfile <contact JSON file> --receiveCount <integer count> $ ./client --password <password> --ndf <NDF JSON file> -l client.log -s <session directory> --destfile <contact JSON file> --receiveCount <integer count>
``` ```
#### Sending Authenticated Channel Requests ### Sending Authenticated Channel Requests
See [Sending Safe Messages Between Two (2) Users](#sending-safe-messages-between-two-2-users) See [Sending Safe Messages Between Two (2) Users](#sending-safe-messages-between-two-2-users)
#### Confirming Authenticated Channel Requests ### Confirming Authenticated Channel Requests
Setting up an authenticated channel between clients is a back-and-forth process that happens in sequence. One client Setting up an authenticated channel between clients is a back-and-forth process that happens in sequence. One client
sends a request and waits for the other to accept it. sends a request and waits for the other to accept it.
See the previous section, [Sending safe messages between 2 users](#sending-safe-messages-between-2-users), for example See the previous section, [Sending safe messages between 2 users](#sending-safe-messages-between-two-2-users), for example,
commands showing how to set up an end-to-end connection between clients before sending messages. commands showing how to set up an end-to-end connection between clients before sending messages.
As with received messages, there is no command for checking for authenticated channel requests; you'll be notified of As with received messages, there is no command for checking for authenticated channel requests; you'll be notified of
any pending requests whenever the client is run. any pending requests whenever the client is run.
``` ```shell
$ ./client.win64 --password password --ndf ndf.json -l client.log -s session-directory --destfile user-contact8.json --waitTimeout 120 -m "Hi User 7, from User 8 with E2E Encryption" $ ./client.win64 --password password --ndf ndf.json -l client.log -s session-directory --destfile user-contact8.json --waitTimeout 120 -m "Hi User 7, from User 8 with E2E Encryption"
Authentication channel request from: 8zAWY69UUK/FkMBGY3ViR5MMfcp1GoKn6Y3c/64NYNYD Authentication channel request from: 8zAWY69UUK/FkMBGY3ViR5MMfcp1GoKn6Y3c/64NYNYD
Sending to yYAztmoCoAH2VIr00zPxnj/ZRvdiDdURjdDWys0KYI4D: Hi User 7, from User 8 with E2E Encryption Sending to yYAztmoCoAH2VIr00zPxnj/ZRvdiDdURjdDWys0KYI4D: Hi User 7, from User 8 with E2E Encryption
...@@ -206,7 +204,7 @@ Received 0 ...@@ -206,7 +204,7 @@ Received 0
``` ```
##### Troubleshooting ### Troubleshooting
**`panic: Could not confirm authentication channel for ...`** **`panic: Could not confirm authentication channel for ...`**
...@@ -218,7 +216,7 @@ Retrying the request should fix this. If necessary, you may increase the time th ...@@ -218,7 +216,7 @@ Retrying the request should fix this. If necessary, you may increase the time th
before timeout using the `--auth-timeout` flag (default 120s). before timeout using the `--auth-timeout` flag (default 120s).
This error will also occur with the receiving client if it received the request but failed to confirm it before the This error will also occur with the receiving client if it received the request but failed to confirm it before the
requesting client reached a timeout. In this case, the request needs to be resent while the other client reattempts to requesting client reached a timeout. In this case, the request must be resent while the other client reattempts to
confirm the channel. confirm the channel.
**`panic: Received request not found`** **`panic: Received request not found`**
...@@ -226,9 +224,9 @@ confirm the channel. ...@@ -226,9 +224,9 @@ confirm the channel.
You may also run into the `panic: Received request not found` error when attempting to confirm an authenticated channel You may also run into the `panic: Received request not found` error when attempting to confirm an authenticated channel
request. This means your client has not received the request. If one has been sent, simply retrying should fix this. request. This means your client has not received the request. If one has been sent, simply retrying should fix this.
Full usage of client can be found with `client --help`: Full usage of the client can be found with `client --help`:
``` ```shell
$ ./client --help $ ./client --help
Runs a client for cMix anonymous communication platform Runs a client for cMix anonymous communication platform
...@@ -237,6 +235,7 @@ Usage: ...@@ -237,6 +235,7 @@ Usage:
client [command] client [command]
Available Commands: Available Commands:
broadcast Send broadcast messages
fileTransfer Send and receive file for cMix client fileTransfer Send and receive file for cMix client
generate Generates version and dependency information for the Elixxir binary generate Generates version and dependency information for the Elixxir binary
getndf Download the network definition file from the network and print it. getndf Download the network definition file from the network and print it.
...@@ -249,20 +248,24 @@ Available Commands: ...@@ -249,20 +248,24 @@ Available Commands:
Flags: Flags:
--accept-channel Accept the channel request for the corresponding recipient ID --accept-channel Accept the channel request for the corresponding recipient ID
--auth-timeout uint The number of seconds to wait for an authentication channelto confirm (default 120) --auth-timeout uint The number of seconds to wait for an authentication channelto confirm (default 60)
--delete-all-requests Delete the all contact requests, both sent and received. --backupIdList string JSON file containing the backed up partner IDs
--backupIn string Path to load backup client from --backupIn string Path to load backup client from
--backupOut string Path to output backup client. --backupJsonOut string Path to output unencrypted client JSON backup.
--backupOut string Path to output encrypted client backup. If no path is supplied, the backup system is not started.
--backupPass string Passphrase to encrypt/decrypt backup --backupPass string Passphrase to encrypt/decrypt backup
--delete-channel Delete the channel information for the corresponding recipient ID --delete-all-requests DeleteFingerprint the all contact requests, both sent and received.
--delete-receive-requests Delete the all received contact requests. --delete-channel DeleteFingerprint the channel information for the corresponding recipient ID
--delete-sent-requests Delete the all sent contact requests. --delete-receive-requests DeleteFingerprint the all received contact requests.
--delete-request DeleteFingerprint the request for the specified ID given by the destfile flag's contact file.
--delete-sent-requests DeleteFingerprint the all sent contact requests.
--destfile string Read this contact file for the destination id --destfile string Read this contact file for the destination id
-d, --destid string ID to send message to (if below 40, will be precanned. Use '0x' or 'b64:' for hex and base64 representations) (default "0") -d, --destid string ID to send message to (if below 40, will be precanned. Use '0x' or 'b64:' for hex and base64 representations) (default "0")
--e2eMaxKeys uint Max keys used before blocking until a rekey completes (default 800) --e2eMaxKeys uint Max keys used before blocking until a rekey completes (default 2000)
--e2eMinKeys uint Minimum number of keys used before requesting rekey (default 500) --e2eMinKeys uint Minimum number of keys used before requesting rekey (default 1000)
--e2eNumReKeys uint Number of rekeys reserved for rekey operations (default 16) --e2eNumReKeys uint Number of rekeys reserved for rekey operations (default 16)
--e2eRekeyThreshold float64 Number between 0 an 1. Percent of keys used before a rekey is started --e2eRekeyThreshold float Number between 0 an 1. Percent of keys used before a rekey is started (default 0.05)
--force-legacy Force client to operate using legacy identities.
--forceHistoricalRounds Force all rounds to be sent to historical round retrieval --forceHistoricalRounds Force all rounds to be sent to historical round retrieval
--forceMessagePickupRetry Enable a mechanism which forces a 50% chance of no message pickup, instead triggering the message pickup retry mechanism --forceMessagePickupRetry Enable a mechanism which forces a 50% chance of no message pickup, instead triggering the message pickup retry mechanism
-h, --help help for client -h, --help help for client
...@@ -275,13 +278,14 @@ Flags: ...@@ -275,13 +278,14 @@ Flags:
--protoUserOut string Path to which a normally constructed client will write proto user JSON file --protoUserOut string Path to which a normally constructed client will write proto user JSON file
--protoUserPath string Path to proto user JSON file containing cryptographic primitives the client will load --protoUserPath string Path to proto user JSON file containing cryptographic primitives the client will load
--receiveCount uint How many messages we should wait for before quitting (default 1) --receiveCount uint How many messages we should wait for before quitting (default 1)
--regcode string Identity code (optional) --regcode string ReceptionIdentity code (optional)
--send-auth-request Send an auth request to the specified destination and waitfor confirmation --send-auth-request Send an auth request to the specified destination and waitfor confirmation
--sendCount uint The number of times to send the message (default 1) --sendCount uint The number of times to send the message (default 1)
--sendDelay uint The delay between sending the messages in ms (default 500) --sendDelay uint The delay between sending the messages in ms (default 500)
--sendid uint Use precanned user id (must be between 1 and 40, inclusive) --sendid uint Use precanned user id (must be between 1 and 40, inclusive)
-s, --session string Sets the initial storage directory for client session data -s, --session string Sets the initial storage directory for client session data
--slowPolling Enables polling for unfiltered network updates with RSA signatures --slowPolling Enables polling for unfiltered network updates with RSA signatures
--splitSends Force sends to go over multiple rounds if possible
--unsafe Send raw, unsafe messages without e2e encryption. --unsafe Send raw, unsafe messages without e2e encryption.
--unsafe-channel-creation Turns off the user identity authenticated channel check, automatically approving authenticated channels --unsafe-channel-creation Turns off the user identity authenticated channel check, automatically approving authenticated channels
--verboseRoundTracking Verbose round tracking, keeps track and prints all rounds the client was aware of while running. Defaults to false if not set. --verboseRoundTracking Verbose round tracking, keeps track and prints all rounds the client was aware of while running. Defaults to false if not set.
...@@ -292,131 +296,111 @@ Flags: ...@@ -292,131 +296,111 @@ Flags:
Use "client [command] --help" for more information about a command. Use "client [command] --help" for more information about a command.
``` ```
**Note:** The client cannot be used on the betanet with precanned user ids. >💡 **Note:** The client cannot be used on the xx network with pre-canned user IDs.
## Library Overview ## Library Overview
The xx client is designed to be used as a go library (and by extension a The xx client is designed to be a go library (and, by extension, a C library).
c library).
Support is also present for go mobile to build Android and iOS libraries. We Support is also present for Go mobile to build Android and iOS libraries. In addition, we bind all exported symbols from
bind all exported symbols from the bindings package for use on mobile the bindings package for use on mobile platforms.
platforms.
### Implementation Notes ### Implementation Notes
Clients need to perform the same actions *in the same order* as shown in Clients must perform the same actions *in the same order* as shown in `cmd/root.go`. Specifically, certain handlers need
`cmd/root.go`. Specifically, certain handlers need to be registered and to be registered and set up before starting network threads. Additionally, you cannot perform certain actions until the
set up before starting network threads. Additionally, you cannot perform certain actions until the network connection network connection reaches a "healthy" state.
reaches a "healthy" state.
Refer to Setting Up a cMix Client in the API documentation for specific on how to do this.
See [main.go](https://git.xx.network/elixxir/xxdk-examples/-/blob/sample-messaging-app/sample-messaging-app/main.go) for relevant code listings on when and how to perform these actions.
The [Getting Started](https://xxdk-dev.xx.network/getting-started) guide provides further detail. See the [xxdk Example repository](https://git.xx.network/elixxir/xxdk-examples/-/tree/master) for various example
implementations.
You can also visit the [API Quick Reference](https://xxdk-dev.xx.network/quick-reference) In addition, the [Getting Started](https://xxdk-dev.xx.network/getting-started) guide provides further detail.
for information on the types and functions exposed by the Client API.
You can also visit the [API Quick Reference](https://xxdk-dev.xx.network/quick-reference) for information on the types
The main entry point for developing with the client is `api/client` (or and functions exposed by the Client API.
`bindings/client`). We recommend using go doc to explore:
The main entry point for developing with the client is `xxdk/cmix` (or `bindings/cmix`). We recommend using the
``` [documentation in the Go package directory](https://pkg.go.dev/gitlab.com/elixxir/client/xxdk).
go doc -all ./api
go doc -all ./interfaces Looking at the API will, for example, show you there is a `RoundEvents` callback registration function, which lets your
``` client see round events.
Looking at the API will, for example, show you there is a RoundEvents callback > ```go
registration function, which lets your client see round events: > func (c *Cmix) GetRoundEvents() interfaces.RoundEvents
> ```
``` > RegisterRoundEventsCb registers a callback for round events.
func (c *Client) GetRoundEvents() interfaces.RoundEvents
RegisterRoundEventsCb registers a callback for round events. And then, inside the `RoundEvents` interfaces:
```
> ```go
and then inside interfaces: > type RoundEvents interface {
> // designates a callback to call on the specified event
``` > // rid is the id of the round the event occurs on
type RoundEvents interface { > // callback is the callback the event is triggered on
// designates a callback to call on the specified event > // timeout is the amount of time before an error event is returned
// rid is the id of the round the event occurs on > // valid states are the states which the event should trigger on
// callback is the callback the event is triggered on > AddRoundEvent(rid id.Round, callback ds.RoundEventCallback,
// timeout is the amount of time before an error event is returned > timeout time.Duration, validStates ...states.Round) *ds.EventCallback
// valid states are the states which the event should trigger on >
AddRoundEvent(rid id.Round, callback ds.RoundEventCallback, > // designates a go channel to signal the specified event
timeout time.Duration, validStates ...states.Round) *ds.EventCallback > // rid is the id of the round the event occurs on
> // eventChan is the channel the event is triggered on
// designates a go channel to signal the specified event > // timeout is the amount of time before an error event is returned
// rid is the id of the round the event occurs on > // valid states are the states which the event should trigger on
// eventChan is the channel the event is triggered on > AddRoundEventChan(rid id.Round, eventChan chan ds.EventReturn,
// timeout is the amount of time before an error event is returned > timeout time.Duration, validStates ...states.Round) *ds.EventCallback
// valid states are the states which the event should trigger on >
AddRoundEventChan(rid id.Round, eventChan chan ds.EventReturn, > // Allows the un-registration of a round event before it triggers
timeout time.Duration, validStates ...states.Round) *ds.EventCallback > Remove(rid id.Round, e *ds.EventCallback)
> }
//Allows the un-registration of a round event before it triggers > ```
Remove(rid id.Round, e *ds.EventCallback)
} Which, when investigated, yields the following prototype.
```
> ```go
Which, when investigated, yields the following prototype: > // Callbacks must use this function signature
> type RoundEventCallback func(ri *pb.RoundInfo, timedOut bool)
``` > ```
// Callbacks must use this function signature
type RoundEventCallback func(ri *pb.RoundInfo, timedOut bool) Showing that you can receive a full `RoundInfo` object for any round event
```
showing that you can receive a full RoundInfo object for any round event
received by the client library on the network. received by the client library on the network.
### Building the Library for iOS and Android ### Building the Library for iOS and Android
To set up Gomobile for Android, install the NDK and pass the -ndk flag To set up gomobile for Android, install the NDK and pass the `-ndk` flag ` $ gomobile init`. Other repositories that use
to ` $ gomobile init`. Other repositories that use Gomobile for gomobile for binding should include a shell script that creates the bindings. For iOS, gomobile must be run on an OS X
binding should include a shell script that creates the bindings. For machine with Xcode installed.
iOS, gomobile must be run on an OS X machine with Xcode installed.
Important reference info: Important reference info:
1. [Setting up Gomobile and subcommands](https://godoc.org/golang.org/x/mobile/cmd/gomobile) 1. [Setting up gomobile and subcommands](https://pkg.go.dev/golang.org/x/mobile/cmd/gomobile)
2. [Reference cycles, type restrictions](https://godoc.org/golang.org/x/mobile/cmd/gobind) 2. [Reference cycles, type restrictions](https://pkg.go.dev/golang.org/x/mobile/cmd/gobind)
To clone and build: To clone and build:
``` ```shell
# Go mobile install # Go mobile install
go get -u golang.org/x/mobile/cmd/gomobile $ go get golang.org/x/mobile/bind
go get -u golang.org/x/mobile/bind $ go install golang.org/x/mobile/cmd/gomobile@latest
gomobile init... # Note this line will be different depending on sdk/target! $ gomobile init... # Note this line will be different depending on sdk/target!
# Get and test code # Get and test code
git clone https://gitlab.com/elixxir/client.git client $ git clone https://gitlab.com/elixxir/client.git client
cd client $ cd client
go mod vendor -v $ go mod vendor
go mod tidy $ go mod tidy
go test ./... $ go test ./...
# Android # Android
gomobile bind -target android -androidapi 21 gitlab.com/elixxir/client/bindings $ gomobile bind -target android -androidapi 21 gitlab.com/elixxir/client/bindings
# iOS # iOS
gomobile bind -target ios gitlab.com/elixxir/client/bindings $ gomobile bind -target ios gitlab.com/elixxir/client/bindings
zip -r iOS.zip Bindings.framework $ zip -r iOS.zip Bindings.framework
``` ```
You can verify that all symbols got bound by unzipping You can verify that all symbols got bound by unzipping `bindings-sources.jar` and inspecting the resulting source files.
`bindings-sources.jar` and inspecting the resulting source files.
Every time you make a change to the client or bindings, you must
rebuild the client bindings into a .aar or iOS.zip to propagate those
changes to the app. There's a script that runs gomobile for you in the
`bindings-integration` repository.
## Roadmap
See the larger network documentation for more, but there are 2 specific
parts of the roadmap that are intended for the client:
* Ephemeral IDs - Sending messages to users with temporal/ephemeral recipient
user identities.
* User Discovery - A bot that will allow the user to look for others on the
network.
* Notifications - An optional notifications system which uses firebase
* Efficiency improvements - mechanisms for message pickup and network tracking
* will evolve to allow tradeoffs and options for use
We are also always looking at simplifying and improving the library interface. Every time you make a change to the client or bindings, you must rebuild the client bindings into a `.aar` or `iOS.zip`
to propagate those changes to the app. There's a script that runs gomobile for you in the `bindings-integration`
repository.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment