@diamondslab/diamonds 1.0.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 (229) hide show
  1. package/README.md +618 -0
  2. package/diamonds/README.md +3 -0
  3. package/dist/core/CallbackManager.d.ts +13 -0
  4. package/dist/core/CallbackManager.d.ts.map +1 -0
  5. package/dist/core/CallbackManager.js +95 -0
  6. package/dist/core/CallbackManager.js.map +1 -0
  7. package/dist/core/DeploymentManager.d.ts +10 -0
  8. package/dist/core/DeploymentManager.d.ts.map +1 -0
  9. package/dist/core/DeploymentManager.js +50 -0
  10. package/dist/core/DeploymentManager.js.map +1 -0
  11. package/dist/core/Diamond.d.ts +58 -0
  12. package/dist/core/Diamond.d.ts.map +1 -0
  13. package/dist/core/Diamond.js +146 -0
  14. package/dist/core/Diamond.js.map +1 -0
  15. package/dist/core/DiamondDeployer.d.ts +10 -0
  16. package/dist/core/DiamondDeployer.d.ts.map +1 -0
  17. package/dist/core/DiamondDeployer.js +33 -0
  18. package/dist/core/DiamondDeployer.js.map +1 -0
  19. package/dist/core/index.d.ts +5 -0
  20. package/dist/core/index.d.ts.map +1 -0
  21. package/dist/core/index.js +12 -0
  22. package/dist/core/index.js.map +1 -0
  23. package/dist/index.d.ts +6 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +22 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/repositories/DBDeploymentRepository.d.ts +1 -0
  28. package/dist/repositories/DBDeploymentRepository.d.ts.map +1 -0
  29. package/dist/repositories/DBDeploymentRepository.js +20 -0
  30. package/dist/repositories/DBDeploymentRepository.js.map +1 -0
  31. package/dist/repositories/DeploymentRepository.d.ts +8 -0
  32. package/dist/repositories/DeploymentRepository.d.ts.map +1 -0
  33. package/dist/repositories/DeploymentRepository.js +7 -0
  34. package/dist/repositories/DeploymentRepository.js.map +1 -0
  35. package/dist/repositories/FileDeploymentRepository.d.ts +18 -0
  36. package/dist/repositories/FileDeploymentRepository.d.ts.map +1 -0
  37. package/dist/repositories/FileDeploymentRepository.js +58 -0
  38. package/dist/repositories/FileDeploymentRepository.js.map +1 -0
  39. package/dist/repositories/databaseHandler.d.ts +1 -0
  40. package/dist/repositories/databaseHandler.d.ts.map +1 -0
  41. package/dist/repositories/databaseHandler.js +13 -0
  42. package/dist/repositories/databaseHandler.js.map +1 -0
  43. package/dist/repositories/index.d.ts +4 -0
  44. package/dist/repositories/index.d.ts.map +1 -0
  45. package/dist/repositories/index.js +20 -0
  46. package/dist/repositories/index.js.map +1 -0
  47. package/dist/repositories/jsonFileHandler.d.ts +81 -0
  48. package/dist/repositories/jsonFileHandler.d.ts.map +1 -0
  49. package/dist/repositories/jsonFileHandler.js +223 -0
  50. package/dist/repositories/jsonFileHandler.js.map +1 -0
  51. package/dist/repositories/prismaDBHandler.d.ts +1 -0
  52. package/dist/repositories/prismaDBHandler.d.ts.map +1 -0
  53. package/dist/repositories/prismaDBHandler.js +11 -0
  54. package/dist/repositories/prismaDBHandler.js.map +1 -0
  55. package/dist/schemas/DeploymentSchema.d.ts +309 -0
  56. package/dist/schemas/DeploymentSchema.d.ts.map +1 -0
  57. package/dist/schemas/DeploymentSchema.js +56 -0
  58. package/dist/schemas/DeploymentSchema.js.map +1 -0
  59. package/dist/schemas/index.d.ts +2 -0
  60. package/dist/schemas/index.d.ts.map +1 -0
  61. package/dist/schemas/index.js +18 -0
  62. package/dist/schemas/index.js.map +1 -0
  63. package/dist/strategies/BaseDeploymentStrategy.d.ts +41 -0
  64. package/dist/strategies/BaseDeploymentStrategy.d.ts.map +1 -0
  65. package/dist/strategies/BaseDeploymentStrategy.js +545 -0
  66. package/dist/strategies/BaseDeploymentStrategy.js.map +1 -0
  67. package/dist/strategies/DeploymentStrategy.d.ts +19 -0
  68. package/dist/strategies/DeploymentStrategy.d.ts.map +1 -0
  69. package/dist/strategies/DeploymentStrategy.js +3 -0
  70. package/dist/strategies/DeploymentStrategy.js.map +1 -0
  71. package/dist/strategies/LocalDeploymentStrategy.d.ts +4 -0
  72. package/dist/strategies/LocalDeploymentStrategy.d.ts.map +1 -0
  73. package/dist/strategies/LocalDeploymentStrategy.js +8 -0
  74. package/dist/strategies/LocalDeploymentStrategy.js.map +1 -0
  75. package/dist/strategies/OZDefenderDeploymentStrategy.d.ts +62 -0
  76. package/dist/strategies/OZDefenderDeploymentStrategy.d.ts.map +1 -0
  77. package/dist/strategies/OZDefenderDeploymentStrategy.js +757 -0
  78. package/dist/strategies/OZDefenderDeploymentStrategy.js.map +1 -0
  79. package/dist/strategies/RPCDeploymentStrategy.d.ts +139 -0
  80. package/dist/strategies/RPCDeploymentStrategy.d.ts.map +1 -0
  81. package/dist/strategies/RPCDeploymentStrategy.js +710 -0
  82. package/dist/strategies/RPCDeploymentStrategy.js.map +1 -0
  83. package/dist/strategies/index.d.ts +6 -0
  84. package/dist/strategies/index.d.ts.map +1 -0
  85. package/dist/strategies/index.js +12 -0
  86. package/dist/strategies/index.js.map +1 -0
  87. package/dist/types/config.d.ts +26 -0
  88. package/dist/types/config.d.ts.map +1 -0
  89. package/dist/types/config.js +3 -0
  90. package/dist/types/config.js.map +1 -0
  91. package/dist/types/defender.d.ts +22 -0
  92. package/dist/types/defender.d.ts.map +1 -0
  93. package/dist/types/defender.js +3 -0
  94. package/dist/types/defender.js.map +1 -0
  95. package/dist/types/deployments.d.ts +71 -0
  96. package/dist/types/deployments.d.ts.map +1 -0
  97. package/dist/types/deployments.js +20 -0
  98. package/dist/types/deployments.js.map +1 -0
  99. package/dist/types/index.d.ts +5 -0
  100. package/dist/types/index.d.ts.map +1 -0
  101. package/dist/types/index.js +21 -0
  102. package/dist/types/index.js.map +1 -0
  103. package/dist/types/rpc.d.ts +35 -0
  104. package/dist/types/rpc.d.ts.map +1 -0
  105. package/dist/types/rpc.js +3 -0
  106. package/dist/types/rpc.js.map +1 -0
  107. package/dist/utils/common.d.ts +20 -0
  108. package/dist/utils/common.d.ts.map +1 -0
  109. package/dist/utils/common.js +45 -0
  110. package/dist/utils/common.js.map +1 -0
  111. package/dist/utils/configurationResolver.d.ts +30 -0
  112. package/dist/utils/configurationResolver.d.ts.map +1 -0
  113. package/dist/utils/configurationResolver.js +151 -0
  114. package/dist/utils/configurationResolver.js.map +1 -0
  115. package/dist/utils/contractMapping.d.ts +29 -0
  116. package/dist/utils/contractMapping.d.ts.map +1 -0
  117. package/dist/utils/contractMapping.js +224 -0
  118. package/dist/utils/contractMapping.js.map +1 -0
  119. package/dist/utils/defenderClients.d.ts +5 -0
  120. package/dist/utils/defenderClients.d.ts.map +1 -0
  121. package/dist/utils/defenderClients.js +21 -0
  122. package/dist/utils/defenderClients.js.map +1 -0
  123. package/dist/utils/defenderStore.d.ts +14 -0
  124. package/dist/utils/defenderStore.d.ts.map +1 -0
  125. package/dist/utils/defenderStore.js +92 -0
  126. package/dist/utils/defenderStore.js.map +1 -0
  127. package/dist/utils/diamondAbiGenerator.d.ts +113 -0
  128. package/dist/utils/diamondAbiGenerator.d.ts.map +1 -0
  129. package/dist/utils/diamondAbiGenerator.js +415 -0
  130. package/dist/utils/diamondAbiGenerator.js.map +1 -0
  131. package/dist/utils/diffDeployedFacets.d.ts +26 -0
  132. package/dist/utils/diffDeployedFacets.d.ts.map +1 -0
  133. package/dist/utils/diffDeployedFacets.js +106 -0
  134. package/dist/utils/diffDeployedFacets.js.map +1 -0
  135. package/dist/utils/index.d.ts +16 -0
  136. package/dist/utils/index.d.ts.map +1 -0
  137. package/dist/utils/index.js +35 -0
  138. package/dist/utils/index.js.map +1 -0
  139. package/dist/utils/loupe.d.ts +44 -0
  140. package/dist/utils/loupe.d.ts.map +1 -0
  141. package/dist/utils/loupe.js +128 -0
  142. package/dist/utils/loupe.js.map +1 -0
  143. package/dist/utils/rpcStore.d.ts +36 -0
  144. package/dist/utils/rpcStore.d.ts.map +1 -0
  145. package/dist/utils/rpcStore.js +166 -0
  146. package/dist/utils/rpcStore.js.map +1 -0
  147. package/dist/utils/signer.d.ts +36 -0
  148. package/dist/utils/signer.d.ts.map +1 -0
  149. package/dist/utils/signer.js +91 -0
  150. package/dist/utils/signer.js.map +1 -0
  151. package/dist/utils/txlogging.d.ts +13 -0
  152. package/dist/utils/txlogging.d.ts.map +1 -0
  153. package/dist/utils/txlogging.js +87 -0
  154. package/dist/utils/txlogging.js.map +1 -0
  155. package/dist/utils/workspaceSetup.d.ts +32 -0
  156. package/dist/utils/workspaceSetup.d.ts.map +1 -0
  157. package/dist/utils/workspaceSetup.js +311 -0
  158. package/dist/utils/workspaceSetup.js.map +1 -0
  159. package/docs/DIAMOND_ABI_CONFIGURATION_SUMMARY.md +40 -0
  160. package/docs/DIAMOND_ABI_GENERATION.md +220 -0
  161. package/docs/DIAMOND_ABI_GENERATOR_EXAMPLES.md +1204 -0
  162. package/docs/DIAMOND_ABI_GENERATOR_IMPLEMENTATION.md +947 -0
  163. package/docs/DIAMOND_ABI_GENERATOR_QUICK_REFERENCE.md +336 -0
  164. package/docs/README-DEFENDER.md +394 -0
  165. package/docs/README_DIAMOND_ABI_GENERATOR.md +303 -0
  166. package/docs/ROADMAP.md +250 -0
  167. package/docs/assets/image.png +0 -0
  168. package/docs/defender-integration.md +451 -0
  169. package/docs/diamond_module-BaseStrategy_design-v2.uxf +247 -0
  170. package/docs/diamond_module-BaseStrategy_design.uxf +272 -0
  171. package/docs/monitoring-troubleshooting.md +556 -0
  172. package/docs/testing-guide.md +713 -0
  173. package/examples/Diamond_Config_and_Deployment_examples/diamonds/ProxyDiamond/callbacks/ERC20ProxyFacet.ts +31 -0
  174. package/examples/Diamond_Config_and_Deployment_examples/diamonds/ProxyDiamond/proxydiamond.config.json +27 -0
  175. package/examples/Local_Hardhat_Deployer_Script_example/LocalDiamondDeployer.ts +180 -0
  176. package/examples/OZ_Defender_Deployer_Script_example/OZDiamondDeployer.ts +107 -0
  177. package/examples/OZ_Defender_Deployer_Script_example/run-oz-deploy.ts +17 -0
  178. package/examples/Test_examples/ProxyDiamondDeployment.test.ts +202 -0
  179. package/examples/defender-deployment/.env.example +35 -0
  180. package/examples/defender-deployment/README.md +415 -0
  181. package/examples/defender-deployment/contracts/ExampleDiamond.sol +41 -0
  182. package/examples/defender-deployment/contracts/ExampleFacet1.sol +84 -0
  183. package/examples/defender-deployment/contracts/ExampleFacet2.sol +104 -0
  184. package/examples/defender-deployment/contracts/UpgradeFacet.sol +92 -0
  185. package/examples/defender-deployment/deploy-script.ts +170 -0
  186. package/examples/defender-deployment/diamond-config.json +36 -0
  187. package/examples/defender-deployment/upgrade-script.ts +237 -0
  188. package/examples/hardhat-diamonds-config.example.ts +41 -0
  189. package/package.json +228 -0
  190. package/src/core/CallbackManager.ts +70 -0
  191. package/src/core/DeploymentManager.ts +64 -0
  192. package/src/core/Diamond.ts +197 -0
  193. package/src/core/DiamondDeployer.ts +36 -0
  194. package/src/core/index.ts +4 -0
  195. package/src/index.ts +5 -0
  196. package/src/repositories/DBDeploymentRepository.ts +22 -0
  197. package/src/repositories/DeploymentRepository.ts +12 -0
  198. package/src/repositories/FileDeploymentRepository.ts +67 -0
  199. package/src/repositories/databaseHandler.ts +14 -0
  200. package/src/repositories/index.ts +4 -0
  201. package/src/repositories/jsonFileHandler.ts +252 -0
  202. package/src/repositories/prismaDBHandler.ts +10 -0
  203. package/src/schemas/DeploymentSchema.ts +71 -0
  204. package/src/schemas/index.ts +1 -0
  205. package/src/strategies/BaseDeploymentStrategy.ts +649 -0
  206. package/src/strategies/DeploymentStrategy.ts +25 -0
  207. package/src/strategies/LocalDeploymentStrategy.ts +5 -0
  208. package/src/strategies/OZDefenderDeploymentStrategy.ts +849 -0
  209. package/src/strategies/RPCDeploymentStrategy.ts +881 -0
  210. package/src/strategies/index.ts +5 -0
  211. package/src/types/config.ts +34 -0
  212. package/src/types/defender.ts +24 -0
  213. package/src/types/deployments.ts +102 -0
  214. package/src/types/index.ts +4 -0
  215. package/src/types/rpc.ts +37 -0
  216. package/src/utils/common.ts +54 -0
  217. package/src/utils/configurationResolver.ts +141 -0
  218. package/src/utils/contractMapping.ts +220 -0
  219. package/src/utils/defenderClients.ts +22 -0
  220. package/src/utils/defenderStore.ts +62 -0
  221. package/src/utils/diamondAbiGenerator.ts +523 -0
  222. package/src/utils/diffDeployedFacets.ts +131 -0
  223. package/src/utils/index.ts +15 -0
  224. package/src/utils/loupe.ts +159 -0
  225. package/src/utils/rpcStore.ts +152 -0
  226. package/src/utils/signer.ts +93 -0
  227. package/src/utils/txlogging.ts +97 -0
  228. package/src/utils/workspaceSetup.ts +315 -0
  229. package/test/README.md +136 -0
@@ -0,0 +1,92 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.17;
3
+
4
+ contract UpgradeFacet {
5
+ bytes32 constant STORAGE_POSITION = keccak256("upgrade.facet.storage");
6
+
7
+ struct FacetStorage {
8
+ uint256 upgradeCount;
9
+ mapping(uint256 => uint256) upgradeTimestamps;
10
+ bool initialized;
11
+ string[] upgradeLog;
12
+ }
13
+
14
+ function facetStorage() internal pure returns (FacetStorage storage fs) {
15
+ bytes32 position = STORAGE_POSITION;
16
+ assembly {
17
+ fs.slot := position
18
+ }
19
+ }
20
+
21
+ event Initialized(uint256 timestamp);
22
+ event UpgradeLogged(uint256 indexed upgradeId, string description, uint256 timestamp);
23
+ event SystemUpgraded(string version, uint256 timestamp);
24
+
25
+ function initialize() external {
26
+ FacetStorage storage fs = facetStorage();
27
+ require(!fs.initialized, "Already initialized");
28
+
29
+ fs.initialized = true;
30
+ fs.upgradeCount = 0;
31
+
32
+ emit Initialized(block.timestamp);
33
+ }
34
+
35
+ function logUpgrade(string memory description) external {
36
+ FacetStorage storage fs = facetStorage();
37
+ require(fs.initialized, "Not initialized");
38
+
39
+ uint256 upgradeId = fs.upgradeCount++;
40
+ fs.upgradeTimestamps[upgradeId] = block.timestamp;
41
+ fs.upgradeLog.push(description);
42
+
43
+ emit UpgradeLogged(upgradeId, description, block.timestamp);
44
+ }
45
+
46
+ function getUpgradeCount() external view returns (uint256) {
47
+ FacetStorage storage fs = facetStorage();
48
+ return fs.upgradeCount;
49
+ }
50
+
51
+ function getUpgradeTimestamp(uint256 upgradeId) external view returns (uint256) {
52
+ FacetStorage storage fs = facetStorage();
53
+ require(upgradeId < fs.upgradeCount, "Invalid upgrade ID");
54
+ return fs.upgradeTimestamps[upgradeId];
55
+ }
56
+
57
+ function getUpgradeLog() external view returns (string[] memory) {
58
+ FacetStorage storage fs = facetStorage();
59
+ return fs.upgradeLog;
60
+ }
61
+
62
+ function getLatestUpgrade() external view returns (string memory, uint256) {
63
+ FacetStorage storage fs = facetStorage();
64
+ require(fs.upgradeCount > 0, "No upgrades logged");
65
+
66
+ uint256 latestId = fs.upgradeCount - 1;
67
+ return (fs.upgradeLog[latestId], fs.upgradeTimestamps[latestId]);
68
+ }
69
+
70
+ function markSystemUpgrade(string memory _version) external {
71
+ FacetStorage storage fs = facetStorage();
72
+ require(fs.initialized, "Not initialized");
73
+
74
+ string memory description = string(abi.encodePacked("System upgrade to version ", _version));
75
+
76
+ uint256 upgradeId = fs.upgradeCount++;
77
+ fs.upgradeTimestamps[upgradeId] = block.timestamp;
78
+ fs.upgradeLog.push(description);
79
+
80
+ emit UpgradeLogged(upgradeId, description, block.timestamp);
81
+ emit SystemUpgraded(_version, block.timestamp);
82
+ }
83
+
84
+ function isInitialized() external view returns (bool) {
85
+ FacetStorage storage fs = facetStorage();
86
+ return fs.initialized;
87
+ }
88
+
89
+ function version() external pure returns (string memory) {
90
+ return "1.0.0";
91
+ }
92
+ }
@@ -0,0 +1,170 @@
1
+ import { ethers } from 'hardhat';
2
+ import { Diamond } from '../../src/core/Diamond';
3
+ import { DiamondDeployer } from '../../src/core/DiamondDeployer';
4
+ import { FileDeploymentRepository } from '../../src/repositories/FileDeploymentRepository';
5
+ import { OZDefenderDeploymentStrategy } from '../../src/strategies/OZDefenderDeploymentStrategy';
6
+ import * as path from 'path';
7
+ import * as fs from 'fs-extra';
8
+
9
+ async function main() {
10
+ console.log('šŸš€ Starting Defender deployment...');
11
+
12
+ // Get network information
13
+ const network = await ethers.provider.getNetwork();
14
+ const signers = await ethers.getSigners();
15
+ const deployer = signers[0];
16
+
17
+ console.log(`šŸ“ Network: ${network.name} (${network.chainId})`);
18
+ console.log(`šŸ‘¤ Deployer: ${deployer.address}`);
19
+
20
+ // Load configuration
21
+ const configPath = path.join(__dirname, 'diamond-config.json');
22
+ const exampleConfig = {
23
+ diamondName: 'ExampleDiamond',
24
+ networkName: network.name,
25
+ chainId: network.chainId,
26
+ deploymentsPath: path.join(__dirname, 'deployments'),
27
+ contractsPath: path.join(__dirname, 'contracts'),
28
+ callbacksPath: path.join(__dirname, 'callbacks'),
29
+ configFilePath: configPath,
30
+ deployedDiamondDataFilePath: path.join(__dirname, 'deployments', `examplediamond-${network.name}-${network.chainId}.json`)
31
+ };
32
+
33
+ // Ensure directories exist
34
+ await fs.ensureDir(exampleConfig.deploymentsPath);
35
+ await fs.ensureDir(exampleConfig.callbacksPath);
36
+
37
+ // Create diamond instance
38
+ const repository = new FileDeploymentRepository(exampleConfig);
39
+ const diamond = new Diamond(exampleConfig, repository);
40
+
41
+ // Setup provider and signer
42
+ diamond.setProvider(ethers.provider);
43
+ diamond.setSigner(deployer);
44
+
45
+ // Validate environment variables
46
+ const requiredEnvVars = [
47
+ 'DEFENDER_API_KEY',
48
+ 'DEFENDER_API_SECRET',
49
+ 'DEFENDER_RELAYER_ADDRESS',
50
+ 'DEFENDER_SAFE_ADDRESS'
51
+ ];
52
+
53
+ for (const envVar of requiredEnvVars) {
54
+ if (!process.env[envVar]) {
55
+ console.error(`āŒ Missing required environment variable: ${envVar}`);
56
+ console.log('Please check your .env file and ensure all Defender credentials are set.');
57
+ process.exit(1);
58
+ }
59
+ }
60
+
61
+ // Create Defender strategy
62
+ const strategy = new OZDefenderDeploymentStrategy(
63
+ process.env.DEFENDER_API_KEY!,
64
+ process.env.DEFENDER_API_SECRET!,
65
+ process.env.DEFENDER_RELAYER_ADDRESS!,
66
+ process.env.AUTO_APPROVE === 'true',
67
+ process.env.DEFENDER_SAFE_ADDRESS!,
68
+ 'Safe',
69
+ true // verbose logging
70
+ );
71
+
72
+ console.log('šŸ›”ļø Defender strategy configured');
73
+ console.log(`āš™ļø Auto-approve: ${process.env.AUTO_APPROVE === 'true' ? 'enabled' : 'disabled'}`);
74
+
75
+ // Execute deployment
76
+ const diamondDeployer = new DiamondDeployer(diamond, strategy);
77
+
78
+ try {
79
+ await diamondDeployer.deployDiamond();
80
+
81
+ console.log('\nāœ… Deployment completed successfully!');
82
+
83
+ // Output deployment information
84
+ const deployedData = diamond.getDeployedDiamondData();
85
+ console.log('\nšŸ“Š Deployment Summary:');
86
+ console.log(`Diamond Address: ${deployedData.DiamondAddress}`);
87
+ console.log(`Deployer Address: ${deployedData.DeployerAddress}`);
88
+ console.log(`Network: ${network.name} (Chain ID: ${network.chainId})`);
89
+
90
+ console.log('\nšŸ“‹ Deployed Facets:');
91
+ if (deployedData.DeployedFacets) {
92
+ Object.entries(deployedData.DeployedFacets).forEach(([name, facet]) => {
93
+ console.log(` ${name}:`);
94
+ console.log(` Address: ${facet.address}`);
95
+ console.log(` Version: ${facet.version}`);
96
+ console.log(` Selectors: ${facet.funcSelectors?.length || 0}`);
97
+ if (facet.tx_hash) {
98
+ console.log(` TX Hash: ${facet.tx_hash}`);
99
+ }
100
+ });
101
+ }
102
+
103
+ // Save deployment summary
104
+ const summary = {
105
+ timestamp: new Date().toISOString(),
106
+ network: network.name,
107
+ chainId: network.chainId,
108
+ deployerAddress: deployer.address,
109
+ diamondAddress: deployedData.DiamondAddress,
110
+ facets: deployedData.DeployedFacets,
111
+ deploymentMethod: 'OpenZeppelin Defender'
112
+ };
113
+
114
+ const summaryPath = path.join(exampleConfig.deploymentsPath, 'deployment-summary.json');
115
+ await fs.writeJson(summaryPath, summary, { spaces: 2 });
116
+
117
+ console.log(`\nšŸ“„ Deployment summary saved to: ${summaryPath}`);
118
+
119
+ // Display next steps
120
+ console.log('\nšŸŽÆ Next Steps:');
121
+ console.log('1. Verify contracts on block explorer');
122
+ console.log('2. Test diamond functionality');
123
+ console.log('3. Set up monitoring and alerts');
124
+ console.log('4. Prepare upgrade scenarios');
125
+
126
+ if (process.env.AUTO_APPROVE !== 'true') {
127
+ console.log('\nāš ļø Note: Auto-approval is disabled. Check your Defender dashboard for pending proposals.');
128
+ }
129
+
130
+ } catch (error) {
131
+ console.error('\nāŒ Deployment failed:', error);
132
+
133
+ // Save error information for debugging
134
+ const errorInfo = {
135
+ timestamp: new Date().toISOString(),
136
+ error: error instanceof Error ? {
137
+ message: error.message,
138
+ stack: error.stack,
139
+ name: error.name
140
+ } : String(error),
141
+ network: network.name,
142
+ chainId: network.chainId,
143
+ deployerAddress: deployer.address
144
+ };
145
+
146
+ const errorPath = path.join(exampleConfig.deploymentsPath, 'deployment-error.json');
147
+ await fs.writeJson(errorPath, errorInfo, { spaces: 2 });
148
+
149
+ console.log(`\nšŸ” Error details saved to: ${errorPath}`);
150
+ console.log('\nTroubleshooting tips:');
151
+ console.log('1. Check your Defender API credentials');
152
+ console.log('2. Ensure sufficient balance for gas fees');
153
+ console.log('3. Verify network connectivity');
154
+ console.log('4. Check Defender dashboard for detailed logs');
155
+
156
+ process.exit(1);
157
+ }
158
+ }
159
+
160
+ // Handle script execution
161
+ if (require.main === module) {
162
+ main()
163
+ .then(() => process.exit(0))
164
+ .catch((error) => {
165
+ console.error('Unhandled error:', error);
166
+ process.exit(1);
167
+ });
168
+ }
169
+
170
+ export { main as deployWithDefender };
@@ -0,0 +1,36 @@
1
+ {
2
+ "protocolVersion": 0.0,
3
+ "protocolInitFacet": "ExampleFacet1",
4
+ "facets": {
5
+ "DiamondCutFacet": {
6
+ "priority": 10,
7
+ "versions": {
8
+ "0.0": {}
9
+ }
10
+ },
11
+ "DiamondLoupeFacet": {
12
+ "priority": 20,
13
+ "versions": {
14
+ "0.0": {}
15
+ }
16
+ },
17
+ "ExampleFacet1": {
18
+ "priority": 30,
19
+ "versions": {
20
+ "0.0": {
21
+ "deployInit": "initialize()",
22
+ "callbacks": ["logDeployment"]
23
+ }
24
+ }
25
+ },
26
+ "ExampleFacet2": {
27
+ "priority": 40,
28
+ "versions": {
29
+ "0.0": {
30
+ "deployInit": "setup()",
31
+ "callbacks": ["validateSetup"]
32
+ }
33
+ }
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,237 @@
1
+ import { ethers } from 'hardhat';
2
+ import { Diamond } from '../../src/core/Diamond';
3
+ import { DiamondDeployer } from '../../src/core/DiamondDeployer';
4
+ import { FileDeploymentRepository } from '../../src/repositories/FileDeploymentRepository';
5
+ import { OZDefenderDeploymentStrategy } from '../../src/strategies/OZDefenderDeploymentStrategy';
6
+ import * as path from 'path';
7
+ import * as fs from 'fs-extra';
8
+
9
+ async function main() {
10
+ console.log('ā™»ļø Starting upgrade process...');
11
+
12
+ // Get network information
13
+ const network = await ethers.provider.getNetwork();
14
+ const signers = await ethers.getSigners();
15
+ const deployer = signers[0];
16
+
17
+ console.log(`šŸ“ Network: ${network.name} (${network.chainId})`);
18
+ console.log(`šŸ‘¤ Deployer: ${deployer.address}`);
19
+
20
+ // Load and update configuration
21
+ const configPath = path.join(__dirname, 'diamond-config.json');
22
+ const deploymentDataPath = path.join(__dirname, 'deployments', `examplediamond-${network.name}-${network.chainId}.json`);
23
+
24
+ // Check if initial deployment exists
25
+ if (!await fs.pathExists(deploymentDataPath)) {
26
+ console.error('āŒ No existing deployment found. Please run deploy-script.ts first.');
27
+ process.exit(1);
28
+ }
29
+
30
+ console.log('šŸ“„ Loading existing deployment data...');
31
+
32
+ // Load current configuration
33
+ const config = await fs.readJson(configPath);
34
+ const originalVersion = config.protocolVersion;
35
+
36
+ console.log(`šŸ“Š Current protocol version: ${originalVersion}`);
37
+
38
+ // Update configuration for upgrade
39
+ config.protocolVersion = 1.0;
40
+
41
+ // Add new UpgradeFacet
42
+ config.facets['UpgradeFacet'] = {
43
+ priority: 50,
44
+ versions: {
45
+ "1.0": {
46
+ deployInit: "initialize()",
47
+ callbacks: ["logUpgrade"]
48
+ }
49
+ }
50
+ };
51
+
52
+ // Upgrade existing ExampleFacet1 to version 1.0
53
+ if (!config.facets['ExampleFacet1'].versions) {
54
+ config.facets['ExampleFacet1'].versions = {};
55
+ }
56
+ config.facets['ExampleFacet1'].versions["1.0"] = {
57
+ upgradeInit: "upgradeToV1()",
58
+ callbacks: ["validateUpgrade"]
59
+ };
60
+
61
+ console.log('šŸ“ Updated configuration:');
62
+ console.log(` - Protocol version: ${originalVersion} → ${config.protocolVersion}`);
63
+ console.log(' - Added UpgradeFacet v1.0');
64
+ console.log(' - Upgraded ExampleFacet1 to v1.0');
65
+
66
+ // Save updated configuration
67
+ await fs.writeJson(configPath, config, { spaces: 2 });
68
+
69
+ // Setup diamond configuration
70
+ const diamondConfig = {
71
+ diamondName: 'ExampleDiamond',
72
+ networkName: network.name,
73
+ chainId: network.chainId,
74
+ deploymentsPath: path.join(__dirname, 'deployments'),
75
+ contractsPath: path.join(__dirname, 'contracts'),
76
+ callbacksPath: path.join(__dirname, 'callbacks'),
77
+ configFilePath: configPath,
78
+ deployedDiamondDataFilePath: deploymentDataPath
79
+ };
80
+
81
+ // Create diamond instance
82
+ const repository = new FileDeploymentRepository(diamondConfig);
83
+ const diamond = new Diamond(diamondConfig, repository);
84
+
85
+ diamond.setProvider(ethers.provider);
86
+ diamond.setSigner(deployer);
87
+
88
+ // Validate environment variables
89
+ const requiredEnvVars = [
90
+ 'DEFENDER_API_KEY',
91
+ 'DEFENDER_API_SECRET',
92
+ 'DEFENDER_RELAYER_ADDRESS',
93
+ 'DEFENDER_SAFE_ADDRESS'
94
+ ];
95
+
96
+ for (const envVar of requiredEnvVars) {
97
+ if (!process.env[envVar]) {
98
+ console.error(`āŒ Missing required environment variable: ${envVar}`);
99
+ process.exit(1);
100
+ }
101
+ }
102
+
103
+ // Create Defender strategy
104
+ const strategy = new OZDefenderDeploymentStrategy(
105
+ process.env.DEFENDER_API_KEY!,
106
+ process.env.DEFENDER_API_SECRET!,
107
+ process.env.DEFENDER_RELAYER_ADDRESS!,
108
+ process.env.AUTO_APPROVE === 'true',
109
+ process.env.DEFENDER_SAFE_ADDRESS!,
110
+ 'Safe',
111
+ true // verbose logging
112
+ );
113
+
114
+ console.log('šŸ›”ļø Defender strategy configured for upgrade');
115
+
116
+ // Load existing deployment data to show before state
117
+ const existingData = diamond.getDeployedDiamondData();
118
+ console.log('\nšŸ“Š Pre-upgrade State:');
119
+ console.log(`Diamond Address: ${existingData.DiamondAddress}`);
120
+ if (existingData.DeployedFacets) {
121
+ console.log('Current Facets:');
122
+ Object.entries(existingData.DeployedFacets).forEach(([name, facet]) => {
123
+ console.log(` ${name}: v${facet.version} at ${facet.address}`);
124
+ });
125
+ }
126
+
127
+ // Execute upgrade
128
+ const diamondDeployer = new DiamondDeployer(diamond, strategy);
129
+
130
+ try {
131
+ console.log('\nšŸš€ Starting upgrade deployment...');
132
+ await diamondDeployer.deployDiamond(); // Automatically detects upgrade scenario
133
+
134
+ console.log('\nāœ… Upgrade completed successfully!');
135
+
136
+ // Output upgrade information
137
+ const upgradedData = diamond.getDeployedDiamondData();
138
+ console.log('\nšŸ“Š Post-upgrade State:');
139
+ console.log(`Diamond Address: ${upgradedData.DiamondAddress}`);
140
+
141
+ if (upgradedData.DeployedFacets) {
142
+ console.log('Updated Facets:');
143
+ Object.entries(upgradedData.DeployedFacets).forEach(([name, facet]) => {
144
+ const isNew = !existingData.DeployedFacets?.[name];
145
+ const isUpgraded = existingData.DeployedFacets?.[name]?.version !== facet.version;
146
+
147
+ let status = '';
148
+ if (isNew) status = ' [NEW]';
149
+ else if (isUpgraded) status = ' [UPGRADED]';
150
+
151
+ console.log(` ${name}: v${facet.version} at ${facet.address}${status}`);
152
+ });
153
+ }
154
+
155
+ // Create upgrade summary
156
+ const upgradeSummary = {
157
+ timestamp: new Date().toISOString(),
158
+ network: network.name,
159
+ chainId: network.chainId,
160
+ deployerAddress: deployer.address,
161
+ diamondAddress: upgradedData.DiamondAddress,
162
+ upgrade: {
163
+ fromVersion: originalVersion,
164
+ toVersion: config.protocolVersion,
165
+ newFacets: ['UpgradeFacet'],
166
+ upgradedFacets: ['ExampleFacet1'],
167
+ deploymentMethod: 'OpenZeppelin Defender'
168
+ },
169
+ facets: upgradedData.DeployedFacets
170
+ };
171
+
172
+ const summaryPath = path.join(diamondConfig.deploymentsPath, 'upgrade-summary.json');
173
+ await fs.writeJson(summaryPath, upgradeSummary, { spaces: 2 });
174
+
175
+ console.log(`\nšŸ“„ Upgrade summary saved to: ${summaryPath}`);
176
+
177
+ // Display next steps
178
+ console.log('\nšŸŽÆ Next Steps:');
179
+ console.log('1. Test new functionality');
180
+ console.log('2. Verify upgrade initialization');
181
+ console.log('3. Update documentation');
182
+ console.log('4. Notify stakeholders');
183
+
184
+ if (process.env.AUTO_APPROVE !== 'true') {
185
+ console.log('\nāš ļø Note: Auto-approval is disabled. Check your Defender dashboard for pending proposals.');
186
+ }
187
+
188
+ } catch (error) {
189
+ console.error('\nāŒ Upgrade failed:', error);
190
+
191
+ // Restore original configuration
192
+ config.protocolVersion = originalVersion;
193
+ delete config.facets['UpgradeFacet'];
194
+ if (config.facets['ExampleFacet1'].versions && config.facets['ExampleFacet1'].versions["1.0"]) {
195
+ delete config.facets['ExampleFacet1'].versions["1.0"];
196
+ }
197
+ await fs.writeJson(configPath, config, { spaces: 2 });
198
+
199
+ console.log('šŸ”„ Configuration restored to pre-upgrade state');
200
+
201
+ // Save error information
202
+ const errorInfo = {
203
+ timestamp: new Date().toISOString(),
204
+ error: error instanceof Error ? {
205
+ message: error.message,
206
+ stack: error.stack,
207
+ name: error.name
208
+ } : String(error),
209
+ network: network.name,
210
+ chainId: network.chainId,
211
+ deployerAddress: deployer.address,
212
+ attemptedUpgrade: {
213
+ fromVersion: originalVersion,
214
+ toVersion: 1.0
215
+ }
216
+ };
217
+
218
+ const errorPath = path.join(diamondConfig.deploymentsPath, 'upgrade-error.json');
219
+ await fs.writeJson(errorPath, errorInfo, { spaces: 2 });
220
+
221
+ console.log(`\nšŸ” Error details saved to: ${errorPath}`);
222
+
223
+ process.exit(1);
224
+ }
225
+ }
226
+
227
+ // Handle script execution
228
+ if (require.main === module) {
229
+ main()
230
+ .then(() => process.exit(0))
231
+ .catch((error) => {
232
+ console.error('Unhandled error:', error);
233
+ process.exit(1);
234
+ });
235
+ }
236
+
237
+ export { main as upgradeWithDefender };
@@ -0,0 +1,41 @@
1
+ // Example hardhat.config.ts extension for hardhat-diamonds integration
2
+ // This would be used when the hardhat-diamonds plugin is available
3
+
4
+ import { HardhatUserConfig } from "hardhat/config";
5
+ import "@nomiclabs/hardhat-waffle";
6
+ import "@nomiclabs/hardhat-ethers";
7
+ // import "@gnus.ai/hardhat-diamonds"; // When available
8
+
9
+ const config: HardhatUserConfig = {
10
+ solidity: "0.8.17",
11
+
12
+ // Extended configuration for hardhat-diamonds plugin
13
+ diamonds: {
14
+ // Multiple diamond configurations can be defined
15
+ ProxyDiamond: {
16
+ deploymentsPath: "./diamonds",
17
+ contractsPath: "./contracts",
18
+ callbacksPath: "./diamonds/ProxyDiamond/callbacks",
19
+ configFilePath: "./diamonds/ProxyDiamond/proxydiamond.config.json",
20
+ // Network-specific deployment file paths will be auto-generated
21
+ },
22
+
23
+ TestDiamond: {
24
+ deploymentsPath: "./test-diamonds",
25
+ contractsPath: "./test/mocks/contracts",
26
+ callbacksPath: "./test-diamonds/TestDiamond/callbacks",
27
+ configFilePath: "./test-diamonds/TestDiamond/testdiamond.config.json",
28
+ },
29
+
30
+ // More diamonds can be configured...
31
+ },
32
+
33
+ networks: {
34
+ hardhat: {
35
+ chainId: 31337,
36
+ },
37
+ // Other networks...
38
+ },
39
+ };
40
+
41
+ export default config;