diff --git a/package.json b/package.json index ecef94e..e183af8 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,7 @@ "web3": "1.5.2" }, "volta": { - "node": "14.21.3", + "node": "16.20.2", "yarn": "1.22.10" } } diff --git a/src/bootstrap/dataloader.js b/src/bootstrap/dataloader.js index c14571a..dd4cf21 100644 --- a/src/bootstrap/dataloader.js +++ b/src/bootstrap/dataloader.js @@ -260,22 +260,37 @@ const evidenceFetcher = async ([subgraph, disputeId]) => { ) .then((res) => res.data.data.dispute.evidenceGroup.evidence); - return await Promise.all( - evidence.map(async (evidenceItem) => { - const uri = getHttpUri(evidenceItem.URI); - - const fileRes = await axios.get(uri); - - if (fileRes.status !== 200) - throw new Error(`HTTP Error: Unable to fetch file at ${uri}. Returned status code ${fileRes.status}`); - - return { - evidenceJSON: fileRes.data, - submittedAt: evidenceItem.creationTime, - submittedBy: evidenceItem.sender, - }; - }) - ); + return ( + await Promise.all( + evidence.map(async (evidenceItem) => { + try { + const uri = getHttpUri(evidenceItem.URI); + try { + const fileRes = await axios.get(uri); + if (fileRes.status !== 200) + throw new Error(`HTTP Error: Unable to fetch file at ${uri}. Returned status code ${fileRes.status}`); + + return { + evidenceJSON: fileRes.data, + submittedAt: evidenceItem.creationTime, + submittedBy: evidenceItem.sender, + }; + } catch (requestError) { + // URI is correct, but the request failed + return { + error: `${requestError.message}. Requested URI: ${uri}`, + submittedAt: evidenceItem.creationTime, + submittedBy: evidenceItem.sender, + }; + } + } catch (uriError) { + // invalid uri, returning null to be filtered out + console.error(uriError.message); + return null; + } + }) + ) + ).filter((e) => !!e); // This will filter out the null values (invalid URIs) }; export function useEvidence(chainId, disputeID) { diff --git a/src/components/case-details-card.jsx b/src/components/case-details-card.jsx index 265eb85..09c062e 100644 --- a/src/components/case-details-card.jsx +++ b/src/components/case-details-card.jsx @@ -262,8 +262,11 @@ export default function CaseDetailsCard({ ID }) { const [committedVote, setCommittedVote] = useStoredCommittedVote(); useEffect(() => { - if (dispute?.arbitrated && !arbitrableWhitelist[chainId]?.includes(dispute?.arbitrated.toLowerCase())) - console.warn("Arbitrable not included in whitelist for evidence display"); + if (dispute?.arbitrated && !arbitrableWhitelist[chainId]?.includes(dispute?.arbitrated.toLowerCase())) { + console.warn("Arbitrable NOT included in whitelist for evidence display: ", dispute?.arbitrated); + } else { + console.info("Arbitrable included in whitelist for evidence display: ", dispute?.arbitrated); + } }, [dispute?.arbitrated, chainId]); useEffect(() => { @@ -451,7 +454,6 @@ export default function CaseDetailsCard({ ID }) { return url; } }, [metaEvidence, ID, dispute, chainId, KlerosLiquid.address]); - return ( <> .ant-card-body { padding-top: 12px !important; } -` +`; + const StyledTitle = styled.div` color: #4d00b4; font-size: 18px; font-weight: 500; line-height: 21px; -` +`; + const StyledDescription = styled.div` color: #000000; font-size: 14px; @@ -30,7 +32,8 @@ const StyledDescription = styled.div` white-space: -pre-wrap; /* Opera 4-6 */ white-space: -o-pre-wrap; /* Opera 7 */ word-wrap: break-word; /* Internet Explorer 5.5+ */ -` +`; + const StyledFooter = styled.div` background: #f5f1fd; margin: 0 -46px -23px -46px; @@ -39,94 +42,95 @@ const StyledFooter = styled.div` @media (max-width: 767px) { margin: 0 -23px -23px -23px; } -` +`; + const StyledFooterBody = styled.div` padding: 13px 46px 23px; -` +`; + const StyledSubmitter = styled.div` color: #4d00b4; font-size: 14px; font-weight: 500; -` +`; + const StyledTime = styled.div` font-weight: 400; -` - -const truncateAddress = address => - `${address.substring(0, 6)}...${address.substring( - address.length - 4, - address.length - )}` - -const months = [ - 'Jan', - 'Feb', - 'Mar', - 'Apr', - 'May', - 'June', - 'July', - 'Aug', - 'Sept', - 'Oct', - 'Nov', - 'Dec' -] - -export const displayDateUTC = dateString => { - const _date = new Date(dateString) - - const date = String(_date.getUTCDate()).replace(/\b(\d{1})\b/g, '0$1') - const month = _date.getUTCMonth() - const year = _date.getUTCFullYear() - const hours = String(_date.getUTCHours()).replace(/\b(\d{1})\b/g, '0$1') - const minutes = String(_date.getUTCMinutes()).replace(/\b(\d{1})\b/g, '0$1') - - return `${date} ${months[month]} ${year} ${hours}:${minutes} UTC` -} +`; + +const ErrorStyledCard = styled(StyledCard)` + background: #fff3cd; + border-color: #ffeeba; +`; + +const truncateAddress = (address) => + `${address.substring(0, 6)}...${address.substring(address.length - 4, address.length)}`; + +const months = ["Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"]; + +export const displayDateUTC = (dateString) => { + const _date = new Date(dateString); + + const date = String(_date.getUTCDate()).replace(/\b(\d{1})\b/g, "0$1"); + const month = _date.getUTCMonth(); + const year = _date.getUTCFullYear(); + const hours = String(_date.getUTCHours()).replace(/\b(\d{1})\b/g, "0$1"); + const minutes = String(_date.getUTCMinutes()).replace(/\b(\d{1})\b/g, "0$1"); + + return `${date} ${months[month]} ${year} ${hours}:${minutes} UTC`; +}; const EvidenceCard = ({ evidence, metaEvidence, chainId }) => { - const submittedAtDate = new Date(evidence.submittedAt * 1000) + const submittedAtDate = new Date(evidence.submittedAt * 1000); + + if (evidence.error) { + return ( + + Error Loading Evidence + Error: {evidence.error} + + + + Submitted By: {metaEvidence?.aliases?.[evidence.submittedBy] || truncateAddress(evidence.submittedBy)} + {displayDateUTC(submittedAtDate)} + + + + + ); + } return ( - - {evidence.evidenceJSON.title || evidence.evidenceJSON.name} - - } - > + {evidence.evidenceJSON.title || evidence.evidenceJSON.name}}> {evidence.evidenceJSON.description} - Submitted By:{' '} + Submitted By:{" "} - {metaEvidence.aliases && - metaEvidence.aliases[evidence.submittedBy] - ? metaEvidence.aliases[evidence.submittedBy] - : truncateAddress(evidence.submittedBy)} + {metaEvidence?.aliases?.[evidence.submittedBy] || truncateAddress(evidence.submittedBy)} - + {displayDateUTC(submittedAtDate)} - + - ) -} + ); +}; -export default EvidenceCard +export default EvidenceCard; diff --git a/src/temp/arbitrable-whitelist.js b/src/temp/arbitrable-whitelist.js index c0dbe53..a6b9437 100644 --- a/src/temp/arbitrable-whitelist.js +++ b/src/temp/arbitrable-whitelist.js @@ -28,7 +28,7 @@ const arbitrableWhitelist = { "0xf339047c85d0dd2645f2bd802a1e8a5e7af61053", "0xf65c7560d6ce320cc3a16a07f1f65aab66396b9e", "0xf72cfd1b34a91a64f9a98537fe63fbab7530adca", - ], + ].map((address) => address.toLowerCase()), 100: [ "0x0b928165a67df8254412483ae8c3b8cc7f2b4d36", "0x1d48a279966f37385b4ab963530c6dc813b3a8df", @@ -44,13 +44,14 @@ const arbitrableWhitelist = { "0x76944a2678a0954a610096ee78e8ceb8d46d5922", "0x86e72802d9abbf7505a889721fd4d6947b02320e", "0x957a53a994860be4750810131d9c876b2f52d6e1", + "0x9FE4D9E4989ad031FDc424d8C34D77E70aA0b269", "0xa2bfff0553de7405781fe0c39c04a383f04b9c80", "0xa78ec5742a5d360f92f6d6d7e775fb35ab559a51", "0xaeecfa44639b61d2e0a9534d918789d94a24a9de", "0xd5994f15be9987104d9821aa99d1c97227c7c08c", "0xe04f5791d671d5c4e08ab49b39807087b591ea3e", "0xf7de5537ecd69a94695fcf4bcdbdee6329b63322", - ], + ].map((address) => address.toLowerCase()), }; export default arbitrableWhitelist;