Skip to content
Open
Show file tree
Hide file tree
Changes from 5 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
8 changes: 5 additions & 3 deletions packages/apps/wallet-sdk-example/src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ export const Header: React.FC = () => {
<Link to="/kadenanames">Kadena Names</Link>
</NavHeaderLink>
</Tooltip>
<Tooltip text="Get all accounts by PublicKey.">
<NavHeaderLink href="/accountsbypublickey" asChild>
<Link to="/accountsbypublickey">Accounts by public key</Link>
</NavHeaderLink>
</Tooltip>
</NavHeaderLinkList>

<Tooltip text="Select the network for executing commands.">
Expand All @@ -84,9 +89,6 @@ export const Header: React.FC = () => {
<SelectItem key="testnet04" textValue="Testnet">
Testnet
</SelectItem>
<SelectItem key="testnet05" textValue="Testnet Pact5">
Testnet (Pact 5)
</SelectItem>
</NavHeaderSelect>
</Tooltip>
<Tooltip text="Switch between light and dark themes.">
Expand Down
76 changes: 76 additions & 0 deletions packages/apps/wallet-sdk-example/src/hooks/accountsByPublickey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import type {
GraphType,
IFungibleAccount,
IFungibleAccountsResponse,
} from '@kadena/wallet-sdk';
import { walletSdk } from '@kadena/wallet-sdk';
import { useQuery } from '@tanstack/react-query';
import { useEffect, useState } from 'react';
import { useWalletState } from '../state/wallet';
import { useFunctionTracker } from './functionTracker';

/**
* Custom hook to fetch fungible accounts by public key.
*
* @param publicKey - The public key associated with the account.
* @param fungibleName - The name of the fungible token.
* @param graphType - The type of GraphQL endpoint to use (Kadena or Hackachain).
* @returns An object containing the fetched accounts, loading state, error, and refetch function.
*/
export const useAccountsByPublicKey = (
publicKey: string,
fungibleName: string,
graphType: GraphType = 'hackachain',
) => {
const wallet = useWalletState();
const [accounts, setAccounts] = useState<IFungibleAccount[]>([]);

const trackGetAccounts = useFunctionTracker(
'walletSdk.getFungibleAccountsByPublicKey',
);

const {
data: accountsResponse,
error,
isLoading,
refetch,
} = useQuery<IFungibleAccountsResponse | undefined>({
queryKey: [
'accountsByPublicKey',
publicKey,
fungibleName,
wallet.selectedNetwork,
graphType,
],
enabled: false,
queryFn: async () => {
if (!publicKey || !fungibleName || !wallet.selectedNetwork) {
return undefined;
}

return trackGetAccounts.wrap(walletSdk.getFungibleAccountsByPublicKey)({
publicKey,
fungibleName,
networkId: wallet.selectedNetwork,
graphType,
});
},
});

useEffect(() => {
if (accountsResponse?.fungibleAccounts) {
setAccounts(accountsResponse.fungibleAccounts);
} else {
setAccounts([]);
}
}, [accountsResponse]);

return {
accounts,
error,
isLoading,
refetch,
// Demo: Track function calls for debugging or logging purposes
functionCalls: [trackGetAccounts.data],
};
};
1 change: 0 additions & 1 deletion packages/apps/wallet-sdk-example/src/host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export type ChainwebHostGenerator = (options: {
export const chainwebHostMap: Record<string, string | string[]> = {
mainnet01: 'https://api.chainweb.com',
testnet04: 'https://api.testnet.chainweb.com',
testnet05: 'https://api.testnet.chainweb.com',
};

export const getChainIdByNetwork = (networkId: string): ChainId => {
Expand Down
138 changes: 138 additions & 0 deletions packages/apps/wallet-sdk-example/src/pages/accountsByPublickey.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { MonoFormatListBulleted } from '@kadena/kode-icons/system';
import {
Button,
Card,
Cell,
Column,
ContentHeader,
Divider,
Row,
Stack,
Table,
TableBody,
TableHeader,
Text,
TextField,
} from '@kadena/kode-ui';

import { useState } from 'react';
import SdkFunctionDisplay from '../components/SdkFunctionDisplayer'; // Demo
import { TextEllipsis } from '../components/Text';
import { useAccountsByPublicKey } from '../hooks/accountsByPublickey';

export const AccountsByPublicKey = () => {
const [publicKey, setPublicKey] = useState<string>('');
const [fungibleName, setFungibleName] = useState<string>('');

const { accounts, functionCalls, error, isLoading, refetch } =
useAccountsByPublicKey(publicKey, fungibleName);

const handleFetchAccounts = () => {
refetch();
};

return (
<div className="w-full max-w-[1000px] mx-auto p-6">
<Card fullWidth>
<ContentHeader
heading="Accounts"
description="View accounts associated with your public key."
icon={<MonoFormatListBulleted />}
/>

<Divider />

<Stack flexDirection="column" gap="md" className="mb-6">
<Text variant="ui" bold>
Fetch Accounts
</Text>
<Stack flexDirection="row" gap="md">
<TextField
label="Public Key"
placeholder="Enter public key"
value={publicKey}
onValueChange={setPublicKey}
size="md"
/>
<TextField
label="Fungible Name"
placeholder="Enter fungible name"
value={fungibleName}
onValueChange={setFungibleName}
size="md"
/>
<Button
variant="primary"
onPress={handleFetchAccounts}
isDisabled={!publicKey || !fungibleName}
>
Fetch
</Button>
</Stack>
</Stack>

<Divider />

{error && (
<Text variant="ui" className="mb-4">
Error fetching accounts: {error.message}
</Text>
)}

{isLoading && (
<Stack alignItems="center" justifyContent="center" className="py-10">
<Text variant="ui" className="mt-4">
Loading accounts...
</Text>
</Stack>
)}

{!isLoading && !error && (
<Stack flexDirection="column" gap="md">
<Text variant="ui" bold>
Associated accounts
</Text>

{accounts?.length ? (
<Table aria-label="Associated Accounts">
<TableHeader>
<Column>Account Name</Column>
<Column>Chain</Column>
</TableHeader>
<TableBody>
{accounts.map((accountItem, index) => (
<Row key={`associated-account-${index}`}>
<Cell>
<TextEllipsis maxLength={15} withCopyButton>
{accountItem.accountName}
</TextEllipsis>
</Cell>
<Cell>
{accountItem.chainAccounts.map((chain, chainIndex) => (
<div key={`chain-${chainIndex}`}>
{chain.chainId} ({chain.accountName})
</div>
))}
</Cell>
</Row>
))}
</TableBody>
</Table>
) : (
<Text variant="ui">No associated accounts</Text>
)}
</Stack>
)}
</Card>

{/*
This is for Demo purposes, displaying what SDK function is executed for this action
*/}
{functionCalls.map((data, index) => (
<SdkFunctionDisplay key={`display-${index}`} data={data} />
))}
</div>
);
};

export default AccountsByPublicKey;
5 changes: 5 additions & 0 deletions packages/apps/wallet-sdk-example/src/routes.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { RouteObject } from 'react-router-dom';

import { AccountsByPublicKey } from './pages/accountsByPublickey';
import MarkdownPage from './pages/Home';
import { KadenaNames } from './pages/kadenaNames/KadenaNamesResolver';
import { Transfer } from './pages/Transfer';
Expand Down Expand Up @@ -27,6 +28,10 @@ const routes: RouteObject[] = [
path: '/kadenanames',
element: <KadenaNames />,
},
{
path: 'accountsbypublickey',
element: <AccountsByPublicKey />,
},
];

export default routes;
Loading
Loading