diff --git a/.changeset/strange-steaks-begin.md b/.changeset/strange-steaks-begin.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/strange-steaks-begin.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/packages/apps/rwa-demo/src/app/(app)/SideBar.tsx b/packages/apps/rwa-demo/src/app/(app)/SideBar.tsx index 422b3c46d0..b2d5d108ee 100644 --- a/packages/apps/rwa-demo/src/app/(app)/SideBar.tsx +++ b/packages/apps/rwa-demo/src/app/(app)/SideBar.tsx @@ -7,6 +7,7 @@ import { MonoLightMode, MonoLogout, MonoNetworkCheck, + MonoVpnLock, } from '@kadena/kode-icons'; import { Button, @@ -67,6 +68,12 @@ export const SideBar: FC = () => { component={Link} href="/" /> + } + label="Assets" + component={Link} + href="/assets" + /> } appContext={ 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 new file mode 100644 index 0000000000..5479556818 --- /dev/null +++ b/packages/apps/rwa-demo/src/app/(app)/assets/[uuid]/page.tsx @@ -0,0 +1,17 @@ +'use client'; +import { useAsset } from '@/hooks/asset'; +import { useParams } from 'next/navigation'; +import { useMemo } from 'react'; + +const Assets = () => { + const { getAsset } = useAsset(); + const { uuid } = useParams(); + const asset = useMemo(() => { + return getAsset(uuid as string); + }, [uuid]); + + console.log({ asset }); + return
{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 new file mode 100644 index 0000000000..75f529954b --- /dev/null +++ b/packages/apps/rwa-demo/src/app/(app)/assets/page.tsx @@ -0,0 +1,35 @@ +'use client'; + +import { useAsset } from '@/hooks/asset'; +import { CompactTable, CompactTableFormatters } from '@kadena/kode-ui/patterns'; +import Link from 'next/link'; + +const Assets = () => { + const { assets } = useAsset(); + + return ( + <> + + + ); +}; + +export default Assets; diff --git a/packages/apps/rwa-demo/src/app/(app)/page.tsx b/packages/apps/rwa-demo/src/app/(app)/page.tsx index 460330bace..4a5bedf559 100644 --- a/packages/apps/rwa-demo/src/app/(app)/page.tsx +++ b/packages/apps/rwa-demo/src/app/(app)/page.tsx @@ -6,12 +6,11 @@ import { OwnerRootPage } from '@/components/HomePage/OwnerRootPage'; import { useAccount } from '@/hooks/account'; const Home = () => { - const { isAgent, isInvestor } = useAccount(); + const { isAgent, isInvestor, isOwner } = useAccount(); - console.log('asset', isAgent); return ( <> - {!isAgent && } + {isOwner && } {isAgent && } {isInvestor && } diff --git a/packages/apps/rwa-demo/src/components/AccountProvider/AccountProvider.tsx b/packages/apps/rwa-demo/src/components/AccountProvider/AccountProvider.tsx index ccb71cae48..04df705990 100644 --- a/packages/apps/rwa-demo/src/components/AccountProvider/AccountProvider.tsx +++ b/packages/apps/rwa-demo/src/components/AccountProvider/AccountProvider.tsx @@ -3,6 +3,7 @@ import { getBalance as getBalanceFnc } from '@/services/getBalance'; import { isAgent } from '@/services/isAgent'; import { isFrozen } from '@/services/isFrozen'; import { isInvestor } from '@/services/isInvestor'; +import { isOwner } from '@/services/isOwner'; import { getAccountCookieName } from '@/utils/getAccountCookieName'; import type { ICommand, IUnsignedCommand } from '@kadena/client'; import { useRouter } from 'next/navigation'; @@ -24,6 +25,7 @@ export interface IAccountContext { logout: () => void; sign: (tx: IUnsignedCommand) => Promise; isAgent: boolean; + isOwner: boolean; isInvestor: boolean; isFrozen: boolean; selectAccount: (account: IWalletAccount) => void; @@ -38,6 +40,7 @@ export const AccountContext = createContext({ logout: () => {}, sign: async () => undefined, isAgent: false, + isOwner: false, isInvestor: false, isFrozen: false, selectAccount: () => {}, @@ -48,6 +51,7 @@ export const AccountProvider: FC = ({ children }) => { const [account, setAccount] = useState(); const [accounts, setAccounts] = useState(); const [isMounted, setIsMounted] = useState(false); + const [isOwnerState, setIsOwnerState] = useState(false); const [isAgentState, setIsAgentState] = useState(false); const [isInvestorState, setIsInvestorState] = useState(false); const [isFrozenState, setIsFrozenState] = useState(false); @@ -58,6 +62,10 @@ export const AccountProvider: FC = ({ children }) => { const resIsAgent = await isAgent({ agent: account.address }); setIsAgentState(!!resIsAgent); }; + const checkIsOwner = async (account: IWalletAccount) => { + const resIsOwner = await isOwner({ owner: account.address }); + setIsOwnerState(!!resIsOwner); + }; const checkIsInvestor = async (account: IWalletAccount) => { const resIsInvestor = await isInvestor({ account }); setIsInvestorState(!!resIsInvestor); @@ -132,10 +140,13 @@ export const AccountProvider: FC = ({ children }) => { useEffect(() => { if (!account) { setIsAgentState(false); + setIsOwnerState(false); setIsInvestorState(false); return; } + // eslint-disable-next-line @typescript-eslint/no-floating-promises + checkIsOwner(account); // eslint-disable-next-line @typescript-eslint/no-floating-promises checkIsAgent(account); // eslint-disable-next-line @typescript-eslint/no-floating-promises @@ -176,6 +187,7 @@ export const AccountProvider: FC = ({ children }) => { logout, sign, isMounted, + isOwner: isOwnerState, isAgent: isAgentState, isInvestor: isInvestorState, isFrozen: isFrozenState, diff --git a/packages/apps/rwa-demo/src/components/AssetProvider/AssetProvider.tsx b/packages/apps/rwa-demo/src/components/AssetProvider/AssetProvider.tsx index 54d24980db..3a8eb1572f 100644 --- a/packages/apps/rwa-demo/src/components/AssetProvider/AssetProvider.tsx +++ b/packages/apps/rwa-demo/src/components/AssetProvider/AssetProvider.tsx @@ -21,12 +21,14 @@ export interface IAssetContext { assets: IAsset[]; paused: boolean; setAsset: (asset: IAsset) => void; + getAsset: (uuid: string) => IAsset | undefined; } export const AssetContext = createContext({ assets: [], paused: false, setAsset: () => {}, + getAsset: (uuid: string) => undefined, }); export const AssetProvider: FC = ({ children }) => { @@ -39,10 +41,11 @@ export const AssetProvider: FC = ({ children }) => { getLocalStorageKey(LOCALSTORAGE_ASSETS_SELECTED_KEY) ?? ''; const { paused } = usePaused(); - const getAssets = () => { + const getAssets = (): IAsset[] => { const result = localStorage.getItem(storageKey); - setAssets(JSON.parse(result ?? '[]')); - router.refresh(); + const arr = JSON.parse(result ?? '[]'); + setAssets(arr); + return arr ?? []; }; const storageListener = (event: StorageEvent | Event) => { @@ -55,9 +58,15 @@ export const AssetProvider: FC = ({ children }) => { localStorage.setItem(selectedKey, JSON.stringify(data)); setAsset(data); + router.replace('/'); router.refresh(); }; + const getAsset = (uuid: string) => { + const data = getAssets().find((a) => a.uuid === uuid); + return data; + }; + useEffect(() => { getAssets(); window.addEventListener(storageKey, storageListener); @@ -79,7 +88,7 @@ export const AssetProvider: FC = ({ children }) => { return ( {children} diff --git a/packages/apps/rwa-demo/src/hooks/freeze.ts b/packages/apps/rwa-demo/src/hooks/freeze.ts index 0ae4f94abd..4cecbb2bdd 100644 --- a/packages/apps/rwa-demo/src/hooks/freeze.ts +++ b/packages/apps/rwa-demo/src/hooks/freeze.ts @@ -47,7 +47,6 @@ export const useFreeze = ({ investorAccount }: { investorAccount: string }) => { useEffect(() => { if (!data?.events?.length) return; const params = JSON.parse(data?.events[0].parameters ?? '[]'); - console.log(params); if (params.length < 2 || params[0] !== investorAccount) return; setFrozen(params[1]); diff --git a/packages/apps/rwa-demo/src/services/addAgent.ts b/packages/apps/rwa-demo/src/services/addAgent.ts index dfd321428e..27b9a6d64d 100644 --- a/packages/apps/rwa-demo/src/services/addAgent.ts +++ b/packages/apps/rwa-demo/src/services/addAgent.ts @@ -32,6 +32,15 @@ export const addAgent = async ( keys: [createPubKeyFromAccount(data.accountName)], pred: 'keys-all', }) + .addData('roles', [ + 'agent-admin', + 'supply-modifier', + 'freezer', + 'transfer-manager', + 'recovery', + 'compliance', + 'whitelist-manager', + ]) .setNetworkId(getNetwork().networkId) .createTransaction(); diff --git a/packages/apps/rwa-demo/src/services/isOwner.ts b/packages/apps/rwa-demo/src/services/isOwner.ts new file mode 100644 index 0000000000..04b11e3c6b --- /dev/null +++ b/packages/apps/rwa-demo/src/services/isOwner.ts @@ -0,0 +1,29 @@ +import { getClient, getNetwork } from '@/utils/client'; +import { getAsset } from '@/utils/getAsset'; +import { Pact } from '@kadena/client'; + +export interface IIsOwnerProps { + owner: string; +} + +export const isOwner = async (data: IIsOwnerProps) => { + const client = getClient(); + console.log({ data }); + + const transaction = Pact.builder + .execution(`(RWA.${getAsset()}.is-owner (read-string 'owner))`) + .setMeta({ + senderAccount: data.owner, + chainId: getNetwork().chainId, + }) + .addData('owner', data.owner) + .setNetworkId(getNetwork().networkId) + .createTransaction(); + + const { result } = await client.local(transaction, { + preflight: false, + signatureVerification: false, + }); + + return result.status === 'success' ? result.data : undefined; +}; diff --git a/packages/apps/rwa-demo/src/services/transferTokens.ts b/packages/apps/rwa-demo/src/services/transferTokens.ts index 451c2611ad..eb027f5297 100644 --- a/packages/apps/rwa-demo/src/services/transferTokens.ts +++ b/packages/apps/rwa-demo/src/services/transferTokens.ts @@ -18,7 +18,6 @@ export const transferTokens = async ( data: ITransferTokensProps, account: IWalletAccount, ) => { - console.log(new PactNumber(data.amount).toPrecision(2)); return Pact.builder .execution( `