Integrate Your Protocol into Reservoir

Integrate your protocol's liquidity into Reservoir

For marketplaces and NFT liquidity protocols, order distribution is key. Because Reservoir is open-source, you can integrate your new marketplace or liquidity protocol into Reservoir yourself, and instantly get distribution to across the Reservoir ecosystem, including to Opensea Pro.

Integrating your protocol

There are three major steps to complete you integration:

  1. SDK integration
  2. Indexer integration
  3. Router integration


We recommend forking the indexer and working internally before making a one pass PR to the indexer.

SDK integration

Every exchange that we support needs to have a corresponding SDK implementation. You can checkout the SDK repo here.

We need the following (below examples are taken from the LooksRare integration):

The way to check an integration is via automated tests which reside in the contracts package.Here are the tests for the LooksRare integration as an example. Since the tests are run on mainnet forks, make sure to have a .env file in the contracts package directory containing the following:


Indexer Integration

Once the SDK integration is done, the next step is to add support for the new exchange at the indexer level (this builds on top of the previous core SDK integration, which the indexer uses as an abstraction for the low-level exchange details).

We need the following (below examples are taken from the LooksRare integration):

  • order parsing/validation logic - This implies quite a few checks ensuring that the order is properly formatted and valid - some checks are exchange-independent (like validity times) while other checks are exchange-dependent (like nonce validation))
  • order fillability checking logic - the above validation logic will use the fillability checking logic in order to associate an up-to-date status to the order
  • event ingestion logic -
    • event definitions
    • event handling logic - the examples are pretty easy to follow along and adjust for any other new exchanges. It involves keeping orders validated based on events happening on-chain like cancels or fills/

To check the indexer part of the integration, it would be useful to write unit/integration tests that check different logic:

Router Integration

In order to support some advanced features (eg. buying listings / filling bids from different protocols) a router module is needed.

Here are some examples and tests to help with module construction.

Once the module is ready and tested, the next and final step is integrating it within the smart-routing logic which resides in the SDK’s Router class. For integrating listings, you should cover the fillListingsTx method while bids are covered by the fillBidsTx method. The smart-routing logic for the new protocol can actually be implemented without a corresponding router module, but in this case the functionality will be severely restricted. Here’s an example of handling listings of a protocol without a router module.

Running and testing locally

  • Run docker-compose rm -f && docker-compose up --remove-orphans to bootstrap a local postgres and redis instance (the Docker daemon must be running in the background)
  • Run yarn && yarn build && yarn start to install any dependencies, migrate the database, and start the indexer
  • Run yarn test to trigger the tests
  • If needed, it’s also possible to manually trigger syncing data from the blockchain via curl -X POST -H ‘Content-Type: application/json’ -H ‘X-Admin-Api-Key: admin’ -d ‘{“fromBlock”: 1, “toBlock”: 1}’ http://localhost:3000/admin/sync-events


  • It will be useful to take a look at the examples most similar to the protocol being integrated. For example, an off-chain orderbook protocol’s integration should be very similar to eg. LooksRare, Seaport, an on-chain orderbook protocol should be similar to eg. Foundation, while an AMM-like protocol should be similar to eg. Sudoswap, NFTX.


What's the difference between price and value?

For listings value = price, for bids value = price - fees. Value is basically what the taker needs to pay for listings or what the taker will receive for bids

What's the difference between currency_price and price?

Value and Price are always denominated in ETH (or the native currency of the chain) while currency value are the in the currency the order was made in.

What does is_reservoir refer to?

Is_reservoir is used to denote Reservoir native orders. You'll want that to be null/false

What does missing_royalties refer to?

The missing royalties are the difference between the royalties the order pays and the full royalties the creator configured. For example if an order pays a royalty of 0.5% but the creator set their royalties to 10% the missing royalties will be 9.5%. You shouldn't set that to a negative value, just leave it empty if all royalties are paid (even if more royalties than configured are paid).