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

Money Market #1003

Draft
wants to merge 19 commits into
base: develop
Choose a base branch
from
Draft
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
6 changes: 5 additions & 1 deletion apps/frontend/.env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
REACT_APP_RATES_HISTORY_API_URL=https://bob-mm-cache.test.sovryn.app/data/rates-history

REACT_APP_GRAPH_RSK=https://subgraph.test.sovryn.app/subgraphs/name/DistributedCollective/sovryn-subgraph

REACT_APP_GRAPH_BOB=https://bob-ambient-subgraph.test.sovryn.app/subgraphs/name/DistributedCollective/bob-ambient-subgraph
Expand All @@ -23,4 +25,6 @@ REACT_APP_ENABLE_SERVICE_WORKER=false
REACT_APP_SIMULATE_TX=false
REACT_APP_ESTIMATOR_URI=https://simulator.sovryn.app

REACT_APP_DATADOG_CLIENT_TOKEN=
REACT_APP_DATADOG_CLIENT_TOKEN=

REACT_APP_GRAPH_BOB_AAVE=https://bob-mm.test.sovryn.app/subgraphs/name/DistributedCollective/sov-protocol-subgraphs
5 changes: 5 additions & 0 deletions apps/frontend/codegen.fetch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ generates:
- ${REACT_APP_GRAPH_BOB}
plugins:
- schema-ast
./src/utils/graphql/bobAave/schema.graphql:
schema:
- ${REACT_APP_GRAPH_BOB_AAVE}
plugins:
- schema-ast
hooks:
afterAllFileWrite:
- prettier ./src/utils/graphql/**/schema.graphql --write
15 changes: 15 additions & 0 deletions apps/frontend/codegen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,21 @@ generates:
Bytes: string
BigInt: string
BigDecimal: string
./src/utils/graphql/bobAave/generated.tsx:
schema:
- './src/utils/graphql/bobAave/schema.graphql'
documents:
- './src/utils/graphql/bobAave/operations/*.graphql'
plugins:
- typescript
- typescript-operations
- typescript-react-apollo
config:
withHooks: true
scalars:
Bytes: string
BigInt: string
BigDecimal: string
./src/utils/graphql/zero/generated.tsx:
schema:
- './src/utils/graphql/zero/schema.graphql'
Expand Down
4 changes: 4 additions & 0 deletions apps/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
"homepage": ".",
"private": true,
"dependencies": {
"@aave/contract-helpers": "1.29.1",
"@aave/math-utils": "1.29.1",
"@apollo/client": "3.7.1",
"@apollo/react-hooks": "4.0.0",
"@loadable/component": "5.15.2",
Expand All @@ -28,6 +30,7 @@
"@uniswap/permit2-sdk": "1.2.0",
"bitcoin-address-validation": "2.2.1",
"chart.js": "4.1.1",
"chartjs-adapter-date-fns": "3.0.0",
"classnames": "2.3.2",
"date-fns": "2.30.0",
"dayjs": "1.11.7",
Expand All @@ -54,6 +57,7 @@
"react-slider": "2.0.6",
"react-timer-hook": "3.0.7",
"reactjs-localstorage": "1.0.1",
"reflect-metadata": "0.2.2",
"remark-gfm": "3.0.1",
"rxjs": "7.5.6",
"sanitize-html": "2.11.0",
Expand Down
33 changes: 33 additions & 0 deletions apps/frontend/src/app/1_atoms/Icons/Icons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';

import { IconType } from '@sovryn/ui';

export const WalletIcon: IconType = (
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M13.0405 4.25812H12.1364V2.14087C12.1365 2.03601 12.1129 1.93273 12.0675 1.84008C12.0222 1.74744 11.9566 1.66829 11.8764 1.60957C11.7965 1.55118 11.7047 1.51483 11.6089 1.50367C11.5131 1.49251 11.4163 1.50689 11.3268 1.54556L2.46318 4.30293C2.38353 4.34114 2.31133 4.39546 2.25045 4.46296C2.02458 4.60047 1.83624 4.80015 1.70446 5.04181C1.57268 5.28347 1.50215 5.55855 1.5 5.83921V12.9189C1.50156 13.3377 1.65583 13.7389 1.92921 14.035C2.20259 14.3312 2.57293 14.4983 2.95955 14.5H13.0405C13.4271 14.4983 13.7974 14.3312 14.0708 14.035C14.3442 13.7389 14.4984 13.3377 14.5 12.9189V5.83921C14.4984 5.4204 14.3442 5.01922 14.0708 4.72307C13.7974 4.42692 13.4271 4.25981 13.0405 4.25812ZM10.9545 4.25812H5.74864L10.9545 3.08824V4.25812ZM13.3182 10.6593H10.9545C10.6411 10.6593 10.3405 10.5244 10.1189 10.2843C9.89724 10.0442 9.77273 9.7186 9.77273 9.37906C9.77273 9.03952 9.89724 8.71389 10.1189 8.4738C10.3405 8.23371 10.6411 8.09882 10.9545 8.09882H13.3182V10.6593ZM10.9545 6.81859C10.3277 6.81859 9.72647 7.08835 9.2832 7.56853C8.83993 8.04872 8.59091 8.69998 8.59091 9.37906C8.59091 10.0581 8.83993 10.7094 9.2832 11.1896C9.72647 11.6698 10.3277 11.9395 10.9545 11.9395H13.3182V12.9189C13.3182 12.9987 13.2889 13.0752 13.2368 13.1316C13.1848 13.1881 13.1141 13.2198 13.0405 13.2198H2.95955C2.88589 13.2198 2.81525 13.1881 2.76316 13.1316C2.71108 13.0752 2.68182 12.9987 2.68182 12.9189V5.83921C2.68182 5.7997 2.689 5.76058 2.70296 5.72408C2.71692 5.68758 2.73737 5.65441 2.76316 5.62647C2.78895 5.59854 2.81957 5.57638 2.85326 5.56126C2.88696 5.54614 2.92307 5.53835 2.95955 5.53835H13.0405C13.0769 5.53835 13.113 5.54614 13.1467 5.56126C13.1804 5.57638 13.211 5.59854 13.2368 5.62647C13.2626 5.65441 13.2831 5.68758 13.297 5.72408C13.311 5.76058 13.3182 5.7997 13.3182 5.83921V6.81859H10.9545Z"
fill="#B6BAC2"
/>
<path
d="M11.547 10.0187C11.8733 10.0187 12.1379 9.73211 12.1379 9.37858C12.1379 9.02505 11.8733 8.73846 11.547 8.73846C11.2206 8.73846 10.9561 9.02505 10.9561 9.37858C10.9561 9.73211 11.2206 10.0187 11.547 10.0187Z"
fill="#B6BAC2"
/>
</svg>
);

export const EModeIcon: IconType = (
<svg
width="16"
height="16"
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M2.7888 9.33172C2.68519 9.33172 2.62925 9.21023 2.69661 9.13151L9.96917 0.632031C10.0511 0.536295 10.2066 0.613419 10.1799 0.736569L8.89071 6.695C8.87435 6.7706 8.93195 6.84199 9.00929 6.84199L13.8677 6.84199C13.9757 6.84199 14.0299 6.97243 13.9537 7.04893L5.54038 15.4971C5.44947 15.5884 5.29773 15.4938 5.3397 15.372L7.36548 9.49257C7.39262 9.41378 7.3341 9.33172 7.25077 9.33172H2.7888Z" />
</svg>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, { FC } from 'react';

import { BOB_CHAIN_ID } from '../../../config/chains';

import {
AmountRenderer,
AmountRendererProps,
} from '../AmountRenderer/AmountRenderer';
import { AssetRenderer } from '../AssetRenderer/AssetRenderer';

type AaveRowTitleProps = AmountRendererProps & {
isOpen?: boolean;
asset: string;
label?: string;
};

export const AaveRowTitle: FC<AaveRowTitleProps> = ({
asset,
label,
isOpen = false,
...props
}) => (
<div className="flex justify-between items-center w-full pr-3">
<AssetRenderer
showAssetLogo
asset={asset}
className="mr-1"
chainId={BOB_CHAIN_ID}
/>
{!isOpen && (
<div className="pl-1 flex items-center font-medium">
<AmountRenderer {...props} />
{label && (
<span className="ml-1 text-gray-30 font-semibold text-sm">
{label}
</span>
)}
</div>
)}
</div>
);
55 changes: 30 additions & 25 deletions apps/frontend/src/app/2_molecules/AmountRenderer/AmountRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {

const { decimal, thousand } = getLocaleSeparators();

type AmountRendererProps = {
export type AmountRendererProps = {
value: Decimalish;
precision?: number;
className?: string;
Expand All @@ -42,6 +42,7 @@ type AmountRendererProps = {
trigger?: TooltipTrigger;
decimals?: number;
asIf?: boolean;
infiniteFrom?: Decimalish;
};

export const AmountRenderer: FC<AmountRendererProps> = ({
Expand All @@ -57,6 +58,7 @@ export const AmountRenderer: FC<AmountRendererProps> = ({
trigger = TooltipTrigger.click,
decimals = 18,
asIf,
infiniteFrom,
}) => {
const adjustedValue = useMemo(
() =>
Expand Down Expand Up @@ -129,6 +131,11 @@ export const AmountRenderer: FC<AmountRendererProps> = ({
[adjustedValue, calculatedPrecision, precision],
);

const isInfinite = useMemo(
() => !!(infiniteFrom && Decimal.from(value).gt(infiniteFrom)),
[infiniteFrom, value],
);

return (
<Tooltip
content={
Expand All @@ -142,33 +149,31 @@ export const AmountRenderer: FC<AmountRendererProps> = ({
</span>
</span>
}
className={classNames({
'cursor-pointer': shouldShowTooltip,
})}
disabled={!shouldShowTooltip}
className={classNames({ 'cursor-pointer': shouldShowTooltip }, className)}
disabled={!shouldShowTooltip || isInfinite}
trigger={trigger}
dataAttribute={dataAttribute}
>
<span className={className}>
{isAnimated ? (
<CountUp
start={0}
end={countUpValues.end}
decimals={calculatedPrecision}
duration={1} //do not set lower than 1 overwise it can cause a bug
separator={thousand}
decimal={decimal}
prefix={shouldShowRoundingPrefix ? `~ ${prefix}` : `${prefix}`}
suffix={` ${suffix}`}
/>
) : (
<>
{shouldShowRoundingPrefix ? '~ ' : ''}
{prefix}
{localeFormattedValue} {suffix}
</>
)}
</span>
{isAnimated ? (
<CountUp
start={0}
end={countUpValues.end}
decimals={calculatedPrecision}
duration={1} //do not set lower than 1 overwise it can cause a bug
separator={thousand}
decimal={decimal}
prefix={shouldShowRoundingPrefix ? `~ ${prefix}` : `${prefix}`}
suffix={` ${suffix}`}
/>
) : isInfinite ? (
<span>∞</span>
) : (
<span>
{shouldShowRoundingPrefix ? '~ ' : ''}
{prefix}
{localeFormattedValue} {suffix}
</span>
)}
</Tooltip>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, { FC } from 'react';

import classNames from 'classnames';

import { Icon, IconNames } from '@sovryn/ui';

import {
AmountRenderer,
AmountRendererProps,
} from '../AmountRenderer/AmountRenderer';

type AmountTransitionProps = {
className?: string;
to: AmountRendererProps;
from: AmountRendererProps;
};

export const AmountTransition: FC<AmountTransitionProps> = ({
from,
to,
className,
}) => (
<div className={classNames('flex items-center gap-1', className)}>
<AmountRenderer {...from} />
<Icon icon={IconNames.ARROW_RIGHT} className="h-2 flex-shrink-0" />
<AmountRenderer {...to} />
</div>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import React, { FC, useCallback } from 'react';

import { AmountInput, Paragraph, Select, SelectOption } from '@sovryn/ui';
import { Decimal, Decimalish } from '@sovryn/utils';

import { AmountRenderer } from '../AmountRenderer/AmountRenderer';
import { AssetRenderer } from '../AssetRenderer/AssetRenderer';
import { MaxButton } from '../MaxButton/MaxButton';

type AssetAmountInputProps = {
label?: string;
chainId?: string | undefined;
maxAmount?: Decimalish;
invalid?: boolean;
amountLabel?: string;
amountValue?: string | number;
onAmountChange?: (value: string) => void;
onMaxClicked?: (value: boolean) => void;
assetValue: string;
assetUsdValue?: Decimalish;
assetOptions: SelectOption<string>[];
onAssetChange: (asset: string) => void;
};

export const AssetAmountInput: FC<AssetAmountInputProps> = ({
label,
chainId,
maxAmount,
amountLabel,
amountValue,
onAmountChange,
onMaxClicked,
invalid,
assetValue,
assetUsdValue,
assetOptions,
onAssetChange,
}) => {
const assetOptionRenderer = useCallback(
({ value }) => (
<AssetRenderer
chainId={chainId}
dataAttribute="asset-amount"
showAssetLogo
asset={value}
/>
),
[chainId],
);

const handleMaxClick = useCallback(() => {
if (maxAmount) {
onMaxClicked?.(true);
onAmountChange?.(Decimal.from(maxAmount).toString());
}
}, [maxAmount, onAmountChange, onMaxClicked]);

const handleChangeAmount = useCallback(
(value: string) => {
onAmountChange?.(value);
onMaxClicked?.(false);
},
[onAmountChange, onMaxClicked],
);

return (
<div>
{label && (
<Paragraph className="mb-1 text-gray-30 font-medium text-xs">
{label}
</Paragraph>
)}

<div className="relative">
{maxAmount !== undefined && (
<span className="absolute right-0 -top-3 -translate-y-1/2">
<MaxButton
token={assetValue}
value={maxAmount}
precision={2}
onClick={handleMaxClick}
/>
</span>
)}

<div className="flex space-x-3">
<div className="text-right flex-grow space-y-1">
<AmountInput
label={amountLabel}
value={amountValue}
onChangeText={handleChangeAmount}
placeholder="0"
invalid={invalid}
/>
<AmountRenderer
className="text-gray-40 mr-4"
value={assetUsdValue ?? 0}
precision={2}
prefix="$"
/>
</div>

<Select
value={assetValue}
onChange={onAssetChange}
options={assetOptions}
labelRenderer={assetOptionRenderer}
className="min-w-[6.7rem]"
menuClassName="max-h-[10rem] sm:max-h-[20rem]"
/>
</div>
</div>
</div>
);
};
Loading
Loading