rocketh 0.9.2 → 0.10.1
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-34ZUTWTW.js → chunk-M4UAFNSM.js} +196 -52
- package/dist/chunk-M4UAFNSM.js.map +1 -0
- package/dist/cli.cjs +214 -66
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +7 -7
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +195 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +39 -23
- package/dist/index.d.ts +39 -23
- package/dist/index.js +1 -1
- package/package.json +4 -2
- package/src/cli.ts +2 -3
- package/src/environment/deployments.ts +3 -3
- package/src/environment/index.ts +32 -12
- package/src/environment/types.ts +32 -13
- package/src/executor/index.ts +124 -39
- package/src/utils/eth.ts +103 -0
- package/dist/chunk-34ZUTWTW.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -115,9 +115,9 @@ function stringToJSON(str) {
|
|
|
115
115
|
// src/environment/deployments.ts
|
|
116
116
|
var import_node_path2 = __toESM(require("path"), 1);
|
|
117
117
|
var import_node_fs2 = __toESM(require("fs"), 1);
|
|
118
|
-
function loadDeployments(deploymentsPath,
|
|
118
|
+
function loadDeployments(deploymentsPath, networkName, onlyABIAndAddress, expectedChain) {
|
|
119
119
|
const deploymentsFound = {};
|
|
120
|
-
const deployPath = import_node_path2.default.join(deploymentsPath,
|
|
120
|
+
const deployPath = import_node_path2.default.join(deploymentsPath, networkName);
|
|
121
121
|
let filesStats;
|
|
122
122
|
try {
|
|
123
123
|
filesStats = traverse(deployPath, void 0, void 0, (name) => !name.startsWith(".") && name !== "solcInputs");
|
|
@@ -139,7 +139,7 @@ function loadDeployments(deploymentsPath, subPath, onlyABIAndAddress, expectedCh
|
|
|
139
139
|
genesisHash = chainData.genesisHash;
|
|
140
140
|
} else {
|
|
141
141
|
throw new Error(
|
|
142
|
-
`A '.chain' or '.chainId' file is expected to be present in the deployment folder for network ${
|
|
142
|
+
`A '.chain' or '.chainId' file is expected to be present in the deployment folder for network ${networkName}`
|
|
143
143
|
);
|
|
144
144
|
}
|
|
145
145
|
}
|
|
@@ -430,7 +430,7 @@ function displayTransaction(transaction) {
|
|
|
430
430
|
}
|
|
431
431
|
}
|
|
432
432
|
async function createEnvironment(config, providedContext) {
|
|
433
|
-
const provider = "provider" in config ? config.provider : new import_eip_1193_jsonrpc_provider.JSONRPCHTTPProvider(config.nodeUrl);
|
|
433
|
+
const provider = "provider" in config.network ? config.network.provider : new import_eip_1193_jsonrpc_provider.JSONRPCHTTPProvider(config.network.nodeUrl);
|
|
434
434
|
const transport = (0, import_viem.custom)(provider);
|
|
435
435
|
const viemClient = (0, import_viem.createPublicClient)({ transport });
|
|
436
436
|
const chainId = (await viemClient.getChainId()).toString();
|
|
@@ -442,23 +442,29 @@ async function createEnvironment(config, providedContext) {
|
|
|
442
442
|
}
|
|
443
443
|
let networkName;
|
|
444
444
|
let saveDeployments;
|
|
445
|
-
let
|
|
445
|
+
let networkTags = {};
|
|
446
|
+
for (const networkTag of config.network.tags) {
|
|
447
|
+
networkTags[networkTag] = true;
|
|
448
|
+
}
|
|
446
449
|
if ("nodeUrl" in config) {
|
|
447
|
-
networkName = config.
|
|
450
|
+
networkName = config.network.name;
|
|
448
451
|
saveDeployments = true;
|
|
449
452
|
} else {
|
|
450
|
-
if (config.
|
|
451
|
-
networkName = config.
|
|
453
|
+
if (config.network.name) {
|
|
454
|
+
networkName = config.network.name;
|
|
452
455
|
} else {
|
|
453
456
|
networkName = "memory";
|
|
454
457
|
}
|
|
455
458
|
if (networkName === "memory" || networkName === "hardhat") {
|
|
456
|
-
|
|
459
|
+
networkTags["memory"] = true;
|
|
457
460
|
saveDeployments = false;
|
|
458
461
|
} else {
|
|
459
462
|
saveDeployments = true;
|
|
460
463
|
}
|
|
461
464
|
}
|
|
465
|
+
if (config.saveDeployments !== void 0) {
|
|
466
|
+
saveDeployments = config.saveDeployments;
|
|
467
|
+
}
|
|
462
468
|
const resolvedAccounts = {};
|
|
463
469
|
const accountCache = {};
|
|
464
470
|
async function getAccount(name, accounts, accountDef) {
|
|
@@ -538,15 +544,21 @@ async function createEnvironment(config, providedContext) {
|
|
|
538
544
|
artifacts: providedContext.artifacts,
|
|
539
545
|
network: {
|
|
540
546
|
name: networkName,
|
|
547
|
+
fork: config.network.fork,
|
|
541
548
|
saveDeployments,
|
|
542
|
-
tags
|
|
549
|
+
tags: networkTags
|
|
543
550
|
}
|
|
544
551
|
};
|
|
545
|
-
const { deployments } = loadDeployments(
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
552
|
+
const { deployments } = loadDeployments(
|
|
553
|
+
config.deployments,
|
|
554
|
+
context.network.name,
|
|
555
|
+
false,
|
|
556
|
+
context.network.fork ? void 0 : {
|
|
557
|
+
chainId,
|
|
558
|
+
genesisHash,
|
|
559
|
+
deleteDeploymentsIfDifferentGenesisHash: true
|
|
560
|
+
}
|
|
561
|
+
);
|
|
550
562
|
const namedAccounts = {};
|
|
551
563
|
const namedSigners = {};
|
|
552
564
|
const addressSigners = {};
|
|
@@ -898,7 +910,72 @@ async function createEnvironment(config, providedContext) {
|
|
|
898
910
|
};
|
|
899
911
|
}
|
|
900
912
|
|
|
913
|
+
// src/utils/eth.ts
|
|
914
|
+
function avg(arr) {
|
|
915
|
+
const sum = arr.reduce((a, v) => a + v);
|
|
916
|
+
return sum / BigInt(arr.length);
|
|
917
|
+
}
|
|
918
|
+
async function getGasPriceEstimate(provider, options) {
|
|
919
|
+
const defaultOptions = {
|
|
920
|
+
blockCount: 20,
|
|
921
|
+
newestBlock: "pending",
|
|
922
|
+
rewardPercentiles: [10, 50, 80]
|
|
923
|
+
};
|
|
924
|
+
const optionsResolved = options ? { ...defaultOptions, ...options } : defaultOptions;
|
|
925
|
+
const historicalBlocks = optionsResolved.blockCount;
|
|
926
|
+
const rawFeeHistory = await provider.request({
|
|
927
|
+
method: "eth_feeHistory",
|
|
928
|
+
params: [`0x${historicalBlocks.toString(16)}`, optionsResolved.newestBlock, optionsResolved.rewardPercentiles]
|
|
929
|
+
});
|
|
930
|
+
let blockNum = Number(rawFeeHistory.oldestBlock);
|
|
931
|
+
const lastBlock = blockNum + rawFeeHistory.reward.length;
|
|
932
|
+
let index = 0;
|
|
933
|
+
const blocksHistory = [];
|
|
934
|
+
while (blockNum < lastBlock) {
|
|
935
|
+
blocksHistory.push({
|
|
936
|
+
number: blockNum,
|
|
937
|
+
baseFeePerGas: BigInt(rawFeeHistory.baseFeePerGas[index]),
|
|
938
|
+
gasUsedRatio: Number(rawFeeHistory.gasUsedRatio[index]),
|
|
939
|
+
priorityFeePerGas: rawFeeHistory.reward[index].map((x) => BigInt(x))
|
|
940
|
+
});
|
|
941
|
+
blockNum += 1;
|
|
942
|
+
index += 1;
|
|
943
|
+
}
|
|
944
|
+
const percentilePriorityFeeAverages = [];
|
|
945
|
+
for (let i = 0; i < optionsResolved.rewardPercentiles.length; i++) {
|
|
946
|
+
percentilePriorityFeeAverages.push(avg(blocksHistory.map((b) => b.priorityFeePerGas[i])));
|
|
947
|
+
}
|
|
948
|
+
const baseFeePerGas = BigInt(rawFeeHistory.baseFeePerGas[rawFeeHistory.baseFeePerGas.length - 1]);
|
|
949
|
+
const result = [];
|
|
950
|
+
for (let i = 0; i < optionsResolved.rewardPercentiles.length; i++) {
|
|
951
|
+
result.push({
|
|
952
|
+
maxFeePerGas: percentilePriorityFeeAverages[i] + baseFeePerGas,
|
|
953
|
+
maxPriorityFeePerGas: percentilePriorityFeeAverages[i]
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
return result;
|
|
957
|
+
}
|
|
958
|
+
async function getRoughGasPriceEstimate(provider, options) {
|
|
959
|
+
const defaultOptions = {
|
|
960
|
+
blockCount: 20,
|
|
961
|
+
newestBlock: "pending",
|
|
962
|
+
rewardPercentiles: [10, 50, 80]
|
|
963
|
+
};
|
|
964
|
+
const optionsResolved = options ? { ...defaultOptions, ...options } : defaultOptions;
|
|
965
|
+
if (optionsResolved.rewardPercentiles.length !== 3) {
|
|
966
|
+
throw new Error(`rough gas estimate require 3 percentile, it defaults to [10,50,80]`);
|
|
967
|
+
}
|
|
968
|
+
const result = await getGasPriceEstimate(provider, optionsResolved);
|
|
969
|
+
return {
|
|
970
|
+
slow: result[0],
|
|
971
|
+
average: result[1],
|
|
972
|
+
fast: result[2]
|
|
973
|
+
};
|
|
974
|
+
}
|
|
975
|
+
|
|
901
976
|
// src/executor/index.ts
|
|
977
|
+
var import_prompts = __toESM(require("prompts"), 1);
|
|
978
|
+
var import_viem2 = require("viem");
|
|
902
979
|
if (!process.env["ROCKETH_SKIP_ESBUILD"]) {
|
|
903
980
|
require("esbuild-register/dist/node").register();
|
|
904
981
|
}
|
|
@@ -909,24 +986,55 @@ function execute(context, callback, options) {
|
|
|
909
986
|
scriptModule.dependencies = options.dependencies;
|
|
910
987
|
return scriptModule;
|
|
911
988
|
}
|
|
912
|
-
function readConfig(options
|
|
989
|
+
function readConfig(options) {
|
|
913
990
|
let configFile;
|
|
914
991
|
try {
|
|
915
992
|
const configString = import_node_fs4.default.readFileSync("./rocketh.json", "utf-8");
|
|
916
993
|
configFile = JSON.parse(configString);
|
|
917
994
|
} catch {
|
|
918
995
|
}
|
|
919
|
-
|
|
996
|
+
if (configFile) {
|
|
997
|
+
if (!options.deployments && configFile.deployments) {
|
|
998
|
+
options.deployments = configFile.deployments;
|
|
999
|
+
}
|
|
1000
|
+
if (!options.scripts && configFile.scripts) {
|
|
1001
|
+
options.scripts = configFile.scripts;
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
920
1004
|
const fromEnv = process.env["ETH_NODE_URI_" + options.network];
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
if (
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
1005
|
+
const fork = typeof options.network !== "string";
|
|
1006
|
+
let networkName = "memory";
|
|
1007
|
+
if (options.network) {
|
|
1008
|
+
if (typeof options.network === "string") {
|
|
1009
|
+
networkName = options.network;
|
|
1010
|
+
} else if ("fork" in options.network) {
|
|
1011
|
+
networkName = options.network.fork;
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
let networkTags = configFile?.networks && configFile?.networks[networkName]?.tags || [];
|
|
1015
|
+
if (!options.provider) {
|
|
1016
|
+
let nodeUrl;
|
|
1017
|
+
if (typeof fromEnv === "string") {
|
|
1018
|
+
nodeUrl = fromEnv;
|
|
1019
|
+
} else {
|
|
1020
|
+
if (configFile) {
|
|
1021
|
+
const network = configFile.networks && configFile.networks[networkName];
|
|
1022
|
+
if (network && network.rpcUrl) {
|
|
1023
|
+
nodeUrl = network.rpcUrl;
|
|
1024
|
+
} else {
|
|
1025
|
+
if (options?.ignoreMissingRPC) {
|
|
1026
|
+
nodeUrl = "";
|
|
1027
|
+
} else {
|
|
1028
|
+
if (options.network === "localhost") {
|
|
1029
|
+
nodeUrl = "http://127.0.0.1:8545";
|
|
1030
|
+
} else {
|
|
1031
|
+
logger.error(`network "${options.network}" is not configured. Please add it to the rocketh.json file`);
|
|
1032
|
+
process.exit(1);
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
928
1036
|
} else {
|
|
929
|
-
if (
|
|
1037
|
+
if (options?.ignoreMissingRPC) {
|
|
930
1038
|
nodeUrl = "";
|
|
931
1039
|
} else {
|
|
932
1040
|
if (options.network === "localhost") {
|
|
@@ -937,47 +1045,61 @@ function readConfig(options, extra) {
|
|
|
937
1045
|
}
|
|
938
1046
|
}
|
|
939
1047
|
}
|
|
940
|
-
} else {
|
|
941
|
-
if (extra?.ignoreMissingRPC) {
|
|
942
|
-
nodeUrl = "";
|
|
943
|
-
} else {
|
|
944
|
-
if (options.network === "localhost") {
|
|
945
|
-
nodeUrl = "http://127.0.0.1:8545";
|
|
946
|
-
} else {
|
|
947
|
-
logger.error(`network "${options.network}" is not configured. Please add it to the rocketh.json file`);
|
|
948
|
-
process.exit(1);
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
1048
|
}
|
|
1049
|
+
return {
|
|
1050
|
+
network: {
|
|
1051
|
+
nodeUrl,
|
|
1052
|
+
name: networkName,
|
|
1053
|
+
tags: networkTags,
|
|
1054
|
+
fork
|
|
1055
|
+
},
|
|
1056
|
+
deployments: options.deployments,
|
|
1057
|
+
saveDeployments: options.saveDeployments,
|
|
1058
|
+
scripts: options.scripts,
|
|
1059
|
+
tags: typeof options.tags === "undefined" ? void 0 : options.tags.split(","),
|
|
1060
|
+
logLevel: options.logLevel,
|
|
1061
|
+
askBeforeProceeding: options.askBeforeProceeding
|
|
1062
|
+
};
|
|
1063
|
+
} else {
|
|
1064
|
+
return {
|
|
1065
|
+
network: {
|
|
1066
|
+
provider: options.provider,
|
|
1067
|
+
name: networkName,
|
|
1068
|
+
tags: networkTags,
|
|
1069
|
+
fork
|
|
1070
|
+
},
|
|
1071
|
+
deployments: options.deployments,
|
|
1072
|
+
saveDeployments: options.saveDeployments,
|
|
1073
|
+
scripts: options.scripts,
|
|
1074
|
+
tags: typeof options.tags === "undefined" ? void 0 : options.tags.split(","),
|
|
1075
|
+
logLevel: options.logLevel,
|
|
1076
|
+
askBeforeProceeding: options.askBeforeProceeding
|
|
1077
|
+
};
|
|
952
1078
|
}
|
|
953
|
-
return {
|
|
954
|
-
nodeUrl,
|
|
955
|
-
networkName: options.network,
|
|
956
|
-
deployments: options.deployments,
|
|
957
|
-
scripts: options.scripts,
|
|
958
|
-
tags: typeof options.tags === "undefined" ? void 0 : options.tags.split(",")
|
|
959
|
-
};
|
|
960
1079
|
}
|
|
961
|
-
function readAndResolveConfig(options
|
|
962
|
-
return resolveConfig(readConfig(options
|
|
1080
|
+
function readAndResolveConfig(options) {
|
|
1081
|
+
return resolveConfig(readConfig(options));
|
|
963
1082
|
}
|
|
964
1083
|
function resolveConfig(config) {
|
|
965
1084
|
const resolvedConfig = {
|
|
966
1085
|
...config,
|
|
967
|
-
|
|
1086
|
+
network: config.network,
|
|
1087
|
+
// TODO default to || {name: 'memory'....}
|
|
968
1088
|
deployments: config.deployments || "deployments",
|
|
969
1089
|
scripts: config.scripts || "deploy",
|
|
970
|
-
tags: config.tags || []
|
|
1090
|
+
tags: config.tags || [],
|
|
1091
|
+
networkTags: config.networkTags || [],
|
|
1092
|
+
saveDeployments: config.saveDeployments
|
|
971
1093
|
};
|
|
972
1094
|
return resolvedConfig;
|
|
973
1095
|
}
|
|
974
|
-
async function loadEnvironment(
|
|
975
|
-
const resolvedConfig =
|
|
1096
|
+
async function loadEnvironment(options, context) {
|
|
1097
|
+
const resolvedConfig = readAndResolveConfig(options);
|
|
976
1098
|
const { external, internal } = await createEnvironment(resolvedConfig, context);
|
|
977
1099
|
return external;
|
|
978
1100
|
}
|
|
979
|
-
async function loadAndExecuteDeployments(
|
|
980
|
-
const resolvedConfig =
|
|
1101
|
+
async function loadAndExecuteDeployments(options, args) {
|
|
1102
|
+
const resolvedConfig = readAndResolveConfig(options);
|
|
981
1103
|
return executeDeployScripts(resolvedConfig, args);
|
|
982
1104
|
}
|
|
983
1105
|
async function executeDeployScripts(config, args) {
|
|
@@ -1096,6 +1218,28 @@ async function executeDeployScripts(config, args) {
|
|
|
1096
1218
|
for (const scriptFilePath of scriptFilePaths) {
|
|
1097
1219
|
recurseDependencies(scriptFilePath);
|
|
1098
1220
|
}
|
|
1221
|
+
if (config.askBeforeProceeding) {
|
|
1222
|
+
const gasPriceEstimate = await getRoughGasPriceEstimate(external.network.provider);
|
|
1223
|
+
const prompt = await (0, import_prompts.default)({
|
|
1224
|
+
type: "confirm",
|
|
1225
|
+
name: "proceed",
|
|
1226
|
+
message: `gas price is currently in this range:
|
|
1227
|
+
slow: ${(0, import_viem2.formatEther)(gasPriceEstimate.slow.maxFeePerGas)} (priority: ${(0, import_viem2.formatEther)(
|
|
1228
|
+
gasPriceEstimate.slow.maxPriorityFeePerGas
|
|
1229
|
+
)})
|
|
1230
|
+
average: ${(0, import_viem2.formatEther)(gasPriceEstimate.average.maxFeePerGas)} (priority: ${(0, import_viem2.formatEther)(
|
|
1231
|
+
gasPriceEstimate.average.maxPriorityFeePerGas
|
|
1232
|
+
)})
|
|
1233
|
+
fast: ${(0, import_viem2.formatEther)(gasPriceEstimate.fast.maxFeePerGas)} (priority: ${(0, import_viem2.formatEther)(
|
|
1234
|
+
gasPriceEstimate.fast.maxPriorityFeePerGas
|
|
1235
|
+
)})
|
|
1236
|
+
|
|
1237
|
+
Do you want to proceed (note that gas price can change for each tx)`
|
|
1238
|
+
});
|
|
1239
|
+
if (!prompt.proceed) {
|
|
1240
|
+
process.exit();
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1099
1243
|
for (const deployScript of scriptsToRun.concat(scriptsToRunAtTheEnd)) {
|
|
1100
1244
|
const filename = import_node_path4.default.basename(deployScript.filePath);
|
|
1101
1245
|
const relativeFilepath = import_node_path4.default.relative(".", deployScript.filePath);
|