diff --git a/apps/contract-verification/src/app/Verifiers/AbstractVerifier.ts b/apps/contract-verification/src/app/Verifiers/AbstractVerifier.ts index c575cb755b..0bfc84d786 100644 --- a/apps/contract-verification/src/app/Verifiers/AbstractVerifier.ts +++ b/apps/contract-verification/src/app/Verifiers/AbstractVerifier.ts @@ -1,5 +1,5 @@ import { CompilerAbstract } from '@remix-project/remix-solidity' -import { SubmittedContract, VerifierIdentifier } from '../types/VerificationTypes' +import { SubmittedContract, VerificationResponse } from '../types/VerificationTypes' export abstract class AbstractVerifier { apiUrl: string @@ -10,6 +10,6 @@ export abstract class AbstractVerifier { this.enabled = true } - abstract verify(submittedContract: SubmittedContract, compilerAbstract: CompilerAbstract): Promise + abstract verify(submittedContract: SubmittedContract, compilerAbstract: CompilerAbstract): Promise abstract lookup(): Promise } diff --git a/apps/contract-verification/src/app/Verifiers/SourcifyVerifier.ts b/apps/contract-verification/src/app/Verifiers/SourcifyVerifier.ts index 75e6c15e41..e3ef968d0d 100644 --- a/apps/contract-verification/src/app/Verifiers/SourcifyVerifier.ts +++ b/apps/contract-verification/src/app/Verifiers/SourcifyVerifier.ts @@ -1,10 +1,37 @@ import { CompilerAbstract, SourcesCode } from '@remix-project/remix-solidity' import { AbstractVerifier } from './AbstractVerifier' -import { SourcifyReceipt } from '../Receipts/SourcifyReceipt' -import { SourcifyVerificationError, SourcifyVerificationResponse, SubmittedContract } from '../types/VerificationTypes' +import { SubmittedContract, VerificationResponse } from '../types/VerificationTypes' + +interface SourcifyVerifyRequest { + address: string + chain: string + files: Record + creatorTxHash?: string + chosenContract?: string +} + +type SourcifyVerificationStatus = 'perfect' | 'partial' | null + +interface SourcifyVerificationResponse { + result: [ + { + address: string + chainId: string + status: SourcifyVerificationStatus + libraryMap: { + [key: string]: string + } + message?: string + } + ] +} + +interface SourcifyVerificationError { + error: 'string' +} export class SourcifyVerifier extends AbstractVerifier { - async verify(submittedContract: SubmittedContract, compilerAbstract: CompilerAbstract) { + async verify(submittedContract: SubmittedContract, compilerAbstract: CompilerAbstract): Promise { const metadataStr = compilerAbstract.data.contracts[submittedContract.filePath][submittedContract.contractName].metadata const sources = compilerAbstract.source.sources console.log('selectedFilePath:', submittedContract.filePath) @@ -20,8 +47,8 @@ export class SourcifyVerifier extends AbstractVerifier { acc[fileName] = content return acc }, {}) - const body = { - chainId: submittedContract.chainId, + const body: SourcifyVerifyRequest = { + chain: submittedContract.chainId, address: submittedContract.address, files: { 'metadata.json': metadataStr, @@ -41,12 +68,26 @@ export class SourcifyVerifier extends AbstractVerifier { if (!response.ok) { const errorResponse: SourcifyVerificationError = await response.json() - console.error('Error on Sourcify verification at', this.apiUrl, 'Status:', response.status, 'Response:', JSON.stringify(errorResponse)) + console.error('Error on Sourcify verification at ' + this.apiUrl + '\nStatus: ' + response.status + '\nResponse: ' + JSON.stringify(errorResponse)) throw new Error(errorResponse.error) } - const jsonResponse: SourcifyVerificationResponse = await response.json() - return jsonResponse + const verificationResponse: SourcifyVerificationResponse = await response.json() + + if (verificationResponse.result[0].status === null) { + console.error('Error on Sourcify verification at ' + this.apiUrl + '\nStatus: ' + response.status + '\nResponse: ' + verificationResponse.result[0].message) + throw new Error(verificationResponse.result[0].message) + } + + // Map to a user-facing status message + let status = 'unknown' + if (verificationResponse.result[0].status === 'perfect') { + status = 'fully verified' + } else if (verificationResponse.result[0].status === 'partial') { + status = 'partially verified' + } + + return { status, receiptId: null } } async lookup(): Promise { diff --git a/apps/contract-verification/src/app/components/AccordionReceipt.tsx b/apps/contract-verification/src/app/components/AccordionReceipt.tsx index 827f357c4a..9b29c00a4b 100644 --- a/apps/contract-verification/src/app/components/AccordionReceipt.tsx +++ b/apps/contract-verification/src/app/components/AccordionReceipt.tsx @@ -95,6 +95,7 @@ const ReceiptsBody = ({ contract }: { contract: SubmittedContract }) => { Status Message ReceiptID + {/*TODO add link*/} diff --git a/apps/contract-verification/src/app/types/VerificationTypes.ts b/apps/contract-verification/src/app/types/VerificationTypes.ts index d5e28c3a69..b14942a354 100644 --- a/apps/contract-verification/src/app/types/VerificationTypes.ts +++ b/apps/contract-verification/src/app/types/VerificationTypes.ts @@ -32,7 +32,7 @@ export interface VerifierInfo { export interface VerificationReceipt { receiptId?: string verifierInfo: VerifierInfo - status: SourcifyVerificationStatus | 'error' | null + status: string | 'error' | 'pending' | null message?: string } @@ -67,23 +67,9 @@ export function isContract(contract: SubmittedContract | SubmittedProxyContract) return contract.type === 'contract' } -export type SourcifyVerificationStatus = 'perfect' | 'partial' | null - -export interface SourcifyVerificationResponse { - result: [ - { - address: string - chainId: string - status: SourcifyVerificationStatus - libraryMap: { - [key: string]: string - } - } - ] -} - -export interface SourcifyVerificationError { - error: 'string' +export interface VerificationResponse { + status: string | 'pending' + receiptId: string | null } export interface EtherscanRequest { diff --git a/apps/contract-verification/src/app/views/VerifyView.tsx b/apps/contract-verification/src/app/views/VerifyView.tsx index a635d05ef3..864e538aca 100644 --- a/apps/contract-verification/src/app/views/VerifyView.tsx +++ b/apps/contract-verification/src/app/views/VerifyView.tsx @@ -66,7 +66,10 @@ export const VerifyView = () => { if (verifier instanceof SourcifyVerifier) { try { const response = await verifier.verify(newSubmittedContract, compilerAbstract) - receipt.status = response.result[0].status + receipt.status = response.status + if (response.receiptId) { + receipt.receiptId = response.receiptId + } } catch (e) { const err = e as Error receipt.status = 'error' @@ -74,6 +77,7 @@ export const VerifyView = () => { } } else if (verifier instanceof EtherscanVerifier) { try { + // TODO generalize parameters to pass constructorargs optionally on the AbstractVerifier const response = await verifier.verify(newSubmittedContract, compilerAbstract, abiEncodedConstructorArgs) receipt.status = 'perfect' } catch (e) {