dop-stick
Version:
Source control tooling for versionable-upgradeable smart contracts
152 lines • 6.58 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.configLoader = exports.ConfigLoader = void 0;
const fs = __importStar(require("fs/promises"));
const path = __importStar(require("path"));
const ethers = __importStar(require("ethers"));
const hardhatHelpers_1 = require("./hardhatHelpers");
class ConfigLoader {
constructor() {
this.config = null;
}
static getInstance() {
if (!ConfigLoader.instance) {
ConfigLoader.instance = new ConfigLoader();
}
return ConfigLoader.instance;
}
async loadConfig() {
if (this.config)
return this.config;
const configPath = path.join(process.cwd(), ConfigLoader.CONFIG_FILE_NAME);
try {
const configFile = await fs.readFile(configPath, 'utf8');
const config = JSON.parse(configFile);
await this.validateConfig(config);
this.config = config;
return config;
}
catch (error) {
if (error instanceof Error) {
throw new Error(`Failed to load dop-stick.config.json: ${error.message}\n` +
'Please ensure you have a valid dop-stick.config.json file in your project root.');
}
throw error;
}
}
async validateConfig(config) {
var _a, _b;
if (!((_a = config.paths) === null || _a === void 0 ? void 0 : _a.upgrades)) {
throw new Error('Missing required config: paths.upgrades');
}
const upgradesPath = path.join(process.cwd(), config.paths.upgrades);
try {
await fs.access(upgradesPath);
}
catch (_c) {
throw new Error(`Upgrades file not found at: ${upgradesPath}`);
}
if ((_b = config.paths) === null || _b === void 0 ? void 0 : _b.typechain) {
const typechainPath = path.join(process.cwd(), config.paths.typechain);
try {
await fs.access(typechainPath);
}
catch (_d) {
throw new Error(`Typechain directory not found at: ${typechainPath}`);
}
}
if (!process.env.DIAMOND_ADDRESS) {
throw new Error('DIAMOND_ADDRESS environment variable is not set. ' +
'Please set it to your diamond contract address.');
}
if (!ethers.utils.isAddress(process.env.DIAMOND_ADDRESS)) {
throw new Error('Invalid DIAMOND_ADDRESS environment variable. ' +
'Please set a valid contract address.');
}
}
async getUpgradeServiceContract(config) {
var _a, _b;
try {
const upgradeService = (_a = config.contracts) === null || _a === void 0 ? void 0 : _a.upgradeService;
if (!upgradeService) {
throw new Error('Upgrade service configuration not found');
}
// Get the custom function configuration
const customFunctionConfig = (_b = upgradeService.customFunctions) === null || _b === void 0 ? void 0 : _b.diamondCut;
let diamondCutFunctionName;
// Determine the function name to look for in the ABI
if (typeof customFunctionConfig === 'string') {
diamondCutFunctionName = customFunctionConfig;
}
else if (customFunctionConfig && 'name' in customFunctionConfig) {
diamondCutFunctionName = customFunctionConfig.name;
}
else {
diamondCutFunctionName = 'diamondCut';
}
// Validate ABI contains the required function
const abi = upgradeService.abi;
if (!abi || !Array.isArray(abi)) {
throw new Error('Invalid or missing ABI in upgrade service configuration');
}
const hasDiamondCutFunction = abi.some(item => {
if (typeof item === 'string') {
return item.includes(`function ${diamondCutFunctionName}`);
}
return item.type === 'function' && item.name === diamondCutFunctionName;
});
if (!hasDiamondCutFunction) {
throw new Error(`ABI must contain the diamond cut function (${diamondCutFunctionName})`);
}
const signer = await this.getSigner();
return new ethers.ContractFactory(abi, [], signer);
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
throw new Error(`Failed to create upgrade service contract: ${errorMessage}`);
}
}
// Helper function to get signer (can be imported from existing utils)
async getSigner() {
const provider = await (0, hardhatHelpers_1.getProvider)();
if (!process.env.PRIVATE_KEY) {
throw new Error('PRIVATE_KEY environment variable is not set');
}
return new ethers.Wallet(process.env.PRIVATE_KEY, provider);
}
}
exports.ConfigLoader = ConfigLoader;
ConfigLoader.CONFIG_FILE_NAME = 'dop-stick.config.json';
ConfigLoader.DEFAULT_UPGRADE_SERVICE = {
name: 'DiamondCutFacet',
path: 'facets'
};
// Basic Diamond Cut ABI - only what we need
ConfigLoader.DEFAULT_UPGRADE_SERVICE_ABI = [
"function diamondCut((address facetAddress, uint8 action, bytes4[] functionSelectors)[] _diamondCut, address _init, bytes _calldata) external"
];
exports.configLoader = ConfigLoader.getInstance();
//# sourceMappingURL=configLoader.js.map