Skip to content

Commit

Permalink
Merge pull request #252 from sotatek-dev/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
Sotatek-TanHoang authored Jan 9, 2025
2 parents f39f7c6 + b3228c3 commit f429d41
Show file tree
Hide file tree
Showing 43 changed files with 1,123 additions and 275 deletions.
4 changes: 2 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ GAS_FEE_EVM=0.00001
DECIMAL_TOKEN_EVM=18

# coinmarketcap
COINMARKET_KEY=233ae614-1377-40e6-83c6-c042185a5a23
COINMARKET_URL='https://pro-api.coinmarketcap.com/v2/cryptocurrency/quotes/latest?id=1027,8646'
COINMARKET_KEY=
COINMARKET_URL=

MINA_BRIDGE_SC_PRIVATE_KEY=EKF19hihcXry9QMttf719fVp56DuRB2vZySdeQ1y9BkkvWWxnJAa

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/auto-deploy-develop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ jobs:
with:
node-version: v18.20.4
- run: |
echo "${{ vars.MINA_BRIDGE_BE_DEV }}" >> .env
echo "${{ secrets.MINA_BRIDGE_BE_DEV }}" >> .env
docker build . -t mina-bridge:1.0.0
docker compose -f docker-compose.dev.yaml up -d --remove-orphans
docker-compose -f docker-compose.dev.yaml up -d --remove-orphans
2 changes: 1 addition & 1 deletion .github/workflows/auto-deploy-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ jobs:
with:
node-version: v18.20.4
- run: |
echo "${{ vars.MINA_BRIDGE_BE_TEST }}" >> .env
echo "${{ secrets.MINA_BRIDGE_BE_TEST }}" >> .env
docker build . -t mina-bridge:1.0.0
docker compose -f docker-compose.dev.yaml up -d --remove-orphans
41 changes: 41 additions & 0 deletions design/add-new-token.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
@startuml
actor admin as "Admin"
boundary admin_site as "Admin Site"
queue bull_queue
boundary metamask
boundary aurowallet
control api
database db
actor user as "User"
boundary user_site as "User Site"

group Admin create new pair on web ui

admin -> admin_site: enter create pair page
admin -> admin_site: fill in form
admin -> admin_site: click create button
admin_site -> api: create pair in database

api -> bull_queue: create job new pair
api --> admin_site: pair created ok


end
group Job deploy token
bull_queue -> job: trigger job
job -> mina: create token
job -> eth: whitelist token
end
group Crawler confirm new pair
mina -> crawler: event from mina bridge
eth -> crawler: event from eth bridge
crawler --> crawler: process event
crawler -> db: save pair status
end
group User see new pair
user -> user_site: view pair list page
user_site -> api: list of pairs
api-> user_site: pairs include new pair
user_site --> user: display pairs
end
@enduml
56 changes: 28 additions & 28 deletions docker-compose.dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,34 +66,34 @@ services:
networks:
- myNetwork
user: node
sender-mina-2:
image: mina-bridge:1.0.0
command: >
sh -c "npm run console sender-mina-bridge-unlock"
tty: true
restart: always
environment:
SIGNER_MINA_PRIVATE_KEY : ${SIGNER_MINA_PRIVATE_KEY_2}
depends_on:
- postgres
- redis
networks:
- myNetwork
user: node
sender-mina-3:
image: mina-bridge:1.0.0
command: >
sh -c "npm run console sender-mina-bridge-unlock"
tty: true
restart: always
environment:
SIGNER_MINA_PRIVATE_KEY : ${SIGNER_MINA_PRIVATE_KEY_3}
depends_on:
- postgres
- redis
networks:
- myNetwork
user: node
# sender-mina-2:
# image: mina-bridge:1.0.0
# command: >
# sh -c "npm run console sender-mina-bridge-unlock"
# tty: true
# restart: always
# environment:
# SIGNER_MINA_PRIVATE_KEY : ${SIGNER_MINA_PRIVATE_KEY_2}
# depends_on:
# - postgres
# - redis
# networks:
# - myNetwork
# user: node
# sender-mina-3:
# image: mina-bridge:1.0.0
# command: >
# sh -c "npm run console sender-mina-bridge-unlock"
# tty: true
# restart: always
# environment:
# SIGNER_MINA_PRIVATE_KEY : ${SIGNER_MINA_PRIVATE_KEY_3}
# depends_on:
# - postgres
# - redis
# networks:
# - myNetwork
# user: node
validate-evm-signature-1:
image: mina-bridge:1.0.0
command: >
Expand Down
14 changes: 10 additions & 4 deletions src/config/common.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ConfigService } from '@nestjs/config';

import { EEnvKey } from '../constants/env.constant.js';
import { RpcFactory } from '../shared/modules/web3/web3.module.js';
import { ETHBridgeContract } from '../shared/modules/web3/web3.service.js';
import { Erc20ContractTemplate, ETHBridgeContract } from '../shared/modules/web3/web3.service.js';

async function createRpcService(configService: ConfigService) {
return await RpcFactory(configService);
Expand All @@ -18,15 +18,21 @@ function getEthBridgeAddress(configService: ConfigService) {
function getEthBridgeStartBlock(configService: ConfigService) {
return +configService.get<number>(EEnvKey.ETH_BRIDGE_START_BLOCK)!;
}

async function initializeEthContract(configService: ConfigService) {
export interface IRpcInit {
bridgeContract: ETHBridgeContract;
erc20Template: Erc20ContractTemplate;
}
async function initializeEthContract(configService: ConfigService): Promise<IRpcInit> {
const [rpcEthService, address, _startBlock] = await Promise.all([
createRpcEthService(configService),
getEthBridgeAddress(configService),
getEthBridgeStartBlock(configService),
]);

// Instantiate the ETHBridgeContract with the resolved dependencies
return new ETHBridgeContract(rpcEthService, address!, _startBlock);
return {
bridgeContract: new ETHBridgeContract(rpcEthService, address!, _startBlock),
erc20Template: new Erc20ContractTemplate(rpcEthService),
};
}
export { createRpcService, createRpcEthService, getEthBridgeAddress, getEthBridgeStartBlock, initializeEthContract };
2 changes: 1 addition & 1 deletion src/config/config.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const getEnvFile = () => {
[EEnvKey.MINA_BRIDGE_CONTRACT_ADDRESS]: Joi.string().required(),
[EEnvKey.ETH_BRIDGE_CONTRACT_ADDRESS]: Joi.string().required(),
[EEnvKey.ETH_TOKEN_BRIDGE_ADDRESS]: Joi.string().required(),
[EEnvKey.MINA_TOKEN_BRIDGE_ADDRESS]: Joi.string().required(),
// [EEnvKey.MINA_TOKEN_BRIDGE_ADDRESS]: Joi.string().required(),
[EEnvKey.ADMIN_MESSAGE_FOR_SIGN]: Joi.string().required(),
[EEnvKey.MINA_BRIDGE_SC_PRIVATE_KEY]: Joi.string().required(),
[EEnvKey.ETH_BRIDGE_DOMAIN_NAME]: Joi.string().required(),
Expand Down
3 changes: 3 additions & 0 deletions src/constants/blockchain.constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ export enum EEventStatus {
export enum ETokenPairStatus {
ENABLE = 'enable',
DISABLE = 'disable',
CREATED = 'created',
DEPLOYING = 'deploying',
DEPLOY_FAILED = 'deploy_failed',
}

export enum EMinaChainEnviroment {
Expand Down
1 change: 1 addition & 0 deletions src/constants/env.constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export enum EEnvKey {
MINA_TOKEN_BRIDGE_ADDRESS = 'MINA_TOKEN_BRIDGE_ADDRESS',
MINA_BRIDGE_SC_PRIVATE_KEY = 'MINA_BRIDGE_SC_PRIVATE_KEY',
SIGNER_PRIVATE_KEY = 'SIGNER_PRIVATE_KEY',
ADMIN_EVM_PRIVATE_KEY = 'ADMIN_EVM_PRIVATE_KEY',
NUMBER_OF_BLOCK_PER_JOB = 'NUMBER_OF_BLOCK_PER_JOB',
ADMIN_MESSAGE_FOR_SIGN = 'ADMIN_MESSAGE_FOR_SIGN',
SIGNER_MINA_PRIVATE_KEY = 'SIGNER_MINA_PRIVATE_KEY',
Expand Down
1 change: 1 addition & 0 deletions src/constants/error.constant.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export enum EError {
OTHER_SYSTEM_ERROR = 'OTHER_SYSTEM_ERROR',
FORBIDDEN_RESOURCE = 'FORBIDDEN_RESOURCE',
ACTION_CANNOT_PROCESSED = 'ACTION_CANNOT_PROCESSED',
DUPLICATED_ACTION = 'DUPLICATED_ACTION',
USER_NOT_FOUND = 'USER_NOT_FOUND',
WRONG_EMAIL_OR_PASS = 'WRONG_EMAIL_OR_PASS',
Expand Down
6 changes: 6 additions & 0 deletions src/constants/queue.constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@ export enum EQueueName {
}
export const getEvmValidatorQueueName = (index: number) => `EVM_VALIDATOR_${index}`;
export const getMinaValidatorQueueName = (index: number) => `MINA_VALIDATOR_${index}`;

// job priority, lower index is higher priority
export enum EJobPriority {
DEPLOY_TOKEN,
UNLOCK,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { MigrationInterface, QueryRunner, TableColumn } from 'typeorm';

export class AddTokenFieldsCommonConfig1735615966984 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
return queryRunner.addColumns('common_configuration', [
new TableColumn({
name: 'from_chain',
type: 'varchar',
length: '255',
isNullable: true,
}),
new TableColumn({
name: 'to_chain',
type: 'varchar',
length: '255',
isNullable: true,
}),
new TableColumn({
name: 'from_symbol',
type: 'varchar',
length: '255',
isNullable: true,
}),
new TableColumn({
name: 'to_symbol',
type: 'varchar',
length: '255',
isNullable: true,
}),
new TableColumn({
name: 'from_address',
type: 'varchar',
length: '255',
isNullable: true,
}),
new TableColumn({
name: 'to_address',
type: 'varchar',
length: '255',
isNullable: true,
}),
new TableColumn({
name: 'from_decimal',
type: 'int',
isNullable: true,
}),
new TableColumn({
name: 'to_decimal',
type: 'int',
isNullable: true,
}),
new TableColumn({
name: 'from_sc_address',
type: 'varchar',
length: '255',
isNullable: true,
}),
new TableColumn({
name: 'to_sc_address',
type: 'varchar',
length: '255',
isNullable: true,
}),
new TableColumn({
name: 'status',
type: 'varchar',
length: '255',
isNullable: true,
}),
]);
}

public async down(queryRunner: QueryRunner): Promise<void> {
return queryRunner.dropColumns('common_configuration', [
'from_chain',
'to_chain',
'from_symbol',
'to_symbol',
'from_address',
'to_address',
'from_decimal',
'to_decimal',
'from_sc_address',
'to_sc_address',
'status',
]);
}
}
17 changes: 17 additions & 0 deletions src/database/migrations/1736238200965-unique-token-address.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { MigrationInterface, QueryRunner, TableUnique } from 'typeorm';

export class UniqueTokenAddress1736238200965 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.createUniqueConstraint(
'common_configuration',
new TableUnique({
name: 'unique_from_address',
columnNames: ['from_address'],
}),
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.dropUniqueConstraint('common_configuration', 'unique-from-address');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { MigrationInterface, QueryRunner, TableColumn } from 'typeorm';

export class AddToggleVisibilityTokenPair1736240154189 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
return queryRunner.addColumns('common_configuration', [
new TableColumn({
name: 'is_hidden',
type: 'boolean',
default: false,
}),
]);
}

public async down(queryRunner: QueryRunner): Promise<void> {
return queryRunner.dropColumns('common_configuration', ['is_hidden']);
}
}
30 changes: 27 additions & 3 deletions src/database/repositories/common-configuration.repository.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,42 @@
import { isArray, isNotEmpty } from 'class-validator';
import { UpdateCommonConfigBodyDto } from 'modules/users/dto/common-config-request.dto.js';
import { EntityRepository } from 'nestjs-typeorm-custom-repository';
import { Brackets, ILike, In } from 'typeorm';

import { ETableName } from '../../constants/entity.constant.js';
import { BaseRepository } from '../../core/base-repository.js';
import { CommonConfig } from '../../modules/crawler/entities/common-config.entity.js';
import { GetTokensReqDto } from '../../modules/users/dto/user-request.dto.js';

@EntityRepository(CommonConfig)
export class CommonConfigRepository extends BaseRepository<CommonConfig> {
protected alias: ETableName = ETableName.COMMON_CONFIGURATION;

public getCommonConfig() {
return this.createQueryBuilder(`${this.alias}`).select().getOne();
}
public getManyAndPagination(dto: GetTokensReqDto, role: 'user' | 'admin' = 'admin') {
const qb = this.createQb();
qb.select();
if (isArray(dto.statuses)) {
qb.andWhere({ status: In(dto.statuses) });
}
if (isNotEmpty(dto.assetName)) {
qb.andWhere({ asset: ILike(`%${dto.assetName}%`) });
}
if (role === 'user') {
qb.andWhere({ isHidden: false });
}
if (isNotEmpty(dto.tokenAddress)) {
qb.andWhere(
new Brackets(qb => {
qb.orWhere({ fromAddress: ILike(dto.tokenAddress) });
qb.orWhere({ toAddress: ILike(dto.tokenAddress) });
}),
);
}

qb.orderBy('id', 'DESC');
this.queryBuilderAddPagination(qb, dto);
return qb.getManyAndCount();
}
public updateCommonConfig(id: number, updateConfig: UpdateCommonConfigBodyDto) {
return this.createQueryBuilder(`${this.alias}`)
.update(CommonConfig)
Expand Down
Loading

0 comments on commit f429d41

Please sign in to comment.