The Unified Indexer Service (UIS) is the blockchain indexing architecture used by Ripple Custody for ledger-specific indexing, event processing, and ledger APIs. UIS uses a decomposed, chain-specific adapter architecture with isolated ledger and network components.
For a complete and up-to-date list of which ledgers are supported, please refer to the Supported blockchain ledgers page.
UIS is available for SaaS deployments and for on-premises deployments from v1.26. If you are migrating an on-premises deployment from legacy indexers to UIS, see the UIS on-premises migration guide.
The Unified Indexer Service indexes blockchain data and exposes it to Ripple Custody through a small set of services:
| Service | Description |
|---|---|
| Indexer | Reads blocks from a blockchain node and records them. One indexer runs per ledger and network (for example, Solana devnet and Solana mainnet each run their own indexer), so an issue on one network does not affect the others. |
| Processor | Turns indexed blocks into the transaction events consumed by Ripple Custody. Shared across all ledgers. |
| Blockchain API | The single interface for blockchain operations — retrieves events, checks balances, prepares and broadcasts transactions. Shared across all ledgers. |
| Cockpit | Holds the ledger and network configuration the UIS runs against. This configuration is managed by Ripple Custody. |
For on-premises deployments, each indexer connects to a blockchain node that you provision — see On-premises node requirements below.
Ripple Custody supports a wide range of blockchains. Depending on the chain, indexing is handled either by UIS or by a standalone indexer. For on-premises deployments from v1.26:
- Solana, TRON, and XRPL use UIS automatically and do not require a per-network UIS configuration setting.
- Arbitrum, Base, and Optimism require UIS and must be explicitly configured with
type: "uis"to be operable. - Ethereum, Polygon, and Stellar continue to use existing standalone indexers unless you explicitly configure them to use UIS.
On-premises customers should be aware that a rewrite of the UIS will be available for on-premises deployment starting in the next LTS release. At that time, those blockchains configured with type: "uis" will need to be updated to use the new UIS.
For an on-premises deployment of UIS, you are responsible for provisioning and maintaining your own blockchain nodes. The service must be able to connect to these nodes to index transactions. The following table lists minimum node requirements for on-premises UIS deployments. Check the configuration packaged with your release for release-specific changes.
| Blockchain | Node type | Minimum version | Connection | Archive requirement | Additional details |
|---|---|---|---|---|---|
| Arbitrum | Geth compatible | v3.7.X | JSON-RPC over HTTP | Non-Archive | Debug mode must be enabled. |
| Base | Geth compatible | v0.14.1 | JSON-RPC over HTTP | Non-Archive | Debug mode must be enabled. |
| Ethereum | Geth | v1.16.4 | JSON-RPC over HTTP | Archive (Required) | Debug APIs must be enabled. High request volume (~1.2k - 300k/hour). |
| Optimism | Geth compatible | v1.101511 | JSON-RPC over HTTP | Non-Archive | Debug mode must be enabled. |
| Polygon | Geth compatible | v1.16.4 | JSON-RPC over HTTP | Archive (Required) | Debug mode must be enabled. |
| Solana | Agave | mainnet 2.3.10 / devnet 3.0.0 | JSON-RPC over HTTP | Archive Recommended | Estimated request volume is ~9000/hour. No debug mode needed. |
| Stellar | Horizon | v23.0.0 | HTTP | Archive (Preferred) | Requires application/x-www-form-urlencoded content-type for broadcasting transactions. |
| TRON | FullNode | v4.8.0 | RPC over HTTP | Archive (Preferred) | Estimated request volume is ~150k/day. |
| XRPL | FullNode | 2.6.X | HTTP | Archive Recommended | Request volume is not based on tracked accounts. |
For SaaS deployments, UIS is enabled and managed by Ripple for supported chains.
For on-premises deployments, UIS is available from v1.26 or later.
Use UIS automatically:
| Chain | Status |
|---|---|
| Solana | Uses UIS automatically. No per-network type: "uis" setting is required. |
| XRPL | Uses UIS automatically. No per-network type: "uis" setting is required. |
| TRON | Uses UIS automatically. No per-network type: "uis" setting is required. |
Must be explicitly configured to use UIS:
| Chain | Status |
|---|---|
| Arbitrum | Requires UIS. Configure the network with type: "uis" and provide node access settings. |
| Base | Requires UIS. Configure the network with type: "uis" and provide node access settings. |
| Optimism | Requires UIS. Configure the network with type: "uis" and provide node access settings. |
| Ethereum | Optional. You can continue using the legacy indexer or migrate to UIS. |
| Polygon | Optional. You can continue using the legacy indexer or migrate to UIS. |
| Stellar | Optional. You can continue using the legacy indexer or migrate to UIS. |
Arbitrum, Base, and Optimism require UIS because there is no supported legacy-indexer path for those chains. They still need explicit configuration in on-premises deployments because Ripple Custody must know which network to run, which node endpoint to use, and which authentication settings to apply.
Other EVM chains like Ethereum and Polygon can optionally use UIS or continue with legacy indexers.
Stellar can also optionally use UIS or continue with legacy indexers.
Migrating a chain to the Unified Indexer is a one-way process and cannot be rolled back.
Please plan your migration carefully. For any questions about the deployment process, please contact your CPE or our Support team.
To enable UIS for a specific chain, set the type parameter to "uis" in that network's configuration block within your Helm chart's values.yaml file.
The example code below shows the correct structure for enabling the UIS for an Optimism Sepolia testnet:
ledgers:
evm:
networks:
- name: optimism-sepolia
type: "uis" # Enable UIS for this network
raw_config: |
tracker.opindexer-sepolia.base-url = "http://api-management-uis"
...
indexer:
...
node:
# URL for your provisioned Optimism Sepolia node.
url: "http://your-optimism-sepolia-node-url"For complete step-by-step migration instructions, including pre-migration setup, database preparation, and validation steps, see the UIS on-premises migration guide.
If your EVM blockchain node requires authentication (for example, a Besu node that issues short-lived JWTs, or a third-party provider that expects a static header token), add an authentication block to the network's indexer.node config. This automatically deploys a Node Gateway sidecar in the same pod as the EVM indexer.
Use mode: header to inject a fixed key-value pair into every outbound request:
ledgers:
evm:
networks:
- name: mainnet
type: "uis"
indexer:
node:
url: "https://eth-node-provider.internal/"
authentication:
mode: header
header:
key: "x-auth-token"
value: "secret"Use mode: customJwt when the node requires a short-lived bearer token fetched from a separate token endpoint. Node Gateway fetches and caches the token, refreshing it before expiry.
ledgers:
evm:
networks:
- name: testnet-goerli
type: "uis"
indexer:
node:
url: "https://example-mas-node.internal/"
authentication:
mode: customJwt
customJwt:
tokenUrl: "https://example.com/api/generate-access-token"
tokenMethod: POST
apiKeyHeader: "x-api-key"
apiKeyValue: "your-api-key"
requestBody:
signature: "your-signature"
tokenJsonPath: data
tokenExpirySeconds: 3600
refreshBufferSeconds: 300customJwt field reference:
| Field | Type | Required | Description |
|---|---|---|---|
tokenUrl | String (URL) | Yes | Endpoint that issues the access token. |
tokenMethod | String | Yes | HTTP method for the token request (POST or GET). |
apiKeyHeader | String | No | Header name to include in the token request for API-key authentication of the token endpoint itself. |
apiKeyValue | String | No | Value for the apiKeyHeader. Store this in a Kubernetes Secret and inject via env var. |
requestBody | Map | No | Key-value pairs sent as the JSON body of the token request. |
tokenJsonPath | String | Yes | JSON path expression to extract the token value from the token endpoint response (e.g., data or access_token). |
tokenExpirySeconds | Integer | Yes | Lifetime of the fetched token in seconds. Node Gateway caches the token for this duration. |
refreshBufferSeconds | Integer | Yes | Seconds before expiry at which Node Gateway proactively fetches a new token. Must be less than tokenExpirySeconds. |