diff --git a/libs/market-info/src/components/market-info/market-info-panels.tsx b/libs/market-info/src/components/market-info/market-info-panels.tsx
index ccaccc984..24fb9a72f 100644
--- a/libs/market-info/src/components/market-info/market-info-panels.tsx
+++ b/libs/market-info/src/components/market-info/market-info-panels.tsx
@@ -1,4 +1,5 @@
import type { ComponentProps } from 'react';
+import { useState } from 'react';
import { useMemo } from 'react';
import { AssetDetailsTable, useAssetDataProvider } from '@vegaprotocol/assets';
import { t } from '@vegaprotocol/i18n';
@@ -6,7 +7,7 @@ import {
totalFeesPercentage,
marketDataProvider,
} from '@vegaprotocol/market-list';
-import { ExternalLink, Splash } from '@vegaprotocol/ui-toolkit';
+import { Dialog, ExternalLink, Splash } from '@vegaprotocol/ui-toolkit';
import {
addDecimalsFormatNumber,
formatNumber,
@@ -26,6 +27,7 @@ import { ConditionOperatorMapping } from '@vegaprotocol/types';
import { MarketTradingModeMapping } from '@vegaprotocol/types';
import { useEnvironment } from '@vegaprotocol/environment';
import type { Provider } from '@vegaprotocol/oracles';
+import { OracleProfileTitle, OracleFullProfile } from '@vegaprotocol/oracles';
import { OracleBasicProfile, useOracleProofs } from '@vegaprotocol/oracles';
import { useDataProvider } from '@vegaprotocol/react-helpers';
@@ -456,6 +458,11 @@ export const OracleInfoPanel = ({
const { VEGA_EXPLORER_URL, ORACLE_PROOFS_URL } = useEnvironment();
const { data } = useOracleProofs(ORACLE_PROOFS_URL);
+ const oracleId =
+ type === 'settlementData'
+ ? product.dataSourceSpecForSettlementData.id
+ : product.dataSourceSpecForTradingTermination.id;
+
return (
{type === 'settlementData'
? t('View settlement data specification')
@@ -488,10 +492,12 @@ export const DataSourceProof = ({
data,
providers,
type,
+ id,
}: {
data: DataSourceDefinition;
providers: Provider[] | undefined;
type: 'settlementData' | 'termination';
+ id: string;
}) => {
if (data.sourceType.__typename === 'DataSourceDefinitionExternal') {
const signers = data.sourceType.sourceType.signers || [];
@@ -509,7 +515,7 @@ export const DataSourceProof = ({
providers={providers}
signer={signer}
type={type}
- index={i}
+ id={id}
/>
);
})}
@@ -540,12 +546,14 @@ const OracleLink = ({
providers,
signer,
type,
+ id,
}: {
providers: Provider[];
signer: SignerKind;
type: 'settlementData' | 'termination';
- index: number;
+ id: string;
}) => {
+ const [dialogOpen, setDialogOpen] = useState(false);
const signerProviders = providers.filter((p) => {
if (signer.__typename === 'PubKey') {
if (
@@ -575,10 +583,20 @@ const OracleLink = ({
return (
{signerProviders.map((provider) => (
-
+
+ setDialogOpen(!dialogOpen)}
+ >
+ }
+ open={dialogOpen}
+ onChange={() => setDialogOpen(!dialogOpen)}
+ aria-labelledby="oracle-proof-dialog"
+ >
+
+
+
))}
);
diff --git a/libs/oracles/src/lib/components/index.ts b/libs/oracles/src/lib/components/index.ts
index 8706f7f57..98884d206 100644
--- a/libs/oracles/src/lib/components/index.ts
+++ b/libs/oracles/src/lib/components/index.ts
@@ -1 +1,2 @@
export * from './oracle-basic-profile';
+export * from './oracle-full-profile';
diff --git a/libs/oracles/src/lib/components/oracle-basic-profile/oracle-basic-profile.tsx b/libs/oracles/src/lib/components/oracle-basic-profile/oracle-basic-profile.tsx
index 38c08383f..2da066b35 100644
--- a/libs/oracles/src/lib/components/oracle-basic-profile/oracle-basic-profile.tsx
+++ b/libs/oracles/src/lib/components/oracle-basic-profile/oracle-basic-profile.tsx
@@ -1,10 +1,10 @@
import { t } from '@vegaprotocol/i18n';
import type { Provider } from '../../oracle-schema';
import {
+ ButtonLink,
ExternalLink,
Icon,
Intent,
- Link,
VegaIcon,
VegaIconNames,
} from '@vegaprotocol/ui-toolkit';
@@ -12,7 +12,7 @@ import type { IconName } from '@blueprintjs/icons';
import { IconNames } from '@blueprintjs/icons';
import classNames from 'classnames';
-const getVerifiedStatusIcon = (provider: Provider) => {
+export const getVerifiedStatusIcon = (provider: Provider) => {
const getIconIntent = () => {
switch (provider.oracle.status) {
case 'GOOD':
@@ -54,7 +54,13 @@ const getVerifiedStatusIcon = (provider: Provider) => {
};
};
-export const OracleBasicProfile = ({ provider }: { provider: Provider }) => {
+export const OracleBasicProfile = ({
+ provider,
+ onClick,
+}: {
+ provider: Provider;
+ onClick?: (value?: boolean) => void;
+}) => {
const { icon, message, intent } = getVerifiedStatusIcon(provider);
const verifiedProofs = provider.proofs.filter(
@@ -77,18 +83,14 @@ export const OracleBasicProfile = ({ provider }: { provider: Provider }) => {
<>
{provider.url && (
-
-
- {provider.name}
-
- ({verifiedProofs.length})
-
+
+ onClick && onClick(true)}>
+ {provider.name}
+
+
+ ({verifiedProofs.length})
-
+
)}
(
+
+);
+
+export const OraclePrimary = Template.bind({});
+
+OraclePrimary.args = {
+ provider: {
+ name: 'Test oracle',
+ url: 'https://zombo.com',
+ description_markdown:
+ 'Some markdown describing the oracle provider.\n\nTwitter: @FacesPics2\n',
+ oracle: {
+ status: 'GOOD',
+ status_reason: '',
+ first_verified: '2023-02-28T00:00:00.000Z',
+ last_verified: '2023-02-28T00:00:00.000Z',
+ type: 'eth_address',
+ eth_address: '0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC',
+ },
+ proofs: [
+ {
+ format: 'signed_message',
+ available: true,
+ type: 'eth_address',
+ eth_address: '0x949AF81E51D57831AE52591d17fBcdd1014a5f52',
+ message: 'SOMEHEX',
+ },
+ ],
+ github_link:
+ 'https://github.com/vegaprotocol/well-known/blob/main/oracle-providers/eth_address-0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC.toml',
+ },
+};
diff --git a/libs/oracles/src/lib/components/oracle-full-profile/oracle-full-profile.tsx b/libs/oracles/src/lib/components/oracle-full-profile/oracle-full-profile.tsx
new file mode 100644
index 000000000..3e4d123f4
--- /dev/null
+++ b/libs/oracles/src/lib/components/oracle-full-profile/oracle-full-profile.tsx
@@ -0,0 +1,132 @@
+import { t } from '@vegaprotocol/i18n';
+import type { Provider } from '../../oracle-schema';
+import {
+ ExternalLink,
+ Icon,
+ Intent,
+ VegaIcon,
+ VegaIconNames,
+} from '@vegaprotocol/ui-toolkit';
+import type { IconName } from '@blueprintjs/icons';
+import classNames from 'classnames';
+import { getLinkIcon, getVerifiedStatusIcon } from '../oracle-basic-profile';
+import { useEnvironment } from '@vegaprotocol/environment';
+
+export const OracleProfileTitle = ({ provider }: { provider: Provider }) => {
+ const { icon, intent } = getVerifiedStatusIcon(provider);
+ const verifiedProofs = provider.proofs.filter(
+ (proof) => proof.available === true
+ );
+ return (
+
+ {provider.url && (
+
+ {provider.name}
+
+ ({verifiedProofs.length})
+
+
+ )}
+
+
+
+
+ );
+};
+
+export const OracleFullProfile = ({
+ provider,
+ id,
+}: {
+ provider: Provider;
+ id: string;
+}) => {
+ const { message } = getVerifiedStatusIcon(provider);
+ const { VEGA_EXPLORER_URL } = useEnvironment();
+
+ const signedProofs = provider.proofs.filter(
+ (proof) => proof.format === 'signed_message' && proof.available === true
+ );
+
+ const links = provider.proofs
+ .filter((proof) => proof.format === 'url' && proof.available === true)
+ .map((proof) => ({
+ ...proof,
+ url: 'url' in proof ? proof.url : '',
+ icon: getLinkIcon(proof.type),
+ }));
+
+ return (
+
+
+ {message}
+
+
+
+
+
+ {t('%s verified accounts', links.length.toString())}
+
+ {links.length > 0 ? (
+
+ {links.map((link) => (
+
+
+
+
+
+ {link.type}{' '}
+
+
+
+ ))}
+
+ ) : (
+
+ {t('This oracle has not proven ownership of any accounts.')}
+
+ )}
+
+
+
+ {t('Details')}
+
+ {id && (
+
+ {t('Block explorer')}
+
+ )}
+ {provider.github_link && (
+
+ {t('Oracle repository')}
+
+ )}
+
+
+
+
+
+ {t('Oracle in %s %s', [
+ signedProofs.length.toString(),
+ signedProofs.length === 1 ? 'market' : 'markets',
+ ])}
+
+
+
+ );
+};
diff --git a/libs/ui-toolkit/src/components/dialog/dialog.tsx b/libs/ui-toolkit/src/components/dialog/dialog.tsx
index 21918b352..6e719beb9 100644
--- a/libs/ui-toolkit/src/components/dialog/dialog.tsx
+++ b/libs/ui-toolkit/src/components/dialog/dialog.tsx
@@ -13,7 +13,7 @@ interface DialogProps {
onChange?: (isOpen: boolean) => void;
onCloseAutoFocus?: (e: Event) => void;
onInteractOutside?: (e: Event) => void;
- title?: string;
+ title?: string | ReactNode;
icon?: ReactNode;
intent?: Intent;
size?: 'small' | 'medium';