Skip to content

Commit

Permalink
support base-sepolia lookups for kyc sbts
Browse files Browse the repository at this point in the history
  • Loading branch information
calebtuttle committed Oct 15, 2024
1 parent 4f9733e commit 54bc8f2
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 10 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ We plan to support more chains in the future. If you would like to use Holonym o
```JSON
{
"hasValidSbt": false,
"message": "SBT is expired or does not exist"
"message": "SBT is expired or does not exist"
}
```

Expand All @@ -76,7 +76,7 @@ See the following documentation [How to get user's proofs](https://holonym.gitbo
| name | description | type | in | required |
| ----------------- | --------------------------------- | ------ | ----- | -------- |
| `credential-type` | 'gov-id', 'epassport', or 'phone' | string | path | true |
| `network` | 'optimism' or 'optimism-goerli' | string | path | true |
| `network` | 'optimism' or 'base-sepolia' | string | path | true |
| `user` | User's blockchain address | string | query | true |
| `action-id` | Action ID | string | query | true |

Expand Down
20 changes: 20 additions & 0 deletions src/constants/HubV3TestnetABI.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export default [
"function balanceOf(address) view returns (uint256)",
"function getApproved(uint256) view returns (address)",
"function getIdentifier(address,bytes32) pure returns (bytes32)",
"function getSBT(address,bytes32) view returns (tuple(uint256,uint256[],bool))",
"function isApprovedForAll(address,address) view returns (bool)",
"function name() view returns (string)",
"function owner() view returns (address)",
"function ownerOf(uint256) view returns (address)",
"function renounceOwnership()",
"function revokeSBT(address,bytes32)",
"function sbtOwners(bytes32) view returns (uint256, bool)",
"function setSBT(bytes32 circuitId, address sbtReceiver, uint expiration, uint nullifier, uint[] calldata publicValues)",
"function supportsInterface(bytes4) view returns (bool)",
"function symbol() view returns (string)",
"function tokenURI(uint256) view returns (string)",
"function transferOwnership(address)",
"function usedNullifiers(uint256) view returns (bool)",
"function getSBTByNullifier(uint256 nullifier) view returns (tuple(uint256 expiry, uint256[] publicValues, bool revoked) sbt)",
];
7 changes: 5 additions & 2 deletions src/constants/misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ export const defaultActionId = 123456789;
export const hubV3Address = "0x2AA822e264F8cc31A2b9C22f39e5551241e94DfB";
export const hubV3Chain = 10;

export const hubV3TestnetAddress = "0x98221c937C51f5bBe615CB104435395c93b1AD8D";
export const hubV3TestnetChain = 84532;

export const govIdIssuerAddress =
"0x03fae82f38bf01d9799d57fdda64fad4ac44e4c2c2f16c5bf8e1873d0a3e1993";
export const phoneIssuerAddress =
Expand All @@ -18,10 +21,10 @@ export const v3PhoneSybilResistanceCircuitId =
"0xbce052cf723dca06a21bd3cf838bc518931730fb3db7859fc9cc86f0d5483495";
export const v3EPassportSybilResistanceCircuitId =
"0xf2ce248b529343e105f7b3c16459da619281c5f81cf716d28f7df9f87667364d";
export const v3CleanHandsCircuitId =
export const v3CleanHandsCircuitId =
"0x1c98fc4f7f1ad3805aefa81ad25fa466f8342292accf69566b43691d12742a19";

export const ePassportIssuerMerkleRoot =
export const ePassportIssuerMerkleRoot =
"0x111abc2c2de1738067395fa944c07ce6e44c4a38accfed392797bb94cee2cdac";

export const zeronymCleanHandsEthSignSchemaId = "onchain_evm_10_0x8";
Expand Down
64 changes: 64 additions & 0 deletions src/services/sybil-resistance.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from "../constants/contractAddresses.js";
import {
hubV3Address,
hubV3TestnetAddress,
govIdIssuerAddress,
phoneIssuerAddress,
v3KYCSybilResistanceCircuitId,
Expand All @@ -19,6 +20,67 @@ import {
} from "../constants/misc.js";
import AntiSybilStoreABI from "../constants/AntiSybilStoreABI.js";
import HubV3ABI from "../constants/HubV3ABI.js";
import HubV3TestnetABI from "../constants/HubV3TestnetABI.js";

// ---------------------------------------------
// Testnet stuff
// ---------------------------------------------

async function sybilResistanceKycTestnet(req, res) {
const address = req.query.user;
const actionId = req.query["action-id"];
if (!address) {
return res
.status(400)
.json({ error: "Request query params do not include user address" });
}
if (!actionId) {
return res
.status(400)
.json({ error: "Request query params do not include action-id" });
}
if (!assertValidAddress(address)) {
return res.status(400).json({ error: "Invalid user address" });
}
if (!parseInt(actionId)) {
return res.status(400).json({ error: "Invalid action-id" });
}

// Check blocklist first
// const blockListResult = await blocklistGetAddress(address);
// if (blockListResult.Item) {
// return res.status(200).json({ result: false });
// }

// const network = req.params.network;

const provider = providers["base-sepolia"];

const hubV3Contract = new ethers.Contract(
hubV3TestnetAddress,
HubV3TestnetABI,
provider
);

// Check v3 contract for KYC SBT
try {
const sbt = await hubV3Contract.getSBT(address, v3KYCSybilResistanceCircuitId);

// For sandbox, we don't care about expiry or issuer or action ID. We just
// check whether the user has an SBT.

return res.status(200).json({ result: !!sbt });
} catch (err) {
if ((err.errorArgs?.[0] ?? "").includes("SBT is expired")) {
return res.status(200).json({ result: false });
}

throw err;
}
}
// ---------------------------------------------
// END: Testnet stuff
// ---------------------------------------------

async function sybilResistanceGovIdNear(req, res) {
const user = req.query.user;
Expand Down Expand Up @@ -123,6 +185,8 @@ async function sybilResistanceGovId(req, res) {
try {
if (req.params.network === "near") {
return await sybilResistanceGovIdNear(req, res);
} else if (req.params.network === "base-sepolia") {
return await sybilResistanceKycTestnet(req, res);
}

const address = req.query.user;
Expand Down
16 changes: 10 additions & 6 deletions src/services/testnet-minter.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { randomBytes } from "crypto";
import { ethers } from "ethers";
import { v3KYCSybilResistanceCircuitId } from "../constants/misc.js";
import {
hubV3TestnetAddress,
v3KYCSybilResistanceCircuitId,
} from "../constants/misc.js";
import HubV3TestnetABI from "../constants/HubV3TestnetABI.js";
import { providers } from "../init.js";

export async function setKycSbt(req, res) {
Expand All @@ -12,11 +16,11 @@ export async function setKycSbt(req, res) {

const { circuitId, sbtReceiver, expiration, nullifier, publicValues } = req.body;

const abi = [
"function setSBT(bytes32 circuitId, address sbtReceiver, uint expiration, uint nullifier, uint[] calldata publicValues)",
];
const address = "0x98221c937C51f5bBe615CB104435395c93b1AD8D";
const contract = new ethers.Contract(address, abi, testnetMinterWallet);
const contract = new ethers.Contract(
hubV3TestnetAddress,
HubV3TestnetABI,
testnetMinterWallet
);

const tx = await contract.setSBT(
// circuitId,
Expand Down

0 comments on commit 54bc8f2

Please sign in to comment.