diff --git a/src/application-mapping.ts b/src/application-mapping.ts index 6628ebc..13f0ab7 100644 --- a/src/application-mapping.ts +++ b/src/application-mapping.ts @@ -7,7 +7,7 @@ import { contractApplicationStateToString, contractMilestoneStateToString, isPla import { addApplicationUpdateNotification, addMilestoneUpdateNotification } from './utils/notifications' import { ApplicationMilestoneUpdate, GrantApplicationRequest, GrantApplicationUpdate, GrantProposedClaim, validateApplicationMilestoneUpdate, validateGrantApplicationRequest, validateGrantApplicationUpdate } from './json-schema' -export function handleApplicationSubmitted(event: ApplicationSubmitted): void { +export async function handleApplicationSubmitted(event: ApplicationSubmitted): void { const applicationId = event.params.applicationId.toHex() const milestoneCount = event.params.milestoneCount.toI32() const grantId = event.params.grant.toHex() @@ -24,7 +24,7 @@ export function handleApplicationSubmitted(event: ApplicationSubmitted): void { return } - const jsonResult = validatedJsonFromIpfs(event.params.metadataHash, validateGrantApplicationRequest) + const jsonResult = await validatedJsonFromIpfs(event.params.metadataHash, validateGrantApplicationRequest) if(jsonResult.error) { log.warning(`[${event.transaction.hash.toHex()}] error in mapping application: "${jsonResult.error!}"`, []) return @@ -74,7 +74,7 @@ export function handleApplicationSubmitted(event: ApplicationSubmitted): void { addApplicationUpdateNotification(entity, event.transaction.hash.toHex(), event.params.owner) } -export function handleApplicationUpdated(event: ApplicationUpdated): void { +export async function handleApplicationUpdated(event: ApplicationUpdated): void { const applicationId = event.params.applicationId.toHex() const metaHash = event.params.metadataHash const milestoneCount = event.params.milestoneCount.toI32() @@ -116,7 +116,7 @@ export function handleApplicationUpdated(event: ApplicationUpdated): void { entity.state = strStateResult.value! // some valid IPFS hash if(isPlausibleIPFSHash(metaHash)) { - const jsonResult = validatedJsonFromIpfs(event.params.metadataHash, validateGrantApplicationUpdate) + const jsonResult = await validatedJsonFromIpfs(event.params.metadataHash, validateGrantApplicationUpdate) if(jsonResult.error) { log.warning(`[${event.transaction.hash.toHex()}] error in mapping application update: "${jsonResult.error!}"`, []) return @@ -203,7 +203,7 @@ export function handleApplicationUpdated(event: ApplicationUpdated): void { addApplicationUpdateNotification(entity, event.transaction.hash.toHex(), event.transaction.from) } -export function handleMilestoneUpdated(event: MilestoneUpdated): void { +export async function handleMilestoneUpdated(event: MilestoneUpdated): void { const applicationId = event.params._id.toHex() const milestoneId = `${applicationId}.${event.params._milestoneId.toI32()}` @@ -223,7 +223,7 @@ export function handleMilestoneUpdated(event: MilestoneUpdated): void { entity.state = strStateResult.value! if(isPlausibleIPFSHash(event.params._metadataHash)) { - const jsonResult = validatedJsonFromIpfs(event.params._metadataHash, validateApplicationMilestoneUpdate) + const jsonResult = await validatedJsonFromIpfs(event.params._metadataHash, validateApplicationMilestoneUpdate) if(jsonResult.error) { log.warning(`[${event.transaction.hash.toHex()}] failed to update milestone from IPFS, ID="${milestoneId}" error=${jsonResult.error!}`, []) return diff --git a/src/communication-mapping.ts b/src/communication-mapping.ts index de9e6f3..5bbde41 100644 --- a/src/communication-mapping.ts +++ b/src/communication-mapping.ts @@ -5,7 +5,7 @@ import { validatedJsonFromIpfs } from './json-schema/json' import { addCommentAddedNotification } from './utils/notifications' import { PrivateCommentAddRequest, validatePrivateCommentAddRequest } from './json-schema' -export function handleCommentAdded(event: CommentAdded): void { +export async function handleCommentAdded(event: CommentAdded): void { const workspaceId = event.params.workspaceId.toHex() const grantAddress = event.params.grantAddress.toHex() const applicationId = event.params.applicationId.toHex() @@ -30,7 +30,7 @@ export function handleCommentAdded(event: CommentAdded): void { commentEntity.createdAt = timestamp if(isPrivate) { - const result = validatedJsonFromIpfs(commentMetadataHash, validatePrivateCommentAddRequest) + const result = await validatedJsonFromIpfs(commentMetadataHash, validatePrivateCommentAddRequest) if(result) { if(result.value == null) { diff --git a/src/grant-mapping.ts b/src/grant-mapping.ts index 1a436f7..d3b9a24 100644 --- a/src/grant-mapping.ts +++ b/src/grant-mapping.ts @@ -11,7 +11,7 @@ import { disburseReward } from './utils/handle-disburse-reward' import { addFundsTransferNotification } from './utils/notifications' import { GrantCreateRequest, validateGrantCreateRequest } from './json-schema' -export function handleGrantCreated(event: GrantCreated): void { +export async function handleGrantCreated(event: GrantCreated): void { const workspaceId = event.params.workspaceId.toHex() const grantAddress = event.params.grantAddress const time = event.params.time.toI32() @@ -22,7 +22,7 @@ export function handleGrantCreated(event: GrantCreated): void { return } - const entityResult = validatedJsonFromIpfs(event.params.metadataHash, validateGrantCreateRequest) + const entityResult = await validatedJsonFromIpfs(event.params.metadataHash, validateGrantCreateRequest) if(entityResult.error) { log.warning(`[${event.transaction.hash.toHex()}] error in mapping grant with metadata hash "${entityResult.error!}"`, []) return diff --git a/src/json-schema/json.ts b/src/json-schema/json.ts index a8e1995..73d75d3 100644 --- a/src/json-schema/json.ts +++ b/src/json-schema/json.ts @@ -1,10 +1,7 @@ import { BigDecimal, BigInt, Bytes, ipfs, json, JSONValue, JSONValueKind, log, TypedMap } from '@graphprotocol/graph-ts' -// import { config } from 'dotenv'; +import axios from 'axios'; -// config({ path: '.env.production' }) - -// const infuraIpfsProjectId = process.env.INFURA_IPFS_PROJECT_ID || '' -// const infuraIpfsApiKey = process.env.INFURA_IPFS_API_KEY || '' +const IPFS_DOWNLOAD_ENDPOINT = 'https://api.thegraph.com/ipfs/api/v0/cat' /** Generic result structure to catch successful & errorred results */ export class Result { @@ -230,7 +227,7 @@ export function validateBytesFromStringResult(r: Result): Result } /// Fetch a JSON file from IPFS & validate it using a given function -export function validatedJsonFromIpfs(hash: string, mapFunction: (json: JSONValue) => Result): Result { +export async function validatedJsonFromIpfs (hash: string, mapFunction: (json: JSONValue) => Result): Result { let data: Bytes | null // this mechanism exists to prevent IPFS calls while testing // since IPFS is not supported on matchstick as of now @@ -238,7 +235,17 @@ export function validatedJsonFromIpfs(hash: string, mapFunction: (json: JSONV data = Bytes.fromUTF8(hash.slice(5)) } else { log.info('Fetching IPFS hash...', [hash]) - data = ipfs.cat(hash) + + const result = await getFromIPFS(hash) as string + + log.info('Fetched results (new way)', [result]) + + // if(result){ + data = Bytes.fromUTF8(result) + // } + // else { + // data = ipfs.cat(hash) + // } log.info('Fetched IPFS hash', [hash]) } @@ -257,4 +264,37 @@ export function validatedJsonFromIpfs(hash: string, mapFunction: (json: JSONV } return mapFunction(jsonDataResult.value) +} + +export const getFromIPFS = async (hash: string) => { + if(hash === '') { + return '' + } + let data + try { + const result = await axios.get(`${IPFS_DOWNLOAD_ENDPOINT}?arg=${hash}`, { + timeout: 10000 + }) + + data = result.data + + return data + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } catch(e: any) { + // console.log(e) + } + // fallback + try { + const result = await axios.get(`https://ipfs.io/ipfs/${hash}`, { + timeout: 10000 + }) + data = result.data + + return data + + } catch(e: any) { + + } + return '' } \ No newline at end of file diff --git a/src/review-mapping.ts b/src/review-mapping.ts index b9107d0..0655128 100644 --- a/src/review-mapping.ts +++ b/src/review-mapping.ts @@ -7,7 +7,7 @@ import { reviewSubmittedNotification } from './utils/notifications' import { rubricSetHandler } from './utils/rubricSetHandler' import { ReviewSetRequest, validateReviewSetRequest } from './json-schema' -export function handleReviewSubmitted(event: ReviewSubmitted): void { +export async function handleReviewSubmitted(event: ReviewSubmitted): void { const reviewId = event.params._reviewId.toHex() const workspace = event.params._workspaceId.toHex() const reviewerAddress = event.params._reviewerAddress @@ -16,7 +16,7 @@ export function handleReviewSubmitted(event: ReviewSubmitted): void { const memberId = `${workspace}.${reviewer}` - const jsonResult = validatedJsonFromIpfs(event.params._metadataHash, validateReviewSetRequest) + const jsonResult = await validatedJsonFromIpfs(event.params._metadataHash, validateReviewSetRequest) if(jsonResult.error) { log.warning(`[${event.transaction.hash.toHex()}] error in mapping review: "${jsonResult.error!}"`, []) return diff --git a/src/utils/generics.ts b/src/utils/generics.ts index 3f01b67..ad890b8 100644 --- a/src/utils/generics.ts +++ b/src/utils/generics.ts @@ -316,7 +316,7 @@ export function getUSDReward(asset: Bytes, value: BigInt): i32 { return result.toI32() } -export function mapWorkspaceMembersUpdate( +export async function mapWorkspaceMembersUpdate( workspaceId: string, time: BigInt, members: Address[], @@ -360,7 +360,7 @@ export function mapWorkspaceMembersUpdate( } if(metadataHash) { - const updateResult = validatedJsonFromIpfs(metadataHash[i], validateWorkspaceMemberUpdate) + const updateResult = await validatedJsonFromIpfs(metadataHash[i], validateWorkspaceMemberUpdate) if(updateResult.error) { return { error: updateResult.error, value: null } } diff --git a/src/utils/grantUpdateHandler.ts b/src/utils/grantUpdateHandler.ts index 0d80782..e9e5ba4 100644 --- a/src/utils/grantUpdateHandler.ts +++ b/src/utils/grantUpdateHandler.ts @@ -13,7 +13,7 @@ class GrantUpdateParams { hash: string } -export function grantUpdateHandler(params: GrantUpdateParams): void { +export async function grantUpdateHandler(params: GrantUpdateParams): void { const grantId = params.grantId const entity = Grant.load(grantId) if(!entity) { @@ -27,7 +27,7 @@ export function grantUpdateHandler(params: GrantUpdateParams): void { entity.acceptingApplications = params.acceptingApplications if(isPlausibleIPFSHash(params.hash)) { - const jsonResult = validatedJsonFromIpfs(params.hash, validateGrantUpdateRequest) + const jsonResult = await validatedJsonFromIpfs(params.hash, validateGrantUpdateRequest) if(jsonResult.error) { log.warning(`[${params.transactionHash}] error in updating grant metadata, error: ${jsonResult.error!}`, []) return diff --git a/src/utils/rubricSetHandler.ts b/src/utils/rubricSetHandler.ts index fd251cf..7646ebb 100644 --- a/src/utils/rubricSetHandler.ts +++ b/src/utils/rubricSetHandler.ts @@ -3,7 +3,7 @@ import { Grant, Rubric, RubricItem } from '../../generated/schema' import { RubricSetRequest, validateRubricSetRequest } from '../json-schema' import { validatedJsonFromIpfs } from '../json-schema/json' -export function rubricSetHandler( +export async function rubricSetHandler( event: ethereum.Event, _grantId: string, _workspaceId: string, @@ -14,7 +14,7 @@ export function rubricSetHandler( const grantId = _grantId const workspaceId = _workspaceId - const jsonResult = validatedJsonFromIpfs(_metadataHash, validateRubricSetRequest) + const jsonResult = await validatedJsonFromIpfs(_metadataHash, validateRubricSetRequest) if(jsonResult.error) { log.warning(`[${event.transaction.hash.toHex()}] error in mapping application: "${jsonResult.error!}"`, []) return diff --git a/src/workspace-mapping.ts b/src/workspace-mapping.ts index c137390..52bc7bf 100644 --- a/src/workspace-mapping.ts +++ b/src/workspace-mapping.ts @@ -35,10 +35,10 @@ import { WorkspaceUpdateRequest } from './json-schema' -export function handleWorkspaceCreated(event: WorkspaceCreated): void { +export async function handleWorkspaceCreated(event: WorkspaceCreated): void { const entityId = event.params.id.toHex() - const jsonResult = validatedJsonFromIpfs(event.params.metadataHash, validateWorkspaceCreateRequest) + const jsonResult = await validatedJsonFromIpfs(event.params.metadataHash, validateWorkspaceCreateRequest) if(jsonResult.error) { log.warning(`[${event.transaction.hash.toHex()}] error in mapping workspace create: "${jsonResult.error!}"`, []) return @@ -88,7 +88,7 @@ export function handleWorkspaceCreated(event: WorkspaceCreated): void { entity.save() } -export function handleWorkspaceUpdated(event: WorkspaceUpdated): void { +export async function handleWorkspaceUpdated(event: WorkspaceUpdated): void { const entityId = event.params.id.toHex() const entity = Workspace.load(entityId) @@ -99,7 +99,7 @@ export function handleWorkspaceUpdated(event: WorkspaceUpdated): void { entity.updatedAtS = event.params.time.toI32() - const jsonResult = validatedJsonFromIpfs(event.params.metadataHash, validateWorkspaceUpdateRequest) + const jsonResult = await validatedJsonFromIpfs(event.params.metadataHash, validateWorkspaceUpdateRequest) if(jsonResult.error) { log.warning(`[${event.transaction.hash.toHex()}] error in mapping workspace update: "${jsonResult.error!}"`, []) return