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

192 support ubipools #219

Merged
merged 11 commits into from
Sep 1, 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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"shx": "^0.3.4",
"syncpack": "^8.2.4",
"ts-node": "^10.9.1",
"vercel": "^34.3.1"
"vercel": "^37.1.1"
},
"lint-staged": {
"packages/app/**/*.{ts,tsx}": [
Expand Down
4 changes: 2 additions & 2 deletions packages/app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@gooddollar/goodcollective-app",
"version": "1.0.0",
"version": "1.1.0",
"private": true,
"scripts": {
"android": "react-native run-android",
Expand Down Expand Up @@ -82,6 +82,7 @@
"@tsconfig/react-native": "^2.0.2",
"@types/fast-text-encoding": "^1",
"@types/jest": "^29.2.1",
"@types/lodash": "^4.17.7",
"@types/moment-duration-format": "^2",
"@types/qs": "^6",
"@types/react": "^18.2.12",
Expand All @@ -99,7 +100,6 @@
"react-test-renderer": "18.2.0",
"typechain": "^8.1.1",
"typescript": "^5.1.3",
"vercel": "latest",
"vite": "^4.5.0",
"vite-plugin-dynamic-import": "^1.5.0",
"vite-plugin-node-polyfills": "^0.16.0",
Expand Down
27 changes: 16 additions & 11 deletions packages/app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,23 @@ import { Colors } from './utils/colors';
import { useCreateSubgraphApolloClient, useCreateMongoDbApolloClient } from './hooks/apollo';
import { MongoDbApolloProvider } from './components/providers/MongoDbApolloProvider';

const celoProvider = jsonRpcProvider({
rpc: (chain) => {
if (chain.id === 42220) {
return {
http: 'https://rpc.ankr.com/celo',
};
}
return null;
},
});
function App(): JSX.Element {
const { publicClient, webSocketPublicClient } = configureChains([celo, mainnet], [publicProvider(), celoProvider]);
const { publicClient, webSocketPublicClient } = configureChains(
[celo, mainnet],
[
publicProvider(),
jsonRpcProvider({
rpc: (chain) => {
if (chain.id === 42220) {
return {
http: 'https://rpc.ankr.com/celo',
};
}
return null;
},
}),
]
);

const connectors = [
new MetaMaskConnector({
Expand Down
57 changes: 37 additions & 20 deletions packages/app/src/components/DonateComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import Dropdown from './Dropdown';
import { getDonateStyles, getFrequencyPlural } from '../utils';
import { useContractCalls, useGetTokenPrice } from '../hooks';
import { useAccount, useNetwork } from 'wagmi';
import { IpfsCollective } from '../models/models';
import { Collective } from '../models/models';
import { useGetTokenBalance } from '../hooks/useGetTokenBalance';
import { acceptablePriceImpact, Frequency, frequencyOptions, SupportedNetwork } from '../models/constants';
import { acceptablePriceImpact, Frequency, frequencyOptions, GDEnvTokens, SupportedNetwork } from '../models/constants';
import { InfoIconOrange } from '../assets';
import { useParams } from 'react-router-native';
import Decimal from 'decimal.js';
Expand All @@ -28,7 +28,7 @@ import ThankYouModal from './modals/ThankYouModal';
import useCrossNavigate from '../routes/useCrossNavigate';

interface DonateComponentProps {
collective: IpfsCollective;
collective: Collective;
}

function DonateComponent({ collective }: DonateComponentProps) {
Expand All @@ -51,26 +51,39 @@ function DonateComponent({ collective }: DonateComponentProps) {
navigate(`/profile/${address}`);
}

const [currency, setCurrency] = useState<string>('G$');
const [frequency, setFrequency] = useState<Frequency>(Frequency.Monthly);
const [duration, setDuration] = useState(12);
const [decimalDonationAmount, setDecimalDonationAmount] = useState(0);

const tokenList = useTokenList();
const gdEnvSymbol =
Object.keys(tokenList).find((key) => {
if (key.startsWith('G$')) {
return tokenList[key].address.toLowerCase() === collective.rewardToken.toLowerCase();
} else return false;
}) || 'G$';

const GDToken = GDEnvTokens[gdEnvSymbol];

const currencyOptions: { value: string; label: string }[] = useMemo(() => {
let options = Object.keys(tokenList).map((key) => ({
value: key,
label: key,
}));
let options = Object.keys(tokenList).reduce<Array<{ value: string; label: string }>>((acc, key) => {
if (!key.startsWith('G$') || key === gdEnvSymbol) {
acc.push({ value: key, label: key });
}
return acc;
}, []);

return options;
}, [tokenList]);
}, [tokenList, gdEnvSymbol]);

const [currency, setCurrency] = useState<string>(gdEnvSymbol || 'G$');

const {
path: swapPath,
rawMinimumAmountOut,
priceImpact,
status: swapRouteStatus,
} = useSwapRoute(currency, decimalDonationAmount, duration);
} = useSwapRoute(currency, GDToken, decimalDonationAmount, duration);

const { handleApproveToken, isRequireApprove } = useApproveSwapTokenCallback(
currency,
Expand All @@ -79,7 +92,7 @@ function DonateComponent({ collective }: DonateComponentProps) {
(value: boolean) => setApproveSwapModalVisible(value),
collectiveId as `0x${string}`
);
const approvalNotReady = handleApproveToken === undefined && currency !== 'G$';
const approvalNotReady = handleApproveToken === undefined && currency.startsWith('G$') === false;

const { supportFlowWithSwap, supportFlow, supportSingleTransferAndCall, supportSingleWithSwap } = useContractCalls(
collectiveId,
Expand All @@ -97,12 +110,12 @@ function DonateComponent({ collective }: DonateComponentProps) {

const handleDonate = useCallback(async () => {
if (frequency === Frequency.OneTime) {
if (currency === 'G$') {
if (currency.startsWith('G$')) {
return await supportSingleTransferAndCall();
} else {
return await supportSingleWithSwap();
}
} else if (currency === 'G$') {
} else if (currency.startsWith('G$')) {
return await supportFlow();
}

Expand Down Expand Up @@ -143,18 +156,22 @@ function DonateComponent({ collective }: DonateComponentProps) {
supportSingleWithSwap,
]);

const currencyDecimals = useToken(currency).decimals;
const donorCurrencyBalance = useGetTokenBalance(currency, address, chain?.id, true);
const token = useToken(currency);
const currencyDecimals = token.decimals;
const donorCurrencyBalance = useGetTokenBalance(token.address, address, chain?.id, true);

const totalDecimalDonation = new Decimal(duration * decimalDonationAmount);
const totalDonationFormatted = totalDecimalDonation.toDecimalPlaces(currencyDecimals, Decimal.ROUND_DOWN).toString();

const isNonZeroDonation = totalDecimalDonation.gt(0);
const isInsufficientBalance =
isNonZeroDonation && (!donorCurrencyBalance || totalDecimalDonation.gt(donorCurrencyBalance));
const isInsufficientLiquidity = isNonZeroDonation && currency !== 'G$' && swapRouteStatus === SwapRouteState.NO_ROUTE;
const isInsufficientLiquidity =
isNonZeroDonation && currency.startsWith('G$') === false && swapRouteStatus === SwapRouteState.NO_ROUTE;
const isUnacceptablePriceImpact =
isNonZeroDonation && currency !== 'G$' && priceImpact ? priceImpact > acceptablePriceImpact : false;
isNonZeroDonation && currency.startsWith('G$') === false && priceImpact
? priceImpact > acceptablePriceImpact
: false;

const { price } = useGetTokenPrice(currency);
const donationAmountUsdValue = price ? formatFiatCurrency(decimalDonationAmount * price) : undefined;
Expand Down Expand Up @@ -199,7 +216,7 @@ function DonateComponent({ collective }: DonateComponentProps) {
<View>
<Text style={styles.title}>Donate</Text>
<Text style={styles.description}>
Support {collective.name}{' '}
Support {collective.ipfs.name}{' '}
{isDesktopResolution && (
<>
<br />
Expand Down Expand Up @@ -487,7 +504,7 @@ function DonateComponent({ collective }: DonateComponentProps) {
onPress={handleDonate}
isLoading={swapRouteStatus === SwapRouteState.LOADING}
disabled={
(currency !== 'G$' && swapRouteStatus !== SwapRouteState.READY) ||
(currency.startsWith('G$') === false && swapRouteStatus !== SwapRouteState.READY) ||
address === undefined ||
chain?.id === undefined ||
!(chain.id in SupportedNetwork) ||
Expand All @@ -502,7 +519,7 @@ function DonateComponent({ collective }: DonateComponentProps) {
<ThankYouModal
openModal={thankYouModalVisible}
address={address}
collective={collective}
collective={collective.ipfs}
isStream={frequency !== Frequency.OneTime}
/>
</View>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,32 @@ import { Image, Text, View, StyleSheet } from 'react-native';
import { InterRegular, InterSemiBold } from '../utils/webFonts';
import { Colors } from '../utils/colors';
import { useMediaQuery } from 'native-base';
import { useDonorCollectivesFlowingBalancesWithAltStaticBalance } from '../hooks/useFlowingBalance';
import { useDonorCollectivesFlowingBalances } from '../hooks/useFlowingBalance';
import { DonorCollective } from '../models/models';
import { useGetTokenBalance } from '../hooks/useGetTokenBalance';
import { SupportedNetwork } from '../models/constants';
import Decimal from 'decimal.js';

interface FlowingDonationsRowItemProps {
rowInfo: string;
collective: `0x${string}`;
donorCollectives: DonorCollective[];
tokenPrice: number | undefined;
currency?: string;
imageUrl: string;
additionalBalance?: string;
}

function FlowingDonationsRowItem({
rowInfo,
collective,
donorCollectives,
tokenPrice,
currency,
imageUrl,
additionalBalance,
}: FlowingDonationsRowItemProps) {
const [isDesktopResolution] = useMediaQuery({
minWidth: 920,
});

const currentBalance = useGetTokenBalance('G$', collective, SupportedNetwork.CELO);
const balanceUsed = additionalBalance
? new Decimal(currentBalance).add(additionalBalance).toFixed(0, Decimal.ROUND_DOWN)
: currentBalance;
const { formatted: formattedCurrentPool, usdValue: usdValueCurrentPool } =
useDonorCollectivesFlowingBalancesWithAltStaticBalance(balanceUsed, donorCollectives, tokenPrice);
const { formatted: formattedDonations, usdValue: donationsUsdValue } = useDonorCollectivesFlowingBalances(
donorCollectives,
tokenPrice
);

return (
<View style={styles.row}>
Expand All @@ -47,10 +38,10 @@ function FlowingDonationsRowItem({
<Text style={styles.rowData}>
<View style={{ gap: 2 }}>
<Text>
<Text>{currency}</Text> <Text style={{ ...InterRegular }}>{formattedCurrentPool}</Text>
{isDesktopResolution && currency && <Text style={styles.rowBalance}> = {usdValueCurrentPool} USD</Text>}
<Text>{currency}</Text> <Text style={{ ...InterRegular }}>{formattedDonations}</Text>
{isDesktopResolution && currency && <Text style={styles.rowBalance}> = {donationsUsdValue} USD</Text>}
</Text>
{!isDesktopResolution && currency && <Text style={styles.rowBalance}>= {usdValueCurrentPool} USD</Text>}
{!isDesktopResolution && currency && <Text style={styles.rowBalance}>= {donationsUsdValue} USD</Text>}
</View>
</Text>
</View>
Expand Down
29 changes: 20 additions & 9 deletions packages/app/src/components/FlowingDonationsRowItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,43 @@ import { Image, Text, View, StyleSheet } from 'react-native';
import { InterRegular, InterSemiBold } from '../utils/webFonts';
import { Colors } from '../utils/colors';
import { useMediaQuery } from 'native-base';
import { useDonorCollectivesFlowingBalances } from '../hooks/useFlowingBalance';
import { useDonorCollectivesFlowingBalancesWithAltStaticBalance } from '../hooks/useFlowingBalance';
sirpy marked this conversation as resolved.
Show resolved Hide resolved
import { DonorCollective } from '../models/models';
import { useGetTokenBalance } from '../hooks/useGetTokenBalance';
import { SupportedNetwork } from '../models/constants';
import Decimal from 'decimal.js';
import { useTokenByAddress } from '../hooks/useTokenList';

interface FlowingDonationsRowItemProps {
rowInfo: string;
collective: `0x${string}`;
donorCollectives: DonorCollective[];
tokenPrice: number | undefined;
currency?: string;
currency: string;
imageUrl: string;
additionalBalance?: string;
}

function FlowingDonationsRowItem({
rowInfo,
collective,
donorCollectives,
tokenPrice,
currency,
imageUrl,
additionalBalance,
}: FlowingDonationsRowItemProps) {
const token = useTokenByAddress(currency);
const [isDesktopResolution] = useMediaQuery({
minWidth: 920,
});

const { formatted: formattedDonations, usdValue: donationsUsdValue } = useDonorCollectivesFlowingBalances(
donorCollectives,
tokenPrice
);
const currentBalance = useGetTokenBalance(currency, collective, SupportedNetwork.CELO);
const balanceUsed = additionalBalance
? new Decimal(currentBalance).add(additionalBalance).toFixed(0, Decimal.ROUND_DOWN)
: currentBalance;
const { formatted: formattedCurrentPool, usdValue: usdValueCurrentPool } =
useDonorCollectivesFlowingBalancesWithAltStaticBalance(balanceUsed, donorCollectives, tokenPrice);

return (
<View style={styles.row}>
Expand All @@ -38,10 +49,10 @@ function FlowingDonationsRowItem({
<Text style={styles.rowData}>
<View style={{ gap: 2 }}>
<Text>
<Text>{currency}</Text> <Text style={{ ...InterRegular }}>{formattedDonations}</Text>
{isDesktopResolution && currency && <Text style={styles.rowBalance}> = {donationsUsdValue} USD</Text>}
<Text>{token.symbol}</Text> <Text style={{ ...InterRegular }}>{formattedCurrentPool}</Text>
{isDesktopResolution && currency && <Text style={styles.rowBalance}> = {usdValueCurrentPool} USD</Text>}
</Text>
{!isDesktopResolution && currency && <Text style={styles.rowBalance}>= {donationsUsdValue} USD</Text>}
{!isDesktopResolution && currency && <Text style={styles.rowBalance}>= {usdValueCurrentPool} USD</Text>}
</View>
</Text>
</View>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Colors } from '../../utils/colors';
import { PlaceholderAvatar } from '../../assets';
import { useGetTokenBalance } from '../../hooks/useGetTokenBalance';
import { formatNumberWithCommas } from '../../lib/formatFiatCurrency';
import { SupportedNetwork } from '../../models/constants';
import { GDToken, SupportedNetwork } from '../../models/constants';

interface ConnectedAccountDisplayProps {
isDesktopResolution: boolean;
Expand All @@ -24,7 +24,7 @@ export const ConnectedAccountDisplay = (props: ConnectedAccountDisplayProps) =>
chainName = 'Unsupported Network';
}

const tokenBalance = useGetTokenBalance('G$', address, chain?.id, true);
const tokenBalance = useGetTokenBalance(GDToken.address, address, chain?.id, true);
const formattedTokenBalance = formatNumberWithCommas(tokenBalance);
const { data: ensName } = useEnsName({ address, chainId: 1 });

Expand Down
6 changes: 5 additions & 1 deletion packages/app/src/components/RoundedButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ function RoundedButton({
disabled={disabled}
style={[styles.button, { backgroundColor, maxWidth: maxWidth ?? 'auto' }]}
onPress={onPress}>
{isLoading ? (<ActivityIndicator size="large" color={Colors.blue[200]} />) : (<Text style={[styles.nonSeeTypeText, dynamicTextStyle]}>{title}</Text>)}
{isLoading ? (
<ActivityIndicator size="large" color={Colors.blue[200]} />
) : (
<Text style={[styles.nonSeeTypeText, dynamicTextStyle]}>{title}</Text>
)}
</TouchableOpacity>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SupportTx } from '../../models/models';
import { formatAddress } from '../../lib/formatAddress';
import { useEnsName } from 'wagmi';
import { useEnsName, useWaitForTransaction } from 'wagmi';
import Decimal from 'decimal.js';
import TransactionListItem from './TransactionListItem';
import { useFetchFullName } from '../../hooks/useFetchFullName';
Expand Down Expand Up @@ -31,6 +31,11 @@ export function SupportTransactionListItem({ transaction }: SupportTransactionLi
const { data: ensName } = useEnsName({ address: userAddress, chainId: 1 });
const userFullName = useFetchFullName(userAddress);
const userIdentifier = userFullName ?? ensName ?? formatAddress(userAddress);
const flowUpdateLog = useWaitForTransaction({ hash: hash as `0x${string}`, chainId: 42220 });
// super fluid event flowupdated event https://www.4byte.directory/event-signatures/?bytes_signature=0x57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e
const flowLogIndex = flowUpdateLog.data?.logs.find(
(_) => _.topics[0] === '0x57269d2ebcccecdcc0d9d2c0a0b80ead95f344e28ec20f50f709811f209d4e0e'
sirpy marked this conversation as resolved.
Show resolved Hide resolved
)?.logIndex;

const flowingAmount = useMemo(() => {
return transaction.isFlowUpdate ? (
Expand Down Expand Up @@ -66,7 +71,7 @@ export function SupportTransactionListItem({ transaction }: SupportTransactionLi
isStream={transaction.isFlowUpdate}
explorerLink={
// ? `${env.REACT_APP_SUPERFLUID_EXPLORER}/streams/${donor}-${transaction.collective}-${transaction.rewardToken}-0.0`
transaction.isFlowUpdate ? `${env.REACT_APP_SUPERFLUID_EXPLORER}/accounts/${donor}?tab=streams` : undefined
transaction.isFlowUpdate ? `${env.REACT_APP_SUPERFLUID_EXPLORER}/${hash}-${flowLogIndex}` : undefined
}
icon={getTxIcon(transaction)}
userIdentifier={userIdentifier}
Expand Down
Loading
Loading