diff --git a/README.md b/README.md index b8df78e5f..8fcac22d2 100644 --- a/README.md +++ b/README.md @@ -51,14 +51,13 @@ In a future version, we plan to address this by routing ETH and token contributi ## Documentation -- [Running clr.fund instance](docs/admin.md) +- [BrightId setup](docs/brightid.md) +- [Deployment](docs/deployment.md) - [Providing matching funds](docs/funding-source.md) - [How to tally votes and verify results](docs/tally-verify.md) - [Running the subgraph](docs/subgraph.md) - [Sitemap](docs/sitemap.md) - [Website theme and customization](docs/theme.md) -- [Deployment](docs/deployment.md) -- [BrightId setup](docs/brightid.md) ## Development diff --git a/contracts/package.json b/contracts/package.json index c50070f2a..ce042042f 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -7,7 +7,7 @@ "build": "hardhat compile", "node": "hardhat node --port 18545 --hostname 0.0.0.0", "deploy:local": "yarn clean && yarn build && hardhat run --network localhost scripts/deploy.ts", - "deploy:arbitrum": "hardhat run --network arbitrum scripts/deployRound.ts", + "deploy:arbitrum": "hardhat run --network arbitrum scripts/deploy.ts", "deployTestRound:local": "hardhat run --network localhost scripts/deployTestRound.ts", "contribute:local": "hardhat run --network localhost scripts/contribute.ts", "vote:local": "hardhat run --network localhost scripts/vote.ts", diff --git a/contracts/scripts/deployRound.ts b/contracts/scripts/deployRound.ts deleted file mode 100644 index faa6b99fa..000000000 --- a/contracts/scripts/deployRound.ts +++ /dev/null @@ -1,243 +0,0 @@ -import { ethers } from 'hardhat' -import { Contract, utils } from 'ethers' -import { Keypair } from '@clrfund/maci-utils' - -import { deployMaciFactory } from '../utils/deployment' -import { getEventArg } from '../utils/contracts' -import { MaciParameters } from '../utils/maci' - -async function main() { - console.log('*******************') - console.log('Deploying a new clr.fund instance of contracts!') - console.log('*******************') - const [deployer] = await ethers.getSigners() - console.log('deployer.address: ', deployer.address) - - const circuit = 'prod' - let maciFactory = await deployMaciFactory(deployer, circuit) - await maciFactory.deployTransaction.wait() - console.log('maciFactory.address: ', maciFactory.address) - - const FundingRoundFactory = await ethers.getContractFactory( - 'FundingRoundFactory', - deployer - ) - const fundingRoundFactory = await FundingRoundFactory.deploy( - maciFactory.address - ) - await fundingRoundFactory.deployTransaction.wait() - console.log('fundingRoundFactory.address: ', fundingRoundFactory.address) - - const transferOwnershipTx = await maciFactory.transferOwnership( - fundingRoundFactory.address - ) - await transferOwnershipTx.wait() - - const userRegistryType = process.env.USER_REGISTRY_TYPE || 'simple' - let userRegistry: Contract - if (userRegistryType === 'simple') { - const SimpleUserRegistry = await ethers.getContractFactory( - 'SimpleUserRegistry', - deployer - ) - userRegistry = await SimpleUserRegistry.deploy() - } else if (userRegistryType === 'brightid') { - const BrightIdUserRegistry = await ethers.getContractFactory( - 'BrightIdUserRegistry', - deployer - ) - userRegistry = await BrightIdUserRegistry.deploy( - utils.formatBytes32String(process.env.BRIGHTID_CONTEXT || 'clr.fund'), - process.env.BRIGHTID_VERIFIER_ADDR, - process.env.BRIGHTID_SPONSOR - ) - } else { - throw new Error('unsupported user registry type') - } - await userRegistry.deployTransaction.wait() - console.log('userRegistry.address: ', userRegistry.address) - - const setUserRegistryTx = await fundingRoundFactory.setUserRegistry( - userRegistry.address - ) - await setUserRegistryTx.wait() - - const recipientRegistryType = process.env.RECIPIENT_REGISTRY_TYPE || 'simple' - let recipientRegistry: Contract - if (recipientRegistryType === 'simple') { - const SimpleRecipientRegistry = await ethers.getContractFactory( - 'SimpleRecipientRegistry', - deployer - ) - recipientRegistry = await SimpleRecipientRegistry.deploy( - fundingRoundFactory.address - ) - } else if (recipientRegistryType === 'optimistic') { - const OptimisticRecipientRegistry = await ethers.getContractFactory( - 'OptimisticRecipientRegistry', - deployer - ) - recipientRegistry = await OptimisticRecipientRegistry.deploy( - ethers.BigNumber.from(10).pow(ethers.BigNumber.from(18)).div(10), - 300, - fundingRoundFactory.address - ) - } else { - throw new Error('unsupported recipient registry type') - } - await recipientRegistry.deployTransaction.wait() - console.log('recipientRegistry.address: ', recipientRegistry.address) - - const setRecipientRegistryTx = await fundingRoundFactory.setRecipientRegistry( - recipientRegistry.address - ) - await setRecipientRegistryTx.wait() - - const setTokenTx = await fundingRoundFactory.setToken( - process.env.NATIVE_TOKEN_ADDRESS - ) - await setTokenTx.wait() - - // Generate coordinator key - const keypair = new Keypair() - const coordinatorPubKey = keypair.pubKey - const serializedCoordinatorPrivKey = keypair.privKey.serialize() - const serializedCoordinatorPubKey = keypair.pubKey.serialize() - const setCoordinatorTx = await fundingRoundFactory.setCoordinator( - deployer.address, - coordinatorPubKey.asContractParam() - ) - await setCoordinatorTx.wait() - console.log('serializedCoordinatorPrivKey: ', serializedCoordinatorPrivKey) - console.log('serializedCoordinatorPubKey: ', serializedCoordinatorPubKey) - - maciFactory = await ethers.getContractAt('MACIFactory', maciFactory.address) - const maciParameters = await MaciParameters.read(maciFactory) - maciParameters.update({ - signUpDuration: 86400 * 14, - votingDuration: 86400 * 3, - }) - const setMaciParametersTx = await fundingRoundFactory.setMaciParameters( - ...maciParameters.values() - ) - await setMaciParametersTx.wait() - - const metadataRecipient1 = { - name: 'Commons Simulator', - description: - 'Funding open-source projects & other public goods is the killer app of blockchain tech. Giveth & BlockScience are joining forces to build the Commons Stack: a modular library of well engineered components that can be used to create economic models for projects that are creating value, yet have trouble finding sustainable business models.', - imageHash: 'QmbMP2fMiy6ek5uQZaxG3bzT9gSqMWxpdCUcQg1iSeEFMU', - tagline: 'Modeling Sustainable Funding for Public Good', - category: 'Data', - problemSpace: 'metadata.problemSpace', - plans: 'metadata.plans', - teamName: 'metadata.teamName', - teamDescription: 'metadata.teamDescription', - githubUrl: 'https://github.com/', - radicleUrl: 'https://radicle.xyz/', - websiteUrl: 'https://website.com/', - twitterUrl: 'https://twitter.com/', - discordUrl: 'https://discord.com/', - bannerImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - thumbnailImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - } - - const metadataRecipient2 = { - name: 'Synthereum', - description: - 'The aim of our synthetic assets is to help creating fiat-based wallet and applications on any local currencies, and help to create stock, commodities portfolio in order to bring more traditional users within the DeFi ecosystem.', - imageHash: 'QmbMP2fMiy6ek5uQZaxG3bzT9gSqMWxpdCUcQg1iSeEFMU', - tagline: - 'Synthetic assets with liquidity pools to bridge traditional and digital finance.', - category: 'Content', - problemSpace: 'metadata.problemSpace', - plans: 'metadata.plans', - teamName: 'metadata.teamName', - teamDescription: 'metadata.teamDescription', - githubUrl: 'https://github.com/', - radicleUrl: 'https://radicle.xyz/', - websiteUrl: 'https://website.com/', - twitterUrl: 'https://twitter.com/', - discordUrl: 'https://discord.com/', - bannerImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - thumbnailImageHash: 'QmaDy75RkRVtZcbYeqMDLcCK8dDvahfik68zP7FbpxvD2F', - } - - const addFundingSourceTx = await fundingRoundFactory.addFundingSource( - deployer.address - ) - await addFundingSourceTx.wait() - console.log('Added funding source', deployer.address) - - const deployNewRoundTx = await fundingRoundFactory.deployNewRound() - await deployNewRoundTx.wait() - - if (recipientRegistryType === 'simple') { - const recipients = [ - { account: deployer.address, metadata: metadataRecipient1 }, - { account: deployer.address, metadata: metadataRecipient2 }, - ] - let addRecipientTx - for (const recipient of recipients) { - addRecipientTx = await recipientRegistry.addRecipient( - deployer.address, - JSON.stringify(recipient.metadata) - ) - addRecipientTx.wait() - } - } else if (recipientRegistryType === 'optimistic') { - const deposit = await recipientRegistry.baseDeposit() - const recipient1Added = await recipientRegistry.addRecipient( - deployer.address, - JSON.stringify(metadataRecipient1), - { value: deposit } - ) - await recipient1Added.wait() - - const recipient1Id = await getEventArg( - recipient1Added, - recipientRegistry, - 'RequestSubmitted', - '_recipientId' - ) - const executeRequest1 = await recipientRegistry.executeRequest(recipient1Id) - await executeRequest1.wait() - - const recipient2Added = await recipientRegistry.addRecipient( - deployer.address, - JSON.stringify(metadataRecipient2), - { value: deposit } - ) - await recipient2Added.wait() - - const recipient2Id = await getEventArg( - recipient2Added, - recipientRegistry, - 'RequestSubmitted', - '_recipientId' - ) - const executeRequest2 = await recipientRegistry.executeRequest(recipient2Id) - await executeRequest2.wait() - - const fundingRoundAddress = await fundingRoundFactory.getCurrentRound() - console.log('fundingRound.address: ', fundingRoundAddress) - - const fundingRound = await ethers.getContractAt( - 'FundingRound', - fundingRoundAddress - ) - const maciAddress = await fundingRound.maci() - console.log('maci.address: ', maciAddress) - - console.log('*******************') - console.log('Deploy complete!') - console.log('*******************') - } -} - -main() - .then(() => process.exit(0)) - .catch((error) => { - console.error(error) - process.exit(1) - }) diff --git a/contracts/tasks/deploySponsor.ts b/contracts/tasks/deploySponsor.ts new file mode 100644 index 000000000..58ddaaa0c --- /dev/null +++ b/contracts/tasks/deploySponsor.ts @@ -0,0 +1,9 @@ +import { task } from 'hardhat/config' + +task('deploy-sponsor', 'Deploy the BrightID sponsor contract').setAction( + async (_, { ethers }) => { + const SponsorContract = await ethers.getContractFactory('BrightIdSponsor') + const sponsor = await SponsorContract.deploy() + console.log('Deployed the sponsor contract at', sponsor.address) + } +) diff --git a/contracts/tasks/index.ts b/contracts/tasks/index.ts index 127ee1c98..37d8529c8 100644 --- a/contracts/tasks/index.ts +++ b/contracts/tasks/index.ts @@ -11,3 +11,4 @@ import './auditTally' import './fetchRound' import './mergeAllocations' import './setDurations' +import './deploySponsor' diff --git a/docs/admin.md b/docs/admin.md deleted file mode 100644 index 9ea246020..000000000 --- a/docs/admin.md +++ /dev/null @@ -1,311 +0,0 @@ -# Running clr.fund instance on Goerli - -This document describes deployment and administration of clr.fund contracts using [hardhat console](https://hardhat.org/guides/hardhat-console.html) on the Linux platform. - -For example, to start a hardhat console configured for the Goerli network: - -**Prepare .env file** - -You will need to set up an RPC provider for the `JSONRPC_HTTP_URL` variable. Can use infura, pocket, alchemy, etc. - -**Prepare wallet** - -Update `contracts/.env`. See [.env.example](../contracts/.env.example) for details. - -```bash -# Connect using mnemonic -WALLET_MNEMONIC={{mnemonic-phrase}} - -# or connect using single private key -WALLET_PRIVATE_KEY={{deployer-private-key}} -``` - -**Open hardhat console** - -``` -cd contracts/ -yarn hardhat console --network goerli -``` - - -## Deployment - -### MACI factory - -Deploy MACI factory: - -```js -const [deployer] = await ethers.getSigners() -const { deployMaciFactory } = require('./utils/deployment') -const maciFactory = await deployMaciFactory(deployer, 'prod') -``` - -The `deployMaciFactory` function deploys MACI factory and other contracts required by it: - -- Poseidon T3 library -- Poseidon T6 library -- State tree batch update verifier contract -- Quadratic vote tally verifier contract - -Alternatively, one can deploy these contracts one by one: - -```js -const { deployContract, deployMaciFactory } = require('./utils/deployment') -const poseidonT3 = await deployContract(deployer, ':PoseidonT3') -const poseidonT6 = await deployContract(deployer, ':PoseidonT6') -const batchUstVerifier = await deployContract(deployer, 'BatchUpdateStateTreeVerifierMedium') -const qvtVerifier = await deployContract(deployer, 'QuadVoteTallyVerifierMedium') -const maciFactory = await deployMaciFactory(deployer, 'medium', { poseidonT3, poseidonT6, batchUstVerifier, qvtVerifier }) -``` - -### Funding round factory - -Funding round factory is the main clr.fund contract. Its owner configures clr.fund and manages the deployment and finalization of funding rounds. - -Deploy funding round factory: - -```js -const FundingRoundFactory = await ethers.getContractFactory('FundingRoundFactory', deployer) -const factory = await FundingRoundFactory.deploy(maciFactory.address) -``` - -Transfer ownership of MACI factory: - -```js -await maciFactory.transferOwnership(factory.address) -``` - -### User registry - -clr.fund can work with any user registry that implements [IUserRegistry](../contracts/contracts/userRegistry/IUserRegistry.sol) interface. - -For example, to deploy the simple user registry: - -```js -const SimpleUserRegistry = await ethers.getContractFactory('SimpleUserRegistry', deployer) -const userRegistry = await SimpleUserRegistry.deploy() -``` - -or to deploy BrightID user registry: - -```js -const BrightIdUserRegistry = await ethers.getContractFactory('BrightIdUserRegistry', deployer) -const userRegistry = await BrightIdUserRegistry.deploy('', '') -``` - -Configure funding round factory to use registry: - -```js -await factory.setUserRegistry(userRegistry.address) -``` - -### Recipient registry - -clr.fund can work with any recipient registry that implements [IRecipientRegistry](../contracts/contracts/recipientRegistry/IRecipientRegistry.sol) interface. - -For example, to deploy Optimistic Recipient Registry - -```js -const OptimisticRecipientRegistry = await ethers.getContractFactory('OptimisticRecipientRegistry', deployer) -const securityDeposit = ethers.BigNumber.from(10).pow(ethers.BigNumber.from(18)).div(10) // 0.1 ETH -const recipientRegistry = await OptimisticRecipientRegistry.deploy(securityDeposit, 300, deployer.address) -``` - -or to deploy Kleros GTCR adapter: - -```js -const KlerosGTCRAdapter = await ethers.getContractFactory('KlerosGTCRAdapter', deployer) -const recipientRegistry = await KlerosGTCRAdapter.deploy('', factory.address) -``` - -#### Transferring registry ownership - -If registry contracts inherit from [OpenZeppelin's Ownable contract](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol), you can transfer ownership after you deploy: - -```js -const factory = await ethers.getContractAt('FundingRoundFactory', factory.address) -const recipientRegistryAddress = await factory.recipientRegistry() -const registry = await ethers.getContractAt('OptimisticRecipientRegistry', recipientRegistryAddress) -const transferTx = await registry.transferOwnership('') -``` - -## Configuration - -Configure funding round factory to use registry: - -```js -await factory.setRecipientRegistry(recipientRegistry.address) -``` - -Set native token: - -```js -// this can be any ERC20 compatible token address -const tokenAddress = '0x4f38007de2adba1ba6467d4b82e8de59c2298a3e' -await factory.setToken(tokenAddress) -``` - -If a [coordinator](./tally-verify.md) key has not yet been created. Make sure you save your keys in a file as they will not be displayed again, and you're private key is needed to generate the proofs at the end, and tally the votes: - -```js -// Generate coordinator key -const { Keypair } = require('maci-domainobjs') -const keypair = new Keypair() -const coordinatorPubKey = keypair.pubKey -const serializedCoordinatorPrivKey = keypair.privKey.serialize() -const serializedCoordinatorPubKey = keypair.pubKey.serialize() -// Save the below keys elsewhere -console.log('Private key:', serializedCoordinatorPrivKey) -console.log('Public key: ', serializedCoordinatorPubKey) -// Set coordinator: -await factory.setCoordinator(deployer.address, coordinatorPubKey.asContractParam()) -``` - -If using an existing coordinator key: - -```js -const serializedCoordinatorPubKey = '' -const { PubKey } = require('maci-domainobjs') -const coordinatorPubKey = PubKey.unserialize(serializedCoordinatorPubKey) -await factory.setCoordinator(deployer.address, coordinatorPubKey.asContractParam()) -``` - -> Note, when calling `.setCoordinator()` a different address can be used for the coordinator. "Deployer" used here. - -Set [MACI parameters](../contracts/utils/maci.ts): - -```js -let { MaciParameters } = require('./utils/maci') -let maciFactory = await ethers.getContractAt('MACIFactory', maciFactory.address) -let maciParameters = await MaciParameters.read(maciFactory) -maciParameters.update({ signUpDuration: 86400 * 14, votingDuration: 86400 * 3 }) -await factory.setMaciParameters(...maciParameters.values()) -``` - -Add [funding source](./funding-source.md) (if needed): - -```js -await factory.addFundingSource(deployer.address) -``` - -> Note, a different address can be used for the funding source. "Deployer" used here. - -Or remove funding source: - -```js -await factory.removeFundingSource('
') -``` - -## Running the funding round - -Administrator of clr.fund instance should set parameters before starting the funding round. Once the round has started, it is mostly autonomous and its parameters can not be changed. It can only be finalized (allowing recipients to claim allocated funding) or cancelled (allowing contributors can withdraw their funds). - -Start new funding round: - -```js -await factory.deployNewRound() -``` - -Info to keep track of: - -``` -deployer.address -maciFactory.address -factory.address -recipientRegistry.address -userRegistry.address -serializedCoordinatorPrivKey -serializedCoordinatorPubKey -``` - -Finalize current round and transfer matching funds to the pool: - -```js -await factory.transferMatchingFunds('', '') -``` - -The arguments for `transferMatchingFunds` method should be taken from `tally.json` file published by the [coordinator](./tally-verify.md): - -- `total-spent` value can be found by key `totalVoiceCredits.spent`. -- `total-spent-salt` value can be found by key `totalVoiceCredits.salt`. - -Cancel current round: - -```js -await factory.cancelCurrentRound() -``` - -## Contract deployment script -There is a new deployRound script that has been created that automates the above process (minus taking the new factory address and injecting it into the UI). To run this, first change directory to the contracts folder, configure the `.env` file. - -Make sure the following parameters are set: - -- JSONRPC_HTTP_URL -- WALLET_PRIVATE_KEY or WALLET_MNEMONIC -- NATIVE_TOKEN_ADDRESS - -Then, run the following: - -``` -npx hardhat run --network {network-name} scripts/deployRound.ts -``` - -## Subgraph -The clrfund web app uses subgraph to index contract event data. You can set up a local instance of subgraph following this [guide](./subgraph.md) or create a hosted instance with [theGraph](https://thegraph.com/hosted-service/) and deploy the subgraphs like this: - -1) change directory to subgraph -2) update the config/goerli.json - - set `address` to your funding round factory address - - set the `factoryStartBlock` to the block before your funding round factory was created - - set the `recipientRegistryStartBlock` to the block before your recipient registry was created - -3) generate subgraph.yaml -``` -npx mustache config/goerli.json subgraph.template.yaml > subgraph.yaml -``` - -4) deploy subgraph -``` -npm run codegen -npm run build -npx graph auth --product hosted-service -npx graph deploy --product hosted-service /clrfund -``` - -## GUN -The clrfund web app stores data in the gundb. To ensure the service is available, start a gundb peer using docker like this: - -``` -docker run -p 8765:8765 gundb/gun -``` - -See https://github.com/amark/gun for more details about GUN - -## User interface - -User interface can be configured using environment variables. See [.env file example](../vue-app/.env.example) for details. - -If following along with Goerli, - 1) make sure to update `VITE_CLRFUND_FACTORY_ADDRESS` with your Goerli funding factory address - 2) update `VITE_ETHEREUM_API_URL` with a Goerli provider (ie. Infura or Alchemy) - 3) update `VITE_ETHEREUM_API_CHAINID` to 5 (Goerli chain id) - 4) update `VITE_SUBGRAPH_URL` with your subgraph url - 5) update `VITE_IPFS_API_KEY` and `VITE_IPFS_SECRET_API_KEY` with your pinata ipfs api key values - 6) double check you are using the same user and recipient registry types as used during deployment above. - -Build the dApp for production: - -``` -yarn build -``` - -Add static files to IPFS: - -``` -ipfs add -r vue-app/dist/ -``` - -``` -yarn start:web -``` - diff --git a/docs/deployment.md b/docs/deployment.md index 9224d8c98..89a69a7f9 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -1,6 +1,30 @@ # Deploy to a network -## Using the deployment scripts +## Setup BrightID +If using BrightID as the user registry type: + +### Register your app with BrightID using the following form: + +https://forms.gle/pxHw6aQy155yCuA39 + +Note: select the `hex address (ONLY)` option to identify users and the `meet` verification type + +Once the app is registered, you will get an appId which will be set to `BRIGHTID_CONTEXT` when deploying the contracts in later steps. + +### Setup BrightID sponsorship keys + +1. Generate sponsorship signing keys here: https://tweetnacl.js.org/#/sign +2. Provide the public key to BrightID support through their discord channel: https://discord.gg/QW7ThZ5K4V +3. Save the private key for setting up the clrfund user interface in environment variable: `VITE_BRIGHTID_SPONSOR_KEY` + + +## Deploy Contracts + +### Deploy the BrightID sponsor contract + +1. Run `yarn hardhat --network {network} deploy-sponsor` +2. Verify the contract by running `yarn hardhat --network arbitrum-goerli verify {contract address}` +3. Set `BRIGHTID_SPONSOR` to the contract address in the next step ### Edit the `/contracts/.env` file @@ -12,12 +36,30 @@ USER_REGISTRY_TYPE=simple JSONRPC_HTTP_URL=https://NETWORK.alchemyapi.io/v2/ADD_API_KEY WALLET_PRIVATE_KEY= NATIVE_TOKEN_ADDRESS= +BRIGHTID_CONTEXT= +BRIGHTID_SPONSOR= ``` ### Run the deploy script -1. Adjust the `/contracts/scripts/deployRound.ts` as you wish. By default, it will deploy a new round with two random recipients. -2. Run `npx hardhat run --network {network} scripts/deployRound.ts` or use one of the `yarn deploy:{network}` available in `/contracts/package.json`. +1. Adjust the `/contracts/scripts/deploy.ts` as you wish. +2. Run `yarn hardhat run --network {network} scripts/deploy.ts` or use one of the `yarn deploy:{network}` available in `/contracts/package.json`. +3. To deploy a new funding round, update the .env file with the funding round factory address deployed in the previous step and run the `newRound.ts` script: + +``` +# .env +FACTORY_ADDRESS= +``` + +``` +yarn hardhat run --network {network} scripts/newRound.ts +``` + +4. Verify all deployed contracts: + +``` +yarn hardhat verify-all {funding-round-factory-address} --network {network} +``` ### Deploy the subgraph @@ -28,15 +70,58 @@ Inside `/subgraph`: 1. Prepare the `subgraph.yaml` with the correct network data - Update or create a new JSON file which you want to use, under `/config` - Run `yarn prepare:{network}` -2. Deploy it by running `graph deploy --product hosted-service USERNAME/SUBGRAPH` +2. Build: + - `yarn codegen` + - `yarn build` +3. Authenticate with `yarn graph auth --product hosted-service ` +4. Deploy it by running `yarn graph deploy --product hosted-service USERNAME/SUBGRAPH` + + +### Deploy the user interface + +#### Deploy on netlify + +##### Setup the environment variables + +copy .env.example from the `/vue-app` folder to .env and make sure to revise the following parameters + +``` +VITE_ETHEREUM_MAINNET_API_URL=https://mainnet.infura.io/v3/ADD_API_KEY +VITE_ETHEREUM_API_URL= +VITE_ETHEREUM_API_CHAINID= +VITE_INFURA_ID= +VITE_IPFS_API_KEY= +VITE_IPFS_SECRET_API_KEY= +VITE_SUBGRAPH_URL= +VITE_CLRFUND_FACTORY_ADDRESS= +VITE_USER_REGISTRY_TYPE= +VITE_BRIGHTID_CONTEXT= +VITE_BRIGHTID_SPONSOR_KEY= +VITE_BRIGHTID_SPONSOR_API_URL=https://brightid.clr.fund/brightid/v6/operations +VITE_RECIPIENT_REGISTRY_TYPE= +# see google-sheets.md for instruction on how to set these +GOOGLE_APPLICATION_CREDENTIALS= +VITE_GOOGLE_SPREADSHEET_ID= -### Deploy the netlify functions +``` + +##### Setup the netlify functions + +1. Set the `functions directory` to `vue-app/dist/lambda`. + +See [How to set netlify function directory](https://docs.netlify.com/functions/optional-configuration/?fn-language=ts) + +2. Set environment variable: `AWS_LAMBDA_JS_RUNTIME=nodejs18.x` -The netlify functions are located at /vue-app/src/lambda. To deploy the netlify functions, make sure the functions directory is set to `vue-app/dist/lambda`. [How to set netlify function directory](https://docs.netlify.com/functions/optional-configuration/?fn-language=ts) +This environment variable is needed for the `sponsor.js` function. If not set, it will throw error `fetch not found`. -The `sponsor.js` function will also need the environment variable `AWS_LAMBDA_JS_RUNTIME` set. Otherwise, it will throw error `fetch not found`. + +#### Deploy on IPFS + +Add static files to IPFS: ``` -AWS_LAMBDA_JS_RUNTIME=nodejs18.x -``` \ No newline at end of file +ipfs add -r vue-app/dist/ +``` + diff --git a/vue-app/.env.example b/vue-app/.env.example index 4801601ba..5e52ba294 100644 --- a/vue-app/.env.example +++ b/vue-app/.env.example @@ -1,5 +1,5 @@ # Ethereum Mainnet provider (used for ENS lookups) -VITE_ETHEREUM_MAINNET_API_URL=https://mainnet.infura.io/v3/be4ab600ccbc4855b230b7311db04c35 +VITE_ETHEREUM_MAINNET_API_URL=https://mainnet.infura.io/v3/ADD_API_KEY # Chain details where contract is deployed VITE_ETHEREUM_API_URL=http://localhost:18545