UNPKG

dop-stick

Version:

Source control tooling for versionable-upgradeable smart contracts

145 lines 6.25 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LibraryManager = void 0; const ethers_1 = require("ethers"); const libraryTimelineAdapter_1 = require("../logsAndMetrics/adapters/libraryTimelineAdapter"); class LibraryManager { constructor(provider, signer, libraries) { this.deployedLibraries = new Map(); this.libraryConfigs = new Map(); this.provider = provider; this.signer = signer; this.timeline = new libraryTimelineAdapter_1.LibraryTimelineAdapter(); if (libraries) { Object.entries(libraries).forEach(([name, config]) => { this.libraryConfigs.set(name, config); }); } } async resolveLibraries(requiredLibraries) { this.timeline.startLibraryResolution(requiredLibraries); const resolved = {}; for (const libName of requiredLibraries) { try { const libAddress = await this.resolveLibrary(libName); resolved[libName] = libAddress; this.timeline.logLibraryResolved(libName, libAddress); } catch (error) { this.timeline.logLibraryError(libName, error); throw error; } } return resolved; } async resolveLibrary(name) { var _a; // Return if already deployed if (this.deployedLibraries.has(name)) { return this.deployedLibraries.get(name); } const config = this.libraryConfigs.get(name); if (!config) { throw new Error(`Library configuration not found for: ${name}`); } // If address is provided, verify it if (config.address) { const code = await this.provider.getCode(config.address); if (code !== '0x') { this.deployedLibraries.set(name, config.address); return config.address; } } // Deploy dependencies first if ((_a = config.dependencies) === null || _a === void 0 ? void 0 : _a.length) { this.timeline.logDependencyResolution(name, config.dependencies); await Promise.all(config.dependencies.map(dep => this.resolveLibrary(dep))); } // Deploy the library return await this.deployLibrary(config); } async deployLibrary(config) { var _a; if (!config.bytecode || !config.abi) { throw new Error(`Missing bytecode or ABI for library: ${config.name}`); } this.timeline.logLibraryDeployment(config.name, 'starting'); try { // Replace library references in bytecode if needed let processedBytecode = config.bytecode; if ((_a = config.dependencies) === null || _a === void 0 ? void 0 : _a.length) { for (const dep of config.dependencies) { const depAddress = this.deployedLibraries.get(dep); if (!depAddress) { throw new Error(`Dependency not deployed: ${dep}`); } processedBytecode = this.linkLibrary(processedBytecode, dep, depAddress); } } // Deploy const factory = new ethers_1.ethers.ContractFactory(config.abi, processedBytecode, this.signer); const library = await factory.deploy(); await library.deployed(); this.deployedLibraries.set(config.name, library.address); this.timeline.logLibraryDeployment(config.name, 'success', library.address); return library.address; } catch (error) { this.timeline.logLibraryDeployment(config.name, 'failed', undefined, error); throw error; } } linkLibrary(bytecode, libName, libAddress) { const placeholder = `__$${ethers_1.ethers.utils.solidityKeccak256(['string'], [libName]).slice(2, 36)}$__`; const regex = new RegExp(placeholder, 'g'); return bytecode.replace(regex, libAddress.slice(2)); } /** * Deploy a library using a specific wallet * @param lib Library reference to deploy * @param wallet Wallet to use for deployment * @returns Promise<LibraryDeploymentResult> */ async deployLibraryWithWallet(lib, wallet) { var _a; const config = this.libraryConfigs.get(lib.name); if (!config) { throw new Error(`Library configuration not found for: ${lib.name}`); } if (!config.bytecode || !config.abi) { throw new Error(`Missing bytecode or ABI for library: ${lib.name}`); } this.timeline.logLibraryDeployment(lib.name, 'starting'); try { // Replace library references in bytecode if needed let processedBytecode = config.bytecode; if ((_a = config.dependencies) === null || _a === void 0 ? void 0 : _a.length) { for (const dep of config.dependencies) { const depAddress = this.deployedLibraries.get(dep); if (!depAddress) { throw new Error(`Dependency not deployed: ${dep}`); } processedBytecode = this.linkLibrary(processedBytecode, dep, depAddress); } } // Deploy using provided wallet const factory = new ethers_1.ethers.ContractFactory(config.abi, processedBytecode, wallet); const library = await factory.deploy(); const deployedLibrary = await library.deployed(); const result = { name: lib.name, address: deployedLibrary.address, deploymentHash: library.deployTransaction.hash }; this.deployedLibraries.set(lib.name, result.address); this.timeline.logLibraryDeployment(lib.name, 'success', result.address); return result; } catch (error) { this.timeline.logLibraryDeployment(lib.name, 'failed', undefined, error); throw error; } } } exports.LibraryManager = LibraryManager; //# sourceMappingURL=libraryManager.js.map