Skip to content

Commit

Permalink
Lp inspect: move registry info to frontend (#197)
Browse files Browse the repository at this point in the history
  • Loading branch information
grod220 authored Dec 10, 2024
1 parent 3d12b04 commit 04771cd
Show file tree
Hide file tree
Showing 14 changed files with 407 additions and 343 deletions.
111 changes: 108 additions & 3 deletions src/pages/inspect/lp/api/position.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,117 @@
import { useQuery } from '@tanstack/react-query';
import { PositionTimelineResponse } from '@/shared/api/server/position/timeline/types';
import {
PositionExecutions,
PositionStateResponse,
PositionTimelineResponse,
PositionWithdrawal,
VolumeAndFeesResponse,
} from '@/shared/api/server/position/timeline/types';
import { apiFetch } from '@/shared/utils/api-fetch.ts';
import {
PositionExecutionsVV,
PositionStateVV,
PositionTimelineResponseVV,
PositionWithdrawalVV,
VolumeAndFeesAll,
} from '@/pages/inspect/lp/api/types.ts';
import { Registry } from '@penumbra-labs/registry';
import { registryQueryFn } from '@/shared/api/registry.ts';
import { getValueView } from '@/shared/api/server/book/helpers.ts';

const positionsStateAddVV = (res: PositionStateResponse, registry: Registry): PositionStateVV => {
return {
reserves1: getValueView(registry, res.reserves1),
reserves2: getValueView(registry, res.reserves2),
unit1: getValueView(registry, res.unit1),
unit2: getValueView(registry, res.unit2),
offer1: getValueView(registry, res.offer1),
offer2: getValueView(registry, res.offer2),
priceRef1: getValueView(registry, res.priceRef1),
priceRef2: getValueView(registry, res.priceRef2),
priceRef1Inv: getValueView(registry, res.priceRef1Inv),
priceRef2Inv: getValueView(registry, res.priceRef2Inv),
feeBps: res.feeBps,
openingHeight: res.openingHeight,
openingTime: res.openingTime,
openingTx: res.openingTx,
closingHeight: res.closingHeight,
closingTime: res.closingTime,
closingTx: res.closingTx,
};
};

const executionsAddVV = (res: PositionExecutions, registry: Registry): PositionExecutionsVV => {
return {
items: res.items.map(p => ({
input: getValueView(registry, p.input),
output: getValueView(registry, p.output),
fee: getValueView(registry, p.fee),
reserves1: getValueView(registry, p.reserves1),
reserves2: getValueView(registry, p.reserves2),
contextStart: registry.getMetadata(p.contextStart),
contextEnd: registry.getMetadata(p.contextEnd),
time: p.time,
height: p.height,
})),
skipped: res.skipped,
};
};

const withdrawalsAddVV = (
res: PositionWithdrawal[],
registry: Registry,
): PositionWithdrawalVV[] => {
return res.map(w => ({
reserves1: getValueView(registry, w.reserves1),
reserves2: getValueView(registry, w.reserves2),
time: w.time,
height: w.height,
txHash: w.txHash,
}));
};

const volumeAddVV = (res: VolumeAndFeesResponse, registry: Registry): VolumeAndFeesAll => {
return {
asset1: registry.getMetadata(res.asset1),
asset2: registry.getMetadata(res.asset2),
totals: {
volume1: getValueView(registry, res.totals.volume1),
volume2: getValueView(registry, res.totals.volume2),
fees1: getValueView(registry, res.totals.fees1),
fees2: getValueView(registry, res.totals.fees2),
executionCount: res.totals.executionCount,
},
all: res.all.map(v => ({
volume1: getValueView(registry, v.volume1),
volume2: getValueView(registry, v.volume2),
fees1: getValueView(registry, v.fees1),
fees2: getValueView(registry, v.fees2),
contextAssetStart: registry.getMetadata(v.contextAssetStart),
contextAssetEnd: registry.getMetadata(v.contextAssetEnd),
executionCount: v.executionCount,
})),
};
};

const timelineFetch = async (id: string): Promise<PositionTimelineResponseVV> => {
const result = await apiFetch<PositionTimelineResponse>(
`/api/position/timeline?positionId=${id}`,
);

const registry = await registryQueryFn();

return {
state: positionsStateAddVV(result.state, registry),
executions: executionsAddVV(result.executions, registry),
withdrawals: withdrawalsAddVV(result.withdrawals, registry),
volumeAndFees: volumeAddVV(result.volumeAndFees, registry),
};
};

export const useLpPosition = (id: string) => {
return useQuery({
queryKey: ['lpPosition', id],
retry: 1,
queryFn: async () =>
apiFetch<PositionTimelineResponse>(`/api/position/timeline?positionId=${id}`),
queryFn: () => timelineFetch(id),
});
};
70 changes: 70 additions & 0 deletions src/pages/inspect/lp/api/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { Metadata, ValueView } from '@penumbra-zone/protobuf/penumbra/core/asset/v1/asset_pb';

export interface PositionStateVV {
reserves1: ValueView;
reserves2: ValueView;
unit1: ValueView;
unit2: ValueView;
offer1: ValueView;
offer2: ValueView;
priceRef1: ValueView;
priceRef2: ValueView;
priceRef1Inv: ValueView;
priceRef2Inv: ValueView;
feeBps: number;
openingHeight: number;
openingTime: string;
openingTx?: string;
closingHeight?: number;
closingTime?: string;
closingTx?: string;
}

export interface VolumeAndFeesVV {
volume1: ValueView;
volume2: ValueView;
fees1: ValueView;
fees2: ValueView;
contextAssetStart: Metadata;
contextAssetEnd: Metadata;
executionCount: number;
}

export interface VolumeAndFeesAll {
asset1: Metadata;
asset2: Metadata;
totals: Omit<VolumeAndFeesVV, 'contextAssetStart' | 'contextAssetEnd'>;
all: VolumeAndFeesVV[];
}

export interface PositionWithdrawalVV {
reserves1: ValueView;
reserves2: ValueView;
time: string;
height: number;
txHash: string;
}

export interface PositionExecutionVV {
input: ValueView;
output: ValueView;
fee: ValueView;
reserves1: ValueView;
reserves2: ValueView;
contextStart: Metadata;
contextEnd: Metadata;
time: string;
height: number;
}

export interface PositionExecutionsVV {
items: PositionExecutionVV[];
skipped: number;
}

export interface PositionTimelineResponseVV {
executions: PositionExecutionsVV;
state: PositionStateVV;
withdrawals: PositionWithdrawalVV[];
volumeAndFees: VolumeAndFeesAll;
}
13 changes: 5 additions & 8 deletions src/pages/inspect/ui/actions.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { Text } from '@penumbra-zone/ui/Text';
import {
PositionStateResponse,
PositionWithdrawal,
} from '@/shared/api/server/position/timeline/types.ts';
import { Card } from '@penumbra-zone/ui/Card';
import { ValueViewComponent } from '@penumbra-zone/ui/ValueView';
import { TimeDisplay } from '@/pages/inspect/ui/time.tsx';
import { useLpIdInUrl } from '@/pages/inspect/ui/result.tsx';
import { useLpPosition } from '@/pages/inspect/lp/api/position.ts';
import { Skeleton } from '@/shared/ui/skeleton.tsx';
import { PositionStateVV, PositionWithdrawalVV } from '@/pages/inspect/lp/api/types.ts';

export const PositionClosed = ({
closingTx,
Expand Down Expand Up @@ -43,7 +40,7 @@ export const PositionClosed = ({
);
};

export const PositionWithdraw = ({ withdrawal }: { withdrawal: PositionWithdrawal }) => {
export const PositionWithdraw = ({ withdrawal }: { withdrawal: PositionWithdrawalVV }) => {
return (
<div className='grid grid-cols-6 items-center mb-4'>
<div className='col-span-4'>
Expand All @@ -69,7 +66,7 @@ export const PositionWithdraw = ({ withdrawal }: { withdrawal: PositionWithdrawa
);
};

export const PositionOpen = ({ state }: { state: PositionStateResponse }) => {
export const PositionOpen = ({ state }: { state: PositionStateVV }) => {
return (
<div className='grid grid-cols-6 items-center mb-4'>
<div className='col-span-4'>
Expand Down Expand Up @@ -99,8 +96,8 @@ const DataBody = ({
state,
withdrawals,
}: {
state: PositionStateResponse;
withdrawals: PositionWithdrawal[];
state: PositionStateVV;
withdrawals: PositionWithdrawalVV[];
}) => {
return (
<div className='flex flex-col gap-4 justify-center'>
Expand Down
23 changes: 10 additions & 13 deletions src/pages/inspect/ui/executions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,15 @@ import { TimeDisplay } from '@/pages/inspect/ui/time.tsx';
import { useLpIdInUrl } from '@/pages/inspect/ui/result.tsx';
import { useLpPosition } from '@/pages/inspect/lp/api/position.ts';
import { Skeleton } from '@/shared/ui/skeleton.tsx';
import { PositionClosed, PositionOpen, PositionWithdraw } from '@/pages/inspect/ui/actions.tsx';
import {
PositionExecutions,
PositionStateResponse,
PositionWithdrawal,
} from '@/shared/api/server/position/timeline/types.ts';
import { PositionWithdraw, PositionClosed, PositionOpen } from '@/pages/inspect/ui/actions.tsx';
PositionExecutionsVV,
PositionExecutionVV,
PositionStateVV,
PositionWithdrawalVV,
} from '@/pages/inspect/lp/api/types.ts';

interface ExecutionProps {
execution: PositionExecutions['items'][0];
}

const Execution = ({ execution: e }: ExecutionProps) => {
const Execution = ({ execution: e }: { execution: PositionExecutionVV }) => {
return (
<div className='grid grid-cols-6 items-center mb-4'>
<div className='col-span-2'>
Expand Down Expand Up @@ -93,9 +90,9 @@ const DataBody = ({
withdrawals,
executions,
}: {
state: PositionStateResponse;
withdrawals: PositionWithdrawal[];
executions: PositionExecutions;
state: PositionStateVV;
withdrawals: PositionWithdrawalVV[];
executions: PositionExecutionsVV;
}) => {
return (
<div>
Expand Down
4 changes: 2 additions & 2 deletions src/pages/inspect/ui/state-details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { Icon } from '@penumbra-zone/ui/Icon';
import { Density } from '@penumbra-zone/ui/Density';
import { useLpPosition } from '@/pages/inspect/lp/api/position.ts';
import { useLpIdInUrl } from '@/pages/inspect/ui/result.tsx';
import { PositionStateResponse } from '@/shared/api/server/position/timeline/types.ts';
import { Skeleton } from '@/shared/ui/skeleton.tsx';
import { PositionStateVV } from '@/pages/inspect/lp/api/types.ts';

const DataBody = ({ state }: { state: PositionStateResponse }) => {
const DataBody = ({ state }: { state: PositionStateVV }) => {
return (
<>
<div className='flex items-start justify-between gap-2'>
Expand Down
14 changes: 10 additions & 4 deletions src/pages/inspect/ui/volume.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { Table } from '@penumbra-zone/ui/Table';
import { AssetIcon } from '@penumbra-zone/ui/AssetIcon';
import { useLpIdInUrl } from '@/pages/inspect/ui/result.tsx';
import { useLpPosition } from '@/pages/inspect/lp/api/position.ts';
import { VolumeAndFeesResponse } from '@/shared/api/server/position/timeline/types.ts';
import { Skeleton } from '@/shared/ui/skeleton';
import { Card } from '@penumbra-zone/ui/Card';
import { VolumeAndFeesAll } from '@/pages/inspect/lp/api/types.ts';

const skeletonRows = 4;

Expand Down Expand Up @@ -52,7 +52,7 @@ const LoadingState = () => {
);
};

const DataBody = ({ v }: { v: VolumeAndFeesResponse }) => {
const DataBody = ({ v }: { v: VolumeAndFeesAll }) => {
return (
<Density compact>
<Table>
Expand Down Expand Up @@ -116,9 +116,15 @@ const DataBody = ({ v }: { v: VolumeAndFeesResponse }) => {
<Table.Tr key={i}>
<Table.Td>
<div className='flex items-center gap-2'>
<AssetIcon metadata={row.contextAssetStart} />
<div className='flex gap-1'>
<AssetIcon metadata={row.contextAssetStart} />
{row.contextAssetStart.symbol}
</div>
<Icon IconComponent={ArrowRight} color='text.primary' size='sm' />
<AssetIcon metadata={row.contextAssetEnd} />
<div className='flex gap-1'>
<AssetIcon metadata={row.contextAssetEnd} />
{row.contextAssetEnd.symbol}
</div>
</div>
</Table.Td>
<Table.Td hAlign='center'>
Expand Down
5 changes: 5 additions & 0 deletions src/pages/trade/ui/positions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
import { bech32mPositionId } from '@penumbra-zone/bech32m/plpid';
import { Button } from '@penumbra-zone/ui/Button';
import { positionsStore } from '@/pages/trade/model/positions';
import Link from 'next/link';
import { SquareArrowOutUpRight } from 'lucide-react';

const LoadingRow = () => {
return (
Expand Down Expand Up @@ -260,6 +262,9 @@ const PositionsInner = observer(({ showInactive }: { showInactive: boolean }) =>
<Text detail color='text.secondary' truncate>
{bech32PositionId}
</Text>
<Link href={`/inspect/lp/${bech32PositionId}`}>
<SquareArrowOutUpRight className='w-4 h-4 text-text-secondary' />
</Link>
</Cell>
<Cell>
<ActionButton state={p.positionState} id={p.positionId} />
Expand Down
Loading

0 comments on commit 04771cd

Please sign in to comment.