Skip to content

Generate Solana Indexers from IDL

The Aleph Indexer Generator simplifies the process of creating indexers for Solana programs, by using Anchor's IDLs. It generates the necessary boilerplate code for launching your own Solana indexer on our open-source, multi-threaded node.js framework, using moleculer.

Getting started

1. Clone the repository

git clone https://github.com/aleph-im/solana-indexer-library.git

2. Navigate to the project's root directory

cd solana-indexer-library

3. Install the necessary dependencies and build the project:

npm install && npm run build

4. Generate your indexer from a local or remote Anchor IDL:

Using local IDL file

  1. Move a copy of the idl of your program to the path:
    solana-indexer-library/src/idl/<idl-name>.json
    
  2. Run the generate command, passing the IDL name as an argument:
    npm run generate <idl-name>
    
  3. Optionally, include your program's address as a second argument:
    npm run generate <idl-name> <program-address>
    

Remote IDL

  1. Ensure Anchor is installed locally and that the program you want to index has an initialized IDL account. A simple way to check for this is to run the following command:
    anchor idl fetch <program-address>
    
    This way you can also retrieve the IDL file from the program's address:
    anchor idl fetch -o <out-file.json> <program-address>
    
  2. If it is your own program, you can use the following command to initialize the IDL account:
    anchor idl init -f <target/idl/program-name.json> <program-address>
    
  3. Run the generate command of the indexer generator, providing your program's address:
    npm run generate <program-address>
    

Run the indexer

  1. Navigate to the generate package directory
    cd packages/<idl-name>
    
  2. Install dependencies and build the package
    npm i && npm run build
    
  3. Add your RPC on SOLANA_RPC env
  4. Grant execution permission to the script and run it
    chmod +x run.sh
    ./run.sh
    

If you wait for a moment you will see a message warning you that it is now running a GraphQL server on http://localhost:8080.

Deploying your Indexer to Aleph.im

To deploy your indexer, read this documentation

Supported Queries

Total program accounts and instruction invocations

Return global stats about the amount of accounts and total amount of instructions processed by the indexer:

{
    globalStats {
        totalAccounts {
            State
            TicketAccountData
        }
        totalAccesses
        totalAccessesByProgramId
    }
}

Accounts

Get all accounts, their addresses, Anchor type and contents:

{
  accounts {
    address
    type
    data {
      ...on State {
        msolMint
        adminAuthority
        liqPool {
          lpLiquidityTarget
          lpMaxFee {
            basisPoints
          }
          lpMinFee {
            basisPoints
          }
          treasuryCut {
            basisPoints
          }
        }
        # and other fields, see generated GraphQL schema
      }
      ... on TicketAccountData {
        beneficiary
        stateAddress
        lamportsAmount
        # and other fields, see generated GraphQL schema
      }
    }
  }
}

Indexing state

Get the current progress of the indexer. Accurate means that the indexer fetched all transaction signatures belonging to that account, progress tells you how much percent of all transactions have been fetched and processed.

{
  accountState(account: "8szGkuLTAux9XMgZ2vtY39jVSowEcpBfFfD8hXSEqdGC", blockchain: "solana", type: transaction) {
    accurate
    progress
    pending
    processed
  }
}

General account stats

Get accesses in the last hour, day, week or in total:

{
  accountStats(account: "7ekbc8F72Zm4KKQwbgSe7UTaiprHb8nkmbA2ti5hKoCX", blockchain: "solana") {
    stats {
      last1h {
        accesses
      }
      last24h {
        accesses
      }
      last7d {
        accesses
      }
      total {
        accesses
      }
    }
  }
}

Account time series stats

Get aggregated accesses by signing wallet and month:

{
  accountTimeSeriesStats(timeFrame:Month, account: "7ekbc8F72Zm4KKQwbgSe7UTaiprHb8nkmbA2ti5hKoCX", type: "access", blockchain: "solana") {
    series {
      date
      value {
        ...on AccessTimeStats {
          accessesByProgramId
        }
      }
    }
  }
}

Processed instructions (Events)

Get the latest 1000 processed instructions:

{
  events(account: "7ekbc8F72Zm4KKQwbgSe7UTaiprHb8nkmbA2ti5hKoCX", types: OrderUnstake, limit: 10) {
    id
    timestamp
    type
    signer
    ...on OrderUnstakeEvent {
      info {
        state
        msolAmount
        burnMsolFrom
        burnMsolAuthority
        newTicketAccount
      }
    }
  }
}