diff --git a/docs/deployment.md b/docs/deployment.md
index 284076f84..4d292238e 100644
--- a/docs/deployment.md
+++ b/docs/deployment.md
@@ -162,6 +162,8 @@ VITE_GOOGLE_SPREADSHEET_ID=
```
+Note: if VITE_SUBGRAPH_URL is not set, the app will try to get the round information from the vue-app/src/rounds.json file which can be generated using the `hardhat export-round` command.
+
##### Setup the netlify functions
1. Set the `functions directory` to `vue-app/dist/lambda`.
diff --git a/vue-app/src/App.vue b/vue-app/src/App.vue
index 923ff52d0..3c7ad9b98 100644
--- a/vue-app/src/App.vue
+++ b/vue-app/src/App.vue
@@ -4,25 +4,12 @@
-
-
@@ -32,33 +19,23 @@
diff --git a/vue-app/src/locales/cn.json b/vue-app/src/locales/cn.json
index 63d63539e..ecbc7e298 100644
--- a/vue-app/src/locales/cn.json
+++ b/vue-app/src/locales/cn.json
@@ -719,6 +719,7 @@
"tooltip2": "{chain} 链上钱包余额",
"h2_3": "项目",
"div1": "正在审核",
+ "withdraw_button": "取回 {contribution} {tokenSymbol}",
"btn2_1": "预览",
"btn2_2": "查看",
"div2": "您尚未提交任何项目"
@@ -886,7 +887,6 @@
"div8": "匹配池",
"div9": "剩余的将会加入匹配池",
"div10": "平均分配 {contribution} {tokenSymbol}",
- "button1": "取回 {contribution} {tokenSymbol}",
"div11": "不可以",
"div11_if2": "重新分配",
"div11_if3": "捐赠",
diff --git a/vue-app/src/locales/en.json b/vue-app/src/locales/en.json
index 8462655d5..031def9e7 100644
--- a/vue-app/src/locales/en.json
+++ b/vue-app/src/locales/en.json
@@ -719,6 +719,7 @@
"tooltip2": "Balance of wallet on {chain} chain",
"h2_3": "Projects",
"div1": "Under review",
+ "withdraw_button": "Withdraw {contribution} {tokenSymbol}",
"btn2_1": "Preview",
"btn2_2": "View",
"div2": "You haven't submitted any projects"
@@ -886,7 +887,6 @@
"div8": "Matching pool",
"div9": "Remaining funds go to matching pool",
"div10": "Split {contribution} {tokenSymbol} evenly",
- "button1": "Withdraw {contribution} {tokenSymbol}",
"div11": "Can't",
"div11_if2": "reallocate",
"div11_if3": "contribute",
diff --git a/vue-app/src/locales/es.json b/vue-app/src/locales/es.json
index d76cba03a..ec1371371 100644
--- a/vue-app/src/locales/es.json
+++ b/vue-app/src/locales/es.json
@@ -719,6 +719,7 @@
"tooltip2": "Saldo de la billetera en la cadena {chain}",
"h2_3": "Proyectos",
"div1": "En revisión",
+ "withdraw_button": "Retirar {contribution} {tokenSymbol}",
"btn2_1": "Vista previa",
"btn2_2": "Ver",
"div2": "No has enviado ningún proyecto"
@@ -886,7 +887,6 @@
"div8": "Matching pool",
"div9": "Los fondos restantes se destinarán al matching pool",
"div10": "Distribuir {contribution} {tokenSymbol} de manera uniforme",
- "button1": "Retirar {contribution} {tokenSymbol}",
"div11": "No puedes",
"div11_if2": "reasignar",
"div11_if3": "contribuir",
diff --git a/vue-app/src/router/index.ts b/vue-app/src/router/index.ts
index e6e415a07..86a75d5b9 100644
--- a/vue-app/src/router/index.ts
+++ b/vue-app/src/router/index.ts
@@ -1,6 +1,6 @@
import { createRouter, createWebHashHistory } from 'vue-router'
import type { RouteRecordRaw } from 'vue-router'
-import { isUserRegistrationRequired, isOptimisticRecipientRegistry } from '@/api/core'
+import { isUserRegistrationRequired, isOptimisticRecipientRegistry, isActiveApp } from '@/api/core'
const Landing = () => import('@/views/Landing.vue')
const JoinLanding = () => import('@/views/JoinLanding.vue')
@@ -262,7 +262,7 @@ if (isUserRegistrationRequired) {
)
}
-if (isOptimisticRecipientRegistry) {
+if (isOptimisticRecipientRegistry && isActiveApp) {
routes.push({
path: '/recipients',
name: 'recipients',
diff --git a/vue-app/src/stores/app.ts b/vue-app/src/stores/app.ts
index 9b2009d76..d977e04b7 100644
--- a/vue-app/src/stores/app.ts
+++ b/vue-app/src/stores/app.ts
@@ -9,10 +9,10 @@ import {
serializeCart,
} from '@/api/contributions'
import { getCommittedCart } from '@/api/cart'
-import { operator, chain, ThemeMode, recipientRegistryType, recipientJoinDeadlineConfig } from '@/api/core'
-import { type RoundInfo, RoundStatus, getRoundInfo } from '@/api/round'
+import { operator, chain, ThemeMode, recipientRegistryType, recipientJoinDeadlineConfig, isActiveApp } from '@/api/core'
+import { type RoundInfo, RoundStatus, getRoundInfo, getLeaderboardRoundInfo } from '@/api/round'
import { getTally, type Tally } from '@/api/tally'
-import { type ClrFund, getClrFundInfo } from '@/api/clrFund'
+import { type ClrFund, getClrFundInfo, getMatchingFunds } from '@/api/clrFund'
import { getMACIFactoryInfo, type MACIFactory } from '@/api/maci-factory'
import { isSameAddress } from '@/utils/accounts'
import { storage } from '@/api/storage'
@@ -23,6 +23,8 @@ import { getAssetsUrl } from '@/utils/url'
import { getTokenLogo } from '@/utils/tokens'
import { assert, ASSERT_MISSING_ROUND, ASSERT_MISSING_SIGNATURE, ASSERT_NOT_CONNECTED_WALLET } from '@/utils/assert'
import { Keypair } from '@clrfund/common'
+import { getRounds } from '@/api/rounds'
+import { DateTime } from 'luxon'
export type AppState = {
isAppReady: boolean
@@ -68,6 +70,11 @@ export const useAppStore = defineStore('app', {
return recipientJoinDeadlineConfig
}
+ if (!isActiveApp) {
+ // when running in static mode, do not allow adding recipients
+ return DateTime.now()
+ }
+
const recipientStore = useRecipientStore()
if (!state.currentRound || !recipientStore.recipientRegistryInfo) {
return null
@@ -113,6 +120,9 @@ export const useAppStore = defineStore('app', {
isCurrentRound:
state =>
(roundAddress: string): boolean => {
+ if (state.currentRoundAddress === null) {
+ return false
+ }
const currentRoundAddress = state.currentRoundAddress || ''
return isSameAddress(roundAddress, currentRoundAddress)
},
@@ -460,12 +470,44 @@ export const useAppStore = defineStore('app', {
stateIndex,
}
},
+ async loadStaticClrFundInfo() {
+ const rounds = await getRounds()
+ // rounds are sorted in reverse order, first one is the newest round
+ const currentRound = rounds[0]
+
+ let maxRecipients = 0
+ if (currentRound) {
+ const network = currentRound.network || ''
+ const currentRoundInfo = await getLeaderboardRoundInfo(currentRound.address, network)
+ if (currentRoundInfo) {
+ const matchingPool = await getMatchingFunds(currentRoundInfo.nativeTokenAddress)
+ this.clrFund = {
+ nativeTokenAddress: currentRoundInfo.nativeTokenAddress,
+ nativeTokenSymbol: currentRoundInfo.nativeTokenSymbol,
+ nativeTokenDecimals: currentRoundInfo.nativeTokenDecimals,
+ userRegistryAddress: currentRoundInfo.userRegistryAddress,
+ recipientRegistryAddress: currentRoundInfo.recipientRegistryAddress,
+ matchingPool,
+ }
+ this.selectRound(currentRound.address)
+ this.currentRound = currentRoundInfo
+ if (currentRoundInfo.tally) {
+ this.tally = currentRoundInfo.tally
+ }
+ maxRecipients = currentRoundInfo.maxRecipients
+ }
+ }
+ if (!this.clrFund) {
+ this.clrFund = await getClrFundInfo()
+ }
+ await this.loadMACIFactoryInfo(maxRecipients)
+ },
async loadClrFundInfo() {
const clrFund = await getClrFundInfo()
this.clrFund = clrFund
},
- async loadMACIFactoryInfo() {
- const factory = await getMACIFactoryInfo()
+ async loadMACIFactoryInfo(maxRecipients?: number) {
+ const factory = await getMACIFactoryInfo(maxRecipients)
this.maciFactory = factory
},
async loadTally() {
diff --git a/vue-app/src/views/Profile.vue b/vue-app/src/views/Profile.vue
index 768352a67..b4c6612e9 100644
--- a/vue-app/src/views/Profile.vue
+++ b/vue-app/src/views/Profile.vue
@@ -56,6 +56,16 @@