Skip to content

Commit

Permalink
Add hello world example (#360)
Browse files Browse the repository at this point in the history
* Add hello world example

* Update wasm

* Update scripts

* Update docs

* update hello readme

* update docs + schema

* Update docs

Co-authored-by: Rashad Alston <rashad@Rashads-MacBook-Pro.local>
  • Loading branch information
ra0x3 and Rashad Alston authored Nov 30, 2022
1 parent d32175a commit 0d406b9
Show file tree
Hide file tree
Showing 52 changed files with 1,139 additions and 330 deletions.
33 changes: 33 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
resolver = "2"
members = [
"examples/block-explorer/explorer-index",
"examples/hello-world/hello-bin",
"examples/hello-world/hello-index",
"examples/simple-wasm/simple-wasm",
"examples/simple-wasm/simple",
"packages/fuel-indexer-api-server",
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ DATABASE_URL=postgres://postgres@localhost bash scripts/run_migrations.bash
### Start the service

```bash
cargo run --bin fuel-indexer -- --manifest fuel-indexer-tests/assets/fuel_indexer_test.yaml
cargo run --bin fuel-indexer
```
1 change: 1 addition & 0 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- [Configuration](./getting-started/configuration.md)
- [Quickstart](./quickstart/index.md)
- [Examples](./examples/index.md)
- [Hello World](./examples/hello-world.md)
- [Block Explorer](./examples/block-explorer.md)
- [Components](./components/index.md)
- [Assets](./components/assets/index.md)
Expand Down
2 changes: 1 addition & 1 deletion docs/src/examples/block-explorer.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ mod explorer_index {
Once blocks have been added to the database by the indexer, you can query for them by using a query similar to the following:

```sh
curl -X POST http://127.0.0.1:29987/api/graph/fuel_examples \
curl -X POST http://127.0.0.1:29987/api/graph/fuel_examples \
-H 'content-type: application/json' \
-d '{"query": "query { block { id height timestamp }}", "params": "b"}' \
| json_pp
Expand Down
111 changes: 111 additions & 0 deletions docs/src/examples/hello-world.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Hello World

A "Hello World" type of program for the Fuel Indexer service.

```rust
//! A rudimentary block explorer implementation demonstrating how blocks, transactions,
//! contracts, and accounts can be persisted into the database.
//!
//! Build this example's WASM module using the following command. Note that a
//! wasm32-unknown-unknown target will be required.
//!
//! ```bash
//! cargo build -p hello-index --release --target wasm32-unknown-unknown
//! ```
//!
//! Start a local test Fuel node
//!
//! ```bash
//! cargo run --bin fuel-node
//! ```
//!
//! With your database backend set up, now start your fuel-indexer binary using the
//! assets from this example:
//!
//! ```bash
//! cargo run --bin fuel-indexer -- --manifest examples/hello-world/hello-index.manifest.yaml
//! ```
//!
//! Now trigger an event.
//!
//! ```bash
//! cargo run --bin hello-bin
//! ```

extern crate alloc;
use fuel_indexer_macros::indexer;
use fuel_indexer_plugin::{types::Bytes32, utils::sha256_digest};

// A utility function used to convert an arbitrarily sized string into Bytes32
// using the first 32 bytes of the String. This might be provided by a standard-ish
// library in the future.
fn bytes32(data: &str) -> Bytes32 {
let data = sha256_digest(&data);
let mut buff = [0u8; 32];
buff.copy_from_slice(&data.as_bytes()[..32]);
Bytes32::from(buff)
}

// A utility function used to convert an arbitrarily sized string into u64
// using the first 8 bytes of the String. This might be provided by a standard-ish
// library in the future.
fn u64_id(data: &str) -> u64 {
let mut buff = [0u8; 8];
buff.copy_from_slice(&data.as_bytes()[..8]);
u64::from_le_bytes(buff)
}

#[indexer(manifest = "examples/hello-world/hello-index.manifest.yaml")]
mod hello_world_index {
fn index_logged_greeting(event: Greeting, block: BlockData) {
// Since all events require a u64 ID field, let's derive an ID using the
// name of the person in the Greeting
let greeter_id = u64_id(&event.person.name.to_string());

// Here we 'get or create' a Salutation based on the ID of the event
// emiited in the LogData receipt of our smart contract
let greeting = match Salutation::load(event.id) {
Some(mut g) => {
// If we found an event, let's use block height as a proxy for time
g.last_seen = block.height;
g
}
None => {
// If we did not already have this Saluation stored in the database. Here we
// show how you can use the String255 type to store strings with length <= 255
let message =
format!("{} 👋, my name is {}", &event.greeting, &event.person.name);

Salutation {
id: event.id,
message_hash: bytes32(&message),
message,
greeter: greeter_id,
first_seen: block.height,
last_seen: block.height,
}
}
};

// Here we do the same with Greeter that we did for Saluation -- if we have an event
// already saved in the database, load it and update it. If we do not have this Greeter
// in the database then create one
let greeter = match Greeter::load(greeter_id) {
Some(mut g) => {
g.last_seen = block.height;
g
}
None => Greeter {
id: greeter_id,
first_seen: block.height,
name: event.person.name.to_string(),
last_seen: block.height,
},
};

// Both entity saves will occur in the same transaction
greeting.save();
greeter.save();
}
}
```
2 changes: 2 additions & 0 deletions docs/src/examples/index.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Examples

- [Hello World](./hello-world.md)
- A "Hello World" type of program for the Fuel Indexer service.
- [Block Explorer](./block-explorer.md)
- An extremely basic block explorer implementation that shows how blocks, transactions, contracts, and accounts can be persisted into the database.
37 changes: 14 additions & 23 deletions docs/src/getting-started/fuel-indexer-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,22 @@ When running a Fuel indexer service as a standalone binary, you can just simply
The convetion for a Fuel project layout including a Fuel indexer is:

```text
➜ my-project tree . -I target/ -I out/
.
├── contracts
│ └── my-contract
│ ├── Forc.lock
│ ├── Forc.toml
│ ├── out
│ │ └── debug
│ │ ├── my-contract-abi.json
│ │ ├── my-contract-storage_slots.json
│ │ └── my-contract.bin
│ ├── src
│ │ └── main.sw
│ └── tests
│ └── harness.rs
│   └── greeting
│   ├── Forc.toml
│   └── src
│   └── main.sw
├── frontend
└── index.html
   └── index.html
└── indexer
── my-index.manifest.yaml
├── my-index
├── Cargo.toml
── src
└── lib.rs
└── schema
└── schema.graphql
11 directories, 14 files
── hello-index
├── Cargo.toml
├── hello-index.manifest.yaml
── schema
│   └── hello-index.schema.graphql
└── src
└── lib.rs
8 directories, 7 files
```
Loading

0 comments on commit 0d406b9

Please sign in to comment.