Skip to content

Commit

Permalink
UI changes to support different recipient registries
Browse files Browse the repository at this point in the history
  • Loading branch information
yuetloo committed Mar 10, 2022
1 parent 031b394 commit e59f499
Show file tree
Hide file tree
Showing 20 changed files with 260 additions and 88 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ to run `yarn test` or `yarn test:contracts`.
- [Vue js modal](http://vue-js-modal.yev.io/)
- [Ethers](https://docs.ethers.io/v5/)
- [Gun](https://gun.eco/docs/)
- [GraphQL Code Generator](https://www.graphql-code-generator.com/docs/guides/vue) - used to generate the [/graphql/API.ts](https://github.com/clrfund/monorepo/blob/develop/vue-app/src/graphql/API.ts)

### Visual Studio Code

Expand Down
3 changes: 3 additions & 0 deletions vue-app/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ export default class App extends Vue {
'verify',
'verify-step',
'verified',
'not-found',
]
return !excludedRoutes.includes(this.$route.name || '')
}
Expand All @@ -166,6 +167,7 @@ export default class App extends Vue {
'verify',
'verify-step',
'verified',
'not-found',
]
return !excludedRoutes.includes(this.$route.name || '')
}
Expand All @@ -189,6 +191,7 @@ export default class App extends Vue {
'verify',
'project-added',
'verified',
'not-found',
]
return !excludedRoutes.includes(this.$route.name || '')
}
Expand Down
2 changes: 2 additions & 0 deletions vue-app/src/api/abi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { abi as SimpleRecipientRegistry } from '../../../contracts/build/contrac
import { abi as OptimisticRecipientRegistry } from '../../../contracts/build/contracts/contracts/recipientRegistry/OptimisticRecipientRegistry.sol/OptimisticRecipientRegistry.json'
import { abi as KlerosGTCR } from '../../../contracts/build/contracts/contracts/recipientRegistry/IKlerosGTCR.sol/IKlerosGTCR.json'
import { abi as KlerosGTCRAdapter } from '../../../contracts/build/contracts/contracts/recipientRegistry/KlerosGTCRAdapter.sol/KlerosGTCRAdapter.json'
import { abi as BaseRecipientRegistry } from '../../../contracts/build/contracts/contracts/recipientRegistry/BaseRecipientRegistry.sol/BaseRecipientRegistry.json'

export {
ERC20,
Expand All @@ -20,4 +21,5 @@ export {
OptimisticRecipientRegistry,
KlerosGTCR,
KlerosGTCRAdapter,
BaseRecipientRegistry,
}
9 changes: 8 additions & 1 deletion vue-app/src/api/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,16 @@ if (
) {
throw new Error('invalid user registry type')
}
export enum RecipientRegistryType {
SIMPLE = 'simple',
OPTIMISTIC = 'optimistic',
KLEROS = 'kleros',
}
export const recipientRegistryType = process.env.VUE_APP_RECIPIENT_REGISTRY_TYPE
if (
!['simple', 'optimistic', 'kleros'].includes(recipientRegistryType as string)
!Object.values(RecipientRegistryType).includes(
recipientRegistryType as RecipientRegistryType
)
) {
throw new Error('invalid recipient registry type')
}
Expand Down
35 changes: 2 additions & 33 deletions vue-app/src/api/recipient-registry-optimistic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,13 @@ import {
import { isHexString } from '@ethersproject/bytes'
import { DateTime } from 'luxon'
import { getEventArg } from '@/utils/contracts'
import { chain } from '@/api/core'

import { OptimisticRecipientRegistry } from './abi'
import { provider, ipfsGatewayUrl, recipientRegistryPolicy } from './core'
import { ipfsGatewayUrl } from './core'
import { Project } from './projects'
import sdk from '@/graphql/sdk'
import { Recipient } from '@/graphql/API'

export interface RegistryInfo {
deposit: BigNumber
depositToken: string
challengePeriodDuration: number
listingPolicyUrl: string
recipientCount: number
owner: string
}

export async function getRegistryInfo(
registryAddress: string
): Promise<RegistryInfo> {
const registry = new Contract(
registryAddress,
OptimisticRecipientRegistry,
provider
)
const deposit = await registry.baseDeposit()
const challengePeriodDuration = await registry.challengePeriodDuration()
const recipientCount = await registry.getRecipientCount()
const owner = await registry.owner()
return {
deposit,
depositToken: chain.currency,
challengePeriodDuration: challengePeriodDuration.toNumber(),
listingPolicyUrl: `${ipfsGatewayUrl}/ipfs/${recipientRegistryPolicy}`,
recipientCount: recipientCount.toNumber(),
owner,
}
}
import { RegistryInfo } from './recipient-registry'

export enum RequestType {
Registration = 'Registration',
Expand Down
45 changes: 45 additions & 0 deletions vue-app/src/api/recipient-registry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { BigNumber, Contract } from 'ethers'
import sdk from '@/graphql/sdk'
import { BaseRecipientRegistry } from './abi'
import { provider, ipfsGatewayUrl, recipientRegistryPolicy } from './core'
import { chain } from '@/api/core'

export interface RegistryInfo {
deposit: BigNumber
depositToken: string
challengePeriodDuration: number
listingPolicyUrl: string
recipientCount: number
owner: string
}

export async function getRegistryInfo(
registryAddress: string
): Promise<RegistryInfo> {
const data = await sdk.GetRecipientRegistry({
registryAddress: registryAddress.toLowerCase(),
})

const recipientRegistry = data.recipientRegistry
const baseDeposit = recipientRegistry?.baseDeposit || BigNumber.from(0)
const challengePeriodDuration =
recipientRegistry?.challengePeriodDuration || BigNumber.from(0)
const owner = recipientRegistry?.owner || ''

/* TODO: get recipient count from the subgraph */
const registry = new Contract(
registryAddress,
BaseRecipientRegistry,
provider
)
const recipientCount = await registry.getRecipientCount()

return {
deposit: baseDeposit,
depositToken: chain.currency,
challengePeriodDuration: challengePeriodDuration.toNumber(),
listingPolicyUrl: `${ipfsGatewayUrl}/ipfs/${recipientRegistryPolicy}`,
recipientCount: recipientCount.toNumber(),
owner,
}
}
11 changes: 7 additions & 4 deletions vue-app/src/components/CriteriaModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,26 @@
</div>
</div>
</div>
<links to="/join/project" class="btn-primary fit-content"
<links
v-if="supportRegistration"
to="/join/project"
class="btn-primary fit-content"
>Add project</links
>
</div>
</div>
</template>

<script lang="ts">
import Vue from 'vue'
import Component from 'vue-class-component'
import Component, { mixins } from 'vue-class-component'
import Links from '@/components/Links.vue'
import { operator } from '@/api/core'
import { criteria, Criterion } from '@/plugins/round/criteria'
import { RecipientRegistryPlugin } from '@/plugins/registry/RecipientRegistryPlugin'
@Component({ components: { Links } })
export default class CriteriaModal extends Vue {
export default class CriteriaModal extends mixins(RecipientRegistryPlugin) {
get criteria(): Criterion[] {
return criteria
}
Expand Down
33 changes: 33 additions & 0 deletions vue-app/src/graphql/API.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,19 @@ export type Scalars = {



/** The block at which the query should be executed. */
export type Block_Height = {
/** Value containing a block hash */
hash: Maybe<Scalars['Bytes']>;
/** Value containing a block number */
number: Maybe<Scalars['Int']>;
/**
* Value containing the minimum block number.
* In the case of `number_gte`, the query will be executed on the latest block only if
* the subgraph has progressed to or past the minimum block number.
* Defaults to the latest block when omitted.
*
*/
number_gte: Maybe<Scalars['Int']>;
};

Expand Down Expand Up @@ -1199,6 +1209,7 @@ export enum Message_OrderBy {
Timestamp = 'timestamp'
}

/** Defines the order direction, either ascending or descending */
export enum OrderDirection {
Asc = 'asc',
Desc = 'desc'
Expand Down Expand Up @@ -2405,6 +2416,13 @@ export type GetRecipientDonationsQueryVariables = Exact<{

export type GetRecipientDonationsQuery = { __typename?: 'Query', donations: Array<{ __typename?: 'Donation', id: string }> };

export type GetRecipientRegistryQueryVariables = Exact<{
registryAddress: Scalars['ID'];
}>;


export type GetRecipientRegistryQuery = { __typename?: 'Query', recipientRegistry: Maybe<{ __typename?: 'RecipientRegistry', id: string, baseDeposit: Maybe<any>, challengePeriodDuration: Maybe<any>, owner: Maybe<any>, controller: Maybe<any>, maxRecipients: Maybe<any> }> };

export type GetRecipientsQueryVariables = Exact<{
registryAddress: Scalars['String'];
}>;
Expand Down Expand Up @@ -2486,6 +2504,18 @@ export const GetRecipientDonationsDocument = gql`
}
}
`;
export const GetRecipientRegistryDocument = gql`
query GetRecipientRegistry($registryAddress: ID!) {
recipientRegistry(id: $registryAddress) {
id
baseDeposit
challengePeriodDuration
owner
controller
maxRecipients
}
}
`;
export const GetRecipientsDocument = gql`
query GetRecipients($registryAddress: String!) {
recipients(where: {recipientRegistry: $registryAddress}) {
Expand Down Expand Up @@ -2545,6 +2575,9 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper =
GetRecipientDonations(variables: GetRecipientDonationsQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GetRecipientDonationsQuery> {
return withWrapper((wrappedRequestHeaders) => client.request<GetRecipientDonationsQuery>(GetRecipientDonationsDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'GetRecipientDonations');
},
GetRecipientRegistry(variables: GetRecipientRegistryQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GetRecipientRegistryQuery> {
return withWrapper((wrappedRequestHeaders) => client.request<GetRecipientRegistryQuery>(GetRecipientRegistryDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'GetRecipientRegistry');
},
GetRecipients(variables: GetRecipientsQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GetRecipientsQuery> {
return withWrapper((wrappedRequestHeaders) => client.request<GetRecipientsQuery>(GetRecipientsDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'GetRecipients');
},
Expand Down
10 changes: 10 additions & 0 deletions vue-app/src/graphql/queries/GetRecipientRegistry.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
query GetRecipientRegistry($registryAddress: ID!) {
recipientRegistry(id: $registryAddress) {
id
baseDeposit
challengePeriodDuration
owner
controller
maxRecipients
}
}
24 changes: 24 additions & 0 deletions vue-app/src/plugins/registry/RecipientRegistryPlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Vue from 'vue'
import Component from 'vue-class-component'
import { recipientRegistryType, RecipientRegistryType } from '@/api/core'

// these registries support recipient registration
const SUPPORT_REGISTRATION = [RecipientRegistryType.OPTIMISTIC]

// these registries require registration deposits
const REQUIRE_DEPOSIT = [RecipientRegistryType.OPTIMISTIC]

@Component
export class RecipientRegistryPlugin extends Vue {
get supportRegistration(): boolean {
return SUPPORT_REGISTRATION.includes(
recipientRegistryType as RecipientRegistryType
)
}

get requireDeposit(): boolean {
return REQUIRE_DEPOSIT.includes(
recipientRegistryType as RecipientRegistryType
)
}
}
13 changes: 13 additions & 0 deletions vue-app/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import VerifyView from '../views/Verify.vue'
import RecipientRegistryView from '@/views/RecipientRegistry.vue'
import CartView from '@/views/Cart.vue'
import TransactionSuccess from '@/views/TransactionSuccess.vue'
import NotFound from '@/views/NotFound.vue'

Vue.use(VueRouter)

Expand Down Expand Up @@ -228,6 +229,18 @@ const routes = [
title: 'Transaction Success',
},
},
{
path: '/not-found',
name: 'not-found',
component: NotFound,
meta: {
title: 'Page Not Found',
},
},
{
path: '*',
redirect: '/not-found',
},
]
const router = new VueRouter({
base: window.location.pathname,
Expand Down
2 changes: 1 addition & 1 deletion vue-app/src/store/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { RoundStatus, getRoundInfo } from '@/api/round'
import { storage } from '@/api/storage'
import { getTally } from '@/api/tally'
import { getEtherBalance, getTokenBalance, isVerifiedUser } from '@/api/user'
import { getRegistryInfo } from '@/api/recipient-registry-optimistic'
import { getRegistryInfo } from '@/api/recipient-registry'

// Constants
import {
Expand Down
6 changes: 2 additions & 4 deletions vue-app/src/store/getters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@ import { RoundInfo, RoundStatus } from '@/api/round'
import { Tally } from '@/api/tally'
import { User } from '@/api/user'
import { Factory } from '@/api/factory'
import {
RecipientApplicationData,
RegistryInfo,
} from '@/api/recipient-registry-optimistic'
import { RecipientApplicationData } from '@/api/recipient-registry-optimistic'
import { RegistryInfo } from '@/api/recipient-registry'

// Utils
import { isSameAddress } from '@/utils/accounts'
Expand Down
6 changes: 2 additions & 4 deletions vue-app/src/store/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@ import { RoundInfo } from '@/api/round'
import { Tally } from '@/api/tally'
import { User } from '@/api/user'
import { Factory } from '@/api/factory'
import {
RecipientApplicationData,
RegistryInfo,
} from '@/api/recipient-registry-optimistic'
import { RecipientApplicationData } from '@/api/recipient-registry-optimistic'
import { RegistryInfo } from '@/api/recipient-registry'

// Constants
import {
Expand Down
Loading

0 comments on commit e59f499

Please sign in to comment.