Skip to content

Commit

Permalink
US-2101 Refactor RNS registration screens for better readability and …
Browse files Browse the repository at this point in the history
…remove circular dependencies (#883)

* feat: __DEV__ resetApp for dev purposes if cannot login

* refactor: RNS Processor to a single instance

* lint: add spaces for readability, rename type

* refactor: commitment logic of RnsProcessor

* lint: convert fn to avoid lint error

* refactor: calculateRnsDomainPrice function

* refactor: formatTokenValues to accept additional resultDecimals param

* refactor: make actionTitle optional in getPopupMessage

* feat: add actual calculation of the price

* refactor: ProfileCreateScreen and profileState functions

* feat: enhance pending transaction
  • Loading branch information
TravellerOnTheRun authored Feb 26, 2024
1 parent cb4ce10 commit 794c2fd
Show file tree
Hide file tree
Showing 28 changed files with 646 additions and 522 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Dispatch, SetStateAction } from 'react'
import { Dispatch, SetStateAction, useCallback } from 'react'
import { FC, ReactNode, createContext, useState, useContext } from 'react'

import GlobalErrorHandlerView from './GlobalErrorHandlerView'
Expand Down Expand Up @@ -26,10 +26,11 @@ const GlobalErrorHandlerProvider: React.FC<GlobalErrorHandlerProviderType> = ({
}) => {
const [globalError, setGlobalError] = useState<string | null>(null)
const [compKey, setCompKey] = useState(0)
const handleReload = () => {

const handleReload = useCallback(() => {
setGlobalError(null)
setCompKey(curKey => curKey + 1)
}
}, [])

return (
<GlobalErrorHandlerContext.Provider
Expand Down
3 changes: 3 additions & 0 deletions src/lib/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ const resources = {
info_box_close_button: 'close',
initial_screen_title: 'Wallet',
initial_screen_button_retry_login: 'Retry unlock',
initial_screen_button_reset_app: 'Reset App',
initial_screen_button_create: 'Create a wallet',
initial_screen_button_import: 'Import existing wallet',
initial_screen_welcome_footer:
Expand Down Expand Up @@ -390,6 +391,8 @@ const resources = {
'URI is not valid. Please try with a new URI.',
popup_message_rns:
'Register your username to allow others to send you funds without worrying about mistyping or inputting wrong address',
popup_not_possible_to_register_rns:
'It is not possible to register RNS domain at this time',
popup_link_text: 'Get username here',
wallet_deployment_label: 'Rif Wallet Deployment',
wallet_backup_title: 'Warning!',
Expand Down
146 changes: 73 additions & 73 deletions src/lib/rns/RnsProcessor.ts
Original file line number Diff line number Diff line change
@@ -1,59 +1,94 @@
import { RSKRegistrar } from '@rsksmart/rns-sdk'
import { BigNumber } from 'ethers'
import { BigNumber, utils } from 'ethers'

import {
getRnsProcessor,
hasRnsProcessor,
saveRnsProcessor,
getRnsProcessIndex,
hasRnsProcessIndex,
saveRnsProcessIndex,
} from 'storage/RnsProcessorStore'
import { OnSetTransactionStatusChange } from 'screens/send/types'
import { RNS_ADDRESSES_TYPE } from 'screens/rnsManager/types'
import {
OnSetTransactionStatusChange,
TransactionStatus,
} from 'store/shared/types'
import { Wallet } from 'shared/wallet'

interface RNSProcessorConstructor {
wallet: Wallet
address: string
onSetTransactionStatusChange?: OnSetTransactionStatusChange
rnsAddresses: RNS_ADDRESSES_TYPE
import { RelayWallet } from '../relayWallet'

interface DomainRegistrationProcess {
domain: string
secret: string
hash: string
registrationHash: string
duration: number
commitmentRequested: boolean
commitmentConfirmed: boolean
registeringRequested: boolean
registeringConfirmed: boolean
commitmentRequestedTimestamp: number
}
export enum DomainRegistrationEnum {
COMMITMENT_REQUESTED = 'COMMITMENT_REQUESTED',
COMMITMENT_CONFIRMED = 'COMMITMENT_CONFIRMED',
WAITING_COMMITMENT = 'WAITING_COMMITMENT',
COMMITMENT_READY = 'COMMITMENT_READY',
REGISTERING_REQUESTED = 'REGISTERING_REQUESTED',
REGISTERING_CONFIRMED = 'REGISTERING_CONFIRMED',
}

export interface IDomainRegistrationProcessIndex {
[domain: string]: DomainRegistrationProcess
}

export const calculateRnsDomainPrice = async (
rskRegistrar: RSKRegistrar,
label: string,
years: number,
) => {
return utils.formatUnits(
await rskRegistrar.price(label, BigNumber.from(years)),
)
}

export class RnsProcessor {
private rskRegistrar
private address
private address: string
private index: IDomainRegistrationProcessIndex = {}
private rnsAddresses: RNS_ADDRESSES_TYPE
public rskRegistrar
onSetTransactionStatusChange?: OnSetTransactionStatusChange

constructor({
wallet,
address,
onSetTransactionStatusChange,
rnsAddresses,
}: RNSProcessorConstructor) {
this.address = address
constructor(
wallet: Wallet,
onSetTransactionStatusChange: OnSetTransactionStatusChange,
rnsAddresses: RNS_ADDRESSES_TYPE,
) {
this.address =
wallet instanceof RelayWallet ? wallet.smartWalletAddress : wallet.address
this.rnsAddresses = rnsAddresses
this.rskRegistrar = new RSKRegistrar(
this.rnsAddresses.rskOwnerAddress,
this.rnsAddresses.fifsAddrRegistrarAddress,
this.rnsAddresses.rifTokenAddress,
wallet,
)
if (hasRnsProcessor()) {
this.index = getRnsProcessor()

if (hasRnsProcessIndex()) {
this.index = getRnsProcessIndex()
}

this.onSetTransactionStatusChange = onSetTransactionStatusChange
}
private setIndex = (
domain: string,
domainRegistrationProcess: IDomainRegistrationProcess,
domainRegistrationProcess: DomainRegistrationProcess,
) => {
this.index[domain] = domainRegistrationProcess
saveRnsProcessor(this.index)
saveRnsProcessIndex(this.index)
}

public deleteRnsProcess = (domain: string) => {
delete this.index[domain]
saveRnsProcessor(this.index)
saveRnsProcessIndex(this.index)
}

public process = async (domain: string, duration: number) => {
Expand All @@ -64,7 +99,7 @@ export class RnsProcessor {

this.onSetTransactionStatusChange?.({
...makeCommitmentTransaction,
txStatus: 'PENDING',
txStatus: TransactionStatus.PENDING,
value: BigNumber.from('0'),
finalAddress: this.rnsAddresses.fifsAddrRegistrarAddress,
})
Expand All @@ -84,7 +119,7 @@ export class RnsProcessor {
makeCommitmentTransaction.wait().then(commitmentTransaction => {
this.onSetTransactionStatusChange?.({
...commitmentTransaction,
txStatus: 'CONFIRMED',
txStatus: TransactionStatus.USER_CONFIRM,
})
this.setIndex(domain, {
...this.index[domain],
Expand Down Expand Up @@ -120,33 +155,22 @@ export class RnsProcessor {
return new Date() > timeWithThreeMinutesAdded
}

public canReveal = async (
domain: string,
isWaitingForCommitmentTransaction = true,
) => {
public canReveal = async (domain: string) => {
try {
// Fail-safe to only ping rskRegistrar after 3 minutes have passed since the transaction was created
// This to avoid request load
if (
this.index[domain]?.commitmentConfirmed ||
(!isWaitingForCommitmentTransaction &&
this.isDomainAllowedToPingRskRegistrarCanReveal(domain))
) {
const canReveal = await this.rskRegistrar.canReveal(
this.index[domain].hash,
)
if (await canReveal()) {
return DomainRegistrationEnum.COMMITMENT_READY
} else {
return DomainRegistrationEnum.WAITING_COMMITMENT
}
const canReveal = await this.rskRegistrar.canReveal(
this.index[domain].hash,
)

if (await canReveal()) {
return DomainRegistrationEnum.COMMITMENT_READY
} else {
return DomainRegistrationEnum.WAITING_COMMITMENT
}
} catch (err) {
throw new Error((err as Error).message)
}
}

public price = async (domain: string) => {
if (this.index[domain]) {
const alias = this.index[domain]?.domain
Expand All @@ -165,6 +189,7 @@ export class RnsProcessor {
try {
const { hash, duration } = this.index[domain]
const canReveal = await this.rskRegistrar.canReveal(hash)

if (await canReveal()) {
const price = await this.rskRegistrar.price(
domain,
Expand All @@ -181,7 +206,7 @@ export class RnsProcessor {
)
this.onSetTransactionStatusChange?.({
...tx,
txStatus: 'PENDING',
txStatus: TransactionStatus.PENDING,
finalAddress: this.rnsAddresses.fifsAddrRegistrarAddress,
})
this.setIndex(domain, {
Expand All @@ -193,7 +218,7 @@ export class RnsProcessor {
tx.wait().then(txReceipt => {
this.onSetTransactionStatusChange?.({
...txReceipt,
txStatus: 'CONFIRMED',
txStatus: TransactionStatus.USER_CONFIRM,
})
this.setIndex(domain, {
...this.index[domain],
Expand All @@ -214,32 +239,7 @@ export class RnsProcessor {
}
}
}
public getStatus = (domain: string): IDomainRegistrationProcess => {
public getStatus = (domain: string): DomainRegistrationProcess => {
return this.index[domain]
}
}

interface IDomainRegistrationProcess {
domain: string
secret: string
hash: string
registrationHash: string
duration: number
commitmentRequested: boolean
commitmentConfirmed: boolean
registeringRequested: boolean
registeringConfirmed: boolean
commitmentRequestedTimestamp: number
}
export enum DomainRegistrationEnum {
COMMITMENT_REQUESTED = 'COMMITMENT_REQUESTED',
COMMITMENT_CONFIRMED = 'COMMITMENT_CONFIRMED',
WAITING_COMMITMENT = 'WAITING_COMMITMENT',
COMMITMENT_READY = 'COMMITMENT_READY',
REGISTERING_REQUESTED = 'REGISTERING_REQUESTED',
REGISTERING_CONFIRMED = 'REGISTERING_CONFIRMED',
}

export interface IDomainRegistrationProcessIndex {
[domain: string]: IDomainRegistrationProcess
}
1 change: 0 additions & 1 deletion src/lib/rns/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export * from './RnsProcessor'
export * from './useRifToken'
export * from './useRnsDomainPriceInRif'
export * from './useProfileStatusColors'
10 changes: 0 additions & 10 deletions src/lib/rns/useRnsDomainPriceInRif.ts

This file was deleted.

1 change: 1 addition & 0 deletions src/navigation/profileNavigator/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export const ProfileNavigator = ({
navigation,
}: RootTabsScreenProps<rootTabsRouteNames.Profile>) => {
const { top } = useSafeAreaInsets()

useEffect(() => {
navigation.setOptions({
headerShown: false,
Expand Down
48 changes: 48 additions & 0 deletions src/redux/shared/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { IApiTransaction } from '@rsksmart/rif-wallet-services'
import { ContractReceipt } from 'ethers'

import { TransactionResponseWithoutWait } from 'screens/send/types'

import { ActivityRowPresentationObject } from '../slices/transactionsSlice'

export enum TransactionStatus {
SUCCESS = 'SUCCESS',
PENDING = 'PENDING',
FAILED = 'FAILED',
USER_CONFIRM = 'USER_CONFIRM',
}

export interface TransactionExtras {
symbol?: string
finalAddress?: string
enhancedAmount?: string
original?: TransactionResponseWithoutWait
}

type TransferTransactionStatus =
| TransferTransactionStatusPending
| TransferTransactionStatusConfirmed
| TransferTransactionStatusFailed

type TransferTransactionStatusPending = {
txStatus: TransactionStatus.PENDING
} & TransactionExtras &
TransactionResponseWithoutWait

type TransferTransactionStatusConfirmed = {
txStatus: TransactionStatus.USER_CONFIRM
original?: TransactionResponseWithoutWait
} & ContractReceipt

type TransferTransactionStatusFailed = {
txStatus: TransactionStatus.FAILED
} & TransactionResponseWithoutWait

export type OnSetTransactionStatusChange = (
transaction: TransferTransactionStatus,
) => void

export type ApiTransactionWithExtras = IApiTransaction & TransactionExtras
export type ModifyTransaction = Partial<IApiTransaction> &
Pick<IApiTransaction, 'hash'> &
Pick<ActivityRowPresentationObject, 'status'>
Loading

0 comments on commit 794c2fd

Please sign in to comment.