Skip to content

Commit 75cc2db

Browse files
authored
Add error callback and error redirect url (#71)
1 parent e0dee42 commit 75cc2db

4 files changed

Lines changed: 101 additions & 2 deletions

File tree

src/Reclaim.ts

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ import {
3232
SetParamsError,
3333
SetSignatureError,
3434
SignatureGeneratingError,
35-
SignatureNotFoundError
35+
SignatureNotFoundError,
36+
ErrorDuringVerificationError
3637
} from './utils/errors'
3738
import { validateContext, validateFunctionParams, validateParameters, validateSignature, validateURL, validateModalOptions } from './utils/validationUtils'
3839
import { fetchStatusUrl, initSession, updateSession } from './utils/sessionUtils'
@@ -166,6 +167,8 @@ const emptyTemplateData: TemplateData = {
166167
context: '',
167168
parameters: {},
168169
redirectUrl: '',
170+
errorCallbackUrl: '',
171+
errorRedirectUrl: '',
169172
acceptAiProviders: false,
170173
sdkVersion: '',
171174
providerVersion: '',
@@ -185,6 +188,8 @@ export class ReclaimProofRequest {
185188
private resolvedProviderVersion?: string;
186189
private parameters: { [key: string]: string };
187190
private redirectUrl?: string;
191+
private errorCallbackUrl?: TemplateData['errorCallbackUrl'];
192+
private errorRedirectUrl?: TemplateData['errorRedirectUrl'];
188193
private intervals: Map<string, NodeJS.Timer> = new Map();
189194
private timeStamp: string;
190195
private sdkVersion: string;
@@ -370,6 +375,8 @@ export class ReclaimProofRequest {
370375
parameters,
371376
signature,
372377
redirectUrl,
378+
errorCallbackUrl,
379+
errorRedirectUrl,
373380
timeStamp,
374381
timestamp,
375382
appCallbackUrl,
@@ -405,6 +412,14 @@ export class ReclaimProofRequest {
405412
validateURL(appCallbackUrl, 'fromJsonString');
406413
}
407414

415+
if (errorRedirectUrl) {
416+
validateURL(errorRedirectUrl, 'fromJsonString');
417+
}
418+
419+
if (errorCallbackUrl) {
420+
validateURL(errorCallbackUrl, 'fromJsonString');
421+
}
422+
408423
if (context) {
409424
validateContext(context);
410425
}
@@ -450,6 +465,8 @@ export class ReclaimProofRequest {
450465
proofRequestInstance.resolvedProviderVersion = resolvedProviderVersion;
451466
proofRequestInstance.modalOptions = modalOptions;
452467
proofRequestInstance.jsonProofResponse = jsonProofResponse ?? false;
468+
proofRequestInstance.errorCallbackUrl = errorCallbackUrl;
469+
proofRequestInstance.errorRedirectUrl = errorRedirectUrl;
453470
return proofRequestInstance
454471
} catch (error) {
455472
logger.info('Failed to parse JSON string in fromJsonString:', error);
@@ -500,6 +517,43 @@ export class ReclaimProofRequest {
500517
this.redirectUrl = url;
501518
}
502519

520+
/**
521+
* Sets a custom callback URL where errors will be submitted via HTTP POST
522+
*
523+
* Errors will be HTTP POSTed with `header 'Content-Type': 'application/json'`.
524+
* When a custom error callback URL is set, Reclaim will no longer receive errors upon submission,
525+
* and listeners on the startSession method will not be triggered. Your application must
526+
* coordinate with your backend to receive errors.
527+
*
528+
* @param url - The URL where errors should be submitted via HTTP POST
529+
* @throws {InvalidParamError} When URL is invalid
530+
*
531+
* @example
532+
* ```typescript
533+
* proofRequest.setErrorCallbackUrl('https://your-backend.com/error-callback');
534+
* ```
535+
*/
536+
setErrorCallbackUrl(url: string): void {
537+
validateURL(url, 'setErrorCallbackUrl')
538+
this.errorCallbackUrl = url
539+
}
540+
541+
/**
542+
* Sets an error redirect URL where users will be redirected after error in verification process
543+
*
544+
* @param url - The URL where users should be redirected after error in verification process
545+
* @throws {InvalidParamError} When URL is invalid
546+
*
547+
* @example
548+
* ```typescript
549+
* proofRequest.setErrorRedirectUrl('https://your-app.com/error');
550+
* ```
551+
*/
552+
setErrorRedirectUrl(url: string): void {
553+
validateURL(url, 'setErrorRedirectUrl');
554+
this.errorRedirectUrl = url;
555+
}
556+
503557
/**
504558
* Sets the claim creation type for the proof request
505559
*
@@ -661,6 +715,31 @@ export class ReclaimProofRequest {
661715
}
662716
}
663717

718+
/**
719+
* Returns the currently configured error callback URL
720+
*
721+
* If no custom error callback URL was set via setErrorCallbackUrl(), this returns the default
722+
* Reclaim service error callback URL with the current session ID.
723+
*
724+
* @returns The error callback URL where proofs will be submitted
725+
* @throws {GetAppCallbackUrlError} When unable to retrieve the error callback URL
726+
*
727+
* @example
728+
* ```typescript
729+
* const callbackUrl = proofRequest.getErrorCallbackUrl();
730+
* console.log('Errors will be sent to:', callbackUrl);
731+
* ```
732+
*/
733+
getErrorCallbackUrl(): string {
734+
try {
735+
validateFunctionParams([{ input: this.sessionId, paramName: 'sessionId', isString: true }], 'getErrorCallbackUrl');
736+
return this.errorCallbackUrl || `${constants.DEFAULT_RECLAIM_ERROR_CALLBACK_URL}${this.sessionId}`
737+
} catch (error) {
738+
logger.info("Error getting error callback url", error)
739+
throw new GetAppCallbackUrlError("Error getting error callback url", error as Error)
740+
}
741+
}
742+
664743
/**
665744
* Returns the status URL for monitoring the current session
666745
*
@@ -782,6 +861,8 @@ export class ReclaimProofRequest {
782861
parameters: this.parameters,
783862
signature: this.signature,
784863
redirectUrl: this.redirectUrl,
864+
errorCallbackUrl: this.errorCallbackUrl,
865+
errorRedirectUrl: this.errorRedirectUrl,
785866
timestamp: this.timeStamp, // New field with correct spelling
786867
timeStamp: this.timeStamp, // @deprecated: Remove in future versions
787868
options: this.options,
@@ -821,6 +902,8 @@ export class ReclaimProofRequest {
821902
resolvedProviderVersion: this.resolvedProviderVersion ?? '',
822903
parameters: this.parameters,
823904
redirectUrl: this.redirectUrl ?? '',
905+
errorCallbackUrl: this.getErrorCallbackUrl(),
906+
errorRedirectUrl: this.errorRedirectUrl,
824907
acceptAiProviders: this.options?.acceptAiProviders ?? false,
825908
sdkVersion: this.sdkVersion,
826909
jsonProofResponse: this.jsonProofResponse,
@@ -1208,6 +1291,10 @@ export class ReclaimProofRequest {
12081291
return; // Continue monitoring if under timeout
12091292
}
12101293

1294+
if (statusUrlResponse.session.statusV2 === SessionStatus.ERROR_SUBMISSION_FAILED || statusUrlResponse.session.statusV2 === SessionStatus.ERROR_SUBMITTED) {
1295+
throw new ErrorDuringVerificationError();
1296+
}
1297+
12111298
const isDefaultCallbackUrl = this.getAppCallbackUrl() === `${constants.DEFAULT_RECLAIM_CALLBACK_URL}${this.sessionId}`;
12121299

12131300
if (isDefaultCallbackUrl) {

src/utils/constants.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ export const constants = {
1212
return `${BACKEND_BASE_URL}/api/sdk/callback?callbackId=`;
1313
},
1414

15+
// Default error callback URL for Reclaim protocol
16+
get DEFAULT_RECLAIM_ERROR_CALLBACK_URL() {
17+
return `${BACKEND_BASE_URL}/api/sdk/error-callback?callbackId=`;
18+
},
19+
1520
// Default status URL for Reclaim sessions
1621
get DEFAULT_RECLAIM_STATUS_URL() {
1722
return `${BACKEND_BASE_URL}/api/sdk/session/`;

src/utils/errors.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,5 @@ export const SetSignatureError = createErrorClass('SetSignatureError');
3737
export const GetAppCallbackUrlError = createErrorClass("GetAppCallbackUrlError");
3838
export const StatusUrlError = createErrorClass('StatusUrlError');
3939
export const InavlidParametersError = createErrorClass('InavlidParametersError');
40-
export const ProofSubmissionFailedError = createErrorClass('ProofSubmissionFailedError');
40+
export const ProofSubmissionFailedError = createErrorClass('ProofSubmissionFailedError');
41+
export const ErrorDuringVerificationError = createErrorClass('ErrorDuringVerificationError');

src/utils/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ export enum SessionStatus {
135135
PROOF_SUBMITTED = 'PROOF_SUBMITTED',
136136
AI_PROOF_SUBMITTED = 'AI_PROOF_SUBMITTED',
137137
PROOF_SUBMISSION_FAILED = 'PROOF_SUBMISSION_FAILED',
138+
ERROR_SUBMITTED = 'ERROR_SUBMITTED',
139+
ERROR_SUBMISSION_FAILED = 'ERROR_SUBMISSION_FAILED',
138140
PROOF_MANUAL_VERIFICATION_SUBMITED = 'PROOF_MANUAL_VERIFICATION_SUBMITED',
139141
};
140142

@@ -153,6 +155,8 @@ export type ProofPropertiesJSON = {
153155
timeStamp?: string;
154156
timestamp?: string; // new timestamp field
155157
appCallbackUrl?: string;
158+
errorCallbackUrl?: TemplateData['errorCallbackUrl'];
159+
errorRedirectUrl?: TemplateData['errorRedirectUrl'];
156160
claimCreationType?: ClaimCreationType;
157161
options?: ProofRequestOptions;
158162
sdkVersion: string;
@@ -171,6 +175,8 @@ export type TemplateData = {
171175
context: string;
172176
parameters: { [key: string]: string };
173177
redirectUrl: string;
178+
errorCallbackUrl?: string | null;
179+
errorRedirectUrl?: string | null;
174180
acceptAiProviders: boolean;
175181
sdkVersion: string;
176182
jsonProofResponse?: boolean;

0 commit comments

Comments
 (0)