Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: suppot TFGrid-KYC #3531

Merged
merged 50 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
e0942aa
Feat: add kyc to profile storage
0oM4R Oct 15, 2024
2f8e5eb
Feat: WIP adding KYC UI
0oM4R Oct 16, 2024
4805e7f
Feat: suppot TFGrid-KYC in gridclient
0oM4R Oct 16, 2024
c6f9e07
chore: export KYC client
0oM4R Oct 16, 2024
154c17f
Chore:
0oM4R Oct 16, 2024
ef66fde
chore : use urlJoin
0oM4R Oct 16, 2024
3d14655
refactor: retrive address from mnemoinic
0oM4R Oct 16, 2024
6632a56
chore: add api prefix as const
0oM4R Oct 17, 2024
e955e6a
Merge branch 'development' of github.com:threefoldtech/tfgrid-sdk-ts …
0oM4R Oct 21, 2024
bdcb5ce
Merge branch 'development_kyc' of github.com:threefoldtech/tfgrid-sdk…
0oM4R Oct 21, 2024
2af3b4d
prepare KYC client
0oM4R Oct 21, 2024
d11860f
WIP: itegrate the kyc client in dashboard
0oM4R Oct 21, 2024
7579268
chore: update status response
0oM4R Oct 22, 2024
96cc450
Feat: handle idenfy iframe
0oM4R Oct 22, 2024
34aa6fc
chore: create kyc store
0oM4R Oct 22, 2024
6ce858d
chore: use kyc in env
0oM4R Oct 22, 2024
6ea1b4b
chore: use kyc store
0oM4R Oct 22, 2024
f03cf67
WIP: kyc style
0oM4R Oct 22, 2024
96ad9b5
Style: enhance kyc dialog loading
0oM4R Oct 22, 2024
1873a50
chore: add kyc to gridclient
0oM4R Oct 22, 2024
c93b84e
chore pass kyc url in gridclient options
0oM4R Oct 22, 2024
f571351
chore: handle domain post/prefix
0oM4R Oct 22, 2024
1255404
WIP: add kyc errors
0oM4R Oct 23, 2024
70c00af
kyc: add token errors
0oM4R Oct 23, 2024
5f20410
finalize errors
0oM4R Oct 23, 2024
60266c2
add kyc client to twindeployment handler
0oM4R Oct 23, 2024
d5d33ee
apply error handling
0oM4R Oct 23, 2024
74df586
add requirekyc
0oM4R Oct 23, 2024
8917e32
update tooltip
0oM4R Oct 23, 2024
b7d9b4d
Merge branch 'development' of github.com:threefoldtech/tfgrid-sdk-ts …
0oM4R Oct 23, 2024
50bb804
cleanup
0oM4R Oct 23, 2024
02afab2
cleanup
0oM4R Oct 23, 2024
647f653
cleanup
0oM4R Oct 23, 2024
2f3a69d
style: add icon, remove check
0oM4R Oct 23, 2024
15852f6
UX: enhance token error handling
0oM4R Oct 23, 2024
0ed4767
chore: use enum status code
0oM4R Oct 24, 2024
583212d
rephrase client error message
0oM4R Oct 24, 2024
a74b9d4
fix typo
0oM4R Oct 24, 2024
23e194e
chore: use new status endpoint
0oM4R Oct 27, 2024
5d7fd30
Fix:
0oM4R Oct 28, 2024
5a28b4f
chore: enhance error messages
0oM4R Oct 29, 2024
be22124
Refactor:
0oM4R Oct 29, 2024
395f606
Refactor:
0oM4R Oct 29, 2024
3096bfa
fix: headers, enahnce error msg
0oM4R Oct 29, 2024
d95d163
refactor:
0oM4R Oct 30, 2024
02a4fc0
WIP: handle diffrent networks
0oM4R Oct 30, 2024
9758bd9
docs: add kyc to build docs
0oM4R Oct 30, 2024
38539a3
refactor:
0oM4R Oct 30, 2024
5ad3c2f
feat: add isHealty to kyc client
0oM4R Oct 30, 2024
f8ffea0
chore: remove kyc check on createNameContract
0oM4R Oct 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions packages/grid_client/src/clients/kyc/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { Keyring } from "@polkadot/keyring";
import { KeyringPair } from "@polkadot/keyring/types";
import { waitReady } from "@polkadot/wasm-crypto";

import { KeypairType, send } from "../..";
import { KycHeaders, TokenResponse, VerificationDataResponse, VerificationStatusResponse } from "./types";

/**
* The KYC class provides methods to interact with a TFGid KYC (Know Your Customer) service.
* It allows fetching verification data, status, and token by preparing necessary headers
* and sending requests to the specified API domain.
*
* @class KYC
* @example
* ```typescript
* const kyc = new KYC("https://api.example.com", "TFChain-address", KeypairType.sr25519, "mnemonic");
* const data = await kyc.data();
* const status = await kyc.status();
* const token = await kyc.token();
* ```
* @param {string} apiDomain - The API domain for the KYC service.
* @param {string} address - The TFChain address.
* @param {KeypairType} [keypairType=KeypairType.sr25519] - The type of keypair to use.
* @param {string} mnemonic - The mnemonic for generating the keypair.
* @method data - Fetches the verification data from the KYC service.
* @method status - Fetches the verification status from the KYC service.
* @method token - Fetches the token from the KYC service.
*/
export default class KYC {
private keyr: Keyring;
/**
* Creates an instance of KYC.
* @param apiDomain - The API domain for the TFGrid KYC service.
* @param address - The TFChain user address.
* @param keypairType - The type of keypair to use (default is sr25519).
* @param mnemonic - The mnemonic for generating the keypair.
*/
constructor(
public apiDomain: string,
public address: string,
AhmedHanafy725 marked this conversation as resolved.
Show resolved Hide resolved
public keypairType: KeypairType = KeypairType.sr25519,
private mnemonic: string,
) {
this.keyr = new Keyring({ type: keypairType });
}

/**
* Retrieves a key pair from the mnemonic.
*
* @returns {Promise<KeyringPair>} A promise that resolves to a KeyringPair object.
* @private
*/
private async getKey(): Promise<KeyringPair> {
await waitReady();
return this.keyr.addFromUri(this.mnemonic);
}
/**
* Converts a string message to its hexadecimal representation.
* @param message - The message to convert.
* @returns The hexadecimal representation of the message.
*/
private stringToHex(message: string): string {
AhmedHanafy725 marked this conversation as resolved.
Show resolved Hide resolved
return Buffer.from(message).toString("hex");
}
/**
* Converts a hexadecimal string to a byte array.
* @param hex - The hexadecimal string to convert.
* @returns {Uint8Array} The byte array representation of the hexadecimal string.
*/
private bytesFromHex(hex: string): Uint8Array {
AhmedHanafy725 marked this conversation as resolved.
Show resolved Hide resolved
return new Uint8Array(Buffer.from(hex, "hex"));
}

/**
* Prepares the headers required for TFGrid KYC requests.
*
* This method generates a set of headers that include a timestamp-based challenge,
* a signed challenge using the user's key, and other necessary information.
*
* @returns {Promise<Record<string, string>>} A promise that resolves to an object containing the prepared headers.
*
*/
private async prepareHeaders(): Promise<Record<string, string>> {
0oM4R marked this conversation as resolved.
Show resolved Hide resolved
const timestamp = Date.now();
const challenge = this.stringToHex(`${this.apiDomain}:${timestamp}`);
const key = await this.getKey();
const signedChallenge = key.sign(this.bytesFromHex(challenge));
const signedMsgHex = Buffer.from(signedChallenge).toString("hex");

const headers: KycHeaders = {
"content-type": "application/json",
"X-Client-ID": this.address,
"X-Challenge": challenge,
"X-Signature": signedMsgHex,
};
return headers as unknown as Record<string, string>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unknown?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes we have to convert the type to record so we have to use it ref
What do you suggest?

}

/**
* Fetches the verification data from the API.
*
* @returns {Promise<VerificationDataResponse>} A promise that resolves to the verification data response.
* @throws {RequestError} If there is an issue with fetching the data.
*/
async data(): Promise<VerificationDataResponse> {
const headers = await this.prepareHeaders();
return (await send("GET", `${this.apiDomain}/data`, "", headers)) as VerificationDataResponse;
AhmedHanafy725 marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Retrieves the current verification status.
*
* @returns {Promise<VerificationStatusResponse>} A promise that resolves to the verification status response.
* @throws {RequestError} If there is an issue with fetching the status data.
*/
async status(): Promise<VerificationStatusResponse> {
const headers = await this.prepareHeaders();
return (await send("GET", `${this.apiDomain}/status`, "", headers)) as VerificationStatusResponse;
}

/**
* Retrieves a token data from the KYC service API.
*
* @returns {Promise<TokenResponse>} A promise that resolves to a TokenResponse object.
* @throws {RequestError} If there is an issue with fetching the token data.
*/
async token(): Promise<TokenResponse> {
const headers = await this.prepareHeaders();
return (await send("POST", `${this.apiDomain}/token`, "", headers)) as TokenResponse;
}
}
84 changes: 84 additions & 0 deletions packages/grid_client/src/clients/kyc/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* KYC service token response type
*/
export interface TokenResponse {
authToken: string;
clientId: string;
digitString: string;
expiryTime: number;
message: string;
scanRef: string;
sessionLength: number;
tokenType: string;
}
/**
* @interface VerificationStatusResponse
* KYC service token response type
*/
export interface VerificationStatusResponse {
autoDocument: string;
autoFace: string;
clientId: string;
fraudTags: string[];
manualDocument: string;
manualFace: string;
mismatchTags: string[];
scanRef: string;
status: string;
}

export interface VerificationDataResponse {
additionalData: object;
address: string;
addressVerification: object;
ageEstimate: string;
authority: string;
birthPlace: string;
clientId: string;
clientIpProxyRiskLevel: string;
docBirthName: string;
docDateOfIssue: string;
docDob: string;
docExpiry: string;
docFirstName: string;
docIssuingCountry: string;
docLastName: string;
docNationality: string;
docNumber: string;
docPersonalCode: string;
docSex: string;
docTemporaryAddress: string;
docType: string;
driverLicenseCategory: string;
duplicateDocFaces: string[];
duplicateFaces: string[];
fullName: string;
manuallyDataChanged: boolean;
mothersMaidenName: string;
orgAddress: string;
orgAuthority: string;
orgBirthName: string;
orgBirthPlace: string;
orgFirstName: string;
orgLastName: string;
orgMothersMaidenName: string;
orgNationality: string;
orgTemporaryAddress: string;
scanRef: string;
selectedCountry: string;
}

/**
* Interface representing the headers required for KYC (Know Your Customer) requests.
*
* @property {string} content-type - The MIME type of the request body.
* @property {string} X-Client-ID - TF chian address
* @property {string} X-Challenge - hex-encoded message `{api-domain}:{timestamp}`.
* @property {string} X-Signature - hex-encoded sr25519|ed25519 signature.
*/
export interface KycHeaders {
"content-type": string;
"X-Client-ID": string;
"X-Challenge": string;
"X-Signature": string;
}
Loading