From 94d2976e6c8fb4d1446fad849528800aeebb3711 Mon Sep 17 00:00:00 2001 From: Spencer Ofwiti Date: Mon, 8 Feb 2021 14:47:07 +0300 Subject: [PATCH] Completed form handling. --- src/app/_helpers/index.ts | 1 + src/app/_services/transaction.service.ts | 11 ++ src/app/_services/user.service.ts | 31 +++++ .../account-details.component.html | 115 +++++++++++++----- .../account-details.component.ts | 69 ++++++++++- src/app/pages/accounts/accounts.module.ts | 42 ++++--- .../create-account.component.html | 42 +++++-- .../create-account.component.ts | 51 +++++++- .../disbursement/disbursement.component.html | 14 ++- .../disbursement/disbursement.component.ts | 39 +++++- .../export-accounts.component.html | 7 +- .../export-accounts.component.ts | 20 ++- .../settings/invite/invite.component.html | 9 +- .../pages/settings/invite/invite.component.ts | 20 ++- .../organization/organization.component.html | 15 ++- .../organization/organization.component.ts | 21 +++- src/app/pages/settings/settings.module.ts | 4 +- src/environments/environment.prod.ts | 2 + src/environments/environment.ts | 2 + 19 files changed, 431 insertions(+), 84 deletions(-) diff --git a/src/app/_helpers/index.ts b/src/app/_helpers/index.ts index 5952914..b1af67f 100644 --- a/src/app/_helpers/index.ts +++ b/src/app/_helpers/index.ts @@ -1,3 +1,4 @@ export * from './mock-backend'; export * from './array-sum'; export * from './accountIndex'; +export * from './custom-error-state-matcher'; diff --git a/src/app/_services/transaction.service.ts b/src/app/_services/transaction.service.ts index b19c23b..3552600 100644 --- a/src/app/_services/transaction.service.ts +++ b/src/app/_services/transaction.service.ts @@ -83,4 +83,15 @@ export class TransactionService { console.log(error); }); } + + transferRequest(tokenAddress: string, senderAddress: string, recipientAddress: string, value: number): Observable { + return this.http.post( + `${environment.cicEthUrl}/transfer`, + { + tokenAddress: tokenAddress, + from: senderAddress, + to: recipientAddress, + value: value, + }); + } } diff --git a/src/app/_services/user.service.ts b/src/app/_services/user.service.ts index f73594b..c1088db 100644 --- a/src/app/_services/user.service.ts +++ b/src/app/_services/user.service.ts @@ -22,6 +22,37 @@ export class UserService { constructor(private http: HttpClient) { } + resetPin(phone: string): Observable { + const params = new HttpParams().set('phoneNumber', phone); + return this.http.get(`${environment.cicUssdUrl}/pin`, { params }); + } + + createAccount(accountType: string, idNumber: string, phoneNumber: string, givenName: string, surname: string, directoryEntry: string, + location: string, gender: string, referrer: string, businessCategory: string): Observable { + console.log(accountType); + return this.http.post( + `${environment.cicUssdUrl}/user`, + { + accountType: accountType, + idNumber: idNumber, + phone: phoneNumber, + givenName: givenName, + surname: surname, + directoryEntry: directoryEntry, + location: location, + gender: gender, + referrer: referrer, + businessCategory: businessCategory + } + ); + } + + changeAccountInfo(status: string, name: string, phoneNumber: string, type: string, token: string, failedPinAttempts: string, bio: string, + gender: string, businessCategory: string, userLocation: string, location: string, referrer: string): Observable { + console.log(status); + return ; + } + getAccounts(): void { this.http.get(`${environment.cicCacheUrl}/accounts`).pipe(first()).subscribe(accounts => this.accountsList.next(accounts)); } diff --git a/src/app/pages/accounts/account-details/account-details.component.html b/src/app/pages/accounts/account-details/account-details.component.html index 10df82b..e6caa32 100644 --- a/src/app/pages/accounts/account-details/account-details.component.html +++ b/src/app/pages/accounts/account-details/account-details.component.html @@ -27,7 +27,8 @@ Address: {{account?.address}} - + +
Loading... @@ -43,90 +44,110 @@
DETAILS - - +
-
+
STATUS - + Unapproved Approved + Status is required.
Name(s): * - + + Name is required.
Phone Number: - + + Phone Number is required.
ACCOUNT TYPE: - + USER CASHIER VENDOR TOKENAGENT GROUPACCOUNT + Type is required.
USER TOKEN: - + RESERVE ERNIE BERT + Token is required.
Failed Pin Attempts: - + + + Failed Pin Attempts is required. +
Bio: - + + Bio is required.
GENDER: - + MALE FEMALE OTHER + Gender is required.
BUSINESS CATEGORY: - + Food/Water Fuel/Energy Education @@ -138,23 +159,32 @@ Savings Group Savings Group + + Category is required. +
User Location: - + + + User Location is required. +
LOCATION: - +
- + {{village}} @@ -162,26 +192,42 @@
+ Location is required.
Referred By: - + + Referrer is required.
- +
- +
- + +
+ +
+
@@ -210,8 +256,12 @@ {{account?.type}} {{account?.created}} - {{account?.status}} - {{account?.status}} + + {{account?.status}} + + + {{account?.status}} + @@ -291,8 +341,8 @@ search - + View @@ -350,7 +400,8 @@ - + STATUS - {{user.status}} - {{user.status}} + + {{user.status}} + + + {{user.status}} + @@ -433,10 +488,12 @@ - + - +
diff --git a/src/app/pages/accounts/account-details/account-details.component.ts b/src/app/pages/accounts/account-details/account-details.component.ts index 3df2a7e..c9dcf70 100644 --- a/src/app/pages/accounts/account-details/account-details.component.ts +++ b/src/app/pages/accounts/account-details/account-details.component.ts @@ -7,6 +7,8 @@ import {MatSort} from '@angular/material/sort'; import {LocationService, TransactionService, UserService} from '../../../_services'; import {ActivatedRoute, Params, Router} from '@angular/router'; import {first} from 'rxjs/operators'; +import {FormBuilder, FormGroup, Validators} from '@angular/forms'; +import {CustomErrorStateMatcher} from '../../../_helpers'; @Component({ selector: 'app-account-details', @@ -29,6 +31,7 @@ export class AccountDetailsComponent implements OnInit { @ViewChild('HistoryTablePaginator', {static: true}) historyTablePaginator: MatPaginator; @ViewChild('HistoryTableSort', {static: true}) historyTableSort: MatSort; + accountInfoForm: FormGroup; account: any; accounts: any[] = []; accountsType = 'all'; @@ -42,14 +45,31 @@ export class AccountDetailsComponent implements OnInit { transaction: any; transactions: any[]; transactionsType = 'all'; + matcher = new CustomErrorStateMatcher(); + submitted: boolean = false; constructor( + private formBuilder: FormBuilder, private locationService: LocationService, private transactionService: TransactionService, private userService: UserService, private route: ActivatedRoute, private router: Router ) { + this.accountInfoForm = this.formBuilder.group({ + status: ['', Validators.required], + name: ['', Validators.required], + phoneNumber: ['', Validators.required], + type: ['', Validators.required], + token: ['', Validators.required], + failedPinAttempts: ['', Validators.required], + bio: ['', Validators.required], + gender: ['', Validators.required], + businessCategory: ['', Validators.required], + userLocation: ['', Validators.required], + location: ['', Validators.required], + referrer: ['', Validators.required] + }); this.route.paramMap.subscribe((params: Params) => { this.userService.getAccountById(params.get('id')).pipe(first()).subscribe(account => { this.account = account; @@ -58,6 +78,20 @@ export class AccountDetailsComponent implements OnInit { this.historyDataSource.paginator = this.historyTablePaginator; this.historyDataSource.sort = this.historyTableSort; }); + this.accountInfoForm.patchValue({ + status: account.status, + name: account.name, + phoneNumber: account.phone, + type: account.type, + token: account.token, + failedPinAttempts: account.failedPinAttempts, + bio: account.bio, + gender: account.gender, + businessCategory: account.category, + // userLocation: account.userLocation, + location: account.location, + referrer: account.referrer + }); }); }); this.userService.getAccounts(); @@ -120,7 +154,30 @@ export class AccountDetailsComponent implements OnInit { this.router.navigateByUrl(`/accounts/${account.id}`); } - saveInfo(): void {} + get accountInfoFormStub(): any { return this.accountInfoForm.controls; } + + saveInfo(): void { + this.submitted = true; + console.log(this.accountInfoFormStub.userLocation.value); + if (this.accountInfoForm.invalid) { return; } + this.userService.changeAccountInfo( + this.accountInfoFormStub.status.value, + this.accountInfoFormStub.name.value, + this.accountInfoFormStub.phoneNumber.value, + this.accountInfoFormStub.type.value, + this.accountInfoFormStub.token.value, + this.accountInfoFormStub.failedPinAttempts.value, + this.accountInfoFormStub.bio.value, + this.accountInfoFormStub.gender.value, + this.accountInfoFormStub.businessCategory.value, + this.accountInfoFormStub.userLocation.value, + this.accountInfoFormStub.location.value, + this.accountInfoFormStub.referrer.value, + ).pipe(first()).subscribe(res => { + console.log(res); + }); + this.submitted = false; + } filterAccounts(): void { if (this.accountsType === 'all') { @@ -143,4 +200,14 @@ export class AccountDetailsComponent implements OnInit { this.transactionsDataSource.data = this.transactions.filter(transaction => transaction.type === this.transactionsType); } } + + resetPin(): void { + this.userService.resetPin(this.account.phone).pipe(first()).subscribe(res => { + console.log(res); + }); + } + + setDefault(formStub: any, name: string, value: string): void { + formStub[name].value = value; + } } diff --git a/src/app/pages/accounts/accounts.module.ts b/src/app/pages/accounts/accounts.module.ts index f8ae146..8689bd5 100644 --- a/src/app/pages/accounts/accounts.module.ts +++ b/src/app/pages/accounts/accounts.module.ts @@ -23,29 +23,31 @@ import {TransactionsModule} from '../transactions/transactions.module'; import {MatTabsModule} from '@angular/material/tabs'; import {MatRippleModule} from '@angular/material/core'; import {MatProgressSpinnerModule} from '@angular/material/progress-spinner'; +import {ReactiveFormsModule} from '@angular/forms'; @NgModule({ declarations: [AccountsComponent, AccountDetailsComponent, CreateAccountComponent, DisbursementComponent, ExportAccountsComponent], - imports: [ - CommonModule, - AccountsRoutingModule, - SharedModule, - DataTablesModule, - MatTableModule, - MatSortModule, - MatCheckboxModule, - MatPaginatorModule, - MatInputModule, - MatFormFieldModule, - MatButtonModule, - MatCardModule, - MatIconModule, - MatSelectModule, - TransactionsModule, - MatTabsModule, - MatRippleModule, - MatProgressSpinnerModule - ] + imports: [ + CommonModule, + AccountsRoutingModule, + SharedModule, + DataTablesModule, + MatTableModule, + MatSortModule, + MatCheckboxModule, + MatPaginatorModule, + MatInputModule, + MatFormFieldModule, + MatButtonModule, + MatCardModule, + MatIconModule, + MatSelectModule, + TransactionsModule, + MatTabsModule, + MatRippleModule, + MatProgressSpinnerModule, + ReactiveFormsModule + ] }) export class AccountsModule { } diff --git a/src/app/pages/accounts/create-account/create-account.component.html b/src/app/pages/accounts/create-account/create-account.component.html index b2136cf..5f6cc91 100644 --- a/src/app/pages/accounts/create-account/create-account.component.html +++ b/src/app/pages/accounts/create-account/create-account.component.html @@ -22,84 +22,103 @@ CREATE A USER ACCOUNT
-
+
Account Type: - + USER CASHIER VENDOR TOKENAGENT GROUPACCOUNT + Account type is required.
ID Number: - + + ID Number is required.
Phone Number: - + + Phone Number is required.
Given Name(s):* - + + Given Names are required.
Family/Surname: - + + Surname is required.
Directory Entry: - + + Directory Entry is required.
Location: - + +
+
+ + + {{village}} + + +
+
+
+ Location is required.

Gender: - + FEMALE MALE OTHER + Gender is required.
Referrer Phone Number: - + + Referrer is required.
Business Category: - + Food/Water Fuel/Energy Education @@ -111,6 +130,7 @@ Savings Group Other + Business Category is required.
diff --git a/src/app/pages/accounts/create-account/create-account.component.ts b/src/app/pages/accounts/create-account/create-account.component.ts index a46193c..481dfd2 100644 --- a/src/app/pages/accounts/create-account/create-account.component.ts +++ b/src/app/pages/accounts/create-account/create-account.component.ts @@ -1,5 +1,10 @@ import { Component, OnInit } from '@angular/core'; import {Router} from '@angular/router'; +import {FormBuilder, FormGroup, Validators} from '@angular/forms'; +import {ErrorStateMatcher} from '@angular/material/core'; +import {LocationService, UserService} from '../../../_services'; +import {first} from 'rxjs/operators'; +import {CustomErrorStateMatcher} from '../../../_helpers'; @Component({ selector: 'app-create-account', @@ -7,15 +12,57 @@ import {Router} from '@angular/router'; styleUrls: ['./create-account.component.scss'] }) export class CreateAccountComponent implements OnInit { + createForm: FormGroup; + matcher = new CustomErrorStateMatcher(); + submitted: boolean = false; + locations: any; constructor( - private router: Router + private formBuilder: FormBuilder, + private router: Router, + private userService: UserService, + private locationService: LocationService ) { } ngOnInit(): void { + this.createForm = this.formBuilder.group({ + accountType: ['', Validators.required], + idNumber: ['', Validators.required], + phoneNumber: ['', Validators.required], + givenName: ['', Validators.required], + surname: ['', Validators.required], + directoryEntry: ['', Validators.required], + location: ['', Validators.required], + gender: ['', Validators.required], + referrer: ['', Validators.required], + businessCategory: ['', Validators.required] + }); + this.locationService.getLocations(); + this.locationService.locationsSubject.subscribe(locations => { + this.locations = locations; + }); } + get createFormStub(): any { return this.createForm.controls; } + onSubmit(): void { - this.router.navigateByUrl(`/accounts`); + this.submitted = true; + if (this.createForm.invalid) { return; } + this.userService.createAccount( + this.createFormStub.accountType.value, + this.createFormStub.idNumber.value, + this.createFormStub.phoneNumber.value, + this.createFormStub.givenName.value, + this.createFormStub.surname.value, + this.createFormStub.directoryEntry.value, + this.createFormStub.location.value, + this.createFormStub.gender.value, + this.createFormStub.referrer.value, + this.createFormStub.businessCategory.value, + ).pipe(first()).subscribe(res => { + console.log(res); + }); + // this.router.navigateByUrl(`/accounts`); + this.submitted = false; } } diff --git a/src/app/pages/accounts/disbursement/disbursement.component.html b/src/app/pages/accounts/disbursement/disbursement.component.html index b059d8a..137a153 100644 --- a/src/app/pages/accounts/disbursement/disbursement.component.html +++ b/src/app/pages/accounts/disbursement/disbursement.component.html @@ -6,22 +6,28 @@
- +
TRANSACTION TYPE - + DISBURSEMENT TRANSFER DEPOSIT RECLAMATION + Transaction type is required. + + + Enter Recipient: + Enter Amount: - + + Amount is required. -
diff --git a/src/app/pages/accounts/disbursement/disbursement.component.ts b/src/app/pages/accounts/disbursement/disbursement.component.ts index 6e1d4c5..056dbaf 100644 --- a/src/app/pages/accounts/disbursement/disbursement.component.ts +++ b/src/app/pages/accounts/disbursement/disbursement.component.ts @@ -1,4 +1,8 @@ -import {Component, OnInit, EventEmitter, Output} from '@angular/core'; +import {Component, OnInit, EventEmitter, Output, Input} from '@angular/core'; +import {FormBuilder, FormGroup, Validators} from '@angular/forms'; +import {CustomErrorStateMatcher} from '../../../_helpers'; +import {TransactionService} from '../../../_services'; +import {first} from 'rxjs/operators'; @Component({ selector: 'app-disbursement', @@ -6,14 +10,43 @@ import {Component, OnInit, EventEmitter, Output} from '@angular/core'; styleUrls: ['./disbursement.component.scss'] }) export class DisbursementComponent implements OnInit { + @Input() account; @Output() cancelDisbursmentEvent = new EventEmitter(); + disbursementForm: FormGroup; + matcher = new CustomErrorStateMatcher(); + submitted: boolean = false; - constructor() { } + constructor( + private formBuilder: FormBuilder, + private transactionService: TransactionService + ) { } ngOnInit(): void { + this.disbursementForm = this.formBuilder.group({ + transactionType: ['', Validators.required], + recipient: '', + amount: ['', Validators.required] + }); } - createTransfer(): void {} + get disbursementFormStub(): any { return this.disbursementForm.controls; } + + createTransfer(): void { + this.submitted = true; + if (this.disbursementForm.invalid) { return; } + if (this.disbursementFormStub.transactionType.value === 'transfer') { + this.transactionService.transferRequest( + this.account.token, + this.account.address, + this.disbursementFormStub.recipient.value, + this.disbursementFormStub.amount.value + ).pipe(first()).subscribe(res => { + console.log(res); + }); + } + console.log(this.disbursementFormStub.transactionType.value); + this.submitted = false; + } cancel(): void { this.cancelDisbursmentEvent.emit(); diff --git a/src/app/pages/accounts/export-accounts/export-accounts.component.html b/src/app/pages/accounts/export-accounts/export-accounts.component.html index 192415d..4f98e6c 100644 --- a/src/app/pages/accounts/export-accounts/export-accounts.component.html +++ b/src/app/pages/accounts/export-accounts/export-accounts.component.html @@ -22,21 +22,22 @@ EXPORT ACCOUNTS
- +
Export : - + VENDORS PARTNERS SELECTED + Account Type is required.
- +
diff --git a/src/app/pages/accounts/export-accounts/export-accounts.component.ts b/src/app/pages/accounts/export-accounts/export-accounts.component.ts index cc96402..a974653 100644 --- a/src/app/pages/accounts/export-accounts/export-accounts.component.ts +++ b/src/app/pages/accounts/export-accounts/export-accounts.component.ts @@ -1,4 +1,6 @@ import { Component, OnInit } from '@angular/core'; +import {FormBuilder, FormGroup, Validators} from '@angular/forms'; +import {CustomErrorStateMatcher} from '../../../_helpers'; @Component({ selector: 'app-export-accounts', @@ -6,10 +8,26 @@ import { Component, OnInit } from '@angular/core'; styleUrls: ['./export-accounts.component.scss'] }) export class ExportAccountsComponent implements OnInit { + exportForm: FormGroup; + matcher = new CustomErrorStateMatcher(); + submitted: boolean = false; - constructor() { } + constructor( + private formBuilder: FormBuilder + ) { } ngOnInit(): void { + this.exportForm = this.formBuilder.group({ + accountType: ['', Validators.required], + transfers: [''] + }); } + get exportFormStub(): any { return this.exportForm.controls; } + + export(): void { + this.submitted = true; + if (this.exportForm.invalid) { return; } + this.submitted = false; + } } diff --git a/src/app/pages/settings/invite/invite.component.html b/src/app/pages/settings/invite/invite.component.html index 7de4cf0..3f3d458 100644 --- a/src/app/pages/settings/invite/invite.component.html +++ b/src/app/pages/settings/invite/invite.component.html @@ -23,17 +23,20 @@ INVITE NEW USERS
- + Email Address: - + + Email is required.
- + Superadmin
Admin
Subadmin
View
+ Role is required.
diff --git a/src/app/pages/settings/invite/invite.component.ts b/src/app/pages/settings/invite/invite.component.ts index 029239b..5aec4ed 100644 --- a/src/app/pages/settings/invite/invite.component.ts +++ b/src/app/pages/settings/invite/invite.component.ts @@ -1,4 +1,6 @@ import { Component, OnInit } from '@angular/core'; +import {FormBuilder, FormGroup, Validators} from '@angular/forms'; +import {CustomErrorStateMatcher} from '../../../_helpers'; @Component({ selector: 'app-invite', @@ -6,10 +8,26 @@ import { Component, OnInit } from '@angular/core'; styleUrls: ['./invite.component.scss'] }) export class InviteComponent implements OnInit { + inviteForm: FormGroup; + submitted: boolean = false; + matcher = new CustomErrorStateMatcher(); - constructor() { } + constructor( + private formBuilder: FormBuilder + ) { } ngOnInit(): void { + this.inviteForm = this.formBuilder.group({ + email: ['', Validators.required], + role: ['', Validators.required] + }); } + get inviteFormStub(): any { return this.inviteForm.controls; } + + invite(): void { + this.submitted = true; + if (this.inviteForm.invalid) { return; } + this.submitted = false; + } } diff --git a/src/app/pages/settings/organization/organization.component.html b/src/app/pages/settings/organization/organization.component.html index a4de5e3..9e38bf9 100644 --- a/src/app/pages/settings/organization/organization.component.html +++ b/src/app/pages/settings/organization/organization.component.html @@ -23,24 +23,31 @@ DEFAULT ORGANISATION SETTINGS
-
+ Default Disbursement * - + RCU + + Default Disbursement is required. +
- Require Transfer Card * + Require Transfer Card *
Default Country Code * - + KE Kenya US United States ETH Ethiopia GER Germany UG Uganda + + Country Code is required. +
diff --git a/src/app/pages/settings/organization/organization.component.ts b/src/app/pages/settings/organization/organization.component.ts index b7e9eee..42ee358 100644 --- a/src/app/pages/settings/organization/organization.component.ts +++ b/src/app/pages/settings/organization/organization.component.ts @@ -1,4 +1,6 @@ import { Component, OnInit } from '@angular/core'; +import {FormBuilder, FormGroup, Validators} from '@angular/forms'; +import {CustomErrorStateMatcher} from '../../../_helpers'; @Component({ selector: 'app-organization', @@ -6,10 +8,27 @@ import { Component, OnInit } from '@angular/core'; styleUrls: ['./organization.component.scss'] }) export class OrganizationComponent implements OnInit { + organizationForm: FormGroup; + submitted: boolean = false; + matcher = new CustomErrorStateMatcher(); - constructor() { } + constructor( + private formBuilder: FormBuilder + ) { } ngOnInit(): void { + this.organizationForm = this.formBuilder.group({ + disbursement: ['', Validators.required], + transfer: '', + countryCode: ['', Validators.required] + }); } + get organizationFormStub(): any { return this.organizationForm.controls; } + + onSubmit(): void { + this.submitted = true; + if (this.organizationForm.invalid) { return; } + this.submitted = false; + } } diff --git a/src/app/pages/settings/settings.module.ts b/src/app/pages/settings/settings.module.ts index 42839a1..004a0ca 100644 --- a/src/app/pages/settings/settings.module.ts +++ b/src/app/pages/settings/settings.module.ts @@ -18,6 +18,7 @@ import {MatRadioModule} from '@angular/material/radio'; import {MatCheckboxModule} from '@angular/material/checkbox'; import {MatSelectModule} from '@angular/material/select'; import {MatMenuModule} from '@angular/material/menu'; +import {ReactiveFormsModule} from '@angular/forms'; @NgModule({ @@ -37,7 +38,8 @@ import {MatMenuModule} from '@angular/material/menu'; MatRadioModule, MatCheckboxModule, MatSelectModule, - MatMenuModule + MatMenuModule, + ReactiveFormsModule ] }) export class SettingsModule { } diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index 038229b..05bef67 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -3,6 +3,8 @@ export const environment = { cicCacheUrl: 'http://localhost:5555', cicScriptsUrl: 'http://localhost:9999', web3Provider: 'ws://localhost:63545', + cicUssdUrl: 'http://localhost:63315', + cicEthUrl: 'http://localhost:63314', contractAddress: '0x35Ef60C4624Eaf6AeEBeBec9Ddd3CBA6b24C4b17', signerAddress: '0xEb3907eCad74a0013c259D5874AE7f22DcBcC95C', registryAddress: '0xb708175e3f6Cd850643aAF7B32212AFad50e2549' diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 98276ce..5ac2925 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -7,6 +7,8 @@ export const environment = { cicCacheUrl: 'http://localhost:5555', cicScriptsUrl: 'http://localhost:9999', web3Provider: 'ws://localhost:63545', + cicUssdUrl: 'http://localhost:63315', + cicEthUrl: 'http://localhost:63314', contractAddress: '0x35Ef60C4624Eaf6AeEBeBec9Ddd3CBA6b24C4b17', signerAddress: '0xEb3907eCad74a0013c259D5874AE7f22DcBcC95C', registryAddress: '0xb708175e3f6Cd850643aAF7B32212AFad50e2549'