mirror of
https://github.com/emo2007/block-accounting.git
synced 2025-01-18 15:36:27 +00:00
multisig fully ready + salaries almost ready.
refactor contracts and refactor structure of app. swagger update
This commit is contained in:
parent
ed2f6b9eca
commit
9ec370c8f6
@ -1,7 +1,7 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { AppController } from './app.controller';
|
import { AppController } from './app.controller';
|
||||||
import { AppService } from './app.service';
|
import { AppService } from './app.service';
|
||||||
import { ContractFactoryModule } from './contract-factory/contract-factory.module';
|
|
||||||
import { ContractInteractModule } from './contract-interact/contract-interact.module';
|
import { ContractInteractModule } from './contract-interact/contract-interact.module';
|
||||||
import { ConfigModule } from '@nestjs/config';
|
import { ConfigModule } from '@nestjs/config';
|
||||||
|
|
||||||
@ -10,7 +10,6 @@ import { ConfigModule } from '@nestjs/config';
|
|||||||
ConfigModule.forRoot({
|
ConfigModule.forRoot({
|
||||||
isGlobal: true,
|
isGlobal: true,
|
||||||
}),
|
}),
|
||||||
ContractFactoryModule,
|
|
||||||
ContractInteractModule,
|
ContractInteractModule,
|
||||||
],
|
],
|
||||||
controllers: [AppController],
|
controllers: [AppController],
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
import { Test, TestingModule } from '@nestjs/testing';
|
|
||||||
import { ContractFactoryController } from './contract-factory.controller';
|
|
||||||
import { ContractFactoryService } from './contract-factory.service';
|
|
||||||
|
|
||||||
describe('ContractFactoryController', () => {
|
|
||||||
let controller: ContractFactoryController;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
const module: TestingModule = await Test.createTestingModule({
|
|
||||||
controllers: [ContractFactoryController],
|
|
||||||
providers: [ContractFactoryService],
|
|
||||||
}).compile();
|
|
||||||
|
|
||||||
controller = module.get<ContractFactoryController>(ContractFactoryController);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be defined', () => {
|
|
||||||
expect(controller).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,26 +0,0 @@
|
|||||||
import {
|
|
||||||
Controller,
|
|
||||||
Get,
|
|
||||||
Post,
|
|
||||||
Body,
|
|
||||||
Patch,
|
|
||||||
Param,
|
|
||||||
Delete,
|
|
||||||
} from '@nestjs/common';
|
|
||||||
import { ContractFactoryService } from './contract-factory.service';
|
|
||||||
import { CreateContractFactoryDto } from './dto/create-contract-factory.dto';
|
|
||||||
import { UpdateContractFactoryDto } from './dto/update-contract-factory.dto';
|
|
||||||
import { ApiTags } from '@nestjs/swagger';
|
|
||||||
import { MultiSigWalletDto } from 'src/hardhat/modules/dto/multi-sig.dto';
|
|
||||||
@ApiTags('contract-factory')
|
|
||||||
@Controller('contract-factory')
|
|
||||||
export class ContractFactoryController {
|
|
||||||
constructor(
|
|
||||||
private readonly contractFactoryService: ContractFactoryService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
@Post('multi-sig')
|
|
||||||
create(@Body() createContractFactoryDto: MultiSigWalletDto) {
|
|
||||||
return this.contractFactoryService.createMultiSig(createContractFactoryDto);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
import { HardhatModule } from '../hardhat/modules/hardhat.module';
|
|
||||||
import { Module } from '@nestjs/common';
|
|
||||||
import { ContractFactoryService } from './contract-factory.service';
|
|
||||||
import { ContractFactoryController } from './contract-factory.controller';
|
|
||||||
|
|
||||||
@Module({
|
|
||||||
imports: [HardhatModule],
|
|
||||||
controllers: [ContractFactoryController],
|
|
||||||
providers: [ContractFactoryService],
|
|
||||||
})
|
|
||||||
export class ContractFactoryModule {}
|
|
@ -1,18 +0,0 @@
|
|||||||
import { Test, TestingModule } from '@nestjs/testing';
|
|
||||||
import { ContractFactoryService } from './contract-factory.service';
|
|
||||||
|
|
||||||
describe('ContractFactoryService', () => {
|
|
||||||
let service: ContractFactoryService;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
const module: TestingModule = await Test.createTestingModule({
|
|
||||||
providers: [ContractFactoryService],
|
|
||||||
}).compile();
|
|
||||||
|
|
||||||
service = module.get<ContractFactoryService>(ContractFactoryService);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be defined', () => {
|
|
||||||
expect(service).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,21 +0,0 @@
|
|||||||
import { HardhatService } from '../hardhat/modules/hardhat.service';
|
|
||||||
import { Injectable } from '@nestjs/common';
|
|
||||||
import { CreateContractFactoryDto } from './dto/create-contract-factory.dto';
|
|
||||||
import { SalariesService } from 'src/hardhat/modules/salary.service';
|
|
||||||
import { MultiSigWalletService } from 'src/hardhat/modules/multi-sig/multi-sig.service';
|
|
||||||
import { MultiSigWalletDto } from 'src/hardhat/modules/dto/multi-sig.dto';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class ContractFactoryService {
|
|
||||||
constructor(
|
|
||||||
private readonly salaryService: SalariesService,
|
|
||||||
private readonly multiSigService: MultiSigWalletService,
|
|
||||||
) {}
|
|
||||||
async createSalary(createContractFactoryDto: CreateContractFactoryDto) {
|
|
||||||
return await this.salaryService.deploy();
|
|
||||||
}
|
|
||||||
|
|
||||||
async createMultiSig(dto: MultiSigWalletDto) {
|
|
||||||
return await this.multiSigService.deploy(dto);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
import { ApiProperty } from '@nestjs/swagger';
|
|
||||||
export enum ContractType {
|
|
||||||
SALARY,
|
|
||||||
AGREEMENT,
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CreateContractFactoryDto {
|
|
||||||
@ApiProperty({
|
|
||||||
enum: ContractType,
|
|
||||||
})
|
|
||||||
contractType: ContractType;
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
import { PartialType } from '@nestjs/mapped-types';
|
|
||||||
import { CreateContractFactoryDto } from './create-contract-factory.dto';
|
|
||||||
|
|
||||||
export class UpdateContractFactoryDto extends PartialType(CreateContractFactoryDto) {}
|
|
@ -1,20 +0,0 @@
|
|||||||
import { Test, TestingModule } from '@nestjs/testing';
|
|
||||||
import { ContractInteractController } from './contract-interact.controller';
|
|
||||||
import { ContractInteractService } from './contract-interact.service';
|
|
||||||
|
|
||||||
describe('ContractInteractController', () => {
|
|
||||||
let controller: ContractInteractController;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
const module: TestingModule = await Test.createTestingModule({
|
|
||||||
controllers: [ContractInteractController],
|
|
||||||
providers: [ContractInteractService],
|
|
||||||
}).compile();
|
|
||||||
|
|
||||||
controller = module.get<ContractInteractController>(ContractInteractController);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be defined', () => {
|
|
||||||
expect(controller).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,12 +1,9 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { ContractInteractService } from './contract-interact.service';
|
|
||||||
|
|
||||||
import { HardhatModule } from 'src/hardhat/modules/hardhat.module';
|
import { HardhatModule } from 'src/hardhat/modules/hardhat.module';
|
||||||
import { MultiSigInteractController } from './multi-sig-interact.controller';
|
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [HardhatModule],
|
imports: [HardhatModule],
|
||||||
controllers: [MultiSigInteractController],
|
controllers: [],
|
||||||
providers: [ContractInteractService],
|
providers: [],
|
||||||
})
|
})
|
||||||
export class ContractInteractModule {}
|
export class ContractInteractModule {}
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
import { Test, TestingModule } from '@nestjs/testing';
|
|
||||||
import { ContractInteractService } from './contract-interact.service';
|
|
||||||
|
|
||||||
describe('ContractInteractService', () => {
|
|
||||||
let service: ContractInteractService;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
const module: TestingModule = await Test.createTestingModule({
|
|
||||||
providers: [ContractInteractService],
|
|
||||||
}).compile();
|
|
||||||
|
|
||||||
service = module.get<ContractInteractService>(ContractInteractService);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be defined', () => {
|
|
||||||
expect(service).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,26 +0,0 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
|
||||||
import { CreateContractInteractDto } from './dto/create-contract-interact.dto';
|
|
||||||
import { UpdateContractInteractDto } from './dto/update-contract-interact.dto';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class ContractInteractService {
|
|
||||||
create(createContractInteractDto: CreateContractInteractDto) {
|
|
||||||
return 'This action adds a new contractInteract';
|
|
||||||
}
|
|
||||||
|
|
||||||
findAll() {
|
|
||||||
return `This action returns all contractInteract`;
|
|
||||||
}
|
|
||||||
|
|
||||||
findOne(id: number) {
|
|
||||||
return `This action returns a #${id} contractInteract`;
|
|
||||||
}
|
|
||||||
|
|
||||||
update(id: number, updateContractInteractDto: UpdateContractInteractDto) {
|
|
||||||
return `This action updates a #${id} contractInteract`;
|
|
||||||
}
|
|
||||||
|
|
||||||
remove(id: number) {
|
|
||||||
return `This action removes a #${id} contractInteract`;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { IsOptional, IsString } from 'class-validator';
|
import { IsNumber, IsOptional, IsString } from 'class-validator';
|
||||||
|
|
||||||
export class SubmitTransactionDto {
|
export class SubmitTransactionDto {
|
||||||
@IsString()
|
@IsString()
|
||||||
@ -16,3 +16,29 @@ export class SubmitTransactionDto {
|
|||||||
// @ApiProperty()
|
// @ApiProperty()
|
||||||
data: string;
|
data: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ConfirmTransactionDto {
|
||||||
|
@IsString()
|
||||||
|
@ApiProperty()
|
||||||
|
contractAddress: string;
|
||||||
|
@ApiProperty()
|
||||||
|
@IsNumber()
|
||||||
|
index: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ExecuteTransactionDto extends ConfirmTransactionDto {}
|
||||||
|
|
||||||
|
export class RevokeConfirmationDto extends ConfirmTransactionDto {}
|
||||||
|
|
||||||
|
export class GetTransactionCount {}
|
||||||
|
|
||||||
|
export class GetTransactionDto extends ConfirmTransactionDto {}
|
||||||
|
|
||||||
|
export class DepositMultiSigDto {
|
||||||
|
@IsString()
|
||||||
|
@ApiProperty()
|
||||||
|
contractAddress: string;
|
||||||
|
@IsString()
|
||||||
|
@ApiProperty()
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
10
chain-api/src/contract-interact/ethers.helpers.ts
Normal file
10
chain-api/src/contract-interact/ethers.helpers.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { TransactionReceipt, ethers } from 'ethers';
|
||||||
|
|
||||||
|
export const parseLogs = (
|
||||||
|
txReceipt: TransactionReceipt,
|
||||||
|
contract: ethers.Contract,
|
||||||
|
) => {
|
||||||
|
return txReceipt.logs
|
||||||
|
.map((log) => contract.interface.parseLog(log))
|
||||||
|
.find((log) => !!log);
|
||||||
|
};
|
@ -1,20 +0,0 @@
|
|||||||
import { Body, Controller, Get, Param, Post } from '@nestjs/common';
|
|
||||||
import { ApiOkResponse, ApiTags } from '@nestjs/swagger';
|
|
||||||
import { MultiSigWalletService } from 'src/hardhat/modules/multi-sig/multi-sig.service';
|
|
||||||
import { SubmitTransactionDto } from './dto/multi-sig.dto';
|
|
||||||
@ApiTags('multi-sig-interact')
|
|
||||||
@Controller()
|
|
||||||
export class MultiSigInteractController {
|
|
||||||
constructor(private readonly multiSigWalletService: MultiSigWalletService) {}
|
|
||||||
|
|
||||||
@Get('owners/:address')
|
|
||||||
async getOwners(@Param('address') address: string) {
|
|
||||||
return this.multiSigWalletService.getOwners(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ApiOkResponse()
|
|
||||||
@Post('submit-transaction')
|
|
||||||
async submitTransaction(@Body() dto: SubmitTransactionDto) {
|
|
||||||
return this.multiSigWalletService.submitTransaction(dto);
|
|
||||||
}
|
|
||||||
}
|
|
33
chain-api/src/filters/http.filter.ts
Normal file
33
chain-api/src/filters/http.filter.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import {
|
||||||
|
ArgumentsHost,
|
||||||
|
Catch,
|
||||||
|
ExceptionFilter,
|
||||||
|
HttpException,
|
||||||
|
HttpStatus,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { error } from 'console';
|
||||||
|
import { Request, Response } from 'express';
|
||||||
|
|
||||||
|
@Catch()
|
||||||
|
export class AllExceptionsFilter implements ExceptionFilter {
|
||||||
|
// constructor(private readonly httpAdapterHost: HttpAdapterHost) {}
|
||||||
|
|
||||||
|
catch(exception: any, host: ArgumentsHost): void {
|
||||||
|
console.log('🚀 ~ AllExceptionsFilter ~ exception:', exception);
|
||||||
|
const ctx = host.switchToHttp();
|
||||||
|
const response = ctx.getResponse<Response>();
|
||||||
|
const request = ctx.getRequest<Request>();
|
||||||
|
const httpStatus =
|
||||||
|
exception instanceof HttpException
|
||||||
|
? exception.getStatus()
|
||||||
|
: HttpStatus.INTERNAL_SERVER_ERROR;
|
||||||
|
|
||||||
|
const responseBody = {
|
||||||
|
statusCode: httpStatus,
|
||||||
|
error: exception?.info?.error.message || exception.toString(),
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
response.status(500).json(responseBody);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
License
|
||||||
|
sender
|
||||||
|
receiver
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
@ -9,6 +9,7 @@ contract Salaries {
|
|||||||
address public multisigWallet;
|
address public multisigWallet;
|
||||||
mapping(address => uint) public salaries;
|
mapping(address => uint) public salaries;
|
||||||
|
|
||||||
|
//0xF0d50568e3A7e8259E16663972b11910F89BD8e7
|
||||||
constructor(address _multisigWallet, address _priceFeedAddress) {
|
constructor(address _multisigWallet, address _priceFeedAddress) {
|
||||||
multisigWallet = _multisigWallet;
|
multisigWallet = _multisigWallet;
|
||||||
dataFeed = AggregatorV3Interface(_priceFeedAddress);
|
dataFeed = AggregatorV3Interface(_priceFeedAddress);
|
||||||
@ -19,6 +20,10 @@ contract Salaries {
|
|||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSalary(address employee) public view returns(uint) {
|
||||||
|
return salaries[employee];
|
||||||
|
}
|
||||||
|
|
||||||
function getLatestUSDTPriceInETH() public view returns (int) {
|
function getLatestUSDTPriceInETH() public view returns (int) {
|
||||||
(
|
(
|
||||||
,
|
,
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
|
|
||||||
|
|
||||||
const JAN_1ST_2030 = 1893456000;
|
|
||||||
const ONE_GWEI: bigint = 1_000_000_000n;
|
|
||||||
|
|
||||||
const LockModule = buildModule("LockModule", (m) => {
|
|
||||||
const unlockTime = m.getParameter("unlockTime", JAN_1ST_2030);
|
|
||||||
const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI);
|
|
||||||
|
|
||||||
const lock = m.contract("Lock", [unlockTime], {
|
|
||||||
value: lockedAmount,
|
|
||||||
});
|
|
||||||
|
|
||||||
return { lock };
|
|
||||||
});
|
|
||||||
|
|
||||||
export default LockModule;
|
|
@ -1,17 +0,0 @@
|
|||||||
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
|
|
||||||
|
|
||||||
const JAN_1ST_2030 = 1893456000;
|
|
||||||
const ONE_GWEI: bigint = 1_000_000_000n;
|
|
||||||
|
|
||||||
const owners = ["0xfE87F7EF2a58a1f363a444332df6c131C683e35f"];
|
|
||||||
|
|
||||||
const MultiSigModule = buildModule("MultiSigWallet", (m) => {
|
|
||||||
const ownerP = m.getParameter("owners", owners);
|
|
||||||
const confirmationsP = m.getParameter("_numConfirmationsRequired", 1);
|
|
||||||
|
|
||||||
const deploy = m.contract("MultiSigWallet", [ownerP, confirmationsP]);
|
|
||||||
|
|
||||||
return { deploy };
|
|
||||||
});
|
|
||||||
|
|
||||||
export default MultiSigModule;
|
|
@ -1,11 +0,0 @@
|
|||||||
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
|
|
||||||
//npx hardhat ignition deploy ignition/modules/Salaries.ts --network amoy
|
|
||||||
//SalariesModule#Salaries - 0xac45e95Dd5C7F9B1a6C3e4883d04952B9C974b05
|
|
||||||
const SalariesModule = buildModule("SalariesModule", (m) => {
|
|
||||||
const salaryContract = m.contract("Salaries");
|
|
||||||
|
|
||||||
const answer = m.call(salaryContract, "getChainlinkDataFeedLatestAnswer", []);
|
|
||||||
console.log("🚀 ~ SalariesModule ~ answer:", answer);
|
|
||||||
return { salaryContract };
|
|
||||||
});
|
|
||||||
export default SalariesModule;
|
|
@ -4,9 +4,6 @@ import { ProviderService } from 'src/provider/provider.service';
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export abstract class BaseContractService {
|
export abstract class BaseContractService {
|
||||||
constructor(
|
constructor(public readonly providerService: ProviderService) {}
|
||||||
public readonly configService: ConfigService,
|
|
||||||
public readonly providerService: ProviderService,
|
|
||||||
) {}
|
|
||||||
abstract deploy(dto: object): Promise<any>;
|
abstract deploy(dto: object): Promise<any>;
|
||||||
}
|
}
|
||||||
|
60
chain-api/src/hardhat/modules/dto/ethers.dto.ts
Normal file
60
chain-api/src/hardhat/modules/dto/ethers.dto.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import { ethers } from 'ethers';
|
||||||
|
|
||||||
|
// Define a TypeScript type for the EventLog based on the provided structure
|
||||||
|
export type TransactionLogs = {
|
||||||
|
provider: ethers.JsonRpcApiProvider;
|
||||||
|
transactionHash: string;
|
||||||
|
blockHash: string;
|
||||||
|
blockNumber: number;
|
||||||
|
removed: boolean | undefined;
|
||||||
|
address: string;
|
||||||
|
data: string;
|
||||||
|
topics: string[];
|
||||||
|
index: number;
|
||||||
|
transactionIndex: number;
|
||||||
|
interface: Interface;
|
||||||
|
fragment: EventFragment;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Interface = {
|
||||||
|
fragments: Fragment[];
|
||||||
|
deploy: ConstructorFragment[];
|
||||||
|
fallback: any | null;
|
||||||
|
receive: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Fragment = {};
|
||||||
|
|
||||||
|
type ConstructorFragment = {};
|
||||||
|
|
||||||
|
type EventFragment = {
|
||||||
|
type: string;
|
||||||
|
inputs: any[];
|
||||||
|
name: string;
|
||||||
|
anonymous: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
type SubmitArgs = {
|
||||||
|
args: [
|
||||||
|
owner: string,
|
||||||
|
txIndex: bigint,
|
||||||
|
to: string,
|
||||||
|
value: bigint,
|
||||||
|
data: string,
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
type ConfirmArgs = {
|
||||||
|
args: [owner: string, txIndex: bigint];
|
||||||
|
};
|
||||||
|
type ExecuteArgs = {
|
||||||
|
args: [owner: string, txIndex: bigint];
|
||||||
|
};
|
||||||
|
type DepositArgs = {
|
||||||
|
args: [owner: string, value: bigint, address: string];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SubmitTransactionLogs = TransactionLogs & SubmitArgs;
|
||||||
|
export type ConfirmTransactionLogs = TransactionLogs & ConfirmArgs;
|
||||||
|
export type ExecuteTransactionLogs = TransactionLogs & ExecuteArgs;
|
||||||
|
export type DepositLogs = TransactionLogs & DepositArgs;
|
@ -1,15 +1,13 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { HardhatService } from './hardhat.service';
|
import { HardhatService } from './hardhat.service';
|
||||||
import { ProviderModule } from 'src/provider/provider.module';
|
import { ProviderModule } from 'src/provider/provider.module';
|
||||||
import { MultiSigWalletService } from './multi-sig/multi-sig.service';
|
|
||||||
import { SalariesService } from './salary.service';
|
|
||||||
import { BaseContractService } from './base-contract.service';
|
|
||||||
import { MultiSigModule } from './multi-sig/multi-sig.module';
|
import { MultiSigModule } from './multi-sig/multi-sig.module';
|
||||||
|
import { SalariesModule } from './salaries/salaries.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [ProviderModule, MultiSigModule],
|
imports: [ProviderModule, MultiSigModule, SalariesModule],
|
||||||
controllers: [],
|
controllers: [],
|
||||||
providers: [HardhatService, SalariesService],
|
providers: [HardhatService],
|
||||||
exports: [HardhatService, SalariesService, MultiSigModule],
|
exports: [HardhatService, MultiSigModule, SalariesModule],
|
||||||
})
|
})
|
||||||
export class HardhatModule {}
|
export class HardhatModule {}
|
||||||
|
@ -0,0 +1,65 @@
|
|||||||
|
import { Body, Controller, Get, Param, Post } from '@nestjs/common';
|
||||||
|
import { ApiOkResponse, ApiTags } from '@nestjs/swagger';
|
||||||
|
import { MultiSigWalletService } from 'src/hardhat/modules/multi-sig/multi-sig.service';
|
||||||
|
import {
|
||||||
|
ConfirmTransactionDto,
|
||||||
|
DepositMultiSigDto,
|
||||||
|
ExecuteTransactionDto,
|
||||||
|
GetTransactionDto,
|
||||||
|
RevokeConfirmationDto,
|
||||||
|
SubmitTransactionDto,
|
||||||
|
} from '../../../contract-interact/dto/multi-sig.dto';
|
||||||
|
import { MultiSigWalletDto } from './multi-sig.dto';
|
||||||
|
@ApiTags('multi-sig')
|
||||||
|
@Controller('multi-sig')
|
||||||
|
export class MultiSigInteractController {
|
||||||
|
constructor(private readonly multiSigWalletService: MultiSigWalletService) {}
|
||||||
|
|
||||||
|
@Post('deploy')
|
||||||
|
async deploy(@Body() dto: MultiSigWalletDto) {
|
||||||
|
return this.multiSigWalletService.deploy(dto);
|
||||||
|
}
|
||||||
|
@Get('owners/:address')
|
||||||
|
async getOwners(@Param('address') address: string) {
|
||||||
|
return this.multiSigWalletService.getOwners(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOkResponse()
|
||||||
|
@Post('submit-transaction')
|
||||||
|
async submitTransaction(@Body() dto: SubmitTransactionDto) {
|
||||||
|
return this.multiSigWalletService.submitTransaction(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOkResponse()
|
||||||
|
@Post('confirm-transaction')
|
||||||
|
async confirmTransaction(@Body() dto: ConfirmTransactionDto) {
|
||||||
|
return this.multiSigWalletService.confirmTransaction(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOkResponse()
|
||||||
|
@Post('execute-transaction')
|
||||||
|
async executeTransaction(@Body() dto: ExecuteTransactionDto) {
|
||||||
|
return this.multiSigWalletService.executeTransaction(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOkResponse()
|
||||||
|
@Post('revoke-confirmation')
|
||||||
|
async revokeConfirmation(@Body() dto: RevokeConfirmationDto) {
|
||||||
|
return this.multiSigWalletService.revokeConfirmation(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('transaction-count/:contractAddress')
|
||||||
|
async getTransactionCount(@Param('contractAddress') contractAddress: string) {
|
||||||
|
return this.multiSigWalletService.getTransactionCount(contractAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('transaction')
|
||||||
|
async getTransaction(@Body() dto: GetTransactionDto) {
|
||||||
|
return this.multiSigWalletService.getTransaction(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('deposit')
|
||||||
|
async deposit(@Body() dto: DepositMultiSigDto) {
|
||||||
|
return this.multiSigWalletService.deposit(dto);
|
||||||
|
}
|
||||||
|
}
|
@ -5,10 +5,11 @@ import { ProviderModule } from 'src/provider/provider.module';
|
|||||||
import { BaseContractService } from '../base-contract.service';
|
import { BaseContractService } from '../base-contract.service';
|
||||||
import { ProviderService } from 'src/provider/provider.service';
|
import { ProviderService } from 'src/provider/provider.service';
|
||||||
import { MultiSigWalletService } from './multi-sig.service';
|
import { MultiSigWalletService } from './multi-sig.service';
|
||||||
|
import { MultiSigInteractController } from './multi-sig-interact.controller';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [ProviderModule],
|
imports: [ProviderModule],
|
||||||
controllers: [],
|
controllers: [MultiSigInteractController],
|
||||||
providers: [MultiSigWalletService],
|
providers: [MultiSigWalletService],
|
||||||
exports: [MultiSigWalletService],
|
exports: [MultiSigWalletService],
|
||||||
})
|
})
|
||||||
|
@ -1,11 +1,23 @@
|
|||||||
import { MultiSigWallet } from '../../typechain-types/contracts/MultiSigWallet';
|
import { TransactionReceipt, ethers } from 'ethers';
|
||||||
import { Injectable } from '@nestjs/common';
|
|
||||||
import { ethers } from 'ethers';
|
|
||||||
import { ConfigService } from '@nestjs/config';
|
import { ConfigService } from '@nestjs/config';
|
||||||
import * as hre from 'hardhat';
|
import * as hre from 'hardhat';
|
||||||
import { BaseContractService } from '../base-contract.service';
|
import { BaseContractService } from '../base-contract.service';
|
||||||
import { MultiSigWalletDto } from '../dto/multi-sig.dto';
|
import { MultiSigWalletDto } from './multi-sig.dto';
|
||||||
import { SubmitTransactionDto } from 'src/contract-interact/dto/multi-sig.dto';
|
import {
|
||||||
|
ConfirmTransactionDto,
|
||||||
|
DepositMultiSigDto,
|
||||||
|
ExecuteTransactionDto,
|
||||||
|
GetTransactionDto,
|
||||||
|
RevokeConfirmationDto,
|
||||||
|
SubmitTransactionDto,
|
||||||
|
} from 'src/contract-interact/dto/multi-sig.dto';
|
||||||
|
import {
|
||||||
|
ConfirmTransactionLogs,
|
||||||
|
DepositLogs,
|
||||||
|
ExecuteTransactionLogs,
|
||||||
|
SubmitTransactionLogs,
|
||||||
|
} from 'src/hardhat/modules/dto/ethers.dto';
|
||||||
|
import { parseLogs } from 'src/contract-interact/ethers.helpers';
|
||||||
|
|
||||||
export class MultiSigWalletService extends BaseContractService {
|
export class MultiSigWalletService extends BaseContractService {
|
||||||
async deploy(dto: MultiSigWalletDto) {
|
async deploy(dto: MultiSigWalletDto) {
|
||||||
@ -21,13 +33,8 @@ export class MultiSigWalletService extends BaseContractService {
|
|||||||
dto.confirmations,
|
dto.confirmations,
|
||||||
);
|
);
|
||||||
await myContract.waitForDeployment();
|
await myContract.waitForDeployment();
|
||||||
|
|
||||||
console.log(
|
|
||||||
'🚀 ~ HardhatService ~ deploySalaryContract ~ myContract:',
|
|
||||||
myContract,
|
|
||||||
);
|
|
||||||
const address = myContract.getAddress();
|
const address = myContract.getAddress();
|
||||||
console.log('🚀 ~ SalariesService ~ deploy ~ address:', address);
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getOwners(address: string) {
|
async getOwners(address: string) {
|
||||||
@ -46,23 +53,119 @@ export class MultiSigWalletService extends BaseContractService {
|
|||||||
async submitTransaction(dto: SubmitTransactionDto) {
|
async submitTransaction(dto: SubmitTransactionDto) {
|
||||||
const { destination, value, data, contractAddress } = dto;
|
const { destination, value, data, contractAddress } = dto;
|
||||||
const { abi } = await hre.artifacts.readArtifact('MultiSigWallet');
|
const { abi } = await hre.artifacts.readArtifact('MultiSigWallet');
|
||||||
const multiSigContract = new ethers.Contract(contractAddress, abi);
|
|
||||||
|
|
||||||
const signer = await this.providerService.getSigner();
|
const signer = await this.providerService.getSigner();
|
||||||
|
|
||||||
const contract = new ethers.Contract(contractAddress, abi, signer);
|
const contract = new ethers.Contract(contractAddress, abi, signer);
|
||||||
console.log(
|
|
||||||
'🚀 ~ MultiSigWalletService ~ submitTransaction ~ contract:',
|
|
||||||
contract.interface,
|
|
||||||
);
|
|
||||||
|
|
||||||
const tx = await contract.submitTransaction(
|
const tx = await contract.submitTransaction(destination, value, data);
|
||||||
destination,
|
const txResponse: TransactionReceipt = await tx.wait();
|
||||||
value,
|
|
||||||
new TextEncoder().encode(data),
|
const eventParse = parseLogs(txResponse, contract);
|
||||||
);
|
|
||||||
console.log('🚀 ~ MultiSigWalletService ~ submitTransaction ~ tx:', tx);
|
return {
|
||||||
|
txHash: txResponse.hash,
|
||||||
|
sender: eventParse.args[0].toString(),
|
||||||
|
txIndex: eventParse.args[1].toString(),
|
||||||
|
to: eventParse.args[2].toString(),
|
||||||
|
value: eventParse.args[3].toString(),
|
||||||
|
data: eventParse.args[4].toString(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async confirmTransaction(dto: ConfirmTransactionDto) {
|
||||||
|
const { contractAddress, index } = dto;
|
||||||
|
const { abi } = await hre.artifacts.readArtifact('MultiSigWallet');
|
||||||
|
const signer = await this.providerService.getSigner();
|
||||||
|
|
||||||
|
const contract = new ethers.Contract(contractAddress, abi, signer);
|
||||||
|
|
||||||
|
const tx = await contract.confirmTransaction(index);
|
||||||
|
|
||||||
|
const txResponse: TransactionReceipt = await tx.wait();
|
||||||
|
|
||||||
|
const eventParse = parseLogs(txResponse, contract);
|
||||||
|
|
||||||
|
return {
|
||||||
|
txHash: txResponse.hash,
|
||||||
|
sender: eventParse.args[0].toString(),
|
||||||
|
txIndex: eventParse.args[1].toString(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async executeTransaction(dto: ExecuteTransactionDto) {
|
||||||
|
const { index, contractAddress } = dto;
|
||||||
|
const { abi } = await hre.artifacts.readArtifact('MultiSigWallet');
|
||||||
|
const signer = await this.providerService.getSigner();
|
||||||
|
|
||||||
|
const contract = new ethers.Contract(contractAddress, abi, signer);
|
||||||
|
|
||||||
|
const tx = await contract.executeTransaction(index);
|
||||||
|
|
||||||
|
const txResponse: TransactionReceipt = await tx.wait();
|
||||||
|
const eventParse = parseLogs(txResponse, contract);
|
||||||
|
return {
|
||||||
|
txHash: txResponse.hash,
|
||||||
|
sender: eventParse.args[0].toString(),
|
||||||
|
txIndex: eventParse.args[1].toString(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async revokeConfirmation(dto: RevokeConfirmationDto) {
|
||||||
|
const { index, contractAddress } = dto;
|
||||||
|
const { abi } = await hre.artifacts.readArtifact('MultiSigWallet');
|
||||||
|
const signer = await this.providerService.getSigner();
|
||||||
|
|
||||||
|
const contract = new ethers.Contract(contractAddress, abi, signer);
|
||||||
|
|
||||||
|
const tx = await contract.revokeConfirmation(index);
|
||||||
|
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getTransactionCount(contractAddress: string) {
|
||||||
|
const { abi } = await hre.artifacts.readArtifact('MultiSigWallet');
|
||||||
|
const signer = await this.providerService.getSigner();
|
||||||
|
|
||||||
|
const contract = new ethers.Contract(contractAddress, abi, signer);
|
||||||
|
|
||||||
|
const txCount = await contract.getTransactionCount();
|
||||||
|
|
||||||
|
return txCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getTransaction(dto: GetTransactionDto) {
|
||||||
|
const { index, contractAddress } = dto;
|
||||||
|
const { abi } = await hre.artifacts.readArtifact('MultiSigWallet');
|
||||||
|
const signer = await this.providerService.getSigner();
|
||||||
|
|
||||||
|
const contract = new ethers.Contract(contractAddress, abi, signer);
|
||||||
|
|
||||||
|
const tx = await contract.getTransaction(index);
|
||||||
|
|
||||||
|
return tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
async deposit(dto: DepositMultiSigDto) {
|
||||||
|
const { contractAddress, value } = dto;
|
||||||
|
const signer = await this.providerService.getSigner();
|
||||||
|
|
||||||
|
const { abi } = await hre.artifacts.readArtifact('MultiSigWallet');
|
||||||
|
const contract = new ethers.Contract(contractAddress, abi, signer);
|
||||||
|
|
||||||
|
const tx = await signer.sendTransaction({
|
||||||
|
to: contractAddress,
|
||||||
|
value: BigInt(value),
|
||||||
|
});
|
||||||
|
|
||||||
|
const txResponse: TransactionReceipt = await tx.wait();
|
||||||
|
|
||||||
|
const eventParse = parseLogs(txResponse, contract);
|
||||||
|
|
||||||
|
return {
|
||||||
|
txHash: txResponse.hash,
|
||||||
|
sender: eventParse.args[0].toString(),
|
||||||
|
value: eventParse.args[1].toString(),
|
||||||
|
contractBalance: eventParse.args[2].toString(),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
import { Body, Controller, Get, Param, Post } from '@nestjs/common';
|
||||||
|
import { SalariesService } from './salaries.service';
|
||||||
|
import {
|
||||||
|
GetEmployeeSalariesDto,
|
||||||
|
SalariesDeployDto,
|
||||||
|
SetSalaryDto,
|
||||||
|
} from './salaries.dto';
|
||||||
|
import { ApiTags } from '@nestjs/swagger';
|
||||||
|
@ApiTags('salaries')
|
||||||
|
@Controller('salaries')
|
||||||
|
export class SalariesController {
|
||||||
|
constructor(private readonly salariesService: SalariesService) {}
|
||||||
|
|
||||||
|
@Post('deploy')
|
||||||
|
async deploy(@Body() dto: SalariesDeployDto) {
|
||||||
|
return this.salariesService.deploy(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('usdt-price/:contractAddress')
|
||||||
|
async getUsdtPrice(@Param('contractAddress') contractAddress: string) {
|
||||||
|
return this.salariesService.getLatestUSDTPrice(contractAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('set-salary')
|
||||||
|
async setSalary(@Body() dto: SetSalaryDto) {
|
||||||
|
return this.salariesService.setSalary(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get('salary')
|
||||||
|
async getSalary(@Body() dto: GetEmployeeSalariesDto) {
|
||||||
|
return this.salariesService.getSalary(dto);
|
||||||
|
}
|
||||||
|
}
|
32
chain-api/src/hardhat/modules/salaries/salaries.dto.ts
Normal file
32
chain-api/src/hardhat/modules/salaries/salaries.dto.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { IsNumber, IsString } from 'class-validator';
|
||||||
|
|
||||||
|
export class SalariesDeployDto {
|
||||||
|
@ApiProperty()
|
||||||
|
@IsString()
|
||||||
|
multiSigWallet: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SetSalaryDto {
|
||||||
|
@ApiProperty()
|
||||||
|
@IsString()
|
||||||
|
multiSigWallet: string;
|
||||||
|
@ApiProperty()
|
||||||
|
@IsString()
|
||||||
|
contractAddress: string;
|
||||||
|
@ApiProperty()
|
||||||
|
@IsString()
|
||||||
|
employeeAddress: string;
|
||||||
|
@ApiProperty()
|
||||||
|
@IsNumber()
|
||||||
|
salary: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GetEmployeeSalariesDto {
|
||||||
|
@ApiProperty()
|
||||||
|
@IsString()
|
||||||
|
contractAddress: string;
|
||||||
|
@ApiProperty()
|
||||||
|
@IsString()
|
||||||
|
employeeAddress: string;
|
||||||
|
}
|
13
chain-api/src/hardhat/modules/salaries/salaries.module.ts
Normal file
13
chain-api/src/hardhat/modules/salaries/salaries.module.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { SalariesService } from './salaries.service';
|
||||||
|
import { ProviderModule } from 'src/provider/provider.module';
|
||||||
|
import { SalariesController } from './salaries-interact.controller';
|
||||||
|
import { MultiSigModule } from '../multi-sig/multi-sig.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [ProviderModule, MultiSigModule],
|
||||||
|
controllers: [SalariesController],
|
||||||
|
providers: [SalariesService],
|
||||||
|
exports: [SalariesService],
|
||||||
|
})
|
||||||
|
export class SalariesModule {}
|
75
chain-api/src/hardhat/modules/salaries/salaries.service.ts
Normal file
75
chain-api/src/hardhat/modules/salaries/salaries.service.ts
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { BaseContractService } from '../base-contract.service';
|
||||||
|
import { ethers } from 'ethers';
|
||||||
|
import {
|
||||||
|
GetEmployeeSalariesDto,
|
||||||
|
SalariesDeployDto,
|
||||||
|
SetSalaryDto,
|
||||||
|
} from './salaries.dto';
|
||||||
|
import * as hre from 'hardhat';
|
||||||
|
import { MultiSigWalletService } from '../multi-sig/multi-sig.service';
|
||||||
|
import { ProviderService } from '../../../provider/provider.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class SalariesService extends BaseContractService {
|
||||||
|
constructor(
|
||||||
|
private readonly multiSigWalletService: MultiSigWalletService,
|
||||||
|
public readonly providerService: ProviderService,
|
||||||
|
) {
|
||||||
|
super(providerService);
|
||||||
|
}
|
||||||
|
async deploy(dto: SalariesDeployDto): Promise<any> {
|
||||||
|
const { abi, bytecode } = await hre.artifacts.readArtifact('Salaries');
|
||||||
|
|
||||||
|
const signer = await this.providerService.getSigner();
|
||||||
|
|
||||||
|
const salaryContract = new ethers.ContractFactory(abi, bytecode, signer);
|
||||||
|
|
||||||
|
const myContract = await salaryContract.deploy(
|
||||||
|
dto.multiSigWallet,
|
||||||
|
'0xF0d50568e3A7e8259E16663972b11910F89BD8e7',
|
||||||
|
);
|
||||||
|
await myContract.waitForDeployment();
|
||||||
|
return await myContract.getAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
async getLatestUSDTPrice(contractAddress: string) {
|
||||||
|
const { abi } = await hre.artifacts.readArtifact('Salaries');
|
||||||
|
const signer = await this.providerService.getSigner();
|
||||||
|
|
||||||
|
const contract = new ethers.Contract(contractAddress, abi, signer);
|
||||||
|
|
||||||
|
const answer: string = await contract.getLatestUSDTPriceInETH();
|
||||||
|
return parseInt(answer) / 1e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
async setSalary(dto: SetSalaryDto) {
|
||||||
|
const { employeeAddress, salary, contractAddress, multiSigWallet } = dto;
|
||||||
|
const ISubmitMultiSig = new ethers.Interface([
|
||||||
|
'function setSalary(address employee, uint salaryInUSDT)',
|
||||||
|
]);
|
||||||
|
|
||||||
|
const data = ISubmitMultiSig.encodeFunctionData('setSalary', [
|
||||||
|
employeeAddress,
|
||||||
|
salary,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return await this.multiSigWalletService.submitTransaction({
|
||||||
|
contractAddress: multiSigWallet,
|
||||||
|
destination: contractAddress,
|
||||||
|
value: '0',
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async getSalary(dto: GetEmployeeSalariesDto) {
|
||||||
|
const { employeeAddress, contractAddress } = dto;
|
||||||
|
const { abi } = await hre.artifacts.readArtifact('Salaries');
|
||||||
|
const signer = await this.providerService.getSigner();
|
||||||
|
|
||||||
|
const contract = new ethers.Contract(contractAddress, abi, signer);
|
||||||
|
|
||||||
|
const answer: string = await contract.getSalary(employeeAddress);
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
}
|
@ -1,41 +0,0 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
|
||||||
import { ethers } from 'ethers';
|
|
||||||
import { ConfigService } from '@nestjs/config';
|
|
||||||
import * as hre from 'hardhat';
|
|
||||||
import { BaseContractService } from './base-contract.service';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class SalariesService extends BaseContractService {
|
|
||||||
getSalaries() {}
|
|
||||||
|
|
||||||
async deploy() {
|
|
||||||
const provider = await this.providerService.getProvider();
|
|
||||||
|
|
||||||
const salary = await hre.artifacts.readArtifact('Salaries');
|
|
||||||
const abi = salary.abi;
|
|
||||||
const bytecode = salary.deployedBytecode;
|
|
||||||
const signer = new ethers.Wallet(
|
|
||||||
this.configService.getOrThrow('POLYGON_PK'),
|
|
||||||
provider,
|
|
||||||
);
|
|
||||||
|
|
||||||
const salaryContract = new ethers.ContractFactory(
|
|
||||||
abi,
|
|
||||||
salary.bytecode,
|
|
||||||
signer,
|
|
||||||
);
|
|
||||||
|
|
||||||
const myContract = await salaryContract.deploy(
|
|
||||||
'multisig address',
|
|
||||||
this.configService.getOrThrow('CHAINLINK_AGGREGATOR_V3'),
|
|
||||||
);
|
|
||||||
await myContract.waitForDeployment();
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
'🚀 ~ HardhatService ~ deploySalaryContract ~ myContract:',
|
|
||||||
myContract,
|
|
||||||
);
|
|
||||||
const address = myContract.getAddress();
|
|
||||||
console.log('🚀 ~ SalariesService ~ deploy ~ address:', address);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,8 @@
|
|||||||
import { NestFactory } from '@nestjs/core';
|
import { HttpAdapterHost, NestFactory } from '@nestjs/core';
|
||||||
import { AppModule } from './app.module';
|
import { AppModule } from './app.module';
|
||||||
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
|
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
|
||||||
import { ValidationPipe } from '@nestjs/common';
|
import { ValidationPipe } from '@nestjs/common';
|
||||||
|
import { AllExceptionsFilter } from './filters/http.filter';
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
const app = await NestFactory.create(AppModule);
|
const app = await NestFactory.create(AppModule);
|
||||||
|
|
||||||
@ -13,6 +14,7 @@ async function bootstrap() {
|
|||||||
const document = SwaggerModule.createDocument(app, config);
|
const document = SwaggerModule.createDocument(app, config);
|
||||||
SwaggerModule.setup('api', app, document);
|
SwaggerModule.setup('api', app, document);
|
||||||
app.useGlobalPipes(new ValidationPipe());
|
app.useGlobalPipes(new ValidationPipe());
|
||||||
|
app.useGlobalFilters(new AllExceptionsFilter());
|
||||||
await app.listen(3000);
|
await app.listen(3000);
|
||||||
|
|
||||||
console.log('Swagger avaliable at http://localhost:3000/api');
|
console.log('Swagger avaliable at http://localhost:3000/api');
|
||||||
|
Loading…
Reference in New Issue
Block a user