/**
 * This logic is in a separate file with no dependencies so that it can be
 * loaded and executed as soon as possible to fulfill the purpose of the protocol
 * detection technique. The effectiveness of this is obviously subject to how web
 * apps bundle/consume the blockstack.js lib.
 */ const GLOBAL_DETECTION_CACHE_KEY = '_blockstackDidCheckEchoReply' ; const ECHO_REPLY_PARAM = 'echoReply' ; const AUTH_CONTINUATION_PARAM = 'authContinuation' ; function getQueryStringParams ( query ) { if ( ! query ) { return { } ; } const trimmed = /^[?#]/ . test ( query ) ? query . slice ( 1 ) : query ; return trimmed . split ( '&' ) . reduce ( ( params , param ) => { const [ key , value ] = param . split ( '=' ) ; params [ key ] = value ? decodeURIComponent ( value . replace ( /\+/g , ' ' ) ) : '' ; return params ; } , { } as Record < string , string > ) ; } returns hidden export function protocolEchoReplyDetection ( ) { let globalScope ; if ( typeof self !== 'undefined' ) { globalScope = self ; } else if ( typeof window !== 'undefined' ) { globalScope = window ; } else { return false ; } if ( ! globalScope . location || ! globalScope . localStorage ) { return false ; } const existingDetection = ( globalScope as any ) [ GLOBAL_DETECTION_CACHE_KEY ] ; if ( typeof existingDetection === 'boolean' ) { return existingDetection ; } const searchParams = getQueryStringParams ( globalScope . location . search ) ; const echoReplyParam = searchParams [ ECHO_REPLY_PARAM ] ; if ( echoReplyParam ) { ( globalScope as any ) [ GLOBAL_DETECTION_CACHE_KEY ] = true ; const echoReplyKey = `echo-reply-${ echoReplyParam }` ; globalScope . localStorage . setItem ( echoReplyKey , 'success' ) ; globalScope . setTimeout ( ( ) => { const authContinuationParam = searchParams [ AUTH_CONTINUATION_PARAM ] ; globalScope . location . href = authContinuationParam ; } , 10 ) ; return true ; } return false ; }