@codex-data/sdk 1.0.9 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist/resources/graphql.d.ts +177 -681
  2. package/dist/resources/graphql.d.ts.map +1 -1
  3. package/dist/resources/graphql.js +67 -79
  4. package/dist/resources/graphql.js.map +1 -1
  5. package/dist/sdk/Mutation.d.ts +2 -2
  6. package/dist/sdk/Mutation.d.ts.map +1 -1
  7. package/dist/sdk/Mutation.js +2 -2
  8. package/dist/sdk/Mutation.js.map +1 -1
  9. package/dist/sdk/Query.d.ts +57 -52
  10. package/dist/sdk/Query.d.ts.map +1 -1
  11. package/dist/sdk/Query.js +56 -51
  12. package/dist/sdk/Query.js.map +1 -1
  13. package/dist/sdk/Subscribe.d.ts +17 -18
  14. package/dist/sdk/Subscribe.d.ts.map +1 -1
  15. package/dist/sdk/Subscribe.js +126 -133
  16. package/dist/sdk/Subscribe.js.map +1 -1
  17. package/dist/sdk/generated/gql.d.ts +135 -104
  18. package/dist/sdk/generated/gql.d.ts.map +1 -1
  19. package/dist/sdk/generated/gql.js +44 -40
  20. package/dist/sdk/generated/gql.js.map +1 -1
  21. package/dist/sdk/generated/graphql.d.ts +1612 -1103
  22. package/dist/sdk/generated/graphql.d.ts.map +1 -1
  23. package/dist/sdk/generated/graphql.js +113 -121
  24. package/dist/sdk/generated/graphql.js.map +1 -1
  25. package/dist/sdk/index.d.ts +45 -0
  26. package/dist/sdk/index.d.ts.map +1 -1
  27. package/dist/sdk/index.js +83 -5
  28. package/dist/sdk/index.js.map +1 -1
  29. package/dist/sdk/index.test.js +232 -7
  30. package/dist/sdk/index.test.js.map +1 -1
  31. package/package.json +1 -1
  32. package/src/resources/generated_queries/Balances.graphql +15 -0
  33. package/src/resources/generated_queries/DetailedWalletStats.graphql +4 -0
  34. package/src/resources/generated_queries/FilterNetworkWallets.graphql +57 -0
  35. package/src/resources/generated_queries/FilterNftPoolCollections.graphql +8 -0
  36. package/src/resources/generated_queries/FilterNftPools.graphql +7 -0
  37. package/src/resources/generated_queries/FilterPairs.graphql +60 -0
  38. package/src/resources/generated_queries/FilterTokenWallets.graphql +16 -0
  39. package/src/resources/generated_queries/FilterTokens.graphql +47 -0
  40. package/src/resources/generated_queries/FilterWallets.graphql +1 -0
  41. package/src/resources/generated_queries/GetBars.graphql +31 -0
  42. package/src/resources/generated_queries/GetCommunityNotes.graphql +16 -0
  43. package/src/resources/generated_queries/GetDetailedPairStats.graphql +30 -0
  44. package/src/resources/generated_queries/GetDetailedPairsStats.graphql +30 -0
  45. package/src/resources/generated_queries/GetDetailedStats.graphql +338 -0
  46. package/src/resources/generated_queries/GetLatestPairs.graphql +57 -0
  47. package/src/resources/generated_queries/GetLatestTokens.graphql +39 -0
  48. package/src/resources/generated_queries/GetNftEvents.graphql +9 -0
  49. package/src/resources/generated_queries/GetNftPool.graphql +2 -0
  50. package/src/resources/generated_queries/GetNftPoolCollection.graphql +8 -0
  51. package/src/resources/generated_queries/GetNftPoolCollectionsByExchange.graphql +8 -0
  52. package/src/resources/generated_queries/GetNftPoolEvents.graphql +2 -0
  53. package/src/resources/generated_queries/GetNftPoolsByCollectionAndExchange.graphql +2 -0
  54. package/src/resources/generated_queries/GetNftPoolsByOwner.graphql +2 -0
  55. package/src/resources/generated_queries/Holders.graphql +15 -0
  56. package/src/resources/generated_queries/LiquidityLocks.graphql +1 -0
  57. package/src/resources/generated_queries/ListPairsForToken.graphql +30 -0
  58. package/src/resources/generated_queries/ListPairsWithMetadataForToken.graphql +60 -0
  59. package/src/resources/generated_queries/ListTopTokens.graphql +55 -0
  60. package/src/resources/generated_queries/PairMetadata.graphql +30 -0
  61. package/src/resources/generated_queries/PrimeHolders.graphql +15 -0
  62. package/src/resources/generated_queries/SearchTokens.graphql +67 -0
  63. package/src/resources/generated_queries/Token.graphql +15 -0
  64. package/src/resources/generated_queries/Tokens.graphql +15 -0
  65. package/src/resources/generated_queries/WalletChart.graphql +1 -0
  66. package/src/resources/generated_subscriptions/OnBalanceUpdated.graphql +15 -0
  67. package/src/resources/generated_subscriptions/OnBarsUpdated.graphql +2 -10
  68. package/src/resources/generated_subscriptions/OnDetailedStatsUpdated.graphql +1 -6
  69. package/src/resources/generated_subscriptions/OnEventsCreated.graphql +0 -2
  70. package/src/resources/generated_subscriptions/OnHoldersUpdated.graphql +15 -0
  71. package/src/resources/generated_subscriptions/OnLaunchpadTokenEvent.graphql +15 -0
  72. package/src/resources/generated_subscriptions/OnNftEventsCreated.graphql +9 -0
  73. package/src/resources/generated_subscriptions/OnNftPoolEventsCreated.graphql +2 -0
  74. package/src/resources/generated_subscriptions/OnPairMetadataUpdated.graphql +32 -10
  75. package/src/resources/generated_subscriptions/OnTokenBarsUpdated.graphql +2 -10
  76. package/src/resources/graphql.schema.json +457 -5137
  77. package/src/resources/graphql.ts +183 -743
  78. package/src/resources/schema.graphql +6752 -11058
  79. package/src/sdk/Mutation.ts +4 -4
  80. package/src/sdk/Query.ts +128 -109
  81. package/src/sdk/Subscribe.ts +208 -223
  82. package/src/sdk/generated/gql.ts +106 -86
  83. package/src/sdk/generated/graphql.ts +320 -842
  84. package/src/sdk/index.test.ts +361 -10
  85. package/src/sdk/index.ts +89 -6
  86. package/src/resources/generated_queries/GetSimulateTokenContractResults.graphql +0 -128
  87. package/src/resources/generated_subscriptions/OnSimulateTokenContract.graphql +0 -121
@@ -1,6 +1,6 @@
1
1
  import { DocumentNode } from "graphql";
2
2
 
3
- import { Codex } from "./index";
3
+ import { ApiConfig, Codex } from "./index";
4
4
 
5
5
  const getNetworksDocument = {
6
6
  kind: "Document",
@@ -34,45 +34,396 @@ const subscribePriceUpdatedString = `subscription onPriceUpdated($address: Strin
34
34
 
35
35
  describe("Codex", () => {
36
36
  let sdk: Codex;
37
+
37
38
  beforeEach(() => {
38
39
  sdk = new Codex("dummy-key");
39
40
  });
40
41
 
42
+ describe("constructor", () => {
43
+ it("should initialize with default config when no apiConfig provided", () => {
44
+ const sdkInstance = new Codex("test-key");
45
+ expect(sdkInstance).toBeInstanceOf(Codex);
46
+ expect(sdkInstance.queries).toBeDefined();
47
+ expect(sdkInstance.mutations).toBeDefined();
48
+ expect(sdkInstance.subscriptions).toBeDefined();
49
+ });
50
+
51
+ it("should throw error when apiKey is not provided", () => {
52
+ expect(() => new Codex("")).toThrow("apiKey must be defined");
53
+ expect(() => new Codex(null as any)).toThrow("apiKey must be defined");
54
+ expect(() => new Codex(undefined as any)).toThrow(
55
+ "apiKey must be defined",
56
+ );
57
+ });
58
+
59
+ it("should initialize with custom apiConfig", () => {
60
+ const customConfig: Partial<ApiConfig> = {
61
+ apiUrl: "https://custom.api.com/graphql",
62
+ apiRealtimeUrl: "wss://custom.api.com/graphql",
63
+ headers: { "Custom-Header": "value" },
64
+ wsHeaders: { "WS-Header": "ws-value" },
65
+ ws: false,
66
+ };
67
+
68
+ const sdkInstance = new Codex("test-key", customConfig);
69
+ expect(sdkInstance).toBeInstanceOf(Codex);
70
+ });
71
+
72
+ it("should merge custom config with default config", () => {
73
+ const customConfig: Partial<ApiConfig> = {
74
+ headers: { "Custom-Header": "value" },
75
+ ws: false,
76
+ };
77
+
78
+ // Mock the createGraphQLClient and createWebsocketClient to verify they're called with merged config
79
+ const createGraphQLClientSpy = jest.spyOn(
80
+ Codex.prototype as any,
81
+ "createGraphQLClient",
82
+ );
83
+ const createWebsocketClientSpy = jest.spyOn(
84
+ Codex.prototype as any,
85
+ "createWebsocketClient",
86
+ );
87
+
88
+ new Codex("test-key", customConfig);
89
+
90
+ // Verify the merged config was used
91
+ expect(createGraphQLClientSpy).toHaveBeenCalledWith(
92
+ expect.objectContaining({
93
+ apiUrl: "https://graph.codex.io/graphql", // default
94
+ apiRealtimeUrl: "wss://graph.codex.io/graphql", // default
95
+ headers: { "Custom-Header": "value" }, // custom
96
+ ws: false, // custom
97
+ }),
98
+ );
99
+
100
+ createGraphQLClientSpy.mockRestore();
101
+ createWebsocketClientSpy.mockRestore();
102
+ });
103
+ });
104
+
105
+ describe("updateConfig", () => {
106
+ it("should update configuration and recreate clients", () => {
107
+ const disposeSpy = jest.spyOn(sdk, "dispose");
108
+ const createGraphQLClientSpy = jest.spyOn(
109
+ sdk as any,
110
+ "createGraphQLClient",
111
+ );
112
+ const createWebsocketClientSpy = jest.spyOn(
113
+ sdk as any,
114
+ "createWebsocketClient",
115
+ );
116
+
117
+ const newConfig: Partial<ApiConfig> = {
118
+ apiUrl: "https://new-api.com/graphql",
119
+ headers: { "New-Header": "new-value" },
120
+ };
121
+
122
+ sdk.updateConfig(newConfig);
123
+
124
+ expect(disposeSpy).toHaveBeenCalled();
125
+ expect(createGraphQLClientSpy).toHaveBeenCalled();
126
+ expect(createWebsocketClientSpy).toHaveBeenCalled();
127
+
128
+ disposeSpy.mockRestore();
129
+ createGraphQLClientSpy.mockRestore();
130
+ createWebsocketClientSpy.mockRestore();
131
+ });
132
+
133
+ it("should merge new config with existing config", () => {
134
+ const initialConfig: Partial<ApiConfig> = {
135
+ headers: { "Initial-Header": "initial-value" },
136
+ ws: true,
137
+ };
138
+
139
+ const sdkWithConfig = new Codex("test-key", initialConfig);
140
+ const parseConfigSpy = jest.spyOn(sdkWithConfig as any, "parseConfig");
141
+
142
+ const updateConfig: Partial<ApiConfig> = {
143
+ headers: { "Updated-Header": "updated-value" },
144
+ apiUrl: "https://updated-api.com/graphql",
145
+ };
146
+
147
+ sdkWithConfig.updateConfig(updateConfig);
148
+
149
+ // Verify parseConfig was called with merged configuration
150
+ expect(parseConfigSpy).toHaveBeenCalledWith(
151
+ expect.objectContaining({
152
+ headers: { "Updated-Header": "updated-value" },
153
+ apiUrl: "https://updated-api.com/graphql",
154
+ ws: true, // from initial config
155
+ }),
156
+ );
157
+
158
+ parseConfigSpy.mockRestore();
159
+ });
160
+
161
+ it("should dispose existing websocket connection before creating new one", () => {
162
+ // Mock wsClient
163
+ const mockDispose = jest.fn();
164
+ (sdk as any).wsClient = { dispose: mockDispose };
165
+
166
+ const disposeSpy = jest.spyOn(sdk, "dispose");
167
+
168
+ sdk.updateConfig({ headers: { "New-Header": "value" } });
169
+
170
+ expect(disposeSpy).toHaveBeenCalled();
171
+ disposeSpy.mockRestore();
172
+ });
173
+ });
174
+
175
+ describe("getRequestHeaders", () => {
176
+ it("should return static headers when no dynamic headers are configured", async () => {
177
+ const staticHeaders = { "Static-Header": "static-value" };
178
+ const sdkWithHeaders = new Codex("test-key", { headers: staticHeaders });
179
+
180
+ const headers = await (sdkWithHeaders as any).getRequestHeaders();
181
+
182
+ expect(headers).toEqual(staticHeaders);
183
+ });
184
+
185
+ it("should return dynamic headers when applyHeaders is configured", async () => {
186
+ const dynamicHeaders = { "Dynamic-Header": "dynamic-value" };
187
+ const applyHeaders = jest.fn().mockResolvedValue(dynamicHeaders);
188
+
189
+ const sdkWithDynamicHeaders = new Codex("test-key", { applyHeaders });
190
+
191
+ const headers = await (sdkWithDynamicHeaders as any).getRequestHeaders();
192
+
193
+ expect(applyHeaders).toHaveBeenCalled();
194
+ expect(headers).toEqual(dynamicHeaders);
195
+ });
196
+
197
+ it("should merge static and dynamic headers with dynamic taking precedence", async () => {
198
+ const staticHeaders = { "Header-1": "static", "Header-2": "static" };
199
+ const dynamicHeaders = { "Header-2": "dynamic", "Header-3": "dynamic" };
200
+ const applyHeaders = jest.fn().mockResolvedValue(dynamicHeaders);
201
+
202
+ const sdkWithBothHeaders = new Codex("test-key", {
203
+ headers: staticHeaders,
204
+ applyHeaders,
205
+ });
206
+
207
+ const headers = await (sdkWithBothHeaders as any).getRequestHeaders();
208
+
209
+ expect(headers).toEqual({
210
+ "Header-1": "static",
211
+ "Header-2": "dynamic", // dynamic overrides static
212
+ "Header-3": "dynamic",
213
+ });
214
+ });
215
+
216
+ it("should handle applyHeaders returning undefined", async () => {
217
+ const staticHeaders = { "Static-Header": "static-value" };
218
+ const applyHeaders = jest.fn().mockResolvedValue(undefined);
219
+
220
+ const sdkWithUndefinedDynamic = new Codex("test-key", {
221
+ headers: staticHeaders,
222
+ applyHeaders,
223
+ });
224
+
225
+ const headers = await (
226
+ sdkWithUndefinedDynamic as any
227
+ ).getRequestHeaders();
228
+
229
+ expect(headers).toEqual(staticHeaders);
230
+ });
231
+ });
232
+
233
+ describe("dispose", () => {
234
+ it("should dispose websocket client when it exists", async () => {
235
+ const mockDispose = jest.fn();
236
+ (sdk as any).wsClient = { dispose: mockDispose };
237
+
238
+ await sdk.dispose();
239
+
240
+ expect(mockDispose).toHaveBeenCalled();
241
+ });
242
+
243
+ it("should not throw error when websocket client is undefined", async () => {
244
+ (sdk as any).wsClient = undefined;
245
+
246
+ await expect(sdk.dispose()).resolves.not.toThrow();
247
+ });
248
+ });
249
+
250
+ describe("websocket configuration", () => {
251
+ it("should create websocket client when ws is true (default)", () => {
252
+ const createWebsocketClientSpy = jest.spyOn(
253
+ Codex.prototype as any,
254
+ "createWebsocketClient",
255
+ );
256
+
257
+ new Codex("test-key");
258
+
259
+ expect(createWebsocketClientSpy).toHaveBeenCalledWith(
260
+ expect.objectContaining({ ws: true }),
261
+ );
262
+
263
+ createWebsocketClientSpy.mockRestore();
264
+ });
265
+
266
+ it("should not create websocket client when ws is false", () => {
267
+ const createWebsocketClientSpy = jest.spyOn(
268
+ Codex.prototype as any,
269
+ "createWebsocketClient",
270
+ );
271
+
272
+ new Codex("test-key", { ws: false });
273
+
274
+ expect(createWebsocketClientSpy).toHaveBeenCalledWith(
275
+ expect.objectContaining({ ws: false }),
276
+ );
277
+
278
+ createWebsocketClientSpy.mockRestore();
279
+ });
280
+
281
+ it("should throw error when trying to subscribe without websocket enabled", () => {
282
+ const sdkWithoutWs = new Codex("test-key", { ws: false });
283
+
284
+ expect(() => {
285
+ sdkWithoutWs.subscribe(
286
+ subscribePriceUpdatedString,
287
+ { address: "0xtoken", networkId: 1 },
288
+ { next: jest.fn(), error: jest.fn(), complete: jest.fn() },
289
+ );
290
+ }).toThrow("Websocket is not enabled in the config");
291
+ });
292
+ });
293
+
41
294
  describe("query", () => {
42
- it("send a fetch request with the correct params", async () => {
295
+ it("should send a fetch request with the correct params", async () => {
43
296
  const fetchSpy = jest
44
297
  .spyOn(sdk["client"], "request")
45
298
  .mockResolvedValue({} as unknown);
299
+
46
300
  await sdk.query(getNetworksDocument, {});
301
+
47
302
  expect(fetchSpy).toHaveBeenCalledWith(getNetworksDocument, {}, {});
48
303
  });
304
+
305
+ it("should include request headers in the request", async () => {
306
+ const mockHeaders = { "Test-Header": "test-value" };
307
+ const getRequestHeadersSpy = jest
308
+ .spyOn(sdk as any, "getRequestHeaders")
309
+ .mockResolvedValue(mockHeaders);
310
+ const fetchSpy = jest
311
+ .spyOn(sdk["client"], "request")
312
+ .mockResolvedValue({} as unknown);
313
+
314
+ await sdk.query(getNetworksDocument, {});
315
+
316
+ expect(getRequestHeadersSpy).toHaveBeenCalled();
317
+ expect(fetchSpy).toHaveBeenCalledWith(
318
+ getNetworksDocument,
319
+ {},
320
+ mockHeaders,
321
+ );
322
+
323
+ getRequestHeadersSpy.mockRestore();
324
+ });
49
325
  });
326
+
327
+ describe("mutation", () => {
328
+ it("should send a request with the correct params", async () => {
329
+ const fetchSpy = jest
330
+ .spyOn(sdk["client"], "request")
331
+ .mockResolvedValue({} as unknown);
332
+
333
+ await sdk.mutation(getNetworksDocument, {});
334
+
335
+ expect(fetchSpy).toHaveBeenCalledWith(getNetworksDocument, {}, {});
336
+ });
337
+
338
+ it("should include request headers in the request", async () => {
339
+ const mockHeaders = { "Test-Header": "test-value" };
340
+ const getRequestHeadersSpy = jest
341
+ .spyOn(sdk as any, "getRequestHeaders")
342
+ .mockResolvedValue(mockHeaders);
343
+ const fetchSpy = jest
344
+ .spyOn(sdk["client"], "request")
345
+ .mockResolvedValue({} as unknown);
346
+
347
+ await sdk.mutation(getNetworksDocument, {});
348
+
349
+ expect(getRequestHeadersSpy).toHaveBeenCalled();
350
+ expect(fetchSpy).toHaveBeenCalledWith(
351
+ getNetworksDocument,
352
+ {},
353
+ mockHeaders,
354
+ );
355
+
356
+ getRequestHeadersSpy.mockRestore();
357
+ });
358
+ });
359
+
50
360
  describe("send", () => {
51
361
  it("should return the results of the query", async () => {
52
362
  const fetchSpy = jest
53
363
  .spyOn(sdk["client"], "request")
54
364
  .mockResolvedValue({} as unknown);
365
+
55
366
  await sdk.send(getNetworksString, {});
367
+
56
368
  expect(fetchSpy).toHaveBeenCalledWith(getNetworksString, {}, {});
57
369
  });
370
+
371
+ it("should include request headers in the request", async () => {
372
+ const mockHeaders = { "Test-Header": "test-value" };
373
+ const getRequestHeadersSpy = jest
374
+ .spyOn(sdk as any, "getRequestHeaders")
375
+ .mockResolvedValue(mockHeaders);
376
+ const fetchSpy = jest
377
+ .spyOn(sdk["client"], "request")
378
+ .mockResolvedValue({} as unknown);
379
+
380
+ await sdk.send(getNetworksString, {});
381
+
382
+ expect(getRequestHeadersSpy).toHaveBeenCalled();
383
+ expect(fetchSpy).toHaveBeenCalledWith(getNetworksString, {}, mockHeaders);
384
+
385
+ getRequestHeadersSpy.mockRestore();
386
+ });
58
387
  });
388
+
59
389
  describe("subscribe", () => {
60
390
  it("should return a cleanup function", () => {
61
- const next = jest.fn(),
62
- error = jest.fn(),
63
- complete = jest.fn();
64
- const sink = {
65
- next,
66
- error,
67
- complete,
68
- };
391
+ const next = jest.fn();
392
+ const error = jest.fn();
393
+ const complete = jest.fn();
394
+ const sink = { next, error, complete };
395
+
69
396
  jest.spyOn(sdk["wsClient"] as any, "subscribe").mockReturnValue(() => {});
397
+
70
398
  const cleanup = sdk.subscribe(
71
399
  subscribePriceUpdatedString,
72
400
  { address: "0xtoken", networkId: 1 },
73
401
  sink,
74
402
  );
403
+
75
404
  expect(typeof cleanup).toBe("function");
76
405
  });
406
+
407
+ it("should call wsClient.subscribe with correct parameters", () => {
408
+ const next = jest.fn();
409
+ const error = jest.fn();
410
+ const complete = jest.fn();
411
+ const sink = { next, error, complete };
412
+ const variables = { address: "0xtoken", networkId: 1 };
413
+
414
+ const subscribeSpy = jest
415
+ .spyOn(sdk["wsClient"] as any, "subscribe")
416
+ .mockReturnValue(() => {});
417
+
418
+ sdk.subscribe(subscribePriceUpdatedString, variables, sink);
419
+
420
+ expect(subscribeSpy).toHaveBeenCalledWith(
421
+ {
422
+ query: subscribePriceUpdatedString,
423
+ variables,
424
+ },
425
+ sink,
426
+ );
427
+ });
77
428
  });
78
429
  });
package/src/sdk/index.ts CHANGED
@@ -48,17 +48,34 @@ export class Codex {
48
48
  public mutations: Mutation;
49
49
  public subscriptions: Subscribe;
50
50
 
51
+ /**
52
+ * @param apiKey - The api key to use for the requests.
53
+ * @param apiConfig - The configuration to use for the requests.
54
+ */
51
55
  constructor(
52
56
  private apiKey: string,
53
57
  private apiConfig?: Partial<ApiConfig>,
54
58
  ) {
55
- invariant(this.apiKey, "apiKey must be defined");
56
- const config = Object.assign({}, defaultConfig, apiConfig);
57
-
59
+ const config = this.parseConfig(this.apiConfig ?? {});
58
60
  this.queries = new Query(this);
59
61
  this.mutations = new Mutation(this);
60
62
  this.subscriptions = new Subscribe(this);
61
- this.client = new GraphQLClient(config.apiUrl, {
63
+
64
+ this.client = this.createGraphQLClient(config);
65
+ this.wsClient = this.createWebsocketClient(config);
66
+
67
+ this.wsClient?.on("error", (error) => {
68
+ console.error("Websocket error: ", error);
69
+ });
70
+ }
71
+
72
+ private parseConfig(config: Partial<ApiConfig>) {
73
+ invariant(this.apiKey, "apiKey must be defined");
74
+ return Object.assign({}, defaultConfig, config);
75
+ }
76
+
77
+ private createGraphQLClient(config: ApiConfig) {
78
+ return new GraphQLClient(config.apiUrl, {
62
79
  method: "POST",
63
80
  headers: new Headers({
64
81
  "Content-Type": "application/json",
@@ -67,7 +84,10 @@ export class Codex {
67
84
  ...config.headers,
68
85
  }),
69
86
  });
70
- this.wsClient = config.ws
87
+ }
88
+
89
+ private createWebsocketClient(config: ApiConfig) {
90
+ return config.ws
71
91
  ? createClient({
72
92
  webSocketImpl: WebSocket,
73
93
  keepAlive: 10_000, // ping server every 10 seconds
@@ -91,6 +111,51 @@ export class Codex {
91
111
  return headers;
92
112
  }
93
113
 
114
+ /**
115
+ * Need to update the headers on the websocket connection.
116
+ * This is useful if the api key changes, or you need to modify the connection init params at all.
117
+ * NOTE: it will dispose of the old connection, so all existing subscriptions will be closed.
118
+ */
119
+ public updateConfig(incomingConfig: Partial<ApiConfig>) {
120
+ // If we have an existing websocket connection, dispose of it.
121
+ if (this.wsClient) this.dispose();
122
+
123
+ // Merge the incoming config with the existing config.
124
+ const config = this.parseConfig(
125
+ Object.assign({}, this.apiConfig, incomingConfig),
126
+ );
127
+
128
+ // Create a new websocket connection with the new headers.
129
+ this.wsClient = this.createWebsocketClient(config);
130
+ this.client = this.createGraphQLClient(config);
131
+
132
+ this.wsClient?.on("error", (error) => {
133
+ console.error("Websocket error: ", error);
134
+ });
135
+ this.wsClient?.on("closed", (er) => {
136
+ console.log("Websocket closed", er);
137
+ });
138
+ this.wsClient?.on("connecting", () => {
139
+ console.log("Websocket connecting");
140
+ });
141
+ }
142
+
143
+ /**
144
+ * Call this to dispose of the websocket connection, and make this class ready for garbage collection.
145
+ * This will also close any open subscriptions.
146
+ *
147
+ * It's useful for when you need to modify some of the configuration, or when you're done with the class.
148
+ */
149
+ public async dispose() {
150
+ this.wsClient?.dispose();
151
+ }
152
+
153
+ /**
154
+ * This is the preferred way to execute queries.
155
+ * @param doc - The graphql document node to execute.
156
+ * @param args - The variables to pass to the document.
157
+ * @returns The result of the query.
158
+ */
94
159
  public async query<TResults, TVars extends Variables>(
95
160
  doc: TypedDocumentNode<TResults, TVars>,
96
161
  args: TVars = {} as TVars,
@@ -103,6 +168,12 @@ export class Codex {
103
168
  return res as TResults;
104
169
  }
105
170
 
171
+ /**
172
+ * This is functionally the same thing as the `query` method, but it's more expressive.
173
+ * @param doc - The graphql document node to execute.
174
+ * @param args - The variables to pass to the document.
175
+ * @returns The result of the mutation.
176
+ */
106
177
  public async mutation<TResults, TVars extends Variables>(
107
178
  doc: TypedDocumentNode<TResults, TVars>,
108
179
  args: TVars = {} as TVars,
@@ -115,7 +186,13 @@ export class Codex {
115
186
  return res as TResults;
116
187
  }
117
188
 
118
- // Very simple network based fetch implementation, no compilation required
189
+ /**
190
+ * This should be used when you don't want to use graphql libaries to create a document node,
191
+ * and would rather just pass in a string.
192
+ * @param gqlString - The graphql document string to execute.
193
+ * @param args - The variables to pass to the document.
194
+ * @returns The result of the mutation.
195
+ */
119
196
  public async send<TResults, V extends Variables = Variables>(
120
197
  gqlString: string,
121
198
  args: V = {} as V,
@@ -128,6 +205,12 @@ export class Codex {
128
205
  return res;
129
206
  }
130
207
 
208
+ /**
209
+ * @param doc - The graphql document string to execute.
210
+ * @param args - The variables to pass to the document.
211
+ * @param sink - The sink to receive the results.
212
+ * @returns A cleanup function to unsubscribe from the subscription.
213
+ */
131
214
  public subscribe<
132
215
  TResults,
133
216
  TVars extends Record<string, unknown> = Record<string, never>,
@@ -1,128 +0,0 @@
1
- query GetSimulateTokenContractResults(
2
- $contractAddress: String!
3
- $cursor: String
4
- $limit: Int
5
- $networkId: Int!
6
- $simulationId: String
7
- ) {
8
- getSimulateTokenContractResults(
9
- contractAddress: $contractAddress
10
- cursor: $cursor
11
- limit: $limit
12
- networkId: $networkId
13
- simulationId: $simulationId
14
- ) {
15
- cursor
16
- results {
17
- analysisType
18
- blockNumber
19
- contractBalance {
20
- tokenContractEthBalance
21
- tokenContractTokenBalance
22
- }
23
- contractHashKey
24
- creator {
25
- creatorAddress
26
- creatorEthBalance
27
- creatorTokenBalance
28
- }
29
- deploy {
30
- deploySuccess
31
- tokenMintedToDeployer
32
- }
33
- errors {
34
- contractBalanceErrors {
35
- tokenContractEthBalanceError
36
- tokenContractTokenBalanceError
37
- }
38
- creatorErrors {
39
- creatorEthBalanceError
40
- creatorTokenBalanceError
41
- }
42
- deployErrors {
43
- deployError
44
- tokenMintedToDeployerError
45
- }
46
- liquidityErrors {
47
- addLiquidityError
48
- lpTotalSupplyError
49
- postLiquidityEnableTradingError
50
- preLiquidityEnableTradingError
51
- }
52
- ownerErrors {
53
- ownerAddressError
54
- ownerEthBalanceError
55
- ownerTokenBalanceError
56
- }
57
- simulatorError
58
- swapErrors {
59
- buyError
60
- buyErrorEnum
61
- sellError
62
- sellErrorEnum
63
- }
64
- tokenErrors {
65
- canRenounceOwnershipError
66
- canTransferOwnershipError
67
- decimalsError
68
- tokenNameError
69
- tokenSymbolError
70
- totalSupplyError
71
- }
72
- transferErrors {
73
- tokenContractApprovalError
74
- tokenTransferredToContractError
75
- userApprovalError
76
- }
77
- }
78
- id
79
- liquidity {
80
- addLiquiditySuccess
81
- liquiditySetByPreLiquidityOpenTradingCall
82
- lpTotalSupply
83
- pairAddress
84
- postLiquidityEnableTradingCall
85
- postLiquidityEnableTradingSuccess
86
- preLiquidityEnableTradingCall
87
- preLiquidityEnableTradingSuccess
88
- preLiquidityEnableTradingSupportsTransfer
89
- }
90
- networkId
91
- owner {
92
- ownerAddress
93
- ownerEthBalance
94
- ownerTokenBalance
95
- }
96
- sortKey
97
- status
98
- swap {
99
- buyGasUsed
100
- buySuccess
101
- buyTax
102
- maxBuyAmount
103
- maxSellAmount
104
- sellGasUsed
105
- sellSuccess
106
- sellTax
107
- }
108
- timestamp
109
- token {
110
- canRenounceOwnership
111
- canTransferOwnership
112
- contractAddress
113
- decimals
114
- isOwnerRenounced
115
- tokenName
116
- tokenSymbol
117
- totalSupply
118
- }
119
- transfer {
120
- tokenContractApprovalSuccess
121
- tokenTransferredToContractSuccess
122
- userApprovalSuccess
123
- }
124
- uuid
125
- uuidHashKey
126
- }
127
- }
128
- }