Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LP position action views #187

Merged
merged 1 commit into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions packages/ui/components/ui/tx/action-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import { ActionDutchAuctionWithdrawViewComponent } from './actions-views/action-
import { ValueView } from '@penumbra-zone/protobuf/penumbra/core/asset/v1/asset_pb';
import { DelegatorVoteComponent } from './actions-views/delegator-vote';
import { ValidatorVoteComponent } from './actions-views/validator-vote';
import { PositionOpenComponent } from './actions-views/position-open';
import { PositionCloseComponent } from './actions-views/position-close';
import { PositionWithdrawComponent } from './actions-views/position-withdraw';

type Case = Exclude<ActionView['actionView']['case'], undefined>;

Expand Down Expand Up @@ -121,13 +124,13 @@ export const ActionViewComponent = ({
return <UnimplementedView label='Proposal Deposit Claim' />;

case 'positionOpen':
return <UnimplementedView label='Position Open' />;
return <PositionOpenComponent value={actionView.value} />;

case 'positionClose':
return <UnimplementedView label='Position Close' />;
return <PositionCloseComponent value={actionView.value} />;

case 'positionWithdraw':
return <UnimplementedView label='Position Withdraw' />;
return <PositionWithdrawComponent value={actionView.value} />;

case 'positionRewardClaim':
return <UnimplementedView label='Position Reward Claim' />;
Expand Down
21 changes: 21 additions & 0 deletions packages/ui/components/ui/tx/actions-views/position-close.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ViewBox } from '../viewbox';
import { ActionDetails } from './action-details';
import { PositionClose } from '@penumbra-zone/protobuf/penumbra/core/component/dex/v1/dex_pb';
import { bech32mPositionId } from '@penumbra-zone/bech32m/plpid';

export const PositionCloseComponent = ({ value }: { value: PositionClose }) => {
return (
<ViewBox
label='Position Close'
visibleContent={
<ActionDetails>
{value.positionId && (
<ActionDetails.Row label='Position ID'>
{bech32mPositionId(value.positionId)}
</ActionDetails.Row>
)}
</ActionDetails>
}
/>
);
};
126 changes: 126 additions & 0 deletions packages/ui/components/ui/tx/actions-views/position-open.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { ViewBox } from '../viewbox';
import { ActionDetails } from './action-details';
import { uint8ArrayToBase64 } from '@penumbra-zone/types/base64';
import {
PositionOpen,
PositionState_PositionStateEnum,
} from '@penumbra-zone/protobuf/penumbra/core/component/dex/v1/dex_pb';
import { joinLoHiAmount } from '@penumbra-zone/types/amount';
import { bech32mAssetId } from '@penumbra-zone/bech32m/passet';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../tooltip';
import { InfoIcon } from 'lucide-react';

export const PositionOpenComponent = ({ value }: { value: PositionOpen }) => {
return (
<ViewBox
label='Position Open'
visibleContent={
<ActionDetails>
<ActionDetails.Row label='State'>
{stateToString(value.position?.state?.state)}
</ActionDetails.Row>

<ActionDetails.Row label='Sequence'>
{value.position?.state?.sequence ? value.position.state.sequence.toString() : '0'}
</ActionDetails.Row>

{!!value.position?.phi?.pair?.asset1 && (
<ActionDetails.Row label='Asset 1'>
<ActionDetails.TruncatedText>
{bech32mAssetId(value.position.phi.pair.asset1)}
</ActionDetails.TruncatedText>
</ActionDetails.Row>
)}

{!!value.position?.phi?.pair?.asset2 && (
<ActionDetails.Row label='Asset 2'>
<ActionDetails.TruncatedText>
{bech32mAssetId(value.position.phi.pair.asset2)}
</ActionDetails.TruncatedText>
</ActionDetails.Row>
)}

{!!value.position?.phi?.component?.fee && (
<ActionDetails.Row label='fee'>{value.position.phi.component.fee}</ActionDetails.Row>
)}

{value.position?.nonce && (
<ActionDetails.Row label='Nonce'>
<ActionDetails.TruncatedText>
{uint8ArrayToBase64(value.position.nonce)}
</ActionDetails.TruncatedText>
</ActionDetails.Row>
)}

<ActionDetails.Row label='Close on fill'>
{value.position?.closeOnFill ? 'true' : 'false'}
</ActionDetails.Row>

<div className='flex gap-2'>
<p className='font-bold'>Trading Parameters</p>
<TooltipProvider>
<Tooltip>
<TooltipTrigger>
<InfoIcon className='size-4 cursor-pointer text-muted-foreground hover:text-[#8D5728]' />
</TooltipTrigger>
<TooltipContent className='w-[250px]'>
<p>
p and q are the price coefficients of the trading function: phi(r1, r2) = p * r1
+ q * r2, where r1 and r2 represent the old and new reserves.
</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>

{value.position?.phi?.component?.p && (
<ActionDetails.Row label='p'>
{joinLoHiAmount(value.position.phi.component.p).toString()}
</ActionDetails.Row>
)}

{value.position?.phi?.component?.q && (
<ActionDetails.Row label='q'>
{joinLoHiAmount(value.position.phi.component.q).toString()}
</ActionDetails.Row>
)}

{value.position?.reserves?.r1 && (
<ActionDetails.Row label='r1'>
{joinLoHiAmount(value.position.reserves.r1).toString()}
</ActionDetails.Row>
)}

{value.position?.reserves?.r2 && (
<ActionDetails.Row label='r2'>
{joinLoHiAmount(value.position.reserves.r2).toString()}
</ActionDetails.Row>
)}
</ActionDetails>
}
/>
);
};

export const stateToString = (state?: PositionState_PositionStateEnum): string => {
switch (state) {
case PositionState_PositionStateEnum.UNSPECIFIED: {
return 'UNSPECIFIED';
}
case PositionState_PositionStateEnum.OPENED: {
return 'OPENED';
}
case PositionState_PositionStateEnum.CLOSED: {
return 'CLOSED';
}
case PositionState_PositionStateEnum.WITHDRAWN: {
return 'WITHDRAWN';
}
case PositionState_PositionStateEnum.CLAIMED: {
return 'CLAIMED';
}
case undefined: {
return 'UNSPECIFIED';
}
}
};
32 changes: 32 additions & 0 deletions packages/ui/components/ui/tx/actions-views/position-withdraw.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { ViewBox } from '../viewbox';
import { ActionDetails } from './action-details';
import { PositionWithdraw } from '@penumbra-zone/protobuf/penumbra/core/component/dex/v1/dex_pb';
import { bech32mPositionId } from '@penumbra-zone/bech32m/plpid';
import { uint8ArrayToBase64 } from '@penumbra-zone/types/base64';

export const PositionWithdrawComponent = ({ value }: { value: PositionWithdraw }) => {
return (
<ViewBox
label='Position Withdraw'
visibleContent={
<ActionDetails>
{value.positionId && (
<ActionDetails.Row label='Position ID'>
{bech32mPositionId(value.positionId)}
</ActionDetails.Row>
)}

<ActionDetails.Row label='Sequence'>
{value.sequence ? value.sequence.toString() : '0'}
</ActionDetails.Row>

{value.reservesCommitment?.inner && (
<ActionDetails.Row label='Reserves commitment'>
{uint8ArrayToBase64(value.reservesCommitment.inner)}
</ActionDetails.Row>
)}
</ActionDetails>
}
/>
);
};