Skip to content

Commit

Permalink
Merge pull request #538 from clrfund/feature/simple-registry-changes
Browse files Browse the repository at this point in the history
Allow recipient registry owner to add recipients for simple recipient registry type
  • Loading branch information
auryn-macmillan authored Aug 8, 2022
2 parents ba0dd13 + ee70287 commit f80f857
Show file tree
Hide file tree
Showing 31 changed files with 314 additions and 197 deletions.
15 changes: 10 additions & 5 deletions contracts/scripts/deployRecipientRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,13 @@ import { RecipientRegistryFactory } from '../utils/recipient-registry-factory'
async function main() {
const recipientRegistryType = process.env.RECIPIENT_REGISTRY_TYPE || 'simple'
const fundingRoundFactoryAddress = process.env.FUNDING_ROUND_FACTORY_ADDRESS
const challengePeriodDuration = process.env.CHALLENGE_PERIOD_IN_SECONDS || 300
const baseDeposit = process.env.BASE_DEPOSIT || UNIT.div(10).toString()
let challengePeriodDuration = '0'
let baseDeposit = '0'

if (recipientRegistryType === 'optimistic') {
challengePeriodDuration = process.env.CHALLENGE_PERIOD_IN_SECONDS || '300'
baseDeposit = process.env.BASE_DEPOSIT || UNIT.div(10).toString()
}

if (!fundingRoundFactoryAddress) {
console.log('Environment variable FUNDING_ROUND_FACTORY_ADDRESS not set')
Expand All @@ -35,9 +40,9 @@ async function main() {
console.log('*******************')
console.log(`Deploying a new ${recipientRegistryType} recipient registry!`)
console.log(` challenge period in seconds: ${challengePeriodDuration}`)
console.log(` baseDeposit ${baseDeposit}`)
console.log(` fundingRoundFactoryAddress ${fundingRoundFactoryAddress}`)
console.log(` fundingRoundFactoryOwner ${factoryOwner}`)
console.log(` baseDeposit: ${baseDeposit}`)
console.log(` fundingRoundFactoryAddress: ${fundingRoundFactoryAddress}`)
console.log(` fundingRoundFactoryOwner: ${factoryOwner}`)
const [deployer] = await ethers.getSigners()

const recipientRegistry = await RecipientRegistryFactory.deploy(
Expand Down
24 changes: 12 additions & 12 deletions subgraph/src/MACIMapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ import { FundingRound, Message, PublicKey } from '../generated/schema'
// - contract.verifier(...)

export function handlePublishMessage(event: PublishMessage): void {
const fundingRoundId = event.transaction.to.toHexString()
let fundingRoundId = event.transaction.to.toHexString()
if (fundingRoundId == null) {
log.error(
'Error: handlePublishMessage failed fundingRound not registered',
[]
)
return
}
const fundingRound = FundingRound.load(fundingRoundId)
let fundingRound = FundingRound.load(fundingRoundId)
if (fundingRound == null) {
log.error(
'Error: handlePublishMessage failed fundingRound not registered',
Expand All @@ -37,23 +37,23 @@ export function handlePublishMessage(event: PublishMessage): void {
return
}

const messageID = event.transaction.hash.toHexString()
let messageID = event.transaction.hash.toHexString()

const timestamp = event.block.timestamp.toString()
const message = new Message(messageID)
let timestamp = event.block.timestamp.toString()
let message = new Message(messageID)
message.data = event.params._message.data
message.iv = event.params._message.iv

const publicKeyId = event.transaction.from.toHexString()
const publicKey = PublicKey.load(publicKeyId)
let publicKeyId = event.transaction.from.toHexString()
let publicKey = PublicKey.load(publicKeyId)

//NOTE: If the public keys aren't being tracked initialize them
if (publicKey == null) {
const publicKey = new PublicKey(publicKeyId)
let publicKey = new PublicKey(publicKeyId)
publicKey.x = event.params._encPubKey.x
publicKey.y = event.params._encPubKey.y

const _messages = [messageID] as string[]
let _messages = [messageID] as string[]
publicKey.messages = _messages
publicKey.fundingRound = fundingRoundId

Expand All @@ -68,12 +68,12 @@ export function handlePublishMessage(event: PublishMessage): void {
}

export function handleSignUp(event: SignUp): void {
const publicKeyId = event.transaction.from.toHexString()
const publicKey = PublicKey.load(publicKeyId)
let publicKeyId = event.transaction.from.toHexString()
let publicKey = PublicKey.load(publicKeyId)

//NOTE: If the public keys aren't being tracked initialize them
if (publicKey == null) {
const publicKey = new PublicKey(publicKeyId)
let publicKey = new PublicKey(publicKeyId)
publicKey.x = event.params._userPubKey.x
publicKey.y = event.params._userPubKey.y
publicKey.stateIndex = event.params._stateIndex
Expand Down
6 changes: 4 additions & 2 deletions subgraph/src/RecipientMapping.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Recipient } from '../generated/schema'

export const RECIPIENT_REQUEST_TYPE_REGISTRATION = '0'
export const RECIPIENT_REQUEST_TYPE_REMOVAL = '1'

export function removeRecipient(id: string, timestamp: string): void {
let recipient = Recipient.load(id)
if (recipient) {
// TODO: should we hard delete the recipient record?
recipient.rejected = true
recipient.requestType = RECIPIENT_REQUEST_TYPE_REMOVAL
recipient.lastUpdatedAt = timestamp
recipient.save()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@ import {
} from '../../generated/templates/KlerosRecipientRegistry/KlerosRecipientRegistry'

import { Recipient } from '../../generated/schema'
import { removeRecipient } from '../RecipientMapping'
import {
removeRecipient,
RECIPIENT_REQUEST_TYPE_REGISTRATION,
} from '../RecipientMapping'

export function handleRecipientAdded(event: RecipientAdded): void {
let recipientRegistryId = event.address.toHexString()

let recipientId = event.params._tcrItemId.toHexString()
let recipient = new Recipient(recipientId)
recipient.requestType = RECIPIENT_REQUEST_TYPE_REGISTRATION
// recipient was verified by kleros
recipient.verified = true
recipient.recipientRegistry = recipientRegistryId
recipient.createdAt = event.block.timestamp.toString()
recipient.recipientIndex = event.params._index
Expand Down
2 changes: 1 addition & 1 deletion subgraph/src/recipientRegistry/RecipientRegistryType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export enum RecipientRegistryType {

let registryTypeMap = new TypedMap<string, RecipientRegistryType>()
registryTypeMap.set('simple', RecipientRegistryType.Simple)
registryTypeMap.set('klerso', RecipientRegistryType.Kleros)
registryTypeMap.set('kleros', RecipientRegistryType.Kleros)
registryTypeMap.set('optimistic', RecipientRegistryType.Optimistic)

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import {
} from '../../generated/templates/SimpleRecipientRegistry/SimpleRecipientRegistry'

import { Recipient } from '../../generated/schema'
import { removeRecipient } from '../RecipientMapping'
import {
removeRecipient,
RECIPIENT_REQUEST_TYPE_REGISTRATION,
} from '../RecipientMapping'

export function handleRecipientAdded(event: RecipientAdded): void {
let recipientRegistryId = event.address.toHexString()
Expand All @@ -13,12 +16,15 @@ export function handleRecipientAdded(event: RecipientAdded): void {
let recipient = new Recipient(recipientId)

recipient.requester = event.transaction.from.toHexString()
recipient.requestType = RECIPIENT_REQUEST_TYPE_REGISTRATION
recipient.recipientRegistry = recipientRegistryId
recipient.recipientMetadata = event.params._metadata
recipient.recipientIndex = event.params._index
recipient.recipientAddress = event.params._recipient
recipient.submissionTime = event.params._timestamp.toString()
recipient.requestResolvedHash = event.transaction.hash
// recipients are verified as they are added by the admin
recipient.verified = true
recipient.createdAt = event.block.timestamp.toString()

recipient.save()
Expand Down
8 changes: 4 additions & 4 deletions vue-app/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,16 @@ VUE_APP_GOOGLE_SPREADSHEET_ID=

# metadata registry configurations
# The networks where metadata is stored; as comma separated strings
# i.e. rinkeby,ropsten,mainnet
# i.e. arbitrum-rinkeby,ropsten,mainnet
VUE_APP_METADATA_NETWORKS=

# metadata registry subgraph url prefix
# Add the network part (VUE_APP_METADATA_NETWORKS) to form the complete url
# i.e. https://api.thegraph.com/subgraphs/name/yuetloo/metadata-
METADATA_SUBGRAPH_URL_PREFIX=
# i.e. https://api.thegraph.com/subgraphs/name/clrfund/metadata-
VUE_APP_METADATA_SUBGRAPH_URL_PREFIX=

# subgraph query batch size, default to 30
QUERY_BATCH_SIZE=
VUE_APP_QUERY_BATCH_SIZE=

# Select the sheet's name to write the data, by default 'Raw'
GOOGLE_SHEET_NAME=
3 changes: 2 additions & 1 deletion vue-app/src/api/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ export const METADATA_NETWORKS = process.env.VUE_APP_METADATA_NETWORKS
? process.env.VUE_APP_METADATA_NETWORKS.split(',')
: ['rinkeby']

export const QUERY_BATCH_SIZE = Number(process.env.QUERY_BATCH_SIZE) || 30
export const QUERY_BATCH_SIZE =
Number(process.env.VUE_APP_QUERY_BATCH_SIZE) || 30

export const MAX_RETRIES = Number(process.env.VUE_APP_MAX_RETRIES) || 10

Expand Down
9 changes: 2 additions & 7 deletions vue-app/src/api/projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
recipientRegistryType,
} from './core'

import SimpleRegistry from './recipient-registry-simple'
import KlerosRegistry from './recipient-registry-kleros'
import RecipientRegistry from './recipient-registry'

Expand Down Expand Up @@ -57,9 +56,7 @@ export async function getProjects(
startTime?: number,
endTime?: number
): Promise<Project[]> {
if (recipientRegistryType === 'simple') {
return await SimpleRegistry.getProjects(registryAddress, startTime, endTime)
} else if (recipientRegistryType === 'kleros') {
if (recipientRegistryType === 'kleros') {
return await KlerosRegistry.getProjects(registryAddress, startTime, endTime)
} else {
return await RecipientRegistry.getProjects(
Expand All @@ -74,9 +71,7 @@ export async function getProject(
registryAddress: string,
recipientId: string
): Promise<Project | null> {
if (recipientRegistryType === 'simple') {
return await SimpleRegistry.getProject(registryAddress, recipientId)
} else if (recipientRegistryType === 'kleros') {
if (recipientRegistryType === 'kleros') {
return await KlerosRegistry.getProject(registryAddress, recipientId)
} else {
return await RecipientRegistry.getProject(recipientId)
Expand Down
4 changes: 2 additions & 2 deletions vue-app/src/api/recipient-registry-kleros.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,8 @@ export function create(): RecipientRegistryInterface {
removeProject,
registerProject,
rejectProject,
isRegistrationOpen: true,
requireRegistrationDeposit: true,
isSelfRegistration: false, //TODO: add support for self registration
requireRegistrationDeposit: false,
}
}

Expand Down
2 changes: 1 addition & 1 deletion vue-app/src/api/recipient-registry-optimistic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export function create(): RecipientRegistryInterface {
registerProject,
removeProject,
rejectProject,
isRegistrationOpen: true,
isSelfRegistration: true,
requireRegistrationDeposit: true,
}
}
Expand Down
36 changes: 28 additions & 8 deletions vue-app/src/api/recipient-registry-simple.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { BigNumber, Contract, Event, Signer } from 'ethers'
import { TransactionResponse } from '@ethersproject/abstract-provider'
import { ContractTransaction } from '@ethersproject/contracts'

import { isHexString } from '@ethersproject/bytes'

import { SimpleRecipientRegistry } from './abi'
import { provider, ipfsGatewayUrl } from './core'
import { provider, ipfsGatewayUrl, chain } from './core'
import { RecipientRegistryInterface } from './types'
import { Project, toProjectInterface } from './projects'

Expand Down Expand Up @@ -122,18 +123,37 @@ export function addRecipient(
recipientData: any,
_deposit: BigNumber,
signer: Signer
): Promise<TransactionResponse> {
): Promise<ContractTransaction> {
const registry = new Contract(
registryAddress,
SimpleRecipientRegistry,
signer
)
const { address, ...metadata } = recipientData
return registry.addRecipient(address, JSON.stringify(metadata))
const { id, fund } = recipientData
if (!id) {
throw new Error('Missing metadata id')
}

const { currentChainReceivingAddress: address } = fund
if (!address) {
throw new Error(`Missing recipient address for the ${chain.name} network`)
}

const json = { id }
return registry.addRecipient(address, JSON.stringify(json))
}

function removeProject() {
throw new Error('removeProject not implemented')
function removeProject(
registryAddress: string,
recipientId: string,
signer: Signer
): Promise<ContractTransaction> {
const registry = new Contract(
registryAddress,
SimpleRecipientRegistry,
signer
)
return registry.removeRecipient(recipientId)
}

function rejectProject() {
Expand All @@ -150,7 +170,7 @@ export function create(): RecipientRegistryInterface {
removeProject,
registerProject,
rejectProject,
isRegistrationOpen: false,
isSelfRegistration: false,
requireRegistrationDeposit: false,
}
}
Expand Down
33 changes: 28 additions & 5 deletions vue-app/src/api/recipient-registry.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BigNumber, Contract } from 'ethers'
import { BigNumber, Contract, Signer } from 'ethers'
import sdk from '@/graphql/sdk'
import { BaseRecipientRegistry } from './abi'
import {
Expand All @@ -23,7 +23,7 @@ import KlerosRegistry from './recipient-registry-kleros'
import { isHexString } from '@ethersproject/bytes'
import { Recipient } from '@/graphql/API'
import { Project } from './projects'
import { Metadata } from './metadata'
import { Metadata, MetadataFormData } from './metadata'
import { DateTime } from 'luxon'

const registryLookup: Record<RecipientRegistryType, Function> = {
Expand Down Expand Up @@ -74,7 +74,7 @@ export async function getRegistryInfo(
listingPolicyUrl: `${ipfsGatewayUrl}/ipfs/${recipientRegistryPolicy}`,
recipientCount: recipientCount.toNumber(),
owner,
isRegistrationOpen: registry.isRegistrationOpen,
isSelfRegistration: registry.isSelfRegistration,
requireRegistrationDeposit: registry.requireRegistrationDeposit,
}
}
Expand Down Expand Up @@ -342,11 +342,19 @@ export async function getRequests(
const requestType = Number(recipient.requestType)
if (requestType === RequestTypeCode.Registration) {
// Registration request
const { name, description, imageHash, thumbnailImageHash } = metadata
const {
name,
description,
imageHash,
bannerImageHash,
thumbnailImageHash,
} = metadata

metadata = {
name,
description,
imageUrl: `${ipfsGatewayUrl}/ipfs/${imageHash}`,
bannerImageUrl: `${ipfsGatewayUrl}/ipfs/${bannerImageHash}`,
thumbnailImageUrl: thumbnailImageHash
? `${ipfsGatewayUrl}/ipfs/${thumbnailImageHash}`
: `${ipfsGatewayUrl}/ipfs/${imageHash}`,
Expand Down Expand Up @@ -393,4 +401,19 @@ export async function getRequests(
return Object.keys(requests).map((recipientId) => requests[recipientId])
}

export default { getProject, getProjects, projectExists }
export async function addRecipient(
registryAddress: string,
recipientMetadata: MetadataFormData,
deposit: BigNumber,
signer: Signer
) {
const registry = RecipientRegistry.create(recipientRegistryType)
return registry.addRecipient(
registryAddress,
recipientMetadata,
deposit,
signer
)
}

export default { addRecipient, getProject, getProjects, projectExists }
Loading

0 comments on commit f80f857

Please sign in to comment.