diff --git a/src/modules/deployer/controllers/deployer.controller.ts b/src/modules/deployer/controllers/deployer.controller.ts index 19ef013..78fb8f8 100644 --- a/src/modules/deployer/controllers/deployer.controller.ts +++ b/src/modules/deployer/controllers/deployer.controller.ts @@ -1,6 +1,24 @@ -import { Controller } from "@nestjs/common"; +import { Body, Controller, Get, Post } from "@nestjs/common"; +import { DeployerService } from "../services"; +import { ConfigService } from "@nestjs/config"; +import { DeployerDto } from "../dtos"; -@Controller() +@Controller('contract') export class DeployerController { - // Controller methods go here + constructor( + private readonly service: DeployerService, + private readonly config: ConfigService, + ){} + + @Post() + async createContract(@Body() dto: DeployerDto) { + return this.service.createContract(dto); + } + + @Get() + async getContracts(){ + return this.service.getContracts(); + } + + } \ No newline at end of file diff --git a/src/modules/deployer/deployer.module.ts b/src/modules/deployer/deployer.module.ts index 9abb126..902078b 100644 --- a/src/modules/deployer/deployer.module.ts +++ b/src/modules/deployer/deployer.module.ts @@ -1,9 +1,11 @@ import { Module } from "@nestjs/common"; +import { DeployerController } from "./controllers"; +import { DeployerService } from "./services"; @Module({ imports: [], - controllers: [], - providers: [], + controllers: [DeployerController], + providers: [DeployerService], exports: [], }) export class DeployerModule {} \ No newline at end of file diff --git a/src/modules/deployer/dtos/deployer.dto.ts b/src/modules/deployer/dtos/deployer.dto.ts new file mode 100644 index 0000000..9156db4 --- /dev/null +++ b/src/modules/deployer/dtos/deployer.dto.ts @@ -0,0 +1,9 @@ +import { Transform } from "class-transformer"; +import { IsNotEmpty, IsString } from "class-validator"; + +export class DeployerDto { + @IsNotEmpty({ message: 'Contract name is required' }) + @IsString({ message: 'Contract name must be a string' }) + @Transform(({ value }) => value.toString()) + contractName: string; +} \ No newline at end of file diff --git a/src/modules/deployer/dtos/index.ts b/src/modules/deployer/dtos/index.ts index e69de29..9f783b2 100644 --- a/src/modules/deployer/dtos/index.ts +++ b/src/modules/deployer/dtos/index.ts @@ -0,0 +1 @@ +export * from './deployer.dto'; \ No newline at end of file diff --git a/src/modules/deployer/services/deployer.service.ts b/src/modules/deployer/services/deployer.service.ts index 0df24c9..ddbd743 100644 --- a/src/modules/deployer/services/deployer.service.ts +++ b/src/modules/deployer/services/deployer.service.ts @@ -1,6 +1,102 @@ import { Injectable } from "@nestjs/common"; +import { ConfigService } from "@nestjs/config"; +import { ProviderService } from "src/common/utils"; +import { PostgresService } from "src/core/psql/postgres.service"; +import { DeployerDto } from "../dtos"; +import { ethers } from "ethers"; +import { Contract } from "../types"; @Injectable() export class DeployerService { - // Service methods go here + constructor( + private readonly config: ConfigService, + private readonly db: PostgresService, + private readonly provider: ProviderService + ){} + + async createContract(dto: DeployerDto) { + try{ + const { provider, wallet } = await this.provider.getProviderAndWallet(); + if (!provider || !wallet) { + throw new Error('Provider or wallet not initialized'); + } + + const {abi, bytecode} = await this.provider.getAbiAndBytecode(); + if (!abi) { + throw new Error('ABI not found'); + } + + const contract = new ethers.ContractFactory( + abi, + bytecode, + wallet + ); + + const contractInstance = await contract.deploy( dto.contractName ,{ + value: ethers.toBigInt(0), + maxFeePerGas: 1000n, + maxPriorityFeePerGas: 0n, + gasLimit: 3_000_000, + chainId: (await provider.getNetwork()).chainId, + }); + + await contractInstance.waitForDeployment(); + const deployedAddress = await contractInstance.getAddress(); + + const contractData: Contract = { + contractaddress: deployedAddress, + useraddress: wallet.address.toLowerCase(), + } + + await this.db.insert('contracts', contractData); + + return { + status: 'success', + message: 'Contract created successfully at address: ' + deployedAddress, + }; + + } catch (error) { + return { + statusCode: error.statusCode, + message: error.message || 'Contract creation failed', + }; + } + } + + async getContracts() { + const { provider, wallet } = await this.provider.getProviderAndWallet(); + if (!provider || !wallet) { + throw new Error('Provider or wallet not initialized'); + } + + const contractList = await this.db.getAll('contracts', { + useraddress: wallet.address.toLowerCase(), + }); + + if (contractList.length === 0) { + return 'No contracts found'; + } + + const { abi } = await this.provider.getAbiAndBytecode(); + if (!abi) { + throw new Error('ABI not found'); + } + + const contractsWithTx = await Promise.all(contractList.map(async contract => { + const contractInstance = new ethers.Contract(contract.contractaddress, abi, provider); + let contractName = ''; + try { + contractName = await contractInstance.getName(); + } catch (err) { + contractName = 'Unknown'; + } + return { + contractAddress: contract.contractaddress, + contractName, + contractBalance: (await provider.getBalance(contract.contractaddress)).toString() + }; + })); + + return contractsWithTx; + } } \ No newline at end of file diff --git a/src/modules/module.module.ts b/src/modules/module.module.ts index a924c08..b9388b7 100644 --- a/src/modules/module.module.ts +++ b/src/modules/module.module.ts @@ -1,6 +1,7 @@ import { Module } from "@nestjs/common"; +import { DeployerModule } from "./deployer/deployer.module"; @Module({ - imports: [] + imports: [DeployerModule] }) export class ModulesModule {} \ No newline at end of file