working lib setup for tutorial
This commit is contained in:
committed by
mfahampshire
parent
c022486e63
commit
204b2e1101
@@ -38,7 +38,6 @@ chapter-line-height = "2em"
|
||||
section-line-height = "1.5em"
|
||||
|
||||
# if true, never read and touch the files in theme dir
|
||||
turn-off = false
|
||||
|
||||
[preprocessor.admonish]
|
||||
command = "mdbook-admonish"
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
# Building a Cosmos Blockchain Service with the Rust SDK
|
||||
|
||||
This tutorial is for Rust developers wanting to interact with the Rust SDK and take a first step at building a service with which to interact with a blockchain.
|
||||
The key here is to think of the service as a proxy: it interacts with the blockchain _on the client's behalf_, shielding it from the Validator it interacts with, whilst also being shielded from the client by the mixnet!
|
||||
|
||||
The key here is to think of the service as a proxy: it interacts with the blockchain _on the client's behalf_, shielding it from the Validator it interacts with, whilst also being shielded from the client by the mixnet.
|
||||
|
||||
> This service also nicely highlights the limitations of the mixnet - even though with this code your metadata is shielded from the Validator, and even the service does not know your Nym address, application-level information such as a blockchain address is not made private, in virtue of the fact that using the mixnet provides solely network-level privacy. For information on what application-level privacy Nym offers, check out the [coconut credential SDK example]().
|
||||
|
||||
@@ -1,13 +1,92 @@
|
||||
# Preparing Your Lib
|
||||
|
||||
We'll now move on to preparing shared data structures and functions in `src/lib.rs`.
|
||||
Now move on to preparing shared data structures and functions in `src/lib.rs`.
|
||||
|
||||
These include the Request and Response types we'll be passing between the Client and the Service through the mixnet, as well as shared functions such as client creation, and parsing incoming messages.
|
||||
These include the request and response types the client and the service will be passing through the mixnet, as well as shared functions such as client creation, and message parsing.
|
||||
|
||||
## Data Structures
|
||||
## Dependencies
|
||||
The dependecies for the shared `lib` file are the following:
|
||||
```rust
|
||||
use cosmrs::{tendermint, AccountId};
|
||||
use nym_sdk::mixnet::{
|
||||
AnonymousSenderTag, MixnetClient, MixnetClientBuilder, ReconstructedMessage, StoragePaths,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::path::PathBuf;
|
||||
pub mod client;
|
||||
pub mod service;
|
||||
```
|
||||
|
||||
Since this is the file where client creation and message parsing are handled, the various `nym_sdk` imports, as well as `serde`'s (de)serialisation functionality, are required. This file also imports the `client` and `service` specific logic not found in `bin/`, as well as `PathBuf` to read filepaths, and `cosmrs` types for defining Nyx blockchain accounts.
|
||||
|
||||
## Constants
|
||||
Below this are the chain-related `const` variables. These have been hardcoded for this demo.
|
||||
|
||||
```rust
|
||||
pub const DEFAULT_VALIDATOR_RPC: &str = "https://sandbox-validator1.nymtech.net";
|
||||
pub const DEFAULT_DENOM: &str = "unym";
|
||||
pub const DEFAULT_PREFIX: &str = "n";
|
||||
```
|
||||
|
||||
These define the RPC endpoint your service will use to interact with the blockchain - in this case the Sandbox testnet - as well as the coin denomination and Bech32-prefix of the blockchain accounts.
|
||||
|
||||
## Shared Data Structures
|
||||
Define the following structs for our different request and responses that will be serialised and sent through the mixnet between your client and service binaries:
|
||||
|
||||
```rust
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
pub struct SequenceRequest {
|
||||
pub validator: String,
|
||||
pub signer_address: AccountId,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
pub struct SequenceRequestResponse {
|
||||
pub account_number: u64,
|
||||
pub sequence: u64,
|
||||
pub chain_id: tendermint::chain::Id,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum RequestTypes {
|
||||
Sequence(SequenceRequest),
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum ResponseTypes {
|
||||
Sequence(SequenceRequestResponse),
|
||||
}
|
||||
```
|
||||
|
||||
TODO explainer of each
|
||||
|
||||
## Shared Functions
|
||||
Now to define functions shared by the `client` and `service` binaries.
|
||||
|
||||
### Client Creation
|
||||
The following function is called on startup by each binary, with the `config_path` being a filepath for storing client config.
|
||||
|
||||
### Parsing Incoming
|
||||
```rust
|
||||
// create our client with specified path for key storage
|
||||
pub async fn create_client(config_path: PathBuf) -> MixnetClient {
|
||||
let config_dir = config_path;
|
||||
let storage_paths = StoragePaths::new_from_dir(&config_dir).unwrap();
|
||||
let client = MixnetClientBuilder::new_with_default_storage(storage_paths)
|
||||
.await
|
||||
.unwrap()
|
||||
.build()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
client.connect_to_mixnet().await.unwrap()
|
||||
}
|
||||
```
|
||||
|
||||
> If keys and config already exist at this location, re-running this function **will not** overwrite them.
|
||||
|
||||
### Parsing Incoming messages
|
||||
TODO smoosh them into one function with the return type being an `Option<sender_tag>` instead
|
||||
|
||||
Next to define two functions: one for listening _for_ messages from the mixnet (used by our `service`), and one for listening out for a _reply_ after sending a message to another Nym client (in this case, when sending a message from the `client` to the `service`).
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
This tutorial involves writing two pieces of code in Rust:
|
||||
|
||||
- A client side binary used to construct a blockchain query and send this query to a service, which will interact with a Cosmos SDK blockchain on our behalf.
|
||||
- A client side binary used to construct a blockchain query and send this query to a service, which will interact with a Cosmos SDK blockchain on our behalf (bear in mind this principle works for all blockchains - we're just utilising the `cosmrs` library to interact with the Nyx blockchain in this tutorial).
|
||||
- A service which will listen out for requests from the mixnet, act on those requests, and anonymously reply to the client sending the requests.
|
||||
|
||||
You will learn how to do the following with the Rust SDK:
|
||||
|
||||
@@ -20,13 +20,47 @@ cargo new nym-cosmos-service
|
||||
└── src
|
||||
├── client.rs
|
||||
├── lib.rs
|
||||
├── main.rs
|
||||
└── service.rs
|
||||
|
||||
3 directories, 7 files
|
||||
3 directories, 6 files
|
||||
```
|
||||
|
||||
* Finally add the following dependencies - you can just copy and paste this into your `Cargo.toml` file:
|
||||
* Add the following dependencies to your `Cargo.toml` file:
|
||||
```
|
||||
TODO pull validator client code etc from the monorepo instead of workspace loading
|
||||
[dependencies]
|
||||
anyhow = "1.0.72"
|
||||
clap = { version = "4.0", features = ["derive"] }
|
||||
bip39 = { version = "2.0.0", features = ["zeroize"] }
|
||||
cosmrs = "=0.14.0"
|
||||
TODO
|
||||
# tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
|
||||
tokio = "1.24.1"
|
||||
bs58 = "0.5.0"
|
||||
serde = "1.0.152"
|
||||
serde_json = "1.0.91"
|
||||
```
|
||||
|
||||
These are non Nym-specific dependencies for the project. `anyhow` is for catch-all error handling, `clap` is for setting up the CLI commands, `cosmrs` for cosmos-specific types and functionality, `tokio` for the async/await environment, and `serde` for (de)serialisation.
|
||||
|
||||
* Next add Nym-specific dependencies. Since these libraries are not yet on [crates io](https://crates.io) then you need to import them from the Nym monorepo:
|
||||
```
|
||||
nym-sdk = { git = "https://github.com/nymtech/nym" }
|
||||
nym-sphinx-addressing = { git = "https://github.com/nymtech/nym" }
|
||||
nym-validator-client = { git = "https://github.com/nymtech/nym" }
|
||||
nym-bin-common = { git = "https://github.com/nymtech/nym" }
|
||||
nym-sphinx-anonymous-replies = { git = "https://github.com/nymtech/nym" }
|
||||
```
|
||||
|
||||
The `sphinx` dependencies are for packet- and address-related functionality, the `validator-client` for Nyx blockchain specific configs, `common` for client logging, and the `sdk` for SDK functionality: creating and managing client storage and connections, and sending and receiving messages to and from the mixnet.
|
||||
|
||||
* Finally add the following underneath your `[dependencies]`:
|
||||
```
|
||||
[[bin]]
|
||||
name = "client"
|
||||
path = "bin/client.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "service"
|
||||
path = "bin/service.rs"
|
||||
```
|
||||
This defines multiple binaries to run in a single cargo project, as outlined [here](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#binaries).
|
||||
|
||||
Reference in New Issue
Block a user