@@ -10,7 +10,6 @@ import {
1010 SendTokenResponse ,
1111 ChainType ,
1212 EVMInstanceAndConfig ,
13- CouponValidity
1413} from './types'
1514
1615import {
@@ -22,7 +21,13 @@ import {
2221 DEBUG ,
2322} from './config.json'
2423import { CouponService } from './CouponService/couponService'
25- import { checkMainnetBalance } from './utils/mainnetBalanceCheck'
24+ import {
25+ PIPELINE_CHECKS ,
26+ PipelineCheckValidity ,
27+ checkCouponPipeline ,
28+ checkMainnetBalancePipeline ,
29+ pipelineFailureMessage
30+ } from './utils/pipelineChecks'
2631
2732dotenv . config ( )
2833
@@ -73,11 +78,13 @@ const getChainByID = (chains: ChainType[], id: string): ChainType | undefined =>
7378 return reply
7479}
7580
81+ const separateConfigFields = [ 'COUPON_REQUIRED' , 'MAINNET_BALANCE_CHECK_RPC' ]
82+
7683// Populates the missing config keys of the child using the parent's config
7784const populateConfig = ( child : any , parent : any ) : any => {
7885 Object . keys ( parent || { } ) . forEach ( ( key ) => {
79- // Do not copy COUPON config (in ERC20 tokens) from host chain
80- if ( key !== 'COUPON_REQUIRED' && ! child [ key ] ) {
86+ // Do not copy configs of separateConfigFields (in ERC20 tokens) from host chain
87+ if ( ! separateConfigFields . includes ( key ) && ! child [ key ] ) {
8188 child [ key ] = parent [ key ]
8289 }
8390 } )
@@ -130,60 +137,50 @@ router.post('/sendToken', captcha.middleware, async (req: any, res: any) => {
130137 const dripAmount = erc20Instance ?. config . DRIP_AMOUNT ?? evm . config . DRIP_AMOUNT
131138
132139 /**
133- * MAINNET BALANCE OR COUPON VALIDATION checks
134- * 1. If mainnet balance check is enabled, users would be required to have mainnet balance
135- * 2. If coupon validation is enabled, users would need a specific coupon id to get tokens
136- * 3. If both are enabled, then any one would be sufficient
140+ * Pipeline Checks
141+ * 1. Pipelines are checks or rules that a request goes through before being processed
142+ * 2. The request should pass at least one pipeline check
143+ * 3. If no pipeline check is required for a token, then directly process the request
144+ * 4. Currently, we have 2 pipeline checks: Coupon Check & Mainnet Balance Check
137145 */
146+ const mainnetCheckEnabledRPC = ( erc20Instance ? erc20Instance . config . MAINNET_BALANCE_CHECK_RPC : evm . config . MAINNET_BALANCE_CHECK_RPC ) ?? false
147+ const couponCheckEnabled = couponConfig . IS_ENABLED && ( ( erc20Instance ? erc20Instance . config . COUPON_REQUIRED : evm . config . COUPON_REQUIRED ) ?? false )
138148
139- // mainnet balance checks
140- const mainnetCheckEnabledRPC = erc20Instance ?. config . MAINNET_BALANCE_CHECK_RPC ?? evm . config . MAINNET_BALANCE_CHECK_RPC ?? false
141- let mainnetCheckPassed = false
142- if ( mainnetCheckEnabledRPC && ( await checkMainnetBalance ( faucetConfigId , mainnetCheckEnabledRPC , address ) ) ) {
143- mainnetCheckPassed = true
144- }
149+ let pipelineValidity : PipelineCheckValidity = { isValid : false , dripAmount}
150+ ! pipelineValidity . isValid && couponCheckEnabled && await checkCouponPipeline ( couponService , pipelineValidity , faucetConfigId , coupon )
151+
152+ // don't check mainnet balance, if coupon is provided
153+ ! pipelineValidity . isValid && ! coupon && mainnetCheckEnabledRPC && await checkMainnetBalancePipeline ( pipelineValidity , mainnetCheckEnabledRPC , address )
145154
146- // validate coupon
147- let couponValidity : CouponValidity = { isValid : false , amount : dripAmount }
148155 if (
149- // check coupon validation only if mainnet check failed (either no-balance or check not enabled)
150- ! mainnetCheckPassed &&
151-
152- // coupon checks
153- couponConfig . IS_ENABLED &&
154- // if request is for erc20 tokens
155- ( ( erc20Instance && erc20Instance . config . COUPON_REQUIRED ) ||
156- // if request is for evm native token
157- ( erc20Instance === undefined && evm . config . COUPON_REQUIRED ) )
156+ ( mainnetCheckEnabledRPC || couponCheckEnabled ) &&
157+ ! pipelineValidity . isValid
158158 ) {
159- // if coupon is required but not passed in request
160- if ( coupon === undefined ) {
161- res . status ( 400 ) . send ( { message : "Coupon is required for this chain or token!" } )
162- return
163- }
164- couponValidity = await couponService . consumeCouponAmount ( coupon , faucetConfigId , dripAmount )
165- if ( ! couponValidity . isValid ) {
166- res . status ( 400 ) . send ( { message : "Invalid or expired coupon provided. Contact support team on Discord!" } )
167- return
168- }
159+ // failed
160+ res . status ( 400 ) . send ( { message : pipelineValidity . errorMessage + pipelineFailureMessage ( mainnetCheckEnabledRPC , couponCheckEnabled ) } )
161+ return
169162 }
170163
171164 // logging requests (if enabled)
172- DEBUG && console . log ( "New faucet request:" , JSON . stringify ( {
173- "type" : "NewFaucetRequest" ,
174- "address" : address ,
175- "chain" : chain ,
176- "erc20" : erc20 ,
177- "ip" : req . headers [ "cf-connecting-ip" ] || req . ip
165+ DEBUG && console . log ( JSON . stringify ( {
166+ type : "NewFaucetRequest" ,
167+ faucetConfigId,
168+ address,
169+ chain,
170+ erc20,
171+ checkPassedType : pipelineValidity . checkPassedType ,
172+ dripAmount : pipelineValidity . dripAmount ,
173+ mainnetBalance : pipelineValidity . mainnetBalance ,
174+ ip : req . headers [ "cf-connecting-ip" ] || req . ip
178175 } ) )
179176
180177 // send request
181- evm . instance . sendToken ( address , erc20 , couponValidity . amount , async ( data : SendTokenResponse ) => {
178+ evm . instance . sendToken ( address , erc20 , pipelineValidity . dripAmount , async ( data : SendTokenResponse ) => {
182179 const { status, message, txHash } = data
183180
184181 // reclaim coupon if transaction is failed
185- if ( coupon && couponValidity . isValid && txHash === undefined ) {
186- await couponService . reclaimCouponAmount ( coupon , dripAmount )
182+ if ( pipelineValidity . checkPassedType === PIPELINE_CHECKS . COUPON && coupon && txHash === undefined ) {
183+ await couponService . reclaimCouponAmount ( coupon , pipelineValidity . dripAmount )
187184 }
188185 res . status ( status ) . send ( { message, txHash} )
189186 } )
0 commit comments