Account balances endpoint (#147)
* add accounts/positions to api * strong type apis
This commit is contained in:
parent
7efb7908c0
commit
8e0bb97839
@ -9,10 +9,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
|
||||
const accountId = req.query.id
|
||||
|
||||
const account = await (await fetch(`${ENV.URL_API}/accounts/${accountId}${VERCEL_BYPASS}`)).json()
|
||||
const position: Position = await (
|
||||
await fetch(`${ENV.URL_API}/accounts/${accountId}${VERCEL_BYPASS}`)
|
||||
).json()
|
||||
|
||||
if (account) {
|
||||
return res.status(200).json(account.debts)
|
||||
if (position) {
|
||||
return res.status(200).json(position.debts)
|
||||
}
|
||||
|
||||
return res.status(404)
|
||||
|
@ -9,10 +9,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
|
||||
const accountId = req.query.id
|
||||
|
||||
const account = await (await fetch(`${ENV.URL_API}/accounts/${accountId}${VERCEL_BYPASS}`)).json()
|
||||
const position: Position = await (
|
||||
await fetch(`${ENV.URL_API}/accounts/${accountId}${VERCEL_BYPASS}`)
|
||||
).json()
|
||||
|
||||
if (account) {
|
||||
return res.status(200).json(account.deposits)
|
||||
if (position) {
|
||||
return res.status(200).json(position.deposits)
|
||||
}
|
||||
|
||||
return res.status(404)
|
||||
|
@ -2,6 +2,7 @@ import { CosmWasmClient } from '@cosmjs/cosmwasm-stargate'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
|
||||
import { ENV, ENV_MISSING_MESSAGE } from 'constants/env'
|
||||
import { resolvePositionResponse } from 'utils/resolvers'
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (!ENV.URL_RPC || !ENV.ADDRESS_CREDIT_MANAGER) {
|
||||
@ -12,14 +13,14 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
|
||||
const client = await CosmWasmClient.connect(ENV.URL_RPC)
|
||||
|
||||
const data = await client.queryContractSmart(ENV.ADDRESS_CREDIT_MANAGER, {
|
||||
const data: PositionResponse = await client.queryContractSmart(ENV.ADDRESS_CREDIT_MANAGER, {
|
||||
positions: {
|
||||
account_id: accountId,
|
||||
},
|
||||
})
|
||||
|
||||
if (data) {
|
||||
return res.status(200).json(data)
|
||||
return res.status(200).json(resolvePositionResponse(data))
|
||||
}
|
||||
|
||||
return res.status(404)
|
||||
|
@ -10,7 +10,6 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
return res.status(404).json(ENV_MISSING_MESSAGE)
|
||||
}
|
||||
|
||||
const marketAssets = getMarketAssets()
|
||||
const $liquidity = fetch(`${ENV.URL_API}/markets/liquidity${VERCEL_BYPASS}`)
|
||||
const $markets = fetch(`${ENV.URL_API}/markets${VERCEL_BYPASS}`)
|
||||
const $prices = fetch(`${ENV.URL_API}/prices${VERCEL_BYPASS}`)
|
||||
@ -18,16 +17,17 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
const borrow: BorrowAsset[] = await Promise.all([$liquidity, $markets, $prices]).then(
|
||||
async ([$liquidity, $markets, $prices]) => {
|
||||
const liquidity: Coin[] = await $liquidity.json()
|
||||
const markets: Market[] = await $markets.json()
|
||||
const borrowEnabledMarkets: Market[] = (await $markets.json()).filter(
|
||||
(market: Market) => market.borrowEnabled,
|
||||
)
|
||||
const prices: Coin[] = await $prices.json()
|
||||
|
||||
return marketAssets.map((asset) => {
|
||||
const currentMarket = markets.find((market) => market.denom === asset.denom)
|
||||
const price = prices.find((coin) => coin.denom === asset.denom)?.amount ?? '1'
|
||||
const amount = liquidity.find((coin) => coin.denom === asset.denom)?.amount ?? '0'
|
||||
return borrowEnabledMarkets.map((market) => {
|
||||
const price = prices.find((coin) => coin.denom === market.denom)?.amount ?? '1'
|
||||
const amount = liquidity.find((coin) => coin.denom === market.denom)?.amount ?? '0'
|
||||
return {
|
||||
denom: asset.denom,
|
||||
borrowRate: currentMarket?.borrow_rate ?? '0',
|
||||
denom: market.denom,
|
||||
borrowRate: market.borrowRate ?? 0,
|
||||
liquidity: {
|
||||
amount: amount,
|
||||
value: new BigNumber(amount).times(price).toString(),
|
||||
|
@ -21,7 +21,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
{
|
||||
underlying_debt_amount: {
|
||||
denom: "${asset.denom}"
|
||||
amount_scaled: "${asset.debt_total_scaled}"
|
||||
amount_scaled: "${asset.debtTotalScaled}"
|
||||
}
|
||||
}`,
|
||||
)
|
||||
|
@ -13,15 +13,15 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
|
||||
let query = ''
|
||||
|
||||
markets.forEach((asset: any) => {
|
||||
markets.forEach((market: Market) => {
|
||||
query += getContractQuery(
|
||||
denomToKey(asset.denom),
|
||||
denomToKey(market.denom),
|
||||
ENV.ADDRESS_RED_BANK || '',
|
||||
`
|
||||
{
|
||||
underlying_liquidity_amount: {
|
||||
denom: "${asset.denom}"
|
||||
amount_scaled: "${asset.collateral_total_scaled}"
|
||||
denom: "${market.denom}"
|
||||
amount_scaled: "${market.collateralTotalScaled}"
|
||||
}
|
||||
}`,
|
||||
)
|
||||
|
@ -4,6 +4,7 @@ import { NextApiRequest, NextApiResponse } from 'next'
|
||||
import { ENV, ENV_MISSING_MESSAGE } from 'constants/env'
|
||||
import { getMarketAssets } from 'utils/assets'
|
||||
import { denomToKey } from 'utils/query'
|
||||
import { resolveMarketResponses } from 'utils/resolvers'
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (!ENV.URL_GQL || !ENV.ADDRESS_RED_BANK || !ENV.ADDRESS_INCENTIVES) {
|
||||
@ -35,11 +36,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
const market = result.rbwasmkey[`${denomToKey(asset.denom)}`]
|
||||
return market
|
||||
})
|
||||
return res.status(200).json(markets)
|
||||
return res.status(200).json(resolveMarketResponses(markets))
|
||||
}
|
||||
|
||||
interface RedBankData {
|
||||
rbwasmkey: {
|
||||
[key: string]: Market
|
||||
[key: string]: MarketResponse
|
||||
}
|
||||
}
|
||||
|
35
src/pages/api/wallets/[address]/accounts/positions.ts
Normal file
35
src/pages/api/wallets/[address]/accounts/positions.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { CosmWasmClient } from '@cosmjs/cosmwasm-stargate'
|
||||
import { NextApiRequest, NextApiResponse } from 'next'
|
||||
|
||||
import { ENV, ENV_MISSING_MESSAGE, VERCEL_BYPASS } from 'constants/env'
|
||||
import { resolvePositionResponses } from 'utils/resolvers'
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (!ENV.URL_RPC || !ENV.ADDRESS_CREDIT_MANAGER || !ENV.URL_API) {
|
||||
return res.status(404).json(ENV_MISSING_MESSAGE)
|
||||
}
|
||||
|
||||
const address = req.query.address
|
||||
|
||||
const accounts: string[] = await (
|
||||
await fetch(`${ENV.URL_API}/wallets/${address}/accounts${VERCEL_BYPASS}`)
|
||||
).json()
|
||||
|
||||
const client = await CosmWasmClient.connect(ENV.URL_RPC)
|
||||
|
||||
const $positions: Promise<PositionResponse>[] = accounts.map((account) =>
|
||||
client.queryContractSmart(ENV.ADDRESS_CREDIT_MANAGER!, {
|
||||
positions: {
|
||||
account_id: `${account}`,
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
const positions = await Promise.all($positions).then((positions) => positions)
|
||||
|
||||
if (positions) {
|
||||
return res.status(200).json(resolvePositionResponses(positions))
|
||||
}
|
||||
|
||||
return res.status(404)
|
||||
}
|
6
src/types/interfaces/account.d.ts
vendored
Normal file
6
src/types/interfaces/account.d.ts
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
interface Position {
|
||||
account: string
|
||||
deposits: import('@cosmjs/stargate').Coin[]
|
||||
debts: import('@cosmjs/stargate').Coin[]
|
||||
lends: import('@cosmjs/stargate').Coin[]
|
||||
}
|
2
src/types/interfaces/asset.d.ts
vendored
2
src/types/interfaces/asset.d.ts
vendored
@ -18,7 +18,7 @@ interface OtherAsset extends Omit<Asset, 'symbol'> {
|
||||
|
||||
interface BorrowAsset {
|
||||
denom: string
|
||||
borrowRate: string | null
|
||||
borrowRate: number | null
|
||||
liquidity: {
|
||||
amount: string
|
||||
value: string
|
||||
|
9
src/types/interfaces/market.d.ts
vendored
Normal file
9
src/types/interfaces/market.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
interface Market {
|
||||
denom: string
|
||||
borrowRate: number
|
||||
debtTotalScaled: number
|
||||
collateralTotalScaled: number
|
||||
depositEnabled: boolean
|
||||
borrowEnabled: boolean
|
||||
depositCap: number
|
||||
}
|
@ -1,4 +1,11 @@
|
||||
interface Market {
|
||||
interface PositionResponse {
|
||||
account_id: string
|
||||
deposits: Coin[]
|
||||
debts: Coin[]
|
||||
lends: Coin[]
|
||||
}
|
||||
|
||||
interface MarketResponse {
|
||||
denom: string
|
||||
max_loan_to_value: string
|
||||
liquidation_threshold: string
|
||||
@ -21,11 +28,3 @@ interface Market {
|
||||
borrow_enabled: boolean
|
||||
deposit_cap: string
|
||||
}
|
||||
|
||||
interface MarketResult {
|
||||
wasm: MarketData
|
||||
}
|
||||
|
||||
interface MarketData {
|
||||
[key: string]: Market
|
||||
}
|
@ -11,13 +11,12 @@ export async function callAPI<T>(endpoint: string): Promise<T> {
|
||||
}
|
||||
|
||||
export async function getBorrowData() {
|
||||
await sleep()
|
||||
return callAPI<BorrowAsset[]>('/markets/borrow')
|
||||
}
|
||||
|
||||
export async function getCreditAccounts(address: string) {
|
||||
if (!address) return []
|
||||
return callAPI<any[]>(`/wallets/${address}/accounts`)
|
||||
return callAPI<string[]>(`/wallets/${address}/accounts`)
|
||||
}
|
||||
|
||||
export async function getMarkets() {
|
||||
@ -41,11 +40,13 @@ export async function getAccountDeposits(account: string) {
|
||||
if (!account) return []
|
||||
return callAPI<Coin[]>(`/accounts/${account}/deposits`)
|
||||
}
|
||||
|
||||
export async function getWalletBalances(wallet: string) {
|
||||
if (!wallet) return []
|
||||
return callAPI<Coin[]>(`/wallets/${wallet}/balances`)
|
||||
}
|
||||
|
||||
async function sleep() {
|
||||
return new Promise((resolve) => setTimeout(resolve, 2500))
|
||||
export async function getAccountsPositions(wallet: string) {
|
||||
if (!wallet) return []
|
||||
return callAPI<Position[]>(`/wallets/${wallet}/accounts/positions`)
|
||||
}
|
||||
|
24
src/utils/resolvers.ts
Normal file
24
src/utils/resolvers.ts
Normal file
@ -0,0 +1,24 @@
|
||||
export function resolvePositionResponses(responses: PositionResponse[]): Position[] {
|
||||
return responses.map(resolvePositionResponse)
|
||||
}
|
||||
|
||||
export function resolvePositionResponse(response: PositionResponse): Position {
|
||||
return {
|
||||
account: response.account_id,
|
||||
deposits: response.deposits,
|
||||
debts: response.debts,
|
||||
lends: response.lends,
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveMarketResponses(responses: MarketResponse[]): Market[] {
|
||||
return responses.map((response) => ({
|
||||
denom: response.denom,
|
||||
borrowRate: Number(response.borrow_rate),
|
||||
debtTotalScaled: Number(response.debt_total_scaled),
|
||||
collateralTotalScaled: Number(response.collateral_total_scaled),
|
||||
depositEnabled: response.deposit_enabled,
|
||||
borrowEnabled: response.borrow_enabled,
|
||||
depositCap: Number(response.deposit_cap),
|
||||
}))
|
||||
}
|
Loading…
Reference in New Issue
Block a user