Understanding Sales
Add an adapter to the Core SDK, to normalize interactions with the contract
https://github.com/reservoirprotocol/core/tree/main/packages/sdk/src
Create a directory in /packages/sdk/src
and name it using only lowercase characters and dash (-) instead of space. For example: lorem-ipsum
for the Lorem Ipsum protocol.
Create addresses.ts
and add the protocol’s exchange contract address for each network:
// addresses.ts
import { ChainIdToAddress, Network } from "../utils";
export const Exchange: ChainIdToAddress = {
[Network.Ethereum]: "0x9757f2d2b135150bbeb65308d4a91804107cd8d6",
[Network.EthereumGoerli]: "0xd4a57a3bd3657d0d46b4c5bac12b3f156b9b886b",
};
Create index.ts
an export the Exchange object from addresses.ts
import * as Addresses from "./addresses";
export { Addresses };
```
Edit /packages/sdk/src/index.ts to export the new protocol’s addresses.
```
import * as LoremIpsum from "./lorem-ipsum";
export {
...
LoremIpsum,
};
Start listening to and saving events (fills, cancels, etc) in the Indexer
https://github.com/reservoirprotocol/indexer/tree/v5/src/sync/events/data
import { Interface } from "@ethersproject/abi";
import { Rarible } from "@reservoir0x/sdk";
import { config } from "@/config/index";
import { EventData } from "@/events-sync/data";
export const match: EventData = {
kind: "rarible-match",
addresses: { [Rarible.Addresses.Exchange[config.chainId].toLowerCase()
]: true },
topic: "0x268820db288a211986b26a8fda86b1e0046281b21206936bb0e61c67b5c79ef4",
numTopics: 1,
abi: new Interface([
`event Match(
bytes32 leftHash,
bytes32 rightHash,
address leftMaker,
address rightMaker,
uint newLeftFill,
uint newRightFill,
(bytes4 assetClass, bytes data) leftAsset,
(bytes4 assetClass, bytes data) rightAsset
)`,
]),
};
Create [protocol-name].ts
in /src/sync/events/data and add a method for each event that will be tracked. The fields correspond to the following:
- kind: unique identifier for the event (format: lowercase and replace spaces with dash (-))
- addresses: an object where the key is the exchange contract address and value equal true. Use the SDK to retrieve the contract address
- topic: the even topic. Use the following script to get this value
const { Interface } = require('@ethersproject/abi')
const main = () => {
const iface = new Interface([
`event Match(
bytes32 leftHash,
bytes32 rightHash,
address leftMaker,
address rightMaker,
uint newLeftFill,
uint newRightFill,
(bytes4 assetClass, bytes data) leftAsset,
(bytes4 assetClass, bytes data) rightAsset
)`,
])
console.log(iface.getEventTopic('Match'))
}
main()
If the event contains an Interface, replace it with a solidity data type. For example, from IERC20 token
to address token
.
To run this script you need to run npm init -y
and install ethers.js yarn add ethers
. Once finished, run the script using node main.js
- numTopics: The number of topics for the event
- abi: The event’s abi
Go to /src/sync/events/data/index.ts and
- Import all the methods from /src/sync/events/data/[protocol-name].ts:
import * as rarible from "@/events-sync/data/rarible";
- Add new event types to the EventDataKind type. Include the type for each event created in 3. /src/sync/events/data/[protocol-name].ts
- Pass the events in /src/sync/events/data/[protocol-name].ts to the getEventData method.
- Add a case for each event to the internalGetEventData method
Create a migration file which will add [protocol-name] as a valid order kind.
In your terminal go to the root directory of the indexer repo and call
yarn migrate create -t sql [protocol-name]-order-kind
and then change the content of the generated file to:
-- Up Migration
ALTER TYPE "order_kind_t" ADD VALUE '[protocol-name]';
-- Down Migration
Go to /src/sync/events/index.ts and in the switch case of the syncEvents method add a case for each event in /src/sync/events/data/[protocol-name].ts
case "event-name": {
const { args } = eventData.abi.parseLog(log);
const leftHash = args["leftHash"].toLowerCase();
const leftMaker = args["leftMaker"].toLowerCase();
const rightMaker = args["rightMaker"].toLowerCase();
const newLeftFill = args["newLeftFill"].toString();
const newRightFill = args["newRightFill"].toString();
const leftAsset = args["leftAsset"];
const rightAsset = args["rightAsset"];
// Format or modify the parsed data from `args` and
// push a new object to the database using
// fillEventsPartial.push()
fillEventsPartial.push({
orderKind,
orderId,
orderSide,
maker,
taker,
price,
contract,
tokenId,
amount,
baseEventParams,
});
break;
}
Make sure to make all the addresses lowercase.
To test the integration:
- Run
docker-compose up
to bootstrap a local postgres and redis instance. (The Docker daemon must be running in the background) - In a separate terminal, run
yarn; yarn build; yarn start
to migrate the database and start the indexer - Run
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`
To sync events for any particular block
The results would be shown in http://localhost:3000/sales/bulk/v1
You may log the args
object to debug any issues.
Updated about 2 years ago