# How to integrate Interep (example app) ## Reputation badges as NFTs ### Idea Ability to mine an NFT representing the high reputation earned on Web2 platforms "pseudo-anonymously" (no link between Web2 accounts and Ethereum account). ### What problems can be solved? #### Attestation for access to services Reputation NFTs could be used to access services that require sybil-resistance. A service requiring these NFTs will be free of bots and fake accounts. For example, faucet services on testnets, which give ethers to developers, can require these NFTs rather than requesting the sharing of addresses on personal Twitter accounts. #### Collateral for a loan If Interep reputation badges acquire intrinsic value because they are used in different platforms/services, they could be used as collateral for borrowing within Ethereum's DeFi ecosystem. For example, a user could borrow $2000 from a service in exchange for a reputation NFT. The service might accept this as it is fairly certain that the user will not give up its NFT, as it gives them access to other services. ### Why can Interep be useful? Groups can be categorised by provider. The so-called OAuth providers currently supported (Twitter, Reddit, Github) allow users to join the group that best represents the reputation of users on those platforms. Reputation is measured in 4 levels (gold, silver, bronze, not_sufficient) and it is calculated according to criteria set by Interep. For example, a user with a good reputation on Github (e.g. high number of followers and stars) will have a gold reputation, and will be able to join the gold group of the Github provider with Interep. Interep therefore provides a reliable system that guarantees that anonymously represented users belong to certain groups. Since membership in these groups can also be anonymously verified onchain with zero-knowledge technologies, it is possible to create a system that allows Ethereum accounts to create their onchain reputation badges only if they belong to gold groups. ### What could the app look like? The architecture will be quite simple: - Web App: The app can be a simple web app (without any server) that uses the Interep APIs to allow users to join groups and to create zk proofs with Semaphore. - Smart Contract: There will then be a contract in which a function will verify the zk proof and it will mint an NFT if the verification is successful. So, a common use case for the app will be: 1. The user connects their Ethereum wallet; 2. the user sees a list of Interep providers (Twitter, Reddit, Github) and selects Twitter; 3. the user signs a message on Metamask to create their id commitment; 4. the app sends a request to Interep to add the id commitment to a Twitter group; 5. Interep calculates the user reputation and adds their id commitment to the group related to the newly calculated reputation; 6. the app shows the result of the operation and asks the user if they want to create their badge; 7. the user clicks on the button to create their reputation badge; 8. the app creates a zk proof and opens the wallet to sends the transaction to the contract; 9. the user confirms the transaction on Metamask; 10. the contract verifies that the proof is valid and mints a Twitter reputation NFT. ### Dev tools #### Contracts ##### `@semaphore/contracts` NPM package similar to OpenZeppelin's `@openzeppelin/contracts-upgradeable`. Devs should be able to import the Semaphore contracts they need on Solidity and extend their contract. Semaphore contracts should be organized so that features are separated into different contracts, so that developers can integrate only what they need. Usually devs who wants integrate Interep will only use the function to verify proofs and broadcast signals (i.e. `broadcastSignal`). Trees are managed by Interep externally. ##### Interep `Group.sol` interface Devs will need to use the already deployed Interep contract, so they will need to have a Solidity interface with which to use the contract functions. Basically they will use the Interep contract to verify that the root exists onchain. Devs can write the interface manually or Interep may provide it as an NPM package in the future (not needed in a first version). ###### Example: ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol"; import "@semaphore/contracts/Semaphore.sol"; import "./IGroups.sol"; contract ReputationBadge is ERC721BurnableUpgradeable, Semaphore { IGroups public groups; function initialize( string memory _name, string memory _symbol, address _groupsAddress ) public initializer { groups = IGroups(_groupsAddress); __ERC721_init(_name, _symbol); __ERC721Burnable_init_unchained(); } function safeMint( bytes memory _signal, uint256[8] memory _proof, uint256 _root, uint256 _nullifiersHash, uint232 _externalNullifier ) public isValidSignalAndProof( _signal, _proof, _root, _nullifiersHash, _externalNullifier ) { require( groups.isValidRoot(_root), "ReputationBadge: the root is not valid" ); // TODO: get address and token id from signal & mint the token. } } ``` #### Client-side For simplicity, in this example application it is assumed that the user has already used the Interep app to join a Twitter group. ##### `@interep/identity` Interep NPM package used to create Semaphore identity commitments. Devs can use it with Ethers/Web3.js and Metamask. ###### Example: ```ts import createIdentity from "@interep/identity" import detectEthereumProvider from "@metamask/detect-provider" import { ethers } from "ethers" const ethereumProvider = await detectEthereumProvider() const provider = new ethers.providers.Web3Provider(ethereumProvider) const signer = provider.getSigner() function sign(message: string): Promise<string> { return signer.signMessage(message) } const identity = await createIdentity(sign, "twitter") const identityCommitment = identity.genIdentityCommitment().toString() ``` ##### `@interep/api` Interep NPM package that wraps the Interep APIs in simple functions. Devs can use it to obtain a Merkle proof, to add id commitments to groups (or remove them), and to get other info about providers and groups. ###### Example: ```ts import { API } from "@interep/api" const api = new API() const merkleProof = await api.getMerkleTreeProof({ provider: "github", name: reputation, identityCommitment }) ``` ##### `@semaphore/proof` NPM package that devs can use to create a zk proof. The proof and other parameters can now be sent in the contract transaction described above. Devs shouldn't know anything about the circuit and ZK files. These static files should already be inside the library, or if they are too big they can be hosted on AWS. ###### Example: ```ts import { genProof } from "@semaphore/proof" // signal should contain address and token id. const proof = await genProof(identity, merkleProof, signal) // TODO: send eth transaction. ``` #### Improvements 1. The last two client-side packages can be integrated in only one package `@interep/proof` which can be used as follow: ```ts import createProof from "@interep/proof" // args can be a list of arbitrary arguments that will be packed in bytes. const proof = await createProof(identity, args) await reputationBadgeContract.safeMint(proof) ``` ###### tags: `interep`