Skip to content

Commit

Permalink
Merge branch 'develop' into fix/transak-getUrl-input-validation
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkNerdi authored Feb 29, 2024
2 parents dec6319 + e1c20c9 commit 176b69f
Show file tree
Hide file tree
Showing 30 changed files with 221 additions and 160 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import { openUrlInBrowser } from '@core/app'
import { handleError } from '@core/error/handlers'
import { localize } from '@core/i18n'
import { IIrc27Nft, Nft, isIrc27Nft, isNftLocked } from '@core/nfts'
import { isEvmChain } from '@core/network'
import { IIrc27Nft, Nft, isNftLocked } from '@core/nfts'
import { checkActiveProfileAuthAsync } from '@core/profile/actions'
import { activeProfile, updateActiveProfile } from '@core/profile/stores'
import { CollectiblesRoute, collectiblesRouter } from '@core/router'
Expand All @@ -14,7 +15,7 @@
export let nft: Nft
$: isLocked = isNftLocked(nft)
$: isBurnDisabled = isLocked || !isIrc27Nft(nft)
$: isBurnDisabled = isLocked || isEvmChain(nft.networkId)
$: isCurrentPfp = $activeProfile.pfp?.id === nft.id
function onSetPfpClick(): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { handleError } from '@core/error/handlers'
import { IConnectedDapp } from '@auxiliary/wallet-connect/interface'
import { CallbackParameters } from '@auxiliary/wallet-connect/types'
import { signAndSendTransactionFromEvm } from '@core/wallet/actions'
import { sendAndPersistTransactionFromEvm, signEvmTransaction } from '@core/wallet/actions'
import { selectedAccount } from '@core/account/stores'
import { ExplorerEndpoint, IChain, getDefaultExplorerUrl } from '@core/network'
import { DappInfo, TransactionAssetSection } from '@ui'
Expand All @@ -13,6 +13,7 @@
import {
calculateEstimatedGasFeeFromTransactionData,
calculateMaxGasFeeFromTransactionData,
getHexEncodedTransaction,
getMethodNameForEvmTransaction,
} from '@core/layer-2'
import { getTokenFromSelectedAccountTokens } from '@core/token/stores'
Expand All @@ -28,17 +29,23 @@
import { BASE_TOKEN_ID } from '@core/token/constants'
import { checkActiveProfileAuthAsync } from '@core/profile/actions'
import { LedgerAppName } from '@core/ledger'
import { DappVerification } from '@auxiliary/wallet-connect/enums'
import { DappVerification, RpcMethod } from '@auxiliary/wallet-connect/enums'
import { LegacyTransaction } from '@ethereumjs/tx'
export let preparedTransaction: EvmTransactionData
export let chain: IChain
export let dapp: IConnectedDapp
export let signAndSend: boolean
export let verifiedState: DappVerification
export let method: RpcMethod.EthSendTransaction | RpcMethod.EthSignTransaction | RpcMethod.EthSendRawTransaction
export let callback: (params: CallbackParameters) => void
const { id } = chain.getConfiguration()
$: localeKey = signAndSend ? (isSmartContractCall ? 'smartContractCall' : 'sendTransaction') : 'signTransaction'
$: localeKey =
method === RpcMethod.EthSignTransaction
? 'signTransaction'
: isSmartContractCall
? 'smartContractCall'
: 'sendTransaction'
let nft: Nft | undefined
let tokenTransfer: TokenTransferData | undefined
Expand Down Expand Up @@ -79,6 +86,30 @@
}
}
async function getSignedTransaction(): Promise<string> {
if (preparedTransaction?.v && preparedTransaction?.s && preparedTransaction?.r) {
const transaction = LegacyTransaction.fromTxData(preparedTransaction)
return getHexEncodedTransaction(transaction)
} else {
return await signEvmTransaction(preparedTransaction, chain, $selectedAccount)
}
}
async function signOrSend(): Promise<void> {
const signedTransaction = await getSignedTransaction()
if (method === RpcMethod.EthSignTransaction) {
callback({ result: signedTransaction })
return
}
const transactionHash = await sendAndPersistTransactionFromEvm(
preparedTransaction,
signedTransaction,
chain,
$selectedAccount
)
callback({ result: transactionHash })
}
async function onConfirmClick(): Promise<void> {
try {
await checkActiveProfileAuthAsync(LedgerAppName.Ethereum)
Expand All @@ -89,15 +120,11 @@
try {
busy = true
modifyPopupState({ preventClose: true })
const response = await signAndSendTransactionFromEvm(
preparedTransaction,
chain,
$selectedAccount,
signAndSend
)
await signOrSend()
modifyPopupState({ preventClose: false }, true)
busy = false
callback({ result: response })
openPopup({
id: PopupId.SuccessfulDappInteraction,
props: {
Expand All @@ -112,7 +139,7 @@
}
}
$: setMethodName(preparedTransaction)
$: void setMethodName(preparedTransaction)
async function setMethodName(preparedTransaction: EvmTransactionData): Promise<void> {
const result = await getMethodNameForEvmTransaction(preparedTransaction)
methodName = result?.startsWith('0x') ? undefined : result
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import { DEFAULT_ACCOUNT_RECOVERY_CONFIGURATION } from '@core/profile'
import { RecoverAccountsPayload, recoverAccounts } from '@core/profile-manager'
import { checkActiveProfileAuth, getBaseToken, loadAccounts } from '@core/profile/actions'
import { activeAccounts, activeProfile, visibleActiveAccounts } from '@core/profile/stores'
import { activeAccounts, activeProfile, activeProfileId, visibleActiveAccounts } from '@core/profile/stores'
import { formatTokenAmountBestMatch } from '@core/token'
import { refreshAccountTokensForActiveProfile } from '@core/token/actions'
import { closePopup } from '@desktop/auxiliary/popup'
Expand Down Expand Up @@ -141,7 +141,7 @@
onDestroy(async () => {
if (hasUsedWalletFinder) {
await refreshAccountTokensForActiveProfile()
await generateAndStoreActivitiesForAllAccounts()
await generateAndStoreActivitiesForAllAccounts($activeProfileId)
loadNftsForActiveProfile()
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import { SupportedNamespaces } from '@auxiliary/wallet-connect/types'
import { Text } from '@bloomwalletio/ui'
import { getPermissionForMethod } from '@auxiliary/wallet-connect/utils'
import { RpcMethod } from '@auxiliary/wallet-connect/enums'
import { SelectionOption } from '@core/utils/interfaces'
export let checkedMethods: string[]
Expand Down Expand Up @@ -37,7 +38,7 @@
}
checkedMethods[method.method] = true
const permission = getPermissionForMethod(method.method)
const permission = getPermissionForMethod(method.method as RpcMethod)
if (!permission || addedPermission[permission]) {
continue
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
import {
createEvmTransactionFromSendFlowParameters,
createStardustOutputFromSendFlowParameters,
signAndSendTransactionFromEvm,
sendAndPersistTransactionFromEvm,
signAndSendStardustTransaction,
signEvmTransaction,
} from '@core/wallet/actions'
import { sendFlowParameters } from '@core/wallet/stores'
import { getNetworkIdFromSendFlowParameters, validateSendConfirmation } from '@core/wallet/utils'
Expand Down Expand Up @@ -104,7 +105,9 @@
busy = true
modifyPopupState({ preventClose: true })
if (isSourceNetworkLayer2) {
await signAndSendTransactionFromEvm(preparedTransaction, chain, $selectedAccount, true)
const signedTransaction = await signEvmTransaction(preparedTransaction, chain, $selectedAccount)
await sendAndPersistTransactionFromEvm(preparedTransaction, signedTransaction, chain, $selectedAccount)
} else {
await signAndSendStardustTransaction(preparedOutput, $selectedAccount)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export const GENERAL_SUPPORTED_METHODS = ['wallet_watchAsset']
import { RpcMethod } from '../enums'

export const GENERAL_SUPPORTED_METHODS = [RpcMethod.WalletWatchAsset]
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { DappPermission } from '../enums/dapp-permission.enum'
import { RpcMethod } from '../enums/rpc-method.enum'

export const METHODS_FOR_PERMISSION = {
[DappPermission.SignData]: [
'eth_sign',
'personal_sign',
'eth_signTypedData',
'eth_signTypedData_v3',
'eth_signTypedData_v4',
RpcMethod.EthSign,
RpcMethod.PersonalSign,
RpcMethod.EthSignTypedData,
RpcMethod.EthSignTypedDataV3,
RpcMethod.EthSignTypedDataV4,
],
[DappPermission.SignTransaction]: ['eth_signTransaction'],
[DappPermission.SendTransaction]: ['eth_sendTransaction', 'eth_sendRawTransaction'],
[DappPermission.SignTransaction]: [RpcMethod.EthSignTransaction],
[DappPermission.SendTransaction]: [RpcMethod.EthSendTransaction, RpcMethod.EthSendRawTransaction],
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './dapp-permission.enum'
export * from './dapp-verification.enum'
export * from './rpc-method.enum'
export * from './wallet-connect-events.enum'
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export enum RpcMethod {
EthSign = 'eth_sign',
PersonalSign = 'personal_sign',
EthSignTypedData = 'eth_signTypedData',
EthSignTypedDataV3 = 'eth_signTypedData_v3',
EthSignTypedDataV4 = 'eth_signTypedData_v4',
EthSignTransaction = 'eth_signTransaction',
EthSendTransaction = 'eth_sendTransaction',
EthSendRawTransaction = 'eth_sendRawTransaction',
WalletWatchAsset = 'wallet_watchAsset',
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import { EvmTransactionData } from '@core/layer-2'
import { switchToRequiredAccount } from '@auxiliary/wallet-connect/utils'
import { getSdkError } from '@walletconnect/utils'
import { Platform } from '@core/app'
import { DappVerification } from '../enums'
import { DappVerification, RpcMethod } from '../enums'

export async function handleEthTransaction(
evmTransactionData: EvmTransactionData & { from: string },
dapp: IConnectedDapp,
chain: IChain,
signAndSend: boolean,
method: RpcMethod.EthSendTransaction | RpcMethod.EthSignTransaction | RpcMethod.EthSendRawTransaction,
responseCallback: (params: CallbackParameters) => void,
verifiedState: DappVerification
): Promise<void> {
Expand All @@ -28,7 +28,7 @@ export async function handleEthTransaction(
return
}

if (!nonce || !gasPrice || !gasLimit) {
if (nonce === undefined || !gasPrice || !gasLimit) {
try {
const { nonce, gasPrice, gasLimit } = await buildEvmTransactionData(
chain,
Expand Down Expand Up @@ -61,7 +61,7 @@ export async function handleEthTransaction(
chain,
dapp,
preparedTransaction: evmTransactionData,
signAndSend,
method,
verifiedState,
callback: responseCallback,
onCancel: () => responseCallback({ error: getSdkError('USER_REJECTED') }),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ import { handleEthSignTypedData } from './eth_signTypedData.handler'
import { handleEthTransaction } from './eth_transaction.handler'
import { handleSignMessage } from './sign_message.handler'
import { handleWatchAsset } from '@auxiliary/wallet-connect/handlers'
import { DappVerification } from '../enums'
import { DappVerification, RpcMethod } from '../enums'
import { EvmTransactionData, getEvmTransactionFromHexString } from '@core/layer-2'

export function onSessionRequest(event: Web3WalletTypes.SessionRequest): void {
// We need to call this here, because if the dapp requests too fast after approval, we won't have the dapp in the store yet
setConnectedDapps()
const { topic, params, id, verifyContext } = event
const { request, chainId } = params
const method = request.method
const method = request.method as RpcMethod

const dapp = getConnectedDappByOrigin(verifyContext.verified.origin)
const verifiedState: DappVerification = verifyContext.verified.isScam
Expand Down Expand Up @@ -58,23 +59,28 @@ export function onSessionRequest(event: Web3WalletTypes.SessionRequest): void {
return
}

const signAndSend = method === 'eth_sendTransaction'

switch (method) {
case 'eth_sendTransaction':
case 'eth_signTransaction':
void handleEthTransaction(request.params[0], dapp, chain, signAndSend, returnResponse, verifiedState)
case RpcMethod.EthSendTransaction:
case RpcMethod.EthSignTransaction:
case RpcMethod.EthSendRawTransaction: {
const evmTransactionData: EvmTransactionData & { from: string } =
method === RpcMethod.EthSendRawTransaction
? getEvmTransactionFromHexString(request.params[0])
: request.params[0]

void handleEthTransaction(evmTransactionData, dapp, chain, method, returnResponse, verifiedState)
break
case 'eth_sign':
case 'personal_sign':
}
case RpcMethod.EthSign:
case RpcMethod.PersonalSign:
void handleSignMessage(request.params, dapp, method, chain, returnResponse, verifiedState)
break
case 'eth_signTypedData':
case 'eth_signTypedData_v3':
case 'eth_signTypedData_v4':
case RpcMethod.EthSignTypedData:
case RpcMethod.EthSignTypedDataV3:
case RpcMethod.EthSignTypedDataV4:
void handleEthSignTypedData(request.params, method, dapp, chain, returnResponse, verifiedState)
break
case 'wallet_watchAsset':
case RpcMethod.WalletWatchAsset:
void handleWatchAsset(request.params, dapp, chain, returnResponse)
break
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import { CallbackParameters } from '../types'
import { switchToRequiredAccount } from '../utils'
import { getSdkError } from '@walletconnect/utils'
import { Platform } from '@core/app'
import { DappVerification } from '../enums'
import { DappVerification, RpcMethod } from '../enums'
import { parseSiweMessage, validateSiwe } from '@core/layer-2'
import { showNotification } from '@auxiliary/notification'
import { localize } from '@core/i18n'

export async function handleSignMessage(
params: unknown,
dapp: IConnectedDapp,
method: 'personal_sign' | 'eth_sign',
method: RpcMethod.PersonalSign | RpcMethod.EthSign,
chain: IChain,
responseCallback: (params: CallbackParameters) => void,
verifiedState: DappVerification
Expand All @@ -26,8 +26,8 @@ export async function handleSignMessage(

// Type for `eth_sign` params: [ address, hexMessage ]
// Type for `personal_sign` params: [ hexMessage, address ]
const hexMessage = method === 'personal_sign' ? params[0] : params[1]
const accountAddress = method === 'personal_sign' ? params[1] : params[0]
const hexMessage = method === RpcMethod.PersonalSign ? params[0] : params[1]
const accountAddress = method === RpcMethod.PersonalSign ? params[1] : params[0]

if (typeof hexMessage !== 'string') {
responseCallback({ error: getSdkError('INVALID_METHOD') })
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { METHODS_FOR_PERMISSION } from '../constants'
import { DappPermission } from '../enums'
import { DappPermission, RpcMethod } from '../enums'

export function getPermissionForMethod(method: string): DappPermission | undefined {
export function getPermissionForMethod(method: RpcMethod): DappPermission | undefined {
for (const permission of Object.values(DappPermission)) {
const supportedMethods = METHODS_FOR_PERMISSION[permission] ?? []

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { NetworkId } from '@core/network'
import { setOutgoingAsyncActivitiesToClaimed } from './setOutgoingAsyncActivitiesToClaimed'

export async function generateAndStoreActivitiesForAccount(
profileId: string,
account: IAccountState,
networkId: NetworkId
): Promise<void> {
Expand All @@ -34,7 +35,7 @@ export async function generateAndStoreActivitiesForAccount(
const balanceChangeActivities = await generateActivitiesFromBalanceChanges(account)
activities.push(...balanceChangeActivities)

const chainActivities = await generateActivitiesFromChains(account)
const chainActivities = await generateActivitiesFromChains(profileId, account)
activities.push(...chainActivities)

// Step 4: set account activities with generated activities
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { activeAccounts } from '@core/profile/stores'
import { generateAndStoreActivitiesForAccount } from './generateAndStoreActivitiesForAccount'
import { getActiveNetworkId } from '@core/network'

export async function generateAndStoreActivitiesForAllAccounts(): Promise<void> {
export async function generateAndStoreActivitiesForAllAccounts(profileId: string): Promise<void> {
try {
const networkId = getActiveNetworkId()
const accounts = get(activeAccounts)

await Promise.all(
accounts.map((activeAccount) => generateAndStoreActivitiesForAccount(activeAccount, networkId))
accounts.map((activeAccount) => generateAndStoreActivitiesForAccount(profileId, activeAccount, networkId))
)
} catch (err) {
console.error(err)
Expand Down
Loading

0 comments on commit 176b69f

Please sign in to comment.