diff --git a/config.example.yaml b/config.example.yaml index 22b3fd19..2cab2051 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -53,6 +53,10 @@ contracts: stabullArbAddress: "0x1234...5678" # Dispair v4 contract address dispair: "0x1234...5678" + # Optional interpreter/store overrides, only needed when the deployer above + # does not expose them onchain (RaindexV6 deployers only expose parse2) + interpreter: "0x1234...5678" + store: "0x1234...5678" v5: # Sushi RP arb v5 contract address sushiArbAddress: "0x1234...5678" @@ -64,6 +68,10 @@ contracts: stabullArbAddress: "0x1234...5678" # Dispair v5 contract address dispair: "0x1234...5678" + # Optional interpreter/store overrides, only needed when the deployer above + # does not expose them onchain (RaindexV6 deployers only expose parse2) + interpreter: "0x1234...5678" + store: "0x1234...5678" v6: # Sushi RP arb v6 contract address sushiArbAddress: "0x1234...5678" @@ -77,6 +85,10 @@ contracts: raindexArbAddress: "0x1234...5678" # Dispair v6 contract address dispair: "0x1234...5678" + # Optional interpreter/store overrides, only needed when the deployer above + # does not expose them onchain (RaindexV6 deployers only expose parse2) + interpreter: "0x1234...5678" + store: "0x1234...5678" # list of liquidity providers # if provided through an env var, they should be separated by a comma diff --git a/lib/sushiswap b/lib/sushiswap index 540aebc2..0f3da6d4 160000 --- a/lib/sushiswap +++ b/lib/sushiswap @@ -1 +1 @@ -Subproject commit 540aebc24f047fbbf0a1be166b0f0cfecc3cfbee +Subproject commit 0f3da6d41861a4497dec12199010440db74a7a97 diff --git a/src/config/validators.test.ts b/src/config/validators.test.ts index 68685aa0..49e932bc 100644 --- a/src/config/validators.test.ts +++ b/src/config/validators.test.ts @@ -778,6 +778,8 @@ describe("Test yaml Validator methods", async function () { v4: { sushiArb: sushiArbV4 as `0x${string}`, dispair: dispairV4 as `0x${string}`, + interpreter: undefined, + store: undefined, genericArb: genericArbV4 as `0x${string}`, balancerArb: balancerArbV4 as `0x${string}`, stabullArb: stabullArbV4 as `0x${string}`, @@ -802,6 +804,8 @@ describe("Test yaml Validator methods", async function () { v5: { sushiArb: sushiArbV5 as `0x${string}`, dispair: dispairV5 as `0x${string}`, + interpreter: undefined, + store: undefined, genericArb: genericArbV5 as `0x${string}`, balancerArb: balancerArbV5 as `0x${string}`, stabullArb: stabullArbV5 as `0x${string}`, @@ -827,6 +831,8 @@ describe("Test yaml Validator methods", async function () { v6: { sushiArb: sushiArbV6 as `0x${string}`, dispair: dispairV6 as `0x${string}`, + interpreter: undefined, + store: undefined, genericArb: genericArbV6 as `0x${string}`, balancerArb: balancerArbV6 as `0x${string}`, stabullArb: stabullArbV6 as `0x${string}`, @@ -856,6 +862,8 @@ describe("Test yaml Validator methods", async function () { v4: { sushiArb: sushiArbV4 as `0x${string}`, dispair: dispairV4 as `0x${string}`, + interpreter: undefined, + store: undefined, genericArb: undefined, balancerArb: undefined, stabullArb: undefined, @@ -863,6 +871,8 @@ describe("Test yaml Validator methods", async function () { v5: { sushiArb: undefined, dispair: undefined, + interpreter: undefined, + store: undefined, genericArb: genericArbV5 as `0x${string}`, balancerArb: undefined, stabullArb: undefined, @@ -870,6 +880,8 @@ describe("Test yaml Validator methods", async function () { v6: { sushiArb: undefined, dispair: undefined, + interpreter: undefined, + store: undefined, genericArb: undefined, balancerArb: balancerArbV6 as `0x${string}`, stabullArb: undefined, @@ -891,6 +903,8 @@ describe("Test yaml Validator methods", async function () { v4: { sushiArb: sushiArbV4 as `0x${string}`, dispair: undefined, + interpreter: undefined, + store: undefined, genericArb: undefined, balancerArb: undefined, stabullArb: undefined, @@ -912,6 +926,8 @@ describe("Test yaml Validator methods", async function () { v5: { sushiArb: undefined, dispair: dispairV5 as `0x${string}`, + interpreter: undefined, + store: undefined, genericArb: undefined, balancerArb: balancerArbV5 as `0x${string}`, stabullArb: undefined, @@ -932,6 +948,8 @@ describe("Test yaml Validator methods", async function () { v6: { sushiArb: undefined, dispair: undefined, + interpreter: undefined, + store: undefined, genericArb: undefined, balancerArb: undefined, stabullArb: undefined, @@ -968,6 +986,8 @@ describe("Test yaml Validator methods", async function () { v4: { sushiArb: sushiArbV4 as `0x${string}`, dispair: dispairV4 as `0x${string}`, + interpreter: undefined, + store: undefined, genericArb: undefined, balancerArb: undefined, stabullArb: undefined, @@ -991,6 +1011,8 @@ describe("Test yaml Validator methods", async function () { v6: { sushiArb: undefined, dispair: undefined, + interpreter: undefined, + store: undefined, genericArb: undefined, balancerArb: balancerArbV6 as `0x${string}`, stabullArb: undefined, diff --git a/src/config/validators.ts b/src/config/validators.ts index 1cdf45c2..4dab16e7 100644 --- a/src/config/validators.ts +++ b/src/config/validators.ts @@ -471,6 +471,12 @@ export namespace Validator { export function resolveContracts(input: any): AppOptionsContracts { const dispairV4 = resolveAddress(input?.contracts?.v4?.dispair, "dispair v4", true); + const interpreterV4 = resolveAddress( + input?.contracts?.v4?.interpreter, + "interpreter v4", + true, + ); + const storeV4 = resolveAddress(input?.contracts?.v4?.store, "store v4", true); const sushiArbAddressV4 = resolveAddress( input?.contracts?.v4?.sushiArbAddress, "sushiArbAddress v4", @@ -492,6 +498,12 @@ export namespace Validator { true, ); const dispairV5 = resolveAddress(input?.contracts?.v5?.dispair, "dispair v5", true); + const interpreterV5 = resolveAddress( + input?.contracts?.v5?.interpreter, + "interpreter v5", + true, + ); + const storeV5 = resolveAddress(input?.contracts?.v5?.store, "store v5", true); const sushiArbAddressV5 = resolveAddress( input?.contracts?.v5?.sushiArbAddress, "sushiArbAddress v5", @@ -513,6 +525,12 @@ export namespace Validator { true, ); const dispairV6 = resolveAddress(input?.contracts?.v6?.dispair, "dispair v6", true); + const interpreterV6 = resolveAddress( + input?.contracts?.v6?.interpreter, + "interpreter v6", + true, + ); + const storeV6 = resolveAddress(input?.contracts?.v6?.store, "store v6", true); const sushiArbAddressV6 = resolveAddress( input?.contracts?.v6?.sushiArbAddress, "sushiArbAddress v6", @@ -549,6 +567,8 @@ export namespace Validator { contracts.v4 = { sushiArb: sushiArbAddressV4 as `0x${string}` | undefined, dispair: dispairV4 as `0x${string}` | undefined, + interpreter: interpreterV4 as `0x${string}` | undefined, + store: storeV4 as `0x${string}` | undefined, genericArb: genericArbAddressV4 as `0x${string}` | undefined, balancerArb: balancerArbAddressV4 as `0x${string}` | undefined, stabullArb: stabullArbAddressV4 as `0x${string}` | undefined, @@ -564,6 +584,8 @@ export namespace Validator { contracts.v5 = { sushiArb: sushiArbAddressV5 as `0x${string}` | undefined, dispair: dispairV5 as `0x${string}` | undefined, + interpreter: interpreterV5 as `0x${string}` | undefined, + store: storeV5 as `0x${string}` | undefined, genericArb: genericArbAddressV5 as `0x${string}` | undefined, balancerArb: balancerArbAddressV5 as `0x${string}` | undefined, stabullArb: stabullArbAddressV5 as `0x${string}` | undefined, @@ -580,6 +602,8 @@ export namespace Validator { contracts.v6 = { sushiArb: sushiArbAddressV6 as `0x${string}` | undefined, dispair: dispairV6 as `0x${string}` | undefined, + interpreter: interpreterV6 as `0x${string}` | undefined, + store: storeV6 as `0x${string}` | undefined, genericArb: genericArbAddressV6 as `0x${string}` | undefined, balancerArb: balancerArbAddressV6 as `0x${string}` | undefined, stabullArb: stabullArbAddressV6 as `0x${string}` | undefined, diff --git a/src/config/yaml.test.ts b/src/config/yaml.test.ts index 921b81fb..45444734 100644 --- a/src/config/yaml.test.ts +++ b/src/config/yaml.test.ts @@ -97,6 +97,8 @@ orderbookTradeTypes: sushiArb: "0x1111111111111111111111111111111111111111", balancerArb: "0x3333333333333333333333333333333333333333", dispair: "0x2222222222222222222222222222222222222222", + interpreter: undefined, + store: undefined, genericArb: undefined, stabullArb: "0x4444444444444444444444444444444444444444", }, @@ -179,6 +181,8 @@ orderbookTradeTypes: v5: { sushiArbAddress: "0x1111111111111111111111111111111111111111", dispair: "0x2222222222222222222222222222222222222222", + interpreter: undefined, + store: undefined, genericArbAddress: "0x3333333333333333333333333333333333333333", }, }, diff --git a/src/config/yaml.ts b/src/config/yaml.ts index ebc37217..16c471be 100644 --- a/src/config/yaml.ts +++ b/src/config/yaml.ts @@ -33,6 +33,10 @@ export type AppOptionsContracts = { v4?: { sushiArb?: `0x${string}`; dispair?: `0x${string}`; + /** Optional interpreter override, for deployers that do not expose it onchain */ + interpreter?: `0x${string}`; + /** Optional store override, for deployers that do not expose it onchain */ + store?: `0x${string}`; genericArb?: `0x${string}`; balancerArb?: `0x${string}`; stabullArb?: `0x${string}`; @@ -40,6 +44,10 @@ export type AppOptionsContracts = { v5?: { sushiArb?: `0x${string}`; dispair?: `0x${string}`; + /** Optional interpreter override, for deployers that do not expose it onchain */ + interpreter?: `0x${string}`; + /** Optional store override, for deployers that do not expose it onchain */ + store?: `0x${string}`; genericArb?: `0x${string}`; balancerArb?: `0x${string}`; stabullArb?: `0x${string}`; @@ -47,6 +55,10 @@ export type AppOptionsContracts = { v6?: { sushiArb?: `0x${string}`; dispair?: `0x${string}`; + /** Optional interpreter override, for deployers that do not expose it onchain */ + interpreter?: `0x${string}`; + /** Optional store override, for deployers that do not expose it onchain */ + store?: `0x${string}`; genericArb?: `0x${string}`; balancerArb?: `0x${string}`; stabullArb?: `0x${string}`; diff --git a/src/order/index.test.ts b/src/order/index.test.ts index 120f5cb0..debc836f 100644 --- a/src/order/index.test.ts +++ b/src/order/index.test.ts @@ -1747,6 +1747,101 @@ describe("Test OrderManager", () => { expect(result.size).toBe(0); }); + it("should not throw when the chain has no routing base tokens configured", async () => { + // a chain that sushi has no BASES_TO_CHECK_TRADES_AGAINST entry for + delete (BASES_TO_CHECK_TRADES_AGAINST as any)[state.chainConfig.id]; + + const orderARes = Result.ok({ + type: Order.Type.V4, + owner: "0xowner", + validInputs: [ + { + token: "0xinput", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + validOutputs: [ + { + token: "0xoutput", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + }); + const orderBRes = Result.ok({ + type: Order.Type.V4, + owner: "0xowner", + validInputs: [ + { + token: "0xbasetoken", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + validOutputs: [ + { + token: "0xinput", + vaultId: + "0x0000000000000000000000000000000000000000000000000000000000000001", + }, + ], + }); + (Order.tryFromBytes as Mock) + .mockReturnValueOnce(orderARes) + .mockReturnValueOnce(orderBRes); + const orderA = { + __version: SubgraphVersions.V6, + orderHash: "0xhashA", + orderbook: { id: "0xorderbook" }, + orderBytes: "0xbytesA", + outputs: [ + { + token: { address: "0xoutput", symbol: "OUT", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + inputs: [ + { + token: { address: "0xinput", symbol: "IN", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + }; + const orderB = { + __version: SubgraphVersions.V6, + orderHash: "0xhashB", + orderbook: { id: "0xorderbook" }, + orderBytes: "0xbytesB", + outputs: [ + { + token: { address: "0xinput", symbol: "IN", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + inputs: [ + { + token: { address: "0xbasetoken", symbol: "BASE", decimals: "18" }, + balance: + "0xffffffee00000000000000000000000000000000000000000000000000000001", + }, + ], + }; + + await orderManager.addOrder(orderA as any); + await orderManager.addOrder(orderB as any); + + const pairA = getPair("0xorderbook", "0xhashA", "0xoutput", "0xinput"); + + const result = orderManager.getCounterpartyOrdersAgainstBaseTokens(pairA); + + expect(result).toBeInstanceOf(Map); + expect(result.size).toBe(0); + }); + it("should skip non-base tokens", async () => { const mockBaseToken = { address: "0xbasetoken", symbol: "BASE", decimals: 18 }; (BASES_TO_CHECK_TRADES_AGAINST as any)[state.chainConfig.id] = [mockBaseToken as any]; diff --git a/src/order/index.ts b/src/order/index.ts index 565d45fc..73b03f1a 100644 --- a/src/order/index.ts +++ b/src/order/index.ts @@ -588,7 +588,7 @@ export class OrderManager { // skip mirrored order pairs and pairs with middle token that is not in routing base tokens if ( tkn === sellToken || - BASES_TO_CHECK_TRADES_AGAINST[this.state.chainConfig.id].every( + (BASES_TO_CHECK_TRADES_AGAINST[this.state.chainConfig.id] ?? []).every( (baseToken) => baseToken.address.toLowerCase() !== tkn, ) ) { diff --git a/src/state/contracts.test.ts b/src/state/contracts.test.ts index 46794278..e77fa0eb 100644 --- a/src/state/contracts.test.ts +++ b/src/state/contracts.test.ts @@ -608,6 +608,55 @@ describe("resolveVersionContracts", () => { }); }); + it("should prefer configured interpreter/store over onchain reads", async () => { + const mockAddresses = { + dispair: "0xdispairAddress" as `0x${string}`, + interpreter: "0xconfiguredInterpreter" as `0x${string}`, + store: "0xconfiguredStore" as `0x${string}`, + sushiArb: "0xsushiArbAddress" as `0x${string}`, + }; + + const result = await resolveVersionContracts(mockClient, mockAddresses, "v6"); + + expect(result).toEqual({ + dispair: { + deployer: "0xdispairAddress", + interpreter: "0xconfiguredInterpreter", + store: "0xconfiguredStore", + }, + sushiArb: "0xsushiArbAddress", + }); + // the RaindexV6 deployer only exposes parse2, so it must not be read at all + expect(mockClient.readContract).not.toHaveBeenCalled(); + }); + + it("should still read onchain for whichever of interpreter/store is not configured", async () => { + const mockAddresses = { + dispair: "0xdispairAddress" as `0x${string}`, + interpreter: "0xconfiguredInterpreter" as `0x${string}`, + sushiArb: "0xsushiArbAddress" as `0x${string}`, + }; + + mockClient.readContract.mockResolvedValueOnce("0xstoreAddress" as `0x${string}`); + + const result = await resolveVersionContracts(mockClient, mockAddresses, "v6"); + + expect(result).toEqual({ + dispair: { + deployer: "0xdispairAddress", + interpreter: "0xconfiguredInterpreter", + store: "0xstoreAddress", + }, + sushiArb: "0xsushiArbAddress", + }); + expect(mockClient.readContract).toHaveBeenCalledTimes(1); + expect(mockClient.readContract).toHaveBeenCalledWith({ + address: "0xdispairAddress", + functionName: "I_STORE", + abi: ABI.Deployer.Primary.DeployerV6, + }); + }); + it("should resolve version contracts for v6 with all addresses when all contract calls succeed", async () => { const mockAddresses = { dispair: "0xdispairAddress" as `0x${string}`, diff --git a/src/state/contracts.ts b/src/state/contracts.ts index db152d94..b6b90c58 100644 --- a/src/state/contracts.ts +++ b/src/state/contracts.ts @@ -79,24 +79,37 @@ export async function resolveVersionContracts( return undefined; } - const interpreter = await client - .readContract({ - address: addresses.dispair, - functionName: version === "v6" ? "I_INTERPRETER" : "iInterpreter", - abi: version === "v6" ? ABI.Deployer.Primary.DeployerV6 : ABI.Deployer.Primary.Deployer, - }) - .catch(() => undefined); + // Not every expression deployer exposes its interpreter and store onchain; the + // RaindexV6-era deployers, for instance, only expose parse2. Prefer the + // configured overrides when they are given and only read onchain otherwise. + const interpreter = + addresses.interpreter ?? + (await client + .readContract({ + address: addresses.dispair, + functionName: version === "v6" ? "I_INTERPRETER" : "iInterpreter", + abi: + version === "v6" + ? ABI.Deployer.Primary.DeployerV6 + : ABI.Deployer.Primary.Deployer, + }) + .catch(() => undefined)); if (!interpreter) { return undefined; } - const store = await client - .readContract({ - address: addresses.dispair, - functionName: version === "v6" ? "I_STORE" : "iStore", - abi: version === "v6" ? ABI.Deployer.Primary.DeployerV6 : ABI.Deployer.Primary.Deployer, - }) - .catch(() => undefined); + const store = + addresses.store ?? + (await client + .readContract({ + address: addresses.dispair, + functionName: version === "v6" ? "I_STORE" : "iStore", + abi: + version === "v6" + ? ABI.Deployer.Primary.DeployerV6 + : ABI.Deployer.Primary.Deployer, + }) + .catch(() => undefined)); if (!store) { return undefined; } diff --git a/src/subgraph/index.ts b/src/subgraph/index.ts index 8b5abbf6..ee03553a 100644 --- a/src/subgraph/index.ts +++ b/src/subgraph/index.ts @@ -7,7 +7,7 @@ import { PreAssembledSpan } from "../logger"; import { SpanStatusCode } from "@opentelemetry/api"; import { ErrorSeverity, errorSnapshot } from "../error"; import { SgOrder, SgTransaction, SubgraphSyncState, SubgraphVersions } from "./types"; -import { getTxsQuery, orderbooksQuery, DEFAULT_PAGE_SIZE, getQueryPaginated } from "./query"; +import { getTxsQuery, getOrderbooksQuery, DEFAULT_PAGE_SIZE, getQueryPaginated } from "./query"; // re-export export * from "./types"; @@ -70,7 +70,11 @@ export class SubgraphManager { */ async getOrderbooks(): Promise> { const promises = this.subgraphs.map((url) => - axios.post(url, { query: orderbooksQuery }, { headers, timeout: this.requestTimeout }), + axios.post( + url, + { query: getOrderbooksQuery(this.getSubgraphVersion(url)) }, + { headers, timeout: this.requestTimeout }, + ), ); const queryResults = await Promise.allSettled(promises); const addresses = queryResults.flatMap( @@ -152,7 +156,7 @@ export class SubgraphManager { const res = await axios.post( url, { - query: getQueryPaginated(skip, this.filters), + query: getQueryPaginated(skip, this.filters, version), }, { headers, timeout: this.requestTimeout }, ); @@ -234,7 +238,14 @@ export class SubgraphManager { try { const res = await axios.post( url, - { query: getTxsQuery(startTimestamp, this.syncState[url].skip) }, + { + query: getTxsQuery( + startTimestamp, + this.syncState[url].skip, + undefined, + this.getSubgraphVersion(url), + ), + }, { headers, timeout: this.requestTimeout }, ); if (typeof res?.data?.data?.transactions !== "undefined") { diff --git a/src/subgraph/query.test.ts b/src/subgraph/query.test.ts index 7e26fa5c..362a3cec 100644 --- a/src/subgraph/query.test.ts +++ b/src/subgraph/query.test.ts @@ -1,5 +1,6 @@ import { describe, it, expect } from "vitest"; -import { getQueryPaginated, getTxsQuery, DEFAULT_PAGE_SIZE } from "./query"; +import { getOrderbooksQuery, getQueryPaginated, getTxsQuery, DEFAULT_PAGE_SIZE } from "./query"; +import { SubgraphVersions } from "./types"; describe("Test getQueryPaginated", () => { it("should generate query with no filters", () => { @@ -27,6 +28,42 @@ describe("Test getQueryPaginated", () => { expect(query).toContain('orderbook_not_in: ["0xnotbook"]'); expect(query).toContain("skip: 10"); }); + + it("should select the legacy orderbook entity by default", () => { + const query = getQueryPaginated(0, undefined, SubgraphVersions.LEGACY); + expect(query).toContain("orderbook {"); + expect(query).not.toContain("raindex"); + }); + + it("should alias the v6 raindex entity as orderbook", () => { + const query = getQueryPaginated(0, undefined, SubgraphVersions.V6); + expect(query).toContain("orderbook: raindex {"); + }); + + it("should use the raindex filter key on v6", () => { + const filters = { + includeOrderbooks: new Set(["0xbook"]), + excludeOrderbooks: new Set(["0xnotbook"]), + }; + const query = getQueryPaginated(0, filters, SubgraphVersions.V6); + expect(query).toContain('raindex_in: ["0xbook"]'); + expect(query).toContain('raindex_not_in: ["0xnotbook"]'); + expect(query).not.toContain("orderbook_in"); + expect(query).not.toContain("orderbook_not_in"); + }); +}); + +describe("Test getOrderbooksQuery", () => { + it("should query orderbooks on legacy", () => { + const query = getOrderbooksQuery(SubgraphVersions.LEGACY); + expect(query).toContain("orderbooks {"); + expect(query).not.toContain("raindices"); + }); + + it("should alias raindices as orderbooks on v6", () => { + const query = getOrderbooksQuery(SubgraphVersions.V6); + expect(query).toContain("orderbooks: raindices {"); + }); }); describe("Test getTxsQuery", () => { @@ -36,4 +73,16 @@ describe("Test getTxsQuery", () => { expect(query).toContain("skip: 20"); expect(query).toContain(`first: ${DEFAULT_PAGE_SIZE}`); }); + + it("should select the legacy orderbook entity by default", () => { + const query = getTxsQuery(123456, 20); + expect(query).toContain("orderbook {"); + expect(query).not.toContain("raindex"); + }); + + it("should alias the v6 raindex entity as orderbook", () => { + const query = getTxsQuery(123456, 20, undefined, SubgraphVersions.V6); + expect(query).toContain("orderbook: raindex {"); + expect(query).not.toContain("\n orderbook {"); + }); }); diff --git a/src/subgraph/query.ts b/src/subgraph/query.ts index bf648c88..3e682147 100644 --- a/src/subgraph/query.ts +++ b/src/subgraph/query.ts @@ -1,14 +1,31 @@ import { SgFilter } from "./filter"; +import { SubgraphVersions } from "./types"; export const DEFAULT_PAGE_SIZE = 1000 as const; +/** + * The orderbook entity was renamed to `raindex` in the v6 subgraph schema, so v6 + * queries select it under an `orderbook` alias. That keeps the response shape + * identical across versions and leaves every consumer of `SgOrder`/`SgTransaction` + * untouched. + * @param version - The subgraph schema version being queried + */ +export function orderbookField(version: SubgraphVersions): string { + return version === SubgraphVersions.V6 ? "orderbook: raindex" : "orderbook"; +} + /** * Method to get the subgraph query body for order details with optional filters * @param skip - Number of results to skip * @param filters - Applies the filters for query * @returns the query string */ -export function getQueryPaginated(skip: number, filters?: SgFilter): string { +export function getQueryPaginated( + skip: number, + filters?: SgFilter, + version: SubgraphVersions = SubgraphVersions.LEGACY, +): string { + const orderbook = orderbookField(version); const getFilterVar = (header: string, f?: Set) => f ? `${header}: [${[...f].map((v) => `"${v.toLowerCase()}"`).join(", ")}], ` : ""; @@ -16,8 +33,13 @@ export function getQueryPaginated(skip: number, filters?: SgFilter): string { const exOwnerFilter = getFilterVar("owner_not_in", filters?.excludeOwners); const incOrderFilter = getFilterVar("orderHash_in", filters?.includeOrders); const exOrderFilter = getFilterVar("orderHash_not_in", filters?.excludeOrders); - const incOrderbookFilter = getFilterVar("orderbook_in", filters?.includeOrderbooks); - const exOrderbookFilter = getFilterVar("orderbook_not_in", filters?.excludeOrderbooks); + // the orderbook entity is also named `raindex` on the filter input in v6 + const orderbookFilterKey = version === SubgraphVersions.V6 ? "raindex" : "orderbook"; + const incOrderbookFilter = getFilterVar(`${orderbookFilterKey}_in`, filters?.includeOrderbooks); + const exOrderbookFilter = getFilterVar( + `${orderbookFilterKey}_not_in`, + filters?.excludeOrderbooks, + ); return `{ orders( @@ -42,7 +64,7 @@ export function getQueryPaginated(skip: number, filters?: SgFilter): string { meta active nonce - orderbook { + ${orderbook} { id } inputs { @@ -67,8 +89,8 @@ export function getQueryPaginated(skip: number, filters?: SgFilter): string { }`; } -export const orderbooksQuery = `{ - orderbooks { +export const getOrderbooksQuery = (version: SubgraphVersions = SubgraphVersions.LEGACY) => `{ + ${version === SubgraphVersions.V6 ? "orderbooks: raindices" : "orderbooks"} { id } }`; @@ -88,7 +110,13 @@ export const statusCheckQuery = `{ * @param skip - Skips the first number of results * @param endTimestamp - (optional) The timestamp to end query at */ -export const getTxsQuery = (startTimestamp: number, skip: number, endTimestamp?: number) => { +export const getTxsQuery = ( + startTimestamp: number, + skip: number, + endTimestamp?: number, + version: SubgraphVersions = SubgraphVersions.LEGACY, +) => { + const orderbook = orderbookField(version); const endTimestampClause = typeof endTimestamp === "number" ? `timestamp_lte: "${endTimestamp}"` : ""; return `{transactions( @@ -112,7 +140,7 @@ export const getTxsQuery = (startTimestamp: number, skip: number, endTimestamp?: meta active nonce - orderbook { + ${orderbook} { id } inputs { @@ -147,7 +175,7 @@ export const getTxsQuery = (startTimestamp: number, skip: number, endTimestamp?: meta active nonce - orderbook { + ${orderbook} { id } inputs { @@ -183,7 +211,7 @@ export const getTxsQuery = (startTimestamp: number, skip: number, endTimestamp?: symbol } } - orderbook { + ${orderbook} { id } } @@ -200,7 +228,7 @@ export const getTxsQuery = (startTimestamp: number, skip: number, endTimestamp?: symbol } } - orderbook { + ${orderbook} { id } } @@ -219,7 +247,7 @@ export const getTxsQuery = (startTimestamp: number, skip: number, endTimestamp?: symbol } } - orderbook { + ${orderbook} { id } } @@ -236,7 +264,7 @@ export const getTxsQuery = (startTimestamp: number, skip: number, endTimestamp?: symbol } } - orderbook { + ${orderbook} { id } }