diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..136b6d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +# Compiler files +cache/ +out/ +node_modules +broadcast/ + +# Dotenv file +.env +.env.* + +.vscode +lib + +.hardhat/contracts + +# Deployment files +**deployments/test.json +**/tmp/* +!**/tmp/example.json diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..888d42d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/forge-std"] + path = lib/forge-std + url = https://github.com/foundry-rs/forge-std diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..7951405 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +lib \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..8e6b141 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,14 @@ +{ + "tabWidth": 2, + "printWidth": 100, + + "overrides": [ + { + "files": "*.sol", + "options": { + "tabWidth": 2, + "printWidth": 100 + } + } + ] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..ef50180 --- /dev/null +++ b/README.md @@ -0,0 +1,77 @@ +
+
+ Logo + +

+ Sismo Connect Solidity +

+ +

+ Made by Sismo +

+ +

+ + + + + + + + + +

+
+ + +Sismo Connect Solidity is a Solidity library that allows you to verify the zk-proofs of your Sismo Connect Application onchain and simplify the use of the [sismo-connect-onchain-verifier](https://github.com/sismo-core/sismo-connect-onchain-verifier). + +Here is the link to the full documentation of the library: [Sismo Connect Solidity Library](https://docs.sismo.io/build-with-sismo-connect/technical-documentation/solidity) + +You can learn more on Sismo Connect [here](https://docs.sismo.io/discover-sismo-connect/empower-your-app). + +### Prerequisites + +- [Node.js](https://nodejs.org/en/download/) >= 18.15.0 (Latest LTS version) +- [Yarn](https://classic.yarnpkg.com/en/docs/install) +- [Foundry](https://book.getfoundry.sh/) + +## Usage + +### Installation + +```bash +# update foundry +foundryup + +# install the package +forge install sismo-core/sismo-connect-solidity --no-commit + +# add the remapping in remappings.txt +echo $'sismo-connect-solidity/=lib/sismo-connect-packages/src/' >> remappings.txt +``` + +### Import the library +In your solidity file: + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "sismo-connect-solidity/SismoLib.sol"; // import the library +``` + +## License + +Distributed under the MIT License. + +## Contribute + +Please, feel free to open issues, PRs or simply provide feedback! + +## Contact + +Send us a message in [Telegram](https://builders.sismo.io/) or [Discord](https://discord.gg/sismo) + +
+bottom \ No newline at end of file diff --git a/foundry.toml b/foundry.toml new file mode 100644 index 0000000..4d9fd31 --- /dev/null +++ b/foundry.toml @@ -0,0 +1,17 @@ +[profile.default] +optimizer_runs = 1000000 +verbosity = 1 +libs = ["lib"] +fs_permissions = [{ access = "read-write", path = "./"}] + +bytecode_hash="none" + +[fmt] +ignore = ["test/libs/SimoConnectLib.t.sol"] + +[rpc_endpoints] +polygon = "${RPC_URL}" +gnosis = "${RPC_URL}" +goerli = "${RPC_URL}" +mumbai = "${RPC_URL}" +mainnet = "${RPC_URL}" diff --git a/lib/forge-std b/lib/forge-std new file mode 160000 index 0000000..74cfb77 --- /dev/null +++ b/lib/forge-std @@ -0,0 +1 @@ +Subproject commit 74cfb77e308dd188d2f58864aaf44963ae6b88b1 diff --git a/package.json b/package.json new file mode 100644 index 0000000..d45b901 --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "name": "sismo-connect-onchain-verifier", + "version": "1.0.0", + "main": "index.js", + "repository": "git@github.com:sismo-core/sismo-connect-onchain-verifier.git", + "author": "Hadrien Charlanes <35774097+dhadrien@users.noreply.github.com>", + "license": "MIT", + "devDependencies": { + "prettier": "^2.3.1", + "prettier-plugin-solidity": "^1.0.0-beta.13" + }, + "scripts": { + "lint": "prettier --write **.sol", + "setup-fork": "./script/bash/setup-fork.sh" + } +} diff --git a/remappings.txt b/remappings.txt new file mode 100644 index 0000000..83fbb69 --- /dev/null +++ b/remappings.txt @@ -0,0 +1 @@ +forge-std/=lib/forge-std/src/ \ No newline at end of file diff --git a/src/SismoConnectLib.sol b/src/SismoConnectLib.sol new file mode 100644 index 0000000..3ece713 --- /dev/null +++ b/src/SismoConnectLib.sol @@ -0,0 +1,857 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import {RequestBuilder, SismoConnectRequest, SismoConnectResponse, SismoConnectConfig} from "./utils/RequestBuilder.sol"; +import {AuthRequestBuilder, AuthRequest, Auth, VerifiedAuth, AuthType} from "./utils/AuthRequestBuilder.sol"; +import {ClaimRequestBuilder, ClaimRequest, Claim, VerifiedClaim, ClaimType} from "./utils/ClaimRequestBuilder.sol"; +import {SignatureBuilder, SignatureRequest, Signature} from "./utils/SignatureBuilder.sol"; +import {VaultConfig} from "./utils/Structs.sol"; +import {ISismoConnectVerifier, SismoConnectVerifiedResult} from "./interfaces/ISismoConnectVerifier.sol"; +import {IAddressesProvider} from "./interfaces/IAddressesProvider.sol"; +import {SismoConnectHelper} from "./utils/SismoConnectHelper.sol"; + +contract SismoConnect { + uint256 public constant SISMO_CONNECT_LIB_VERSION = 2; + + IAddressesProvider public constant ADDRESSES_PROVIDER_V2 = + IAddressesProvider(0x3Cd5334eB64ebBd4003b72022CC25465f1BFcEe6); + + ISismoConnectVerifier immutable _sismoConnectVerifier; + + // external libraries + AuthRequestBuilder immutable _authRequestBuilder; + ClaimRequestBuilder immutable _claimRequestBuilder; + SignatureBuilder immutable _signatureBuilder; + RequestBuilder immutable _requestBuilder; + + // config + bytes16 public immutable APP_ID; + bool public immutable IS_IMPERSONATION_MODE; + + constructor(SismoConnectConfig memory _config) { + APP_ID = _config.appId; + IS_IMPERSONATION_MODE = _config.vault.isImpersonationMode; + + _sismoConnectVerifier = ISismoConnectVerifier( + ADDRESSES_PROVIDER_V2.get(string("sismoConnectVerifier-v1.2")) + ); + // external libraries + _authRequestBuilder = AuthRequestBuilder( + ADDRESSES_PROVIDER_V2.get(string("authRequestBuilder-v1.1")) + ); + _claimRequestBuilder = ClaimRequestBuilder( + ADDRESSES_PROVIDER_V2.get(string("claimRequestBuilder-v1.1")) + ); + _signatureBuilder = SignatureBuilder( + ADDRESSES_PROVIDER_V2.get(string("signatureBuilder-v1.1")) + ); + _requestBuilder = RequestBuilder(ADDRESSES_PROVIDER_V2.get(string("requestBuilder-v1.1"))); + } + + // public function because it needs to be used by this contract and can be used by other contracts + function config() public view returns (SismoConnectConfig memory) { + return buildConfig(APP_ID, IS_IMPERSONATION_MODE); + } + + function buildConfig(bytes16 appId) internal pure returns (SismoConnectConfig memory) { + return SismoConnectConfig({appId: appId, vault: buildVaultConfig()}); + } + + function buildConfig( + bytes16 appId, + bool isImpersonationMode + ) internal pure returns (SismoConnectConfig memory) { + return SismoConnectConfig({appId: appId, vault: buildVaultConfig(isImpersonationMode)}); + } + + function buildVaultConfig() internal pure returns (VaultConfig memory) { + return VaultConfig({isImpersonationMode: false}); + } + + function buildVaultConfig(bool isImpersonationMode) internal pure returns (VaultConfig memory) { + return VaultConfig({isImpersonationMode: isImpersonationMode}); + } + + function verify( + bytes memory responseBytes, + AuthRequest memory auth, + ClaimRequest memory claim, + SignatureRequest memory signature, + bytes16 namespace + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(auth, claim, signature, namespace); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + AuthRequest memory auth, + ClaimRequest memory claim, + bytes16 namespace + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(auth, claim, namespace); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + AuthRequest memory auth, + SignatureRequest memory signature, + bytes16 namespace + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(auth, signature, namespace); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + ClaimRequest memory claim, + SignatureRequest memory signature, + bytes16 namespace + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(claim, signature, namespace); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + AuthRequest memory auth, + bytes16 namespace + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(auth, namespace); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + ClaimRequest memory claim, + bytes16 namespace + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(claim, namespace); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + AuthRequest memory auth, + ClaimRequest memory claim, + SignatureRequest memory signature + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(auth, claim, signature); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + AuthRequest memory auth, + ClaimRequest memory claim + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(auth, claim); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + AuthRequest memory auth, + SignatureRequest memory signature + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(auth, signature); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + ClaimRequest memory claim, + SignatureRequest memory signature + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(claim, signature); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + AuthRequest memory auth + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(auth); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + ClaimRequest memory claim + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(claim); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + SismoConnectRequest memory request + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + AuthRequest[] memory auths, + ClaimRequest[] memory claims, + SignatureRequest memory signature, + bytes16 namespace + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(auths, claims, signature, namespace); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + AuthRequest[] memory auths, + ClaimRequest[] memory claims, + bytes16 namespace + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(auths, claims, namespace); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + AuthRequest[] memory auths, + SignatureRequest memory signature, + bytes16 namespace + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(auths, signature, namespace); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + ClaimRequest[] memory claims, + SignatureRequest memory signature, + bytes16 namespace + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(claims, signature, namespace); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + AuthRequest[] memory auths, + bytes16 namespace + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(auths, namespace); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + ClaimRequest[] memory claims, + bytes16 namespace + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(claims, namespace); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + AuthRequest[] memory auths, + ClaimRequest[] memory claims, + SignatureRequest memory signature + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(auths, claims, signature); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + AuthRequest[] memory auths, + ClaimRequest[] memory claims + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(auths, claims); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + AuthRequest[] memory auths, + SignatureRequest memory signature + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(auths, signature); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + ClaimRequest[] memory claims, + SignatureRequest memory signature + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(claims, signature); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + AuthRequest[] memory auths + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(auths); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function verify( + bytes memory responseBytes, + ClaimRequest[] memory claims + ) internal returns (SismoConnectVerifiedResult memory) { + SismoConnectResponse memory response = abi.decode(responseBytes, (SismoConnectResponse)); + SismoConnectRequest memory request = buildRequest(claims); + return _sismoConnectVerifier.verify(response, request, config()); + } + + function buildClaim( + bytes16 groupId, + bytes16 groupTimestamp, + uint256 value, + ClaimType claimType, + bytes memory extraData + ) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId, groupTimestamp, value, claimType, extraData); + } + + function buildClaim(bytes16 groupId) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId); + } + + function buildClaim( + bytes16 groupId, + bytes16 groupTimestamp + ) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId, groupTimestamp); + } + + function buildClaim(bytes16 groupId, uint256 value) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId, value); + } + + function buildClaim( + bytes16 groupId, + ClaimType claimType + ) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId, claimType); + } + + function buildClaim( + bytes16 groupId, + bytes memory extraData + ) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId, extraData); + } + + function buildClaim( + bytes16 groupId, + bytes16 groupTimestamp, + uint256 value + ) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId, groupTimestamp, value); + } + + function buildClaim( + bytes16 groupId, + bytes16 groupTimestamp, + ClaimType claimType + ) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId, groupTimestamp, claimType); + } + + function buildClaim( + bytes16 groupId, + bytes16 groupTimestamp, + bytes memory extraData + ) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId, groupTimestamp, extraData); + } + + function buildClaim( + bytes16 groupId, + uint256 value, + ClaimType claimType + ) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId, value, claimType); + } + + function buildClaim( + bytes16 groupId, + uint256 value, + bytes memory extraData + ) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId, value, extraData); + } + + function buildClaim( + bytes16 groupId, + ClaimType claimType, + bytes memory extraData + ) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId, claimType, extraData); + } + + function buildClaim( + bytes16 groupId, + bytes16 groupTimestamp, + uint256 value, + ClaimType claimType + ) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId, groupTimestamp, value, claimType); + } + + function buildClaim( + bytes16 groupId, + bytes16 groupTimestamp, + uint256 value, + bytes memory extraData + ) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId, groupTimestamp, value, extraData); + } + + function buildClaim( + bytes16 groupId, + bytes16 groupTimestamp, + ClaimType claimType, + bytes memory extraData + ) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId, groupTimestamp, claimType, extraData); + } + + function buildClaim( + bytes16 groupId, + uint256 value, + ClaimType claimType, + bytes memory extraData + ) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId, value, claimType, extraData); + } + + function buildClaim( + bytes16 groupId, + bool isOptional, + bool isSelectableByUser + ) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId, isOptional, isSelectableByUser); + } + + function buildClaim( + bytes16 groupId, + bytes16 groupTimestamp, + bool isOptional, + bool isSelectableByUser + ) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId, groupTimestamp, isOptional, isSelectableByUser); + } + + function buildClaim( + bytes16 groupId, + uint256 value, + bool isOptional, + bool isSelectableByUser + ) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId, value, isOptional, isSelectableByUser); + } + + function buildClaim( + bytes16 groupId, + ClaimType claimType, + bool isOptional, + bool isSelectableByUser + ) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId, claimType, isOptional, isSelectableByUser); + } + + function buildClaim( + bytes16 groupId, + bytes16 groupTimestamp, + uint256 value, + bool isOptional, + bool isSelectableByUser + ) internal view returns (ClaimRequest memory) { + return + _claimRequestBuilder.build(groupId, groupTimestamp, value, isOptional, isSelectableByUser); + } + + function buildClaim( + bytes16 groupId, + bytes16 groupTimestamp, + ClaimType claimType, + bool isOptional, + bool isSelectableByUser + ) internal view returns (ClaimRequest memory) { + return + _claimRequestBuilder.build( + groupId, + groupTimestamp, + claimType, + isOptional, + isSelectableByUser + ); + } + + function buildClaim( + bytes16 groupId, + uint256 value, + ClaimType claimType, + bool isOptional, + bool isSelectableByUser + ) internal view returns (ClaimRequest memory) { + return _claimRequestBuilder.build(groupId, value, claimType, isOptional, isSelectableByUser); + } + + function buildClaim( + bytes16 groupId, + bytes16 groupTimestamp, + uint256 value, + ClaimType claimType, + bool isOptional, + bool isSelectableByUser + ) internal view returns (ClaimRequest memory) { + return + _claimRequestBuilder.build( + groupId, + groupTimestamp, + value, + claimType, + isOptional, + isSelectableByUser + ); + } + + function buildAuth( + AuthType authType, + bool isAnon, + uint256 userId, + bytes memory extraData + ) internal view returns (AuthRequest memory) { + return _authRequestBuilder.build(authType, isAnon, userId, extraData); + } + + function buildAuth(AuthType authType) internal view returns (AuthRequest memory) { + return _authRequestBuilder.build(authType); + } + + function buildAuth(AuthType authType, bool isAnon) internal view returns (AuthRequest memory) { + return _authRequestBuilder.build(authType, isAnon); + } + + function buildAuth(AuthType authType, uint256 userId) internal view returns (AuthRequest memory) { + return _authRequestBuilder.build(authType, userId); + } + + function buildAuth( + AuthType authType, + bytes memory extraData + ) internal view returns (AuthRequest memory) { + return _authRequestBuilder.build(authType, extraData); + } + + function buildAuth( + AuthType authType, + bool isAnon, + uint256 userId + ) internal view returns (AuthRequest memory) { + return _authRequestBuilder.build(authType, isAnon, userId); + } + + function buildAuth( + AuthType authType, + bool isAnon, + bytes memory extraData + ) internal view returns (AuthRequest memory) { + return _authRequestBuilder.build(authType, isAnon, extraData); + } + + function buildAuth( + AuthType authType, + uint256 userId, + bytes memory extraData + ) internal view returns (AuthRequest memory) { + return _authRequestBuilder.build(authType, userId, extraData); + } + + function buildAuth( + AuthType authType, + bool isOptional, + bool isSelectableByUser + ) internal view returns (AuthRequest memory) { + return _authRequestBuilder.build(authType, isOptional, isSelectableByUser); + } + + function buildAuth( + AuthType authType, + bool isOptional, + bool isSelectableByUser, + uint256 userId + ) internal view returns (AuthRequest memory) { + return _authRequestBuilder.build(authType, isOptional, isSelectableByUser, userId); + } + + function buildAuth( + AuthType authType, + bool isAnon, + bool isOptional, + bool isSelectableByUser + ) internal view returns (AuthRequest memory) { + return _authRequestBuilder.build(authType, isAnon, isOptional, isSelectableByUser); + } + + function buildAuth( + AuthType authType, + uint256 userId, + bool isOptional + ) internal view returns (AuthRequest memory) { + return _authRequestBuilder.build(authType, userId, isOptional); + } + + function buildAuth( + AuthType authType, + bool isAnon, + uint256 userId, + bool isOptional + ) internal view returns (AuthRequest memory) { + return _authRequestBuilder.build(authType, isAnon, userId, isOptional); + } + + function buildSignature(bytes memory message) internal view returns (SignatureRequest memory) { + return _signatureBuilder.build(message); + } + + function buildSignature( + bytes memory message, + bool isSelectableByUser + ) internal view returns (SignatureRequest memory) { + return _signatureBuilder.build(message, isSelectableByUser); + } + + function buildSignature( + bytes memory message, + bytes memory extraData + ) internal view returns (SignatureRequest memory) { + return _signatureBuilder.build(message, extraData); + } + + function buildSignature( + bytes memory message, + bool isSelectableByUser, + bytes memory extraData + ) internal view returns (SignatureRequest memory) { + return _signatureBuilder.build(message, isSelectableByUser, extraData); + } + + function buildSignature(bool isSelectableByUser) internal view returns (SignatureRequest memory) { + return _signatureBuilder.build(isSelectableByUser); + } + + function buildSignature( + bool isSelectableByUser, + bytes memory extraData + ) internal view returns (SignatureRequest memory) { + return _signatureBuilder.build(isSelectableByUser, extraData); + } + + function buildRequest( + AuthRequest memory auth, + ClaimRequest memory claim, + SignatureRequest memory signature + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(auth, claim, signature); + } + + function buildRequest( + AuthRequest memory auth, + ClaimRequest memory claim + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(auth, claim, _GET_EMPTY_SIGNATURE_REQUEST()); + } + + function buildRequest( + ClaimRequest memory claim, + SignatureRequest memory signature + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(claim, signature); + } + + function buildRequest( + AuthRequest memory auth, + SignatureRequest memory signature + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(auth, signature); + } + + function buildRequest( + ClaimRequest memory claim + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(claim, _GET_EMPTY_SIGNATURE_REQUEST()); + } + + function buildRequest( + AuthRequest memory auth + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(auth, _GET_EMPTY_SIGNATURE_REQUEST()); + } + + function buildRequest( + AuthRequest memory auth, + ClaimRequest memory claim, + SignatureRequest memory signature, + bytes16 namespace + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(auth, claim, signature, namespace); + } + + function buildRequest( + AuthRequest memory auth, + ClaimRequest memory claim, + bytes16 namespace + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(auth, claim, _GET_EMPTY_SIGNATURE_REQUEST(), namespace); + } + + function buildRequest( + ClaimRequest memory claim, + SignatureRequest memory signature, + bytes16 namespace + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(claim, signature, namespace); + } + + function buildRequest( + AuthRequest memory auth, + SignatureRequest memory signature, + bytes16 namespace + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(auth, signature, namespace); + } + + function buildRequest( + ClaimRequest memory claim, + bytes16 namespace + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(claim, _GET_EMPTY_SIGNATURE_REQUEST(), namespace); + } + + function buildRequest( + AuthRequest memory auth, + bytes16 namespace + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(auth, _GET_EMPTY_SIGNATURE_REQUEST(), namespace); + } + + function buildRequest( + AuthRequest[] memory auths, + ClaimRequest[] memory claims, + SignatureRequest memory signature + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(auths, claims, signature); + } + + function buildRequest( + AuthRequest[] memory auths, + ClaimRequest[] memory claims + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(auths, claims, _GET_EMPTY_SIGNATURE_REQUEST()); + } + + function buildRequest( + ClaimRequest[] memory claims, + SignatureRequest memory signature + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(claims, signature); + } + + function buildRequest( + AuthRequest[] memory auths, + SignatureRequest memory signature + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(auths, signature); + } + + function buildRequest( + ClaimRequest[] memory claims + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(claims, _GET_EMPTY_SIGNATURE_REQUEST()); + } + + function buildRequest( + AuthRequest[] memory auths + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(auths, _GET_EMPTY_SIGNATURE_REQUEST()); + } + + function buildRequest( + AuthRequest[] memory auths, + ClaimRequest[] memory claims, + SignatureRequest memory signature, + bytes16 namespace + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(auths, claims, signature, namespace); + } + + function buildRequest( + AuthRequest[] memory auths, + ClaimRequest[] memory claims, + bytes16 namespace + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(auths, claims, _GET_EMPTY_SIGNATURE_REQUEST(), namespace); + } + + function buildRequest( + ClaimRequest[] memory claims, + SignatureRequest memory signature, + bytes16 namespace + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(claims, signature, namespace); + } + + function buildRequest( + AuthRequest[] memory auths, + SignatureRequest memory signature, + bytes16 namespace + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(auths, signature, namespace); + } + + function buildRequest( + ClaimRequest[] memory claims, + bytes16 namespace + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(claims, _GET_EMPTY_SIGNATURE_REQUEST(), namespace); + } + + function buildRequest( + AuthRequest[] memory auths, + bytes16 namespace + ) internal view returns (SismoConnectRequest memory) { + return _requestBuilder.build(auths, _GET_EMPTY_SIGNATURE_REQUEST(), namespace); + } + + function _GET_EMPTY_SIGNATURE_REQUEST() internal view returns (SignatureRequest memory) { + return _signatureBuilder.buildEmpty(); + } +} diff --git a/src/interfaces/IAddressesProvider.sol b/src/interfaces/IAddressesProvider.sol new file mode 100644 index 0000000..54b42e6 --- /dev/null +++ b/src/interfaces/IAddressesProvider.sol @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +interface IAddressesProvider { + /** + * @dev Sets the address of a contract. + * @param contractAddress Address of the contract. + * @param contractName Name of the contract. + */ + function set(address contractAddress, string memory contractName) external; + + /** + * @dev Sets the address of multiple contracts. + * @param contractAddresses Addresses of the contracts. + * @param contractNames Names of the contracts. + */ + function setBatch(address[] calldata contractAddresses, string[] calldata contractNames) external; + + /** + * @dev Returns the address of a contract. + * @param contractName Name of the contract (string). + * @return Address of the contract. + */ + function get(string memory contractName) external view returns (address); + + /** + * @dev Returns the address of a contract. + * @param contractNameHash Hash of the name of the contract (bytes32). + * @return Address of the contract. + */ + function get(bytes32 contractNameHash) external view returns (address); + + /** + * @dev Returns the addresses of all contracts inputed. + * @param contractNames Names of the contracts as strings. + */ + function getBatch(string[] calldata contractNames) external view returns (address[] memory); + + /** + * @dev Returns the addresses of all contracts inputed. + * @param contractNamesHash Names of the contracts as strings. + */ + function getBatch(bytes32[] calldata contractNamesHash) external view returns (address[] memory); + + /** + * @dev Returns the addresses of all contracts in `_contractNames` + * @return Names, Hashed Names and Addresses of all contracts. + */ + function getAll() external view returns (string[] memory, bytes32[] memory, address[] memory); +} diff --git a/src/interfaces/IBaseVerifier.sol b/src/interfaces/IBaseVerifier.sol new file mode 100644 index 0000000..777d8fd --- /dev/null +++ b/src/interfaces/IBaseVerifier.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.17; + +import {SismoConnectProof, VerifiedAuth, VerifiedClaim} from "../utils/Structs.sol"; + +interface IBaseVerifier { + function verify( + bytes16 appId, + bytes16 namespace, + bool isImpersonationMode, + bytes memory signedMessage, + SismoConnectProof memory sismoConnectProof + ) external returns (VerifiedAuth memory, VerifiedClaim memory); +} diff --git a/src/interfaces/ISismoConnectVerifier.sol b/src/interfaces/ISismoConnectVerifier.sol new file mode 100644 index 0000000..5749e8f --- /dev/null +++ b/src/interfaces/ISismoConnectVerifier.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "../utils/Structs.sol"; + +interface ISismoConnectVerifier { + event VerifierSet(bytes32, address); + + error AppIdMismatch(bytes16 receivedAppId, bytes16 expectedAppId); + error NamespaceMismatch(bytes16 receivedNamespace, bytes16 expectedNamespace); + error VersionMismatch(bytes32 requestVersion, bytes32 responseVersion); + error SignatureMessageMismatch(bytes requestMessageSignature, bytes responseMessageSignature); + + function verify( + SismoConnectResponse memory response, + SismoConnectRequest memory request, + SismoConnectConfig memory config + ) external returns (SismoConnectVerifiedResult memory); + + function SISMO_CONNECT_VERSION() external view returns (bytes32); +} diff --git a/src/utils/AuthBuilder.sol b/src/utils/AuthBuilder.sol new file mode 100644 index 0000000..02822f7 --- /dev/null +++ b/src/utils/AuthBuilder.sol @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "./Structs.sol"; + +library AuthBuilder { + // default values for Auth Request + AuthType public constant DEFAULT_AUTH_TYPE = AuthType.VAULT; + bool public constant DEFAULT_AUTH_IS_ANON = false; + uint256 public constant DEFAULT_AUTH_USER_ID = 0; + bool public constant DEFAULT_AUTH_IS_SELECTABLE_BY_USER = true; + bytes public constant DEFAULT_AUTH_EXTRA_DATA = ""; + + function build( + AuthType authType, + bool isAnon, + uint256 userId, + bool isSelectableByUser, + bytes memory extraData + ) external pure returns (Auth memory) { + return + Auth({ + authType: authType, + isAnon: isAnon, + userId: userId, + isSelectableByUser: isSelectableByUser, + extraData: extraData + }); + } + + function build( + AuthType authType, + bool isAnon, + uint256 userId, + bytes memory extraData + ) external pure returns (Auth memory) { + return + Auth({ + authType: authType, + isAnon: isAnon, + userId: userId, + isSelectableByUser: DEFAULT_AUTH_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } + + function build(AuthType authType) external pure returns (Auth memory) { + return + Auth({ + authType: authType, + isAnon: DEFAULT_AUTH_IS_ANON, + userId: DEFAULT_AUTH_USER_ID, + isSelectableByUser: DEFAULT_AUTH_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_AUTH_EXTRA_DATA + }); + } + + function build(AuthType authType, bool isAnon) external pure returns (Auth memory) { + return + Auth({ + authType: authType, + isAnon: isAnon, + userId: DEFAULT_AUTH_USER_ID, + isSelectableByUser: DEFAULT_AUTH_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_AUTH_EXTRA_DATA + }); + } + + function build(AuthType authType, uint256 userId) external pure returns (Auth memory) { + return + Auth({ + authType: authType, + isAnon: DEFAULT_AUTH_IS_ANON, + userId: userId, + isSelectableByUser: DEFAULT_AUTH_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_AUTH_EXTRA_DATA + }); + } + + function build(AuthType authType, bytes memory extraData) external pure returns (Auth memory) { + return + Auth({ + authType: authType, + isAnon: DEFAULT_AUTH_IS_ANON, + userId: DEFAULT_AUTH_USER_ID, + isSelectableByUser: DEFAULT_AUTH_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } + + function build( + AuthType authType, + bool isAnon, + uint256 userId + ) external pure returns (Auth memory) { + return + Auth({ + authType: authType, + isAnon: isAnon, + userId: userId, + isSelectableByUser: DEFAULT_AUTH_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_AUTH_EXTRA_DATA + }); + } + + function build( + AuthType authType, + bool isAnon, + bytes memory extraData + ) external pure returns (Auth memory) { + return + Auth({ + authType: authType, + isAnon: isAnon, + userId: DEFAULT_AUTH_USER_ID, + isSelectableByUser: DEFAULT_AUTH_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } + + function build( + AuthType authType, + uint256 userId, + bytes memory extraData + ) external pure returns (Auth memory) { + return + Auth({ + authType: authType, + isAnon: DEFAULT_AUTH_IS_ANON, + userId: userId, + isSelectableByUser: DEFAULT_AUTH_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } + + function build( + AuthType authType, + bool isAnon, + uint256 userId, + bool isSelectableByUser + ) external pure returns (Auth memory) { + return + Auth({ + authType: authType, + isAnon: isAnon, + userId: userId, + isSelectableByUser: isSelectableByUser, + extraData: DEFAULT_AUTH_EXTRA_DATA + }); + } +} diff --git a/src/utils/AuthMatchingLib.sol b/src/utils/AuthMatchingLib.sol new file mode 100644 index 0000000..a1f90a9 --- /dev/null +++ b/src/utils/AuthMatchingLib.sol @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "./Structs.sol"; + +// The role of this library is to check for a given AuthRequest if there is a matching Auth in the response +// It returns a level of matching between the AuthRequest and the Auth in the response +// The level of matching is a number between 0 and 7 (000 to 111 in binary) +// The level of matching is calculated by adding the following values: +// 1 if the authType in the AuthRequest is the same as the authType in the Auth +// 2 if the isAnon in the AuthRequest is the same as the isAnon in the Auth +// 4 if the userId in the AuthRequest is the same as the userId in the Auth +// The level of matching is then used to determine if the AuthRequest is fulfilled or not +library AuthMatchingLib { + error AuthInRequestNotFoundInResponse( + uint8 requestAuthType, + bool requestIsAnon, + uint256 requestUserId, + bytes requestExtraData + ); + error AuthIsAnonAndUserIdNotFound(bool requestIsAnon, uint256 requestUserId); + error AuthTypeAndUserIdNotFound(uint8 requestAuthType, uint256 requestUserId); + error AuthUserIdNotFound(uint256 requestUserId); + error AuthTypeAndIsAnonNotFound(uint8 requestAuthType, bool requestIsAnon); + error AuthIsAnonNotFound(bool requestIsAnon); + error AuthTypeNotFound(uint8 requestAuthType); + + // Check if the AuthRequest is fulfilled by the Auth in the response + // and return the level of matching between the AuthRequest and the Auth in the response + function _matchLevel( + Auth memory auth, + AuthRequest memory authRequest + ) internal pure returns (uint8) { + uint8 matchingPropertiesLevel = 0; + + if (auth.authType == authRequest.authType) { + matchingPropertiesLevel += 1; // 001 + } + if (auth.isAnon == authRequest.isAnon) { + matchingPropertiesLevel += 2; // 010 + } + + if (authRequest.authType == AuthType.VAULT) { + // If authType is Vault the user can't choose a particular userId + // It will be always defined as userId = Hash(VaultSecret, AppId) + // There is then no specific constraint on the isSelectableByUser and userId properties) + matchingPropertiesLevel += 4; // 100 + } else if ((authRequest.isSelectableByUser == false) && (auth.userId == authRequest.userId)) { + // if the userId in the auth request can NOT be chosen by the user when generating the proof (isSelectableByUser == true) + // we check if the userId of the auth in the request matches the userId of the auth in the response + matchingPropertiesLevel += 4; // 100 + } else if (authRequest.isSelectableByUser == true) { + // if the userId in the auth request can be chosen by the user when generating the proof (isSelectableByUser == true) + // we dont check if the userId of the auth in the request matches the userId of the auth in the response + // the property is considered as matching + matchingPropertiesLevel += 4; // 100 + } + + return matchingPropertiesLevel; + } + + function handleAuthErrors(uint8 maxMatchingProperties, AuthRequest memory auth) public pure { + // if the maxMatchingProperties is equal to 7 (111 in bits), it means that the auth in the request matches with one of the auths in the response + // otherwise, we can look at the binary representation of the maxMatchingProperties to know which properties are not matching and throw an error (the 0 bits represent the properties that are not matching) + if (maxMatchingProperties == 0) { + // 000 + // no property of the auth in the request matches with any property of the auths in the response + revert AuthInRequestNotFoundInResponse( + uint8(auth.authType), + auth.isAnon, + auth.userId, + auth.extraData + ); + } else if (maxMatchingProperties == 1) { + // 001 + // only the authType property of the auth in the request matches with one of the auths in the response + revert AuthIsAnonAndUserIdNotFound(auth.isAnon, auth.userId); + } else if (maxMatchingProperties == 2) { + // 010 + // only the isAnon property of the auth in the request matches with one of the auths in the response + revert AuthTypeAndUserIdNotFound(uint8(auth.authType), auth.userId); + } else if (maxMatchingProperties == 3) { + // 011 + // only the authType and isAnon properties of the auth in the request match with one of the auths in the response + revert AuthUserIdNotFound(auth.userId); + } else if (maxMatchingProperties == 4) { + // 100 + // only the userId property of the auth in the request matches with one of the auths in the response + revert AuthTypeAndIsAnonNotFound(uint8(auth.authType), auth.isAnon); + } else if (maxMatchingProperties == 5) { + // 101 + // only the authType and userId properties of the auth in the request matches with one of the auths in the response + revert AuthIsAnonNotFound(auth.isAnon); + } else if (maxMatchingProperties == 6) { + // 110 + // only the isAnon and userId properties of the auth in the request matches with one of the auths in the response + revert AuthTypeNotFound(uint8(auth.authType)); + } + } +} diff --git a/src/utils/AuthRequestBuilder.sol b/src/utils/AuthRequestBuilder.sol new file mode 100644 index 0000000..68886c6 --- /dev/null +++ b/src/utils/AuthRequestBuilder.sol @@ -0,0 +1,302 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "./Structs.sol"; + +contract AuthRequestBuilder { + // default values for Auth Request + bool public constant DEFAULT_AUTH_REQUEST_IS_ANON = false; + uint256 public constant DEFAULT_AUTH_REQUEST_USER_ID = 0; + bool public constant DEFAULT_AUTH_REQUEST_IS_OPTIONAL = false; + bytes public constant DEFAULT_AUTH_REQUEST_EXTRA_DATA = ""; + + error InvalidUserIdAndIsSelectableByUserAuthType(); + error InvalidUserIdAndAuthType(); + + function build( + AuthType authType, + bool isAnon, + uint256 userId, + bool isOptional, + bool isSelectableByUser, + bytes memory extraData + ) external pure returns (AuthRequest memory) { + return + _build({ + authType: authType, + isAnon: isAnon, + userId: userId, + isOptional: isOptional, + isSelectableByUser: isSelectableByUser, + extraData: extraData + }); + } + + function build( + AuthType authType, + bool isAnon, + uint256 userId, + bytes memory extraData + ) external pure returns (AuthRequest memory) { + return + _build({ + authType: authType, + isAnon: isAnon, + userId: userId, + isOptional: DEFAULT_AUTH_REQUEST_IS_OPTIONAL, + extraData: extraData + }); + } + + function build(AuthType authType) external pure returns (AuthRequest memory) { + return + _build({ + authType: authType, + isAnon: DEFAULT_AUTH_REQUEST_IS_ANON, + userId: DEFAULT_AUTH_REQUEST_USER_ID, + isOptional: DEFAULT_AUTH_REQUEST_IS_OPTIONAL, + extraData: DEFAULT_AUTH_REQUEST_EXTRA_DATA + }); + } + + function build(AuthType authType, bool isAnon) external pure returns (AuthRequest memory) { + return + _build({ + authType: authType, + isAnon: isAnon, + userId: DEFAULT_AUTH_REQUEST_USER_ID, + isOptional: DEFAULT_AUTH_REQUEST_IS_OPTIONAL, + extraData: DEFAULT_AUTH_REQUEST_EXTRA_DATA + }); + } + + function build(AuthType authType, uint256 userId) external pure returns (AuthRequest memory) { + return + _build({ + authType: authType, + isAnon: DEFAULT_AUTH_REQUEST_IS_ANON, + userId: userId, + isOptional: DEFAULT_AUTH_REQUEST_IS_OPTIONAL, + extraData: DEFAULT_AUTH_REQUEST_EXTRA_DATA + }); + } + + function build( + AuthType authType, + bytes memory extraData + ) external pure returns (AuthRequest memory) { + return + _build({ + authType: authType, + isAnon: DEFAULT_AUTH_REQUEST_IS_ANON, + userId: DEFAULT_AUTH_REQUEST_USER_ID, + isOptional: DEFAULT_AUTH_REQUEST_IS_OPTIONAL, + extraData: extraData + }); + } + + function build( + AuthType authType, + bool isAnon, + uint256 userId + ) external pure returns (AuthRequest memory) { + return + _build({ + authType: authType, + isAnon: isAnon, + userId: userId, + isOptional: DEFAULT_AUTH_REQUEST_IS_OPTIONAL, + extraData: DEFAULT_AUTH_REQUEST_EXTRA_DATA + }); + } + + function build( + AuthType authType, + bool isAnon, + bytes memory extraData + ) external pure returns (AuthRequest memory) { + return + _build({ + authType: authType, + isAnon: isAnon, + userId: DEFAULT_AUTH_REQUEST_USER_ID, + isOptional: DEFAULT_AUTH_REQUEST_IS_OPTIONAL, + extraData: extraData + }); + } + + function build( + AuthType authType, + uint256 userId, + bytes memory extraData + ) external pure returns (AuthRequest memory) { + return + _build({ + authType: authType, + isAnon: DEFAULT_AUTH_REQUEST_IS_ANON, + userId: userId, + isOptional: DEFAULT_AUTH_REQUEST_IS_OPTIONAL, + extraData: extraData + }); + } + + // allow dev to choose for isOptional + // the user is ask to choose isSelectableByUser to avoid the function signature collision + // between build(AuthType authType, bool isOptional) and build(AuthType authType, bool isAnon) + + function build( + AuthType authType, + bool isOptional, + bool isSelectableByUser + ) external pure returns (AuthRequest memory) { + return + _build({ + authType: authType, + isAnon: DEFAULT_AUTH_REQUEST_IS_ANON, + userId: DEFAULT_AUTH_REQUEST_USER_ID, + isOptional: isOptional, + isSelectableByUser: isSelectableByUser, + extraData: DEFAULT_AUTH_REQUEST_EXTRA_DATA + }); + } + + function build( + AuthType authType, + bool isOptional, + bool isSelectableByUser, + uint256 userId + ) external pure returns (AuthRequest memory) { + return + _build({ + authType: authType, + isAnon: DEFAULT_AUTH_REQUEST_IS_ANON, + userId: userId, + isOptional: isOptional, + isSelectableByUser: isSelectableByUser, + extraData: DEFAULT_AUTH_REQUEST_EXTRA_DATA + }); + } + + // the user is ask to choose isSelectableByUser to avoid the function signature collision + // between build(AuthType authType, bool isAnon, bool isOptional) and build(AuthType authType, bool isOptional, bool isSelectableByUser) + + function build( + AuthType authType, + bool isAnon, + bool isOptional, + bool isSelectableByUser + ) external pure returns (AuthRequest memory) { + return + _build({ + authType: authType, + isAnon: isAnon, + userId: DEFAULT_AUTH_REQUEST_USER_ID, + isOptional: isOptional, + isSelectableByUser: isSelectableByUser, + extraData: DEFAULT_AUTH_REQUEST_EXTRA_DATA + }); + } + + function build( + AuthType authType, + uint256 userId, + bool isOptional + ) external pure returns (AuthRequest memory) { + return + _build({ + authType: authType, + isAnon: DEFAULT_AUTH_REQUEST_IS_ANON, + userId: userId, + isOptional: isOptional, + extraData: DEFAULT_AUTH_REQUEST_EXTRA_DATA + }); + } + + function build( + AuthType authType, + bool isAnon, + uint256 userId, + bool isOptional + ) external pure returns (AuthRequest memory) { + return + _build({ + authType: authType, + isAnon: isAnon, + userId: userId, + isOptional: isOptional, + extraData: DEFAULT_AUTH_REQUEST_EXTRA_DATA + }); + } + + function _build( + AuthType authType, + bool isAnon, + uint256 userId, + bool isOptional, + bytes memory extraData + ) internal pure returns (AuthRequest memory) { + return + _build({ + authType: authType, + isAnon: isAnon, + userId: userId, + isOptional: isOptional, + isSelectableByUser: _authIsSelectableDefaultValue(authType, userId), + extraData: extraData + }); + } + + function _build( + AuthType authType, + bool isAnon, + uint256 userId, + bool isOptional, + bool isSelectableByUser, + bytes memory extraData + ) internal pure returns (AuthRequest memory) { + // When `userId` is 0, it means the app does not require a specific auth account and the user needs + // to choose the account they want to use for the app. + // When `isSelectableByUser` is true, the user can select the account they want to use. + // The combination of `userId = 0` and `isSelectableByUser = false` does not make sense and should not be used. + // If this combination is detected, the function will revert with an error. + if (authType != AuthType.VAULT && userId == 0 && isSelectableByUser == false) { + revert InvalidUserIdAndIsSelectableByUserAuthType(); + } + // When requesting an authType VAULT, the `userId` must be 0 and isSelectableByUser must be true. + if (authType == AuthType.VAULT && userId != 0 && isSelectableByUser == false) { + revert InvalidUserIdAndAuthType(); + } + return + AuthRequest({ + authType: authType, + isAnon: isAnon, + userId: userId, + isOptional: isOptional, + isSelectableByUser: isSelectableByUser, + extraData: extraData + }); + } + + function _authIsSelectableDefaultValue( + AuthType authType, + uint256 requestedUserId + ) internal pure returns (bool) { + // isSelectableByUser value should always be false in case of VAULT authType. + // This is because the user can't select the account they want to use for the app. + // the userId = Hash(VaultSecret, AppId) in the case of VAULT authType. + if (authType == AuthType.VAULT) { + return false; + } + // When `requestedUserId` is 0, it means no specific auth account is requested by the app, + // so we want the default value for `isSelectableByUser` to be `true`. + if (requestedUserId == 0) { + return true; + } + // When `requestedUserId` is not 0, it means a specific auth account is requested by the app, + // so we want the default value for `isSelectableByUser` to be `false`. + else { + return false; + } + // However, the dev can still override this default value by setting `isSelectableByUser` to `true`. + } +} diff --git a/src/utils/ClaimBuilder.sol b/src/utils/ClaimBuilder.sol new file mode 100644 index 0000000..bab321f --- /dev/null +++ b/src/utils/ClaimBuilder.sol @@ -0,0 +1,274 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "./Structs.sol"; + +library ClaimBuilder { + // default value for Claim Request + bytes16 public constant DEFAULT_CLAIM_GROUP_TIMESTAMP = bytes16("latest"); + uint256 public constant DEFAULT_CLAIM_VALUE = 1; + ClaimType public constant DEFAULT_CLAIM_TYPE = ClaimType.GTE; + bool public constant DEFAULT_CLAIM_IS_SELECTABLE_BY_USER = true; + bytes public constant DEFAULT_CLAIM_EXTRA_DATA = ""; + + function build( + bytes16 groupId, + bytes16 groupTimestamp, + uint256 value, + ClaimType claimType, + bool isSelectableByUser, + bytes memory extraData + ) external pure returns (Claim memory) { + return + Claim({ + claimType: claimType, + groupId: groupId, + groupTimestamp: groupTimestamp, + value: value, + isSelectableByUser: isSelectableByUser, + extraData: extraData + }); + } + + function build( + bytes16 groupId, + bytes16 groupTimestamp, + uint256 value, + ClaimType claimType, + bytes memory extraData + ) external pure returns (Claim memory) { + return + Claim({ + claimType: claimType, + groupId: groupId, + groupTimestamp: groupTimestamp, + value: value, + isSelectableByUser: DEFAULT_CLAIM_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } + + function build(bytes16 groupId) external pure returns (Claim memory) { + return + Claim({ + groupId: groupId, + groupTimestamp: DEFAULT_CLAIM_GROUP_TIMESTAMP, + value: DEFAULT_CLAIM_VALUE, + claimType: DEFAULT_CLAIM_TYPE, + isSelectableByUser: DEFAULT_CLAIM_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_CLAIM_EXTRA_DATA + }); + } + + function build(bytes16 groupId, bytes16 groupTimestamp) external pure returns (Claim memory) { + return + Claim({ + groupId: groupId, + groupTimestamp: groupTimestamp, + value: DEFAULT_CLAIM_VALUE, + claimType: DEFAULT_CLAIM_TYPE, + isSelectableByUser: DEFAULT_CLAIM_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_CLAIM_EXTRA_DATA + }); + } + + function build(bytes16 groupId, uint256 value) external pure returns (Claim memory) { + return + Claim({ + groupId: groupId, + groupTimestamp: DEFAULT_CLAIM_GROUP_TIMESTAMP, + value: value, + claimType: DEFAULT_CLAIM_TYPE, + isSelectableByUser: DEFAULT_CLAIM_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_CLAIM_EXTRA_DATA + }); + } + + function build(bytes16 groupId, ClaimType claimType) external pure returns (Claim memory) { + return + Claim({ + groupId: groupId, + groupTimestamp: DEFAULT_CLAIM_GROUP_TIMESTAMP, + value: DEFAULT_CLAIM_VALUE, + claimType: claimType, + isSelectableByUser: DEFAULT_CLAIM_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_CLAIM_EXTRA_DATA + }); + } + + function build(bytes16 groupId, bytes memory extraData) external pure returns (Claim memory) { + return + Claim({ + groupId: groupId, + groupTimestamp: DEFAULT_CLAIM_GROUP_TIMESTAMP, + value: DEFAULT_CLAIM_VALUE, + claimType: DEFAULT_CLAIM_TYPE, + isSelectableByUser: DEFAULT_CLAIM_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } + + function build( + bytes16 groupId, + bytes16 groupTimestamp, + uint256 value + ) external pure returns (Claim memory) { + return + Claim({ + groupId: groupId, + groupTimestamp: groupTimestamp, + value: value, + claimType: DEFAULT_CLAIM_TYPE, + isSelectableByUser: DEFAULT_CLAIM_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_CLAIM_EXTRA_DATA + }); + } + + function build( + bytes16 groupId, + bytes16 groupTimestamp, + ClaimType claimType + ) external pure returns (Claim memory) { + return + Claim({ + groupId: groupId, + groupTimestamp: groupTimestamp, + value: DEFAULT_CLAIM_VALUE, + claimType: claimType, + isSelectableByUser: DEFAULT_CLAIM_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_CLAIM_EXTRA_DATA + }); + } + + function build( + bytes16 groupId, + bytes16 groupTimestamp, + bytes memory extraData + ) external pure returns (Claim memory) { + return + Claim({ + groupId: groupId, + groupTimestamp: groupTimestamp, + value: DEFAULT_CLAIM_VALUE, + claimType: DEFAULT_CLAIM_TYPE, + isSelectableByUser: DEFAULT_CLAIM_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } + + function build( + bytes16 groupId, + uint256 value, + ClaimType claimType + ) external pure returns (Claim memory) { + return + Claim({ + groupId: groupId, + groupTimestamp: DEFAULT_CLAIM_GROUP_TIMESTAMP, + value: value, + claimType: claimType, + isSelectableByUser: DEFAULT_CLAIM_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_CLAIM_EXTRA_DATA + }); + } + + function build( + bytes16 groupId, + uint256 value, + bytes memory extraData + ) external pure returns (Claim memory) { + return + Claim({ + groupId: groupId, + groupTimestamp: DEFAULT_CLAIM_GROUP_TIMESTAMP, + value: value, + claimType: DEFAULT_CLAIM_TYPE, + isSelectableByUser: DEFAULT_CLAIM_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } + + function build( + bytes16 groupId, + ClaimType claimType, + bytes memory extraData + ) external pure returns (Claim memory) { + return + Claim({ + groupId: groupId, + groupTimestamp: DEFAULT_CLAIM_GROUP_TIMESTAMP, + value: DEFAULT_CLAIM_VALUE, + claimType: claimType, + isSelectableByUser: DEFAULT_CLAIM_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } + + function build( + bytes16 groupId, + bytes16 groupTimestamp, + uint256 value, + ClaimType claimType + ) external pure returns (Claim memory) { + return + Claim({ + groupId: groupId, + groupTimestamp: groupTimestamp, + value: value, + claimType: claimType, + isSelectableByUser: DEFAULT_CLAIM_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_CLAIM_EXTRA_DATA + }); + } + + function build( + bytes16 groupId, + bytes16 groupTimestamp, + uint256 value, + bytes memory extraData + ) external pure returns (Claim memory) { + return + Claim({ + groupId: groupId, + groupTimestamp: groupTimestamp, + value: value, + claimType: DEFAULT_CLAIM_TYPE, + isSelectableByUser: DEFAULT_CLAIM_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } + + function build( + bytes16 groupId, + bytes16 groupTimestamp, + ClaimType claimType, + bytes memory extraData + ) external pure returns (Claim memory) { + return + Claim({ + groupId: groupId, + groupTimestamp: groupTimestamp, + value: DEFAULT_CLAIM_VALUE, + claimType: claimType, + isSelectableByUser: DEFAULT_CLAIM_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } + + function build( + bytes16 groupId, + uint256 value, + ClaimType claimType, + bytes memory extraData + ) external pure returns (Claim memory) { + return + Claim({ + groupId: groupId, + groupTimestamp: DEFAULT_CLAIM_GROUP_TIMESTAMP, + value: value, + claimType: claimType, + isSelectableByUser: DEFAULT_CLAIM_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } +} diff --git a/src/utils/ClaimMatchingLib.sol b/src/utils/ClaimMatchingLib.sol new file mode 100644 index 0000000..693f5d3 --- /dev/null +++ b/src/utils/ClaimMatchingLib.sol @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "./Structs.sol"; + +library ClaimMatchingLib { + error ClaimInRequestNotFoundInResponse( + uint8 responseClaimType, + bytes16 responseClaimGroupId, + bytes16 responseClaimGroupTimestamp, + uint256 responseClaimValue, + bytes responseExtraData + ); + error ClaimGroupIdAndGroupTimestampNotFound( + bytes16 requestClaimGroupId, + bytes16 requestClaimGroupTimestamp + ); + error ClaimTypeAndGroupTimestampNotFound( + uint8 requestClaimType, + bytes16 requestClaimGroupTimestamp + ); + error ClaimGroupTimestampNotFound(bytes16 requestClaimGroupTimestamp); + error ClaimTypeAndGroupIdNotFound(uint8 requestClaimType, bytes16 requestClaimGroupId); + error ClaimGroupIdNotFound(bytes16 requestClaimGroupId); + error ClaimTypeNotFound(uint8 requestClaimType); + + // Check if the AuthRequest is fulfilled by the Auth in the response + // and return the level of matching between the AuthRequest and the Auth in the response + function _matchLevel( + Claim memory claim, + ClaimRequest memory claimRequest + ) internal pure returns (uint8) { + uint8 matchingPropertiesLevel = 0; + + if (claim.claimType == claimRequest.claimType) { + matchingPropertiesLevel += 1; // 001 + } + if (claim.groupId == claimRequest.groupId) { + matchingPropertiesLevel += 2; // 010 + } + if (claim.groupTimestamp == claimRequest.groupTimestamp) { + matchingPropertiesLevel += 4; // 100 + } + + return matchingPropertiesLevel; + } + + function handleClaimErrors(uint8 maxMatchingProperties, ClaimRequest memory claim) public pure { + // if the maxMatchingProperties is equal to 7 (111 in bits), it means that the claim in the request matches with one of the claims in the response + // otherwise, we can look at the binary representation of the maxMatchingProperties to know which properties are not matching and throw an error (the 0 bits represent the properties that are not matching) + if (maxMatchingProperties == 0) { + // 000 + // no property of the claim in the request matches with any property of the claims in the response + revert ClaimInRequestNotFoundInResponse( + uint8(claim.claimType), + claim.groupId, + claim.groupTimestamp, + claim.value, + claim.extraData + ); + } else if (maxMatchingProperties == 1) { + // 001 + // only the claimType property of the claim in the request matches with one of the claims in the response + revert ClaimGroupIdAndGroupTimestampNotFound(claim.groupId, claim.groupTimestamp); + } else if (maxMatchingProperties == 2) { + // 010 + // only the groupId property of the claim in the request matches with one of the claims in the response + revert ClaimTypeAndGroupTimestampNotFound(uint8(claim.claimType), claim.groupTimestamp); + } else if (maxMatchingProperties == 3) { + // 011 + // only the claimType and groupId properties of the claim in the request match with one of the claims in the response + revert ClaimGroupTimestampNotFound(claim.groupTimestamp); + } else if (maxMatchingProperties == 4) { + // 100 + // only the groupTimestamp property of the claim in the request matches with one of the claims in the response + revert ClaimTypeAndGroupIdNotFound(uint8(claim.claimType), claim.groupId); + } else if (maxMatchingProperties == 5) { + // 101 + // only the claimType and groupTimestamp properties of the claim in the request matches with one of the claims in the response + revert ClaimGroupIdNotFound(claim.groupId); + } else if (maxMatchingProperties == 6) { + // 110 + // only the groupId and groupTimestamp properties of the claim in the request matches with one of the claims in the response + revert ClaimTypeNotFound(uint8(claim.claimType)); + } + } +} diff --git a/src/utils/ClaimRequestBuilder.sol b/src/utils/ClaimRequestBuilder.sol new file mode 100644 index 0000000..c415d00 --- /dev/null +++ b/src/utils/ClaimRequestBuilder.sol @@ -0,0 +1,453 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "./Structs.sol"; + +contract ClaimRequestBuilder { + // default value for Claim Request + bytes16 public constant DEFAULT_CLAIM_REQUEST_GROUP_TIMESTAMP = bytes16("latest"); + uint256 public constant DEFAULT_CLAIM_REQUEST_VALUE = 1; + ClaimType public constant DEFAULT_CLAIM_REQUEST_TYPE = ClaimType.GTE; + bool public constant DEFAULT_CLAIM_REQUEST_IS_OPTIONAL = false; + bool public constant DEFAULT_CLAIM_REQUEST_IS_SELECTABLE_BY_USER = true; + bytes public constant DEFAULT_CLAIM_REQUEST_EXTRA_DATA = ""; + + function build( + bytes16 groupId, + bytes16 groupTimestamp, + uint256 value, + ClaimType claimType, + bool isOptional, + bool isSelectableByUser, + bytes memory extraData + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + claimType: claimType, + groupId: groupId, + groupTimestamp: groupTimestamp, + value: value, + isOptional: isOptional, + isSelectableByUser: isSelectableByUser, + extraData: extraData + }); + } + + function build( + bytes16 groupId, + bytes16 groupTimestamp, + uint256 value, + ClaimType claimType, + bytes memory extraData + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + claimType: claimType, + groupId: groupId, + groupTimestamp: groupTimestamp, + value: value, + isOptional: DEFAULT_CLAIM_REQUEST_IS_OPTIONAL, + isSelectableByUser: DEFAULT_CLAIM_REQUEST_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } + + function build(bytes16 groupId) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: DEFAULT_CLAIM_REQUEST_GROUP_TIMESTAMP, + value: DEFAULT_CLAIM_REQUEST_VALUE, + claimType: DEFAULT_CLAIM_REQUEST_TYPE, + isOptional: DEFAULT_CLAIM_REQUEST_IS_OPTIONAL, + isSelectableByUser: DEFAULT_CLAIM_REQUEST_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_CLAIM_REQUEST_EXTRA_DATA + }); + } + + function build( + bytes16 groupId, + bytes16 groupTimestamp + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: groupTimestamp, + value: DEFAULT_CLAIM_REQUEST_VALUE, + claimType: DEFAULT_CLAIM_REQUEST_TYPE, + isOptional: DEFAULT_CLAIM_REQUEST_IS_OPTIONAL, + isSelectableByUser: DEFAULT_CLAIM_REQUEST_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_CLAIM_REQUEST_EXTRA_DATA + }); + } + + function build(bytes16 groupId, uint256 value) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: DEFAULT_CLAIM_REQUEST_GROUP_TIMESTAMP, + value: value, + claimType: DEFAULT_CLAIM_REQUEST_TYPE, + isOptional: DEFAULT_CLAIM_REQUEST_IS_OPTIONAL, + isSelectableByUser: DEFAULT_CLAIM_REQUEST_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_CLAIM_REQUEST_EXTRA_DATA + }); + } + + function build(bytes16 groupId, ClaimType claimType) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: DEFAULT_CLAIM_REQUEST_GROUP_TIMESTAMP, + value: DEFAULT_CLAIM_REQUEST_VALUE, + claimType: claimType, + isOptional: DEFAULT_CLAIM_REQUEST_IS_OPTIONAL, + isSelectableByUser: DEFAULT_CLAIM_REQUEST_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_CLAIM_REQUEST_EXTRA_DATA + }); + } + + function build( + bytes16 groupId, + bytes memory extraData + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: DEFAULT_CLAIM_REQUEST_GROUP_TIMESTAMP, + value: DEFAULT_CLAIM_REQUEST_VALUE, + claimType: DEFAULT_CLAIM_REQUEST_TYPE, + isOptional: DEFAULT_CLAIM_REQUEST_IS_OPTIONAL, + isSelectableByUser: DEFAULT_CLAIM_REQUEST_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } + + function build( + bytes16 groupId, + bytes16 groupTimestamp, + uint256 value + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: groupTimestamp, + value: value, + claimType: DEFAULT_CLAIM_REQUEST_TYPE, + isOptional: DEFAULT_CLAIM_REQUEST_IS_OPTIONAL, + isSelectableByUser: DEFAULT_CLAIM_REQUEST_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_CLAIM_REQUEST_EXTRA_DATA + }); + } + + function build( + bytes16 groupId, + bytes16 groupTimestamp, + ClaimType claimType + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: groupTimestamp, + value: DEFAULT_CLAIM_REQUEST_VALUE, + claimType: claimType, + isOptional: DEFAULT_CLAIM_REQUEST_IS_OPTIONAL, + isSelectableByUser: DEFAULT_CLAIM_REQUEST_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_CLAIM_REQUEST_EXTRA_DATA + }); + } + + function build( + bytes16 groupId, + bytes16 groupTimestamp, + bytes memory extraData + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: groupTimestamp, + value: DEFAULT_CLAIM_REQUEST_VALUE, + claimType: DEFAULT_CLAIM_REQUEST_TYPE, + isOptional: DEFAULT_CLAIM_REQUEST_IS_OPTIONAL, + isSelectableByUser: DEFAULT_CLAIM_REQUEST_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } + + function build( + bytes16 groupId, + uint256 value, + ClaimType claimType + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: DEFAULT_CLAIM_REQUEST_GROUP_TIMESTAMP, + value: value, + claimType: claimType, + isOptional: DEFAULT_CLAIM_REQUEST_IS_OPTIONAL, + isSelectableByUser: DEFAULT_CLAIM_REQUEST_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_CLAIM_REQUEST_EXTRA_DATA + }); + } + + function build( + bytes16 groupId, + uint256 value, + bytes memory extraData + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: DEFAULT_CLAIM_REQUEST_GROUP_TIMESTAMP, + value: value, + claimType: DEFAULT_CLAIM_REQUEST_TYPE, + isOptional: DEFAULT_CLAIM_REQUEST_IS_OPTIONAL, + isSelectableByUser: DEFAULT_CLAIM_REQUEST_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } + + function build( + bytes16 groupId, + ClaimType claimType, + bytes memory extraData + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: DEFAULT_CLAIM_REQUEST_GROUP_TIMESTAMP, + value: DEFAULT_CLAIM_REQUEST_VALUE, + claimType: claimType, + isOptional: DEFAULT_CLAIM_REQUEST_IS_OPTIONAL, + isSelectableByUser: DEFAULT_CLAIM_REQUEST_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } + + function build( + bytes16 groupId, + bytes16 groupTimestamp, + uint256 value, + ClaimType claimType + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: groupTimestamp, + value: value, + claimType: claimType, + isOptional: DEFAULT_CLAIM_REQUEST_IS_OPTIONAL, + isSelectableByUser: DEFAULT_CLAIM_REQUEST_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_CLAIM_REQUEST_EXTRA_DATA + }); + } + + function build( + bytes16 groupId, + bytes16 groupTimestamp, + uint256 value, + bytes memory extraData + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: groupTimestamp, + value: value, + claimType: DEFAULT_CLAIM_REQUEST_TYPE, + isOptional: DEFAULT_CLAIM_REQUEST_IS_OPTIONAL, + isSelectableByUser: DEFAULT_CLAIM_REQUEST_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } + + function build( + bytes16 groupId, + bytes16 groupTimestamp, + ClaimType claimType, + bytes memory extraData + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: groupTimestamp, + value: DEFAULT_CLAIM_REQUEST_VALUE, + claimType: claimType, + isOptional: DEFAULT_CLAIM_REQUEST_IS_OPTIONAL, + isSelectableByUser: DEFAULT_CLAIM_REQUEST_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } + + function build( + bytes16 groupId, + uint256 value, + ClaimType claimType, + bytes memory extraData + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: DEFAULT_CLAIM_REQUEST_GROUP_TIMESTAMP, + value: value, + claimType: claimType, + isOptional: DEFAULT_CLAIM_REQUEST_IS_OPTIONAL, + isSelectableByUser: DEFAULT_CLAIM_REQUEST_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } + + // allow dev to choose for isOptional + // we force to also set isSelectableByUser + // otherwise function signatures would be colliding + // between build(bytes16 groupId, bool isOptional) and build(bytes16 groupId, bool isSelectableByUser) + // we keep this logic for all function signature combinations + + function build( + bytes16 groupId, + bool isOptional, + bool isSelectableByUser + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: DEFAULT_CLAIM_REQUEST_GROUP_TIMESTAMP, + value: DEFAULT_CLAIM_REQUEST_VALUE, + claimType: DEFAULT_CLAIM_REQUEST_TYPE, + isOptional: isOptional, + isSelectableByUser: isSelectableByUser, + extraData: DEFAULT_CLAIM_REQUEST_EXTRA_DATA + }); + } + + function build( + bytes16 groupId, + bytes16 groupTimestamp, + bool isOptional, + bool isSelectableByUser + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: groupTimestamp, + value: DEFAULT_CLAIM_REQUEST_VALUE, + claimType: DEFAULT_CLAIM_REQUEST_TYPE, + isOptional: isOptional, + isSelectableByUser: isSelectableByUser, + extraData: DEFAULT_CLAIM_REQUEST_EXTRA_DATA + }); + } + + function build( + bytes16 groupId, + uint256 value, + bool isOptional, + bool isSelectableByUser + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: DEFAULT_CLAIM_REQUEST_GROUP_TIMESTAMP, + value: value, + claimType: DEFAULT_CLAIM_REQUEST_TYPE, + isOptional: isOptional, + isSelectableByUser: isSelectableByUser, + extraData: DEFAULT_CLAIM_REQUEST_EXTRA_DATA + }); + } + + function build( + bytes16 groupId, + ClaimType claimType, + bool isOptional, + bool isSelectableByUser + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: DEFAULT_CLAIM_REQUEST_GROUP_TIMESTAMP, + value: DEFAULT_CLAIM_REQUEST_VALUE, + claimType: claimType, + isOptional: isOptional, + isSelectableByUser: isSelectableByUser, + extraData: DEFAULT_CLAIM_REQUEST_EXTRA_DATA + }); + } + + function build( + bytes16 groupId, + bytes16 groupTimestamp, + uint256 value, + bool isOptional, + bool isSelectableByUser + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: groupTimestamp, + value: value, + claimType: DEFAULT_CLAIM_REQUEST_TYPE, + isOptional: isOptional, + isSelectableByUser: isSelectableByUser, + extraData: DEFAULT_CLAIM_REQUEST_EXTRA_DATA + }); + } + + function build( + bytes16 groupId, + bytes16 groupTimestamp, + ClaimType claimType, + bool isOptional, + bool isSelectableByUser + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: groupTimestamp, + value: DEFAULT_CLAIM_REQUEST_VALUE, + claimType: claimType, + isOptional: isOptional, + isSelectableByUser: isSelectableByUser, + extraData: DEFAULT_CLAIM_REQUEST_EXTRA_DATA + }); + } + + function build( + bytes16 groupId, + uint256 value, + ClaimType claimType, + bool isOptional, + bool isSelectableByUser + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: DEFAULT_CLAIM_REQUEST_GROUP_TIMESTAMP, + value: value, + claimType: claimType, + isOptional: isOptional, + isSelectableByUser: isSelectableByUser, + extraData: DEFAULT_CLAIM_REQUEST_EXTRA_DATA + }); + } + + function build( + bytes16 groupId, + bytes16 groupTimestamp, + uint256 value, + ClaimType claimType, + bool isOptional, + bool isSelectableByUser + ) external pure returns (ClaimRequest memory) { + return + ClaimRequest({ + groupId: groupId, + groupTimestamp: groupTimestamp, + value: value, + claimType: claimType, + isOptional: isOptional, + isSelectableByUser: isSelectableByUser, + extraData: DEFAULT_CLAIM_REQUEST_EXTRA_DATA + }); + } +} diff --git a/src/utils/Fmt.sol b/src/utils/Fmt.sol new file mode 100644 index 0000000..05279c2 --- /dev/null +++ b/src/utils/Fmt.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "./Structs.sol"; +import "forge-std/console.sol"; + +library fmt { + function printAuthRequest(AuthRequest memory auth, string memory indication) external view { + console.log(indication); + console.log("authType", uint8(auth.authType)); + console.log("isAnon", auth.isAnon); + console.log("userId", auth.userId); + console.log("isOptional", auth.isOptional); + console.log("isSelectableByUser", auth.isSelectableByUser); + console.log("extraData"); + console.logBytes(auth.extraData); + } + + function printAuth(Auth memory auth, string memory indication) external view { + console.log(indication); + console.log("authType", uint8(auth.authType)); + console.log("isAnon", auth.isAnon); + console.log("userId", auth.userId); + console.log("isSelectableByuser", auth.isSelectableByUser); + console.log("extraData"); + console.logBytes(auth.extraData); + } +} diff --git a/src/utils/RequestBuilder.sol b/src/utils/RequestBuilder.sol new file mode 100644 index 0000000..76199ad --- /dev/null +++ b/src/utils/RequestBuilder.sol @@ -0,0 +1,402 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "./Structs.sol"; +import {SignatureBuilder} from "./SignatureBuilder.sol"; + +contract RequestBuilder { + // default value for namespace + bytes16 public constant DEFAULT_NAMESPACE = bytes16(keccak256("main")); + // default value for a signature request + SignatureRequest DEFAULT_SIGNATURE_REQUEST = + SignatureRequest({ + message: "MESSAGE_SELECTED_BY_USER", + isSelectableByUser: false, + extraData: "" + }); + + function build( + AuthRequest memory auth, + ClaimRequest memory claim, + SignatureRequest memory signature, + bytes16 namespace + ) external pure returns (SismoConnectRequest memory) { + AuthRequest[] memory auths = new AuthRequest[](1); + auths[0] = auth; + ClaimRequest[] memory claims = new ClaimRequest[](1); + claims[0] = claim; + return ( + SismoConnectRequest({ + namespace: namespace, + auths: auths, + claims: claims, + signature: signature + }) + ); + } + + function build( + AuthRequest memory auth, + ClaimRequest memory claim, + bytes16 namespace + ) external view returns (SismoConnectRequest memory) { + AuthRequest[] memory auths = new AuthRequest[](1); + auths[0] = auth; + ClaimRequest[] memory claims = new ClaimRequest[](1); + claims[0] = claim; + return ( + SismoConnectRequest({ + namespace: namespace, + auths: auths, + claims: claims, + signature: DEFAULT_SIGNATURE_REQUEST + }) + ); + } + + function build( + ClaimRequest memory claim, + SignatureRequest memory signature, + bytes16 namespace + ) external pure returns (SismoConnectRequest memory) { + AuthRequest[] memory auths = new AuthRequest[](0); + ClaimRequest[] memory claims = new ClaimRequest[](1); + claims[0] = claim; + return ( + SismoConnectRequest({ + namespace: namespace, + auths: auths, + claims: claims, + signature: signature + }) + ); + } + + function build( + ClaimRequest memory claim, + bytes16 namespace + ) external view returns (SismoConnectRequest memory) { + AuthRequest[] memory auths = new AuthRequest[](0); + ClaimRequest[] memory claims = new ClaimRequest[](1); + claims[0] = claim; + return ( + SismoConnectRequest({ + namespace: namespace, + auths: auths, + claims: claims, + signature: DEFAULT_SIGNATURE_REQUEST + }) + ); + } + + function build( + AuthRequest memory auth, + SignatureRequest memory signature, + bytes16 namespace + ) external pure returns (SismoConnectRequest memory) { + AuthRequest[] memory auths = new AuthRequest[](1); + auths[0] = auth; + ClaimRequest[] memory claims = new ClaimRequest[](0); + return ( + SismoConnectRequest({ + namespace: namespace, + auths: auths, + claims: claims, + signature: signature + }) + ); + } + + function build( + AuthRequest memory auth, + bytes16 namespace + ) external view returns (SismoConnectRequest memory) { + AuthRequest[] memory auths = new AuthRequest[](1); + auths[0] = auth; + ClaimRequest[] memory claims = new ClaimRequest[](0); + return ( + SismoConnectRequest({ + namespace: namespace, + auths: auths, + claims: claims, + signature: DEFAULT_SIGNATURE_REQUEST + }) + ); + } + + function build( + AuthRequest memory auth, + ClaimRequest memory claim, + SignatureRequest memory signature + ) external pure returns (SismoConnectRequest memory) { + AuthRequest[] memory auths = new AuthRequest[](1); + auths[0] = auth; + ClaimRequest[] memory claims = new ClaimRequest[](1); + claims[0] = claim; + return ( + SismoConnectRequest({ + namespace: DEFAULT_NAMESPACE, + auths: auths, + claims: claims, + signature: signature + }) + ); + } + + function build( + AuthRequest memory auth, + ClaimRequest memory claim + ) external view returns (SismoConnectRequest memory) { + AuthRequest[] memory auths = new AuthRequest[](1); + auths[0] = auth; + ClaimRequest[] memory claims = new ClaimRequest[](1); + claims[0] = claim; + return ( + SismoConnectRequest({ + namespace: DEFAULT_NAMESPACE, + auths: auths, + claims: claims, + signature: DEFAULT_SIGNATURE_REQUEST + }) + ); + } + + function build( + AuthRequest memory auth, + SignatureRequest memory signature + ) external pure returns (SismoConnectRequest memory) { + AuthRequest[] memory auths = new AuthRequest[](1); + auths[0] = auth; + ClaimRequest[] memory claims = new ClaimRequest[](0); + return ( + SismoConnectRequest({ + namespace: DEFAULT_NAMESPACE, + auths: auths, + claims: claims, + signature: signature + }) + ); + } + + function build(AuthRequest memory auth) external view returns (SismoConnectRequest memory) { + AuthRequest[] memory auths = new AuthRequest[](1); + auths[0] = auth; + ClaimRequest[] memory claims = new ClaimRequest[](0); + return ( + SismoConnectRequest({ + namespace: DEFAULT_NAMESPACE, + auths: auths, + claims: claims, + signature: DEFAULT_SIGNATURE_REQUEST + }) + ); + } + + function build( + ClaimRequest memory claim, + SignatureRequest memory signature + ) external pure returns (SismoConnectRequest memory) { + AuthRequest[] memory auths = new AuthRequest[](0); + ClaimRequest[] memory claims = new ClaimRequest[](1); + claims[0] = claim; + return ( + SismoConnectRequest({ + namespace: DEFAULT_NAMESPACE, + auths: auths, + claims: claims, + signature: signature + }) + ); + } + + function build(ClaimRequest memory claim) external view returns (SismoConnectRequest memory) { + AuthRequest[] memory auths = new AuthRequest[](0); + ClaimRequest[] memory claims = new ClaimRequest[](1); + claims[0] = claim; + return ( + SismoConnectRequest({ + namespace: DEFAULT_NAMESPACE, + auths: auths, + claims: claims, + signature: DEFAULT_SIGNATURE_REQUEST + }) + ); + } + + // build with arrays for auths and claims + function build( + AuthRequest[] memory auths, + ClaimRequest[] memory claims, + SignatureRequest memory signature, + bytes16 namespace + ) external pure returns (SismoConnectRequest memory) { + return ( + SismoConnectRequest({ + namespace: namespace, + auths: auths, + claims: claims, + signature: signature + }) + ); + } + + function build( + AuthRequest[] memory auths, + ClaimRequest[] memory claims, + bytes16 namespace + ) external view returns (SismoConnectRequest memory) { + return ( + SismoConnectRequest({ + namespace: namespace, + auths: auths, + claims: claims, + signature: DEFAULT_SIGNATURE_REQUEST + }) + ); + } + + function build( + ClaimRequest[] memory claims, + SignatureRequest memory signature, + bytes16 namespace + ) external pure returns (SismoConnectRequest memory) { + AuthRequest[] memory auths = new AuthRequest[](0); + return ( + SismoConnectRequest({ + namespace: namespace, + auths: auths, + claims: claims, + signature: signature + }) + ); + } + + function build( + ClaimRequest[] memory claims, + bytes16 namespace + ) external view returns (SismoConnectRequest memory) { + AuthRequest[] memory auths = new AuthRequest[](0); + return ( + SismoConnectRequest({ + namespace: namespace, + auths: auths, + claims: claims, + signature: DEFAULT_SIGNATURE_REQUEST + }) + ); + } + + function build( + AuthRequest[] memory auths, + SignatureRequest memory signature, + bytes16 namespace + ) external pure returns (SismoConnectRequest memory) { + ClaimRequest[] memory claims = new ClaimRequest[](0); + return ( + SismoConnectRequest({ + namespace: namespace, + auths: auths, + claims: claims, + signature: signature + }) + ); + } + + function build( + AuthRequest[] memory auths, + bytes16 namespace + ) external view returns (SismoConnectRequest memory) { + ClaimRequest[] memory claims = new ClaimRequest[](0); + return ( + SismoConnectRequest({ + namespace: namespace, + auths: auths, + claims: claims, + signature: DEFAULT_SIGNATURE_REQUEST + }) + ); + } + + function build( + AuthRequest[] memory auths, + ClaimRequest[] memory claims, + SignatureRequest memory signature + ) external pure returns (SismoConnectRequest memory) { + return ( + SismoConnectRequest({ + namespace: DEFAULT_NAMESPACE, + auths: auths, + claims: claims, + signature: signature + }) + ); + } + + function build( + AuthRequest[] memory auths, + ClaimRequest[] memory claims + ) external view returns (SismoConnectRequest memory) { + return ( + SismoConnectRequest({ + namespace: DEFAULT_NAMESPACE, + auths: auths, + claims: claims, + signature: DEFAULT_SIGNATURE_REQUEST + }) + ); + } + + function build( + AuthRequest[] memory auths, + SignatureRequest memory signature + ) external pure returns (SismoConnectRequest memory) { + ClaimRequest[] memory claims = new ClaimRequest[](0); + return ( + SismoConnectRequest({ + namespace: DEFAULT_NAMESPACE, + auths: auths, + claims: claims, + signature: signature + }) + ); + } + + function build(AuthRequest[] memory auths) external view returns (SismoConnectRequest memory) { + ClaimRequest[] memory claims = new ClaimRequest[](0); + return ( + SismoConnectRequest({ + namespace: DEFAULT_NAMESPACE, + auths: auths, + claims: claims, + signature: DEFAULT_SIGNATURE_REQUEST + }) + ); + } + + function build( + ClaimRequest[] memory claims, + SignatureRequest memory signature + ) external pure returns (SismoConnectRequest memory) { + AuthRequest[] memory auths = new AuthRequest[](0); + return ( + SismoConnectRequest({ + namespace: DEFAULT_NAMESPACE, + auths: auths, + claims: claims, + signature: signature + }) + ); + } + + function build(ClaimRequest[] memory claims) external view returns (SismoConnectRequest memory) { + AuthRequest[] memory auths = new AuthRequest[](0); + return ( + SismoConnectRequest({ + namespace: DEFAULT_NAMESPACE, + auths: auths, + claims: claims, + signature: DEFAULT_SIGNATURE_REQUEST + }) + ); + } +} diff --git a/src/utils/SignatureBuilder.sol b/src/utils/SignatureBuilder.sol new file mode 100644 index 0000000..c74c300 --- /dev/null +++ b/src/utils/SignatureBuilder.sol @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "./Structs.sol"; + +contract SignatureBuilder { + // default values for Signature Request + bytes public constant DEFAULT_SIGNATURE_REQUEST_MESSAGE = "MESSAGE_SELECTED_BY_USER"; + bool public constant DEFAULT_SIGNATURE_REQUEST_IS_SELECTABLE_BY_USER = false; + bytes public constant DEFAULT_SIGNATURE_REQUEST_EXTRA_DATA = ""; + + function build(bytes memory message) external pure returns (SignatureRequest memory) { + return + SignatureRequest({ + message: message, + isSelectableByUser: DEFAULT_SIGNATURE_REQUEST_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_SIGNATURE_REQUEST_EXTRA_DATA + }); + } + + function build( + bytes memory message, + bool isSelectableByUser + ) external pure returns (SignatureRequest memory) { + return + SignatureRequest({ + message: message, + isSelectableByUser: isSelectableByUser, + extraData: DEFAULT_SIGNATURE_REQUEST_EXTRA_DATA + }); + } + + function build( + bytes memory message, + bytes memory extraData + ) external pure returns (SignatureRequest memory) { + return + SignatureRequest({ + message: message, + isSelectableByUser: DEFAULT_SIGNATURE_REQUEST_IS_SELECTABLE_BY_USER, + extraData: extraData + }); + } + + function build( + bytes memory message, + bool isSelectableByUser, + bytes memory extraData + ) external pure returns (SignatureRequest memory) { + return + SignatureRequest({ + message: message, + isSelectableByUser: isSelectableByUser, + extraData: extraData + }); + } + + function build(bool isSelectableByUser) external pure returns (SignatureRequest memory) { + return + SignatureRequest({ + message: DEFAULT_SIGNATURE_REQUEST_MESSAGE, + isSelectableByUser: isSelectableByUser, + extraData: DEFAULT_SIGNATURE_REQUEST_EXTRA_DATA + }); + } + + function build( + bool isSelectableByUser, + bytes memory extraData + ) external pure returns (SignatureRequest memory) { + return + SignatureRequest({ + message: DEFAULT_SIGNATURE_REQUEST_MESSAGE, + isSelectableByUser: isSelectableByUser, + extraData: extraData + }); + } + + function buildEmpty() external pure returns (SignatureRequest memory) { + return + SignatureRequest({ + message: DEFAULT_SIGNATURE_REQUEST_MESSAGE, + isSelectableByUser: DEFAULT_SIGNATURE_REQUEST_IS_SELECTABLE_BY_USER, + extraData: DEFAULT_SIGNATURE_REQUEST_EXTRA_DATA + }); + } +} diff --git a/src/utils/SismoConnectHelper.sol b/src/utils/SismoConnectHelper.sol new file mode 100644 index 0000000..aaee6e0 --- /dev/null +++ b/src/utils/SismoConnectHelper.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "./Structs.sol"; + +library SismoConnectHelper { + error AuthTypeNotFoundInVerifiedResult(AuthType authType); + + function getUserId( + SismoConnectVerifiedResult memory result, + AuthType authType + ) internal pure returns (uint256) { + // get the first userId that matches the authType + for (uint256 i = 0; i < result.auths.length; i++) { + if (result.auths[i].authType == authType) { + return result.auths[i].userId; + } + } + revert AuthTypeNotFoundInVerifiedResult(authType); + } + + function getUserIds( + SismoConnectVerifiedResult memory result, + AuthType authType + ) internal pure returns (uint256[] memory) { + // get all userIds that match the authType + uint256[] memory userIds = new uint256[](result.auths.length); + for (uint256 i = 0; i < result.auths.length; i++) { + if (result.auths[i].authType == authType) { + userIds[i] = result.auths[i].userId; + } + } + return userIds; + } + + function getSignedMessage( + SismoConnectVerifiedResult memory result + ) internal pure returns (bytes memory) { + return result.signedMessage; + } +} diff --git a/src/utils/SismoConnectProofBuilder.sol b/src/utils/SismoConnectProofBuilder.sol new file mode 100644 index 0000000..70e88f0 --- /dev/null +++ b/src/utils/SismoConnectProofBuilder.sol @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import "./Structs.sol"; + +library ProofBuilder { + // default values for SismoConnect Proof + bytes32 public constant DEFAULT_PROOF_PROVING_SCHEME = bytes32("hydra-s3.1"); + bytes public constant DEFAULT_PROOF_EXTRA_DATA = ""; + + function build( + Auth memory auth, + Claim memory claim, + bytes memory proofData + ) external pure returns (SismoConnectProof memory) { + Auth[] memory auths = new Auth[](1); + auths[0] = auth; + Claim[] memory claims = new Claim[](1); + claims[0] = claim; + return + SismoConnectProof({ + auths: auths, + claims: claims, + proofData: proofData, + provingScheme: DEFAULT_PROOF_PROVING_SCHEME, + extraData: DEFAULT_PROOF_EXTRA_DATA + }); + } + + function build( + Auth memory auth, + Claim memory claim, + bytes memory proofData, + bytes32 provingScheme + ) external pure returns (SismoConnectProof memory) { + Auth[] memory auths = new Auth[](1); + auths[0] = auth; + Claim[] memory claims = new Claim[](1); + claims[0] = claim; + return + SismoConnectProof({ + auths: auths, + claims: claims, + proofData: proofData, + provingScheme: provingScheme, + extraData: DEFAULT_PROOF_EXTRA_DATA + }); + } + + function build( + Auth memory auth, + bytes memory proofData + ) external pure returns (SismoConnectProof memory) { + Auth[] memory auths = new Auth[](1); + auths[0] = auth; + Claim[] memory claims = new Claim[](0); + return + SismoConnectProof({ + auths: auths, + claims: claims, + proofData: proofData, + provingScheme: DEFAULT_PROOF_PROVING_SCHEME, + extraData: DEFAULT_PROOF_EXTRA_DATA + }); + } + + function build( + Auth memory auth, + bytes memory proofData, + bytes32 provingScheme + ) external pure returns (SismoConnectProof memory) { + Auth[] memory auths = new Auth[](1); + auths[0] = auth; + Claim[] memory claims = new Claim[](0); + return + SismoConnectProof({ + auths: auths, + claims: claims, + proofData: proofData, + provingScheme: provingScheme, + extraData: DEFAULT_PROOF_EXTRA_DATA + }); + } + + function build( + Claim memory claim, + bytes memory proofData + ) external pure returns (SismoConnectProof memory) { + Auth[] memory auths = new Auth[](0); + Claim[] memory claims = new Claim[](1); + claims[0] = claim; + return + SismoConnectProof({ + auths: auths, + claims: claims, + proofData: proofData, + provingScheme: DEFAULT_PROOF_PROVING_SCHEME, + extraData: DEFAULT_PROOF_EXTRA_DATA + }); + } + + function build( + Claim memory claim, + bytes memory proofData, + bytes32 provingScheme + ) external pure returns (SismoConnectProof memory) { + Auth[] memory auths = new Auth[](0); + Claim[] memory claims = new Claim[](1); + claims[0] = claim; + return + SismoConnectProof({ + auths: auths, + claims: claims, + proofData: proofData, + provingScheme: provingScheme, + extraData: DEFAULT_PROOF_EXTRA_DATA + }); + } + + function build( + Auth[] memory auths, + Claim[] memory claims, + bytes memory proofData + ) external pure returns (SismoConnectProof memory) { + return + SismoConnectProof({ + auths: auths, + claims: claims, + proofData: proofData, + provingScheme: DEFAULT_PROOF_PROVING_SCHEME, + extraData: DEFAULT_PROOF_EXTRA_DATA + }); + } + + function build( + Auth[] memory auths, + Claim[] memory claims, + bytes memory proofData, + bytes32 provingScheme + ) external pure returns (SismoConnectProof memory) { + return + SismoConnectProof({ + auths: auths, + claims: claims, + proofData: proofData, + provingScheme: provingScheme, + extraData: DEFAULT_PROOF_EXTRA_DATA + }); + } +} diff --git a/src/utils/Structs.sol b/src/utils/Structs.sol new file mode 100644 index 0000000..afdc6e4 --- /dev/null +++ b/src/utils/Structs.sol @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +struct SismoConnectRequest { + bytes16 namespace; + AuthRequest[] auths; + ClaimRequest[] claims; + SignatureRequest signature; +} + +struct SismoConnectConfig { + bytes16 appId; + VaultConfig vault; +} + +struct VaultConfig { + bool isImpersonationMode; +} + +struct AuthRequest { + AuthType authType; + uint256 userId; // default: 0 + // flags + bool isAnon; // default: false -> true not supported yet, need to throw if true + bool isOptional; // default: false + bool isSelectableByUser; // default: true + // + bytes extraData; // default: "" +} + +struct ClaimRequest { + ClaimType claimType; // default: GTE + bytes16 groupId; + bytes16 groupTimestamp; // default: bytes16("latest") + uint256 value; // default: 1 + // flags + bool isOptional; // default: false + bool isSelectableByUser; // default: true + // + bytes extraData; // default: "" +} + +struct SignatureRequest { + bytes message; // default: "MESSAGE_SELECTED_BY_USER" + bool isSelectableByUser; // default: false + bytes extraData; // default: "" +} + +enum AuthType { + VAULT, + GITHUB, + TWITTER, + EVM_ACCOUNT, + TELEGRAM, + DISCORD +} + +enum ClaimType { + GTE, + GT, + EQ, + LT, + LTE +} + +struct Auth { + AuthType authType; + bool isAnon; + bool isSelectableByUser; + uint256 userId; + bytes extraData; +} + +struct Claim { + ClaimType claimType; + bytes16 groupId; + bytes16 groupTimestamp; + bool isSelectableByUser; + uint256 value; + bytes extraData; +} + +struct Signature { + bytes message; + bytes extraData; +} + +struct SismoConnectResponse { + bytes16 appId; + bytes16 namespace; + bytes32 version; + bytes signedMessage; + SismoConnectProof[] proofs; +} + +struct SismoConnectProof { + Auth[] auths; + Claim[] claims; + bytes32 provingScheme; + bytes proofData; + bytes extraData; +} + +struct SismoConnectVerifiedResult { + bytes16 appId; + bytes16 namespace; + bytes32 version; + VerifiedAuth[] auths; + VerifiedClaim[] claims; + bytes signedMessage; +} + +struct VerifiedAuth { + AuthType authType; + bool isAnon; + uint256 userId; + bytes extraData; + bytes proofData; +} + +struct VerifiedClaim { + ClaimType claimType; + bytes16 groupId; + bytes16 groupTimestamp; + uint256 value; + bytes extraData; + uint256 proofId; + bytes proofData; +}