Skip to content

Commit

Permalink
feat: adding rust client tutorial (#1582)
Browse files Browse the repository at this point in the history
* feat: adding rust client tutorial

* Apply suggestions from code review

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: sidebar

---------

Co-authored-by: joshcs.eth <[email protected]>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: jcstein <[email protected]>
  • Loading branch information
4 people authored Jun 18, 2024
1 parent 63461aa commit e3f080b
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 9 deletions.
4 changes: 4 additions & 0 deletions .vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,10 @@ function sidebarHome() {
text: "Golang client tutorial",
link: "/developers/golang-client-tutorial",
},
{
text: "Rust client tutorial",
link: "/developers/rust-client-tutorial",
},
{
text: "Celestia-node RPC API documentation",
link: "https://node-rpc-docs.celestia.org/",
Expand Down
8 changes: 1 addition & 7 deletions developers/golang-client-tutorial.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
---
next:
text: "Prompt Scavenger"
link: "/developers/prompt-scavenger"
---

# Golang client library guide {#golang-client-library}
# Golang client library tutorial {#golang-client-library}

This section tutorial will guide you through using the most common RPC endpoints with the golang client library.

Expand Down
4 changes: 2 additions & 2 deletions developers/prompt-scavenger.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
description: Learn how to interact with the Celestia Node API with this tutorial.
prev:
text: "Golang client tutorial"
link: "/developers/golang-client-tutorial"
text: "Rust client tutorial"
link: "/developers/rust-client-tutorial"
---

# Prompt scavenger
Expand Down
145 changes: 145 additions & 0 deletions developers/rust-client-tutorial.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
---
next:
text: "Prompt Scavenger"
link: "/developers/prompt-scavenger"
---

# Rust client library tutorial {#rust-client-library}

This section tutorial will guide you through using the most common RPC endpoints with [Lumina](https://github.com/eigerco/lumina/tree/main/rpc)'s rust client library.

You will need to
[setup dependencies, install, and run celestia-node](./node-tutorial.md#setting-up-dependencies)
if you have not already.

## Project setup

To start, add `celestia_rpc` and `celestia_types` as a dependency to your project:

```bash
cargo add celestia_rpc celestia_types
```

To use the following methods, you will need the node URL and your auth token. To get your auth token, see this [guide](./node-tutorial.md#auth-token). To run your node without an auth token, you can use the `--rpc.skip-auth` flag when starting your node. This allows you to pass an empty string as your auth token.

The default URL is `http://localhost:26658`. If you would like to use subscription methods, such as `SubscribeHeaders` below, you must use the `ws` protocol in place of `http`: `ws://localhost:26658`.

## Submitting and retrieving blobs

The [blob.Submit](https://node-rpc-docs.celestia.org/?version=v0.11.0#blob.Submit) method takes an array of blobs and a gas price, returning the height the blob was successfully posted at.

- The namespace can be generated with `Namespace::new_v0`.
- The blobs can be generated with `Blob::new`.
- You can set `GasPrice::default()` as the gas price to have celestia-node automatically determine an appropriate gas price.

The [blob.GetAll](https://node-rpc-docs.celestia.org/?version=v0.11.0#blob.GetAll) method takes a height and array of namespaces, returning the array of blobs found in the given namespaces.

```rust
use celestia_rpc::{BlobClient, Client, HeaderClient, ShareClient};
use celestia_types::blob::GasPrice;
use celestia_types::{nmt::Namespace, Blob, ExtendedDataSquare};

async fn submit_blob(url: &str, token: &str) {
let client = Client::new(url, Some(token))
.await
.expect("Failed creating rpc client");

// let's use the DEADBEEF namespace
let namespace = Namespace::new_v0(&[0xDE, 0xAD, 0xBE, 0xEF]).expect("Invalid namespace");

// create a blob
let blob = Blob::new(namespace, b"Hello, World!".to_vec()).expect("Blob creation failed");

// submit the blob to the network
let height = client
.blob_submit(&[blob.clone()], GasPrice::default())
.await
.expect("Failed submitting blob");

println!("Blob was included at height {}", height);

// fetch the blob back from the network
let retrieved_blobs = client
.blob_get_all(height, &[namespace])
.await
.expect("Failed to retrieve blobs");

assert_eq!(retrieved_blobs.len(), 1);
assert_eq!(retrieved_blobs[0].data, b"Hello, World!");
assert_eq!(retrieved_blobs[0].commitment, blob.commitment);
}
```

## Subscribing to new headers

You can subscribe to new headers using the [header.Subscribe](https://node-rpc-docs.celestia.org/?version=v0.11.0#header.Subscribe) method. This method returns a `Subscription` that will receive new headers as they are produced. In this example, we will fetch all blobs at the height of the new header in the `0xDEADBEEF` namespace.

```rust
async fn subscribe_headers(url: &str, token: &str) {
let client = Client::new(url, Some(token))
.await
.expect("Failed creating rpc client");

let mut header_sub = client
.header_subscribe()
.await
.expect("Failed subscribing to incoming headers");

// setup the namespace we will filter blobs by
let namespace = Namespace::new_v0(&[0xDE, 0xAD, 0xBE, 0xEF]).expect("Invalid namespace");

while let Some(extended_header) = header_sub.next().await {
match extended_header {
Ok(header) => {
let height = header.header.height.value();
// fetch all blobs at the height of the new header

let blobs = match client.blob_get_all(height, &[namespace]).await {
Ok(blobs) => blobs,
Err(e) => {
eprintln!("Error fetching blobs: {}", e);
continue;
}
};

println!(
"Found {} blobs at height {} in the 0xDEADBEEF namespace",
blobs.len(),
height
);
}
Err(e) => {
eprintln!("Error receiving header: {}", e);
}
}
}
}

```

## Fetching an Extended Data Square (EDS)

You can fetch an [Extended Data Square (EDS)](https://celestiaorg.github.io/celestia-app/specs/data_structures.html#erasure-coding) using the [share.GetEDS](https://node-rpc-docs.celestia.org/?version=v0.11.0#share.GetEDS) method. This method takes a header and returns the EDS at the given height.

```rust
async fn get_eds(url: &str, token: &str) -> ExtendedDataSquare {
let client = Client::new(url, Some(token))
.await
.expect("Failed creating rpc client");

// first get the header of the block you want to fetch the EDS from
let latest_header = client
.header_local_head()
.await
.expect("Failed fetching header");

client
.share_get_eds(&latest_header)
.await
.expect("Failed to get EDS from latest header")
}
```

## API documentation

To see the full list of available methods, see the [API documentation](https://node-rpc-docs.celestia.org/?version=v0.11.0).

0 comments on commit e3f080b

Please sign in to comment.