@vaultsfyi/sdk 1.0.0

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.
@@ -0,0 +1,5 @@
1
+
2
+ > @vaultsfyi/sdk@0.0.1 lint:fix /Users/pawel/Documents/code/vaultsfyi/packages/sdk
3
+ > biome check . --write
4
+
5
+ Checked 8 files in 22ms. No fixes applied.
@@ -0,0 +1,9 @@
1
+
2
+ > @vaultsfyi/sdk@0.0.1 lint /Users/pawel/Documents/code/vaultsfyi/packages/sdk
3
+ > pnpm typecheck && biome check .
4
+
5
+
6
+ > @vaultsfyi/sdk@0.0.1 typecheck /Users/pawel/Documents/code/vaultsfyi/packages/sdk
7
+ > tsc --noEmit
8
+
9
+ Checked 8 files in 24ms. No fixes applied.
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@vaultsfyi/sdk",
3
+ "version": "1.0.0",
4
+ "description": "An SDK for interacting with the Vaults.fyi API",
5
+ "exports": {
6
+ ".": "./src/client.ts"
7
+ },
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "devDependencies": {
12
+ "@biomejs/biome": "1.9.4",
13
+ "openapi-typescript": "^7.4.1",
14
+ "vitest": "2.1.1",
15
+ "typescript": "5.5.4"
16
+ },
17
+ "scripts": {
18
+ "updateOpenApiSchema": "openapi-typescript http://localhost:3001/v1/documentation/json -o ./src/types/openapi.ts && biome check ./src/types/openapi.ts --write",
19
+ "typecheck": "tsc --noEmit",
20
+ "lint": "pnpm typecheck && biome check .",
21
+ "lint:fix": "biome check . --write"
22
+ }
23
+ }
package/src/client.ts ADDED
@@ -0,0 +1,155 @@
1
+ import { HttpResponseError } from './errors'
2
+ import type { paths } from './types/openapi'
3
+ import { generateQueryParams } from './utils/generateQueryParams'
4
+
5
+ export interface ConstructorOptions {
6
+ apiKey: string
7
+ }
8
+
9
+ export interface InternalOptions {
10
+ apiBaseUrl: string
11
+ }
12
+
13
+ type Endpoint = keyof paths
14
+
15
+ type ExtractResponse<T> = T extends { responses: { 200: { content: { 'application/json': infer R } } } } ? R : never
16
+ type Response<T extends Endpoint> = ExtractResponse<paths[T]['get' | 'post']>
17
+
18
+ type ExtractParams<T> = T extends { parameters: infer P extends { path?: any; query?: any } }
19
+ ? Pick<P, 'path' | 'query'>
20
+ : never
21
+ type Body<T extends Endpoint> = paths[T]['post'] extends {
22
+ requestBody: { content: { 'application/json': infer R } }
23
+ }
24
+ ? { body: R }
25
+ : paths[T]['post'] extends {
26
+ requestBody?: { content: { 'application/json': infer R } }
27
+ }
28
+ ? { body?: R }
29
+ : undefined
30
+
31
+ type Params<T extends Endpoint> = Body<T> extends undefined
32
+ ? ExtractParams<paths[T]['get' | 'post']>
33
+ : ExtractParams<paths[T]['get' | 'post']> & Body<T>
34
+
35
+ type ActionEndpoint =
36
+ | '/v1/transactions/vaults/deposit'
37
+ | '/v1/transactions/vaults/redeem'
38
+ | '/v1/transactions/vaults/request-redeem'
39
+ | '/v1/transactions/vaults/claim-redeem'
40
+
41
+ export class VaultsSdk {
42
+ private apiBaseUrl: string
43
+ private apiKey: string
44
+
45
+ constructor(options: ConstructorOptions)
46
+ constructor(options: ConstructorOptions, internalOptions: InternalOptions)
47
+ constructor(options: ConstructorOptions, internalOptions?: InternalOptions) {
48
+ this.apiKey = options.apiKey
49
+ this.apiBaseUrl = internalOptions?.apiBaseUrl ?? 'https://api.vaults.fyi'
50
+ }
51
+
52
+ private async fetchData<T extends Endpoint>(
53
+ endpoint: string,
54
+ params?: Params<T>,
55
+ method: 'POST' | 'GET' = 'GET'
56
+ ): Promise<Response<T>> {
57
+ const queryParams = generateQueryParams(params?.query)
58
+
59
+ const body = (params as Body<T>)?.body
60
+ const stringifiedBody = body ? JSON.stringify(body) : undefined
61
+
62
+ const response = await fetch(`${this.apiBaseUrl}${endpoint}${queryParams}`, {
63
+ method,
64
+ headers: {
65
+ 'Content-Type': 'application/json',
66
+ 'x-api-key': this.apiKey,
67
+ },
68
+ body: stringifiedBody,
69
+ })
70
+
71
+ if (!response.ok) {
72
+ const error = await response.json()
73
+ throw new HttpResponseError(error.message)
74
+ }
75
+
76
+ return response.json()
77
+ }
78
+
79
+ async bestDepositOption(params: Params<'/v1/portfolio/best-deposit-options/{userAddress}'>) {
80
+ const { userAddress } = params.path
81
+ return await this.fetchData<'/v1/portfolio/best-deposit-options/{userAddress}'>(
82
+ `/v1/portfolio/best-deposit-options/${userAddress}`,
83
+ params,
84
+ 'POST'
85
+ )
86
+ }
87
+
88
+ async getVault(params: Params<'/v1/vaults/{network}/{vaultAddress}/'>) {
89
+ const { network, vaultAddress } = params.path
90
+ return await this.fetchData<'/v1/vaults/{network}/{vaultAddress}/'>(
91
+ `/v1/vaults/${network}/${vaultAddress}/`,
92
+ params
93
+ )
94
+ }
95
+
96
+ async getVaultHolderEvents(params: Params<'/v1/vaults/{network}/{vaultAddress}/holder-events/{holder}'>) {
97
+ const { network, vaultAddress, holder } = params.path
98
+ return await this.fetchData<'/v1/vaults/{network}/{vaultAddress}/holder-events/{holder}'>(
99
+ `/v1/vaults/${network}/${vaultAddress}/holder-events/${holder}`,
100
+ params
101
+ )
102
+ }
103
+
104
+ async getVaultTotalReturns(params: Params<'/v1/vaults/{network}/{vaultAddress}/holder-total-returns/{holder}'>) {
105
+ const { network, vaultAddress, holder } = params.path
106
+ return await this.fetchData<'/v1/vaults/{network}/{vaultAddress}/holder-total-returns/{holder}'>(
107
+ `/v1/vaults/${network}/${vaultAddress}/holder-total-returns/${holder}`,
108
+ params
109
+ )
110
+ }
111
+
112
+ async getAllVaults(params?: Params<'/v1/detailed/vaults'>) {
113
+ return await this.fetchData<'/v1/detailed/vaults'>('/v1/detailed/vaults', params)
114
+ }
115
+
116
+ async getVaultApy(params: Params<'/v1/vaults/{network}/{vaultAddress}/apy'>) {
117
+ const { network, vaultAddress } = params.path
118
+ return await this.fetchData<'/v1/vaults/{network}/{vaultAddress}/apy'>(
119
+ `/v1/vaults/${network}/${vaultAddress}/apy`,
120
+ params
121
+ )
122
+ }
123
+
124
+ async getHistoricalData(params: Params<'/v1/vaults/{network}/{vaultAddress}/historical-data'>) {
125
+ const { network, vaultAddress } = params.path
126
+ return await this.fetchData<'/v1/vaults/{network}/{vaultAddress}/historical-data'>(
127
+ `/v1/vaults/${network}/${vaultAddress}/historical-data`,
128
+ params
129
+ )
130
+ }
131
+
132
+ async getActionsDetails(params: Params<'/v1/transactions/vaults/actions/details'>) {
133
+ return await this.fetchData<'/v1/transactions/vaults/actions/details'>(
134
+ '/v1/transactions/vaults/actions/details',
135
+ params
136
+ )
137
+ }
138
+
139
+ async getWalletBalances(params: Params<'/v1/portfolio/wallet-balances'>) {
140
+ return await this.fetchData<'/v1/portfolio/wallet-balances'>('/v1/transactions/wallet-balances', params)
141
+ }
142
+
143
+ async getAllPositions(params: Params<'/v1/portfolio/positions/{userAddress}'>) {
144
+ const { userAddress } = params.path
145
+ return await this.fetchData<'/v1/portfolio/positions/{userAddress}'>(`/v1/transactions/positions/${userAddress}`)
146
+ }
147
+
148
+ async getActions(endpoint: (ActionEndpoint | string) & {}, params: Params<ActionEndpoint>) {
149
+ return await this.fetchData<ActionEndpoint>(endpoint, params)
150
+ }
151
+
152
+ async getBenchmarks() {
153
+ return await this.fetchData<'/v1/benchmarks'>('/v1/benchmarks')
154
+ }
155
+ }
package/src/errors.ts ADDED
@@ -0,0 +1 @@
1
+ export class HttpResponseError extends Error {}