rocketh 0.9.1 → 0.10.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/CHANGELOG.md +12 -0
- package/dist/{chunk-LPKP3ACG.js → chunk-4RQLWJEN.js} +255 -53
- package/dist/chunk-4RQLWJEN.js.map +1 -0
- package/dist/cli.cjs +268 -66
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +5 -6
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +257 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +71 -25
- package/dist/index.d.ts +71 -25
- package/dist/index.js +7 -1
- package/package.json +2 -1
- package/src/cli.ts +2 -3
- package/src/environment/deployments.ts +3 -3
- package/src/environment/index.ts +66 -15
- package/src/environment/types.ts +34 -15
- package/src/environment/utils/artifacts.ts +151 -0
- package/src/executor/index.ts +94 -39
- package/src/index.ts +2 -0
- package/dist/chunk-LPKP3ACG.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { EIP1193Account, EIP1193DATA, EIP1193QUANTITY, EIP1193SignerProvider, EIP1193ProviderWithoutEvents, EIP1193WalletProvider, EIP1193TransactionReceipt } from 'eip-1193';
|
|
1
|
+
import { EIP1193Account, EIP1193DATA, EIP1193QUANTITY, EIP1193SignerProvider, EIP1193ProviderWithoutEvents, EIP1193WalletProvider, EIP1193TransactionReceipt, EIP1193GenericRequestProvider } from 'eip-1193';
|
|
2
|
+
import * as abitype from 'abitype';
|
|
2
3
|
import { Abi, Narrow } from 'abitype';
|
|
3
4
|
export { Abi, AbiConstructor, AbiError, AbiEvent, AbiFallback, AbiFunction, AbiReceive } from 'abitype';
|
|
4
|
-
import { Chain, DeployContractParameters } from 'viem';
|
|
5
|
+
import { Chain, Address, DeployContractParameters } from 'viem';
|
|
6
|
+
import { Chain as Chain$1 } from 'viem/chains';
|
|
5
7
|
|
|
6
8
|
type ProgressIndicator = {
|
|
7
9
|
start(msg?: string): ProgressIndicator;
|
|
@@ -195,27 +197,38 @@ type Context<Artifacts extends UnknownArtifacts = UnknownArtifacts, NamedAccount
|
|
|
195
197
|
accounts: NamedAccounts;
|
|
196
198
|
artifacts: Artifacts;
|
|
197
199
|
};
|
|
198
|
-
type
|
|
199
|
-
|
|
200
|
+
type NetworkConfigBase = {
|
|
201
|
+
name: string;
|
|
202
|
+
tags: string[];
|
|
203
|
+
fork?: boolean;
|
|
204
|
+
};
|
|
205
|
+
type NetworkConfigForJSONRPC = NetworkConfigBase & {
|
|
206
|
+
nodeUrl: string;
|
|
207
|
+
};
|
|
208
|
+
type NetworkConfigForEIP1193Provider = NetworkConfigBase & {
|
|
209
|
+
provider: EIP1193ProviderWithoutEvents;
|
|
210
|
+
};
|
|
211
|
+
type NetworkConfig = NetworkConfigForJSONRPC | NetworkConfigForEIP1193Provider;
|
|
212
|
+
type Config = {
|
|
213
|
+
network: NetworkConfig;
|
|
214
|
+
networkTags?: string[];
|
|
200
215
|
scripts?: string;
|
|
201
216
|
deployments?: string;
|
|
217
|
+
saveDeployments?: boolean;
|
|
202
218
|
tags?: string[];
|
|
203
219
|
logLevel?: number;
|
|
204
220
|
gasPricing?: {};
|
|
205
221
|
};
|
|
206
|
-
type ConfigForJSONRPC = BaseConfig & {
|
|
207
|
-
networkName: string;
|
|
208
|
-
nodeUrl: string;
|
|
209
|
-
};
|
|
210
|
-
type ConfigForEIP1193Provider = BaseConfig & {
|
|
211
|
-
provider: EIP1193ProviderWithoutEvents;
|
|
212
|
-
};
|
|
213
|
-
type Config = ConfigForJSONRPC | ConfigForEIP1193Provider;
|
|
214
222
|
type ResolvedConfig = Config & {
|
|
215
223
|
deployments: string;
|
|
216
224
|
scripts: string;
|
|
217
225
|
tags: string[];
|
|
218
|
-
|
|
226
|
+
network: {
|
|
227
|
+
name: string;
|
|
228
|
+
tags: string[];
|
|
229
|
+
fork?: boolean;
|
|
230
|
+
};
|
|
231
|
+
saveDeployments?: boolean;
|
|
219
232
|
};
|
|
220
233
|
interface Environment<Artifacts extends UnknownArtifacts = UnknownArtifacts, NamedAccounts extends UnresolvedUnknownNamedAccounts = UnresolvedUnknownNamedAccounts, Deployments extends UnknownDeployments = UnknownDeployments> {
|
|
221
234
|
config: ResolvedConfig;
|
|
@@ -238,7 +251,15 @@ interface Environment<Artifacts extends UnknownArtifacts = UnknownArtifacts, Nam
|
|
|
238
251
|
savePendingDeployment<TAbi extends Abi = Abi>(pendingDeployment: PendingDeployment<TAbi>): Promise<Deployment<TAbi>>;
|
|
239
252
|
savePendingExecution(pendingExecution: PendingExecution): Promise<EIP1193TransactionReceipt>;
|
|
240
253
|
get<TAbi extends Abi>(name: string): Deployment<TAbi>;
|
|
241
|
-
getOrNull<TAbi extends Abi>(name: string): Deployment<TAbi> |
|
|
254
|
+
getOrNull<TAbi extends Abi>(name: string): Deployment<TAbi> | null;
|
|
255
|
+
fromAddressToNamedABI<TAbi extends Abi>(address: Address): {
|
|
256
|
+
mergedABI: TAbi;
|
|
257
|
+
names: string[];
|
|
258
|
+
};
|
|
259
|
+
fromAddressToNamedABIOrNull<TAbi extends Abi>(address: Address): {
|
|
260
|
+
mergedABI: TAbi;
|
|
261
|
+
names: string[];
|
|
262
|
+
} | null;
|
|
242
263
|
showMessage(message: string): void;
|
|
243
264
|
showProgress(message?: string): ProgressIndicator;
|
|
244
265
|
}
|
|
@@ -294,20 +315,22 @@ declare function execute<Artifacts extends UnknownArtifacts = UnknownArtifacts,
|
|
|
294
315
|
dependencies?: string[];
|
|
295
316
|
}): DeployScriptModule<Artifacts, NamedAccounts, ArgumentsType, Deployments>;
|
|
296
317
|
type ConfigOptions = {
|
|
297
|
-
network
|
|
318
|
+
network?: string | {
|
|
319
|
+
fork: string;
|
|
320
|
+
};
|
|
298
321
|
deployments?: string;
|
|
299
322
|
scripts?: string;
|
|
300
323
|
tags?: string;
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
ignoreMissingRPC?: boolean;
|
|
304
|
-
}): Config;
|
|
305
|
-
declare function readAndResolveConfig(options: ConfigOptions, extra?: {
|
|
324
|
+
logLevel?: number;
|
|
325
|
+
provider?: EIP1193ProviderWithoutEvents | EIP1193GenericRequestProvider;
|
|
306
326
|
ignoreMissingRPC?: boolean;
|
|
307
|
-
|
|
327
|
+
saveDeployments?: boolean;
|
|
328
|
+
};
|
|
329
|
+
declare function readConfig(options: ConfigOptions): Config;
|
|
330
|
+
declare function readAndResolveConfig(options: ConfigOptions): ResolvedConfig;
|
|
308
331
|
declare function resolveConfig(config: Config): ResolvedConfig;
|
|
309
|
-
declare function loadEnvironment<Artifacts extends UnknownArtifacts = UnknownArtifacts, NamedAccounts extends UnresolvedUnknownNamedAccounts = UnresolvedUnknownNamedAccounts>(
|
|
310
|
-
declare function loadAndExecuteDeployments<Artifacts extends UnknownArtifacts = UnknownArtifacts, NamedAccounts extends UnresolvedUnknownNamedAccounts = UnresolvedUnknownNamedAccounts, ArgumentsType = undefined, Deployments extends UnknownDeployments = UnknownDeployments>(
|
|
332
|
+
declare function loadEnvironment<Artifacts extends UnknownArtifacts = UnknownArtifacts, NamedAccounts extends UnresolvedUnknownNamedAccounts = UnresolvedUnknownNamedAccounts>(options: ConfigOptions, context: ProvidedContext<Artifacts, NamedAccounts>): Promise<Environment>;
|
|
333
|
+
declare function loadAndExecuteDeployments<Artifacts extends UnknownArtifacts = UnknownArtifacts, NamedAccounts extends UnresolvedUnknownNamedAccounts = UnresolvedUnknownNamedAccounts, ArgumentsType = undefined, Deployments extends UnknownDeployments = UnknownDeployments>(options: ConfigOptions, args?: ArgumentsType): Promise<Environment>;
|
|
311
334
|
declare function executeDeployScripts<Artifacts extends UnknownArtifacts = UnknownArtifacts, NamedAccounts extends UnresolvedUnknownNamedAccounts = UnresolvedUnknownNamedAccounts, ArgumentsType = undefined, Deployments extends UnknownDeployments = UnknownDeployments>(config: ResolvedConfig, args?: ArgumentsType): Promise<Environment>;
|
|
312
335
|
|
|
313
336
|
type EnvironmentExtenstion = (env: Environment) => Environment;
|
|
@@ -315,7 +338,7 @@ declare function extendEnvironment(extension: EnvironmentExtenstion): void;
|
|
|
315
338
|
type SignerProtocolFunction = (protocolString: string) => Promise<NamedSigner>;
|
|
316
339
|
declare function handleSignerProtocol(protocol: string, getSigner: SignerProtocolFunction): void;
|
|
317
340
|
|
|
318
|
-
declare function loadDeployments(deploymentsPath: string,
|
|
341
|
+
declare function loadDeployments(deploymentsPath: string, networkName: string, onlyABIAndAddress?: boolean, expectedChain?: {
|
|
319
342
|
chainId: string;
|
|
320
343
|
genesisHash?: `0x${string}`;
|
|
321
344
|
deleteDeploymentsIfDifferentGenesisHash?: boolean;
|
|
@@ -325,4 +348,27 @@ declare function loadDeployments(deploymentsPath: string, subPath: string, onlyA
|
|
|
325
348
|
genesisHash?: `0x${string}`;
|
|
326
349
|
};
|
|
327
350
|
|
|
328
|
-
|
|
351
|
+
type CreateMutable<Type> = {
|
|
352
|
+
-readonly [Property in keyof Type]: Type[Property];
|
|
353
|
+
};
|
|
354
|
+
declare function mergeArtifacts(list: {
|
|
355
|
+
name: string;
|
|
356
|
+
artifact: Artifact<Abi>;
|
|
357
|
+
}[]): {
|
|
358
|
+
mergedABI: (abitype.AbiConstructor | abitype.AbiError | abitype.AbiEvent | abitype.AbiFallback | abitype.AbiFunction | abitype.AbiReceive)[];
|
|
359
|
+
added: Map<string, abitype.AbiConstructor | abitype.AbiError | abitype.AbiEvent | abitype.AbiFallback | abitype.AbiFunction | abitype.AbiReceive>;
|
|
360
|
+
mergedDevDocs: CreateMutable<DevDoc>;
|
|
361
|
+
mergedUserDocs: CreateMutable<UserDoc>;
|
|
362
|
+
sigJSMap: Map<`0x${string}`, {
|
|
363
|
+
index: number;
|
|
364
|
+
routeName: string;
|
|
365
|
+
functionName: string;
|
|
366
|
+
}>;
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
declare const chainById: {
|
|
370
|
+
[chainId: string]: Chain$1;
|
|
371
|
+
};
|
|
372
|
+
declare function getChain(id: string): Chain$1;
|
|
373
|
+
|
|
374
|
+
export { type AccountDefinition, type AccountType, type Artifact, type Config, type ConfigOptions, type Context, type CreationGasEstimate, type DeployScriptFunction, type DeployScriptModule, type Deployment, type DeploymentConstruction, type DevDoc, type DevErrorDoc, type DevEventDoc, type DevMethodDoc, type Environment, type GasEstimate, type GasEstimates, type Libraries, type NamedSigner, type NetworkConfig, type NoticeUserDoc, type PartialDeployment, type PendingDeployment, type PendingExecution, type PendingTransaction, type ProvidedContext, type ResolvedAccount, type ResolvedConfig, type ResolvedNamedAccounts, type ResolvedNamedSigners, type ScriptCallback, type Storage, type StorageLayout, type TypeDef, type UnknownArtifacts, type UnknownDeployments, type UnknownDeploymentsAcrossNetworks, type UnknownNamedAccounts, type UnresolvedUnknownNamedAccounts, type UserDoc, chainById, execute, executeDeployScripts, extendEnvironment, getChain, handleSignerProtocol, loadAndExecuteDeployments, loadDeployments, loadEnvironment, mergeArtifacts, readAndResolveConfig, readConfig, resolveConfig };
|
package/dist/index.js
CHANGED
|
@@ -1,23 +1,29 @@
|
|
|
1
1
|
import {
|
|
2
|
+
chainById,
|
|
2
3
|
execute,
|
|
3
4
|
executeDeployScripts,
|
|
4
5
|
extendEnvironment,
|
|
6
|
+
getChain,
|
|
5
7
|
handleSignerProtocol,
|
|
6
8
|
loadAndExecuteDeployments,
|
|
7
9
|
loadDeployments,
|
|
8
10
|
loadEnvironment,
|
|
11
|
+
mergeArtifacts,
|
|
9
12
|
readAndResolveConfig,
|
|
10
13
|
readConfig,
|
|
11
14
|
resolveConfig
|
|
12
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-4RQLWJEN.js";
|
|
13
16
|
export {
|
|
17
|
+
chainById,
|
|
14
18
|
execute,
|
|
15
19
|
executeDeployScripts,
|
|
16
20
|
extendEnvironment,
|
|
21
|
+
getChain,
|
|
17
22
|
handleSignerProtocol,
|
|
18
23
|
loadAndExecuteDeployments,
|
|
19
24
|
loadDeployments,
|
|
20
25
|
loadEnvironment,
|
|
26
|
+
mergeArtifacts,
|
|
21
27
|
readAndResolveConfig,
|
|
22
28
|
readConfig,
|
|
23
29
|
resolveConfig
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rocketh",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "deploy smart contract on ethereum-compatible networks",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"eip-1193-jsonrpc-provider": "^0.3.0",
|
|
29
29
|
"esbuild": "^0.20.1",
|
|
30
30
|
"esbuild-register": "^3.5.0",
|
|
31
|
+
"ethers": "^6.11.1",
|
|
31
32
|
"figlet": "^1.7.0",
|
|
32
33
|
"ldenv": "^0.3.9",
|
|
33
34
|
"named-logs": "^0.2.2",
|
package/src/cli.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
2
|
import {loadEnv} from 'ldenv';
|
|
3
|
-
import {loadAndExecuteDeployments, readConfig} from '.';
|
|
3
|
+
import {ConfigOptions, loadAndExecuteDeployments, readConfig} from '.';
|
|
4
4
|
import {Command} from 'commander';
|
|
5
5
|
import pkg from '../package.json';
|
|
6
6
|
|
|
@@ -20,6 +20,5 @@ program
|
|
|
20
20
|
.parse(process.argv);
|
|
21
21
|
|
|
22
22
|
const options = program.opts();
|
|
23
|
-
const config = readConfig(options as any);
|
|
24
23
|
|
|
25
|
-
loadAndExecuteDeployments({...
|
|
24
|
+
loadAndExecuteDeployments({...(options as ConfigOptions), logLevel: 1});
|
|
@@ -5,12 +5,12 @@ import {UnknownDeployments} from './types';
|
|
|
5
5
|
|
|
6
6
|
export function loadDeployments(
|
|
7
7
|
deploymentsPath: string,
|
|
8
|
-
|
|
8
|
+
networkName: string,
|
|
9
9
|
onlyABIAndAddress?: boolean,
|
|
10
10
|
expectedChain?: {chainId: string; genesisHash?: `0x${string}`; deleteDeploymentsIfDifferentGenesisHash?: boolean}
|
|
11
11
|
): {deployments: UnknownDeployments; chainId?: string; genesisHash?: `0x${string}`} {
|
|
12
12
|
const deploymentsFound: UnknownDeployments = {};
|
|
13
|
-
const deployPath = path.join(deploymentsPath,
|
|
13
|
+
const deployPath = path.join(deploymentsPath, networkName);
|
|
14
14
|
|
|
15
15
|
let filesStats;
|
|
16
16
|
try {
|
|
@@ -34,7 +34,7 @@ export function loadDeployments(
|
|
|
34
34
|
genesisHash = chainData.genesisHash;
|
|
35
35
|
} else {
|
|
36
36
|
throw new Error(
|
|
37
|
-
`A '.chain' or '.chainId' file is expected to be present in the deployment folder for network ${
|
|
37
|
+
`A '.chain' or '.chainId' file is expected to be present in the deployment folder for network ${networkName}`
|
|
38
38
|
);
|
|
39
39
|
}
|
|
40
40
|
}
|
package/src/environment/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {TransactionReceipt, createPublicClient, custom} from 'viem';
|
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
AccountType,
|
|
7
|
+
Artifact,
|
|
7
8
|
Deployment,
|
|
8
9
|
Environment,
|
|
9
10
|
NamedSigner,
|
|
@@ -18,7 +19,7 @@ import {
|
|
|
18
19
|
UnresolvedUnknownNamedAccounts,
|
|
19
20
|
} from './types';
|
|
20
21
|
import {JSONRPCHTTPProvider} from 'eip-1193-jsonrpc-provider';
|
|
21
|
-
import {Abi} from 'abitype';
|
|
22
|
+
import {Abi, Address} from 'abitype';
|
|
22
23
|
import {InternalEnvironment} from '../internal/types';
|
|
23
24
|
import path from 'node:path';
|
|
24
25
|
import {JSONToString, stringToJSON} from '../utils/json';
|
|
@@ -35,6 +36,7 @@ import {ProvidedContext} from '../executor/types';
|
|
|
35
36
|
import {ProgressIndicator, log, spin} from '../internal/logging';
|
|
36
37
|
import {PendingExecution} from './types';
|
|
37
38
|
import {getChain} from './utils/chains';
|
|
39
|
+
import {mergeArtifacts} from './utils/artifacts';
|
|
38
40
|
|
|
39
41
|
type ReceiptResult = {receipt: EIP1193TransactionReceipt; latestBlockNumber: EIP1193QUANTITY};
|
|
40
42
|
|
|
@@ -83,7 +85,9 @@ export async function createEnvironment<
|
|
|
83
85
|
providedContext: ProvidedContext<Artifacts, NamedAccounts>
|
|
84
86
|
): Promise<{internal: InternalEnvironment; external: Environment<Artifacts, NamedAccounts, Deployments>}> {
|
|
85
87
|
const provider =
|
|
86
|
-
'provider' in config
|
|
88
|
+
'provider' in config.network
|
|
89
|
+
? config.network.provider
|
|
90
|
+
: (new JSONRPCHTTPProvider(config.network.nodeUrl) as EIP1193ProviderWithoutEvents);
|
|
87
91
|
|
|
88
92
|
const transport = custom(provider);
|
|
89
93
|
const viemClient = createPublicClient({transport});
|
|
@@ -98,24 +102,32 @@ export async function createEnvironment<
|
|
|
98
102
|
|
|
99
103
|
let networkName: string;
|
|
100
104
|
let saveDeployments: boolean;
|
|
101
|
-
let
|
|
105
|
+
let networkTags: {[tag: string]: boolean} = {};
|
|
106
|
+
for (const networkTag of config.network.tags) {
|
|
107
|
+
networkTags[networkTag] = true;
|
|
108
|
+
}
|
|
109
|
+
|
|
102
110
|
if ('nodeUrl' in config) {
|
|
103
|
-
networkName = config.
|
|
111
|
+
networkName = config.network.name;
|
|
104
112
|
saveDeployments = true;
|
|
105
113
|
} else {
|
|
106
|
-
if (config.
|
|
107
|
-
networkName = config.
|
|
114
|
+
if (config.network.name) {
|
|
115
|
+
networkName = config.network.name;
|
|
108
116
|
} else {
|
|
109
117
|
networkName = 'memory';
|
|
110
118
|
}
|
|
111
119
|
if (networkName === 'memory' || networkName === 'hardhat') {
|
|
112
|
-
|
|
120
|
+
networkTags['memory'] = true;
|
|
113
121
|
saveDeployments = false;
|
|
114
122
|
} else {
|
|
115
123
|
saveDeployments = true;
|
|
116
124
|
}
|
|
117
125
|
}
|
|
118
126
|
|
|
127
|
+
if (config.saveDeployments !== undefined) {
|
|
128
|
+
saveDeployments = config.saveDeployments;
|
|
129
|
+
}
|
|
130
|
+
|
|
119
131
|
const resolvedAccounts: {[name: string]: ResolvedAccount} = {};
|
|
120
132
|
|
|
121
133
|
const accountCache: {[name: string]: ResolvedAccount} = {};
|
|
@@ -203,16 +215,26 @@ export async function createEnvironment<
|
|
|
203
215
|
artifacts: providedContext.artifacts as Artifacts,
|
|
204
216
|
network: {
|
|
205
217
|
name: networkName,
|
|
218
|
+
fork: config.network.fork,
|
|
206
219
|
saveDeployments,
|
|
207
|
-
tags,
|
|
220
|
+
tags: networkTags,
|
|
208
221
|
},
|
|
209
222
|
};
|
|
210
223
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
224
|
+
// console.log(`context`, JSON.stringify(context.network, null, 2));
|
|
225
|
+
|
|
226
|
+
const {deployments} = loadDeployments(
|
|
227
|
+
config.deployments,
|
|
228
|
+
context.network.name,
|
|
229
|
+
false,
|
|
230
|
+
context.network.fork
|
|
231
|
+
? undefined
|
|
232
|
+
: {
|
|
233
|
+
chainId,
|
|
234
|
+
genesisHash,
|
|
235
|
+
deleteDeploymentsIfDifferentGenesisHash: true,
|
|
236
|
+
}
|
|
237
|
+
);
|
|
216
238
|
|
|
217
239
|
const namedAccounts: {[name: string]: EIP1193Account} = {};
|
|
218
240
|
const namedSigners: {[name: string]: NamedSigner} = {};
|
|
@@ -280,8 +302,35 @@ export async function createEnvironment<
|
|
|
280
302
|
return deployment;
|
|
281
303
|
}
|
|
282
304
|
|
|
283
|
-
function getOrNull<TAbi extends Abi>(name: string): Deployment<TAbi> |
|
|
284
|
-
return deployments[name] as Deployment<TAbi> |
|
|
305
|
+
function getOrNull<TAbi extends Abi>(name: string): Deployment<TAbi> | null {
|
|
306
|
+
return (deployments[name] || null) as Deployment<TAbi> | null;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function fromAddressToNamedABIOrNull<TAbi extends Abi>(address: Address): {mergedABI: TAbi; names: string[]} | null {
|
|
310
|
+
let list: {name: string; artifact: Artifact<Abi>}[] = [];
|
|
311
|
+
for (const name of Object.keys(deployments)) {
|
|
312
|
+
const deployment = deployments[name];
|
|
313
|
+
if (deployment.address.toLowerCase() == address.toLowerCase()) {
|
|
314
|
+
list.push({name, artifact: deployment});
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
if (list.length === 0) {
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const {mergedABI} = mergeArtifacts(list);
|
|
322
|
+
return {
|
|
323
|
+
mergedABI: mergedABI as unknown as TAbi,
|
|
324
|
+
names: list.map((v) => v.name),
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function fromAddressToNamedABI<TAbi extends Abi>(address: Address): {mergedABI: TAbi; names: string[]} {
|
|
329
|
+
const n = fromAddressToNamedABIOrNull<TAbi>(address);
|
|
330
|
+
if (!n) {
|
|
331
|
+
throw new Error(`could not find artifact for address ${address}`);
|
|
332
|
+
}
|
|
333
|
+
return n;
|
|
285
334
|
}
|
|
286
335
|
|
|
287
336
|
async function save<TAbi extends Abi>(name: string, deployment: Deployment<TAbi>): Promise<Deployment<TAbi>> {
|
|
@@ -594,6 +643,8 @@ export async function createEnvironment<
|
|
|
594
643
|
savePendingExecution,
|
|
595
644
|
get,
|
|
596
645
|
getOrNull,
|
|
646
|
+
fromAddressToNamedABI,
|
|
647
|
+
fromAddressToNamedABIOrNull,
|
|
597
648
|
showMessage,
|
|
598
649
|
showProgress,
|
|
599
650
|
};
|
package/src/environment/types.ts
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
EIP1193WalletProvider,
|
|
10
10
|
} from 'eip-1193';
|
|
11
11
|
import {Abi, Narrow, AbiError, AbiEvent, AbiConstructor, AbiFallback, AbiFunction, AbiReceive} from 'abitype';
|
|
12
|
-
import type {DeployContractParameters} from 'viem';
|
|
12
|
+
import type {Address, DeployContractParameters} from 'viem';
|
|
13
13
|
import type {Chain} from 'viem';
|
|
14
14
|
import {ProgressIndicator} from '../internal/logging';
|
|
15
15
|
|
|
@@ -209,30 +209,47 @@ export type Context<
|
|
|
209
209
|
artifacts: Artifacts;
|
|
210
210
|
};
|
|
211
211
|
|
|
212
|
-
type
|
|
213
|
-
|
|
212
|
+
type NetworkConfigBase = {
|
|
213
|
+
name: string;
|
|
214
|
+
tags: string[];
|
|
215
|
+
fork?: boolean;
|
|
216
|
+
};
|
|
217
|
+
type NetworkConfigForJSONRPC = NetworkConfigBase & {
|
|
218
|
+
nodeUrl: string;
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
type NetworkConfigForEIP1193Provider = NetworkConfigBase & {
|
|
222
|
+
provider: EIP1193ProviderWithoutEvents;
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
export type NetworkConfig = NetworkConfigForJSONRPC | NetworkConfigForEIP1193Provider;
|
|
226
|
+
|
|
227
|
+
export type Config = {
|
|
228
|
+
network: NetworkConfig;
|
|
229
|
+
networkTags?: string[];
|
|
214
230
|
scripts?: string;
|
|
215
231
|
deployments?: string;
|
|
232
|
+
saveDeployments?: boolean;
|
|
216
233
|
|
|
217
234
|
tags?: string[];
|
|
235
|
+
|
|
218
236
|
logLevel?: number;
|
|
219
237
|
// TODO
|
|
220
238
|
gasPricing?: {};
|
|
221
239
|
};
|
|
222
240
|
|
|
223
|
-
type
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
241
|
+
export type ResolvedConfig = Config & {
|
|
242
|
+
deployments: string;
|
|
243
|
+
scripts: string;
|
|
244
|
+
tags: string[];
|
|
245
|
+
network: {
|
|
246
|
+
name: string;
|
|
247
|
+
tags: string[];
|
|
248
|
+
fork?: boolean;
|
|
249
|
+
};
|
|
250
|
+
saveDeployments?: boolean;
|
|
230
251
|
};
|
|
231
252
|
|
|
232
|
-
export type Config = ConfigForJSONRPC | ConfigForEIP1193Provider;
|
|
233
|
-
|
|
234
|
-
export type ResolvedConfig = Config & {deployments: string; scripts: string; tags: string[]; networkName: string};
|
|
235
|
-
|
|
236
253
|
export interface Environment<
|
|
237
254
|
Artifacts extends UnknownArtifacts = UnknownArtifacts,
|
|
238
255
|
NamedAccounts extends UnresolvedUnknownNamedAccounts = UnresolvedUnknownNamedAccounts,
|
|
@@ -254,7 +271,9 @@ export interface Environment<
|
|
|
254
271
|
savePendingDeployment<TAbi extends Abi = Abi>(pendingDeployment: PendingDeployment<TAbi>): Promise<Deployment<TAbi>>;
|
|
255
272
|
savePendingExecution(pendingExecution: PendingExecution): Promise<EIP1193TransactionReceipt>;
|
|
256
273
|
get<TAbi extends Abi>(name: string): Deployment<TAbi>;
|
|
257
|
-
getOrNull<TAbi extends Abi>(name: string): Deployment<TAbi> |
|
|
274
|
+
getOrNull<TAbi extends Abi>(name: string): Deployment<TAbi> | null;
|
|
275
|
+
fromAddressToNamedABI<TAbi extends Abi>(address: Address): {mergedABI: TAbi; names: string[]};
|
|
276
|
+
fromAddressToNamedABIOrNull<TAbi extends Abi>(address: Address): {mergedABI: TAbi; names: string[]} | null;
|
|
258
277
|
showMessage(message: string): void;
|
|
259
278
|
showProgress(message?: string): ProgressIndicator;
|
|
260
279
|
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import {Abi} from 'abitype';
|
|
2
|
+
import {Artifact, DevDoc, UserDoc} from '../types';
|
|
3
|
+
import {FunctionFragment} from 'ethers';
|
|
4
|
+
|
|
5
|
+
type CreateMutable<Type> = {
|
|
6
|
+
-readonly [Property in keyof Type]: Type[Property];
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
type ArrayElement<ArrayType extends readonly unknown[]> = ArrayType extends readonly (infer ElementType)[]
|
|
10
|
+
? ElementType
|
|
11
|
+
: never;
|
|
12
|
+
|
|
13
|
+
// from https://gist.github.com/egardner/efd34f270cc33db67c0246e837689cb9
|
|
14
|
+
function deepEqual(obj1: any, obj2: any): boolean {
|
|
15
|
+
// Private
|
|
16
|
+
function isObject(obj: any) {
|
|
17
|
+
if (typeof obj === 'object' && obj != null) {
|
|
18
|
+
return true;
|
|
19
|
+
} else {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (obj1 === obj2) {
|
|
25
|
+
return true;
|
|
26
|
+
} else if (isObject(obj1) && isObject(obj2)) {
|
|
27
|
+
if (Object.keys(obj1).length !== Object.keys(obj2).length) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
for (var prop in obj1) {
|
|
31
|
+
if (!deepEqual(obj1[prop], obj2[prop])) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function mergeDoc(values: any, mergedDevDocs: any, field: string) {
|
|
41
|
+
if (values[field]) {
|
|
42
|
+
const mergedEventDocs = (mergedDevDocs[field] = mergedDevDocs[field] || {});
|
|
43
|
+
for (const signature of Object.keys(values[field])) {
|
|
44
|
+
if (mergedEventDocs[signature] && !deepEqual(mergedEventDocs[signature], values[field][signature])) {
|
|
45
|
+
throw new Error(`Doc ${field} conflict: "${signature}" `);
|
|
46
|
+
}
|
|
47
|
+
mergedEventDocs[signature] = values[field][signature];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function mergeArtifacts(list: {name: string; artifact: Artifact<Abi>}[]) {
|
|
53
|
+
const mergedABI: CreateMutable<Abi> = [];
|
|
54
|
+
const added: Map<string, ArrayElement<Abi>> = new Map();
|
|
55
|
+
const mergedDevDocs: CreateMutable<DevDoc> = {kind: 'dev', version: 1, methods: {}};
|
|
56
|
+
const mergedUserDocs: CreateMutable<UserDoc> = {kind: 'user', version: 1, methods: {}};
|
|
57
|
+
const sigJSMap: Map<`0x${string}`, {index: number; routeName: string; functionName: string}> = new Map();
|
|
58
|
+
|
|
59
|
+
for (let i = 0; i < list.length; i++) {
|
|
60
|
+
const listElem = list[i];
|
|
61
|
+
for (const element of listElem.artifact.abi) {
|
|
62
|
+
if (element.type === 'function') {
|
|
63
|
+
// const selector = getFunctionSelector(element);
|
|
64
|
+
const selector = FunctionFragment.from(element).selector as `0x${string}`;
|
|
65
|
+
if (sigJSMap.has(selector)) {
|
|
66
|
+
const existing = sigJSMap.get(selector);
|
|
67
|
+
throw new Error(
|
|
68
|
+
`ABI conflict: ${existing!.routeName} has function "${existing!.functionName}" which conflict with ${
|
|
69
|
+
listElem.name
|
|
70
|
+
}'s "${element.name}" (selector: "${selector}") `
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
sigJSMap.set(selector, {index: i, routeName: listElem.name, functionName: element.name});
|
|
74
|
+
|
|
75
|
+
const exists = added.has(element.name);
|
|
76
|
+
if (exists) {
|
|
77
|
+
// TODO check if same
|
|
78
|
+
} else {
|
|
79
|
+
added.set(element.name, element);
|
|
80
|
+
mergedABI.push(element);
|
|
81
|
+
}
|
|
82
|
+
} else if (element.type === 'constructor') {
|
|
83
|
+
// we skip it
|
|
84
|
+
} else if (element.type === 'error') {
|
|
85
|
+
const exists = added.has(element.name);
|
|
86
|
+
if (exists) {
|
|
87
|
+
// TODO check if same
|
|
88
|
+
} else {
|
|
89
|
+
added.set(element.name, element);
|
|
90
|
+
mergedABI.push(element);
|
|
91
|
+
}
|
|
92
|
+
} else if (element.type === 'event') {
|
|
93
|
+
const exists = added.has(element.name);
|
|
94
|
+
if (exists) {
|
|
95
|
+
// TODO check if same
|
|
96
|
+
} else {
|
|
97
|
+
added.set(element.name, element);
|
|
98
|
+
mergedABI.push(element);
|
|
99
|
+
}
|
|
100
|
+
} else if (element.type === 'fallback') {
|
|
101
|
+
} else if (element.type === 'receive') {
|
|
102
|
+
} else {
|
|
103
|
+
// if ('name' in element) {
|
|
104
|
+
// const exists = added.has(element.name);
|
|
105
|
+
// if (exists) {
|
|
106
|
+
// // TODO check if same
|
|
107
|
+
// } else {
|
|
108
|
+
// added.set(element.name, element);
|
|
109
|
+
// mergedABI.push(element);
|
|
110
|
+
// }
|
|
111
|
+
// }
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const devdoc = listElem.artifact.devdoc;
|
|
115
|
+
if (devdoc) {
|
|
116
|
+
mergeDoc(devdoc, mergedDevDocs, 'events');
|
|
117
|
+
mergeDoc(devdoc, mergedDevDocs, 'errors');
|
|
118
|
+
mergeDoc(devdoc, mergedDevDocs, 'methods');
|
|
119
|
+
if (devdoc.author) {
|
|
120
|
+
if (mergedDevDocs.author && mergedDevDocs.author != devdoc.author) {
|
|
121
|
+
throw new Error(`DevDoc author conflict `);
|
|
122
|
+
}
|
|
123
|
+
mergedDevDocs.author = devdoc.author;
|
|
124
|
+
if (mergedDevDocs.title && mergedDevDocs.title != devdoc.title) {
|
|
125
|
+
throw new Error(`DevDoc title conflict `);
|
|
126
|
+
}
|
|
127
|
+
mergedDevDocs.title = devdoc.title;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const userdoc = listElem.artifact.userdoc;
|
|
132
|
+
if (userdoc) {
|
|
133
|
+
mergeDoc(userdoc, mergedUserDocs, 'events');
|
|
134
|
+
mergeDoc(userdoc, mergedUserDocs, 'errors');
|
|
135
|
+
mergeDoc(userdoc, mergedUserDocs, 'methods');
|
|
136
|
+
if (userdoc.notice) {
|
|
137
|
+
if (mergedUserDocs.notice && mergedUserDocs.notice != userdoc.notice) {
|
|
138
|
+
throw new Error(`UserDoc notice conflict `);
|
|
139
|
+
}
|
|
140
|
+
mergedUserDocs.notice = userdoc.notice;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
mergedABI,
|
|
146
|
+
added,
|
|
147
|
+
mergedDevDocs,
|
|
148
|
+
mergedUserDocs,
|
|
149
|
+
sigJSMap,
|
|
150
|
+
};
|
|
151
|
+
}
|