-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature(api): added api for faucet to allocate fund to user (#346)
* feature(api): added api for faucet to allocate fund to user * added e2e test * fixed pr comments * added e2e for ratelimiting * added invalid address test case
- Loading branch information
1 parent
7abc99f
commit 23175ef
Showing
22 changed files
with
696 additions
and
442 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { CallHandler, ExecutionContext, HttpException, Injectable, NestInterceptor } from "@nestjs/common"; | ||
import { isAddress } from 'ethers'; | ||
|
||
@Injectable() | ||
export class AddressValidationInterceptor implements NestInterceptor { | ||
intercept(context: ExecutionContext, next: CallHandler) { | ||
const request = context.switchToHttp().getRequest(); | ||
const { address } = request.params; | ||
if (!isAddress(address)) { | ||
throw new HttpException('Invalid Ethereum address', 400); | ||
} | ||
return next.handle(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from "@nestjs/common"; | ||
import { EnvironmentNetwork, getEnvironment } from "@waveshq/walletkit-core"; | ||
|
||
@Injectable() | ||
export class DefaultNetworkInterceptor implements NestInterceptor { | ||
intercept(context: ExecutionContext, next: CallHandler) { | ||
const request = context.switchToHttp().getRequest(); | ||
const { network } = request.query; | ||
const { networks } = getEnvironment(process.env.NODE_ENV); | ||
|
||
if (!network || !networks.includes(network) ) { | ||
request.query.network = EnvironmentNetwork.MainNet; // Set your default network here | ||
} | ||
|
||
return next.handle(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { CACHE_MANAGER } from '@nestjs/cache-manager'; | ||
import { Controller, Get, HttpException, Inject, Param, Query, UseInterceptors } from '@nestjs/common'; | ||
import { ConfigService } from '@nestjs/config'; | ||
import { EnvironmentNetwork } from '@waveshq/walletkit-core'; | ||
import { TransactionResponse } from 'ethers'; | ||
|
||
import { AddressValidationInterceptor } from './AddressValidationInterceptor'; | ||
import { DefaultNetworkInterceptor } from './DefaultNetworkInterceptor'; | ||
import { FaucetService } from './FaucetService'; | ||
|
||
|
||
@Controller('faucet') | ||
export class FaucetController { | ||
constructor( | ||
@Inject(CACHE_MANAGER) private cacheManager: any, | ||
private readonly faucetService: FaucetService, | ||
private configService: ConfigService, | ||
) {} | ||
|
||
@Get(':address') | ||
@UseInterceptors(AddressValidationInterceptor, DefaultNetworkInterceptor) | ||
async sendFunds(@Param('address') address: string, @Query('network') network: EnvironmentNetwork): Promise<TransactionResponse> { | ||
const key = `FAUCET_${address}_${network}`; | ||
const isCached = await this.cacheManager.get(key); | ||
if (isCached) { | ||
throw new HttpException('Transfer already done, pleas try again later.', 403); | ||
} | ||
const amountToSend: string = this.configService.getOrThrow('faucetAmountPerRequest'); // Amount to send in DFI | ||
const ttl = +this.configService.getOrThrow('throttleTimePerAddress') | ||
const response = await this.faucetService.sendFundsToUser(address, amountToSend, network); | ||
await this.cacheManager.set(key, true, { ttl }); | ||
return response; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { CacheModule } from '@nestjs/cache-manager'; | ||
import { Module } from '@nestjs/common'; | ||
|
||
import { FaucetController } from './FaucetController'; | ||
import { FaucetService } from './FaucetService'; | ||
|
||
@Module({ | ||
imports: [ | ||
CacheModule.register(), | ||
], | ||
controllers: [FaucetController], | ||
providers: [FaucetService], | ||
}) | ||
export class FaucetModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* eslint-disable guard-for-in */ | ||
import { Injectable, Logger } from '@nestjs/common'; | ||
import { ConfigService } from '@nestjs/config'; | ||
import { EnvironmentNetwork } from '@waveshq/walletkit-core'; | ||
import { ethers, parseEther,TransactionResponse } from 'ethers'; | ||
|
||
import { EVMProviderService } from '../service/EVMProviderService'; | ||
|
||
@Injectable() | ||
export class FaucetService { | ||
private readonly logger: Logger; | ||
|
||
private readonly privateKey: string; | ||
|
||
constructor( | ||
private configService: ConfigService, | ||
) { | ||
this.logger = new Logger(FaucetService.name); | ||
this.privateKey = this.configService.getOrThrow('privateKey') | ||
} | ||
|
||
async sendFundsToUser(address: string, amount: string, network: EnvironmentNetwork): Promise<TransactionResponse> { | ||
const evmProviderService = new EVMProviderService(network) | ||
const wallet = new ethers.Wallet(this.privateKey, evmProviderService.provider); | ||
const nonce = await evmProviderService.provider.getTransactionCount(wallet.address); | ||
const tx = { | ||
to: address, | ||
value: parseEther(amount), | ||
nonce | ||
}; | ||
this.logger.log(`Initiating transfer of ${amount} DFI ${network} to address ${address}`) | ||
const response = await wallet.sendTransaction(tx) | ||
this.logger.log(`Transfer done to address ${address} of amount ${amount} DFI ${network} with txn hash ${response.hash} at ${new Date().toTimeString()}.`) | ||
return response | ||
} | ||
} |
Oops, something went wrong.