Files
inji-wallet/shared/request.ts
KiruthikaJeyashankar 5305e7d7ea [INJIMOB-3392] add token request logic in wallet for vci flow (#2014)
* [INJIMOB-3392] add token request logic in wallet for vci flow

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

* [INJIMOB-3392] chore: update integration of VCIClient native module

Changes are updated as per new changes in the library

Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>

* [INJIMOB-3390] refactor: event structure of token request

Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>

* [INJIMOB-3392] fix tokenEndpoint method and refactorings

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

* [INJIMOB-3392] cnonce decode from accesstoken and credential response destructuring fix

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

* [INJIMOB-3390] add: getIssuerMetadata in kotlin NativeModule

Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>

* [INJIMOB-3393] fix: auth callback in android

Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>

* [INJIMOB-3390] fix: proofJwt issue in download flow

Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>

* [INJIMOB-3392] fix credentialofferflow

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

* [INJIMOB-3392]fix format issues in bridge layer

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

* [INJIMOB-3392]fix activity log texts on application reopen

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

* [INJIMOB-3392]cache issuer metadata by key: issuerhost

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

* [INJIMOB-3392] fix error scenarios and cleanup issuermachine

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

* [INJIMOB-3392] refactor request method to handle missing error scenarios

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

* [INJIMOB-3392] fix max lines for txcode description to 2

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

* [INJIMOB-3392] rename credentialissueruri to credentialissuer

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

* [INJIMOB-3392] take cnonce from outside accesstoken

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

* [INJIMOB-3392] declare random-values at entry file

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

* [INJIMOB-3392] set fallback keytype to user priority first

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

* [INJIMOB-3392] add locales for network request failed error

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

* [INJIMOB-3392] remove console log

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

* [INJIMOB-3392] refactor and clean up code

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>

---------

Signed-off-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>
Signed-off-by: KiruthikaJeyashankar <kiruthikavjshankar@gmail.com>
Co-authored-by: Abhishek Paul <paul.apaul.abhishek.ap@gmail.com>
2025-07-24 11:42:00 +05:30

155 lines
4.0 KiB
TypeScript

import {
DecodedCredential,
VerifiableCredential,
} from '../machines/VerifiableCredential/VCMetaMachine/vc';
import {__AppId} from './GlobalVariables';
import {MIMOTO_BASE_URL, REQUEST_TIMEOUT} from './constants';
import NetInfo from '@react-native-community/netinfo';
import { ErrorMessage } from './openId4VCI/Utils';
export type HTTP_METHOD = 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';
export class BackendResponseError extends Error {
constructor(name: string, message: string) {
super(message);
this.name = name;
}
}
async function assertInternetConnection() {
const net = await NetInfo.fetch();
if (!net.isConnected || net.isInternetReachable === false) {
console.info('No internet');
throw new Error('No internet connection');
}
}
export async function request(
method: HTTP_METHOD,
path: `/${string}` | string,
body?: Record<string, unknown>,
host = MIMOTO_BASE_URL,
headers: Record<string, string> = {
'Content-Type': 'application/json',
},
timeoutMillis?: number | undefined,
) {
if (path.includes('v1/mimoto')) {
headers['X-AppId'] = __AppId.getValue();
}
const requestUrl = path.startsWith('https://') ? path : host + path;
let response;
try {
if (timeoutMillis === undefined) {
response = await fetch(requestUrl, {
method,
headers,
body: body ? JSON.stringify(body) : undefined,
});
} else {
console.info(`Making a web request to ${requestUrl}`);
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeoutMillis);
try {
response = await fetch(requestUrl, {
method,
headers,
body: body ? JSON.stringify(body) : undefined,
signal: controller.signal,
});
} catch (error: any) {
clearTimeout(timeoutId);
console.error(`Request failed: ${requestUrl}:`, error);
if (error.name === 'AbortError') {
throw new Error(REQUEST_TIMEOUT);
}
await assertInternetConnection();
throw error;
}
}
} catch (error: any) {
console.error(`Failed to fetch from ${requestUrl}:`, error);
await assertInternetConnection();
throw error;
}
let jsonResponse;
try {
jsonResponse = await response.json();
} catch (jsonError) {
console.warn(`Failed to parse JSON from ${requestUrl}`, jsonError);
throw new Error(ErrorMessage.NETWORK_REQUEST_FAILED+' Invalid JSON response');
}
if (response.status >= 400) {
const backendUrl = host + path;
const errorMessage =
jsonResponse.message ||
(typeof jsonResponse.error === 'object'
? JSON.stringify(jsonResponse.error)
: jsonResponse.error);
console.error(
`The backend API ${backendUrl} returned error code ${response.status} with message --> ${errorMessage}`,
);
throw new Error(errorMessage);
}
if (jsonResponse.errors && jsonResponse.errors.length) {
const { errorCode, errorMessage } = jsonResponse.errors.shift();
console.error(
`The backend API ${requestUrl} returned structured error --> error code: ${errorCode}, message: ${errorMessage}`,
);
throw new BackendResponseError(errorCode, errorMessage);
}
return jsonResponse;
}
interface ResponseError {
errorCode: string;
errorMessage: string;
}
interface BackendResponse<T> {
id: string;
version: string;
response: T;
str?: string;
responsetime?: string;
metadata?: string;
errors?: ResponseError[];
}
export type OtpRequestResponse = BackendResponse<{
maskedMobile?: string;
maskedEmail?: string;
}>;
export type VcGenerateResponse = BackendResponse<{
vc: string;
message: string;
}>;
export type CredentialRequestResponse = BackendResponse<{
id: string;
requestId: string;
}>;
export type CredentialStatusResponse = BackendResponse<{
statusCode: 'NEW' | 'ISSUED' | 'printing';
}>;
export interface CredentialDownloadResponse {
credential?: DecodedCredential;
verifiableCredential?: VerifiableCredential;
}