mirror of
https://github.com/pezkuwichain/pezkuwi-apps.git
synced 2026-07-29 09:05:45 +00:00
129 lines
3.8 KiB
TypeScript
129 lines
3.8 KiB
TypeScript
// Copyright 2017-2026 @pezkuwi/app-staking authors & contributors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
import type { ContractPromise } from '@pezkuwi/api-contract';
|
|
import type { ContractCallOutcome } from '@pezkuwi/api-contract/types';
|
|
import type { ActionStatus } from '@pezkuwi/react-components/Status/types';
|
|
import type { Option } from '@pezkuwi/types';
|
|
import type { ContractInfo } from '@pezkuwi/types/interfaces';
|
|
import type { ContractLink } from './types.js';
|
|
|
|
import React, { useCallback } from 'react';
|
|
|
|
import { AddressInfo, AddressMini, Button, Forget, styled } from '@pezkuwi/react-components';
|
|
import { useApi, useCall, useToggle } from '@pezkuwi/react-hooks';
|
|
import { keyring } from '@pezkuwi/ui-keyring';
|
|
import { isUndefined } from '@pezkuwi/util';
|
|
|
|
import Messages from '../shared/Messages.js';
|
|
import { useTranslation } from '../translate.js';
|
|
|
|
interface Props {
|
|
className?: string;
|
|
contract: ContractPromise;
|
|
index: number;
|
|
links?: ContractLink[];
|
|
onCall: (contractIndex: number, messaeIndex: number, resultCb: (messageIndex: number, result?: ContractCallOutcome) => void) => void;
|
|
}
|
|
|
|
function transformInfo (optInfo: Option<ContractInfo>): ContractInfo | null {
|
|
return optInfo.unwrapOr(null);
|
|
}
|
|
|
|
function Contract ({ className, contract, index, links, onCall }: Props): React.ReactElement<Props> | null {
|
|
const { t } = useTranslation();
|
|
const { api } = useApi();
|
|
const info = useCall<ContractInfo | null>(api.query.contracts.contractInfoOf, [contract.address], { transform: transformInfo });
|
|
const [isForgetOpen, toggleIsForgetOpen] = useToggle();
|
|
|
|
const _onCall = useCallback(
|
|
(messageIndex: number, resultCb: (messageIndex: number, result?: ContractCallOutcome) => void) =>
|
|
onCall(index, messageIndex, resultCb),
|
|
[index, onCall]
|
|
);
|
|
|
|
const _onForget = useCallback(
|
|
(): void => {
|
|
const status: Partial<ActionStatus> = {
|
|
account: contract.address,
|
|
action: 'forget'
|
|
};
|
|
|
|
try {
|
|
keyring.forgetContract(contract.address.toString());
|
|
status.status = 'success';
|
|
status.message = t('address forgotten');
|
|
} catch (error) {
|
|
status.status = 'error';
|
|
status.message = (error as Error).message;
|
|
}
|
|
|
|
toggleIsForgetOpen();
|
|
},
|
|
[contract.address, t, toggleIsForgetOpen]
|
|
);
|
|
|
|
return (
|
|
<StyledTr className={className}>
|
|
<td className='address top'>
|
|
{isForgetOpen && (
|
|
<Forget
|
|
address={contract.address.toString()}
|
|
key='modal-forget-contract'
|
|
mode='contract'
|
|
onClose={toggleIsForgetOpen}
|
|
onForget={_onForget}
|
|
/>
|
|
)}
|
|
<AddressMini value={contract.address} />
|
|
</td>
|
|
<td className='all top'>
|
|
<Messages
|
|
contract={contract}
|
|
contractAbi={contract.abi}
|
|
isWatching
|
|
onSelect={_onCall}
|
|
trigger={links?.length}
|
|
withMessages
|
|
/>
|
|
</td>
|
|
<td className='top'>
|
|
{links?.map(({ blockHash, blockNumber }, index): React.ReactNode => (
|
|
<a
|
|
href={`#/explorer/query/${blockHash}`}
|
|
key={`${index}-${blockNumber}`}
|
|
>#{blockNumber}</a>
|
|
))}
|
|
</td>
|
|
<td className='number'>
|
|
<AddressInfo
|
|
address={contract.address}
|
|
withBalance
|
|
withBalanceToggle
|
|
/>
|
|
</td>
|
|
<td className='start together'>
|
|
{!isUndefined(info) && (
|
|
info
|
|
? info.type
|
|
: t('Not on-chain')
|
|
)}
|
|
</td>
|
|
<td className='button'>
|
|
<Button
|
|
icon='trash'
|
|
onClick={toggleIsForgetOpen}
|
|
/>
|
|
</td>
|
|
</StyledTr>
|
|
);
|
|
}
|
|
|
|
const StyledTr = styled.tr`
|
|
td.top a+a {
|
|
margin-left: 0.75rem;
|
|
}
|
|
`;
|
|
|
|
export default React.memo(Contract);
|