Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
3cd6a54
3 cli setup testing framework (#35)
cristiam86 Jul 3, 2024
ab3b32b
33 cli add a warning at init to say that the config is going to be ov…
cristiam86 Jul 3, 2024
b77fec8
37 cli run simulator on certain branch (#39)
cristiam86 Jul 3, 2024
ddb0714
41 cli add beta releases for staging branch (#42)
cristiam86 Jul 3, 2024
26302e4
Release v0.0.32-beta.0 [skip ci]
Jul 3, 2024
60d6da3
43 cli fix missing endpoints and simulator response (#44)
cristiam86 Jul 3, 2024
6a2d6ab
Release v0.0.32-beta.1 [skip ci]
Jul 3, 2024
586ffa8
43 cli fix missing endpoints and simulator response (#45)
cristiam86 Jul 3, 2024
59a9fc6
Release v0.0.32-beta.2 [skip ci]
Jul 3, 2024
0e96ecd
46 cli add node and docker version (#47)
denishacquin Jul 26, 2024
8f0a798
Release v0.0.32-beta.3 [skip ci]
Jul 26, 2024
da8a16f
chore(deps): update dependency eslint to v9
renovate[bot] Oct 25, 2024
9a2befb
chore(deps): update tibdex/github-app-token action to v2
renovate[bot] Nov 6, 2024
fd4883e
chore(deps): update actions/setup-node action to v4
renovate[bot] Jan 9, 2025
a461688
chore(deps): update dependency esbuild to ^0.25.0 [security]
renovate[bot] Feb 12, 2025
39ec17b
feat: new log and spinner class
epsjunior Feb 14, 2025
134df7f
feat: adding spinner to keygen command
epsjunior Feb 14, 2025
25967f9
feat: adding spinner and logs to command config
epsjunior Feb 14, 2025
0c9f777
feat: new up command(class)
epsjunior Feb 17, 2025
5544edb
feat: refac init, base action and unit tests
epsjunior Feb 20, 2025
5c454bd
merging
epsjunior Feb 20, 2025
07d1f86
fix: merging commit
epsjunior Feb 20, 2025
df6c846
chore(deps): update dependency @release-it/conventional-changelog to v10
renovate[bot] Feb 20, 2025
e461692
chore(deps): update dependency eslint-config-prettier to v10
renovate[bot] Feb 20, 2025
c0ebac0
fix(deps): update dependency inquirer to v12
renovate[bot] Feb 20, 2025
753158f
chore(deps): update dependency jsdom to v26
renovate[bot] Feb 20, 2025
ac0ab0e
chore(deps): update dependency release-it to v18
renovate[bot] Feb 20, 2025
69416b5
fix(deps): update all non-major dependencies
renovate[bot] Feb 21, 2025
eddef2b
Merge branch 'renovate/actions-setup-node-4.x'
epsjunior Feb 21, 2025
8ae848b
Merge branch 'renovate/major-eslint-monorepo'
epsjunior Feb 21, 2025
4faf084
Merge branch 'renovate/tibdex-github-app-token-2.x'
epsjunior Feb 21, 2025
77d0e2b
Merge branch 'renovate/inquirer-12.x'
epsjunior Feb 21, 2025
914a989
Merge branch 'renovate/all-minor-patch'
epsjunior Feb 21, 2025
fa6cc67
fix: merging
epsjunior Feb 21, 2025
26cd6c1
Merge branch 'renovate/release-it-conventional-changelog-10.x'
epsjunior Feb 21, 2025
f65690d
fix: merging conflicts
epsjunior Feb 21, 2025
02467b1
Merge branch 'renovate/jsdom-26.x'
epsjunior Feb 21, 2025
9af428d
Merge branch 'renovate/release-it-18.x'
epsjunior Feb 21, 2025
c293bef
fix: updating packages and fixing breaking changes
epsjunior Feb 21, 2025
1c05553
fix: merging conflicts
epsjunior Feb 24, 2025
189dc35
fix: package json
epsjunior Feb 24, 2025
ac3cfa3
fix: merging conflicts
epsjunior Feb 24, 2025
9b115e1
fix: package lock
epsjunior Feb 24, 2025
157c74a
chore: ollama hint message
epsjunior Feb 24, 2025
257f3b2
feat: new deploy script command
epsjunior Feb 27, 2025
554f959
tests: including new tests
epsjunior Feb 27, 2025
84d8aa0
fix: esbuild version
epsjunior Feb 27, 2025
14a1195
fix: esbuild prod
epsjunior Feb 28, 2025
6629cba
feat: call command using base action
epsjunior Mar 4, 2025
cb38da8
mege
epsjunior Mar 5, 2025
a61f131
fix: merge
epsjunior Mar 5, 2025
d84f1d3
fix: package lock
epsjunior Mar 6, 2025
6bd5d55
fix: 1- not logging 'false' and not sending the expected type to rpc
epsjunior Mar 7, 2025
c192bc4
chore: adding important log
epsjunior Mar 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion esbuild.config.dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default {
banner: {
js: `const _importMetaUrl = new URL(import.meta.url).pathname;`,
},
external: ["commander", "dockerode", "dotenv", "ethers", "inquirer", "update-check", "ssh2"]
external: ["commander", "dockerode", "dotenv", "ethers", "inquirer", "update-check", "ssh2", "esbuild"]

},
watch: true,
Expand Down
5 changes: 3 additions & 2 deletions esbuild.config.prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ export default {
outfile: "dist/index.js",
platform: "node",
target: "es2020",
define: { "import.meta.url": "_importMetaUrl" },
format: "esm",
define: { "import.meta.url": "import.meta.url" },
banner: {
js: `const _importMetaUrl = new URL(import.meta.url).pathname;`,
},
external: ["commander", "dockerode", "dotenv", "ethers", "inquirer", "update-check", "ssh2"]
external: ["commander", "dockerode", "dotenv", "ethers", "inquirer", "update-check", "ssh2", "esbuild"]
},
watch: false,
};
246 changes: 123 additions & 123 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"@typescript-eslint/parser": "^8.0.0",
"@vitest/coverage-v8": "^2.1.4",
"cross-env": "^7.0.3",
"esbuild": "^0.25.0",
"esbuild": ">=0.25.0",
"eslint": "^9.0.0",
"eslint-config-prettier": "^10.0.0",
"eslint-import-resolver-typescript": "^3.6.1",
Expand Down
36 changes: 16 additions & 20 deletions src/commands/contracts/call.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ import { createClient, createAccount } from "genlayer-js";
import { simulator } from "genlayer-js/chains";
import type { GenLayerClient } from "genlayer-js/types";
import { getPrivateKey } from "../../lib/accounts/getPrivateKey";
import { BaseAction } from "../../lib/actions/BaseAction";

export interface CallOptions {
args: any[];
}

export class CallAction {
export class CallAction extends BaseAction{
private genlayerClient: GenLayerClient<typeof simulator>;

constructor() {
super();
this.genlayerClient = createClient({
chain: simulator,
endpoint: process.env.VITE_JSON_RPC_SERVER_URL,
Expand All @@ -27,27 +29,23 @@ export class CallAction {
method: string;
args: any[];
}): Promise<void> {
console.log(`Calling method ${method} on contract at ${contractAddress}...`);
this.startSpinner(`Calling method ${method} on contract at ${contractAddress}...`);

const contractSchema = await this.genlayerClient.getContractSchema(contractAddress);

if(!contractSchema.methods.hasOwnProperty(method)){
console.error(`method ${method} not found.`);
process.exit(1);
this.failSpinner(`method ${method} not found.`);
return
}

const readonly = contractSchema.methods[method as any].readonly;

try {
if (readonly) {
await this.executeRead(contractAddress, method, args);
} else {
await this.executeWrite(contractAddress, method, args);
}
} catch (error) {
console.error("Error calling contract method:", error);
throw error;
if (readonly) {
await this.executeRead(contractAddress, method, args);
return
}

await this.executeWrite(contractAddress, method, args);
}

private async executeRead(contractAddress: string, method: string, args: any[]): Promise<void> {
Expand All @@ -57,10 +55,9 @@ export class CallAction {
functionName: method,
args,
});
console.log("Read result:", result);
this.succeedSpinner("Read operation successfully executed", result);
} catch (error) {
console.error("Error during read operation:", error);
throw error;
this.failSpinner("Error during read operation", error);
}
}

Expand All @@ -77,11 +74,10 @@ export class CallAction {
retries: 15,
interval: 2000,
});
console.log("Write transaction hash:", hash);
console.log("Result:", result);
this.log("Write transaction hash:", hash);
this.succeedSpinner("Write operation successfully executed", result);
} catch (error) {
console.error("Error during write operation:", error);
throw error;
this.failSpinner("Error during write operation", error);
}
}
}
132 changes: 107 additions & 25 deletions src/commands/contracts/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
import fs from "fs";
import path from "path";
import { createClient, createAccount } from "genlayer-js";
import { simulator } from "genlayer-js/chains";
import type { GenLayerClient } from "genlayer-js/types";
import { getPrivateKey } from "../../lib/accounts/getPrivateKey";
import { BaseAction } from "../../lib/actions/BaseAction";
import { pathToFileURL } from "url";
import { TransactionStatus } from "genlayer-js/types";
import { buildSync } from "esbuild";

export interface DeployOptions {
contract?: string;
// network: string;
args?: any[];
kwargs?: string;
}

export class DeployAction {
export class DeployAction extends BaseAction {
private genlayerClient: GenLayerClient<typeof simulator>;
private readonly deployDir = path.resolve(process.cwd(), "deploy");

constructor() {
super();
this.genlayerClient = createClient({
chain: simulator,
endpoint: process.env.VITE_JSON_RPC_SERVER_URL,
Expand All @@ -29,44 +34,121 @@ export class DeployAction {
return fs.readFileSync(contractPath, "utf-8");
}

async deploy(options: DeployOptions): Promise<void> {

const argsUsed = options.args && options.args.length > 0;
const kwargsUsed = options.kwargs && options.kwargs.trim() !== "";
private async executeTsScript(filePath: string): Promise<void> {
const outFile = filePath.replace(/\.ts$/, ".compiled.js");
this.startSpinner(`Transpiling TypeScript file: ${filePath}`);
try {
buildSync({
entryPoints: [filePath],
outfile: outFile,
bundle: false,
platform: "node",
format: "esm",
target: "es2020",
sourcemap: false,
});
await this.executeJsScript(filePath, outFile);
} catch (error) {
this.failSpinner(`Error executing: ${filePath}`, error);
} finally {
fs.unlinkSync(outFile);
}
}

if (argsUsed && kwargsUsed) {
throw new Error("Invalid usage: Please specify either `args` or `kwargs`, but not both.");
private async executeJsScript(filePath: string, transpiledFilePath?: string): Promise<void> {
this.startSpinner(`Executing file: ${filePath}`);
try {
const module = await import(pathToFileURL(transpiledFilePath || filePath).href);
if (!module.default || typeof module.default !== "function") {
this.failSpinner(`No "default" function found in: ${filePath}`);
return
}
await module.default(this.genlayerClient);
this.succeedSpinner(`Successfully executed: ${filePath}`);
} catch (error) {
this.failSpinner(`Error executing: ${filePath}`, error);
}
}

if (!options.contract) {
console.error("No contract specified for deployment.");
async deployScripts() {
this.startSpinner("Searching for deploy scripts...");
if (!fs.existsSync(this.deployDir)) {
this.failSpinner("No deploy folder found.");
return;
}
const files = fs.readdirSync(this.deployDir)
.filter(file => file.endsWith(".ts") || file.endsWith(".js"))
.sort((a, b) => {
const numA = parseInt(a.split("_")[0]);
const numB = parseInt(b.split("_")[0]);

const contractCode = this.readContractCode(options.contract);
if (!isNaN(numA) && !isNaN(numB)) return numA - numB;
if (!isNaN(numA)) return -1;
if (!isNaN(numB)) return 1;
return a.localeCompare(b);
});

if (!contractCode) {
console.error("Contract code is empty.");
if (files.length === 0) {
this.failSpinner("No deploy scripts found.");
return;
}

const leaderOnly = false;
let deployParams: any = { code: contractCode, args: options.args, leaderOnly };
this.setSpinnerText(`Found ${files.length} deploy scripts. Executing...`);

console.log("Starting contract deployment...");
console.log("Deployment Parameters:", deployParams);
for (const file of files) {
const filePath = path.resolve(this.deployDir, file);
this.setSpinnerText(`Executing script: ${filePath}`);
try {
if (file.endsWith(".ts")) {
await this.executeTsScript(filePath);
} else {
await this.executeJsScript(filePath);
}
} catch (error) {
this.failSpinner(`Error executing script: ${filePath}`, error);
}
}
}

async deploy(options: DeployOptions): Promise<void> {
try {
const hash = await this.genlayerClient.deployContract(deployParams) as any;
this.startSpinner("Setting up the deployment environment...");
await this.genlayerClient.initializeConsensusSmartContract();

if (!options.contract) {
this.failSpinner("No contract specified for deployment.");
return;
}
this.setSpinnerText("Reading contract code...");
const contractCode = this.readContractCode(options.contract);

if (!contractCode) {
this.failSpinner("Contract code is empty.");
return;
}

const leaderOnly = false;
const deployParams: any = { code: contractCode, args: options.args, leaderOnly };

this.setSpinnerText("Starting contract deployment...");
this.log("Deployment Parameters:", deployParams);

const hash = (await this.genlayerClient.deployContract(deployParams)) as any;
const result = await this.genlayerClient.waitForTransactionReceipt({
hash,
retries: 15,
interval: 2000,
status: TransactionStatus.ACCEPTED,
});

const result = await this.genlayerClient.waitForTransactionReceipt({hash, retries: 15, interval: 2000})
this.log("Deployment Receipt:", result);

console.log("Contract deployed successfully.");
console.log("Transaction Hash:", hash);
console.log("Contract Address:", result.data?.contract_address);
this.succeedSpinner("Contract deployed successfully.", {
"Transaction Hash": hash,
"Contract Address": result.data?.contract_address,
});
} catch (error) {
console.error("Error deploying contract:", error);
throw new Error("Contract deployment failed.");
this.failSpinner("Error deploying contract", error);
}
}
}
17 changes: 14 additions & 3 deletions src/commands/contracts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,34 @@ import { Command } from "commander";
import { DeployAction, DeployOptions } from "./deploy";
import { CallAction, CallOptions } from "./call";

function parseArg(value: string, previous: any[] = []): any[] {
if (value === "true") return [...previous, true];
if (value === "false") return [...previous, false];
if (!isNaN(Number(value))) return [...previous, Number(value)];
return [...previous, value];
}

export function initializeContractsCommands(program: Command) {

program
.command("deploy")
.description("Deploy intelligent contracts")
.option("--contract <contractPath>", "Path to the smart contract to deploy")
// .option("--network <networkName>", "Specify the network (e.g., testnet)", "localnet")
.option("--args <args...>", "Positional arguments for the contract (space-separated, use quotes for multi-word arguments)", [])
.option("--args <args...>", "Positional arguments for the contract (space-separated, use quotes for multi-word arguments)", parseArg, [])
.action(async (options: DeployOptions) => {
const deployer = new DeployAction();
await deployer.deploy(options);
if(options.contract){
await deployer.deploy(options);
}else {
await deployer.deployScripts();
}
});

program
.command("call <contractAddress> <method>")
.description("Call a contract method")
.option("--args <args...>", "Positional arguments for the method (space-separated, use quotes for multi-word arguments)", [])
.option("--args <args...>", "Positional arguments for the method (space-separated, use quotes for multi-word arguments)", parseArg, [])
.action(async (contractAddress: string, method: string, options: CallOptions) => {
const caller = new CallAction();
await caller.call({ contractAddress, method, ...options });
Expand Down
1 change: 0 additions & 1 deletion src/commands/general/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ export class InitAction extends BaseAction {
const selectedLlmProviders = llmProvidersAnswer.selectedLlmProviders as AiProviders[];

let defaultOllamaModel = this.getConfig().defaultOllamaModel;
AI_PROVIDERS_CONFIG.ollama.hint = `(This will download and run a local instance of ${defaultOllamaModel})`;
const aiProvidersEnvVars: Record<string, string> = {};
const configurableAiProviders = selectedLlmProviders.filter(
(provider: AiProviders) => AI_PROVIDERS_CONFIG[provider].envVar
Expand Down
12 changes: 6 additions & 6 deletions src/lib/actions/BaseAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,27 +42,27 @@ export class BaseAction extends ConfigFileManager {

protected log(message: string, data?: any): void {
console.log(chalk.white(`\n${message}`));
if (data) console.log(this.formatOutput(data));
if (data !== undefined) console.log(this.formatOutput(data));
}

protected logSuccess(message: string, data?: any): void {
console.log(chalk.green(`\n✔ ${message}`));
if (data) console.log(chalk.green(this.formatOutput(data)));
if (data !== undefined) console.log(chalk.green(this.formatOutput(data)));
}

protected logInfo(message: string, data?: any): void {
console.log(chalk.blue(`\nℹ ${message}`));
if (data) console.log(chalk.blue(this.formatOutput(data)));
if (data !== undefined) console.log(chalk.blue(this.formatOutput(data)));
}

protected logWarning(message: string, data?: any): void {
console.log(chalk.yellow(`\n⚠ ${message}`));
if (data) console.log(chalk.yellow(this.formatOutput(data)));
if (data !== undefined) console.log(chalk.yellow(this.formatOutput(data)));
}

protected logError(message: string, error?: any): void {
console.error(chalk.red(`\n✖ ${message}`));
if (error) console.error(chalk.red(this.formatOutput(error)));
if (error !== undefined) console.error(chalk.red(this.formatOutput(error)));
}

protected startSpinner(message: string) {
Expand All @@ -71,7 +71,7 @@ export class BaseAction extends ConfigFileManager {
}

protected succeedSpinner(message: string, data?: any): void {
if (data) this.log('Result:', data);
if (data !== undefined) this.log('Result:', data);
this.spinner.succeed(chalk.green(message));
}

Expand Down
2 changes: 1 addition & 1 deletion src/lib/config/simulator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export type AiProvidersConfigType = {
export const AI_PROVIDERS_CONFIG: AiProvidersConfigType = {
ollama: {
name: "Ollama",
hint: "(This will download and run a local instance of Llama 3)",
hint: "(By default, this will download and run a local instance of Llama 3)",
cliOptionValue: "ollama",
},
openai: {
Expand Down
Loading