@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.
- package/README.md +618 -0
- package/diamonds/README.md +3 -0
- package/dist/core/CallbackManager.d.ts +13 -0
- package/dist/core/CallbackManager.d.ts.map +1 -0
- package/dist/core/CallbackManager.js +95 -0
- package/dist/core/CallbackManager.js.map +1 -0
- package/dist/core/DeploymentManager.d.ts +10 -0
- package/dist/core/DeploymentManager.d.ts.map +1 -0
- package/dist/core/DeploymentManager.js +50 -0
- package/dist/core/DeploymentManager.js.map +1 -0
- package/dist/core/Diamond.d.ts +58 -0
- package/dist/core/Diamond.d.ts.map +1 -0
- package/dist/core/Diamond.js +146 -0
- package/dist/core/Diamond.js.map +1 -0
- package/dist/core/DiamondDeployer.d.ts +10 -0
- package/dist/core/DiamondDeployer.d.ts.map +1 -0
- package/dist/core/DiamondDeployer.js +33 -0
- package/dist/core/DiamondDeployer.js.map +1 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +12 -0
- package/dist/core/index.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/repositories/DBDeploymentRepository.d.ts +1 -0
- package/dist/repositories/DBDeploymentRepository.d.ts.map +1 -0
- package/dist/repositories/DBDeploymentRepository.js +20 -0
- package/dist/repositories/DBDeploymentRepository.js.map +1 -0
- package/dist/repositories/DeploymentRepository.d.ts +8 -0
- package/dist/repositories/DeploymentRepository.d.ts.map +1 -0
- package/dist/repositories/DeploymentRepository.js +7 -0
- package/dist/repositories/DeploymentRepository.js.map +1 -0
- package/dist/repositories/FileDeploymentRepository.d.ts +18 -0
- package/dist/repositories/FileDeploymentRepository.d.ts.map +1 -0
- package/dist/repositories/FileDeploymentRepository.js +58 -0
- package/dist/repositories/FileDeploymentRepository.js.map +1 -0
- package/dist/repositories/databaseHandler.d.ts +1 -0
- package/dist/repositories/databaseHandler.d.ts.map +1 -0
- package/dist/repositories/databaseHandler.js +13 -0
- package/dist/repositories/databaseHandler.js.map +1 -0
- package/dist/repositories/index.d.ts +4 -0
- package/dist/repositories/index.d.ts.map +1 -0
- package/dist/repositories/index.js +20 -0
- package/dist/repositories/index.js.map +1 -0
- package/dist/repositories/jsonFileHandler.d.ts +81 -0
- package/dist/repositories/jsonFileHandler.d.ts.map +1 -0
- package/dist/repositories/jsonFileHandler.js +223 -0
- package/dist/repositories/jsonFileHandler.js.map +1 -0
- package/dist/repositories/prismaDBHandler.d.ts +1 -0
- package/dist/repositories/prismaDBHandler.d.ts.map +1 -0
- package/dist/repositories/prismaDBHandler.js +11 -0
- package/dist/repositories/prismaDBHandler.js.map +1 -0
- package/dist/schemas/DeploymentSchema.d.ts +309 -0
- package/dist/schemas/DeploymentSchema.d.ts.map +1 -0
- package/dist/schemas/DeploymentSchema.js +56 -0
- package/dist/schemas/DeploymentSchema.js.map +1 -0
- package/dist/schemas/index.d.ts +2 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +18 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/strategies/BaseDeploymentStrategy.d.ts +41 -0
- package/dist/strategies/BaseDeploymentStrategy.d.ts.map +1 -0
- package/dist/strategies/BaseDeploymentStrategy.js +545 -0
- package/dist/strategies/BaseDeploymentStrategy.js.map +1 -0
- package/dist/strategies/DeploymentStrategy.d.ts +19 -0
- package/dist/strategies/DeploymentStrategy.d.ts.map +1 -0
- package/dist/strategies/DeploymentStrategy.js +3 -0
- package/dist/strategies/DeploymentStrategy.js.map +1 -0
- package/dist/strategies/LocalDeploymentStrategy.d.ts +4 -0
- package/dist/strategies/LocalDeploymentStrategy.d.ts.map +1 -0
- package/dist/strategies/LocalDeploymentStrategy.js +8 -0
- package/dist/strategies/LocalDeploymentStrategy.js.map +1 -0
- package/dist/strategies/OZDefenderDeploymentStrategy.d.ts +62 -0
- package/dist/strategies/OZDefenderDeploymentStrategy.d.ts.map +1 -0
- package/dist/strategies/OZDefenderDeploymentStrategy.js +757 -0
- package/dist/strategies/OZDefenderDeploymentStrategy.js.map +1 -0
- package/dist/strategies/RPCDeploymentStrategy.d.ts +139 -0
- package/dist/strategies/RPCDeploymentStrategy.d.ts.map +1 -0
- package/dist/strategies/RPCDeploymentStrategy.js +710 -0
- package/dist/strategies/RPCDeploymentStrategy.js.map +1 -0
- package/dist/strategies/index.d.ts +6 -0
- package/dist/strategies/index.d.ts.map +1 -0
- package/dist/strategies/index.js +12 -0
- package/dist/strategies/index.js.map +1 -0
- package/dist/types/config.d.ts +26 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +3 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/defender.d.ts +22 -0
- package/dist/types/defender.d.ts.map +1 -0
- package/dist/types/defender.js +3 -0
- package/dist/types/defender.js.map +1 -0
- package/dist/types/deployments.d.ts +71 -0
- package/dist/types/deployments.d.ts.map +1 -0
- package/dist/types/deployments.js +20 -0
- package/dist/types/deployments.js.map +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +21 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/rpc.d.ts +35 -0
- package/dist/types/rpc.d.ts.map +1 -0
- package/dist/types/rpc.js +3 -0
- package/dist/types/rpc.js.map +1 -0
- package/dist/utils/common.d.ts +20 -0
- package/dist/utils/common.d.ts.map +1 -0
- package/dist/utils/common.js +45 -0
- package/dist/utils/common.js.map +1 -0
- package/dist/utils/configurationResolver.d.ts +30 -0
- package/dist/utils/configurationResolver.d.ts.map +1 -0
- package/dist/utils/configurationResolver.js +151 -0
- package/dist/utils/configurationResolver.js.map +1 -0
- package/dist/utils/contractMapping.d.ts +29 -0
- package/dist/utils/contractMapping.d.ts.map +1 -0
- package/dist/utils/contractMapping.js +224 -0
- package/dist/utils/contractMapping.js.map +1 -0
- package/dist/utils/defenderClients.d.ts +5 -0
- package/dist/utils/defenderClients.d.ts.map +1 -0
- package/dist/utils/defenderClients.js +21 -0
- package/dist/utils/defenderClients.js.map +1 -0
- package/dist/utils/defenderStore.d.ts +14 -0
- package/dist/utils/defenderStore.d.ts.map +1 -0
- package/dist/utils/defenderStore.js +92 -0
- package/dist/utils/defenderStore.js.map +1 -0
- package/dist/utils/diamondAbiGenerator.d.ts +113 -0
- package/dist/utils/diamondAbiGenerator.d.ts.map +1 -0
- package/dist/utils/diamondAbiGenerator.js +415 -0
- package/dist/utils/diamondAbiGenerator.js.map +1 -0
- package/dist/utils/diffDeployedFacets.d.ts +26 -0
- package/dist/utils/diffDeployedFacets.d.ts.map +1 -0
- package/dist/utils/diffDeployedFacets.js +106 -0
- package/dist/utils/diffDeployedFacets.js.map +1 -0
- package/dist/utils/index.d.ts +16 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +35 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/loupe.d.ts +44 -0
- package/dist/utils/loupe.d.ts.map +1 -0
- package/dist/utils/loupe.js +128 -0
- package/dist/utils/loupe.js.map +1 -0
- package/dist/utils/rpcStore.d.ts +36 -0
- package/dist/utils/rpcStore.d.ts.map +1 -0
- package/dist/utils/rpcStore.js +166 -0
- package/dist/utils/rpcStore.js.map +1 -0
- package/dist/utils/signer.d.ts +36 -0
- package/dist/utils/signer.d.ts.map +1 -0
- package/dist/utils/signer.js +91 -0
- package/dist/utils/signer.js.map +1 -0
- package/dist/utils/txlogging.d.ts +13 -0
- package/dist/utils/txlogging.d.ts.map +1 -0
- package/dist/utils/txlogging.js +87 -0
- package/dist/utils/txlogging.js.map +1 -0
- package/dist/utils/workspaceSetup.d.ts +32 -0
- package/dist/utils/workspaceSetup.d.ts.map +1 -0
- package/dist/utils/workspaceSetup.js +311 -0
- package/dist/utils/workspaceSetup.js.map +1 -0
- package/docs/DIAMOND_ABI_CONFIGURATION_SUMMARY.md +40 -0
- package/docs/DIAMOND_ABI_GENERATION.md +220 -0
- package/docs/DIAMOND_ABI_GENERATOR_EXAMPLES.md +1204 -0
- package/docs/DIAMOND_ABI_GENERATOR_IMPLEMENTATION.md +947 -0
- package/docs/DIAMOND_ABI_GENERATOR_QUICK_REFERENCE.md +336 -0
- package/docs/README-DEFENDER.md +394 -0
- package/docs/README_DIAMOND_ABI_GENERATOR.md +303 -0
- package/docs/ROADMAP.md +250 -0
- package/docs/assets/image.png +0 -0
- package/docs/defender-integration.md +451 -0
- package/docs/diamond_module-BaseStrategy_design-v2.uxf +247 -0
- package/docs/diamond_module-BaseStrategy_design.uxf +272 -0
- package/docs/monitoring-troubleshooting.md +556 -0
- package/docs/testing-guide.md +713 -0
- package/examples/Diamond_Config_and_Deployment_examples/diamonds/ProxyDiamond/callbacks/ERC20ProxyFacet.ts +31 -0
- package/examples/Diamond_Config_and_Deployment_examples/diamonds/ProxyDiamond/proxydiamond.config.json +27 -0
- package/examples/Local_Hardhat_Deployer_Script_example/LocalDiamondDeployer.ts +180 -0
- package/examples/OZ_Defender_Deployer_Script_example/OZDiamondDeployer.ts +107 -0
- package/examples/OZ_Defender_Deployer_Script_example/run-oz-deploy.ts +17 -0
- package/examples/Test_examples/ProxyDiamondDeployment.test.ts +202 -0
- package/examples/defender-deployment/.env.example +35 -0
- package/examples/defender-deployment/README.md +415 -0
- package/examples/defender-deployment/contracts/ExampleDiamond.sol +41 -0
- package/examples/defender-deployment/contracts/ExampleFacet1.sol +84 -0
- package/examples/defender-deployment/contracts/ExampleFacet2.sol +104 -0
- package/examples/defender-deployment/contracts/UpgradeFacet.sol +92 -0
- package/examples/defender-deployment/deploy-script.ts +170 -0
- package/examples/defender-deployment/diamond-config.json +36 -0
- package/examples/defender-deployment/upgrade-script.ts +237 -0
- package/examples/hardhat-diamonds-config.example.ts +41 -0
- package/package.json +228 -0
- package/src/core/CallbackManager.ts +70 -0
- package/src/core/DeploymentManager.ts +64 -0
- package/src/core/Diamond.ts +197 -0
- package/src/core/DiamondDeployer.ts +36 -0
- package/src/core/index.ts +4 -0
- package/src/index.ts +5 -0
- package/src/repositories/DBDeploymentRepository.ts +22 -0
- package/src/repositories/DeploymentRepository.ts +12 -0
- package/src/repositories/FileDeploymentRepository.ts +67 -0
- package/src/repositories/databaseHandler.ts +14 -0
- package/src/repositories/index.ts +4 -0
- package/src/repositories/jsonFileHandler.ts +252 -0
- package/src/repositories/prismaDBHandler.ts +10 -0
- package/src/schemas/DeploymentSchema.ts +71 -0
- package/src/schemas/index.ts +1 -0
- package/src/strategies/BaseDeploymentStrategy.ts +649 -0
- package/src/strategies/DeploymentStrategy.ts +25 -0
- package/src/strategies/LocalDeploymentStrategy.ts +5 -0
- package/src/strategies/OZDefenderDeploymentStrategy.ts +849 -0
- package/src/strategies/RPCDeploymentStrategy.ts +881 -0
- package/src/strategies/index.ts +5 -0
- package/src/types/config.ts +34 -0
- package/src/types/defender.ts +24 -0
- package/src/types/deployments.ts +102 -0
- package/src/types/index.ts +4 -0
- package/src/types/rpc.ts +37 -0
- package/src/utils/common.ts +54 -0
- package/src/utils/configurationResolver.ts +141 -0
- package/src/utils/contractMapping.ts +220 -0
- package/src/utils/defenderClients.ts +22 -0
- package/src/utils/defenderStore.ts +62 -0
- package/src/utils/diamondAbiGenerator.ts +523 -0
- package/src/utils/diffDeployedFacets.ts +131 -0
- package/src/utils/index.ts +15 -0
- package/src/utils/loupe.ts +159 -0
- package/src/utils/rpcStore.ts +152 -0
- package/src/utils/signer.ts +93 -0
- package/src/utils/txlogging.ts +97 -0
- package/src/utils/workspaceSetup.ts +315 -0
- package/test/README.md +136 -0
|
@@ -0,0 +1,947 @@
|
|
|
1
|
+
# Diamond ABI Generator - Implementation Guide
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The Diamond ABI Generator is a comprehensive tool for generating unified ABI (Application Binary Interface) files for ERC-2535 Diamond Proxy contracts. It combines the ABIs of all deployed and planned facets into a single, cohesive interface that can be used with frontend frameworks, TypeScript projects, and development tools.
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
1. [Quick Start](#quick-start)
|
|
10
|
+
2. [Installation & Setup](#installation--setup)
|
|
11
|
+
3. [Command Line Interface](#command-line-interface)
|
|
12
|
+
4. [Programmatic Usage](#programmatic-usage)
|
|
13
|
+
5. [TypeChain Integration](#typechain-integration)
|
|
14
|
+
6. [Viem Integration](#viem-integration)
|
|
15
|
+
7. [ABIType Integration](#abitype-integration)
|
|
16
|
+
8. [Configuration Options](#configuration-options)
|
|
17
|
+
9. [Advanced Features](#advanced-features)
|
|
18
|
+
10. [Best Practices](#best-practices)
|
|
19
|
+
11. [Troubleshooting](#troubleshooting)
|
|
20
|
+
12. [Examples](#examples)
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
### Prerequisites
|
|
25
|
+
|
|
26
|
+
- Node.js 16+ and npm/yarn
|
|
27
|
+
- Hardhat project with compiled contracts
|
|
28
|
+
- Diamonds module setup with deployment configuration
|
|
29
|
+
|
|
30
|
+
### Basic Usage
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Generate ABI for your diamond
|
|
34
|
+
npm run diamond-abi generate --diamond YourDiamond --network localhost
|
|
35
|
+
|
|
36
|
+
# Preview ABI changes before deployment
|
|
37
|
+
npm run diamond-abi preview --diamond YourDiamond --verbose
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Installation & Setup
|
|
41
|
+
|
|
42
|
+
### 1. Ensure Diamonds Module is Configured
|
|
43
|
+
|
|
44
|
+
Your project should already have the diamonds module configured with:
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
// hardhat.config.ts
|
|
48
|
+
import { HardhatUserConfig } from "hardhat/config";
|
|
49
|
+
import "@nomicfoundation/hardhat-toolbox";
|
|
50
|
+
import "diamonds";
|
|
51
|
+
|
|
52
|
+
const config: HardhatUserConfig = {
|
|
53
|
+
solidity: "0.8.19",
|
|
54
|
+
networks: {
|
|
55
|
+
localhost: {
|
|
56
|
+
url: "http://127.0.0.1:8545"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export default config;
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 2. Verify Deployment Configuration
|
|
65
|
+
|
|
66
|
+
Ensure your diamond deployment configuration exists:
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
// diamonds/YourDiamond.localhost.config.json
|
|
70
|
+
{
|
|
71
|
+
"protocolVersion": "1.0.0",
|
|
72
|
+
"facets": [
|
|
73
|
+
{
|
|
74
|
+
"name": "DiamondCutFacet",
|
|
75
|
+
"priority": 1,
|
|
76
|
+
"libraries": []
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"name": "DiamondLoupeFacet",
|
|
80
|
+
"priority": 2,
|
|
81
|
+
"libraries": []
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 3. Install Additional Dependencies (if needed)
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npm install --save-dev @types/node typescript
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Command Line Interface
|
|
94
|
+
|
|
95
|
+
### Generate Command
|
|
96
|
+
|
|
97
|
+
Generate a complete ABI for your deployed diamond:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
npm run diamond-abi generate [options]
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Options:**
|
|
104
|
+
|
|
105
|
+
- `-d, --diamond <name>`: Diamond name (default: "GeniusDiamond")
|
|
106
|
+
- `-n, --network <name>`: Network name (default: "localhost")
|
|
107
|
+
- `-c, --chain-id <id>`: Chain ID (default: "31337")
|
|
108
|
+
- `-o, --output <dir>`: Output directory (default: "artifacts/diamond-abi")
|
|
109
|
+
- `--deployments-path <path>`: Deployments path (default: "./diamonds")
|
|
110
|
+
- `--contracts-path <path>`: Contracts path (default: "./contracts")
|
|
111
|
+
- `--include-source`: Include source information in ABI
|
|
112
|
+
- `--validate-selectors`: Validate function selector uniqueness
|
|
113
|
+
- `-v, --verbose`: Verbose output
|
|
114
|
+
|
|
115
|
+
**Examples:**
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# Basic generation
|
|
119
|
+
npm run diamond-abi generate --diamond MyDiamond
|
|
120
|
+
|
|
121
|
+
# Generate with source info and validation
|
|
122
|
+
npm run diamond-abi generate --diamond MyDiamond --include-source --validate-selectors -v
|
|
123
|
+
|
|
124
|
+
# Generate for specific network
|
|
125
|
+
npm run diamond-abi generate --diamond MyDiamond --network sepolia --chain-id 11155111
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Preview Command
|
|
129
|
+
|
|
130
|
+
Preview ABI changes before applying diamond cuts:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
npm run diamond-abi preview [options]
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Options:**
|
|
137
|
+
|
|
138
|
+
- Same as generate command
|
|
139
|
+
- Shows what the ABI would look like with planned cuts
|
|
140
|
+
|
|
141
|
+
**Example:**
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# Preview changes with detailed output
|
|
145
|
+
npm run diamond-abi preview --diamond MyDiamond --verbose
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Compare Command
|
|
149
|
+
|
|
150
|
+
Compare two ABI files to see differences:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
npm run diamond-abi compare <file1> <file2>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Validate Command
|
|
157
|
+
|
|
158
|
+
Validate an ABI file:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
npm run diamond-abi validate <file>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Programmatic Usage
|
|
165
|
+
|
|
166
|
+
### Basic Usage
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
import { generateDiamondAbi, Diamond } from 'diamonds';
|
|
170
|
+
import { FileDeploymentRepository } from 'diamonds/repositories';
|
|
171
|
+
|
|
172
|
+
// Setup
|
|
173
|
+
const config = {
|
|
174
|
+
diamondName: 'YourDiamond',
|
|
175
|
+
networkName: 'localhost',
|
|
176
|
+
chainId: 31337,
|
|
177
|
+
deploymentsPath: './diamonds',
|
|
178
|
+
contractsPath: './contracts'
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
const repository = new FileDeploymentRepository(config);
|
|
182
|
+
const diamond = new Diamond(config, repository);
|
|
183
|
+
|
|
184
|
+
// Generate ABI
|
|
185
|
+
const result = await generateDiamondAbi(diamond, {
|
|
186
|
+
outputDir: './artifacts/diamond-abi',
|
|
187
|
+
includeSourceInfo: true,
|
|
188
|
+
validateSelectors: true,
|
|
189
|
+
verbose: true
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
console.log(`Generated ABI with ${result.stats.totalFunctions} functions`);
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Advanced Usage
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
import {
|
|
199
|
+
DiamondAbiGenerator,
|
|
200
|
+
DiamondAbiGenerationOptions,
|
|
201
|
+
previewDiamondAbi
|
|
202
|
+
} from 'diamonds';
|
|
203
|
+
|
|
204
|
+
// Create generator instance for multiple operations
|
|
205
|
+
const generator = new DiamondAbiGenerator({
|
|
206
|
+
diamond: diamond,
|
|
207
|
+
outputDir: './artifacts/diamond-abi',
|
|
208
|
+
includeSourceInfo: true,
|
|
209
|
+
validateSelectors: true,
|
|
210
|
+
verbose: true
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// Generate current ABI
|
|
214
|
+
const currentAbi = await generator.generateAbi();
|
|
215
|
+
|
|
216
|
+
// Preview with planned cuts
|
|
217
|
+
const plannedCuts = [
|
|
218
|
+
{
|
|
219
|
+
name: 'NewFacet',
|
|
220
|
+
facetAddress: '0x...',
|
|
221
|
+
action: 0, // Add
|
|
222
|
+
functionSelectors: ['0x12345678', '0x87654321']
|
|
223
|
+
}
|
|
224
|
+
];
|
|
225
|
+
|
|
226
|
+
const previewResult = await previewDiamondAbi(diamond, plannedCuts, {
|
|
227
|
+
verbose: true
|
|
228
|
+
});
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Using Generated ABI
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
import { ethers } from 'ethers';
|
|
235
|
+
import DiamondABI from './artifacts/diamond-abi/YourDiamond.json';
|
|
236
|
+
|
|
237
|
+
// Create contract instance
|
|
238
|
+
const provider = new ethers.providers.JsonRpcProvider();
|
|
239
|
+
const diamond = new ethers.Contract(
|
|
240
|
+
diamondAddress,
|
|
241
|
+
DiamondABI.abi,
|
|
242
|
+
provider
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
// Call functions
|
|
246
|
+
const result = await diamond.someFunction();
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## TypeChain Integration
|
|
250
|
+
|
|
251
|
+
### 1. Install TypeChain
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
npm install --save-dev typechain @typechain/ethers-v5 @typechain/hardhat
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### 2. Configure Hardhat
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
// hardhat.config.ts
|
|
261
|
+
import { HardhatUserConfig } from "hardhat/config";
|
|
262
|
+
import "@typechain/hardhat";
|
|
263
|
+
import "diamonds";
|
|
264
|
+
|
|
265
|
+
const config: HardhatUserConfig = {
|
|
266
|
+
solidity: "0.8.19",
|
|
267
|
+
typechain: {
|
|
268
|
+
outDir: "typechain-types",
|
|
269
|
+
target: "ethers-v5",
|
|
270
|
+
alwaysGenerateOverloads: false,
|
|
271
|
+
discriminateTypes: true,
|
|
272
|
+
dontOverrideCompile: false
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
export default config;
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### 3. Generate Types
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
# Generate diamond ABI first
|
|
283
|
+
npm run diamond-abi generate --diamond YourDiamond
|
|
284
|
+
|
|
285
|
+
# Generate TypeChain types
|
|
286
|
+
npx typechain --target ethers-v5 --out-dir typechain-types 'artifacts/diamond-abi/*.json'
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### 4. Use Generated Types
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
import { YourDiamond } from '../typechain-types/YourDiamond';
|
|
293
|
+
import { ethers } from 'ethers';
|
|
294
|
+
|
|
295
|
+
const provider = new ethers.providers.JsonRpcProvider();
|
|
296
|
+
const diamond = YourDiamond__factory.connect(diamondAddress, provider);
|
|
297
|
+
|
|
298
|
+
// Type-safe function calls
|
|
299
|
+
const result: string = await diamond.someFunction();
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### 5. Automated Integration
|
|
303
|
+
|
|
304
|
+
Create a script to automate the process:
|
|
305
|
+
|
|
306
|
+
```typescript
|
|
307
|
+
// scripts/generate-diamond-types.ts
|
|
308
|
+
import { generateDiamondAbi, Diamond } from 'diamonds';
|
|
309
|
+
import { exec } from 'child_process';
|
|
310
|
+
import { promisify } from 'util';
|
|
311
|
+
|
|
312
|
+
const execAsync = promisify(exec);
|
|
313
|
+
|
|
314
|
+
async function generateTypes() {
|
|
315
|
+
// Generate diamond ABI
|
|
316
|
+
const result = await generateDiamondAbi(diamond, {
|
|
317
|
+
outputDir: './artifacts/diamond-abi'
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
// Generate TypeChain types
|
|
321
|
+
await execAsync('npx typechain --target ethers-v5 --out-dir typechain-types artifacts/diamond-abi/*.json');
|
|
322
|
+
|
|
323
|
+
console.log('✅ Types generated successfully');
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
generateTypes().catch(console.error);
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
## Viem Integration
|
|
330
|
+
|
|
331
|
+
### 1. Installation
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
npm install viem
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### 2. Use Generated ABI with Viem
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
import { createPublicClient, createWalletClient, http } from 'viem';
|
|
341
|
+
import { mainnet } from 'viem/chains';
|
|
342
|
+
import DiamondABI from './artifacts/diamond-abi/YourDiamond.json';
|
|
343
|
+
|
|
344
|
+
// Create clients
|
|
345
|
+
const publicClient = createPublicClient({
|
|
346
|
+
chain: mainnet,
|
|
347
|
+
transport: http()
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
const walletClient = createWalletClient({
|
|
351
|
+
chain: mainnet,
|
|
352
|
+
transport: http()
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// Read functions
|
|
356
|
+
const result = await publicClient.readContract({
|
|
357
|
+
address: diamondAddress,
|
|
358
|
+
abi: DiamondABI.abi,
|
|
359
|
+
functionName: 'someFunction',
|
|
360
|
+
args: []
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
// Write functions
|
|
364
|
+
const hash = await walletClient.writeContract({
|
|
365
|
+
address: diamondAddress,
|
|
366
|
+
abi: DiamondABI.abi,
|
|
367
|
+
functionName: 'someWriteFunction',
|
|
368
|
+
args: [arg1, arg2]
|
|
369
|
+
});
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### 3. Type-Safe Viem Usage
|
|
373
|
+
|
|
374
|
+
```typescript
|
|
375
|
+
import { Abi } from 'viem';
|
|
376
|
+
import DiamondABI from './artifacts/diamond-abi/YourDiamond.json';
|
|
377
|
+
|
|
378
|
+
const abi = DiamondABI.abi as Abi;
|
|
379
|
+
|
|
380
|
+
// Type-safe contract interactions
|
|
381
|
+
const result = await publicClient.readContract({
|
|
382
|
+
address: diamondAddress,
|
|
383
|
+
abi,
|
|
384
|
+
functionName: 'someFunction' // TypeScript will provide autocompletion
|
|
385
|
+
});
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### 4. Generate Viem Types
|
|
389
|
+
|
|
390
|
+
```typescript
|
|
391
|
+
// scripts/generate-viem-types.ts
|
|
392
|
+
import { generateDiamondAbi } from 'diamonds';
|
|
393
|
+
import { writeFileSync } from 'fs';
|
|
394
|
+
|
|
395
|
+
async function generateViemTypes() {
|
|
396
|
+
const result = await generateDiamondAbi(diamond);
|
|
397
|
+
|
|
398
|
+
// Generate Viem-specific type definitions
|
|
399
|
+
const viemTypes = `
|
|
400
|
+
// Auto-generated Viem types for ${diamond.diamondName}
|
|
401
|
+
import { Abi } from 'viem';
|
|
402
|
+
|
|
403
|
+
export const ${diamond.diamondName}ABI = ${JSON.stringify(result.abi, null, 2)} as const;
|
|
404
|
+
|
|
405
|
+
export type ${diamond.diamondName}ABI = typeof ${diamond.diamondName}ABI;
|
|
406
|
+
`;
|
|
407
|
+
|
|
408
|
+
writeFileSync('./types/diamond-viem.ts', viemTypes);
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
## ABIType Integration
|
|
413
|
+
|
|
414
|
+
### 1. Installation
|
|
415
|
+
|
|
416
|
+
```bash
|
|
417
|
+
npm install abitype
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### 2. Generate ABIType Types
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
// scripts/generate-abitype.ts
|
|
424
|
+
import { generateDiamondAbi } from 'diamonds';
|
|
425
|
+
import { writeFileSync } from 'fs';
|
|
426
|
+
|
|
427
|
+
async function generateAbiTypes() {
|
|
428
|
+
const result = await generateDiamondAbi(diamond);
|
|
429
|
+
|
|
430
|
+
const abiTypesContent = `
|
|
431
|
+
// Auto-generated ABIType types for ${diamond.diamondName}
|
|
432
|
+
import { Abi } from 'abitype';
|
|
433
|
+
|
|
434
|
+
export const ${diamond.diamondName}ABI = ${JSON.stringify(result.abi, null, 2)} as const satisfies Abi;
|
|
435
|
+
|
|
436
|
+
export type ${diamond.diamondName}ABI = typeof ${diamond.diamondName}ABI;
|
|
437
|
+
|
|
438
|
+
// Extract function names
|
|
439
|
+
export type ${diamond.diamondName}FunctionNames = ${diamond.diamondName}ABI[number]['name'];
|
|
440
|
+
|
|
441
|
+
// Extract events
|
|
442
|
+
export type ${diamond.diamondName}Events = Extract<${diamond.diamondName}ABI[number], { type: 'event' }>;
|
|
443
|
+
`;
|
|
444
|
+
|
|
445
|
+
writeFileSync('./types/diamond-abitype.ts', abiTypesContent);
|
|
446
|
+
}
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
### 3. Use ABIType Types
|
|
450
|
+
|
|
451
|
+
```typescript
|
|
452
|
+
import { YourDiamondABI, YourDiamondFunctionNames } from './types/diamond-abitype';
|
|
453
|
+
|
|
454
|
+
// Type-safe function name usage
|
|
455
|
+
const functionName: YourDiamondFunctionNames = 'someFunction';
|
|
456
|
+
|
|
457
|
+
// Use with other libraries
|
|
458
|
+
import { parseAbi } from 'abitype';
|
|
459
|
+
const parsedAbi = parseAbi(YourDiamondABI);
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
## Configuration Options
|
|
463
|
+
|
|
464
|
+
### DiamondAbiGenerationOptions
|
|
465
|
+
|
|
466
|
+
```typescript
|
|
467
|
+
interface DiamondAbiGenerationOptions {
|
|
468
|
+
/** Diamond instance to generate ABI for */
|
|
469
|
+
diamond: Diamond;
|
|
470
|
+
|
|
471
|
+
/** Output directory for generated ABI files */
|
|
472
|
+
outputDir?: string;
|
|
473
|
+
|
|
474
|
+
/** Whether to include source information in ABI */
|
|
475
|
+
includeSourceInfo?: boolean;
|
|
476
|
+
|
|
477
|
+
/** Whether to validate function selector uniqueness */
|
|
478
|
+
validateSelectors?: boolean;
|
|
479
|
+
|
|
480
|
+
/** Whether to log verbose output */
|
|
481
|
+
verbose?: boolean;
|
|
482
|
+
|
|
483
|
+
/** Custom facet cuts to include (for preview/planning) */
|
|
484
|
+
customFacetCuts?: FacetCuts;
|
|
485
|
+
}
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
### Generated Output Structure
|
|
489
|
+
|
|
490
|
+
```text
|
|
491
|
+
artifacts/diamond-abi/
|
|
492
|
+
├── YourDiamond.json # Complete diamond artifact
|
|
493
|
+
├── YourDiamond.d.ts # TypeScript interface
|
|
494
|
+
└── metadata.json # Generation metadata
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
**YourDiamond.json Structure:**
|
|
498
|
+
|
|
499
|
+
```json
|
|
500
|
+
{
|
|
501
|
+
"_format": "hh-sol-artifact-1",
|
|
502
|
+
"contractName": "YourDiamond",
|
|
503
|
+
"sourceName": "diamond-abi/DiamondABI.sol",
|
|
504
|
+
"abi": [...],
|
|
505
|
+
"bytecode": "",
|
|
506
|
+
"deployedBytecode": "",
|
|
507
|
+
"linkReferences": {},
|
|
508
|
+
"deployedLinkReferences": {},
|
|
509
|
+
"_diamondMetadata": {
|
|
510
|
+
"generatedAt": "2024-01-01T00:00:00.000Z",
|
|
511
|
+
"diamondName": "YourDiamond",
|
|
512
|
+
"networkName": "localhost",
|
|
513
|
+
"chainId": 31337,
|
|
514
|
+
"selectorMap": {
|
|
515
|
+
"0x01ffc9a7": "DiamondLoupeFacet",
|
|
516
|
+
"0x52ef6b2c": "DiamondLoupeFacet"
|
|
517
|
+
},
|
|
518
|
+
"stats": {
|
|
519
|
+
"totalFunctions": 15,
|
|
520
|
+
"totalEvents": 5,
|
|
521
|
+
"totalErrors": 2,
|
|
522
|
+
"facetCount": 4,
|
|
523
|
+
"duplicateSelectorsSkipped": 0
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
## Advanced Features
|
|
530
|
+
|
|
531
|
+
### 1. Custom Facet Filters
|
|
532
|
+
|
|
533
|
+
```typescript
|
|
534
|
+
const generator = new DiamondAbiGenerator({
|
|
535
|
+
diamond: diamond,
|
|
536
|
+
outputDir: './artifacts/diamond-abi'
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
// Only include specific facets
|
|
540
|
+
const result = await generator.generateAbi({
|
|
541
|
+
facetFilter: (facetName: string) => {
|
|
542
|
+
return !facetName.includes('Test'); // Exclude test facets
|
|
543
|
+
}
|
|
544
|
+
});
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
### 2. Preview Mode
|
|
548
|
+
|
|
549
|
+
```typescript
|
|
550
|
+
// Preview ABI changes before applying cuts
|
|
551
|
+
const plannedCuts = [
|
|
552
|
+
{
|
|
553
|
+
name: 'NewFacet',
|
|
554
|
+
facetAddress: '0x...',
|
|
555
|
+
action: 0, // Add
|
|
556
|
+
functionSelectors: ['0x12345678']
|
|
557
|
+
}
|
|
558
|
+
];
|
|
559
|
+
|
|
560
|
+
const preview = await previewDiamondAbi(diamond, plannedCuts, {
|
|
561
|
+
verbose: true
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
console.log(`Preview: ${preview.stats.totalFunctions} functions`);
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
### 3. Batch Operations
|
|
568
|
+
|
|
569
|
+
```typescript
|
|
570
|
+
// Generate ABIs for multiple diamonds
|
|
571
|
+
const diamonds = ['Diamond1', 'Diamond2', 'Diamond3'];
|
|
572
|
+
|
|
573
|
+
const results = await Promise.all(
|
|
574
|
+
diamonds.map(diamondName => {
|
|
575
|
+
const config = { ...baseConfig, diamondName };
|
|
576
|
+
const diamond = new Diamond(config, repository);
|
|
577
|
+
return generateDiamondAbi(diamond, { outputDir: `./artifacts/${diamondName}` });
|
|
578
|
+
})
|
|
579
|
+
);
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
### 4. Custom Output Formats
|
|
583
|
+
|
|
584
|
+
```typescript
|
|
585
|
+
// Generate custom output formats
|
|
586
|
+
const result = await generateDiamondAbi(diamond);
|
|
587
|
+
|
|
588
|
+
// Generate React hooks
|
|
589
|
+
const reactHooks = generateReactHooks(result.abi);
|
|
590
|
+
writeFileSync('./src/hooks/useDiamond.ts', reactHooks);
|
|
591
|
+
|
|
592
|
+
// Generate GraphQL schema
|
|
593
|
+
const graphqlSchema = generateGraphQLSchema(result.abi);
|
|
594
|
+
writeFileSync('./schema.graphql', graphqlSchema);
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
## Best Practices
|
|
598
|
+
|
|
599
|
+
### 1. Automation
|
|
600
|
+
|
|
601
|
+
Create npm scripts for common tasks:
|
|
602
|
+
|
|
603
|
+
```json
|
|
604
|
+
{
|
|
605
|
+
"scripts": {
|
|
606
|
+
"diamond:abi": "npm run diamond-abi generate",
|
|
607
|
+
"diamond:types": "npm run diamond:abi && npx typechain --target ethers-v5 --out-dir typechain-types artifacts/diamond-abi/*.json",
|
|
608
|
+
"diamond:preview": "npm run diamond-abi preview --verbose",
|
|
609
|
+
"diamond:validate": "npm run diamond-abi validate artifacts/diamond-abi/*.json"
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
### 2. CI/CD Integration
|
|
615
|
+
|
|
616
|
+
```yaml
|
|
617
|
+
# .github/workflows/diamond-abi.yml
|
|
618
|
+
name: Diamond ABI Generation
|
|
619
|
+
|
|
620
|
+
on:
|
|
621
|
+
push:
|
|
622
|
+
branches: [main, develop]
|
|
623
|
+
pull_request:
|
|
624
|
+
branches: [main]
|
|
625
|
+
|
|
626
|
+
jobs:
|
|
627
|
+
generate-abi:
|
|
628
|
+
runs-on: ubuntu-latest
|
|
629
|
+
steps:
|
|
630
|
+
- uses: actions/checkout@v3
|
|
631
|
+
- uses: actions/setup-node@v3
|
|
632
|
+
with:
|
|
633
|
+
node-version: '18'
|
|
634
|
+
- run: npm ci
|
|
635
|
+
- run: npm run compile
|
|
636
|
+
- run: npm run diamond:abi
|
|
637
|
+
- run: npm run diamond:types
|
|
638
|
+
- uses: actions/upload-artifact@v3
|
|
639
|
+
with:
|
|
640
|
+
name: diamond-abi
|
|
641
|
+
path: artifacts/diamond-abi/
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
### 3. Version Control
|
|
645
|
+
|
|
646
|
+
```gitignore
|
|
647
|
+
# Include generated ABIs in version control
|
|
648
|
+
!artifacts/diamond-abi/
|
|
649
|
+
artifacts/diamond-abi/*.json
|
|
650
|
+
artifacts/diamond-abi/*.d.ts
|
|
651
|
+
|
|
652
|
+
# But exclude temporary files
|
|
653
|
+
artifacts/diamond-abi/tmp/
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
### 4. Error Handling
|
|
657
|
+
|
|
658
|
+
```typescript
|
|
659
|
+
async function generateAbiSafely() {
|
|
660
|
+
try {
|
|
661
|
+
const result = await generateDiamondAbi(diamond, {
|
|
662
|
+
validateSelectors: true,
|
|
663
|
+
verbose: true
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
// Validate result
|
|
667
|
+
if (result.stats.totalFunctions === 0) {
|
|
668
|
+
throw new Error('No functions found in generated ABI');
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
return result;
|
|
672
|
+
} catch (error) {
|
|
673
|
+
console.error('ABI generation failed:', error);
|
|
674
|
+
|
|
675
|
+
// Fallback to previous version
|
|
676
|
+
const fallbackPath = './artifacts/diamond-abi/YourDiamond.json';
|
|
677
|
+
if (existsSync(fallbackPath)) {
|
|
678
|
+
console.log('Using fallback ABI');
|
|
679
|
+
return JSON.parse(readFileSync(fallbackPath, 'utf8'));
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
throw error;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
```
|
|
686
|
+
|
|
687
|
+
## Troubleshooting
|
|
688
|
+
|
|
689
|
+
### Common Issues
|
|
690
|
+
|
|
691
|
+
#### 1. "No artifacts found"
|
|
692
|
+
|
|
693
|
+
**Problem:** Contract artifacts not found during ABI generation.
|
|
694
|
+
|
|
695
|
+
**Solution:**
|
|
696
|
+
|
|
697
|
+
```bash
|
|
698
|
+
# Compile contracts first
|
|
699
|
+
npm run compile
|
|
700
|
+
|
|
701
|
+
# Check artifacts directory
|
|
702
|
+
ls artifacts/contracts/
|
|
703
|
+
|
|
704
|
+
# Generate ABI with verbose output
|
|
705
|
+
npm run diamond-abi generate --verbose
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
#### 2. "Function selector collision"
|
|
709
|
+
|
|
710
|
+
**Problem:** Multiple functions with the same selector.
|
|
711
|
+
|
|
712
|
+
**Solution:**
|
|
713
|
+
|
|
714
|
+
```typescript
|
|
715
|
+
// Enable selector validation
|
|
716
|
+
const result = await generateDiamondAbi(diamond, {
|
|
717
|
+
validateSelectors: true,
|
|
718
|
+
verbose: true
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
// Check for duplicates in output
|
|
722
|
+
if (result.stats.duplicateSelectorsSkipped > 0) {
|
|
723
|
+
console.warn('Duplicate selectors found');
|
|
724
|
+
}
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
#### 3. "Missing deployment data"
|
|
728
|
+
|
|
729
|
+
**Problem:** Diamond deployment data not found.
|
|
730
|
+
|
|
731
|
+
**Solution:**
|
|
732
|
+
|
|
733
|
+
```bash
|
|
734
|
+
# Check deployment files
|
|
735
|
+
ls diamonds/
|
|
736
|
+
|
|
737
|
+
# Verify deployment configuration
|
|
738
|
+
cat diamonds/YourDiamond.localhost.config.json
|
|
739
|
+
|
|
740
|
+
# Check deployment data
|
|
741
|
+
cat diamonds/YourDiamond.localhost.json
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
#### 4. "TypeChain generation fails"
|
|
745
|
+
|
|
746
|
+
**Problem:** TypeChain cannot process generated ABI.
|
|
747
|
+
|
|
748
|
+
**Solution:**
|
|
749
|
+
|
|
750
|
+
```bash
|
|
751
|
+
# Generate ABI first
|
|
752
|
+
npm run diamond-abi generate
|
|
753
|
+
|
|
754
|
+
# Check ABI validity
|
|
755
|
+
npm run diamond-abi validate artifacts/diamond-abi/YourDiamond.json
|
|
756
|
+
|
|
757
|
+
# Generate types with debug
|
|
758
|
+
npx typechain --target ethers-v5 --out-dir typechain-types artifacts/diamond-abi/*.json --show-stack-traces
|
|
759
|
+
```
|
|
760
|
+
|
|
761
|
+
### Debug Mode
|
|
762
|
+
|
|
763
|
+
Enable verbose logging for detailed debugging:
|
|
764
|
+
|
|
765
|
+
```typescript
|
|
766
|
+
const result = await generateDiamondAbi(diamond, {
|
|
767
|
+
verbose: true,
|
|
768
|
+
validateSelectors: true,
|
|
769
|
+
includeSourceInfo: true
|
|
770
|
+
});
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
This will output:
|
|
774
|
+
|
|
775
|
+
- Facet processing details
|
|
776
|
+
- Selector calculations
|
|
777
|
+
- ABI item additions
|
|
778
|
+
- Statistics and warnings
|
|
779
|
+
|
|
780
|
+
## Examples
|
|
781
|
+
|
|
782
|
+
### Example 1: Basic Integration
|
|
783
|
+
|
|
784
|
+
```typescript
|
|
785
|
+
// scripts/generate-diamond-abi.ts
|
|
786
|
+
import { generateDiamondAbi, Diamond } from 'diamonds';
|
|
787
|
+
import { FileDeploymentRepository } from 'diamonds/repositories';
|
|
788
|
+
|
|
789
|
+
async function main() {
|
|
790
|
+
const config = {
|
|
791
|
+
diamondName: 'GameDiamond',
|
|
792
|
+
networkName: 'localhost',
|
|
793
|
+
chainId: 31337,
|
|
794
|
+
deploymentsPath: './diamonds',
|
|
795
|
+
contractsPath: './contracts'
|
|
796
|
+
};
|
|
797
|
+
|
|
798
|
+
const repository = new FileDeploymentRepository(config);
|
|
799
|
+
const diamond = new Diamond(config, repository);
|
|
800
|
+
|
|
801
|
+
const result = await generateDiamondAbi(diamond, {
|
|
802
|
+
outputDir: './artifacts/diamond-abi',
|
|
803
|
+
includeSourceInfo: true,
|
|
804
|
+
verbose: true
|
|
805
|
+
});
|
|
806
|
+
|
|
807
|
+
console.log(`✅ Generated ABI with ${result.stats.totalFunctions} functions`);
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
main().catch(console.error);
|
|
811
|
+
```
|
|
812
|
+
|
|
813
|
+
### Example 2: Frontend Integration
|
|
814
|
+
|
|
815
|
+
```typescript
|
|
816
|
+
// src/contracts/diamond.ts
|
|
817
|
+
import { ethers } from 'ethers';
|
|
818
|
+
import DiamondABI from '../artifacts/diamond-abi/GameDiamond.json';
|
|
819
|
+
|
|
820
|
+
export class DiamondContract {
|
|
821
|
+
private contract: ethers.Contract;
|
|
822
|
+
|
|
823
|
+
constructor(address: string, provider: ethers.Provider) {
|
|
824
|
+
this.contract = new ethers.Contract(
|
|
825
|
+
address,
|
|
826
|
+
DiamondABI.abi,
|
|
827
|
+
provider
|
|
828
|
+
);
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
async getPlayerStats(playerId: string) {
|
|
832
|
+
return await this.contract.getPlayerStats(playerId);
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
async createGame(gameParams: any) {
|
|
836
|
+
return await this.contract.createGame(gameParams);
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
### Example 3: Testing Integration
|
|
842
|
+
|
|
843
|
+
```typescript
|
|
844
|
+
// test/diamond-abi.test.ts
|
|
845
|
+
import { expect } from 'chai';
|
|
846
|
+
import { generateDiamondAbi } from 'diamonds';
|
|
847
|
+
import { ethers } from 'hardhat';
|
|
848
|
+
|
|
849
|
+
describe('Diamond ABI Generation', () => {
|
|
850
|
+
it('should generate valid ABI', async () => {
|
|
851
|
+
const result = await generateDiamondAbi(diamond, {
|
|
852
|
+
validateSelectors: true
|
|
853
|
+
});
|
|
854
|
+
|
|
855
|
+
expect(result.abi).to.be.an('array');
|
|
856
|
+
expect(result.stats.totalFunctions).to.be.greaterThan(0);
|
|
857
|
+
expect(result.stats.duplicateSelectorsSkipped).to.equal(0);
|
|
858
|
+
});
|
|
859
|
+
|
|
860
|
+
it('should work with ethers.js', async () => {
|
|
861
|
+
const result = await generateDiamondAbi(diamond);
|
|
862
|
+
|
|
863
|
+
const contract = new ethers.Contract(
|
|
864
|
+
diamondAddress,
|
|
865
|
+
result.abi,
|
|
866
|
+
ethers.provider
|
|
867
|
+
);
|
|
868
|
+
|
|
869
|
+
const isValidInterface = ethers.utils.Interface.isInterface(contract.interface);
|
|
870
|
+
expect(isValidInterface).to.be.true;
|
|
871
|
+
});
|
|
872
|
+
});
|
|
873
|
+
```
|
|
874
|
+
|
|
875
|
+
### Example 4: Advanced Workflow
|
|
876
|
+
|
|
877
|
+
```typescript
|
|
878
|
+
// scripts/diamond-deployment-workflow.ts
|
|
879
|
+
import { generateDiamondAbi, previewDiamondAbi } from 'diamonds';
|
|
880
|
+
|
|
881
|
+
async function deploymentWorkflow() {
|
|
882
|
+
// 1. Generate current ABI
|
|
883
|
+
const currentAbi = await generateDiamondAbi(diamond, {
|
|
884
|
+
outputDir: './artifacts/diamond-abi/current',
|
|
885
|
+
verbose: true
|
|
886
|
+
});
|
|
887
|
+
|
|
888
|
+
// 2. Preview changes
|
|
889
|
+
const plannedCuts = [
|
|
890
|
+
{
|
|
891
|
+
name: 'NewFeatureFacet',
|
|
892
|
+
facetAddress: '0x...',
|
|
893
|
+
action: 0,
|
|
894
|
+
functionSelectors: ['0x12345678', '0x87654321']
|
|
895
|
+
}
|
|
896
|
+
];
|
|
897
|
+
|
|
898
|
+
const preview = await previewDiamondAbi(diamond, plannedCuts, {
|
|
899
|
+
outputDir: './artifacts/diamond-abi/preview',
|
|
900
|
+
verbose: true
|
|
901
|
+
});
|
|
902
|
+
|
|
903
|
+
// 3. Compare and validate
|
|
904
|
+
const functionDiff = preview.stats.totalFunctions - currentAbi.stats.totalFunctions;
|
|
905
|
+
console.log(`📊 Function count will change by: ${functionDiff}`);
|
|
906
|
+
|
|
907
|
+
// 4. Generate types
|
|
908
|
+
await generateTypes(preview.outputPath!);
|
|
909
|
+
|
|
910
|
+
// 5. Run tests
|
|
911
|
+
await runTests();
|
|
912
|
+
|
|
913
|
+
console.log('✅ Deployment workflow completed');
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
async function generateTypes(abiPath: string) {
|
|
917
|
+
const { exec } = require('child_process');
|
|
918
|
+
return new Promise((resolve, reject) => {
|
|
919
|
+
exec(`npx typechain --target ethers-v5 --out-dir typechain-types ${abiPath}`, (error: any) => {
|
|
920
|
+
if (error) reject(error);
|
|
921
|
+
else resolve(true);
|
|
922
|
+
});
|
|
923
|
+
});
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
async function runTests() {
|
|
927
|
+
const { exec } = require('child_process');
|
|
928
|
+
return new Promise((resolve, reject) => {
|
|
929
|
+
exec('npm test', (error: any) => {
|
|
930
|
+
if (error) reject(error);
|
|
931
|
+
else resolve(true);
|
|
932
|
+
});
|
|
933
|
+
});
|
|
934
|
+
}
|
|
935
|
+
```
|
|
936
|
+
|
|
937
|
+
## Conclusion
|
|
938
|
+
|
|
939
|
+
The Diamond ABI Generator provides a comprehensive solution for managing ERC-2535 Diamond Proxy ABIs. By following this implementation guide, you can:
|
|
940
|
+
|
|
941
|
+
- Generate unified ABIs for complex diamond contracts
|
|
942
|
+
- Integrate with modern development tools (TypeChain, Viem, ABIType)
|
|
943
|
+
- Automate ABI generation in your development workflow
|
|
944
|
+
- Maintain type safety across your entire application stack
|
|
945
|
+
- Preview and validate changes before deployment
|
|
946
|
+
|
|
947
|
+
For additional support and advanced use cases, refer to the API documentation and examples in the repository.
|