From 0593ff52fa98563800bee4df696111834cc4dc45 Mon Sep 17 00:00:00 2001 From: Steven Straatemans Date: Wed, 8 Jan 2025 09:03:50 +0100 Subject: [PATCH 1/6] fix the allowed check for distribution of tokens --- packages/apps/rwa-demo/src/hooks/distributeTokens.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/apps/rwa-demo/src/hooks/distributeTokens.ts b/packages/apps/rwa-demo/src/hooks/distributeTokens.ts index 96cb2c245c..6043393d04 100644 --- a/packages/apps/rwa-demo/src/hooks/distributeTokens.ts +++ b/packages/apps/rwa-demo/src/hooks/distributeTokens.ts @@ -11,6 +11,7 @@ import { useEffect, useState } from 'react'; import { useAccount } from './account'; import { useAsset } from './asset'; import { useFreeze } from './freeze'; +import { useGetInvestorBalance } from './getInvestorBalance'; import { useTransactions } from './transactions'; export const useDistributeTokens = ({ @@ -22,6 +23,7 @@ export const useDistributeTokens = ({ const { paused, asset } = useAsset(); const { account, sign, accountRoles, isMounted } = useAccount(); + const { data: investorBalance } = useGetInvestorBalance({ investorAccount }); const { addTransaction, isActiveAccountChangeTx } = useTransactions(); const { addNotification } = useNotifications(); const [isAllowed, setIsAllowed] = useState(false); @@ -62,7 +64,8 @@ export const useDistributeTokens = ({ asset.maxSupply === INFINITE_COMPLIANCE) && ((asset.maxInvestors > INFINITE_COMPLIANCE && asset.maxInvestors > asset.investorCount) || - asset.maxInvestors === INFINITE_COMPLIANCE), + asset.maxInvestors === INFINITE_COMPLIANCE || + investorBalance > 0), ); }, [ frozen, @@ -72,6 +75,7 @@ export const useDistributeTokens = ({ accountRoles, isActiveAccountChangeTx, asset, + investorBalance, ]); return { submit, isAllowed }; From 439f097feae4fa8966287273aa618a0c62eb5c73 Mon Sep 17 00:00:00 2001 From: Steven Straatemans Date: Wed, 8 Jan 2025 09:04:18 +0100 Subject: [PATCH 2/6] open an asset via the asset overview page --- .../src/app/(app)/assets/[uuid]/page.tsx | 42 ------------------- .../rwa-demo/src/app/(app)/assets/page.tsx | 24 ++++++++--- 2 files changed, 18 insertions(+), 48 deletions(-) delete mode 100644 packages/apps/rwa-demo/src/app/(app)/assets/[uuid]/page.tsx diff --git a/packages/apps/rwa-demo/src/app/(app)/assets/[uuid]/page.tsx b/packages/apps/rwa-demo/src/app/(app)/assets/[uuid]/page.tsx deleted file mode 100644 index 70dda762ad..0000000000 --- a/packages/apps/rwa-demo/src/app/(app)/assets/[uuid]/page.tsx +++ /dev/null @@ -1,42 +0,0 @@ -'use client'; -import type { IWalletAccount } from '@/components/AccountProvider/AccountType'; -import type { IAsset } from '@/components/AssetProvider/AssetProvider'; -import { useAccount } from '@/hooks/account'; -import { useAsset } from '@/hooks/asset'; -import { - SideBarBreadcrumbs, - SideBarBreadcrumbsItem, -} from '@kadena/kode-ui/patterns'; -import { useParams } from 'next/navigation'; -import { useEffect, useState } from 'react'; - -const Assets = () => { - const { getAsset } = useAsset(); - const { account } = useAccount(); - const [asset, setAsset] = useState(); - const { uuid } = useParams(); - - const initData = async (uuid: string, account: IWalletAccount) => { - const data = await getAsset(uuid, account); - setAsset(data); - }; - - useEffect(() => { - if (!account) return; - // eslint-disable-next-line @typescript-eslint/no-floating-promises - initData(uuid as string, account); - }, [uuid, account?.address]); - - return ( - <> - - Assets - - Assets - - -
{JSON.stringify(asset, null, 2)}
- - ); -}; -export default Assets; diff --git a/packages/apps/rwa-demo/src/app/(app)/assets/page.tsx b/packages/apps/rwa-demo/src/app/(app)/assets/page.tsx index 7282017d3b..9fc6d3cb40 100644 --- a/packages/apps/rwa-demo/src/app/(app)/assets/page.tsx +++ b/packages/apps/rwa-demo/src/app/(app)/assets/page.tsx @@ -1,8 +1,10 @@ 'use client'; import { AssetFormScreen } from '@/components/AssetForm/AssetFormScreen'; +import type { IAsset } from '@/components/AssetProvider/AssetProvider'; import { Confirmation } from '@/components/Confirmation/Confirmation'; import { SideBarBreadcrumbs } from '@/components/SideBarBreadcrumbs/SideBarBreadcrumbs'; +import { useAccount } from '@/hooks/account'; import { useAsset } from '@/hooks/asset'; import { MonoAdd, MonoDelete, MonoFindInPage } from '@kadena/kode-icons'; import { Button } from '@kadena/kode-ui'; @@ -18,22 +20,32 @@ import { SectionCardHeader, SideBarBreadcrumbsItem, useLayout, + useNotifications, } from '@kadena/kode-ui/patterns'; -import { useRouter } from 'next/navigation'; import { useState } from 'react'; const Assets = () => { - const { assets, removeAsset } = useAsset(); + const { account } = useAccount(); + const { assets, removeAsset, setAsset, getAsset } = useAsset(); + const { addNotification } = useNotifications(); const [openSide, setOpenSide] = useState(false); - const router = useRouter(); const { setIsRightAsideExpanded, isRightAsideExpanded } = useLayout(); const handleDelete = (value: any) => { removeAsset(value); }; - const handleLink = async (uuid: any) => { - router.push(`/assets/${uuid}`); + const handleLink = async (assetProp: IAsset) => { + const asset = await getAsset(assetProp.uuid, account!); + if (!asset) { + addNotification({ + intent: 'negative', + label: 'asset is not found', + }); + return; + } + setAsset(asset); + window.location.href = '/'; }; return ( @@ -78,7 +90,7 @@ const Assets = () => { }, { label: '', - key: 'uuid', + key: '', width: '10%', render: CompactTableFormatters.FormatActions({ trigger: ( From 73aac978db53cdcdba69455a92548c4d6fbde66e Mon Sep 17 00:00:00 2001 From: Steven Straatemans Date: Wed, 8 Jan 2025 09:40:56 +0100 Subject: [PATCH 3/6] add forced transfer functionality --- .changeset/short-planets-grin.md | 2 + .../investors/[investorAccount]/page.tsx | 10 ++++ packages/apps/rwa-demo/src/app/(app)/page.tsx | 5 +- .../components/TransferForm/TransferForm.tsx | 39 ++++++++++++++-- .../apps/rwa-demo/src/hooks/transferTokens.ts | 5 +- .../src/services/forcedTransferTokens.ts | 46 +++++++++++++++++++ .../rwa-demo/src/services/transferTokens.ts | 1 + 7 files changed, 101 insertions(+), 7 deletions(-) create mode 100644 .changeset/short-planets-grin.md create mode 100644 packages/apps/rwa-demo/src/services/forcedTransferTokens.ts diff --git a/.changeset/short-planets-grin.md b/.changeset/short-planets-grin.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/short-planets-grin.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/packages/apps/rwa-demo/src/app/(app)/(isAgent)/investors/[investorAccount]/page.tsx b/packages/apps/rwa-demo/src/app/(app)/(isAgent)/investors/[investorAccount]/page.tsx index 5dfcfc5982..4f7d55e2c5 100644 --- a/packages/apps/rwa-demo/src/app/(app)/(isAgent)/investors/[investorAccount]/page.tsx +++ b/packages/apps/rwa-demo/src/app/(app)/(isAgent)/investors/[investorAccount]/page.tsx @@ -8,6 +8,8 @@ import { PartiallyFreezeTokensForm } from '@/components/PartiallyFreezeTokensFor import { SideBarBreadcrumbs } from '@/components/SideBarBreadcrumbs/SideBarBreadcrumbs'; import { TXTYPES } from '@/components/TransactionsProvider/TransactionsProvider'; import { TransactionTypeSpinner } from '@/components/TransactionTypeSpinner/TransactionTypeSpinner'; +import { TransferForm } from '@/components/TransferForm/TransferForm'; +import { useAccount } from '@/hooks/account'; import { useAddInvestor } from '@/hooks/addInvestor'; import { useDistributeTokens } from '@/hooks/distributeTokens'; import { useGetInvestor } from '@/hooks/getInvestor'; @@ -19,6 +21,7 @@ import { useParams } from 'next/navigation'; const InvestorPage = () => { const params = useParams(); + const { accountRoles } = useAccount(); const investorAccount = decodeURIComponent(params.investorAccount as string); const { isAllowed: isPartiallyFreezeTokensAllowed } = useTogglePartiallyFreezeTokens({ @@ -47,6 +50,13 @@ const InvestorPage = () => { + {accountRoles.isTransferManager() && ( + Forced transfer} + /> + )} { } /> - } /> + } + /> diff --git a/packages/apps/rwa-demo/src/components/TransferForm/TransferForm.tsx b/packages/apps/rwa-demo/src/components/TransferForm/TransferForm.tsx index 1d34d7fbcb..275d040c97 100644 --- a/packages/apps/rwa-demo/src/components/TransferForm/TransferForm.tsx +++ b/packages/apps/rwa-demo/src/components/TransferForm/TransferForm.tsx @@ -1,9 +1,18 @@ import { useAccount } from '@/hooks/account'; import { useGetFrozenTokens } from '@/hooks/getFrozenTokens'; +import { useGetInvestorBalance } from '@/hooks/getInvestorBalance'; import { useGetInvestors } from '@/hooks/getInvestors'; import { useTransferTokens } from '@/hooks/transferTokens'; import type { ITransferTokensProps } from '@/services/transferTokens'; -import { Button, Select, SelectItem, TextField } from '@kadena/kode-ui'; +import { + Button, + Notification, + NotificationHeading, + Select, + SelectItem, + Stack, + TextField, +} from '@kadena/kode-ui'; import { RightAside, RightAsideContent, @@ -14,21 +23,30 @@ import { import type { FC, ReactElement } from 'react'; import { cloneElement, useState } from 'react'; import { Controller, useForm } from 'react-hook-form'; +import { IWalletAccount } from '../AccountProvider/AccountType'; import { AssetPausedMessage } from '../AssetPausedMessage/AssetPausedMessage'; interface IProps { onClose?: () => void; trigger: ReactElement; + isForced?: boolean; + investorAccount: string; } -export const TransferForm: FC = ({ onClose, trigger }) => { +export const TransferForm: FC = ({ + onClose, + trigger, + isForced = false, + investorAccount, +}) => { const [isOpen, setIsOpen] = useState(false); const { setIsRightAsideExpanded, isRightAsideExpanded } = useLayout(); - const { account, balance } = useAccount(); + const { account } = useAccount(); + const { data: balance } = useGetInvestorBalance({ investorAccount }); const { data: investors } = useGetInvestors(); const { submit, isAllowed } = useTransferTokens(); const { data: frozenAmount } = useGetFrozenTokens({ - investorAccount: account?.address!, + investorAccount: investorAccount, }); const { @@ -41,6 +59,7 @@ export const TransferForm: FC = ({ onClose, trigger }) => { amount: 0, investorFromAccount: account?.address!, investorToAccount: '', + isForced, }, }); @@ -67,7 +86,7 @@ export const TransferForm: FC = ({ onClose, trigger }) => { if (!account) return; - const maxAmount = balance - frozenAmount; + const maxAmount = isForced ? balance : balance - frozenAmount; return ( <> @@ -76,6 +95,16 @@ export const TransferForm: FC = ({ onClose, trigger }) => {
+ {isForced && ( + + + Warning + This is a forced transfer (partial frozen tokens can also be + transfered) + + + )} + { const submit = async (data: ITransferTokensProps) => { try { - const tx = await transferTokens(data, account!); + const tx = data.isForced + ? await forcedTransferTokens(data, account!) + : await transferTokens(data, account!); const signedTransaction = await sign(tx); if (!signedTransaction) return; diff --git a/packages/apps/rwa-demo/src/services/forcedTransferTokens.ts b/packages/apps/rwa-demo/src/services/forcedTransferTokens.ts new file mode 100644 index 0000000000..0cf5752edc --- /dev/null +++ b/packages/apps/rwa-demo/src/services/forcedTransferTokens.ts @@ -0,0 +1,46 @@ +import type { IWalletAccount } from '@/components/AccountProvider/AccountType'; +import { getNetwork } from '@/utils/client'; +import { getAsset } from '@/utils/getAsset'; +import { getPubkeyFromAccount } from '@/utils/getPubKey'; +import { Pact } from '@kadena/client'; +import { PactNumber } from '@kadena/pactjs'; +import type { ITransferTokensProps } from './transferTokens'; + +const createPubKeyFromAccount = (account: string): string => { + return account.replace('k:', '').replace('r:', ''); +}; + +export const forcedTransferTokens = async ( + data: ITransferTokensProps, + account: IWalletAccount, +) => { + return Pact.builder + .execution( + ` + (${getAsset()}.forced-transfer (read-string 'investorFrom) (read-string 'investorTo) ${new PactNumber(data.amount).toDecimal()})`, + ) + .addData('agent', account.address) + .addData('investorFrom', data.investorFromAccount) + .addData('investorTo', data.investorToAccount) + .setMeta({ + senderAccount: account.address, + chainId: getNetwork().chainId, + }) + .addSigner(createPubKeyFromAccount(data.investorFromAccount), (withCap) => [ + withCap(`${getAsset()}.FORCED-TRANSFER`), + withCap(`${getAsset()}.ONLY-AGENT`, 'transfer-manager'), + withCap( + `${getAsset()}.TRANSFER`, + data.investorFromAccount, + data.investorToAccount, + { + decimal: data.amount, + }, + ), + ]) + .addSigner(getPubkeyFromAccount(account), (withCap) => [ + withCap(`coin.GAS`), + ]) + .setNetworkId(getNetwork().networkId) + .createTransaction(); +}; diff --git a/packages/apps/rwa-demo/src/services/transferTokens.ts b/packages/apps/rwa-demo/src/services/transferTokens.ts index 9c43fdb861..9961831153 100644 --- a/packages/apps/rwa-demo/src/services/transferTokens.ts +++ b/packages/apps/rwa-demo/src/services/transferTokens.ts @@ -9,6 +9,7 @@ export interface ITransferTokensProps { amount: number; investorFromAccount: string; investorToAccount: string; + isForced?: boolean; } const createPubKeyFromAccount = (account: string): string => { From 0830d3c8e19c1611f17ad250116e628d62aed67f Mon Sep 17 00:00:00 2001 From: Steven Straatemans Date: Wed, 8 Jan 2025 09:43:59 +0100 Subject: [PATCH 4/6] fix build --- packages/apps/rwa-demo/src/app/(app)/assets/page.tsx | 3 +-- .../apps/rwa-demo/src/components/TransferForm/TransferForm.tsx | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/apps/rwa-demo/src/app/(app)/assets/page.tsx b/packages/apps/rwa-demo/src/app/(app)/assets/page.tsx index 9fc6d3cb40..2424b47df0 100644 --- a/packages/apps/rwa-demo/src/app/(app)/assets/page.tsx +++ b/packages/apps/rwa-demo/src/app/(app)/assets/page.tsx @@ -1,7 +1,6 @@ 'use client'; import { AssetFormScreen } from '@/components/AssetForm/AssetFormScreen'; -import type { IAsset } from '@/components/AssetProvider/AssetProvider'; import { Confirmation } from '@/components/Confirmation/Confirmation'; import { SideBarBreadcrumbs } from '@/components/SideBarBreadcrumbs/SideBarBreadcrumbs'; import { useAccount } from '@/hooks/account'; @@ -35,7 +34,7 @@ const Assets = () => { removeAsset(value); }; - const handleLink = async (assetProp: IAsset) => { + const handleLink = async (assetProp: any) => { const asset = await getAsset(assetProp.uuid, account!); if (!asset) { addNotification({ diff --git a/packages/apps/rwa-demo/src/components/TransferForm/TransferForm.tsx b/packages/apps/rwa-demo/src/components/TransferForm/TransferForm.tsx index 275d040c97..90f43c0712 100644 --- a/packages/apps/rwa-demo/src/components/TransferForm/TransferForm.tsx +++ b/packages/apps/rwa-demo/src/components/TransferForm/TransferForm.tsx @@ -23,7 +23,6 @@ import { import type { FC, ReactElement } from 'react'; import { cloneElement, useState } from 'react'; import { Controller, useForm } from 'react-hook-form'; -import { IWalletAccount } from '../AccountProvider/AccountType'; import { AssetPausedMessage } from '../AssetPausedMessage/AssetPausedMessage'; interface IProps { From 5ff737d67b1aae161e8276b1dd556175f336e2b8 Mon Sep 17 00:00:00 2001 From: Steven Straatemans Date: Wed, 8 Jan 2025 10:38:31 +0100 Subject: [PATCH 5/6] fix the permissions for forced transfer --- .../components/TransferForm/TransferForm.tsx | 23 ++++++--- .../src/hooks/forcedTransferTokens.ts | 50 +++++++++++++++++++ .../apps/rwa-demo/src/hooks/transferTokens.ts | 5 +- .../src/services/forcedTransferTokens.ts | 3 +- 4 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 packages/apps/rwa-demo/src/hooks/forcedTransferTokens.ts diff --git a/packages/apps/rwa-demo/src/components/TransferForm/TransferForm.tsx b/packages/apps/rwa-demo/src/components/TransferForm/TransferForm.tsx index 90f43c0712..67fae1b1c0 100644 --- a/packages/apps/rwa-demo/src/components/TransferForm/TransferForm.tsx +++ b/packages/apps/rwa-demo/src/components/TransferForm/TransferForm.tsx @@ -1,4 +1,5 @@ import { useAccount } from '@/hooks/account'; +import { useForcedTransferTokens } from '@/hooks/forcedTransferTokens'; import { useGetFrozenTokens } from '@/hooks/getFrozenTokens'; import { useGetInvestorBalance } from '@/hooks/getInvestorBalance'; import { useGetInvestors } from '@/hooks/getInvestors'; @@ -43,9 +44,11 @@ export const TransferForm: FC = ({ const { account } = useAccount(); const { data: balance } = useGetInvestorBalance({ investorAccount }); const { data: investors } = useGetInvestors(); + const { submit: forcedSubmit, isAllowed: isForcedAllowed } = + useForcedTransferTokens(); const { submit, isAllowed } = useTransferTokens(); const { data: frozenAmount } = useGetFrozenTokens({ - investorAccount: investorAccount, + investorAccount, }); const { @@ -56,7 +59,7 @@ export const TransferForm: FC = ({ } = useForm({ values: { amount: 0, - investorFromAccount: account?.address!, + investorFromAccount: investorAccount, investorToAccount: '', isForced, }, @@ -75,16 +78,19 @@ export const TransferForm: FC = ({ }; const onSubmit = async (data: ITransferTokensProps) => { - await submit(data); + if (data.isForced) { + await forcedSubmit(data); + } else { + await submit(data); + } handleOnClose(); }; const filteredInvestors = investors.filter( - (i) => i.accountName !== account?.address, + (i) => i.accountName !== investorAccount, ); if (!account) return; - const maxAmount = isForced ? balance : balance - frozenAmount; return ( @@ -156,7 +162,12 @@ export const TransferForm: FC = ({ - diff --git a/packages/apps/rwa-demo/src/hooks/forcedTransferTokens.ts b/packages/apps/rwa-demo/src/hooks/forcedTransferTokens.ts new file mode 100644 index 0000000000..46a30e83ca --- /dev/null +++ b/packages/apps/rwa-demo/src/hooks/forcedTransferTokens.ts @@ -0,0 +1,50 @@ +import { + interpretErrorMessage, + TXTYPES, +} from '@/components/TransactionsProvider/TransactionsProvider'; +import { forcedTransferTokens } from '@/services/forcedTransferTokens'; +import type { ITransferTokensProps } from '@/services/transferTokens'; +import { getClient } from '@/utils/client'; +import { useNotifications } from '@kadena/kode-ui/patterns'; +import { useEffect, useState } from 'react'; +import { useAccount } from './account'; +import { useAsset } from './asset'; +import { useTransactions } from './transactions'; + +export const useForcedTransferTokens = () => { + const { account, sign, isMounted, accountRoles } = useAccount(); + const { paused } = useAsset(); + const { addTransaction } = useTransactions(); + const { addNotification } = useNotifications(); + const [isAllowed, setIsAllowed] = useState(false); + + const submit = async (data: ITransferTokensProps) => { + try { + const tx = await forcedTransferTokens(data, account!); + const signedTransaction = await sign(tx); + if (!signedTransaction) return; + + const client = getClient(); + const res = await client.submit(signedTransaction); + + return addTransaction({ + ...res, + type: TXTYPES.TRANSFERTOKENS, + accounts: [data.investorFromAccount, data.investorToAccount], + }); + } catch (e: any) { + addNotification({ + intent: 'negative', + label: 'there was an error', + message: interpretErrorMessage(e.message), + }); + } + }; + + useEffect(() => { + if (!isMounted) return; + setIsAllowed(!paused && accountRoles.isTransferManager()); + }, [paused, isMounted, accountRoles]); + + return { submit, isAllowed }; +}; diff --git a/packages/apps/rwa-demo/src/hooks/transferTokens.ts b/packages/apps/rwa-demo/src/hooks/transferTokens.ts index eb6d800cd8..1e99455b62 100644 --- a/packages/apps/rwa-demo/src/hooks/transferTokens.ts +++ b/packages/apps/rwa-demo/src/hooks/transferTokens.ts @@ -2,7 +2,6 @@ import { interpretErrorMessage, TXTYPES, } from '@/components/TransactionsProvider/TransactionsProvider'; -import { forcedTransferTokens } from '@/services/forcedTransferTokens'; import type { ITransferTokensProps } from '@/services/transferTokens'; import { transferTokens } from '@/services/transferTokens'; import { getClient } from '@/utils/client'; @@ -23,9 +22,7 @@ export const useTransferTokens = () => { const submit = async (data: ITransferTokensProps) => { try { - const tx = data.isForced - ? await forcedTransferTokens(data, account!) - : await transferTokens(data, account!); + const tx = await transferTokens(data, account!); const signedTransaction = await sign(tx); if (!signedTransaction) return; diff --git a/packages/apps/rwa-demo/src/services/forcedTransferTokens.ts b/packages/apps/rwa-demo/src/services/forcedTransferTokens.ts index 0cf5752edc..959ee41c4e 100644 --- a/packages/apps/rwa-demo/src/services/forcedTransferTokens.ts +++ b/packages/apps/rwa-demo/src/services/forcedTransferTokens.ts @@ -26,8 +26,7 @@ export const forcedTransferTokens = async ( senderAccount: account.address, chainId: getNetwork().chainId, }) - .addSigner(createPubKeyFromAccount(data.investorFromAccount), (withCap) => [ - withCap(`${getAsset()}.FORCED-TRANSFER`), + .addSigner(createPubKeyFromAccount(account.address), (withCap) => [ withCap(`${getAsset()}.ONLY-AGENT`, 'transfer-manager'), withCap( `${getAsset()}.TRANSFER`, From 75dc1cf5b523c3c89efc8430a3f7a865389799f5 Mon Sep 17 00:00:00 2001 From: Steven Straatemans Date: Wed, 8 Jan 2025 10:44:32 +0100 Subject: [PATCH 6/6] add admin acount to the transaction warning --- packages/apps/rwa-demo/src/hooks/forcedTransferTokens.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/apps/rwa-demo/src/hooks/forcedTransferTokens.ts b/packages/apps/rwa-demo/src/hooks/forcedTransferTokens.ts index 46a30e83ca..6bbd8bbfc0 100644 --- a/packages/apps/rwa-demo/src/hooks/forcedTransferTokens.ts +++ b/packages/apps/rwa-demo/src/hooks/forcedTransferTokens.ts @@ -30,7 +30,11 @@ export const useForcedTransferTokens = () => { return addTransaction({ ...res, type: TXTYPES.TRANSFERTOKENS, - accounts: [data.investorFromAccount, data.investorToAccount], + accounts: [ + account?.address!, + data.investorFromAccount, + data.investorToAccount, + ], }); } catch (e: any) { addNotification({