diff --git a/src/lib/deploy.js b/src/lib/deploy.js index 5c6cc17c..a877b1dd 100644 --- a/src/lib/deploy.js +++ b/src/lib/deploy.js @@ -401,7 +401,7 @@ export async function deploy({ alias, yes }) { // we need to fail if any answer other than "yes" or "y" is given. val = val.toLowerCase(); if (!(val === 'yes' || val === 'y')) { - log(' Aborted. Transaction not sent.'); + log(chalk.red('\n Aborted. Transaction not sent.')); process.exit(1); } return val; @@ -444,6 +444,14 @@ export async function deploy({ alias, yes }) { } async function getContractName(config, build, alias) { + if (build.smartContracts.length === 0) { + log( + chalk.red( + `\n No smart contracts found in the project.\n Please make sure you have at least one class that extends the o1js \`SmartContract\`.\n Aborted.` + ) + ); + process.exit(1); + } // Identify which smart contract to be deployed for this deploy alias. let contractName = chooseSmartContract(config, build, alias); diff --git a/src/lib/helpers.js b/src/lib/helpers.js index c5a1e730..d5e36acc 100644 --- a/src/lib/helpers.js +++ b/src/lib/helpers.js @@ -342,33 +342,35 @@ function checkClassInheritance( const classInfo = classesMap[className]; if (!classInfo) return false; - // Ensure that the parent class hierarchy is processed - if (classInfo.extends && !classesMap[classInfo.extends]) { - const parentMapping = importMappings[classInfo.extends]; - if (parentMapping) { - Object.assign( - classesMap, - buildClassHierarchy(parentMapping.resolvedPath) - ); - importMappings = Object.assign( - importMappings, - resolveImports(parentMapping.resolvedPath) - ); + // Propagate inheritsFromO1jsSmartContract from parent class + if (classInfo.extends) { + const parentClassResult = checkClassInheritance( + classInfo.extends, + targetClass, + classesMap, + visitedClasses, + importMappings + ); + + // Propagate the inheritsFromO1jsSmartContract flag + if (parentClassResult) { + classInfo.inheritsFromO1jsSmartContract = true; } } - // Check if the class extends the target class from 'o1js' + // Check if the class directly extends the target class if ( classInfo.extends === targetClass && - classInfo.inheritsFromO1jsSmartContract + importMappings[classInfo.extends]?.moduleName === 'o1js' ) { + classInfo.inheritsFromO1jsSmartContract = true; return true; } // Check each implemented interface for (const iface of classInfo.implements) { if ( - (iface === targetClass && classInfo.inheritsFromO1jsSmartContract) || + (iface === targetClass && importMappings[iface]?.moduleName === 'o1js') || checkClassInheritance( iface, targetClass, @@ -382,25 +384,31 @@ function checkClassInheritance( } } - // If there is no parent class, return false - if (!classInfo.extends) return false; - - // Recursively check the parent class - const parentClassResult = checkClassInheritance( - classInfo.extends, - targetClass, - classesMap, - visitedClasses, - importMappings - ); - - // Propagate the inheritsFromO1jsSmartContract flag - if (parentClassResult) { - classInfo.inheritsFromO1jsSmartContract = true; - return true; + // Additional check for imported base class + if (importMappings[classInfo.extends]) { + const baseClassPath = importMappings[classInfo.extends].resolvedPath; + const baseClassMap = buildClassHierarchy(baseClassPath); + Object.assign(classesMap, baseClassMap); + const baseClassInfo = baseClassMap[classInfo.extends]; + if (baseClassInfo && baseClassInfo.extends === targetClass) { + classInfo.inheritsFromO1jsSmartContract = true; + return true; + } else if (baseClassInfo) { + const parentClassResult = checkClassInheritance( + baseClassInfo.extends, + targetClass, + classesMap, + visitedClasses, + importMappings + ); + if (parentClassResult) { + classInfo.inheritsFromO1jsSmartContract = true; + return true; + } + } } - return false; + return classInfo.inheritsFromO1jsSmartContract; } export default step;