Skip to content

Commit 4d369a6

Browse files
committed
feat: define custom subgraphs
refactor: split indexer files
1 parent cbd7f54 commit 4d369a6

File tree

5 files changed

+152
-83
lines changed

5 files changed

+152
-83
lines changed

src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,4 @@ export * from "./releases";
33
export * from "./types";
44

55
export * as chains from "./chains";
6-
export * as indexers from "./indexers";
76
export * as nativeTokens from "./native-tokens";

src/indexers/envio.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* @see https://docs.sablier.com/api/overview
3+
*/
4+
import { ChainId } from "@src/chains/ids";
5+
import type { Sablier } from "@src/types";
6+
7+
const ENVIO_BASE_URL = "https://indexer.hyperindex.xyz";
8+
9+
const envio = {
10+
endpoints: {
11+
airdrops: `${ENVIO_BASE_URL}/508d217/v1/graphql`,
12+
flow: `${ENVIO_BASE_URL}/3b4ea6b/v1/graphql`,
13+
lockup: `${ENVIO_BASE_URL}/53b7e25/v1/graphql`,
14+
},
15+
/**
16+
* Chains not supported by Envio. Monitor their docs for updates.
17+
* @see https://docs.envio.dev/docs/HyperSync/hypersync-supported-networks
18+
* @see https://github.com/enviodev/docs/issues/619
19+
*/
20+
unsupportedChains: {
21+
[ChainId.CORE_DAO]: true,
22+
[ChainId.FORM]: true,
23+
[ChainId.IOTEX]: true,
24+
[ChainId.LIGHTLINK]: true,
25+
[ChainId.SEI]: true,
26+
[ChainId.SUPERSEED]: true,
27+
[ChainId.TAIKO]: true,
28+
[ChainId.TANGLE]: true,
29+
[ChainId.ULTRA]: true,
30+
},
31+
};
32+
33+
/** @internal */
34+
export function getEnvioEndpoint(protocol: Sablier.Protocol, chainId: number): string | undefined {
35+
if (protocol === "legacy" || chainId in envio.unsupportedChains) {
36+
return undefined;
37+
}
38+
return envio.endpoints[protocol];
39+
}

src/indexers/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/**
2+
* @see https://docs.sablier.com/api/overview
3+
*/
4+
export * from "./envio";
5+
export * from "./thegraph";

src/indexers.ts renamed to src/indexers/thegraph.ts

Lines changed: 77 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,14 @@
11
/**
22
* @see https://docs.sablier.com/api/overview
33
*/
4-
import { ChainId } from "./chains/ids";
5-
import type { Sablier } from "./types";
4+
import { ChainId } from "@src/chains/ids";
5+
import type { Sablier } from "@src/types";
66

7-
const ENVIO_BASE_URL = "https://indexer.hyperindex.xyz";
87
const THEGRAPH_ORG_ID = 57079; // Sablier organization ID on The Graph
98

10-
const envio = {
11-
endpoints: {
12-
airdrops: `${ENVIO_BASE_URL}/508d217/v1/graphql`,
13-
flow: `${ENVIO_BASE_URL}/3b4ea6b/v1/graphql`,
14-
lockup: `${ENVIO_BASE_URL}/53b7e25/v1/graphql`,
15-
},
16-
/**
17-
* Chains not supported by Envio. Monitor their docs for updates.
18-
* @see https://docs.envio.dev/docs/HyperSync/hypersync-supported-networks
19-
* @see https://github.com/enviodev/docs/issues/619
20-
*/
21-
unsupportedChains: {
22-
[ChainId.CORE_DAO]: true,
23-
[ChainId.FORM]: true,
24-
[ChainId.IOTEX]: true,
25-
[ChainId.LIGHTLINK]: true,
26-
[ChainId.SEI]: true,
27-
[ChainId.SUPERSEED]: true,
28-
[ChainId.TAIKO]: true,
29-
[ChainId.TANGLE]: true,
30-
[ChainId.ULTRA]: true,
31-
},
32-
};
9+
type OfficialSubgraphMap = Record<number, { id: string; name: string }>;
3310

34-
const subgraphs: Record<Sablier.Protocol, Sablier.Subgraphs> = {
11+
const officialSubgraphs: Record<Sablier.Protocol, OfficialSubgraphMap> = {
3512
airdrops: {
3613
// ────────────────────────────────────────────────────────────────────────────────
3714
// Mainnets
@@ -162,27 +139,82 @@ const subgraphs: Record<Sablier.Protocol, Sablier.Subgraphs> = {
162139
},
163140
};
164141

165-
/** @internal */
166-
export function getEnvioEndpoint(protocol: Sablier.Protocol, chainId: number): string | undefined {
167-
if (protocol === "legacy" || chainId in envio.unsupportedChains) {
168-
return undefined;
169-
}
170-
return envio.endpoints[protocol];
171-
}
142+
type CustomSubgraphMap = Record<number, { explorer?: string; url: string }>;
143+
144+
const baseURLs = {
145+
LIGHTLINK: "https://graph.phoenix.lightlink.io/query/subgraphs/name/lightlink",
146+
ULTRA: "https://graph.evm.ultra.io/subgraphs/name/sablier",
147+
XDC: "https://graphql.xinfin.network/subgraphs/name/xdc",
148+
};
149+
150+
const customSubgraphs: Record<Sablier.Protocol, CustomSubgraphMap> = {
151+
airdrops: {
152+
[ChainId.LIGHTLINK]: {
153+
explorer: `${baseURLs.LIGHTLINK}/sablier-airdrops-lightlink/graphql`,
154+
url: `${baseURLs.LIGHTLINK}/sablier-airdrops-lightlink`,
155+
},
156+
[ChainId.ULTRA]: {
157+
url: `${baseURLs.ULTRA}/sablier-airdrops-ultra`,
158+
},
159+
[ChainId.XDC]: {
160+
explorer: `${baseURLs.XDC}/sablier-airdrops-xdc/graphql`,
161+
url: `${baseURLs.XDC}/sablier-airdrops-xdc`,
162+
},
163+
},
164+
flow: {
165+
[ChainId.LIGHTLINK]: {
166+
explorer: `${baseURLs.LIGHTLINK}/sablier-flow-lightlink/graphql`,
167+
url: `${baseURLs.LIGHTLINK}/sablier-flow-lightlink`,
168+
},
169+
[ChainId.ULTRA]: {
170+
url: `${baseURLs.ULTRA}/sablier-flow-ultra`,
171+
},
172+
[ChainId.XDC]: {
173+
explorer: `${baseURLs.XDC}/sablier-flow-xdc/graphql`,
174+
url: `${baseURLs.XDC}/sablier-flow-xdc`,
175+
},
176+
},
177+
legacy: {
178+
[ChainId.RONIN]: {
179+
url: "https://subgraph.satsuma-prod.com/d8d041c49d56/sablierlabs/sablier-ronin/api",
180+
},
181+
},
182+
lockup: {
183+
[ChainId.LIGHTLINK]: {
184+
explorer: `${baseURLs.LIGHTLINK}/sablier-lockup-lightlink/graphql`,
185+
url: `${baseURLs.LIGHTLINK}/sablier-lockup-lightlink`,
186+
},
187+
[ChainId.ULTRA]: {
188+
url: `${baseURLs.ULTRA}/sablier-lockup-ultra`,
189+
},
190+
[ChainId.XDC]: {
191+
explorer: `${baseURLs.XDC}/sablier-lockup-xdc/graphql`,
192+
url: `${baseURLs.XDC}/sablier-lockup-xdc`,
193+
},
194+
},
195+
};
172196

173197
/** @internal */
174198
export function getTheGraph(protocol: Sablier.Protocol, chainId: number): Sablier.TheGraph | undefined {
175-
const subgraph = subgraphs[protocol][chainId];
176-
if (!subgraph) {
177-
return undefined;
199+
const officialSubgraph = officialSubgraphs[protocol][chainId];
200+
if (officialSubgraph) {
201+
return {
202+
explorer: `https://thegraph.com/explorer/subgraphs/${officialSubgraph.id}`,
203+
studio: `https://api.studio.thegraph.com/query/${THEGRAPH_ORG_ID}/${officialSubgraph.name}/version/latest`,
204+
subgraph: {
205+
id: officialSubgraph.id,
206+
url: (apiKey: string) => `https://gateway.thegraph.com/api/${apiKey}/subgraphs/id/${officialSubgraph.id}`,
207+
},
208+
};
209+
}
210+
211+
const customSubgraph = customSubgraphs[protocol][chainId];
212+
if (customSubgraph) {
213+
return {
214+
customURL: customSubgraph.url,
215+
explorer: customSubgraph.explorer,
216+
};
178217
}
179218

180-
return {
181-
explorer: `https://thegraph.com/explorer/subgraphs/${subgraph.id}`,
182-
studio: `https://api.studio.thegraph.com/query/${THEGRAPH_ORG_ID}/${subgraph.name}/version/latest`,
183-
subgraph: {
184-
id: subgraph.id,
185-
url: (apiKey: string) => `https://gateway.thegraph.com/api/${apiKey}/subgraphs/id/${subgraph.id}`,
186-
},
187-
};
219+
return undefined;
188220
}

src/types.ts

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,6 @@ export declare namespace Sablier {
88

99
export type AliasMap = Record<string, string>;
1010

11-
/**
12-
* @description The native token on an EVM chain, used for paying gas fees.
13-
*/
14-
export type NativeToken = {
15-
decimals: number;
16-
name: string;
17-
symbol: string;
18-
};
19-
2011
export type Chain = {
2112
/** @description URL of the blockchain explorer. */
2213
explorerURL: string;
@@ -96,15 +87,18 @@ export declare namespace Sablier {
9687

9788
export type Manifest = string[] | ManifestLockupV1;
9889

99-
/**
100-
* @description Supported Sablier protocol types.
101-
*/
90+
/** @description The native token on an EVM chain, used for paying gas fees. */
91+
export type NativeToken = {
92+
decimals: number;
93+
name: string;
94+
symbol: string;
95+
};
96+
97+
/** @description Supported Sablier protocol types. */
10298
export type Protocol = "airdrops" | "flow" | "legacy" | "lockup";
10399

104-
/**
105-
* @description Base interface for all releases
106-
*/
107-
export type ReleaseBase = {
100+
/** @description Common interface for all releases. */
101+
export type ReleaseCommon = {
108102
/** @description A map of contract names to their aliases, used in the Sablier Interface and the subgraphs. */
109103
aliases?: { [contractName: string]: string };
110104
/** @description Whether this is the latest release for this protocol. */
@@ -120,8 +114,8 @@ export declare namespace Sablier {
120114
* core and periphery sub-categories.
121115
* @see https://github.com/sablier-labs/v2-periphery
122116
*/
123-
export type ReleaseLockupV1 = ReleaseBase & {
124-
readonly kind: "lockupV1";
117+
export type ReleaseLockupV1 = ReleaseCommon & {
118+
kind: "lockupV1";
125119
deployments: DeploymentLockupV1[];
126120
manifest: ManifestLockupV1;
127121
};
@@ -130,44 +124,44 @@ export declare namespace Sablier {
130124
* @description A standard release is a collection of deployments for a given protocol and version.
131125
* This is the default release type for most protocols.
132126
*/
133-
export type ReleaseStandard = ReleaseBase & {
134-
readonly kind: "standard";
127+
export type ReleaseStandard = ReleaseCommon & {
128+
kind: "standard";
135129
deployments: Deployment[];
136130
manifest: Manifest;
137131
};
138132

139-
/**
140-
* @description Union type representing all possible release types
141-
*/
133+
/** @description Union type representing all possible release types. */
142134
export type Release = ReleaseStandard | ReleaseLockupV1;
143135

144136
export type Repository = {
145137
commit: string;
146138
url: `https://github.com/sablier-labs/${string}`;
147139
};
148140

149-
export type Subgraph = {
150-
id: string;
151-
name: string;
152-
};
153-
154-
/**
155-
* @description Map of chain IDs to their corresponding subgraph configurations.
156-
*/
157-
export type Subgraphs = Record<number, Subgraph>;
158-
159-
export type TheGraph = {
141+
/** Shared “explorer” + “studio” fields (docs written only once) */
142+
interface TheGraphCommon {
160143
/** @description URL to The Graph explorer. */
161-
explorer: string;
144+
explorer?: string;
162145
/** @description URL to The Graph studio. */
163-
studio: string;
146+
studio?: string;
147+
}
148+
interface TheGraphCustom extends TheGraphCommon {
149+
/** @description URL to a custom subgraph. */
150+
customURL: string;
151+
subgraph?: never;
152+
}
153+
154+
interface TheGraphOfficial extends TheGraphCommon {
155+
customURL?: never;
164156
subgraph: {
165157
/** @description ID of the subgraph. */
166158
id: string;
167159
/** @description Function to generate the subgraph URL with a user-provided API key. */
168160
url: (apiKey: string) => string;
169161
};
170-
};
162+
}
163+
164+
export type TheGraph = TheGraphCustom | TheGraphOfficial;
171165

172166
export type VersionAirdrops = typeof versions.airdrops.v1_3;
173167

0 commit comments

Comments
 (0)