Skip to content

Commit 32c9e0d

Browse files
committed
feat: borrow assets
1 parent 3c99dc8 commit 32c9e0d

File tree

11 files changed

+265
-652
lines changed

11 files changed

+265
-652
lines changed

apps/indexer/src/app/app.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ export async function app(fastify: FastifyInstance, opts: AppOptions) {
3030
});
3131

3232
fastify.addHook('onError', async (request, _reply, error) => {
33-
request.log.error({ err: error }, 'unhandled error');
34-
// push to Sentry, Prometheus, etc.
33+
if (error?.statusCode === 500) {
34+
// push to Sentry, Prometheus, etc.
35+
request.log.error({ err: error }, 'unhandled error');
36+
}
3537
});
3638
}

apps/indexer/src/app/routes/_chain/routes.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { TTokenSelected, tTokensSelectors } from '../../../database/selectors';
88
import {
99
fetchPoolList,
1010
fetchPoolReserves,
11+
selectPoolById,
1112
} from '../../../libs/loaders/money-market';
1213
import { paginationResponse, paginationSchema } from '../../../libs/pagination';
1314
import { areAddressesEqual } from '../../../libs/utils/helpers';
@@ -127,20 +128,18 @@ export default async function (fastify: FastifyInstance) {
127128
);
128129

129130
fastify.withTypeProvider<ZodTypeProvider>().get(
130-
'/money-market/:pool',
131+
'/money-market/:pool/reserves',
131132
{
132133
schema: {
133134
querystring: paginationSchema,
134135
},
135-
// config: {
136-
// cache: true,
137-
// },
136+
config: {
137+
cache: true,
138+
},
138139
},
139140
async (req: FastifyRequest<{ Params: { pool: string } }>, reply) => {
140141
const pools = await fetchPoolList(req.chain.chainId);
141-
const pool = pools.find(
142-
(p) => p.address.toLowerCase() === req.params.pool.toLowerCase(),
143-
);
142+
const pool = selectPoolById(req.params.pool, pools);
144143

145144
if (!pool) {
146145
return reply.notFound('Pool not found');
@@ -167,18 +166,19 @@ export default async function (fastify: FastifyInstance) {
167166
// const { virtualAccActive } = reserveRaw;
168167
return {
169168
originalId: index,
170-
id: `!!${req.chain.chainId}-${reserveRaw.underlyingAsset}-${pool.address}`.toLowerCase(),
171-
underlyingAsset: reserveRaw.underlyingAsset.toLowerCase(),
169+
id: `${req.chain.chainId}-${reserveRaw.underlyingAsset}-${pool.address}`.toLowerCase(),
170+
// underlyingAsset: reserveRaw.underlyingAsset.toLowerCase(),
172171

173172
token: tokens.find((t) =>
174173
areAddressesEqual(t.address, reserveRaw.underlyingAsset),
175174
),
175+
pool,
176176

177-
name: reserveRaw.name,
177+
// name: reserveRaw.name,
178178
// symbol: ammSymbolMap[reserveRaw.underlyingAsset.toLowerCase()]
179179
// ? ammSymbolMap[reserveRaw.underlyingAsset.toLowerCase()]
180180
// : reserveRaw.symbol,
181-
decimals: reserveRaw.decimals.toNumber(),
181+
// decimals: reserveRaw.decimals.toNumber(),
182182
baseLTVasCollateral: reserveRaw.baseLTVasCollateral.toString(),
183183
reserveLiquidationThreshold:
184184
reserveRaw.reserveLiquidationThreshold.toString(),

apps/indexer/src/libs/loaders/money-market.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ const uiPoolDataProviderAbi = [
354354
] as const;
355355

356356
type PoolDefinition = {
357+
id: string | 'default';
357358
name: string;
358359
logoURI: string;
359360
address: Address;
@@ -364,7 +365,7 @@ type PoolDefinition = {
364365
weth: Address;
365366
treasury: Address;
366367
subgraphURI: string;
367-
priceFeedUrl: string;
368+
priceFeedURI: string;
368369
};
369370

370371
export async function fetchPoolList(chainId: ChainId) {
@@ -383,6 +384,13 @@ export async function fetchPoolList(chainId: ChainId) {
383384
return data.items;
384385
}
385386

387+
export function selectPoolById(
388+
id: PoolDefinition['id'],
389+
pools: PoolDefinition[],
390+
) {
391+
return pools.find((pool) => pool.id === id);
392+
}
393+
386394
export async function fetchPoolReserves(
387395
chainId: ChainSelector,
388396
pool: PoolDefinition,

apps/web-app/src/components/MoneyMarket/components/BorrowAssetsList/components/AssetsTable/AssetsTable.tsx

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { AmountRenderer } from '@/components/ui/amount-renderer';
1313
import { Button } from '@/components/ui/button';
1414
import { Dialog } from '@/components/ui/dialog';
1515
import { InfoButton } from '@/components/ui/info-button';
16-
import { type MoneyMarketPoolReserve } from '@sovryn/slayer-sdk';
16+
import type { MoneyMarketPoolReserve } from '@sovryn/slayer-sdk';
1717

1818
type AssetsTableProps = {
1919
assets: MoneyMarketPoolReserve[];
@@ -108,20 +108,12 @@ export const AssetsTable: FC<AssetsTableProps> = ({ assets }) => {
108108
</TableCell>
109109
<TableCell className="border-neutral-800 border-y">
110110
<span className="flex items-center gap-1">
111-
<AmountRenderer
112-
value={
113-
Number(asset.totalLiquidity) /
114-
Math.pow(10, asset.token.decimals)
115-
}
116-
/>
111+
<AmountRenderer value={asset.availableLiquidity} />
117112
{asset.token.symbol}
118113
</span>
119114
<p className="text-neutral-500 font-medium text-xs">
120115
<AmountRenderer
121-
value={
122-
Number(asset.totalLiquidity) /
123-
Math.pow(10, asset.token.decimals)
124-
}
116+
value={asset.availableLiquidity}
125117
prefix="$"
126118
decimals={2}
127119
showApproxSign

apps/web-app/src/components/MoneyMarket/components/BorrowDialog/BorrowDialog.tsx

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import { sdk } from '@/lib/sdk';
1313
import { useSlayerTx } from '@/lib/transactions';
1414
import { validateDecimal } from '@/lib/validations';
1515
import { BORROW_RATE_MODES } from '@sovryn/slayer-sdk';
16-
import { useQuery } from '@tanstack/react-query';
1716
import { useAccount } from 'wagmi';
1817
import z from 'zod';
1918
import { useStore } from 'zustand';
@@ -38,21 +37,6 @@ const BorrowDialogForm = () => {
3837
});
3938
const { address } = useAccount();
4039

41-
useQuery({
42-
queryKey: ['reserve-data', reserve.id],
43-
queryFn: async () => {
44-
console.log('Fetching reserve data for:', reserve.id);
45-
const data = await sdk.moneyMarket.useReserve(reserve).getReservesData();
46-
console.log('Reserve data:', data);
47-
return data;
48-
},
49-
enabled: !!reserve,
50-
throwOnError(error, query) {
51-
console.error('Error fetching reserve data:', error, query);
52-
return true;
53-
},
54-
});
55-
5640
const form = useAppForm({
5741
defaultValues: {
5842
amount: '',
@@ -63,11 +47,14 @@ const BorrowDialogForm = () => {
6347
},
6448
onSubmit: ({ value }) => {
6549
begin(() =>
66-
sdk.moneyMarket
67-
.useReserve(reserve)
68-
.borrow(value.amount, BORROW_RATE_MODES.variable, {
50+
sdk.moneyMarket.borrow(
51+
reserve,
52+
value.amount,
53+
BORROW_RATE_MODES.variable,
54+
{
6955
account: address!,
70-
}),
56+
},
57+
),
7158
);
7259
},
7360
onSubmitInvalid(props) {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { cn } from "@/lib/utils"
2+
3+
function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
4+
return (
5+
<div
6+
data-slot="skeleton"
7+
className={cn("bg-accent animate-pulse rounded-md", className)}
8+
{...props}
9+
/>
10+
)
11+
}
12+
13+
export { Skeleton }

apps/web-app/src/routes/money-market.tsx

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,35 +15,57 @@ import {
1515
netWorth,
1616
} from '@/components/MoneyMarket/MoneyMarket.constants';
1717
import { Heading } from '@/components/ui/heading/heading';
18+
import { getContext } from '@/integrations/tanstack-query/root-provider';
1819
import { sdk } from '@/lib/sdk';
19-
import { isAbortError } from '@sovryn/slayer-shared';
20+
import { useQuery } from '@tanstack/react-query';
2021
import z from 'zod';
2122

2223
const poolSearchSchema = z.object({
2324
offset: z.number().min(0).default(0),
2425
limit: z.number().min(1).max(100).default(20),
2526
search: z.string().default(''),
27+
pool: z.string().default('default'),
2628
});
2729

2830
export const Route = createFileRoute('/money-market')({
2931
component: RouteComponent,
3032
validateSearch: poolSearchSchema,
31-
loaderDeps: ({ search: { offset, limit, search } }) => ({
33+
loaderDeps: ({ search: { offset, limit, search, pool } }) => ({
3234
offset,
3335
limit,
3436
search,
37+
pool,
3538
}),
36-
loader: ({ abortController, deps }) =>
37-
sdk.moneyMarket
38-
.listReserves({
39-
signal: abortController.signal,
40-
query: deps,
41-
})
42-
.catch((e) => (isAbortError(e) ? null : Promise.reject(e))),
39+
loader: ({ deps: { pool } }) => {
40+
const client = getContext().queryClient;
41+
client.prefetchQuery({
42+
queryKey: ['money-market:pools'],
43+
queryFn: () => sdk.moneyMarket.listPools(),
44+
staleTime: 1000 * 60 * 60, // 1 hour
45+
});
46+
47+
client.prefetchQuery({
48+
queryKey: ['money-market:reserve', pool || 'default'],
49+
queryFn: () => sdk.moneyMarket.listReserves(pool || 'default'),
50+
staleTime: 1000 * 60 * 60, // 1 hour
51+
});
52+
},
4353
});
4454

4555
function RouteComponent() {
46-
const pools = Route.useLoaderData();
56+
const { pool } = Route.useLoaderDeps();
57+
58+
// const { data: pools } = useQuery({
59+
// queryKey: ['money-market:pools'],
60+
// queryFn: () => sdk.moneyMarket.listPools(),
61+
// staleTime: 1000 * 60 * 60, // 1 hour
62+
// });
63+
64+
const { data: reserves } = useQuery({
65+
queryKey: ['money-market:reserve', pool || 'default'],
66+
queryFn: () => sdk.moneyMarket.listReserves(pool || 'default'),
67+
staleTime: 1000 * 60 * 60, // 1 hour
68+
});
4769

4870
return (
4971
<>
@@ -64,7 +86,7 @@ function RouteComponent() {
6486
<div className="grid grid-cols-1 2xl:grid-cols-2 2xl:gap-4 space-y-4">
6587
<div className="space-y-4">
6688
<LendPositionsList
67-
lendPositions={(pools?.data ?? []).map((r) => r.data)}
89+
lendPositions={reserves?.data ?? []}
6890
supplyBalance={100}
6991
collateralBalance={50}
7092
supplyWeightedApy={2.5}
@@ -78,9 +100,7 @@ function RouteComponent() {
78100
borrowPower={1.29}
79101
supplyWeightedApy={0.05}
80102
/>
81-
<BorrowAssetsList
82-
borrowAssets={(pools?.data ?? []).map((r) => r.data)}
83-
/>
103+
<BorrowAssetsList borrowAssets={reserves?.data ?? []} />
84104
</div>
85105
</div>
86106
</div>

packages/sdk/src/lib/context.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Chain, PublicClient, Transport, WalletClient } from 'viem';
44
import { INDEXER_URL, Mode, modes } from '../constants.js';
55
import { SdkPaginatedQuery } from '../types.js';
66

7-
const logger = debug('slayer-sdk:context');
7+
const log = debug('slayer-sdk:context');
88

99
export type FetchLike = typeof fetch;
1010

@@ -49,7 +49,7 @@ export class Context<chain extends Chain> {
4949
throw new Error('publicClient is required in SdkConfig');
5050
if (cfg.indexerBaseUrl) {
5151
cfg.mode = modes.custom;
52-
logger.log('Using custom indexer base URL:', cfg.indexerBaseUrl);
52+
log('Using custom indexer base URL:', cfg.indexerBaseUrl);
5353
}
5454
if (!cfg.mode) cfg.mode = modes.production;
5555
this.config = cfg;

0 commit comments

Comments
 (0)