Skip to content

Commit

Permalink
Merge branch 'main' into fix-dust-after-settling-positions
Browse files Browse the repository at this point in the history
  • Loading branch information
leomassazza authored Jan 13, 2025
2 parents f79bfc1 + fa05ea3 commit da6e5e6
Show file tree
Hide file tree
Showing 55 changed files with 372 additions and 519 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ See the [website](https://foil.xyz), [app](https://app.foil.xyz), and [docs](htt
- Start the app
- `pnpm run dev:app` and access at http://localhost:3000
- Connect your wallet application to http://localhost:8545 (Chain ID 13370) **Remember to reset the nonce in the wallet after restarting the node.**
- Start the data service
- `pnpm run dev:data` and access at http://localhost:3001
- Start the API
- `pnpm run dev:api` and access at http://localhost:3001
- Start the website
- `pnpm run dev:website` and access at http://localhost:3002
- Start the docs
Expand All @@ -23,6 +23,7 @@ See the [website](https://foil.xyz), [app](https://app.foil.xyz), and [docs](htt
- Go to `/packages/protocol`
- Bump the version in `/packages/protocol/package.json`
- Verify there are no issues with `pnpm simulate-deploy:sepolia --rpc-url <rpc-url> --private-key <private-key>`

Then:
```
pnpm deploy:sepolia --rpc-url <rpc-url> --private-key <private-key>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"dev:app": "pnpm --filter app run dev",
"dev:docs": "pnpm --filter docs run dev",
"dev:website": "pnpm --filter website run dev",
"dev:data": "concurrently \"NODE_ENV=development pnpm --filter data run dev:service\" \"NODE_ENV=development pnpm --filter data run dev:worker\"",
"dev:api": "concurrently \"NODE_ENV=development pnpm --filter api run dev:service\" \"NODE_ENV=development pnpm --filter api run dev:worker\"",
"start:reindex-market": "pnpm --filter data run start:reindex-market",
"start:reindex-missing": "pnpm --filter data run start:reindex-missing"
},
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion packages/data/package.json → packages/api/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@foil/data",
"name": "@foil/api",
"version": "1.0.0",
"private": true,
"license": "MIT",
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Resolver, Query, Arg, Int, FieldResolver, Root } from "type-graphql";
import { Between, In } from "typeorm";
import dataSource from "../../db";
import { Market } from "../../models/Market";
import { Resource } from "../../models/Resource";
Expand Down Expand Up @@ -65,6 +64,7 @@ const mapPositionToType = (position: Position): PositionType => ({
borrowedQuoteToken: position.borrowedQuoteToken,
lpBaseToken: position.lpBaseToken,
lpQuoteToken: position.lpQuoteToken,
isSettled: position.isSettled,
});

const mapTransactionToType = (transaction: Transaction): TransactionType => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ export class PositionType {

@Field(() => String, { nullable: true })
lpQuoteToken: string | null;

@Field(() => Boolean, { nullable: true })
isSettled: boolean | null;
}

@ObjectType()
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
28 changes: 20 additions & 8 deletions packages/data/src/service.ts → packages/api/src/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ const startServer = async () => {
"/markets",
handleAsyncErrors(async (req, res, next) => {
const markets = await marketRepository.find({
relations: ["epochs"],
relations: ["epochs", "resource"],
});

const formattedMarkets = markets.map((market) => ({
Expand Down Expand Up @@ -434,7 +434,7 @@ const startServer = async () => {

const positions = await positionRepository.find({
where,
relations: ["epoch", "epoch.market"],
relations: ["epoch", "epoch.market", "epoch.market.resource"],
order: { positionId: "ASC" },
});

Expand Down Expand Up @@ -478,7 +478,7 @@ const startServer = async () => {
positionId: Number(positionId),
epoch: { market: { id: market.id } },
},
relations: ["epoch", "epoch.market"],
relations: ["epoch", "epoch.market", "epoch.market.resource"],
});

if (!position) {
Expand Down Expand Up @@ -517,7 +517,8 @@ const startServer = async () => {
.innerJoinAndSelect("transaction.position", "position")
.innerJoinAndSelect("position.epoch", "epoch")
.innerJoinAndSelect("epoch.market", "market")
.innerJoinAndSelect("transaction.event", "event") // Join Event data
.innerJoinAndSelect("market.resource", "resource")
.innerJoinAndSelect("transaction.event", "event")
.where("market.chainId = :chainId", { chainId })
.andWhere("market.address = :address", { address })
.orderBy("position.positionId", "ASC")
Expand Down Expand Up @@ -957,7 +958,7 @@ const startServer = async () => {

const positions = await positionRepository.find({
where: { owner: address },
relations: ["epoch", "epoch.market", "transactions"],
relations: ["epoch", "epoch.market", "epoch.market.resource", "transactions"],
});

const transactions = await transactionRepository.find({
Expand All @@ -966,6 +967,7 @@ const startServer = async () => {
"position",
"position.epoch",
"position.epoch.market",
"position.epoch.market.resource",
"event",
],
});
Expand Down Expand Up @@ -1444,6 +1446,16 @@ const startServer = async () => {

const hydratedTransaction = {
...transaction,
position: {
...transaction.position,
epoch: {
...transaction.position?.epoch,
market: {
...transaction.position?.epoch?.market,
resource: transaction.position?.epoch?.market?.resource
}
}
},
collateralDelta: "0",
baseTokenDelta: "0",
quoteTokenDelta: "0",
Expand Down Expand Up @@ -1484,9 +1496,9 @@ const startServer = async () => {
hydratedPositions.push(hydratedTransaction);

// set up for next transaction
lastBaseToken = BigInt(currentBaseTokenBalance);
lastQuoteToken = BigInt(currentQuoteTokenBalance);
lastCollateral = BigInt(currentCollateralBalance);
lastBaseToken = BigInt(transaction.baseToken);
lastQuoteToken = BigInt(transaction.quoteToken);
lastCollateral = BigInt(transaction.collateral);
}
return hydratedPositions;
};
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
124 changes: 1 addition & 123 deletions packages/app/src/app/admin/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,103 +4,28 @@

import axios from 'axios';
import { useState } from 'react';
import { useSignMessage } from 'wagmi';

import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { toast } from '~/hooks/use-toast';
import MarketsTable from '~/lib/components/MarketsTable';
import {
ADMIN_AUTHENTICATE_MSG,
API_BASE_URL,
} from '~/lib/constants/constants';
import { API_BASE_URL } from '~/lib/constants/constants';
import type { RenderJob } from '~/lib/interfaces/interfaces';

const JobStatus = ({
job,
lastRefresh,
}: {
job: RenderJob;
lastRefresh: string;
}) => {
return (
<Card className="mt-4">
<CardHeader>
<CardTitle>Job Status</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-2">
{Object.entries(job).map(([key, value]) => (
<div className="flex justify-between" key={key}>
<p className="font-medium">{key}:</p>
<p>{value}</p>
</div>
))}
<div className="flex justify-between text-sm text-muted-foreground">
<p>Last Refresh:</p>
<p>{lastRefresh}</p>
</div>
</div>
</CardContent>
</Card>
);
};

const Admin = () => {
const [chainId, setChainId] = useState('');
const [address, setAddress] = useState('');
const [job, setJob] = useState<RenderJob | undefined>();
const [lastRefresh, setLastRefresh] = useState('');
const [loadingAction, setLoadingAction] = useState<{
[actionName: string]: boolean;
}>({});
const [reindexOpen, setReindexOpen] = useState(false);
const [statusOpen, setStatusOpen] = useState(false);
const { signMessageAsync } = useSignMessage();
const [manualServiceId, setManualServiceId] = useState('');
const [manualJobId, setManualJobId] = useState('');

const handleReindex = async () => {
try {
setLoadingAction((prev) => ({ ...prev, reindex: true }));
const timestamp = Date.now();

const signature = await signMessageAsync({
message: ADMIN_AUTHENTICATE_MSG,
});
const response = await axios.get(
`${API_BASE_URL}/reindex?chainId=${chainId}&address=${address}&signature=${signature}&timestamp=${timestamp}`
);
if (response.data.success && response.data.job) {
setJob(response.data.job);
} else {
setJob(undefined);
toast({
title: 'Failed to get position from uniswap',
description: `Unable to reindex: ${response.data.error}`,
variant: 'destructive',
});
}
setLoadingAction((prev) => ({ ...prev, reindex: false }));
} catch (e: any) {
console.error('error:', e);
setJob(undefined);
toast({
title: 'Failed to get position from uniswap',
description: `Unable to reindex: ${e?.response?.data?.error}`,
variant: 'destructive',
});
setLoadingAction((prev) => ({ ...prev, reindex: false }));
}
};

const handleGetStatus = async () => {
const serviceId = manualServiceId || job?.serviceId;
const jobId = manualJobId || job?.id;
Expand All @@ -114,7 +39,6 @@ const Admin = () => {

if (response.data.success && response.data.job) {
setJob(response.data.job);
setLastRefresh(new Date().toISOString());
}
setLoadingAction((prev) => ({ ...prev, getStatus: false }));
};
Expand All @@ -124,55 +48,9 @@ const Admin = () => {
<MarketsTable />

<div className="flex gap-4 my-4 ml-4">
<Button onClick={() => setReindexOpen(true)}>Reindex Market</Button>
<Button onClick={() => setStatusOpen(true)}>Check Job Status</Button>
</div>

<Dialog open={reindexOpen} onOpenChange={setReindexOpen}>
<DialogContent>
<DialogHeader>
<DialogTitle>Reindex Market</DialogTitle>
</DialogHeader>
<div className="space-y-4">
<div className="space-y-2">
<label className="block">
<span className="text-sm font-medium">Market Address</span>
<Input
id="marketAddress"
value={address}
onChange={(e) => setAddress(e.target.value)}
/>
</label>
</div>

<div className="space-y-2">
<label className="block">
<span className="text-sm font-medium">Chain ID</span>
<Input
id="chainId"
value={chainId}
onChange={(e) => setChainId(e.target.value)}
/>
</label>
</div>

<Button
onClick={handleReindex}
disabled={loadingAction.reindex}
className="w-full"
>
{loadingAction.reindex ? (
<div className="animate-spin"></div>
) : (
'Submit'
)}
</Button>

{job ? <JobStatus job={job} lastRefresh={lastRefresh} /> : null}
</div>
</DialogContent>
</Dialog>

<Dialog open={statusOpen} onOpenChange={setStatusOpen}>
<DialogContent>
<DialogHeader>
Expand Down
21 changes: 16 additions & 5 deletions packages/app/src/app/resources/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { useQuery } from '@tanstack/react-query';
import { type ColumnDef } from '@tanstack/react-table';
import { format } from 'date-fns';
import { ChevronRight } from 'lucide-react';
import { ChevronRight, Loader2 } from 'lucide-react';
import Link from 'next/link';
import React from 'react';
import { formatUnits } from 'viem';
Expand Down Expand Up @@ -159,7 +159,8 @@ const generatePlaceholderIndexPrices = () => {

const renderPriceDisplay = (
isLoading: boolean,
price: ResourcePrice | undefined
price: ResourcePrice | undefined,
resourceId: string
) => {
if (isLoading) {
return <span className="text-2xl font-bold">Loading...</span>;
Expand All @@ -169,15 +170,17 @@ const renderPriceDisplay = (
return <span className="text-2xl font-bold">No price data</span>;
}

const unit = resourceId === 'celestia-blobspace' ? 'μTIA' : 'gwei';

return (
<span className="text-2xl font-bold">
<NumberDisplay value={formatUnits(BigInt(price.value), 9)} /> gwei
<NumberDisplay value={formatUnits(BigInt(price.value), 9)} /> {unit}
</span>
);
};

const MarketContent = ({ params }: { params: { id: string } }) => {
const { data: resources } = useResources();
const { data: resources, isLoading: isLoadingResources } = useResources();
const category = MARKET_CATEGORIES.find((c) => c.id === params.id);
const { data: latestPrice, isLoading: isPriceLoading } =
useLatestResourcePrice(params.id);
Expand Down Expand Up @@ -222,6 +225,14 @@ const MarketContent = ({ params }: { params: { id: string } }) => {
);
}

if (isLoadingResources) {
return (
<div className="flex justify-center items-center py-8">
<Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
</div>
);
}

// Get the current resource and its markets
const resource = resources?.find((r) => r.slug === params.id);
const epochs =
Expand Down Expand Up @@ -253,7 +264,7 @@ const MarketContent = ({ params }: { params: { id: string } }) => {
Current Price
</span>
<div className="flex items-baseline gap-2">
{renderPriceDisplay(isPriceLoading, latestPrice)}
{renderPriceDisplay(isPriceLoading, latestPrice, params.id)}
</div>
</div>
</CardContent>
Expand Down
Loading

0 comments on commit da6e5e6

Please sign in to comment.