From 3aba6aaa972b8b88f0491e5f9dbbf80a738bd344 Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 25 Aug 2023 13:30:00 -0400 Subject: [PATCH 01/33] Remove outdated 'M1 Docker not supported' blurb --- docs/src/getting-started/dependencies.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/docs/src/getting-started/dependencies.md b/docs/src/getting-started/dependencies.md index 748d6e54a..dd9312d78 100644 --- a/docs/src/getting-started/dependencies.md +++ b/docs/src/getting-started/dependencies.md @@ -10,12 +10,6 @@ To run the Fuel indexer, you'll need to install a few dependencies on your syste If you don't want to install a database directly onto your system, you can use Docker to run it as an isolated container. You can install it by following the [install instructions](https://docs.docker.com/get-docker/). For reference purposes, we provide a [`docker compose` file](https://github.com/FuelLabs/fuel-indexer/blob/develop/scripts/docker-compose.yaml) that runs a Postgres database and the Fuel indexer service. -> IMPORTANT: Note for Apple Silicon macOS users: -> -> Using the Fuel indexer through Docker on Apple Silicon systems is currently not supported. -> -> We're working to bring support to these systems. - Also, it's assumed that you have the Rust programming language installed on your system. If that is not the case, please refer to the [Rust installation instructions](https://www.rust-lang.org/tools/install) for more information. ## `fuelup` From 1c9d75d29679a853b57217f53d58e7c3a333ba3b Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 25 Aug 2023 13:38:28 -0400 Subject: [PATCH 02/33] Remove hello world as it's too complicated --- docs/src/SUMMARY.md | 1 - docs/src/getting-started/hello-world.md | 19 ------------------- 2 files changed, 20 deletions(-) delete mode 100644 docs/src/getting-started/hello-world.md diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 16ce436fc..25277f2b2 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -7,7 +7,6 @@ - [Dependencies](./getting-started/dependencies.md) - [Quickstart](./getting-started/quickstart.md) -- [Hello World](./getting-started/hello-world.md) - [Starting the Fuel Indexer](./getting-started/starting-the-fuel-indexer.md) # Reference Guide diff --git a/docs/src/getting-started/hello-world.md b/docs/src/getting-started/hello-world.md deleted file mode 100644 index 51ba30a85..000000000 --- a/docs/src/getting-started/hello-world.md +++ /dev/null @@ -1,19 +0,0 @@ -# Hello World - -Below is a simple "Hello World" Sway contract that we want to index. This contract has a function called `new_greeting` that logs a `Greeting` and a `Person`. - -```rust, ignore -{{#include ../../../examples/hello-world/contracts/greeting/src/main.sw}} -``` - -We can define our schema like this in the schema file: - -```graphql -{{#include ../../../examples/hello-world/hello-indexer/schema/hello_indexer.schema.graphql}} -``` - -Now that our schema is defined, here is how we can implement the WASM module in our `lib.rs` file: - -```rust,ignore -{{#include ../../../examples/hello-world/hello-indexer/src/lib.rs}} -``` From 2074060dac97160591c83bb9b4224d60f90c03c7 Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 25 Aug 2023 13:43:13 -0400 Subject: [PATCH 03/33] Move Queries section under GraphQL section --- docs/src/SUMMARY.md | 8 ++++---- docs/src/{ => graphql}/queries/full-example.md | 0 docs/src/{ => graphql}/queries/index.md | 0 docs/src/{ => graphql}/queries/pagination.md | 0 docs/src/{ => graphql}/queries/search-filtering.md | 0 5 files changed, 4 insertions(+), 4 deletions(-) rename docs/src/{ => graphql}/queries/full-example.md (100%) rename docs/src/{ => graphql}/queries/index.md (100%) rename docs/src/{ => graphql}/queries/pagination.md (100%) rename docs/src/{ => graphql}/queries/search-filtering.md (100%) diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 25277f2b2..3040c6b75 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -36,10 +36,10 @@ - [Directives](./graphql/directives.md) - [API Server](./graphql/api-server.md) - [Playground](./graphql/playground.md) -- [Queries](./queries/index.md) - - [Search and Filtering](./queries/search-filtering.md) - - [Pagination](./queries/pagination.md) - - [A Full Example](./queries/full-example.md) + - [Queries](./graphql/queries/index.md) + - [Search and Filtering](./graphql/queries/search-filtering.md) + - [Pagination](./graphql/queries/pagination.md) + - [A Full Example](./graphql/queries/full-example.md) - [Database](./database/index.md) - [Foreign Keys](./database/foreign-keys.md) - [ID Types](./database/ids.md) diff --git a/docs/src/queries/full-example.md b/docs/src/graphql/queries/full-example.md similarity index 100% rename from docs/src/queries/full-example.md rename to docs/src/graphql/queries/full-example.md diff --git a/docs/src/queries/index.md b/docs/src/graphql/queries/index.md similarity index 100% rename from docs/src/queries/index.md rename to docs/src/graphql/queries/index.md diff --git a/docs/src/queries/pagination.md b/docs/src/graphql/queries/pagination.md similarity index 100% rename from docs/src/queries/pagination.md rename to docs/src/graphql/queries/pagination.md diff --git a/docs/src/queries/search-filtering.md b/docs/src/graphql/queries/search-filtering.md similarity index 100% rename from docs/src/queries/search-filtering.md rename to docs/src/graphql/queries/search-filtering.md From 8b0358797f5f35c3754e2f8dc554593f74a5b17f Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 25 Aug 2023 14:56:28 -0400 Subject: [PATCH 04/33] Add page for GraphQL scalars --- docs/src/SUMMARY.md | 1 + docs/src/graphql/scalars.md | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 docs/src/graphql/scalars.md diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 3040c6b75..0f7584392 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -33,6 +33,7 @@ - [TransferOut](./indexing/transferout.md) - [Data Types](./data-types/types.md) - [GraphQL](./graphql/index.md) + - [Scalars](./graphql/scalars.md) - [Directives](./graphql/directives.md) - [API Server](./graphql/api-server.md) - [Playground](./graphql/playground.md) diff --git a/docs/src/graphql/scalars.md b/docs/src/graphql/scalars.md new file mode 100644 index 000000000..5eaa62c7f --- /dev/null +++ b/docs/src/graphql/scalars.md @@ -0,0 +1,36 @@ +# Scalars + +The Fuel indexer has a collection of GraphQL scalars that cover virtually any value type in use on the Fuel network. The following list contains each GraphQL scalar type along with its equivalent Rust type. + +| GraphQL Scalar | Rust Type | Notes | +--- | --- | --- +| Address | `u8[32]` | +| AssetId | `u8[32]` | +| ContractId | `u8[32]` | +| Bytes4 | `u8[4]` | +| Bytes8 | `u8[8]` | +| Bytes32 | `u8[32]` | +| Bytes64 | `u8[64]` | +| Blob | `Vec` | Byte blob of arbitary size | +| BlockId | `u8[32]` | 32-byte block ID | +| Boolean | `bool` | +| Charfield | `String` | String of arbitrary size | +| HexString | `Vec` | Byte blob of arbitrary size | +| ID | `SizedAsciiString<64>` | Alias of `UID` +| Int1 | `i8` | +| Int4 | `i32` | +| Int8 | `i64` | +| Int16 | `i128` | +| Json | `String` | JSON string of arbitary size | +| MessageId | `u8[32]` | +| Nonce | `u8[32]` | +| Salt | `u8[32]` | +| Signature | `u8[64]` | 64-byte signature | +| Tai64Timestamp | `Tai64` | `Tai64` timestamp | +| Timestamp | `u64` | +| UInt1 | `u8` | +| UInt4 | `u32` | +| UInt8 | `u64` | +| UInt16 | `u128` | +| UID | `SizedAsciiString<64>` | 32-byte unique ID | +| Virtual | `String` | Used to store types tagged with `@virtual` directive | From f1e320343682d35bab3321c896636df316b63fc9 Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 25 Aug 2023 15:22:16 -0400 Subject: [PATCH 05/33] Remove database pages; move foreign key page to GraphQL section --- docs/src/SUMMARY.md | 3 +-- docs/src/database/ids.md | 18 ------------------ .../relationships.md} | 11 +++++------ 3 files changed, 6 insertions(+), 26 deletions(-) delete mode 100644 docs/src/database/ids.md rename docs/src/{database/foreign-keys.md => graphql/relationships.md} (75%) diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 0f7584392..a7bcd47e2 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -35,6 +35,7 @@ - [GraphQL](./graphql/index.md) - [Scalars](./graphql/scalars.md) - [Directives](./graphql/directives.md) + - [Relationships](./graphql/relationships.md) - [API Server](./graphql/api-server.md) - [Playground](./graphql/playground.md) - [Queries](./graphql/queries/index.md) @@ -42,8 +43,6 @@ - [Pagination](./graphql/queries/pagination.md) - [A Full Example](./graphql/queries/full-example.md) - [Database](./database/index.md) - - [Foreign Keys](./database/foreign-keys.md) - - [ID Types](./database/ids.md) - [forc index](./forc-index/index.md) - [new](./forc-index/new.md) - [check](./forc-index/check.md) diff --git a/docs/src/database/ids.md b/docs/src/database/ids.md deleted file mode 100644 index 7a2b3cfce..000000000 --- a/docs/src/database/ids.md +++ /dev/null @@ -1,18 +0,0 @@ -# ID Types - -There are a few important things related to the use of IDs. - -> **Every GraphQL type defined in your schema file is required to have an id field.** -> -> - This field must be called `id` -> - The type of this `id` field must be a `u64` -> - You typically want to use the `ID` type for these `id` fields -> -> **Why must every field have an ID?** -> -> Since the Fuel Indexer uses WASM runtimes to index events, a foreign function interface (FFI) is needed to call in and out of the runtime. When these calls out of the runtime are made, a pointer is passed back to the indexer service to indicate the memory location for the `id` of the type/object/entity being saved. -> -> **Is this liable to change in the future?** -> -> Yes, ideally we'd like ID's to be of _any_ type, and we plan to work towards this in the future. 👍 -> \ No newline at end of file diff --git a/docs/src/database/foreign-keys.md b/docs/src/graphql/relationships.md similarity index 75% rename from docs/src/database/foreign-keys.md rename to docs/src/graphql/relationships.md index c92c69982..6298d8ec7 100644 --- a/docs/src/database/foreign-keys.md +++ b/docs/src/graphql/relationships.md @@ -1,7 +1,6 @@ -# Foreign Keys +# Relationships -- The Fuel indexer service supports foreign key constraints and relationships using a combination of GraphQL schema and a database. -- There are two types of uses for foreign keys - _implicit_ and _explicit_. +The Fuel indexer service supports foreign key relationships and constraints using a combination of GraphQL schema and a database. There are two types of foreign keys: _implicit_ and _explicit_. > IMPORTANT: > @@ -29,7 +28,7 @@ type Library @entity { } ``` -#### Implicit foreign key breakdown +#### Implicit foreign keys Given the above schema, two entities will be created: a `Book` entity, and a `Library` entity. As you can see, we add the `Book` entity as an attribute on the `Library` entity, thus conveying that we want a one-to-many or one-to-one relationship between `Library` and `Book`. This means that for a given `Library`, we may also fetch one or many `Book` entities. It also means that the column `library.book` will be an integer type that references `book.id`. @@ -47,6 +46,6 @@ type Library @entity { } ``` -#### Explicit foreign key breakdown +#### Explicit foreign keys -For the most part, this works the same way as implicit foreign key usage. However, as you can see, instead of implicitly using `book.id` as the reference column for our `Book` object, we're instead explicitly specifying that we want `book.name` to serve as our foreign key. Also, please note that since we're using `book.name` in our foreign key constraint, that column is required to be unique (via the `@unique` directive). +For the most part, this works the same way as implicit foreign key usage. However, as you can see, instead of implicitly using `book.id` as the reference column for our `Book` object, we're _explicitly_ specifying that we want `book.name` to serve as our foreign key. Also, please note that since we're using `book.name` in our foreign key constraint, that column is required to be unique (via the `@unique` directive). From b2facc84b666634b8bfbd0b891e26aa6519e79fb Mon Sep 17 00:00:00 2001 From: Alexander Date: Tue, 29 Aug 2023 15:35:33 -0400 Subject: [PATCH 06/33] Move data types section to Database section --- docs/src/SUMMARY.md | 2 +- docs/src/{data-types => database}/types.md | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename docs/src/{data-types => database}/types.md (100%) diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index a7bcd47e2..0572f33ea 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -31,7 +31,6 @@ - [ScriptResult](./indexing/scriptresult.md) - [Transfer](./indexing/transfer.md) - [TransferOut](./indexing/transferout.md) -- [Data Types](./data-types/types.md) - [GraphQL](./graphql/index.md) - [Scalars](./graphql/scalars.md) - [Directives](./graphql/directives.md) @@ -43,6 +42,7 @@ - [Pagination](./graphql/queries/pagination.md) - [A Full Example](./graphql/queries/full-example.md) - [Database](./database/index.md) + - [Data Types](./database/types.md) - [forc index](./forc-index/index.md) - [new](./forc-index/new.md) - [check](./forc-index/check.md) diff --git a/docs/src/data-types/types.md b/docs/src/database/types.md similarity index 100% rename from docs/src/data-types/types.md rename to docs/src/database/types.md From 44b7473da4cbe71d8ccf0de4f58a2511f37eb44b Mon Sep 17 00:00:00 2001 From: Alexander Date: Tue, 29 Aug 2023 16:13:46 -0400 Subject: [PATCH 07/33] Redo data types table; clean up type sorting --- docs/src/SUMMARY.md | 3 +- docs/src/database/index.md | 79 ++++++++++++++++++++++++++++++++++--- docs/src/graphql/scalars.md | 10 ++--- 3 files changed, 79 insertions(+), 13 deletions(-) diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 0572f33ea..f1e255470 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -41,8 +41,7 @@ - [Search and Filtering](./graphql/queries/search-filtering.md) - [Pagination](./graphql/queries/pagination.md) - [A Full Example](./graphql/queries/full-example.md) -- [Database](./database/index.md) - - [Data Types](./database/types.md) +- [Storing Info in a Database](./database/index.md) - [forc index](./forc-index/index.md) - [new](./forc-index/new.md) - [check](./forc-index/check.md) diff --git a/docs/src/database/index.md b/docs/src/database/index.md index be01ba0e4..07ed8ae0f 100644 --- a/docs/src/database/index.md +++ b/docs/src/database/index.md @@ -1,10 +1,77 @@ -# Database +# Storing Info in a Database The Fuel indexer uses [PostgreSQL](https://github.com/docker-library/postgres/blob/2f6878ca854713264ebb27c1ba8530c884bcbca5/14/bullseye/Dockerfile) as the primary database. We're open to supporting other storage solutions in the future. -In this chapter, you can find information regarding how your data should be structured for use in the Fuel indexer: +## Data Types -- [Foreign Keys](./foreign-keys.md) - - How foreign keys are handled in the Fuel indexer. -- [⚠️ IDs](./ids.md) - - Explains some conventions surrounding the usage of `ID` types +Below is a mapping of GraphQL schema types to their Sway and database equivalents. Note that an empty cell denotes that there is no direct equivalent for the type in the corresponding domain. + +| GraphQL Scalar | Sway Type | Postgres Type | +--- | --- | --- +| Address | `b256` | varchar(64) | +| AssetId | `u8[32]` | varchar(64) | +| Blob | `str[]` | varchar(10485760) | +| BlockId | | varchar(64) | +| Boolean | `bool` | boolean | +| Bytes4 | `str[4]` | varchar(8) | +| Bytes8 | `str[8]` | varchar(16) | +| Bytes32 | `str[32]` | varchar(64) | +| Bytes64 | `str[64]` | varchar(128) | +| Charfield | `str[]` | varchar(255) | +| ContractId | `b256` | varchar(64) | +| HexString | `str[]` | varchar(10485760) | +| ID | | varchar(64) primary key | +| Int1 | `u8` | integer | +| Int4 | `u32` | integer | +| Int8 | `u64` | bigint | +| Int16 | | numeric(39,0) | +| Json | `str[]` | json | +| MessageId | `str[32]` | varchar(64) | +| Nonce | `str[32]` | varchar(64) | +| Salt | `str[32]` | varchar(64) | +| Signature | `str[64]` | varchar(128) | +| Tai64Timestamp | | varchar(128) | +| Timestamp | `u64` | timestamp | +| UID | | varchar(64) | +| UInt1 | `u8` | integer | +| UInt4 | `u32` | integer | +| UInt8 | `u64` | numeric(20, 0) | +| UInt16 | | numeric(39, 0) | +| Virtual | | json | + +## Example + +Let's define an `Event` struct in a Sway contract: + +```sway +struct Event { + id: u64, + address: Address, + block_height: u64, +} +``` + +The corresponding GraphQL schema to mirror this `Event` struct would resemble: + +```graphql +type Event @entity { + id: ID! + account: Address! + block_height: UInt8! +} +``` + +And finally, this GraphQL schema will generate the following Postgres schema: + +```text + Table "schema.event" + Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description +--------------+-------------+-----------+----------+---------+----------+-------------+--------------+------------- + id | bigint | | not null | | plain | | | + block_height | bigint | | not null | | plain | | | + address | varchar(64) | | not null | | plain | | | + object | bytea | | not null | | extended | | | +Indexes: + "event_pkey" PRIMARY KEY, btree (id) +Access method: heap +``` diff --git a/docs/src/graphql/scalars.md b/docs/src/graphql/scalars.md index 5eaa62c7f..d2ce0424b 100644 --- a/docs/src/graphql/scalars.md +++ b/docs/src/graphql/scalars.md @@ -6,15 +6,15 @@ The Fuel indexer has a collection of GraphQL scalars that cover virtually any va --- | --- | --- | Address | `u8[32]` | | AssetId | `u8[32]` | -| ContractId | `u8[32]` | +| Blob | `Vec` | Byte blob of arbitary size | +| BlockId | `u8[32]` | 32-byte block ID | +| Boolean | `bool` | | Bytes4 | `u8[4]` | | Bytes8 | `u8[8]` | | Bytes32 | `u8[32]` | | Bytes64 | `u8[64]` | -| Blob | `Vec` | Byte blob of arbitary size | -| BlockId | `u8[32]` | 32-byte block ID | -| Boolean | `bool` | | Charfield | `String` | String of arbitrary size | +| ContractId | `u8[32]` | | HexString | `Vec` | Byte blob of arbitrary size | | ID | `SizedAsciiString<64>` | Alias of `UID` | Int1 | `i8` | @@ -28,9 +28,9 @@ The Fuel indexer has a collection of GraphQL scalars that cover virtually any va | Signature | `u8[64]` | 64-byte signature | | Tai64Timestamp | `Tai64` | `Tai64` timestamp | | Timestamp | `u64` | +| UID | `SizedAsciiString<64>` | 32-byte unique ID | | UInt1 | `u8` | | UInt4 | `u32` | | UInt8 | `u64` | | UInt16 | `u128` | -| UID | `SizedAsciiString<64>` | 32-byte unique ID | | Virtual | `String` | Used to store types tagged with `@virtual` directive | From b4c06d1235c0c483ef8acf96603fc8343021d9ec Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 30 Aug 2023 09:17:19 -0400 Subject: [PATCH 08/33] Add info to 'Starting the Fuel Indexer' --- docs/src/SUMMARY.md | 2 +- .../starting-the-fuel-indexer.md | 23 ++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index f1e255470..999ae4c92 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -7,7 +7,7 @@ - [Dependencies](./getting-started/dependencies.md) - [Quickstart](./getting-started/quickstart.md) -- [Starting the Fuel Indexer](./getting-started/starting-the-fuel-indexer.md) +- [Indexer Service Infrastructure](./getting-started/starting-the-fuel-indexer.md) # Reference Guide diff --git a/docs/src/getting-started/starting-the-fuel-indexer.md b/docs/src/getting-started/starting-the-fuel-indexer.md index 50b16b985..c467037c3 100644 --- a/docs/src/getting-started/starting-the-fuel-indexer.md +++ b/docs/src/getting-started/starting-the-fuel-indexer.md @@ -1,6 +1,23 @@ -# Starting the Fuel Indexer +# Indexer Service Infrastructure -## Using CLI options +A Fuel indexer service instance requires just three components: + +- a **Fuel node**: Custom indexers monitor incoming blocks from a Fuel node and extract information about the state of the Fuel blockchain. +- a **Postgres database server**: Extracted information is saved into a database. +- the **indexer service web API**: dApps can query indexers for up-to-date information and operators can deploy/remove indexers as needed. + +The Fuel indexer service will connect to any Fuel node, which means you can run your own node or use a node provided by Fuel. The indexer service web API is included with the Fuel indexer; it's available as soon as the indexer is started through `fuel-indexer run`. The only component that isn't provided for you is a Postgres database server. You should set up a server according to your own needs and specifications. + +## Components + +| Component | Default Host | Default Port | CLI Argument | Environment Variable | +|---|---|---|---|---| +| Fuel Node | localhost | 4000 | `--fuel-node-host` / `--fuel-node-port` | | +| Database Server | localhost | 5432 | `--postgres-user` / `--postgres--password` / `--postgres-host` / `--postgres--port` / `--postgres-database` | | +| Indexer Service Web API | localhost | 29987 | `--web-api-host` / `--web-api-port` | | + +## Starting the Fuel indexer +### Using CLI options ```text Standalone binary for the fuel indexer service. @@ -119,7 +136,7 @@ OPTIONS: ``` -## Using a configuration file +### Using a configuration file ```yaml {{#include ../../../config.yaml}} From 01e0d5d7bac27e79f2a44f2a86b4495282d7cc3c Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 30 Aug 2023 11:56:59 -0400 Subject: [PATCH 09/33] Fix doc tests --- docs/src/SUMMARY.md | 10 ++-- docs/src/database/index.md | 2 +- docs/src/database/types.md | 60 ------------------- .../starting-the-fuel-indexer.md | 1 + .../src/graphql/{queries => }/full-example.md | 0 docs/src/graphql/index.md | 6 +- docs/src/graphql/{queries => }/pagination.md | 0 .../graphql/{queries/index.md => queries.md} | 6 +- docs/src/graphql/relationships.md | 4 -- docs/src/graphql/scalars.md | 2 +- .../graphql/{queries => }/search-filtering.md | 0 docs/src/project-components/index.md | 2 +- docs/src/project-components/schema.md | 2 +- 13 files changed, 16 insertions(+), 79 deletions(-) delete mode 100644 docs/src/database/types.md rename docs/src/graphql/{queries => }/full-example.md (100%) rename docs/src/graphql/{queries => }/pagination.md (100%) rename docs/src/graphql/{queries/index.md => queries.md} (78%) rename docs/src/graphql/{queries => }/search-filtering.md (100%) diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 999ae4c92..77d67c718 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -37,10 +37,10 @@ - [Relationships](./graphql/relationships.md) - [API Server](./graphql/api-server.md) - [Playground](./graphql/playground.md) - - [Queries](./graphql/queries/index.md) - - [Search and Filtering](./graphql/queries/search-filtering.md) - - [Pagination](./graphql/queries/pagination.md) - - [A Full Example](./graphql/queries/full-example.md) + - [Basic Queries](./graphql/queries.md) + - [Search and Filtering](./graphql/search-filtering.md) + - [Pagination](./graphql/pagination.md) + - [A Full Example](./graphql/full-example.md) - [Storing Info in a Database](./database/index.md) - [forc index](./forc-index/index.md) - [new](./forc-index/new.md) @@ -57,7 +57,7 @@ - [start](./forc-postgres/start.md) - [stop](./forc-postgres/stop.md) - [drop](./forc-postgres/drop.md) -- [Authentication](./authentication/index.md) --> +- [Authentication](./authentication/index.md) # For Contributors diff --git a/docs/src/database/index.md b/docs/src/database/index.md index 07ed8ae0f..b4a2c5ab2 100644 --- a/docs/src/database/index.md +++ b/docs/src/database/index.md @@ -7,7 +7,7 @@ The Fuel indexer uses [PostgreSQL](https://github.com/docker-library/postgres/bl Below is a mapping of GraphQL schema types to their Sway and database equivalents. Note that an empty cell denotes that there is no direct equivalent for the type in the corresponding domain. | GraphQL Scalar | Sway Type | Postgres Type | ---- | --- | --- +--- | --- | --- | Address | `b256` | varchar(64) | | AssetId | `u8[32]` | varchar(64) | | Blob | `str[]` | varchar(10485760) | diff --git a/docs/src/database/types.md b/docs/src/database/types.md deleted file mode 100644 index 2dca9a3d3..000000000 --- a/docs/src/database/types.md +++ /dev/null @@ -1,60 +0,0 @@ -# Types - -Below is a mapping of GraphQL schema types to their Sway and database equivalents. - -| Sway Type | GraphQL Schema Type | Postgres Type | -|------|----------|----------| -| b256 | Address | varchar(64) | -| b256 | ContractId | varchar(64) | -| bool | Boolean | bool | -| i64 | Timestamp | timestamp | -| str[] | Blob | bytes | -| str[4] | Bytes4 | varchar(16) | -| str[8] | Bytes8 | varchar(64) | -| str[32] | Bytes32 | varchar(64) | -| str[32] | AssetId | varchar(64) | -| str[32] | MessageId | varchar(64) | -| str[32] | Salt | varchar(64) | -| u32 | UInt4 | integer | -| u64 | ID | bigint primary key | -| u64 | UInt8 | bigint | -| | Json | json | -| | Charfield | varchar(255) | -| | Blob | varchar(10485760) | - -## Example - -Let's define an `Event` struct in a Sway contract: - -```sway -struct Event { - id: u64, - address: Address, - block_height: u64, -} -``` - -The corresponding GraphQL schema to mirror this `Event` struct would resemble: - -```graphql -type Event @entity { - id: ID! - account: Address! - block_height: UInt8! -} -``` - -And finally, this GraphQL schema will generate the following Postgres schema: - -```text - Table "schema.event" - Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description ---------------+-------------+-----------+----------+---------+----------+-------------+--------------+------------- - id | bigint | | not null | | plain | | | - block_height | bigint | | not null | | plain | | | - address | varchar(64) | | not null | | plain | | | - object | bytea | | not null | | extended | | | -Indexes: - "event_pkey" PRIMARY KEY, btree (id) -Access method: heap -``` diff --git a/docs/src/getting-started/starting-the-fuel-indexer.md b/docs/src/getting-started/starting-the-fuel-indexer.md index c467037c3..5be3d7150 100644 --- a/docs/src/getting-started/starting-the-fuel-indexer.md +++ b/docs/src/getting-started/starting-the-fuel-indexer.md @@ -17,6 +17,7 @@ The Fuel indexer service will connect to any Fuel node, which means you can run | Indexer Service Web API | localhost | 29987 | `--web-api-host` / `--web-api-port` | | ## Starting the Fuel indexer + ### Using CLI options ```text diff --git a/docs/src/graphql/queries/full-example.md b/docs/src/graphql/full-example.md similarity index 100% rename from docs/src/graphql/queries/full-example.md rename to docs/src/graphql/full-example.md diff --git a/docs/src/graphql/index.md b/docs/src/graphql/index.md index 640d43933..2a3a3e3b9 100644 --- a/docs/src/graphql/index.md +++ b/docs/src/graphql/index.md @@ -5,7 +5,7 @@ The Fuel indexer uses GraphQL to in order to allow users to query for indexed da - [Directives](./directives.md) - [GraphQL API Server](./api-server.md) - [Playground](./playground.md) -- [Queries](../queries/index.md) +- [Queries](./queries.md) ## Supported Functionality @@ -19,12 +19,12 @@ While we do our best to maintain compliance with the GraphQL specification and p | Functionality | Status | Notes | |------|----------|-------| -| Arguments | ✅ | [read the Search and Filtering section](../queries/search-filtering.md) | +| Arguments | ✅ | [read the Search and Filtering section](./search-filtering.md) | | Aliases | ✅ | | | Fragments | ✅ | inline fragments are currently not supported | | Introspection | ✅ | | | GraphQL Playground | ✅ | [read the Playground section](./playground.md) | -| Pagination | ✅ | [read the Pagination section](../queries/pagination.md) | +| Pagination | ✅ | [read the Pagination section](./pagination.md) | | Directives | 🚧 | [read the Directives section](./directives.md) | | List Types | 🚧 | | | Union Types | 🚧 | | diff --git a/docs/src/graphql/queries/pagination.md b/docs/src/graphql/pagination.md similarity index 100% rename from docs/src/graphql/queries/pagination.md rename to docs/src/graphql/pagination.md diff --git a/docs/src/graphql/queries/index.md b/docs/src/graphql/queries.md similarity index 78% rename from docs/src/graphql/queries/index.md rename to docs/src/graphql/queries.md index e9828c703..cd77d3db6 100644 --- a/docs/src/graphql/queries/index.md +++ b/docs/src/graphql/queries.md @@ -1,6 +1,6 @@ # Queries -Once data has been persisted into your storage backend, you can retrieve it by querying the [GraphQL API server](../graphql/api-server.md). By default, the API server can be reached at `http://localhost:29987/api/graph/:namespace/:identifier`, where `:namespace` and `:identifier` are the values for the respective fields in your indexer's manifest. If you've changed the `WEB_API_HOST` or `WEB_API_PORT` values of your configuration, then you'll need to adjust the URL accordingly. +Once data has been persisted into your storage backend, you can retrieve it by querying the [GraphQL API server](./api-server.md). By default, the API server can be reached at `http://localhost:29987/api/graph/:namespace/:identifier`, where `:namespace` and `:identifier` are the values for the respective fields in your indexer's manifest. If you've changed the `WEB_API_HOST` or `WEB_API_PORT` values of your configuration, then you'll need to adjust the URL accordingly. ## Basic Query @@ -63,7 +63,7 @@ We're requesting the ID, height, and timestamp for each block stored in the back ## Nested Query -The Fuel indexer supports [foreign keys](../database/foreign-keys.md) on entity types; thus, you can also ask for information about a referenced entity inside of your query. A nested query has the following general structure: +The Fuel indexer supports [foreign keys](./relationships.md) on entity types; thus, you can also ask for information about a referenced entity inside of your query. A nested query has the following general structure: ```graphql query { @@ -112,7 +112,7 @@ type Character @entity { } ``` -This schema uses implicit foreign keys to reference other entities; for more information on implicit and explicit foreign keys, please refer to the [Foreign Keys](../database/foreign-keys.md) section of the book. In this contrived example, we're storing information about characters that are found in books which are stored in libraries that can be found in cities. This will be the query that we use to retrieve the aforementioned data: +This schema uses implicit foreign keys to reference other entities; for more information on implicit and explicit foreign keys, please refer to the [Relationships](./relationships.md) section of the book. In this contrived example, we're storing information about characters that are found in books which are stored in libraries that can be found in cities. This will be the query that we use to retrieve the aforementioned data: ```graphql query { diff --git a/docs/src/graphql/relationships.md b/docs/src/graphql/relationships.md index 6298d8ec7..dba3efbd3 100644 --- a/docs/src/graphql/relationships.md +++ b/docs/src/graphql/relationships.md @@ -28,8 +28,6 @@ type Library @entity { } ``` -#### Implicit foreign keys - Given the above schema, two entities will be created: a `Book` entity, and a `Library` entity. As you can see, we add the `Book` entity as an attribute on the `Library` entity, thus conveying that we want a one-to-many or one-to-one relationship between `Library` and `Book`. This means that for a given `Library`, we may also fetch one or many `Book` entities. It also means that the column `library.book` will be an integer type that references `book.id`. ### Explicit foreign keys @@ -46,6 +44,4 @@ type Library @entity { } ``` -#### Explicit foreign keys - For the most part, this works the same way as implicit foreign key usage. However, as you can see, instead of implicitly using `book.id` as the reference column for our `Book` object, we're _explicitly_ specifying that we want `book.name` to serve as our foreign key. Also, please note that since we're using `book.name` in our foreign key constraint, that column is required to be unique (via the `@unique` directive). diff --git a/docs/src/graphql/scalars.md b/docs/src/graphql/scalars.md index d2ce0424b..d026af518 100644 --- a/docs/src/graphql/scalars.md +++ b/docs/src/graphql/scalars.md @@ -3,7 +3,7 @@ The Fuel indexer has a collection of GraphQL scalars that cover virtually any value type in use on the Fuel network. The following list contains each GraphQL scalar type along with its equivalent Rust type. | GraphQL Scalar | Rust Type | Notes | ---- | --- | --- +--- | --- | --- | Address | `u8[32]` | | AssetId | `u8[32]` | | Blob | `Vec` | Byte blob of arbitary size | diff --git a/docs/src/graphql/queries/search-filtering.md b/docs/src/graphql/search-filtering.md similarity index 100% rename from docs/src/graphql/queries/search-filtering.md rename to docs/src/graphql/search-filtering.md diff --git a/docs/src/project-components/index.md b/docs/src/project-components/index.md index ce5e0a2c2..2997f5712 100644 --- a/docs/src/project-components/index.md +++ b/docs/src/project-components/index.md @@ -12,7 +12,7 @@ We'll describe these three different implementations below. ### As tooling for compiling indexers -The Fuel indexer provides functionality to make it easy to build and compile abitrary indexers by using [`forc index`](../forc-index/index.md). For info on how to use indexer tooling to compile arbitrary indexers, check out our [Quickstart](../getting-started/quickstart.md) and [Hello World](../getting-started/hello-world.md) examples for a more in-depth exploration of how to compile indexers. +The Fuel indexer provides functionality to make it easy to build and compile abitrary indexers by using [`forc index`](../forc-index/index.md). For info on how to use indexer tooling to compile arbitrary indexers, check out our [Quickstart](../getting-started/quickstart.md) example for a more in-depth exploration of how to compile indexers. ### As a standalone service diff --git a/docs/src/project-components/schema.md b/docs/src/project-components/schema.md index ba3f1faa9..e8c00ab2a 100644 --- a/docs/src/project-components/schema.md +++ b/docs/src/project-components/schema.md @@ -18,7 +18,7 @@ type SecondThing @entity { ``` The types you see above (e.g., `ID`, `UInt8`, etc) are Fuel abstractions that were created to more seamlessly integrate with the Fuel VM and are not native to GraphQL. A deeper explanation on these -types can be found in [the Types section](../data-types/types.md). +types can be found in [the Types section](../database/index.md). > Important: It is up to developers to manage their own unique IDs for each type, meaning that a data structure's `ID` field needs to be manually generated prior to saving it to the database. This generation can be as simple or complex as you want in order to fit your particular situation; the only requirement is that the developer implement their own custom generation. From a325b9e2ecd6366ed2c2f0f3d15a91f63aadd3d1 Mon Sep 17 00:00:00 2001 From: Rashad Alston Date: Thu, 31 Aug 2023 10:16:19 -0400 Subject: [PATCH 10/33] rashad: piggy back on deekerno's doc improvements --- docs/src/SUMMARY.md | 2 +- docs/src/authentication/index.md | 6 +- docs/src/forc-index/deploy.md | 2 +- docs/src/forc-index/remove.md | 2 +- docs/src/forc-index/status.md | 2 +- docs/src/getting-started/dependencies.md | 26 ++-- docs/src/getting-started/quickstart.md | 53 +++++--- .../starting-the-fuel-indexer.md | 16 ++- docs/src/graphql/full-example.md | 2 +- docs/src/indexing/blocks-and-transactions.md | 125 +++++++++++++++++- docs/src/indexing/index.md | 13 +- docs/src/project-components/index.md | 20 +-- docs/src/project-components/manifest.md | 10 +- docs/src/project-components/module.md | 65 ++++----- docs/src/project-components/schema.md | 31 ++--- plugins/forc-index/README.md | 4 +- 16 files changed, 265 insertions(+), 114 deletions(-) diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 77d67c718..c78faaed4 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -6,8 +6,8 @@ # Getting Started - [Dependencies](./getting-started/dependencies.md) +- [Service Infrastructure](./getting-started/starting-the-fuel-indexer.md) - [Quickstart](./getting-started/quickstart.md) -- [Indexer Service Infrastructure](./getting-started/starting-the-fuel-indexer.md) # Reference Guide diff --git a/docs/src/authentication/index.md b/docs/src/authentication/index.md index cee929fa3..c779e1d7e 100644 --- a/docs/src/authentication/index.md +++ b/docs/src/authentication/index.md @@ -10,10 +10,10 @@ The new authentication functionality offers a flexible and secure way for users ## Usage -Below is a demonstration of basic JWT authentication using an indexer operator at "https://beta-3-indexer.fuel.network" +Below is a demonstration of basic JWT authentication using an indexer operator at "https://beta-4-indexer.fuel.network" ```bash -forc index auth --url https://beta-3-indexer.fuel.network:29987 +forc index auth --url https://beta-4-indexer.fuel.network:29987 ``` You will first be prompted for the password for your wallet: @@ -25,7 +25,7 @@ Please enter your wallet password: After successfully entering your wallet password you should be presented with your new JWT token. ```text -✅ Successfully authenticated at https://beta-3-indexer.fuel.network:29987/api/auth/signature. +✅ Successfully authenticated at https://beta-4-indexer.fuel.network:29987/api/auth/signature. Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiODNlNjhiOTFmNDhjYWM4M.... ``` diff --git a/docs/src/forc-index/deploy.md b/docs/src/forc-index/deploy.md index 896369976..319a5696e 100644 --- a/docs/src/forc-index/deploy.md +++ b/docs/src/forc-index/deploy.md @@ -3,7 +3,7 @@ Deploy an indexer to an indexer service. ```bash -forc index deploy --url https://beta-3-indexer.fuel.network +forc index deploy --url https://beta-4-indexer.fuel.network ``` ```text diff --git a/docs/src/forc-index/remove.md b/docs/src/forc-index/remove.md index 7f01e9c75..5ceaf27df 100644 --- a/docs/src/forc-index/remove.md +++ b/docs/src/forc-index/remove.md @@ -3,7 +3,7 @@ Stop and remove a running indexer. ```bash -forc index remove --url https://beta-3-indexer.fuel.network +forc index remove --url https://beta-4-indexer.fuel.network ``` ```text diff --git a/docs/src/forc-index/status.md b/docs/src/forc-index/status.md index 11e56685e..675568ca8 100644 --- a/docs/src/forc-index/status.md +++ b/docs/src/forc-index/status.md @@ -3,7 +3,7 @@ Check the status of a registered indexer. ```bash -forc index status --url https://beta-3-indexer.fuel.network +forc index status --url https://beta-4-indexer.fuel.network ``` ```text diff --git a/docs/src/getting-started/dependencies.md b/docs/src/getting-started/dependencies.md index dd9312d78..84bfbd2a6 100644 --- a/docs/src/getting-started/dependencies.md +++ b/docs/src/getting-started/dependencies.md @@ -1,16 +1,16 @@ # Dependencies +> This guide covers some of the basics with regard to installing dependencies for the Fuel indexer service. However, note that this guide is meant to be a general overview for most platforms and by no means covers all platforms. If you're having trouble with dependencies on your system, we recommend that you use `docker`. + To run the Fuel indexer, you'll need to install a few dependencies on your system: +- The [Rust programming language, with its package manager](https://www.rust-lang.org/tools/install) - [`fuelup`](#fuelup), the Fuel toolchain manager -- A supported [database](#postgresql) - - As of now we only support Postgres -- The [`wasm32-unknown-unknown`](#wasm) `rustup` target -- [`wasm-snip`](#wasm), a utility for stripping symbols from WebAssemly binaries. - -If you don't want to install a database directly onto your system, you can use Docker to run it as an isolated container. You can install it by following the [install instructions](https://docs.docker.com/get-docker/). For reference purposes, we provide a [`docker compose` file](https://github.com/FuelLabs/fuel-indexer/blob/develop/scripts/docker-compose.yaml) that runs a Postgres database and the Fuel indexer service. +- A [PostgresQL](#postgresql) server backend +- The [`wasm32-unknown-unknown`](#web-assembly-wasm) `rustup` target +- [`wasm-snip`](#web-assembly-wasm), a utility for stripping symbols from WebAssemly binaries. -Also, it's assumed that you have the Rust programming language installed on your system. If that is not the case, please refer to the [Rust installation instructions](https://www.rust-lang.org/tools/install) for more information. +> If you don't want to install a database directly onto your system, you can use Docker to run it as an isolated container. You can install Docker by following the [install instructions](https://docs.docker.com/get-docker/). For reference purposes, we provide a [`docker compose` file](https://github.com/FuelLabs/fuel-indexer/blob/develop/scripts/docker-compose.yaml) that comes with a PostgresSQL server and a Fuel indexer service. ## `fuelup` @@ -20,7 +20,9 @@ We strongly recommend that you use the Fuel indexer through [`forc`, the Fuel or curl --proto '=https' --tlsv1.2 -sSf https://install.fuel.network/fuelup-init.sh | sh ``` -After `fuelup` has been installed, the `forc index` command and `fuel-indexer` binaries will be available on your system. +After `fuelup` has been installed, the `forc index` command and `fuel-indexer` binaries should be available on your system. + +> A simple `forc index check` can be used to show which indexer components you have installed via `fuelup`. ## PostgreSQL @@ -28,7 +30,7 @@ The Fuel indexer requires the use of a database. We currently support [PostgresS > IMPORTANT: Fuel Indexer users on most platforms don't need to explicitly install PostgresQL software via a package manager. When starting the indexer service via `forc index start` simply pass the `--embedded-database` flag in order to have the indexer service download and start an embedded PostgresQL instance via [`forc index postgres`](../forc-postgres/index.md). > -> However if users or devs would like to install PostgresQL via some package manager, feel free to checkout the more detailed installation steps below. +> However note that this `--embedded-database` functionality can be a bit brittle or flaky on some platforms, so alternative methods of installing or using PostgresQL are briefly mentioned below. ### macOS @@ -36,11 +38,13 @@ On macOS systems, you can install PostgreSQL through Homebrew. If it isn't prese Once installed, you can add PostgreSQL to your system by running `brew install postgresql`. -## WASM +## Web Assembly (WASM) Two additonal cargo components will be required to build your indexers: `wasm-snip` and the `wasm32-unknown-unknown` target. -> As of this writing, there is a small bug in newly built Fuel indexer WASM modules that produces a WASM runtime error due an errant upstream dependency. For now, you can use `wasm-snip` to remove the errant symbols from the WASM module. An example can be found in the related script [here](https://github.com/FuelLabs/fuel-indexer/blob/develop/scripts/stripper.bash). +> As of this writing, there is a small bug in newly built Fuel indexer WASM modules that produces a WASM runtime error due an errant upstream dependency. For now, you can use `wasm-snip` to remove the errant symbols from the WASM module, and prevent this issue from happening. An example can be found in the related script [here](https://github.com/FuelLabs/fuel-indexer/blob/develop/scripts/stripper.bash). +> +> Note that since `wasm-snip` strips Web Assembly related symbols, users will temporarily not be allowed to include other WASM-friendly crates (e.g., [`chrono`](https://docs.rs/chrono/latest/chrono/)) in their indexers. ### `wasm-snip` diff --git a/docs/src/getting-started/quickstart.md b/docs/src/getting-started/quickstart.md index 323a4eae5..316730bc9 100644 --- a/docs/src/getting-started/quickstart.md +++ b/docs/src/getting-started/quickstart.md @@ -3,8 +3,10 @@ In this tutorial you will: 1. Bootstrap your development environment. -2. Create, build, and deploy an indexer to an indexer service hooked up to Fuel's `beta-3` testnet. -3. Query your newly created index for data using GraphQL. +2. Create, build, and deploy an indexer to an indexer service hooked up to Fuel's `beta-4` testnet. +3. Query your indexer's newly created index for data using GraphQL. + +--- ## 1. Setting up your environment @@ -34,6 +36,8 @@ Additionally, you'll need the `wasm-snip` utility in order to remove errant symb cargo install wasm-snip ``` +--- + ## 2. Using the `forc-index` plugin The primary means of interfacing with the Fuel indexer for indexer development is the [`forc-index` CLI tool](https://crates.io/crates/forc-index). `forc-index` is a [`forc`](https://github.com/FuelLabs/sway/tree/master/forc) plugin specifically created to interface with the Fuel indexer service. Since we already installed `fuelup` in a previous step [1.1](#11-install-fuelup), we should be able to check that our `forc-index` binary was successfully installed and added to our `PATH`. @@ -98,7 +102,9 @@ To quickly setup and bootstrap the PostgreSQL database that we'll need, we'll us We can quickly create a bootstrapped database and start the Fuel indexer service by running the following command: -> IMPORTANT: Below we're specifying our Postgres hostname as `--postgres-host postgresql`, but you will need to be specific to your own Postgres instance details (see `forc index start --help` for more details). You can try using the `--embedded-database` flag in order to quickly use an embedded instance of Postgres, but this is flaky and often depends on what platform you're using. +> IMPORTANT: Below we're specifying our Postgres hostname as `--postgres-host postgresql`, but you might need to change this based on your own Postgres instance details (see `forc index start --help` for more details). +> +> Additionally, you can try using the `--embedded-database` flag in order to quickly use an embedded instance of Postgres, but this flag can be flaky, and its ease of use often depends on what platform you're using. ```bash forc index start --fuel-node-host beta-4.fuel.network --fuel-node-port 80 --run-migrations --postgres-host postgresql @@ -124,14 +130,17 @@ You should see output indicating the successful creation of a database and start Now that we have our development environment set up, the next step is to create an indexer. ```bash -forc index new hello-indexer --namespace fuelLabs && cd hello-indexer +forc index new hello-indexer --namespace fuellabs && cd hello-indexer ``` -> The `namespace` of your project is a required option. You can think of a `namespace` as your organization name or company name. Your project might contain one or many indexers all under the same `namespace`. For a complete list of options passed to `forc index new`, see [here](../forc-index/new.md) +> The `namespace` of your project is a required option. You can think of a `namespace` as your organization name or company name. Your project might contain one or many indexers all under the same `namespace`. For a complete list of options passed to `forc index new`, see [here](../forc-index/new.md). ```text forc index new hello-indexer --namespace FuelLabs +✅ Successfully created indexer + + ███████╗██╗ ██╗███████╗██╗ ██╗███╗ ██╗██████╗ ███████╗██╗ ██╗███████╗██████╗ ██╔════╝██║ ██║██╔════╝██║ ██║████╗ ██║██╔══██╗██╔════╝╚██╗██╔╝██╔════╝██╔══██╗ █████╗ ██║ ██║█████╗ ██║ ██║██╔██╗ ██║██║ ██║█████╗ ╚███╔╝ █████╗ ██████╔╝ @@ -139,51 +148,57 @@ forc index new hello-indexer --namespace FuelLabs ██║ ╚██████╔╝███████╗███████╗ ██║██║ ╚████║██████╔╝███████╗██╔╝ ██╗███████╗██║ ██║ ╚═╝ ╚═════╝ ╚══════╝╚══════╝ ╚═╝╚═╝ ╚═══╝╚═════╝ ╚══════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ + An easy-to-use, flexible indexing service built to go fast. 🚗💨 + ---- Read the Docs: - Fuel Indexer: https://github.com/FuelLabs/fuel-indexer - Fuel Indexer Book: https://fuellabs.github.io/fuel-indexer/latest - Sway Book: https://fuellabs.github.io/sway/latest -- Rust SDK Book: https://fuellabs.github.io/fuels-rs/latest +- Rust SDK Book: https://rust.fuel.network + Join the Community: -- Follow us @SwayLang: https://twitter.com/fuellabs_ +- Follow us @Fuel: https://twitter.com/fuel_network - Ask questions in dev-chat on Discord: https://discord.com/invite/xfpK4Pe Report Bugs: - Fuel Indexer Issues: https://github.com/FuelLabs/fuel-indexer/issues/new Take a quick tour. + +`forc index auth` + Authenticate against an indexer service. +`forc index build` + Build an indexer. `forc index check` List indexer components. +`forc index deploy` + Deploy an indexer. +`forc index kill` + Kill a running Fuel indexer process on a given port. `forc index new` Create a new indexer. -`forc index start` - Start a local indexer service. -`forc index build` - Build your indexer. -`forc index deploy` - Deploy your indexer. `forc index remove` Stop a running indexer. -`forc index auth` - Authenticate against an indexer service. +`forc index start` + Start a local indexer service. `forc index status` Check the status of an indexer. ``` ### 2.4 Deploying our indexer -At this point, we have a brand new indexer that will index some blocks and transactions. And with both our database and Fuel indexer services up and running, all that's left is to build and deploy the indexer in order to see it in action. Let's build and deploy our indexer: +At this point, we have a brand new indexer that will index some blocks and transactions. And with both our database and Fuel indexer services up and running, all that's left to do is to build and deploy the indexer in order to see it in action. Let's build and deploy our indexer: ```bash forc index deploy ``` -> IMPORTANT: `forc index deploy` by defaults runs `forc index build` prior to deploying the indexer. The same result can be produced by running `forc index build` then subsequently running `forc index deploy`. +> IMPORTANT: `forc index deploy` by defaults runs `forc index build` prior to deploying the indexer. The same result can be produced by running `forc index build` then subsequently running `forc index deploy`. For more info, checkout the [`forc index deploy`](./../forc-index/deploy.md) command. If all goes well, you should see the following: @@ -197,7 +212,7 @@ If all goes well, you should see the following: With our indexer deployed, we should be able to query for newly indexed data after a few seconds. -Below, we write a simple GraphQL query that simply returns a few fields from all transactions that we've indexed. +Below, we write a simple GraphQL query that returns a few fields from all transactions that we've indexed. You can open your GraphQL query playground at `http://127.0.0.1:29987/api/playground/fuellabs/hello_indexer` and submit the following GraphQL query. @@ -244,3 +259,5 @@ The response you get should resemble: ### Finished! 🥳 Congrats, you just created, built, and deployed your first indexer on the world's fastest execution layer. + +For more info on how indexers work, please checkout the [reference guide](./../project-components/index.md). diff --git a/docs/src/getting-started/starting-the-fuel-indexer.md b/docs/src/getting-started/starting-the-fuel-indexer.md index 5be3d7150..19db02c0b 100644 --- a/docs/src/getting-started/starting-the-fuel-indexer.md +++ b/docs/src/getting-started/starting-the-fuel-indexer.md @@ -2,9 +2,19 @@ A Fuel indexer service instance requires just three components: -- a **Fuel node**: Custom indexers monitor incoming blocks from a Fuel node and extract information about the state of the Fuel blockchain. -- a **Postgres database server**: Extracted information is saved into a database. -- the **indexer service web API**: dApps can query indexers for up-to-date information and operators can deploy/remove indexers as needed. +- a **Fuel node** + +> Custom indexers monitor incoming blocks from a Fuel node and extract information about the state of the Fuel blockchain. + +- a **PostgresQL database server** + +> Extracted information is saved into a database. + +- a **web server** + +> dApps can query indexers for up-to-date information and operators can deploy/remove indexers as needed. + +--- The Fuel indexer service will connect to any Fuel node, which means you can run your own node or use a node provided by Fuel. The indexer service web API is included with the Fuel indexer; it's available as soon as the indexer is started through `fuel-indexer run`. The only component that isn't provided for you is a Postgres database server. You should set up a server according to your own needs and specifications. diff --git a/docs/src/graphql/full-example.md b/docs/src/graphql/full-example.md index 942419c95..d5facc066 100644 --- a/docs/src/graphql/full-example.md +++ b/docs/src/graphql/full-example.md @@ -2,7 +2,7 @@ Finally, let's combine nested entities, filtering, and pagination into one complete example. -Sticking with the same block explorer example, let's say that we are looking for a particular transaction and its containing block, but we don't remember either of the hashes. All we know is that the total value of the transaction is greater than zero, it was sometime after the start of the `beta-3` testnet, and it was included as part of the first fifty blocks. Additionally, we don't want to parse through all the results at once, so we only want to look at two records at a time. Finally, we think that it may have been on the more recent side, so we want to check them in reverse chronological order. +Sticking with the same block explorer example, let's say that we are looking for a particular transaction and its containing block, but we don't remember either of the hashes. All we know is that the total value of the transaction is greater than zero, it was sometime after the start of the `beta-4` testnet, and it was included as part of the first fifty blocks. Additionally, we don't want to parse through all the results at once, so we only want to look at two records at a time. Finally, we think that it may have been on the more recent side, so we want to check them in reverse chronological order. Putting all of that together, we get the following query: diff --git a/docs/src/indexing/blocks-and-transactions.md b/docs/src/indexing/blocks-and-transactions.md index ad440d527..2c5f0924d 100644 --- a/docs/src/indexing/blocks-and-transactions.md +++ b/docs/src/indexing/blocks-and-transactions.md @@ -4,33 +4,81 @@ You can use the `BlockData` and `TransactionData` data structures to index impor ## `BlockData` +> The `BlockData` struct is how blocks are represented in the Fuel indexer. It contains metadata such as the ID, height, and time, as well as a list of the transactions it contains (represented by `TransactionData`). It also contains the public key hash of the block producer, if present. + +### Definition + ```rust,ignore pub struct BlockData { - pub height: u64, + pub height: u32, pub id: Bytes32, + pub header: Header, pub producer: Option, pub time: i64, + pub consensus: Consensus, pub transactions: Vec, } ``` -The `BlockData` struct is how blocks are represented in the Fuel indexer. It contains metadata such as the ID, height, and time, as well as a list of the transactions it contains (represented by `TransactionData`). It also contains the public key hash of the block producer, if present. +### Usage + +```rust,ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "my_indexer.manifest.yaml")] +mod my_indexer { + fn handle_block(block_data: BlockData) { + let height = block_data.header.height; + info!("This block #{height}"); + } +} +``` + +--- ## `TransactionData` +> The `TransactionData` struct contains important information about a transaction in the Fuel network. The `id` field is the transaction hash, which is a 32-byte string. The `receipts` field contains a list of `Receipts`, which are generated by a Fuel node during the execution of a Sway smart contract; you can find more information in the [Receipts](./receipts.md) section. + +### Definition + ```rust,ignore pub struct TransactionData { pub transaction: Transaction, - pub status: ClientTransactionStatus, + pub status: TransactionStatus, pub receipts: Vec, - pub id: ClientTxId, + pub id: TxId, +} +``` + +### Usage + +```rust,ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "my_indexer.manifest.yaml")] +mod my_indexer { + fn handle_transaction(block_data: BlockData) { + let height = block_data.header.height; + if !block_data.transactions.is_empty() { + let transaction = block_data.transactions[0]; + info!("Transaction {} in block at height {} has {} receipts", transaction.id, block_data.header.height, transaction.receipts.len()); + } + + } } ``` -The `TransactionData` struct contains important information about a transaction in the Fuel network. The `id` field is the transaction hash, which is a 32-byte string. The `receipts` field contains a list of `Receipts`, which are generated by a Fuel node during the execution of a Sway smart contract; you can find more information in the [Receipts](./receipts.md) section. +--- ### `Transaction` +> `Transaction` refers to the Fuel transaction entity and can be one of three distinct types: `Script`, `Create`, or `Mint`. Explaining the differences between each of the types is out of scope for the Fuel indexer; however, you can find information about the `Transaction` type in the [Fuel specifications](https://specs.fuel.network/master/tx-format/transaction.html). + +### Definition + ```rust,ignore pub enum Transaction { Script(Script), @@ -39,10 +87,43 @@ pub enum Transaction { } ``` -`Transaction` refers to the Fuel transaction entity and can be one of three distinct types: `Script`, `Create`, or `Mint`. Explaining the differences between each of the types is out of scope for the Fuel indexer; however, you can find information about the `Transaction` type in the [Fuel specifications](https://specs.fuel.network/master/tx-format/transaction.html). +### Usage + +```rust,ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "my_indexer.manifest.yaml")] +mod my_indexer { + fn handle_transaction(block_data: BlockData) { + let height = block_data.header.height; + if !block_data.transactions.is_empty() { + let transaction = block_data.transactions[0]; + match transaction.transaction { + fuel::Transaction::Script(tx) => { + info!("We found a script transaction!"); + } + fuel::Transaction::Create(tx) => { + info!("We found a create transaction!"); + } + fuel::Transaction::Mint(tx) => { + info!("We found a mint transaction!"); + } + } + } + + } +} +``` + +--- ### `TransactionStatus` +> `TransactionStatus` refers to the status of a `Transaction` in the Fuel network. + +### Definition + ```rust,ignore pub enum TransactionStatus { Failure { @@ -63,4 +144,34 @@ pub enum TransactionStatus { } ``` -`TransactionStatus` refers to the status of a `Transaction` in the Fuel network. +### Usage + +```rust,ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "my_indexer.manifest.yaml")] +mod my_indexer { + fn handle_transaction(block_data: BlockData) { + let height = block_data.header.height; + if !block_data.transactions.is_empty() { + let transaction = block_data.transactions[0]; + match transaction.transaction { + fuel::Transaction::Script(tx) => { + match tx.status { + fuel::TransactionStatus::Success { + block_id, time + } => { + info!("Transaction {} in block {} was successful at {}", tx.id, block_id, time); + } + } + } + _ => { + info!("We don't care about this transaction type"); + } + } + } + + } +} +``` diff --git a/docs/src/indexing/index.md b/docs/src/indexing/index.md index 7049d42ff..f08aa0003 100644 --- a/docs/src/indexing/index.md +++ b/docs/src/indexing/index.md @@ -1,11 +1,14 @@ # Indexing -You can index three main types of data from the Fuel network: blocks, transactions, and transaction receipts. You can read more about these data types below: +> ### Well what can I index? -- [**Blocks and Transactions**](./blocks-and-transactions.md) +You can index three main types of data from the Fuel network: -- [**Transaction Receipts**](./receipts.md) +- [Blocks](./blocks-and-transactions.md) +- [Transactions](./blocks-and-transactions.md) +- [Transaction receipts](./receipts.md) -If you've previously built an indexer for the EVM, you may be used to only being able to index data that is emitted as an event. -However, with Fuel you can index the entire transaction, which means you can use much more than logged data, allowing you to reduce the number of logs you need in your contract. +> If you've previously built an indexer for the EVM, you may be used to only being able to index data that is emitted as an event. +> +> However, with Fuel you can index the entire transaction, which means you can use much more than logged data, allowing you to reduce the number of logs you need in your contract. diff --git a/docs/src/project-components/index.md b/docs/src/project-components/index.md index 2997f5712..3439b92ab 100644 --- a/docs/src/project-components/index.md +++ b/docs/src/project-components/index.md @@ -4,19 +4,19 @@ The Fuel indexer project can currently be used in a number of different ways: -- as tooling to compile arbitrary indicies +- as tooling to interact with indexers - as a standalone service -- as a part of a Fuel project, alongside other components of the Fuel ecosystem (e.g. [Sway](https://fuellabs.github.io/sway)) +- as a part of a larger Fuel project, alongside other components of the Fuel ecosystem (e.g. [Sway smart contracts](https://fuellabs.github.io/sway)) -We'll describe these three different implementations below. +We'll describe these three different use cases below. -### As tooling for compiling indexers +### As tooling to interact with indexers -The Fuel indexer provides functionality to make it easy to build and compile abitrary indexers by using [`forc index`](../forc-index/index.md). For info on how to use indexer tooling to compile arbitrary indexers, check out our [Quickstart](../getting-started/quickstart.md) example for a more in-depth exploration of how to compile indexers. +The Fuel indexer provides functionality to make it easy to build and compile abitrary indexers by using the [`forc index`](../forc-index/index.md) CLI tool. Using `forc index`, users can create, build, deploy, and remove indexers, as well as authenticate against a running indexer service, and check the status of running indexers. ### As a standalone service -You can also start the Fuel indexer as a standalone binary that connects to a Fuel node to monitor the Fuel blockchain for new blocks and transactions. To do so, run the requisite database migrations, adjust the configuration to connect to a Fuel node, and start the service. +You can also start the Fuel indexer as a standalone service that connects to a Fuel node in order to monitor the Fuel blockchain for new blocks and transactions. To do so, run the requisite database migrations, adjust the configuration to connect to a Fuel node, and start the service. ### As part of a Fuel project @@ -41,10 +41,12 @@ Finally, you can run the Fuel indexer as part of a project that uses other compo └── lib.rs ``` +--- + ## An Indexer Project at a Glance Every Fuel indexer project requires three components: -- a [Manifest](./manifest.md) describing indexer metadata -- a [Schema](./schema.md) containing models for the data you want to index -- a [Module](./module.md) which houses the logic for creating and saving the aforementioned data models +- a [Manifest](./manifest.md) describing how the indexer should work +- a [Schema](./schema.md) containing data models for the data that is to be indexed +- a [Module](./module.md) which contains the logic for how data coming from the FuelVM should be saved into an index diff --git a/docs/src/project-components/manifest.md b/docs/src/project-components/manifest.md index 2de84086b..fe8475b65 100644 --- a/docs/src/project-components/manifest.md +++ b/docs/src/project-components/manifest.md @@ -1,13 +1,15 @@ # Manifest -A manifest serves as the YAML configuration file for a given indexer. A proper manifest has the following structure: +A manifest is a YAML configuration file that specifies various aspects of how an indexer should function: Where should the indexer start? Where should the indexer end? What contract should the indexer subscribe to? + +Below is a sample indexer manifest file ```yaml -namespace: fuel -identifier: index1 +namespace: fuellabs +identifier: order_book_v1 fuel_client: beta-4.fuel.network:80 abi: path/to/my/contract-abi.json -contract_id: "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051" +contract_id: "fuels0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051" graphql_schema: path/to/my/schema.graphql start_block: 1564 end_block: 310000 diff --git a/docs/src/project-components/module.md b/docs/src/project-components/module.md index d8e718286..2a4ddd959 100644 --- a/docs/src/project-components/module.md +++ b/docs/src/project-components/module.md @@ -1,6 +1,8 @@ -# WASM Modules +# Indexer modules -WebAssembly (WASM) modules are compiled binaries that are registered into a Fuel indexer at runtime. The WASM bytes are read in by the indexer and _executors_ are created which will implement blocking calls to the WASM runtime. +> While the Fuel indexer does support native indexer modules, this section will mostly focus on Web Assembly (WASM) modules. + +WebAssembly (WASM) modules are compiled binaries that are registered or deployed to a Fuel indexer at runtime. The WASM bytes are read in by the indexer and _executors_ are created which will essentially pass blocks of on-chain data from the FuelVM to your indexers indefinitely. The WASM module is generated based on your manifest, schema, and your `lib.rs` file. @@ -13,20 +15,23 @@ Here, you can define which functions handle different events based on the functi We can look at the function below as an example: ```rust, ignore -fn index_logged_greeting(greeter: Greeting) { - // function logic goes here +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "my_indexer.manifest.yaml")] +mod my_indexer { + + // This `log_the_greeting` function will be called, when we find + // a `Greeting` in a block. + fn log_the_greeting(greeter: Greeting) { + info!("The greeter is: {greeter:?}"); + } } ``` -All transactions that have a receipt that contains data with a type of `Greeting` will be handled by the function. +> You can learn more about what data can be indexed in the [Indexing](../indexing/index.md) section. -You can learn more about what data can be indexed in the [Indexing](../indexing/index.md) section. - -To save an instance of a schema type in your database, you can call the `save` method on the instance. - -```rust, ignore -instance.save(); -``` +--- ## Usage @@ -36,23 +41,19 @@ To compile your indexer code to WASM, you'll first need to install the `wasm32-u rustup add target wasm32-unknown-unknown ``` -After that, you would compile your indexer code by navigating to the root folder for your indexer code and build. An example of this can be found below: - -```bash -cd /my/index-lib && cargo build --release -``` - -## Notes on WASM - -There are a few points that Fuel indexer users should know when using WASM: - -1. WASM modules are only used if the execution mode specified in your manifest file is `wasm`. - -2. Developers should be aware of what things may not work off-the-shelf in a module: file I/O, thread spawning, and anything that depends on system libraries. This is due to the technological limitations of WASM as a whole; more information can be found [here](https://rustwasm.github.io/docs/book/reference/which-crates-work-with-wasm.html). - -3. As of this writing, there is a small bug in newly built Fuel indexer WASM modules that produces a WASM runtime error due to an errant upstream dependency. For now, a quick workaround requires the use of `wasm-snip` to remove the errant symbols from the WASM module. More info can be found in the related script [here](https://github.com/FuelLabs/fuel-indexer/blob/develop/scripts/stripper.bash). - -4. Users on Apple Silicon macOS systems may experience trouble when trying to build WASM modules due to its `clang` binary not supporting WASM targets. If encountered, you can install a binary with better support from Homebrew (`brew install llvm`) and instruct `rustc` to leverage it by setting the following environment variables: - -- `AR=/opt/homebrew/opt/llvm/bin/llvm-ar` -- `CC=/opt/homebrew/opt/llvm/bin/clang` +After that, you can conveniently use the [`forc index`](./../forc-index/index.md) plugin to manager your indexers. Simply use `forc index build` to build your indexer or checkout the [`forc index build`](./../forc-index/build.md) docs for more options. + +> ## Notes on Web Assembly modules +> +> There are a few points that Fuel indexer users should know when using WASM: +> +> 1. WASM modules are only used if the execution mode specified in your manifest file is `wasm`. +> +> 2. Developers should be aware of what things may not work off-the-shelf in a module: file I/O, thread spawning, and anything that depends on system libraries or makes system calls. This is due to the technological limitations of WASM as a whole; more information can be found [here](https://rustwasm.github.io/docs/book/reference/which-crates-work-with-wasm.html). +> +> 3. As of this writing, there is a small bug in newly built Fuel indexer WASM modules that produces a WASM runtime error due to an errant upstream dependency. For now, a quick workaround requires the use of `wasm-snip` to remove the errant symbols from the WASM module. More info can be found in the related script [here](https://github.com/FuelLabs/fuel-indexer/blob/develop/scripts/stripper.bash). +> +> 4. Users on Apple Silicon macOS systems may experience trouble when trying to build WASM modules due to its `clang` binary not supporting WASM targets. If encountered, you can install a binary with better support from Homebrew (`brew install llvm`) and instruct `rustc` to leverage it by setting the following environment variables: +> +> - `AR=/opt/homebrew/opt/llvm/bin/llvm-ar` +> - `CC=/opt/homebrew/opt/llvm/bin/clang` diff --git a/docs/src/project-components/schema.md b/docs/src/project-components/schema.md index e8c00ab2a..d661538ef 100644 --- a/docs/src/project-components/schema.md +++ b/docs/src/project-components/schema.md @@ -2,30 +2,31 @@ The GraphQL schema is a required component of the Fuel indexer. When data is indexed into the database, the actual values that are persisted to the database will be values created using the data structures defined in the schema. -In its most basic form, a Fuel indexer GraphQL schema should have a `schema` definition that contains a defined query root. The rest of the implementation is up to you. Here's an example of a well-formed schema: +Below is a sample GraphQL schema for a Fuel indexer. ```graphql -type FirstThing @entity { +type Metadata @entity(virtual: true) { + imageUrl: Charfield! + data: Blob +} + +type Account @entity { id: ID! - value: UInt8! + address: Address! + index: UInt8! + metadata: Metadata } -type SecondThing @entity { +type Wallet @entity { id: ID! - optional_value: UInt8 - timestamp: Timestamp! + name: Charfield! + accounts: [Account!]! } ``` -The types you see above (e.g., `ID`, `UInt8`, etc) are Fuel abstractions that were created to more seamlessly integrate with the Fuel VM and are not native to GraphQL. A deeper explanation on these -types can be found in [the Types section](../database/index.md). - -> Important: It is up to developers to manage their own unique IDs for each type, meaning that a data structure's `ID` field needs to be manually generated prior to saving it to the database. This generation can be as simple or complex as you want in order to fit your particular situation; the only requirement is that the developer implement their own custom generation. - -## Required and Optional Fields +For a complete list of all scalars that can be used in a Fuel indexer, please see the [GraphQL Scalars](./../graphql/scalars.md) section. -Required fields are denoted with a `!` following its type; for example, the `value` field of the `FirstThing` type is a `UInt8` and is required to be present for the indexer to successfully persist the entity. If a certain piece of information is essential to your use case, then you should mark that field as required. +Further, for a complete list of how Sway data types, GraphQL scalar types, and Fuel indexer database types map to each other, please see the [Database Types](./../database/index.md) section. -In contrast, optional fields are not required to be present for the indexer to persist the entity in storage. You can denote an optional field by just using the type name; for example, the `optional_value` field of the `SecondThing` type is optional, and should be a `UInt8` if present. If it's possible that a value might not always exist in the data you wish to index, consider making that the corresponding field optional. In your indexer code, you will need to use the `Option` Rust type when assigning a value to an optional field; values that are present should be assigned after being wrapped in `Some(..)` while absent values should be assigned using `None`. -> Important: The `ID` field is _always_ required. An indexer **will** return an error if an optional value is used for the `ID` field. +Finally, for a more in-depth explanation on the schema being used above 👆🏽, please read the [GraphQL](./../graphql/index.md) section. diff --git a/plugins/forc-index/README.md b/plugins/forc-index/README.md index b0cdc2a89..aaa9e2eb2 100644 --- a/plugins/forc-index/README.md +++ b/plugins/forc-index/README.md @@ -25,7 +25,7 @@ forc index start Deploy a given indexer project to a particular endpoint ```bash -forc index deploy --url https://beta-3-indexer.fuel.network +forc index deploy --url https://beta-4-indexer.fuel.network ``` ### `forc index remove` @@ -33,7 +33,7 @@ forc index deploy --url https://beta-3-indexer.fuel.network Kill a running indexer ```bash -forc index remove --url https://beta-3-indexer.fuel.network +forc index remove --url https://beta-4-indexer.fuel.network ``` ### `forc index check` From c6e5a5836035fe54d05c87a4d75fd428426494af Mon Sep 17 00:00:00 2001 From: Rashad Alston Date: Fri, 1 Sep 2023 14:51:48 -0400 Subject: [PATCH 11/33] breakout indexing section --- docs/src/SUMMARY.md | 34 ++-- docs/src/indexing/blocks-and-transactions.md | 177 ------------------ docs/src/indexing/custom-types/index.md | 1 + docs/src/indexing/fuel-types/blocks.md | 32 ++++ docs/src/indexing/fuel-types/index.md | 1 + .../{ => fuel-types/receipts}/burn.md | 8 +- .../{ => fuel-types/receipts}/call.md | 0 .../src/indexing/fuel-types/receipts/index.md | 1 + .../indexing/{ => fuel-types/receipts}/log.md | 0 .../{ => fuel-types/receipts}/logdata.md | 0 .../{ => fuel-types/receipts}/messageout.md | 0 .../{ => fuel-types/receipts}/mint.md | 0 .../{ => fuel-types/receipts}/panic.md | 0 .../{ => fuel-types/receipts}/receipts.md | 0 .../{ => fuel-types/receipts}/return.md | 0 .../{ => fuel-types/receipts}/returndata.md | 0 .../{ => fuel-types/receipts}/revert.md | 0 .../{ => fuel-types/receipts}/scriptresult.md | 0 .../{ => fuel-types/receipts}/transfer.md | 0 .../{ => fuel-types/receipts}/transferout.md | 0 .../indexing/fuel-types/transaction-status.md | 58 ++++++ docs/src/indexing/fuel-types/transactions.md | 33 ++++ docs/src/indexing/index.md | 25 ++- 23 files changed, 168 insertions(+), 202 deletions(-) delete mode 100644 docs/src/indexing/blocks-and-transactions.md create mode 100644 docs/src/indexing/custom-types/index.md create mode 100644 docs/src/indexing/fuel-types/blocks.md create mode 100644 docs/src/indexing/fuel-types/index.md rename docs/src/indexing/{ => fuel-types/receipts}/burn.md (62%) rename docs/src/indexing/{ => fuel-types/receipts}/call.md (100%) create mode 100644 docs/src/indexing/fuel-types/receipts/index.md rename docs/src/indexing/{ => fuel-types/receipts}/log.md (100%) rename docs/src/indexing/{ => fuel-types/receipts}/logdata.md (100%) rename docs/src/indexing/{ => fuel-types/receipts}/messageout.md (100%) rename docs/src/indexing/{ => fuel-types/receipts}/mint.md (100%) rename docs/src/indexing/{ => fuel-types/receipts}/panic.md (100%) rename docs/src/indexing/{ => fuel-types/receipts}/receipts.md (100%) rename docs/src/indexing/{ => fuel-types/receipts}/return.md (100%) rename docs/src/indexing/{ => fuel-types/receipts}/returndata.md (100%) rename docs/src/indexing/{ => fuel-types/receipts}/revert.md (100%) rename docs/src/indexing/{ => fuel-types/receipts}/scriptresult.md (100%) rename docs/src/indexing/{ => fuel-types/receipts}/transfer.md (100%) rename docs/src/indexing/{ => fuel-types/receipts}/transferout.md (100%) create mode 100644 docs/src/indexing/fuel-types/transaction-status.md create mode 100644 docs/src/indexing/fuel-types/transactions.md diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index c78faaed4..f1a82f84b 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -16,21 +16,25 @@ - [Schema](./project-components/schema.md) - [Module](./project-components/module.md) - [Indexing](./indexing/index.md) - - [Blocks and Transactions](./indexing/blocks-and-transactions.md) - - [Receipts](./indexing/receipts.md) - - [Burn](./indexing/burn.md) - - [Call](./indexing/call.md) - - [Log](./indexing/log.md) - - [LogData](./indexing/logdata.md) - - [MessageOut](./indexing/messageout.md) - - [Mint](./indexing/mint.md) - - [Panic](./indexing/panic.md) - - [Return](./indexing/return.md) - - [ReturnData](./indexing/returndata.md) - - [Revert](./indexing/revert.md) - - [ScriptResult](./indexing/scriptresult.md) - - [Transfer](./indexing/transfer.md) - - [TransferOut](./indexing/transferout.md) + - [Custom Types](./indexing/custom-types/index.md) + - [Fuel Types](./indexing/fuel-types/index.md) + - [Blocks](./indexing/fuel-types/blocks.md) + - [Transactions](./indexing/fuel-types/transactions.md) + - [Transaction Status](./indexing/fuel-types/transaction-status.md) + - [Receipts](./indexing/fuel-types/receipts/index.md) + - [Burn](./indexing/fuel-types/receipts/burn.md) + - [Call](./indexing/fuel-types/receipts/call.md) + - [Log](./indexing/fuel-types/receipts/log.md) + - [LogData](./indexing/fuel-types/receipts/logdata.md) + - [MessageOut](./indexing/fuel-types/receipts/messageout.md) + - [Mint](./indexing/fuel-types/receipts/mint.md) + - [Panic](./indexing/fuel-types/receipts/panic.md) + - [Return](./indexing/fuel-types/receipts/return.md) + - [ReturnData](./indexing/fuel-types/receipts/returndata.md) + - [Revert](./indexing/fuel-types/receipts/revert.md) + - [ScriptResult](./indexing/fuel-types/receipts/scriptresult.md) + - [Transfer](./indexing/fuel-types/receipts/transfer.md) + - [TransferOut](./indexing/fuel-types/receipts/transferout.md) - [GraphQL](./graphql/index.md) - [Scalars](./graphql/scalars.md) - [Directives](./graphql/directives.md) diff --git a/docs/src/indexing/blocks-and-transactions.md b/docs/src/indexing/blocks-and-transactions.md deleted file mode 100644 index 2c5f0924d..000000000 --- a/docs/src/indexing/blocks-and-transactions.md +++ /dev/null @@ -1,177 +0,0 @@ -# Blocks and Transactions - -You can use the `BlockData` and `TransactionData` data structures to index important information about the Fuel network for your dApp. - -## `BlockData` - -> The `BlockData` struct is how blocks are represented in the Fuel indexer. It contains metadata such as the ID, height, and time, as well as a list of the transactions it contains (represented by `TransactionData`). It also contains the public key hash of the block producer, if present. - -### Definition - -```rust,ignore -pub struct BlockData { - pub height: u32, - pub id: Bytes32, - pub header: Header, - pub producer: Option, - pub time: i64, - pub consensus: Consensus, - pub transactions: Vec, -} -``` - -### Usage - -```rust,ignore -extern crate alloc; -use fuel_indexer_utils::prelude::*; - -#[indexer(manifest = "my_indexer.manifest.yaml")] -mod my_indexer { - fn handle_block(block_data: BlockData) { - let height = block_data.header.height; - info!("This block #{height}"); - } -} -``` - ---- - -## `TransactionData` - -> The `TransactionData` struct contains important information about a transaction in the Fuel network. The `id` field is the transaction hash, which is a 32-byte string. The `receipts` field contains a list of `Receipts`, which are generated by a Fuel node during the execution of a Sway smart contract; you can find more information in the [Receipts](./receipts.md) section. - -### Definition - -```rust,ignore -pub struct TransactionData { - pub transaction: Transaction, - pub status: TransactionStatus, - pub receipts: Vec, - pub id: TxId, -} -``` - -### Usage - -```rust,ignore -extern crate alloc; -use fuel_indexer_utils::prelude::*; - -#[indexer(manifest = "my_indexer.manifest.yaml")] -mod my_indexer { - fn handle_transaction(block_data: BlockData) { - let height = block_data.header.height; - if !block_data.transactions.is_empty() { - let transaction = block_data.transactions[0]; - info!("Transaction {} in block at height {} has {} receipts", transaction.id, block_data.header.height, transaction.receipts.len()); - } - - } -} -``` - ---- - -### `Transaction` - -> `Transaction` refers to the Fuel transaction entity and can be one of three distinct types: `Script`, `Create`, or `Mint`. Explaining the differences between each of the types is out of scope for the Fuel indexer; however, you can find information about the `Transaction` type in the [Fuel specifications](https://specs.fuel.network/master/tx-format/transaction.html). - -### Definition - -```rust,ignore -pub enum Transaction { - Script(Script), - Create(Create), - Mint(Mint), -} -``` - -### Usage - -```rust,ignore -extern crate alloc; -use fuel_indexer_utils::prelude::*; - -#[indexer(manifest = "my_indexer.manifest.yaml")] -mod my_indexer { - fn handle_transaction(block_data: BlockData) { - let height = block_data.header.height; - if !block_data.transactions.is_empty() { - let transaction = block_data.transactions[0]; - match transaction.transaction { - fuel::Transaction::Script(tx) => { - info!("We found a script transaction!"); - } - fuel::Transaction::Create(tx) => { - info!("We found a create transaction!"); - } - fuel::Transaction::Mint(tx) => { - info!("We found a mint transaction!"); - } - } - } - - } -} -``` - ---- - -### `TransactionStatus` - -> `TransactionStatus` refers to the status of a `Transaction` in the Fuel network. - -### Definition - -```rust,ignore -pub enum TransactionStatus { - Failure { - block_id: String, - time: DateTime, - reason: String, - }, - SqueezedOut { - reason: String, - }, - Submitted { - submitted_at: DateTime, - }, - Success { - block_id: String, - time: DateTime, - }, -} -``` - -### Usage - -```rust,ignore -extern crate alloc; -use fuel_indexer_utils::prelude::*; - -#[indexer(manifest = "my_indexer.manifest.yaml")] -mod my_indexer { - fn handle_transaction(block_data: BlockData) { - let height = block_data.header.height; - if !block_data.transactions.is_empty() { - let transaction = block_data.transactions[0]; - match transaction.transaction { - fuel::Transaction::Script(tx) => { - match tx.status { - fuel::TransactionStatus::Success { - block_id, time - } => { - info!("Transaction {} in block {} was successful at {}", tx.id, block_id, time); - } - } - } - _ => { - info!("We don't care about this transaction type"); - } - } - } - - } -} -``` diff --git a/docs/src/indexing/custom-types/index.md b/docs/src/indexing/custom-types/index.md new file mode 100644 index 000000000..35d5c39b3 --- /dev/null +++ b/docs/src/indexing/custom-types/index.md @@ -0,0 +1 @@ +# Custom Types \ No newline at end of file diff --git a/docs/src/indexing/fuel-types/blocks.md b/docs/src/indexing/fuel-types/blocks.md new file mode 100644 index 000000000..ef884a20e --- /dev/null +++ b/docs/src/indexing/fuel-types/blocks.md @@ -0,0 +1,32 @@ +# `BlockData` + +> The `BlockData` struct is how blocks are represented in the Fuel indexer. It contains metadata such as the ID, height, and time, as well as a list of the transactions it contains (represented by `TransactionData`). It also contains the public key hash of the block producer, if present. + +## Definition + +```rust,ignore +pub struct BlockData { + pub height: u32, + pub id: Bytes32, + pub header: Header, + pub producer: Option, + pub time: i64, + pub consensus: Consensus, + pub transactions: Vec, +} +``` + +## Usage + +```rust,ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "my_indexer.manifest.yaml")] +mod my_indexer { + fn handle_block(block_data: BlockData) { + let height = block_data.header.height; + info!("This block #{height}"); + } +} +``` \ No newline at end of file diff --git a/docs/src/indexing/fuel-types/index.md b/docs/src/indexing/fuel-types/index.md new file mode 100644 index 000000000..4f327e316 --- /dev/null +++ b/docs/src/indexing/fuel-types/index.md @@ -0,0 +1 @@ +# Fuel Types diff --git a/docs/src/indexing/burn.md b/docs/src/indexing/fuel-types/receipts/burn.md similarity index 62% rename from docs/src/indexing/burn.md rename to docs/src/indexing/fuel-types/receipts/burn.md index 8f11889c9..417066451 100644 --- a/docs/src/indexing/burn.md +++ b/docs/src/indexing/fuel-types/receipts/burn.md @@ -1,5 +1,9 @@ # Burn +> - A `Burn` receipt is generated whenever an asset is burned in a Sway contract. [Read more about `Burn` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#burn-receipt) + +### Definition + ```rust, ignore use fuel_types::{AssetId, ContractId}; pub struct Burn { @@ -11,8 +15,8 @@ pub struct Burn { } ``` -- A `Burn` receipt is generated whenever an asset is burned in a Sway contract. -- [Read more about `Burn` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#burn-receipt) +### Usage + You can handle functions that produce a `Burn` receipt type by adding a parameter with the type `Burn`. diff --git a/docs/src/indexing/call.md b/docs/src/indexing/fuel-types/receipts/call.md similarity index 100% rename from docs/src/indexing/call.md rename to docs/src/indexing/fuel-types/receipts/call.md diff --git a/docs/src/indexing/fuel-types/receipts/index.md b/docs/src/indexing/fuel-types/receipts/index.md new file mode 100644 index 000000000..7df216dcf --- /dev/null +++ b/docs/src/indexing/fuel-types/receipts/index.md @@ -0,0 +1 @@ +# Receipts \ No newline at end of file diff --git a/docs/src/indexing/log.md b/docs/src/indexing/fuel-types/receipts/log.md similarity index 100% rename from docs/src/indexing/log.md rename to docs/src/indexing/fuel-types/receipts/log.md diff --git a/docs/src/indexing/logdata.md b/docs/src/indexing/fuel-types/receipts/logdata.md similarity index 100% rename from docs/src/indexing/logdata.md rename to docs/src/indexing/fuel-types/receipts/logdata.md diff --git a/docs/src/indexing/messageout.md b/docs/src/indexing/fuel-types/receipts/messageout.md similarity index 100% rename from docs/src/indexing/messageout.md rename to docs/src/indexing/fuel-types/receipts/messageout.md diff --git a/docs/src/indexing/mint.md b/docs/src/indexing/fuel-types/receipts/mint.md similarity index 100% rename from docs/src/indexing/mint.md rename to docs/src/indexing/fuel-types/receipts/mint.md diff --git a/docs/src/indexing/panic.md b/docs/src/indexing/fuel-types/receipts/panic.md similarity index 100% rename from docs/src/indexing/panic.md rename to docs/src/indexing/fuel-types/receipts/panic.md diff --git a/docs/src/indexing/receipts.md b/docs/src/indexing/fuel-types/receipts/receipts.md similarity index 100% rename from docs/src/indexing/receipts.md rename to docs/src/indexing/fuel-types/receipts/receipts.md diff --git a/docs/src/indexing/return.md b/docs/src/indexing/fuel-types/receipts/return.md similarity index 100% rename from docs/src/indexing/return.md rename to docs/src/indexing/fuel-types/receipts/return.md diff --git a/docs/src/indexing/returndata.md b/docs/src/indexing/fuel-types/receipts/returndata.md similarity index 100% rename from docs/src/indexing/returndata.md rename to docs/src/indexing/fuel-types/receipts/returndata.md diff --git a/docs/src/indexing/revert.md b/docs/src/indexing/fuel-types/receipts/revert.md similarity index 100% rename from docs/src/indexing/revert.md rename to docs/src/indexing/fuel-types/receipts/revert.md diff --git a/docs/src/indexing/scriptresult.md b/docs/src/indexing/fuel-types/receipts/scriptresult.md similarity index 100% rename from docs/src/indexing/scriptresult.md rename to docs/src/indexing/fuel-types/receipts/scriptresult.md diff --git a/docs/src/indexing/transfer.md b/docs/src/indexing/fuel-types/receipts/transfer.md similarity index 100% rename from docs/src/indexing/transfer.md rename to docs/src/indexing/fuel-types/receipts/transfer.md diff --git a/docs/src/indexing/transferout.md b/docs/src/indexing/fuel-types/receipts/transferout.md similarity index 100% rename from docs/src/indexing/transferout.md rename to docs/src/indexing/fuel-types/receipts/transferout.md diff --git a/docs/src/indexing/fuel-types/transaction-status.md b/docs/src/indexing/fuel-types/transaction-status.md new file mode 100644 index 000000000..6a089adbb --- /dev/null +++ b/docs/src/indexing/fuel-types/transaction-status.md @@ -0,0 +1,58 @@ + +# `TransactionStatus` + +> `TransactionStatus` refers to the status of a `Transaction` in the Fuel network. + +## Definition + +```rust,ignore +pub enum TransactionStatus { + Failure { + block_id: String, + time: DateTime, + reason: String, + }, + SqueezedOut { + reason: String, + }, + Submitted { + submitted_at: DateTime, + }, + Success { + block_id: String, + time: DateTime, + }, +} +``` + +## Usage + +```rust,ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "my_indexer.manifest.yaml")] +mod my_indexer { + fn handle_transaction(block_data: BlockData) { + let height = block_data.header.height; + if !block_data.transactions.is_empty() { + let transaction = block_data.transactions[0]; + match transaction.transaction { + fuel::Transaction::Script(tx) => { + match tx.status { + fuel::TransactionStatus::Success { + block_id, time + } => { + info!("Transaction {} in block {} was successful at {}", tx.id, block_id, time); + } + } + } + _ => { + info!("We don't care about this transaction type"); + } + } + } + + } +} +``` diff --git a/docs/src/indexing/fuel-types/transactions.md b/docs/src/indexing/fuel-types/transactions.md new file mode 100644 index 000000000..500a22460 --- /dev/null +++ b/docs/src/indexing/fuel-types/transactions.md @@ -0,0 +1,33 @@ +# `TransactionData` + +> The `TransactionData` struct contains important information about a transaction in the Fuel network. The `id` field is the transaction hash, which is a 32-byte string. The `receipts` field contains a list of `Receipts`, which are generated by a Fuel node during the execution of a Sway smart contract; you can find more information in the [Receipts](./receipts.md) section. + +## Definition + +```rust,ignore +pub struct TransactionData { + pub transaction: Transaction, + pub status: TransactionStatus, + pub receipts: Vec, + pub id: TxId, +} +``` + +## Usage + +```rust,ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "my_indexer.manifest.yaml")] +mod my_indexer { + fn handle_transaction(block_data: BlockData) { + let height = block_data.header.height; + if !block_data.transactions.is_empty() { + let transaction = block_data.transactions[0]; + info!("Transaction {} in block at height {} has {} receipts", transaction.id, block_data.header.height, transaction.receipts.len()); + } + + } +} +``` \ No newline at end of file diff --git a/docs/src/indexing/index.md b/docs/src/indexing/index.md index f08aa0003..2cff9707f 100644 --- a/docs/src/indexing/index.md +++ b/docs/src/indexing/index.md @@ -1,14 +1,23 @@ # Indexing -> ### Well what can I index? - -You can index three main types of data from the Fuel network: - -- [Blocks](./blocks-and-transactions.md) -- [Transactions](./blocks-and-transactions.md) -- [Transaction receipts](./receipts.md) - > If you've previously built an indexer for the EVM, you may be used to only being able to index data that is emitted as an event. > > However, with Fuel you can index the entire transaction, which means you can use much more than logged data, allowing you to reduce the number of logs you need in your contract. + +## What can I index? + +You can index two types of data: Fuel types, and Custom types: + + +### Fuel types + +> Description + +- [Blocks](./fuel-types/blocks.md) +- [Transactions](./fuel-types/transactions.md) +- [Transaction Receipts](./fuel-types/receipts/index.md) + +### Custom types + +> Description From 4f0930af1f71f7a9731fd0fe955c662555e7f581 Mon Sep 17 00:00:00 2001 From: Rashad Alston Date: Fri, 1 Sep 2023 15:57:03 -0400 Subject: [PATCH 12/33] simplify examples --- .../hello_indexer_native.schema.graphql | 4 ---- .../hello-indexer-native/src/main.rs | 21 +++++++------------ .../schema/hello_indexer.schema.graphql | 4 ---- examples/hello-world/hello-indexer/src/lib.rs | 15 ++++++------- 4 files changed, 14 insertions(+), 30 deletions(-) diff --git a/examples/hello-world-native/hello-indexer-native/schema/hello_indexer_native.schema.graphql b/examples/hello-world-native/hello-indexer-native/schema/hello_indexer_native.schema.graphql index 8e6997378..98a900b13 100644 --- a/examples/hello-world-native/hello-indexer-native/schema/hello_indexer_native.schema.graphql +++ b/examples/hello-world-native/hello-indexer-native/schema/hello_indexer_native.schema.graphql @@ -2,17 +2,13 @@ type Greeter @entity { id: ID! name: Charfield! - first_seen: UInt4! last_seen: UInt4! - visits: Blob! } # Calling this `Salutation` so as to not clash with `Greeting` in the contract type Salutation @entity { id: ID! - message_hash: Bytes32! message: Charfield! greeter: Greeter! - first_seen: UInt4! last_seen: UInt4! } diff --git a/examples/hello-world-native/hello-indexer-native/src/main.rs b/examples/hello-world-native/hello-indexer-native/src/main.rs index 7ba4340a2..9b1d4d9d7 100644 --- a/examples/hello-world-native/hello-indexer-native/src/main.rs +++ b/examples/hello-world-native/hello-indexer-native/src/main.rs @@ -28,22 +28,17 @@ use fuel_indexer_utils::prelude::*; )] mod hello_world_native { - async fn index_logged_greeting(event: Greeting, block: BlockData) { - let greeting = event.greeting.to_right_trimmed_str().to_string(); + async fn index_logged_greeting(event: Greeting, block_data: BlockData) { + let height = std::cmp::min(0, block_data.header.height - 1); let name = event.person.name.to_right_trimmed_str().to_string(); - let height = block.height; - let data = vec![1u8, 2, 3, 4, 5, 6, 7, 8].into(); - let greeter = Greeter::new(name.clone(), height, height, data) - .get_or_create() - .await; - + let greeting = event.greeting.to_right_trimmed_str().to_string(); let message = format!("{greeting} 👋, my name is {name}"); - let message_hash = bytes32(&message); - let salutation = - Salutation::new(message_hash, message, greeter.id.clone(), height, height) - .get_or_create() - .await; + let greeter = Greeter::new(name, height).get_or_create().await; + + let salutation = Salutation::new(message, greeter.id.clone(), height) + .get_or_create() + .await; greeter.save().await; salutation.save().await; diff --git a/examples/hello-world/hello-indexer/schema/hello_indexer.schema.graphql b/examples/hello-world/hello-indexer/schema/hello_indexer.schema.graphql index 8e6997378..98a900b13 100644 --- a/examples/hello-world/hello-indexer/schema/hello_indexer.schema.graphql +++ b/examples/hello-world/hello-indexer/schema/hello_indexer.schema.graphql @@ -2,17 +2,13 @@ type Greeter @entity { id: ID! name: Charfield! - first_seen: UInt4! last_seen: UInt4! - visits: Blob! } # Calling this `Salutation` so as to not clash with `Greeting` in the contract type Salutation @entity { id: ID! - message_hash: Bytes32! message: Charfield! greeter: Greeter! - first_seen: UInt4! last_seen: UInt4! } diff --git a/examples/hello-world/hello-indexer/src/lib.rs b/examples/hello-world/hello-indexer/src/lib.rs index e60f37431..f6a77c2c6 100644 --- a/examples/hello-world/hello-indexer/src/lib.rs +++ b/examples/hello-world/hello-indexer/src/lib.rs @@ -32,19 +32,16 @@ use fuel_indexer_utils::prelude::*; #[indexer(manifest = "examples/hello-world/hello-indexer/hello_indexer.manifest.yaml")] mod hello_world_indexer { - fn index_logged_greeting(event: Greeting, block: BlockData) { - let greeting = event.greeting.to_right_trimmed_str().to_string(); + fn index_logged_greeting(event: Greeting, block_data: BlockData) { + let height = std::cmp::min(0, block_data.header.height - 1); let name = event.person.name.to_right_trimmed_str().to_string(); - let height = block.height; - let data = vec![1u8, 2, 3, 4, 5, 6, 7, 8].into(); - let greeter = Greeter::new(name.clone(), height, height, data).get_or_create(); - + let greeting = event.greeting.to_right_trimmed_str().to_string(); let message = format!("{greeting} 👋, my name is {name}"); - let message_hash = bytes32(&message); + + let greeter = Greeter::new(name, height).get_or_create(); let salutation = - Salutation::new(message_hash, message, greeter.id.clone(), height, height) - .get_or_create(); + Salutation::new(message, greeter.id.clone(), height).get_or_create(); greeter.save(); salutation.save(); From f6149bab2a1bdd1cf5517015885d5e8dc94acb60 Mon Sep 17 00:00:00 2001 From: Rashad Alston Date: Fri, 8 Sep 2023 12:26:20 -0400 Subject: [PATCH 13/33] update usage --- docs/src/indexing/fuel-types/receipts/burn.md | 29 ++++++++++++---- docs/src/indexing/fuel-types/receipts/call.md | 32 +++++++++++++----- docs/src/indexing/fuel-types/receipts/log.md | 33 ++++++++++++++----- .../indexing/fuel-types/receipts/logdata.md | 29 +++++++++------- .../fuel-types/receipts/messageout.md | 24 +++++++++----- docs/src/indexing/fuel-types/receipts/mint.md | 31 +++++++++++++---- .../indexing/fuel-types/transaction-status.md | 16 ++++----- docs/src/indexing/fuel-types/transactions.md | 9 +++-- 8 files changed, 142 insertions(+), 61 deletions(-) diff --git a/docs/src/indexing/fuel-types/receipts/burn.md b/docs/src/indexing/fuel-types/receipts/burn.md index 417066451..9455c572f 100644 --- a/docs/src/indexing/fuel-types/receipts/burn.md +++ b/docs/src/indexing/fuel-types/receipts/burn.md @@ -1,8 +1,8 @@ -# Burn +# `Burn` -> - A `Burn` receipt is generated whenever an asset is burned in a Sway contract. [Read more about `Burn` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#burn-receipt) +> A `Burn` receipt is generated whenever an asset is burned in a Sway contract. [Read more about `Burn` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#burn-receipt) -### Definition +## Definition ```rust, ignore use fuel_types::{AssetId, ContractId}; @@ -15,13 +15,28 @@ pub struct Burn { } ``` -### Usage - +## Usage You can handle functions that produce a `Burn` receipt type by adding a parameter with the type `Burn`. ```rust, ignore -fn handle_burn(burn: Burn) { - // handle the emitted Burn receipt +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "my_indexer.manifest.yaml")] +mod my_indexer { + fn handle_burn_receipt(block_data: BlockData) { + let height = block_data.header.height; + if !block_data.transactions.is_empty() { + let transaction = block_data.transactions[0]; + for receipt in transaction.receipts { + match receipt { + fuel::Receipt::Burn { contract_id, .. } => { + info!("Found burn receipt from contract {contract_id:?}"); + } + } + } + } + } } ``` diff --git a/docs/src/indexing/fuel-types/receipts/call.md b/docs/src/indexing/fuel-types/receipts/call.md index 480bab4e3..3892d91cd 100644 --- a/docs/src/indexing/fuel-types/receipts/call.md +++ b/docs/src/indexing/fuel-types/receipts/call.md @@ -1,4 +1,8 @@ -# Call +# `Call` + +> A `Call` receipt is generated whenever a function is called in a Sway contract. The `fn_name` field contains the name of the called function from the aforementioned contract. [Read more about `Call` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#call-receipt). + +## Definition ```rust, ignore use fuel_types::{AssetId, ContractId}; @@ -12,14 +16,26 @@ pub struct Call { } ``` -- A `Call` receipt is generated whenever a function is called in a Sway contract. -- The `fn_name` field contains the name of the called function from the aforementioned contract. -- [Read more about `Call` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#call-receipt) - -You can handle functions that produce a `Call` receipt type by adding a parameter with the type `Call`. +## Usage ```rust, ignore -fn handle_call(call: Call) { - // handle the emitted Call receipt +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "my_indexer.manifest.yaml")] +mod my_indexer { + fn handle_call_receipt(block_data: BlockData) { + let height = block_data.header.height; + if !block_data.transactions.is_empty() { + let transaction = block_data.transactions[0]; + for receipt in transaction.receipts { + match receipt { + fuel::Receipt::Call { contract_id, .. } => { + info!("Found call receipt from contract {contract_id:?}"); + } + } + } + } + } } ``` diff --git a/docs/src/indexing/fuel-types/receipts/log.md b/docs/src/indexing/fuel-types/receipts/log.md index 88a60f8c1..63a9563db 100644 --- a/docs/src/indexing/fuel-types/receipts/log.md +++ b/docs/src/indexing/fuel-types/receipts/log.md @@ -1,4 +1,8 @@ -# Log +# `Log` + +> A `Log` receipt is generated when calling `log()` on a non-reference types in a Sway contracts - specifically `bool`, `u8`, `u16`, `u32`, and `u64`. The `ra` field includes the value being logged while `rb` may include a non-zero value representing a unique ID for the `log` instance. [Read more about `Log` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#log-receipt). + +## Definition ```rust, ignore use fuel_types::ContractId; @@ -9,15 +13,26 @@ pub struct Log { } ``` -- A `Log` receipt is generated when calling `log()` on a non-reference types in a Sway contracts. - - Specifically `bool`, `u8`, `u16`, `u32`, and `u64`. -- The `ra` field includes the value being logged while `rb` may include a non-zero value representing a unique ID for the `log` instance. -- [Read more about `Log` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#log-receipt) - -You can handle functions that produce a `Log` receipt type by adding a parameter with the type `Log`. +## Usage ```rust, ignore -fn handle_log(log: Log) { - // handle the emitted Log receipt +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "my_indexer.manifest.yaml")] +mod my_indexer { + fn handle_log_receipt(block_data: BlockData) { + let height = block_data.header.height; + if !block_data.transactions.is_empty() { + let transaction = block_data.transactions[0]; + for receipt in transaction.receipts { + match receipt { + fuel::Receipt::Log { contract_id, .. } => { + info!("Found log receipt from contract {contract_id:?}"); + } + } + } + } + } } ``` diff --git a/docs/src/indexing/fuel-types/receipts/logdata.md b/docs/src/indexing/fuel-types/receipts/logdata.md index 8da6540a9..3ca421cbc 100644 --- a/docs/src/indexing/fuel-types/receipts/logdata.md +++ b/docs/src/indexing/fuel-types/receipts/logdata.md @@ -1,5 +1,13 @@ -# LogData +# `LogData` + +> A `LogData` receipt is generated when calling `log()` in a Sway contract on a reference type; this includes all types _except_ non-reference types. +> +> The `data` field will include the logged value as a hexadecimal. The `rb` field will contain a unique ID that can be used to look up the logged data type. [Read more about `LogData` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#logdata-receipt). +> +> Note: the example below will run both when the type `MyEvent` is logged as well as when `MyEvent` is returned from a function + +## Definition ```rust,ignore use fuel_types::ContractId; @@ -12,17 +20,16 @@ pub struct LogData { } ``` -- A `LogData` receipt is generated when calling `log()` in a Sway contract on a reference type; this includes all types _except_ non-reference types. -- The `data` field will include the logged value as a hexadecimal. - - The `rb` field will contain a unique ID that can be used to look up the logged data type. -- [Read more about `LogData` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#logdata-receipt) - -You can handle functions that produce a `LogData` receipt type by using the logged type as a function parameter. - -> Note: the example below will run both when the type `MyStruct` is logged as well as when `MyStruct` is returned from a function. +## Usage ```rust, ignore -fn handle_log_data(data: MyStruct) { - // handle the emitted LogData receipt +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "my_indexer.manifest.yaml")] +mod my_indexer { + fn handle_log_data(event: MyEvent) { + info!("Event {event:?} was logged in the contract"); + } } ``` diff --git a/docs/src/indexing/fuel-types/receipts/messageout.md b/docs/src/indexing/fuel-types/receipts/messageout.md index f996db3ca..19d157bb5 100644 --- a/docs/src/indexing/fuel-types/receipts/messageout.md +++ b/docs/src/indexing/fuel-types/receipts/messageout.md @@ -1,4 +1,10 @@ -# MessageOut +# `MessageOut` + +> A `MessageOut` receipt is generated as a result of the `send_typed_message()` Sway method in which a message is sent to a recipient address along with a certain amount of coins. +> +> The `data` field supports data of an arbitrary type `T` and will be decoded by the indexer upon receipt. [Read more about `MessageOut` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#messageout-receipt). + +## Definition ```rust,ignore use fuel_types::{MessageId, Bytes32, Address}; @@ -14,14 +20,16 @@ pub struct MessageOut { } ``` -- A `MessageOut` receipt is generated as a result of the `send_typed_message()` Sway method in which a message is sent to a recipient address along with a certain amount of coins. -- The `data` field supports data of an arbitrary type `T` and will be decoded by the indexer upon receipt. -- [Read more about `MessageOut` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#messageout-receipt) - -You can handle functions that produce a `MessageOut` receipt type by adding a parameter with the type `MessageOut`. +## Usage ```rust, ignore -fn handle_message_out(message_out: MessageOut) { - // handle the emitted MessageOut receipt +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "my_indexer.manifest.yaml")] +mod my_indexer { + fn handle_message_out(event: MyEvent) { + info!("Event {event:?} was logged in the contract"); + } } ``` diff --git a/docs/src/indexing/fuel-types/receipts/mint.md b/docs/src/indexing/fuel-types/receipts/mint.md index 2017478b2..fd63e46c5 100644 --- a/docs/src/indexing/fuel-types/receipts/mint.md +++ b/docs/src/indexing/fuel-types/receipts/mint.md @@ -1,4 +1,8 @@ -# Mint +# `Mint` + +> A `Mint` receipt is generated whenever an asset is burned in a Sway contract. [Read more about `Mint` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#mint-receipt). + +## Definition ```rust, ignore use fuel_types::{AssetId, ContractId}; @@ -11,13 +15,26 @@ pub struct Mint { } ``` -- A `Mint` receipt is generated whenever an asset is burned in a Sway contract. -- [Read more about `Mint` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#mint-receipt) - -You can handle functions that produce a `Mint` receipt type by adding a parameter with the type `Mint`. +## Usage ```rust, ignore -fn handle_mint(mint: Mint) { - // handle the emitted Mint receipt +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "my_indexer.manifest.yaml")] +mod my_indexer { + fn handle_mint_receipt(block_data: BlockData) { + let height = block_data.header.height; + if !block_data.transactions.is_empty() { + let transaction = block_data.transactions[0]; + for receipt in transaction.receipts { + match receipt { + fuel::Receipt::Mint { contract_id, .. } => { + info!("Found mint receipt from contract {contract_id:?}"); + } + } + } + } + } } ``` diff --git a/docs/src/indexing/fuel-types/transaction-status.md b/docs/src/indexing/fuel-types/transaction-status.md index 6a089adbb..a5aa02ea3 100644 --- a/docs/src/indexing/fuel-types/transaction-status.md +++ b/docs/src/indexing/fuel-types/transaction-status.md @@ -38,21 +38,19 @@ mod my_indexer { if !block_data.transactions.is_empty() { let transaction = block_data.transactions[0]; match transaction.transaction { - fuel::Transaction::Script(tx) => { - match tx.status { - fuel::TransactionStatus::Success { - block_id, time - } => { - info!("Transaction {} in block {} was successful at {}", tx.id, block_id, time); - } + fuel::Transaction::Script(tx) => match tx.status { + fuel::TransactionStatus::Success { block_id, time } => { + info!( + "Transaction {} in block {} was successful at {}", + tx.id, block_id, time + ); } - } + }, _ => { info!("We don't care about this transaction type"); } } } - } } ``` diff --git a/docs/src/indexing/fuel-types/transactions.md b/docs/src/indexing/fuel-types/transactions.md index 500a22460..e4191ab22 100644 --- a/docs/src/indexing/fuel-types/transactions.md +++ b/docs/src/indexing/fuel-types/transactions.md @@ -25,9 +25,14 @@ mod my_indexer { let height = block_data.header.height; if !block_data.transactions.is_empty() { let transaction = block_data.transactions[0]; - info!("Transaction {} in block at height {} has {} receipts", transaction.id, block_data.header.height, transaction.receipts.len()); + info!( + "Transaction {} in block at height {} has {} receipts", + transaction.id, + block_data.header.height, + transaction.receipts.len() + ); } - } } + ``` \ No newline at end of file From fb151f54a50c8bd46c487fdf149322c8c0e5d990 Mon Sep 17 00:00:00 2001 From: Rashad Alston Date: Tue, 12 Sep 2023 11:04:02 -0400 Subject: [PATCH 14/33] add types section for gql --- docs/src/SUMMARY.md | 5 ++ docs/src/graphql/types/enums.md | 27 +++++++ docs/src/graphql/types/index.md | 5 ++ docs/src/graphql/types/objects.md | 28 ++++++++ docs/src/graphql/types/unions.md | 70 +++++++++++++++++++ docs/src/indexing/fuel-types/blocks.md | 4 +- docs/src/indexing/fuel-types/receipts/burn.md | 4 +- docs/src/indexing/fuel-types/receipts/call.md | 4 +- docs/src/indexing/fuel-types/receipts/log.md | 4 +- .../indexing/fuel-types/receipts/logdata.md | 4 +- .../fuel-types/receipts/messageout.md | 4 +- docs/src/indexing/fuel-types/receipts/mint.md | 4 +- .../indexing/fuel-types/transaction-status.md | 4 +- docs/src/indexing/fuel-types/transactions.md | 4 +- docs/src/project-components/module.md | 4 +- .../invalid_abi_type_simple_wasm.yaml | 8 +++ .../trybuild/invalid_schema_simple_wasm.yaml | 9 +++ 17 files changed, 172 insertions(+), 20 deletions(-) create mode 100644 docs/src/graphql/types/enums.md create mode 100644 docs/src/graphql/types/index.md create mode 100644 docs/src/graphql/types/objects.md create mode 100644 docs/src/graphql/types/unions.md create mode 100644 packages/fuel-indexer-tests/trybuild/invalid_abi_type_simple_wasm.yaml create mode 100644 packages/fuel-indexer-tests/trybuild/invalid_schema_simple_wasm.yaml diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index f1a82f84b..69b7d3f77 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -7,6 +7,7 @@ - [Dependencies](./getting-started/dependencies.md) - [Service Infrastructure](./getting-started/starting-the-fuel-indexer.md) +- [How it compares](./getting-started/starting-the-fuel-indexer.md) - [Quickstart](./getting-started/quickstart.md) # Reference Guide @@ -36,6 +37,10 @@ - [Transfer](./indexing/fuel-types/receipts/transfer.md) - [TransferOut](./indexing/fuel-types/receipts/transferout.md) - [GraphQL](./graphql/index.md) + - [Types](./graphql/types/index.md) + - [Objects](./graphql/types/objects.md) + - [Enums](./graphql/types/enums.md) + - [Union](./graphql/types/unions.md) - [Scalars](./graphql/scalars.md) - [Directives](./graphql/directives.md) - [Relationships](./graphql/relationships.md) diff --git a/docs/src/graphql/types/enums.md b/docs/src/graphql/types/enums.md new file mode 100644 index 000000000..1dd544354 --- /dev/null +++ b/docs/src/graphql/types/enums.md @@ -0,0 +1,27 @@ +# Enum Types + +Enum types are simply implemented as String types. + +```graphql +enum SignatureLabel { + Multi + Single +} +``` + +> Enum types in relation to Fuel indexer's implementation are just `String` types used primarily to label object types. There is no other way that `enum` types should be used at this time. + +This `SignatureLabel` object type from the GraphQL schema, might be used in an indexer module like so: + +```rust, ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { + fn handle_event(event: Event) { + let label = SignatureLabel::Multi; + assert_eq!(label.to_string(), "SignatureLabel::Multi".to_string()); + } +} +``` \ No newline at end of file diff --git a/docs/src/graphql/types/index.md b/docs/src/graphql/types/index.md new file mode 100644 index 000000000..b725ebef8 --- /dev/null +++ b/docs/src/graphql/types/index.md @@ -0,0 +1,5 @@ +# Types + +- [Object types](./objects.md) +- [Enum types](./enums.md) +- [Union types](./unions.md) \ No newline at end of file diff --git a/docs/src/graphql/types/objects.md b/docs/src/graphql/types/objects.md new file mode 100644 index 000000000..7aba74ec5 --- /dev/null +++ b/docs/src/graphql/types/objects.md @@ -0,0 +1,28 @@ +# Object types + +Object types are the most commonly used type in indexer GraphQL schema. Each object type marked with an `@entity` directive will be converted into a SQL table. + +```graphql +type Account @entity { + id: ID! + address: Address! + balance: UInt8! +} +``` + +This `Account` object type from the GraphQL schema, might be used in an indexer module like so: + +```rust, ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { + fn handle_event(event: Event) { + let address = Address::default(); + let balance = 0; + let account = Account::new(address, balance); + account.save(); + } +} +``` \ No newline at end of file diff --git a/docs/src/graphql/types/unions.md b/docs/src/graphql/types/unions.md new file mode 100644 index 000000000..b4b633edb --- /dev/null +++ b/docs/src/graphql/types/unions.md @@ -0,0 +1,70 @@ +# Union Types + +Union types are unique in that any type marked as a `union` will be converted into an Object type, who's fields are the unique set of fields over all members of the union. + +```graphql +enum TransactionLabel { + Create + Script + Mint +} + +type CreateTransaction @entity { + id: ID! + bytecode_length: UInt8! + contract_id: ContractId! + label: TransactionLabel! +} + +type ScriptTransaction @entity { + id: ID! + maturity: UInt8! + label: TransactionLabel! +} + +type MintTransaction @entity { + id: ID! + metadata: Json + label: TransactionLabel! +} + +union Transaction = CreateTransaction | ScriptTransaction | MintTransaction +``` + +The `Transaction` union type above, will internally produce the following object type: + +```graphql +type Transaction @entity { + id: ID! + bytecode_length: UInt8! + contract_id: ContractId! + label: TransactionLabel! + maturity: UInt8! + metadata: Json +} +``` + +> IMPORTANT: Note the order of the fields in the derived `Transaction` object type: the fields are ordered according to the unique set of fields from each of the union's members. +> +> The `id`, `bytecode_length`, `contract_id`, and `label` fields come first, from the `CreateTransaction` object type. Next comes the `maturity` field from the `ScriptTransaction` object - because the `ScriptTransaction`'s `id` and `label` fiels are already a part of the derived `Transaction` object, courtesy of the `CreateTransaction` object type. Finally, comes the `metadata` field, as part of the `MintTransaction` object type. + +This `Transaction` union type from the GraphQL schema, might be used in an indexer module like so: + +```rust, ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { + fn handle_event(event: Event) { + let bytecode_length = 1024; + let contract_id = ContractId::default(); + let label = TransactionLabel::Create; + let maturity = 10000000; + let metadata = None; + + let transaction = Transaction::new(bytecode_length, contract_id, label, maturity, metadata); + transaction.save(); + } +} +``` \ No newline at end of file diff --git a/docs/src/indexing/fuel-types/blocks.md b/docs/src/indexing/fuel-types/blocks.md index ef884a20e..8de077136 100644 --- a/docs/src/indexing/fuel-types/blocks.md +++ b/docs/src/indexing/fuel-types/blocks.md @@ -22,8 +22,8 @@ pub struct BlockData { extern crate alloc; use fuel_indexer_utils::prelude::*; -#[indexer(manifest = "my_indexer.manifest.yaml")] -mod my_indexer { +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { fn handle_block(block_data: BlockData) { let height = block_data.header.height; info!("This block #{height}"); diff --git a/docs/src/indexing/fuel-types/receipts/burn.md b/docs/src/indexing/fuel-types/receipts/burn.md index 9455c572f..268ccb674 100644 --- a/docs/src/indexing/fuel-types/receipts/burn.md +++ b/docs/src/indexing/fuel-types/receipts/burn.md @@ -23,8 +23,8 @@ You can handle functions that produce a `Burn` receipt type by adding a paramete extern crate alloc; use fuel_indexer_utils::prelude::*; -#[indexer(manifest = "my_indexer.manifest.yaml")] -mod my_indexer { +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { fn handle_burn_receipt(block_data: BlockData) { let height = block_data.header.height; if !block_data.transactions.is_empty() { diff --git a/docs/src/indexing/fuel-types/receipts/call.md b/docs/src/indexing/fuel-types/receipts/call.md index 3892d91cd..c401ee123 100644 --- a/docs/src/indexing/fuel-types/receipts/call.md +++ b/docs/src/indexing/fuel-types/receipts/call.md @@ -22,8 +22,8 @@ pub struct Call { extern crate alloc; use fuel_indexer_utils::prelude::*; -#[indexer(manifest = "my_indexer.manifest.yaml")] -mod my_indexer { +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { fn handle_call_receipt(block_data: BlockData) { let height = block_data.header.height; if !block_data.transactions.is_empty() { diff --git a/docs/src/indexing/fuel-types/receipts/log.md b/docs/src/indexing/fuel-types/receipts/log.md index 63a9563db..a58ffd71f 100644 --- a/docs/src/indexing/fuel-types/receipts/log.md +++ b/docs/src/indexing/fuel-types/receipts/log.md @@ -19,8 +19,8 @@ pub struct Log { extern crate alloc; use fuel_indexer_utils::prelude::*; -#[indexer(manifest = "my_indexer.manifest.yaml")] -mod my_indexer { +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { fn handle_log_receipt(block_data: BlockData) { let height = block_data.header.height; if !block_data.transactions.is_empty() { diff --git a/docs/src/indexing/fuel-types/receipts/logdata.md b/docs/src/indexing/fuel-types/receipts/logdata.md index 3ca421cbc..876aa069f 100644 --- a/docs/src/indexing/fuel-types/receipts/logdata.md +++ b/docs/src/indexing/fuel-types/receipts/logdata.md @@ -26,8 +26,8 @@ pub struct LogData { extern crate alloc; use fuel_indexer_utils::prelude::*; -#[indexer(manifest = "my_indexer.manifest.yaml")] -mod my_indexer { +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { fn handle_log_data(event: MyEvent) { info!("Event {event:?} was logged in the contract"); } diff --git a/docs/src/indexing/fuel-types/receipts/messageout.md b/docs/src/indexing/fuel-types/receipts/messageout.md index 19d157bb5..ebb3f7048 100644 --- a/docs/src/indexing/fuel-types/receipts/messageout.md +++ b/docs/src/indexing/fuel-types/receipts/messageout.md @@ -26,8 +26,8 @@ pub struct MessageOut { extern crate alloc; use fuel_indexer_utils::prelude::*; -#[indexer(manifest = "my_indexer.manifest.yaml")] -mod my_indexer { +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { fn handle_message_out(event: MyEvent) { info!("Event {event:?} was logged in the contract"); } diff --git a/docs/src/indexing/fuel-types/receipts/mint.md b/docs/src/indexing/fuel-types/receipts/mint.md index fd63e46c5..b9b9c2157 100644 --- a/docs/src/indexing/fuel-types/receipts/mint.md +++ b/docs/src/indexing/fuel-types/receipts/mint.md @@ -21,8 +21,8 @@ pub struct Mint { extern crate alloc; use fuel_indexer_utils::prelude::*; -#[indexer(manifest = "my_indexer.manifest.yaml")] -mod my_indexer { +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { fn handle_mint_receipt(block_data: BlockData) { let height = block_data.header.height; if !block_data.transactions.is_empty() { diff --git a/docs/src/indexing/fuel-types/transaction-status.md b/docs/src/indexing/fuel-types/transaction-status.md index a5aa02ea3..2c06352f5 100644 --- a/docs/src/indexing/fuel-types/transaction-status.md +++ b/docs/src/indexing/fuel-types/transaction-status.md @@ -31,8 +31,8 @@ pub enum TransactionStatus { extern crate alloc; use fuel_indexer_utils::prelude::*; -#[indexer(manifest = "my_indexer.manifest.yaml")] -mod my_indexer { +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { fn handle_transaction(block_data: BlockData) { let height = block_data.header.height; if !block_data.transactions.is_empty() { diff --git a/docs/src/indexing/fuel-types/transactions.md b/docs/src/indexing/fuel-types/transactions.md index e4191ab22..0fe8e97d1 100644 --- a/docs/src/indexing/fuel-types/transactions.md +++ b/docs/src/indexing/fuel-types/transactions.md @@ -19,8 +19,8 @@ pub struct TransactionData { extern crate alloc; use fuel_indexer_utils::prelude::*; -#[indexer(manifest = "my_indexer.manifest.yaml")] -mod my_indexer { +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { fn handle_transaction(block_data: BlockData) { let height = block_data.header.height; if !block_data.transactions.is_empty() { diff --git a/docs/src/project-components/module.md b/docs/src/project-components/module.md index 2a4ddd959..87041a54b 100644 --- a/docs/src/project-components/module.md +++ b/docs/src/project-components/module.md @@ -18,8 +18,8 @@ We can look at the function below as an example: extern crate alloc; use fuel_indexer_utils::prelude::*; -#[indexer(manifest = "my_indexer.manifest.yaml")] -mod my_indexer { +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { // This `log_the_greeting` function will be called, when we find // a `Greeting` in a block. diff --git a/packages/fuel-indexer-tests/trybuild/invalid_abi_type_simple_wasm.yaml b/packages/fuel-indexer-tests/trybuild/invalid_abi_type_simple_wasm.yaml new file mode 100644 index 000000000..374a79f92 --- /dev/null +++ b/packages/fuel-indexer-tests/trybuild/invalid_abi_type_simple_wasm.yaml @@ -0,0 +1,8 @@ + + namespace: test_namespace + identifier: simple_wasm_executor + abi: /Users/rashad/dev/repos/fuel-indexer/packages/fuel-indexer-tests/contracts/simple-wasm/out/debug/contracts-abi-reserved-name.json + graphql_schema: /Users/rashad/dev/repos/fuel-indexer/packages/fuel-indexer-tests/indexers/simple-wasm/schema/simple_wasm.graphql + contract_id: ~ + module: + wasm: /Users/rashad/dev/repos/fuel-indexer/target/wasm32-unknown-unknown/release/simple_wasm.wasm \ No newline at end of file diff --git a/packages/fuel-indexer-tests/trybuild/invalid_schema_simple_wasm.yaml b/packages/fuel-indexer-tests/trybuild/invalid_schema_simple_wasm.yaml new file mode 100644 index 000000000..93680770e --- /dev/null +++ b/packages/fuel-indexer-tests/trybuild/invalid_schema_simple_wasm.yaml @@ -0,0 +1,9 @@ + + namespace: test_namespace + identifier: simple_wasm_executor + abi: /Users/rashad/dev/repos/fuel-indexer/packages/fuel-indexer-tests/contracts/simple-wasm/out/debug/contracts-abi.json + # This schema file doesn't actually exist + graphql_schema: schema.graphql + contract_id: ~ + module: + wasm: /Users/rashad/dev/repos/fuel-indexer/target/wasm32-unknown-unknown/release/simple_wasm.wasm \ No newline at end of file From bcf4453cb93bb3e0bbb8159c8cf27256d6317102 Mon Sep 17 00:00:00 2001 From: Rashad Alston Date: Tue, 12 Sep 2023 11:10:18 -0400 Subject: [PATCH 15/33] breakout gql queries + remove plugins --- docs/src/SUMMARY.md | 28 +++++-------------- .../src/graphql/{ => queries}/full-example.md | 0 docs/src/graphql/queries/index.md | 7 +++++ docs/src/graphql/{ => queries}/pagination.md | 0 docs/src/graphql/{ => queries}/playground.md | 0 docs/src/graphql/{ => queries}/queries.md | 0 .../graphql/{ => queries}/search-filtering.md | 0 7 files changed, 14 insertions(+), 21 deletions(-) rename docs/src/graphql/{ => queries}/full-example.md (100%) create mode 100644 docs/src/graphql/queries/index.md rename docs/src/graphql/{ => queries}/pagination.md (100%) rename docs/src/graphql/{ => queries}/playground.md (100%) rename docs/src/graphql/{ => queries}/queries.md (100%) rename docs/src/graphql/{ => queries}/search-filtering.md (100%) diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 69b7d3f77..e10b6bdcf 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -36,6 +36,7 @@ - [ScriptResult](./indexing/fuel-types/receipts/scriptresult.md) - [Transfer](./indexing/fuel-types/receipts/transfer.md) - [TransferOut](./indexing/fuel-types/receipts/transferout.md) +- [Authentication](./authentication/index.md) - [GraphQL](./graphql/index.md) - [Types](./graphql/types/index.md) - [Objects](./graphql/types/objects.md) @@ -45,28 +46,13 @@ - [Directives](./graphql/directives.md) - [Relationships](./graphql/relationships.md) - [API Server](./graphql/api-server.md) - - [Playground](./graphql/playground.md) - - [Basic Queries](./graphql/queries.md) - - [Search and Filtering](./graphql/search-filtering.md) - - [Pagination](./graphql/pagination.md) - - [A Full Example](./graphql/full-example.md) + - [Queries](./graphql/queries/index.md) + - [Playground](./graphql/queries/playground.md) + - [Basic Queries](./graphql/queries/queries.md) + - [Search and Filtering](./graphql/queries/search-filtering.md) + - [Pagination](./graphql/queries/pagination.md) + - [A Full Example](./graphql/queries/full-example.md) - [Storing Info in a Database](./database/index.md) -- [forc index](./forc-index/index.md) - - [new](./forc-index/new.md) - - [check](./forc-index/check.md) - - [build](./forc-index/build.md) - - [start](./forc-index/start.md) - - [deploy](./forc-index/deploy.md) - - [remove](./forc-index/remove.md) - - [kill](./forc-index/kill.md) - - [auth](./forc-index/auth.md) - - [status](./forc-index/status.md) -- [forc index postgres](./forc-postgres/index.md) - - [create](./forc-postgres/create.md) - - [start](./forc-postgres/start.md) - - [stop](./forc-postgres/stop.md) - - [drop](./forc-postgres/drop.md) -- [Authentication](./authentication/index.md) # For Contributors diff --git a/docs/src/graphql/full-example.md b/docs/src/graphql/queries/full-example.md similarity index 100% rename from docs/src/graphql/full-example.md rename to docs/src/graphql/queries/full-example.md diff --git a/docs/src/graphql/queries/index.md b/docs/src/graphql/queries/index.md new file mode 100644 index 000000000..78725bf1c --- /dev/null +++ b/docs/src/graphql/queries/index.md @@ -0,0 +1,7 @@ +# Queries + +- [Basic Queries](./queries.md) +- [Pagination](./pagination.md) +- [Search & Filtering](./search-filtering.md) +- [Full Example](./full-example.md) +- [The GraphQL Playground](./playground.md) diff --git a/docs/src/graphql/pagination.md b/docs/src/graphql/queries/pagination.md similarity index 100% rename from docs/src/graphql/pagination.md rename to docs/src/graphql/queries/pagination.md diff --git a/docs/src/graphql/playground.md b/docs/src/graphql/queries/playground.md similarity index 100% rename from docs/src/graphql/playground.md rename to docs/src/graphql/queries/playground.md diff --git a/docs/src/graphql/queries.md b/docs/src/graphql/queries/queries.md similarity index 100% rename from docs/src/graphql/queries.md rename to docs/src/graphql/queries/queries.md diff --git a/docs/src/graphql/search-filtering.md b/docs/src/graphql/queries/search-filtering.md similarity index 100% rename from docs/src/graphql/search-filtering.md rename to docs/src/graphql/queries/search-filtering.md From 934441828b2adacab9aa4f67f677816311841e36 Mon Sep 17 00:00:00 2001 From: Rashad Alston Date: Tue, 12 Sep 2023 11:25:56 -0400 Subject: [PATCH 16/33] add comparison chart --- docs/src/SUMMARY.md | 2 +- docs/src/getting-started/how-it-compares.md | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 docs/src/getting-started/how-it-compares.md diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index e10b6bdcf..4e0881ac9 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -7,7 +7,7 @@ - [Dependencies](./getting-started/dependencies.md) - [Service Infrastructure](./getting-started/starting-the-fuel-indexer.md) -- [How it compares](./getting-started/starting-the-fuel-indexer.md) +- [How it compares](./getting-started/how-it-compares.md) - [Quickstart](./getting-started/quickstart.md) # Reference Guide diff --git a/docs/src/getting-started/how-it-compares.md b/docs/src/getting-started/how-it-compares.md new file mode 100644 index 000000000..fc4935396 --- /dev/null +++ b/docs/src/getting-started/how-it-compares.md @@ -0,0 +1,17 @@ +# How it compares + +Legend: +- 🟩 : Functionally complete +- 🟨 : Partially complete +- 🟥 : Planned but incomplete +- ⛔ : Not planned + + + + +| Feature | The Graph | Fuel Indexer | Notes | +|:-:|:-:|:-:|:-:| +| Decentralized Hosting | 🟩 | ⛔ | | +| Hosted Indexers | 🟩 | 🟩 | | +| WASM Execution | 🟩 | 🟩 | | +| Native Execution | 🟥 | 🟩 | | \ No newline at end of file From abb825374a43bd67e882a6aa6ce4e8fdfb2bdc9f Mon Sep 17 00:00:00 2001 From: Alexander Date: Tue, 12 Sep 2023 14:44:39 -0400 Subject: [PATCH 17/33] Condense receipts section into receipts page to mirror style of specs page --- docs/src/SUMMARY.md | 26 +- docs/src/indexing/fuel-types/receipts.md | 473 ++++++++++++++++++ docs/src/indexing/fuel-types/receipts/burn.md | 42 -- docs/src/indexing/fuel-types/receipts/call.md | 41 -- .../src/indexing/fuel-types/receipts/index.md | 1 - docs/src/indexing/fuel-types/receipts/log.md | 38 -- .../indexing/fuel-types/receipts/logdata.md | 35 -- .../fuel-types/receipts/messageout.md | 35 -- docs/src/indexing/fuel-types/receipts/mint.md | 40 -- .../src/indexing/fuel-types/receipts/panic.md | 20 - .../indexing/fuel-types/receipts/receipts.md | 19 - .../indexing/fuel-types/receipts/return.md | 24 - .../fuel-types/receipts/returndata.md | 23 - .../indexing/fuel-types/receipts/revert.md | 31 -- .../fuel-types/receipts/scriptresult.md | 20 - .../indexing/fuel-types/receipts/transfer.md | 26 - .../fuel-types/receipts/transferout.md | 25 - 17 files changed, 479 insertions(+), 440 deletions(-) create mode 100644 docs/src/indexing/fuel-types/receipts.md delete mode 100644 docs/src/indexing/fuel-types/receipts/burn.md delete mode 100644 docs/src/indexing/fuel-types/receipts/call.md delete mode 100644 docs/src/indexing/fuel-types/receipts/index.md delete mode 100644 docs/src/indexing/fuel-types/receipts/log.md delete mode 100644 docs/src/indexing/fuel-types/receipts/logdata.md delete mode 100644 docs/src/indexing/fuel-types/receipts/messageout.md delete mode 100644 docs/src/indexing/fuel-types/receipts/mint.md delete mode 100644 docs/src/indexing/fuel-types/receipts/panic.md delete mode 100644 docs/src/indexing/fuel-types/receipts/receipts.md delete mode 100644 docs/src/indexing/fuel-types/receipts/return.md delete mode 100644 docs/src/indexing/fuel-types/receipts/returndata.md delete mode 100644 docs/src/indexing/fuel-types/receipts/revert.md delete mode 100644 docs/src/indexing/fuel-types/receipts/scriptresult.md delete mode 100644 docs/src/indexing/fuel-types/receipts/transfer.md delete mode 100644 docs/src/indexing/fuel-types/receipts/transferout.md diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 4e0881ac9..8561828ad 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -16,26 +16,12 @@ - [Manifest](./project-components/manifest.md) - [Schema](./project-components/schema.md) - [Module](./project-components/module.md) -- [Indexing](./indexing/index.md) - - [Custom Types](./indexing/custom-types/index.md) - - [Fuel Types](./indexing/fuel-types/index.md) - - [Blocks](./indexing/fuel-types/blocks.md) - - [Transactions](./indexing/fuel-types/transactions.md) - - [Transaction Status](./indexing/fuel-types/transaction-status.md) - - [Receipts](./indexing/fuel-types/receipts/index.md) - - [Burn](./indexing/fuel-types/receipts/burn.md) - - [Call](./indexing/fuel-types/receipts/call.md) - - [Log](./indexing/fuel-types/receipts/log.md) - - [LogData](./indexing/fuel-types/receipts/logdata.md) - - [MessageOut](./indexing/fuel-types/receipts/messageout.md) - - [Mint](./indexing/fuel-types/receipts/mint.md) - - [Panic](./indexing/fuel-types/receipts/panic.md) - - [Return](./indexing/fuel-types/receipts/return.md) - - [ReturnData](./indexing/fuel-types/receipts/returndata.md) - - [Revert](./indexing/fuel-types/receipts/revert.md) - - [ScriptResult](./indexing/fuel-types/receipts/scriptresult.md) - - [Transfer](./indexing/fuel-types/receipts/transfer.md) - - [TransferOut](./indexing/fuel-types/receipts/transferout.md) +- [Indexing Fuel Types](./indexing/fuel-types/index.md) + - [Blocks](./indexing/fuel-types/blocks.md) + - [Transactions](./indexing/fuel-types/transactions.md) + - [Transaction Status](./indexing/fuel-types/transaction-status.md) + - [Receipts](./indexing/fuel-types/receipts/index.md) +- [Indexing Custom Types](./indexing/custom-types/index.md) - [Authentication](./authentication/index.md) - [GraphQL](./graphql/index.md) - [Types](./graphql/types/index.md) diff --git a/docs/src/indexing/fuel-types/receipts.md b/docs/src/indexing/fuel-types/receipts.md new file mode 100644 index 000000000..16d805ab8 --- /dev/null +++ b/docs/src/indexing/fuel-types/receipts.md @@ -0,0 +1,473 @@ +# Receipts + +Every transaction in the Fuel network contains a list of receipts with information about that transaction, including what contract function was called, logged data, data returned from a function, etc. + +There are several types of receipts that can be attached to a transaction and indexed. You can learn more about each of these in the sections below. + +- [**Burn**](#burn) +- [**Call**](#call) +- [**Log**](#log) +- [**LogData**](#logdata) +- [**MessageOut**](#messageout) +- [**Mint**](#mint) +- [**Panic**](#panic) +- [**Return**](#return) +- [**ReturnData**](#returndata) +- [**Revert**](#revert) +- [**ScriptResult**](#scriptresult) +- [**Transfer**](#transfer) +- [**TransferOut**](#transferout) + +## Burn + +A `Burn` receipt is generated whenever an asset is burned in a Sway contract. [Read more about `Burn` in the Fuel protocol ABI spec](https://docs.fuel.network/docs/specs/abi/receipts/#burn-receipt). + +```rust, ignore +use fuel_types::{AssetId, ContractId}; +pub struct Burn { + pub sub_id: AssetId, + pub contract_id: ContractId, + pub val: u64, + pub pc: u64, + pub is: u64, +} +``` + +```rust, ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { + fn handle_burn_receipt(block_data: BlockData) { + let height = block_data.header.height; + if !block_data.transactions.is_empty() { + let transaction = block_data.transactions[0]; + for receipt in transaction.receipts { + match receipt { + fuel::Receipt::Burn { contract_id, .. } => { + info!("Found burn receipt from contract {contract_id:?}"); + } + } + } + } + } +} +``` + +## Call + +A `Call` receipt is generated whenever a function is called in a Sway contract. The `fn_name` field contains the name of the called function from the aforementioned contract. [Read more about `Call` in the Fuel protocol ABI spec](https://docs.fuel.network/docs/specs/abi/receipts/#call-receipt). + +```rust, ignore +use fuel_types::{AssetId, ContractId}; +pub struct Call { + pub contract_id: ContractId, + pub to: ContractId, + pub amount: u64, + pub asset_id: AssetId, + pub gas: u64, + pub fn_name: String, +} +``` + +```rust, ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { + fn handle_call_receipt(block_data: BlockData) { + let height = block_data.header.height; + if !block_data.transactions.is_empty() { + let transaction = block_data.transactions[0]; + for receipt in transaction.receipts { + match receipt { + fuel::Receipt::Call { contract_id, .. } => { + info!("Found call receipt from contract {contract_id:?}"); + } + } + } + } + } +} +``` + +## Log + +A `Log` receipt is generated when calling `log()` on a non-reference types in a Sway contracts - specifically `bool`, `u8`, `u16`, `u32`, and `u64`. The `ra` field includes the value being logged while `rb` may include a non-zero value representing a unique ID for the `log` instance. [Read more about `Log` in the Fuel protocol ABI spec](https://docs.fuel.network/docs/specs/abi/receipts/#log-receipt). + +```rust, ignore +use fuel_types::ContractId; +pub struct Log { + pub contract_id: ContractId, + pub ra: u64, + pub rb: u64, +} +``` + +```rust, ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { + fn handle_log_receipt(block_data: BlockData) { + let height = block_data.header.height; + if !block_data.transactions.is_empty() { + let transaction = block_data.transactions[0]; + for receipt in transaction.receipts { + match receipt { + fuel::Receipt::Log { contract_id, .. } => { + info!("Found log receipt from contract {contract_id:?}"); + } + } + } + } + } +} +``` + +## LogData + +A `LogData` receipt is generated when calling `log()` in a Sway contract on a reference type; this includes all types _except_ non-reference types. The `data` field will include the logged value as a hexadecimal. The `rb` field will contain a unique ID that can be used to look up the logged data type. [Read more about `LogData` in the Fuel protocol ABI spec](https://docs.fuel.network/docs/specs/abi/receipts/#logdata-receipt). +> + +```rust,ignore +use fuel_types::ContractId; +pub struct LogData { + pub contract_id: ContractId, + pub data: Vec, + pub rb: u64, + pub len: u64, + pub ptr: u64, +} +``` + +> Note: the example below will run both when the type `MyEvent` is logged as well as when `MyEvent` is returned from a function. + +```rust, ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { + fn handle_log_data(event: MyEvent) { + info!("Event {event:?} was logged in the contract"); + } +} +``` + +## MessageOut + +A `MessageOut` receipt is generated as a result of the `send_typed_message()` Sway method in which a message is sent to a recipient address along with a certain amount of coins. The `data` field supports data of an arbitrary type `T` and will be decoded by the indexer upon receipt. [Read more about `MessageOut` in the Fuel protocol ABI spec](https://docs.fuel.network/docs/specs/abi/receipts/#messageout-receipt). + +```rust,ignore +use fuel_types::{MessageId, Bytes32, Address}; +pub struct MessageOut { + pub message_id: MessageId, + pub sender: Address, + pub recipient: Address, + pub amount: u64, + pub nonce: Bytes32, + pub len: u64, + pub digest: Bytes32, + pub data: Vec, +} +``` + +```rust, ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { + fn handle_message_out(event: MyEvent) { + info!("Event {event:?} was logged in the contract"); + } +} +``` + +## Mint + +A `Mint` receipt is generated whenever an asset is burned in a Sway contract. [Read more about `Mint` in the Fuel protocol ABI spec](https://docs.fuel.network/docs/specs/abi/receipts/#mint-receipt). + +```rust, ignore +use fuel_types::{AssetId, ContractId}; +pub struct Mint { + pub sub_id: AssetId, + pub contract_id: ContractId, + pub val: u64, + pub pc: u64, + pub is: u64, +} +``` + +```rust, ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { + fn handle_mint_receipt(block_data: BlockData) { + let height = block_data.header.height; + if !block_data.transactions.is_empty() { + let transaction = block_data.transactions[0]; + for receipt in transaction.receipts { + match receipt { + fuel::Receipt::Mint { contract_id, .. } => { + info!("Found mint receipt from contract {contract_id:?}"); + } + } + } + } + } +} +``` + +## Panic + +A `Panic` receipt is produced when a Sway smart contract call fails for a reason that doesn't produce a revert. The reason field records the reason for the panic, which is represented by a number between 0 and 255. You can find the mapping between the values and their meanings here in the FuelVM [source code](https://github.com/FuelLabs/fuel-vm/blob/master/fuel-asm/src/panic_reason.rs). [Read more about `Panic` in the Fuel protocol spec](https://docs.fuel.network/docs/specs/abi/receipts/#mint-receipt). + +```rust, ignore +use fuel_types::ContractId; +pub struct Panic { + pub contract_id: ContractId, + pub reason: u32, +} +``` + +```rust, ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { + fn handle_panic_receipt(block_data: BlockData) { + let height = block_data.header.height; + if !block_data.transactions.is_empty() { + let transaction = block_data.transactions[0]; + for receipt in transaction.receipts { + match receipt { + fuel::Receipt::Panic { contract_id, .. } => { + info!("Found panic receipt from contract {contract_id:?}"); + } + } + } + } + } +} +``` + +## Return + +A `Return` receipt is generated when returning a non-reference type in a Sway contract, specifically `bool`, `u8`, `u16`, `u32`, and `u64`. The `val` field includes the value being returned. +- [Read more about `Return` in the Fuel protocol spec](https://docs.fuel.network/docs/specs/abi/receipts/#return-receipt). + +```rust, ignore +use fuel_types::ContractId; +pub struct Return { + pub contract_id: ContractId, + pub val: u64, + pub pc: u64, + pub is: u64, +} +``` + + +You can handle functions that produce a `Return` receipt type by adding a parameter with the type `Return`. + +```rust, ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { + fn handle_return_receipt(block_data: BlockData) { + let height = block_data.header.height; + if !block_data.transactions.is_empty() { + let transaction = block_data.transactions[0]; + for receipt in transaction.receipts { + match receipt { + fuel::Receipt::Return { contract_id, .. } => { + info!("Found return receipt from contract {contract_id:?}"); + } + } + } + } + } +} +``` + +## ReturnData + +A `ReturnData` receipt is generated when returning a reference type in a Sway contract; this includes all types _except_ non-reference types. The `data` field will include the returned value as a hexadecimal. [Read more about `ReturnData` in the Fuel protocol ABI spec](https://docs.fuel.network/docs/specs/abi/receipts/#returndata-receipt). + +```rust, ignore +use fuel_types::ContractId; +pub struct ReturnData { + id: ContractId, + data: Vec, +} +``` + +> Note: the example below will run both when the type `MyStruct` is logged as well as when `MyStruct` is returned from a function. + +```rust, ignore +fn handle_return_data(data: MyStruct) { + // handle the emitted ReturnData receipt +} +``` + +## Revert + +A `Revert` receipt is produced when a Sway smart contract function call fails. The table below lists possible reasons for the failure and their values. The `error_val` field records these values, enabling your indexer to identify the specific cause of the reversion. [Read more about `Revert` in the Fuel protocol spec](https://docs.fuel.network/docs/specs/abi/receipts/#revert-receipt). + +```rust, ignore +use fuel_types::ContractId; +pub struct Revert { + pub contract_id: ContractId, + pub error_val: u64, + } +``` + +| Reason | Value | +|-----------------------|-------| +| FailedRequire | 0 | +| FailedTransferToAddress | 1 | +| FailedSendMessage | 2 | +| FailedAssertEq | 3 | +| FailedAssert | 4 | + + + +```rust, ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { + fn handle_revert_receipt(block_data: BlockData) { + let height = block_data.header.height; + if !block_data.transactions.is_empty() { + let transaction = block_data.transactions[0]; + for receipt in transaction.receipts { + match receipt { + fuel::Receipt::Revert { contract_id, .. } => { + info!("Found return receipt from contract {contract_id:?}"); + } + } + } + } + } +} +``` + +## ScriptResult + +A `ScriptResult` receipt is generated when a contract call resolves; that is, it's generated as a result of the `RET`, `RETD`, and `RVRT` instructions. The `result` field will contain a `0` for success, and a non-zero value otherwise. [Read more about `ScriptResult` in the Fuel protocol spec](https://docs.fuel.network/docs/specs/abi/receipts/#scriptresult-receipt). + +```rust,ignore +pub struct ScriptResult { + pub result: u64, + pub gas_used: u64, +} +``` + +```rust, ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { + fn handle_script_result_receipt(block_data: BlockData) { + let height = block_data.header.height; + if !block_data.transactions.is_empty() { + let transaction = block_data.transactions[0]; + for receipt in transaction.receipts { + match receipt { + fuel::Receipt::ScriptResult { result, .. } => { + info!("Result from script: {result:?}"); + } + } + } + } + } +} +``` + +## Transfer + +A `Transfer` receipt is generated when coins are transferred to a contract as part of a Sway contract. The `asset_id` field contains the asset ID of the transferred coins, as the FuelVM has built-in support for working with multiple assets. The `pc` and `is` fields aren't currently used for anything, but are included for completeness. [Read more about `Transfer` in the Fuel protocol spec](https://docs.fuel.network/docs/specs/abi/receipts/#transfer-receipt). + +```rust,ignore +use fuel_types::{ContractId, AssetId}; +pub struct Transfer { + pub contract_id: ContractId, + pub to: ContractId, + pub amount: u64, + pub asset_id: AssetId, + pub pc: u64, + pub is: u64, +} +``` + +```rust, ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { + fn handle_transfer_receipt(block_data: BlockData) { + let height = block_data.header.height; + if !block_data.transactions.is_empty() { + let transaction = block_data.transactions[0]; + for receipt in transaction.receipts { + match receipt { + fuel::Receipt::Transfer { contract_id, .. } => { + info!("Found transfer receipt from contract {contract_id:?}"); + } + } + } + } + } +} +``` + +## TransferOut + +A `TransferOut` receipt is generated when coins are transferred to an address rather than a contract. Every other field of the receipt works the same way as it does in the `Transfer` receipt. [Read more about `TransferOut` in the Fuel protocol spec](https://docs.fuel.network/docs/specs/abi/receipts/#transferout-receipt). + +```rust,ignore +use fuel_types::{ContractId, AssetId, Address}; +pub struct TransferOut { + pub contract_id: ContractId, + pub to: Address, + pub amount: u64, + pub asset_id: AssetId, + pub pc: u64, + pub is: u64, +} +``` + +```rust, ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { + fn handle_transfer_out_receipt(block_data: BlockData) { + let height = block_data.header.height; + if !block_data.transactions.is_empty() { + let transaction = block_data.transactions[0]; + for receipt in transaction.receipts { + match receipt { + fuel::Receipt::TransferOut { contract_id, .. } => { + info!("Found transfer_out receipt from contract {contract_id:?}"); + } + } + } + } + } +} +``` diff --git a/docs/src/indexing/fuel-types/receipts/burn.md b/docs/src/indexing/fuel-types/receipts/burn.md deleted file mode 100644 index 268ccb674..000000000 --- a/docs/src/indexing/fuel-types/receipts/burn.md +++ /dev/null @@ -1,42 +0,0 @@ -# `Burn` - -> A `Burn` receipt is generated whenever an asset is burned in a Sway contract. [Read more about `Burn` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#burn-receipt) - -## Definition - -```rust, ignore -use fuel_types::{AssetId, ContractId}; -pub struct Burn { - pub sub_id: AssetId, - pub contract_id: ContractId, - pub val: u64, - pub pc: u64, - pub is: u64, -} -``` - -## Usage - -You can handle functions that produce a `Burn` receipt type by adding a parameter with the type `Burn`. - -```rust, ignore -extern crate alloc; -use fuel_indexer_utils::prelude::*; - -#[indexer(manifest = "indexer.manifest.yaml")] -mod indexer_mod { - fn handle_burn_receipt(block_data: BlockData) { - let height = block_data.header.height; - if !block_data.transactions.is_empty() { - let transaction = block_data.transactions[0]; - for receipt in transaction.receipts { - match receipt { - fuel::Receipt::Burn { contract_id, .. } => { - info!("Found burn receipt from contract {contract_id:?}"); - } - } - } - } - } -} -``` diff --git a/docs/src/indexing/fuel-types/receipts/call.md b/docs/src/indexing/fuel-types/receipts/call.md deleted file mode 100644 index c401ee123..000000000 --- a/docs/src/indexing/fuel-types/receipts/call.md +++ /dev/null @@ -1,41 +0,0 @@ -# `Call` - -> A `Call` receipt is generated whenever a function is called in a Sway contract. The `fn_name` field contains the name of the called function from the aforementioned contract. [Read more about `Call` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#call-receipt). - -## Definition - -```rust, ignore -use fuel_types::{AssetId, ContractId}; -pub struct Call { - pub contract_id: ContractId, - pub to: ContractId, - pub amount: u64, - pub asset_id: AssetId, - pub gas: u64, - pub fn_name: String, -} -``` - -## Usage - -```rust, ignore -extern crate alloc; -use fuel_indexer_utils::prelude::*; - -#[indexer(manifest = "indexer.manifest.yaml")] -mod indexer_mod { - fn handle_call_receipt(block_data: BlockData) { - let height = block_data.header.height; - if !block_data.transactions.is_empty() { - let transaction = block_data.transactions[0]; - for receipt in transaction.receipts { - match receipt { - fuel::Receipt::Call { contract_id, .. } => { - info!("Found call receipt from contract {contract_id:?}"); - } - } - } - } - } -} -``` diff --git a/docs/src/indexing/fuel-types/receipts/index.md b/docs/src/indexing/fuel-types/receipts/index.md deleted file mode 100644 index 7df216dcf..000000000 --- a/docs/src/indexing/fuel-types/receipts/index.md +++ /dev/null @@ -1 +0,0 @@ -# Receipts \ No newline at end of file diff --git a/docs/src/indexing/fuel-types/receipts/log.md b/docs/src/indexing/fuel-types/receipts/log.md deleted file mode 100644 index a58ffd71f..000000000 --- a/docs/src/indexing/fuel-types/receipts/log.md +++ /dev/null @@ -1,38 +0,0 @@ -# `Log` - -> A `Log` receipt is generated when calling `log()` on a non-reference types in a Sway contracts - specifically `bool`, `u8`, `u16`, `u32`, and `u64`. The `ra` field includes the value being logged while `rb` may include a non-zero value representing a unique ID for the `log` instance. [Read more about `Log` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#log-receipt). - -## Definition - -```rust, ignore -use fuel_types::ContractId; -pub struct Log { - pub contract_id: ContractId, - pub ra: u64, - pub rb: u64, -} -``` - -## Usage - -```rust, ignore -extern crate alloc; -use fuel_indexer_utils::prelude::*; - -#[indexer(manifest = "indexer.manifest.yaml")] -mod indexer_mod { - fn handle_log_receipt(block_data: BlockData) { - let height = block_data.header.height; - if !block_data.transactions.is_empty() { - let transaction = block_data.transactions[0]; - for receipt in transaction.receipts { - match receipt { - fuel::Receipt::Log { contract_id, .. } => { - info!("Found log receipt from contract {contract_id:?}"); - } - } - } - } - } -} -``` diff --git a/docs/src/indexing/fuel-types/receipts/logdata.md b/docs/src/indexing/fuel-types/receipts/logdata.md deleted file mode 100644 index 876aa069f..000000000 --- a/docs/src/indexing/fuel-types/receipts/logdata.md +++ /dev/null @@ -1,35 +0,0 @@ - -# `LogData` - -> A `LogData` receipt is generated when calling `log()` in a Sway contract on a reference type; this includes all types _except_ non-reference types. -> -> The `data` field will include the logged value as a hexadecimal. The `rb` field will contain a unique ID that can be used to look up the logged data type. [Read more about `LogData` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#logdata-receipt). -> -> Note: the example below will run both when the type `MyEvent` is logged as well as when `MyEvent` is returned from a function - -## Definition - -```rust,ignore -use fuel_types::ContractId; -pub struct LogData { - pub contract_id: ContractId, - pub data: Vec, - pub rb: u64, - pub len: u64, - pub ptr: u64, -} -``` - -## Usage - -```rust, ignore -extern crate alloc; -use fuel_indexer_utils::prelude::*; - -#[indexer(manifest = "indexer.manifest.yaml")] -mod indexer_mod { - fn handle_log_data(event: MyEvent) { - info!("Event {event:?} was logged in the contract"); - } -} -``` diff --git a/docs/src/indexing/fuel-types/receipts/messageout.md b/docs/src/indexing/fuel-types/receipts/messageout.md deleted file mode 100644 index ebb3f7048..000000000 --- a/docs/src/indexing/fuel-types/receipts/messageout.md +++ /dev/null @@ -1,35 +0,0 @@ -# `MessageOut` - -> A `MessageOut` receipt is generated as a result of the `send_typed_message()` Sway method in which a message is sent to a recipient address along with a certain amount of coins. -> -> The `data` field supports data of an arbitrary type `T` and will be decoded by the indexer upon receipt. [Read more about `MessageOut` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#messageout-receipt). - -## Definition - -```rust,ignore -use fuel_types::{MessageId, Bytes32, Address}; -pub struct MessageOut { - pub message_id: MessageId, - pub sender: Address, - pub recipient: Address, - pub amount: u64, - pub nonce: Bytes32, - pub len: u64, - pub digest: Bytes32, - pub data: Vec, -} -``` - -## Usage - -```rust, ignore -extern crate alloc; -use fuel_indexer_utils::prelude::*; - -#[indexer(manifest = "indexer.manifest.yaml")] -mod indexer_mod { - fn handle_message_out(event: MyEvent) { - info!("Event {event:?} was logged in the contract"); - } -} -``` diff --git a/docs/src/indexing/fuel-types/receipts/mint.md b/docs/src/indexing/fuel-types/receipts/mint.md deleted file mode 100644 index b9b9c2157..000000000 --- a/docs/src/indexing/fuel-types/receipts/mint.md +++ /dev/null @@ -1,40 +0,0 @@ -# `Mint` - -> A `Mint` receipt is generated whenever an asset is burned in a Sway contract. [Read more about `Mint` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#mint-receipt). - -## Definition - -```rust, ignore -use fuel_types::{AssetId, ContractId}; -pub struct Mint { - pub sub_id: AssetId, - pub contract_id: ContractId, - pub val: u64, - pub pc: u64, - pub is: u64, -} -``` - -## Usage - -```rust, ignore -extern crate alloc; -use fuel_indexer_utils::prelude::*; - -#[indexer(manifest = "indexer.manifest.yaml")] -mod indexer_mod { - fn handle_mint_receipt(block_data: BlockData) { - let height = block_data.header.height; - if !block_data.transactions.is_empty() { - let transaction = block_data.transactions[0]; - for receipt in transaction.receipts { - match receipt { - fuel::Receipt::Mint { contract_id, .. } => { - info!("Found mint receipt from contract {contract_id:?}"); - } - } - } - } - } -} -``` diff --git a/docs/src/indexing/fuel-types/receipts/panic.md b/docs/src/indexing/fuel-types/receipts/panic.md deleted file mode 100644 index 0cc0e558b..000000000 --- a/docs/src/indexing/fuel-types/receipts/panic.md +++ /dev/null @@ -1,20 +0,0 @@ -# Panic - -```rust, ignore -use fuel_types::ContractId; -pub struct Panic { - pub contract_id: ContractId, - pub reason: u32, -} -``` - -- A `Panic` receipt is produced when a Sway smart contract call fails for a reason that doesn't produce a revert. -- The reason field records the reason for the panic, which is represented by a number between 0 and 255. You can find the mapping between the values and their meanings here in the FuelVM [source code](https://github.com/FuelLabs/fuel-vm/blob/master/fuel-asm/src/panic_reason.rs). -- [Read more about `Panic` in the Fuel Protocol spec](https://specs.fuel.network/master/abi/receipts.html#panic-receipt) -- You can handle functions that could produce a `Panic` receipt by adding a parameter with the type `Panic`. - -```rust, ignore -fn handle_panic(panic: Panic) { - // handle the emitted Panic receipt -} -``` diff --git a/docs/src/indexing/fuel-types/receipts/receipts.md b/docs/src/indexing/fuel-types/receipts/receipts.md deleted file mode 100644 index b72a79a09..000000000 --- a/docs/src/indexing/fuel-types/receipts/receipts.md +++ /dev/null @@ -1,19 +0,0 @@ -# Receipts - -Every transaction in the Fuel network contains a list of receipts with information about that transaction, including what contract function was called, logged data, data returned from a function, etc. - -There are several types of receipts that can be attached to a transaction and indexed. You can learn more about each of these in the sections below. - -- [**Burn**](./burn.md) -- [**Call**](./call.md) -- [**Log**](./log.md) -- [**LogData**](./logdata.md) -- [**MessageOut**](./messageout.md) -- [**Mint**](./mint.md) -- [**Panic**](./panic.md) -- [**Return**](./return.md) -- [**ReturnData**](./returndata.md) -- [**Revert**](./revert.md) -- [**ScriptResult**](./scriptresult.md) -- [**Transfer**](./transfer.md) -- [**TransferOut**](./transferout.md) diff --git a/docs/src/indexing/fuel-types/receipts/return.md b/docs/src/indexing/fuel-types/receipts/return.md deleted file mode 100644 index c3b5efd26..000000000 --- a/docs/src/indexing/fuel-types/receipts/return.md +++ /dev/null @@ -1,24 +0,0 @@ -# Return - -```rust, ignore -use fuel_types::ContractId; -pub struct Return { - pub contract_id: ContractId, - pub val: u64, - pub pc: u64, - pub is: u64, -} -``` - -- A `Return` receipt is generated when returning a non-reference type in a Sway contract. - - Specifically `bool`, `u8`, `u16`, `u32`, and `u64`. -- The `val` field includes the value being returned. -- [Read more about `Log` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#return-receipt) - -You can handle functions that produce a `Return` receipt type by adding a parameter with the type `Return`. - -```rust, ignore -fn handle_return(data: Return) { - // handle the emitted Return receipt -} -``` diff --git a/docs/src/indexing/fuel-types/receipts/returndata.md b/docs/src/indexing/fuel-types/receipts/returndata.md deleted file mode 100644 index f4eabe64a..000000000 --- a/docs/src/indexing/fuel-types/receipts/returndata.md +++ /dev/null @@ -1,23 +0,0 @@ -# ReturnData - -```rust, ignore -use fuel_types::ContractId; -pub struct ReturnData { - id: ContractId, - data: Vec, -} -``` - -- A `ReturnData` receipt is generated when returning a reference type in a Sway contract; this includes all types _except_ non-reference types. -- The `data` field will include the returned value as a hexadecimal. -- [Read more about `ReturnData` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#returndata-receipt) - -You can handle functions that produce a `ReturnData` receipt type by using the returned type as a function parameter. - -> Note: the example below will run both when the type `MyStruct` is logged as well as when `MyStruct` is returned from a function. - -```rust, ignore -fn handle_return_data(data: MyStruct) { - // handle the emitted ReturnData receipt -} -``` diff --git a/docs/src/indexing/fuel-types/receipts/revert.md b/docs/src/indexing/fuel-types/receipts/revert.md deleted file mode 100644 index a7f45869e..000000000 --- a/docs/src/indexing/fuel-types/receipts/revert.md +++ /dev/null @@ -1,31 +0,0 @@ -# Revert - -```rust, ignore -use fuel_types::ContractId; -pub struct Revert { - pub contract_id: ContractId, - pub error_val: u64, - } -``` - -- A `Revert` receipt is produced when a Sway smart contract function call fails. -- The table below lists possible reasons for the failure and their values. -- The `error_val` field records these values, enabling your indexer to identify the specific cause of the reversion. - -| Reason | Value | -|-----------------------|-------| -| FailedRequire | 0 | -| FailedTransferToAddress | 1 | -| FailedSendMessage | 2 | -| FailedAssertEq | 3 | -| FailedAssert | 4 | - -- [Read more about `Revert` in the Fuel Protocol spec](https://specs.fuel.network/master/abi/receipts.html#revert-receipt) - -You can handle functions that could produce a `Revert` receipt by adding a parameter with the type `Revert`. - -```rust, ignore -fn handle_revert(revert: Revert) { - // handle the emitted Revert receipt -} -``` diff --git a/docs/src/indexing/fuel-types/receipts/scriptresult.md b/docs/src/indexing/fuel-types/receipts/scriptresult.md deleted file mode 100644 index a99f20754..000000000 --- a/docs/src/indexing/fuel-types/receipts/scriptresult.md +++ /dev/null @@ -1,20 +0,0 @@ -# ScriptResult - -```rust,ignore -pub struct ScriptResult { - pub result: u64, - pub gas_used: u64, -} -``` - -- A `ScriptResult` receipt is generated when a contract call resolves; that is, it's generated as a result of the `RET`, `RETD`, and `RVRT` instructions. -- The `result` field will contain a `0` for success, and a non-zero value otherwise. -- [Read more about `ScriptResult` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#scriptresult-receipt) - -You can handle functions that produce a `ScriptResult` receipt type by adding a parameter with the type `ScriptResult`. - -```rust, ignore -fn handle_script_result(script_result: ScriptResult) { - // handle the emitted ScriptResult receipt -} -``` diff --git a/docs/src/indexing/fuel-types/receipts/transfer.md b/docs/src/indexing/fuel-types/receipts/transfer.md deleted file mode 100644 index 534b2085c..000000000 --- a/docs/src/indexing/fuel-types/receipts/transfer.md +++ /dev/null @@ -1,26 +0,0 @@ -# Transfer - -```rust,ignore -use fuel_types::{ContractId, AssetId}; -pub struct Transfer { - pub contract_id: ContractId, - pub to: ContractId, - pub amount: u64, - pub asset_id: AssetId, - pub pc: u64, - pub is: u64, -} -``` - -- A `Transfer` receipt is generated when coins are transferred to a contract as part of a Sway contract. -- The `asset_id` field contains the asset ID of the transferred coins, as the FuelVM has built-in support for working with multiple assets. - - The `pc` and `is` fields aren't currently used for anything, but are included for completeness. -- [Read more about `Transfer` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#transfer-receipt) - -You can handle functions that produce a `Transfer` receipt type by adding a parameter with the type `Transfer`. - -```rust, ignore -fn handle_transfer(transfer: Transfer) { - // handle the emitted Transfer receipt -} -``` diff --git a/docs/src/indexing/fuel-types/receipts/transferout.md b/docs/src/indexing/fuel-types/receipts/transferout.md deleted file mode 100644 index 70a2c58e4..000000000 --- a/docs/src/indexing/fuel-types/receipts/transferout.md +++ /dev/null @@ -1,25 +0,0 @@ -# TransferOut - -```rust,ignore -use fuel_types::{ContractId, AssetId, Address}; -pub struct TransferOut { - pub contract_id: ContractId, - pub to: Address, - pub amount: u64, - pub asset_id: AssetId, - pub pc: u64, - pub is: u64, -} -``` - -- A `TransferOut` receipt is generated when coins are transferred to an address rather than a contract. -- Every other field of the receipt works the same way as it does in the `Transfer` receipt. -- [Read more about `TransferOut` in the Fuel protocol ABI spec](https://specs.fuel.network/master/abi/receipts.html#transferout-receipt) - -You can handle functions that produce a `TransferOut` receipt type by adding a parameter with the type `TransferOut`. - -```rust, ignore -fn handle_transferout(transfer_out: TransferOut) { - // handle the emitted TransferOut receipt -} -``` From 4bfda0c76fdc39817259617d48289aff26e75d45 Mon Sep 17 00:00:00 2001 From: Alexander Date: Tue, 12 Sep 2023 15:34:48 -0400 Subject: [PATCH 18/33] Condense TransactionStatus section into Transactions page --- docs/src/SUMMARY.md | 3 +- .../indexing/fuel-types/transaction-status.md | 56 --------------- docs/src/indexing/fuel-types/transactions.md | 69 +++++++++++++++++-- 3 files changed, 65 insertions(+), 63 deletions(-) delete mode 100644 docs/src/indexing/fuel-types/transaction-status.md diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 8561828ad..45ec58219 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -19,8 +19,7 @@ - [Indexing Fuel Types](./indexing/fuel-types/index.md) - [Blocks](./indexing/fuel-types/blocks.md) - [Transactions](./indexing/fuel-types/transactions.md) - - [Transaction Status](./indexing/fuel-types/transaction-status.md) - - [Receipts](./indexing/fuel-types/receipts/index.md) + - [Receipts](./indexing/fuel-types/receipts.md) - [Indexing Custom Types](./indexing/custom-types/index.md) - [Authentication](./authentication/index.md) - [GraphQL](./graphql/index.md) diff --git a/docs/src/indexing/fuel-types/transaction-status.md b/docs/src/indexing/fuel-types/transaction-status.md deleted file mode 100644 index 2c06352f5..000000000 --- a/docs/src/indexing/fuel-types/transaction-status.md +++ /dev/null @@ -1,56 +0,0 @@ - -# `TransactionStatus` - -> `TransactionStatus` refers to the status of a `Transaction` in the Fuel network. - -## Definition - -```rust,ignore -pub enum TransactionStatus { - Failure { - block_id: String, - time: DateTime, - reason: String, - }, - SqueezedOut { - reason: String, - }, - Submitted { - submitted_at: DateTime, - }, - Success { - block_id: String, - time: DateTime, - }, -} -``` - -## Usage - -```rust,ignore -extern crate alloc; -use fuel_indexer_utils::prelude::*; - -#[indexer(manifest = "indexer.manifest.yaml")] -mod indexer_mod { - fn handle_transaction(block_data: BlockData) { - let height = block_data.header.height; - if !block_data.transactions.is_empty() { - let transaction = block_data.transactions[0]; - match transaction.transaction { - fuel::Transaction::Script(tx) => match tx.status { - fuel::TransactionStatus::Success { block_id, time } => { - info!( - "Transaction {} in block {} was successful at {}", - tx.id, block_id, time - ); - } - }, - _ => { - info!("We don't care about this transaction type"); - } - } - } - } -} -``` diff --git a/docs/src/indexing/fuel-types/transactions.md b/docs/src/indexing/fuel-types/transactions.md index 0fe8e97d1..42c7ee134 100644 --- a/docs/src/indexing/fuel-types/transactions.md +++ b/docs/src/indexing/fuel-types/transactions.md @@ -1,8 +1,10 @@ -# `TransactionData` +# Transactions -> The `TransactionData` struct contains important information about a transaction in the Fuel network. The `id` field is the transaction hash, which is a 32-byte string. The `receipts` field contains a list of `Receipts`, which are generated by a Fuel node during the execution of a Sway smart contract; you can find more information in the [Receipts](./receipts.md) section. +## `TransactionData` -## Definition +The `TransactionData` struct contains important information about a transaction in the Fuel network. The `id` field is the transaction hash, which is a 32-byte string. The `receipts` field contains a list of `Receipts`, which are generated by a Fuel node during the execution of a Sway smart contract; you can find more information in the [Receipts](./receipts.md) section. + +### Definition ```rust,ignore pub struct TransactionData { @@ -13,7 +15,7 @@ pub struct TransactionData { } ``` -## Usage +### Usage ```rust,ignore extern crate alloc; @@ -35,4 +37,61 @@ mod indexer_mod { } } -``` \ No newline at end of file +``` + + +## `TransactionStatus` + +`TransactionStatus` refers to the status of a `Transaction` in the Fuel network. + +### Definition + +```rust,ignore +pub enum TransactionStatus { + Failure { + block_id: String, + time: DateTime, + reason: String, + }, + SqueezedOut { + reason: String, + }, + Submitted { + submitted_at: DateTime, + }, + Success { + block_id: String, + time: DateTime, + }, +} +``` + +### Usage + +```rust,ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { + fn handle_transaction(block_data: BlockData) { + let height = block_data.header.height; + if !block_data.transactions.is_empty() { + let transaction = block_data.transactions[0]; + match transaction.transaction { + fuel::Transaction::Script(tx) => match tx.status { + fuel::TransactionStatus::Success { block_id, time } => { + info!( + "Transaction {} in block {} was successful at {}", + tx.id, block_id, time + ); + } + }, + _ => { + info!("We don't care about this transaction type"); + } + } + } + } +} +``` From dd084f80bd3e9a08043836566f069cea7328d29e Mon Sep 17 00:00:00 2001 From: Alexander Date: Tue, 12 Sep 2023 15:48:55 -0400 Subject: [PATCH 19/33] Finish 'Indexing Fuel Types section' adjustments --- docs/src/indexing/fuel-types/index.md | 8 +++++++- docs/src/indexing/index.md | 23 ----------------------- 2 files changed, 7 insertions(+), 24 deletions(-) delete mode 100644 docs/src/indexing/index.md diff --git a/docs/src/indexing/fuel-types/index.md b/docs/src/indexing/fuel-types/index.md index 4f327e316..c3646b0a2 100644 --- a/docs/src/indexing/fuel-types/index.md +++ b/docs/src/indexing/fuel-types/index.md @@ -1 +1,7 @@ -# Fuel Types +# Indexing Fuel Types + +This document provides information about Fuel-specific types and provides examples on how to index each type. + +- [Blocks](./blocks.md) +- [Transactions](./transactions.md) +- [Receipts](./receipts.md) diff --git a/docs/src/indexing/index.md b/docs/src/indexing/index.md deleted file mode 100644 index 2cff9707f..000000000 --- a/docs/src/indexing/index.md +++ /dev/null @@ -1,23 +0,0 @@ -# Indexing - - -> If you've previously built an indexer for the EVM, you may be used to only being able to index data that is emitted as an event. -> -> However, with Fuel you can index the entire transaction, which means you can use much more than logged data, allowing you to reduce the number of logs you need in your contract. - -## What can I index? - -You can index two types of data: Fuel types, and Custom types: - - -### Fuel types - -> Description - -- [Blocks](./fuel-types/blocks.md) -- [Transactions](./fuel-types/transactions.md) -- [Transaction Receipts](./fuel-types/receipts/index.md) - -### Custom types - -> Description From b7d90b92c97d762bdeb0c0df8fee05ec2a507a0f Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 13 Sep 2023 00:52:25 -0400 Subject: [PATCH 20/33] Flatten sections --- docs/src/SUMMARY.md | 43 ++++++------ .../api-server.md | 0 .../directives.md | 0 .../{graphql => designing-a-schema}/index.md | 0 .../relationships.md | 0 .../scalars.md | 0 docs/src/designing-a-schema/types.md | 7 ++ docs/src/graphql/types/enums.md | 27 ------- docs/src/graphql/types/index.md | 5 -- docs/src/graphql/types/objects.md | 28 -------- docs/src/graphql/types/unions.md | 70 ------------------- .../index.md | 0 .../blocks.md | 0 .../index.md | 0 .../receipts.md | 0 .../transactions.md | 0 .../queries.md => querying/basic-queries.md} | 0 .../queries => querying}/full-example.md | 0 .../{graphql/queries => querying}/index.md | 0 .../queries => querying}/pagination.md | 0 .../queries => querying}/playground.md | 0 .../search-and-filtering.md} | 0 .../{database => storing-records}/index.md | 0 23 files changed, 28 insertions(+), 152 deletions(-) rename docs/src/{graphql => designing-a-schema}/api-server.md (100%) rename docs/src/{graphql => designing-a-schema}/directives.md (100%) rename docs/src/{graphql => designing-a-schema}/index.md (100%) rename docs/src/{graphql => designing-a-schema}/relationships.md (100%) rename docs/src/{graphql => designing-a-schema}/scalars.md (100%) create mode 100644 docs/src/designing-a-schema/types.md delete mode 100644 docs/src/graphql/types/enums.md delete mode 100644 docs/src/graphql/types/index.md delete mode 100644 docs/src/graphql/types/objects.md delete mode 100644 docs/src/graphql/types/unions.md rename docs/src/{indexing/custom-types => indexing-custom-types}/index.md (100%) rename docs/src/{indexing/fuel-types => indexing-fuel-types}/blocks.md (100%) rename docs/src/{indexing/fuel-types => indexing-fuel-types}/index.md (100%) rename docs/src/{indexing/fuel-types => indexing-fuel-types}/receipts.md (100%) rename docs/src/{indexing/fuel-types => indexing-fuel-types}/transactions.md (100%) rename docs/src/{graphql/queries/queries.md => querying/basic-queries.md} (100%) rename docs/src/{graphql/queries => querying}/full-example.md (100%) rename docs/src/{graphql/queries => querying}/index.md (100%) rename docs/src/{graphql/queries => querying}/pagination.md (100%) rename docs/src/{graphql/queries => querying}/playground.md (100%) rename docs/src/{graphql/queries/search-filtering.md => querying/search-and-filtering.md} (100%) rename docs/src/{database => storing-records}/index.md (100%) diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 45ec58219..e782822b1 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -7,7 +7,7 @@ - [Dependencies](./getting-started/dependencies.md) - [Service Infrastructure](./getting-started/starting-the-fuel-indexer.md) -- [How it compares](./getting-started/how-it-compares.md) +- [How it Compares](./getting-started/how-it-compares.md) - [Quickstart](./getting-started/quickstart.md) # Reference Guide @@ -16,28 +16,27 @@ - [Manifest](./project-components/manifest.md) - [Schema](./project-components/schema.md) - [Module](./project-components/module.md) -- [Indexing Fuel Types](./indexing/fuel-types/index.md) - - [Blocks](./indexing/fuel-types/blocks.md) - - [Transactions](./indexing/fuel-types/transactions.md) - - [Receipts](./indexing/fuel-types/receipts.md) -- [Indexing Custom Types](./indexing/custom-types/index.md) +- [Designing a Schema](./designing-a-schema/index.md) + - [Types](./designing-a-schema/types.md) + - [Scalars](./designing-a-schema/scalars.md) + - [Directives](./designing-a-schema/directives.md) + - [Relationships](./designing-a-schema/relationships.md) + - [API Server](./designing-a-schema/api-server.md) +- [Indexing Fuel Types](./indexing-fuel-types/index.md) + - [Blocks](./indexing-fuel-types/blocks.md) + - [Transactions](./indexing-fuel-types/transactions.md) + - [Receipts](./indexing-fuel-types/receipts.md) +- [Indexing Custom Types](./indexing-custom-types/index.md) +- [Storing Records](./storing-records/index.md) +- [Querying](./querying/index.md) + - [Basic Queries](./querying/basic-queries.md) + - [Playground](./querying/playground.md) + - [Search and Filtering](./querying/search-and-filtering.md) + - [Pagination](./querying/pagination.md) + - [A Full Example](./querying/full-example.md) - [Authentication](./authentication/index.md) -- [GraphQL](./graphql/index.md) - - [Types](./graphql/types/index.md) - - [Objects](./graphql/types/objects.md) - - [Enums](./graphql/types/enums.md) - - [Union](./graphql/types/unions.md) - - [Scalars](./graphql/scalars.md) - - [Directives](./graphql/directives.md) - - [Relationships](./graphql/relationships.md) - - [API Server](./graphql/api-server.md) - - [Queries](./graphql/queries/index.md) - - [Playground](./graphql/queries/playground.md) - - [Basic Queries](./graphql/queries/queries.md) - - [Search and Filtering](./graphql/queries/search-filtering.md) - - [Pagination](./graphql/queries/pagination.md) - - [A Full Example](./graphql/queries/full-example.md) -- [Storing Info in a Database](./database/index.md) +- [forc index](./forc-index/index.md) +- [forc postgres](./forc-postgres/index.md) # For Contributors diff --git a/docs/src/graphql/api-server.md b/docs/src/designing-a-schema/api-server.md similarity index 100% rename from docs/src/graphql/api-server.md rename to docs/src/designing-a-schema/api-server.md diff --git a/docs/src/graphql/directives.md b/docs/src/designing-a-schema/directives.md similarity index 100% rename from docs/src/graphql/directives.md rename to docs/src/designing-a-schema/directives.md diff --git a/docs/src/graphql/index.md b/docs/src/designing-a-schema/index.md similarity index 100% rename from docs/src/graphql/index.md rename to docs/src/designing-a-schema/index.md diff --git a/docs/src/graphql/relationships.md b/docs/src/designing-a-schema/relationships.md similarity index 100% rename from docs/src/graphql/relationships.md rename to docs/src/designing-a-schema/relationships.md diff --git a/docs/src/graphql/scalars.md b/docs/src/designing-a-schema/scalars.md similarity index 100% rename from docs/src/graphql/scalars.md rename to docs/src/designing-a-schema/scalars.md diff --git a/docs/src/designing-a-schema/types.md b/docs/src/designing-a-schema/types.md new file mode 100644 index 000000000..738b789f3 --- /dev/null +++ b/docs/src/designing-a-schema/types.md @@ -0,0 +1,7 @@ +# Types + +## Objects + +## Enums + +## Unions \ No newline at end of file diff --git a/docs/src/graphql/types/enums.md b/docs/src/graphql/types/enums.md deleted file mode 100644 index 1dd544354..000000000 --- a/docs/src/graphql/types/enums.md +++ /dev/null @@ -1,27 +0,0 @@ -# Enum Types - -Enum types are simply implemented as String types. - -```graphql -enum SignatureLabel { - Multi - Single -} -``` - -> Enum types in relation to Fuel indexer's implementation are just `String` types used primarily to label object types. There is no other way that `enum` types should be used at this time. - -This `SignatureLabel` object type from the GraphQL schema, might be used in an indexer module like so: - -```rust, ignore -extern crate alloc; -use fuel_indexer_utils::prelude::*; - -#[indexer(manifest = "indexer.manifest.yaml")] -mod indexer_mod { - fn handle_event(event: Event) { - let label = SignatureLabel::Multi; - assert_eq!(label.to_string(), "SignatureLabel::Multi".to_string()); - } -} -``` \ No newline at end of file diff --git a/docs/src/graphql/types/index.md b/docs/src/graphql/types/index.md deleted file mode 100644 index b725ebef8..000000000 --- a/docs/src/graphql/types/index.md +++ /dev/null @@ -1,5 +0,0 @@ -# Types - -- [Object types](./objects.md) -- [Enum types](./enums.md) -- [Union types](./unions.md) \ No newline at end of file diff --git a/docs/src/graphql/types/objects.md b/docs/src/graphql/types/objects.md deleted file mode 100644 index 7aba74ec5..000000000 --- a/docs/src/graphql/types/objects.md +++ /dev/null @@ -1,28 +0,0 @@ -# Object types - -Object types are the most commonly used type in indexer GraphQL schema. Each object type marked with an `@entity` directive will be converted into a SQL table. - -```graphql -type Account @entity { - id: ID! - address: Address! - balance: UInt8! -} -``` - -This `Account` object type from the GraphQL schema, might be used in an indexer module like so: - -```rust, ignore -extern crate alloc; -use fuel_indexer_utils::prelude::*; - -#[indexer(manifest = "indexer.manifest.yaml")] -mod indexer_mod { - fn handle_event(event: Event) { - let address = Address::default(); - let balance = 0; - let account = Account::new(address, balance); - account.save(); - } -} -``` \ No newline at end of file diff --git a/docs/src/graphql/types/unions.md b/docs/src/graphql/types/unions.md deleted file mode 100644 index b4b633edb..000000000 --- a/docs/src/graphql/types/unions.md +++ /dev/null @@ -1,70 +0,0 @@ -# Union Types - -Union types are unique in that any type marked as a `union` will be converted into an Object type, who's fields are the unique set of fields over all members of the union. - -```graphql -enum TransactionLabel { - Create - Script - Mint -} - -type CreateTransaction @entity { - id: ID! - bytecode_length: UInt8! - contract_id: ContractId! - label: TransactionLabel! -} - -type ScriptTransaction @entity { - id: ID! - maturity: UInt8! - label: TransactionLabel! -} - -type MintTransaction @entity { - id: ID! - metadata: Json - label: TransactionLabel! -} - -union Transaction = CreateTransaction | ScriptTransaction | MintTransaction -``` - -The `Transaction` union type above, will internally produce the following object type: - -```graphql -type Transaction @entity { - id: ID! - bytecode_length: UInt8! - contract_id: ContractId! - label: TransactionLabel! - maturity: UInt8! - metadata: Json -} -``` - -> IMPORTANT: Note the order of the fields in the derived `Transaction` object type: the fields are ordered according to the unique set of fields from each of the union's members. -> -> The `id`, `bytecode_length`, `contract_id`, and `label` fields come first, from the `CreateTransaction` object type. Next comes the `maturity` field from the `ScriptTransaction` object - because the `ScriptTransaction`'s `id` and `label` fiels are already a part of the derived `Transaction` object, courtesy of the `CreateTransaction` object type. Finally, comes the `metadata` field, as part of the `MintTransaction` object type. - -This `Transaction` union type from the GraphQL schema, might be used in an indexer module like so: - -```rust, ignore -extern crate alloc; -use fuel_indexer_utils::prelude::*; - -#[indexer(manifest = "indexer.manifest.yaml")] -mod indexer_mod { - fn handle_event(event: Event) { - let bytecode_length = 1024; - let contract_id = ContractId::default(); - let label = TransactionLabel::Create; - let maturity = 10000000; - let metadata = None; - - let transaction = Transaction::new(bytecode_length, contract_id, label, maturity, metadata); - transaction.save(); - } -} -``` \ No newline at end of file diff --git a/docs/src/indexing/custom-types/index.md b/docs/src/indexing-custom-types/index.md similarity index 100% rename from docs/src/indexing/custom-types/index.md rename to docs/src/indexing-custom-types/index.md diff --git a/docs/src/indexing/fuel-types/blocks.md b/docs/src/indexing-fuel-types/blocks.md similarity index 100% rename from docs/src/indexing/fuel-types/blocks.md rename to docs/src/indexing-fuel-types/blocks.md diff --git a/docs/src/indexing/fuel-types/index.md b/docs/src/indexing-fuel-types/index.md similarity index 100% rename from docs/src/indexing/fuel-types/index.md rename to docs/src/indexing-fuel-types/index.md diff --git a/docs/src/indexing/fuel-types/receipts.md b/docs/src/indexing-fuel-types/receipts.md similarity index 100% rename from docs/src/indexing/fuel-types/receipts.md rename to docs/src/indexing-fuel-types/receipts.md diff --git a/docs/src/indexing/fuel-types/transactions.md b/docs/src/indexing-fuel-types/transactions.md similarity index 100% rename from docs/src/indexing/fuel-types/transactions.md rename to docs/src/indexing-fuel-types/transactions.md diff --git a/docs/src/graphql/queries/queries.md b/docs/src/querying/basic-queries.md similarity index 100% rename from docs/src/graphql/queries/queries.md rename to docs/src/querying/basic-queries.md diff --git a/docs/src/graphql/queries/full-example.md b/docs/src/querying/full-example.md similarity index 100% rename from docs/src/graphql/queries/full-example.md rename to docs/src/querying/full-example.md diff --git a/docs/src/graphql/queries/index.md b/docs/src/querying/index.md similarity index 100% rename from docs/src/graphql/queries/index.md rename to docs/src/querying/index.md diff --git a/docs/src/graphql/queries/pagination.md b/docs/src/querying/pagination.md similarity index 100% rename from docs/src/graphql/queries/pagination.md rename to docs/src/querying/pagination.md diff --git a/docs/src/graphql/queries/playground.md b/docs/src/querying/playground.md similarity index 100% rename from docs/src/graphql/queries/playground.md rename to docs/src/querying/playground.md diff --git a/docs/src/graphql/queries/search-filtering.md b/docs/src/querying/search-and-filtering.md similarity index 100% rename from docs/src/graphql/queries/search-filtering.md rename to docs/src/querying/search-and-filtering.md diff --git a/docs/src/database/index.md b/docs/src/storing-records/index.md similarity index 100% rename from docs/src/database/index.md rename to docs/src/storing-records/index.md From 62ae61407a5e26a32ca60eeb21232de4fd2c0cb2 Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 13 Sep 2023 12:33:21 -0400 Subject: [PATCH 21/33] Improve Module section --- docs/src/project-components/module.md | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/docs/src/project-components/module.md b/docs/src/project-components/module.md index 87041a54b..6c224c084 100644 --- a/docs/src/project-components/module.md +++ b/docs/src/project-components/module.md @@ -1,21 +1,14 @@ # Indexer modules -> While the Fuel indexer does support native indexer modules, this section will mostly focus on Web Assembly (WASM) modules. +Indexer modules are compiled binaries that process data from the Fuel blockchain into entity types defined in your schema so that the data can be stored in a database. The Fuel indexer supports both WebAssembly (WASM) and native binaries; however, we **strongly** recommend using WASM binaries. -WebAssembly (WASM) modules are compiled binaries that are registered or deployed to a Fuel indexer at runtime. The WASM bytes are read in by the indexer and _executors_ are created which will essentially pass blocks of on-chain data from the FuelVM to your indexers indefinitely. +This document describes the process of creating an indexer module. -The WASM module is generated based on your manifest, schema, and your `lib.rs` file. +## Creating Handlers -## `lib.rs` - -You can implement the logic for handling events and saving data to the database in your `lib.rs` file in the `src` folder. - -Here, you can define which functions handle different events based on the function parameters. If you add a function parameter of a certain type, the function will handle all blocks, transactions, or transaction receipts that contain a matching type. - -We can look at the function below as an example: +Prior to creating a module for an indexer, both the manifest and schema should be created. At compile time, information will be extracted from both of those assets and combined it with your defined logic to create handlers that save data to storage. Let's look at the following example of a module that will be compiled to WASM: ```rust, ignore -extern crate alloc; use fuel_indexer_utils::prelude::*; #[indexer(manifest = "indexer.manifest.yaml")] @@ -23,13 +16,19 @@ mod indexer_mod { // This `log_the_greeting` function will be called, when we find // a `Greeting` in a block. - fn log_the_greeting(greeter: Greeting) { - info!("The greeter is: {greeter:?}"); + fn log_the_greeting(greeting: Greeting) { + info!("The greeting is: {greeting:?}"); } } ``` -> You can learn more about what data can be indexed in the [Indexing](../indexing/index.md) section. +The first line imports the [prelude](https://docs.rs/fuel-indexer-utils/latest/fuel_indexer_utils/prelude/index.html) from `fuel_indexer_utils`; this allows you to quickly bootstrap an indexer by using common types and traits. Then, we have a module decorated with the `#[indexer]` macro. This macro processes a manifest at the supplied file path, parses your schema and Sway contract ABI (if supplied), and generates code that is combined with handler functions in order to create a complete indexer module. + + +Finally, we have an example handler function. You can define which functions handle different events by using the function parameters. If you add a function parameter of a certain type `T`, the function will be triggered whenever that type is found as part of a block, transaction, or receipt. In this example, let's say that you have a Sway contract with a function that logs a `Greeting` struct. When that function executes as part of a transaction, the logged struct will be included in the data that is processed from the Fuel blockchain. Your indexer module will see the struct and execute `log_the_greeting`. + + +> You can learn more about what data can be indexed and find example handlers in the [Indexing Fuel Types](../indexing-fuel-types/index.md) and [Indexing Custom Types](../indexing-custom-types/index.md) sections. --- From 3dc9ff229968a1fd38bd358236433116d1feea2f Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 15 Sep 2023 15:51:18 -0400 Subject: [PATCH 22/33] Add GQL stuff that I accidentally removed ._. --- docs/src/designing-a-schema/types.md | 118 ++++++++++++++++++++++++++- 1 file changed, 117 insertions(+), 1 deletion(-) diff --git a/docs/src/designing-a-schema/types.md b/docs/src/designing-a-schema/types.md index 738b789f3..df3c51466 100644 --- a/docs/src/designing-a-schema/types.md +++ b/docs/src/designing-a-schema/types.md @@ -2,6 +2,122 @@ ## Objects +Object types are the most commonly used type in indexer GraphQL schema. Each object type marked with an `@entity` directive will be converted into a SQL table. + +```graphql +type Account @entity { + id: ID! + address: Address! + balance: UInt8! +} +``` + +This `Account` object type from the GraphQL schema, might be used in an indexer module like so: + +```rust, ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { + fn handle_event(event: Event) { + let address = Address::default(); + let balance = 0; + let account = Account::new(address, balance); + account.save(); + } +} +``` + ## Enums -## Unions \ No newline at end of file +Enum types are simply implemented as String types. + +```graphql +enum SignatureLabel { + Multi + Single +} +``` + +> Enum types in relation to Fuel indexer's implementation are just `String` types used primarily to label object types. There is no other way that `enum` types should be used at this time. +This `SignatureLabel` object type from the GraphQL schema, might be used in an indexer module like so: + +```rust, ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { + fn handle_event(event: Event) { + let label = SignatureLabel::Multi; + assert_eq!(label.to_string(), "SignatureLabel::Multi".to_string()); + } +} +``` + +## Unions + +Union types are unique in that any type marked as a `union` will be converted into an Object type, who's fields are the unique set of fields over all members of the union. + +```graphql +enum TransactionLabel { + Create + Script + Mint +} + +type CreateTransaction @entity { + id: ID! + bytecode_length: UInt8! + contract_id: ContractId! + label: TransactionLabel! +} + +type ScriptTransaction @entity { + id: ID! + maturity: UInt8! + label: TransactionLabel! +} + +type MintTransaction @entity { + id: ID! + metadata: Json + label: TransactionLabel! +} + +union Transaction = CreateTransaction | ScriptTransaction | MintTransaction +``` + +The `Transaction` union type above, will internally produce the following object type: + +```graphql +type Transaction @entity { + id: ID! + bytecode_length: UInt8! + contract_id: ContractId! + label: TransactionLabel! + maturity: UInt8! + metadata: Json +} +``` + +> IMPORTANT: Note the order of the fields in the derived `Transaction` object type: the fields are ordered according to the unique set of fields from each of the union's members. +> +> The `id`, `bytecode_length`, `contract_id`, and `label` fields come first, from the `CreateTransaction` object type. Next comes the `maturity` field from the `ScriptTransaction` object - because the `ScriptTransaction`'s `id` and `label` fiels are already a part of the derived `Transaction` object, courtesy of the `CreateTransaction` object type. Finally, comes the `metadata` field, as part of the `MintTransaction` object type. +This `Transaction` union type from the GraphQL schema, might be used in an indexer module like so: + +```rust, ignore +extern crate alloc; +use fuel_indexer_utils::prelude::*; +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { + fn handle_event(event: Event) { + let bytecode_length = 1024; + let contract_id = ContractId::default(); + let label = TransactionLabel::Create; + let maturity = 10000000; + let metadata = None; + let transaction = Transaction::new(bytecode_length, contract_id, label, maturity, metadata); + transaction.save(); + } +} +``` From 6ed30ca9116ed69a3ec9ddc5608a8a2a353f8d88 Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 15 Sep 2023 16:40:26 -0400 Subject: [PATCH 23/33] Rename infrastructure page --- ...ting-the-fuel-indexer.md => indexer-service-infrastructure.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/src/getting-started/{starting-the-fuel-indexer.md => indexer-service-infrastructure.md} (100%) diff --git a/docs/src/getting-started/starting-the-fuel-indexer.md b/docs/src/getting-started/indexer-service-infrastructure.md similarity index 100% rename from docs/src/getting-started/starting-the-fuel-indexer.md rename to docs/src/getting-started/indexer-service-infrastructure.md From 8d0a91e62879b28f89869d61a5ad6634e9ec7402 Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 15 Sep 2023 16:40:59 -0400 Subject: [PATCH 24/33] Adjust sections on GraphQL index page --- docs/src/designing-a-schema/index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/src/designing-a-schema/index.md b/docs/src/designing-a-schema/index.md index 2a3a3e3b9..606e481ed 100644 --- a/docs/src/designing-a-schema/index.md +++ b/docs/src/designing-a-schema/index.md @@ -1,11 +1,11 @@ -# GraphQL +# Designing a Schema The Fuel indexer uses GraphQL to in order to allow users to query for indexed data. Please note that the Fuel indexer does not support the full GraphQL specification; however, we do our best to reasonably support as much as we can. In this chapter, you can find information on how to leverage our supported features to efficiently get the data you want. +- [Types](./types.md) +- [Scalars](./scalars.md) - [Directives](./directives.md) -- [GraphQL API Server](./api-server.md) -- [Playground](./playground.md) -- [Queries](./queries.md) +- [Relationships](./relationships.md) ## Supported Functionality From e608bb03f764aa8251f2c0c8d6541c327c35c9ca Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 15 Sep 2023 16:59:18 -0400 Subject: [PATCH 25/33] Move api-server.md contents into infrastructure page --- docs/src/designing-a-schema/api-server.md | 108 ---------------- .../indexer-service-infrastructure.md | 121 ++++++++++++++++-- 2 files changed, 112 insertions(+), 117 deletions(-) delete mode 100644 docs/src/designing-a-schema/api-server.md diff --git a/docs/src/designing-a-schema/api-server.md b/docs/src/designing-a-schema/api-server.md deleted file mode 100644 index 5fe77b42d..000000000 --- a/docs/src/designing-a-schema/api-server.md +++ /dev/null @@ -1,108 +0,0 @@ -# GraphQL API Server - -- The `fuel-indexer-api-server` crate of the Fuel indexer contains a standalone GraphQL API server that acts as a queryable endpoint on top of the database. -- Note that the main `fuel-indexer` binary of the indexer project also contains a queryable GraphQL API endpoint. - -> The `fuel-indexer-api-server` crate offers a _standalone_ GraphQL API endpoint, whereas the GraphQL endpoint offered in `fuel-indexer` is bundled with other Fuel indexer functionality (e.g., execution, handling, data-layer contruction, etc). - -## Usage - -To run the standalone Fuel indexer GraphQL API server using a configuration file: - -```bash -fuel-indexer-api-server run --config config.yaml -``` - -In the above example, `config.yaml` is based on [the default service configuration file](https://github.com/FuelLabs/fuel-indexer/blob/develop/config.yaml). - -## Options - -```text -Fuel indexer web API - -USAGE: - fuel-indexer-api-server run [OPTIONS] - -OPTIONS: - --accept-sql-queries - Allow the web API to accept raw SQL queries. - - --auth-enabled - Require users to authenticate for some operations. - - --auth-strategy - Authentication scheme used. [possible values: jwt] - - -c, --config - API server config file. - - --database - Database type. [default: postgres] [possible values: postgres] - - --fuel-node-host - Host of the running Fuel node. [default: localhost] - - --fuel-node-port - Listening port of the running Fuel node. [default: 4000] - - -h, --help - Print help information - - --jwt-expiry - Amount of time (seconds) before expiring token (if JWT scheme is specified). - - --jwt-issuer - Issuer of JWT claims (if JWT scheme is specified). - - --jwt-secret - Secret used for JWT scheme (if JWT scheme is specified). - - --log-level - Log level passed to the Fuel Indexer service. [default: info] [possible values: info, - debug, error, warn] - - --max-body-size - Max body size for web requests. [default: 5242880] - - --metrics - Use Prometheus metrics reporting. - - --postgres-database - Postgres database. - - --postgres-host - Postgres host. - - --postgres-password - Postgres password. - - --postgres-port - Postgres port. - - --postgres-user - Postgres username. - - --rate-limit - Enable rate limiting. - - --rate-limit-request-count - Maximum number of requests to allow over --rate-limit-window.. - - --rate-limit-window-size - Number of seconds over which to allow --rate-limit-rps. - - --run-migrations - Run database migrations before starting service. - - -v, --verbose - Enable verbose logging. - - -V, --version - Print version information - - --web-api-host - Web API host. [default: localhost] - - --web-api-port - Web API port. [default: 29987] -``` diff --git a/docs/src/getting-started/indexer-service-infrastructure.md b/docs/src/getting-started/indexer-service-infrastructure.md index 19db02c0b..d14bd4604 100644 --- a/docs/src/getting-started/indexer-service-infrastructure.md +++ b/docs/src/getting-started/indexer-service-infrastructure.md @@ -2,17 +2,11 @@ A Fuel indexer service instance requires just three components: -- a **Fuel node** +- a **Fuel node**: Custom indexers monitor incoming blocks from a Fuel node and extract information about the state of the Fuel blockchain. -> Custom indexers monitor incoming blocks from a Fuel node and extract information about the state of the Fuel blockchain. +- a **PostgresQL database server**: Extracted information is saved into a database. -- a **PostgresQL database server** - -> Extracted information is saved into a database. - -- a **web server** - -> dApps can query indexers for up-to-date information and operators can deploy/remove indexers as needed. +- a **web server**: dApps can query indexers for up-to-date information and operators can deploy/remove indexers as needed. --- @@ -152,3 +146,112 @@ OPTIONS: ```yaml {{#include ../../../config.yaml}} ``` + + +## Web API Server + +The `fuel-indexer-api-server` crate of the Fuel indexer contains a standalone web API server that acts as a queryable endpoint on top of the database. Note that the main `fuel-indexer` binary of the indexer project also contains the same web API endpoint. + +> The `fuel-indexer-api-server` crate offers a _standalone_ web API endpoint, whereas the API endpoint offered in `fuel-indexer` is bundled with other Fuel indexer functionality (e.g., execution, handling, data-layer construction, etc). Offering the API server as a separate piece allows users to separate components and run them on different systems, if desired. + +### Usage + +To run the standalone Fuel indexer web API server using a configuration file: + +```bash +fuel-indexer-api-server run --config config.yaml +``` + +In the above example, `config.yaml` is based on [the default service configuration file](https://github.com/FuelLabs/fuel-indexer/blob/develop/config.yaml). + +### Options + +```text +Fuel indexer web API + +USAGE: + fuel-indexer-api-server run [OPTIONS] + +OPTIONS: + --accept-sql-queries + Allow the web API to accept raw SQL queries. + + --auth-enabled + Require users to authenticate for some operations. + + --auth-strategy + Authentication scheme used. [possible values: jwt] + + -c, --config + API server config file. + + --database + Database type. [default: postgres] [possible values: postgres] + + --fuel-node-host + Host of the running Fuel node. [default: localhost] + + --fuel-node-port + Listening port of the running Fuel node. [default: 4000] + + -h, --help + Print help information + + --jwt-expiry + Amount of time (seconds) before expiring token (if JWT scheme is specified). + + --jwt-issuer + Issuer of JWT claims (if JWT scheme is specified). + + --jwt-secret + Secret used for JWT scheme (if JWT scheme is specified). + + --log-level + Log level passed to the Fuel Indexer service. [default: info] [possible values: info, + debug, error, warn] + + --max-body-size + Max body size for web requests. [default: 5242880] + + --metrics + Use Prometheus metrics reporting. + + --postgres-database + Postgres database. + + --postgres-host + Postgres host. + + --postgres-password + Postgres password. + + --postgres-port + Postgres port. + + --postgres-user + Postgres username. + + --rate-limit + Enable rate limiting. + + --rate-limit-request-count + Maximum number of requests to allow over --rate-limit-window.. + + --rate-limit-window-size + Number of seconds over which to allow --rate-limit-rps. + + --run-migrations + Run database migrations before starting service. + + -v, --verbose + Enable verbose logging. + + -V, --version + Print version information + + --web-api-host + Web API host. [default: localhost] + + --web-api-port + Web API port. [default: 29987] +``` From 73af6acbcf157f34b73504b476e7296644c5d992 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 17 Sep 2023 14:13:28 -0400 Subject: [PATCH 26/33] Add content explaining how to index custom types --- docs/src/indexing-custom-types/index.md | 226 +++++++++++++++++++++++- 1 file changed, 225 insertions(+), 1 deletion(-) diff --git a/docs/src/indexing-custom-types/index.md b/docs/src/indexing-custom-types/index.md index 35d5c39b3..7deeea0e5 100644 --- a/docs/src/indexing-custom-types/index.md +++ b/docs/src/indexing-custom-types/index.md @@ -1 +1,225 @@ -# Custom Types \ No newline at end of file +# Custom Types + +In addition to Fuel-specific types, you can also index custom Sway types as well. To index custom types from a Sway smart contract, you'll need that contract's ABI in JSON format; the JSON ABI is generated as a result of running `forc build` to build your contract. After that, the process is similar to [indexing Fuel types](./indexing-fuel-types.md). + +Let's go over an example. + +## Contract + +First, let's create a Sway contract with some simple types. + +```sway +contract; + +use std::logging::log; + +struct Addition { + added_value: u64, + updated_total: u64, +} + +struct Subtraction { + subtracted_value: u64, + updated_total: u64, +} + +abi ValueStore { + #[storage(read, write)] + fn add(value: u64); + + #[storage(read, write)] + fn subtract(value: u64) -> Subtraction; +} + +storage { + total: u64 = 1000, +} + +impl ValueStore for Contract { + #[storage(read, write)] + fn add(value: u64) { + let updated_total = storage.total.read() + value; + storage.total.write(updated_total); + log( + Addition { + added_value: value, + updated_total + } + ) + } + + #[storage(read, write)] + fn subtract(value: u64) -> Subtraction { + let updated_total = storage.total.read() - value; + storage.total.write(updated_total); + + Subtraction { + subtracted_value: value, + updated_total + } + } +} +``` + +In this contract, we have two types: `Addition` and `Subtraction`. As we'll soon see, indexers can process custom types that are logged or returned as part of a function. To begin creating an indexer for this contract, let's build the contract and generate a JSON ABI file. Running `forc build` generates a JSON ABI similar to the lightly-edited one below: + +```json +{ + "types": [ + { + "typeId": 0, + "type": "()", + "components": [], + "typeParameters": null + }, + { + "typeId": 1, + "type": "struct Addition", + "components": [ + { + "name": "added_value", + "type": 3, + "typeArguments": null + }, + { + "name": "updated_total", + "type": 3, + "typeArguments": null + } + ], + "typeParameters": null + }, + { + "typeId": 2, + "type": "struct Subtraction", + "components": [ + { + "name": "subtracted_value", + "type": 3, + "typeArguments": null + }, + { + "name": "updated_total", + "type": 3, + "typeArguments": null + } + ], + "typeParameters": null + }, + { + "typeId": 3, + "type": "u64", + "components": null, + "typeParameters": null + } + ], + "functions": [...], + "loggedTypes": [ + { + "logId": 0, + "loggedType": { + "name": "", + "type": 1, + "typeArguments": [] + } + } + ], + "messagesTypes": [...], + "configurables": [...] +} + +``` + +## Schema + +To index the contracts and store information about our Sway types in the database, we should create a schema. Let's design a schema that has an entity for each Sway type: + +```graphql +type AddEntity @entity { + id: ID! + value: UInt8! + updated_total: UInt8! +} + +type SubtractEntity @entity { + id: ID! + value: UInt8! + updated_total: UInt8! +} +``` + +## Manifest + +Before writing the handler code for the types, we need to make sure that our indexer manifest contains the necessary information to allow for the compiler to parse our contract types. Specifically, we should ensure that the `contract_abi` and `graphql_schema` fields point to the correct locations, respectively. + +```yaml +# A namespace is a logical grouping of declared names. Think of the namespace +# as an organization identifier +namespace: fuellabs + +# The identifier field is used to identify the given index. +identifier: custom_types_example + +# The abi option is used to provide a link to the Sway JSON ABI that is generated when you +# build your project. +abi: path/to/custom/type/example/contract-abi.json + +# The particular start block after which you'd like your indexer to start indexing events. +start_block: ~ + +# The particular end block after which you'd like your indexer to stop indexing events. +end_block: ~ + +# The `fuel_client` denotes the address (host, port combination) of the running Fuel client +# that you would like your indexer to index events from. In order to use this per-indexer +# `fuel_client` option, the indexer service at which your indexer is deployed will have to run +# with the `--indexer_net_config` option. +fuel_client: ~ + +# The contract_id specifies which particular contract you would like your index to subscribe to. +contract_id: ~ + +# The graphql_schema field contains the file path that points to the GraphQL schema for the +# given index. +graphql_schema: path/to/custom/type/example/indexer.schema.graphql + +# The module field contains a file path that points to code that will be run as an executor inside +# of the indexer. +# Important: At this time, wasm is the preferred method of execution. +module: + wasm: ~ + +# The resumable field contains a boolean that specifies whether or not the indexer should, synchronise +# with the latest block if it has fallen out of sync. +resumable: true +``` + +## Handler Logic + +Finally, we can create handlers to index these particular types and store them in the database. Let's look at the following example: +```rust, ignore +use fuel_indexer_utils::prelude::*; + +#[indexer(manifest = "indexer.manifest.yaml")] +mod indexer_mod { + fn index_addition(addition_event: Addition) { + let addition = AddEntity { + id: 123, + value: addition_event.added_value, + updated_total: addition_event.updated_total + }; + addition.save(); + } + + fn index_subtraction(subtraction_event: Subtraction) { + let subtraction = SubtractEntity { + id: 123, + value: subtraction_event.subtracted_value, + updated_total: subtraction_event.updated_total + }; + subtraction.save(); + } +} +``` + +Regardless of whether a custom type was logged (e.g. `Addition`) or returned (e.g. `Subtraction`), the type will be available for you to use in your functions. Just include the type(s) you want your function to use in the parameters, and the function will be executed whenever each of the parameters have been satisfied by an instance of the type(s). From dc1eeace5d370aa7b0a848b5815fb64981f245a4 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 17 Sep 2023 14:37:11 -0400 Subject: [PATCH 27/33] Fix doc tests failures --- docs/src/SUMMARY.md | 16 +++++++++++++-- docs/src/designing-a-schema/index.md | 6 +++--- docs/src/designing-a-schema/types.md | 4 ++-- docs/src/forc-index/index.md | 20 +++++++++++-------- docs/src/getting-started/how-it-compares.md | 4 ++-- .../indexer-service-infrastructure.md | 3 +-- docs/src/getting-started/quickstart.md | 2 +- docs/src/indexing-custom-types/index.md | 5 +++-- docs/src/indexing-fuel-types/blocks.md | 2 +- docs/src/indexing-fuel-types/receipts.md | 6 +----- docs/src/indexing-fuel-types/transactions.md | 2 +- docs/src/project-components/module.md | 6 ++---- docs/src/project-components/schema.md | 7 +++---- docs/src/querying/basic-queries.md | 6 +++--- docs/src/querying/index.md | 4 ++-- docs/src/querying/playground.md | 4 +--- 16 files changed, 52 insertions(+), 45 deletions(-) diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index e782822b1..970c27264 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -6,7 +6,7 @@ # Getting Started - [Dependencies](./getting-started/dependencies.md) -- [Service Infrastructure](./getting-started/starting-the-fuel-indexer.md) +- [Service Infrastructure](./getting-started/indexer-service-infrastructure.md) - [How it Compares](./getting-started/how-it-compares.md) - [Quickstart](./getting-started/quickstart.md) @@ -21,7 +21,6 @@ - [Scalars](./designing-a-schema/scalars.md) - [Directives](./designing-a-schema/directives.md) - [Relationships](./designing-a-schema/relationships.md) - - [API Server](./designing-a-schema/api-server.md) - [Indexing Fuel Types](./indexing-fuel-types/index.md) - [Blocks](./indexing-fuel-types/blocks.md) - [Transactions](./indexing-fuel-types/transactions.md) @@ -36,7 +35,20 @@ - [A Full Example](./querying/full-example.md) - [Authentication](./authentication/index.md) - [forc index](./forc-index/index.md) + - [auth](./forc-index/auth.md) + - [build](./forc-index/build.md) + - [check](./forc-index/check.md) + - [deploy](./forc-index/deploy.md) + - [kill](./forc-index/kill.md) + - [new](./forc-index/new.md) + - [remove](./forc-index/remove.md) + - [start](./forc-index/start.md) + - [status](./forc-index/status.md) - [forc postgres](./forc-postgres/index.md) + - [create](./forc-postgres/create.md) + - [drop](./forc-postgres/drop.md) + - [start](./forc-postgres/start.md) + - [stop](./forc-postgres/stop.md) # For Contributors diff --git a/docs/src/designing-a-schema/index.md b/docs/src/designing-a-schema/index.md index 606e481ed..9aee8d414 100644 --- a/docs/src/designing-a-schema/index.md +++ b/docs/src/designing-a-schema/index.md @@ -19,12 +19,12 @@ While we do our best to maintain compliance with the GraphQL specification and p | Functionality | Status | Notes | |------|----------|-------| -| Arguments | ✅ | [read the Search and Filtering section](./search-filtering.md) | +| Arguments | ✅ | [read the Search and Filtering section](../querying/search-and-filtering.md) | | Aliases | ✅ | | | Fragments | ✅ | inline fragments are currently not supported | | Introspection | ✅ | | -| GraphQL Playground | ✅ | [read the Playground section](./playground.md) | -| Pagination | ✅ | [read the Pagination section](./pagination.md) | +| GraphQL Playground | ✅ | [read the Playground section](../querying/playground.md) | +| Pagination | ✅ | [read the Pagination section](../querying/pagination.md) | | Directives | 🚧 | [read the Directives section](./directives.md) | | List Types | 🚧 | | | Union Types | 🚧 | | diff --git a/docs/src/designing-a-schema/types.md b/docs/src/designing-a-schema/types.md index df3c51466..98326a7a9 100644 --- a/docs/src/designing-a-schema/types.md +++ b/docs/src/designing-a-schema/types.md @@ -2,7 +2,7 @@ ## Objects -Object types are the most commonly used type in indexer GraphQL schema. Each object type marked with an `@entity` directive will be converted into a SQL table. +Object types are the most commonly used type in indexer GraphQL schema. Each object type marked with an `@entity` directive will be converted into a SQL table. ```graphql type Account @entity { @@ -56,7 +56,7 @@ mod indexer_mod { ## Unions -Union types are unique in that any type marked as a `union` will be converted into an Object type, who's fields are the unique set of fields over all members of the union. +Union types are unique in that any type marked as a `union` will be converted into an Object type, who's fields are the unique set of fields over all members of the union. ```graphql enum TransactionLabel { diff --git a/docs/src/forc-index/index.md b/docs/src/forc-index/index.md index c582b7aa9..45bc1cf14 100644 --- a/docs/src/forc-index/index.md +++ b/docs/src/forc-index/index.md @@ -15,12 +15,16 @@ OPTIONS: -V, --version Print version information SUBCOMMANDS: - build Build an indexer - check Get status checks on all indexer components - deploy Deploy an indexer asset bundle to a remote or locally running indexer server - help Print this message or the help of the given subcommand(s) - init Create a new indexer project in the current directory - new Create a new indexer project in a new directory - remove Stop and remove a running indexer - start Start a local indexer service + auth Authenticate against an indexer service + build Build an indexer + check Check for Fuel indexer components + deploy Deploy an indexer to an indexer service + help Print this message or the help of the given subcommand(s) + kill Kill the indexer process. Note that this command will kill any process listening + on the default indexer port or the port specified by the `--port` flag + new Create a new indexer project in a new directory + postgres Fuel Postgres Orchestrator + remove Stop and remove a running indexer + start Standalone binary for the Fuel indexer service + status Check the status of a registered indexer ``` diff --git a/docs/src/getting-started/how-it-compares.md b/docs/src/getting-started/how-it-compares.md index fc4935396..431be13c8 100644 --- a/docs/src/getting-started/how-it-compares.md +++ b/docs/src/getting-started/how-it-compares.md @@ -1,6 +1,7 @@ # How it compares Legend: + - 🟩 : Functionally complete - 🟨 : Partially complete - 🟥 : Planned but incomplete @@ -8,10 +9,9 @@ Legend: - | Feature | The Graph | Fuel Indexer | Notes | |:-:|:-:|:-:|:-:| | Decentralized Hosting | 🟩 | ⛔ | | | Hosted Indexers | 🟩 | 🟩 | | | WASM Execution | 🟩 | 🟩 | | -| Native Execution | 🟥 | 🟩 | | \ No newline at end of file +| Native Execution | 🟥 | 🟩 | | diff --git a/docs/src/getting-started/indexer-service-infrastructure.md b/docs/src/getting-started/indexer-service-infrastructure.md index d14bd4604..e77ba16ed 100644 --- a/docs/src/getting-started/indexer-service-infrastructure.md +++ b/docs/src/getting-started/indexer-service-infrastructure.md @@ -147,12 +147,11 @@ OPTIONS: {{#include ../../../config.yaml}} ``` - ## Web API Server The `fuel-indexer-api-server` crate of the Fuel indexer contains a standalone web API server that acts as a queryable endpoint on top of the database. Note that the main `fuel-indexer` binary of the indexer project also contains the same web API endpoint. -> The `fuel-indexer-api-server` crate offers a _standalone_ web API endpoint, whereas the API endpoint offered in `fuel-indexer` is bundled with other Fuel indexer functionality (e.g., execution, handling, data-layer construction, etc). Offering the API server as a separate piece allows users to separate components and run them on different systems, if desired. +> The `fuel-indexer-api-server` crate offers a _standalone_ web API endpoint, whereas the API endpoint offered in `fuel-indexer` is bundled with other Fuel indexer functionality (e.g., execution, handling, data-layer construction, etc). Offering the API server as a separate piece allows users to separate components and run them on different systems, if desired. ### Usage diff --git a/docs/src/getting-started/quickstart.md b/docs/src/getting-started/quickstart.md index 316730bc9..6d8d2367b 100644 --- a/docs/src/getting-started/quickstart.md +++ b/docs/src/getting-started/quickstart.md @@ -102,7 +102,7 @@ To quickly setup and bootstrap the PostgreSQL database that we'll need, we'll us We can quickly create a bootstrapped database and start the Fuel indexer service by running the following command: -> IMPORTANT: Below we're specifying our Postgres hostname as `--postgres-host postgresql`, but you might need to change this based on your own Postgres instance details (see `forc index start --help` for more details). +> IMPORTANT: Below we're specifying our Postgres hostname as `--postgres-host postgresql`, but you might need to change this based on your own Postgres instance details (see `forc index start --help` for more details). > > Additionally, you can try using the `--embedded-database` flag in order to quickly use an embedded instance of Postgres, but this flag can be flaky, and its ease of use often depends on what platform you're using. diff --git a/docs/src/indexing-custom-types/index.md b/docs/src/indexing-custom-types/index.md index 7deeea0e5..2c4045d64 100644 --- a/docs/src/indexing-custom-types/index.md +++ b/docs/src/indexing-custom-types/index.md @@ -1,6 +1,6 @@ # Custom Types -In addition to Fuel-specific types, you can also index custom Sway types as well. To index custom types from a Sway smart contract, you'll need that contract's ABI in JSON format; the JSON ABI is generated as a result of running `forc build` to build your contract. After that, the process is similar to [indexing Fuel types](./indexing-fuel-types.md). +In addition to Fuel-specific types, you can also index custom Sway types as well. To index custom types from a Sway smart contract, you'll need that contract's ABI in JSON format; the JSON ABI is generated as a result of running `forc build` to build your contract. After that, the process is similar to [indexing Fuel types](../indexing-fuel-types/index.md). Let's go over an example. @@ -32,7 +32,7 @@ abi ValueStore { } storage { - total: u64 = 1000, + total: u64 = 1000, } impl ValueStore for Contract { @@ -197,6 +197,7 @@ resumable: true ## Handler Logic Finally, we can create handlers to index these particular types and store them in the database. Let's look at the following example: + ```rust, ignore use fuel_indexer_utils::prelude::*; diff --git a/docs/src/indexing-fuel-types/blocks.md b/docs/src/indexing-fuel-types/blocks.md index 8de077136..df89e8f23 100644 --- a/docs/src/indexing-fuel-types/blocks.md +++ b/docs/src/indexing-fuel-types/blocks.md @@ -29,4 +29,4 @@ mod indexer_mod { info!("This block #{height}"); } } -``` \ No newline at end of file +``` diff --git a/docs/src/indexing-fuel-types/receipts.md b/docs/src/indexing-fuel-types/receipts.md index 16d805ab8..39836aa9c 100644 --- a/docs/src/indexing-fuel-types/receipts.md +++ b/docs/src/indexing-fuel-types/receipts.md @@ -261,8 +261,7 @@ mod indexer_mod { ## Return -A `Return` receipt is generated when returning a non-reference type in a Sway contract, specifically `bool`, `u8`, `u16`, `u32`, and `u64`. The `val` field includes the value being returned. -- [Read more about `Return` in the Fuel protocol spec](https://docs.fuel.network/docs/specs/abi/receipts/#return-receipt). +A `Return` receipt is generated when returning a non-reference type in a Sway contract, specifically `bool`, `u8`, `u16`, `u32`, and `u64`. The `val` field includes the value being returned. [Read more about `Return` in the Fuel protocol spec](https://docs.fuel.network/docs/specs/abi/receipts/#return-receipt). ```rust, ignore use fuel_types::ContractId; @@ -274,7 +273,6 @@ pub struct Return { } ``` - You can handle functions that produce a `Return` receipt type by adding a parameter with the type `Return`. ```rust, ignore @@ -339,8 +337,6 @@ pub struct Revert { | FailedAssertEq | 3 | | FailedAssert | 4 | - - ```rust, ignore extern crate alloc; use fuel_indexer_utils::prelude::*; diff --git a/docs/src/indexing-fuel-types/transactions.md b/docs/src/indexing-fuel-types/transactions.md index 42c7ee134..e3a1e787d 100644 --- a/docs/src/indexing-fuel-types/transactions.md +++ b/docs/src/indexing-fuel-types/transactions.md @@ -1,3 +1,4 @@ + # Transactions ## `TransactionData` @@ -39,7 +40,6 @@ mod indexer_mod { ``` - ## `TransactionStatus` `TransactionStatus` refers to the status of a `Transaction` in the Fuel network. diff --git a/docs/src/project-components/module.md b/docs/src/project-components/module.md index 6c224c084..cf259f8fc 100644 --- a/docs/src/project-components/module.md +++ b/docs/src/project-components/module.md @@ -24,10 +24,8 @@ mod indexer_mod { The first line imports the [prelude](https://docs.rs/fuel-indexer-utils/latest/fuel_indexer_utils/prelude/index.html) from `fuel_indexer_utils`; this allows you to quickly bootstrap an indexer by using common types and traits. Then, we have a module decorated with the `#[indexer]` macro. This macro processes a manifest at the supplied file path, parses your schema and Sway contract ABI (if supplied), and generates code that is combined with handler functions in order to create a complete indexer module. - Finally, we have an example handler function. You can define which functions handle different events by using the function parameters. If you add a function parameter of a certain type `T`, the function will be triggered whenever that type is found as part of a block, transaction, or receipt. In this example, let's say that you have a Sway contract with a function that logs a `Greeting` struct. When that function executes as part of a transaction, the logged struct will be included in the data that is processed from the Fuel blockchain. Your indexer module will see the struct and execute `log_the_greeting`. - > You can learn more about what data can be indexed and find example handlers in the [Indexing Fuel Types](../indexing-fuel-types/index.md) and [Indexing Custom Types](../indexing-custom-types/index.md) sections. --- @@ -47,12 +45,12 @@ After that, you can conveniently use the [`forc index`](./../forc-index/index.md > There are a few points that Fuel indexer users should know when using WASM: > > 1. WASM modules are only used if the execution mode specified in your manifest file is `wasm`. -> +> > 2. Developers should be aware of what things may not work off-the-shelf in a module: file I/O, thread spawning, and anything that depends on system libraries or makes system calls. This is due to the technological limitations of WASM as a whole; more information can be found [here](https://rustwasm.github.io/docs/book/reference/which-crates-work-with-wasm.html). > > 3. As of this writing, there is a small bug in newly built Fuel indexer WASM modules that produces a WASM runtime error due to an errant upstream dependency. For now, a quick workaround requires the use of `wasm-snip` to remove the errant symbols from the WASM module. More info can be found in the related script [here](https://github.com/FuelLabs/fuel-indexer/blob/develop/scripts/stripper.bash). > > 4. Users on Apple Silicon macOS systems may experience trouble when trying to build WASM modules due to its `clang` binary not supporting WASM targets. If encountered, you can install a binary with better support from Homebrew (`brew install llvm`) and instruct `rustc` to leverage it by setting the following environment variables: -> +> > - `AR=/opt/homebrew/opt/llvm/bin/llvm-ar` > - `CC=/opt/homebrew/opt/llvm/bin/clang` diff --git a/docs/src/project-components/schema.md b/docs/src/project-components/schema.md index d661538ef..ef3e7df05 100644 --- a/docs/src/project-components/schema.md +++ b/docs/src/project-components/schema.md @@ -24,9 +24,8 @@ type Wallet @entity { } ``` -For a complete list of all scalars that can be used in a Fuel indexer, please see the [GraphQL Scalars](./../graphql/scalars.md) section. +For a complete list of all scalars that can be used in a Fuel indexer, please see the [GraphQL Scalars](../designing-a-schema/scalars.md) section. -Further, for a complete list of how Sway data types, GraphQL scalar types, and Fuel indexer database types map to each other, please see the [Database Types](./../database/index.md) section. +Further, for a complete list of how Sway data types, GraphQL scalar types, and Fuel indexer database types map to each other, please see the [Database Types](../storing-records/index.md) section. - -Finally, for a more in-depth explanation on the schema being used above 👆🏽, please read the [GraphQL](./../graphql/index.md) section. +Finally, for a more in-depth explanation on the schema being used above 👆🏽, please read the [GraphQL](./../designing-a-schema/index.md) section. diff --git a/docs/src/querying/basic-queries.md b/docs/src/querying/basic-queries.md index cd77d3db6..324d05b2b 100644 --- a/docs/src/querying/basic-queries.md +++ b/docs/src/querying/basic-queries.md @@ -1,6 +1,6 @@ # Queries -Once data has been persisted into your storage backend, you can retrieve it by querying the [GraphQL API server](./api-server.md). By default, the API server can be reached at `http://localhost:29987/api/graph/:namespace/:identifier`, where `:namespace` and `:identifier` are the values for the respective fields in your indexer's manifest. If you've changed the `WEB_API_HOST` or `WEB_API_PORT` values of your configuration, then you'll need to adjust the URL accordingly. +Once data has been persisted into your storage backend, you can retrieve it by querying the [GraphQL API server](../getting-started/indexer-service-infrastructure.md#web-api-server). By default, the API server can be reached at `http://localhost:29987/api/graph/:namespace/:identifier`, where `:namespace` and `:identifier` are the values for the respective fields in your indexer's manifest. If you've changed the `WEB_API_HOST` or `WEB_API_PORT` values of your configuration, then you'll need to adjust the URL accordingly. ## Basic Query @@ -63,7 +63,7 @@ We're requesting the ID, height, and timestamp for each block stored in the back ## Nested Query -The Fuel indexer supports [foreign keys](./relationships.md) on entity types; thus, you can also ask for information about a referenced entity inside of your query. A nested query has the following general structure: +The Fuel indexer supports [foreign keys](../designing-a-schema/relationships.md) on entity types; thus, you can also ask for information about a referenced entity inside of your query. A nested query has the following general structure: ```graphql query { @@ -112,7 +112,7 @@ type Character @entity { } ``` -This schema uses implicit foreign keys to reference other entities; for more information on implicit and explicit foreign keys, please refer to the [Relationships](./relationships.md) section of the book. In this contrived example, we're storing information about characters that are found in books which are stored in libraries that can be found in cities. This will be the query that we use to retrieve the aforementioned data: +This schema uses implicit foreign keys to reference other entities; for more information on implicit and explicit foreign keys, please refer to the [Relationships](../designing-a-schema/relationships.md) section of the book. In this contrived example, we're storing information about characters that are found in books which are stored in libraries that can be found in cities. This will be the query that we use to retrieve the aforementioned data: ```graphql query { diff --git a/docs/src/querying/index.md b/docs/src/querying/index.md index 78725bf1c..bfcfe24dd 100644 --- a/docs/src/querying/index.md +++ b/docs/src/querying/index.md @@ -1,7 +1,7 @@ # Queries -- [Basic Queries](./queries.md) +- [Basic Queries](./basic-queries.md) - [Pagination](./pagination.md) -- [Search & Filtering](./search-filtering.md) +- [Search & Filtering](./search-and-filtering.md) - [Full Example](./full-example.md) - [The GraphQL Playground](./playground.md) diff --git a/docs/src/querying/playground.md b/docs/src/querying/playground.md index 5e645a77b..ec2ed5f42 100644 --- a/docs/src/querying/playground.md +++ b/docs/src/querying/playground.md @@ -6,10 +6,8 @@ Every public indexer can access the GraphQL playground of the Fuel indexer node ## Usage -To use the GraphQL playground to explor your indices, simply [start your indexer service](../getting-started/starting-the-fuel-indexer.md) - then open the following URL in your browser - where `namespace` and `identifier` correspond to the namespace and identifier of the index that you'd like to explore. +To use the GraphQL playground to explor your indices, simply [start your indexer service](../getting-started/indexer-service-infrastructure.md) - then open the following URL in your browser - where `namespace` and `identifier` correspond to the namespace and identifier of the index that you'd like to explore. ```bash http://localhost:29987/api/playground/:namespace/:identifier ``` - -> NOTE: On initial page render, the playground throws a 500. Don't worry about this, you should still be able to query. From 17bbba06bd4646bbc559cac542064b138bd3f668 Mon Sep 17 00:00:00 2001 From: Rashad Alston Date: Mon, 18 Sep 2023 10:16:41 -0400 Subject: [PATCH 28/33] up until 'designing a schema' --- config.yaml | 4 +- docs/src/forc-index/start.md | 4 +- docs/src/getting-started/dependencies.md | 22 +++--- .../indexer-service-infrastructure.md | 71 +++++++++++++------ docs/src/project-components/index.md | 23 ++++++ docs/src/project-components/module.md | 8 ++- docs/src/project-components/schema.md | 2 +- examples/fuel-explorer/README.md | 2 +- examples/hello-world-native/README.md | 2 +- examples/hello-world/README.md | 2 +- packages/fuel-indexer-api-server/src/api.rs | 4 +- .../fuel-indexer-api-server/src/models.rs | 4 +- packages/fuel-indexer-api-server/src/sql.rs | 2 +- packages/fuel-indexer-lib/src/config/cli.rs | 16 ++--- packages/fuel-indexer-lib/src/config/web.rs | 2 +- packages/fuel-indexer-lib/src/defaults.rs | 2 +- ...ommands__forc_index_start_help_output.snap | 4 +- ...__fuel_indexer_api_server_help_output.snap | 2 +- ...el_indexer_api_server_run_help_output.snap | 4 +- ...ommands__fuel_indexer_run_help_output.snap | 4 +- ...apshots__forc_index_start_help_output.snap | 4 +- ...__fuel_indexer_api_server_help_output.snap | 2 +- ...el_indexer_api_server_run_help_output.snap | 4 +- ...apshots__fuel_indexer_run_help_output.snap | 4 +- packages/fuel-indexer/src/service.rs | 2 +- 25 files changed, 129 insertions(+), 71 deletions(-) diff --git a/config.yaml b/config.yaml index 794465086..85bf4dc3b 100644 --- a/config.yaml +++ b/config.yaml @@ -35,7 +35,7 @@ indexer_net_config: false # The number of WASM opcodes after which the indexer will stop execution. metering_points: 30000000000 -# Allow the web API to accept raw SQL queries. +# Allow the web server to accept raw SQL queries. accept_sql_queries: false # Amount of blocks to return in a request to a Fuel node. @@ -64,7 +64,7 @@ web_api: # Web API port. port: 29987 - # Max body size for web API requests. + # Max body size for web server requests. max_body_size: "5242880" # ****************************** diff --git a/docs/src/forc-index/start.md b/docs/src/forc-index/start.md index bd208bf35..826f1e60e 100644 --- a/docs/src/forc-index/start.md +++ b/docs/src/forc-index/start.md @@ -14,7 +14,7 @@ USAGE: OPTIONS: --accept-sql-queries - Allow the web API to accept raw SQL queries. + Allow the web server to accept raw SQL queries. --auth-enabled Require users to authenticate for some operations. @@ -66,7 +66,7 @@ OPTIONS: Indexer config file. --max-body-size - Max body size for web API requests. [default: 5242880] + Max body size for web server requests. [default: 5242880] --metering-points The number of WASM opcodes after which the indexer's event handler will stop execution. diff --git a/docs/src/getting-started/dependencies.md b/docs/src/getting-started/dependencies.md index 84bfbd2a6..24b61742f 100644 --- a/docs/src/getting-started/dependencies.md +++ b/docs/src/getting-started/dependencies.md @@ -1,20 +1,26 @@ # Dependencies -> This guide covers some of the basics with regard to installing dependencies for the Fuel indexer service. However, note that this guide is meant to be a general overview for most platforms and by no means covers all platforms. If you're having trouble with dependencies on your system, we recommend that you use `docker`. +> This guide covers some of the basics with regard to installing dependencies for the Fuel indexer service. However, note that this guide is meant to be a general overview for most platforms and by no means covers all platforms. +> +> If you're having trouble with dependencies on your system, we recommend that you use `docker`. To run the Fuel indexer, you'll need to install a few dependencies on your system: -- The [Rust programming language, with its package manager](https://www.rust-lang.org/tools/install) -- [`fuelup`](#fuelup), the Fuel toolchain manager -- A [PostgresQL](#postgresql) server backend -- The [`wasm32-unknown-unknown`](#web-assembly-wasm) `rustup` target -- [`wasm-snip`](#web-assembly-wasm), a utility for stripping symbols from WebAssemly binaries. +1. The [Rust programming language, with its package manager](https://www.rust-lang.org/tools/install) +2. [`fuelup`](#fuelup), the Fuel toolchain manager +3. A [PostgresQL](#postgresql) server backend +4. The [`wasm32-unknown-unknown`](#web-assembly-wasm) `rustup` target +5. [`wasm-snip`](#web-assembly-wasm), a utility for stripping symbols from WebAssemly binaries. -> If you don't want to install a database directly onto your system, you can use Docker to run it as an isolated container. You can install Docker by following the [install instructions](https://docs.docker.com/get-docker/). For reference purposes, we provide a [`docker compose` file](https://github.com/FuelLabs/fuel-indexer/blob/develop/scripts/docker-compose.yaml) that comes with a PostgresSQL server and a Fuel indexer service. +> If you don't want to install a database directly onto your system, you can use Docker to run a database in an isolated container. You can install Docker by following its [installation instructions](https://docs.docker.com/get-docker/). +> +> For reference purposes, we provide a [`docker compose` file](https://github.com/FuelLabs/fuel-indexer/blob/develop/scripts/docker-compose.yaml) that comes with a PostgresSQL server and a Fuel indexer service. ## `fuelup` -We strongly recommend that you use the Fuel indexer through [`forc`, the Fuel orchestrator](https://fuellabs.github.io/sway/master/book/forc/index.html). You can get `forc` (and other Fuel components) by way of [`fuelup`, the Fuel toolchain manager](https://fuellabs.github.io/fuelup/latest). Install `fuelup` by running the following command, which downloads and runs the installation script. +We strongly recommend that you use the Fuel indexer that's made available via [`forc`, the Fuel orchestrator](https://fuellabs.github.io/sway/master/book/forc/index.html). You can get `forc` (and other Fuel components) by way of [`fuelup`, the Fuel toolchain manager](https://fuellabs.github.io/fuelup/latest). + +Install `fuelup` by running the following command, which downloads and runs the installation script. ```bash curl --proto '=https' --tlsv1.2 -sSf https://install.fuel.network/fuelup-init.sh | sh diff --git a/docs/src/getting-started/indexer-service-infrastructure.md b/docs/src/getting-started/indexer-service-infrastructure.md index e77ba16ed..60831c723 100644 --- a/docs/src/getting-started/indexer-service-infrastructure.md +++ b/docs/src/getting-started/indexer-service-infrastructure.md @@ -1,28 +1,44 @@ # Indexer Service Infrastructure +- [Service Components](#components) +- [Fuel Indexer Service](#fuel-indexer-service) + - [Starting the service via CLI options](#using-cli-options-indexer-service) + - [Starting the service via a config file](#using-a-configuration-file-indexer-service) +- [Fuel Indexer Web Server](#web-api-server) + - [Starting the service via CLI options](#using-cli-options-web-server) + - [Starting the service via a config file](#using-a-configuration-file-web-server) + A Fuel indexer service instance requires just three components: -- a **Fuel node**: Custom indexers monitor incoming blocks from a Fuel node and extract information about the state of the Fuel blockchain. +- a **Fuel Node**: Custom indexers monitor incoming blocks via a Fuel GraphQL server and extract information about the state of the Fuel blockchain. - a **PostgresQL database server**: Extracted information is saved into a database. -- a **web server**: dApps can query indexers for up-to-date information and operators can deploy/remove indexers as needed. +- a **Web Server**: dApps can query indexers for up-to-date information and operators can deploy/remove indexers as needed. --- -The Fuel indexer service will connect to any Fuel node, which means you can run your own node or use a node provided by Fuel. The indexer service web API is included with the Fuel indexer; it's available as soon as the indexer is started through `fuel-indexer run`. The only component that isn't provided for you is a Postgres database server. You should set up a server according to your own needs and specifications. - ## Components | Component | Default Host | Default Port | CLI Argument | Environment Variable | |---|---|---|---|---| -| Fuel Node | localhost | 4000 | `--fuel-node-host` / `--fuel-node-port` | | -| Database Server | localhost | 5432 | `--postgres-user` / `--postgres--password` / `--postgres-host` / `--postgres--port` / `--postgres-database` | | -| Indexer Service Web API | localhost | 29987 | `--web-api-host` / `--web-api-port` | | +| Fuel Node | localhost | 4000 | `--fuel-node-{host,port}` | $FUEL_NODE_{HOST,PORT} | +| Database Server | localhost | 5432 | `--postgres-{username,database,password,host,port}` | $POSTGRES_{USERNAME,DATABASE,PASSWORD,HOST,PORT} | +| Indexer Service Web API | localhost | 29987 | `--web-api-{host,port}` | $WEB_API_{HOST,PORT} | + +--- + +## Fuel Indexer Service + +The Fuel indexer service will connect to any Fuel GraphQL server, which means you can run your own node or use a node provided by Fuel. The indexer service web server is included with the Fuel indexer; it's available as soon as the indexer is started through `fuel-indexer run`. The only component that isn't provided for you is a Postgres database server. You should set up a server according to your own needs and specifications. -## Starting the Fuel indexer +> You can start the indexer service with an array of CLI options. Note that most (if not all) of these options include sensible defaults. -### Using CLI options +### Using CLI options (Indexer Service) + +```bash +fuel-indexer run --help +``` ```text Standalone binary for the fuel indexer service. @@ -32,7 +48,7 @@ USAGE: OPTIONS: --accept-sql-queries - Allow the web API to accept raw SQL queries. + Allow the web server to accept raw SQL queries. --auth-enabled Require users to authenticate for some operations. @@ -84,7 +100,7 @@ OPTIONS: Indexer config file. --max-body-size - Max body size for web API requests. [default: 5242880] + Max body size for web server requests. [default: 5242880] --metering-points The number of WASM opcodes after which the indexer's event handler will stop execution. @@ -141,39 +157,37 @@ OPTIONS: ``` -### Using a configuration file +### Using a configuration file (Indexer Service) ```yaml {{#include ../../../config.yaml}} ``` +---- + ## Web API Server -The `fuel-indexer-api-server` crate of the Fuel indexer contains a standalone web API server that acts as a queryable endpoint on top of the database. Note that the main `fuel-indexer` binary of the indexer project also contains the same web API endpoint. +The `fuel-indexer-api-server` crate of the Fuel indexer contains a standalone web server server that acts as a queryable endpoint on top of the database. Note that the main `fuel-indexer` binary of the indexer project also contains the same web server endpoint. -> The `fuel-indexer-api-server` crate offers a _standalone_ web API endpoint, whereas the API endpoint offered in `fuel-indexer` is bundled with other Fuel indexer functionality (e.g., execution, handling, data-layer construction, etc). Offering the API server as a separate piece allows users to separate components and run them on different systems, if desired. +> The `fuel-indexer-api-server` crate offers a _standalone_ web server endpoint, whereas the API endpoint offered in `fuel-indexer` is bundled with other Fuel indexer functionality (e.g., execution, handling, data-layer construction, etc). Offering the API server as a separate piece allows users to separate components and run them on different systems, if desired. -### Usage +### Using CLI Options (Web Server) -To run the standalone Fuel indexer web API server using a configuration file: +> You can start the indexer service with an array of CLI options. Note that most (if not all) of these options include sensible defaults. ```bash -fuel-indexer-api-server run --config config.yaml +fuel-indexer-api-server run --help ``` -In the above example, `config.yaml` is based on [the default service configuration file](https://github.com/FuelLabs/fuel-indexer/blob/develop/config.yaml). - -### Options - ```text -Fuel indexer web API +Fuel indexer web server USAGE: fuel-indexer-api-server run [OPTIONS] OPTIONS: --accept-sql-queries - Allow the web API to accept raw SQL queries. + Allow the web server to accept raw SQL queries. --auth-enabled Require users to authenticate for some operations. @@ -254,3 +268,14 @@ OPTIONS: --web-api-port Web API port. [default: 29987] ``` + +### Using A Configuration File (Web Server) + +To run the standalone Fuel indexer web server server using a configuration file: + +```bash +fuel-indexer-api-server run --config config.yaml +``` + +In the above example, `config.yaml` is based on [the default service configuration file](https://github.com/FuelLabs/fuel-indexer/blob/develop/config.yaml). + diff --git a/docs/src/project-components/index.md b/docs/src/project-components/index.md index 3439b92ab..a763512ef 100644 --- a/docs/src/project-components/index.md +++ b/docs/src/project-components/index.md @@ -14,10 +14,33 @@ We'll describe these three different use cases below. The Fuel indexer provides functionality to make it easy to build and compile abitrary indexers by using the [`forc index`](../forc-index/index.md) CLI tool. Using `forc index`, users can create, build, deploy, and remove indexers, as well as authenticate against a running indexer service, and check the status of running indexers. +#### Example + +Create, deploy, and check the status of a new indexer. + +```bash +forc index new fuel && \ + cd fuel && forc index deploy --url http://indexer.fuel.network && \ + forc index status --url http://indexer.fuel.network --auth $MY_TOKEN +``` + ### As a standalone service You can also start the Fuel indexer as a standalone service that connects to a Fuel node in order to monitor the Fuel blockchain for new blocks and transactions. To do so, run the requisite database migrations, adjust the configuration to connect to a Fuel node, and start the service. +#### Example + +Create, deploy, and check the status of a new indexer. + +```bash +fuel-indexer run \ + --fuel-node-host beta-4.fuel.network \ + --fuel-node-port 80 \ + --run-migrations \ + --accept-sql-queries \ + --replace-indexer +``` + ### As part of a Fuel project Finally, you can run the Fuel indexer as part of a project that uses other components of the Fuel ecosystem, such as Sway. The convention for a Fuel project layout including an indexer is as follows: diff --git a/docs/src/project-components/module.md b/docs/src/project-components/module.md index cf259f8fc..75214663e 100644 --- a/docs/src/project-components/module.md +++ b/docs/src/project-components/module.md @@ -22,9 +22,13 @@ mod indexer_mod { } ``` -The first line imports the [prelude](https://docs.rs/fuel-indexer-utils/latest/fuel_indexer_utils/prelude/index.html) from `fuel_indexer_utils`; this allows you to quickly bootstrap an indexer by using common types and traits. Then, we have a module decorated with the `#[indexer]` macro. This macro processes a manifest at the supplied file path, parses your schema and Sway contract ABI (if supplied), and generates code that is combined with handler functions in order to create a complete indexer module. +## What's going on here? -Finally, we have an example handler function. You can define which functions handle different events by using the function parameters. If you add a function parameter of a certain type `T`, the function will be triggered whenever that type is found as part of a block, transaction, or receipt. In this example, let's say that you have a Sway contract with a function that logs a `Greeting` struct. When that function executes as part of a transaction, the logged struct will be included in the data that is processed from the Fuel blockchain. Your indexer module will see the struct and execute `log_the_greeting`. +- The first line imports the [prelude](https://docs.rs/fuel-indexer-utils/latest/fuel_indexer_utils/prelude/index.html) from `fuel_indexer_utils`; this allows you to quickly bootstrap an indexer by using common types and traits. Then, we have a module decorated with the `#[indexer]` macro. + - This macro processes a manifest at the supplied file path, parses your schema and Sway contract ABI (if supplied), and generates code that is combined with handler functions in order to create a complete indexer module. + +- Finally, we have an example handler function. You can define which functions handle different events by using the function parameters. If you add a function parameter of a certain type `T`, the function will be triggered whenever that type is found as part of a block, transaction, or receipt. + - In this example, let's say that you have a Sway contract with a function that logs a `Greeting` struct. When that function executes as part of a transaction, the logged struct will be included in the data that is processed from the Fuel blockchain. Your indexer module will see the struct and execute `log_the_greeting`. > You can learn more about what data can be indexed and find example handlers in the [Indexing Fuel Types](../indexing-fuel-types/index.md) and [Indexing Custom Types](../indexing-custom-types/index.md) sections. diff --git a/docs/src/project-components/schema.md b/docs/src/project-components/schema.md index ef3e7df05..f4c93bf20 100644 --- a/docs/src/project-components/schema.md +++ b/docs/src/project-components/schema.md @@ -1,6 +1,6 @@ # GraphQL Schema -The GraphQL schema is a required component of the Fuel indexer. When data is indexed into the database, the actual values that are persisted to the database will be values created using the data structures defined in the schema. +The GraphQL schema is a required component of the Fuel indexer. When data is indexed into the database, the actual values that are persisted to the database will be values created using the data structures defined in the GraphQL schema. Below is a sample GraphQL schema for a Fuel indexer. diff --git a/examples/fuel-explorer/README.md b/examples/fuel-explorer/README.md index cedc46ca2..20a7f8ff8 100644 --- a/examples/fuel-explorer/README.md +++ b/examples/fuel-explorer/README.md @@ -43,7 +43,7 @@ query { ``` > IMPORTANT: Since this example uses a dockerized indexer service, with the GraphQL -> web API being bound at interface `0.0.0.0` your LAN IP might differ from the +> web server being bound at interface `0.0.0.0` your LAN IP might differ from the > `192.168.1.34` mentioned above. > > On *nix platforms you can typically find your LAN IP via `ifconfig | grep inet` \ No newline at end of file diff --git a/examples/hello-world-native/README.md b/examples/hello-world-native/README.md index f51b65e7b..e5ddecd01 100644 --- a/examples/hello-world-native/README.md +++ b/examples/hello-world-native/README.md @@ -52,7 +52,7 @@ query { ``` > IMPORTANT: Since this example uses a dockerized indexer service, with the GraphQL -> web API being bound at interface `0.0.0.0` your LAN IP might differ from the +> web server being bound at interface `0.0.0.0` your LAN IP might differ from the > `192.168.1.34` mentioned above. > > On *nix platforms you can typically find your LAN IP via `ifconfig | grep inet` \ No newline at end of file diff --git a/examples/hello-world/README.md b/examples/hello-world/README.md index 434edb236..3bc0af5f0 100644 --- a/examples/hello-world/README.md +++ b/examples/hello-world/README.md @@ -50,7 +50,7 @@ query { ``` > IMPORTANT: Since this example uses a dockerized indexer service, with the GraphQL -> web API being bound at interface `0.0.0.0` your LAN IP might differ from the +> web server being bound at interface `0.0.0.0` your LAN IP might differ from the > `192.168.1.34` mentioned above. > > On *nix platforms you can typically find your LAN IP via `ifconfig | grep inet` diff --git a/packages/fuel-indexer-api-server/src/api.rs b/packages/fuel-indexer-api-server/src/api.rs index 5aba634a1..bd772bb93 100644 --- a/packages/fuel-indexer-api-server/src/api.rs +++ b/packages/fuel-indexer-api-server/src/api.rs @@ -41,7 +41,7 @@ use tower_http::{ }; use tracing::{error, Level}; -/// Result type returned by web API operations. +/// Result type returned by web server operations. pub type ApiResult = core::result::Result; /// Size of the buffer for reqeusts being passed to the `RateLimitLayer`. @@ -70,7 +70,7 @@ impl From for HttpError { } } -/// Error type returned by web API operations. +/// Error type returned by web server operations. #[derive(Debug, Error)] pub enum ApiError { #[error("Query builder error {0:?}")] diff --git a/packages/fuel-indexer-api-server/src/models.rs b/packages/fuel-indexer-api-server/src/models.rs index 1cddffacd..2b1d19210 100644 --- a/packages/fuel-indexer-api-server/src/models.rs +++ b/packages/fuel-indexer-api-server/src/models.rs @@ -12,7 +12,7 @@ pub struct VerifySignatureRequest { pub message: String, } -/// GraphQL web API response. +/// GraphQL web server response. #[derive(Serialize)] pub(crate) struct QueryResponse { /// Arbitrarily sized JSON response. @@ -74,7 +74,7 @@ impl Claims { } } -/// A SQL query posted to the web API. +/// A SQL query posted to the web server. #[derive(Serialize, Deserialize, Clone, Debug)] pub struct SqlQuery { /// The literal raw SQL query. diff --git a/packages/fuel-indexer-api-server/src/sql.rs b/packages/fuel-indexer-api-server/src/sql.rs index 3d002ead0..2545d7fdf 100644 --- a/packages/fuel-indexer-api-server/src/sql.rs +++ b/packages/fuel-indexer-api-server/src/sql.rs @@ -15,7 +15,7 @@ pub enum SqlValidatorError { /// A validator for SQL queries. /// -/// Intended to ensure that users posting raw SQL queries to web API endpoints +/// Intended to ensure that users posting raw SQL queries to web server endpoints /// are not attempting to do anything malicious. pub struct SqlQueryValidator; diff --git a/packages/fuel-indexer-lib/src/config/cli.rs b/packages/fuel-indexer-lib/src/config/cli.rs index 167608f02..798c9e570 100644 --- a/packages/fuel-indexer-lib/src/config/cli.rs +++ b/packages/fuel-indexer-lib/src/config/cli.rs @@ -63,8 +63,8 @@ pub struct IndexerArgs { #[clap(long, help = "Database type.", default_value = defaults::DATABASE, value_parser(["postgres"]))] pub database: String, - /// Max body size for web API requests. - #[clap(long, help = "Max body size for web API requests.", default_value_t = defaults::MAX_BODY_SIZE )] + /// Max body size for web server requests. + #[clap(long, help = "Max body size for web server requests.", default_value_t = defaults::MAX_BODY_SIZE )] pub max_body_size: usize, /// Postgres username. @@ -184,8 +184,8 @@ pub struct IndexerArgs { )] pub remove_data: bool, - /// Allow the web API to accept raw SQL queries. - #[clap(long, help = "Allow the web API to accept raw SQL queries.")] + /// Allow the web server to accept raw SQL queries. + #[clap(long, help = "Allow the web server to accept raw SQL queries.")] pub accept_sql_queries: bool, /// Amount of blocks to return in a request to a Fuel node. @@ -196,7 +196,7 @@ pub struct IndexerArgs { #[derive(Debug, Parser, Clone)] #[clap( name = "Fuel Indexer API Server", - about = "Fuel indexer web API", + about = "Fuel indexer web server", version )] pub struct ApiServerArgs { @@ -236,7 +236,7 @@ pub struct ApiServerArgs { #[clap(long, help = "Database type.", default_value = defaults::DATABASE, value_parser(["postgres"]))] pub database: String, - /// Max body size for web API requests. + /// Max body size for web server requests. #[clap(long, help = "Max body size for web requests.", default_value_t = defaults::MAX_BODY_SIZE )] pub max_body_size: usize, @@ -313,7 +313,7 @@ pub struct ApiServerArgs { #[clap(long, help = "Number of seconds over which to allow --rate-limit-rps.")] pub rate_limit_window_size: Option, - /// Allow the web API to accept raw SQL queries. - #[clap(long, help = "Allow the web API to accept raw SQL queries.")] + /// Allow the web server to accept raw SQL queries. + #[clap(long, help = "Allow the web server to accept raw SQL queries.")] pub accept_sql_queries: bool, } diff --git a/packages/fuel-indexer-lib/src/config/web.rs b/packages/fuel-indexer-lib/src/config/web.rs index 0506c8417..5dc92189e 100644 --- a/packages/fuel-indexer-lib/src/config/web.rs +++ b/packages/fuel-indexer-lib/src/config/web.rs @@ -19,7 +19,7 @@ pub struct WebApiConfig { #[serde(default)] pub port: String, - /// Max body size for web API requests. + /// Max body size for web server requests. #[serde(default)] pub max_body_size: usize, } diff --git a/packages/fuel-indexer-lib/src/defaults.rs b/packages/fuel-indexer-lib/src/defaults.rs index 2e88f6590..14d5c4e2d 100644 --- a/packages/fuel-indexer-lib/src/defaults.rs +++ b/packages/fuel-indexer-lib/src/defaults.rs @@ -132,5 +132,5 @@ pub const REPLACE_INDEXER: bool = false; /// Whether to remove the indexed data when replacing an indexer. pub const REMOVE_DATA: bool = false; -/// Allow the web API to accept raw SQL queries. +/// Allow the web server to accept raw SQL queries. pub const ACCEPT_SQL: bool = false; diff --git a/packages/fuel-indexer-tests/tests/snapshots/integration_tests__commands__forc_index_start_help_output.snap b/packages/fuel-indexer-tests/tests/snapshots/integration_tests__commands__forc_index_start_help_output.snap index 2cc462b08..d7fac7506 100644 --- a/packages/fuel-indexer-tests/tests/snapshots/integration_tests__commands__forc_index_start_help_output.snap +++ b/packages/fuel-indexer-tests/tests/snapshots/integration_tests__commands__forc_index_start_help_output.snap @@ -9,7 +9,7 @@ USAGE: OPTIONS: --accept-sql-queries - Allow the web API to accept raw SQL queries. + Allow the web server to accept raw SQL queries. --auth-enabled Require users to authenticate for some operations. @@ -61,7 +61,7 @@ OPTIONS: Indexer config file. --max-body-size - Max body size for web API requests. [default: 5242880] + Max body size for web server requests. [default: 5242880] --metering-points The number of WASM opcodes after which the indexer's event handler will stop execution. diff --git a/packages/fuel-indexer-tests/tests/snapshots/integration_tests__commands__fuel_indexer_api_server_help_output.snap b/packages/fuel-indexer-tests/tests/snapshots/integration_tests__commands__fuel_indexer_api_server_help_output.snap index 62f934cb6..f3bb86d04 100644 --- a/packages/fuel-indexer-tests/tests/snapshots/integration_tests__commands__fuel_indexer_api_server_help_output.snap +++ b/packages/fuel-indexer-tests/tests/snapshots/integration_tests__commands__fuel_indexer_api_server_help_output.snap @@ -13,4 +13,4 @@ OPTIONS: SUBCOMMANDS: help Print this message or the help of the given subcommand(s) - run Fuel indexer web API + run Fuel indexer web server diff --git a/packages/fuel-indexer-tests/tests/snapshots/integration_tests__commands__fuel_indexer_api_server_run_help_output.snap b/packages/fuel-indexer-tests/tests/snapshots/integration_tests__commands__fuel_indexer_api_server_run_help_output.snap index afe11352d..1564a42e7 100644 --- a/packages/fuel-indexer-tests/tests/snapshots/integration_tests__commands__fuel_indexer_api_server_run_help_output.snap +++ b/packages/fuel-indexer-tests/tests/snapshots/integration_tests__commands__fuel_indexer_api_server_run_help_output.snap @@ -2,14 +2,14 @@ source: packages/fuel-indexer-tests/tests/commands.rs expression: output --- -Fuel indexer web API +Fuel indexer web server USAGE: fuel-indexer-api-server run [OPTIONS] OPTIONS: --accept-sql-queries - Allow the web API to accept raw SQL queries. + Allow the web server to accept raw SQL queries. --auth-enabled Require users to authenticate for some operations. diff --git a/packages/fuel-indexer-tests/tests/snapshots/integration_tests__commands__fuel_indexer_run_help_output.snap b/packages/fuel-indexer-tests/tests/snapshots/integration_tests__commands__fuel_indexer_run_help_output.snap index 939df7f58..46f9952af 100644 --- a/packages/fuel-indexer-tests/tests/snapshots/integration_tests__commands__fuel_indexer_run_help_output.snap +++ b/packages/fuel-indexer-tests/tests/snapshots/integration_tests__commands__fuel_indexer_run_help_output.snap @@ -9,7 +9,7 @@ USAGE: OPTIONS: --accept-sql-queries - Allow the web API to accept raw SQL queries. + Allow the web server to accept raw SQL queries. --auth-enabled Require users to authenticate for some operations. @@ -61,7 +61,7 @@ OPTIONS: Indexer config file. --max-body-size - Max body size for web API requests. [default: 5242880] + Max body size for web server requests. [default: 5242880] --metering-points The number of WASM opcodes after which the indexer's event handler will stop execution. diff --git a/packages/fuel-indexer-tests/tests/snapshots/integration_tests__snapshots__forc_index_start_help_output.snap b/packages/fuel-indexer-tests/tests/snapshots/integration_tests__snapshots__forc_index_start_help_output.snap index df6bc81e4..fb5e7a9c2 100644 --- a/packages/fuel-indexer-tests/tests/snapshots/integration_tests__snapshots__forc_index_start_help_output.snap +++ b/packages/fuel-indexer-tests/tests/snapshots/integration_tests__snapshots__forc_index_start_help_output.snap @@ -9,7 +9,7 @@ USAGE: OPTIONS: --accept-sql-queries - Allow the web API to accept raw SQL queries. + Allow the web server to accept raw SQL queries. --auth-enabled Require users to authenticate for some operations. @@ -61,7 +61,7 @@ OPTIONS: Indexer config file. --max-body-size - Max body size for web API requests. [default: 5242880] + Max body size for web server requests. [default: 5242880] --metering-points The number of WASM opcodes after which the indexer's event handler will stop execution. diff --git a/packages/fuel-indexer-tests/tests/snapshots/integration_tests__snapshots__fuel_indexer_api_server_help_output.snap b/packages/fuel-indexer-tests/tests/snapshots/integration_tests__snapshots__fuel_indexer_api_server_help_output.snap index 445bc01b9..a0b2193b3 100644 --- a/packages/fuel-indexer-tests/tests/snapshots/integration_tests__snapshots__fuel_indexer_api_server_help_output.snap +++ b/packages/fuel-indexer-tests/tests/snapshots/integration_tests__snapshots__fuel_indexer_api_server_help_output.snap @@ -13,4 +13,4 @@ OPTIONS: SUBCOMMANDS: help Print this message or the help of the given subcommand(s) - run Fuel indexer web API + run Fuel indexer web server diff --git a/packages/fuel-indexer-tests/tests/snapshots/integration_tests__snapshots__fuel_indexer_api_server_run_help_output.snap b/packages/fuel-indexer-tests/tests/snapshots/integration_tests__snapshots__fuel_indexer_api_server_run_help_output.snap index dbd54724b..e3c217c1f 100644 --- a/packages/fuel-indexer-tests/tests/snapshots/integration_tests__snapshots__fuel_indexer_api_server_run_help_output.snap +++ b/packages/fuel-indexer-tests/tests/snapshots/integration_tests__snapshots__fuel_indexer_api_server_run_help_output.snap @@ -2,14 +2,14 @@ source: packages/fuel-indexer-tests/tests/snapshots.rs expression: output --- -Fuel indexer web API +Fuel indexer web server USAGE: fuel-indexer-api-server run [OPTIONS] OPTIONS: --accept-sql-queries - Allow the web API to accept raw SQL queries. + Allow the web server to accept raw SQL queries. --auth-enabled Require users to authenticate for some operations. diff --git a/packages/fuel-indexer-tests/tests/snapshots/integration_tests__snapshots__fuel_indexer_run_help_output.snap b/packages/fuel-indexer-tests/tests/snapshots/integration_tests__snapshots__fuel_indexer_run_help_output.snap index 6d6d3ba40..48aeb1018 100644 --- a/packages/fuel-indexer-tests/tests/snapshots/integration_tests__snapshots__fuel_indexer_run_help_output.snap +++ b/packages/fuel-indexer-tests/tests/snapshots/integration_tests__snapshots__fuel_indexer_run_help_output.snap @@ -9,7 +9,7 @@ USAGE: OPTIONS: --accept-sql-queries - Allow the web API to accept raw SQL queries. + Allow the web server to accept raw SQL queries. --auth-enabled Require users to authenticate for some operations. @@ -61,7 +61,7 @@ OPTIONS: Indexer config file. --max-body-size - Max body size for web API requests. [default: 5242880] + Max body size for web server requests. [default: 5242880] --metering-points The number of WASM opcodes after which the indexer's event handler will stop execution. diff --git a/packages/fuel-indexer/src/service.rs b/packages/fuel-indexer/src/service.rs index a7a01e49f..78c8646db 100644 --- a/packages/fuel-indexer/src/service.rs +++ b/packages/fuel-indexer/src/service.rs @@ -258,7 +258,7 @@ impl IndexerService { Ok(()) } - /// Kick it off! Run the indexer service loop, listening to service messages primarily coming from the web API. + /// Kick it off! Run the indexer service loop, listening to service messages primarily coming from the web server. pub async fn run(mut self) -> IndexerResult<()> { loop { tokio::select! { From e59c7237f3169cc8c247d98232373b9996c1a3ef Mon Sep 17 00:00:00 2001 From: Rashad Alston Date: Mon, 18 Sep 2023 10:45:15 -0400 Subject: [PATCH 29/33] up to 'storing records' section --- docs/src/designing-a-schema/directives.md | 28 ++------------ docs/src/designing-a-schema/index.md | 37 +++++++++--------- docs/src/designing-a-schema/relationships.md | 22 +++++------ docs/src/indexing-custom-types/index.md | 40 +++++++++++++++----- docs/src/project-components/module.md | 2 +- docs/src/storing-records/index.md | 4 +- 6 files changed, 70 insertions(+), 63 deletions(-) diff --git a/docs/src/designing-a-schema/directives.md b/docs/src/designing-a-schema/directives.md index 97fd353f4..5f65a6dcf 100644 --- a/docs/src/designing-a-schema/directives.md +++ b/docs/src/designing-a-schema/directives.md @@ -4,10 +4,9 @@ As of this writing, the list of supported Fuel GraphQL schema directives includes: -- `@indexed` -- `@unique` -- `@join` -- `@virtual` +- `@indexed`: Denotes that a field should include a B-tree index in the database. +- `@unique`: Denotes that field should include a unique index in the database. +- `@join`: Denotes that a field has a "relationship" to another object type. ## `@indexed` @@ -65,23 +64,4 @@ type Library @entity { } ``` -A foreign key constraint will be created on `library.book` that references `book.name`, which relates the `Book`s in a `Library` to the underlying `Book` table. - -## `@virtual` - -The `@virtual` directive instructs the indexer's SQL schema builder to _not_ build SQL tables from types that include this directive on any field. - -```graphql -type Title @entity { - name: CharField! @virtual -} - -type Book @entity { - id: ID! - title: Title! -} -``` - -When SQL tables are generated for the entities above, a table will be created for `Book`, but no table will be created for `Title`. Rather, the `title` field on the `Book` object will exist on the `book` table as a `JSON` field. - -> Important: When using the `@virtual` directive with GraphQL `union` types, each member of the `union` type must either include _only_ types that are not virtual, or _only_ types that are virtual. We do not support mixing and matching virtual types with non-virtual types in unions. +A foreign key constraint will be created on `library.book` that references `book.name`, which relates the `Book`s in a `Library` to the underlying `Book` table. For more info on what exactly is happening here, please see the [Relationships](./relationships.md) section. \ No newline at end of file diff --git a/docs/src/designing-a-schema/index.md b/docs/src/designing-a-schema/index.md index 9aee8d414..9921ec675 100644 --- a/docs/src/designing-a-schema/index.md +++ b/docs/src/designing-a-schema/index.md @@ -1,6 +1,8 @@ # Designing a Schema -The Fuel indexer uses GraphQL to in order to allow users to query for indexed data. Please note that the Fuel indexer does not support the full GraphQL specification; however, we do our best to reasonably support as much as we can. In this chapter, you can find information on how to leverage our supported features to efficiently get the data you want. +The Fuel indexer uses GraphQL in order to allow users to query for indexed data. In this chapter, you can find information on how to leverage our supported features to efficiently get the data you want. + +> ⚠️ Please note that the Fuel indexer does not support the full GraphQL specification; however, we do our best to reasonably support as much as we can. - [Types](./types.md) - [Scalars](./scalars.md) @@ -11,26 +13,27 @@ The Fuel indexer uses GraphQL to in order to allow users to query for indexed da While we do our best to maintain compliance with the GraphQL specification and parity with other implementations, there are a few things that are under development or will not be implemented. Here's a table describing our GraphQL functionality: -```text -✅ -- implemented -🚧 -- planned or in development -⛔ -- will not implement -``` +Legend: + +- 🟩 : Functionally complete +- 🟨 : Partially complete +- 🟥 : Planned but incomplete +- ⛔ : Not planned | Functionality | Status | Notes | |------|----------|-------| -| Arguments | ✅ | [read the Search and Filtering section](../querying/search-and-filtering.md) | -| Aliases | ✅ | | -| Fragments | ✅ | inline fragments are currently not supported | -| Introspection | ✅ | | -| GraphQL Playground | ✅ | [read the Playground section](../querying/playground.md) | -| Pagination | ✅ | [read the Pagination section](../querying/pagination.md) | -| Directives | 🚧 | [read the Directives section](./directives.md) | -| List Types | 🚧 | | -| Union Types | 🚧 | | -| Federation | 🚧 | | +| Arguments | 🟩 | [read the Search and Filtering section](../querying/search-and-filtering.md) | +| Aliases | 🟩 | | +| Fragments | 🟨 | inline fragments are currently not supported | +| Introspection | 🟩 | | +| GraphQL Playground | 🟩 | [read the Playground section](../querying/playground.md) | +| Pagination | 🟨 | [read the Pagination section](../querying/pagination.md) | +| Directives |🟨 | [read the Directives section](./directives.md) | +| List Types |🟨 | | +| Union Types |🟨 | | +| Federation |⛔ | | | Variables | ⛔ | | | Mutations | ⛔ | | -| Enums | ⛔ | | +| Enums | 🟨 | | | Interfaces | ⛔ | | | Input Types| ⛔ | | diff --git a/docs/src/designing-a-schema/relationships.md b/docs/src/designing-a-schema/relationships.md index dba3efbd3..590defc69 100644 --- a/docs/src/designing-a-schema/relationships.md +++ b/docs/src/designing-a-schema/relationships.md @@ -1,6 +1,6 @@ # Relationships -The Fuel indexer service supports foreign key relationships and constraints using a combination of GraphQL schema and a database. There are two types of foreign keys: _implicit_ and _explicit_. +The Fuel indexer service supports foreign key relationships and constraints. There are two types of relationship specifications: _implicit_ and _explicit_. > IMPORTANT: > @@ -17,31 +17,31 @@ Let's learn how to use each foreign key type by looking at some GraphQL schema e ### Implicit foreign keys ```graphql -type Book @entity { +type Library @entity { id: ID! - name: Bytes8! + name: Charfield! } -type Library @entity { +type Book @entity { id: ID! - book: Book! + library: Library! } ``` -Given the above schema, two entities will be created: a `Book` entity, and a `Library` entity. As you can see, we add the `Book` entity as an attribute on the `Library` entity, thus conveying that we want a one-to-many or one-to-one relationship between `Library` and `Book`. This means that for a given `Library`, we may also fetch one or many `Book` entities. It also means that the column `library.book` will be an integer type that references `book.id`. +Given the above schema, two entities will be created: a `Book` entity, and a `Library` entity. As you can see, we add the `Book` entity as an attribute on the `Library` entity, thus conveying that we want a one-to-many or one-to-one relationship between `Library` and `Book`. This means that for a given `Book`, we may also fetch the associated `Library` entity. It also means that the field `Book.library` will be an `ID` scalar type that references `Library.id`. ### Explicit foreign keys ```graphql -type Book @entity { +type Library @entity { id: ID! - name: Bytes8! @unique + name: Charfield! @unique } -type Library @entity { +type Book @entity { id: ID! - book: Book! @join(on:name) + library: Library! join(on:name) } ``` -For the most part, this works the same way as implicit foreign key usage. However, as you can see, instead of implicitly using `book.id` as the reference column for our `Book` object, we're _explicitly_ specifying that we want `book.name` to serve as our foreign key. Also, please note that since we're using `book.name` in our foreign key constraint, that column is required to be unique (via the `@unique` directive). +For the most part, this works the same way as implicit foreign key usage. However, as you can see, instead of implicitly using `Library.id` as the reference column for our `Library` field type on the `Book` object, we're _explicitly_ specifying that we want `Library.name` to serve as our foreign key for the `Book.library` field. Also, please note that since we're using `Library.name` in our foreign key constraint, that column is required to be unique (via the `@unique` directive). diff --git a/docs/src/indexing-custom-types/index.md b/docs/src/indexing-custom-types/index.md index 2c4045d64..d04cb91b9 100644 --- a/docs/src/indexing-custom-types/index.md +++ b/docs/src/indexing-custom-types/index.md @@ -1,10 +1,20 @@ # Custom Types -In addition to Fuel-specific types, you can also index custom Sway types as well. To index custom types from a Sway smart contract, you'll need that contract's ABI in JSON format; the JSON ABI is generated as a result of running `forc build` to build your contract. After that, the process is similar to [indexing Fuel types](../indexing-fuel-types/index.md). +1. [Contract](#1-contract) +2. [Schema](#2-schema) +3. [Manifest](#3-manifest) +4. [Writing a handler](#4-handler-logic) -Let's go over an example. +> In addition to Fuel-specific types, you can also index custom types triggered in your Sway smart contract. -## Contract +To index custom types from a Sway smart contract, you'll need that specific contract's ABI in JSON format; the JSON ABI is generated as a result of running `forc build` to build your contract. After that, the process is similar to [indexing Fuel types](../indexing-fuel-types/index.md). + + +## Example + +Let's cover some of these concepts in an example below. + +### 1. Contract First, let's create a Sway contract with some simple types. @@ -26,7 +36,7 @@ struct Subtraction { abi ValueStore { #[storage(read, write)] fn add(value: u64); - + #[storage(read, write)] fn subtract(value: u64) -> Subtraction; } @@ -61,7 +71,9 @@ impl ValueStore for Contract { } ``` -In this contract, we have two types: `Addition` and `Subtraction`. As we'll soon see, indexers can process custom types that are logged or returned as part of a function. To begin creating an indexer for this contract, let's build the contract and generate a JSON ABI file. Running `forc build` generates a JSON ABI similar to the lightly-edited one below: +- In this contract, we have two types: `Addition` and `Subtraction`. As we'll soon see, indexers can process custom types that are logged or returned as part of a function. +- To begin creating an indexer for this contract, let's build the contract and generate a JSON ABI file. + - Running `forc build` generates a JSON ABI similar to the lightly-edited one below: ```json { @@ -130,7 +142,9 @@ In this contract, we have two types: `Addition` and `Subtraction`. As we'll soon ``` -## Schema +## 2. Schema + +Now that we've discussed how to generate the JSON ABI for our Sway smart contract, let's now cover how to create an associated GraphQL schema. To index the contracts and store information about our Sway types in the database, we should create a schema. Let's design a schema that has an entity for each Sway type: @@ -148,9 +162,17 @@ type SubtractEntity @entity { } ``` -## Manifest +> Note how the types used here, match the types used in our Sway smart contract. For a detailed mapping of these types, please see the [Storing Records](./../storing-records/index.md) section. + +## 3. Manifest + +So far we've covered how to (1) write your Sway smart contract and generate its JSON ABI, and (2) create types in your GraphQL schema that align with your Sway types. + +Next, we'll cover how to write the manifest file for your indexer. + +Before writing any of the handler code for your indexer, we need to make sure that our indexer manifest contains the necessary information to allow for the compiler to parse our contract types. -Before writing the handler code for the types, we need to make sure that our indexer manifest contains the necessary information to allow for the compiler to parse our contract types. Specifically, we should ensure that the `contract_abi` and `graphql_schema` fields point to the correct locations, respectively. +Specifically, we should ensure that the `contract_abi` and `graphql_schema` fields point to the correct locations, respectively. ```yaml # A namespace is a logical grouping of declared names. Think of the namespace @@ -194,7 +216,7 @@ module: resumable: true ``` -## Handler Logic +## 4. Handler Logic Finally, we can create handlers to index these particular types and store them in the database. Let's look at the following example: diff --git a/docs/src/project-components/module.md b/docs/src/project-components/module.md index 75214663e..9f8fb6ee7 100644 --- a/docs/src/project-components/module.md +++ b/docs/src/project-components/module.md @@ -14,7 +14,7 @@ use fuel_indexer_utils::prelude::*; #[indexer(manifest = "indexer.manifest.yaml")] mod indexer_mod { - // This `log_the_greeting` function will be called, when we find + // This `log_the_greeting` function will be called, when we find // a `Greeting` in a block. fn log_the_greeting(greeting: Greeting) { info!("The greeting is: {greeting:?}"); diff --git a/docs/src/storing-records/index.md b/docs/src/storing-records/index.md index b4a2c5ab2..2ac4384fe 100644 --- a/docs/src/storing-records/index.md +++ b/docs/src/storing-records/index.md @@ -1,6 +1,8 @@ # Storing Info in a Database -The Fuel indexer uses [PostgreSQL](https://github.com/docker-library/postgres/blob/2f6878ca854713264ebb27c1ba8530c884bcbca5/14/bullseye/Dockerfile) as the primary database. We're open to supporting other storage solutions in the future. +The Fuel indexer uses [PostgreSQL](https://github.com/docker-library/postgres/blob/2f6878ca854713264ebb27c1ba8530c884bcbca5/14/bullseye/Dockerfile) as the primary database. + +> 💡 We're open to supporting other storage solutions in the future. ## Data Types From e1151a2e241131dd93cfc95a6e653a531898beca Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 18 Sep 2023 11:58:02 -0400 Subject: [PATCH 30/33] Flesh out comparison page --- docs/src/getting-started/how-it-compares.md | 29 +++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/docs/src/getting-started/how-it-compares.md b/docs/src/getting-started/how-it-compares.md index 431be13c8..fb392f6ca 100644 --- a/docs/src/getting-started/how-it-compares.md +++ b/docs/src/getting-started/how-it-compares.md @@ -1,4 +1,9 @@ -# How it compares +# How it Compares + +Since many users may be familiar with indexing by using a solution like The Graph, it may be helpful to provide a comparison between it and the Fuel indexer. Generally, the biggest conceptual differences between the two are as follows: + +- The Fuel indexer does not support publishing indexers to decentralized networks. That being said, the Fuel indexer is developed with the intention of allowing anyone to run an instance and host whatever indexers they want. +- Contracts on the Fuel network can be indexed without the need to add additional events. Whether a user wanted to index information from the very start of a contract or a recent block, the process is the same: define the schema and manifest, write custom handler logic, and deploy to an indexer service. Legend: @@ -11,7 +16,27 @@ Legend: | Feature | The Graph | Fuel Indexer | Notes | |:-:|:-:|:-:|:-:| -| Decentralized Hosting | 🟩 | ⛔ | | | Hosted Indexers | 🟩 | 🟩 | | | WASM Execution | 🟩 | 🟩 | | | Native Execution | 🟥 | 🟩 | | +| Handlers | 🟩 | 🟩 | see [Indexing Fuel Types](../indexing-fuel-types/index.md) and [Indexing Custom Types](../indexing-custom-types/index.md)| +| Updateable Schemas | 🟩 | 🟩 | | +| API Authentication | 🟩 | 🟩 | | +| Starting Block Configuration | 🟩 | 🟩 | | +| Grafted Indexes | 🟩 | 🟥 | | +| Index Ownership Transfer | 🟩 | 🟥 | | +| Unit Testing Framework | 🟩 | 🟥 | Users are able to use `cargo test` | +| Querying: Sorting | 🟩 | 🟩 | | +| Querying: Pagination | 🟩 | 🟩 | | +| Querying: Filtering | 🟩 | 🟩 | | +| Querying: Time Travel | 🟩 | 🟥 | | +| Querying: Fulltext Search | 🟩 | 🟥 | | +| Querying: GraphQL Validation Spec | 🟩 | 🟨 | | +| Schema: Enums | 🟩 | 🟩 | | +| Schema: One-to-one relationships | 🟩 | 🟩 | | +| Schema: One-to-many relationships| 🟩 | 🟩 | | +| Schema: Many-to-many relationships | 🟩 | 🟩 | | +| Schema: Reverse Lookup | 🟩 | 🟥 | | +| AssemblyScript Support | 🟩 | ⛔ | | +| Admin Portal UI | 🟩 | ⛔ | | +| Decentralized Hosting | 🟩 | ⛔ | | From f9d20f85f97a24d358c6eb15bfc119de420cd7b1 Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 18 Sep 2023 12:02:31 -0400 Subject: [PATCH 31/33] Fix doc tests failures --- docs/src/designing-a-schema/directives.md | 2 +- docs/src/getting-started/dependencies.md | 6 +++--- .../getting-started/indexer-service-infrastructure.md | 11 +++++------ docs/src/indexing-custom-types/index.md | 1 - docs/src/project-components/index.md | 1 + docs/src/project-components/module.md | 4 ++-- 6 files changed, 12 insertions(+), 13 deletions(-) diff --git a/docs/src/designing-a-schema/directives.md b/docs/src/designing-a-schema/directives.md index 5f65a6dcf..b429006aa 100644 --- a/docs/src/designing-a-schema/directives.md +++ b/docs/src/designing-a-schema/directives.md @@ -64,4 +64,4 @@ type Library @entity { } ``` -A foreign key constraint will be created on `library.book` that references `book.name`, which relates the `Book`s in a `Library` to the underlying `Book` table. For more info on what exactly is happening here, please see the [Relationships](./relationships.md) section. \ No newline at end of file +A foreign key constraint will be created on `library.book` that references `book.name`, which relates the `Book`s in a `Library` to the underlying `Book` table. For more info on what exactly is happening here, please see the [Relationships](./relationships.md) section. diff --git a/docs/src/getting-started/dependencies.md b/docs/src/getting-started/dependencies.md index 24b61742f..a8f43baaf 100644 --- a/docs/src/getting-started/dependencies.md +++ b/docs/src/getting-started/dependencies.md @@ -1,6 +1,6 @@ # Dependencies -> This guide covers some of the basics with regard to installing dependencies for the Fuel indexer service. However, note that this guide is meant to be a general overview for most platforms and by no means covers all platforms. +> This guide covers some of the basics with regard to installing dependencies for the Fuel indexer service. However, note that this guide is meant to be a general overview for most platforms and by no means covers all platforms. > > If you're having trouble with dependencies on your system, we recommend that you use `docker`. @@ -13,12 +13,12 @@ To run the Fuel indexer, you'll need to install a few dependencies on your syste 5. [`wasm-snip`](#web-assembly-wasm), a utility for stripping symbols from WebAssemly binaries. > If you don't want to install a database directly onto your system, you can use Docker to run a database in an isolated container. You can install Docker by following its [installation instructions](https://docs.docker.com/get-docker/). -> +> > For reference purposes, we provide a [`docker compose` file](https://github.com/FuelLabs/fuel-indexer/blob/develop/scripts/docker-compose.yaml) that comes with a PostgresSQL server and a Fuel indexer service. ## `fuelup` -We strongly recommend that you use the Fuel indexer that's made available via [`forc`, the Fuel orchestrator](https://fuellabs.github.io/sway/master/book/forc/index.html). You can get `forc` (and other Fuel components) by way of [`fuelup`, the Fuel toolchain manager](https://fuellabs.github.io/fuelup/latest). +We strongly recommend that you use the Fuel indexer that's made available via [`forc`, the Fuel orchestrator](https://fuellabs.github.io/sway/master/book/forc/index.html). You can get `forc` (and other Fuel components) by way of [`fuelup`, the Fuel toolchain manager](https://fuellabs.github.io/fuelup/latest). Install `fuelup` by running the following command, which downloads and runs the installation script. diff --git a/docs/src/getting-started/indexer-service-infrastructure.md b/docs/src/getting-started/indexer-service-infrastructure.md index 60831c723..7e5bfe4bd 100644 --- a/docs/src/getting-started/indexer-service-infrastructure.md +++ b/docs/src/getting-started/indexer-service-infrastructure.md @@ -2,11 +2,11 @@ - [Service Components](#components) - [Fuel Indexer Service](#fuel-indexer-service) - - [Starting the service via CLI options](#using-cli-options-indexer-service) - - [Starting the service via a config file](#using-a-configuration-file-indexer-service) + - [Starting the service via CLI options](#using-cli-options-indexer-service) + - [Starting the service via a config file](#using-a-configuration-file-indexer-service) - [Fuel Indexer Web Server](#web-api-server) - - [Starting the service via CLI options](#using-cli-options-web-server) - - [Starting the service via a config file](#using-a-configuration-file-web-server) + - [Starting the service via CLI options](#using-cli-options-web-server) + - [Starting the service via a config file](#using-a-configuration-file-web-server) A Fuel indexer service instance requires just three components: @@ -163,7 +163,7 @@ OPTIONS: {{#include ../../../config.yaml}} ``` ----- +--- ## Web API Server @@ -278,4 +278,3 @@ fuel-indexer-api-server run --config config.yaml ``` In the above example, `config.yaml` is based on [the default service configuration file](https://github.com/FuelLabs/fuel-indexer/blob/develop/config.yaml). - diff --git a/docs/src/indexing-custom-types/index.md b/docs/src/indexing-custom-types/index.md index d04cb91b9..a93456d85 100644 --- a/docs/src/indexing-custom-types/index.md +++ b/docs/src/indexing-custom-types/index.md @@ -9,7 +9,6 @@ To index custom types from a Sway smart contract, you'll need that specific contract's ABI in JSON format; the JSON ABI is generated as a result of running `forc build` to build your contract. After that, the process is similar to [indexing Fuel types](../indexing-fuel-types/index.md). - ## Example Let's cover some of these concepts in an example below. diff --git a/docs/src/project-components/index.md b/docs/src/project-components/index.md index a763512ef..2f3f8c057 100644 --- a/docs/src/project-components/index.md +++ b/docs/src/project-components/index.md @@ -1,3 +1,4 @@ + # A Fuel Indexer Project ## Use Cases diff --git a/docs/src/project-components/module.md b/docs/src/project-components/module.md index 9f8fb6ee7..8c94a5b56 100644 --- a/docs/src/project-components/module.md +++ b/docs/src/project-components/module.md @@ -25,10 +25,10 @@ mod indexer_mod { ## What's going on here? - The first line imports the [prelude](https://docs.rs/fuel-indexer-utils/latest/fuel_indexer_utils/prelude/index.html) from `fuel_indexer_utils`; this allows you to quickly bootstrap an indexer by using common types and traits. Then, we have a module decorated with the `#[indexer]` macro. - - This macro processes a manifest at the supplied file path, parses your schema and Sway contract ABI (if supplied), and generates code that is combined with handler functions in order to create a complete indexer module. + - This macro processes a manifest at the supplied file path, parses your schema and Sway contract ABI (if supplied), and generates code that is combined with handler functions in order to create a complete indexer module. - Finally, we have an example handler function. You can define which functions handle different events by using the function parameters. If you add a function parameter of a certain type `T`, the function will be triggered whenever that type is found as part of a block, transaction, or receipt. - - In this example, let's say that you have a Sway contract with a function that logs a `Greeting` struct. When that function executes as part of a transaction, the logged struct will be included in the data that is processed from the Fuel blockchain. Your indexer module will see the struct and execute `log_the_greeting`. + - In this example, let's say that you have a Sway contract with a function that logs a `Greeting` struct. When that function executes as part of a transaction, the logged struct will be included in the data that is processed from the Fuel blockchain. Your indexer module will see the struct and execute `log_the_greeting`. > You can learn more about what data can be indexed and find example handlers in the [Indexing Fuel Types](../indexing-fuel-types/index.md) and [Indexing Custom Types](../indexing-custom-types/index.md) sections. From ca93c3da3b6f8bb9f5c61168a38041dddcd0832d Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 18 Sep 2023 14:32:44 -0400 Subject: [PATCH 32/33] Update docs/src/getting-started/dependencies.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Maciej Woś --- docs/src/getting-started/dependencies.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/getting-started/dependencies.md b/docs/src/getting-started/dependencies.md index a8f43baaf..442de775f 100644 --- a/docs/src/getting-started/dependencies.md +++ b/docs/src/getting-started/dependencies.md @@ -46,7 +46,7 @@ Once installed, you can add PostgreSQL to your system by running `brew install p ## Web Assembly (WASM) -Two additonal cargo components will be required to build your indexers: `wasm-snip` and the `wasm32-unknown-unknown` target. +Two additional cargo components will be required to build your indexers: `wasm-snip` and the `wasm32-unknown-unknown` target. > As of this writing, there is a small bug in newly built Fuel indexer WASM modules that produces a WASM runtime error due an errant upstream dependency. For now, you can use `wasm-snip` to remove the errant symbols from the WASM module, and prevent this issue from happening. An example can be found in the related script [here](https://github.com/FuelLabs/fuel-indexer/blob/develop/scripts/stripper.bash). > From eddfab6093ad674d0c5d7f0c1ca65d0be16f026b Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 18 Sep 2023 14:32:54 -0400 Subject: [PATCH 33/33] Update docs/src/getting-started/indexer-service-infrastructure.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Maciej Woś --- docs/src/getting-started/indexer-service-infrastructure.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/getting-started/indexer-service-infrastructure.md b/docs/src/getting-started/indexer-service-infrastructure.md index 7e5bfe4bd..13a5eda7d 100644 --- a/docs/src/getting-started/indexer-service-infrastructure.md +++ b/docs/src/getting-started/indexer-service-infrastructure.md @@ -167,7 +167,7 @@ OPTIONS: ## Web API Server -The `fuel-indexer-api-server` crate of the Fuel indexer contains a standalone web server server that acts as a queryable endpoint on top of the database. Note that the main `fuel-indexer` binary of the indexer project also contains the same web server endpoint. +The `fuel-indexer-api-server` crate of the Fuel indexer contains a standalone web server that acts as a queryable endpoint on top of the database. Note that the main `fuel-indexer` binary of the indexer project also contains the same web server endpoint. > The `fuel-indexer-api-server` crate offers a _standalone_ web server endpoint, whereas the API endpoint offered in `fuel-indexer` is bundled with other Fuel indexer functionality (e.g., execution, handling, data-layer construction, etc). Offering the API server as a separate piece allows users to separate components and run them on different systems, if desired.