@chainlink/ace 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/.foundry-version +1 -0
  2. package/.github/CODEOWNERS +1 -0
  3. package/.github/workflows/auto-release-version.yml +107 -0
  4. package/.github/workflows/create-version-pr.yml +95 -0
  5. package/.github/workflows/forge-docs.yml +90 -0
  6. package/.github/workflows/forge-test.yml +59 -0
  7. package/.solhint-test.json +18 -0
  8. package/.solhint.json +16 -0
  9. package/.solhintignore +3 -0
  10. package/.solhintignore-test +2 -0
  11. package/Glossary.md +141 -0
  12. package/LICENSE +59 -0
  13. package/README.md +218 -0
  14. package/assets/chainlink-logo.svg +21 -0
  15. package/chainlink-ace-License-grants +2 -0
  16. package/foundry.toml +33 -0
  17. package/getting_started/GETTING_STARTED.md +477 -0
  18. package/getting_started/MyVault.sol +48 -0
  19. package/getting_started/advanced/.env.example +36 -0
  20. package/getting_started/advanced/GETTING_STARTED_ADVANCED.md +431 -0
  21. package/getting_started/advanced/SanctionsList.sol +25 -0
  22. package/getting_started/advanced/SanctionsPolicy.sol +58 -0
  23. package/package.json +41 -0
  24. package/packages/cross-chain-identity/README.md +148 -0
  25. package/packages/cross-chain-identity/docs/API_GUIDE.md +120 -0
  26. package/packages/cross-chain-identity/docs/API_REFERENCE.md +271 -0
  27. package/packages/cross-chain-identity/docs/CONCEPTS.md +253 -0
  28. package/packages/cross-chain-identity/docs/CREDENTIAL_FLOW.md +195 -0
  29. package/packages/cross-chain-identity/docs/SECURITY.md +70 -0
  30. package/packages/cross-chain-identity/src/CredentialRegistry.sol +245 -0
  31. package/packages/cross-chain-identity/src/CredentialRegistryIdentityValidator.sol +339 -0
  32. package/packages/cross-chain-identity/src/CredentialRegistryIdentityValidatorPolicy.sol +71 -0
  33. package/packages/cross-chain-identity/src/IdentityRegistry.sol +123 -0
  34. package/packages/cross-chain-identity/src/TrustedIssuerRegistry.sol +140 -0
  35. package/packages/cross-chain-identity/src/interfaces/ICredentialDataValidator.sol +30 -0
  36. package/packages/cross-chain-identity/src/interfaces/ICredentialRegistry.sol +170 -0
  37. package/packages/cross-chain-identity/src/interfaces/ICredentialRequirements.sol +192 -0
  38. package/packages/cross-chain-identity/src/interfaces/ICredentialValidator.sol +37 -0
  39. package/packages/cross-chain-identity/src/interfaces/IIdentityRegistry.sol +85 -0
  40. package/packages/cross-chain-identity/src/interfaces/IIdentityValidator.sol +18 -0
  41. package/packages/cross-chain-identity/src/interfaces/ITrustedIssuerRegistry.sol +61 -0
  42. package/packages/cross-chain-identity/test/CredentialRegistry.t.sol +220 -0
  43. package/packages/cross-chain-identity/test/CredentialRegistryIdentityValidator.t.sol +554 -0
  44. package/packages/cross-chain-identity/test/CredentialRegistryIdentityValidatorPolicy.t.sol +114 -0
  45. package/packages/cross-chain-identity/test/IdentityRegistry.t.sol +106 -0
  46. package/packages/cross-chain-identity/test/IdentityValidator.t.sol +969 -0
  47. package/packages/cross-chain-identity/test/TrustedIssuerRegistry.t.sol +123 -0
  48. package/packages/cross-chain-identity/test/helpers/BaseProxyTest.sol +112 -0
  49. package/packages/cross-chain-identity/test/helpers/MockCredentialDataValidator.sol +26 -0
  50. package/packages/cross-chain-identity/test/helpers/MockCredentialRegistryReverting.sol +131 -0
  51. package/packages/policy-management/README.md +197 -0
  52. package/packages/policy-management/docs/API_GUIDE.md +290 -0
  53. package/packages/policy-management/docs/API_REFERENCE.md +173 -0
  54. package/packages/policy-management/docs/CONCEPTS.md +156 -0
  55. package/packages/policy-management/docs/CUSTOM_POLICIES_TUTORIAL.md +195 -0
  56. package/packages/policy-management/docs/POLICY_ORDERING_GUIDE.md +91 -0
  57. package/packages/policy-management/docs/SECURITY.md +57 -0
  58. package/packages/policy-management/src/core/Policy.sol +124 -0
  59. package/packages/policy-management/src/core/PolicyEngine.sol +382 -0
  60. package/packages/policy-management/src/core/PolicyFactory.sol +92 -0
  61. package/packages/policy-management/src/core/PolicyProtected.sol +126 -0
  62. package/packages/policy-management/src/extractors/ComplianceTokenForceTransferExtractor.sol +57 -0
  63. package/packages/policy-management/src/extractors/ComplianceTokenFreezeUnfreezeExtractor.sol +54 -0
  64. package/packages/policy-management/src/extractors/ComplianceTokenMintBurnExtractor.sol +61 -0
  65. package/packages/policy-management/src/extractors/ERC20ApproveExtractor.sol +57 -0
  66. package/packages/policy-management/src/extractors/ERC20TransferExtractor.sol +62 -0
  67. package/packages/policy-management/src/extractors/ERC3643ForcedTransferExtractor.sol +56 -0
  68. package/packages/policy-management/src/extractors/ERC3643FreezeUnfreezeExtractor.sol +55 -0
  69. package/packages/policy-management/src/extractors/ERC3643MintBurnExtractor.sol +51 -0
  70. package/packages/policy-management/src/extractors/ERC3643SetAddressFrozenExtractor.sol +51 -0
  71. package/packages/policy-management/src/interfaces/IExtractor.sol +17 -0
  72. package/packages/policy-management/src/interfaces/IMapper.sol +17 -0
  73. package/packages/policy-management/src/interfaces/IPolicy.sol +61 -0
  74. package/packages/policy-management/src/interfaces/IPolicyEngine.sol +264 -0
  75. package/packages/policy-management/src/interfaces/IPolicyProtected.sol +48 -0
  76. package/packages/policy-management/src/policies/AllowPolicy.sol +104 -0
  77. package/packages/policy-management/src/policies/BypassPolicy.sol +90 -0
  78. package/packages/policy-management/src/policies/IntervalPolicy.sol +223 -0
  79. package/packages/policy-management/src/policies/MaxPolicy.sol +73 -0
  80. package/packages/policy-management/src/policies/OnlyAuthorizedSenderPolicy.sol +84 -0
  81. package/packages/policy-management/src/policies/OnlyOwnerPolicy.sol +35 -0
  82. package/packages/policy-management/src/policies/PausePolicy.sol +82 -0
  83. package/packages/policy-management/src/policies/README.md +632 -0
  84. package/packages/policy-management/src/policies/RejectPolicy.sol +89 -0
  85. package/packages/policy-management/src/policies/RoleBasedAccessControlPolicy.sol +162 -0
  86. package/packages/policy-management/src/policies/SecureMintPolicy.sol +271 -0
  87. package/packages/policy-management/src/policies/VolumePolicy.sol +133 -0
  88. package/packages/policy-management/src/policies/VolumeRatePolicy.sol +192 -0
  89. package/packages/policy-management/test/PolicyEngine.t.sol +368 -0
  90. package/packages/policy-management/test/PolicyFactory.t.sol +114 -0
  91. package/packages/policy-management/test/PolicyProtectedToken.t.sol +75 -0
  92. package/packages/policy-management/test/extractors/ComplianceTokenForceTransferExtractor.t.sol +59 -0
  93. package/packages/policy-management/test/extractors/ComplianceTokenFreezeUnfreezeExtractor.t.sol +74 -0
  94. package/packages/policy-management/test/extractors/ComplianceTokenMintBurnExtractor.t.sol +92 -0
  95. package/packages/policy-management/test/extractors/ERC20ApproveExtractor.t.sol +58 -0
  96. package/packages/policy-management/test/extractors/ERC3643ForcedTransferExtractor.t.sol +59 -0
  97. package/packages/policy-management/test/extractors/ERC3643FreezeUnfreezeExtractor.t.sol +74 -0
  98. package/packages/policy-management/test/extractors/ERC3643MintBurnExtractor.t.sol +73 -0
  99. package/packages/policy-management/test/extractors/ERC3643SetAddressFrozenExtractor.t.sol +56 -0
  100. package/packages/policy-management/test/helpers/BaseProxyTest.sol +75 -0
  101. package/packages/policy-management/test/helpers/CustomMapper.sol +26 -0
  102. package/packages/policy-management/test/helpers/DummyExtractor.sol +11 -0
  103. package/packages/policy-management/test/helpers/ExpectedParameterPolicy.sol +39 -0
  104. package/packages/policy-management/test/helpers/MockAggregatorV3.sol +51 -0
  105. package/packages/policy-management/test/helpers/MockToken.sol +66 -0
  106. package/packages/policy-management/test/helpers/MockTokenExtractor.sol +34 -0
  107. package/packages/policy-management/test/helpers/PolicyAlwaysAllowed.sol +45 -0
  108. package/packages/policy-management/test/helpers/PolicyAlwaysContinue.sol +23 -0
  109. package/packages/policy-management/test/helpers/PolicyAlwaysRejected.sol +23 -0
  110. package/packages/policy-management/test/helpers/PolicyFailingRun.sol +22 -0
  111. package/packages/policy-management/test/policies/AllowPolicy.t.sol +174 -0
  112. package/packages/policy-management/test/policies/BypassPolicy.t.sol +159 -0
  113. package/packages/policy-management/test/policies/IntervalPolicy.t.sol +307 -0
  114. package/packages/policy-management/test/policies/MaxPolicy.t.sol +54 -0
  115. package/packages/policy-management/test/policies/OnlyAuthorizedSenderPolicy.t.sol +95 -0
  116. package/packages/policy-management/test/policies/OnlyOwnerPolicy.t.sol +47 -0
  117. package/packages/policy-management/test/policies/PausePolicy.t.sol +75 -0
  118. package/packages/policy-management/test/policies/RejectPolicy.t.sol +182 -0
  119. package/packages/policy-management/test/policies/RoleBasedAccessControlPolicy.t.sol +223 -0
  120. package/packages/policy-management/test/policies/SecureMintPolicy.t.sol +442 -0
  121. package/packages/policy-management/test/policies/VolumePolicy.t.sol +158 -0
  122. package/packages/policy-management/test/policies/VolumeRatePolicy.t.sol +165 -0
  123. package/packages/tokens/erc-20/src/ComplianceTokenERC20.sol +345 -0
  124. package/packages/tokens/erc-20/src/ComplianceTokenStoreERC20.sol +29 -0
  125. package/packages/tokens/erc-20/test/ComplianceTokenERC20.t.sol +556 -0
  126. package/packages/tokens/erc-20/test/helpers/BaseProxyTest.sol +75 -0
  127. package/packages/tokens/erc-3643/README.md +24 -0
  128. package/packages/tokens/erc-3643/src/ComplianceTokenERC3643.sol +564 -0
  129. package/packages/tokens/erc-3643/src/ComplianceTokenStoreERC3643.sol +30 -0
  130. package/packages/tokens/erc-3643/test/ComplianceTokenERC3643.t.sol +815 -0
  131. package/packages/tokens/erc-3643/test/helpers/BaseProxyTest.sol +76 -0
  132. package/packages/tokens/erc-3643/test/helpers/ExpectedContextPolicy.sol +32 -0
  133. package/packages/vendor/erc-3643/compliance/modular/IModularCompliance.sol +220 -0
  134. package/packages/vendor/erc-3643/registry/interface/IClaimTopicsRegistry.sol +101 -0
  135. package/packages/vendor/erc-3643/registry/interface/IIdentityRegistry.sol +251 -0
  136. package/packages/vendor/erc-3643/registry/interface/IIdentityRegistryStorage.sol +191 -0
  137. package/packages/vendor/erc-3643/registry/interface/ITrustedIssuersRegistry.sol +161 -0
  138. package/packages/vendor/erc-3643/token/IToken.sol +457 -0
  139. package/packages/vendor/onchain-id/interface/IClaimIssuer.sol +53 -0
  140. package/packages/vendor/onchain-id/interface/IERC734.sol +110 -0
  141. package/packages/vendor/onchain-id/interface/IERC735.sol +105 -0
  142. package/packages/vendor/onchain-id/interface/IIdentity.sol +26 -0
  143. package/packages/vendor/onchain-id/interface/IImplementationAuthority.sol +21 -0
  144. package/remappings.txt +6 -0
  145. package/script/DeployComplianceTokenERC20.s.sol +191 -0
  146. package/script/DeployComplianceTokenERC3643.s.sol +208 -0
  147. package/script/DeploySimpleComplianceToken.s.sol +38 -0
  148. package/script/getting_started/DeployGettingStarted.s.sol +74 -0
  149. package/script/getting_started/advanced/DeployAdvancedGettingStarted.s.sol +332 -0
  150. package/script/getting_started/advanced/DeploySanctionsList.s.sol +26 -0
@@ -0,0 +1,123 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity 0.8.26;
3
+
4
+ import {IIdentityRegistry} from "./interfaces/IIdentityRegistry.sol";
5
+ import {PolicyProtected} from "@chainlink/policy-management/core/PolicyProtected.sol";
6
+
7
+ contract IdentityRegistry is PolicyProtected, IIdentityRegistry {
8
+ /// @custom:storage-location erc7201:cross-chain-identity.IdentityRegistry
9
+ struct IdentityRegistryStorage {
10
+ mapping(address account => bytes32 ccid) accountToCcid;
11
+ mapping(bytes32 ccid => address[] accounts) ccidToAccounts;
12
+ }
13
+
14
+ // keccak256(abi.encode(uint256(keccak256("cross-chain-identity.IdentityRegistry")) - 1)) &
15
+ // ~bytes32(uint256(0xff))
16
+ // solhint-disable-next-line const-name-snakecase
17
+ bytes32 private constant identityRegistryStorageLocation =
18
+ 0x95c7dd14054992de17881168e75df13bb7ed90a1eacfff26d4643d48ec30de00;
19
+
20
+ function _identityRegistryStorage() private pure returns (IdentityRegistryStorage storage $) {
21
+ // solhint-disable-next-line no-inline-assembly
22
+ assembly {
23
+ $.slot := identityRegistryStorageLocation
24
+ }
25
+ }
26
+
27
+ /**
28
+ * @dev Initializes the identity registry and sets the policy engine.
29
+ * @param policyEngine The address of the policy engine contract.
30
+ * @param initialOwner The address that will own the newly created registry contract.
31
+ */
32
+ function initialize(address policyEngine, address initialOwner) public virtual initializer {
33
+ __IdentityRegistry_init(policyEngine, initialOwner);
34
+ }
35
+
36
+ function __IdentityRegistry_init(address policyEngine, address initialOwner) internal onlyInitializing {
37
+ __IdentityRegistry_init_unchained();
38
+ __PolicyProtected_init(initialOwner, policyEngine);
39
+ }
40
+
41
+ // solhint-disable-next-line no-empty-blocks
42
+ function __IdentityRegistry_init_unchained() internal onlyInitializing {}
43
+
44
+ /// @inheritdoc IIdentityRegistry
45
+ function registerIdentity(
46
+ bytes32 ccid,
47
+ address account,
48
+ bytes calldata context
49
+ )
50
+ public
51
+ virtual
52
+ override
53
+ runPolicyWithContext(context)
54
+ {
55
+ _registerIdentity(ccid, account, context);
56
+ }
57
+
58
+ /// @inheritdoc IIdentityRegistry
59
+ function registerIdentities(
60
+ bytes32[] calldata ccids,
61
+ address[] calldata accounts,
62
+ bytes calldata context
63
+ )
64
+ public
65
+ virtual
66
+ override
67
+ runPolicyWithContext(context)
68
+ {
69
+ if (ccids.length == 0 || ccids.length != accounts.length) {
70
+ revert InvalidIdentityConfiguration("Invalid input length");
71
+ }
72
+ for (uint256 i = 0; i < ccids.length; i++) {
73
+ _registerIdentity(ccids[i], accounts[i], context);
74
+ }
75
+ }
76
+
77
+ function _registerIdentity(bytes32 ccid, address account, bytes calldata /*context*/ ) internal {
78
+ if (ccid == bytes32(0)) {
79
+ revert InvalidIdentityConfiguration("CCID cannot be empty");
80
+ }
81
+ if (_identityRegistryStorage().accountToCcid[account] != bytes32(0)) {
82
+ revert IdentityAlreadyRegistered(ccid, account);
83
+ }
84
+ _identityRegistryStorage().accountToCcid[account] = ccid;
85
+ _identityRegistryStorage().ccidToAccounts[ccid].push(account);
86
+ emit IdentityRegistered(ccid, account);
87
+ }
88
+
89
+ /// @inheritdoc IIdentityRegistry
90
+ function removeIdentity(
91
+ bytes32 ccid,
92
+ address account,
93
+ bytes calldata context
94
+ )
95
+ public
96
+ virtual
97
+ override
98
+ runPolicyWithContext(context)
99
+ {
100
+ uint256 length = _identityRegistryStorage().ccidToAccounts[ccid].length;
101
+ for (uint256 i = 0; i < length; i++) {
102
+ if (_identityRegistryStorage().ccidToAccounts[ccid][i] == account) {
103
+ _identityRegistryStorage().ccidToAccounts[ccid][i] = _identityRegistryStorage().ccidToAccounts[ccid][length - 1];
104
+ _identityRegistryStorage().ccidToAccounts[ccid].pop();
105
+ delete _identityRegistryStorage().accountToCcid[account];
106
+
107
+ emit IdentityRemoved(ccid, account);
108
+ return;
109
+ }
110
+ }
111
+ revert IdentityNotFound(ccid, account);
112
+ }
113
+
114
+ /// @inheritdoc IIdentityRegistry
115
+ function getIdentity(address account) public view virtual override returns (bytes32) {
116
+ return _identityRegistryStorage().accountToCcid[account];
117
+ }
118
+
119
+ /// @inheritdoc IIdentityRegistry
120
+ function getAccounts(bytes32 ccid) public view virtual override returns (address[] memory) {
121
+ return _identityRegistryStorage().ccidToAccounts[ccid];
122
+ }
123
+ }
@@ -0,0 +1,140 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity 0.8.26;
3
+
4
+ import {ITrustedIssuerRegistry} from "./interfaces/ITrustedIssuerRegistry.sol";
5
+ import {PolicyProtected} from "@chainlink/policy-management/core/PolicyProtected.sol";
6
+
7
+ /**
8
+ * @title TrustedIssuerRegistry
9
+ * @dev Implementation of the ITrustedIssuerRegistry interface using ERC-7201 storage pattern.
10
+ */
11
+ contract TrustedIssuerRegistry is PolicyProtected, ITrustedIssuerRegistry {
12
+ /// @custom:storage-location erc7201:cross-chain-identity.TrustedIssuerRegistry
13
+ struct TrustedIssuerRegistryStorage {
14
+ mapping(bytes32 issuerIdHash => bool isTrusted) trustedIssuers;
15
+ bytes32[] issuerList;
16
+ }
17
+
18
+ // keccak256(abi.encode(uint256(keccak256("cross-chain-identity.TrustedIssuerRegistry")) - 1)) &
19
+ // ~bytes32(uint256(0xff))
20
+ // solhint-disable-next-line const-name-snakecase
21
+ bytes32 private constant trustedIssuerRegistryStorageLocation =
22
+ 0x68705e3417317ecc3ac2b3879fdff408d88085552fb211d60abc5b025809c200;
23
+
24
+ function _trustedIssuerRegistryStorage() private pure returns (TrustedIssuerRegistryStorage storage $) {
25
+ assembly {
26
+ $.slot := trustedIssuerRegistryStorageLocation
27
+ }
28
+ }
29
+
30
+ constructor() {
31
+ _disableInitializers();
32
+ }
33
+
34
+ /**
35
+ * @dev Initializes the trusted issuer registry and sets the policy engine.
36
+ * @param policyEngine The address of the policy engine contract.
37
+ * @param initialOwner The address that will own the newly created registry contract.
38
+ */
39
+ function initialize(address policyEngine, address initialOwner) public virtual initializer {
40
+ __TrustedIssuerRegistry_init(policyEngine, initialOwner);
41
+ }
42
+
43
+ function __TrustedIssuerRegistry_init(address policyEngine, address initialOwner) internal onlyInitializing {
44
+ __TrustedIssuerRegistry_init_unchained();
45
+ __PolicyProtected_init(initialOwner, policyEngine);
46
+ }
47
+
48
+ function __TrustedIssuerRegistry_init_unchained() internal onlyInitializing {}
49
+
50
+ // ------------------------------------------------------------------------
51
+ // Externals
52
+ // ------------------------------------------------------------------------
53
+
54
+ function addTrustedIssuer(
55
+ string memory issuerId,
56
+ bytes calldata context
57
+ )
58
+ external
59
+ override
60
+ runPolicyWithContext(context)
61
+ {
62
+ _addTrustedIssuer(issuerId, context);
63
+ }
64
+
65
+ function removeTrustedIssuer(
66
+ string memory issuerId,
67
+ bytes calldata context
68
+ )
69
+ external
70
+ override
71
+ runPolicyWithContext(context)
72
+ {
73
+ _removeTrustedIssuer(issuerId, context);
74
+ }
75
+
76
+ // ------------------------------------------------------------------------
77
+ // internals
78
+ // ------------------------------------------------------------------------
79
+
80
+ function _addTrustedIssuer(string memory issuerId, bytes calldata context) internal {
81
+ if (bytes(issuerId).length == 0) {
82
+ revert("issuerId cannot be empty");
83
+ }
84
+
85
+ bytes32 issuerIdHash = keccak256(abi.encodePacked(issuerId));
86
+
87
+ TrustedIssuerRegistryStorage storage $ = _trustedIssuerRegistryStorage();
88
+ if ($.trustedIssuers[issuerIdHash]) {
89
+ revert("Issuer already trusted");
90
+ }
91
+
92
+ $.trustedIssuers[issuerIdHash] = true;
93
+ $.issuerList.push(issuerIdHash);
94
+
95
+ emit TrustedIssuerAdded(issuerIdHash, issuerId);
96
+ }
97
+
98
+ function _removeTrustedIssuer(string memory issuerId, bytes calldata context) internal {
99
+ if (bytes(issuerId).length == 0) {
100
+ revert("issuerId cannot be empty");
101
+ }
102
+
103
+ bytes32 issuerIdHash = keccak256(abi.encodePacked(issuerId));
104
+
105
+ TrustedIssuerRegistryStorage storage $ = _trustedIssuerRegistryStorage();
106
+ if (!$.trustedIssuers[issuerIdHash]) {
107
+ revert("Issuer not trusted");
108
+ }
109
+
110
+ $.trustedIssuers[issuerIdHash] = false;
111
+
112
+ uint256 length = $.issuerList.length;
113
+ for (uint256 i = 0; i < length; i++) {
114
+ if ($.issuerList[i] == issuerIdHash) {
115
+ $.issuerList[i] = $.issuerList[length - 1];
116
+ $.issuerList.pop();
117
+ break;
118
+ }
119
+ }
120
+
121
+ emit TrustedIssuerRemoved(issuerIdHash, issuerId);
122
+ }
123
+
124
+ function _isTrustedIssuer(bytes32 issuerIdHash) internal view returns (bool) {
125
+ return _trustedIssuerRegistryStorage().trustedIssuers[issuerIdHash];
126
+ }
127
+
128
+ // ------------------------------------------------------------------------
129
+ // View
130
+ // ------------------------------------------------------------------------
131
+
132
+ function getTrustedIssuers() public view virtual override returns (bytes32[] memory) {
133
+ return _trustedIssuerRegistryStorage().issuerList;
134
+ }
135
+
136
+ function isTrustedIssuer(string memory issuerId) external view override returns (bool) {
137
+ bytes32 issuerIdHash = keccak256(abi.encodePacked(issuerId));
138
+ return _isTrustedIssuer(issuerIdHash);
139
+ }
140
+ }
@@ -0,0 +1,30 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity ^0.8.20;
3
+
4
+ /**
5
+ * @title ICredentialDataValidator
6
+ * @dev Interface for validating the data associated with a credential.
7
+ */
8
+ interface ICredentialDataValidator {
9
+ /**
10
+ * @notice Validates the data associated with a credential assignment.
11
+ * @dev This function MUST NOT revert. Handle all validation failures gracefully and return
12
+ * false instead of allowing exceptions to propagate.
13
+ * @param ccid The cross-chain identity of the account.
14
+ * @param account The account to validate.
15
+ * @param credentialTypeId The credential type identifier to validate.
16
+ * @param credentialData The data associated with the credential.
17
+ * @param context Additional information or authorization to perform the operation.
18
+ * @return True if the credential is valid, false otherwise.
19
+ */
20
+ function validateCredentialData(
21
+ bytes32 ccid,
22
+ address account,
23
+ bytes32 credentialTypeId,
24
+ bytes calldata credentialData,
25
+ bytes calldata context
26
+ )
27
+ external
28
+ view
29
+ returns (bool);
30
+ }
@@ -0,0 +1,170 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity ^0.8.20;
3
+
4
+ import {ICredentialValidator} from "./ICredentialValidator.sol";
5
+
6
+ /**
7
+ * @title ICredentialRegistry
8
+ * @dev Interface for managing the credential registry.
9
+ */
10
+ interface ICredentialRegistry is ICredentialValidator {
11
+ /// @notice Error emitted when a credential type identifier is already registered to the ccid.
12
+ error CredentialAlreadyRegistered(bytes32 ccid, bytes32 credentialTypeId);
13
+ /// @notice Error emitted when a credential type identifier is not found to be associated to the ccid.
14
+ error CredentialNotFound(bytes32 ccid, bytes32 credentialTypeId);
15
+ /// @notice Error emitted when an invalid credential configuration was attempted.
16
+ error InvalidCredentialConfiguration(string errorReason);
17
+
18
+ /**
19
+ * @dev The struct for a credential. A credential is a piece of arbitrary data that is associated with a credential
20
+ * type identifier, and optionally has an expiration time. The data can be anything that is relevant to the credential
21
+ * type.
22
+ * The ICredentialRegistry maps a cross-chain identifier (CCID) to one or more credentials, managing their lifecycle.
23
+ */
24
+ struct Credential {
25
+ uint40 expiresAt;
26
+ bytes credentialData;
27
+ }
28
+
29
+ /**
30
+ * @notice Emitted when a credential is registered.
31
+ * @param ccid The cross-chain identity of the account.
32
+ * @param credentialTypeId The credential type identifier that was registered.
33
+ * @param expiresAt The expiration time of the credential.
34
+ * @param credentialData The data associated with the credential.
35
+ */
36
+ event CredentialRegistered(
37
+ bytes32 indexed ccid, bytes32 indexed credentialTypeId, uint40 expiresAt, bytes credentialData
38
+ );
39
+
40
+ /**
41
+ * @notice Emitted when a credential is removed.
42
+ * @param ccid The cross-chain identity of the account.
43
+ * @param credentialTypeId The credential type identifier that was removed.
44
+ */
45
+ event CredentialRemoved(bytes32 indexed ccid, bytes32 indexed credentialTypeId);
46
+
47
+ /**
48
+ * @notice Emitted when a credential is renewed.
49
+ * @param ccid The cross-chain identity of the account.
50
+ * @param credentialTypeId The credential type identifier that was renewed.
51
+ * @param previousExpiresAt The previous expiration time of the credential.
52
+ * @param expiresAt The new expiration time of the credential.
53
+ */
54
+ event CredentialRenewed(
55
+ bytes32 indexed ccid, bytes32 indexed credentialTypeId, uint40 previousExpiresAt, uint40 expiresAt
56
+ );
57
+
58
+ /**
59
+ * @notice Registers a credential for an account.
60
+ *
61
+ * - MUST revert with `CredentialAlreadyRegistered` if the credential is already registered.
62
+ * - MUST emit the `CredentialRegistered` event.
63
+ *
64
+ * @param ccid The cross-chain identity of the account.
65
+ * @param credentialTypeId The credential type identifier to associate with the account.
66
+ * @param expiresAt The expiration time (MUST be a future timestamp) of the credential, 0 for no expiration.
67
+ * @param credentialData The data associated with the credential.
68
+ * @param context Additional information or authorization to perform the operation.
69
+ */
70
+ function registerCredential(
71
+ bytes32 ccid,
72
+ bytes32 credentialTypeId,
73
+ uint40 expiresAt,
74
+ bytes calldata credentialData,
75
+ bytes calldata context
76
+ )
77
+ external;
78
+
79
+ /**
80
+ * @notice Registers a list of credentials for an account.
81
+ *
82
+ * - MUST revert with `CredentialAlreadyRegistered` if one of the credentials is already registered.
83
+ * - MUST emit the `CredentialRegistered` event for each credential.
84
+ *
85
+ * @param ccid The cross-chain identity of the account.
86
+ * @param credentialTypeIds The credential type identifiers to associate with the account.
87
+ * @param expiresAt The expiration time (MUST be a future timestamp) of the credential, 0 for no expiration.
88
+ * @param credentialDatas The list of data associated with each credential.
89
+ * @param context Additional information or authorization to perform the operation.
90
+ */
91
+ function registerCredentials(
92
+ bytes32 ccid,
93
+ bytes32[] calldata credentialTypeIds,
94
+ uint40 expiresAt,
95
+ bytes[] calldata credentialDatas,
96
+ bytes calldata context
97
+ )
98
+ external;
99
+
100
+ /**
101
+ * @notice Removes a credential from an account.
102
+ *
103
+ * - MUST revert with `CredentialNotFound` if the credential is not found.
104
+ * - MUST emit the `CredentialRemoved` event.
105
+ *
106
+ * @param ccid The cross-chain identity of the account.
107
+ * @param credentialTypeId The credential type identifier to remove from the account.
108
+ * @param context Additional information or authorization to perform the operation.
109
+ */
110
+ function removeCredential(bytes32 ccid, bytes32 credentialTypeId, bytes calldata context) external;
111
+
112
+ /**
113
+ * @notice Renews the expiration time of a credential.
114
+ *
115
+ * - MUST revert with `CredentialNotFound` if the credential is not found.
116
+ * - MUST emit the `CredentialRenewed` event.
117
+ *
118
+ * @param ccid The cross-chain identity of the account.
119
+ * @param credentialTypeId The credential type identifier to renew.
120
+ * @param expiresAt The updated expiration time (MUST be a future timestamp) of the credential, 0 for no expiration.
121
+ * @param context Additional information or authorization to perform the operation.
122
+ */
123
+ function renewCredential(bytes32 ccid, bytes32 credentialTypeId, uint40 expiresAt, bytes calldata context) external;
124
+
125
+ /**
126
+ * @notice Checks if a credential is expired.
127
+ * @param ccid The cross-chain identity of the account.
128
+ * @param credentialTypeId The credential type identifier.
129
+ * @return True if the credential is expired, false otherwise.
130
+ */
131
+ function isCredentialExpired(bytes32 ccid, bytes32 credentialTypeId) external view returns (bool);
132
+
133
+ /**
134
+ * @notice Gets all of the credential types associated with an account, expired or not.
135
+ * @param ccid The cross-chain identity of the account.
136
+ * @return The credential type identifiers associated with the account.
137
+ */
138
+ function getCredentialTypes(bytes32 ccid) external view returns (bytes32[] memory);
139
+
140
+ /**
141
+ * @notice Retrieves a credential associated with a given account and credential type.
142
+ * - MUST revert with `CredentialNotFound` if the credential does not exist for the given `ccid` and
143
+ * `credentialTypeId`.
144
+ *
145
+ * @param ccid The cross-chain identity of the account.
146
+ * @param credentialTypeId The credential type identifier to fetch.
147
+ * @return A `Credential` struct containing:
148
+ * - `expiresAt`: The expiration time of the credential (0 if no expiration).
149
+ * - `credentialData`: The arbitrary data associated with the credential.
150
+ */
151
+ function getCredential(bytes32 ccid, bytes32 credentialTypeId) external view returns (Credential memory);
152
+
153
+ /**
154
+ * @notice Retrieves multiple credentials associated with a given account and a list of credential types.
155
+ * - MUST revert with `CredentialNotFound` if any of the requested credentials do not exist for the given `ccid`.
156
+ *
157
+ * @param ccid The cross-chain identity of the account.
158
+ * @param credentialTypeIds The list of credential type identifiers to fetch.
159
+ * @return An array of `Credential` structs, each containing:
160
+ * - `expiresAt`: The expiration time of the credential (0 if no expiration).
161
+ * - `credentialData`: The arbitrary data associated with the credential.
162
+ */
163
+ function getCredentials(
164
+ bytes32 ccid,
165
+ bytes32[] calldata credentialTypeIds
166
+ )
167
+ external
168
+ view
169
+ returns (Credential[] memory);
170
+ }
@@ -0,0 +1,192 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity ^0.8.20;
3
+
4
+ /**
5
+ * @title ICredentialRequirements
6
+ * @dev The interface for specifying the required credentials of an application/token.
7
+ */
8
+ interface ICredentialRequirements {
9
+ /// @notice Error emitted when a requirement already exists.
10
+ error RequirementExists(bytes32 requirementId);
11
+ /// @notice Error emitted when a requirement is not found.
12
+ error RequirementNotFound(bytes32 requirementId);
13
+ /// @notice Error emitted when a source has already been added.
14
+ error SourceExists(bytes32 credentialTypeId, address identityRegistry, address credentialRegistry);
15
+ /// @notice Error emitted when a credential source is not found.
16
+ error CredentialSourceNotFound(bytes32 credentialTypeId, address identityRegistry, address credentialRegistry);
17
+ /// @notice Error emitted when an invalid requirement configuration was attempted.
18
+ error InvalidRequirementConfiguration(string errorReason);
19
+
20
+ /**
21
+ * @dev The struct for a credential requirement. A requirement is a common identifier that encompasses a list of
22
+ * credentials that satisfies the requirement, how many validations are required of the credential.
23
+ * A credential requirement could be 'invert'. This means that the requirement is satisfied if the credential
24
+ * is not validated in the credential registry. This is useful for requirements that are satisfied by the absence of
25
+ * a credential.
26
+ */
27
+ struct CredentialRequirement {
28
+ bytes32[] credentialTypeIds;
29
+ uint256 minValidations;
30
+ bool invert;
31
+ }
32
+
33
+ /**
34
+ * @dev The struct for a credential source. A `source` is an identity registry and credential registry pair. The
35
+ * IIdentityRegistry maps local addresses to the common cross-chain identifier (CCID). The ICredentialRegistry
36
+ * maps a CCID with one or more credentials, and each credential mapping can optionally have additional data.
37
+ * A data validator contract can optionally be provided, and if present, is used to validate the data associated
38
+ * with the credential.
39
+ */
40
+ struct CredentialSource {
41
+ address identityRegistry;
42
+ address credentialRegistry;
43
+ address dataValidator;
44
+ }
45
+
46
+ /**
47
+ * @dev The input struct used to add a new credential requirement.
48
+ *
49
+ * @param requirementId The identifier of the requirement.
50
+ * @param credentialTypeIds The credential type identifier(s) that satisfy the requirement.
51
+ * @param minValidations The minimum number of validations required for the requirement.
52
+ * @param invert If the requirement is satisfied by the absence of all of the credential(s).
53
+ */
54
+ struct CredentialRequirementInput {
55
+ bytes32 requirementId;
56
+ bytes32[] credentialTypeIds;
57
+ uint256 minValidations;
58
+ bool invert;
59
+ }
60
+
61
+ /**
62
+ * @dev The input struct used to add a new credential source.
63
+ *
64
+ * @param credentialTypeId The credential type identifier.
65
+ * @param identityRegistry The address of the identity registry.
66
+ * @param credentialRegistry The address of the credential registry.
67
+ * @param dataValidator The address of the data validator contract.
68
+ */
69
+ struct CredentialSourceInput {
70
+ bytes32 credentialTypeId;
71
+ address identityRegistry;
72
+ address credentialRegistry;
73
+ address dataValidator;
74
+ }
75
+
76
+ /**
77
+ * @notice Emitted when a new credential requirement is added.
78
+ * @param requirementId The identifier of the requirement.
79
+ * @param credentialTypeIds The credential type identifiers that satisfy the requirement.
80
+ * @param minValidations The minimum number of validations required for the requirement.
81
+ * @param invert Whether the requirement is satisfied by the absence of all of the credential(s).
82
+ */
83
+ event CredentialRequirementAdded(
84
+ bytes32 indexed requirementId, bytes32[] credentialTypeIds, uint256 minValidations, bool invert
85
+ );
86
+
87
+ /**
88
+ * @notice Emitted when a credential requirement is removed.
89
+ * @param requirementId The identifier of the requirement.
90
+ * @param credentialTypeIds The list of credential type identifiers that satisfy the requirement.
91
+ * @param minValidations The minimum number of validations required for the requirement.
92
+ * @param invert Whether the requirement was satisfied by the absence of all of the credential(s).
93
+ */
94
+ event CredentialRequirementRemoved(
95
+ bytes32 indexed requirementId, bytes32[] credentialTypeIds, uint256 minValidations, bool invert
96
+ );
97
+
98
+ /**
99
+ * @notice Emitted when a new credential source is added.
100
+ * @param credentialTypeId The credential type identifier.
101
+ * @param identityRegistry The address of the identity registry.
102
+ * @param credentialRegistry The address of the credential registry.
103
+ * @param dataValidator The address of the data validator contract.
104
+ */
105
+ event CredentialSourceAdded(
106
+ bytes32 indexed credentialTypeId,
107
+ address indexed identityRegistry,
108
+ address indexed credentialRegistry,
109
+ address dataValidator
110
+ );
111
+
112
+ /**
113
+ * @notice Emitted when a credential source is removed.
114
+ * @param credentialTypeId The credential type identifier.
115
+ * @param identityRegistry The address of the identity registry.
116
+ * @param credentialRegistry The address of the credential registry.
117
+ * @param dataValidator The address of the data validator contract.
118
+ */
119
+ event CredentialSourceRemoved(
120
+ bytes32 indexed credentialTypeId,
121
+ address indexed identityRegistry,
122
+ address indexed credentialRegistry,
123
+ address dataValidator
124
+ );
125
+
126
+ /**
127
+ * @notice Adds a new credential requirement.
128
+ *
129
+ * - MUST revert with `RequirementExists` if the requirement already exists.
130
+ * - MUST emit the `CredentialRequirementAdded` event.
131
+ *
132
+ * @param CredentialRequirementInput The input struct used to add a new credential requirement.
133
+ */
134
+ function addCredentialRequirement(CredentialRequirementInput memory CredentialRequirementInput) external;
135
+
136
+ /**
137
+ * @notice Removes a credential requirement.
138
+ *
139
+ * - MUST revert with `RequirementNotFound` if the requirement does not exist.
140
+ * - MUST emit the `CredentialRequirementRemoved` event.
141
+ *
142
+ * @param requirementId The identifier of the requirement.
143
+ */
144
+ function removeCredentialRequirement(bytes32 requirementId) external;
145
+
146
+ /**
147
+ * @notice Gets a credential requirement.
148
+ * @param requirementId The identifier of the requirement.
149
+ * @return The credential requirement.
150
+ */
151
+ function getCredentialRequirement(bytes32 requirementId) external view returns (CredentialRequirement memory);
152
+
153
+ /**
154
+ * @notice Get all of the credential requirement identifiers.
155
+ * @return The credential requirement identifiers.
156
+ */
157
+ function getCredentialRequirementIds() external view returns (bytes32[] memory);
158
+
159
+ /**
160
+ * @notice Adds a new credential source.
161
+ *
162
+ * - MUST revert with `SourceExists` if the source already exists.
163
+ * - MUST emit the `CredentialSourceAdded` event.
164
+ *
165
+ * @param CredentialSourceInput The input struct used to add a new credential source.
166
+ */
167
+ function addCredentialSource(CredentialSourceInput memory CredentialSourceInput) external;
168
+
169
+ /**
170
+ * @notice Removes a credential source.
171
+ *
172
+ * - MUST revert with `CredentialSourceNotFound` if the source does not exist.
173
+ * - MUST emit the `CredentialSourceRemoved` event.
174
+ *
175
+ * @param credentialTypeId The credential type identifier.
176
+ * @param identityRegistry The address of the identity registry.
177
+ * @param credentialRegistry The address of the credential registry.
178
+ */
179
+ function removeCredentialSource(
180
+ bytes32 credentialTypeId,
181
+ address identityRegistry,
182
+ address credentialRegistry
183
+ )
184
+ external;
185
+
186
+ /**
187
+ * @notice Gets all credential sources.
188
+ * @param credentialTypeId The credential type identifier.
189
+ * @return The credential sources.
190
+ */
191
+ function getCredentialSources(bytes32 credentialTypeId) external view returns (CredentialSource[] memory);
192
+ }
@@ -0,0 +1,37 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity ^0.8.20;
3
+
4
+ /**
5
+ * @title ICredentialValidator
6
+ * @dev Interface for validating a ccid has a credential.
7
+ */
8
+ interface ICredentialValidator {
9
+ /**
10
+ * @notice Checks if a credential is valid for the specified cross-chain identity.
11
+ * @dev This function MUST NOT revert. Handle all validation failures gracefully and return
12
+ * false instead of allowing exceptions to propagate.
13
+ * @param ccid The cross-chain identity of the account.
14
+ * @param credentialTypeId The credential type identifier.
15
+ * @param context Additional information or authorization to perform the operation.
16
+ * @return True if the credential is valid, otherwise false.
17
+ */
18
+ function validate(bytes32 ccid, bytes32 credentialTypeId, bytes calldata context) external view returns (bool);
19
+
20
+ /**
21
+ * @notice Checks if all of the credentials are valid for the specified cross-chain identity.
22
+ * @dev This function MUST NOT revert. Handle all validation failures gracefully and return
23
+ * false instead of allowing exceptions to propagate.
24
+ * @param ccid The cross-chain identity of the account.
25
+ * @param credentialTypeIds The credential type identifiers.
26
+ * @param context Additional information or authorization to perform the operation.
27
+ * @return True if the credential is valid, otherwise false.
28
+ */
29
+ function validateAll(
30
+ bytes32 ccid,
31
+ bytes32[] calldata credentialTypeIds,
32
+ bytes calldata context
33
+ )
34
+ external
35
+ view
36
+ returns (bool);
37
+ }