Skip to content

Commit

Permalink
Merge pull request #34 from rsksmart/feat/limit-validation
Browse files Browse the repository at this point in the history
Feat/limit validation
  • Loading branch information
ivegabr authored Nov 14, 2024
2 parents 846b4cb + ff88e88 commit 14940f9
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 7 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ There is no need to change VALUE_TO_DISPENSE, GAS_PRICE, GAS_LIMIT and TAG_MANAG

## Promo Code
In order to use this functionality, you must add an array of objects like this:

```
{ "code": "ESP_01", "activationDate": "2024-11-11", "expirationDate": "2024-11-11" },
{ "code": "ESP_01", "activationDate": "2024-11-13", "expirationDate": "2024-11-14", "maxDispensableRBTC": 1 },
```

## Production deploy
Expand Down
105 changes: 105 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rbtc-faucet",
"version": "2.1.1",
"version": "2.1.3",
"private": true,
"scripts": {
"prod": "NODE_ENV=production next start",
Expand Down
6 changes: 3 additions & 3 deletions src/components/faucet.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ChangeEvent, RefObject, useCallback, useEffect, useState } from 'react';
import React, { ChangeEvent, RefObject, useCallback, useState } from 'react';
import ReCAPTCHA from "react-google-recaptcha";
import { debounce } from '../utils/debounce';
import Spinner from './control/Spinner';
Expand Down Expand Up @@ -41,8 +41,8 @@ const Faucet = (props: FaucetProps) => {


// eslint-disable-next-line react-hooks/exhaustive-deps
const debouncedGetCode = useCallback(debounce((code: string) => {
const data = isCodeActive(code);
const debouncedGetCode = useCallback(debounce(async (code: string) => {
const data = await isCodeActive(code);

setLoading(false);
setValidCode(data.validCode);
Expand Down
23 changes: 21 additions & 2 deletions src/utils/valid-promo-code.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { getPromoCode } from "./env-util";
'use server'

import { loadFaucetHistory } from "@/app/lib/faucetHistory";
import { getPromoCode, getPromoValue } from "./env-util";

type Code = {
code: string;
expirationDate: string; // Expected in "YYYY-MM-DD" format
activationDate: string; // Expected in "YYYY-MM-DD" format
maxDispensableRBTC: number
};

type Response = {
Expand All @@ -17,7 +21,7 @@ type Response = {
* @param code - The code to check
* @returns Response - Object containing the validity of the code and a message
*/
export function isCodeActive(code: string): Response {
export async function isCodeActive(code: string): Promise<Response> {
const codes: Code[] = getPromoCode();
const codeData = codes.find((c) => c.code === code);

Expand All @@ -28,6 +32,13 @@ export function isCodeActive(code: string): Response {
};
}

if (!promoCodeHasRemainingRBTCAllowance(codeData)) {
return {
validCode: false,
msg: "This promo code has reached its maximum usage limit and is no longer available.",
};
}

const today = new Date().toISOString().split("T")[0]; // Format "YYYY-MM-DD"
const { activationDate, expirationDate } = codeData;

Expand All @@ -45,3 +56,11 @@ export function isCodeActive(code: string): Response {
msg: validDate ? "Code is active" : "Code has expired",
};
}

const promoCodeHasRemainingRBTCAllowance = (code: Code) => {
const faucetHistory = loadFaucetHistory();
const PROMO_VALUE_TO_DISPENSE = getPromoValue();
const usedCode = Object.keys(faucetHistory).filter((key) => faucetHistory[key].promoCode === code.code);
const amountDispensed = usedCode.length * PROMO_VALUE_TO_DISPENSE;
return amountDispensed < code.maxDispensableRBTC;
};

0 comments on commit 14940f9

Please sign in to comment.