Step 4: Create minimal test skeleton and run to verify compilation
Run: cd contracts && forge test --match-contract DIDFacetTest -v Expected: 1 test PASS
Step 5: Commit
Task 2: DIDFacetLocal — L2→L1 Sync 实现 + 测试
Files:
Create: contracts/src/did/DIDFacetLocal.sol
Modify: contracts/test/DIDFacet.t.sol
Step 1: Write DIDFacetLocal with L2→L1 sync functions
Step 2: Write L2→L1 sync tests (14 tests)
Add these tests to contracts/test/DIDFacet.t.sol:
Step 3: Run tests
Run: cd contracts && forge test --match-contract DIDFacetTest -v Expected: 17 tests PASS
Step 4: Commit
Task 3: DIDFacetLocal — L1→L2 Request 实现 + 测试
Files:
Modify: contracts/src/did/DIDFacetLocal.sol
Modify: contracts/test/DIDFacet.t.sol
Step 1: Replace request function placeholders with real implementations
Replace the 5 placeholder request* functions in DIDFacetLocal.sol:
Note: Import L2TransactionRequestDirect struct and MockBridgehub — they must be accessible. Since DIDFacetLocal imports from MockBridgehub, move the struct to a shared location or import from the mock file. Simplest: import MockBridgehub directly in DIDFacetLocal (it's a Local test contract anyway).
Actually, better approach: create a minimal IBridgehub interface in contracts/src/interfaces/:
Then DIDFacetLocal imports IBridgehubLocal and MockBridgehub implements it.
// Add import at top:
import {IL1Messenger, L1_MESSENGER_CONTRACT} from "./interfaces/IL1Messenger.sol";
// In createDID(), after existing logic and before closing brace:
IL1Messenger(L1_MESSENGER_CONTRACT).sendToL1(
abi.encode(uint8(0), msg.sender, verificationMethods, serviceEndpointHash, _nonces[msg.sender])
);
// In updateDocument(), after existing logic:
IL1Messenger(L1_MESSENGER_CONTRACT).sendToL1(
abi.encode(uint8(1), msg.sender, verificationMethods, serviceEndpointHash, _nonces[msg.sender])
);
// In deactivateDID(), after existing logic:
IL1Messenger(L1_MESSENGER_CONTRACT).sendToL1(
abi.encode(uint8(2), msg.sender, _nonces[msg.sender])
);
// Add import at top:
import {IL1Messenger, L1_MESSENGER_CONTRACT} from "./interfaces/IL1Messenger.sol";
// In issueCredential(), before return:
IL1Messenger(L1_MESSENGER_CONTRACT).sendToL1(
abi.encode(uint8(3), credentialId, msg.sender, subject, credentialType, claimHash, uint64(block.timestamp), expiresAt)
);
// In revokeCredential(), after setting _revoked:
IL1Messenger(L1_MESSENGER_CONTRACT).sendToL1(
abi.encode(uint8(4), credentialId, msg.sender)
);
// Import should already exist (check first), if not add:
import {IL1Messenger, L1_MESSENGER_CONTRACT} from "./interfaces/IL1Messenger.sol";
// In setCompliance(), after setting compliance mapping:
IL1Messenger(L1_MESSENGER_CONTRACT).sendToL1(
abi.encode(uint8(5), identity, requirement, status)
);
// In addTrustedIssuer(), after setting _trustedIssuers:
IL1Messenger(L1_MESSENGER_CONTRACT).sendToL1(
abi.encode(uint8(6), issuer)
);
// In removeTrustedIssuer(), after deleting _trustedIssuers:
IL1Messenger(L1_MESSENGER_CONTRACT).sendToL1(
abi.encode(uint8(7), issuer)
);
cd era-contracts-l1
git add system-contracts/contracts/DIDRegistry.sol \
system-contracts/contracts/CredentialRegistry.sol \
system-contracts/contracts/IdentityVerifier.sol
git commit -m "feat(did): L1Messenger integration for L2→L1 DID state sync"