@@ -29,6 +29,16 @@ import {
2929 PreFormatted ,
3030} from "./Faucet.components" ;
3131
32+ declare global {
33+ interface Window {
34+ turnstile : {
35+ ready : ( cb : ( ) => void ) => void ;
36+ execute : ( container : string , params : { sitekey : string ; callback : ( token : string ) => void ; "error-callback" : ( errorCode : string ) => void } ) => void ;
37+ reset : ( container : string ) => void ;
38+ } ;
39+ }
40+ }
41+
3242enum Status {
3343 PendingPowSolution ,
3444 PendingTransfer ,
@@ -188,15 +198,30 @@ export const FaucetForm: React.FC<Props> = ({ isTestnetLive }) => {
188198 setStatusText ( undefined ) ;
189199
190200 try {
191- const { challenge, tag } = await api
192- . challenge ( )
193- . catch ( ( { message, code } ) => {
194- throw new Error (
195- `Unable to request challenge: ${ code } - ${ message } `
196- ) ;
197- } ) ;
201+ const { challenge, tag } = await api . challenge ( ) . catch ( ( { message, code } ) => {
202+ throw new Error ( `Unable to request challenge: ${ code } - ${ message } ` ) ;
203+ } ) ;
198204
199205 const solution = await postPowChallenge ( { challenge, difficulty } ) ;
206+
207+ // Only attempt captcha if sitekey is configured
208+ const sitekey = process . env . NAMADA_INTERFACE_TURNSTILE_SITEKEY ;
209+ let captcha_token : string | undefined ;
210+
211+ if ( sitekey && sitekey . trim ( ) !== "" ) {
212+ captcha_token = await new Promise < string > ( ( resolve , reject ) => {
213+ if ( window . turnstile ) {
214+ window . turnstile . execute ( "#turnstile-widget" , {
215+ sitekey,
216+ callback : ( t : string ) => resolve ( t ) ,
217+ "error-callback" : ( errorCode : string ) => reject ( new Error ( `Turnstile error: ${ errorCode } ` ) ) ,
218+ } ) ;
219+ } else {
220+ reject ( new Error ( "Turnstile not loaded but sitekey is configured" ) ) ;
221+ }
222+ } ) ;
223+ }
224+
200225 const submitData : Data = {
201226 solution,
202227 tag,
@@ -206,6 +231,7 @@ export const FaucetForm: React.FC<Props> = ({ isTestnetLive }) => {
206231 token : sanitizedToken ,
207232 amount : amount * 1_000_000 ,
208233 } ,
234+ ...( captcha_token && { captcha_token } ) ,
209235 } ;
210236
211237 await submitFaucetTransfer ( submitData ) ;
@@ -316,7 +342,7 @@ export const FaucetForm: React.FC<Props> = ({ isTestnetLive }) => {
316342 error = {
317343 amount && amount > withdrawLimit ?
318344 `Amount must be less than or equal to ${ withdrawLimit } `
319- : ""
345+ : ""
320346 }
321347 />
322348 </ InputContainer >
@@ -363,6 +389,9 @@ export const FaucetForm: React.FC<Props> = ({ isTestnetLive }) => {
363389 Get Testnet Tokens
364390 </ ActionButton >
365391 </ ButtonContainer >
392+ { process . env . NAMADA_INTERFACE_TURNSTILE_SITEKEY && (
393+ < div id = "turnstile-widget" > </ div >
394+ ) }
366395 </ FaucetFormContainer >
367396 ) ;
368397} ;
0 commit comments