Skip to content

Commit

Permalink
Refactor/tx (#2630)
Browse files Browse the repository at this point in the history
* refactor(dw): tx service

* refactor(dw): account-item

* Refactor AccountItem component to remove default alias value
  • Loading branch information
javadkh2 authored Nov 4, 2024
1 parent 4c46642 commit 59e0dec
Show file tree
Hide file tree
Showing 12 changed files with 128 additions and 91 deletions.
21 changes: 11 additions & 10 deletions packages/apps/dev-wallet/src/Components/AccountItem/AccountItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
} from '@/modules/account/account.repository';
import { useWallet } from '@/modules/wallet/wallet.hook';
import { noStyleLinkClass } from '@/pages/home/style.css';
import { hashStyle } from '@/pages/transactions/style.css';
import { shorten } from '@/utils/helpers';
import { MonoContentCopy } from '@kadena/kode-icons/system';
import { Button, Stack, Text } from '@kadena/kode-ui';
import { Link } from 'react-router-dom';
Expand All @@ -26,16 +28,15 @@ export function AccountItem({
alignItems={'center'}
>
<ListItem>
<Stack flexDirection={'row'} gap={'sm'}>
{alias ? (
<>
<Text>{alias}</Text>
<Text>({address})</Text>
</>
) : (
<Text>{address}</Text>
)}
</Stack>
{alias ? (
<Stack flexDirection={'row'} gap={'sm'} className={hashStyle}>
<Text>{alias}</Text>
<Text className={hashStyle}>({shorten(address, 10)})</Text>
</Stack>
) : (
<Text className={hashStyle}>{shorten(address, 10)}</Text>
)}

<Stack alignItems={'center'} gap={'sm'}>
<Text>
{overallBalance} {getSymbol(contract)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { IAccount } from '@/modules/account/account.repository';
import { syncAccount } from '@/modules/account/account.service';
import { ITransaction } from '@/modules/transaction/transaction.repository';
import { useWallet } from '@/modules/wallet/wallet.hook';
import { TxContainer } from '@/pages/transaction/components/TxContainer';
import { ChainId } from '@kadena/client';
import { MonoAutorenew } from '@kadena/kode-icons/system';
Expand All @@ -10,7 +8,6 @@ import classNames from 'classnames';
import { useState } from 'react';

export function FundOnTestnetButton({
account,
chainId,
fundAccountHandler,
className,
Expand All @@ -21,7 +18,6 @@ export function FundOnTestnetButton({
className?: string;
}) {
const [fundTx, setFundTx] = useState<ITransaction>();
const { syncAllAccounts } = useWallet();
const [done, setDone] = useState(false);

return (
Expand Down Expand Up @@ -50,11 +46,6 @@ export function FundOnTestnetButton({
as="minimized"
onDone={(tx) => {
setFundTx(tx);
if (account) {
syncAccount(account);
} else {
syncAllAccounts();
}
setDone(true);
}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const listItemClass = style([
{
border: 'none',
flex: 1,
maxWidth: '100%',
minHeight: '50px',
background: tokens.kda.foundation.color.background.surface.default,
selectors: {
Expand Down
35 changes: 33 additions & 2 deletions packages/apps/dev-wallet/src/modules/db/db.service.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,17 @@ const injectDb = <R extends (...args: any[]) => Promise<any>>(
type EventTypes = 'add' | 'update' | 'delete';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type Listener = (type: EventTypes, storeName: string, ...data: any[]) => void;

export interface ISubscribe {
/**
* Subscribe to changes in a store
*/
(cb: Listener): () => void;
/**
* Subscribe to changes in a store
*/
(storeName: string, uuid: string, cb: (data: any) => void): () => void;
}
export interface IDBService {
getAll: <T>(
storeName: string,
Expand All @@ -177,12 +188,32 @@ export interface IDBService {
key?: string | undefined,
) => Promise<void>;
remove: (storeName: string, key: string) => Promise<void>;
subscribe: (cb: Listener) => () => void;
subscribe: ISubscribe;
}

export const createDbService = () => {
const listeners: Listener[] = [];
const subscribe: IDBService['subscribe'] = (cb) => {
const subscribe: ISubscribe = (
first: string | Listener,
second?: string,
third?: (data: any) => void,
) => {
let cb: Listener;
if (typeof first === 'string' && second && third) {
cb = (event, storeName, data) => {
if (storeName === first && event) {
if (event === 'delete' && data === second) {
third(undefined);
} else if (data.uuid === second) {
third(data);
}
}
};
} else if (typeof first === 'function') {
cb = first;
} else {
throw new Error('Invalid arguments');
}
listeners.push(cb);
return () => {
const index = listeners.indexOf(cb);
Expand Down
20 changes: 20 additions & 0 deletions packages/apps/dev-wallet/src/modules/db/useSubscribe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useEffect, useState } from 'react';
import { dbService } from './db.service';

export function useSubscribe<T>(table: string, uuid: string | undefined) {
const [state, setState] = useState<T>();

useEffect(() => {
if (!uuid) return;
let unsubscribe: () => void = () => {};
const run = async () => {
const dbState: T = await dbService.getOne(table, uuid);
setState(dbState);
unsubscribe = dbService.subscribe(table, uuid, setState);
};
run();
return () => unsubscribe();
}, [table, uuid]);

return state;
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export async function syncTransactionStatus(
},
};
await transactionRepository.updateTransaction(updatedTx);
await onSubmitTransaction(contTx, client);
await submitTransaction(contTx, client);
const txd = await transactionRepository.getTransaction(tx.uuid);
const updatedTxd = {
...txd,
Expand All @@ -179,7 +179,7 @@ export async function syncTransactionStatus(
return tx;
}

export const onSubmitTransaction = async (
export const submitTransaction = async (
tx: ITransaction,
client: IClient,
onUpdate: (tx: ITransaction) => void = () => {},
Expand Down Expand Up @@ -301,7 +301,7 @@ export const onSubmitTransaction = async (
};
await transactionRepository.updateTransaction(updatedTx);
onUpdate(updatedTx);
await onSubmitTransaction(contTx, client, (tx) => {
await submitTransaction(contTx, client, (tx) => {
updatedTx = {
...updatedTx,
continuation: {
Expand Down
4 changes: 2 additions & 2 deletions packages/apps/dev-wallet/src/modules/wallet/wallet.hook.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,9 @@ export const useWallet = () => {
const availableKey = keySource.keys.find(
(key) => !usedKeys.includes(key.publicKey),
);
// prompt for password anyway for account creation even if the key is available.
await askForPassword();
if (availableKey) {
// prompt for password anyway for account creation even if the key is available.
await askForPassword();
return createAccountByKey({ key: availableKey, contract, alias });
}
// If no available key, create a new one
Expand Down
21 changes: 17 additions & 4 deletions packages/apps/dev-wallet/src/pages/account/account.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useWallet } from '@/modules/wallet/wallet.hook';

import { fundAccount } from '@/modules/account/account.service';
import { fundAccount, syncAccount } from '@/modules/account/account.service';

import { AccountBalanceDistribution } from '@/Components/AccountBalanceDistribution/AccountBalanceDistribution';
import { ConfirmDeletion } from '@/Components/ConfirmDeletion/ConfirmDeletion';
Expand All @@ -12,6 +12,7 @@ import {
isWatchedAccount,
} from '@/modules/account/account.repository';
import { getTransferActivities } from '@/modules/activity/activity.service';
import * as transactionService from '@/modules/transaction/transaction.service';
import { useAsync } from '@/utils/useAsync';
import { ChainId } from '@kadena/client';
import { MonoKey, MonoRemoveRedEye } from '@kadena/kode-icons/system';
Expand All @@ -26,7 +27,7 @@ import { Redistribute } from './Components/Redistribute';
export function AccountPage() {
const { accountId } = useParams();
const prompt = usePrompt();
const { activeNetwork, fungibles, accounts, profile, watchAccounts } =
const { activeNetwork, fungibles, accounts, profile, watchAccounts, client } =
useWallet();
const [redistributionGroupId, setRedistributionGroupId] = useState<string>();
const account =
Expand Down Expand Up @@ -64,15 +65,26 @@ export function AccountPage() {
if (!activeNetwork) {
throw new Error('No active network found');
}
const tx = await fundAccount({
const fundTx = await fundAccount({
address: account?.address ?? keyset.principal,
chainId,
keyset,
profileId: keyset?.profileId,
network: activeNetwork,
});

return tx;
transactionService
.submitTransaction(fundTx, client)
.then((tx) => {
if (tx.result?.result.status === 'success') {
syncAccount(account);
}
})
.catch((e) => {
console.error(e);
});

return fundTx;
};
const isOwnedAccount =
!isWatchedAccount(account) && account.profileId === profile?.uuid;
Expand Down Expand Up @@ -200,6 +212,7 @@ export function AccountPage() {
groupId={redistributionGroupId}
onDone={() => {
setRedistributionGroupId(undefined);
syncAccount(account);
}}
/>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { dbService } from '@/modules/db/db.service';
import { useSubscribe } from '@/modules/db/useSubscribe';
import {
ITransaction,
transactionRepository,
Expand Down Expand Up @@ -29,62 +29,46 @@ export const TxContainer = React.memo(
onUpdate?: (tx: ITransaction) => void;
onDone?: (tx: ITransaction) => void;
}) => {
const [localTransaction, setLocalTransaction] =
useState<ITransaction | null>(null);

const [contTx, setContTx] = useState<ITransaction>();
const [expandedModal, setExpandedModal] = useState(false);
const { sign, client } = useWallet();
const syncing = useRef(false);
const doneRef = useRef(false);

const localTransaction = useSubscribe<ITransaction>(
'transaction',
transaction.uuid,
);
const contTx = useSubscribe<ITransaction>(
'transaction',
transaction.continuation?.continuationTxId,
);

useEffect(() => {
if (!transaction) return;
const unsubscribe = dbService.subscribe((event, table, data) => {
if (table !== 'transaction' || event !== 'update') return;
if (data.uuid === transaction.uuid) {
setLocalTransaction(data);
console.log(
'data.continuation?.continuationTxId',
data.continuation?.continuationTxId,
'contTx?.uuid',
contTx?.uuid,
);
if (data.continuation?.continuationTxId && !contTx?.uuid) {
console.log('fetching contTx');
transactionRepository
.getTransaction(data.continuation.continuationTxId)
.then(setContTx);
}
return;
}
if (contTx?.uuid === data.uuid) {
setContTx(data);
return;
if (
localTransaction &&
localTransaction.status === 'success' &&
(!localTransaction.continuation?.autoContinue ||
contTx?.status === 'success')
) {
if (onDone && !doneRef.current) {
doneRef.current = true;
console.log('onDone', localTransaction);
onDone(localTransaction);
}
});
if (!syncing.current) {
syncing.current = true;
transactionService.syncTransactionStatus(transaction, client);
}
return () => {
unsubscribe();
};
}, [transaction.uuid, contTx?.uuid, transaction, client]);
if (localTransaction?.status === 'submitted' && onUpdate) {
console.log('onUpdate', localTransaction);
onUpdate(localTransaction);
}
}, [localTransaction?.status, contTx?.status]);

useEffect(() => {
if (!transaction) return;
const run = async () => {
const tx = await transactionRepository.getTransaction(transaction.uuid);
setLocalTransaction(tx);
if (tx.continuation?.continuationTxId) {
const cont = await transactionRepository.getTransaction(
tx.continuation.continuationTxId,
);
setContTx(cont);
}
};
run();
}, [transaction]);
if (transaction && !syncing.current) {
syncing.current = true;
transactionService.syncTransactionStatus(transaction, client);
}
}, [transaction.uuid]);

const onSign = async (tx: ITransaction) => {
const signed = (await sign(tx)) as IUnsignedCommand;
Expand Down Expand Up @@ -124,18 +108,18 @@ export const TxContainer = React.memo(

const onSubmit = useCallback(
async (tx: ITransaction) => {
const result = await transactionService.onSubmitTransaction(
const result = await transactionService.submitTransaction(
tx,
client,
// (updatedTx) => {
// // setLocalTransaction(updatedTx);
// },
);
if (onUpdate) onUpdate(result);
if (onDone) onDone(result);

return result;
},
[client, onDone, onUpdate],
[client, onUpdate],
);

if (!localTransaction) return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export const TxList = React.memo(

const onSendAll = async () => {
const onSubmit = async (tx: ITransaction) => {
return transactionService.onSubmitTransaction(tx, client, updateTx);
return transactionService.submitTransaction(tx, client, updateTx);
};

const txs = await Promise.all(
Expand Down
Loading

0 comments on commit 59e0dec

Please sign in to comment.