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

feat(core): testnet faucet page with recaptcha #344

Merged
merged 55 commits into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
a9a6451
feat(ui-ux): testnet faucet page
chloezxyy Nov 2, 2023
bbaa14d
feat(ui-ux): add recaptcha v2
chloezxyy Nov 3, 2023
903a20e
fix(ui-ux): hide /faucet navigation and page if not in Testnet env
chloezxyy Nov 3, 2023
86e53db
feat(server): nestjs setup
lykalabrada Nov 6, 2023
7abc99f
remove nvmrc
lykalabrada Nov 6, 2023
e089e23
fix(ui-ux): evmAddress input and captcha validation
chloezxyy Nov 6, 2023
ae3a8e3
code refactor
chloezxyy Nov 7, 2023
c60bf7d
Merge branch 'main' into chloe/testnet-faucet-ui
chloezxyy Nov 7, 2023
77f546f
code cleanup
chloezxyy Nov 7, 2023
dced78a
Merge branch 'chloe/testnet-faucet-ui' of https://github.com/Birthday…
chloezxyy Nov 7, 2023
23175ef
feature(api): added api for faucet to allocate fund to user (#346)
fullstackninja864 Nov 8, 2023
41e8aa7
fix lint
Nov 8, 2023
207daac
fix typo
Nov 8, 2023
4081d0a
fix lint
Nov 8, 2023
0f8186c
fix ci
Nov 8, 2023
e356202
fix ci
Nov 8, 2023
ebced18
fix ci
Nov 8, 2023
9d56e3c
fix ci
Nov 8, 2023
d0d75e6
fix ci
Nov 8, 2023
b4b0b41
fix ci
Nov 8, 2023
caa2c47
fix ci
Nov 8, 2023
90111e1
fix ci
Nov 8, 2023
d1f4d05
merged lyka/api-setup branch
nattadex Nov 8, 2023
532d82b
moved faucet dir to apps/web
nattadex Nov 8, 2023
e70ff48
changed to getRpcUrl instead of getBaseUrl
nattadex Nov 8, 2023
1588039
api testing
nattadex Nov 9, 2023
f763bff
fixed the cors issue
nattadex Nov 9, 2023
098866a
removed comment
nattadex Nov 9, 2023
65d90ad
print out transaction hash or error
nattadex Nov 9, 2023
1b1327a
merge main
nattadex Nov 9, 2023
9fcd32d
ran prettier
nattadex Nov 9, 2023
b50c1c5
removed unused code
nattadex Nov 9, 2023
baeef45
fixed lint issues
nattadex Nov 9, 2023
792ab66
Merge branch 'main' into chloe/testnet-faucet-ui
chloezxyy Nov 17, 2023
659439d
add import { NestFactory } from '@nestjs/core';
chloezxyy Nov 17, 2023
7373182
fix import problems
chloezxyy Nov 17, 2023
912f623
feat: use user input wallet address
chloezxyy Nov 17, 2023
beb6078
fix: use current connection
chloezxyy Nov 20, 2023
ef41a8f
fix: cors
chloezxyy Nov 20, 2023
4f4832d
fix: use MetascanServerApp
chloezxyy Nov 20, 2023
e9592dd
fix: update allowedHeaders MetascanServerApp
chloezxyy Nov 21, 2023
6425835
feat(server): recaptcha guard on faucet route
chloezxyy Nov 22, 2023
3e1abe8
feat(ui-ux): handle recaptcha validation when sending funds
chloezxyy Nov 22, 2023
c245272
add recaptcha public site key in /web/.env file
chloezxyy Nov 22, 2023
e35a18a
fix format
chloezxyy Nov 22, 2023
078b434
fix(server): private validateRecaptcha guard method
chloezxyy Nov 23, 2023
0875318
Merge branch 'main' into chloe/testnet-faucet-ui
chloezxyy Nov 24, 2023
a0e87eb
update comments
chloezxyy Nov 24, 2023
39585f8
feat(ui-ux): added ux for faucet (#357)
nattadex Nov 24, 2023
2b07d1b
fixed package.json
fullstackninja864 Nov 24, 2023
c74ce55
updated ethers version
fullstackninja864 Nov 24, 2023
4c19bdc
UI fixes
fullstackninja864 Nov 24, 2023
671ccad
fix lint
fullstackninja864 Nov 24, 2023
f34bdcc
hide faucet page
fullstackninja864 Nov 24, 2023
d0f59dc
remove log
fullstackninja864 Nov 24, 2023
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
2 changes: 1 addition & 1 deletion apps/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"@nestjs/throttler": "^5.0.1",
"@waveshq/standard-defichain-jellyfishsdk": "^2.6.1",
"@waveshq/walletkit-core": "^1.3.4",
"axios": "^1.5.0",
"axios": "^1.6.0",
"bignumber.js": "^9.1.2",
"cache-manager": "^5.2.4",
"class-validator": "^0.14.0",
Expand Down
4,887 changes: 3,040 additions & 1,847 deletions apps/server/pnpm-lock.yaml

Large diffs are not rendered by default.

65 changes: 65 additions & 0 deletions apps/server/src/MetascanServerApp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { NestFactory } from '@nestjs/core';
import { NestFastifyApplication } from '@nestjs/platform-fastify';

import { AppModule } from './app.module';

/**
* App which starts the default Metascan Server Application
*/
export class MetascanServerApp<App extends NestFastifyApplication = NestFastifyApplication> {
protected app?: App;

constructor(protected readonly module: any) {}

async createNestApp(): Promise<App> {
const app = await NestFactory.create(AppModule);
await this.configureApp(app);
// @ts-ignore
return app;
}

async configureApp(app): Promise<void> {
app.enableCors({
allowedHeaders: '*',
methods: ['GET', 'PUT', 'POST', 'DELETE'],
maxAge: 60 * 24 * 7,
origin:
process.env.NODE_ENV === 'production'
? [
'https://meta.defiscan.live/',
/https:\/\/([^.]*.\.)*defimetascan\.app/, // allow all subdomains of defimetascan
/https:\/\/([^.]*.)--defimetascan\.netlify\.app/, // allow all netlify preview deployments
/https?:\/\/localhost(:\d+)?/, // allow localhost connection
]
: '*',
});
}

/**
* Run any additional initialisation steps before starting the server.
* If there are additional steps, can be overriden by any extending classes
*/
async init() {
this.app = await this.createNestApp();
return this.app.init();
}

async start(): Promise<App> {
const app = await this.init();

const PORT = process.env.PORT || 3001;
await app.listen(PORT).then(() => {
// eslint-disable-next-line no-console
console.log(`Started server on port ${PORT}`);
});
return app;
}

/**
* Stop NestJs and un-assign this.app
*/
async stop(): Promise<void> {
await this.app?.close();
this.app = undefined;
}
}
6 changes: 4 additions & 2 deletions apps/server/src/faucet/FaucetController.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Controller, Get, HttpException, Inject, Param, Query, UseInterceptors } from '@nestjs/common';
import { Controller, HttpException, Inject, Param, Post, Query, UseGuards, UseInterceptors } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { EnvironmentNetwork } from '@waveshq/walletkit-core';
import { TransactionResponse } from 'ethers';

import { RecaptchaGuard } from '../recaptcha/RecaptchaGuard';
import { AddressValidationInterceptor } from './AddressValidationInterceptor';
import { DefaultNetworkInterceptor } from './DefaultNetworkInterceptor';
import { FaucetService } from './FaucetService';
Expand All @@ -16,7 +17,8 @@ export class FaucetController {
private configService: ConfigService,
) {}

@Get(':address')
@Post(':address')
@UseGuards(RecaptchaGuard)
@UseInterceptors(AddressValidationInterceptor, DefaultNetworkInterceptor)
async sendFunds(
@Param('address') address: string,
Expand Down
6 changes: 4 additions & 2 deletions apps/server/src/faucet/FaucetModule.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { HttpModule } from '@nestjs/axios';
import { CacheModule } from '@nestjs/cache-manager';
import { Module } from '@nestjs/common';

import { RecaptchaGuard } from '../recaptcha/RecaptchaGuard';
import { FaucetController } from './FaucetController';
import { FaucetService } from './FaucetService';

@Module({
imports: [CacheModule.register()],
imports: [CacheModule.register(), HttpModule],
controllers: [FaucetController],
providers: [FaucetService],
providers: [FaucetService, RecaptchaGuard],
})
export class FaucetModule {}
1 change: 1 addition & 0 deletions apps/server/src/faucet/FaucetService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export class FaucetService {
}

async sendFundsToUser(address: string, amount: string, network: EnvironmentNetwork): Promise<TransactionResponse> {
// Send funds to user if recaptcha validation is successful
const evmProviderService = new EVMProviderService(network);
const wallet = new ethers.Wallet(this.privateKey, evmProviderService.provider);
const nonce = await evmProviderService.provider.getTransactionCount(wallet.address);
Expand Down
13 changes: 4 additions & 9 deletions apps/server/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
import { NestFactory } from '@nestjs/core';

import { AppModule } from './app.module';
import { MetascanServerApp } from './MetascanServerApp';

async function bootstrap() {
const app = await NestFactory.create(AppModule);
const PORT = process.env.PORT || 5741;
// eslint-disable-next-line @typescript-eslint/no-floating-promises
app.listen(PORT).then(() => {
// eslint-disable-next-line no-console
console.log(`Started server on port ${PORT}`);
});
const app = new MetascanServerApp(AppModule);
await app.start();
}

void bootstrap();
40 changes: 40 additions & 0 deletions apps/server/src/recaptcha/RecaptchaGuard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { HttpService } from '@nestjs/axios';
import { ExecutionContext, Injectable, Logger } from '@nestjs/common';
import { Request } from 'express';

@Injectable()
export class RecaptchaGuard {
private readonly logger: Logger;

constructor(private readonly httpService: HttpService) {
this.logger = new Logger(RecaptchaGuard.name);
}

async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest<Request>();
return this.validateRecaptcha(request);
}

private async validateRecaptcha(request: Request): Promise<boolean> {
const response = request.body.recaptchaValue;

if (!response) {
this.logger.log('Invalid body in recaptcha request');
return false;
}

const { data } = await this.httpService
.post(
`https://www.google.com/recaptcha/api/siteverify`,
null, // Since we're sending data in the body, set it to null
{
params: {
secret: process.env.SECRET_KEY,
response,
},
},
)
.toPromise();
return data.success;
}
}
5 changes: 4 additions & 1 deletion apps/web/.env
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
NEXT_PUBLIC_RPC_URL_MAINNET="https://blockscout.mainnet.ocean.jellyfishsdk.com"
NEXT_PUBLIC_RPC_URL_TESTNET="https://blockscout.testnet.ocean.jellyfishsdk.com"
NEXT_PUBLIC_RPC_URL_CHANGI="https://blockscout.changi.ocean.jellyfishsdk.com"
NEXT_PUBLIC_RPC_URL_CHANGI="https://blockscout.changi.ocean.jellyfishsdk.com"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use 5741 now for server port 🙏

NEXT_PUBLIC_SERVER_URL="http://localhost:3001/"

NEXT_PUBLIC_SITE_KEY="6LeeoO8oAAAAALPSYZr1_Itr9bBzzQBVDjgjMT0-"
6 changes: 3 additions & 3 deletions apps/web/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@ const securityHeaders = [
value:
`default-src 'none';` +
`base-uri 'self';` +
`child-src 'self' app.netlify.com;` +
`child-src 'self' app.netlify.com https://www.google.com;` +
`form-action 'none';` +
`frame-ancestors 'none';` +
`img-src 'self' images.prismic.io data:;` +
`media-src 'self';` +
`object-src 'none';` +
`script-src 'self' app.netlify.com netlify-cdp-loader.netlify.app ${
`script-src 'self' app.netlify.com netlify-cdp-loader.netlify.app https://www.google.com/recaptcha/ https://www.gstatic.com ${
process.env.NODE_ENV === "development" ? `'unsafe-eval'` : ""
};` +
`style-src 'self' fonts.googleapis.com 'unsafe-inline';` +
`font-src fonts.gstatic.com;` +
`connect-src 'self' *.ocean.jellyfishsdk.com changi.dfi.team ${
process.env.NODE_ENV === "development"
? `ws://localhost:3000/_next/webpack-hmr base-goerli.blockscout.com eth-goerli.blockscout.com`
? `localhost:* 127.0.0.1:* ws://localhost:3000/_next/webpack-hmr base-goerli.blockscout.com eth-goerli.blockscout.com`
: ""
};`,
},
Expand Down
7 changes: 6 additions & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
"dependencies": {
"@floating-ui/react-dom": "^1.3.0",
"@headlessui/react": "^1.7.15",
"@nestjs/axios": "^3.0.1",
"@nestjs/common": "^10.2.5",
"@nestlab/google-recaptcha": "^3.6.0",
"@reduxjs/toolkit": "^1.9.5",
"@waveshq/standard-defichain-jellyfishsdk": "^2.4.1",
"@waveshq/standard-web": "^1.0.4",
Expand All @@ -25,11 +28,12 @@
"connectkit": "^1.4.0",
"dayjs": "^1.11.8",
"dayjs-plugin-utc": "^0.1.2",
"ethers": "^5.7.2",
"ethers": "^6.7.1",
"lodash": "^4.17.21",
"next": "13.4.12",
"react-code-blocks": "0.0.9-0",
"react-dropzone": "^14.2.3",
"react-google-recaptcha": "^3.1.0",
"react-qr-code": "^2.0.11",
"recharts": "^2.7.1",
"viem": "^1.1.0",
Expand All @@ -42,6 +46,7 @@
"@tailwindcss/line-clamp": "^0.4.4",
"@testing-library/cypress": "^9.0.0",
"@types/node": "18.16.3",
"@types/react-google-recaptcha": "^2.1.8",
"@types/recharts": "^1.8.24",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.6.0",
Expand Down
Loading
Loading