Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lend stability pool public query #137

Merged
merged 6 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fast-brooms-search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@shadeprotocol/shadejs": patch
---

lend stability pool query
5 changes: 5 additions & 0 deletions .changeset/unlucky-pandas-develop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@shadeprotocol/shadejs": patch
---

lend contracts in docs
4 changes: 4 additions & 0 deletions docs/contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ This page contains a list of deployed contracts.
| Oracle | secret10n2xl5jmez6r9umtdrth78k0vwmce0l5m9f5dm | 32c4710842b97a526c243a68511b15f58d6e72a388af38a7221ff3244c754e91 |
| stkd-scrt | secret1k6u0cy4feepm6pehnz804zmwakuwdapm69tuc4 | f6be719b3c6feb498d3554ca0398eb6b7e7db262acb33f84a8f12106da6bbb09 |
| Shade Staking | secret1y6px5x7jzrk8hyvy67f06ytn8v0jwculypwxws | 2a1ae7fd2be82931cb11d0ce82b2e243507f2006074e2f316da661beb1abe3c3 |
| Lend Vault Registry (V1) | secret18y86hldtdp9ndj0jekcch49kwr0gwy7upe3ffw | 148a525ec7bffedfc41cbc5339bf22d9e310d49b65831a269c86774fb732948c |
| Lend Vault Registry (V2) | secret1qxk2scacpgj2mmm0af60674afl9e6qneg7yuny | ac5d501827d9a337a618ca493fcbf1323b20771378774a6bf466cb66361bf021 |
| Lend Vault Registry (V3) | secret1wj2czeeknya2n6jag7kpfxlm28dw7q96dgqmfs | d837f716de3732a4118fbcb6d4cd0ef1d84ee83fef924f27b7c2a821f8528b39 |
| Lend Stability Pool | secret1wdxqz26acf2e6rsac8007pd53ak7n8tgeqr46w | 4dcdce6a2f88ef2912b9988119b345b096909aa4ba3881eff19358d983c40210 |

::: tip
The ShadeSwap pairs contracts are accessible via the factory registered pairs query.
Expand Down
37 changes: 36 additions & 1 deletion docs/queries/lend.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,39 @@ async function queryVault({

**output**

See "Vault" type in the all vaults output.
See "Vault" type in the all vaults output.


## Stability Pool
Query info for the stability pool data

**input**
```ts
function queryStabilityPoolInfo({
queryRouterContractAddress,
queryRouterCodeHash,
lcdEndpoint,
chainId,
stabilityPoolContractAddress,
stabilityPoolCodeHash,
minBlockHeightValidationOptions,
}:{
queryRouterContractAddress: string,
queryRouterCodeHash?: string,
lcdEndpoint?: string,
chainId?: string,
stabilityPoolContractAddress: string,
stabilityPoolCodeHash: string,
minBlockHeightValidationOptions?: MinBlockHeightValidationOptions,
}): Promise<StabilityPoolInfo>
```

**output**
```ts
type StabilityPoolInfo = {
silkDeposited: string,
bondAmount: string, // this is value used for calculation
// purposes. It does not represent a token amount.
blockHeight: number,
}
```
2 changes: 2 additions & 0 deletions src/contracts/definitions/lend/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './vaultRegistry';
export * from './stabilityPool';
12 changes: 12 additions & 0 deletions src/contracts/definitions/lend/stabilityPool.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {
test,
expect,
} from 'vitest';
import { msgGetStabilityPoolInfo } from './stabilityPool';

test('it tests the form of the stability pool info message', () => {
const output = {
get_pool_info: {},
};
expect(msgGetStabilityPoolInfo()).toStrictEqual(output);
});
10 changes: 10 additions & 0 deletions src/contracts/definitions/lend/stabilityPool.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* message for the getting the stability pool data
*/
const msgGetStabilityPoolInfo = () => ({
get_pool_info: {},
});

export {
msgGetStabilityPoolInfo,
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
msgGetVaultUserPositions,
msgBorrow,
msgWithdraw,
} from './lend';
} from './vaultRegistry';

test('it tests the form of the vault info message', () => {
const inputVaultId = '1';
Expand Down
2 changes: 2 additions & 0 deletions src/contracts/services/lend/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './vaultRegistry';
export * from './stabilityPool';
87 changes: 87 additions & 0 deletions src/contracts/services/lend/stabilityPool.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import {
test,
expect,
vi,
beforeAll,
} from 'vitest';
import stabilityPoolInfoResponse from '~/test/mocks/lend/stabilityPool/stabilityPoolInfoResponse.json';
import { stabilityPoolInfoParsed } from '~/test/mocks/lend/stabilityPool/stabilityPoolInfoParsed';
import { batchStabilityPoolResponseUnparsed } from '~/test/mocks/lend/stabilityPool/stabilityPoolInfoBatchResponse';
import { of } from 'rxjs';
import { MinBlockHeightValidationOptions } from '~/types';
import {
parseStabilityPoolResponse,
parseStabilityPoolResponseFromQueryRouter,
queryStabilityPoolInfo$,
queryStabilityPoolInfo,
} from './stabilityPool';

const batchQuery$ = vi.hoisted(() => vi.fn());

beforeAll(() => {
vi.mock('~/contracts/definitions/lend/stabilityPool', () => ({
msgGetStabilityPoolInfo: vi.fn(() => 'GET_STABILITY_POOL_MSG'),
}));

vi.mock('~/contracts/services/batchQuery', () => ({
batchQuery$,
}));
});

test('it can parse the stability pool response', () => {
expect(parseStabilityPoolResponse(
stabilityPoolInfoResponse,
1,
)).toStrictEqual(stabilityPoolInfoParsed);
});

test('it can parse the stability pool response via the query router', () => {
expect(parseStabilityPoolResponseFromQueryRouter(
batchStabilityPoolResponseUnparsed,
)).toStrictEqual(stabilityPoolInfoParsed);
});

test('it can call stability pool info service', async () => {
const input = {
queryRouterContractAddress: 'QUERY_ROUTER_CONTRACT_ADDRESS',
queryRouterCodeHash: 'QUERY_ROUTER_CODE_HASH',
lcdEndpoint: 'LCD_ENDPOINT',
chainId: 'CHAIN_ID',
stabilityPoolContractAddress: 'STABILITY_POOL_CONTRACT_ADDRESS',
stabilityPoolCodeHash: 'STABILITY_POOL_CODE_HASH',
minBlockHeightValidationOptions: 'BLOCK_HEIGHT_VALIDATION_OPTIONS' as unknown as MinBlockHeightValidationOptions,
};
// observables function
batchQuery$.mockReturnValueOnce(of(batchStabilityPoolResponseUnparsed));
let output;
queryStabilityPoolInfo$(input).subscribe({
next: (response) => {
output = response;
},
});

const batchQueryInput = {
contractAddress: input.queryRouterContractAddress,
codeHash: input.queryRouterCodeHash,
lcdEndpoint: input.lcdEndpoint,
chainId: input.chainId,
queries: [{
id: input.stabilityPoolContractAddress,
contract: {
address: input.stabilityPoolContractAddress,
codeHash: input.stabilityPoolCodeHash,
},
queryMsg: 'GET_STABILITY_POOL_MSG',
}], // array of length 1 for single query
minBlockHeightValidationOptions: input.minBlockHeightValidationOptions,
};
expect(batchQuery$).toHaveBeenCalledWith(batchQueryInput);

expect(output).toStrictEqual(stabilityPoolInfoParsed);

// async/await function
batchQuery$.mockReturnValueOnce(of(batchStabilityPoolResponseUnparsed));
const response = await queryStabilityPoolInfo(input);
expect(batchQuery$).toHaveBeenCalledWith(batchQueryInput);
expect(response).toStrictEqual(stabilityPoolInfoParsed);
});
140 changes: 140 additions & 0 deletions src/contracts/services/lend/stabilityPool.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import {
MinBlockHeightValidationOptions,
BatchQueryParams,
NormalizationFactor,
BatchQueryParsedResponse,
BatchItemResponseStatus,
} from '~/types';
import { msgGetStabilityPoolInfo } from '~/contracts/definitions';
import {
map,
first,
firstValueFrom,
} from 'rxjs';
import { StabilityPoolInfo, StabilityPoolResponse } from '~/types/contracts/lend';
import { convertCoinFromUDenom } from '~/lib/utils';
import { batchQuery$ } from '../batchQuery';

/**
* parses the direct contract query into the data model
*/
const parseStabilityPoolResponse = (
response: StabilityPoolResponse,
blockHeight: number,
): StabilityPoolInfo => ({
silkDeposited: convertCoinFromUDenom(
response.pool_info.total_silk_deposited,
NormalizationFactor.LEND,
).toString(),
bondAmount: convertCoinFromUDenom(
response.pool_info.total_bond_amount,
NormalizationFactor.LEND,
).toString(),
blockHeight,
});

/**
* parses the query router response into the data model
*/
function parseStabilityPoolResponseFromQueryRouter(
batchQueryResponse: BatchQueryParsedResponse,
): StabilityPoolInfo {
const responseCount = batchQueryResponse.length;
if (responseCount !== 1) {
throw new Error(`${responseCount} responses found, one response is expected`);
}

const response = batchQueryResponse[0];

// handle error state
if (response.status === BatchItemResponseStatus.ERROR) {
throw new Error(response.response);
}

return {
...parseStabilityPoolResponse(
response.response,
response.blockHeight,
),
};
}

/**
* query the stability pool info
*/
function queryStabilityPoolInfo$({
queryRouterContractAddress,
queryRouterCodeHash,
lcdEndpoint,
chainId,
stabilityPoolContractAddress,
stabilityPoolCodeHash,
minBlockHeightValidationOptions,
}:{
queryRouterContractAddress: string,
queryRouterCodeHash?: string,
lcdEndpoint?: string,
chainId?: string,
stabilityPoolContractAddress: string,
stabilityPoolCodeHash: string,
minBlockHeightValidationOptions?: MinBlockHeightValidationOptions,
}) {
const query:BatchQueryParams = {
id: stabilityPoolContractAddress,
contract: {
address: stabilityPoolContractAddress,
codeHash: stabilityPoolCodeHash,
},
queryMsg: msgGetStabilityPoolInfo(),
};

return batchQuery$({
contractAddress: queryRouterContractAddress,
codeHash: queryRouterCodeHash,
lcdEndpoint,
chainId,
queries: [query], // array of length 1 for single query
minBlockHeightValidationOptions,
}).pipe(
map(parseStabilityPoolResponseFromQueryRouter),
first(),
);
}

/**
* query the stability pool info
*/
function queryStabilityPoolInfo({
queryRouterContractAddress,
queryRouterCodeHash,
lcdEndpoint,
chainId,
stabilityPoolContractAddress,
stabilityPoolCodeHash,
minBlockHeightValidationOptions,
}:{
queryRouterContractAddress: string,
queryRouterCodeHash?: string,
lcdEndpoint?: string,
chainId?: string,
stabilityPoolContractAddress: string,
stabilityPoolCodeHash: string,
minBlockHeightValidationOptions?: MinBlockHeightValidationOptions,
}) {
return firstValueFrom(queryStabilityPoolInfo$({
queryRouterContractAddress,
queryRouterCodeHash,
lcdEndpoint,
chainId,
stabilityPoolContractAddress,
stabilityPoolCodeHash,
minBlockHeightValidationOptions,
}));
}

export {
queryStabilityPoolInfo,
queryStabilityPoolInfo$,
parseStabilityPoolResponse,
parseStabilityPoolResponseFromQueryRouter,
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import vaultV2Response from '~/test/mocks/lend/vaultV2Response.json';
import vaultsV2Response from '~/test/mocks/lend/vaultsV2Response.json';
import vaultV3Response from '~/test/mocks/lend/vaultV3Response.json';
import vaultsV3Response from '~/test/mocks/lend/vaultsV3Response.json';
import { VaultVersion } from '~/types/contracts/lend/model';
import { VaultResponse, VaultsResponse } from '~/types/contracts/lend/response';
import { VaultVersion } from '~/types/contracts/lend/vaultRegistry/model';
import { VaultResponse, VaultsResponse } from '~/types/contracts/lend/vaultRegistry/response';
import {
vaultV1Parsed,
vaultsV1Parsed,
Expand All @@ -36,13 +36,13 @@ import {
queryVaults,
queryVault$,
queryVault,
} from './lend';
} from './vaultRegistry';

const sendSecretClientContractQuery$ = vi.hoisted(() => vi.fn());
const batchQuery$ = vi.hoisted(() => vi.fn());

beforeAll(() => {
vi.mock('~/contracts/definitions/lend', () => ({
vi.mock('~/contracts/definitions/lend/vaultRegistry', () => ({
msgGetVaults: vi.fn(() => 'GET_VAULTS_MSG'),
msgGetVault: vi.fn(() => 'GET_VAULT_MSG'),
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,24 @@ import {
VaultResponse,
VaultsResponse,
NormalizationFactor,
} from '~/types/contracts/lend/response';
} from '~/types/contracts/lend/vaultRegistry/response';
import {
convertCoinFromUDenom,
getActiveQueryClient$,
} from '~/index';
import {
Vaults,
Vault,
BatchVaults, VaultVersion,
BatchVaults,
VaultVersion,
LendVaultRegistryContract,
} from '~/types/contracts/lend/model';
} from '~/types/contracts/lend/vaultRegistry/model';
import { sendSecretClientContractQuery$ } from '~/client/services/clientServices';
import BigNumber from 'bignumber.js';
import {
msgGetVault,
msgGetVaults,
} from '~/contracts/definitions/lend';
import { sendSecretClientContractQuery$ } from '~/client/services/clientServices';
import BigNumber from 'bignumber.js';
} from '~/contracts/definitions/lend/vaultRegistry';

/**
* Parse lend vault response
Expand Down
Loading
Loading