Skip to content
This repository has been archived by the owner on Oct 25, 2024. It is now read-only.

enhancement: generate GraphQL schema from JSON ABI #1396

Closed
wants to merge 16 commits into from
Closed
14 changes: 8 additions & 6 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- [Scalars](./designing-a-schema/scalars.md)
- [Directives](./designing-a-schema/directives.md)
- [Relationships](./designing-a-schema/relationships.md)
- [Generating a Schema](./generating-a-schema/index.md)
Copy link
Contributor

Choose a reason for hiding this comment

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

This should go int the Designing a schema section maybe under a section called Automatic Schema Generation (or something that makes it clear what this section is about).

- [Indexing Fuel Types](./indexing-fuel-types/index.md)
- [Blocks](./indexing-fuel-types/blocks.md)
- [Transactions](./indexing-fuel-types/transactions.md)
Expand Down
155 changes: 155 additions & 0 deletions docs/src/generating-a-schema/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# Automatically generating GraphQL schema from JSON ABI

`forc index new` supports automatically generating GraphQL schema from a contract JSON ABI.
Copy link
Contributor

Choose a reason for hiding this comment

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

  • I think this has to be re-written.
  • @lostman We spent weeks on the docs, combing through every single line making sure they read properly and that all examples are informative and work
    • It sucked, it wasn't fun, but the docs are so much better now
    • Let's keep this trend going with the docs in this PR.
    • Ideally the docs should:
      1. Show me the tiniest Sway smart contract with various simple types (struct, enum, etc)
      2. Show me how to use forc index new --json-abi
      3. Show me the resultant schema that gets produced from that command ☝🏼
    • I think we have an example of this in the docs already here (again, I want to be very clear that I realize this is a PITA 😅 )


Sway `struct`s are translated into GrapQL `type`s, and the following `struct` field types are supported:

| Sway Type | GraphQL Type |
|-----------|--------------|
| u128 | U128 |
| u64 | U64 |
| u32 | U32 |
| u8 | U8 |
| i128 | I128 |
| i64 | I64 |
| i32 | I32 |
| i8 | I8 |
| bool | Boolean |
| u8[64] | Bytes64 |
| u8[32] | Bytes32 |
| u8[8] | Bytes8 |
| u8[4] | Bytes4 |
| Vec<u8>| Bytes |
| SizedAsciiString<64> | ID |
| String | String |
| str[32] | Bytes32 |
| str[64] | Bytes64 |

Sway `enum` types can also be translated. However, all enum variants must have `()` type. For example:

```rust
pub enum SimpleEnum {
One: (),
Two: (),
Three: (),
}
```

Will be translated to GraphQL as:

```GraphQL
enum SimpleEnum {
One
Two
Three
}
```

## Example

Using the `DAO-contract-abi.json`, which can be found in the `fuel-indexer` repository:

```bash
forc index new --json-abi ./packages/fuel-indexer-tests/trybuild/abi/DAO-contract-abi.json dao-indexer
```

We get the following schema:

```GraphQL
enum CreationError {
DurationCannotBeZero
InvalidAcceptancePercentage
}

enum InitializationError {
CannotReinitialize
ContractNotInitialized
}

enum ProposalError {
InsufficientApprovals
ProposalExecuted
ProposalExpired
ProposalStillActive
}

enum UserError {
AmountCannotBeZero
IncorrectAssetSent
InsufficientBalance
InvalidId
VoteAmountCannotBeZero
}

type CallDataEntity @entity {
id: ID!
arguments: U64!
function_selector: U64!
}

type CreateProposalEventEntity @entity {
id: ID!
proposal_info: ProposalInfoEntity!
}

type DepositEventEntity @entity {
id: ID!
amount: U64!
user: Identity!
}

type ExecuteEventEntity @entity {
id: ID!
acceptance_percentage: U64!
user: Identity!
}

type InitializeEventEntity @entity {
id: ID!
author: Identity!
token: ContractId!
}

type ProposalEntity @entity {
id: ID!
amount: U64!
asset: ContractId!
call_data: CallDataEntity!
gas: U64!
}

type ProposalInfoEntity @entity {
id: ID!
acceptance_percentage: U64!
author: Identity!
deadline: U64!
executed: Boolean!
no_votes: U64!
proposal_transaction: ProposalEntity!
yes_votes: U64!
}

type UnlockVotesEventEntity @entity {
id: ID!
user: Identity!
vote_amount: U64!
}

type VoteEventEntity @entity {
id: ID!
user: Identity!
vote_amount: U64!
}

type VotesEntity @entity {
id: ID!
no_votes: U64!
yes_votes: U64!
}

type WithdrawEventEntity @entity {
id: ID!
amount: U64!
user: Identity!
}
```
2 changes: 2 additions & 0 deletions packages/fuel-indexer-lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ async-graphql-parser = { workspace = true }
async-graphql-value = { workspace = true }
bincode = { workspace = true }
clap = { features = ["cargo", "derive", "env"], workspace = true }
fuel-abi-types = "0.3"
fuel-indexer-types = { workspace = true }
fuels-code-gen = { version = "0.46", default-features = false }
http = { version = "0.2", default-features = false }
lazy_static = { version = "1.4" }
proc-macro2 = "1.0"
Expand Down
23 changes: 22 additions & 1 deletion packages/fuel-indexer-lib/src/graphql/constants.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use lazy_static::lazy_static;
use std::collections::HashSet;
use std::collections::{HashMap, HashSet};

lazy_static! {

Expand Down Expand Up @@ -61,4 +61,25 @@ lazy_static! {
"Option<Identity>",
"Option<Json>",
]);

pub static ref ABI_TYPE_MAP: HashMap<&'static str, &'static str> = HashMap::from_iter([
lostman marked this conversation as resolved.
Show resolved Hide resolved
("u128", "U128"),
("u64", "U64"),
("u32", "U32"),
("u8", "U8"),
("i128", "I128"),
("i64", "I64"),
("i32", "I32"),
("i8", "I8"),
("bool", "Boolean"),
("u8[64]", "Bytes64"),
("u8[32]", "Bytes32"),
("u8[8]", "Bytes8"),
("u8[4]", "Bytes4"),
("Vec<u8>", "Bytes"),
("SizedAsciiString<64>", "ID"),
("String", "String"),
("str[32]", "Bytes32"),
("str[64]", "Bytes64"),
]);
}
1 change: 1 addition & 0 deletions packages/fuel-indexer-lib/src/graphql/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod constants;
pub mod parser;
pub mod schema_gen;
pub mod types;
pub mod validator;

Expand Down
Loading
Loading