Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
30 changes: 16 additions & 14 deletions packages/mask/src/plugins/Wallet/services/send.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import Web3 from 'web3'
import type { HttpProvider } from 'web3-core'
import { isHex, hexToNumber } from 'web3-utils'
import type { JsonRpcPayload, JsonRpcResponse } from 'web3-core-helpers'
import { isNil } from 'lodash-unified'
import { defer } from '@dimensiondev/kit'
import {
ChainId,
createWeb3,
EthereumMethodType,
getPayloadConfig,
getSignablePayloadConfig,
getPayloadId,
getRPCConstants,
isRiskMethod,
} from '@masknet/web3-shared-evm'
import { openPopupWindow, removePopupWindow } from '../../../../background/services/helper'
import { nativeAPI } from '../../../../shared/native-rpc'
import { WalletRPC } from '../messages'
import { isNil } from 'lodash-unified'

enum JSON_RPC_ERROR_CODE {
INVALID_REQUEST = -32600,
Expand Down Expand Up @@ -119,47 +121,47 @@ export async function send(
options?: Options,
) {
const provider = await createProvider(options?.chainId)
const computedPayload = getPayloadConfig(payload)

switch (payload.method) {
case EthereumMethodType.ETH_SEND_TRANSACTION:
case EthereumMethodType.MASK_REPLACE_TRANSACTION:
const computedPayload = getSignablePayloadConfig(payload)
if (!computedPayload?.from || !computedPayload.to || !options?.chainId) return

const rawTransaction = await WalletRPC.signTransaction(computedPayload.from as string, {
...computedPayload,
chainId: options.chainId,
})
if (!rawTransaction) break
const privateKey = await WalletRPC.exportPrivateKey(computedPayload.from as string)
const web3 = createWeb3(provider)
const transactionSigned = await web3.eth.accounts.signTransaction(computedPayload, `0x${privateKey}`)
if (!transactionSigned.rawTransaction) break

return provider.send(
{
...payload,
method: EthereumMethodType.ETH_SEND_RAW_TRANSACTION,
params: [rawTransaction],
params: [transactionSigned.rawTransaction],
},
callback,
)
case EthereumMethodType.ETH_SIGN_TYPED_DATA:
const [address, dataToSign] = payload.params as [string, string]
const signed = await WalletRPC.signTypedData(address, dataToSign)
const dataSigned = await WalletRPC.signTypedData(address, dataToSign)
try {
callback(null, {
jsonrpc: '2.0',
id: payload.id as number,
result: signed,
result: dataSigned,
})
} catch (error) {
callback(getError(error, null, 'Failed to sign message.'))
}
break
case EthereumMethodType.PERSONAL_SIGN:
const [data, account] = payload.params as [string, string]
const personalSigned = await WalletRPC.signPersonalMessage(data, account)
const messageSigned = await WalletRPC.signPersonalMessage(data, account)
try {
callback(null, {
jsonrpc: '2.0',
id: payload.id as number,
result: personalSigned,
result: messageSigned,
})
} catch (error) {
callback(getError(error, null, 'Failed to sign message.'))
Expand Down Expand Up @@ -219,7 +221,7 @@ export async function confirmRequest(payload: JsonRpcPayload, options?: Options)
return
}
if (response?.error) {
reject(new Error(`Failed to send transaction: ${response.error}`))
reject(new Error(`Failed to send transaction: ${response.error?.message ?? response.error}`))
return
}
WalletRPC.deleteUnconfirmedRequest(payload)
Expand Down
4 changes: 2 additions & 2 deletions packages/web3-shared/evm/utils/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ export async function encodeContractTransaction(
if (!tx.gas) {
tx.gas = await transaction.estimateGas({
from: tx.from as string | undefined,
value: tx.value,
data: tx.data as string | undefined,
to: tx.to as string | undefined,
data: tx.data as string | undefined,
value: tx.value,
})
}

Expand Down
25 changes: 24 additions & 1 deletion packages/web3-shared/evm/utils/payload.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import BigNumber from 'bignumber.js'
import { first } from 'lodash-unified'
import { first, isUndefined, omitBy } from 'lodash-unified'
import type { JsonRpcPayload } from 'web3-core-helpers'
import { hexToNumber } from 'web3-utils'
import { EthereumMethodType, Transaction } from '../types'

export function addGasMargin(value: BigNumber.Value, scale = 3000) {
Expand Down Expand Up @@ -56,3 +57,25 @@ export function getPayloadConfig(payload: JsonRpcPayload) {
return
}
}

export function getSignablePayloadConfig(payload: JsonRpcPayload) {
const raw = getPayloadConfig(payload)
if (!raw) return

const parseHexNumber = (hex: string | number | undefined) =>
typeof hex !== 'undefined' ? hexToNumber(hex ?? '0x0') : undefined

return omitBy(
{
...raw,
value: parseHexNumber(raw.value as string | undefined),
gas: parseHexNumber(raw.gas),
gasPrice: parseHexNumber(raw.gasPrice as string | undefined),
maxFeePerGas: parseHexNumber(raw.maxFeePerGas as string | undefined),
maxPriorityFeePerGas: parseHexNumber(raw.maxPriorityFeePerGas as string | undefined),
chainId: parseHexNumber(raw.chainId),
nonce: parseHexNumber(raw.nonce),
},
isUndefined,
) as Transaction
}
9 changes: 9 additions & 0 deletions packages/web3-shared/evm/utils/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ export function createWeb3(provider: Provider) {
return web3
}

export function createSignableWeb3(provider: Provider, keys: string[]) {
const web3 = createWeb3(provider)
if (keys.length) {
web3.eth.accounts.wallet.clear()
keys.forEach((k) => k && ['0x', '0x0'].includes(k) && web3.eth.accounts.wallet.add(k))
}
return web3
}

export function createWeb3Provider(request: <T>(requestArguments: RequestArguments) => Promise<T>): Web3Provider {
const provider: Web3Provider = {
on() {
Expand Down