xiongzhu hace 2 años
padre
commit
9f153ead16

+ 6 - 1
.env

@@ -64,4 +64,9 @@ WX_MCH_CERT_SERIAL=7E16A0B9C5BD87038BFF7FD2E0D6653CF45F168F
 WX_MCH_CERT_PATH=src/cert/
 WX_NOTIFY_URL=https://gpt.izouma.com/api/notify/weixin
 
-REDIS_URI=redis://:3a4FSzu8ErP9$CQ&@147.139.168.134:6379/0
+REDIS_URI=redis://:3a4FSzu8ErP9$CQ&@147.139.168.134:6379/0
+
+ETHEREUM_NETWORK=goerli
+INFURA_API_KEY=6e36ce031e304b79af723a0a28789083
+ZKSYNC_RPC_URL=https://testnet.era.zksync.dev
+ZKSYNC_CHAIN_ID=280

+ 6 - 1
.env.production

@@ -64,4 +64,9 @@ WX_MCH_CERT_SERIAL=7E16A0B9C5BD87038BFF7FD2E0D6653CF45F168F
 WX_MCH_CERT_PATH=src/cert/
 WX_NOTIFY_URL=https://gpt.izouma.com/api/notify/weixin
 
-REDIS_URI=redis://:3a4FSzu8ErP9$CQ&@127.0.0.1:6379/0
+REDIS_URI=redis://:3a4FSzu8ErP9$CQ&@127.0.0.1:6379/0
+
+ETHEREUM_NETWORK=mainnet
+INFURA_API_KEY=6e36ce031e304b79af723a0a28789083
+ZKSYNC_RPC_URL=https://mainnet.era.zksync.io
+ZKSYNC_CHAIN_ID=324

+ 4 - 1
package.json

@@ -50,6 +50,7 @@
     "class-validator": "^0.13.0",
     "crypto": "^1.0.1",
     "date-fns": "^2.29.3",
+    "ethers": "~5.7.0",
     "eventsource-parser": "^1.0.0",
     "express-basic-auth": "^1.2.1",
     "express-handlebars": "^7.0.6",
@@ -76,7 +77,9 @@
     "tnwx": "^2.5.6",
     "typeorm": "^0.3.12",
     "uuid": "^9.0.0",
-    "yup": "^1.0.0"
+    "web3": "^4.0.1",
+    "yup": "^1.0.0",
+    "zksync-web3": "^0.14.3"
   },
   "devDependencies": {
     "@inquirer/prompts": "^1.0.0",

+ 25 - 0
src/accounts/accounts.controller.ts

@@ -0,0 +1,25 @@
+import { AccountsService } from './accounts.service'
+import { Body, Controller, Delete, Get, Param, Put, Req } from '@nestjs/common'
+import { Account } from './entities/account.entity'
+
+@Controller('accounts')
+export class AccountsController {
+    constructor(private readonly accountsService: AccountsService) {}
+
+    @Get('/my')
+    public async my(@Req() req) {
+        return await this.accountsService.findByUserId(req.user.userId)
+    }
+
+    @Put()
+    public async save(@Body() accounts: Account | Account[], @Req() req) {
+        if(!Array.isArray(accounts)) accounts = [accounts]
+        accounts.forEach(a => a.userId = req.user.userId)
+        return await this.accountsService.save(accounts)
+    }
+
+    @Delete('/:id')
+    public async delete(@Param('id') id: string) {
+        return await this.accountsService.deleteById(parseInt(id))
+    }
+}

+ 13 - 0
src/accounts/accounts.module.ts

@@ -0,0 +1,13 @@
+import { Module } from '@nestjs/common'
+import { AccountsService } from './accounts.service'
+import { AccountsController } from './accounts.controller'
+import { TypeOrmModule } from '@nestjs/typeorm'
+import { Account } from './entities/account.entity'
+
+@Module({
+    imports: [TypeOrmModule.forFeature([Account])],
+    providers: [AccountsService],
+    controllers: [AccountsController],
+    exports: [AccountsService]
+})
+export class AccountsModule {}

+ 35 - 0
src/accounts/accounts.service.ts

@@ -0,0 +1,35 @@
+import { Injectable, InternalServerErrorException } from '@nestjs/common'
+import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'
+import { Account } from './entities/account.entity'
+import { Repository } from 'typeorm'
+
+@Injectable()
+export class AccountsService {
+    constructor(@InjectRepository(Account) private readonly accountsRepository: Repository<Account>) {}
+
+    async save(account: Partial<Account>[]) {
+        return await this.accountsRepository.save(account)
+    }
+
+    async findByUserId(userId: number) {
+        return await this.accountsRepository.findBy({
+            userId
+        })
+    }
+
+    async deleteById(id: number) {
+        return await this.accountsRepository.delete(id)
+    }
+
+    async findById(id: number) {
+        const account = await this.accountsRepository.findOne({
+            where: {
+                id
+            }
+        })
+        if (!account) {
+            throw new InternalServerErrorException('Account not found')
+        }
+        return account
+    }
+}

+ 19 - 0
src/accounts/entities/account.entity.ts

@@ -0,0 +1,19 @@
+import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'
+
+@Entity()
+export class Account {
+    @PrimaryGeneratedColumn()
+    id: number
+
+    @Column()
+    name: string
+
+    @Column()
+    privateKey: string
+
+    @Column()
+    address: string
+
+    @Column()
+    userId: number
+}

+ 4 - 0
src/app.module.ts

@@ -15,6 +15,8 @@ import { SysConfigModule } from './sys-config/sys-config.module'
 import { AllExceptionsFilter } from './filters/all-exceptions-filter.filter'
 import { DownloadModule } from './download/download.module';
 import { GalleryModule } from './gallery/gallery.module';
+import { AccountsModule } from './accounts/accounts.module';
+import { Web3Module } from './web3/web3.module';
 @Module({
     imports: [
         DevtoolsModule.register({
@@ -68,6 +70,8 @@ import { GalleryModule } from './gallery/gallery.module';
         SysConfigModule,
         DownloadModule,
         GalleryModule,
+        AccountsModule,
+        Web3Module,
     ],
     controllers: [],
     providers: [

+ 14 - 0
src/web3/web3.config.ts

@@ -0,0 +1,14 @@
+import { ConfigService, registerAs } from '@nestjs/config'
+import { config } from 'dotenv'
+
+config()
+
+const configService = new ConfigService()
+
+export default registerAs('web3', () => {
+    return {
+        ethereumNetwork: configService.get<string>('ETHEREUM_NETWORK'),
+        infuraApiKey: configService.get<string>('INFURA_API_KEY'),
+        zksyncRpcUrl: configService.get<string>('ZKSYNC_RPC_URL')
+    }
+})

+ 17 - 0
src/web3/web3.controller.ts

@@ -0,0 +1,17 @@
+import { Body, Controller, Post } from '@nestjs/common'
+import { Web3Service } from './web3.service'
+
+@Controller('web3')
+export class Web3Controller {
+    constructor(private readonly web3Service: Web3Service) {}
+
+    @Post('/zk-deposite')
+    public async zkDeposite(@Body() { accountId, amount }) {
+        return await this.web3Service.zkDeposite(accountId, amount)
+    }
+
+    @Post('/zk-widthdraw')
+    public async zkWidthdraw() {
+        return await this.web3Service.zkWidthdraw()
+    }
+}

+ 13 - 0
src/web3/web3.module.ts

@@ -0,0 +1,13 @@
+import { Module } from '@nestjs/common'
+import { Web3Service } from './web3.service'
+import { Web3Controller } from './web3.controller'
+import { ConfigModule } from '@nestjs/config'
+import web3Config from './web3.config'
+import { AccountsModule } from 'src/accounts/accounts.module'
+
+@Module({
+    imports: [ConfigModule.forFeature(web3Config), AccountsModule],
+    providers: [Web3Service],
+    controllers: [Web3Controller]
+})
+export class Web3Module {}

+ 48 - 0
src/web3/web3.service.ts

@@ -0,0 +1,48 @@
+import { Inject, Injectable, Logger } from '@nestjs/common'
+import { ethers } from 'ethers'
+import { Wallet, Provider, utils } from 'zksync-web3'
+import web3Config from './web3.config'
+import { ConfigType } from '@nestjs/config'
+import { AccountsService } from 'src/accounts/accounts.service'
+
+@Injectable()
+export class Web3Service {
+    constructor(
+        @Inject(web3Config.KEY)
+        private readonly web3Configuration: ConfigType<typeof web3Config>,
+        private readonly accountService: AccountsService
+    ) {}
+
+    async zkDeposite(accountId, amount) {
+        const account = await this.accountService.findById(accountId)
+        const provider = new Provider(this.web3Configuration.zksyncRpcUrl)
+        const ethProvider = new ethers.providers.InfuraProvider(
+            this.web3Configuration.ethereumNetwork,
+            this.web3Configuration.infuraApiKey
+        )
+        const wallet = new Wallet(account.privateKey, provider, ethProvider)
+        const deposit = await wallet.deposit({
+            token: utils.ETH_ADDRESS,
+            amount: ethers.utils.parseEther(amount)
+        })
+        Logger.log('Deposit sent. Awaiting confirmation...')
+        // // Await processing of the deposit on L1
+        // const ethereumTxReceipt = await deposit.waitL1Commit()
+
+        // Logger.log('L1 deposit confirmed! Waiting for zkSync...')
+        // // Await processing the deposit on zkSync
+        // const depositReceipt = await deposit.wait()
+        // Logger.log('zkSync deposit committed.')
+
+        // Logger.log('Checking zkSync account balance')
+        // // Retrieving the current (committed) zkSync ETH balance of an account
+        // const committedEthBalance = await wallet.getBalance()
+        // Logger.log('committedEthBalance', ethers.utils.formatEther(committedEthBalance))
+
+        // // Retrieving the ETH balance of an account in the last finalized zkSync block.
+        // const finalizedEthBalance = await wallet.getBalance(utils.ETH_ADDRESS, 'finalized')
+        // Logger.log('finalizedEthBalance', ethers.utils.formatEther(finalizedEthBalance))
+    }
+
+    async zkWidthdraw() {}
+}

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 866 - 4
yarn.lock


Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio