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

133 gnosissafe sdk accountingv3 #139

Closed
wants to merge 3 commits into from
Closed
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
237 changes: 127 additions & 110 deletions apps/frontend/pages/accounting.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable no-useless-computed-key */
import {
Button,
Flex,
Expand All @@ -9,22 +8,18 @@ import {
TabPanels,
Tabs,
} from '@raidguild/design-system';
import { useAccounting, useMemberList } from '@raidguild/dm-hooks';
import {
IMember,
ITokenBalanceLineItem,
IVaultTransaction,
} from '@raidguild/dm-types';
import {
exportToCsv,
formatDate,
REGEX_ETH_ADDRESS,
} from '@raidguild/dm-utils';
useAccountingV3,
useAccountingV2,
useFormattedData,
useMemberList,
} from '@raidguild/dm-hooks';
import { exportToCsv } from '@raidguild/dm-utils';
import _ from 'lodash';
import { useSession } from 'next-auth/react';
import { NextSeo } from 'next-seo';
import Papa from 'papaparse';
import { useCallback, useMemo } from 'react';
import { useCallback } from 'react';

import BalancesTable from '../components/BalancesTable';
import SiteLayout from '../components/SiteLayout';
Expand All @@ -34,76 +29,27 @@ import TransactionsTable from '../components/TransactionsTable';
export const Accounting = () => {
const { data: session } = useSession();
const token = _.get(session, 'token');
const { data, loading, error } = useAccounting({
const {
data: dataFromMolochV2,
loading,
error,
} = useAccountingV2({
token,
});
const { data: dataFromMolochV3 } = useAccountingV3();
const { data: memberData } = useMemberList({
token,
limit: 1000,
});

const { balances, spoils, transactions, tokenPrices } = data;

const members = useMemo(() => {
const memberArray = _.flatten(
_.get(memberData, 'pages')
) as unknown as IMember[];
return _.keyBy(memberArray, (m: IMember) => m.ethAddress?.toLowerCase());
}, [memberData]);

const withPrices = useCallback(
<T extends ITokenBalanceLineItem | IVaultTransaction>(items: T[]) =>
items.map((t) => {
const formattedDate = formatDate(t.date);
const tokenSymbol = t.tokenSymbol?.toLowerCase();
if (
tokenPrices[tokenSymbol] &&
tokenPrices[tokenSymbol][formattedDate]
) {
return {
...t,
priceConversion: tokenPrices[tokenSymbol][formattedDate],
};
}
if (tokenSymbol.includes('xdai')) {
return {
...t,
priceConversion: 1,
};
}
return t;
}),
[tokenPrices]
);
const { balances, spoils, transactions, tokenPrices } = dataFromMolochV2;

const balancesWithPrices = useMemo(
() => withPrices(balances),
[balances, withPrices]
);

const transactionsWithPrices = useMemo(
() => withPrices(transactions),
[transactions, withPrices]
);

const transactionsWithPricesAndMembers = useMemo(
() =>
transactionsWithPrices.map((t) => {
const ethAddress = t.proposalApplicant.toLowerCase();
const m = members[ethAddress];
const memberLink = m?.ethAddress.match(REGEX_ETH_ADDRESS)
? `/members/${ethAddress}`
: undefined;

return {
...t,
memberLink,
memberName: m?.name,
memberEnsName: m?.ensName,
};
}),
[transactionsWithPrices, members]
);
const {
members,
balancesWithPrices,
transactionsWithPrices,
transactionsWithPricesAndMembers,
} = useFormattedData(memberData, balances, transactions, tokenPrices);

const onExportCsv = useCallback(
(type: 'transactions' | 'balances' | 'spoils') => {
Expand Down Expand Up @@ -212,52 +158,123 @@ export const Accounting = () => {

<TabPanels>
<TabPanel>
<Flex
alignItems='right'
justifyContent='right'
marginBlock='20px'
<Tabs
align='start'
colorScheme='whiteAlpha'
variant='unstyled'
defaultIndex={0}
>
<Button
onClick={() => onExportCsv('balances')}
size='sm'
fontWeight='normal'
<Flex
alignItems='right'
justifyContent='space-between'
marginBlock='20px'
>
Export Balances
</Button>
</Flex>
<BalancesTable data={balancesWithPrices} />
<TabList>
<Tab>
<Heading size='sm'>V3 (current)</Heading>
</Tab>
<Tab>
<Heading size='sm'>V2</Heading>
</Tab>
</TabList>
<Button
onClick={() => onExportCsv('balances')}
size='sm'
fontWeight='normal'
>
Export Balances
</Button>
</Flex>

<TabPanels>
<TabPanel>
<BalancesTable data={balancesWithPrices} />
</TabPanel>
<TabPanel>
<div>This is the placeholder for v3 balances data.</div>
</TabPanel>
</TabPanels>
</Tabs>
</TabPanel>
<TabPanel>
<Flex
alignItems='right'
justifyContent='right'
marginBlock='20px'
<Tabs
align='start'
colorScheme='whiteAlpha'
variant='unstyled'
defaultIndex={0}
>
<Button
onClick={() => onExportCsv('transactions')}
size='sm'
fontWeight='normal'
<Flex
alignItems='right'
justifyContent='space-between'
marginBlock='20px'
>
Export Transactions
</Button>
</Flex>
<TransactionsTable data={transactionsWithPricesAndMembers} />
<TabList>
<Tab>
<Heading size='sm'>V3 (current)</Heading>
</Tab>
<Tab>
<Heading size='sm'>V2</Heading>
</Tab>
</TabList>
<Button
onClick={() => onExportCsv('transactions')}
size='sm'
fontWeight='normal'
>
Export Transactions
</Button>
</Flex>

<TabPanels>
<TabPanel>
<TransactionsTable
data={transactionsWithPricesAndMembers}
/>
</TabPanel>
<TabPanel>
<div>This is the placeholder for v3 transactions data.</div>
</TabPanel>
</TabPanels>
</Tabs>
</TabPanel>
<TabPanel>
<Flex
alignItems='right'
justifyContent='right'
marginBlock='20px'
<Tabs
align='start'
colorScheme='whiteAlpha'
variant='unstyled'
defaultIndex={0}
>
<Button
onClick={() => onExportCsv('spoils')}
size='sm'
fontWeight='normal'
<Flex
alignItems='right'
justifyContent='space-between'
marginBlock='20px'
>
Export Spoils
</Button>
</Flex>
<SpoilsTable data={spoils} />
<TabList>
<Tab>
<Heading size='sm'>V3 (current)</Heading>
</Tab>
<Tab>
<Heading size='sm'>V2</Heading>
</Tab>
</TabList>
<Button
onClick={() => onExportCsv('spoils')}
size='sm'
fontWeight='normal'
>
Export Spoils
</Button>
</Flex>

<TabPanels>
<TabPanel>
<SpoilsTable data={spoils} />
</TabPanel>
<TabPanel>
<div>This is the placeholder for v3 spoils data.</div>
</TabPanel>
</TabPanels>
</Tabs>
</TabPanel>
</TabPanels>
</Tabs>
Expand Down
4 changes: 3 additions & 1 deletion libs/dm-hooks/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default as useAccounting } from './useAccounting';
export { default as useAccountingV2 } from './useAccountingV2';
export { default as useAccountingV3 } from './useAccountingV3';
export { default as useApplicationDetail } from './useApplicationDetail';
export {
default as useApplicationList,
Expand All @@ -15,6 +16,7 @@ export { useContacts } from './useContacts';
export { default as useContactUpdate } from './useContactUpdate';
export { default as useDashboardList } from './useDashboardList';
export { default as useDefaultTitle } from './useDefaultTitle';
export { default as useFormattedData } from './useFormattedData';
export * from './useLinks';
export { default as useLinksUpdate } from './useLinksUpdate';
export { default as useMemberCreate } from './useMemberCreate';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ const formatSpoils = async (
return spoils.sort((a, b) => b.date.getTime() - a.date.getTime());
};

export const useAccounting = ({ token }: { token: string }) => {
export const useAccountingV2 = ({ token }: { token: string }) => {
const [transactions, setTransactions] = useState<Array<IVaultTransaction>>(
[]
);
Expand Down Expand Up @@ -453,4 +453,4 @@ export const useAccounting = ({ token }: { token: string }) => {
};
};

export default useAccounting;
export default useAccountingV2;
82 changes: 82 additions & 0 deletions libs/dm-hooks/src/useAccountingV3.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { da } from 'date-fns/locale';
import { useState, useEffect } from 'react';

import { getAddress } from 'viem';


export const transformTokenBalances = (
tokenBalanceRes: any,
safeAddress: string
): any => {
const fiatTotal = tokenBalanceRes.reduce(
(sum: number, balance: any): number => {
sum += Number(balance.fiatBalance);
return sum;
},
0
);

return { safeAddress, tokenBalances: tokenBalanceRes, fiatTotal };
};

export const listTokenBalances = async ({
safeAddress,
}: {
safeAddress: string;
}): Promise<any> => {
const url = 'https://safe-transaction-gnosis-chain.safe.global/api/v1'

if (!url) {
return {
error: 'Error fetching token balances. Please try again.'
};
}

try {
const res = await fetch(
`${url}/safes/${safeAddress}/balances/usd/`
);
const data = await res.json();
console.log(data)
//
return { data: transformTokenBalances(data, safeAddress) };
} catch (err) {
return {
error: 'Error fetching token balances. Please try again.'
};
}
};

// this is a dummy hook
const useAccountingV3 = () => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
const fetchData = async () => {
const checksum = getAddress('0x181ebdb03cb4b54f4020622f1b0eacd67a8c63ac');
console.log(checksum)
const { data, error } = await listTokenBalances({
safeAddress: checksum,
});

if (error) {
setError(error);
console.log('error', error)
} else {
setData(data);
console.log('data', data);
}

setLoading(false);
};

fetchData();
console.log('fetching data', data);
}, [])

return { data: null, loading: false, error: null };
};

export default useAccountingV3;
Loading