Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
DEPLOYER_SK=
ID_HUB_ADDR=
SELF_SCOPE=
SELF_CONFIG_ID=

NEXT_PUBLIC_SELF_APP_NAME=
NEXT_PUBLIC_SELF_SCOPE=
NEXT_PUBLIC_SELF_ENDPOINT=
NEXT_PUBLIC_VERIFICATION_DEPLOYED_ADDR=
NEXT_PUBLIC_SELF_SCOPE_SEED=
3 changes: 0 additions & 3 deletions .gitmodules

This file was deleted.

10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,13 @@ DHK dao snapshot-self plugin prototype

- Snapshot: https://docs.snapshot.box/developer-guides/validation-strategy
- [DHK dao snapshot page](https://snapshot.box/#/s:dhkdao.eth)

- Get Celo Alfajores Testnet token at: [learnweb3](https://learnweb3.io/)
- Get LINK testnet token: https://faucets.chain.link/celo-alfajores-testnet
- Swap for Celo native tokens: https://app.mento.org/

## Deployment

- SelfVerification:

Celo Alfajores Testnet: [`0xED3C8a827cE54C4D74A6476d93A9352D91d4e88E`](https://celo-alfajores.blockscout.com/address/0xED3C8a827cE54C4D74A6476d93A9352D91d4e88E)
3 changes: 3 additions & 0 deletions packages/contracts/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ out/
# Ignores development broadcast logs
!/broadcast
/broadcast/*/31337/

# Celo Alfajores Testnet
/broadcast/*/44787/
/broadcast/**/dry-run/

# Docs
Expand Down
23 changes: 23 additions & 0 deletions packages/contracts/lib/listenEvents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as fs from 'fs';
import * as path from 'path';
import "dotenv/config";

import { createPublicClient, webSocket, parseAbi } from 'viem';

const RPC_URL = "http://localhost:8545";
const contractAddress = process.env.NEXT_PUBLIC_VERIFICATION_DEPLOYED_ADDR || '';

const publicClient = createPublicClient({
transport: webSocket(RPC_URL),
});

console.log(`Listening to on-chain events\nrpc-url: ${RPC_URL}, address: ${contractAddress}`);

// Event types listen to
const unwatch = publicClient.watchEvent({
address: contractAddress,
events: parseAbi([
'event VerificationCompleted(address indexed sender, string indexed nationality, bytes userData)'
]),
onLogs: (logs) => console.log(logs)
});
16 changes: 13 additions & 3 deletions packages/contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,25 @@
"description": "",
"main": "index.js",
"scripts": {
"test": "forge test"
"build": "forge build",
"dev": "pnpm build && conc -n 'node,deploy' -c auto 'pnpm node' 'pnpm deploy:dev'",
"node": "anvil -f https://alfajores-forno.celo-testnet.org/",
"test": "forge test",
"deploy:dev": "wait-on -t 10s tcp:localhost:8545 && forge script script/DeploySelfVerification.s.sol --rpc-url http://localhost:8545 --broadcast",
"listenEvents": "tsx lib/listenEvents.ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"packageManager": "pnpm@10.14.0",
"dependencies": {
"devDependencies": {
"@selfxyz/contracts": "^1.2.0",
"concurrently": "catalog:",
"dotenv": "catalog:",
"viem": "catalog:",
"forge-std": "github:foundry-rs/forge-std#v1.10.0",
"solady": "^0.1.24"
"solady": "^0.1.24",
"tsx": "catalog:",
"wait-on": "catalog:"
}
}
19 changes: 0 additions & 19 deletions packages/contracts/script/Counter.s.sol

This file was deleted.

29 changes: 29 additions & 0 deletions packages/contracts/script/DeploySelfVerification.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import {Script, console} from "forge-std/Script.sol";
import {SelfVerification} from "../src/SelfVerification.sol";

contract SelfVerificationScript is Script {
SelfVerification public sv;

function setUp() public {}

function run() public {
uint256 deployerPrivateKey = vm.envUint("DEPLOYER_SK");

// what's needed to deploy SelfVerification
address idHubAddr = vm.envAddress("ID_HUB_ADDR");
uint256 scope = vm.envUint("SELF_SCOPE");
bytes32 configId = vm.envBytes32("SELF_CONFIG_ID");


vm.startBroadcast(deployerPrivateKey);

sv = new SelfVerification(idHubAddr, scope, configId);

console.log("YourContract deployed at:", address(sv));

vm.stopBroadcast();
}
}
14 changes: 0 additions & 14 deletions packages/contracts/src/Counter.sol

This file was deleted.

38 changes: 22 additions & 16 deletions packages/contracts/src/SelfVerification.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,13 @@ import {ISelfVerificationRoot} from "@selfxyz/contracts/contracts/interfaces/ISe
import {Ownable} from "solady/auth/Ownable.sol";

contract SelfVerification is SelfVerificationRoot, Ownable {
// Store verification status for each user
mapping(address => bool) public verifiedHumans;
// Store no, of times a wallet owner has been verified with a valid ID
mapping(address => uint32) public verifiedHumans;
bytes32 public verificationConfigId;
address public lastUserAddress;

// Event to track successful verifications
event VerificationCompleted(
ISelfVerificationRoot.GenericDiscloseOutputV2 output,
bytes userData
);
event VerificationCompleted(address indexed sender, string indexed nationality, bytes userData);

/**
* @notice Constructor for the contract
Expand All @@ -42,10 +39,11 @@ contract SelfVerification is SelfVerificationRoot, Ownable {
ISelfVerificationRoot.GenericDiscloseOutputV2 memory output,
bytes memory userData
) internal override {
lastUserAddress = address(uint160(output.userIdentifier));
verifiedHumans[lastUserAddress] = true;
address userId = address(uint160(output.userIdentifier));
string memory nationality = output.nationality;
verifiedHumans[userId] += 1;

emit VerificationCompleted(output, userData);
emit VerificationCompleted(userId, nationality, userData);

// Add your custom logic here:
// - Mint NFT to verified user
Expand All @@ -55,21 +53,29 @@ contract SelfVerification is SelfVerificationRoot, Ownable {
}

function getConfigId(
bytes32 _destinationChainId,
bytes32 _userIdentifier,
bytes memory _userDefinedData
bytes32 /* _destinationChainId */,
bytes32 /* _userIdentifier */,
bytes memory /* _userDefinedData */
) public view override returns (bytes32) {
return verificationConfigId;
}

/**
* @notice Check if an address is a verified human
*/
function isVerifiedHuman(address _user) external view returns (bool) {
return verifiedHumans[_user];
function isVerifiedHuman(address user) external view returns (bool) {
return verifiedHumans[user] > 0;
}

function setConfigId(bytes32 _configId) external onlyOwner {
verificationConfigId = _configId;
function setConfigId(bytes32 configId) external onlyOwner {
verificationConfigId = configId;
}

/**
* @notice Expose the internal _setScope function for testing
* @param newScope The new scope value to set
*/
function setScope(uint256 newScope) external onlyOwner {
_setScope(newScope);
}
}
24 changes: 0 additions & 24 deletions packages/contracts/test/Counter.t.sol

This file was deleted.

4 changes: 2 additions & 2 deletions packages/contracts/test/SelfVerification.t.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.28;

import {Test, console} from "forge-std/Test.sol";
import {Test} from "forge-std/Test.sol";
import {SelfVerification} from "../src/SelfVerification.sol";

contract SelfVerificationTest is Test {
Expand All @@ -15,7 +15,7 @@ contract SelfVerificationTest is Test {
sv = new SelfVerification(idHubAddr, scope, configId);
}

function test_ConfigId() public {
function test_ConfigId() view public {
bytes32 chainId = bytes32(0);
bytes32 userId = bytes32(0);
bytes memory data = bytes("0x");
Expand Down
7 changes: 5 additions & 2 deletions packages/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
"lint": "next lint",
"ngrok": "ngrok http --url=burro-concise-regularly.ngrok-free.app 3000",
"tunnel": "concurrently -n 'next,ngrok' -c auto 'pnpm dev' 'pnpm ngrok'"
},
"dependencies": {
"@selfxyz/common": "^0.0.7",
Expand All @@ -16,14 +18,15 @@
"next": "14.2.30",
"react": "^18",
"react-dom": "^18",
"viem": "^2.33.3"
"viem": "catalog:"
},
"devDependencies": {
"@eslint/eslintrc": "^3",
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"concurrently": "catalog:",
"eslint": "^9",
"eslint-config-next": "15.4.6",
"tailwindcss": "^4",
Expand Down
13 changes: 8 additions & 5 deletions packages/web/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,18 @@ function VerificationComponent() {
useEffect(() => {
try {
const app = new SelfAppBuilder({
// Contract integration settings
endpoint: process.env.NEXT_PUBLIC_VERIFICATION_DEPLOYED_ADDR,
endpointType: "staging_celo",
userIdType: "hex",
version: 2,

// app details
appName: process.env.NEXT_PUBLIC_SELF_APP_NAME || "",
scope: process.env.NEXT_PUBLIC_SELF_SCOPE || "",
endpoint: `${process.env.NEXT_PUBLIC_SELF_ENDPOINT}`,
scope: process.env.NEXT_PUBLIC_SELF_SCOPE_SEED || "",
logoBase64: "https://i.postimg.cc/mrmVf9hm/self.png",
userId: userId,
endpointType: "staging_https",
userIdType: "hex",
userDefinedData: "Bonjour Cannes!",
userDefinedData: "DHK dao self-prototype",
disclosures: {
/* 1. what you want to verify from users' identity */
minimumAge: 18,
Expand Down
Loading