Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add hello world example #360

Merged
merged 10 commits into from
Nov 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: "emitted"

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