Skip to content

Commit

Permalink
Merge pull request #103 from sotatek-dev/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
Sotatek-TanHoang authored Sep 27, 2024
2 parents a21fe46 + 1da5dec commit 0e8c5b6
Show file tree
Hide file tree
Showing 15 changed files with 105 additions and 136 deletions.
11 changes: 0 additions & 11 deletions docker-compose.dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,6 @@ services:
networks:
- myNetwork
user: node
get-price-token:
image: mina-bridge:1.0.0
command: >
sh -c "npm run console get-price-token"
tty: true
restart: always
depends_on:
- postgres
networks:
- myNetwork
user: node
validate-evm-signature-1:
image: mina-bridge:1.0.0
command: >
Expand Down
3 changes: 0 additions & 3 deletions src/config/config.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ import redisConfig from './redis.config.js';
[EEnvKey.ETH_BRIDGE_DOMAIN_NAME]: Joi.string().required(),
[EEnvKey.ETH_BRIDGE_DOMAIN_VERSION]: Joi.string().required(),
[EEnvKey.MINA_CRAWL_SAFE_BLOCK]: Joi.number().default(MINA_CRAWL_SAFE_BLOCK),
// coinmarketcap
[EEnvKey.COINMARKET_KEY]: Joi.string().required(),
[EEnvKey.COINMARKET_URL]: Joi.string().required(),
// mina validator
[EEnvKey.MINA_VALIDATOR_THRESHHOLD]: Joi.number().required(),
// fee
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { MigrationInterface, QueryRunner, TableColumn } from 'typeorm';

export class CreateFeeColumnEventLogs1727426782955 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
return queryRunner.addColumns('event_logs', [
new TableColumn({
name: 'tip',
type: 'varchar',
isNullable: true,
}),
new TableColumn({
name: 'gas_fee',
type: 'varchar',
isNullable: true,
}),
]);
}

public async down(queryRunner: QueryRunner): Promise<void> {
return queryRunner.dropColumns('event_logs', ['tip', 'gas_fee']);
}
}
2 changes: 2 additions & 0 deletions src/database/repositories/event-log.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ export class EventLogRepository extends BaseRepository<EventLog> {
protocolFee?: string;
errorDetail?: string;
txHashUnlock?: string;
gasFee?: string;
tip?: string;
}) {
return this.createQueryBuilder(`${this.alias}`)
.update(EventLog)
Expand Down
10 changes: 0 additions & 10 deletions src/database/repositories/token-price.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,4 @@ export class TokenPriceRepository extends BaseRepository<TokenPrice> {
.where(`${this.alias}.symbol IN (:...symbols)`, { symbols })
.getMany();
}

public async getRateETHToMina() {
const rate = await this.createQueryBuilder(`${this.alias}`)
.select(
`(select CAST(price_usd AS REAL) from token_prices tp2 where tp2.symbol = 'ETH') / (select CAST(price_usd AS REAL) from token_prices tp where tp.symbol = 'MINA') as rateETHMINA`,
)
.getRawOne();

return rate;
}
}
15 changes: 0 additions & 15 deletions src/modules/crawler/crawler.console.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,19 +117,4 @@ export class CrawlerConsole {
this.logger.error(error);
}
}

@Command({
command: 'get-price-token',
description: 'get price of token',
})
async getPriceCoinMarketCap() {
try {
while (true) {
await this.jobGetPrice.handleGetPriceToken();
await sleep(43200);
}
} catch (error) {
this.logger.error(error);
}
}
}
6 changes: 6 additions & 0 deletions src/modules/crawler/entities/event-logs.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ export class EventLog extends BaseEntityIncludeTime {
@Column({ name: 'protocol_fee', type: 'varchar', nullable: true })
protocolFee: string;

@Column({ name: 'gas_fee', type: 'varchar', nullable: true })
gasFee: string;

@Column({ type: 'varchar', nullable: true })
tip: string;

@Column({ name: 'event', type: 'varchar', enum: EEventName, nullable: false })
event: EEventName;

Expand Down
31 changes: 11 additions & 20 deletions src/modules/crawler/sender.evmbridge.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import BigNumber from 'bignumber.js/bignumber.mjs';
import { BigNumber } from 'bignumber.js';
// import BigNumber from 'bignumber.js/bignumber.mjs';
import { ethers } from 'ethers';
import { Logger } from 'log4js';

Expand All @@ -14,7 +15,7 @@ import { MultiSignatureRepository } from '../../database/repositories/multi-sign
import { TokenPairRepository } from '../../database/repositories/token-pair.repository.js';
import { LoggerService } from '../../shared/modules/logger/logger.service.js';
import { ETHBridgeContract } from '../../shared/modules/web3/web3.service.js';
import { addDecimal, calculateFee } from '../../shared/utils/bignumber.js';
import { addDecimal, calculateFee, calculateTip } from '../../shared/utils/bignumber.js';
import { EventLog } from './entities/event-logs.entity.js';
import { MultiSignature } from './entities/multi-signature.entity.js';

Expand Down Expand Up @@ -58,18 +59,13 @@ export class SenderEVMBridge {
await this.updateLogStatusWithRetry(dataLock, EEventStatus.FAILED, EError.OVER_DAILY_QUOTA);
return;
}
// const gasFee = await this.ethBridgeContract.getEstimateGas(
// tokenReceivedAddress,
// BigNumber(amountReceive),
// txHashLock,
// receiveAddress,
// 0,
// );
const protocolFee = calculateFee(
amountReceived,
addDecimal(this.configService.get(EEnvKey.GAS_FEE_EVM), this.configService.get(EEnvKey.DECIMAL_TOKEN_EVM)),
configTip.tip,
// fee and received amount.
const gasFeeEth = addDecimal(
this.configService.get(EEnvKey.GAS_FEE_EVM),
this.configService.get(EEnvKey.DECIMAL_TOKEN_EVM),
);
const protocolFee = calculateFee(amountReceived, gasFeeEth, configTip.tip);
// call unlock function
const result = await this.ethBridgeContract.unlock(
tokenReceivedAddress,
BigNumber(amountReceived),
Expand All @@ -87,6 +83,8 @@ export class SenderEVMBridge {
errorDetail: null,
protocolFee,
amountReceived: BigNumber(amountReceived).minus(protocolFee).toFixed(0).toString(),
gasFee: gasFeeEth,
tip: calculateTip(amountReceived, gasFeeEth, configTip.tip).toFixed(0).toString(),
});
} else {
await this.handleError(result.error, dataLock);
Expand Down Expand Up @@ -116,13 +114,6 @@ export class SenderEVMBridge {
return;
}

// const gasFee = await this.ethBridgeContract.getEstimateGas(
// tokenReceivedAddress,
// BigNumber(amountReceive),
// txHashLock,
// receiveAddress,
// 0,
// );
const protocolFee = calculateFee(
amountReceived,
addDecimal(this.configService.get(EEnvKey.GAS_FEE_EVM), this.configService.get(EEnvKey.DECIMAL_TOKEN_EVM)),
Expand Down
50 changes: 28 additions & 22 deletions src/modules/crawler/sender.minabridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ import { CommonConfigRepository } from '../../database/repositories/common-confi
import { EventLogRepository } from '../../database/repositories/event-log.repository.js';
import { MultiSignatureRepository } from '../../database/repositories/multi-signature.repository.js';
import { TokenPairRepository } from '../../database/repositories/token-pair.repository.js';
import { TokenPriceRepository } from '../../database/repositories/token-price.repository.js';
import { LoggerService } from '../../shared/modules/logger/logger.service.js';
import { addDecimal, calculateFee } from '../../shared/utils/bignumber.js';
import { addDecimal, calculateFee, calculateTip } from '../../shared/utils/bignumber.js';
import { TokenPair } from '../users/entities/tokenpair.entity.js';
import { CommonConfig } from './entities/common-config.entity.js';
import { MultiSignature } from './entities/multi-signature.entity.js';
Expand All @@ -36,7 +35,6 @@ export class SenderMinaBridge {
private readonly eventLogRepository: EventLogRepository,
private readonly commonConfigRepository: CommonConfigRepository,
private readonly tokenPairRepository: TokenPairRepository,
private readonly tokenPriceRepository: TokenPriceRepository,
private readonly multiSignatureRepository: MultiSignatureRepository,
private readonly loggerService: LoggerService,
) {
Expand Down Expand Up @@ -71,30 +69,34 @@ export class SenderMinaBridge {
tokenPair: TokenPair,
config: CommonConfig,
amountFrom: string,
): { amountReceived: string; protocolFeeAmount: string } {
): { amountReceived: string; protocolFeeAmount: string; tipAmount: string; gasFeeMina: string } {
// convert decimal from ETH to MINA
const amountReceiveConvert = BigNumber(amountFrom)
.dividedBy(BigNumber(DECIMAL_BASE).pow(tokenPair.fromDecimal))
.multipliedBy(BigNumber(DECIMAL_BASE).pow(tokenPair.toDecimal))
.toString();
const protocolFeeAmount = BigNumber(
calculateFee(
amountReceiveConvert,
addDecimal(this.configService.get(EEnvKey.GASFEEMINA), this.configService.get(EEnvKey.DECIMAL_TOKEN_MINA)),
config.tip,
),
)
const gasFeeMina = addDecimal(
this.configService.get(EEnvKey.GASFEEMINA),
this.configService.get(EEnvKey.DECIMAL_TOKEN_MINA),
);
// calc fee follow MINA decimal.
const protocolFeeAmount = BigNumber(calculateFee(amountReceiveConvert, gasFeeMina, config.tip))
.toFixed(0)
.toString();
const amountReceived = BigNumber(amountReceiveConvert).minus(protocolFeeAmount).toFixed(0).toString();
return { amountReceived, protocolFeeAmount };
return {
amountReceived,
protocolFeeAmount,
tipAmount: calculateTip(amountReceiveConvert, gasFeeMina, config.tip).toFixed(0).toString(),
gasFeeMina,
};
}
public async handleUnlockMina() {
let dataLock, configTip, rateethmina;
let dataLock, configTip;
try {
[dataLock, configTip, { rateethmina }] = await Promise.all([
[dataLock, configTip] = await Promise.all([
this.eventLogRepository.getEventLockWithNetwork(ENetworkName.MINA, this.validatorThreshhold),
this.commonConfigRepository.getCommonConfig(),
this.tokenPriceRepository.getRateETHToMina(),
]);
if (!dataLock) {
return;
Expand Down Expand Up @@ -124,11 +126,13 @@ export class SenderMinaBridge {
});
return;
}
const { amountReceived, protocolFeeAmount } = this.getAmountReceivedAndFee(tokenPair, configTip, amountFrom);
const { amountReceived, protocolFeeAmount, gasFeeMina, tipAmount } = this.getAmountReceivedAndFee(
tokenPair,
configTip,
amountFrom,
);

const rateMINAETH = Number(rateethmina.toFixed(0)) || 2000; // refactor this

const result = await this.callUnlockFunction(amountReceived, id, receiveAddress, protocolFeeAmount, rateMINAETH);
const result = await this.callUnlockFunction(amountReceived, id, receiveAddress);
// Update status eventLog when call function unlock
if (result.success) {
await this.eventLogRepository.updateStatusAndRetryEvenLog({
Expand All @@ -137,8 +141,10 @@ export class SenderMinaBridge {
status: EEventStatus.PROCESSING,
errorDetail: result.error,
txHashUnlock: result.data,
amountReceived: BigNumber(amountReceived).minus(protocolFeeAmount).toFixed(0).toString(),
amountReceived,
protocolFee: protocolFeeAmount,
gasFee: gasFeeMina,
tip: tipAmount,
});
} else {
await this.eventLogRepository.updateStatusAndRetryEvenLog({
Expand All @@ -160,7 +166,7 @@ export class SenderMinaBridge {
}
}

private async callUnlockFunction(amount, txId, receiveAddress, protocolFeeAmount, rateMINAETH) {
private async callUnlockFunction(amount, txId, receiveAddress) {
try {
const generatedSignatures = await this.multiSignatureRepository.findBy({
txId,
Expand All @@ -172,7 +178,7 @@ export class SenderMinaBridge {
this.logger.info('compile the contract...');
await this.compileContract();

const fee = protocolFeeAmount * rateMINAETH + +this.configService.get(EEnvKey.BASE_MINA_BRIDGE_FEE); // in nanomina (1 billion = 1.0 mina)
const fee = +this.configService.get(EEnvKey.BASE_MINA_BRIDGE_FEE); // in nanomina (1 billion = 1.0 mina)
const feePayerPublicKey = this.feePayerKey.toPublicKey();
const bridgePublicKey = this.bridgeKey.toPublicKey();
const receiverPublicKey = PublicKey.fromBase58(receiveAddress);
Expand Down
42 changes: 18 additions & 24 deletions src/modules/crawler/tests/evm-sender.spec.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,30 @@
import { ConfigModule, ConfigService } from '@nestjs/config';
import { ConfigModule } from '@nestjs/config';
import { JwtService } from '@nestjs/jwt';
import { Test, TestingModule } from '@nestjs/testing';
import { ConfigurationModule } from 'config/config.module.js';
import { EAsset } from 'constants/api.constant.js';
import { EEventName, EEventStatus, ENetworkName, ETokenPairStatus } from 'constants/blockchain.constant.js';
import { CommonConfigRepository } from 'database/repositories/common-configuration.repository';
import { CrawlContractRepository } from 'database/repositories/crawl-contract.repository';
import { EventLogRepository } from 'database/repositories/event-log.repository';
import { MultiSignatureRepository } from 'database/repositories/multi-signature.repository';
import { TokenPairRepository } from 'database/repositories/token-pair.repository';
import { TokenPair } from 'modules/users/entities/tokenpair.entity.js';
import { LoggerService } from 'shared/modules/logger/logger.service.js';
import { Web3Module } from 'shared/modules/web3/web3.module.js';
import { ETHBridgeContract } from 'shared/modules/web3/web3.service.js';
import { DataSource, QueryRunner } from 'typeorm';
import { DataSource } from 'typeorm';

import { EventLog } from '../entities';
import { CommonConfig } from '../entities/common-config.entity';
import { MultiSignature } from '../entities/multi-signature.entity';
import { SenderEVMBridge } from '../sender.evmbridge';
import { ConfigurationModule } from '../../../config/config.module.js';
import { EAsset } from '../../../constants/api.constant.js';
import { EEventName, EEventStatus, ENetworkName, ETokenPairStatus } from '../../../constants/blockchain.constant.js';
import { CommonConfigRepository } from '../../../database/repositories/common-configuration.repository.js';
import { CrawlContractRepository } from '../../../database/repositories/crawl-contract.repository.js';
import { EventLogRepository } from '../../../database/repositories/event-log.repository.js';
import { MultiSignatureRepository } from '../../../database/repositories/multi-signature.repository.js';
import { TokenPairRepository } from '../../../database/repositories/token-pair.repository.js';
import { TokenPair } from '../../../modules/users/entities/tokenpair.entity.js';
import { LoggerService } from '../../../shared/modules/logger/logger.service.js';
import { Web3Module } from '../../../shared/modules/web3/web3.module.js';
import { ETHBridgeContract } from '../../../shared/modules/web3/web3.service.js';
import { CommonConfig } from '../entities/common-config.entity.js';
import { EventLog } from '../entities/index.js';
import { MultiSignature } from '../entities/multi-signature.entity.js';
import { SenderEVMBridge } from '../sender.evmbridge.js';

let senderEVMBridge: SenderEVMBridge;
let dataSource: DataSource;
let queryRunner: QueryRunner;
let eventLogRepository: EventLogRepository;
let commonConfigRepository: CommonConfigRepository;
let tokenPairRepository: TokenPairRepository;
let multiSignatureRepository: MultiSignatureRepository;
let loggerService: LoggerService;
let newEthBridgeContract: ETHBridgeContract;
// Mock objects
const mockJwtService = {
Expand Down Expand Up @@ -103,13 +100,10 @@ beforeEach(async () => {

newEthBridgeContract = module.get<ETHBridgeContract>(ETHBridgeContract);
senderEVMBridge = module.get<SenderEVMBridge>(SenderEVMBridge);
dataSource = module.get<DataSource>(DataSource);
queryRunner = dataSource.createQueryRunner();
eventLogRepository = module.get<EventLogRepository>(EventLogRepository);
commonConfigRepository = module.get<CommonConfigRepository>(CommonConfigRepository);
tokenPairRepository = module.get<TokenPairRepository>(TokenPairRepository);
multiSignatureRepository = module.get<MultiSignatureRepository>(MultiSignatureRepository);
loggerService = module.get<LoggerService>(LoggerService);
});

describe('handleValidateUnlockTxEVM', () => {
Expand Down
7 changes: 1 addition & 6 deletions src/modules/crawler/tests/mina-sender.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { CommonConfigRepository } from '../../../database/repositories/common-co
import { EventLogRepository } from '../../../database/repositories/event-log.repository.js';
import { MultiSignatureRepository } from '../../../database/repositories/multi-signature.repository.js';
import { TokenPairRepository } from '../../../database/repositories/token-pair.repository.js';
import { TokenPriceRepository } from '../../../database/repositories/token-price.repository.js';
import { LoggingModule } from '../../../shared/modules/logger/logger.module.js';
import { Web3Module } from '../../../shared/modules/web3/web3.module.js';
import { SenderMinaBridge } from '../sender.minabridge.js';
Expand All @@ -30,9 +29,7 @@ const mockCommonConfigRepository = {
const mockTokenPairRepository = {
getTokenPair: jest.fn(),
};
const mockTokenPriceRepository = {
getRateETHToMina: jest.fn(),
};

const mockMultiSignatureRepository = {
getRateETHToMina: jest.fn(),
findBy: jest.fn(),
Expand All @@ -49,7 +46,6 @@ describe('MinaSenderService', () => {
{ provide: EventLogRepository, useValue: mockEventLogRepository },
{ provide: CommonConfigRepository, useValue: mockCommonConfigRepository },
{ provide: TokenPairRepository, useValue: mockTokenPairRepository },
{ provide: TokenPriceRepository, useValue: mockTokenPriceRepository },
{ provide: MultiSignatureRepository, useValue: mockMultiSignatureRepository },
],
}).compile();
Expand Down Expand Up @@ -91,7 +87,6 @@ describe('MinaSenderService', () => {
dailyQuota: '500',
id: 1,
});
mockTokenPriceRepository.getRateETHToMina.mockResolvedValue({ rateethmina: 3870.44 });
mockTokenPairRepository.getTokenPair.mockResolvedValue({
id: 5,
deletedAt: null,
Expand Down
5 changes: 0 additions & 5 deletions src/modules/users/dto/user-request.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,4 @@ export class GetProtocolFeeBodyDto {
required: true,
})
pairId: number;

@StringField({
required: true,
})
amount: string;
}
Loading

0 comments on commit 0e8c5b6

Please sign in to comment.