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/dist/cli.cjs CHANGED
@@ -95,9 +95,9 @@ function stringToJSON(str) {
95
95
  // src/environment/deployments.ts
96
96
  var import_node_path2 = __toESM(require("path"), 1);
97
97
  var import_node_fs2 = __toESM(require("fs"), 1);
98
- function loadDeployments(deploymentsPath, subPath, onlyABIAndAddress, expectedChain) {
98
+ function loadDeployments(deploymentsPath, networkName, onlyABIAndAddress, expectedChain) {
99
99
  const deploymentsFound = {};
100
- const deployPath = import_node_path2.default.join(deploymentsPath, subPath);
100
+ const deployPath = import_node_path2.default.join(deploymentsPath, networkName);
101
101
  let filesStats;
102
102
  try {
103
103
  filesStats = traverse(deployPath, void 0, void 0, (name) => !name.startsWith(".") && name !== "solcInputs");
@@ -119,7 +119,7 @@ function loadDeployments(deploymentsPath, subPath, onlyABIAndAddress, expectedCh
119
119
  genesisHash = chainData.genesisHash;
120
120
  } else {
121
121
  throw new Error(
122
- `A '.chain' or '.chainId' file is expected to be present in the deployment folder for network ${subPath}`
122
+ `A '.chain' or '.chainId' file is expected to be present in the deployment folder for network ${networkName}`
123
123
  );
124
124
  }
125
125
  }
@@ -266,6 +266,124 @@ function getChain(id) {
266
266
  return chain;
267
267
  }
268
268
 
269
+ // src/environment/utils/artifacts.ts
270
+ var import_ethers = require("ethers");
271
+ function deepEqual(obj1, obj2) {
272
+ function isObject(obj) {
273
+ if (typeof obj === "object" && obj != null) {
274
+ return true;
275
+ } else {
276
+ return false;
277
+ }
278
+ }
279
+ if (obj1 === obj2) {
280
+ return true;
281
+ } else if (isObject(obj1) && isObject(obj2)) {
282
+ if (Object.keys(obj1).length !== Object.keys(obj2).length) {
283
+ return false;
284
+ }
285
+ for (var prop in obj1) {
286
+ if (!deepEqual(obj1[prop], obj2[prop])) {
287
+ return false;
288
+ }
289
+ }
290
+ return true;
291
+ }
292
+ return false;
293
+ }
294
+ function mergeDoc(values, mergedDevDocs, field) {
295
+ if (values[field]) {
296
+ const mergedEventDocs = mergedDevDocs[field] = mergedDevDocs[field] || {};
297
+ for (const signature of Object.keys(values[field])) {
298
+ if (mergedEventDocs[signature] && !deepEqual(mergedEventDocs[signature], values[field][signature])) {
299
+ throw new Error(`Doc ${field} conflict: "${signature}" `);
300
+ }
301
+ mergedEventDocs[signature] = values[field][signature];
302
+ }
303
+ }
304
+ }
305
+ function mergeArtifacts(list) {
306
+ const mergedABI = [];
307
+ const added = /* @__PURE__ */ new Map();
308
+ const mergedDevDocs = { kind: "dev", version: 1, methods: {} };
309
+ const mergedUserDocs = { kind: "user", version: 1, methods: {} };
310
+ const sigJSMap = /* @__PURE__ */ new Map();
311
+ for (let i = 0; i < list.length; i++) {
312
+ const listElem = list[i];
313
+ for (const element of listElem.artifact.abi) {
314
+ if (element.type === "function") {
315
+ const selector = import_ethers.FunctionFragment.from(element).selector;
316
+ if (sigJSMap.has(selector)) {
317
+ const existing = sigJSMap.get(selector);
318
+ throw new Error(
319
+ `ABI conflict: ${existing.routeName} has function "${existing.functionName}" which conflict with ${listElem.name}'s "${element.name}" (selector: "${selector}") `
320
+ );
321
+ }
322
+ sigJSMap.set(selector, { index: i, routeName: listElem.name, functionName: element.name });
323
+ const exists = added.has(element.name);
324
+ if (exists) {
325
+ } else {
326
+ added.set(element.name, element);
327
+ mergedABI.push(element);
328
+ }
329
+ } else if (element.type === "constructor") {
330
+ } else if (element.type === "error") {
331
+ const exists = added.has(element.name);
332
+ if (exists) {
333
+ } else {
334
+ added.set(element.name, element);
335
+ mergedABI.push(element);
336
+ }
337
+ } else if (element.type === "event") {
338
+ const exists = added.has(element.name);
339
+ if (exists) {
340
+ } else {
341
+ added.set(element.name, element);
342
+ mergedABI.push(element);
343
+ }
344
+ } else if (element.type === "fallback") {
345
+ } else if (element.type === "receive") {
346
+ } else {
347
+ }
348
+ }
349
+ const devdoc = listElem.artifact.devdoc;
350
+ if (devdoc) {
351
+ mergeDoc(devdoc, mergedDevDocs, "events");
352
+ mergeDoc(devdoc, mergedDevDocs, "errors");
353
+ mergeDoc(devdoc, mergedDevDocs, "methods");
354
+ if (devdoc.author) {
355
+ if (mergedDevDocs.author && mergedDevDocs.author != devdoc.author) {
356
+ throw new Error(`DevDoc author conflict `);
357
+ }
358
+ mergedDevDocs.author = devdoc.author;
359
+ if (mergedDevDocs.title && mergedDevDocs.title != devdoc.title) {
360
+ throw new Error(`DevDoc title conflict `);
361
+ }
362
+ mergedDevDocs.title = devdoc.title;
363
+ }
364
+ }
365
+ const userdoc = listElem.artifact.userdoc;
366
+ if (userdoc) {
367
+ mergeDoc(userdoc, mergedUserDocs, "events");
368
+ mergeDoc(userdoc, mergedUserDocs, "errors");
369
+ mergeDoc(userdoc, mergedUserDocs, "methods");
370
+ if (userdoc.notice) {
371
+ if (mergedUserDocs.notice && mergedUserDocs.notice != userdoc.notice) {
372
+ throw new Error(`UserDoc notice conflict `);
373
+ }
374
+ mergedUserDocs.notice = userdoc.notice;
375
+ }
376
+ }
377
+ }
378
+ return {
379
+ mergedABI,
380
+ added,
381
+ mergedDevDocs,
382
+ mergedUserDocs,
383
+ sigJSMap
384
+ };
385
+ }
386
+
269
387
  // src/environment/index.ts
270
388
  globalThis.extensions = [];
271
389
  globalThis.signerProtocols = {};
@@ -283,8 +401,8 @@ function displayTransaction(transaction) {
283
401
  return `(gasPrice: ${BigInt(transaction.gasPrice).toString()})`;
284
402
  }
285
403
  }
286
- async function createEnvironment(config2, providedContext) {
287
- const provider = "provider" in config2 ? config2.provider : new import_eip_1193_jsonrpc_provider.JSONRPCHTTPProvider(config2.nodeUrl);
404
+ async function createEnvironment(config, providedContext) {
405
+ const provider = "provider" in config.network ? config.network.provider : new import_eip_1193_jsonrpc_provider.JSONRPCHTTPProvider(config.network.nodeUrl);
288
406
  const transport = (0, import_viem.custom)(provider);
289
407
  const viemClient = (0, import_viem.createPublicClient)({ transport });
290
408
  const chainId = (await viemClient.getChainId()).toString();
@@ -296,23 +414,29 @@ async function createEnvironment(config2, providedContext) {
296
414
  }
297
415
  let networkName;
298
416
  let saveDeployments;
299
- let tags = {};
300
- if ("nodeUrl" in config2) {
301
- networkName = config2.networkName;
417
+ let networkTags = {};
418
+ for (const networkTag of config.network.tags) {
419
+ networkTags[networkTag] = true;
420
+ }
421
+ if ("nodeUrl" in config) {
422
+ networkName = config.network.name;
302
423
  saveDeployments = true;
303
424
  } else {
304
- if (config2.networkName) {
305
- networkName = config2.networkName;
425
+ if (config.network.name) {
426
+ networkName = config.network.name;
306
427
  } else {
307
428
  networkName = "memory";
308
429
  }
309
430
  if (networkName === "memory" || networkName === "hardhat") {
310
- tags["memory"] = true;
431
+ networkTags["memory"] = true;
311
432
  saveDeployments = false;
312
433
  } else {
313
434
  saveDeployments = true;
314
435
  }
315
436
  }
437
+ if (config.saveDeployments !== void 0) {
438
+ saveDeployments = config.saveDeployments;
439
+ }
316
440
  const resolvedAccounts = {};
317
441
  const accountCache = {};
318
442
  async function getAccount(name, accounts, accountDef) {
@@ -392,15 +516,21 @@ async function createEnvironment(config2, providedContext) {
392
516
  artifacts: providedContext.artifacts,
393
517
  network: {
394
518
  name: networkName,
519
+ fork: config.network.fork,
395
520
  saveDeployments,
396
- tags
521
+ tags: networkTags
397
522
  }
398
523
  };
399
- const { deployments } = loadDeployments(config2.deployments, context.network.name, false, {
400
- chainId,
401
- genesisHash,
402
- deleteDeploymentsIfDifferentGenesisHash: true
403
- });
524
+ const { deployments } = loadDeployments(
525
+ config.deployments,
526
+ context.network.name,
527
+ false,
528
+ context.network.fork ? void 0 : {
529
+ chainId,
530
+ genesisHash,
531
+ deleteDeploymentsIfDifferentGenesisHash: true
532
+ }
533
+ );
404
534
  const namedAccounts = {};
405
535
  const namedSigners = {};
406
536
  const addressSigners = {};
@@ -412,7 +542,7 @@ async function createEnvironment(config2, providedContext) {
412
542
  namedSigners[name] = namedSigner;
413
543
  }
414
544
  const perliminaryEnvironment = {
415
- config: config2,
545
+ config,
416
546
  deployments,
417
547
  accounts: namedAccounts,
418
548
  signers: namedSigners,
@@ -426,7 +556,7 @@ async function createEnvironment(config2, providedContext) {
426
556
  }
427
557
  };
428
558
  function ensureDeploymentFolder() {
429
- const folderPath = import_node_path3.default.join(config2.deployments, context.network.name);
559
+ const folderPath = import_node_path3.default.join(config.deployments, context.network.name);
430
560
  import_node_fs3.default.mkdirSync(folderPath, { recursive: true });
431
561
  const chainFilepath = import_node_path3.default.join(folderPath, ".chain");
432
562
  if (!import_node_fs3.default.existsSync(chainFilepath)) {
@@ -442,7 +572,31 @@ async function createEnvironment(config2, providedContext) {
442
572
  return deployment;
443
573
  }
444
574
  function getOrNull(name) {
445
- return deployments[name];
575
+ return deployments[name] || null;
576
+ }
577
+ function fromAddressToNamedABIOrNull(address) {
578
+ let list = [];
579
+ for (const name of Object.keys(deployments)) {
580
+ const deployment = deployments[name];
581
+ if (deployment.address.toLowerCase() == address.toLowerCase()) {
582
+ list.push({ name, artifact: deployment });
583
+ }
584
+ }
585
+ if (list.length === 0) {
586
+ return null;
587
+ }
588
+ const { mergedABI } = mergeArtifacts(list);
589
+ return {
590
+ mergedABI,
591
+ names: list.map((v) => v.name)
592
+ };
593
+ }
594
+ function fromAddressToNamedABI(address) {
595
+ const n = fromAddressToNamedABIOrNull(address);
596
+ if (!n) {
597
+ throw new Error(`could not find artifact for address ${address}`);
598
+ }
599
+ return n;
446
600
  }
447
601
  async function save(name, deployment) {
448
602
  deployments[name] = deployment;
@@ -711,6 +865,8 @@ async function createEnvironment(config2, providedContext) {
711
865
  savePendingExecution,
712
866
  get,
713
867
  getOrNull,
868
+ fromAddressToNamedABI,
869
+ fromAddressToNamedABIOrNull,
714
870
  showMessage,
715
871
  showProgress
716
872
  };
@@ -730,24 +886,55 @@ async function createEnvironment(config2, providedContext) {
730
886
  if (!process.env["ROCKETH_SKIP_ESBUILD"]) {
731
887
  require("esbuild-register/dist/node").register();
732
888
  }
733
- function readConfig(options2, extra) {
889
+ function readConfig(options2) {
734
890
  let configFile;
735
891
  try {
736
892
  const configString = import_node_fs4.default.readFileSync("./rocketh.json", "utf-8");
737
893
  configFile = JSON.parse(configString);
738
894
  } catch {
739
895
  }
740
- let nodeUrl;
896
+ if (configFile) {
897
+ if (!options2.deployments && configFile.deployments) {
898
+ options2.deployments = configFile.deployments;
899
+ }
900
+ if (!options2.scripts && configFile.scripts) {
901
+ options2.scripts = configFile.scripts;
902
+ }
903
+ }
741
904
  const fromEnv = process.env["ETH_NODE_URI_" + options2.network];
742
- if (typeof fromEnv === "string") {
743
- nodeUrl = fromEnv;
744
- } else {
745
- if (configFile) {
746
- const network = configFile.networks && configFile.networks[options2.network];
747
- if (network) {
748
- nodeUrl = network.rpcUrl;
905
+ const fork = typeof options2.network !== "string";
906
+ let networkName = "memory";
907
+ if (options2.network) {
908
+ if (typeof options2.network === "string") {
909
+ networkName = options2.network;
910
+ } else if ("fork" in options2.network) {
911
+ networkName = options2.network.fork;
912
+ }
913
+ }
914
+ let networkTags = configFile?.networks && configFile?.networks[networkName]?.tags || [];
915
+ if (!options2.provider) {
916
+ let nodeUrl;
917
+ if (typeof fromEnv === "string") {
918
+ nodeUrl = fromEnv;
919
+ } else {
920
+ if (configFile) {
921
+ const network = configFile.networks && configFile.networks[networkName];
922
+ if (network && network.rpcUrl) {
923
+ nodeUrl = network.rpcUrl;
924
+ } else {
925
+ if (options2?.ignoreMissingRPC) {
926
+ nodeUrl = "";
927
+ } else {
928
+ if (options2.network === "localhost") {
929
+ nodeUrl = "http://127.0.0.1:8545";
930
+ } else {
931
+ logger.error(`network "${options2.network}" is not configured. Please add it to the rocketh.json file`);
932
+ process.exit(1);
933
+ }
934
+ }
935
+ }
749
936
  } else {
750
- if (extra?.ignoreMissingRPC) {
937
+ if (options2?.ignoreMissingRPC) {
751
938
  nodeUrl = "";
752
939
  } else {
753
940
  if (options2.network === "localhost") {
@@ -758,45 +945,60 @@ function readConfig(options2, extra) {
758
945
  }
759
946
  }
760
947
  }
761
- } else {
762
- if (extra?.ignoreMissingRPC) {
763
- nodeUrl = "";
764
- } else {
765
- if (options2.network === "localhost") {
766
- nodeUrl = "http://127.0.0.1:8545";
767
- } else {
768
- logger.error(`network "${options2.network}" is not configured. Please add it to the rocketh.json file`);
769
- process.exit(1);
770
- }
771
- }
772
948
  }
949
+ return {
950
+ network: {
951
+ nodeUrl,
952
+ name: networkName,
953
+ tags: networkTags,
954
+ fork
955
+ },
956
+ deployments: options2.deployments,
957
+ saveDeployments: options2.saveDeployments,
958
+ scripts: options2.scripts,
959
+ tags: typeof options2.tags === "undefined" ? void 0 : options2.tags.split(","),
960
+ logLevel: options2.logLevel
961
+ };
962
+ } else {
963
+ return {
964
+ network: {
965
+ provider: options2.provider,
966
+ name: networkName,
967
+ tags: networkTags,
968
+ fork
969
+ },
970
+ deployments: options2.deployments,
971
+ saveDeployments: options2.saveDeployments,
972
+ scripts: options2.scripts,
973
+ tags: typeof options2.tags === "undefined" ? void 0 : options2.tags.split(","),
974
+ logLevel: options2.logLevel
975
+ };
773
976
  }
774
- return {
775
- nodeUrl,
776
- networkName: options2.network,
777
- deployments: options2.deployments,
778
- scripts: options2.scripts,
779
- tags: typeof options2.tags === "undefined" ? void 0 : options2.tags.split(",")
780
- };
781
977
  }
782
- function resolveConfig(config2) {
978
+ function readAndResolveConfig(options2) {
979
+ return resolveConfig(readConfig(options2));
980
+ }
981
+ function resolveConfig(config) {
783
982
  const resolvedConfig = {
784
- ...config2,
785
- networkName: config2.networkName || "memory",
786
- deployments: config2.deployments || "deployments",
787
- scripts: config2.scripts || "deploy",
788
- tags: config2.tags || []
983
+ ...config,
984
+ network: config.network,
985
+ // TODO default to || {name: 'memory'....}
986
+ deployments: config.deployments || "deployments",
987
+ scripts: config.scripts || "deploy",
988
+ tags: config.tags || [],
989
+ networkTags: config.networkTags || [],
990
+ saveDeployments: config.saveDeployments
789
991
  };
790
992
  return resolvedConfig;
791
993
  }
792
- async function loadAndExecuteDeployments(config2, args) {
793
- const resolvedConfig = resolveConfig(config2);
994
+ async function loadAndExecuteDeployments(options2, args) {
995
+ const resolvedConfig = readAndResolveConfig(options2);
794
996
  return executeDeployScripts(resolvedConfig, args);
795
997
  }
796
- async function executeDeployScripts(config2, args) {
797
- setLogLevel(typeof config2.logLevel === "undefined" ? 0 : config2.logLevel);
998
+ async function executeDeployScripts(config, args) {
999
+ setLogLevel(typeof config.logLevel === "undefined" ? 0 : config.logLevel);
798
1000
  let filepaths;
799
- filepaths = traverseMultipleDirectory([config2.scripts]);
1001
+ filepaths = traverseMultipleDirectory([config.scripts]);
800
1002
  filepaths = filepaths.filter((v) => !import_node_path4.default.basename(v).startsWith("_")).sort((a, b) => {
801
1003
  if (a < b) {
802
1004
  return -1;
@@ -848,10 +1050,10 @@ async function executeDeployScripts(config2, args) {
848
1050
  bag.push(scriptFilePath);
849
1051
  }
850
1052
  }
851
- if (config2.tags !== void 0 && config2.tags.length > 0) {
1053
+ if (config.tags !== void 0 && config.tags.length > 0) {
852
1054
  let found = false;
853
1055
  if (scriptTags !== void 0) {
854
- for (const tagToFind of config2.tags) {
1056
+ for (const tagToFind of config.tags) {
855
1057
  for (const tag of scriptTags) {
856
1058
  if (tag === tagToFind) {
857
1059
  scriptFilePaths.push(scriptFilePath);
@@ -871,7 +1073,7 @@ async function executeDeployScripts(config2, args) {
871
1073
  if (!providedContext) {
872
1074
  throw new Error(`no context loaded`);
873
1075
  }
874
- const { internal, external } = await createEnvironment(config2, providedContext);
1076
+ const { internal, external } = await createEnvironment(config, providedContext);
875
1077
  await internal.recoverTransactionsIfAny();
876
1078
  const scriptsRegisteredToRun = {};
877
1079
  const scriptsToRun = [];
@@ -935,7 +1137,7 @@ async function executeDeployScripts(config2, args) {
935
1137
  throw e;
936
1138
  }
937
1139
  if (result && typeof result === "boolean") {
938
- const deploymentFolderPath = config2.deployments;
1140
+ const deploymentFolderPath = config.deployments;
939
1141
  }
940
1142
  }
941
1143
  }
@@ -948,7 +1150,7 @@ var import_commander = require("commander");
948
1150
  // package.json
949
1151
  var package_default = {
950
1152
  name: "rocketh",
951
- version: "0.9.0",
1153
+ version: "0.10.0",
952
1154
  description: "deploy smart contract on ethereum-compatible networks",
953
1155
  publishConfig: {
954
1156
  access: "public"
@@ -976,6 +1178,7 @@ var package_default = {
976
1178
  "eip-1193-jsonrpc-provider": "^0.3.0",
977
1179
  esbuild: "^0.20.1",
978
1180
  "esbuild-register": "^3.5.0",
1181
+ ethers: "^6.11.1",
979
1182
  figlet: "^1.7.0",
980
1183
  ldenv: "^0.3.9",
981
1184
  "named-logs": "^0.2.2",
@@ -997,6 +1200,5 @@ var commandName = package_default.name;
997
1200
  var program = new import_commander.Command();
998
1201
  program.name(commandName).version(package_default.version).usage(`${commandName}`).description("execute deploy scripts and store the deployments").option("-s, --scripts <value>", "path the folder containing the deploy scripts to execute").option("-t, --tags <value>", "comma separated list of tags to execute").option("-d, --deployments <value>", "folder where deployments are saved").requiredOption("-n, --network <value>", "network context to use").parse(process.argv);
999
1202
  var options = program.opts();
1000
- var config = readConfig(options);
1001
- loadAndExecuteDeployments({ ...config, logLevel: 1 });
1203
+ loadAndExecuteDeployments({ ...options, logLevel: 1 });
1002
1204
  //# sourceMappingURL=cli.cjs.map