get header decorrator + dynamic seed

This commit is contained in:
emochka2007 2024-05-28 23:14:22 +03:00
parent 4d2e169795
commit 49a2687538
13 changed files with 260 additions and 157 deletions

View File

@ -4,5 +4,5 @@ import { ProviderService } from './provider/provider.service';
@Injectable()
export abstract class BaseContractService {
constructor(public readonly providerService: ProviderService) {}
abstract deploy(dto: object): Promise<any>;
abstract deploy(dto: object, seed: string): Promise<any>;
}

View File

@ -22,13 +22,10 @@ export class ProviderService {
return this.provider;
}
async getSigner() {
async getSigner(seed: string) {
if (!this.provider) {
await this.getProvider();
}
return new ethers.Wallet(
this.configService.getOrThrow('POLYGON_PK'),
this.provider,
);
return ethers.Wallet.fromPhrase(seed, this.provider);
}
}

View File

@ -0,0 +1 @@
import { IsString } from 'class-validator';

View File

@ -6,24 +6,32 @@ import {
RequestAgreementDto,
} from './agreement.dto';
import { ApiTags } from '@nestjs/swagger';
import { GetHeader } from '../../decorators/getHeader.decorator';
@ApiTags('Agreement')
@Controller('agreements')
export class AgreementController {
constructor(private readonly agreementService: AgreementService) {}
@Post('deploy')
async deployAgreement(@Body() deployDto: DeployAgreementDto) {
return await this.agreementService.deploy(deployDto);
async deployAgreement(
@Body() deployDto: DeployAgreementDto,
@GetHeader('X-Seed') seed: string,
) {
return await this.agreementService.deploy(deployDto, seed);
}
@Get(':contractAddress')
async getAgreementResponse(
@Param('contractAddress') contractAddress: string,
@GetHeader('X-Seed') seed: string,
) {
return await this.agreementService.getResponse({ contractAddress });
return await this.agreementService.getResponse({ contractAddress }, seed);
}
@Post('request')
async requestAgreement(@Body() requestDto: RequestAgreementDto) {
return await this.agreementService.request(requestDto);
async requestAgreement(
@Body() requestDto: RequestAgreementDto,
@GetHeader('X-Seed') seed: string,
) {
return await this.agreementService.request(requestDto, seed);
}
}

View File

@ -19,7 +19,7 @@ export class AgreementService extends BaseContractService {
) {
super(providerService);
}
async deploy(dto: DeployAgreementDto): Promise<any> {
async deploy(dto: DeployAgreementDto, seed: string): Promise<any> {
const { multiSigWallet } = dto;
const { bytecode } = await hre.artifacts.readArtifact('Agreement');
@ -36,20 +36,23 @@ export class AgreementService extends BaseContractService {
],
);
const fullBytecode = bytecode + abiEncodedConstructorArguments.substring(2);
const submitData = await this.multiSigService.submitTransaction({
const submitData = await this.multiSigService.submitTransaction(
{
contractAddress: multiSigWallet,
destination: null,
value: '0',
data: fullBytecode,
});
},
seed,
);
delete submitData.data;
return submitData;
}
async getResponse(dto: GetAgreementInfoDto) {
async getResponse(dto: GetAgreementInfoDto, seed: string) {
const { contractAddress } = dto;
const { abi } = await hre.artifacts.readArtifact('Agreement');
const signer = await this.providerService.getSigner();
const signer = await this.providerService.getSigner(seed);
const contract = new ethers.Contract(contractAddress, abi, signer);
@ -57,7 +60,7 @@ export class AgreementService extends BaseContractService {
return answer.toString();
}
async request(dto: RequestAgreementDto) {
async request(dto: RequestAgreementDto, seed: string) {
const { multiSigWallet, contractAddress, url } = dto;
const ISubmitMultiSig = new ethers.Interface([
@ -65,11 +68,14 @@ export class AgreementService extends BaseContractService {
]);
const data = ISubmitMultiSig.encodeFunctionData('request', [url]);
return await this.multiSigService.submitTransaction({
return await this.multiSigService.submitTransaction(
{
contractAddress: multiSigWallet,
destination: contractAddress,
value: '0',
data,
});
},
seed,
);
}
}

View File

@ -9,47 +9,72 @@ import {
RequestLicenseDto,
SetPayoutContractDto,
} from './license.dto';
import { GetHeader } from '../../decorators/getHeader.decorator';
@ApiTags('license')
@Controller('license')
export class LicenseController {
constructor(private readonly licenseService: LicenseService) {}
@Post('request')
async getLicenseRequest(@Body() dto: RequestLicenseDto) {
return this.licenseService.request(dto);
async getLicenseRequest(
@Body() dto: RequestLicenseDto,
@GetHeader('X-Seed') seed: string,
) {
return this.licenseService.request(dto, seed);
}
@Post('deploy')
async deploy(@Body() dto: DeployLicenseDto) {
return this.licenseService.deploy(dto);
async deploy(
@Body() dto: DeployLicenseDto,
@GetHeader('X-Seed') seed: string,
) {
return this.licenseService.deploy(dto, seed);
}
@Get('total-payout')
async getLicenseResponse(@Body() dto: GetLicenseInfoDto) {
return this.licenseService.getTotalPayoutInUSD(dto);
async getLicenseResponse(
@Body() dto: GetLicenseInfoDto,
@GetHeader('X-Seed') seed: string,
) {
return this.licenseService.getTotalPayoutInUSD(dto, seed);
}
@Get('shares')
async getShares(@Body() dto: GetShareLicense) {
return this.licenseService.getShares(dto);
async getShares(
@Body() dto: GetShareLicense,
@GetHeader('X-Seed') seed: string,
) {
return this.licenseService.getShares(dto, seed);
}
@Get('owners')
async getOwners(@Body() dto: GetLicenseInfoDto) {
return this.licenseService.getOwners(dto);
async getOwners(
@Body() dto: GetLicenseInfoDto,
@GetHeader('X-Seed') seed: string,
) {
return this.licenseService.getOwners(dto, seed);
}
@Get('payout-contract')
async getPayoutContract(@Body() dto: GetLicenseInfoDto) {
return this.licenseService.getPayoutContract(dto);
async getPayoutContract(
@Body() dto: GetLicenseInfoDto,
@GetHeader('X-Seed') seed: string,
) {
return this.licenseService.getPayoutContract(dto, seed);
}
@Post('payout')
async payout(@Body() dto: LicensePayoutDto) {
return this.licenseService.payout(dto);
async payout(
@Body() dto: LicensePayoutDto,
@GetHeader('X-Seed') seed: string,
) {
return this.licenseService.payout(dto, seed);
}
@Post('set-payout-contract')
async setPayoutContract(@Body() dto: SetPayoutContractDto) {
return this.licenseService.setPayoutContract(dto);
async setPayoutContract(
@Body() dto: SetPayoutContractDto,
@GetHeader('X-Seed') seed: string,
) {
return this.licenseService.setPayoutContract(dto, seed);
}
}

View File

@ -22,7 +22,7 @@ export class LicenseService extends BaseContractService {
) {
super(providerService);
}
async request(dto: RequestLicenseDto) {
async request(dto: RequestLicenseDto, seed: string) {
const { multiSigWallet, contractAddress, url } = dto;
const ISubmitMultiSig = new ethers.Interface([
@ -30,20 +30,23 @@ export class LicenseService extends BaseContractService {
]);
const data = ISubmitMultiSig.encodeFunctionData('request', [url]);
return await this.multiSigService.submitTransaction({
return await this.multiSigService.submitTransaction(
{
contractAddress: multiSigWallet,
destination: contractAddress,
value: '0',
data,
});
},
seed,
);
}
async getTotalPayoutInUSD(dto: GetLicenseInfoDto) {
async getTotalPayoutInUSD(dto: GetLicenseInfoDto, seed: string) {
const { contractAddress } = dto;
const { abi } = await hre.artifacts.readArtifact(
'StreamingRightsManagement',
);
const signer = await this.providerService.getSigner();
const signer = await this.providerService.getSigner(seed);
const contract = new ethers.Contract(contractAddress, abi, signer);
@ -51,7 +54,7 @@ export class LicenseService extends BaseContractService {
return answer.toString();
}
async deploy(dto: DeployLicenseDto) {
async deploy(dto: DeployLicenseDto, seed: string) {
const { multiSigWallet, shares, owners } = dto;
const { bytecode } = await hre.artifacts.readArtifact(
'StreamingRightsManagement',
@ -80,22 +83,25 @@ export class LicenseService extends BaseContractService {
],
);
const fullBytecode = bytecode + abiEncodedConstructorArguments.substring(2);
const submitData = await this.multiSigService.submitTransaction({
const submitData = await this.multiSigService.submitTransaction(
{
contractAddress: multiSigWallet,
destination: null,
value: '0',
data: fullBytecode,
});
},
seed,
);
delete submitData.data;
return submitData;
}
async getPayoutContract(dto: GetLicenseInfoDto) {
async getPayoutContract(dto: GetLicenseInfoDto, seed: string) {
const { contractAddress } = dto;
const { abi } = await hre.artifacts.readArtifact(
'StreamingRightsManagement',
);
const signer = await this.providerService.getSigner();
const signer = await this.providerService.getSigner(seed);
const contract = new ethers.Contract(contractAddress, abi, signer);
@ -104,12 +110,12 @@ export class LicenseService extends BaseContractService {
return answer;
}
async getOwners(dto: GetLicenseInfoDto) {
async getOwners(dto: GetLicenseInfoDto, seed: string) {
const { contractAddress } = dto;
const { abi } = await hre.artifacts.readArtifact(
'StreamingRightsManagement',
);
const signer = await this.providerService.getSigner();
const signer = await this.providerService.getSigner(seed);
const contract = new ethers.Contract(contractAddress, abi, signer);
@ -129,12 +135,12 @@ export class LicenseService extends BaseContractService {
return owners;
}
async getShares(dto: GetShareLicense) {
async getShares(dto: GetShareLicense, seed: string) {
const { contractAddress, ownerAddress } = dto;
const { abi } = await hre.artifacts.readArtifact(
'StreamingRightsManagement',
);
const signer = await this.providerService.getSigner();
const signer = await this.providerService.getSigner(seed);
const contract = new ethers.Contract(contractAddress, abi, signer);
@ -144,21 +150,24 @@ export class LicenseService extends BaseContractService {
return answer;
}
async payout(dto: LicensePayoutDto) {
async payout(dto: LicensePayoutDto, seed: string) {
const { multiSigWallet, contractAddress } = dto;
const ISubmitMultiSig = new ethers.Interface(['function payout()']);
const data = ISubmitMultiSig.encodeFunctionData('payout');
return await this.multiSigService.submitTransaction({
return await this.multiSigService.submitTransaction(
{
contractAddress: multiSigWallet,
destination: contractAddress,
value: '0',
data,
});
},
seed,
);
}
async setPayoutContract(dto: SetPayoutContractDto) {
async setPayoutContract(dto: SetPayoutContractDto, seed: string) {
const { multiSigWallet, contractAddress, payoutContract } = dto;
const ISubmitMultiSig = new ethers.Interface([
@ -168,11 +177,14 @@ export class LicenseService extends BaseContractService {
payoutContract,
]);
return await this.multiSigService.submitTransaction({
return await this.multiSigService.submitTransaction(
{
contractAddress: multiSigWallet,
destination: contractAddress,
value: '0',
data,
});
},
seed,
);
}
}

View File

@ -12,6 +12,7 @@ import {
RevokeConfirmationDto,
SubmitTransactionDto,
} from '../multi-sig.dto';
import { GetHeader } from '../../decorators/getHeader.decorator';
@ApiTags('multi-sig')
@Controller('multi-sig')
export class MultiSigInteractController {
@ -23,53 +24,81 @@ export class MultiSigInteractController {
@Post('deploy')
async deploy(
@Body() dto: MultiSigWalletDto,
@GetHeader('X-Seed') seed: string,
): Promise<DeployMultiSigResponseDto> {
const addr = await this.multiSigWalletService.deploy(dto);
const addr = await this.multiSigWalletService.deploy(dto, seed);
return {
address: addr,
};
}
@Get('owners/:address')
async getOwners(@Param('address') address: string) {
return this.multiSigWalletService.getOwners(address);
async getOwners(
@Param('address') address: string,
@GetHeader('X-Seed') seed: string,
) {
return this.multiSigWalletService.getOwners(address, seed);
}
@ApiOkResponse()
@Post('submit-transaction')
async submitTransaction(@Body() dto: SubmitTransactionDto) {
return this.multiSigWalletService.submitTransaction(dto);
async submitTransaction(
@Body() dto: SubmitTransactionDto,
@GetHeader('X-Seed') seed: string,
) {
return this.multiSigWalletService.submitTransaction(dto, seed);
}
@ApiOkResponse()
@Post('confirm-transaction')
async confirmTransaction(@Body() dto: ConfirmTransactionDto) {
return this.multiSigWalletService.confirmTransaction(dto);
async confirmTransaction(
@Body() dto: ConfirmTransactionDto,
@GetHeader('X-Seed') seed: string,
) {
return this.multiSigWalletService.confirmTransaction(dto, seed);
}
@ApiOkResponse()
@Post('execute-transaction')
async executeTransaction(@Body() dto: ExecuteTransactionDto) {
return this.multiSigWalletService.executeTransaction(dto);
async executeTransaction(
@Body() dto: ExecuteTransactionDto,
@GetHeader('X-Seed') seed: string,
) {
return this.multiSigWalletService.executeTransaction(dto, seed);
}
@ApiOkResponse()
@Post('revoke-confirmation')
async revokeConfirmation(@Body() dto: RevokeConfirmationDto) {
return this.multiSigWalletService.revokeConfirmation(dto);
async revokeConfirmation(
@Body() dto: RevokeConfirmationDto,
@GetHeader('X-Seed') seed: string,
) {
return this.multiSigWalletService.revokeConfirmation(dto, seed);
}
@Get('transaction-count/:contractAddress')
async getTransactionCount(@Param('contractAddress') contractAddress: string) {
return this.multiSigWalletService.getTransactionCount(contractAddress);
async getTransactionCount(
@Param('contractAddress') contractAddress: string,
@GetHeader('X-Seed') seed: string,
) {
return this.multiSigWalletService.getTransactionCount(
contractAddress,
seed,
);
}
@Get('transaction')
async getTransaction(@Body() dto: GetTransactionDto) {
return this.multiSigWalletService.getTransaction(dto);
async getTransaction(
@Body() dto: GetTransactionDto,
@GetHeader('X-Seed') seed: string,
) {
return this.multiSigWalletService.getTransaction(dto, seed);
}
@Post('deposit')
async deposit(@Body() dto: DepositContractDto) {
return this.multiSigWalletService.deposit(dto);
async deposit(
@Body() dto: DepositContractDto,
@GetHeader('X-Seed') seed: string,
) {
return this.multiSigWalletService.deposit(dto, seed);
}
}

View File

@ -14,11 +14,11 @@ import { BaseContractService } from '../../base/base-contract.service';
import { getContractAddress } from '@ethersproject/address';
export class MultiSigWalletService extends BaseContractService {
async deploy(dto: MultiSigWalletDto) {
async deploy(dto: MultiSigWalletDto, seed: string) {
const { abi, bytecode } =
await hre.artifacts.readArtifact('MultiSigWallet');
const signer = await this.providerService.getSigner();
const signer = await this.providerService.getSigner(seed);
const salaryContract = new ethers.ContractFactory(abi, bytecode, signer);
@ -30,20 +30,20 @@ export class MultiSigWalletService extends BaseContractService {
return myContract.getAddress();
}
async getOwners(address: string) {
async getOwners(address: string, seed: string) {
const { abi } = await hre.artifacts.readArtifact('MultiSigWallet');
const signer = await this.providerService.getSigner();
const signer = await this.providerService.getSigner(seed);
const contract = new ethers.Contract(address, abi, signer);
return await contract.getOwners();
}
async submitTransaction(dto: SubmitTransactionDto) {
async submitTransaction(dto: SubmitTransactionDto, seed: string) {
const { destination, value, data, contractAddress } = dto;
const { abi } = await hre.artifacts.readArtifact('MultiSigWallet');
const signer = await this.providerService.getSigner();
const signer = await this.providerService.getSigner(seed);
const contract = new ethers.Contract(contractAddress, abi, signer);
@ -66,10 +66,10 @@ export class MultiSigWalletService extends BaseContractService {
};
}
async confirmTransaction(dto: ConfirmTransactionDto) {
async confirmTransaction(dto: ConfirmTransactionDto, seed: string) {
const { contractAddress, index } = dto;
const { abi } = await hre.artifacts.readArtifact('MultiSigWallet');
const signer = await this.providerService.getSigner();
const signer = await this.providerService.getSigner(seed);
const contract = new ethers.Contract(contractAddress, abi, signer);
@ -86,10 +86,10 @@ export class MultiSigWalletService extends BaseContractService {
};
}
async executeTransaction(dto: ExecuteTransactionDto) {
async executeTransaction(dto: ExecuteTransactionDto, seed: string) {
const { index, contractAddress, isDeploy } = dto;
const { abi } = await hre.artifacts.readArtifact('MultiSigWallet');
const signer = await this.providerService.getSigner();
const signer = await this.providerService.getSigner(seed);
const contract = new ethers.Contract(contractAddress, abi, signer);
@ -134,45 +134,39 @@ export class MultiSigWalletService extends BaseContractService {
});
}
async revokeConfirmation(dto: RevokeConfirmationDto) {
async revokeConfirmation(dto: RevokeConfirmationDto, seed: string) {
const { index, contractAddress } = dto;
const { abi } = await hre.artifacts.readArtifact('MultiSigWallet');
const signer = await this.providerService.getSigner();
const signer = await this.providerService.getSigner(seed);
const contract = new ethers.Contract(contractAddress, abi, signer);
const tx = await contract.revokeConfirmation(index);
return tx;
return await contract.revokeConfirmation(index);
}
async getTransactionCount(contractAddress: string) {
async getTransactionCount(contractAddress: string, seed: string) {
const { abi } = await hre.artifacts.readArtifact('MultiSigWallet');
const signer = await this.providerService.getSigner();
const signer = await this.providerService.getSigner(seed);
const contract = new ethers.Contract(contractAddress, abi, signer);
const txCount = await contract.getTransactionCount();
return txCount;
return await contract.getTransactionCount();
}
async getTransaction(dto: GetTransactionDto) {
async getTransaction(dto: GetTransactionDto, seed: string) {
const { index, contractAddress } = dto;
const { abi } = await hre.artifacts.readArtifact('MultiSigWallet');
const signer = await this.providerService.getSigner();
const signer = await this.providerService.getSigner(seed);
const contract = new ethers.Contract(contractAddress, abi, signer);
const tx = await contract.getTransaction(index);
return tx;
return await contract.getTransaction(index);
}
async deposit(dto: DepositContractDto) {
async deposit(dto: DepositContractDto, seed: string) {
const { contractAddress, value } = dto;
const convertValue = parseEther(value);
const signer = await this.providerService.getSigner();
const signer = await this.providerService.getSigner(seed);
const { abi } = await hre.artifacts.readArtifact('MultiSigWallet');
const contract = new ethers.Contract(contractAddress, abi, signer);

View File

@ -9,6 +9,7 @@ import {
} from './salaries.dto';
import { ApiOkResponse, ApiTags } from '@nestjs/swagger';
import { DepositContractDto } from '../multi-sig.dto';
import { GetHeader } from '../../decorators/getHeader.decorator';
@ApiTags('salaries')
@Controller('salaries')
@ -21,35 +22,51 @@ export class SalariesController {
@Post('deploy')
async deploy(
@Body() dto: SalariesDeployDto,
@GetHeader('X-Seed') seed: string,
): Promise<DeployContractResponseDto> {
const address = await this.salariesService.deploy(dto);
const address = await this.salariesService.deploy(dto, seed);
return {
address,
};
}
@Get('usdt-price/:contractAddress')
async getUsdtPrice(@Param('contractAddress') contractAddress: string) {
return this.salariesService.getLatestUSDTPrice(contractAddress);
async getUsdtPrice(
@Param('contractAddress') contractAddress: string,
@GetHeader('X-Seed') seed: string,
) {
return this.salariesService.getLatestUSDTPrice(contractAddress, seed);
}
@Post('set-salary')
async setSalary(@Body() dto: SetSalaryDto) {
return this.salariesService.setSalary(dto);
async setSalary(
@Body() dto: SetSalaryDto,
@GetHeader('X-Seed') seed: string,
) {
return this.salariesService.setSalary(dto, seed);
}
@Get('salary')
async getSalary(@Body() dto: GetEmployeeSalariesDto) {
return this.salariesService.getSalary(dto);
async getSalary(
@Body() dto: GetEmployeeSalariesDto,
@GetHeader('X-Seed') seed: string,
) {
return this.salariesService.getSalary(dto, seed);
}
@Post('payout')
async createPayout(@Body() dto: CreatePayoutDto) {
return this.salariesService.createPayout(dto);
async createPayout(
@Body() dto: CreatePayoutDto,
@GetHeader('X-Seed') seed: string,
) {
return this.salariesService.createPayout(dto, seed);
}
@Post('deposit')
async deposit(@Body() dto: DepositContractDto) {
return this.salariesService.deposit(dto);
async deposit(
@Body() dto: DepositContractDto,
@GetHeader('X-Seed') seed: string,
) {
return this.salariesService.deposit(dto, seed);
}
}

View File

@ -21,10 +21,10 @@ export class SalariesService extends BaseContractService {
) {
super(providerService);
}
async deploy(dto: SalariesDeployDto) {
async deploy(dto: SalariesDeployDto, seed: string) {
const { abi, bytecode } = await hre.artifacts.readArtifact('Payroll');
const signer = await this.providerService.getSigner();
const signer = await this.providerService.getSigner(seed);
const salaryContract = new ethers.ContractFactory(abi, bytecode, signer);
@ -36,9 +36,9 @@ export class SalariesService extends BaseContractService {
return await myContract.getAddress();
}
async getLatestUSDTPrice(contractAddress: string) {
async getLatestUSDTPrice(contractAddress: string, seed: string) {
const { abi } = await hre.artifacts.readArtifact('Payroll');
const signer = await this.providerService.getSigner();
const signer = await this.providerService.getSigner(seed);
const contract = new ethers.Contract(contractAddress, abi, signer);
@ -46,7 +46,7 @@ export class SalariesService extends BaseContractService {
return parseInt(answer) / 1e8;
}
async setSalary(dto: SetSalaryDto) {
async setSalary(dto: SetSalaryDto, seed: string) {
const { employeeAddress, salary, contractAddress, multiSigWallet } = dto;
const ISubmitMultiSig = new ethers.Interface([
'function setSalary(address employee, uint salaryInUSDT)',
@ -57,18 +57,21 @@ export class SalariesService extends BaseContractService {
salary,
]);
return await this.multiSigService.submitTransaction({
return await this.multiSigService.submitTransaction(
{
contractAddress: multiSigWallet,
destination: contractAddress,
value: '0',
data,
});
},
seed,
);
}
async getSalary(dto: GetEmployeeSalariesDto) {
async getSalary(dto: GetEmployeeSalariesDto, seed: string) {
const { employeeAddress, contractAddress } = dto;
const { abi } = await hre.artifacts.readArtifact('Payroll');
const signer = await this.providerService.getSigner();
const signer = await this.providerService.getSigner(seed);
const contract = new ethers.Contract(contractAddress, abi, signer);
@ -78,7 +81,7 @@ export class SalariesService extends BaseContractService {
};
}
async createPayout(dto: CreatePayoutDto) {
async createPayout(dto: CreatePayoutDto, seed: string) {
const { employeeAddress, contractAddress, multiSigWallet } = dto;
const ISubmitMultiSig = new ethers.Interface([
'function payoutInETH(address employee)',
@ -87,17 +90,20 @@ export class SalariesService extends BaseContractService {
employeeAddress,
]);
return await this.multiSigService.submitTransaction({
return await this.multiSigService.submitTransaction(
{
contractAddress: multiSigWallet,
destination: contractAddress,
value: '0',
data,
});
},
seed,
);
}
async deposit(dto: DepositContractDto) {
async deposit(dto: DepositContractDto, seed: string) {
const { contractAddress, value } = dto;
const signer = await this.providerService.getSigner();
const signer = await this.providerService.getSigner(seed);
const convertValue = parseEther(value);

View File

@ -0,0 +1,8 @@
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
export const GetHeader = createParamDecorator(
(data: string, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
return request.headers[data.toLowerCase()];
},
);