@whisk/client 0.0.1 → 0.0.4
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.
- package/dist/WhiskClient.d.ts +17 -0
- package/dist/WhiskClient.js +46 -0
- package/dist/WhiskClient.js.map +1 -0
- package/dist/actions/fragments/vault.d.ts +19 -0
- package/dist/actions/fragments/vault.js +16 -0
- package/dist/actions/fragments/vault.js.map +1 -0
- package/dist/actions/getVaultSummaries.d.ts +29 -0
- package/dist/actions/getVaultSummaries.js +22 -0
- package/dist/actions/getVaultSummaries.js.map +1 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.js +19 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/scalarExchange.d.ts +3 -0
- package/dist/scalarExchange.js +14 -0
- package/dist/scalarExchange.js.map +1 -0
- package/dist/types.d.ts +8 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/package.json +12 -2
- package/src/WhiskClient.ts +63 -0
- package/src/actions/fragments/vault.ts +15 -0
- package/src/actions/getVaultSummaries.ts +27 -0
- package/src/client.test.ts +13 -2
- package/src/errors.ts +16 -0
- package/src/index.ts +3 -1
- package/src/scalarExchange.ts +12 -0
- package/src/types.ts +8 -0
- package/dist/index.d.ts.map +0 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { AnyVariables, TypedDocumentNode } from '@urql/core';
|
|
2
|
+
import { ResultAsync } from 'neverthrow';
|
|
3
|
+
import { WhiskError } from './errors.js';
|
|
4
|
+
|
|
5
|
+
interface WhiskClientConfig {
|
|
6
|
+
readonly apiKey: string;
|
|
7
|
+
readonly url?: string;
|
|
8
|
+
readonly debug?: boolean;
|
|
9
|
+
}
|
|
10
|
+
declare class WhiskClient {
|
|
11
|
+
private readonly urql;
|
|
12
|
+
private readonly debug;
|
|
13
|
+
constructor({ apiKey, url, debug }: WhiskClientConfig);
|
|
14
|
+
query<TValue, TVariables extends AnyVariables>(document: TypedDocumentNode<TValue, TVariables>, variables: TVariables): ResultAsync<TValue, WhiskError>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { WhiskClient, type WhiskClientConfig };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cacheExchange,
|
|
3
|
+
fetchExchange,
|
|
4
|
+
Client as UrqlClient
|
|
5
|
+
} from "@urql/core";
|
|
6
|
+
import { errAsync, okAsync, ResultAsync } from "neverthrow";
|
|
7
|
+
import { WhiskError } from "./errors.js";
|
|
8
|
+
import { scalarsExchange } from "./scalarExchange.js";
|
|
9
|
+
const DEFAULT_WHISK_API_URL = "https://api-v2.whisk.so/graphql";
|
|
10
|
+
class WhiskClient {
|
|
11
|
+
urql;
|
|
12
|
+
debug;
|
|
13
|
+
constructor({ apiKey, url = DEFAULT_WHISK_API_URL, debug = false }) {
|
|
14
|
+
this.urql = new UrqlClient({
|
|
15
|
+
url,
|
|
16
|
+
exchanges: [scalarsExchange, cacheExchange, fetchExchange],
|
|
17
|
+
fetchOptions: {
|
|
18
|
+
headers: {
|
|
19
|
+
Authorization: `Bearer ${apiKey}`
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
this.debug = debug;
|
|
24
|
+
}
|
|
25
|
+
query(document, variables) {
|
|
26
|
+
return ResultAsync.fromPromise(
|
|
27
|
+
this.urql.query(document, variables),
|
|
28
|
+
(error) => WhiskError.from(error)
|
|
29
|
+
).andThen((result) => {
|
|
30
|
+
if (result.error?.networkError) {
|
|
31
|
+
return errAsync(WhiskError.from(result.error.networkError));
|
|
32
|
+
}
|
|
33
|
+
if (result.data === void 0) {
|
|
34
|
+
return errAsync(WhiskError.from("No data returned from query"));
|
|
35
|
+
}
|
|
36
|
+
if ((result.error?.graphQLErrors?.length ?? 0) > 0 && this.debug) {
|
|
37
|
+
console.debug("[Whisk Client] GraphQL errors:", result.error?.graphQLErrors);
|
|
38
|
+
}
|
|
39
|
+
return okAsync(result.data);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export {
|
|
44
|
+
WhiskClient
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=WhiskClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/WhiskClient.ts"],"sourcesContent":["import {\n type AnyVariables,\n cacheExchange,\n fetchExchange,\n type TypedDocumentNode,\n Client as UrqlClient,\n} from \"@urql/core\"\nimport { errAsync, okAsync, ResultAsync } from \"neverthrow\"\nimport { WhiskError } from \"./errors.js\"\nimport { scalarsExchange } from \"./scalarExchange.js\"\n\nconst DEFAULT_WHISK_API_URL = \"https://api-v2.whisk.so/graphql\"\n\nexport interface WhiskClientConfig {\n readonly apiKey: string\n readonly url?: string\n readonly debug?: boolean\n}\n\nexport class WhiskClient {\n private readonly urql: UrqlClient\n private readonly debug: boolean\n\n constructor({ apiKey, url = DEFAULT_WHISK_API_URL, debug = false }: WhiskClientConfig) {\n this.urql = new UrqlClient({\n url,\n exchanges: [scalarsExchange, cacheExchange, fetchExchange],\n fetchOptions: {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n },\n },\n })\n\n this.debug = debug\n }\n\n public query<TValue, TVariables extends AnyVariables>(\n document: TypedDocumentNode<TValue, TVariables>,\n variables: TVariables,\n ): ResultAsync<TValue, WhiskError> {\n return ResultAsync.fromPromise(this.urql.query(document, variables), (error: unknown) =>\n WhiskError.from(error),\n ).andThen((result) => {\n // Bubbles up any network errors\n if (result.error?.networkError) {\n return errAsync(WhiskError.from(result.error.networkError))\n }\n\n // Error if we have no data\n if (result.data === undefined) {\n return errAsync(WhiskError.from(\"No data returned from query\"))\n }\n\n // Log any graphql errors (but don't put into error, since partial is fine)\n if ((result.error?.graphQLErrors?.length ?? 0) > 0 && this.debug) {\n console.debug(\"[Whisk Client] GraphQL errors:\", result.error?.graphQLErrors)\n }\n\n return okAsync(result.data)\n })\n }\n}\n"],"mappings":"AAAA;AAAA,EAEE;AAAA,EACA;AAAA,EAEA,UAAU;AAAA,OACL;AACP,SAAS,UAAU,SAAS,mBAAmB;AAC/C,SAAS,kBAAkB;AAC3B,SAAS,uBAAuB;AAEhC,MAAM,wBAAwB;AAQvB,MAAM,YAAY;AAAA,EACN;AAAA,EACA;AAAA,EAEjB,YAAY,EAAE,QAAQ,MAAM,uBAAuB,QAAQ,MAAM,GAAsB;AACrF,SAAK,OAAO,IAAI,WAAW;AAAA,MACzB;AAAA,MACA,WAAW,CAAC,iBAAiB,eAAe,aAAa;AAAA,MACzD,cAAc;AAAA,QACZ,SAAS;AAAA,UACP,eAAe,UAAU,MAAM;AAAA,QACjC;AAAA,MACF;AAAA,IACF,CAAC;AAED,SAAK,QAAQ;AAAA,EACf;AAAA,EAEO,MACL,UACA,WACiC;AACjC,WAAO,YAAY;AAAA,MAAY,KAAK,KAAK,MAAM,UAAU,SAAS;AAAA,MAAG,CAAC,UACpE,WAAW,KAAK,KAAK;AAAA,IACvB,EAAE,QAAQ,CAAC,WAAW;AAEpB,UAAI,OAAO,OAAO,cAAc;AAC9B,eAAO,SAAS,WAAW,KAAK,OAAO,MAAM,YAAY,CAAC;AAAA,MAC5D;AAGA,UAAI,OAAO,SAAS,QAAW;AAC7B,eAAO,SAAS,WAAW,KAAK,6BAA6B,CAAC;AAAA,MAChE;AAGA,WAAK,OAAO,OAAO,eAAe,UAAU,KAAK,KAAK,KAAK,OAAO;AAChE,gBAAQ,MAAM,kCAAkC,OAAO,OAAO,aAAa;AAAA,MAC7E;AAEA,aAAO,QAAQ,OAAO,IAAI;AAAA,IAC5B,CAAC;AAAA,EACH;AACF;","names":[]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as gql_tada from 'gql.tada';
|
|
2
|
+
import { FragmentOf } from '@whisk/graphql';
|
|
3
|
+
|
|
4
|
+
declare const vaultSummaryFragment: gql_tada.TadaDocumentNode<{
|
|
5
|
+
chain: {
|
|
6
|
+
id: number;
|
|
7
|
+
};
|
|
8
|
+
vaultAddress: `0x${string}`;
|
|
9
|
+
totalSupplied: {
|
|
10
|
+
raw: bigint;
|
|
11
|
+
};
|
|
12
|
+
}, {}, {
|
|
13
|
+
fragment: "VaultSummaryFragment";
|
|
14
|
+
on: "MorphoVault";
|
|
15
|
+
masked: false;
|
|
16
|
+
}>;
|
|
17
|
+
type VaultSummary = FragmentOf<typeof vaultSummaryFragment>;
|
|
18
|
+
|
|
19
|
+
export { type VaultSummary, vaultSummaryFragment };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { graphql } from "@whisk/graphql";
|
|
2
|
+
const vaultSummaryFragment = graphql(`
|
|
3
|
+
fragment VaultSummaryFragment on MorphoVault {
|
|
4
|
+
chain {
|
|
5
|
+
id
|
|
6
|
+
}
|
|
7
|
+
vaultAddress
|
|
8
|
+
totalSupplied {
|
|
9
|
+
raw
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
`);
|
|
13
|
+
export {
|
|
14
|
+
vaultSummaryFragment
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=vault.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/fragments/vault.ts"],"sourcesContent":["import { type FragmentOf, graphql } from \"@whisk/graphql\"\n\nexport const vaultSummaryFragment = graphql(`\n fragment VaultSummaryFragment on MorphoVault {\n chain {\n id\n }\n vaultAddress\n totalSupplied {\n raw\n }\n }\n`)\n\nexport type VaultSummary = FragmentOf<typeof vaultSummaryFragment>\n"],"mappings":"AAAA,SAA0B,eAAe;AAElC,MAAM,uBAAuB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAU3C;","names":[]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as gql_tada from 'gql.tada';
|
|
2
|
+
import { VariablesOf } from 'gql.tada';
|
|
3
|
+
import { ResultOf } from '@whisk/graphql';
|
|
4
|
+
import { WhiskActionFn } from '../types.js';
|
|
5
|
+
import '../WhiskClient.js';
|
|
6
|
+
import 'neverthrow';
|
|
7
|
+
import '../errors.js';
|
|
8
|
+
import '@urql/core';
|
|
9
|
+
|
|
10
|
+
declare const vaultSummaryQuery: gql_tada.TadaDocumentNode<{
|
|
11
|
+
morphoVaults: {
|
|
12
|
+
items: ({
|
|
13
|
+
chain: {
|
|
14
|
+
id: number;
|
|
15
|
+
};
|
|
16
|
+
vaultAddress: `0x${string}`;
|
|
17
|
+
totalSupplied: {
|
|
18
|
+
raw: bigint;
|
|
19
|
+
};
|
|
20
|
+
} | null)[];
|
|
21
|
+
};
|
|
22
|
+
}, {
|
|
23
|
+
limit: number;
|
|
24
|
+
}, void>;
|
|
25
|
+
type GetVaultSummariesVariables = VariablesOf<typeof vaultSummaryQuery>;
|
|
26
|
+
type GetVaultSummariesResult = ResultOf<typeof vaultSummaryQuery>["morphoVaults"]["items"];
|
|
27
|
+
declare const getVaultSummaries: WhiskActionFn<GetVaultSummariesResult, GetVaultSummariesVariables>;
|
|
28
|
+
|
|
29
|
+
export { type GetVaultSummariesResult, type GetVaultSummariesVariables, getVaultSummaries, vaultSummaryQuery };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { graphql } from "@whisk/graphql";
|
|
2
|
+
import { vaultSummaryFragment } from "./fragments/vault.js";
|
|
3
|
+
const vaultSummaryQuery = graphql(
|
|
4
|
+
`
|
|
5
|
+
query ($limit: Int!) {
|
|
6
|
+
morphoVaults(limit: $limit) {
|
|
7
|
+
items {
|
|
8
|
+
...VaultSummaryFragment
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
`,
|
|
13
|
+
[vaultSummaryFragment]
|
|
14
|
+
);
|
|
15
|
+
const getVaultSummaries = (client, variables) => {
|
|
16
|
+
return client.query(vaultSummaryQuery, variables).map((result) => result.morphoVaults.items);
|
|
17
|
+
};
|
|
18
|
+
export {
|
|
19
|
+
getVaultSummaries,
|
|
20
|
+
vaultSummaryQuery
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=getVaultSummaries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/actions/getVaultSummaries.ts"],"sourcesContent":["import { graphql, type ResultOf } from \"@whisk/graphql\"\nimport type { VariablesOf } from \"gql.tada\"\nimport type { WhiskActionFn } from \"../types.js\"\nimport { vaultSummaryFragment } from \"./fragments/vault.js\"\n\nexport const vaultSummaryQuery = graphql(\n `\n query ($limit: Int!) {\n morphoVaults(limit: $limit) {\n items {\n ...VaultSummaryFragment\n }\n }\n }\n `,\n [vaultSummaryFragment],\n)\n\nexport type GetVaultSummariesVariables = VariablesOf<typeof vaultSummaryQuery>\nexport type GetVaultSummariesResult = ResultOf<typeof vaultSummaryQuery>[\"morphoVaults\"][\"items\"]\n\nexport const getVaultSummaries: WhiskActionFn<\n GetVaultSummariesResult,\n GetVaultSummariesVariables\n> = (client, variables) => {\n return client.query(vaultSummaryQuery, variables).map((result) => result.morphoVaults.items)\n}\n"],"mappings":"AAAA,SAAS,eAA8B;AAGvC,SAAS,4BAA4B;AAE9B,MAAM,oBAAoB;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,CAAC,oBAAoB;AACvB;AAKO,MAAM,oBAGT,CAAC,QAAQ,cAAc;AACzB,SAAO,OAAO,MAAM,mBAAmB,SAAS,EAAE,IAAI,CAAC,WAAW,OAAO,aAAa,KAAK;AAC7F;","names":[]}
|
package/dist/errors.d.ts
ADDED
package/dist/errors.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class WhiskError extends Error {
|
|
2
|
+
constructor(message, options) {
|
|
3
|
+
super(message, options);
|
|
4
|
+
this.name = "WhiskError";
|
|
5
|
+
}
|
|
6
|
+
static from(error) {
|
|
7
|
+
if (error instanceof WhiskError) {
|
|
8
|
+
return error;
|
|
9
|
+
}
|
|
10
|
+
if (error instanceof Error) {
|
|
11
|
+
return new WhiskError(error.message, { cause: error });
|
|
12
|
+
}
|
|
13
|
+
return new WhiskError(String(error));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
WhiskError
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts"],"sourcesContent":["export class WhiskError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options)\n this.name = \"WhiskError\"\n }\n\n static from(error: unknown): WhiskError {\n if (error instanceof WhiskError) {\n return error\n }\n if (error instanceof Error) {\n return new WhiskError(error.message, { cause: error })\n }\n return new WhiskError(String(error))\n }\n}\n"],"mappings":"AAAO,MAAM,mBAAmB,MAAM;AAAA,EACpC,YAAY,SAAiB,SAAwB;AACnD,UAAM,SAAS,OAAO;AACtB,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,OAAO,KAAK,OAA4B;AACtC,QAAI,iBAAiB,YAAY;AAC/B,aAAO;AAAA,IACT;AACA,QAAI,iBAAiB,OAAO;AAC1B,aAAO,IAAI,WAAW,MAAM,SAAS,EAAE,OAAO,MAAM,CAAC;AAAA,IACvD;AACA,WAAO,IAAI,WAAW,OAAO,KAAK,CAAC;AAAA,EACrC;AACF;","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
1
|
+
export { GetVaultSummariesResult, GetVaultSummariesVariables, getVaultSummaries, vaultSummaryQuery } from './actions/getVaultSummaries.js';
|
|
2
|
+
export { WhiskActionFn } from './types.js';
|
|
3
|
+
export { WhiskClient, WhiskClientConfig } from './WhiskClient.js';
|
|
4
|
+
import 'gql.tada';
|
|
5
|
+
import '@whisk/graphql';
|
|
6
|
+
import 'neverthrow';
|
|
7
|
+
import './errors.js';
|
|
8
|
+
import '@urql/core';
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from \"./actions/getVaultSummaries.js\"\nexport * from \"./types.js\"\nexport * from \"./WhiskClient.js\"\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import customScalarsExchange from "@atmina/urql-custom-scalars-exchange";
|
|
2
|
+
import { schema } from "@whisk/graphql";
|
|
3
|
+
const scalarsExchange = customScalarsExchange({
|
|
4
|
+
schema,
|
|
5
|
+
scalars: {
|
|
6
|
+
BigInt(value) {
|
|
7
|
+
return BigInt(value);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
export {
|
|
12
|
+
scalarsExchange
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=scalarExchange.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/scalarExchange.ts"],"sourcesContent":["import customScalarsExchange from \"@atmina/urql-custom-scalars-exchange\"\nimport { schema } from \"@whisk/graphql\"\n\n// @ts-expect-error - Package has CJS/ESM interop issues with verbatimModuleSyntax\nexport const scalarsExchange = customScalarsExchange({\n schema,\n scalars: {\n BigInt(value: string) {\n return BigInt(value)\n },\n },\n})\n"],"mappings":"AAAA,OAAO,2BAA2B;AAClC,SAAS,cAAc;AAGhB,MAAM,kBAAkB,sBAAsB;AAAA,EACnD;AAAA,EACA,SAAS;AAAA,IACP,OAAO,OAAe;AACpB,aAAO,OAAO,KAAK;AAAA,IACrB;AAAA,EACF;AACF,CAAC;","names":[]}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ResultAsync } from 'neverthrow';
|
|
2
|
+
import { WhiskError } from './errors.js';
|
|
3
|
+
import { WhiskClient } from './WhiskClient.js';
|
|
4
|
+
import '@urql/core';
|
|
5
|
+
|
|
6
|
+
type WhiskActionFn<TData, TVariables = void> = (client: WhiskClient, variables: TVariables) => ResultAsync<TData, WhiskError>;
|
|
7
|
+
|
|
8
|
+
export type { WhiskActionFn };
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@whisk/client",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"license": "MIT",
|
|
@@ -8,7 +8,13 @@
|
|
|
8
8
|
"dist",
|
|
9
9
|
"src"
|
|
10
10
|
],
|
|
11
|
-
"dependencies": {
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@atmina/urql-custom-scalars-exchange": "^1.2.0",
|
|
13
|
+
"@urql/core": "^6.0.1",
|
|
14
|
+
"gql.tada": "1.9.0",
|
|
15
|
+
"neverthrow": "^8.2.0",
|
|
16
|
+
"@whisk/graphql": "0.0.4"
|
|
17
|
+
},
|
|
12
18
|
"sideEffects": false,
|
|
13
19
|
"module": "./dist/index.js",
|
|
14
20
|
"types": "./dist/index.d.ts",
|
|
@@ -18,5 +24,9 @@
|
|
|
18
24
|
"types": "./dist/index.d.ts",
|
|
19
25
|
"default": "./dist/index.js"
|
|
20
26
|
}
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsup",
|
|
30
|
+
"dev": "tsup --watch"
|
|
21
31
|
}
|
|
22
32
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type AnyVariables,
|
|
3
|
+
cacheExchange,
|
|
4
|
+
fetchExchange,
|
|
5
|
+
type TypedDocumentNode,
|
|
6
|
+
Client as UrqlClient,
|
|
7
|
+
} from "@urql/core"
|
|
8
|
+
import { errAsync, okAsync, ResultAsync } from "neverthrow"
|
|
9
|
+
import { WhiskError } from "./errors.js"
|
|
10
|
+
import { scalarsExchange } from "./scalarExchange.js"
|
|
11
|
+
|
|
12
|
+
const DEFAULT_WHISK_API_URL = "https://api-v2.whisk.so/graphql"
|
|
13
|
+
|
|
14
|
+
export interface WhiskClientConfig {
|
|
15
|
+
readonly apiKey: string
|
|
16
|
+
readonly url?: string
|
|
17
|
+
readonly debug?: boolean
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class WhiskClient {
|
|
21
|
+
private readonly urql: UrqlClient
|
|
22
|
+
private readonly debug: boolean
|
|
23
|
+
|
|
24
|
+
constructor({ apiKey, url = DEFAULT_WHISK_API_URL, debug = false }: WhiskClientConfig) {
|
|
25
|
+
this.urql = new UrqlClient({
|
|
26
|
+
url,
|
|
27
|
+
exchanges: [scalarsExchange, cacheExchange, fetchExchange],
|
|
28
|
+
fetchOptions: {
|
|
29
|
+
headers: {
|
|
30
|
+
Authorization: `Bearer ${apiKey}`,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
this.debug = debug
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public query<TValue, TVariables extends AnyVariables>(
|
|
39
|
+
document: TypedDocumentNode<TValue, TVariables>,
|
|
40
|
+
variables: TVariables,
|
|
41
|
+
): ResultAsync<TValue, WhiskError> {
|
|
42
|
+
return ResultAsync.fromPromise(this.urql.query(document, variables), (error: unknown) =>
|
|
43
|
+
WhiskError.from(error),
|
|
44
|
+
).andThen((result) => {
|
|
45
|
+
// Bubbles up any network errors
|
|
46
|
+
if (result.error?.networkError) {
|
|
47
|
+
return errAsync(WhiskError.from(result.error.networkError))
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Error if we have no data
|
|
51
|
+
if (result.data === undefined) {
|
|
52
|
+
return errAsync(WhiskError.from("No data returned from query"))
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Log any graphql errors (but don't put into error, since partial is fine)
|
|
56
|
+
if ((result.error?.graphQLErrors?.length ?? 0) > 0 && this.debug) {
|
|
57
|
+
console.debug("[Whisk Client] GraphQL errors:", result.error?.graphQLErrors)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return okAsync(result.data)
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type FragmentOf, graphql } from "@whisk/graphql"
|
|
2
|
+
|
|
3
|
+
export const vaultSummaryFragment = graphql(`
|
|
4
|
+
fragment VaultSummaryFragment on MorphoVault {
|
|
5
|
+
chain {
|
|
6
|
+
id
|
|
7
|
+
}
|
|
8
|
+
vaultAddress
|
|
9
|
+
totalSupplied {
|
|
10
|
+
raw
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
`)
|
|
14
|
+
|
|
15
|
+
export type VaultSummary = FragmentOf<typeof vaultSummaryFragment>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { graphql, type ResultOf } from "@whisk/graphql"
|
|
2
|
+
import type { VariablesOf } from "gql.tada"
|
|
3
|
+
import type { WhiskActionFn } from "../types.js"
|
|
4
|
+
import { vaultSummaryFragment } from "./fragments/vault.js"
|
|
5
|
+
|
|
6
|
+
export const vaultSummaryQuery = graphql(
|
|
7
|
+
`
|
|
8
|
+
query ($limit: Int!) {
|
|
9
|
+
morphoVaults(limit: $limit) {
|
|
10
|
+
items {
|
|
11
|
+
...VaultSummaryFragment
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
`,
|
|
16
|
+
[vaultSummaryFragment],
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
export type GetVaultSummariesVariables = VariablesOf<typeof vaultSummaryQuery>
|
|
20
|
+
export type GetVaultSummariesResult = ResultOf<typeof vaultSummaryQuery>["morphoVaults"]["items"]
|
|
21
|
+
|
|
22
|
+
export const getVaultSummaries: WhiskActionFn<
|
|
23
|
+
GetVaultSummariesResult,
|
|
24
|
+
GetVaultSummariesVariables
|
|
25
|
+
> = (client, variables) => {
|
|
26
|
+
return client.query(vaultSummaryQuery, variables).map((result) => result.morphoVaults.items)
|
|
27
|
+
}
|
package/src/client.test.ts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
|
+
import { describe, test } from "vitest"
|
|
2
|
+
import { getVaultSummaries, WhiskClient } from "./index.js"
|
|
3
|
+
|
|
1
4
|
describe("dummy", () => {
|
|
2
|
-
test("default", () => {
|
|
3
|
-
|
|
5
|
+
test("default", async () => {
|
|
6
|
+
const whiskClient = new WhiskClient({
|
|
7
|
+
url: "https://staging.api-v2.whisk.so/graphql",
|
|
8
|
+
apiKey: process.env.WHISK_API_KEY as string,
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
const result = await getVaultSummaries(whiskClient, { limit: 10 })
|
|
12
|
+
if (result.isOk()) {
|
|
13
|
+
console.log(result.value.map((r) => r?.totalSupplied))
|
|
14
|
+
}
|
|
4
15
|
})
|
|
5
16
|
})
|
package/src/errors.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export class WhiskError extends Error {
|
|
2
|
+
constructor(message: string, options?: ErrorOptions) {
|
|
3
|
+
super(message, options)
|
|
4
|
+
this.name = "WhiskError"
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
static from(error: unknown): WhiskError {
|
|
8
|
+
if (error instanceof WhiskError) {
|
|
9
|
+
return error
|
|
10
|
+
}
|
|
11
|
+
if (error instanceof Error) {
|
|
12
|
+
return new WhiskError(error.message, { cause: error })
|
|
13
|
+
}
|
|
14
|
+
return new WhiskError(String(error))
|
|
15
|
+
}
|
|
16
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import customScalarsExchange from "@atmina/urql-custom-scalars-exchange"
|
|
2
|
+
import { schema } from "@whisk/graphql"
|
|
3
|
+
|
|
4
|
+
// @ts-expect-error - Package has CJS/ESM interop issues with verbatimModuleSyntax
|
|
5
|
+
export const scalarsExchange = customScalarsExchange({
|
|
6
|
+
schema,
|
|
7
|
+
scalars: {
|
|
8
|
+
BigInt(value: string) {
|
|
9
|
+
return BigInt(value)
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
})
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ResultAsync } from "neverthrow"
|
|
2
|
+
import type { WhiskError } from "./errors.js"
|
|
3
|
+
import type { WhiskClient } from "./WhiskClient.js"
|
|
4
|
+
|
|
5
|
+
export type WhiskActionFn<TData, TVariables = void> = (
|
|
6
|
+
client: WhiskClient,
|
|
7
|
+
variables: TVariables,
|
|
8
|
+
) => ResultAsync<TData, WhiskError>
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM,WAAW,CAAA"}
|