finished first pass at tutorial
This commit is contained in:
@@ -28,21 +28,24 @@
|
||||
|
||||
# Tutorials
|
||||
|
||||
- [(Rust SDK) Cosmos Blockchain Service](tutorials/cosmos-service/intro.md)
|
||||
- [Tutorial Overview](tutorials/cosmos-service/overview.md)
|
||||
- [Preparing Your Environment](tutorials/cosmos-service/preparing-env.md)
|
||||
- [Preparing Your Lib](tutorials/cosmos-service/lib.md)
|
||||
- [Preparing Your Client](tutorials/cosmos-service/client.md)
|
||||
- [Preparing Your Client pt2](tutorials/cosmos-service/client-src.md)
|
||||
- [Preparing Your Service](tutorials/cosmos-service/service.md)
|
||||
- [Preparing Your Service pt2](tutorials/cosmos-service/service-src.md)
|
||||
- [(Typescript) Simple Service Provider](tutorials/simple-service-provider/simple-service-provider.md)
|
||||
- [Tutorial Overview](tutorials/simple-service-provider/overview.md)
|
||||
- [Preparing Your User Client Environment](tutorials/simple-service-provider/preparating-env.md)
|
||||
- [Building Your User Client](tutorials/simple-service-provider/user-client.md)
|
||||
- [Preparing Your Service Provider Environment](tutorials/simple-service-provider/preparating-env2.md)
|
||||
- [Building Your Service Provider](tutorials/simple-service-provider/service-provider.md)
|
||||
- [Sending a Message Through the Mixnet](tutorials/simple-service-provider/sending-message.md)
|
||||
- [Rust SDK](tutorials/rust-sdk.md)
|
||||
- [Blockchain Service pt1](tutorials/cosmos-service/intro.md)
|
||||
- [Tutorial Overview](tutorials/cosmos-service/overview.md)
|
||||
- [Preparing Your Environment](tutorials/cosmos-service/preparing-env.md)
|
||||
- [Preparing Your Lib](tutorials/cosmos-service/lib.md)
|
||||
- [Preparing Your Client](tutorials/cosmos-service/client.md)
|
||||
- [Preparing Your Client pt2](tutorials/cosmos-service/client-src.md)
|
||||
- [Preparing Your Service](tutorials/cosmos-service/service.md)
|
||||
- [Preparing Your Service pt2](tutorials/cosmos-service/service-src.md)
|
||||
- [Querying the Chain](tutorials/cosmos-service/querying.md)
|
||||
- [Typescript](tutorials/typescript.md)
|
||||
- [Simple Service Provider](tutorials/simple-service-provider/simple-service-provider.md)
|
||||
- [Tutorial Overview](tutorials/simple-service-provider/overview.md)
|
||||
- [Preparing Your User Client Environment](tutorials/simple-service-provider/preparating-env.md)
|
||||
- [Building Your User Client](tutorials/simple-service-provider/user-client.md)
|
||||
- [Preparing Your Service Provider Environment](tutorials/simple-service-provider/preparating-env2.md)
|
||||
- [Building Your Service Provider](tutorials/simple-service-provider/service-provider.md)
|
||||
- [Sending a Message Through the Mixnet](tutorials/simple-service-provider/sending-message.md)
|
||||
|
||||
|
||||
# Community Resources
|
||||
|
||||
@@ -14,7 +14,7 @@ use nym_validator_client::nyxd::Coin
|
||||
# Querying via the Mixnet
|
||||
The following is used to construct a `BalanceRequest`, send this to the supplied `service` address, and then handle the response, matching it to a `ResponseType`, in this case the only expected response, a `BalanceResponse`.
|
||||
|
||||
The actual sending of the request is performed by `client.send_bytes`: sending the serialised `BalanceRequest` to the supplied Nym address (the `Recipient` imported from the `nym_sphinx_addressing` crate). It is sending the default number of SURBs along with the message, defined [here](LINK_TO_SURB_DEFAULT_NUMBEr).
|
||||
The actual sending of the request is performed by `client.send_bytes`: sending the serialised `BalanceRequest` to the supplied Nym address (the `Recipient` imported from the `nym_sphinx_addressing` crate). It is sending the default number of SURBs along with the message, defined [here](https://github.com/nymtech/nym/blob/develop/sdk/rust/nym-sdk/src/mixnet/client.rs#L34).
|
||||
|
||||
```rust
|
||||
pub async fn query_balance(
|
||||
|
||||
@@ -4,4 +4,4 @@ This tutorial is for Rust developers wanting to interact with the Rust SDK and t
|
||||
|
||||
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](RELATIVE_PATH).
|
||||
> 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](https://nymtech.net/docs/sdk/rust.html#coconut-credential-generation).
|
||||
|
||||
@@ -79,7 +79,7 @@ impl ResponseTypes {
|
||||
}
|
||||
```
|
||||
|
||||
The above data types are pretty straightforward. Even though there are only one instance of a request type (sent from client to service) and one of a response type (service -> client) so far, a pair of enums has been defined to contain additional response or request types that will be added in the future.
|
||||
The above data types are pretty straightforward. Even though there are only one instance of a request type (sent from client -> service) and one of a response type (service -> client) so far, a pair of enums has been defined to contain additional response or request types that will be added in the future.
|
||||
|
||||
`BalanceRequest` will be used when requesting the service to query the token balance of the supplied address on the client's behalf. You can see the information that will be returned from the chain to the service, and from the service to the client, in `BalanceResponse`.
|
||||
|
||||
@@ -114,7 +114,7 @@ Next to define two functions: one for listening _for_ messages from the mixnet (
|
||||
|
||||
Both functions attempt to deserialise the vec of `ReconstructedMessages` that are reconstructed by the client from delivered Sphinx packets after decryption.
|
||||
|
||||
`handle_request` performs one additional function - parsing the `sender_tag` from the incoming reconstructed message. This is the randomised alphanumeric string used to identify a bucket of _SURBs_ (_S_ingle _U_se _R_eply _B_locks) that are sent along with any outgoing message by default. More information about them can be found [here](LINK_TO_SURBS_DOCS) but all that is necessary to know for now is that these are pre-addressed packets that clients send out with their messages. Any reply to their message that is to be sent back to them back be written to the payload of these packets, but without the entity seeing the destination address. This allows for services to _anonymously reply_ to clients without being able to doxx them.
|
||||
`handle_request` performs one additional function - parsing the `sender_tag` from the incoming reconstructed message. This is the randomised alphanumeric string used to identify a bucket of _SURBs_ (Single Use Reply Blocks) that are sent along with any outgoing message by default. More information about them can be found [here](https://nymtech.net/docs/architecture/traffic-flow.html#private-replies-using-surbs) but all that is necessary to know for now is that these are pre-addressed packets that clients send out with their messages. Any reply to their message that is to be sent back to them back be written to the payload of these packets, but without the entity seeing the destination address. This allows for services to _anonymously reply_ to clients without being able to doxx them.
|
||||
|
||||
```rust
|
||||
pub fn handle_response(message: ReconstructedMessage) -> anyhow::Result<ResponseTypes> {
|
||||
@@ -129,7 +129,7 @@ pub fn handle_request(
|
||||
}
|
||||
```
|
||||
|
||||
Before moving on to the `client` and `service` code, one more function is needed. This allows for both binaries to parse empty incoming messages that they might receive. This is necessary as incoming SURBs as well as requests for more SURBs contain empty data fields for the moment.
|
||||
Before moving on to the `client` and `service` code, one more function is needed. This allows for both binaries to parse empty incoming messages that they might receive. This is necessary as incoming SURBs as well as requests for more SURBs contain empty data fields.
|
||||
|
||||
```rust
|
||||
pub async fn wait_for_non_empty_message(
|
||||
|
||||
@@ -13,30 +13,21 @@ You will learn how to do the following with the Rust SDK:
|
||||
|
||||
|
||||
```
|
||||
+----------+ +----------+ +----------+
|
||||
| Mix Node |<-----------> | Mix Node |<----------->| Mix Node |
|
||||
| Layer 1 | | Layer 2 | | Layer 3 |
|
||||
+----------+ +----------+ +----------+
|
||||
^ ^
|
||||
| |
|
||||
|<--------------------------------------------------+
|
||||
|
|
||||
v
|
||||
+--------------+
|
||||
| Your gateway |
|
||||
+--------------+
|
||||
^
|
||||
|
|
||||
|
|
||||
v
|
||||
+-------------------------------------------+
|
||||
| |
|
||||
| +-------------+ +--------------+ |
|
||||
| | Client code | | Service code | |
|
||||
| +-------------+ +--------------+ |
|
||||
| |
|
||||
+-------------------------------------------+
|
||||
Your Local Machine
|
||||
|
||||
TODO
|
||||
|
||||
REDRAW
|
||||
|
||||
ASCII
|
||||
|
||||
DIAGRAM
|
||||
|
||||
FROM
|
||||
|
||||
PREVIOUS
|
||||
|
||||
TUTORIAL
|
||||
|
||||
```
|
||||
|
||||
You can find the code for these components [here](). You can use it as a reference while building or simply download it and follow along as you progress through the tutorial.
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# Querying the Chain
|
||||
Now that all the code has been written, time to query the blockchain.
|
||||
|
||||
To test against the account operating one of the mix nodes on the testnet, use `n1lcutqz94k739s39u26rvexql40ehf42zd27fwe` in the following instructions:
|
||||
|
||||
```sh
|
||||
# build the binaries
|
||||
cargo build --release
|
||||
|
||||
# open two console windows. In one run the following
|
||||
./target/release/service
|
||||
|
||||
# copy the printed Nym address from the console - this is used by the client when running the chain query
|
||||
|
||||
# in the other run
|
||||
./target/release/client query-balance n1lcutqz94k739s39u26rvexql40ehf42zd27fwe <SERVICE_ADDRESS_FROM_CLIPBOARD>
|
||||
```
|
||||
|
||||
The following happens:
|
||||
* `client` and `service` both start their Nym clients and log the address. `service` is listening for incoming messages from the mixnet.
|
||||
* `client` sends a request to `service` using the supplied `n1...` address as the Nyx account to query the balance of, and the supplied Nym address to communicate with this instance of `service`.
|
||||
* `service` queries the Sandbox testnet blockchain using the `broadcaster` http client. It then serialises the response and returns it using SURBs to the `client`.
|
||||
|
||||
All in all, quite simple. By using the service as a proxy, the client never interacts with the blockchain, thus is not revealing metadata to the operator of the chain or anyone watching incoming traffic to it. Furthermore, the client doesn't even need to share its Nym address with the service, as the service is able to reply via SURBs.
|
||||
|
||||
## Creating Sandbox Account
|
||||
If you wish to create an account on Sandbox to use instead of the supplied account above, the easiest way is by building the `nym-cli` tool and using that to create one:
|
||||
|
||||
```sh
|
||||
# start from the root of the nym monorepo
|
||||
cd tools/nym-cli
|
||||
# build
|
||||
cargo build --release
|
||||
# create account using Sandbox testnet environment
|
||||
../../target/release/nym-cli --config-env-file ../../envs/sandbox.env account create
|
||||
```
|
||||
|
||||
However, since this account is fresh, it won't have any tokens. Querying the balance will still work obviously, it will just return `0`.
|
||||
|
||||
## Get Tokens
|
||||
We're working on getting the faucet up and running again in preparation for part 2 of this tutorial: using the tokens you have privately checked the balance of to generate a [bandwidth credential](https://nymtech.net/docs/bandwidth-credentials.html).
|
||||
|
||||
If you wish to get testnet tokens already then feel free to ask in the [Dev channel](https://matrix.to/#/#dev:nymtech.chat) on Matrix.
|
||||
@@ -1 +1,45 @@
|
||||
# Preparing Your Service pt2
|
||||
|
||||
Now to define the logic of creating the `broadcaster` for interacting with the blockchain, and querying it in `src/service.rs`.
|
||||
|
||||
## Dependencies
|
||||
The following dependencies are for creating a client to interact with the blockchain, and deal with the returned `Coin` type expected from the balance query.
|
||||
|
||||
```rust
|
||||
use crate::{BalanceResponse, DEFAULT_DENOM, DEFAULT_VALIDATOR_RPC};
|
||||
use cosmrs::rpc::HttpClient;
|
||||
use cosmrs::AccountId;
|
||||
use nym_validator_client::nyxd::{Coin, CosmWasmClient};
|
||||
```
|
||||
|
||||
## Creating a `broadcaster`
|
||||
The `broadcaster` is an `HttpClient` taken from `cosmrs`, created with the `DEFAULT_VALIDATOR_RPC` as its default endpoint. The service will use this to query the Sandbox testnet chain.
|
||||
|
||||
```rust
|
||||
pub async fn create_broadcaster() -> anyhow::Result<HttpClient> {
|
||||
let broadcaster: HttpClient = HttpClient::new(DEFAULT_VALIDATOR_RPC)?;
|
||||
Ok(broadcaster)
|
||||
}
|
||||
```
|
||||
|
||||
## Querying the Chain
|
||||
Now to write the logic for querying the chain, using the `broadcaster` created in the previous step to query for the balance of the `account` that the client sent via the mixnet in the `BalanceRequest`. This function returns a `BalanceResponse` containing a `Coin` type, denoting the `balance` and `denom` returned by `get_balance()`.
|
||||
|
||||
```rust
|
||||
pub async fn get_balance(
|
||||
broadcaster: HttpClient,
|
||||
account: AccountId,
|
||||
) -> anyhow::Result<BalanceResponse> {
|
||||
let balance = broadcaster
|
||||
.get_balance(&account, DEFAULT_DENOM.to_string())
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
Ok(BalanceResponse {
|
||||
balance: Coin {
|
||||
amount: balance.amount,
|
||||
denom: balance.denom,
|
||||
},
|
||||
})
|
||||
}
|
||||
```
|
||||
@@ -17,7 +17,7 @@ The imports from `chain_query` are most of the data types and functions defined
|
||||
The `AnonymousSenderTag` type is used for SURBs.
|
||||
|
||||
## main()
|
||||
Also using [tokio](URL) for the async runtime, `main` does the following:
|
||||
Also using tokio for the async runtime, `main` does the following:
|
||||
* If not already existing, creates a Nym client with config at `/tmp/client`. Otherwise it loads the already existing client from this config.
|
||||
* Create a `broadcaster` - this is used by the service to interact with the blockchain, using the consts defined in `src/lib.rs` as chain config.
|
||||
* Listen out for incoming messages, and in much the same way as the `client`, handle and match the incoming request.
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# Rust SDK
|
||||
|
||||
The Rust SDK allows developers building applications in Rust to import and interact with Nym clients as they would any other dependency, instead of running the client as a seperate process on their machine.
|
||||
|
||||
[Read the docs](https://nymtech.net/docs/sdk/rust.html).
|
||||
@@ -0,0 +1 @@
|
||||
# Rust SDK
|
||||
@@ -0,0 +1,3 @@
|
||||
# Typescript
|
||||
|
||||
Tutorial code in this section is built to interact with a standalone Nym client. You can read about interacting with standalone clients [here](https://nymtech.net/docs/clients/websocket-client.html#connecting-to-the-local-websocket), although it is usually preferable to use the [Typescript SDK](https://nymtech.net/docs/sdk/typescript.html).
|
||||
Reference in New Issue
Block a user