diff --git a/README.md b/README.md index e60a7785..63f1fccb 100644 --- a/README.md +++ b/README.md @@ -175,6 +175,46 @@ await sdk.vault.getDaySnapshots({ }) ``` --- +### `sdk.vault.getUserRewards` + +#### Description: + +Daily rewards for the user who has made a deposit in the vault. With the help of this data it is possible to build a chart. + +#### Arguments: + +| Name | Type | Type | Description | +|------|----------|-------------|---------| +| dateFrom | `string` | **Require** | Time to start | +| vaultAddress | `string` | **Require** | - | +| userAddress | `string` | **Require** | - | + +#### Returns: + +```ts +type UserReward = { + rewards: number +} + +type Output = { + days: Record +} +``` + +| Name | Description | +|------|-------------| +| `days` | The result of the query on your parameters, is returned as an object where the keys are timestamps | + +#### Example: + +```ts +await sdk.vault.getUserRewards({ + userAddress: '0x...', + vaultAddress: '0x...', + dateFrom: 1695730032793, +}) +``` +--- ### `sdk.vault.getExitQueue` #### Description: diff --git a/src/graphql/backend/vault/index.ts b/src/graphql/backend/vault/index.ts index 9dd570ed..5341581b 100644 --- a/src/graphql/backend/vault/index.ts +++ b/src/graphql/backend/vault/index.ts @@ -1,2 +1,5 @@ +export { fetchUserRewardsQuery } from './userRewardsQuery.graphql' +export type { UserRewardsQueryPayload, UserRewardsQueryVariables } from './userRewardsQuery.graphql' + export { fetchVaultValidatorsQuery } from './vaultValidatorsQuery.graphql' export type { VaultValidatorsQueryPayload, VaultValidatorsQueryVariables } from './vaultValidatorsQuery.graphql' diff --git a/src/graphql/backend/vault/userRewardsQuery.graphql b/src/graphql/backend/vault/userRewardsQuery.graphql new file mode 100644 index 00000000..c686d152 --- /dev/null +++ b/src/graphql/backend/vault/userRewardsQuery.graphql @@ -0,0 +1,6 @@ +query UserRewards($user: String!, $vaultAddress: String!, $dateFrom: date_as_timestamp!) { + userRewards(user: $user, vaultAddress: $vaultAddress, dateFrom: $dateFrom) { + date, + sumRewards, + } +} diff --git a/src/methods/vault/index.ts b/src/methods/vault/index.ts index 8a9e1f81..95223b0c 100644 --- a/src/methods/vault/index.ts +++ b/src/methods/vault/index.ts @@ -2,6 +2,7 @@ export { default as getVault } from './requests/getVault' export { default as getExitQueue } from './requests/getExitQueue' export { default as getValidators } from './requests/getValidators' export { default as getDaySnapshots } from './requests/getDaySnapshots' +export { default as getUserRewards } from './requests/getUserRewards' export { default as getStakeBalance } from './requests/getStakeBalance' export { default as getWithdrawData } from './requests/getWithdrawData' export { default as getHarvestParams } from './requests/getHarvestParams' diff --git a/src/methods/vault/requests/getUserRewards/index.ts b/src/methods/vault/requests/getUserRewards/index.ts new file mode 100644 index 00000000..9d470a96 --- /dev/null +++ b/src/methods/vault/requests/getUserRewards/index.ts @@ -0,0 +1,35 @@ +import { UserRewardsQueryVariables } from '../../../../graphql/backend/vault' +import { apiUrls, validateArgs } from '../../../../utils' +import modifyUserRewards from './modifyUserRewards' +import { backend } from '../../../../graphql' +import { ModifyUserReward } from './types' + + +type GetUserRewardsInput = { + options: StakeWise.Options + userAddress: UserRewardsQueryVariables['user'] + vaultAddress: UserRewardsQueryVariables['vaultAddress'] + dateFrom: UserRewardsQueryVariables['dateFrom'] +} + +const getUserRewards = async (input: GetUserRewardsInput) => { + const { options, vaultAddress, userAddress, dateFrom } = input + + validateArgs.address({ vaultAddress, userAddress }) + validateArgs.string({ dateFrom }) + + const data = await backend.vault.fetchUserRewardsQuery({ + url: apiUrls.getBackendUrl(options), + variables: { + vaultAddress: vaultAddress.toLowerCase(), + user: userAddress.toLowerCase(), + dateFrom, + } as UserRewardsQueryVariables, + modifyResult: modifyUserRewards, + }) + + return data +} + + +export default getUserRewards diff --git a/src/methods/vault/requests/getUserRewards/modifyUserRewards.spec.ts b/src/methods/vault/requests/getUserRewards/modifyUserRewards.spec.ts new file mode 100644 index 00000000..fa6cbeb7 --- /dev/null +++ b/src/methods/vault/requests/getUserRewards/modifyUserRewards.spec.ts @@ -0,0 +1,45 @@ +import { UserRewardsQueryPayload } from '../../../../graphql/backend/vault' +import modifyUserRewards, { modifyUserReward } from './modifyUserRewards' + + +describe('modifyUserReward and modifyUserRewards functions', () => { + const sampleInput: UserRewardsQueryPayload = { + userRewards: [ + { + date: '1694908800', + sumRewards: '344379922475148628745', + }, + { + date: '1694995200', + sumRewards: '344382187878289278175', + }, + ], + } + + it('should correctly modify a single reward', () => { + const userReward = sampleInput.userRewards[0] + + const result = modifyUserReward(userReward) + + expect(result).toEqual({ + rewards: 344.37992247514865, + }) + }) + + it('should correctly modify multiple rewards', () => { + const expectedResult = { + days: { + 1694908800: { + rewards: 344.37992247514865, + }, + 1694995200: { + rewards: 344.3821878782893, + }, + }, + } + + const result = modifyUserRewards(sampleInput) + + expect(result).toEqual(expectedResult) + }) +}) diff --git a/src/methods/vault/requests/getUserRewards/modifyUserRewards.ts b/src/methods/vault/requests/getUserRewards/modifyUserRewards.ts new file mode 100644 index 00000000..b76642e5 --- /dev/null +++ b/src/methods/vault/requests/getUserRewards/modifyUserRewards.ts @@ -0,0 +1,26 @@ +import { formatEther } from 'ethers' + +import { ModifyUserReward } from './types' +import { UserRewardsQueryPayload } from '../../../../graphql/backend/vault' + + +export const modifyUserReward = (reward: Omit) => { + const totalRewards = reward.sumRewards || '0' + + return { + rewards: Number(formatEther(totalRewards)), + } +} + +const modifyUserRewards = (input: UserRewardsQueryPayload): ModifyUserReward => { + const days = input.userRewards.reduce((acc, { date, ...rest }) => { + acc[Number(date)] = modifyUserReward(rest) + + return acc + }, {} as ModifyUserReward['days']) + + return { days } +} + + +export default modifyUserRewards diff --git a/src/methods/vault/requests/getUserRewards/types.ts b/src/methods/vault/requests/getUserRewards/types.ts new file mode 100644 index 00000000..8352656a --- /dev/null +++ b/src/methods/vault/requests/getUserRewards/types.ts @@ -0,0 +1,7 @@ +type UserReward = { + rewards: number +} + +export type ModifyUserReward = { + days: Record +}