Add lookup function to SourcifyVerifier

pull/5285/head
Manuel Wedler 4 months ago committed by Aniket
parent 8cf9ee652f
commit b7283789af
  1. 4
      apps/contract-verification/src/app/Receipts/SourcifyReceipt.tsx
  2. 4
      apps/contract-verification/src/app/Verifiers/AbstractVerifier.ts
  3. 2
      apps/contract-verification/src/app/Verifiers/EtherscanVerifier.ts
  4. 47
      apps/contract-verification/src/app/Verifiers/SourcifyVerifier.ts
  5. 11
      apps/contract-verification/src/app/types/VerificationTypes.ts
  6. 2
      apps/contract-verification/src/app/views/VerifyView.tsx

@ -1,11 +1,11 @@
import React, { useState, useEffect } from 'react' import React, { useState, useEffect } from 'react'
import { SourcifyVerifier } from '../Verifiers/SourcifyVerifier' import { SourcifyVerifier } from '../Verifiers/SourcifyVerifier'
import { SourcifyVerificationStatus } from '../types/VerificationTypes' // import { SourcifyVerificationStatus } from '../types/VerificationTypes'
import { ReceiptProps } from './props' import { ReceiptProps } from './props'
// A receipt is something to be rendered // A receipt is something to be rendered
export const SourcifyReceipt: React.FC<ReceiptProps> = ({ verifyPromise, address, chainId, verifier }) => { export const SourcifyReceipt: React.FC<ReceiptProps> = ({ verifyPromise, address, chainId, verifier }) => {
const [status, setStatus] = useState<SourcifyVerificationStatus | null>(null) const [status, setStatus] = useState< null>(null)
const [submissionDate] = useState(new Date()) // This will be set once and not change const [submissionDate] = useState(new Date()) // This will be set once and not change
useEffect(() => { useEffect(() => {

@ -1,5 +1,5 @@
import { CompilerAbstract } from '@remix-project/remix-solidity' import { CompilerAbstract } from '@remix-project/remix-solidity'
import { SubmittedContract, VerificationResponse, VerificationStatus } from '../types/VerificationTypes' import { LookupResponse, SubmittedContract, VerificationResponse, VerificationStatus } from '../types/VerificationTypes'
export interface AbstractVerifier { export interface AbstractVerifier {
checkVerificationStatus?(receiptId: string): Promise<VerificationStatus> checkVerificationStatus?(receiptId: string): Promise<VerificationStatus>
@ -16,5 +16,5 @@ export abstract class AbstractVerifier {
} }
abstract verify(submittedContract: SubmittedContract, compilerAbstract: CompilerAbstract): Promise<VerificationResponse> abstract verify(submittedContract: SubmittedContract, compilerAbstract: CompilerAbstract): Promise<VerificationResponse>
abstract lookup(): Promise<any> abstract lookup(contractAddress: string, chainId: string): Promise<LookupResponse>
} }

@ -111,7 +111,7 @@ export class EtherscanVerifier extends AbstractVerifier {
throw new Error(checkStatusResponse.result) throw new Error(checkStatusResponse.result)
} }
let status = 'unknown' let status: VerificationStatus = 'unknown'
if (checkStatusResponse.result === 'Fail - Unable to verify') { if (checkStatusResponse.result === 'Fail - Unable to verify') {
status = 'failed' status = 'failed'
} }

@ -1,6 +1,6 @@
import { CompilerAbstract, SourcesCode } from '@remix-project/remix-solidity' import { CompilerAbstract, SourcesCode } from '@remix-project/remix-solidity'
import { AbstractVerifier } from './AbstractVerifier' import { AbstractVerifier } from './AbstractVerifier'
import { SubmittedContract, VerificationResponse } from '../types/VerificationTypes' import { LookupResponse, SubmittedContract, VerificationResponse, VerificationStatus } from '../types/VerificationTypes'
interface SourcifyVerificationRequest { interface SourcifyVerificationRequest {
address: string address: string
@ -26,10 +26,17 @@ interface SourcifyVerificationResponse {
] ]
} }
interface SourcifyVerificationError { interface SourcifyErrorResponse {
error: 'string' error: 'string'
} }
interface SourcifyLookupResponse {
address: string
// Includes either chainIds or status key
chainIds?: Array<{ chainId: string; status: Exclude<SourcifyVerificationStatus, null> }>
status?: 'false'
}
export class SourcifyVerifier extends AbstractVerifier { export class SourcifyVerifier extends AbstractVerifier {
async verify(submittedContract: SubmittedContract, compilerAbstract: CompilerAbstract): Promise<VerificationResponse> { async verify(submittedContract: SubmittedContract, compilerAbstract: CompilerAbstract): Promise<VerificationResponse> {
const metadataStr = compilerAbstract.data.contracts[submittedContract.filePath][submittedContract.contractName].metadata const metadataStr = compilerAbstract.data.contracts[submittedContract.filePath][submittedContract.contractName].metadata
@ -67,7 +74,7 @@ export class SourcifyVerifier extends AbstractVerifier {
}) })
if (!response.ok) { if (!response.ok) {
const errorResponse: SourcifyVerificationError = await response.json() const errorResponse: SourcifyErrorResponse = await response.json()
console.error('Error on Sourcify verification at ' + this.apiUrl + '\nStatus: ' + response.status + '\nResponse: ' + JSON.stringify(errorResponse)) console.error('Error on Sourcify verification at ' + this.apiUrl + '\nStatus: ' + response.status + '\nResponse: ' + JSON.stringify(errorResponse))
throw new Error(errorResponse.error) throw new Error(errorResponse.error)
} }
@ -80,7 +87,7 @@ export class SourcifyVerifier extends AbstractVerifier {
} }
// Map to a user-facing status message // Map to a user-facing status message
let status = 'unknown' let status: VerificationStatus = 'unknown'
if (verificationResponse.result[0].status === 'perfect') { if (verificationResponse.result[0].status === 'perfect') {
status = 'fully verified' status = 'fully verified'
} else if (verificationResponse.result[0].status === 'partial') { } else if (verificationResponse.result[0].status === 'partial') {
@ -90,12 +97,30 @@ export class SourcifyVerifier extends AbstractVerifier {
return { status, receiptId: null } return { status, receiptId: null }
} }
async lookup(): Promise<any> { async lookup(contractAddress: string, chainId: string): Promise<LookupResponse> {
// Implement the lookup logic here const url = new URL('check-all-by-addresses', this.apiUrl)
console.log('Sourcify lookup started') url.searchParams.append('addresses', contractAddress)
// Placeholder logic for lookup url.searchParams.append('chainIds', chainId)
const lookupResult = {} // Replace with actual lookup logic
console.log('Sourcify lookup completed') const response = await fetch(url.href, { method: 'GET' })
return lookupResult
if (!response.ok) {
const errorResponse: SourcifyErrorResponse = await response.json()
console.error('Error on Sourcify lookup at ' + this.apiUrl + '\nStatus: ' + response.status + '\nResponse: ' + JSON.stringify(errorResponse))
throw new Error(errorResponse.error)
}
const lookupResponse: SourcifyLookupResponse = (await response.json())[0]
let status: VerificationStatus = 'unknown'
if (lookupResponse.status === 'false') {
status = 'not verified'
} else if (lookupResponse.chainIds?.[0].status === 'perfect') {
status = 'fully verified'
} else if (lookupResponse.chainIds?.[0].status === 'partial') {
status = 'partially verified'
}
return { status }
} }
} }

@ -17,7 +17,7 @@ export interface Chain {
infoURL?: string infoURL?: string
} }
export type VerifierIdentifier = "Sourcify" | "Etherscan" | "Blockscout" export type VerifierIdentifier = 'Sourcify' | 'Etherscan' | 'Blockscout'
export interface VerifierSettings { export interface VerifierSettings {
apiUrl: string apiUrl: string
@ -68,9 +68,16 @@ export function isContract(contract: SubmittedContract | SubmittedProxyContract)
return contract.type === 'contract' return contract.type === 'contract'
} }
export type VerificationStatus = string | 'error' | 'pending' type SourcifyStatus = 'fully verified' | 'partially verified'
type EtherscanStatus = 'verified'
export type VerificationStatus = SourcifyStatus | EtherscanStatus | 'failed' | 'pending' | 'not verified' | 'unknown'
export interface VerificationResponse { export interface VerificationResponse {
status: VerificationStatus status: VerificationStatus
receiptId: string | null receiptId: string | null
} }
export interface LookupResponse {
status: VerificationStatus
lookupUrl?: string // TODO How to construct these? Do we need another config value?
}

@ -75,7 +75,7 @@ export const VerifyView = () => {
} }
} catch (e) { } catch (e) {
const err = e as Error const err = e as Error
receipt.status = 'error' receipt.status = 'failed'
receipt.message = err.message receipt.message = err.message
} }

Loading…
Cancel
Save