Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #252

Merged
merged 47 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
121891e
feat: add new token
Sotatek-TanHoang Jan 3, 2025
f96fa0c
Merge pull request #231 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 3, 2025
22e1bc6
feat: update git workflows secrets
Sotatek-TanHoang Jan 3, 2025
6388375
Merge pull request #232 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 3, 2025
2c3a5ef
feat: update apis for tokens
Sotatek-TanHoang Jan 3, 2025
85dbf32
Merge pull request #233 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 3, 2025
79befb4
feat: get tokens pagination
Sotatek-TanHoang Jan 6, 2025
3c16738
Merge pull request #234 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 6, 2025
826800f
feat: add filters for get tokens api
Sotatek-TanHoang Jan 6, 2025
59a7759
Merge pull request #235 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 6, 2025
b3e4a23
feat: job deploy token
Sotatek-TanHoang Jan 7, 2025
95506af
Merge pull request #236 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 7, 2025
1d87b15
feat: job priority
Sotatek-TanHoang Jan 7, 2025
f6271f3
feat: default value token visibility
Sotatek-TanHoang Jan 7, 2025
95ba5c5
Merge pull request #237 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 7, 2025
0d7b34f
feat: api check token exist
Sotatek-TanHoang Jan 7, 2025
f5f8245
Merge pull request #238 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 7, 2025
d48db82
refactor: error handling
Sotatek-TanHoang Jan 7, 2025
58f0705
Merge pull request #239 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 7, 2025
ba328aa
feat: api redeploy
Sotatek-TanHoang Jan 7, 2025
4c49fd3
Merge pull request #240 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 7, 2025
668686e
feat: add guard admin
Sotatek-TanHoang Jan 7, 2025
3f3a46a
fix: remove hardcode keys
Sotatek-TanHoang Jan 8, 2025
f0122d8
Merge pull request #241 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 8, 2025
223dbb1
feat: add order for get tokens api
Sotatek-TanHoang Jan 8, 2025
b574e99
Merge pull request #242 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 8, 2025
ecbde01
fix: search list token
Sotatek-TanHoang Jan 8, 2025
caee91f
feat: update api tokens for users
Sotatek-TanHoang Jan 8, 2025
b200aee
fix: get list token users
Sotatek-TanHoang Jan 8, 2025
280e9db
Merge pull request #243 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 8, 2025
f23bf44
feat: update seed
Sotatek-TanHoang Jan 8, 2025
8af879a
Merge pull request #244 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 8, 2025
8985974
fix: seed token
Sotatek-TanHoang Jan 8, 2025
8411b58
Merge pull request #245 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 8, 2025
5553c59
feat: update daily quota api
Sotatek-TanHoang Jan 8, 2025
703fa96
Merge pull request #246 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 8, 2025
d0f8958
fix: api daily quota
Sotatek-TanHoang Jan 8, 2025
5b6ceeb
Merge pull request #247 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 8, 2025
a2972e4
fix: job unlock provider
Sotatek-TanHoang Jan 8, 2025
ee8344b
Merge pull request #248 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 8, 2025
53e467f
fix: check daily quota
Sotatek-TanHoang Jan 8, 2025
f02ee21
Merge pull request #249 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 8, 2025
2c3032c
feat: update total circulation
Sotatek-TanHoang Jan 8, 2025
35cac02
fix: default value total circulation
Sotatek-TanHoang Jan 8, 2025
d593218
Merge pull request #250 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 8, 2025
bfef957
fix: get daily quota
Sotatek-TanHoang Jan 8, 2025
b3228c3
Merge pull request #251 from sotatek-dev/feat/add-token
Sotatek-TanHoang Jan 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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