Skip to content

The subgraph for the defi protocols that are integrated with opty.fi 's earn protocol.

License

Notifications You must be signed in to change notification settings

Opty-Fi/megagraph

Repository files navigation

Megagraph

The subgraph for the DeFi protocols that are integrated with OptyFi's earn-protocol.

Subgraph

Ethereum

Polygon

Development

Prerequisites:

  • Node JS 12.x.x and above
  • Install the prerequisite modules:
    yarn
  • Setup your environment variables:
    cp .env.example .env
    and populate accordingly.

Naming conventions:

  • ./config/ directory:

    • all$CONFIG.json files:
      • format:
        {
          "network": "$CONFIG",
          "adapters": [
            {
              "adapter": "AdapterName",
              "contracts": [
                {
                  "contract": "ContractName",
                  "abis": ["AbiName", "SupportingAbiName"],
                  "entities": ["<Adapter>EntityName"],
                  "events": [
                    {
                      "event-name": "EventName",
                      "event-params": "(list, of, params, from, event, sig)"
                    }
                  ],
                  "instances": [
                    {
                      "symbol": "SYMBOL", // if multiple
                      "address": "0xAddressValue",
                      "startBlock": 12345
                    }
                  ]
                }
              ]
            }
          ]
        }
  • ./schema.graphql file:

    type <Adapter><EntityName> @entity {
      id: ID!
      fieldName: DataType
    }
  • ./src/<Adapter>/ directory:

    • abis/ directory:

      • all <AbiName>.json files from ./config/$CONFIG.json file's adapters[i].contracts[j].abis
    • mappings/ directory:

      • all <ContractName>.ts files from ./config/$CONFIG.json file's adapters[i].contracts[j].contract

      • for each <ContractName>.ts file, at minimum the generated:

        • WebAssembly typescript reference:

          import {
            <Adapter><ContractName>
          } from "../../../generated/<Adapter><ContractName><SymbolDAI>/<Adapter><ContractName>";
        • event handlers:

          import {
            <EventName> as <EventName>Event,
            ...
          } from "../../../generated/<Adapter><ContractName><symbol>/<Adapter><ContractName>";
          
          export function handle<EventName>(event: <EventName>Event): void {
            ...
          }
          export function handle...
        • graphql entities:

          import {
            <Adapter><EntityName>
          } from "../../../generated/schema";
      • repeat for the next <ContractName>.ts file

  • The above will leverage the ./package.json "yarn mustache-yaml" script to populate a ./subgraph.yaml file for use with the yarn codegen script.

Local development:

  1. Install ganache-cli
  2. Clone a graph node locally
  3. In your local graph-node:
    • Adjust the ./docker/docker-compose.yaml file:
      services:
        graph-node:
          environment:
            ethereum:
      
      from 'mainnet:http...' to 'builderevm:http...' and save
  4. Spin up a ganache instance on the side:
    ganache-cli -d -h 0.0.0.0 --networkId 31337
  5. In your local graph-node:
    • In the docker directory:
      cd ./docker
    • Initialize the docker container:
      docker-compose up
  6. In the megagraph root directory, run:
    yarn setup:dev

Deploying to The Graph:

  1. Create an account and login, and ensure that your Access token is populated in your .env file
  2. In your local megagraph directory, run:
    yarn setup

Detailed Instructions

Generate manifest from mustache template:

  • Run the following command:
    yarn mustache-yaml
    If the execution is successful, you should see a new ./subgraph.yaml file created from the ./subgraph.template.yaml file, based on the ./config/$CONFIG.json file as per the Naming conventions above.

Generating subgraph code:

  • Run the following command:
    yarn codegen
    If the generation was successful, you should see a new ./generated/ folder.

Running a build:

  • Run the build command:
    graph build
    If the build is successful, you should see a new ./build/ folder.
  • Note: this step is performed automatically when running the yarn deploy script, or when manually executing the graph deploy command.

Deploying the subgraph:

  • To deploy, we can run the deploy command using the Graph CLI. To deploy, you will first need to copy the Access token for the subgraph you created in the Graph console.

  • Next, run the following commands:

    graph auth https://api.thegraph.com/deploy/ <ACCESS_TOKEN>
    
    yarn deploy

    Once the subgraph is deployed, you should see it show up in your dashboard.

    When you click on the subgraph, it should open the Graph explorer.

Example querying:

In the dashboard, we should be able to start querying for data. Run the following query to get a list of tokens and their metadata:

{
  tokens {
    id
    tokenID
    contentURI
    metadataURI
  }
}

We can also configure the order direction:

{
  tokens(orderBy: id, orderDirection: desc) {
    id
    tokenID
    contentURI
    metadataURI
  }
}

Or choose to skip forward a certain number of results to implement some basic pagination:

{
  tokens(skip: 100, orderBy: id, orderDirection: desc) {
    id
    tokenID
    contentURI
    metadataURI
  }
}

Or query for users and their associated content:

{
  users {
    id
    tokens {
      id
      contentURI
    }
  }
}

Updating the subgraph:

For example adding the capabilities to sort by the timestamp that an NFT was created.

  • Add a new createdAtTimestamp field to the Token entity:

    type Token @entity {
      id: ID!
      tokenID: BigInt!
      contentURI: String!
      metadataURI: String!
      creator: User!
      owner: User!
      createdAtTimestamp: BigInt! # added new field
    }
  • Re-run the yarn codegen script.

  • Update the mapping to save this new field:

    // update the handleTransfer function to add the createdAtTimestamp to the token object
    export function handleTransfer(event: TransferEvent): void {
      let token = Token.load(event.params.tokenId.toString());
      if (!token) {
        token = new Token(event.params.tokenId.toString());
        token.creator = event.params.to.toHex();
        token.tokenID = event.params.tokenId;
    
        // Add the createdAtTimestamp to the token object
        token.createdAtTimestamp = event.block.timestamp;
    
        let tokenContract = TokenContract.bind(event.address);
        token.contentURI = tokenContract.tokenURI(event.params.tokenId);
        token.metadataURI = tokenContract.tokenMetadataURI(event.params.tokenId);
      }
      token.owner = event.params.to.toHex();
      token.save();
    
      let user = User.load(event.params.to.toHex());
      if (!user) {
        user = new User(event.params.to.toHex());
        user.save();
      }
    }
  • Re-deploy the subgraph:

    yarn deploy

After redeployment, a query can be made by timestamp to view the most recently created NFTs:

{
  tokens(orderBy: createdAtTimestamp, orderDirection: desc) {
    id
    tokenID
    contentURI
    metadataURI
  }
}