-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New token input feature flagged (#1270)
* input almost there * token input finished with placeholders * token picker fixed * slippage fully added * primary stats created * max button wired up * feature flag primary stats * cleanup globals * final cleanup * fix feature flagged modal header * updates per comments * update coding style guide * fix icons * rename openlongprimarystats * rename file
- Loading branch information
1 parent
0e34ad7
commit e38b87e
Showing
10 changed files
with
605 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
apps/hyperdrive-trading/src/ui/base/components/PrimaryStat.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { ReactNode } from "react"; | ||
|
||
export function PrimaryStat({ | ||
label, | ||
value, | ||
valueUnit, | ||
subValue, | ||
valueClassName, | ||
}: { | ||
label: string; | ||
value: ReactNode; | ||
valueUnit: string; | ||
subValue?: ReactNode; | ||
valueClassName?: string; | ||
}): JSX.Element { | ||
return ( | ||
<div className="flex flex-col gap-1"> | ||
<p className="text-sm text-neutral-content">{label}</p> | ||
<div className={valueClassName}> | ||
<p className="text-h3 font-bold">{value}</p> | ||
<p className="ml-1">{valueUnit}</p> | ||
</div> | ||
{subValue && <p className="text-sm text-neutral-content">{subValue}</p>} | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
125 changes: 125 additions & 0 deletions
125
apps/hyperdrive-trading/src/ui/hyperdrive/longs/OpenLongPreview/OpenLongStats.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
import { calculateAprFromPrice } from "@delvtech/hyperdrive-viem"; | ||
import { | ||
findBaseToken, | ||
findYieldSourceToken, | ||
HyperdriveConfig, | ||
TokenConfig, | ||
} from "@hyperdrive/appconfig"; | ||
import classNames from "classnames"; | ||
import Skeleton from "react-loading-skeleton"; | ||
import { convertMillisecondsToDays } from "src/base/convertMillisecondsToDays"; | ||
import { formatRate } from "src/base/formatRate"; | ||
import { QueryStatusWithIdle } from "src/base/queryStatus"; | ||
import { convertSharesToBase } from "src/hyperdrive/convertSharesToBase"; | ||
import { useAppConfig } from "src/ui/appconfig/useAppConfig"; | ||
import { PrimaryStat } from "src/ui/base/components/PrimaryStat"; | ||
import { formatBalance } from "src/ui/base/formatting/formatBalance"; | ||
import { useFixedRate } from "src/ui/hyperdrive/longs/hooks/useFixedRate"; | ||
interface OpenLongStatsProps { | ||
hyperdrive: HyperdriveConfig; | ||
bondAmount: bigint; | ||
amountPaid: bigint; | ||
openLongPreviewStatus: QueryStatusWithIdle; | ||
activeToken: TokenConfig<any>; | ||
asBase: boolean; | ||
vaultSharePrice: bigint | undefined; | ||
} | ||
export function OpenLongStats({ | ||
hyperdrive, | ||
openLongPreviewStatus, | ||
amountPaid, | ||
bondAmount, | ||
activeToken, | ||
asBase, | ||
vaultSharePrice, | ||
}: OpenLongStatsProps): JSX.Element { | ||
const appConfig = useAppConfig(); | ||
const baseToken = findBaseToken({ | ||
baseTokenAddress: hyperdrive.baseToken, | ||
tokens: appConfig.tokens, | ||
}); | ||
const sharesToken = findYieldSourceToken({ | ||
yieldSourceTokenAddress: hyperdrive.sharesToken, | ||
tokens: appConfig.tokens, | ||
}); | ||
const { fixedApr } = useFixedRate(hyperdrive.address); | ||
|
||
const isBaseAmount = asBase || sharesToken.extensions.isSharesPeggedToBase; | ||
const amountPaidInBase = isBaseAmount | ||
? amountPaid | ||
: convertSharesToBase({ | ||
sharesAmount: amountPaid, | ||
vaultSharePrice: vaultSharePrice, | ||
decimals: baseToken.decimals, | ||
}); | ||
const yieldAtMaturity = bondAmount - amountPaidInBase; | ||
const termLengthMS = Number(hyperdrive.poolConfig.positionDuration * 1000n); | ||
const numDays = convertMillisecondsToDays(termLengthMS); | ||
return ( | ||
<div className="flex flex-row justify-between px-4"> | ||
<PrimaryStat | ||
label="Your Fixed Rate" | ||
value={ | ||
openLongPreviewStatus === "loading" ? ( | ||
<Skeleton width={100} /> | ||
) : ( | ||
<> | ||
{bondAmount > 0 | ||
? `${formatRate( | ||
calculateAprFromPrice({ | ||
positionDuration: | ||
hyperdrive.poolConfig.positionDuration || 0n, | ||
baseAmount: amountPaidInBase, | ||
bondAmount: bondAmount, | ||
}), | ||
baseToken.decimals, | ||
)}%` | ||
: `${fixedApr?.formatted}%`} | ||
</> | ||
) | ||
} | ||
valueUnit="APR" | ||
subValue={ | ||
openLongPreviewStatus === "loading" ? ( | ||
<Skeleton width={100} /> | ||
) : ( | ||
<>{`${formatBalance({ | ||
balance: bondAmount, | ||
decimals: baseToken.decimals, | ||
places: baseToken.places, | ||
})} hy${baseToken.symbol}`}</> | ||
) | ||
} | ||
valueClassName="bg-gradient-to-r from-accent to-primary bg-clip-text text-transparent flex items-end" | ||
/> | ||
<div className="daisy-divider daisy-divider-horizontal mx-0" /> | ||
<PrimaryStat | ||
label="Value at Maturity" | ||
value={ | ||
openLongPreviewStatus === "loading" ? ( | ||
<Skeleton width={100} /> | ||
) : ( | ||
<span | ||
className={classNames("flex", { | ||
"text-base-content/80": !amountPaid, | ||
})} | ||
> | ||
<img | ||
src={activeToken.iconUrl} | ||
className="mr-1 h-9 rounded-full p-1" | ||
/> | ||
{`${formatBalance({ | ||
balance: amountPaidInBase + yieldAtMaturity, | ||
decimals: baseToken.decimals, | ||
places: baseToken.places, | ||
})} `} | ||
</span> | ||
) | ||
} | ||
valueUnit={`${activeToken.symbol}`} | ||
valueClassName="text-base-content flex items-end" | ||
subValue={`Term: ${numDays} days`} | ||
/> | ||
</div> | ||
); | ||
} |
Oops, something went wrong.