Docs
Search⌘ K
  • Home
  • About The Graph
  • Supported Networks
  • Protocol Contracts
  • Subgraphs
    • Substreams
      • Token API
        • AI Suite
          • Indexing
            • Resources
              Indexing

              5 minutes

              GraphTally Guide

              Learn about The Graph’s new payment system, GraphTally (previously Timeline Aggregation Protocol)⁠. This system provides fast, efficient microtransactions with minimized trust.

              Overview

              GraphTally is a drop-in replacement to the Scalar payment system currently in place. It provides the following key features:

              • Efficiently handles micropayments.
              • Adds a layer of consolidations to onchain transactions and costs.
              • Allows Indexers control of receipts and payments, guaranteeing payment for queries.
              • Enables decentralized, trustless gateways and improves indexer service performance for multiple senders.

              How It Works

              GraphTally allows a sender to make multiple payments to a receiver through Receipts, which are then aggregated into a single payment called a Receipt Aggregate Voucher (RAV). This aggregated payment can be verified on the blockchain, reducing the number of transactions and simplifying the payment process.

              For each query, the gateway sends a signed receipt that is stored in your database. The indexer-tap-agent aggregates these receipts into RAVs through periodic requests. You can update a RAV by sending it with newer receipts, which generates a new RAV with an increased value.

              RAV Details

              • RAVs represent money waiting to be sent to the blockchain.
              • The system continuously aggregates receipts to ensure that the total value of non-aggregated receipts does not exceed the configured max_amount_willing_to_lose_grt.
              • Each RAV can be redeemed once in the contracts, which is why they are sent after the allocation is closed.

              Redeeming RAVs

              The redemption process is fully automated when running both indexer-tap-agent and indexer-agent:

              1. An Indexer closes an allocation.
              2. After the recently-closed-allocation-buffer period, indexer-tap-agent takes all pending receipts for that allocation and requests aggregation into a final RAV, marking it as last.
              3. indexer-agent takes all the last RAVs and sends redeem requests to the blockchain, updating the redeem_at value.
              4. During the finality-time period, indexer-agent monitors for blockchain reorganizations:
                • If the transaction was reverted, the RAV is resent to the blockchain.
                • If not reverted, it gets marked as final.

              Blockchain Addresses

              Contracts

              ContractArbitrum Mainnet (42161)Arbitrum Sepolia (421614)
              TAP Verifier0x33f9E93266ce0E108fc85DdE2f71dab555A0F05a0xfC24cE7a4428A6B89B52645243662A02BA734ECF
              AllocationIDTracker0x5B2F33d7Ca6Ec88f5586f2528f58c20843D9FE7c0xAaC28a10d707bbc6e02029f1bfDAEB5084b2aD11
              Escrow0x8f477709eF277d4A880801D01A140a9CF88bA0d30x1e4dC4f9F95E102635D8F7ED71c5CdbFa20e2d02

              Gateway

              ComponentEdge and Node Mainnet (Arbitrum Mainnet)Edge and Node Testnet (Arbitrum Sepolia)
              Sender0xDDE4cfFd3D9052A9cb618fC05a1Cd02be1f2F4670xC3dDf37906724732FfD748057FEBe23379b0710D
              Signers0xfF4B7A5EfD00Ff2EC3518D4F250A27e4c29A22110xFb142dE83E261e43a81e9ACEADd1c66A0DB121FE
              Aggregatorhttps://tap-aggregator.network.thegraph.comhttps://tap-aggregator.testnet.thegraph.com

              Prerequisites

              In addition to typical indexer requirements, you’ll need a tap-escrow-subgraph endpoint to query escrow information. You can use The Graph Network to query or self-host on your graph-node:

              • Graph TAP Arbitrum Sepolia Subgraph (for The Graph testnet)
              • Graph TAP Arbitrum One Subgraph (for The Graph mainnet)

              Note: indexer-agent does not currently handle the indexing of this Subgraph like it does for the Network Subgraph deployment. You must index it manually.

              Migration Guide

              Software Requirements

              Required Versions

              • indexer-agent: Latest version supporting TAP⁠
              • indexer-service-rs: Latest release⁠
              • indexer-tap-agent: Latest release⁠

              Docker Images

              1# Indexer Service2docker pull ghcr.io/graphprotocol/indexer-service-rs:latest34# TAP Agent5docker pull ghcr.io/graphprotocol/indexer-tap-agent:latest

              Migration Steps

              1. Update Indexer Agent

              • Continue using your existing indexer-agent
              • Add the --tap-subgraph-endpoint argument to enable TAP functionality and RAV redemption
              • Example: --tap-subgraph-endpoint https://api.thegraph.com/subgraphs/name/graphprotocol/tap-mainnet

              2. Replace Indexer Service

              • Fully replace your TypeScript indexer-service with indexer-service-rs
              • The new service is stateless and can be scaled horizontally
              • Use the same database as your existing setup

              3. Deploy TAP Agent

              • Run exactly one instance of indexer-tap-agent
              • This component manages receipt aggregation and RAV creation
              • It must have access to the same database as other indexer components

              4. Configuration

              Both indexer-service-rs and indexer-tap-agent share a TOML configuration file. Create a configuration file and pass it with --config /path/to/config.toml.

              Minimal Configuration Example
              1# Essential configuration for indexer-rs components2# All values below must be updated to match your setup34[indexer]5indexer_address = "0x1111111111111111111111111111111111111111"6operator_mnemonic = "your twelve word mnemonic phrase here ..."78[database]9# Use the same database as your indexer-agent10postgres_url = "postgresql://user:password@localhost:5432/indexer_db"1112[graph_node]13# Your graph-node endpoints14query_url = "http://graph-node:8000"15status_url = "http://graph-node:8000/graphql"1617[subgraphs.network]18# The Graph Network Subgraph (use query_url OR deployment_id, not both)19query_url = "https://api.thegraph.com/subgraphs/name/graphprotocol/graph-network-arbitrum"20# deployment_id = "QmUVskWrz1ZiQZ76AtyhcfFDEH1ELnRpoyEhVL8p6NFTbR"2122[subgraphs.escrow]23# TAP Escrow Subgraph (use query_url OR deployment_id, not both)24query_url = "https://api.thegraph.com/subgraphs/name/graphprotocol/tap-arbitrum-one"25# deployment_id = "QmPcbDomKwfsmVBNbvncU8gdWTvUiH9zVFYxDMc5ohpjvU"2627[blockchain]28# For Arbitrum mainnet29chain_id = 4216130receipts_verifier_address = "0x33f9E93266ce0E108fc85DdE2f71dab555A0F05a"3132# For Arbitrum Sepolia testnet, use:33# chain_id = 42161434# receipts_verifier_address = "0xfC24cE7a4428A6B89B52645243662A02BA734ECF"3536[tap]37# Maximum GRT amount to risk before requiring aggregation38# Use string format to prevent rounding errors39max_amount_willing_to_lose_grt = "0.1"4041[tap.sender_aggregator_endpoints]42# Gateway endpoints for RAV aggregation43# Mainnet44"0xDDE4cfFd3D9052A9cb618fC05a1Cd02be1f2F467" = "https://tap-aggregator.network.thegraph.com"4546# For testnet, use:47# "0xC3dDf37906724732FfD748057FEBe23379b0710D" = "https://tap-aggregator.testnet.thegraph.com"
              Environment Variable Overrides

              You can override any configuration value using environment variables:

              1# Pattern: [PREFIX]__[SECTION]__[KEY]2# PREFIX can be INDEXER_SERVICE or TAP_AGENT34# Examples:5export INDEXER_SERVICE__DATABASE__POSTGRES_URL="postgresql://..."6export TAP_AGENT__TAP__MAX_AMOUNT_WILLING_TO_LOSE_GRT="0.5"7export INDEXER_SERVICE__BLOCKCHAIN__RECEIPTS_VERIFIER_ADDRESS="0x..."
              Advanced Configuration

              For all configuration options, see:

              • Full configuration example⁠
              • Default values⁠

              Logging

              Set the log level using the RUST_LOG environment variable:

              1# Recommended for production2export RUST_LOG=indexer_service=info,indexer_tap_agent=info34# For debugging5export RUST_LOG=indexer_service=debug,indexer_tap_agent=debug67# TAP-specific debugging8export RUST_LOG=indexer_tap_agent=debug,info

              Monitoring

              Metrics

              All components expose Prometheus metrics on port 7300:

              • http://indexer-service:7300/metrics
              • http://tap-agent:7300/metrics

              Key metrics to monitor:

              • Receipt Processing: Track receipt validation, aggregation rates, and failures
              • RAV Creation: Monitor RAV request success/failure rates
              • Unaggregated Fees: Ensure fees stay below max_amount_willing_to_lose_grt
              • Sender Balances: Track escrow account balances and obligations

              Grafana Dashboard

              Import the official Grafana dashboard⁠ for comprehensive monitoring of:

              • TAP receipt flow and aggregation status
              • RAV creation and redemption lifecycle
              • System performance and error rates
              • Database query performance

              Troubleshooting

              Common issues and solutions:

              1. RAV requests failing:

                • Check aggregator endpoint connectivity
                • Verify sender configuration in tap.sender_aggregator_endpoints
                • Review debug logs for specific error messages
              2. Receipts not aggregating:

                • Ensure tap-agent is running (only one instance)
                • Check database connectivity
                • Verify max_amount_willing_to_lose_grt is not too high
              3. High unaggregated fees:

                • Lower max_amount_willing_to_lose_grt to trigger more frequent aggregation
                • Check if specific senders are having aggregation issues
                • Monitor the Grafana dashboard for aggregation patterns

              Deployment Options

              Docker Compose

              Example compose configuration for both services:

              1version: '3.8'23services:4  indexer-service:5    image: ghcr.io/graphprotocol/indexer-service-rs:latest6    ports:7      - '7600:7600' # Service port8      - '7300:7300' # Metrics port9    volumes:10      - ./config.toml:/config.toml11    command: ['--config', '/config.toml']12    environment:13      - RUST_LOG=indexer_service=info14    restart: unless-stopped1516  tap-agent:17    image: ghcr.io/graphprotocol/indexer-tap-agent:latest18    ports:19      - '7301:7300' # Metrics port (different host port)20    volumes:21      - ./config.toml:/config.toml22    command: ['--config', '/config.toml']23    environment:24      - RUST_LOG=indexer_tap_agent=info25    restart: unless-stopped

              Kubernetes

              For Kubernetes deployments, see the Graph Launchpad charts⁠ which include:

              • Helm charts for both services
              • ConfigMap templates for configuration
              • Service and ingress definitions
              • Prometheus ServiceMonitor resources

              Best Practices

              1. Database Performance:

                • Ensure your PostgreSQL instance has adequate resources
                • Monitor query performance through metrics
                • Regular maintenance of receipt tables
              2. High Availability:

                • Run multiple indexer-service-rs instances behind a load balancer
                • Keep tap-agent as a single instance with proper monitoring
                • Use database connection pooling
              3. Security:

                • Store operator mnemonic securely (use environment variables)
                • Restrict database access to indexer components only
                • Monitor for unusual receipt patterns
              4. Capacity Planning:

                • Monitor receipt growth rate
                • Plan database storage accordingly
                • Set appropriate max_amount_willing_to_lose_grt based on query volume

              Additional Resources

              • indexer-rs Repository⁠
              • TAP Core Documentation⁠
              • The Graph Discord - Get help in the #indexers channel
              • Support⁠ - Report issues or get help
              ⁠Edit on GitHub⁠

              GraphcastSupported Network Requirements
              On this page
              • Overview
              • How It Works
              • RAV Details
              • Redeeming RAVs
              • Blockchain Addresses
              • Contracts
              • Gateway
              • Prerequisites
              • Migration Guide
              • Software Requirements
              • Migration Steps
              • Logging
              • Monitoring
              • Metrics
              • Grafana Dashboard
              • Troubleshooting
              • Deployment Options
              • Docker Compose
              • Kubernetes
              • Best Practices
              • Additional Resources
              The GraphStatusTestnetBrand AssetsForumSecurityPrivacy PolicyTerms of Service