Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
* finish intents

* fix intent match

* fix custom weight size

* remove under construction image

* add more mobile resisizng, prepare assets grid for main net rewards queries, remove Three

* finish claim transaction

* add rewards claim UI, transactions, & queries

* add drawer controller for wallet modal, add filter for defi table

* add better styles to filter buttons

* change deploy workflow branch

* fix webui deploy branch

* clean up code, make intent setting safer

* fix staking util types

* make intent memo safer

* remove useless null & unused imports

* remove console log

* finish authz tx

* fix portfolio percentage width

* fix spinner size in defi table

* match all button styles

* rename main app component

* fix mobile menu links

---------

Co-authored-by: Jacob Gadikian <[email protected]>
  • Loading branch information
chalabi2 and faddat authored Jan 16, 2024
1 parent 3cd641a commit cced40c
Show file tree
Hide file tree
Showing 73 changed files with 1,281 additions and 771 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/devWebUiDeploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ name: Build & Deploy web-ui with dev environment to Github Pages
on:
push:
branches:
- bunDev
- bunDev2
paths:
- web-ui/**
pull_request:
branches:
- bunDev
- bunDev2
paths:
- web-ui/**

Expand Down
58 changes: 29 additions & 29 deletions web-ui/.env.development
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
NEXT_PUBLIC_CHAIN_ENV="mainnet"
NEXT_PUBLIC_MAINNET_LCD_ENDPOINT_QUICKSILVER="https://lcd.quicksilver.zone/"
NEXT_PUBLIC_MAINNET_RPC_ENDPOINT_QUICKSILVER="https://rpc.quicksilver.zone/"
NEXT_PUBLIC_MAINNET_LCD_ENDPOINT_COSMOSHUB=https://lcd.cosmoshub-4.quicksilver.zone
NEXT_PUBLIC_MAINNET_RPC_ENDPOINT_COSMOSHUB=https://rpc.cosmoshub-4.quicksilver.zone
NEXT_PUBLIC_MAINNET_LCD_ENDPOINT_OSMOSIS="https://lcd.osmosis-1.quicksilver.zone"
NEXT_PUBLIC_MAINNET_RPC_ENDPOINT_OSMOSIS="https://rpc.osmosis-1.quicksilver.zone"
NEXT_PUBLIC_MAINNET_LCD_ENDPOINT_STARGAZE="https://lcd.stargaze-1.quicksilver.zone"
NEXT_PUBLIC_MAINNET_RPC_ENDPOINT_STARGAZE="https://rpc.stargaze-1.quicksilver.zone"
NEXT_PUBLIC_MAINNET_LCD_ENDPOINT_REGEN="https://lcd.regen-1.quicksilver.zone"
NEXT_PUBLIC_MAINNET_RPC_ENDPOINT_REGEN="https://rpc.regen-1.quicksilver.zone"
NEXT_PUBLIC_MAINNET_LCD_ENDPOINT_SOMMELIER="https://lcd.sommelier-3.quicksilver.zone"
NEXT_PUBLIC_MAINNET_RPC_ENDPOINT_SOMMELIER="https://rpc.sommelier-3.quicksilver.zone"
NEXT_PUBLIC_QUICKSILVER_API="https://lcd.quicksilver.zone"
NEXT_PUBLIC_QUICKSILVER_DATA_API="https://data.quicksilver.zone"
ZONE_URL="quicksilver.zone"
REACT_APP_WHITELISTED_ZONES="osmosis-1,stargaze-1,regen-1,cosmoshub-4,sommelier-3"
REACT_APP_ENABLE_UNBONDING="true"
REACT_APP_ENABLE_SET_INTENT="true"
REACT_APP_ENABLE_CLAIMS="true"
APY_ZONES_ENDPOINT = "https://chains.cosmos.directory"
NEXT_PUBLIC_OSMOSIS_API="https://api.osmosis.zone"
NEXT_PUBLIC_WHITELISTED_DENOM="uatom,ustars,uosmo,usomm,uregen"
NEXT_PUBLIC_WHITELISTED_ZONES="osmosis-1,stargaze-1,regen-1,cosmoshub-4,sommelier-3"
NEXT_PUBLIC_COSMOSHUB_CHAIN_ID=cosmoshub-4
NEXT_PUBLIC_OSMOSIS_CHAIN_ID=osmosis-1
NEXT_PUBLIC_STARGAZE_CHAIN_ID=stargaze-1
NEXT_PUBLIC_REGEN_CHAIN_ID=regen-1
NEXT_PUBLIC_SOMMELIER_CHAIN_ID=sommelier-3
# NEXT_PUBLIC_CHAIN_ENV="testnet"
# NEXT_PUBLIC_TESTNET_LCD_ENDPOINT_QUICKSILVER="https://lcd.test.quicksilver.zone"
# NEXT_PUBLIC_TESTNET_RPC_ENDPOINT_QUICKSILVER="https://rpc.test.quicksilver.zone"
# NEXT_PUBLIC_TESTNET_LCD_ENDPOINT_COSMOSHUB=https://lcd.provider.test.quicksilver.zone
# NEXT_PUBLIC_TESTNET_RPC_ENDPOINT_COSMOSHUB=https://rpc.provider.test.quicksilver.zone
# NEXT_PUBLIC_TESTNET_LCD_ENDPOINT_OSMOSIS="https://lcd.osmo-test-5.test.quicksilver.zone"
# NEXT_PUBLIC_TESTNET_RPC_ENDPOINT_OSMOSIS="https://rpc.osmo-test-5.test.quicksilver.zone"
# NEXT_PUBLIC_TESTNET_LCD_ENDPOINT_STARGAZE="https://lcd.elgafar-1.test.quicksilver.zone"
# NEXT_PUBLIC_TESTNET_RPC_ENDPOINT_STARGAZE="https://rpc.elgafar-1.test.quicksilver.zone"
# NEXT_PUBLIC_TESTNET_LCD_ENDPOINT_REGEN="https://lcd.regen-redwood-1.test.quicksilver.zone"
# NEXT_PUBLIC_TESTNET_RPC_ENDPOINT_REGEN="https://rpc.regen-redwood-1.test.quicksilver.zone"
# NEXT_PUBLIC_TESTNET_LCD_ENDPOINT_SOMMELIER="https://lcd.sommelier-3.quicksilver.zone"
# NEXT_PUBLIC_TESTNET_RPC_ENDPOINT_SOMMELIER="https://rpc.sommelier-3.quicksilver.zone"
# NEXT_PUBLIC_QUICKSILVER_API="https://lcd.test.quicksilver.zone"
# NEXT_PUBLIC_QUICKSILVER_DATA_API="https://data.test.quicksilver.zone"
# ZONE_URL="quicksilver.zone"
# REACT_APP_WHITELISTED_ZONES="osmosis-1,stargaze-1,regen-1,cosmoshub-4,sommelier-3"
# REACT_APP_ENABLE_UNBONDING="true"
# REACT_APP_ENABLE_SET_INTENT="true"
# REACT_APP_ENABLE_CLAIMS="true"
# APY_ZONES_ENDPOINT = "https://chains.cosmos.directory"
# NEXT_PUBLIC_OSMOSIS_API="https://api.osmosis.zone"
# NEXT_PUBLIC_WHITELISTED_DENOM="uatom,ustars,uosmo,usomm,uregen"
# NEXT_PUBLIC_WHITELISTED_ZONES="osmosis-1,stargaze-1,regen-1,cosmoshub-4,sommelier-3"
# NEXT_PUBLIC_COSMOSHUB_CHAIN_ID=provider
# NEXT_PUBLIC_OSMOSIS_CHAIN_ID=osmo-test-5
# NEXT_PUBLIC_STARGAZE_CHAIN_ID=elgafar-1
# NEXT_PUBLIC_REGEN_CHAIN_ID=regen-redwood-1
# NEXT_PUBLIC_SOMMELIER_CHAIN_ID=sommelier-3
15 changes: 3 additions & 12 deletions web-ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,13 @@ Please ensure your IDE is configured to use Typescript v4.9.3

**Mobile Menu**

- connect wallet button

- graphic elements

- font size / style / decorations

**DevOps**

- make onboarding networks seamless

**Assets Page**

- claim rewards claim.test.quicksilver.zone/address/current \*/epoch

- intent query

claim rewards - rewards get claimed at epoch after your submit tx its not immediate
**Blockers**

no solid way to track rewards rn
- main net reward current & epoch queries
- update grantee address in query & tx
Binary file modified web-ui/bun.lockb
Binary file not shown.
10 changes: 2 additions & 8 deletions web-ui/components/Airdrop/airdropSection.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { useAccordionStyles } from '@chakra-ui/accordion';
import { CheckIcon, ChevronDownIcon, ChevronRightIcon, InfoOutlineIcon } from '@chakra-ui/icons';
import { ChevronDownIcon, ChevronRightIcon, InfoOutlineIcon } from '@chakra-ui/icons';
import {
Accordion,
AccordionItem,
AccordionButton,
AccordionPanel,
AccordionIcon,
Box,
Button,
Flex,
Expand All @@ -14,12 +12,10 @@ import {
Tooltip,
VStack,
HStack,
useColorModeValue,
Icon,
Badge,
useDisclosure,
} from '@chakra-ui/react';
import { useState } from 'react';

interface AirdropAccordionItemProps {
index: number;
Expand Down Expand Up @@ -67,8 +63,6 @@ const AirdropAccordionItem: React.FC<AirdropAccordionItemProps> = ({ index, defa
};

const AirdropSection = () => {
const { isOpen, onToggle } = useDisclosure();

return isBeta ? (
// What to render if isBeta is true
<Flex
Expand All @@ -89,7 +83,7 @@ const AirdropSection = () => {
left: 0,
right: 0,
bottom: 0,
backgroundImage: "url('/quicksilver/img/underConstruction.png')",

backgroundSize: 'contain',
backgroundPosition: 'center',
backdropFilter: 'blur(10px)',
Expand Down
46 changes: 29 additions & 17 deletions web-ui/components/Assets/assetsGrid.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, SimpleGrid, VStack, Text, Button, Divider, useColorModeValue, HStack, Flex, Grid, GridItem, Spinner } from '@chakra-ui/react';
import { Box, VStack, Text, Divider, HStack, Flex, Grid, GridItem, Spinner } from '@chakra-ui/react';
import React from 'react';

import QDepositModal from './modals/qTokenDepositModal';
Expand Down Expand Up @@ -31,10 +31,6 @@ type Amount = {
amount: string;
};

type Asset = {
[key: string]: Amount[];
};

type Errors = {
Errors: any;
};
Expand All @@ -52,20 +48,36 @@ type LiquidRewardsData = {
errors: Errors;
};

type UseLiquidRewardsQueryReturnType = {
liquidRewards: LiquidRewardsData | undefined;
isLoading: boolean;
isError: boolean;
};

const AssetCard: React.FC<AssetCardProps> = ({ assetName, balance, apy, nativeAssetName, isWalletConnected, nonNative }) => {
const nonNativeBalance = nonNative?.assets['quicksilver-2']
? nonNative.assets['quicksilver-2'][0].Amount.find((amount) => amount.denom === `uq${nativeAssetName.toLowerCase()}`)
const calculateTotalBalance = (nonNative: LiquidRewardsData | undefined, nativeAssetName: string) => {
if (!nonNative) {
return '0';
}
const chainIds = ['osmosis-1', 'secret-1', 'umee-1', 'cosmoshub-4', 'stargaze-1', 'sommelier-3', 'regen-1'];
let totalAmount = 0;

chainIds.forEach((chainId) => {
const assetsInChain = nonNative?.assets[chainId];
if (assetsInChain) {
assetsInChain.forEach((asset: any) => {
const assetAmount = asset.Amount.find((amount: { denom: string }) => amount.denom === `uq${nativeAssetName.toLowerCase()}`);
if (assetAmount) {
totalAmount += parseInt(assetAmount.amount, 10); // assuming amount is a string
}
});
}
});

return shiftDigits(totalAmount.toString(), -6); // Adjust the shift as per your data's scale
};

const nativeAssets = nonNative?.assets['rhye-2']
? nonNative.assets['rhye-2'][0].Amount.find((amount) => amount.denom === `uq${nativeAssetName.toLowerCase()}`)
: undefined;

const formattedNonNativeBalance = nonNativeBalance
? shiftDigits(nonNativeBalance.amount, -6) // Assuming the amount is in micro units
: '0';
const formattedNonNativeBalance = calculateTotalBalance(nonNative, nativeAssetName);

const formattedNativebalance = nativeAssets ? shiftDigits(nativeAssets.amount, -6) : '0';

if (!balance || !apy) {
return (
Expand Down Expand Up @@ -109,7 +121,7 @@ const AssetCard: React.FC<AssetCardProps> = ({ assetName, balance, apy, nativeAs
</GridItem>
<GridItem>
<Text fontSize="md" textAlign="right" fontWeight="semibold">
{balance}
{formattedNativebalance}
</Text>
</GridItem>
<GridItem>
Expand Down
119 changes: 99 additions & 20 deletions web-ui/components/Assets/intents.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
import { ChevronLeftIcon, ChevronRightIcon } from '@chakra-ui/icons';
import { Box, Flex, Text, Button, IconButton, VStack, Image, Heading, SlideFade, Spinner } from '@chakra-ui/react';
import { color } from 'framer-motion';
import { useState } from 'react';
import {
Box,
Flex,
Text,
Button,
IconButton,
VStack,
Image,
Heading,
SlideFade,
Spinner,
SkeletonCircle,
SkeletonText,
} from '@chakra-ui/react';

import { Key, useState } from 'react';

import SignalIntentModal from './modals/signalIntentProcess';

import { useIntentQuery } from '@/hooks/useQueries';
import { useIntentQuery, useValidatorLogos, useValidatorsQuery } from '@/hooks/useQueries';
import { networks as prodNetworks, testNetworks as devNetworks } from '@/state/chains/prod';
import { truncateString } from '@/utils';

export interface StakingIntentProps {
address: string;
isWalletConnected: boolean;
}

const StakingIntent: React.FC<StakingIntentProps> = ({ address, isWalletConnected }) => {
const validators = [
{ name: '', logo: '', percentage: '' },
{ name: '', logo: '', percentage: '' },
];
const networks = process.env.NEXT_PUBLIC_CHAIN_ENV === 'mainnet' ? prodNetworks : devNetworks;

const chains = ['Cosmos', 'Osmosis', 'Stargaze', 'Regen', 'Sommelier'];
Expand All @@ -29,7 +39,38 @@ const StakingIntent: React.FC<StakingIntentProps> = ({ address, isWalletConnecte

const currentNetwork = networks[currentChainIndex];

const { intent, isLoading, isError } = useIntentQuery(currentNetwork.chainName, address ?? '');
const { validatorsData } = useValidatorsQuery(currentNetwork.chainName);
const { data: validatorLogos } = useValidatorLogos(currentNetwork.chainName, validatorsData || []);

const { intent, refetch } = useIntentQuery(currentNetwork.chainName, address ?? '');

interface ValidatorDetails {
moniker: string;
logoUrl: string | undefined;
}

interface ValidatorMap {
[valoper_address: string]: ValidatorDetails;
}

const validatorsMap: ValidatorMap =
validatorsData?.reduce((map: ValidatorMap, validatorInfo) => {
map[validatorInfo.address] = {
moniker: validatorInfo.name,
logoUrl: validatorLogos?.[validatorInfo.address],
};
return map;
}, {}) || {};

const validatorsWithDetails =
intent?.data?.intent.intents.map((validatorIntent: { valoper_address: string; weight: string }) => {
const validatorDetails = validatorsMap[validatorIntent.valoper_address];
return {
moniker: validatorDetails?.moniker,
logoUrl: validatorDetails?.logoUrl,
percentage: `${(parseFloat(validatorIntent.weight) * 100).toFixed(2)}%`,
};
}) || [];

const handleLeftArrowClick = () => {
setCurrentChainIndex((prevIndex) => (prevIndex === 0 ? networks.length - 1 : prevIndex - 1));
Expand Down Expand Up @@ -78,7 +119,12 @@ const StakingIntent: React.FC<StakingIntentProps> = ({ address, isWalletConnecte
Edit Intent
<ChevronRightIcon />
</Button>
<SignalIntentModal selectedOption={currentNetwork} isOpen={isSignalIntentModalOpen} onClose={closeSignalIntentModal} />
<SignalIntentModal
refetch={refetch}
selectedOption={currentNetwork}
isOpen={isSignalIntentModalOpen}
onClose={closeSignalIntentModal}
/>
</Flex>

<Flex borderBottom="1px" borderBottomColor="complimentary.900" alignItems="center" justifyContent="space-between">
Expand Down Expand Up @@ -111,17 +157,50 @@ const StakingIntent: React.FC<StakingIntentProps> = ({ address, isWalletConnecte
/>
</Flex>

<VStack spacing={2} align="stretch">
{validators.map((validator, index) => (
<Flex key={index} justifyContent="space-between" w="full" alignItems="center">
<Flex alignItems="center" gap={2}>
<Text fontSize="md">{validator.name}</Text>
<VStack pb={4} overflowY="auto" gap={4} spacing={2} align="stretch" maxH="250px">
{validatorsWithDetails.map(
(validator: { logoUrl: string; moniker: string; percentage: string }, index: Key | null | undefined) => (
<Flex key={index} justifyContent="space-between" w="full" alignItems="center">
<Flex alignItems="center" gap={2}>
{validator.logoUrl ? (
<Image
borderRadius={'full'}
src={validator.logoUrl}
alt={validator.moniker}
boxSize="26px"
objectFit="cover"
marginRight="8px"
/>
) : (
<SkeletonCircle
boxSize="26px"
objectFit="cover"
marginRight="8px"
display="inline-block"
verticalAlign="middle"
startColor="complimentary.900"
endColor="complimentary.100"
/>
)}
{validator.moniker ? (
<Text fontSize="md">{truncateString(validator.moniker, 20)}</Text>
) : (
<SkeletonText
display="inline-block"
verticalAlign="middle"
startColor="complimentary.900"
endColor="complimentary.100"
noOfLines={1}
width="100px"
/>
)}
</Flex>
<Text fontSize="lg" fontWeight="bold">
{validator.percentage}
</Text>
</Flex>
<Text fontSize="lg" fontWeight="bold">
{validator.percentage}
</Text>
</Flex>
))}
),
)}
</VStack>
</VStack>
</Box>
Expand Down
Loading

0 comments on commit cced40c

Please sign in to comment.