feat(explorer): add signature viewer (#5264)
Co-authored-by: Madalina Raicu <madalina@raygroup.uk>
This commit is contained in:
parent
8182da3b31
commit
e06f4818fc
@ -12,7 +12,8 @@ import { type VegaICellRendererParams } from '@vegaprotocol/datagrid';
|
|||||||
import { useRef, useLayoutEffect } from 'react';
|
import { useRef, useLayoutEffect } from 'react';
|
||||||
import { BREAKPOINT_MD } from '../../config/breakpoints';
|
import { BREAKPOINT_MD } from '../../config/breakpoints';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { type RowClickedEvent, ColDef } from 'ag-grid-community';
|
import { ColDef } from 'ag-grid-community';
|
||||||
|
import type { RowClickedEvent } from 'ag-grid-community';
|
||||||
|
|
||||||
type AssetsTableProps = {
|
type AssetsTableProps = {
|
||||||
data: AssetFieldsFragment[] | null;
|
data: AssetFieldsFragment[] | null;
|
||||||
|
@ -8,7 +8,8 @@ import {
|
|||||||
type VegaValueFormatterParams,
|
type VegaValueFormatterParams,
|
||||||
} from '@vegaprotocol/datagrid';
|
} from '@vegaprotocol/datagrid';
|
||||||
import { useLayoutEffect, useMemo, useRef, useState } from 'react';
|
import { useLayoutEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { type RowClickedEvent, ColDef } from 'ag-grid-community';
|
import { ColDef } from 'ag-grid-community';
|
||||||
|
import type { RowClickedEvent } from 'ag-grid-community';
|
||||||
import { getDateTimeFormat } from '@vegaprotocol/utils';
|
import { getDateTimeFormat } from '@vegaprotocol/utils';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import {
|
import {
|
||||||
|
59
apps/explorer/src/app/components/signature/signature.tsx
Normal file
59
apps/explorer/src/app/components/signature/signature.tsx
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { useState } from 'react';
|
||||||
|
import type { BlockExplorerTransactionResult } from '../../routes/types/block-explorer-response';
|
||||||
|
import {
|
||||||
|
CopyWithTooltip,
|
||||||
|
VegaIcon,
|
||||||
|
VegaIconNames,
|
||||||
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
|
import { t } from '@vegaprotocol/i18n';
|
||||||
|
|
||||||
|
interface SignatureProps {
|
||||||
|
signature: BlockExplorerTransactionResult['signature'];
|
||||||
|
}
|
||||||
|
|
||||||
|
const valueClass =
|
||||||
|
'font-mono px-2.5 py-0.5 text-xs max-w-[200px] cursor-pointer';
|
||||||
|
const valueClassClosed = 'text-ellipsis overflow-hidden';
|
||||||
|
const valueClassOpen = 'break-words text-left';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Viewer component for a vega signature. Featuers copy and pasting, truncation
|
||||||
|
*
|
||||||
|
* @param signature
|
||||||
|
*/
|
||||||
|
export const Signature = ({ signature }: SignatureProps) => {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
|
if (!signature || !signature.value || !signature.version || !signature.algo) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="inline-flex border rounded signature-component relative pr-[20px]">
|
||||||
|
<span
|
||||||
|
className="bg-gray-100 px-2.5 py-0.5 text-xs text-gray-500 select-none cursor-default"
|
||||||
|
title={`Version ${signature.version}`}
|
||||||
|
>
|
||||||
|
{signature.algo}
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
isOpen
|
||||||
|
? `${valueClass} ${valueClassOpen}`
|
||||||
|
: `${valueClass} ${valueClassClosed}`
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<CopyWithTooltip text={signature.value}>
|
||||||
|
<span title={signature.value}>{signature.value}</span>
|
||||||
|
</CopyWithTooltip>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
onClick={() => setIsOpen(!isOpen)}
|
||||||
|
className="absolute top-[-3px] right-0 pr-2"
|
||||||
|
title={t('Show full signature')}
|
||||||
|
>
|
||||||
|
<VegaIcon name={isOpen ? VegaIconNames.EYE_OFF : VegaIconNames.EYE} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -9,6 +9,7 @@ import { Time } from '../../../time';
|
|||||||
import { ChainResponseCode } from '../chain-response-code/chain-reponse.code';
|
import { ChainResponseCode } from '../chain-response-code/chain-reponse.code';
|
||||||
import { TxDataView } from '../../tx-data-view';
|
import { TxDataView } from '../../tx-data-view';
|
||||||
import Hash from '../../../links/hash';
|
import Hash from '../../../links/hash';
|
||||||
|
import { Signature } from '../../../signature/signature';
|
||||||
|
|
||||||
interface TxDetailsSharedProps {
|
interface TxDetailsSharedProps {
|
||||||
txData: BlockExplorerTransactionResult | undefined;
|
txData: BlockExplorerTransactionResult | undefined;
|
||||||
@ -75,6 +76,12 @@ export const TxDetailsShared = ({
|
|||||||
<BlockLink height={height} />
|
<BlockLink height={height} />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
<TableRow modifier="bordered">
|
||||||
|
<TableCell {...sharedHeaderProps}>{t('Signature')}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<Signature signature={txData.signature} />
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
<TableRow modifier="bordered">
|
<TableRow modifier="bordered">
|
||||||
<TableCell {...sharedHeaderProps}>{t('Time')}</TableCell>
|
<TableCell {...sharedHeaderProps}>{t('Time')}</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
|
@ -98,6 +98,8 @@ describe('TxDetailsTransfer', () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
signature: {
|
signature: {
|
||||||
|
version: '1',
|
||||||
|
algo: 'vega/ed25519',
|
||||||
value:
|
value:
|
||||||
'610c2e196a7d4fed4413b9e82af267b1ff3e30e943df3a3d28096fd60604d430d752fbaf6dd4f84d496be78885bb6118f40560bff7832c06bd7a3d67b718b700',
|
'610c2e196a7d4fed4413b9e82af267b1ff3e30e943df3a3d28096fd60604d430d752fbaf6dd4f84d496be78885bb6118f40560bff7832c06bd7a3d67b718b700',
|
||||||
},
|
},
|
||||||
|
@ -20,6 +20,8 @@ const generateTxs = (number: number): BlockExplorerTransactionResult[] => {
|
|||||||
'4b782482f587d291e8614219eb9a5ee9280fa2c58982dee71d976782a9be1964',
|
'4b782482f587d291e8614219eb9a5ee9280fa2c58982dee71d976782a9be1964',
|
||||||
type: 'Submit Order',
|
type: 'Submit Order',
|
||||||
signature: {
|
signature: {
|
||||||
|
version: '1',
|
||||||
|
algo: 'vega/ed25519',
|
||||||
value: '123',
|
value: '123',
|
||||||
},
|
},
|
||||||
code: 0,
|
code: 0,
|
||||||
|
@ -23,6 +23,8 @@ const txData: BlockExplorerTransactionResult = {
|
|||||||
type: 'type',
|
type: 'type',
|
||||||
command: {} as ValidatorHeartbeat,
|
command: {} as ValidatorHeartbeat,
|
||||||
signature: {
|
signature: {
|
||||||
|
version: '1',
|
||||||
|
algo: 'vega/ed25519',
|
||||||
value: '123',
|
value: '123',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -11,6 +11,8 @@ export interface BlockExplorerTransactionResult {
|
|||||||
cursor: string;
|
cursor: string;
|
||||||
command: components['schemas']['blockexplorerv1transaction'];
|
command: components['schemas']['blockexplorerv1transaction'];
|
||||||
signature: {
|
signature: {
|
||||||
|
version: string;
|
||||||
|
algo: string;
|
||||||
value: string;
|
value: string;
|
||||||
};
|
};
|
||||||
error?: string;
|
error?: string;
|
||||||
|
Loading…
Reference in New Issue
Block a user