@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,148 @@
1
+ > **Prerequisite: Understanding Policy Management**
2
+ >
3
+ > This component is designed to be securely governed by the **[Policy Management](../policy-management/README.md)** component. The following examples and guides assume you have a basic understanding of how the `PolicyEngine` and policies work. We recommend reviewing the Policy Management documentation first.
4
+
5
+ # Cross-Chain Identity
6
+
7
+ **A unified identity and credential management system for all EVM-compatible blockchains, secured by the Policy Management component.**
8
+
9
+ Cross-Chain Identity provides a **single identity system** that works across all EVM chains. Using Cross-Chain Identifiers (**CCID**s) as unique identity anchors, you can **attach credentials** like
10
+ KYC, AML, or custom verifications **to each CCID** once and verify them everywhere—no more maintaining separate identity systems on each chain.
11
+
12
+ ## Why This Matters
13
+
14
+ Managing user identity and compliance credentials (like KYC/AML) across multiple blockchains is a major challenge. Without a unified system, a user's identity is tied to a single address, forcing them to re-verify for every new address and on every new chain. This is expensive, inefficient, and a terrible user experience.
15
+
16
+ ```solidity
17
+ // ❌ Before: A fragmented, per-address system. A user's KYC is tied
18
+ // to one address and doesn't apply to their other addresses.
19
+ contract FragmentedDApp {
20
+ mapping(address => bool) public isKycVerified;
21
+
22
+ function sensitiveAction() public {
23
+ // This fails if the user calls from a different, un-verified address,
24
+ // even if they are the same person who completed KYC.
25
+ require(isKycVerified[msg.sender], "User not verified");
26
+ // ...
27
+ }
28
+ }
29
+
30
+ // ✅ After: A unified, identity-centric system. A user's credential is
31
+ // attached to their universal identity (CCID), not just one address. Any of
32
+ // their linked addresses can be used to pass a compliance check.
33
+ import { PolicyProtected } from "@chainlink/policy-management/core/PolicyProtected.sol";
34
+
35
+ contract UnifiedDApp is PolicyProtected {
36
+ function sensitiveAction() public runPolicy {
37
+ // The attached CredentialRegistryIdentityValidatorPolicy checks the credential
38
+ // associated with the msg.sender's underlying CCID.
39
+ // ...
40
+ }
41
+ }
42
+ ```
43
+
44
+ The Cross-Chain Identity component solves this with a universal **Cross-Chain Identifier (CCID)**. By attaching a credential to a user's single, persistent identity instead of a single address, that credential becomes portable and reusable across all their addresses and all EVM chains. A user verifies once and is recognized everywhere.
45
+
46
+ When this system is governed by the Policy Management component, it becomes not just portable, but also dynamically upgradeable, allowing you to change your credential requirements on the fly.
47
+
48
+ ## How It Works: An Overview
49
+
50
+ Cross-Chain Identity is built on two core pillars:
51
+
52
+ 1. **[Cross-Chain Identifier (CCID)](docs/CONCEPTS.md#1-cross-chain-identifier-ccid)**: A unique `bytes32` identifier that links a user's various blockchain addresses (EVM) into a single, universal identity.
53
+ 2. **[Credential Management](docs/CONCEPTS.md#2-credential-management)**: A standardized framework to issue, manage, and verify credentials (like KYC/AML) associated with a CCID. By attaching credentials to a CCID instead of a wallet address, they become portable across all chains.
54
+
55
+ These concepts are implemented through a few key onchain contracts and offchain actors.
56
+
57
+ ### Core Identity Components
58
+
59
+ - **`IdentityRegistry` & `CredentialRegistry`**: These two contracts are the heart of the system. The first maps user addresses to their universal CCID, and the second stores the credentials (like KYC status) associated with that CCID.
60
+ - **Credential Issuer (Offchain Actor)**: This is a trusted entity (e.g., your KYC provider) that performs real-world verification. It has the onchain permission to create new identities in the `IdentityRegistry` and/or issue credentials to them in the `CredentialRegistry`.
61
+ - **`CredentialRegistryIdentityValidatorPolicy`**: This is a specialized, pre-built policy that contains all the logic for checking credentials. You attach this to your application's functions to enforce your compliance rules.
62
+
63
+ ### The Governance Layer (Policy Management)
64
+
65
+ The entire identity system is designed to be securely governed by the [Policy Management component](../policy-management/README.md).
66
+
67
+ - **Protecting the Registries**: The administrative functions on the `IdentityRegistry` and `CredentialRegistry` are protected by a `PolicyEngine`. This ensures that no unauthorized changes can be made.
68
+ - **Authorizing Issuers**: Instead of hardcoding who can manage the registries, you use a policy (like `OnlyAuthorizedSenderPolicy`) to grant a specific `Credential Issuer` the permission to call administrative functions on the `IdentityRegistry` and/or the `CredentialRegistry`.
69
+
70
+ This two-layered approach provides a powerful separation of concerns: the identity components manage the data, and the policy components manage the permissions.
71
+
72
+ This diagram illustrates how the components work together in the recommended, integrated pattern.
73
+
74
+ ```mermaid
75
+ graph TD
76
+ subgraph "Offchain"
77
+ Issuer["Credential Issuer"]
78
+ end
79
+
80
+ subgraph "Onchain Application"
81
+ YourApp["Your dApp<br/>(PolicyProtected)"]
82
+ end
83
+
84
+ subgraph "Policy Management"
85
+ PE["PolicyEngine"]
86
+ IVP["CredentialRegistryIdentityValidatorPolicy"]
87
+ IssuancePolicy["Issuance Policy<br/>(e.g., OnlyAuthorizedSender)"]
88
+ end
89
+
90
+ subgraph "Cross-Chain Identity"
91
+ IR["IdentityRegistry"]
92
+ CR["CredentialRegistry"]
93
+ end
94
+
95
+ Issuer -- "1- Issues Credential" --> CR
96
+ Issuer -- "1- Creates Identity" --> IR
97
+ CR -- "is protected by" --> PE
98
+ IR -- "is protected by" --> PE
99
+ PE -- "uses" --> IssuancePolicy
100
+
101
+ YourApp -- "2- User calls protected function" --> PE
102
+ PE -- "3- Validates user via" --> IVP
103
+ IVP -- "4- Reads from" --> IR
104
+ IVP -- "4- Reads from" --> CR
105
+ ```
106
+
107
+ **Key Benefits**:
108
+
109
+ - **Cross-Chain Consistency**: Verify credentials issued on any EVM chain.
110
+ - **Secure by Design**: All administrative actions on the identity registries are governed by onchain policies.
111
+ - **Role Separation**: Clearly separates the role of the credential issuer from the application owner.
112
+ - **Dynamic & Upgradeable**: Update your verification requirements (e.g., require a new credential) or change your list of trusted issuers simply by updating a policy in the engine, with no changes to your core application.
113
+ - **Privacy Preserving**: Private information stays offchain, only verification results are onchain.
114
+
115
+ ## How to Use
116
+
117
+ Using the Cross-Chain Identity component in a secure, integrated way involves three main steps, which are typically performed in a deployment script:
118
+
119
+ 1. **Deploy and Secure Infrastructure**: Deploy the `IdentityRegistry` and `CredentialRegistry`, making sure to set their owner to your `PolicyEngine` instance.
120
+ 2. **Configure Validation**: Deploy and configure the `CredentialRegistryIdentityValidatorPolicy` with your desired credential requirements (e.g., must have KYC). Then, use the `PolicyEngine` to attach this policy to the application functions you want to protect.
121
+ 3. **Authorize Issuers**: Deploy an access control policy (like `OnlyAuthorizedSenderPolicy`) to grant a trusted off-chain entity the permission to issue new credentials.
122
+
123
+ This setup creates a robust system where credential issuance and validation are both governed by flexible, onchain policies.
124
+
125
+ → **For a complete, step-by-step code walkthrough, see the [API Guide](./docs/API_GUIDE.md).**
126
+
127
+ ## Critical Requirements
128
+
129
+ ### Non-Reverting View Functions
130
+
131
+ **All view functions in Cross-Chain Identity interfaces MUST NOT revert under any circumstances.** This is a critical requirement for reliable system operation.
132
+
133
+ Specifically, the following functions must be implemented with defensive programming patterns:
134
+
135
+ - `IIdentityValidator.validate()`
136
+ - `ICredentialDataValidator.validateCredentialData()`
137
+ - `ICredentialRegistryValidator.validate()` and `validateAll()`
138
+
139
+ Implementations should use try-catch blocks around external calls and return appropriate boolean results rather than allowing reverts to propagate. This ensures that credential validation failures in one source don't block the entire validation process.
140
+
141
+ ## Next Steps
142
+
143
+ - **[Core Concepts](./docs/CONCEPTS.md)**: A deep dive into the architecture and design rationale.
144
+ - **[Credential Flow](./docs/CREDENTIAL_FLOW.md)**: A detailed sequence diagram of the entire verification process.
145
+ - **[API Guide](./docs/API_GUIDE.md)**: A developer-focused guide for common tasks.
146
+ - **[API Reference](./docs/API_REFERENCE.md)**: Complete interface specifications.
147
+ - **[Security Considerations](./docs/SECURITY.md)**: A checklist of key principles for a secure implementation.
148
+ - **[Implementation](./src/) & [Tests](./test/)**: Examine the reference implementation in `/src` and see it in action in the `/test` folder.
@@ -0,0 +1,120 @@
1
+ # API Guide: Cross-Chain Identity
2
+
3
+ This guide provides practical, task-oriented examples for using the Cross-Chain Identity component as part of the integrated Chainlink ACE, secured by the Policy Management component.
4
+
5
+ ## 1. Setting Up the Identity Infrastructure
6
+
7
+ The first step is to deploy the core contracts. The recommended pattern is to create a secure system where the `IdentityRegistry` and `CredentialRegistry` are governed by a `PolicyEngine`.
8
+
9
+ Here is how you would write the deployment script code:
10
+
11
+ ```solidity
12
+ // --- In your deployment script ---
13
+ import { PolicyEngine } from "@chainlink/policy-management/core/PolicyEngine.sol";
14
+ import { IdentityRegistry } from "@chainlink/cross-chain-identity/src/IdentityRegistry.sol";
15
+ import { CredentialRegistry } from "@chainlink/cross-chain-identity/src/CredentialRegistry.sol";
16
+
17
+ // 1. Deploy the engine that will act as the guardian
18
+ PolicyEngine policyEngine = new PolicyEngine();
19
+ bool defaultAllow = true;
20
+ policyEngine.initialize(defaultAllow, address(this)); // Recommended default
21
+
22
+ // 2. Deploy the registries and transfer their ownership to the engine
23
+ IdentityRegistry identityRegistry = new IdentityRegistry();
24
+ identityRegistry.initialize(address(policyEngine));
25
+
26
+ CredentialRegistry credentialRegistry = new CredentialRegistry();
27
+ credentialRegistry.initialize(address(policyEngine));
28
+ ```
29
+
30
+ With this setup, all administrative actions on the registries (like issuing credentials) are now under the control of the `PolicyEngine`.
31
+
32
+ ## Task 2: Performing Validation with `CredentialRegistryIdentityValidatorPolicy`
33
+
34
+ The primary way to check for credentials in an integrated system is with the `CredentialRegistryIdentityValidatorPolicy`. This is a specialized policy that contains all the logic needed to query the registries.
35
+
36
+ ### Step 2.1: Deploy and Configure the Policy
37
+
38
+ First, deploy an instance of `CredentialRegistryIdentityValidatorPolicy`. Its `initialize` function takes the credential sources and requirements as ABI-encoded arguments.
39
+
40
+ ```solidity
41
+ // --- In your deployment script ---
42
+ import { CredentialRegistryIdentityValidatorPolicy } from "@chainlink/cross-chain-identity/src/CredentialRegistryIdentityValidatorPolicy.sol";
43
+ import { ICredentialRequirements } from "@chainlink/cross-chain-identity/src/interfaces/ICredentialRequirements.sol";
44
+
45
+ // e.g.: Define the KYC credential type we will be checking for
46
+ bytes32 kycCredential = keccak256("common.kyc");
47
+
48
+ // 1. Define the Credential Source
49
+ // This tells the policy which registries to use for the "common.kyc" type.
50
+ ICredentialRequirements.CredentialSourceInput[] memory sources = new ICredentialRequirements.CredentialSourceInput[](1);
51
+ sources[0] = ICredentialRequirements.CredentialSourceInput(kycCredential, address(identityRegistry), address(credentialRegistry), address(0));
52
+
53
+ // 2. Define the Credential Requirement
54
+ // This specifies that an identity must have at least one "common.kyc" credential.
55
+ bytes32[] memory requiredCredentials = new bytes32[](1);
56
+ requiredCredentials[0] = kycCredential;
57
+ ICredentialRequirements.CredentialRequirementInput[] memory requirements = new ICredentialRequirements.CredentialRequirementInput[](1);
58
+ requirements[0] = ICredentialRequirements.CredentialRequirementInput(keccak256("requirement.KYC"), requiredCredentials, 1, false);
59
+
60
+ // 3. Deploy and initialize the policy
61
+ CredentialRegistryIdentityValidatorPolicy kycCheckPolicy = new CredentialRegistryIdentityValidatorPolicy();
62
+ kycCheckPolicy.initialize(address(policyEngine), address(this), abi.encode(sources, requirements));
63
+ ```
64
+
65
+ ### Step 2.2: Attach the Policy to Your Application
66
+
67
+ Next, use the `PolicyEngine` to apply your `kycCheckPolicy` to a protected function, such as an ERC20 token's `transfer` method.
68
+
69
+ ```solidity
70
+ // --- In your deployment script ---
71
+ import { ERC20TransferExtractor } from "@chainlink/policy-management/extractors/ERC20TransferExtractor.sol";
72
+
73
+ // 1. Register an extractor to parse the 'to' address from the transfer function
74
+ ERC20TransferExtractor transferExtractor = new ERC20TransferExtractor();
75
+ policyEngine.setExtractor(myToken.transfer.selector, address(transferExtractor));
76
+
77
+ // 2. Specify that our policy needs the 'to' parameter from the extractor
78
+ bytes32[] memory transferParams = new bytes32[](1);
79
+ transferParams[0] = transferExtractor.PARAM_TO();
80
+
81
+ // 3. Add the policy to the engine for the token's transfer function
82
+ policyEngine.addPolicy(
83
+ address(myToken),
84
+ myToken.transfer.selector,
85
+ address(kycCheckPolicy),
86
+ transferParams
87
+ );
88
+ ```
89
+
90
+ Your token is now protected. All calls to `transfer()` will be automatically checked to ensure the recipient has a valid KYC credential.
91
+
92
+ ## Task 3: Authorizing a Credential Issuer
93
+
94
+ The final step is to grant a trusted offchain entity (the **Credential Issuer**) permission to write to the `CredentialRegistry`.
95
+
96
+ **The Goal:** You want to allow a specific address (`verificationIssuer`) to call `registerCredential` on the `CredentialRegistry`, but no one else.
97
+
98
+ **The Action:** You deploy a simple access control policy (like `OnlyAuthorizedSenderPolicy`) and apply it to the `registerCredential` function on the registry contract itself.
99
+
100
+ ```solidity
101
+ // --- In your deployment script ---
102
+ import { OnlyAuthorizedSenderPolicy } from "@chainlink/policy-management/policies/OnlyAuthorizedSenderPolicy.sol";
103
+
104
+ address verificationIssuer = 0x...; // The address of your trusted KYC provider
105
+
106
+ // 1. Deploy a policy that manages a list of authorized senders
107
+ OnlyAuthorizedSenderPolicy issuerPolicy = new OnlyAuthorizedSenderPolicy();
108
+ issuerPolicy.initialize(address(policyEngine), address(this), new bytes(0));
109
+ issuerPolicy.authorizeSender(verificationIssuer);
110
+
111
+ // 2. Apply this policy to the CredentialRegistry's `registerCredential` function
112
+ policyEngine.addPolicy(
113
+ address(credentialRegistry),
114
+ credentialRegistry.registerCredential.selector,
115
+ address(issuerPolicy),
116
+ new bytes32[](0) // No parameters needed for this policy
117
+ );
118
+ ```
119
+
120
+ Your system is now fully configured. The `verificationIssuer` is the only entity that can issue KYC credentials, and your `myToken` contract will automatically enforce that all recipients of a transfer possess one.
@@ -0,0 +1,271 @@
1
+ > **Note for Developers:** This file provides a complete, auto-generated list of all functions and interfaces. For a more practical, task-oriented guide with code examples, please see the **[API Guide](API_GUIDE.md)** first.
2
+
3
+ # API Reference: Cross-Chain Identity
4
+
5
+ This document provides the complete, formal interface specifications for the Cross-Chain Identity component.
6
+
7
+ ## Core Interfaces
8
+
9
+ ### IIdentityRegistry
10
+
11
+ **File:** [`src/interfaces/IIdentityRegistry.sol`](../src/interfaces/IIdentityRegistry.sol)
12
+
13
+ The `IIdentityRegistry` manages how each local blockchain address maps to a Cross-Chain Identifier (CCID). By interacting with this registry, applications can link multiple addresses to a single identity.
14
+
15
+ #### Key Functions
16
+
17
+ ```solidity
18
+ interface IIdentityRegistry {
19
+ function registerIdentity(bytes32 ccid, address account, bytes calldata context) external;
20
+ function registerIdentities(bytes32[] calldata ccids, address[] calldata accounts, bytes calldata context) external;
21
+ function removeIdentity(bytes32 ccid, address account, bytes calldata context) external;
22
+ function getIdentity(address account) external view returns (bytes32);
23
+ function getAccounts(bytes32 ccid) external view returns (address[] memory);
24
+ }
25
+ ```
26
+
27
+ #### Events
28
+
29
+ ```solidity
30
+ event IdentityRegistered(bytes32 indexed ccid, address indexed account);
31
+ event IdentityRemoved(bytes32 indexed ccid, address indexed account);
32
+ ```
33
+
34
+ #### Errors
35
+
36
+ ```solidity
37
+ error IdentityAlreadyRegistered(bytes32 ccid, address account);
38
+ error IdentityNotFound(bytes32 ccid, address account);
39
+ error InvalidConfiguration(bytes errorReason);
40
+ ```
41
+
42
+ ### ICredentialRegistry
43
+
44
+ **File:** [`src/interfaces/ICredentialRegistry.sol`](../src/interfaces/ICredentialRegistry.sol)
45
+
46
+ The `ICredentialRegistry` manages the lifecycle of credentials linked to a CCID, including registration, removal, and renewal processes.
47
+
48
+ #### Credential Struct
49
+
50
+ ```solidity
51
+ struct Credential {
52
+ uint40 expiresAt;
53
+ bytes credentialData;
54
+ }
55
+ ```
56
+
57
+ #### Key Functions
58
+
59
+ ```solidity
60
+ interface ICredentialRegistry {
61
+ function registerCredential(
62
+ bytes32 ccid,
63
+ bytes32 credentialTypeId,
64
+ uint40 expiresAt,
65
+ bytes calldata credentialData,
66
+ bytes calldata context
67
+ ) external;
68
+
69
+ function registerCredentials(
70
+ bytes32 ccid,
71
+ bytes32[] calldata credentialTypeIds,
72
+ uint40 expiresAt,
73
+ bytes[] calldata credentialDatas,
74
+ bytes calldata context
75
+ ) external;
76
+
77
+ function removeCredential(bytes32 ccid, bytes32 credentialTypeId, bytes calldata context) external;
78
+
79
+ function renewCredential(bytes32 ccid, bytes32 credentialTypeId, uint40 expiresAt, bytes calldata context) external;
80
+
81
+ function isCredentialExpired(bytes32 ccid, bytes32 credentialTypeId) external view returns (bool);
82
+
83
+ function getCredentialTypes(bytes32 ccid) external view returns (bytes32[] memory);
84
+
85
+ function getCredential(bytes32 ccid, bytes32 credentialTypeId) external view returns (Credential memory);
86
+
87
+ function getCredentials(
88
+ bytes32 ccid,
89
+ bytes32[] calldata credentialTypeIds
90
+ ) external view returns (Credential[] memory);
91
+ }
92
+ ```
93
+
94
+ #### Events
95
+
96
+ ```solidity
97
+ event CredentialRegistered(
98
+ bytes32 indexed ccid, bytes32 indexed credentialTypeId, uint40 expiresAt, bytes credentialData
99
+ );
100
+ event CredentialRemoved(bytes32 indexed ccid, bytes32 indexed credentialTypeId);
101
+ event CredentialRenewed(
102
+ bytes32 indexed ccid,
103
+ bytes32 indexed credentialTypeId,
104
+ uint40 previousExpiresAt,
105
+ uint40 expiresAt
106
+ );
107
+ ```
108
+
109
+ #### Errors
110
+
111
+ ```solidity
112
+ error CredentialAlreadyRegistered(bytes32 ccid, bytes32 credentialTypeId);
113
+ error CredentialNotFound(bytes32 ccid, bytes32 credentialTypeId);
114
+ error InvalidConfiguration(string errorReason);
115
+ ```
116
+
117
+ ### ICredentialRegistryValidator
118
+
119
+ **File:** [`src/interfaces/ICredentialRegistryValidator.sol`](../src/interfaces/ICredentialRegistryValidator.sol)
120
+
121
+ The `ICredentialRegistryValidator` provides validation functionality to check whether credentials exist and are valid for a given CCID.
122
+
123
+ #### Key Functions
124
+
125
+ ```solidity
126
+ interface ICredentialRegistryValidator {
127
+ function validate(bytes32 ccid, bytes32 credentialTypeId, bytes calldata context) external view returns (bool);
128
+
129
+ function validateAll(
130
+ bytes32 ccid,
131
+ bytes32[] calldata credentialTypeIds,
132
+ bytes calldata context
133
+ ) external view returns (bool);
134
+ }
135
+ ```
136
+
137
+ #### Critical Requirements
138
+
139
+ **Non-Reverting Guarantee:** The `validate` and `validateAll` functions, along with all other view functions in `ICredentialRegistryValidator` implementations **MUST NOT revert under any circumstances**. This requirement is critical to ensure reliable interactions with credential registry validator contracts.
140
+
141
+ ## Application Integration Interfaces
142
+
143
+ ### ICredentialRequirements
144
+
145
+ **File:** [`src/interfaces/ICredentialRequirements.sol`](../src/interfaces/ICredentialRequirements.sol)
146
+
147
+ The `ICredentialRequirements` interface allows applications to define complex credential requirements using multiple sources and validation rules.
148
+
149
+ #### Key Structs
150
+
151
+ ```solidity
152
+ struct CredentialRequirement {
153
+ bytes32[] credentialTypeIds;
154
+ uint256 minValidations;
155
+ bool invert;
156
+ }
157
+
158
+ struct CredentialSource {
159
+ address identityRegistry;
160
+ address credentialRegistry;
161
+ address dataValidator;
162
+ }
163
+
164
+ struct CredentialRequirementInput {
165
+ bytes32 requirementId;
166
+ bytes32[] credentialTypeIds;
167
+ uint256 minValidations;
168
+ bool invert;
169
+ }
170
+
171
+ struct CredentialSourceInput {
172
+ bytes32 credentialTypeId;
173
+ address identityRegistry;
174
+ address credentialRegistry;
175
+ address dataValidator;
176
+ }
177
+ ```
178
+
179
+ #### Key Functions
180
+
181
+ ```solidity
182
+ interface ICredentialRequirements {
183
+ function addCredentialRequirement(CredentialRequirementInput memory input) external;
184
+ function removeCredentialRequirement(bytes32 requirementId) external;
185
+ function getCredentialRequirement(bytes32 requirementId) external view returns (CredentialRequirement memory);
186
+ function getCredentialRequirementIds() external view returns (bytes32[] memory);
187
+
188
+ function addCredentialSource(CredentialSourceInput memory input) external;
189
+ function removeCredentialSource(
190
+ bytes32 credentialTypeId,
191
+ address identityRegistry,
192
+ address credentialRegistry
193
+ ) external;
194
+ function getCredentialSources(bytes32 credentialTypeId) external view returns (CredentialSource[] memory);
195
+ }
196
+ ```
197
+
198
+ #### Events
199
+
200
+ ```solidity
201
+ event CredentialRequirementAdded(bytes32 indexed requirementId, bytes32[] credentialTypeIds, uint256 minValidations, bool invert);
202
+ event CredentialRequirementRemoved(bytes32 indexed requirementId, bytes32[] credentialTypeIds, uint256 minValidations, bool invert);
203
+ event CredentialSourceAdded(
204
+ bytes32 indexed credentialTypeId,
205
+ address indexed identityRegistry,
206
+ address indexed credentialRegistry,
207
+ address dataValidator
208
+ );
209
+ event CredentialSourceRemoved(
210
+ bytes32 indexed credentialTypeId,
211
+ address indexed identityRegistry,
212
+ address indexed credentialRegistry,
213
+ address dataValidator
214
+ );
215
+ ```
216
+
217
+ #### Errors
218
+
219
+ ```solidity
220
+ error RequirementExists(bytes32 requirementId);
221
+ error RequirementNotFound(bytes32 requirementId);
222
+ error SourceExists(bytes32 credentialTypeId, address identityRegistry, address credentialRegistry);
223
+ error SourceNotFound(bytes32 credentialTypeId, address identityRegistry, address credentialRegistry);
224
+ error InvalidConfiguration(string errorReason);
225
+ ```
226
+
227
+ ### IIdentityValidator
228
+
229
+ **File:** [`src/interfaces/IIdentityValidator.sol`](../src/interfaces/IIdentityValidator.sol)
230
+
231
+ The `IIdentityValidator` provides a unified interface for applications to validate user accounts against defined credential requirements.
232
+
233
+ #### Key Functions
234
+
235
+ ```solidity
236
+ interface IIdentityValidator {
237
+ function validate(address account, bytes calldata context) external view returns (bool);
238
+ }
239
+ ```
240
+
241
+ #### Critical Requirements
242
+
243
+ **Non-Reverting Guarantee:** The `validate` function and all other view functions in `IIdentityValidator` implementations **MUST NOT revert under any circumstances**. This requirement is critical to ensure reliable interactions with IdentityValidator contracts.
244
+
245
+ Implementations must use defensive programming patterns such as try-catch blocks around external calls to gracefully handle failures and return appropriate boolean results rather than allowing reverts to propagate.
246
+
247
+ ## Data Validation Interface
248
+
249
+ ### ICredentialDataValidator
250
+
251
+ **File:** [`src/interfaces/ICredentialDataValidator.sol`](../src/interfaces/ICredentialDataValidator.sol)
252
+
253
+ The `ICredentialDataValidator` is an optional interface for implementing custom validation rules on the data attached to a credential.
254
+
255
+ #### Key Functions
256
+
257
+ ```solidity
258
+ interface ICredentialDataValidator {
259
+ function validateCredentialData(
260
+ bytes32 ccid,
261
+ address account,
262
+ bytes32 credentialTypeId,
263
+ bytes calldata credentialData,
264
+ bytes calldata context
265
+ ) external view returns (bool);
266
+ }
267
+ ```
268
+
269
+ #### Critical Requirements
270
+
271
+ **Non-Reverting Guarantee:** The `validateCredentialData` function and all other view functions in `ICredentialDataValidator` implementations **MUST NOT revert under any circumstances**. This requirement is critical to ensure reliable interactions with data validator contracts.