From 7ee6f0c9af4f3b5b9c6458127d44c017edc0901d Mon Sep 17 00:00:00 2001 From: MikeDiam Date: Wed, 14 Feb 2024 14:02:44 +0300 Subject: [PATCH 1/5] [list requests] add requests --- .graphqlconfig | 2 +- README.md | 114 +++++++++++++++--- .../vault/blocklistAccountsQuery.graphql | 6 + src/graphql/subgraph/vault/index.ts | 6 + src/graphql/subgraph/vault/vaultQuery.graphql | 10 +- .../vault/whitelistAccountsQuery.graphql | 6 + .../vault/requests/getBlocklist/index.ts | 68 +++++++++++ .../getBlocklist/modifyBlocklist.spec.ts | 43 +++++++ .../requests/getBlocklist/modifyBlocklist.ts | 24 ++++ .../vault/requests/getBlocklist/types.ts | 6 + .../requests/getVault/modifyVault.spec.ts | 60 +-------- .../vault/requests/getVault/modifyVault.ts | 13 +- src/methods/vault/requests/getVault/types.ts | 11 +- .../vault/requests/getWhitelist/index.ts | 68 +++++++++++ .../getWhitelist/modifyWhitelist.spec.ts | 43 +++++++ .../requests/getWhitelist/modifyWhitelist.ts | 24 ++++ .../vault/requests/getWhitelist/types.ts | 6 + 17 files changed, 411 insertions(+), 99 deletions(-) create mode 100644 src/graphql/subgraph/vault/blocklistAccountsQuery.graphql create mode 100644 src/graphql/subgraph/vault/whitelistAccountsQuery.graphql create mode 100644 src/methods/vault/requests/getBlocklist/index.ts create mode 100644 src/methods/vault/requests/getBlocklist/modifyBlocklist.spec.ts create mode 100644 src/methods/vault/requests/getBlocklist/modifyBlocklist.ts create mode 100644 src/methods/vault/requests/getBlocklist/types.ts create mode 100644 src/methods/vault/requests/getWhitelist/index.ts create mode 100644 src/methods/vault/requests/getWhitelist/modifyWhitelist.spec.ts create mode 100644 src/methods/vault/requests/getWhitelist/modifyWhitelist.ts create mode 100644 src/methods/vault/requests/getWhitelist/types.ts diff --git a/.graphqlconfig b/.graphqlconfig index b69777b2..24ac2b47 100644 --- a/.graphqlconfig +++ b/.graphqlconfig @@ -11,7 +11,7 @@ "extensions": { "endpoints": { "Subgraph GraphQL": { - "url": "https://graph-testnet.stakewise.io/subgraphs/name/stakewise/stakewise", + "url": "https://holesky-graph.stakewise.io/subgraphs/name/stakewise/stakewise/graphql", "headers": { "user-agent": "JS GraphQL" }, diff --git a/README.md b/README.md index 24f55af7..6c2475ab 100644 --- a/README.md +++ b/README.md @@ -84,17 +84,19 @@ const sdk = new StakeWiseSDK({ network: Network.Mainnet }) ## Quick Links ##### Request table: -| **Vault** | **osToken** | **Utils** | -|------|-------------|------| -| [sdk.vault.getStakerActions](#sdkvaultgetstakeractions) | [sdk.osToken.getBurnAmount](#sdkostokengetburnamount) | [sdk.utils.getSwiseUsdPrice](#sdkutilsgetswiseusdprice) | -| [sdk.vault.getSnapshots](#sdkvaultgetsnapshots) | [sdk.osToken.getHealthFactor](#sdkostokengethealthfactor) | [sdk.utils.getTransactions](#sdkutilsgettransactions) | +| **Vault** | **osToken** | **Utils** | +|-------------------------------------------------------------------|-------------|------| +| [sdk.vault.getStakerActions](#sdkvaultgetstakeractions) | [sdk.osToken.getBurnAmount](#sdkostokengetburnamount) | [sdk.utils.getSwiseUsdPrice](#sdkutilsgetswiseusdprice) | +| [sdk.vault.getSnapshots](#sdkvaultgetsnapshots) | [sdk.osToken.getHealthFactor](#sdkostokengethealthfactor) | [sdk.utils.getTransactions](#sdkutilsgettransactions) | | [sdk.vault.getExitQueuePositions](#sdkvaultgetexitqueuepositions) | [sdk.osToken.getAPY](#sdkostokengetapy) | -| [sdk.vault.getValidators](#sdkvaultgetvalidators) | [sdk.osToken.getPosition](#sdkostokengetposition) | -| [sdk.vault.getVault](#sdkvaultgetvault) | [sdk.osToken.getMaxMint](#sdkostokengetmaxmint) | -| [sdk.vault.getMaxWithdraw](#sdkvaultgetmaxwithdraw) | [sdk.osToken.getBaseData](#sdkostokengetbasedata) | -| [sdk.vault.getHarvestParams](#sdkvaultgetharvestparams) | [sdk.osToken.getSharesFromAssets](#sdkostokengetsharesfromassets) | -| [sdk.vault.getStakeBalance](#sdkvaultgetstakebalance) | [sdk.osToken.getAssetsFromShares](#sdkostokengetassetsfromshares) | -|[sdk.vault.getUserRewards](#sdkvaultgetuserrewards) | [sdk.vault.getScorePercentiles](#sdkvaultgetscorepercentiles) +| [sdk.vault.getValidators](#sdkvaultgetvalidators) | [sdk.osToken.getPosition](#sdkostokengetposition) | +| [sdk.vault.getVault](#sdkvaultgetvault) | [sdk.osToken.getMaxMint](#sdkostokengetmaxmint) | +| [sdk.vault.getMaxWithdraw](#sdkvaultgetmaxwithdraw) | [sdk.osToken.getBaseData](#sdkostokengetbasedata) | +| [sdk.vault.getHarvestParams](#sdkvaultgetharvestparams) | [sdk.osToken.getSharesFromAssets](#sdkostokengetsharesfromassets) | +| [sdk.vault.getStakeBalance](#sdkvaultgetstakebalance) | [sdk.osToken.getAssetsFromShares](#sdkostokengetassetsfromshares) | +| [sdk.vault.getUserRewards](#sdkvaultgetuserrewards) | [sdk.vault.getScorePercentiles](#sdkvaultgetscorepercentiles) +| [sdk.vault.getWhitelist](#sdkvaultgetwhitelist) +| [sdk.vault.getBlocklist](#sdkvaultgetblocklist) ##### Table of transactions: | **Vault** | **osToken** | @@ -283,6 +285,90 @@ await sdk.vault.getUserRewards({ }) ``` --- +### `sdk.vault.getWhitelist` + +#### Description: + +Fetch the whitelist for private vaults. Only addresses included in this list are eligible to stake in the private vault. The number of addresses in this list is indicated by the vault whitelistCount field. + + +#### Arguments: + +| Name | Type | Type | Description | +|------|-------------------|-------------|---| +| vaultAddress | `string` | **Require** | - | +| orderDirection | `'asc' \| 'desc'` | **Optional** | Sort, by default `desc` (descending order) | +| search | `string` | **Optional** | Filters results by the address field | +| limit | `number` | **Optional** | Limit the number of addresses, default is 100 | +| skip | `number` | **Optional** | Skip the number of addresses, default is 0 | + +#### Returns: + +```ts +type List = { + createdAt: number + address: string +} + +type Output = { + whitelist: List[] +} +``` + +| Name | Description | +|------|-------------| +| `whitelist` | An array of objects representing the result of the query based on your parameters | + +#### Example: + +```ts +await sdk.vault.getWhitelist({ + vaultAddress: '0x...', +}) +``` +--- +### `sdk.vault.getBlocklist` + +#### Description: + +Fetch the blocklist for blocklisted vaults. Addresses included in this list are not eligible to stake in the blocklisted vault. The number of addresses in this list is indicated by the vault blocklistCount field. + + +#### Arguments: + +| Name | Type | Type | Description | +|------|---------------|-------------|---| +| vaultAddress | `string` | **Require** | - | +| orderDirection | `'asc' \| 'desc'` | **Optional** | Sort, by default `desc` (descending order) | +| search | `string` | **Optional** | Filters results by the address field | +| limit | `number` | **Optional** | Limit the number of addresses, default is 100 | +| skip | `number` | **Optional** | Skip the number of addresses, default is 0 | + +#### Returns: + +```ts +type List = { + createdAt: number + address: string +} + +type Output = { + blocklist: List[] +} +``` + +| Name | Description | +|------|-------------| +| `blocklist` | An array of objects representing the result of the query based on your parameters | + +#### Example: + +```ts +await sdk.vault.getBlocklist({ + vaultAddress: '0x...', +}) +``` +--- ### `sdk.vault.getExitQueuePositions` #### Description: @@ -407,14 +493,6 @@ type Output = { tokenSymbol: string | null displayName: string | null description: string | null - whitelist: Array<{ - createdAt: number - address: string - }> | null - blocklist: Array<{ - createdAt: number - address: string - }> | null performance: number } ``` diff --git a/src/graphql/subgraph/vault/blocklistAccountsQuery.graphql b/src/graphql/subgraph/vault/blocklistAccountsQuery.graphql new file mode 100644 index 00000000..10584a29 --- /dev/null +++ b/src/graphql/subgraph/vault/blocklistAccountsQuery.graphql @@ -0,0 +1,6 @@ +query BlocklistAccounts($where: VaultBlockedAccount_filter, $limit: Int, $skip: Int, $orderDirection: OrderDirection) { + vaultBlockedAccounts(where: $where, first: $limit, skip: $skip, orderDirection: $orderDirection, orderBy: createdAt) { + createdAt + address + } +} diff --git a/src/graphql/subgraph/vault/index.ts b/src/graphql/subgraph/vault/index.ts index 47edabe5..77ef49f7 100644 --- a/src/graphql/subgraph/vault/index.ts +++ b/src/graphql/subgraph/vault/index.ts @@ -3,3 +3,9 @@ export type { VaultQueryPayload, VaultQueryVariables } from './vaultQuery.graphq export { fetchHarvestParamsQuery } from './harvestParamsQuery.graphql' export type { HarvestParamsQueryPayload, HarvestParamsQueryVariables } from './harvestParamsQuery.graphql' + +export { fetchWhitelistAccountsQuery } from './whitelistAccountsQuery.graphql' +export type { WhitelistAccountsQueryPayload, WhitelistAccountsQueryVariables } from './whitelistAccountsQuery.graphql' + +export { fetchBlocklistAccountsQuery } from './blocklistAccountsQuery.graphql' +export type { BlocklistAccountsQueryPayload, BlocklistAccountsQueryVariables } from './blocklistAccountsQuery.graphql' diff --git a/src/graphql/subgraph/vault/vaultQuery.graphql b/src/graphql/subgraph/vault/vaultQuery.graphql index 7226ab33..35d86c98 100644 --- a/src/graphql/subgraph/vault/vaultQuery.graphql +++ b/src/graphql/subgraph/vault/vaultQuery.graphql @@ -23,13 +23,7 @@ query Vault($address: ID!) { validatorsRoot blocklistManager weeklyApy - } - privateVaultAccounts(where: { vault: $address }, first: 1000) { - createdAt - address - } - vaultBlockedAccounts(where: { vault: $address }, first: 1000) { - createdAt - address + blocklistCount + whitelistCount } } diff --git a/src/graphql/subgraph/vault/whitelistAccountsQuery.graphql b/src/graphql/subgraph/vault/whitelistAccountsQuery.graphql new file mode 100644 index 00000000..e7a0e5b1 --- /dev/null +++ b/src/graphql/subgraph/vault/whitelistAccountsQuery.graphql @@ -0,0 +1,6 @@ +query WhitelistAccounts($where: PrivateVaultAccount_filter, $limit: Int, $skip: Int, $orderDirection: OrderDirection) { + privateVaultAccounts(where: $where, first: $limit, skip: $skip, orderDirection: $orderDirection, orderBy: createdAt) { + createdAt + address + } +} diff --git a/src/methods/vault/requests/getBlocklist/index.ts b/src/methods/vault/requests/getBlocklist/index.ts new file mode 100644 index 00000000..42625200 --- /dev/null +++ b/src/methods/vault/requests/getBlocklist/index.ts @@ -0,0 +1,68 @@ +import type { BlocklistAccountsQueryVariables, BlocklistAccountsQueryPayload } from '../../../../graphql/subgraph/vault' +import { apiUrls, validateArgs } from '../../../../utils' +import graphql from '../../../../graphql' +import { ModifiedBlocklist } from './types' +import modifyBlocklist from './modifyBlocklist' + + +type GetBlocklistInput = { + vaultAddress: string + orderDirection?: BlocklistAccountsQueryVariables['orderDirection'] + search?: string + limit?: number + skip?: number + options: StakeWise.Options +} + +type GetBlocklistOutput = { + blocklist: { + createdAt: number + address: string + }[] +} + +const getBlocklist = async (input: GetBlocklistInput): Promise => { + const { vaultAddress, orderDirection, search, limit, skip, options } = input + + validateArgs.address({ vaultAddress }) + + if (typeof skip !== 'undefined') { + validateArgs.number({ skip }) + } + + if (typeof limit !== 'undefined') { + validateArgs.number({ limit }) + } + + if (typeof search !== 'undefined') { + validateArgs.string({ search }) + } + + if (typeof orderDirection !== 'undefined') { + if (![ 'asc', 'desc' ].includes(orderDirection)) { + throw new Error(`The "orderDirection" argument must be "asc" or "desc"`) + } + } + + const where = search + ? { vault: vaultAddress, address_contains: search } as BlocklistAccountsQueryVariables['where'] + : { vault: vaultAddress } as BlocklistAccountsQueryVariables['where'] + + const data = await graphql.subgraph.vault.fetchBlocklistAccountsQuery({ + url: apiUrls.getSubgraphqlUrl(options), + variables: { + where, + skip: skip || 0, + limit: limit || 100, + orderDirection: orderDirection || 'desc', + }, + modifyResult: (data: BlocklistAccountsQueryPayload) => modifyBlocklist({ data }), + }) + + return { + blocklist: data, + } +} + + +export default getBlocklist diff --git a/src/methods/vault/requests/getBlocklist/modifyBlocklist.spec.ts b/src/methods/vault/requests/getBlocklist/modifyBlocklist.spec.ts new file mode 100644 index 00000000..2c1e93cd --- /dev/null +++ b/src/methods/vault/requests/getBlocklist/modifyBlocklist.spec.ts @@ -0,0 +1,43 @@ +import modifyBlocklist from './modifyBlocklist' +import type { BlocklistAccountsQueryPayload } from '../../../../graphql/subgraph/vault' + + +describe('modifyBlocklist', () => { + const mockBlocklistQueryPayload: BlocklistAccountsQueryPayload = { + vaultBlockedAccounts: [ + { createdAt: '1693395816', address: '0xeefffd4c23d2e8c845870e273861e7d60df49663' }, + { createdAt: '1693395816', address: '0xeefffd4c23d2e8c845870e273861e7d60df49663' }, + ], + } + + it('should correctly transform the whitelist data', () => { + const expectedModifiedVault = [ + { + createdAt: 1693395816000, + address: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', + }, + { + createdAt: 1693395816000, + address: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', + }, + ] + + const result = modifyBlocklist({ + data: mockBlocklistQueryPayload, + }) + + expect(result).toEqual(expectedModifiedVault) + }) + + it('should handle empty privateVaultAccounts correctly', () => { + const mockDataWithoutBlockedAccounts: BlocklistAccountsQueryPayload = { + vaultBlockedAccounts: [], + } + + const result = modifyBlocklist({ + data: mockDataWithoutBlockedAccounts, + }) + + expect(result).toEqual([]) + }) +}) diff --git a/src/methods/vault/requests/getBlocklist/modifyBlocklist.ts b/src/methods/vault/requests/getBlocklist/modifyBlocklist.ts new file mode 100644 index 00000000..127a4b8f --- /dev/null +++ b/src/methods/vault/requests/getBlocklist/modifyBlocklist.ts @@ -0,0 +1,24 @@ +import { getAddress } from 'ethers' + +import { ModifiedBlocklist } from './types' +import type { BlocklistAccountsQueryPayload } from '../../../../graphql/subgraph/vault' + + +type ModifyBlocklistInput = { + data: BlocklistAccountsQueryPayload +} + +const modifyAddress = ({ createdAt, address }: { createdAt: string, address: string }) => ({ + createdAt: Number(createdAt) * 1000, + address: getAddress(address), +}) + +const modifyBlocklist = (input: ModifyBlocklistInput): ModifiedBlocklist => { + const { data } = input + const { vaultBlockedAccounts } = data + + return vaultBlockedAccounts.map(modifyAddress) +} + + +export default modifyBlocklist diff --git a/src/methods/vault/requests/getBlocklist/types.ts b/src/methods/vault/requests/getBlocklist/types.ts new file mode 100644 index 00000000..3f55a3a1 --- /dev/null +++ b/src/methods/vault/requests/getBlocklist/types.ts @@ -0,0 +1,6 @@ +type ListItem = { + createdAt: number + address: string +} + +export type ModifiedBlocklist = ListItem[] diff --git a/src/methods/vault/requests/getVault/modifyVault.spec.ts b/src/methods/vault/requests/getVault/modifyVault.spec.ts index 7a20ccd4..04ccb0a1 100644 --- a/src/methods/vault/requests/getVault/modifyVault.spec.ts +++ b/src/methods/vault/requests/getVault/modifyVault.spec.ts @@ -21,6 +21,8 @@ describe('modifyVault', () => { createdAt: '1693395816', displayName: 'Mock Vault', weeklyApy: '2.80', + blocklistCount: '0', + whitelistCount: '0', totalAssets: '150000000000', capacity: '1000000000000000', validatorsRoot: 'mockValidators', @@ -33,14 +35,6 @@ describe('modifyVault', () => { feeRecipient: '0xeefffd4c23d2e8c845870e273861e7d60df49663', blocklistManager: '0xeefffd4c23d2e8c845870e273861e7d60df49663', }, - privateVaultAccounts: [ - { createdAt: '1693395816', address: '0xeefffd4c23d2e8c845870e273861e7d60df49663' }, - { createdAt: '1693395816', address: '0xeefffd4c23d2e8c845870e273861e7d60df49663' }, - ], - vaultBlockedAccounts: [ - { createdAt: '1693395817', address: '0xeefffd4c23d2e8c845870e273861e7d60df49663' }, - { createdAt: '1693395817', address: '0xeefffd4c23d2e8c845870e273861e7d60df49663' }, - ], } it('should correctly transform the vault data', () => { @@ -51,6 +45,8 @@ describe('modifyVault', () => { performance: 10, isPrivate: false, isBlocklist: false, + blocklistCount: 0, + whitelistCount: 0, capacity: '0.001', tokenSymbol: 'mTKN', imageUrl: 'mockUrl', @@ -68,26 +64,6 @@ describe('modifyVault', () => { mevRecipient: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', vaultKeysManager: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', blocklistManager: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', - whitelist: [ - { - createdAt: 1693395816000, - address: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', - }, - { - createdAt: 1693395816000, - address: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', - }, - ], - blocklist: [ - { - createdAt: 1693395817000, - address: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', - }, - { - createdAt: 1693395817000, - address: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', - }, - ], } const result = modifyVault({ @@ -115,34 +91,6 @@ describe('modifyVault', () => { expect(result.mevRecipient).toEqual(configs[network].addresses.base.sharedMevEscrow) }) - it('should handle empty privateVaultAccounts correctly', () => { - const mockDataWithoutPrivateAccounts: VaultQueryPayload = { - ...mockVaultQueryPayload, - privateVaultAccounts: [], - } - - const result = modifyVault({ - data: mockDataWithoutPrivateAccounts, - network, - }) - - expect(result.whitelist).toEqual([]) - }) - - it('should handle empty vaultBlockedAccounts correctly', () => { - const mockDataWithoutBlockedAccounts: VaultQueryPayload = { - ...mockVaultQueryPayload, - vaultBlockedAccounts: [], - } - - const result = modifyVault({ - data: mockDataWithoutBlockedAccounts, - network, - }) - - expect(result.blocklist).toEqual([]) - }) - it('should handle feePercent being 0', () => { const mockDataWithZeroFee: VaultQueryPayload = { ...mockVaultQueryPayload, diff --git a/src/methods/vault/requests/getVault/modifyVault.ts b/src/methods/vault/requests/getVault/modifyVault.ts index ba2717da..e08ae507 100644 --- a/src/methods/vault/requests/getVault/modifyVault.ts +++ b/src/methods/vault/requests/getVault/modifyVault.ts @@ -10,14 +10,9 @@ type ModifyVaultInput = { network: Network } -const modifyAddress = ({ createdAt, address }: { createdAt: string, address: string }) => ({ - createdAt: Number(createdAt) * 1000, - address: getAddress(address), -}) - const modifyVault = (input: ModifyVaultInput): ModifiedVault => { const { data, network } = input - const { vault, privateVaultAccounts, vaultBlockedAccounts } = data + const { vault } = data const { admin, @@ -29,6 +24,8 @@ const modifyVault = (input: ModifyVaultInput): ModifiedVault => { keysManager, totalAssets, feeRecipient, + blocklistCount, + whitelistCount, weeklyApy, ...rest } = vault @@ -45,10 +42,10 @@ const modifyVault = (input: ModifyVaultInput): ModifiedVault => { feeRecipient: getAddress(feeRecipient), vaultKeysManager: getAddress(keysManager), apy: Number(weeklyApy), + blocklistCount: Number(blocklistCount), + whitelistCount: Number(whitelistCount), whitelister: vault.whitelister ? getAddress(vault.whitelister) : '', blocklistManager: vault.blocklistManager ? getAddress(vault.blocklistManager) : '', - whitelist: privateVaultAccounts.map(modifyAddress), - blocklist: vaultBlockedAccounts.map(modifyAddress), mevRecipient: mevEscrow ? getAddress(mevEscrow) : configs[network].addresses.base.sharedMevEscrow, diff --git a/src/methods/vault/requests/getVault/types.ts b/src/methods/vault/requests/getVault/types.ts index 998b1bf6..61fab980 100644 --- a/src/methods/vault/requests/getVault/types.ts +++ b/src/methods/vault/requests/getVault/types.ts @@ -1,14 +1,9 @@ import type { VaultQueryPayload } from '../../../../graphql/subgraph/vault' -type ListItem = { - createdAt: number - address: string -} - export type ModifiedVault = Omit< VaultQueryPayload['vault'], - 'admin' | 'address' | 'mevEscrow' | 'keysManager' | 'weeklyApy' | 'performance' | 'createdAt' + 'admin' | 'address' | 'mevEscrow' | 'keysManager' | 'weeklyApy' | 'performance' | 'createdAt' | 'blocklistCount' | 'whitelistCount' > & { apy: number createdAt: number @@ -16,8 +11,8 @@ export type ModifiedVault = Omit< performance: number vaultAddress: string mevRecipient: string + blocklistCount: number + whitelistCount: number vaultKeysManager: string isSmoothingPool: boolean - whitelist: ListItem[] - blocklist: ListItem[] } diff --git a/src/methods/vault/requests/getWhitelist/index.ts b/src/methods/vault/requests/getWhitelist/index.ts new file mode 100644 index 00000000..ace37096 --- /dev/null +++ b/src/methods/vault/requests/getWhitelist/index.ts @@ -0,0 +1,68 @@ +import type { WhitelistAccountsQueryVariables, WhitelistAccountsQueryPayload } from '../../../../graphql/subgraph/vault' +import { apiUrls, validateArgs } from '../../../../utils' +import graphql from '../../../../graphql' +import { ModifiedWhitelist } from './types' +import modifyWhitelist from './modifyWhitelist' + + +type GetWhitelistInput = { + vaultAddress: string + orderDirection?: WhitelistAccountsQueryVariables['orderDirection'] + search?: string + limit?: number + skip?: number + options: StakeWise.Options +} + +type GetWhitelistOutput = { + whitelist: { + createdAt: number + address: string + }[] +} + +const getWhitelist = async (input: GetWhitelistInput): Promise => { + const { vaultAddress, orderDirection, search, limit, skip, options } = input + + validateArgs.address({ vaultAddress }) + + if (typeof skip !== 'undefined') { + validateArgs.number({ skip }) + } + + if (typeof limit !== 'undefined') { + validateArgs.number({ limit }) + } + + if (typeof search !== 'undefined') { + validateArgs.string({ search }) + } + + if (typeof orderDirection !== 'undefined') { + if (![ 'asc', 'desc' ].includes(orderDirection)) { + throw new Error(`The "orderDirection" argument must be "asc" or "desc"`) + } + } + + const where = search + ? { vault: vaultAddress, address_contains: search } as WhitelistAccountsQueryVariables['where'] + : { vault: vaultAddress } as WhitelistAccountsQueryVariables['where'] + + const data = await graphql.subgraph.vault.fetchWhitelistAccountsQuery({ + url: apiUrls.getSubgraphqlUrl(options), + variables: { + where, + skip: skip || 0, + limit: limit || 100, + orderDirection: orderDirection || 'desc', + }, + modifyResult: (data: WhitelistAccountsQueryPayload) => modifyWhitelist({ data }), + }) + + return { + whitelist: data, + } +} + + +export default getWhitelist diff --git a/src/methods/vault/requests/getWhitelist/modifyWhitelist.spec.ts b/src/methods/vault/requests/getWhitelist/modifyWhitelist.spec.ts new file mode 100644 index 00000000..3d912b4b --- /dev/null +++ b/src/methods/vault/requests/getWhitelist/modifyWhitelist.spec.ts @@ -0,0 +1,43 @@ +import modifyWhitelist from './modifyWhitelist' +import type { WhitelistAccountsQueryPayload } from '../../../../graphql/subgraph/vault' + + +describe('modifyWhitelist', () => { + const mockWhitelistQueryPayload: WhitelistAccountsQueryPayload = { + privateVaultAccounts: [ + { createdAt: '1693395816', address: '0xeefffd4c23d2e8c845870e273861e7d60df49663' }, + { createdAt: '1693395816', address: '0xeefffd4c23d2e8c845870e273861e7d60df49663' }, + ], + } + + it('should correctly transform the whitelist data', () => { + const expectedModifiedVault = [ + { + createdAt: 1693395816000, + address: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', + }, + { + createdAt: 1693395816000, + address: '0xeEFFFD4C23D2E8c845870e273861e7d60Df49663', + }, + ] + + const result = modifyWhitelist({ + data: mockWhitelistQueryPayload, + }) + + expect(result).toEqual(expectedModifiedVault) + }) + + it('should handle empty privateVaultAccounts correctly', () => { + const mockDataWithoutPrivateAccounts: WhitelistAccountsQueryPayload = { + privateVaultAccounts: [], + } + + const result = modifyWhitelist({ + data: mockDataWithoutPrivateAccounts, + }) + + expect(result).toEqual([]) + }) +}) diff --git a/src/methods/vault/requests/getWhitelist/modifyWhitelist.ts b/src/methods/vault/requests/getWhitelist/modifyWhitelist.ts new file mode 100644 index 00000000..8ce10da1 --- /dev/null +++ b/src/methods/vault/requests/getWhitelist/modifyWhitelist.ts @@ -0,0 +1,24 @@ +import { getAddress } from 'ethers' + +import { ModifiedWhitelist } from './types' +import type { WhitelistAccountsQueryPayload } from '../../../../graphql/subgraph/vault' + + +type ModifyWhitelistInput = { + data: WhitelistAccountsQueryPayload +} + +const modifyAddress = ({ createdAt, address }: { createdAt: string, address: string }) => ({ + createdAt: Number(createdAt) * 1000, + address: getAddress(address), +}) + +const modifyWhitelist = (input: ModifyWhitelistInput): ModifiedWhitelist => { + const { data } = input + const { privateVaultAccounts } = data + + return privateVaultAccounts.map(modifyAddress) +} + + +export default modifyWhitelist diff --git a/src/methods/vault/requests/getWhitelist/types.ts b/src/methods/vault/requests/getWhitelist/types.ts new file mode 100644 index 00000000..7ec341ac --- /dev/null +++ b/src/methods/vault/requests/getWhitelist/types.ts @@ -0,0 +1,6 @@ +type ListItem = { + createdAt: number + address: string +} + +export type ModifiedWhitelist = ListItem[] From 2615c97620518426d423de986eba4191715ef62f Mon Sep 17 00:00:00 2001 From: MikeDiam Date: Wed, 14 Feb 2024 14:08:43 +0300 Subject: [PATCH 2/5] [list requests] add requests --- README.md | 56 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 6c2475ab..bcc8e2ba 100644 --- a/README.md +++ b/README.md @@ -485,6 +485,8 @@ type Output = { whitelister: string vaultAddress: string mevRecipient: string + whitelistCount: number + blocklistCount: number imageUrl: string | null blocklistManager: string vaultKeysManager: string @@ -497,32 +499,34 @@ type Output = { } ``` -| Name | Description | -|--------------------|-----------------------------------------| -| `apy` | Current vault apy | -| `isErc20` | Does the vault have its own ERC20 token | -| `capacity` | Maximum TVL of Vault | -| `createdAt` | Date of Creation | -| `feePercent` | Commission rate | -| `isPrivate` | Whether the storage is private | -| `isBlocklist` | Whether the storage has blocklist | -| `vaultAdmin` | Vault administrator address | -| `totalAssets` | TVL of Vault | -| `feeRecipient` | Vault fee address | -| `whitelister` | Whitelist manager | -| `vaultAddress` | Address of vault | -| `mevRecipient` | Validator fee recipient | -| `imageUrl` | Link for vault logo | -| `blocklistManager` | Blocklist manager | -| `vaultKeysManager` | Keys manager address | -| `isSmoothingPool` | Smoothing poll or Vault escrow | -| `tokenName` | ERC20 token name | -| `tokenSymbol` | ERC20 token symbol | -| `displayName` | Name of vault | -| `description` | Description of vault | -| `whitelist` | List of authorized users for deposits | -| `blocklist` | List of blocked users for deposits | -| `performance` | Vault performance indicator (percent) | +| Name | Description | +|--------------------|---------------------------------------------------------------| +| `apy` | Current vault apy | +| `isErc20` | Does the vault have its own ERC20 token | +| `capacity` | Maximum TVL of Vault | +| `createdAt` | Date of Creation | +| `feePercent` | Commission rate | +| `isPrivate` | Whether the storage is private | +| `isBlocklist` | Whether the storage has blocklist | +| `vaultAdmin` | Vault administrator address | +| `totalAssets` | TVL of Vault | +| `feeRecipient` | Vault fee address | +| `whitelister` | Whitelist manager | +| `vaultAddress` | Address of vault | +| `mevRecipient` | Validator fee recipient | +| `whitelistCount` | Number of addresses in the [whitelist](#sdkvaultgetwhitelist) | +| `blocklistCount` | Number of addresses in the [blocklist](#sdkvaultgetblocklist) | +| `imageUrl` | Link for vault logo | +| `blocklistManager` | Blocklist manager | +| `vaultKeysManager` | Keys manager address | +| `isSmoothingPool` | Smoothing poll or Vault escrow | +| `tokenName` | ERC20 token name | +| `tokenSymbol` | ERC20 token symbol | +| `displayName` | Name of vault | +| `description` | Description of vault | +| `whitelist` | List of authorized users for deposits | +| `blocklist` | List of blocked users for deposits | +| `performance` | Vault performance indicator (percent) | #### Example: From 015ffa4fbc6a0c46494d037d67c5226e69616d39 Mon Sep 17 00:00:00 2001 From: MikeDiam Date: Fri, 16 Feb 2024 09:48:26 +0300 Subject: [PATCH 3/5] [list requests] update list modal --- src/methods/vault/index.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/methods/vault/index.ts b/src/methods/vault/index.ts index 1faef0fc..5d7dc01d 100644 --- a/src/methods/vault/index.ts +++ b/src/methods/vault/index.ts @@ -1,6 +1,8 @@ // Requests import getVault from './requests/getVault' import getSnapshots from './requests/getSnapshots' +import getWhitelist from './requests/getWhitelist' +import getBlocklist from './requests/getBlocklist' import getValidators from './requests/getValidators' import getUserRewards from './requests/getUserRewards' import getMaxWithdraw from './requests/getMaxWithdraw' @@ -27,6 +29,8 @@ export default { getMaxWithdraw, getValidators, getSnapshots, + getWhitelist, + getBlocklist, getVault, }, transactions: { From 07794d22deda05b4dd22ffe57b82e16fb61770c4 Mon Sep 17 00:00:00 2001 From: MikeDiam Date: Fri, 16 Feb 2024 10:08:35 +0300 Subject: [PATCH 4/5] [api cache] return abort request --- src/methods/vault/requests/getBlocklist/index.ts | 6 +----- src/methods/vault/requests/getBlocklist/modifyBlocklist.ts | 4 +++- src/methods/vault/requests/getBlocklist/types.ts | 4 +++- src/methods/vault/requests/getWhitelist/index.ts | 6 +----- src/methods/vault/requests/getWhitelist/modifyWhitelist.ts | 4 +++- src/methods/vault/requests/getWhitelist/types.ts | 4 +++- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/methods/vault/requests/getBlocklist/index.ts b/src/methods/vault/requests/getBlocklist/index.ts index 42625200..70697d26 100644 --- a/src/methods/vault/requests/getBlocklist/index.ts +++ b/src/methods/vault/requests/getBlocklist/index.ts @@ -48,7 +48,7 @@ const getBlocklist = async (input: GetBlocklistInput): Promise({ + return graphql.subgraph.vault.fetchBlocklistAccountsQuery({ url: apiUrls.getSubgraphqlUrl(options), variables: { where, @@ -58,10 +58,6 @@ const getBlocklist = async (input: GetBlocklistInput): Promise modifyBlocklist({ data }), }) - - return { - blocklist: data, - } } diff --git a/src/methods/vault/requests/getBlocklist/modifyBlocklist.ts b/src/methods/vault/requests/getBlocklist/modifyBlocklist.ts index 127a4b8f..bdbbec9b 100644 --- a/src/methods/vault/requests/getBlocklist/modifyBlocklist.ts +++ b/src/methods/vault/requests/getBlocklist/modifyBlocklist.ts @@ -17,7 +17,9 @@ const modifyBlocklist = (input: ModifyBlocklistInput): ModifiedBlocklist => { const { data } = input const { vaultBlockedAccounts } = data - return vaultBlockedAccounts.map(modifyAddress) + return { + blocklist: vaultBlockedAccounts.map(modifyAddress), + } } diff --git a/src/methods/vault/requests/getBlocklist/types.ts b/src/methods/vault/requests/getBlocklist/types.ts index 3f55a3a1..15e30734 100644 --- a/src/methods/vault/requests/getBlocklist/types.ts +++ b/src/methods/vault/requests/getBlocklist/types.ts @@ -3,4 +3,6 @@ type ListItem = { address: string } -export type ModifiedBlocklist = ListItem[] +export type ModifiedBlocklist = { + blocklist: ListItem[] +} diff --git a/src/methods/vault/requests/getWhitelist/index.ts b/src/methods/vault/requests/getWhitelist/index.ts index ace37096..18201e71 100644 --- a/src/methods/vault/requests/getWhitelist/index.ts +++ b/src/methods/vault/requests/getWhitelist/index.ts @@ -48,7 +48,7 @@ const getWhitelist = async (input: GetWhitelistInput): Promise({ + return graphql.subgraph.vault.fetchWhitelistAccountsQuery({ url: apiUrls.getSubgraphqlUrl(options), variables: { where, @@ -58,10 +58,6 @@ const getWhitelist = async (input: GetWhitelistInput): Promise modifyWhitelist({ data }), }) - - return { - whitelist: data, - } } diff --git a/src/methods/vault/requests/getWhitelist/modifyWhitelist.ts b/src/methods/vault/requests/getWhitelist/modifyWhitelist.ts index 8ce10da1..9a56fcdf 100644 --- a/src/methods/vault/requests/getWhitelist/modifyWhitelist.ts +++ b/src/methods/vault/requests/getWhitelist/modifyWhitelist.ts @@ -17,7 +17,9 @@ const modifyWhitelist = (input: ModifyWhitelistInput): ModifiedWhitelist => { const { data } = input const { privateVaultAccounts } = data - return privateVaultAccounts.map(modifyAddress) + return { + whitelist: privateVaultAccounts.map(modifyAddress), + } } diff --git a/src/methods/vault/requests/getWhitelist/types.ts b/src/methods/vault/requests/getWhitelist/types.ts index 7ec341ac..552e706f 100644 --- a/src/methods/vault/requests/getWhitelist/types.ts +++ b/src/methods/vault/requests/getWhitelist/types.ts @@ -3,4 +3,6 @@ type ListItem = { address: string } -export type ModifiedWhitelist = ListItem[] +export type ModifiedWhitelist = { + whitelist: ListItem[] +} From 312e236819bd448acc71a4616c473569e4ac3f44 Mon Sep 17 00:00:00 2001 From: MikeDiam Date: Mon, 19 Feb 2024 14:31:20 +0300 Subject: [PATCH 5/5] [list requests] update requests --- src/methods/vault/requests/getBlocklist/index.ts | 6 ++++-- src/methods/vault/requests/getWhitelist/index.ts | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/methods/vault/requests/getBlocklist/index.ts b/src/methods/vault/requests/getBlocklist/index.ts index 70697d26..6772ba27 100644 --- a/src/methods/vault/requests/getBlocklist/index.ts +++ b/src/methods/vault/requests/getBlocklist/index.ts @@ -44,9 +44,11 @@ const getBlocklist = async (input: GetBlocklistInput): Promise({ url: apiUrls.getSubgraphqlUrl(options), diff --git a/src/methods/vault/requests/getWhitelist/index.ts b/src/methods/vault/requests/getWhitelist/index.ts index 18201e71..901e8947 100644 --- a/src/methods/vault/requests/getWhitelist/index.ts +++ b/src/methods/vault/requests/getWhitelist/index.ts @@ -44,9 +44,11 @@ const getWhitelist = async (input: GetWhitelistInput): Promise({ url: apiUrls.getSubgraphqlUrl(options),