Skip to content

Commit

Permalink
fix: getFee logic to account for Relay and EOA difference
Browse files Browse the repository at this point in the history
  • Loading branch information
TravellerOnTheRun committed Feb 20, 2024
1 parent bf39cf3 commit 35dd446
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 75 deletions.
36 changes: 19 additions & 17 deletions src/lib/eoaWallet/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ import {
} from '@ethersproject/abstract-provider'
import { TypedDataSigner } from '@ethersproject/abstract-signer'
import { fromSeed, mnemonicToSeedSync } from '@rsksmart/rif-id-mnemonic'
import { RelayPayment } from '@rsksmart/rif-relay-light-sdk'
import { getDPathByChainId } from '@rsksmart/rlogin-dpath'
import {
BigNumberish,
Bytes,
BytesLike,
TypedDataDomain,
Expand All @@ -33,38 +31,42 @@ const generatePrivateKey = (mnemonic: string, chainId: ChainID) => {
return privateKey
}

export enum RequestType {
SEND_TRANSACTION = 'sendTransaction',
SIGN_MESSAGE = 'signMessage',
SIGN_TYPED_DATA = 'signTypedData',
}

export type Request =
| SendTransactionRequest
| SignMessageRequest
| SignTypedDataRequest

export type OnRequest = (request: Request) => void

export interface IncomingRequest<Type, Payload, ConfirmArgs> {
type: Type
payload: Payload
confirm: (args?: ConfirmArgs) => Promise<void>
confirm: (args: ConfirmArgs) => Promise<void>
reject: (reason?: any) => void
}

export type SignMessageRequest = IncomingRequest<'signMessage', BytesLike, void>

export interface OverriddableTransactionOptions {
gasLimit: BigNumberish
gasPrice: BigNumberish
tokenPayment?: RelayPayment
pendingTxsCount?: number
}
export type SignMessageRequest = IncomingRequest<
RequestType.SIGN_MESSAGE,
BytesLike,
void
>

export type SendTransactionRequest = IncomingRequest<
'sendTransaction',
RequestType.SEND_TRANSACTION,
TransactionRequest,
Partial<OverriddableTransactionOptions>
unknown
>

export type SignTypedDataArgs = Parameters<TypedDataSigner['_signTypedData']>

export type SignTypedDataRequest = IncomingRequest<
'signTypedData',
RequestType.SIGN_TYPED_DATA,
SignTypedDataArgs,
void
>
Expand Down Expand Up @@ -124,7 +126,7 @@ export class EOAWallet extends Wallet {

return new Promise((resolve, reject) => {
const nextRequest = Object.freeze<SendTransactionRequest>({
type: 'sendTransaction',
type: RequestType.SEND_TRANSACTION,
payload: transactionRequest,
confirm: async () => {
try {
Expand Down Expand Up @@ -152,7 +154,7 @@ export class EOAWallet extends Wallet {
): Promise<string> {
return new Promise((resolve, reject) => {
const nextRequest = Object.freeze<SignTypedDataRequest>({
type: 'signTypedData',
type: RequestType.SIGN_TYPED_DATA,
payload: [domain, types, value],
confirm: async () => {
try {
Expand All @@ -175,7 +177,7 @@ export class EOAWallet extends Wallet {
signMessage(message: string | Bytes): Promise<string> {
return new Promise((resolve, reject) => {
const nextRequest = Object.freeze<SignMessageRequest>({
type: 'signMessage',
type: RequestType.SIGN_MESSAGE,
payload: message,
confirm: async () => {
try {
Expand Down
1 change: 1 addition & 0 deletions src/lib/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ const resources = {
'Please, wait for previous transaction to succeed or fail before making the next one',
send_screen_sending_transaction: 'Sending transaction...',
send_screen_return_to_home: 'Return to Home Screen',
send_transaction_popup: 'Invalid "to" address, rejecting transaction',
security_info_header: 'Security Information',
security_info_user_agreement: 'User agreement',
security_info_disclaimer:
Expand Down
55 changes: 28 additions & 27 deletions src/lib/relayWallet/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,17 @@ import {
TransactionRequest,
TransactionResponse,
} from '@ethersproject/abstract-provider'
import {
RIFRelaySDK,
RelayPayment,
RifRelayConfig,
} from '@rsksmart/rif-relay-light-sdk'
import { Wallet, providers } from 'ethers'
import { BigNumber, BigNumberish, Wallet, providers } from 'ethers'
import { BlockchainAuthenticatorConfig } from '@json-rpc-tools/utils'
import { defineReadOnly } from 'ethers/lib/utils'
import { RIFRelaySDK } from '@rsksmart/rif-relay-light-sdk'

import {
ChainID,
EOAWallet,
IncomingRequest,
OnRequest,
SendTransactionRequest,
RequestType,
WalletState,
} from '../eoaWallet'

Expand All @@ -31,6 +28,25 @@ const filterTxOptions = (transactionRequest: TransactionRequest) =>
return obj
}, {})

export interface RelayPayment {
tokenContract: string
tokenAmount: BigNumber
tokenGasIncrease?: number
}

export interface OverriddableTransactionOptions {
gasLimit: BigNumberish
gasPrice: BigNumberish
tokenPayment: RelayPayment
pendingTxsCount?: number
}

type SendRelayTransactionRequest = IncomingRequest<
RequestType.SEND_TRANSACTION,
TransactionRequest,
OverriddableTransactionOptions
>

export class RelayWallet extends EOAWallet {
public rifRelaySdk: RIFRelaySDK

Expand Down Expand Up @@ -104,12 +120,11 @@ export class RelayWallet extends EOAWallet {
transactionRequest: TransactionRequest,
): Promise<TransactionResponse> {
return new Promise((resolve, reject) => {
const nextRequest = Object.freeze<SendTransactionRequest>({
type: 'sendTransaction',
const nextRequest = Object.freeze<SendRelayTransactionRequest>({
type: RequestType.SEND_TRANSACTION,
payload: transactionRequest,
confirm: async overriddenOptions => {
// check if paying with tokens:
if (overriddenOptions && overriddenOptions.tokenPayment) {
try {
console.log('sendRelayTransaction', transactionRequest)
return resolve(
await this.rifRelaySdk.sendRelayTransaction(
Expand All @@ -121,23 +136,9 @@ export class RelayWallet extends EOAWallet {
overriddenOptions.tokenPayment,
),
)
} catch (err) {
reject(err)
}

// direct execute transaction paying gas with EOA wallet:
const txOptions = {
...filterTxOptions(transactionRequest),
...(overriddenOptions || {}),
}

console.log('txOptions', txOptions)

return resolve(
await this.rifRelaySdk.smartWallet.directExecute(
transactionRequest.to!,
transactionRequest.data ?? HashZero,
txOptions,
),
)
},
reject,
})
Expand Down
14 changes: 6 additions & 8 deletions src/shared/utils/tokenValues.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,19 +64,17 @@ export const getDefaultFeeEOA = () => RBTCToken
export const getDefaultFeeRelay = (chainId: ChainID) =>
getDefaultTokens(chainId)[0]

// make sure to only pass originalTx to value
export const getFee = (chainId: ChainID, to?: string) => {
export const getDefaultTokenContract = (chainId: ChainID) =>
isRelayWallet ? getDefaultFeeRelay(chainId) : getDefaultFeeEOA()

export const getFee = (chainId: ChainID, address?: string) => {
switch (isRelayWallet) {
case true:
const allowedToken = getAllowedFees(chainId).find(
fee => fee.contractAddress.toLowerCase() === to?.toLowerCase(),
fee => fee.contractAddress.toLowerCase() === address?.toLowerCase(),
)

// if the token was not found
// in case of Relay it means that it goes
// directly from an address to address
// which means it is RBTC
return !allowedToken ? getDefaultFeeEOA() : allowedToken
return !allowedToken ? getDefaultFeeRelay(chainId) : allowedToken
case false:
return getDefaultFeeEOA()
}
Expand Down
8 changes: 5 additions & 3 deletions src/ux/requestsModal/RequestHandler.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { RequestType } from 'lib/eoaWallet'

import { RequestWithBitcoin } from 'shared/types'
import { ReviewBitcoinTransactionContainer } from 'src/ux/requestsModal/ReviewBitcoinTransactionContainer'

Expand All @@ -22,14 +24,14 @@ const RequestTypeSwitch = ({
}: RequestTypeSwitchProps) => {
let ComponentToRender = null
switch (request.type) {
case 'sendTransaction':
case RequestType.SEND_TRANSACTION:
ComponentToRender = ReviewTransactionContainer
break
case 'SEND_BITCOIN':
ComponentToRender = ReviewBitcoinTransactionContainer
break
case 'signMessage':
case 'signTypedData':
case RequestType.SIGN_MESSAGE:
case RequestType.SIGN_TYPED_DATA:
ComponentToRender = SignRequestHandlerContainer
break
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,25 @@ import { useTranslation } from 'react-i18next'
import { Alert, StyleSheet, View } from 'react-native'
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { isAddress } from '@rsksmart/rsk-utils'
import { ZERO_ADDRESS } from '@rsksmart/rif-relay-light-sdk'
import { showMessage } from 'react-native-flash-message'

import { balanceToDisplay, convertTokenToUSD } from 'lib/utils'
import { RelayWallet } from 'lib/relayWallet'
import {
OverriddableTransactionOptions,
SendTransactionRequest,
} from 'lib/eoaWallet'
import { OverriddableTransactionOptions, RelayWallet } from 'lib/relayWallet'
import { SendTransactionRequest } from 'lib/eoaWallet'

import { AppButtonBackgroundVarietyEnum } from 'components/index'
import { getTokenAddress } from 'core/config'
import { TokenSymbol } from 'screens/home/TokenImage'
import { TransactionSummaryScreenProps } from 'screens/transactionSummary'
import { TransactionSummaryComponent } from 'screens/transactionSummary/TransactionSummaryComponent'
import { sharedColors } from 'shared/constants'
import { castStyle, errorHandler, getFee, rbtcMap } from 'shared/utils'
import {
castStyle,
errorHandler,
getDefaultTokenContract,
getFee,
rbtcMap,
} from 'shared/utils'
import { selectChainId } from 'store/slices/settingsSlice'
import { selectUsdPrices } from 'store/slices/usdPricesSlice'
import { useAppDispatch, useAppSelector } from 'store/storeUtils'
Expand All @@ -32,6 +35,7 @@ import {
EnhancedTransactionRequest,
enhanceWithGas,
} from 'shared/utils/enhanceWithGas'
import { getPopupMessage } from 'shared/popupMessage'

const tokenToBoolMap = new Map([
[TokenSymbol.RIF, true],
Expand Down Expand Up @@ -81,11 +85,6 @@ export const ReviewTransactionContainer = ({
gasLimit,
} = enhancedTransactionRequest

const fee = useMemo(
() => getFee(chainId, txRequest.to),
[chainId, txRequest.to],
)

const getTokenBySymbol = useCallback(
(symb: string) => {
const result = Object.values(balances).find(
Expand All @@ -109,28 +108,32 @@ export const ReviewTransactionContainer = ({
return getTokenBySymbol(symbol).contractAddress
}
}
return fee.contractAddress
}, [symbol, fee.contractAddress, chainId, getTokenBySymbol])

return getDefaultTokenContract(chainId).contractAddress
}, [symbol, chainId, getTokenBySymbol])

const fee = useMemo(() => getFee(chainId, txRequest.to), [chainId, txRequest])

const tokenQuote = tokenPrices[tokenContract]?.price
const feeQuote = tokenPrices[fee.contractAddress]?.price

useEffect(() => {
if (txRequest.to && !isAddress(txRequest.to)) {
console.log('Invalid "to" address, rejecting transaction')
onCancel()
showMessage(
getPopupMessage(t('send_transaction_popup'), t('ok'), onCancel),
)
}
}, [onCancel, txRequest.to])
}, [onCancel, txRequest.to, t])

// this hook estimatesGas for txRequest
useEffect(() => {
const fn = async () => {
try {
const estimatedCost = await wallet.estimateGas(
txRequest,
fee.contractAddress !== ZERO_ADDRESS
? fee.contractAddress
: undefined,
fee.contractAddress,
)

setTxCost(estimatedCost)

const eTx = await enhanceWithGas(wallet, txRequest, chainId)
Expand Down

0 comments on commit 35dd446

Please sign in to comment.