Skip to content

Commit

Permalink
sdk v2
Browse files Browse the repository at this point in the history
  • Loading branch information
Tarnadas committed Nov 22, 2024
1 parent 2bba396 commit ca32142
Show file tree
Hide file tree
Showing 13 changed files with 426 additions and 529 deletions.
1 change: 1 addition & 0 deletions app/components/Assets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export const Assets: FC = () => {
});
const balance = useMemo(
() => (status >= AccountStatusEnum.Connected ? deposit.balance : undefined),
// eslint-disable-next-line react-hooks/exhaustive-deps
[status, deposit, account.chainId]
);
const { withdraw, availableWithdraw } = useWithdraw();
Expand Down
158 changes: 65 additions & 93 deletions app/components/ClosePosition.tsx
Original file line number Diff line number Diff line change
@@ -1,61 +1,67 @@
import { useOrderEntry, useSymbolsInfo } from '@orderly.network/hooks';
import { API, OrderEntity, OrderSide, OrderType } from '@orderly.network/types';
import { API, OrderlyOrder, OrderSide, OrderType } from '@orderly.network/types';
import { Slider } from '@radix-ui/themes';
import { useNotifications } from '@web3-onboard/react';
import { FixedNumber } from 'ethers';
import { Dispatch, FC, SetStateAction, useState } from 'react';
import { Controller, SubmitHandler, useForm } from 'react-hook-form';
import { Dispatch, FC, SetStateAction, useCallback, useState } from 'react';

import { Spinner, TokenInput } from '.';

import { getDecimalsFromTick } from '~/utils';
import { renderFormError } from '~/utils/form';

type Inputs = {
direction: OrderSide;
type: OrderType;
quantity: string | number;
};

export const ClosePosition: FC<{
position: API.PositionExt;
refresh: import('swr/_internal').KeyedMutator<API.PositionInfo>;
setOpen: Dispatch<SetStateAction<boolean>>;
}> = ({ position, refresh, setOpen }) => {
}> = ({ position, setOpen }) => {
const [loading, setLoading] = useState(false);

const symbolsInfo = useSymbolsInfo();

const { register, handleSubmit, control } = useForm<Inputs>({
defaultValues: {
direction: position.position_qty > 0 ? OrderSide.SELL : OrderSide.BUY,
type: OrderType.MARKET,
quantity: Math.abs(position.position_qty)
const {
submit,
setValue,
formattedOrder,
metaState: { dirty, errors, submitted }
} = useOrderEntry(position.symbol, {
initialOrder: {
side: position.position_qty > 0 ? OrderSide.SELL : OrderSide.BUY,
order_type: OrderType.MARKET,
order_quantity: String(Math.abs(position.position_qty)),
reduce_only: true
}
});
const { onSubmit, helper } = useOrderEntry(
{
symbol: position.symbol,
side: OrderSide.BUY,
order_type: OrderType.MARKET
const hasError = useCallback(
(
key: keyof OrderlyOrder
):
| {
type: string;
message: string;
}
| undefined => {
if (!dirty[key] && !submitted) {
return;
}
return errors?.[key];
},
{ watchOrderbook: true }
[errors, dirty, submitted]
);
const [_0, customNotification] = useNotifications();

if (symbolsInfo.isNil) {
return <Spinner />;
}

const submitForm: SubmitHandler<Inputs> = async (data) => {
const submitForm = async () => {
setLoading(true);
const { update } = customNotification({
eventCode: 'closePosition',
type: 'pending',
message: 'Closing position...'
});
try {
await onSubmit(getInput(data, position.symbol));
await submit();
update({
eventCode: 'closePositionSuccess',
type: 'success',
Expand All @@ -72,7 +78,6 @@ export const ClosePosition: FC<{
});
} finally {
setLoading(false);
refresh();
setOpen(false);
}
};
Expand All @@ -82,62 +87,47 @@ export const ClosePosition: FC<{
const [baseDecimals] = getDecimalsFromTick(symbolInfo);

return (
<form className="flex flex-1 flex-col gap-6 w-full" onSubmit={handleSubmit(submitForm)}>
<form
className="flex flex-1 flex-col gap-6 w-full"
onSubmit={(event) => {
event.preventDefault();
submitForm();
}}
>
<div>Partially or fully close your open position at mark price.</div>

<input className="hidden" {...register('direction')} />
<input className="hidden" {...register('type')} />

<label className="flex flex-col">
<span className="font-bold font-size-5">Quantity ({base})</span>
<Controller
name="quantity"
control={control}
rules={{
validate: {
custom: async (_, data) => {
const errors = await getValidationErrors(data, position.symbol, helper.validator);
return errors?.order_quantity != null ? errors.order_quantity.message : true;
}
}

<TokenInput
className={`mb-2 ${hasError('order_quantity') ? 'border-[var(--color-red)]' : ''}`}
decimals={baseDecimals}
placeholder="Quantity"
name="order_quantity"
value={formattedOrder.order_quantity}
onValueChange={(value) => {
setValue('order_quantity', value.toString());
}}
render={({ field: { name, onBlur, onChange, value }, fieldState: { error } }) => (
<>
<TokenInput
className={`mb-2 ${error != null ? 'border-[var(--color-red)]' : ''}`}
decimals={baseDecimals}
placeholder="Quantity"
name={name}
onBlur={onBlur}
onChange={onChange}
value={value}
onValueChange={(newVal) => {
value = newVal.toString();
}}
min={FixedNumber.fromString('0')}
max={FixedNumber.fromString(String(Math.abs(position.position_qty)))}
hasError={error != null}
/>
<Slider
value={[Number(value)]}
defaultValue={[100]}
variant="surface"
name={name}
onValueChange={(value) => {
onChange(value[0]);
}}
onValueCommit={onBlur}
min={0}
max={Math.abs(position.position_qty)}
step={symbolInfo.base_tick}
/>
<div className="font-size-[1.1rem] flex w-full justify-center my-1">
{value} {base}
</div>
{renderFormError(error)}
</>
)}
min={FixedNumber.fromString('0')}
max={FixedNumber.fromString(String(Math.abs(position.position_qty)))}
hasError={!!hasError('order_quantity')}
/>
<Slider
value={[Number(formattedOrder.order_quantity)]}
defaultValue={[100]}
variant="surface"
name="order_quantity"
onValueChange={(value) => {
setValue('order_quantity', value.toString());
}}
min={0}
max={Math.abs(position.position_qty)}
step={symbolInfo.base_tick}
/>
<div className="font-size-[1.1rem] flex w-full justify-center my-1">
{formattedOrder.order_quantity} {base}
</div>
{renderFormError(hasError('order_quantity'))}
</label>

<button
Expand All @@ -150,21 +140,3 @@ export const ClosePosition: FC<{
</form>
);
};

async function getValidationErrors(
data: Inputs,
symbol: string,
validator: ReturnType<typeof useOrderEntry>['helper']['validator']
): Promise<ReturnType<ReturnType<typeof useOrderEntry>['helper']['validator']>> {
return validator(getInput(data, symbol));
}

function getInput(data: Inputs, symbol: string): OrderEntity {
return {
symbol,
side: data.direction,
order_type: data.type,
order_quantity: String(data.quantity),
reduce_only: true
};
}
Loading

0 comments on commit ca32142

Please sign in to comment.