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

[READY] 456 Create UI for BRLa offramp KYC #493

Open
wants to merge 53 commits into
base: staging
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
4c2e152
implement basic PIXKYCForm
Sharqiewicz Feb 19, 2025
033e649
Merge branch 'staging' into 456-create-a-ui-for-brl-offramp-kyc
gianfra-t Feb 20, 2025
ce1e17a
Merge branch '471-add-support-for-offramping-brla-digital-token' into…
gianfra-t Feb 20, 2025
dc3f8e5
Merge branch 'staging' into 456-create-a-ui-for-brl-offramp-kyc
gianfra-t Feb 20, 2025
f3ac457
fixes
gianfra-t Feb 20, 2025
09d28cb
connect BrlaInput and PixKyc components to offramp flow
gianfra-t Feb 21, 2025
3f0dd33
move swap into a separate component
gianfra-t Feb 21, 2025
de6ad1d
add placeholder kyc status spinner
gianfra-t Feb 21, 2025
3f4323f
Merge branch 'staging' into 456-create-a-ui-for-brl-offramp-kyc
gianfra-t Feb 21, 2025
55b4157
connecting brla offramp with details modal
gianfra-t Feb 21, 2025
e733c4b
refactor PIX form code, add animations
Sharqiewicz Feb 26, 2025
b36feda
animate BRL KYC Form, implement unified Input component
Sharqiewicz Feb 26, 2025
8afc550
change OutputTokenType to enum
Sharqiewicz Feb 27, 2025
23a606b
rename Input to Field as it is related with react-hook-form
Sharqiewicz Feb 27, 2025
9042128
Refactor BrlaSwapFields
Sharqiewicz Feb 27, 2025
fcc22d0
implement BrlaField component
Sharqiewicz Feb 27, 2025
23f8955
implement KYCForm component
Sharqiewicz Feb 27, 2025
8247d16
implement VerificationStatus component (BRLA)
Sharqiewicz Feb 27, 2025
5adf457
implement useBRLAKYCProcess hook
Sharqiewicz Feb 27, 2025
f72318c
add validation for inputs
Sharqiewicz Feb 27, 2025
d2bfa32
refactor BrlaExtendedForm
Sharqiewicz Feb 27, 2025
7d2dcc2
rename comments
Sharqiewicz Feb 27, 2025
f8cc120
fix Field registers react-hook-form
Sharqiewicz Feb 27, 2025
67f7b14
clean useSubmitOfframp
Sharqiewicz Mar 2, 2025
8b48180
add header to KYCForm
Sharqiewicz Mar 2, 2025
824ccb0
add docs for brla.controller getAccount
Sharqiewicz Mar 2, 2025
af4977c
change onSwapConfirm type
Sharqiewicz Mar 3, 2025
e74cbf4
fix TokenDefinition type in swap
Sharqiewicz Mar 3, 2025
39eff84
refactor useBRLAKYCProcess
Sharqiewicz Mar 3, 2025
d81ad38
create brla logic hooks
Sharqiewicz Mar 3, 2025
1e9e15e
fix Spinner styles
Sharqiewicz Mar 3, 2025
8990b25
animate VerificationStatus
Sharqiewicz Mar 3, 2025
c8a618f
show progress kyc after submitting
Sharqiewicz Mar 3, 2025
f1cc7ca
shorten logic brla service
Sharqiewicz Mar 3, 2025
be625d7
remove placeholder birthdate
Sharqiewicz Mar 3, 2025
052d5e4
add basic yup validation
Sharqiewicz Mar 3, 2025
53e34b7
Merge branch 'staging' into 456-create-a-ui-for-brl-offramp-kyc
Sharqiewicz Mar 4, 2025
d870e64
fix brla form types
Sharqiewicz Mar 4, 2025
caaa916
remove unnecessary comment
Sharqiewicz Mar 4, 2025
3895349
remove unnecessary signer-service hooks.ts brla
Sharqiewicz Mar 4, 2025
4dd5fc5
Merge branch 'staging' into 456-create-a-ui-for-brl-offramp-kyc
Sharqiewicz Mar 4, 2025
0efce5d
Move brla fields further down in swap form
ebma Mar 4, 2025
929826f
Add placeholder to text fieelds and remove heading
ebma Mar 4, 2025
48ddfdb
Check existence of brla username and password in constructor
ebma Mar 4, 2025
c9702d6
Merge branch 'staging' into 456-create-a-ui-for-brl-offramp-kyc
gianfra-t Mar 4, 2025
5c8db69
add address fields, modify kyc states
gianfra-t Mar 4, 2025
f62ba6b
Merge branch '456-create-a-ui-for-brl-offramp-kyc' of github.com:pend…
gianfra-t Mar 4, 2025
f7d933b
modify store validator, ui states
gianfra-t Mar 5, 2025
362eb86
modifications to kyc status logic from backend
gianfra-t Mar 5, 2025
168258e
add initialize failed message state and action to offramp store, fail…
gianfra-t Mar 5, 2025
cea3a2b
use dialog from ref.current, replace dialog visible setter for global…
gianfra-t Mar 5, 2025
9785e21
fix build, remove comments
gianfra-t Mar 5, 2025
4cbb93f
prevent early return issues
gianfra-t Mar 5, 2025
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
6 changes: 3 additions & 3 deletions signer-service/src/api/middlewares/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ export const validateBrlaTriggerOfframpInput: RequestHandler = (req, res, next)
};

export const validataSubaccountCreation: RequestHandler = (req, res, next) => {
const { phone, taxIdType, address, fullName, cpf, birthDate, companyName, startDate, cnpj } =
const { phone, taxIdType, address, fullName, cpf, birthdate, companyName, startDate, cnpj } =
req.body as RegisterSubaccountPayload;

if (taxIdType !== 'CPF' && taxIdType !== 'CNPJ') {
Expand Down Expand Up @@ -340,8 +340,8 @@ export const validataSubaccountCreation: RequestHandler = (req, res, next) => {
return;
}

if (!birthDate) {
res.status(400).json({ error: 'Missing birthDate parameter' });
if (!birthdate) {
res.status(400).json({ error: 'Missing birthdate parameter' });
return;
}

Expand Down
2 changes: 1 addition & 1 deletion signer-service/src/api/services/brla/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export interface RegisterSubaccountPayload {
address: BrlaAddress;
fullName: string;
cpf: string;
birthDate: string;
birthdate: string;
companyName?: string;
startDate?: string;
cnpj?: string;
Expand Down
56 changes: 42 additions & 14 deletions src/components/BrlaComponents/BrlaExtendedForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,39 +24,67 @@ const PIXKYCFORM_FIELDS: BrlaFieldProps[] = [
index: 0,
},
{
id: ExtendedBrlaFieldOptions.ADDRESS,
label: 'Address',
id: ExtendedBrlaFieldOptions.FULL_NAME,
label: 'Full Name',
type: 'text',
placeholder: 'Address',
placeholder: 'Full Name',
required: true,
index: 1,
},
{
id: ExtendedBrlaFieldOptions.FULL_NAME,
label: 'Full Name',
id: ExtendedBrlaFieldOptions.CEP,
label: 'CEP',
type: 'text',
placeholder: 'Full Name',
placeholder: 'CEP',
required: true,
index: 2,
},
{
id: ExtendedBrlaFieldOptions.CPF,
label: 'CPF',
id: ExtendedBrlaFieldOptions.CITY,
label: 'City',
type: 'text',
placeholder: 'CPF',
validationPattern: {
value: /^\d{11}$/,
message: 'CPF must be 11 digits',
},
placeholder: 'City',
required: true,
index: 3,
},
{
id: ExtendedBrlaFieldOptions.STATE,
label: 'State',
type: 'text',
placeholder: 'State',
required: true,
index: 4,
},
{
id: ExtendedBrlaFieldOptions.STREET,
label: 'Street',
type: 'text',
placeholder: 'Street',
required: true,
index: 5,
},
{
id: ExtendedBrlaFieldOptions.NUMBER,
label: 'Number',
type: 'text',
placeholder: 'Number',
required: true,
index: 6,
},
{
id: ExtendedBrlaFieldOptions.DISTRICT,
label: 'District',
type: 'text',
placeholder: 'District',
required: true,
index: 7,
},
{
id: ExtendedBrlaFieldOptions.BIRTHDATE,
label: 'Birthdate',
type: 'date',
required: true,
index: 4,
index: 8,
},
];

Expand Down
6 changes: 6 additions & 0 deletions src/components/BrlaComponents/BrlaField/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ export enum StandardBrlaFieldOptions {
export enum ExtendedBrlaFieldOptions {
PHONE = 'phone',
ADDRESS = 'address',
CEP = 'cep',
CITY = 'city',
STATE = 'state',
STREET = 'street',
NUMBER = 'number',
DISTRICT = 'district',
FULL_NAME = 'fullName',
CPF = 'cpf',
BIRTHDATE = 'birthdate',
Expand Down
37 changes: 32 additions & 5 deletions src/hooks/brla/useBRLAKYCProcess/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import { useCallback, useState, useEffect } from 'react';
import { useQueryClient } from '@tanstack/react-query';

import { KYCStatus } from '../../../components/BrlaComponents/VerificationStatus';
import { useOfframpActions } from '../../../stores/offrampStore';
import { useOfframpActions, useOfframpStore } from '../../../stores/offrampStore';
import { useOfframpSubmission } from '../useOfframpSubmission';
import { useKYCStatusQuery } from '../useKYCStatusQuery';
import { KYCFormData } from '../useKYCForm';
import { createSubaccount } from '../../../services/signingService';
import { useFormStore } from '../../../stores/formStore';

export interface BrlaKycStatus {
status: string;
Expand Down Expand Up @@ -53,6 +55,7 @@ const useVerificationStatusUI = () => {

export function useKYCProcess(setIsOfframpSummaryDialogVisible: (isVisible: boolean) => void) {
const { verificationStatus, statusMessage, updateStatus, resetToDefault } = useVerificationStatusUI();
const { taxId } = useFormStore();
const [isSubmitted, setIsSubmitted] = useState(false);

const [cpf, setCpf] = useState<string | null>(null);
Expand Down Expand Up @@ -83,11 +86,32 @@ export function useKYCProcess(setIsOfframpSummaryDialogVisible: (isVisible: bool

const handleFormSubmit = useCallback(
Copy link
Member

Choose a reason for hiding this comment

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

This function is missing a call to the createSubaccount() endpoint of our signer service with the relevant fields. Only then, can we query the KYC status of the user and expect to get a meaningful response.

async (formData: KYCFormData) => {
if (!taxId) {
throw new Error('useKYCProcess: Tax ID must be defined at this point');
}
resetToDefault();
setCpf(formData.cpf);
setIsSubmitted(true);

await queryClient.invalidateQueries({ queryKey: ['kyc-status', formData.cpf] });
await queryClient.invalidateQueries({ queryKey: ['kyc-status', taxId] });
const addressObject = {
cep: formData.cep,
city: formData.city,
street: formData.street,
number: formData.number,
district: formData.district,
state: formData.state,
};
createSubaccount({
...formData,
cpf: taxId,
birthdate: formData.birthdate.toDateString(),
address: addressObject,
taxIdType: 'CPF',
})
.catch((error) => handleError(error.message))
.then(() => {
setCpf(taxId); // Only define cpf after the subaccount creation is successful. Otherwise query will fail.
});
},
[queryClient, resetToDefault],
);
Expand All @@ -97,21 +121,24 @@ export function useKYCProcess(setIsOfframpSummaryDialogVisible: (isVisible: bool

const handleStatus = async (status: string) => {
const mappedStatus = status as KYCResponseStatus;
setIsSubmitted(false);

const statusHandlers: Record<KYCResponseStatus, () => Promise<void>> = {
[KYCResponseStatus.SUCCESS]: async () => {
updateStatus(KYCStatus.SUCCESS, STATUS_MESSAGES.SUCCESS);
await delay(SUCCESS_DISPLAY_DURATION_MS);
setIsSubmitted(false);
proceedWithOfframp();
},
[KYCResponseStatus.FAILED]: async () => {
updateStatus(KYCStatus.FAILED, STATUS_MESSAGES.FAILED);
await delay(ERROR_DISPLAY_DURATION_MS);
setIsSubmitted(false);
resetToDefault();
handleBackClick();
},
[KYCResponseStatus.PENDING]: async () => undefined,
[KYCResponseStatus.PENDING]: async () => {
undefined;
Copy link
Member Author

Choose a reason for hiding this comment

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

?

},
};

const handler = statusHandlers[mappedStatus];
Expand Down
33 changes: 25 additions & 8 deletions src/hooks/brla/useKYCForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,38 @@ const kycFormSchema = yup
.required('Phone number is required')
.matches(/^\+?[1-9]\d{9,14}$/, 'Invalid phone number format'),

[ExtendedBrlaFieldOptions.ADDRESS]: yup
.string()
.required('Address is required')
.min(5, 'Address must be at least 5 characters'),

[ExtendedBrlaFieldOptions.FULL_NAME]: yup
.string()
.required('Full name is required')
.min(3, 'Name must be at least 3 characters')
.matches(/^[a-zA-Z\s]*$/, 'Name can only contain letters and spaces'),

[ExtendedBrlaFieldOptions.CPF]: yup
[ExtendedBrlaFieldOptions.CEP]: yup
.string()
.required('CEP is required')
.min(3, 'CEP must be at least 3 characters'),

[ExtendedBrlaFieldOptions.CITY]: yup
.string()
.required('City is required')
.min(5, 'City must be at least 5 characters'),

[ExtendedBrlaFieldOptions.STATE]: yup
.string()
.required('State is required')
.min(3, 'State must be at least 3 characters'),

[ExtendedBrlaFieldOptions.STREET]: yup
.string()
.required('Street is required')
.min(5, 'Street must be at least 5 characters'),

[ExtendedBrlaFieldOptions.NUMBER]: yup.string().required('Number is required'),

[ExtendedBrlaFieldOptions.DISTRICT]: yup
.string()
.required('CPF is required')
.matches(/^\d{11}$/, 'CPF must be 11 digits'),
.required('District is required')
.min(3, 'District must be at least 3 characters'),

[ExtendedBrlaFieldOptions.BIRTHDATE]: yup
.date()
Expand Down
2 changes: 1 addition & 1 deletion src/services/signingService.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export interface RegisterSubaccountPayload {
};
fullName: string;
cpf: string;
birthDate: string;
birthdate: string;
}

export interface SignerServiceSep10Request {
Expand Down
2 changes: 1 addition & 1 deletion src/stores/formStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type FormStore = FormState & {
actions: FormStoreActions;
};

const useFormStore = create<FormStore>((set) => ({
export const useFormStore = create<FormStore>((set) => ({
fromAmount: undefined,
fromToken: undefined,
toToken: undefined,
Expand Down