@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,1204 @@
1
+ # Diamond ABI Generator - Practical Examples & Patterns
2
+
3
+ ## Overview
4
+
5
+ This document provides practical examples and common patterns for implementing the Diamond ABI Generator in real-world projects. It complements the main implementation guide with focused examples for specific use cases.
6
+
7
+ ## Table of Contents
8
+
9
+ 1. [Common Integration Patterns](#common-integration-patterns)
10
+ 2. [Frontend Framework Integration](#frontend-framework-integration)
11
+ 3. [Testing Patterns](#testing-patterns)
12
+ 4. [CI/CD Integration](#cicd-integration)
13
+ 5. [Performance Optimization](#performance-optimization)
14
+ 6. [Custom Tooling](#custom-tooling)
15
+ 7. [Migration Strategies](#migration-strategies)
16
+
17
+ ## Common Integration Patterns
18
+
19
+ ### Pattern 1: Basic Project Setup
20
+
21
+ ```typescript
22
+ // scripts/setup-diamond-abi.ts
23
+ import { generateDiamondAbi, Diamond } from 'diamonds';
24
+ import { FileDeploymentRepository } from 'diamonds/repositories';
25
+ import { writeFileSync, mkdirSync } from 'fs';
26
+ import { join } from 'path';
27
+
28
+ interface ProjectConfig {
29
+ diamondName: string;
30
+ networkName: string;
31
+ chainId: number;
32
+ outputDir: string;
33
+ }
34
+
35
+ export class DiamondAbiManager {
36
+ private diamond: Diamond;
37
+ private config: ProjectConfig;
38
+
39
+ constructor(config: ProjectConfig) {
40
+ this.config = config;
41
+
42
+ const diamondConfig = {
43
+ diamondName: config.diamondName,
44
+ networkName: config.networkName,
45
+ chainId: config.chainId,
46
+ deploymentsPath: './diamonds',
47
+ contractsPath: './contracts'
48
+ };
49
+
50
+ const repository = new FileDeploymentRepository(diamondConfig);
51
+ this.diamond = new Diamond(diamondConfig, repository);
52
+ }
53
+
54
+ async generateAbi() {
55
+ const result = await generateDiamondAbi(this.diamond, {
56
+ outputDir: this.config.outputDir,
57
+ includeSourceInfo: true,
58
+ validateSelectors: true,
59
+ verbose: true
60
+ });
61
+
62
+ return result;
63
+ }
64
+
65
+ async generateTypes() {
66
+ const result = await this.generateAbi();
67
+
68
+ // Generate additional type files
69
+ await this.generateViemTypes(result);
70
+ await this.generateReactTypes(result);
71
+
72
+ return result;
73
+ }
74
+
75
+ private async generateViemTypes(result: any) {
76
+ const viemTypes = `
77
+ // Auto-generated Viem types for ${this.config.diamondName}
78
+ import { Abi } from 'viem';
79
+
80
+ export const ${this.config.diamondName}ABI = ${JSON.stringify(result.abi, null, 2)} as const;
81
+ export type ${this.config.diamondName}ABI = typeof ${this.config.diamondName}ABI;
82
+
83
+ // Selector mapping
84
+ export const selectorMap = ${JSON.stringify(result.selectorMap, null, 2)} as const;
85
+ `;
86
+
87
+ const outputPath = join(this.config.outputDir, 'viem-types.ts');
88
+ writeFileSync(outputPath, viemTypes);
89
+ }
90
+
91
+ private async generateReactTypes(result: any) {
92
+ const reactTypes = `
93
+ // Auto-generated React types for ${this.config.diamondName}
94
+ import { Contract } from 'ethers';
95
+
96
+ export interface ${this.config.diamondName}Contract extends Contract {
97
+ // Add your specific function signatures here
98
+ // These would be generated from the ABI
99
+ }
100
+
101
+ export const ${this.config.diamondName}ABI = ${JSON.stringify(result.abi, null, 2)};
102
+ `;
103
+
104
+ const outputPath = join(this.config.outputDir, 'react-types.ts');
105
+ writeFileSync(outputPath, reactTypes);
106
+ }
107
+ }
108
+
109
+ // Usage
110
+ const manager = new DiamondAbiManager({
111
+ diamondName: 'GameDiamond',
112
+ networkName: 'localhost',
113
+ chainId: 31337,
114
+ outputDir: './src/contracts'
115
+ });
116
+
117
+ manager.generateTypes().then(() => {
118
+ console.log('āœ… Diamond ABI and types generated');
119
+ });
120
+ ```
121
+
122
+ ### Pattern 2: Multi-Network Support
123
+
124
+ ```typescript
125
+ // scripts/multi-network-abi.ts
126
+ import { DiamondAbiManager } from './setup-diamond-abi';
127
+
128
+ const networks = [
129
+ { name: 'localhost', chainId: 31337 },
130
+ { name: 'sepolia', chainId: 11155111 },
131
+ { name: 'mainnet', chainId: 1 }
132
+ ];
133
+
134
+ const diamonds = ['GameDiamond', 'TradingDiamond', 'GovernanceDiamond'];
135
+
136
+ async function generateAllAbis() {
137
+ for (const network of networks) {
138
+ for (const diamondName of diamonds) {
139
+ try {
140
+ const manager = new DiamondAbiManager({
141
+ diamondName,
142
+ networkName: network.name,
143
+ chainId: network.chainId,
144
+ outputDir: `./src/contracts/${network.name}`
145
+ });
146
+
147
+ await manager.generateTypes();
148
+ console.log(`āœ… Generated ABI for ${diamondName} on ${network.name}`);
149
+ } catch (error) {
150
+ console.error(`āŒ Failed to generate ABI for ${diamondName} on ${network.name}:`, error);
151
+ }
152
+ }
153
+ }
154
+ }
155
+
156
+ generateAllAbis();
157
+ ```
158
+
159
+ ### Pattern 3: Watch Mode for Development
160
+
161
+ ```typescript
162
+ // scripts/watch-diamond-abi.ts
163
+ import { watch } from 'fs';
164
+ import { DiamondAbiManager } from './setup-diamond-abi';
165
+ import { debounce } from 'lodash';
166
+
167
+ class DiamondAbiWatcher {
168
+ private manager: DiamondAbiManager;
169
+ private regenerateAbi: () => Promise<void>;
170
+
171
+ constructor(manager: DiamondAbiManager) {
172
+ this.manager = manager;
173
+ this.regenerateAbi = debounce(async () => {
174
+ try {
175
+ console.log('šŸ”„ Regenerating Diamond ABI...');
176
+ await this.manager.generateTypes();
177
+ console.log('āœ… Diamond ABI regenerated');
178
+ } catch (error) {
179
+ console.error('āŒ Failed to regenerate ABI:', error);
180
+ }
181
+ }, 1000);
182
+ }
183
+
184
+ start() {
185
+ // Watch for contract changes
186
+ watch('./contracts', { recursive: true }, (eventType, filename) => {
187
+ if (filename?.endsWith('.sol')) {
188
+ console.log(`šŸ“ Contract changed: ${filename}`);
189
+ this.regenerateAbi();
190
+ }
191
+ });
192
+
193
+ // Watch for diamond deployment changes
194
+ watch('./diamonds', { recursive: true }, (eventType, filename) => {
195
+ if (filename?.endsWith('.json')) {
196
+ console.log(`šŸ’Ž Diamond deployment changed: ${filename}`);
197
+ this.regenerateAbi();
198
+ }
199
+ });
200
+
201
+ console.log('šŸ‘€ Watching for changes...');
202
+ }
203
+ }
204
+
205
+ // Usage
206
+ const manager = new DiamondAbiManager({
207
+ diamondName: 'GameDiamond',
208
+ networkName: 'localhost',
209
+ chainId: 31337,
210
+ outputDir: './src/contracts'
211
+ });
212
+
213
+ const watcher = new DiamondAbiWatcher(manager);
214
+ watcher.start();
215
+ ```
216
+
217
+ ## Frontend Framework Integration
218
+
219
+ ### React + Ethers.js Integration
220
+
221
+ ```typescript
222
+ // src/hooks/useDiamond.ts
223
+ import { useEffect, useState } from 'react';
224
+ import { ethers } from 'ethers';
225
+ import { GameDiamondABI } from '../contracts/GameDiamond';
226
+
227
+ export function useDiamond(address: string, provider: ethers.providers.Provider) {
228
+ const [contract, setContract] = useState<ethers.Contract | null>(null);
229
+ const [loading, setLoading] = useState(true);
230
+ const [error, setError] = useState<string | null>(null);
231
+
232
+ useEffect(() => {
233
+ async function setupContract() {
234
+ try {
235
+ setLoading(true);
236
+ const diamondContract = new ethers.Contract(
237
+ address,
238
+ GameDiamondABI.abi,
239
+ provider
240
+ );
241
+ setContract(diamondContract);
242
+ setError(null);
243
+ } catch (err) {
244
+ setError(err instanceof Error ? err.message : 'Failed to setup contract');
245
+ } finally {
246
+ setLoading(false);
247
+ }
248
+ }
249
+
250
+ setupContract();
251
+ }, [address, provider]);
252
+
253
+ return { contract, loading, error };
254
+ }
255
+
256
+ // Usage component
257
+ export function GameComponent() {
258
+ const { contract, loading, error } = useDiamond(
259
+ '0x...',
260
+ new ethers.providers.Web3Provider(window.ethereum)
261
+ );
262
+
263
+ if (loading) return <div>Loading...</div>;
264
+ if (error) return <div>Error: {error}</div>;
265
+
266
+ return (
267
+ <div>
268
+ <button onClick={() => contract?.someFunction()}>
269
+ Call Function
270
+ </button>
271
+ </div>
272
+ );
273
+ }
274
+ ```
275
+
276
+ ### Next.js Integration
277
+
278
+ ```typescript
279
+ // next.config.js
280
+ /** @type {import('next').NextConfig} */
281
+ const nextConfig = {
282
+ webpack: (config) => {
283
+ // Handle JSON imports for ABI files
284
+ config.module.rules.push({
285
+ test: /\.json$/,
286
+ type: 'json'
287
+ });
288
+
289
+ return config;
290
+ }
291
+ };
292
+
293
+ module.exports = nextConfig;
294
+
295
+ // pages/api/diamond-abi.ts
296
+ import { NextApiRequest, NextApiResponse } from 'next';
297
+ import { generateDiamondAbi } from 'diamonds';
298
+
299
+ export default async function handler(
300
+ req: NextApiRequest,
301
+ res: NextApiResponse
302
+ ) {
303
+ if (req.method !== 'GET') {
304
+ return res.status(405).json({ message: 'Method not allowed' });
305
+ }
306
+
307
+ try {
308
+ const { diamondName, network } = req.query;
309
+
310
+ // Generate ABI on-demand
311
+ const result = await generateDiamondAbi(diamond, {
312
+ verbose: false
313
+ });
314
+
315
+ res.status(200).json({
316
+ abi: result.abi,
317
+ selectorMap: result.selectorMap,
318
+ stats: result.stats
319
+ });
320
+ } catch (error) {
321
+ res.status(500).json({
322
+ message: 'Failed to generate ABI',
323
+ error: error instanceof Error ? error.message : 'Unknown error'
324
+ });
325
+ }
326
+ }
327
+ ```
328
+
329
+ ### Vue.js Integration
330
+
331
+ ```typescript
332
+ // src/composables/useDiamond.ts
333
+ import { ref, computed } from 'vue';
334
+ import { ethers } from 'ethers';
335
+ import { GameDiamondABI } from '../contracts/GameDiamond';
336
+
337
+ export function useDiamond(address: string) {
338
+ const contract = ref<ethers.Contract | null>(null);
339
+ const loading = ref(false);
340
+ const error = ref<string | null>(null);
341
+
342
+ const isReady = computed(() => contract.value !== null);
343
+
344
+ async function connect(provider: ethers.providers.Provider) {
345
+ loading.value = true;
346
+ error.value = null;
347
+
348
+ try {
349
+ contract.value = new ethers.Contract(
350
+ address,
351
+ GameDiamondABI.abi,
352
+ provider
353
+ );
354
+ } catch (err) {
355
+ error.value = err instanceof Error ? err.message : 'Failed to connect';
356
+ } finally {
357
+ loading.value = false;
358
+ }
359
+ }
360
+
361
+ async function callFunction(functionName: string, ...args: any[]) {
362
+ if (!contract.value) {
363
+ throw new Error('Contract not connected');
364
+ }
365
+
366
+ return await contract.value[functionName](...args);
367
+ }
368
+
369
+ return {
370
+ contract: computed(() => contract.value),
371
+ loading: computed(() => loading.value),
372
+ error: computed(() => error.value),
373
+ isReady,
374
+ connect,
375
+ callFunction
376
+ };
377
+ }
378
+ ```
379
+
380
+ ## Testing Patterns
381
+
382
+ ### Unit Testing Pattern
383
+
384
+ ```typescript
385
+ // test/diamond-abi.test.ts
386
+ import { expect } from 'chai';
387
+ import { generateDiamondAbi, Diamond } from 'diamonds';
388
+ import { FileDeploymentRepository } from 'diamonds/repositories';
389
+ import { ethers } from 'hardhat';
390
+
391
+ describe('Diamond ABI Generation', () => {
392
+ let diamond: Diamond;
393
+ let repository: FileDeploymentRepository;
394
+
395
+ beforeEach(async () => {
396
+ const config = {
397
+ diamondName: 'TestDiamond',
398
+ networkName: 'localhost',
399
+ chainId: 31337,
400
+ deploymentsPath: './test/fixtures/diamonds',
401
+ contractsPath: './contracts'
402
+ };
403
+
404
+ repository = new FileDeploymentRepository(config);
405
+ diamond = new Diamond(config, repository);
406
+ });
407
+
408
+ describe('Basic ABI Generation', () => {
409
+ it('should generate valid ABI', async () => {
410
+ const result = await generateDiamondAbi(diamond, {
411
+ validateSelectors: true,
412
+ verbose: false
413
+ });
414
+
415
+ expect(result.abi).to.be.an('array');
416
+ expect(result.abi.length).to.be.greaterThan(0);
417
+ expect(result.stats.totalFunctions).to.be.greaterThan(0);
418
+ expect(result.stats.duplicateSelectorsSkipped).to.equal(0);
419
+ });
420
+
421
+ it('should include metadata', async () => {
422
+ const result = await generateDiamondAbi(diamond, {
423
+ includeSourceInfo: true,
424
+ outputDir: './test/output'
425
+ });
426
+
427
+ const artifact = JSON.parse(
428
+ require('fs').readFileSync(result.outputPath!, 'utf8')
429
+ );
430
+
431
+ expect(artifact._diamondMetadata).to.exist;
432
+ expect(artifact._diamondMetadata.diamondName).to.equal('TestDiamond');
433
+ expect(artifact._diamondMetadata.selectorMap).to.exist;
434
+ });
435
+ });
436
+
437
+ describe('Contract Integration', () => {
438
+ it('should work with ethers.js', async () => {
439
+ const result = await generateDiamondAbi(diamond);
440
+
441
+ // Mock deployment
442
+ const [deployer] = await ethers.getSigners();
443
+ const mockAddress = '0x1234567890123456789012345678901234567890';
444
+
445
+ // Create contract instance
446
+ const contract = new ethers.Contract(
447
+ mockAddress,
448
+ result.abi,
449
+ deployer
450
+ );
451
+
452
+ expect(contract.interface).to.exist;
453
+ expect(contract.interface.functions).to.exist;
454
+ });
455
+ });
456
+
457
+ describe('Error Handling', () => {
458
+ it('should handle missing facets gracefully', async () => {
459
+ // Test with diamond that has missing facet artifacts
460
+ const result = await generateDiamondAbi(diamond, {
461
+ verbose: true
462
+ });
463
+
464
+ expect(result.abi).to.be.an('array');
465
+ // Should still generate ABI with available facets
466
+ });
467
+
468
+ it('should detect selector collisions', async () => {
469
+ // Add duplicate selectors to registry
470
+ diamond.registerFunctionSelectors({
471
+ '0x12345678': {
472
+ facetName: 'TestFacet1',
473
+ priority: 100,
474
+ address: '0x1111111111111111111111111111111111111111',
475
+ action: 1
476
+ },
477
+ '0x12345678': {
478
+ facetName: 'TestFacet2',
479
+ priority: 100,
480
+ address: '0x2222222222222222222222222222222222222222',
481
+ action: 1
482
+ }
483
+ });
484
+
485
+ const result = await generateDiamondAbi(diamond, {
486
+ validateSelectors: true,
487
+ verbose: true
488
+ });
489
+
490
+ expect(result.stats.duplicateSelectorsSkipped).to.be.greaterThan(0);
491
+ });
492
+ });
493
+ });
494
+ ```
495
+
496
+ ### Integration Testing Pattern
497
+
498
+ ```typescript
499
+ // test/integration/diamond-abi-workflow.test.ts
500
+ import { expect } from 'chai';
501
+ import { spawn } from 'child_process';
502
+ import { existsSync, readFileSync } from 'fs';
503
+ import { join } from 'path';
504
+
505
+ describe('Diamond ABI Workflow Integration', () => {
506
+ const testOutputDir = './test/tmp/diamond-abi';
507
+
508
+ beforeEach(async () => {
509
+ // Clean up previous test outputs
510
+ if (existsSync(testOutputDir)) {
511
+ await import('fs').then(fs => fs.rmSync(testOutputDir, { recursive: true }));
512
+ }
513
+ });
514
+
515
+ it('should complete full CLI workflow', async () => {
516
+ // Test CLI command
517
+ const cliResult = await runCLI([
518
+ 'generate',
519
+ '--diamond', 'TestDiamond',
520
+ '--network', 'localhost',
521
+ '--output', testOutputDir,
522
+ '--verbose'
523
+ ]);
524
+
525
+ expect(cliResult.exitCode).to.equal(0);
526
+ expect(cliResult.stdout).to.include('āœ… Diamond ABI generation completed');
527
+
528
+ // Verify output files
529
+ const artifactPath = join(testOutputDir, 'TestDiamond.json');
530
+ const typesPath = join(testOutputDir, 'TestDiamond.d.ts');
531
+
532
+ expect(existsSync(artifactPath)).to.be.true;
533
+ expect(existsSync(typesPath)).to.be.true;
534
+
535
+ // Verify artifact content
536
+ const artifact = JSON.parse(readFileSync(artifactPath, 'utf8'));
537
+ expect(artifact.contractName).to.equal('TestDiamond');
538
+ expect(artifact.abi).to.be.an('array');
539
+ expect(artifact._diamondMetadata).to.exist;
540
+ });
541
+
542
+ it('should handle TypeChain generation', async () => {
543
+ // Generate ABI first
544
+ await runCLI([
545
+ 'generate',
546
+ '--diamond', 'TestDiamond',
547
+ '--output', testOutputDir
548
+ ]);
549
+
550
+ // Generate TypeChain types
551
+ const typechainResult = await runCLI([
552
+ 'npx', 'typechain',
553
+ '--target', 'ethers-v5',
554
+ '--out-dir', join(testOutputDir, 'typechain'),
555
+ join(testOutputDir, '*.json')
556
+ ]);
557
+
558
+ expect(typechainResult.exitCode).to.equal(0);
559
+ expect(existsSync(join(testOutputDir, 'typechain'))).to.be.true;
560
+ });
561
+
562
+ async function runCLI(args: string[]): Promise<{
563
+ exitCode: number;
564
+ stdout: string;
565
+ stderr: string;
566
+ }> {
567
+ return new Promise((resolve) => {
568
+ const process = spawn('npm', ['run', 'diamond-abi', ...args], {
569
+ stdio: 'pipe'
570
+ });
571
+
572
+ let stdout = '';
573
+ let stderr = '';
574
+
575
+ process.stdout.on('data', (data) => {
576
+ stdout += data.toString();
577
+ });
578
+
579
+ process.stderr.on('data', (data) => {
580
+ stderr += data.toString();
581
+ });
582
+
583
+ process.on('close', (code) => {
584
+ resolve({
585
+ exitCode: code || 0,
586
+ stdout,
587
+ stderr
588
+ });
589
+ });
590
+ });
591
+ }
592
+ });
593
+ ```
594
+
595
+ ## CI/CD Integration
596
+
597
+ ### GitHub Actions Workflow
598
+
599
+ ```yaml
600
+ # .github/workflows/diamond-abi.yml
601
+ name: Diamond ABI Generation and Validation
602
+
603
+ on:
604
+ push:
605
+ branches: [main, develop]
606
+ pull_request:
607
+ branches: [main]
608
+
609
+ jobs:
610
+ generate-abi:
611
+ runs-on: ubuntu-latest
612
+
613
+ strategy:
614
+ matrix:
615
+ network: [localhost, sepolia, mainnet]
616
+ diamond: [GameDiamond, TradingDiamond]
617
+
618
+ steps:
619
+ - name: Checkout code
620
+ uses: actions/checkout@v3
621
+
622
+ - name: Setup Node.js
623
+ uses: actions/setup-node@v3
624
+ with:
625
+ node-version: '18'
626
+ cache: 'npm'
627
+
628
+ - name: Install dependencies
629
+ run: npm ci
630
+
631
+ - name: Compile contracts
632
+ run: npm run compile
633
+
634
+ - name: Generate Diamond ABI
635
+ run: |
636
+ npm run diamond-abi generate \
637
+ --diamond ${{ matrix.diamond }} \
638
+ --network ${{ matrix.network }} \
639
+ --output ./artifacts/diamond-abi/${{ matrix.network }} \
640
+ --include-source \
641
+ --validate-selectors \
642
+ --verbose
643
+
644
+ - name: Generate TypeChain types
645
+ run: |
646
+ npx typechain \
647
+ --target ethers-v5 \
648
+ --out-dir ./typechain-types/${{ matrix.network }} \
649
+ ./artifacts/diamond-abi/${{ matrix.network }}/*.json
650
+
651
+ - name: Validate ABI
652
+ run: |
653
+ npm run diamond-abi validate \
654
+ ./artifacts/diamond-abi/${{ matrix.network }}/${{ matrix.diamond }}.json
655
+
656
+ - name: Upload ABI artifacts
657
+ uses: actions/upload-artifact@v3
658
+ with:
659
+ name: diamond-abi-${{ matrix.network }}-${{ matrix.diamond }}
660
+ path: |
661
+ ./artifacts/diamond-abi/${{ matrix.network }}/
662
+ ./typechain-types/${{ matrix.network }}/
663
+
664
+ validate-integration:
665
+ needs: generate-abi
666
+ runs-on: ubuntu-latest
667
+
668
+ steps:
669
+ - name: Checkout code
670
+ uses: actions/checkout@v3
671
+
672
+ - name: Setup Node.js
673
+ uses: actions/setup-node@v3
674
+ with:
675
+ node-version: '18'
676
+ cache: 'npm'
677
+
678
+ - name: Install dependencies
679
+ run: npm ci
680
+
681
+ - name: Download ABI artifacts
682
+ uses: actions/download-artifact@v3
683
+ with:
684
+ path: ./artifacts/
685
+
686
+ - name: Run integration tests
687
+ run: npm run test:integration
688
+
689
+ - name: Test TypeScript compilation
690
+ run: npx tsc --noEmit --project tsconfig.json
691
+ ```
692
+
693
+ ### GitLab CI/CD Pipeline
694
+
695
+ ```yaml
696
+ # .gitlab-ci.yml
697
+ stages:
698
+ - compile
699
+ - generate-abi
700
+ - validate
701
+ - deploy
702
+
703
+ variables:
704
+ NODE_VERSION: "18"
705
+
706
+ compile-contracts:
707
+ stage: compile
708
+ image: node:$NODE_VERSION
709
+ script:
710
+ - npm ci
711
+ - npm run compile
712
+ artifacts:
713
+ paths:
714
+ - artifacts/contracts/
715
+ - cache/
716
+ expire_in: 1 hour
717
+
718
+ generate-diamond-abi:
719
+ stage: generate-abi
720
+ image: node:$NODE_VERSION
721
+ needs: [compile-contracts]
722
+ parallel:
723
+ matrix:
724
+ - NETWORK: [localhost, sepolia, mainnet]
725
+ DIAMOND: [GameDiamond, TradingDiamond]
726
+ script:
727
+ - npm ci
728
+ - |
729
+ npm run diamond-abi generate \
730
+ --diamond $DIAMOND \
731
+ --network $NETWORK \
732
+ --output ./artifacts/diamond-abi/$NETWORK \
733
+ --include-source \
734
+ --validate-selectors \
735
+ --verbose
736
+ - |
737
+ npx typechain \
738
+ --target ethers-v5 \
739
+ --out-dir ./typechain-types/$NETWORK \
740
+ ./artifacts/diamond-abi/$NETWORK/*.json
741
+ artifacts:
742
+ paths:
743
+ - artifacts/diamond-abi/
744
+ - typechain-types/
745
+ expire_in: 1 day
746
+
747
+ validate-abi:
748
+ stage: validate
749
+ image: node:$NODE_VERSION
750
+ needs: [generate-diamond-abi]
751
+ script:
752
+ - npm ci
753
+ - npm run test:integration
754
+ - npx tsc --noEmit
755
+ artifacts:
756
+ reports:
757
+ junit: test-results.xml
758
+ ```
759
+
760
+ ## Performance Optimization
761
+
762
+ ### Caching Strategy
763
+
764
+ ```typescript
765
+ // src/utils/diamond-abi-cache.ts
766
+ import { createHash } from 'crypto';
767
+ import { readFileSync, writeFileSync, existsSync } from 'fs';
768
+ import { join } from 'path';
769
+
770
+ export class DiamondAbiCache {
771
+ private cacheDir: string;
772
+
773
+ constructor(cacheDir: string = './cache/diamond-abi') {
774
+ this.cacheDir = cacheDir;
775
+ }
776
+
777
+ getCacheKey(diamond: Diamond, options: any): string {
778
+ const hashInput = JSON.stringify({
779
+ diamondName: diamond.diamondName,
780
+ networkName: diamond.networkName,
781
+ chainId: diamond.chainId,
782
+ deploymentHash: this.getDeploymentHash(diamond),
783
+ options
784
+ });
785
+
786
+ return createHash('sha256').update(hashInput).digest('hex');
787
+ }
788
+
789
+ async get(cacheKey: string): Promise<any | null> {
790
+ const cachePath = join(this.cacheDir, `${cacheKey}.json`);
791
+
792
+ if (!existsSync(cachePath)) {
793
+ return null;
794
+ }
795
+
796
+ try {
797
+ const cached = JSON.parse(readFileSync(cachePath, 'utf8'));
798
+
799
+ // Check if cache is still valid (e.g., less than 1 hour old)
800
+ const maxAge = 60 * 60 * 1000; // 1 hour
801
+ if (Date.now() - cached.timestamp > maxAge) {
802
+ return null;
803
+ }
804
+
805
+ return cached.data;
806
+ } catch (error) {
807
+ return null;
808
+ }
809
+ }
810
+
811
+ async set(cacheKey: string, data: any): Promise<void> {
812
+ const cachePath = join(this.cacheDir, `${cacheKey}.json`);
813
+
814
+ const cacheData = {
815
+ timestamp: Date.now(),
816
+ data
817
+ };
818
+
819
+ writeFileSync(cachePath, JSON.stringify(cacheData, null, 2));
820
+ }
821
+
822
+ private getDeploymentHash(diamond: Diamond): string {
823
+ const deploymentData = diamond.getDeployedDiamondData();
824
+ return createHash('sha256')
825
+ .update(JSON.stringify(deploymentData))
826
+ .digest('hex');
827
+ }
828
+ }
829
+
830
+ // Usage with caching
831
+ export async function generateDiamondAbiWithCache(
832
+ diamond: Diamond,
833
+ options: any = {}
834
+ ): Promise<any> {
835
+ const cache = new DiamondAbiCache();
836
+ const cacheKey = cache.getCacheKey(diamond, options);
837
+
838
+ // Try to get from cache first
839
+ const cached = await cache.get(cacheKey);
840
+ if (cached) {
841
+ console.log('āœ… Using cached Diamond ABI');
842
+ return cached;
843
+ }
844
+
845
+ // Generate fresh ABI
846
+ const result = await generateDiamondAbi(diamond, options);
847
+
848
+ // Cache the result
849
+ await cache.set(cacheKey, result);
850
+
851
+ return result;
852
+ }
853
+ ```
854
+
855
+ ### Parallel Processing
856
+
857
+ ```typescript
858
+ // src/utils/parallel-abi-generator.ts
859
+ import { generateDiamondAbi } from 'diamonds';
860
+ import { Worker } from 'worker_threads';
861
+ import { cpus } from 'os';
862
+
863
+ export class ParallelAbiGenerator {
864
+ private maxWorkers: number;
865
+
866
+ constructor(maxWorkers: number = cpus().length) {
867
+ this.maxWorkers = maxWorkers;
868
+ }
869
+
870
+ async generateMultiple(configs: DiamondConfig[]): Promise<any[]> {
871
+ const chunks = this.chunkArray(configs, this.maxWorkers);
872
+ const promises = chunks.map(chunk => this.processChunk(chunk));
873
+ const results = await Promise.all(promises);
874
+
875
+ return results.flat();
876
+ }
877
+
878
+ private chunkArray<T>(array: T[], chunkSize: number): T[][] {
879
+ const chunks: T[][] = [];
880
+ for (let i = 0; i < array.length; i += chunkSize) {
881
+ chunks.push(array.slice(i, i + chunkSize));
882
+ }
883
+ return chunks;
884
+ }
885
+
886
+ private async processChunk(configs: DiamondConfig[]): Promise<any[]> {
887
+ return new Promise((resolve, reject) => {
888
+ const worker = new Worker(`
889
+ const { parentPort } = require('worker_threads');
890
+ const { generateDiamondAbi, Diamond } = require('diamonds');
891
+ const { FileDeploymentRepository } = require('diamonds/repositories');
892
+
893
+ parentPort.on('message', async (configs) => {
894
+ const results = [];
895
+
896
+ for (const config of configs) {
897
+ try {
898
+ const repository = new FileDeploymentRepository(config);
899
+ const diamond = new Diamond(config, repository);
900
+ const result = await generateDiamondAbi(diamond);
901
+ results.push({ config, result, success: true });
902
+ } catch (error) {
903
+ results.push({ config, error: error.message, success: false });
904
+ }
905
+ }
906
+
907
+ parentPort.postMessage(results);
908
+ });
909
+ `, { eval: true });
910
+
911
+ worker.postMessage(configs);
912
+
913
+ worker.on('message', (results) => {
914
+ worker.terminate();
915
+ resolve(results);
916
+ });
917
+
918
+ worker.on('error', (error) => {
919
+ worker.terminate();
920
+ reject(error);
921
+ });
922
+ });
923
+ }
924
+ }
925
+ ```
926
+
927
+ ## Custom Tooling
928
+
929
+ ### VS Code Extension Integration
930
+
931
+ ```typescript
932
+ // src/vscode-extension/diamond-abi-provider.ts
933
+ import * as vscode from 'vscode';
934
+ import { generateDiamondAbi } from 'diamonds';
935
+
936
+ export class DiamondAbiProvider {
937
+ private context: vscode.ExtensionContext;
938
+
939
+ constructor(context: vscode.ExtensionContext) {
940
+ this.context = context;
941
+ this.registerCommands();
942
+ }
943
+
944
+ private registerCommands() {
945
+ const generateCommand = vscode.commands.registerCommand(
946
+ 'diamond-abi.generate',
947
+ async () => {
948
+ const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
949
+ if (!workspaceFolder) {
950
+ vscode.window.showErrorMessage('No workspace folder found');
951
+ return;
952
+ }
953
+
954
+ const diamondName = await vscode.window.showInputBox({
955
+ prompt: 'Enter diamond name',
956
+ value: 'GameDiamond'
957
+ });
958
+
959
+ if (!diamondName) return;
960
+
961
+ const networkName = await vscode.window.showQuickPick(
962
+ ['localhost', 'sepolia', 'mainnet'],
963
+ { placeHolder: 'Select network' }
964
+ );
965
+
966
+ if (!networkName) return;
967
+
968
+ try {
969
+ await vscode.window.withProgress({
970
+ location: vscode.ProgressLocation.Notification,
971
+ title: 'Generating Diamond ABI...',
972
+ cancellable: false
973
+ }, async (progress) => {
974
+ progress.report({ increment: 0 });
975
+
976
+ // Generate ABI
977
+ const result = await generateDiamondAbi(diamond, {
978
+ outputDir: './artifacts/diamond-abi',
979
+ verbose: true
980
+ });
981
+
982
+ progress.report({ increment: 100 });
983
+
984
+ vscode.window.showInformationMessage(
985
+ `āœ… Generated ABI with ${result.stats.totalFunctions} functions`
986
+ );
987
+ });
988
+ } catch (error) {
989
+ vscode.window.showErrorMessage(
990
+ `Failed to generate ABI: ${error}`
991
+ );
992
+ }
993
+ }
994
+ );
995
+
996
+ this.context.subscriptions.push(generateCommand);
997
+ }
998
+ }
999
+ ```
1000
+
1001
+ ### Custom CLI Tool
1002
+
1003
+ ```typescript
1004
+ // scripts/advanced-diamond-cli.ts
1005
+ #!/usr/bin/env node
1006
+
1007
+ import { Command } from 'commander';
1008
+ import inquirer from 'inquirer';
1009
+ import chalk from 'chalk';
1010
+ import { generateDiamondAbi } from 'diamonds';
1011
+
1012
+ const program = new Command();
1013
+
1014
+ program
1015
+ .name('diamond-tools')
1016
+ .description('Advanced Diamond ABI tools')
1017
+ .version('1.0.0');
1018
+
1019
+ program
1020
+ .command('interactive')
1021
+ .description('Interactive ABI generation wizard')
1022
+ .action(async () => {
1023
+ console.log(chalk.blue('šŸ”® Diamond ABI Generation Wizard'));
1024
+
1025
+ const answers = await inquirer.prompt([
1026
+ {
1027
+ type: 'input',
1028
+ name: 'diamondName',
1029
+ message: 'Diamond name:',
1030
+ default: 'GameDiamond'
1031
+ },
1032
+ {
1033
+ type: 'list',
1034
+ name: 'network',
1035
+ message: 'Select network:',
1036
+ choices: [
1037
+ { name: 'Localhost (31337)', value: 'localhost' },
1038
+ { name: 'Sepolia (11155111)', value: 'sepolia' },
1039
+ { name: 'Mainnet (1)', value: 'mainnet' }
1040
+ ]
1041
+ },
1042
+ {
1043
+ type: 'checkbox',
1044
+ name: 'features',
1045
+ message: 'Select features:',
1046
+ choices: [
1047
+ { name: 'Include source information', value: 'includeSource' },
1048
+ { name: 'Validate selectors', value: 'validateSelectors' },
1049
+ { name: 'Generate TypeChain types', value: 'generateTypes' },
1050
+ { name: 'Generate Viem types', value: 'generateViem' },
1051
+ { name: 'Verbose output', value: 'verbose' }
1052
+ ]
1053
+ }
1054
+ ]);
1055
+
1056
+ try {
1057
+ const options = {
1058
+ outputDir: './artifacts/diamond-abi',
1059
+ includeSourceInfo: answers.features.includes('includeSource'),
1060
+ validateSelectors: answers.features.includes('validateSelectors'),
1061
+ verbose: answers.features.includes('verbose')
1062
+ };
1063
+
1064
+ const result = await generateDiamondAbi(diamond, options);
1065
+
1066
+ console.log(chalk.green('\nāœ… ABI generation completed!'));
1067
+ console.log(chalk.cyan(`Functions: ${result.stats.totalFunctions}`));
1068
+ console.log(chalk.cyan(`Events: ${result.stats.totalEvents}`));
1069
+ console.log(chalk.cyan(`Facets: ${result.stats.facetCount}`));
1070
+
1071
+ if (answers.features.includes('generateTypes')) {
1072
+ console.log(chalk.blue('\nšŸ”„ Generating TypeChain types...'));
1073
+ // Generate TypeChain types
1074
+ const { exec } = require('child_process');
1075
+ exec('npx typechain --target ethers-v5 --out-dir typechain-types artifacts/diamond-abi/*.json');
1076
+ }
1077
+
1078
+ if (answers.features.includes('generateViem')) {
1079
+ console.log(chalk.blue('\nšŸ”„ Generating Viem types...'));
1080
+ // Generate Viem types
1081
+ // Implementation here
1082
+ }
1083
+
1084
+ } catch (error) {
1085
+ console.error(chalk.red('āŒ Error:'), error);
1086
+ }
1087
+ });
1088
+
1089
+ program.parse();
1090
+ ```
1091
+
1092
+ ## Migration Strategies
1093
+
1094
+ ### From Hardhat to Diamond ABI
1095
+
1096
+ ```typescript
1097
+ // scripts/migrate-to-diamond-abi.ts
1098
+ import { readFileSync, writeFileSync, existsSync } from 'fs';
1099
+ import { join } from 'path';
1100
+ import { glob } from 'glob';
1101
+
1102
+ export class MigrationTool {
1103
+ async migrateFromHardhat() {
1104
+ console.log('šŸ”„ Migrating from Hardhat artifacts to Diamond ABI...');
1105
+
1106
+ // Find all existing contract artifacts
1107
+ const artifactPaths = glob.sync('./artifacts/contracts/**/*.json');
1108
+
1109
+ for (const artifactPath of artifactPaths) {
1110
+ if (artifactPath.includes('.dbg.json')) continue;
1111
+
1112
+ const artifact = JSON.parse(readFileSync(artifactPath, 'utf8'));
1113
+
1114
+ // Check if this is a diamond-related contract
1115
+ if (this.isDiamondContract(artifact)) {
1116
+ await this.convertArtifact(artifact, artifactPath);
1117
+ }
1118
+ }
1119
+
1120
+ console.log('āœ… Migration completed');
1121
+ }
1122
+
1123
+ private isDiamondContract(artifact: any): boolean {
1124
+ // Check for diamond-specific patterns
1125
+ const diamondPatterns = [
1126
+ 'Diamond',
1127
+ 'Facet',
1128
+ 'Loupe',
1129
+ 'Cut'
1130
+ ];
1131
+
1132
+ return diamondPatterns.some(pattern =>
1133
+ artifact.contractName.includes(pattern)
1134
+ );
1135
+ }
1136
+
1137
+ private async convertArtifact(artifact: any, originalPath: string) {
1138
+ // Convert to diamond ABI format
1139
+ const diamondArtifact = {
1140
+ ...artifact,
1141
+ _diamondMetadata: {
1142
+ generatedAt: new Date().toISOString(),
1143
+ migratedFrom: originalPath,
1144
+ originalFormat: 'hardhat-artifact'
1145
+ }
1146
+ };
1147
+
1148
+ // Write to new location
1149
+ const newPath = originalPath.replace('/artifacts/contracts/', '/artifacts/diamond-abi/');
1150
+ writeFileSync(newPath, JSON.stringify(diamondArtifact, null, 2));
1151
+
1152
+ console.log(`āœ… Converted ${artifact.contractName}`);
1153
+ }
1154
+ }
1155
+ ```
1156
+
1157
+ ### Version Upgrade Strategy
1158
+
1159
+ ```typescript
1160
+ // scripts/upgrade-diamond-abi.ts
1161
+ export class UpgradeManager {
1162
+ async upgradeToLatestVersion() {
1163
+ console.log('šŸ”„ Upgrading Diamond ABI to latest version...');
1164
+
1165
+ // Backup existing ABIs
1166
+ await this.backupExistingAbis();
1167
+
1168
+ // Regenerate with latest features
1169
+ await this.regenerateAbis();
1170
+
1171
+ // Validate upgrade
1172
+ await this.validateUpgrade();
1173
+
1174
+ console.log('āœ… Upgrade completed');
1175
+ }
1176
+
1177
+ private async backupExistingAbis() {
1178
+ const backupDir = `./artifacts/diamond-abi-backup-${Date.now()}`;
1179
+ // Copy existing ABIs to backup directory
1180
+ }
1181
+
1182
+ private async regenerateAbis() {
1183
+ // Regenerate all ABIs with latest version
1184
+ }
1185
+
1186
+ private async validateUpgrade() {
1187
+ // Run tests to ensure upgrade was successful
1188
+ }
1189
+ }
1190
+ ```
1191
+
1192
+ ## Conclusion
1193
+
1194
+ These practical examples and patterns provide a comprehensive foundation for implementing the Diamond ABI Generator in real-world projects. The patterns cover:
1195
+
1196
+ - **Integration Patterns**: Basic setup, multi-network support, and development workflows
1197
+ - **Frontend Integration**: React, Next.js, and Vue.js examples
1198
+ - **Testing**: Unit and integration testing strategies
1199
+ - **CI/CD**: Automated workflows for different platforms
1200
+ - **Performance**: Caching and parallel processing optimizations
1201
+ - **Custom Tooling**: VS Code extensions and CLI tools
1202
+ - **Migration**: Strategies for adopting the Diamond ABI system
1203
+
1204
+ Choose the patterns that best fit your project's needs and customize them according to your specific requirements.