Skip to content

Commit

Permalink
Lend vault messages (#125)
Browse files Browse the repository at this point in the history
* feat: lend vault public queries
  • Loading branch information
AustinWoetzel authored Apr 22, 2024
1 parent 555f33e commit a8b185f
Show file tree
Hide file tree
Showing 24 changed files with 2,822 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/beige-teachers-enjoy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@shadeprotocol/shadejs": minor
---

lend vault queries
1 change: 1 addition & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export default defineConfig({
collapsed: false,
items: [
{ text: 'Swap', link: '/queries/swap' },
{ text: 'Lend', link: '/queries/lend' },
{ text: 'Oracle', link: '/queries/oracle' },
{ text: 'stkd-SCRT', link: '/queries/derivativeScrt' },
{ text: 'Shade Staking', link: '/queries/shadeStaking' },
Expand Down
132 changes: 132 additions & 0 deletions docs/queries/lend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Lend Examples

This page demonstrates how to query the Shade Lend contracts.

## All Vaults
Query multiple vault registry contracts and return info about all the vaults in each registry.

**input**
```ts
async function queryVaults({
queryRouterContractAddress,
queryRouterCodeHash,
lcdEndpoint,
chainId,
vaultRegistryContracts,
}:{
queryRouterContractAddress: string,
queryRouterCodeHash?: string,
lcdEndpoint?: string,
chainId?: string,
vaultRegistryContracts: LendVaultRegistryContract[]
}): Promise<BatchVaults>

type LendVaultRegistryContract = {
address: string,
codeHash: string,
vaultType: VaultType,
};

enum VaultType {
V1 = 'v1',
V2 = 'v2',
V3 = 'v3',
}
```

**output**

```ts

type BatchVaults = BatchVaultsItem[]

type BatchVaultsItem = {
vaultRegistryContractAddress: string,
vaults: Vaults,
blockHeight: number,
}

type Vaults = {
[id: string]: Vault,
}

type Vault = {
id: string,
vaultType: VaultType,
name: string,
collateralAddress: string,
silkMaxAllowance: string,
silkAllowanceUsed: string,
maxLtv: number, // decimal percent
collateral: {
total: string,
elastic: string,
base: string,
safe: string,
lastAccruedAt: Date,
oracleDelay: number,
},
debt: {
total: string,
base: string,
lastAccruedAt: Date,
}
interestRate: {
current: number, // decimal percent
target: number,
delta: number,
ratePerSecond: number,
lastUpdatedAt: Date,
},
borrowFee: {
current: number, // decimal percent
target: number,
delta: number,
ratePerSecond: number,
lastUpdatedAt: Date,
},
liquidationFee: {
discount: number,
minimumDebt: string,
daoShare: number,
callerShare: number
}
isProtocolOnly: boolean,
status: LendContractStatus,
openPositions: number,
totalPositions: number,
whitelist: string[],
}

enum LendContractStatus {
NORMAL = 'normal',
DEPRECATED = 'deprecated',
FROZEN = 'frozen'
}
```

## Single Vault
Query info for a single vault.

**input**
```ts
async function queryVault({
vaultRegistryContractAddress,
vaultRegistryCodeHash,
vaultType,
vaultId,
lcdEndpoint,
chainId,
}:{
vaultRegistryContractAddress: string,
vaultRegistryCodeHash?: string,
vaultType: VaultType,
vaultId: string,
lcdEndpoint?: string,
chainId?: string,
}): Promise<Vault>
```

**output**

See "Vault" type in the all vaults output.
1 change: 1 addition & 0 deletions src/contracts/definitions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './swap';
export * from './derivativeShd';
export * from './derivativeScrt';
export * from './shadeStaking';
export * from './lend';
132 changes: 132 additions & 0 deletions src/contracts/definitions/lend.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import {
test,
expect,
} from 'vitest';
import {
msgGetVault,
msgGetVaults,
msgGetVaultUserPosition,
msgGetVaultUserPositions,
msgBorrow,
msgWithdraw,
} from './lend';

test('it tests the form of the vault info message', () => {
const inputVaultId = '1';

const output = {
vault: {
vault_id: inputVaultId,
},
};
expect(msgGetVault(inputVaultId)).toStrictEqual(output);
});

test('it tests the form of the multiple vaults info message', () => {
const inputStartingPageNumber = '1';

const output = {
vaults: {
starting_page: inputStartingPageNumber,
},
};
expect(msgGetVaults(inputStartingPageNumber)).toStrictEqual(output);
});

test('it tests the form of the vault user position message', () => {
const inputVaultId = '1';
const permit = {
params: {
data: 'PERMIT_DATA',
contract: 'CONTRACT',
key: 'KEY',
},
chain_id: 'CHAIN_ID',
signature: {
pub_key: {
type: 'TYPE',
value: 'VALUE',
},
signature: 'SIGNATURE',
},
};

const output = {
with_permit: {
permit,
query: {
position: {
vault_id: inputVaultId,
},
},
},
};
expect(msgGetVaultUserPosition(permit, inputVaultId)).toStrictEqual(output);
});

test('it tests the form of the vaults user position message', () => {
const inputVaultIds = ['1', '2'];
const permit = {
params: {
data: 'PERMIT_DATA',
contract: 'CONTRACT',
key: 'KEY',
},
chain_id: 'CHAIN_ID',
signature: {
pub_key: {
type: 'TYPE',
value: 'VALUE',
},
signature: 'SIGNATURE',
},
};

const output = {
with_permit: {
permit,
query: {
positions: {
vault_ids: inputVaultIds,
},
},
},
};
expect(msgGetVaultUserPositions(permit, inputVaultIds)).toStrictEqual(output);
});

test('it test the form of the borrow message', () => {
const input = {
borrowAmount: 'BORROW_AMOUNT',
maxBorrowFee: 'BORROW_FEE',
vaultId: 'VAULT_ID',
};

const output = {
vault_action: {
vault_id: input.vaultId,
msg: {
borrow: {
amount: input.borrowAmount,
max_fee: input.maxBorrowFee,
},
},
},
};
expect(msgBorrow(input)).toStrictEqual(output);
});

test('it test the form of the withdraw message', () => {
const input = {
withdrawAmount: 'WITHDRAW_AMOUNT',
vaultId: 'VAULT_ID',
};

const output = {
vault_action: {
vault_id: input.vaultId,
msg: { withdraw: input.withdrawAmount },
},
};
expect(msgWithdraw(input.withdrawAmount, input.vaultId)).toStrictEqual(output);
});
96 changes: 96 additions & 0 deletions src/contracts/definitions/lend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { AccountPermit } from '~/types/permit';

/**
* message for the getting the vault info
*/
const msgGetVault = (vaultId: string) => ({
vault: {
vault_id: vaultId,
},
});

/**
* message for the getting multiple vaults info.
* @param startingPage The data is paginated and returned
* for the starting page and all pages after. Use "1" to query all vaults.
*/
const msgGetVaults = (startingPage: string) => ({
vaults: {
starting_page: startingPage,
},
});

/**
* message for the getting a user position
*/
const msgGetVaultUserPosition = (permit: AccountPermit, vaultId: string) => ({
with_permit: {
permit,
query: {
position: {
vault_id: vaultId,
},
},
},
});

/**
* message for getting multiple user positions
*/
const msgGetVaultUserPositions = (permit: AccountPermit, vaultIds: string[]) => ({
with_permit: {
permit,
query: {
positions: {
vault_ids: vaultIds,
},
},
},
});

/**
* message to borrow silk from a lend vault
*/
const msgBorrow = ({
borrowAmount,
maxBorrowFee,
vaultId,
}: {
borrowAmount: string,
maxBorrowFee?: string,
vaultId: string,
}) => ({
vault_action: {
vault_id: vaultId,
msg: {
borrow: {
amount: borrowAmount,
max_fee: maxBorrowFee,
},
},
},
});

/**
* message to withdraw collateral from a lend vault
*/
const msgWithdraw = (
withdrawAmount: string,
vaultId: string,
) => ({
vault_action: {
vault_id: vaultId,
msg: {
withdraw: withdrawAmount,
},
},
});

export {
msgGetVault,
msgGetVaults,
msgGetVaultUserPosition,
msgGetVaultUserPositions,
msgBorrow,
msgWithdraw,
};
1 change: 1 addition & 0 deletions src/contracts/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './swap';
export * from './derivativeScrt';
export * from './derivativeShd';
export * from './shadeStaking';
export * from './lend';
Loading

0 comments on commit a8b185f

Please sign in to comment.