From 945b85809734edada382fce82e5d0734d74667ba Mon Sep 17 00:00:00 2001 From: Jack Works <5390719+Jack-Works@users.noreply.github.com> Date: Fri, 27 Feb 2026 08:49:40 +0000 Subject: [PATCH 1/3] wip --- eslint.config.js | 1 - .../services/identity/persona/sign.ts | 63 +++++++++---------- .../services/wallet/services/send.ts | 40 +++++++----- .../services/wallet/services/wallet/index.ts | 6 +- .../components/ConnectedWallet/index.tsx | 3 +- .../pages/Personas/AccountDetail/index.tsx | 3 +- .../pages/Personas/ConnectWallet/index.tsx | 3 +- .../Personas/PersonaAvatarSetting/index.tsx | 3 +- .../Personas/PersonaSignRequest/index.tsx | 3 +- packages/mask/shared-ui/initUIContext.ts | 2 +- .../shared-ui/initialization/walletSetup.ts | 1 - packages/plugin-infra/src/dom/context.ts | 4 +- .../NextID/src/hooks/usePersonaSign.ts | 2 +- .../hooks/useClaimNftRedpacketCallback.ts | 10 ++- .../src/SiteAdaptor/hooks/useSignedMessage.ts | 3 +- packages/shared-base/src/types/Account.ts | 13 ++++ packages/shared/src/hooks/useVerifyContent.ts | 6 +- packages/shared/src/hooks/useVerifyNextID.ts | 6 +- .../src/Web3/Base/state/Provider.ts | 5 +- .../src/Web3/EVM/apis/ComposerAPI.ts | 5 +- .../src/Web3/EVM/apis/RequestAPI.ts | 2 +- .../src/Web3/EVM/apis/SignerAPI.ts | 15 ++--- .../src/Web3/EVM/middleware/Interceptor.ts | 3 +- .../src/Web3/EVM/state/Provider.ts | 2 +- .../src/Web3/Flow/apis/Web3StateAPI.ts | 2 +- .../src/Web3/Flow/state/Provider.ts | 8 +-- .../src/Web3/Solana/apis/Web3StateAPI.ts | 2 +- .../src/Web3/Solana/state/Provider.ts | 8 +-- packages/web3-providers/src/types/Wallet.ts | 7 +-- packages/web3-shared/base/src/specs/index.ts | 5 -- packages/web3-shared/evm/package.json | 1 - .../evm/src/helpers/createAccount.ts | 12 ++-- .../evm/src/helpers/signMessage.ts | 13 ++-- .../evm/src/helpers/signTransaction.ts | 12 ++-- .../evm/src/libs/AccountTransaction.ts | 2 - .../web3-shared/evm/src/libs/PayloadEditor.ts | 58 ++++++++++------- packages/web3-shared/evm/src/libs/Signer.ts | 21 ------- packages/web3-shared/evm/src/libs/index.ts | 1 - packages/web3-shared/evm/src/types/index.ts | 14 ++--- pnpm-lock.yaml | 3 - 40 files changed, 174 insertions(+), 199 deletions(-) delete mode 100644 packages/web3-shared/evm/src/libs/Signer.ts diff --git a/eslint.config.js b/eslint.config.js index 7d5d4e1e1d93..20cbdb7c37e2 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -21,7 +21,6 @@ const deferPackages = [ '@metamask/eth-sig-util', '@masknet/gun-utils', 'web3-eth', - 'web3-eth-accounts', 'twitter-text', 'web3-utils', '@solana/web3.js', diff --git a/packages/mask/background/services/identity/persona/sign.ts b/packages/mask/background/services/identity/persona/sign.ts index bb64692a2bd7..7392136c8c3e 100644 --- a/packages/mask/background/services/identity/persona/sign.ts +++ b/packages/mask/background/services/identity/persona/sign.ts @@ -5,53 +5,50 @@ import { fromBase64URL, PopupRoutes, type ECKeyIdentifier, - type SignType, MaskMessages, + type SignMessage, } from '@masknet/shared-base' import { queryPersonasWithPrivateKey } from '../../../database/persona/web.js' import { openPopupWindow } from '../../helper/popup-opener.js' +async function getIdentifier(message: unknown, identifier?: ECKeyIdentifier, source?: string, silent = false) { + if (!identifier || !silent) { + const requestID = crypto.randomUUID() + await openPopupWindow(PopupRoutes.PersonaSignRequest, { + message: JSON.stringify(message), + requestID, + identifier: identifier?.toText(), + source, + }) + + return timeout( + new Promise((resolve, reject) => { + MaskMessages.events.personaSignRequest.on((approval) => { + if (approval.requestID !== requestID) return + if (!approval.selectedPersona) reject(new Error('The user refused to sign message with persona.')) + resolve(approval.selectedPersona!) + }) + }), + 60 * 1000, + 'Timeout of signing with persona.', + ) + } + return identifier +} /** * Generate a signature w or w/o confirmation from user */ export async function signWithPersona( - type: SignType, - message: unknown, + message: SignMessage, identifier?: ECKeyIdentifier, - source?: string, + origin?: string, silent = false, ): Promise { - const getIdentifier = async () => { - if (!identifier || !silent) { - const requestID = crypto.randomUUID() - await openPopupWindow(PopupRoutes.PersonaSignRequest, { - message: JSON.stringify(message), - requestID, - identifier: identifier?.toText(), - source, - }) - - return timeout( - new Promise((resolve, reject) => { - MaskMessages.events.personaSignRequest.on((approval) => { - if (approval.requestID !== requestID) return - if (!approval.selectedPersona) - reject(new Error('The user refused to sign message with persona.')) - resolve(approval.selectedPersona!) - }) - }), - 60 * 1000, - 'Timeout of signing with persona.', - ) - } - return identifier - } - - const identifier_ = await getIdentifier() + identifier = await getIdentifier(message.data, identifier, origin, silent) // find the persona with the signer's identifier - const persona = (await queryPersonasWithPrivateKey()).find((x) => x.identifier === identifier_) + const persona = (await queryPersonasWithPrivateKey()).find((x) => x.identifier === identifier) if (!persona?.privateKey.d) throw new Error('Persona not found') - return Signer.sign(type, Buffer.from(fromBase64URL(persona.privateKey.d)), message) + return Signer.sign(message, Buffer.from(fromBase64URL(persona.privateKey.d))) } diff --git a/packages/mask/background/services/wallet/services/send.ts b/packages/mask/background/services/wallet/services/send.ts index f6fea576f4c6..aa3475e3c542 100644 --- a/packages/mask/background/services/wallet/services/send.ts +++ b/packages/mask/background/services/wallet/services/send.ts @@ -1,5 +1,5 @@ import type { JsonRpcRequest } from 'web3-types' -import { ECKeyIdentifier, type SignType } from '@masknet/shared-base' +import { ECKeyIdentifier, SignType } from '@masknet/shared-base' import { EVMRequestReadonly, EVMWeb3Readonly } from '@masknet/web3-providers' import { ChainId, @@ -8,10 +8,10 @@ import { EthereumMethodType, PayloadEditor, type TransactionOptions, - Signer, } from '@masknet/web3-shared-evm' import { signWithWallet } from './wallet/index.js' import { signWithPersona } from '../../identity/persona/sign.js' +import type { TransactionSerializable } from 'viem' /** * The entrance of all RPC requests to MaskWallet. @@ -23,25 +23,35 @@ export async function send(payload: JsonRpcRequest, options?: TransactionOptions from, chainId = options?.chainId ?? ChainId.Mainnet, signableMessage, - signableConfig, + signableTransaction, } = PayloadEditor.fromPayload(payload, options) const identifier = ECKeyIdentifier.from(options?.identifier).unwrapOr(undefined) - const signer = - identifier ? - new Signer(identifier, (type: SignType, message: T, identifier?: ECKeyIdentifier) => - signWithPersona(type, message, identifier, undefined, true), - ) - : new Signer(owner || from!, signWithWallet) + const signTransaction = async (transaction: TransactionSerializable) => { + const message = { type: SignType.Transaction as const, data: transaction } + if (identifier) { + return signWithPersona(message, identifier) + } else { + return signWithWallet(message, owner || from!) + } + } + const signMessageOrTypedData = async (type: SignType.Message | SignType.TypedData, message: string) => { + const msg = { type, data: message } + if (identifier) { + return signWithPersona(msg, identifier) + } else { + return signWithWallet(msg, owner || from!) + } + } switch (payload.method) { case EthereumMethodType.eth_sendTransaction: case EthereumMethodType.MASK_REPLACE_TRANSACTION: - if (!signableConfig) throw new Error('No transaction to be sent.') + if (!signableTransaction) throw new Error('No transaction to be sent.') try { return createJsonRpcResponse( pid, - await EVMWeb3Readonly.sendSignedTransaction(await signer.signTransaction(signableConfig), { + await EVMWeb3Readonly.sendSignedTransaction(await signTransaction(signableTransaction), { chainId, providerURL, }), @@ -53,21 +63,21 @@ export async function send(payload: JsonRpcRequest, options?: TransactionOptions case EthereumMethodType.personal_sign: try { if (!signableMessage) throw new Error('No message to be signed.') - return createJsonRpcResponse(pid, await signer.signMessage(signableMessage)) + return createJsonRpcResponse(pid, await signMessageOrTypedData(SignType.Message, signableMessage)) } catch (error) { throw ErrorEditor.from(error, null, 'Failed to sign message.').error } case EthereumMethodType.eth_signTypedData_v4: try { if (!signableMessage) throw new Error('No typed data to be signed.') - return createJsonRpcResponse(pid, await signer.signTypedData(signableMessage)) + return createJsonRpcResponse(pid, await signMessageOrTypedData(SignType.TypedData, signableMessage)) } catch (error) { throw ErrorEditor.from(error, null, 'Failed to sign typed data.').error } case EthereumMethodType.eth_signTransaction: try { - if (!signableConfig) throw new Error('No transaction to be signed.') - return createJsonRpcResponse(pid, await signer.signTransaction(signableConfig)) + if (!signableTransaction) throw new Error('No transaction to be signed.') + return createJsonRpcResponse(pid, await signTransaction(signableTransaction)) } catch (error) { throw ErrorEditor.from(error, null, 'Failed to sign transaction.').error } diff --git a/packages/mask/background/services/wallet/services/wallet/index.ts b/packages/mask/background/services/wallet/services/wallet/index.ts index 8a89579b6ee3..280a6fde1ee2 100644 --- a/packages/mask/background/services/wallet/services/wallet/index.ts +++ b/packages/mask/background/services/wallet/services/wallet/index.ts @@ -4,7 +4,7 @@ import defer * as web3_utils from 'web3-utils' import { toBytes } from '@ethereumjs/util' import { api } from '@dimensiondev/mask-wallet-core/proto' import { Signer } from '@masknet/web3-providers' -import { ImportSource, type SignType, type Wallet } from '@masknet/shared-base' +import { ImportSource, type SignMessage, type Wallet } from '@masknet/shared-base' import { HD_PATH_WITHOUT_INDEX_ETHEREUM } from '@masknet/web3-shared-base' import * as Mask from '../maskwallet/index.js' import * as database from './database/index.js' @@ -249,8 +249,8 @@ export async function resetAllWallets() { await database.resetAllWallets() } -export async function signWithWallet(type: SignType, message: T, address: string) { - return Signer.sign(type, Buffer.from(toBytes(`0x${await exportPrivateKey(address)}`)), message) +export async function signWithWallet(message: SignMessage, address: string) { + return Signer.sign(message, Buffer.from(toBytes(`0x${await exportPrivateKey(address)}`))) } export async function exportMnemonicWords(address: string, unverifiedPassword?: string) { diff --git a/packages/mask/popups/components/ConnectedWallet/index.tsx b/packages/mask/popups/components/ConnectedWallet/index.tsx index c3b17ddf32e5..9cdd196af62c 100644 --- a/packages/mask/popups/components/ConnectedWallet/index.tsx +++ b/packages/mask/popups/components/ConnectedWallet/index.tsx @@ -117,8 +117,7 @@ export const ConnectedWallet = memo(function ConnectedWallet() { if (!result) return const signature = await Services.Identity.signWithPersona( - SignType.Message, - result.signPayload, + { type: SignType.Message, data: result.signPayload }, persona.identifier, location.origin, true, diff --git a/packages/mask/popups/pages/Personas/AccountDetail/index.tsx b/packages/mask/popups/pages/Personas/AccountDetail/index.tsx index 05552a27e955..70f4f608f0a8 100644 --- a/packages/mask/popups/pages/Personas/AccountDetail/index.tsx +++ b/packages/mask/popups/pages/Personas/AccountDetail/index.tsx @@ -77,8 +77,7 @@ export const Component = memo(() => { if (!result) return const signature = await Service.Identity.signWithPersona( - SignType.Message, - result.signPayload, + { type: SignType.Message, data: result.signPayload }, currentPersona.identifier, location.origin, true, diff --git a/packages/mask/popups/pages/Personas/ConnectWallet/index.tsx b/packages/mask/popups/pages/Personas/ConnectWallet/index.tsx index a8c6baa69321..469844309e39 100644 --- a/packages/mask/popups/pages/Personas/ConnectWallet/index.tsx +++ b/packages/mask/popups/pages/Personas/ConnectWallet/index.tsx @@ -172,8 +172,7 @@ export const Component = memo(function ConnectWalletPage() { if (!payload) return const personaSignature = await Services.Identity.signWithPersona( - SignType.Message, - payload.signPayload, + { type: SignType.Message, data: payload.signPayload }, currentPersona.identifier, location.origin, true, diff --git a/packages/mask/popups/pages/Personas/PersonaAvatarSetting/index.tsx b/packages/mask/popups/pages/Personas/PersonaAvatarSetting/index.tsx index 0e8bc1f57a06..0c6937be990c 100644 --- a/packages/mask/popups/pages/Personas/PersonaAvatarSetting/index.tsx +++ b/packages/mask/popups/pages/Personas/PersonaAvatarSetting/index.tsx @@ -132,8 +132,7 @@ const PersonaAvatarSetting = memo(function PersonaAvatar() { // Verify Wallet sign with persona if (bindingWallets.some((x) => isSameAddress(x.identity, account))) { sign = await Services.Identity.signWithPersona( - SignType.Message, - JSON.stringify(data), + { type: SignType.Message, data: JSON.stringify(data) }, currentPersona.identifier, location.origin, true, diff --git a/packages/mask/popups/pages/Personas/PersonaSignRequest/index.tsx b/packages/mask/popups/pages/Personas/PersonaSignRequest/index.tsx index 17546c92d1dd..f166c3c61c9b 100644 --- a/packages/mask/popups/pages/Personas/PersonaSignRequest/index.tsx +++ b/packages/mask/popups/pages/Personas/PersonaSignRequest/index.tsx @@ -60,8 +60,7 @@ export const Component = memo(function PersonaSignRequest() { case MethodAfterPersonaSign.DISCONNECT_NEXT_ID: if (!message) break const signature = await Services.Identity.signWithPersona( - SignType.Message, - message, + { type: SignType.Message, data: message }, selectedPersona, location.origin, true, diff --git a/packages/mask/shared-ui/initUIContext.ts b/packages/mask/shared-ui/initUIContext.ts index bfbd57509e2d..a17d72547e4d 100644 --- a/packages/mask/shared-ui/initUIContext.ts +++ b/packages/mask/shared-ui/initUIContext.ts @@ -40,7 +40,7 @@ export function setupUIContext() { queryPersonaByProfile: Services.Identity.queryPersonaByProfile, openDashboard: Services.Helper.openDashboard, openPopupWindow, - signWithPersona: (a, b, c, d) => Services.Identity.signWithPersona(a, b, c, location.origin, d), + signWithPersona: (a, b, c) => Services.Identity.signWithPersona(a, b, location.origin, c), hasPaymentPassword: Services.Wallet.hasPassword, createPersona: () => Services.Helper.openDashboard(DashboardRoutes.SignUpPersona), attachProfile: Services.Identity.attachProfile, diff --git a/packages/mask/shared-ui/initialization/walletSetup.ts b/packages/mask/shared-ui/initialization/walletSetup.ts index 8a1ca131501c..47847302d047 100644 --- a/packages/mask/shared-ui/initialization/walletSetup.ts +++ b/packages/mask/shared-ui/initialization/walletSetup.ts @@ -7,7 +7,6 @@ import { delay } from '@masknet/kit' import { openPopupWindow } from '../utils/openPopup.js' await initWallet({ - signWithPersona: (a, b, c, d) => Services.Identity.signWithPersona(a, b, c, location.origin, d), WalletConnectContext: { openWalletConnectDialog: async (uri: string) => { if (Sniffings.is_popup_page) { diff --git a/packages/plugin-infra/src/dom/context.ts b/packages/plugin-infra/src/dom/context.ts index d1b94e32e749..b098f517f5fe 100644 --- a/packages/plugin-infra/src/dom/context.ts +++ b/packages/plugin-infra/src/dom/context.ts @@ -10,7 +10,7 @@ import type { PopupRoutes, PopupRoutesParamsMap, ProfileIdentifier, - SignType, + SignMessage, SocialIdentity, } from '@masknet/shared-base' import type { Subscription } from 'use-subscription' @@ -41,7 +41,7 @@ export interface __UIContext__ { params: T extends keyof PopupRoutesParamsMap ? PopupRoutesParamsMap[T] : undefined, ): Promise /** Sign a message with persona (w or w/o popups) */ - signWithPersona(type: SignType, message: unknown, identifier?: ECKeyIdentifier, silent?: boolean): Promise + signWithPersona(message: SignMessage, identifier?: ECKeyIdentifier, silent?: boolean): Promise hasPaymentPassword(): Promise createPersona: () => void setCurrentPersonaIdentifier: ((x?: PersonaIdentifier) => Promise) | undefined diff --git a/packages/plugins/NextID/src/hooks/usePersonaSign.ts b/packages/plugins/NextID/src/hooks/usePersonaSign.ts index cb16fb5e8258..72c229e96fbf 100644 --- a/packages/plugins/NextID/src/hooks/usePersonaSign.ts +++ b/packages/plugins/NextID/src/hooks/usePersonaSign.ts @@ -6,7 +6,7 @@ export function usePersonaSign(message?: string, currentIdentifier?: ECKeyIdenti return useAsyncFn(async () => { if (!message || !currentIdentifier) return try { - return await signWithPersona?.(SignType.Message, message, currentIdentifier) + return await signWithPersona?.({ type: SignType.Message, data: message }, currentIdentifier) } catch { return } diff --git a/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useClaimNftRedpacketCallback.ts b/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useClaimNftRedpacketCallback.ts index 16d594a2d363..74e8844ca652 100644 --- a/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useClaimNftRedpacketCallback.ts +++ b/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useClaimNftRedpacketCallback.ts @@ -7,7 +7,7 @@ import { EVMWeb3 } from '@masknet/web3-providers' import { useNftRedPacketContract } from './useNftRedPacketContract.js' import type { RedPacketNftJSONPayload } from '@masknet/web3-providers/types' import { useSignedMessage } from './useSignedMessage.js' -import { useMemo } from 'react' +import type { Hex } from 'viem' const EXTRA_GAS_PER_NFT = 335 @@ -16,12 +16,10 @@ export function useClaimNftRedpacketCallback(payload: RedPacketNftJSONPayload, t const nftRedPacketContract = useNftRedPacketContract(chainId) const { refetch } = useSignedMessage(account, payload) const id = payload.id - const signedMsg = useMemo(() => { - return signMessage(account, payload.privateKey).signature ?? '' - }, [account, payload.privateKey]) return useAsyncFn(async () => { - if (!nftRedPacketContract || !id || !account || !totalAmount || !signedMsg) return + if (!nftRedPacketContract || !id || !account || !totalAmount || !payload.privateKey) return + const signedMsg = await signMessage(account, payload.privateKey as Hex) const transaction = nftRedPacketContract.methods.claim(id, signedMsg, account) const estimatedGas = await transaction.estimateGas({ from: account }) const tx = await new ContractTransaction(nftRedPacketContract).fillAll(transaction, { @@ -30,5 +28,5 @@ export function useClaimNftRedpacketCallback(payload: RedPacketNftJSONPayload, t chainId, }) return EVMWeb3.sendTransaction(tx, { chainId }) - }, [id, refetch, account, chainId, totalAmount, signedMsg]) + }, [id, refetch, account, chainId, totalAmount, account, payload.privateKey]) } diff --git a/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useSignedMessage.ts b/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useSignedMessage.ts index c94569d85859..ad58a7d79811 100644 --- a/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useSignedMessage.ts +++ b/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useSignedMessage.ts @@ -4,6 +4,7 @@ import { type RedPacketJSONPayload, type RedPacketNftJSONPayload } from '@maskne import { signMessage } from '@masknet/web3-shared-evm' import { useQuery } from '@tanstack/react-query' import { usePlatformType } from './usePlatformType.js' +import type { Hex } from 'viem' // TODO NFT redpacket is not supported by the API yet. export function useSignedMessage( @@ -34,7 +35,7 @@ export function useSignedMessage( queryKey: ['red-packet', 'signed-message', rpid, version, password, account, profile, isTokenRedPacket], queryFn: async () => { if (isTokenRedPacket && version <= 3) return password ?? null - if (password) return signMessage(account, password).signature + if (password) return signMessage(account, password as Hex) if (!profile) return '' return ( (await FireflyRedPacket.createClaimSignature({ diff --git a/packages/shared-base/src/types/Account.ts b/packages/shared-base/src/types/Account.ts index cefde04d0226..32e8cc9d5149 100644 --- a/packages/shared-base/src/types/Account.ts +++ b/packages/shared-base/src/types/Account.ts @@ -1,3 +1,4 @@ +import type { TransactionSerializable } from 'viem' export interface Account { account: string chainId: ChainId @@ -10,3 +11,15 @@ export enum SignType { TypedData = 'typedData', Transaction = 'transaction', } + +export type SignMessage = SignMessage_String | SignMessage_Transaction + +export interface SignMessage_String { + type: SignType.Message | SignType.TypedData + data: string +} + +export interface SignMessage_Transaction { + type: SignType.Transaction + data: TransactionSerializable +} diff --git a/packages/shared/src/hooks/useVerifyContent.ts b/packages/shared/src/hooks/useVerifyContent.ts index b063c780c368..b401d3b88cac 100644 --- a/packages/shared/src/hooks/useVerifyContent.ts +++ b/packages/shared/src/hooks/useVerifyContent.ts @@ -32,7 +32,11 @@ export function useVerifyContent(personaIdentifier: PersonaIdentifier | undefine ) if (!payload) throw new Error('Failed to create persona payload.') - const signature = await signWithPersona(SignType.Message, payload.signPayload, personaIdentifier, true) + const signature = await signWithPersona( + { type: SignType.Message, data: payload.signPayload }, + personaIdentifier, + true, + ) const post = payload.postContent.replace('%SIG_BASE64%', toBase64(fromHex(signature))) return { post, diff --git a/packages/shared/src/hooks/useVerifyNextID.ts b/packages/shared/src/hooks/useVerifyNextID.ts index 6094fd2bff07..1e7da047411b 100644 --- a/packages/shared/src/hooks/useVerifyNextID.ts +++ b/packages/shared/src/hooks/useVerifyNextID.ts @@ -23,7 +23,11 @@ async function createAndSignMessage(platform: NextIDPlatform, persona: PersonaIn ) if (!payload) throw new Error('Failed to create persona payload.') - const signature = await signWithPersona(SignType.Message, payload.signPayload, persona.identifier, true) + const signature = await signWithPersona( + { type: SignType.Message, data: payload.signPayload }, + persona.identifier, + true, + ) if (!signature) throw new Error('Failed to sign by persona.') return { payload, signature } } diff --git a/packages/web3-providers/src/Web3/Base/state/Provider.ts b/packages/web3-providers/src/Web3/Base/state/Provider.ts index ed6c2c2f2801..06478d54ddda 100644 --- a/packages/web3-providers/src/Web3/Base/state/Provider.ts +++ b/packages/web3-providers/src/Web3/Base/state/Provider.ts @@ -29,10 +29,7 @@ export abstract class ProviderState, ProviderType>>, - ) {} + constructor(protected storage: StorageObject, ProviderType>>) {} protected init() { this.setupSubscriptions() this.setupProviders() diff --git a/packages/web3-providers/src/Web3/EVM/apis/ComposerAPI.ts b/packages/web3-providers/src/Web3/EVM/apis/ComposerAPI.ts index 085a20694672..844065068f12 100644 --- a/packages/web3-providers/src/Web3/EVM/apis/ComposerAPI.ts +++ b/packages/web3-providers/src/Web3/EVM/apis/ComposerAPI.ts @@ -5,19 +5,18 @@ import { Interceptor } from '../middleware/Interceptor.js' import { RecentTransaction } from '../middleware/RecentTransaction.js' import { TransactionWatcher } from '../middleware/TransactionWatcher.js' import type { ConnectionContext } from '../libs/ConnectionContext.js' -import type { WalletAPI } from '../../../entry-types.js' import { Permit } from '../middleware/Permit.js' let instance: EVMComposer | undefined export class Composer { - static compose(signWithPersona: WalletAPI.SignWithPersona) { + static compose() { if (instance) return instance instance = EVMComposer.from( new Permit(), Nonce, new Translator(), - new Interceptor(signWithPersona), + new Interceptor(), new RecentTransaction(), new TransactionWatcher(), ) diff --git a/packages/web3-providers/src/Web3/EVM/apis/RequestAPI.ts b/packages/web3-providers/src/Web3/EVM/apis/RequestAPI.ts index 88f7c6d0b3e6..2ad2d0a3ec9e 100644 --- a/packages/web3-providers/src/Web3/EVM/apis/RequestAPI.ts +++ b/packages/web3-providers/src/Web3/EVM/apis/RequestAPI.ts @@ -28,7 +28,7 @@ export class EVMRequestAPI extends EVMRequestReadonlyAPI { const context = createContext(requestArguments, options) try { - await Composer.compose(this.Provider.signWithPersona).dispatch(context, async () => { + await Composer.compose().dispatch(context, async () => { if (!context.writable) return try { switch (context.method) { diff --git a/packages/web3-providers/src/Web3/EVM/apis/SignerAPI.ts b/packages/web3-providers/src/Web3/EVM/apis/SignerAPI.ts index 4da41b4ed21c..00bbdd10e7b4 100644 --- a/packages/web3-providers/src/Web3/EVM/apis/SignerAPI.ts +++ b/packages/web3-providers/src/Web3/EVM/apis/SignerAPI.ts @@ -1,29 +1,30 @@ import defer * as _metamask_eth_sig_util from '@metamask/eth-sig-util' -import { signTransaction, type Transaction } from '@masknet/web3-shared-evm' -import { SignType, toHex } from '@masknet/shared-base' +import { signTransaction } from '@masknet/web3-shared-evm' +import { type SignMessage, SignType, toHex } from '@masknet/shared-base' import { unreachable } from '@masknet/kit' +import type { Hex } from 'viem' export class Signer { - static async sign(type: SignType, key: Buffer, message: unknown): Promise { + static async sign({ type, data }: SignMessage, key: Buffer): Promise { switch (type) { case SignType.Message: return _metamask_eth_sig_util.personalSign({ privateKey: key, - data: message as string, + data, }) case SignType.TypedData: return _metamask_eth_sig_util.signTypedData({ privateKey: key, - data: JSON.parse(message as string), + data: JSON.parse(data), version: _metamask_eth_sig_util.SignTypedDataVersion.V4, }) case SignType.Transaction: - const transaction = message as Transaction + const transaction = data const chainId = transaction.chainId if (!chainId) throw new Error('Invalid chain id.') - const { rawTransaction } = await signTransaction(transaction, toHex(key)) + const rawTransaction = await signTransaction(transaction, toHex(key) as Hex) if (!rawTransaction) throw new Error('Failed to sign transaction.') return rawTransaction diff --git a/packages/web3-providers/src/Web3/EVM/middleware/Interceptor.ts b/packages/web3-providers/src/Web3/EVM/middleware/Interceptor.ts index 9e59e87e3f96..3009d44a0f74 100644 --- a/packages/web3-providers/src/Web3/EVM/middleware/Interceptor.ts +++ b/packages/web3-providers/src/Web3/EVM/middleware/Interceptor.ts @@ -6,10 +6,9 @@ import { WalletConnect } from '../interceptors/WalletConnect.js' import { MetaMaskLike } from '../interceptors/MetaMaskLike.js' import { Popups } from '../interceptors/Popups.js' import { CustomNetwork } from '../interceptors/CustomNetwork.js' -import type { WalletAPI } from '../../../entry-types.js' export class Interceptor implements Middleware { - constructor(private signWithPersona: WalletAPI.SignWithPersona) { + constructor() { this.composers = { [ProviderType.None]: Composer.from(new NoneWallet()), [ProviderType.BitGet]: Composer.from(new MetaMaskLike(ProviderType.BitGet)), diff --git a/packages/web3-providers/src/Web3/EVM/state/Provider.ts b/packages/web3-providers/src/Web3/EVM/state/Provider.ts index 5d1de6ded710..89dc96112cad 100644 --- a/packages/web3-providers/src/Web3/EVM/state/Provider.ts +++ b/packages/web3-providers/src/Web3/EVM/state/Provider.ts @@ -23,7 +23,7 @@ export class EVMProvider extends ProviderState, ProviderType>>, hostedProviderStorage: BaseHostedStorage, ) { - super(context.signWithPersona, storage) + super(storage) this.providers = createEVMWalletProviders(context, hostedProviderStorage) this.init() } diff --git a/packages/web3-providers/src/Web3/Flow/apis/Web3StateAPI.ts b/packages/web3-providers/src/Web3/Flow/apis/Web3StateAPI.ts index f11e570c716f..7aaa3d7b29f0 100644 --- a/packages/web3-providers/src/Web3/Flow/apis/Web3StateAPI.ts +++ b/packages/web3-providers/src/Web3/Flow/apis/Web3StateAPI.ts @@ -31,7 +31,7 @@ export async function createFlowState(context: WalletAPI.IOContext): Promise new Provider.FlowProvider(context.signWithPersona, provider), + Provider: () => new Provider.FlowProvider(provider), AddressBook: () => new AddressBook.FlowAddressBook(address), IdentityService: () => new IdentityService.FlowIdentityService(), Settings: () => new Settings.FlowSettings(settings), diff --git a/packages/web3-providers/src/Web3/Flow/state/Provider.ts b/packages/web3-providers/src/Web3/Flow/state/Provider.ts index c673e62a31f5..da03d98bd182 100644 --- a/packages/web3-providers/src/Web3/Flow/state/Provider.ts +++ b/packages/web3-providers/src/Web3/Flow/state/Provider.ts @@ -13,15 +13,11 @@ import { import { createFlowWalletProviders } from '../providers/index.js' import { FlowChainResolver } from '../apis/ResolverAPI.js' import { ProviderState, type ProviderStorage } from '../../Base/state/Provider.js' -import type { WalletAPI } from '../../../entry-types.js' import type { Account, StorageObject } from '@masknet/shared-base' export class FlowProvider extends ProviderState { - constructor( - signWithPersona: WalletAPI.SignWithPersona, - storage: StorageObject, ProviderType>>, - ) { - super(signWithPersona, storage) + constructor(storage: StorageObject, ProviderType>>) { + super(storage) this.init() } public providers = createFlowWalletProviders() diff --git a/packages/web3-providers/src/Web3/Solana/apis/Web3StateAPI.ts b/packages/web3-providers/src/Web3/Solana/apis/Web3StateAPI.ts index 9253febb3621..9472f5dfa17c 100644 --- a/packages/web3-providers/src/Web3/Solana/apis/Web3StateAPI.ts +++ b/packages/web3-providers/src/Web3/Solana/apis/Web3StateAPI.ts @@ -31,7 +31,7 @@ export async function createSolanaState(context: WalletAPI.IOContext): Promise new Provider.SolanaProvider(context.signWithPersona, provider), + Provider: () => new Provider.SolanaProvider(provider), AddressBook: () => new AddressBook.SolanaAddressBook(address), IdentityService: () => new IdentityService.SolanaIdentityService(), Settings: () => new Settings.SolanaSettings(settings), diff --git a/packages/web3-providers/src/Web3/Solana/state/Provider.ts b/packages/web3-providers/src/Web3/Solana/state/Provider.ts index 5c2a2b63498d..9800690c822e 100644 --- a/packages/web3-providers/src/Web3/Solana/state/Provider.ts +++ b/packages/web3-providers/src/Web3/Solana/state/Provider.ts @@ -13,15 +13,11 @@ import { import { createSolanaWalletProviders } from '../providers/index.js' import { SolanaChainResolver } from '../apis/ResolverAPI.js' import { ProviderState, type ProviderStorage } from '../../Base/state/Provider.js' -import type { WalletAPI } from '../../../entry-types.js' import type { Account, StorageObject } from '@masknet/shared-base' export class SolanaProvider extends ProviderState { - constructor( - signWithPersona: WalletAPI.SignWithPersona, - storage: StorageObject, ProviderType>>, - ) { - super(signWithPersona, storage) + constructor(storage: StorageObject, ProviderType>>) { + super(storage) this.init() } public providers = createSolanaWalletProviders() diff --git a/packages/web3-providers/src/types/Wallet.ts b/packages/web3-providers/src/types/Wallet.ts index c79b2df03cb1..2eecc77e634d 100644 --- a/packages/web3-providers/src/types/Wallet.ts +++ b/packages/web3-providers/src/types/Wallet.ts @@ -4,11 +4,11 @@ import type { ECKeyIdentifier, Account, Wallet, - SignType, PopupRoutes, PopupRoutesParamsMap, PersonaInformation, ImportSource, + SignMessage, } from '@masknet/shared-base' import type { JsonRpcResponse, JsonRpcRequest } from 'web3-types' import type { ChainId, TransactionOptions } from '@masknet/web3-shared-evm' @@ -67,8 +67,7 @@ export namespace WalletAPI { disconnectAllWalletsFromOrigin(origin: string, type: 'any' | 'sdk' | 'internal'): Promise } export type SignWithPersona = ( - type: SignType, - message: unknown, + message: SignMessage, identifier?: ECKeyIdentifier, silent?: boolean, ) => Promise @@ -86,8 +85,6 @@ export namespace WalletAPI { MaskWalletContext: MaskWalletIOContext MessageContext: MessageIOContext WalletConnectContext: WalletConnectIOContext - /** Sign a message with persona (w or w/o popups) */ - signWithPersona: SignWithPersona } export interface Provider { readonly ready: boolean diff --git a/packages/web3-shared/base/src/specs/index.ts b/packages/web3-shared/base/src/specs/index.ts index 6d7e892bc3ce..0af249ddcef3 100644 --- a/packages/web3-shared/base/src/specs/index.ts +++ b/packages/web3-shared/base/src/specs/index.ts @@ -3,7 +3,6 @@ import type { Subscription } from 'use-subscription' import type { JsonRpcRequest } from 'web3-types' import type { Emitter } from '@servie/events' import type { - ECKeyIdentifier, EnhanceableSite, ExtensionSite, NetworkPluginID, @@ -12,7 +11,6 @@ import type { SocialAddress, SocialIdentity, SocialAccount, - SignType, Web3BioProfile, } from '@masknet/shared-base' @@ -1294,9 +1292,6 @@ export interface ProviderState { ) => Promise> /** Disconnect with the provider. */ disconnect: (providerType: ProviderType) => Promise - /** Sign a message with persona (w or w/o popups) */ - // TODO: this is not the best place to put this signature, but to avoid IOContext leaked as a global variable, we'll put it here for now. - signWithPersona(type: SignType, message: unknown, identifier?: ECKeyIdentifier, silent?: boolean): Promise } export interface BalanceNotifierState { diff --git a/packages/web3-shared/evm/package.json b/packages/web3-shared/evm/package.json index 0cb6bba888c2..1db18c8f71b1 100644 --- a/packages/web3-shared/evm/package.json +++ b/packages/web3-shared/evm/package.json @@ -24,7 +24,6 @@ "punycode": "^2.3.1", "web3-core": "1.10.4", "web3-eth": "1.10.4", - "web3-eth-accounts": "1.10.4", "web3-eth-contract": "1.10.4", "web3-utils": "1.10.4", "web3-types": "1.10.0", diff --git a/packages/web3-shared/evm/src/helpers/createAccount.ts b/packages/web3-shared/evm/src/helpers/createAccount.ts index b527902e6afb..66b01e92ba54 100644 --- a/packages/web3-shared/evm/src/helpers/createAccount.ts +++ b/packages/web3-shared/evm/src/helpers/createAccount.ts @@ -1,9 +1,7 @@ -import type { Account } from 'web3-core' -import defer * as Web3Accounts from 'web3-eth-accounts' -import type { Accounts } from 'web3-eth-accounts' +import { generatePrivateKey, privateKeyToAddress } from 'viem/accounts' -export function createAccount(): Account { - const Accounts_ = Web3Accounts.default as unknown as typeof Accounts - const accounts = new Accounts_() - return accounts.create() +export function createAccount() { + const privateKey = generatePrivateKey() + const address = privateKeyToAddress(privateKey) + return { privateKey, address } } diff --git a/packages/web3-shared/evm/src/helpers/signMessage.ts b/packages/web3-shared/evm/src/helpers/signMessage.ts index f6cb889203ce..27d0dbf75c27 100644 --- a/packages/web3-shared/evm/src/helpers/signMessage.ts +++ b/packages/web3-shared/evm/src/helpers/signMessage.ts @@ -1,8 +1,9 @@ -import defer * as Web3Accounts from 'web3-eth-accounts' -import type { Accounts } from 'web3-eth-accounts' +import type { Hex } from 'viem' +import { signMessage as viem_sign } from 'viem/accounts' -export function signMessage(message: string, privateKey: string): Web3Accounts.Sign { - const Accounts_ = Web3Accounts.default as unknown as typeof Accounts - const accounts = new Accounts_() - return accounts.sign(message, privateKey) +export function signMessage(message: string, privateKey: Hex): Promise { + return viem_sign({ + message: message.startsWith('0x') ? { raw: message as Hex } : message, + privateKey, + }) } diff --git a/packages/web3-shared/evm/src/helpers/signTransaction.ts b/packages/web3-shared/evm/src/helpers/signTransaction.ts index 69ea4b572ed4..973a20e14ab2 100644 --- a/packages/web3-shared/evm/src/helpers/signTransaction.ts +++ b/packages/web3-shared/evm/src/helpers/signTransaction.ts @@ -1,10 +1,6 @@ -import defer * as Web3Accounts from 'web3-eth-accounts' -import type { Accounts } from 'web3-eth-accounts' -import type { Transaction } from '../types/index.js' +import { signTransaction as viem_signTransaction } from 'viem/accounts' +import type { Hex, TransactionSerializable } from 'viem' -export function signTransaction(transaction: Transaction, privateKey: string) { - if (typeof transaction.nonce === 'undefined') throw new Error('Nonce is required.') - const Accounts_ = Web3Accounts.default as unknown as typeof Accounts - const accounts = new Accounts_() - return accounts.signTransaction(transaction, privateKey) +export function signTransaction(transaction: TransactionSerializable, privateKey: Hex) { + return viem_signTransaction({ privateKey, transaction }) } diff --git a/packages/web3-shared/evm/src/libs/AccountTransaction.ts b/packages/web3-shared/evm/src/libs/AccountTransaction.ts index 64b3c7c1db98..977513ffb3f3 100644 --- a/packages/web3-shared/evm/src/libs/AccountTransaction.ts +++ b/packages/web3-shared/evm/src/libs/AccountTransaction.ts @@ -57,7 +57,6 @@ export class AccountTransaction { maxFeePerGas, data, nonce, - _disableExceptionSnackbar, _disableSuccessSnackbar, _disableSnackbar, } = { @@ -76,7 +75,6 @@ export class AccountTransaction { maxPriorityFeePerGas: maxPriorityFeePerGas ? normalizeHex(maxPriorityFeePerGas) : undefined, maxFeePerGas: maxFeePerGas ? normalizeHex(maxFeePerGas) : undefined, nonce, - _disableExceptionSnackbar, _disableSuccessSnackbar, _disableSnackbar, }, diff --git a/packages/web3-shared/evm/src/libs/PayloadEditor.ts b/packages/web3-shared/evm/src/libs/PayloadEditor.ts index ba1e85d8eea2..bc91a9ffb9d0 100644 --- a/packages/web3-shared/evm/src/libs/PayloadEditor.ts +++ b/packages/web3-shared/evm/src/libs/PayloadEditor.ts @@ -1,8 +1,6 @@ import { first, isUndefined, omitBy } from 'lodash-es' -import defer * as web3_utils from 'web3-utils' import type { JsonRpcRequest } from 'web3-types' import type { Wallet } from '@masknet/shared-base' -import { formatEthereumAddress } from '../helpers/formatter.js' import { parseChainId } from '../helpers/parseChainId.js' import { createJsonRpcRequest } from '../helpers/createJsonRpcRequest.js' import { @@ -14,6 +12,7 @@ import { import { readonlyMethodType } from '../helpers/isReadonlyMethodType.js' import { riskyMethodType } from '../helpers/isRiskyMethodType.js' import { gasConsumingMethodType } from '../helpers/isGasConsumingMethodType.js' +import { hexToBigInt, hexToNumber, isHex, type Hex, type TransactionSerializable } from 'viem' type Options = Pick @@ -87,7 +86,7 @@ export class PayloadEditor { return omitBy( { ...raw, - nonce: parseHexNumber(raw?.nonce), + nonce: toNumber(raw?.nonce), from: raw?.from ?? this.options?.account, chainId: parseChainId(raw?.chainId) ?? this.options?.chainId, }, @@ -124,24 +123,27 @@ export class PayloadEditor { } } - get signableConfig() { + get signableTransaction(): TransactionSerializable | undefined { if (!this.config) return - return omitBy( - { - ...this.config, - from: this.config.from ? formatEthereumAddress(this.config.from) : '', - value: parseHexNumberString(this.config.value), - gas: parseHexNumberString(this.config.gas), - gasPrice: parseHexNumberString(this.config.gasPrice), - maxFeePerGas: parseHexNumberString(this.config.maxFeePerGas), - maxPriorityFeePerGas: parseHexNumberString(this.config.maxPriorityFeePerGas), - // TODO: revert to parseHexNumberString after updating MaskCore - chainId: parseHexNumber(this.config.chainId), - nonce: parseHexNumberString(this.config.nonce), - }, - isUndefined, - ) as Transaction + const tx = { + ...this.config, + type: + this.config.type === '0x0' ? 'legacy' + : this.config.type === '0x1' ? 'eip2930' + : this.config.type === '0x2' ? 'eip1559' + : undefined, + to: this.config.to as Hex, + data: this.config.data as Hex, + value: toBigInt(this.config.value), + gas: toBigInt(this.config.gas), + gasPrice: toBigInt(this.config.gasPrice), + maxFeePerGas: toBigInt(this.config.maxFeePerGas), + maxPriorityFeePerGas: toBigInt(this.config.maxPriorityFeePerGas), + chainId: toNumber(this.config.chainId), + nonce: toNumber(this.config.nonce), + } as TransactionSerializable + return omitBy(tx, isUndefined) } get risky() { @@ -179,10 +181,20 @@ export class PayloadEditor { } } -function parseHexNumberString(hex: string | number | undefined) { - return typeof hex !== 'undefined' ? web3_utils.hexToNumberString(hex ?? '0x0') : undefined +function toBigInt(hex: string | number | undefined) { + if (typeof hex === 'number') return BigInt(hex) + if (typeof hex === 'string') { + if (isHex(hex)) return hexToBigInt(hex) + return BigInt(hex) + } + return undefined } -function parseHexNumber(hex: string | number | undefined) { - return typeof hex !== 'undefined' ? (web3_utils.hexToNumber(hex) as number) : undefined +function toNumber(hex: string | number | undefined) { + if (typeof hex === 'number') return hex + if (typeof hex === 'string') { + if (isHex(hex)) return Number(hexToNumber(hex)) + return Number(hex) + } + return undefined } diff --git a/packages/web3-shared/evm/src/libs/Signer.ts b/packages/web3-shared/evm/src/libs/Signer.ts deleted file mode 100644 index e3e5555a7a24..000000000000 --- a/packages/web3-shared/evm/src/libs/Signer.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { SignType } from '@masknet/shared-base' -import type { Transaction } from '@masknet/web3-shared-evm' - -export class Signer { - constructor( - private identifier: T, - private sign: (type: SignType, message: string | Transaction, identifier: T) => Promise, - ) {} - - signMessage(message: string): Promise { - return this.sign(SignType.Message, message, this.identifier) - } - - signTypedData(data: string): Promise { - return this.sign(SignType.TypedData, data, this.identifier) - } - - signTransaction(transaction: Transaction): Promise { - return this.sign(SignType.Transaction, transaction, this.identifier) - } -} diff --git a/packages/web3-shared/evm/src/libs/index.ts b/packages/web3-shared/evm/src/libs/index.ts index 0191b7bc38b7..a8b5ba6e1c2b 100644 --- a/packages/web3-shared/evm/src/libs/index.ts +++ b/packages/web3-shared/evm/src/libs/index.ts @@ -8,5 +8,4 @@ export * from './GasEditor.js' export * from './PayloadEditor.js' export * from './ProviderURL.js' export * from './RequestID.js' -export * from './Signer.js' export * from './Web3.js' diff --git a/packages/web3-shared/evm/src/types/index.ts b/packages/web3-shared/evm/src/types/index.ts index 2041ee92185c..e73e1169806e 100644 --- a/packages/web3-shared/evm/src/types/index.ts +++ b/packages/web3-shared/evm/src/types/index.ts @@ -406,7 +406,11 @@ export interface Transaction { from?: string to?: string value?: string - /** gasLimit */ + // value?: bigint + // gas?: bigint + // gasPrice?: bigint + // maxPriorityFeePerGas?: bigint + // maxFeePerGas?: bigint gas?: string gasPrice?: string maxPriorityFeePerGas?: string @@ -416,16 +420,8 @@ export interface Transaction { chainId?: number type?: '0x0' | '0x1' | '0x2' - // CELO - feeCurrency?: string // address of the ERC20 contract to use to pay for gas and the gateway fee - gatewayFeeRecipient?: string // coinbase address of the full serving the light client's transactions - gatewayFee?: string // value paid to the gateway fee recipient, denominated in the fee currency - _disableSnackbar?: boolean _disableSuccessSnackbar?: boolean - _disableExceptionSnackbar?: boolean - - _isOKXSwap?: boolean } export type TransactionReceipt = Web3TransactionReceipt export type TransactionDetailed = Web3Transaction diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ba7959d79e73..049b437e62d2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2967,9 +2967,6 @@ importers: web3-eth: specifier: 1.10.4 version: 1.10.4(encoding@0.1.13) - web3-eth-accounts: - specifier: 1.10.4 - version: 1.10.4(encoding@0.1.13) web3-eth-contract: specifier: 1.10.4 version: 1.10.4(encoding@0.1.13) From b1a6b065da2d40889d57eeb59816c0c3346c0987 Mon Sep 17 00:00:00 2001 From: Jack Works <5390719+Jack-Works@users.noreply.github.com> Date: Thu, 12 Mar 2026 01:08:28 +0000 Subject: [PATCH 2/3] wip --- .vscode/settings.json | 1 + eslint.config.js | 6 ++ .../background/services/helper/firefly.ts | 2 +- .../services/wallet/services/legacyWallet.ts | 4 +- .../services/wallet/services/wallet/index.ts | 8 +- .../twitter.com/collecting/post.ts | 6 +- .../site-adaptors/twitter.com/utils/fetch.ts | 7 +- .../AddDeriveWallet/index.tsx | 6 +- .../Wallet/GasSetting/GasSetting1559.tsx | 14 ++-- .../Wallet/GasSetting/Prior1559GasSetting.tsx | 7 +- .../Wallet/Interaction/TransactionRequest.tsx | 14 ++-- packages/mask/popups/pages/Wallet/utils.ts | 4 +- .../Claim/src/hooks/useAirDropActivity.ts | 21 ++++-- .../src/SiteAdaptor/hooks/useClaimCallback.ts | 6 +- .../SiteAdaptor/hooks/useCreateCallback.tsx | 6 +- .../hooks/useCreateNftRedpacketCallback.ts | 6 +- .../hooks/useCreateNftRedpacketGas.ts | 6 +- .../SiteAdaptor/hooks/useDefaultCreateGas.ts | 6 +- .../hooks/useHandleCreateOrSelect.ts | 14 ++-- .../hooks/useNftRedPacketContract.ts | 6 +- .../components/TokenSection/useGasLimit.ts | 5 +- packages/shared-base/src/helpers/pvtsutils.ts | 9 ++- .../UI/components/SettingsBoard/Context.tsx | 26 +++---- .../GasSettingModal/Prior1559GasSetting.tsx | 4 +- packages/web3-hooks/evm/src/useContract.ts | 29 +------ packages/web3-providers/package.json | 2 + .../web3-providers/src/Alchemy/helpers.ts | 4 +- .../src/Web3/Base/apis/Utils.ts | 53 +------------ .../src/Web3/EVM/apis/ConnectionAPI.ts | 11 ++- .../Web3/EVM/apis/ConnectionReadonlyAPI.ts | 13 ++-- .../src/Web3/EVM/apis/ContractReadonlyAPI.ts | 10 +-- .../src/Web3/EVM/apis/SignerAPI.ts | 3 +- .../web3-providers/src/Web3/EVM/apis/Utils.ts | 34 +-------- .../src/Web3/EVM/interceptors/MaskWallet.ts | 5 +- .../Web3/EVM/interceptors/WalletConnect.ts | 4 +- .../src/Web3/EVM/middleware/Nonce.ts | 6 +- .../src/Web3/EVM/providers/Base.ts | 7 +- .../src/Web3/EVM/providers/BaseHosted.ts | 13 +++- .../src/Web3/EVM/providers/Opera.ts | 5 +- .../src/Web3/EVM/providers/WalletConnect.ts | 5 +- .../checkers/AccountChecker.ts | 23 +++--- .../src/Web3/EVM/translators/Astar.ts | 6 +- .../src/Web3/EVM/translators/Base.ts | 29 +++---- .../src/Web3/Flow/apis/ResolverAPI.ts | 4 +- .../src/Web3/Flow/apis/Utils.ts | 32 +------- .../src/Web3/Router/types/index.ts | 4 +- .../src/Web3/Solana/apis/ResolverAPI.ts | 4 +- .../src/Web3/Solana/apis/Utils.ts | 36 +-------- .../src/helpers/fetchJsonRpcResponse.ts | 4 +- .../web3-shared/evm/src/helpers/address.ts | 18 +---- .../evm/src/helpers/createContract.ts | 6 +- .../src/helpers/getTransactionSignature.ts | 12 --- packages/web3-shared/evm/src/helpers/pack.ts | 31 -------- .../evm/src/helpers/parseStringOrBytes32.ts | 13 +--- .../resolveNonFungibleTokenIdFromEnsDomain.ts | 5 +- .../evm/src/helpers/splitSignature.ts | 4 +- packages/web3-shared/evm/src/helpers/token.ts | 12 --- packages/web3-shared/evm/src/index.ts | 2 - .../evm/src/libs/AccountTransaction.ts | 24 ++---- .../evm/src/libs/ContractTransaction.ts | 19 +++-- .../web3-shared/evm/src/libs/GasEditor.ts | 16 ++-- .../web3-shared/evm/src/libs/RequestID.ts | 75 ------------------- packages/web3-shared/evm/src/libs/index.ts | 1 - .../web3-shared/evm/tests/helpers/pack.ts | 19 ----- .../web3-shared/flow/src/helpers/address.ts | 4 - .../web3-shared/flow/src/helpers/token.ts | 13 ---- .../web3-shared/solana/src/helpers/address.ts | 4 - .../web3-shared/solana/src/helpers/token.ts | 14 ---- packages/web3-shared/solana/src/index.ts | 1 - pnpm-lock.yaml | 6 ++ 70 files changed, 230 insertions(+), 609 deletions(-) delete mode 100644 packages/web3-shared/evm/src/helpers/getTransactionSignature.ts delete mode 100644 packages/web3-shared/evm/src/helpers/pack.ts delete mode 100644 packages/web3-shared/evm/src/libs/RequestID.ts delete mode 100644 packages/web3-shared/evm/tests/helpers/pack.ts delete mode 100644 packages/web3-shared/solana/src/helpers/token.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index b32cb66cdda3..9b22fceb32e6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,7 @@ { "typescript.tsdk": "node_modules/typescript/lib", "typescript.preferences.importModuleSpecifierEnding": "js", + // https://github.com/microsoft/typescript-go/issues/2780 "typescript.experimental.useTsgo": true, "js/ts.implicitProjectConfig.module": "NodeNext", "js/ts.implicitProjectConfig.target": "ESNext", diff --git a/eslint.config.js b/eslint.config.js index 20cbdb7c37e2..888f2b8ee49a 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -465,6 +465,12 @@ const moduleSystemRules = { message: 'Avoid using type unsafe methods.', importNames: ['get'], }, + { + name: 'viem', + message: + 'Use toHex from @masknet/shared-base. They have different behaviors on "0x-" strings. If you want to use the original toHex, import it like import { toHex as viem_toHex } from "viem".', + importNames: ['toHex'], + }, { name: 'react-use', importNames: ['useLocalStorage'], diff --git a/packages/mask/background/services/helper/firefly.ts b/packages/mask/background/services/helper/firefly.ts index 1e44ba691c47..2a35be68b170 100644 --- a/packages/mask/background/services/helper/firefly.ts +++ b/packages/mask/background/services/helper/firefly.ts @@ -74,7 +74,7 @@ export async function encrypt(plainText: string, cryptoKey: string): Promise('[data-testid="tweet"]') @@ -122,7 +122,7 @@ function registerPostCollectorInner( const tweetNode = getTweetNode(node) const parentTweetNode = isQuotedTweet(tweetNode) ? getParentTweetNode(tweetNode!) : null if (!tweetNode || shouldSkipDecrypt(node, tweetNode)) { - return `keccak256:${web3_utils.keccak256(node.innerText)}` + return `keccak256:${keccak256(toHex(node.innerText))}` } const parentTweetId = parentTweetNode ? getPostId(parentTweetNode) : '' const tweetId = getPostId(tweetNode) diff --git a/packages/mask/content-script/site-adaptors/twitter.com/utils/fetch.ts b/packages/mask/content-script/site-adaptors/twitter.com/utils/fetch.ts index a63b67cebe23..608199c509f5 100644 --- a/packages/mask/content-script/site-adaptors/twitter.com/utils/fetch.ts +++ b/packages/mask/content-script/site-adaptors/twitter.com/utils/fetch.ts @@ -1,4 +1,3 @@ -import defer * as web3_utils from 'web3-utils' import { flattenDeep } from 'lodash-es' import { normalizeImageURL, parseId } from './url.js' import { @@ -16,6 +15,8 @@ import { } from '@masknet/typed-message' import { collectNodeText, collectTwitterEmoji } from '../../../utils/index.js' import { IMAGE_RENDER_IGNORE } from '../customization/render-fragments.js' +import { keccak256 } from 'viem' +import { toHex } from '@masknet/shared-base' /** * Get post id from dom, including normal tweet, quoted tweet and retweet one @@ -38,9 +39,9 @@ export function getPostId(node: HTMLElement) { } else if (timeNode) { // Quoted tweet in timeline has no a status link to detail page, // so use the timestamp as post id instead - pid = `timestamp-keccak256:${web3_utils.keccak256(timeNode.getAttribute('datetime')!)}` + pid = `timestamp-keccak256:${keccak256(toHex(timeNode.getAttribute('datetime')!))}` } else { - pid = `keccak256:${web3_utils.keccak256(node.innerText)}` + pid = `keccak256:${keccak256(toHex(node.innerText))}` } // You can't retweet a tweet or a retweet, but only cancel retweeting diff --git a/packages/mask/dashboard/pages/CreateMaskWallet/AddDeriveWallet/index.tsx b/packages/mask/dashboard/pages/CreateMaskWallet/AddDeriveWallet/index.tsx index 099cd0035e56..fe3db26f63e1 100644 --- a/packages/mask/dashboard/pages/CreateMaskWallet/AddDeriveWallet/index.tsx +++ b/packages/mask/dashboard/pages/CreateMaskWallet/AddDeriveWallet/index.tsx @@ -3,11 +3,10 @@ import urlcat from 'urlcat' import { memo, useCallback, useMemo, useState } from 'react' import { useAsyncFn } from 'react-use' import { useLocation, useNavigate } from 'react-router-dom' -import defer * as web3_utils from 'web3-utils' import { useQueries, useQuery } from '@tanstack/react-query' import { delay } from '@masknet/kit' import { DeriveWalletTable } from '@masknet/shared' -import { DashboardRoutes, EMPTY_LIST } from '@masknet/shared-base' +import { DashboardRoutes, EMPTY_LIST, toHex } from '@masknet/shared-base' import { makeStyles } from '@masknet/theme' import { useWallet, useWallets } from '@masknet/web3-hooks-base' import { EVMWeb3 } from '@masknet/web3-providers' @@ -28,6 +27,7 @@ import { SetupFrameController } from '../../../components/SetupFrame/index.js' import { ResetWalletContext } from '../context.js' import Services from '#services' import { Trans } from '@lingui/react/macro' +import { keccak256 } from 'viem' const useStyles = makeStyles()((theme) => ({ header: { @@ -85,7 +85,7 @@ export const Component = memo(function AddDeriveWallet() { const { mnemonic, password, isReset } = state // Avoid leaking mnemonic to react-query - const mnemonicHash = web3_utils.sha3(mnemonic) + const mnemonicHash = keccak256(toHex(mnemonic)) const [pathIndexes, setPathIndexes] = useState([]) const { handlePasswordAndWallets } = ResetWalletContext.useContainer() diff --git a/packages/mask/popups/pages/Wallet/GasSetting/GasSetting1559.tsx b/packages/mask/popups/pages/Wallet/GasSetting/GasSetting1559.tsx index 8f88afa62623..b9498e47439b 100644 --- a/packages/mask/popups/pages/Wallet/GasSetting/GasSetting1559.tsx +++ b/packages/mask/popups/pages/Wallet/GasSetting/GasSetting1559.tsx @@ -4,14 +4,13 @@ import { useNavigate } from 'react-router-dom' import { Controller, useForm } from 'react-hook-form' import { isEmpty } from 'lodash-es' import { z as zod } from 'zod' -import defer * as web3_utils from 'web3-utils' import { BigNumber } from 'bignumber.js' import { makeStyles } from '@masknet/theme' import { formatGweiToEther, formatGweiToWei, formatWeiToEther, formatWeiToGwei } from '@masknet/web3-shared-evm' import { zodResolver } from '@hookform/resolvers/zod' import { Typography } from '@mui/material' import { LoadingButton } from '@mui/lab' -import { NetworkPluginID, PopupRoutes, NUMERIC_INPUT_REGEXP_PATTERN } from '@masknet/shared-base' +import { NetworkPluginID, PopupRoutes, NUMERIC_INPUT_REGEXP_PATTERN, toHex } from '@masknet/shared-base' import { formatCurrency, GasOptionType, @@ -31,6 +30,7 @@ import { StyledInput } from '../../../components/StyledInput/index.js' import Services from '#services' import { FormattedCurrency } from '@masknet/shared' import { Trans, useLingui } from '@lingui/react/macro' +import { formatGwei } from 'viem' const useStyles = makeStyles()((theme) => ({ options: { @@ -236,9 +236,9 @@ export const GasSetting1559 = memo(() => { if (value.formatterTransaction._tx.maxFeePerGas && value.formatterTransaction._tx.maxPriorityFeePerGas) { setValue( 'maxPriorityFeePerGas', - web3_utils.fromWei(toFixed(value.formatterTransaction._tx.maxPriorityFeePerGas), 'gwei'), + formatGwei(BigInt(toFixed(value.formatterTransaction._tx.maxPriorityFeePerGas))), ) - setValue('maxFeePerGas', web3_utils.fromWei(toFixed(value.formatterTransaction._tx.maxFeePerGas), 'gwei')) + setValue('maxFeePerGas', formatGwei(BigInt(toFixed(value.formatterTransaction._tx.maxFeePerGas)))) } else { setOption(1) } @@ -268,9 +268,9 @@ export const GasSetting1559 = memo(() => { param === 'latest' ? param : ( { ...Object(param), - gas: web3_utils.toHex(new BigNumber(data.gasLimit).toString()), - maxPriorityFeePerGas: web3_utils.toHex(formatGweiToWei(data.maxPriorityFeePerGas).toFixed(0)), - maxFeePerGas: web3_utils.toHex(formatGweiToWei(data.maxFeePerGas).toFixed(0)), + gas: toHex(data.gasLimit), + maxPriorityFeePerGas: toHex(formatGweiToWei(data.maxPriorityFeePerGas).toFixed(0)), + maxFeePerGas: toHex(formatGweiToWei(data.maxFeePerGas).toFixed(0)), } ), ) diff --git a/packages/mask/popups/pages/Wallet/GasSetting/Prior1559GasSetting.tsx b/packages/mask/popups/pages/Wallet/GasSetting/Prior1559GasSetting.tsx index 2610bc4850e4..fedf570794b2 100644 --- a/packages/mask/popups/pages/Wallet/GasSetting/Prior1559GasSetting.tsx +++ b/packages/mask/popups/pages/Wallet/GasSetting/Prior1559GasSetting.tsx @@ -4,10 +4,9 @@ import { Controller, useForm } from 'react-hook-form' import { useNavigate } from 'react-router-dom' import { BigNumber } from 'bignumber.js' import { isEmpty } from 'lodash-es' -import defer * as web3_utils from 'web3-utils' import { z as zod } from 'zod' import { zodResolver } from '@hookform/resolvers/zod' -import { NetworkPluginID, NUMERIC_INPUT_REGEXP_PATTERN, PopupRoutes } from '@masknet/shared-base' +import { NetworkPluginID, NUMERIC_INPUT_REGEXP_PATTERN, PopupRoutes, toHex } from '@masknet/shared-base' import { Typography } from '@mui/material' import { LoadingButton } from '@mui/lab' import { useChainContext, useGasOptions, useNativeToken, useNativeTokenPrice } from '@masknet/web3-hooks-base' @@ -228,8 +227,8 @@ export const Prior1559GasSetting = memo(() => { if (!value) return const config = value.payload.params!.map((param) => ({ ...Object(param), - gas: web3_utils.toHex(new BigNumber(data.gasLimit).toString()), - gasPrice: web3_utils.toHex(formatGweiToWei(data.gasPrice).toString()), + gas: toHex(data.gasLimit), + gasPrice: toHex(formatGweiToWei(data.gasPrice).toFixed(0)), })) await Services.Wallet.updateUnconfirmedRequest({ ...value.payload, diff --git a/packages/mask/popups/pages/Wallet/Interaction/TransactionRequest.tsx b/packages/mask/popups/pages/Wallet/Interaction/TransactionRequest.tsx index 6cf0d1d87522..0d7def544dba 100644 --- a/packages/mask/popups/pages/Wallet/Interaction/TransactionRequest.tsx +++ b/packages/mask/popups/pages/Wallet/Interaction/TransactionRequest.tsx @@ -1,6 +1,6 @@ import { Trans } from '@lingui/react/macro' import { Icons } from '@masknet/icons' -import { NetworkPluginID } from '@masknet/shared-base' +import { NetworkPluginID, toHex } from '@masknet/shared-base' import { makeStyles } from '@masknet/theme' import { useChainContext, usePrivyWallet, useWallet, useWeb3State } from '@masknet/web3-hooks-base' import { GasOptionType, MessageStateType, TransactionDescriptorType } from '@masknet/web3-shared-base' @@ -15,12 +15,10 @@ import { } from '@masknet/web3-shared-evm' import { Box, Button, Typography } from '@mui/material' import { useQueryClient, useSuspenseQuery } from '@tanstack/react-query' -import { BigNumber } from 'bignumber.js' import { produce } from 'immer' import { compact, mapValues, omit } from 'lodash-es' import { useCallback, useEffect, useState } from 'react' import { useLatest } from 'react-use' -import defer * as web3_utils from 'web3-utils' import { TransactionPreview } from '../../../components/TransactionPreview/index.js' import { UnlockERC20Token } from '../../../components/UnlockERC20Token/index.js' import { UnlockERC721Token } from '../../../components/UnlockERC721Token/index.js' @@ -125,6 +123,8 @@ export function TransactionRequest(props: InteractionItemProps) { if (privyWallet) { const provider = await privyWallet.getEthereumProvider() const result: string = await provider.request(request.request.arguments) + // TODO: + // eslint-disable-next-line react-compiler/react-compiler mockingPrivyPid += 1 await Message?.updateMessage(request.ID, { request: request.request, @@ -175,12 +175,12 @@ export function TransactionRequest(props: InteractionItemProps) { ...(gasConfig ? mapValues(omit(gasConfig, 'gasOptionType'), (value, key) => { if (key === 'gasCurrency' || !value) return - return web3_utils.toHex(value) + return toHex(value) }) : {}), - gasLimit: web3_utils.toHex(new BigNumber(gasConfig?.gas ?? x.gas).toString()), - chainId: web3_utils.toHex(x.chainId), - nonce: web3_utils.toHex(x.nonce), + gasLimit: toHex(gasConfig?.gas ?? x.gas), + chainId: toHex(x.chainId), + nonce: toHex(x.nonce), } }), ) diff --git a/packages/mask/popups/pages/Wallet/utils.ts b/packages/mask/popups/pages/Wallet/utils.ts index 352d963405c4..40f917ed3f8d 100644 --- a/packages/mask/popups/pages/Wallet/utils.ts +++ b/packages/mask/popups/pages/Wallet/utils.ts @@ -1,5 +1,4 @@ import { mapKeys } from 'lodash-es' -import defer * as web3_utils from 'web3-utils' import { EVMWeb3 } from '@masknet/web3-providers' import { ERC20Abi } from '@masknet/web3-contracts/types/ERC20.js' import { toFixed, type RecentTransaction } from '@masknet/web3-shared-base' @@ -12,6 +11,7 @@ import { } from '@masknet/web3-shared-evm' import { ReplaceType, type GasSetting } from './type.js' import { GasSettingModal } from '../../modals/modal-controls.js' +import { toHex } from '@masknet/shared-base' const MaxUint256 = toFixed('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff') @@ -38,7 +38,7 @@ export async function modifyTransaction( const newConfig = { ...candidate, ...oldGasSettings, - ...mapKeys(gasSettings, (value) => (typeof value === 'undefined' ? value : web3_utils.toHex(value))), + ...mapKeys(gasSettings, (value) => (typeof value === 'undefined' ? value : toHex(value))), } if (replaceType === ReplaceType.CANCEL) { await EVMWeb3.cancelTransaction(transaction.id, newConfig, { diff --git a/packages/plugins/Claim/src/hooks/useAirDropActivity.ts b/packages/plugins/Claim/src/hooks/useAirDropActivity.ts index aa29006a08ea..316865ccef15 100644 --- a/packages/plugins/Claim/src/hooks/useAirDropActivity.ts +++ b/packages/plugins/Claim/src/hooks/useAirDropActivity.ts @@ -1,13 +1,14 @@ import { last } from 'lodash-es' -import defer * as web3_utils from 'web3-utils' // cspell:disable-next-line import { MerkleTree } from 'merkletreejs' import { secondsToMilliseconds } from 'date-fns' import { useChainContext } from '@masknet/web3-hooks-base' import { Airdrop } from '@masknet/web3-providers' import { isSameAddress } from '@masknet/web3-shared-base' -import { type ChainId, formatEtherToWei, pack } from '@masknet/web3-shared-evm' +import { type ChainId, formatEtherToWei } from '@masknet/web3-shared-evm' import { useQuery } from '@tanstack/react-query' +import { encodePacked, keccak256, type Hex } from 'viem' +import { toHex } from '@masknet/shared-base' export function useAirDropActivity(chainId: ChainId) { const { account } = useChainContext() @@ -22,13 +23,23 @@ export function useAirDropActivity(chainId: ChainId) { const claimerList = Object.entries(claimers) const claimer = claimerList.find(([address]) => isSameAddress(address, account)) const airdropList = claimerList.map(([address, amount]) => { - return web3_utils.keccak256(pack(['address', 'uint256'], [address, formatEtherToWei(amount)])) + return encodePacked( + ['address', 'uint256'], + [address as Hex, BigInt(formatEtherToWei(amount).toFixed(0))], + ) + }) + const merkleTree = new MerkleTree(airdropList, (value: Buffer) => keccak256(toHex(value)), { + sortPairs: true, }) - const merkleTree = new MerkleTree(airdropList, web3_utils.keccak256, { sortPairs: true }) const amount = claimer ? last(claimer) : undefined const leaf = amount ? - web3_utils.keccak256(pack(['address', 'uint256'], [account, formatEtherToWei(amount)])) + keccak256( + encodePacked( + ['address', 'uint256'], + [account as Hex, BigInt(formatEtherToWei(amount).toFixed(0))], + ), + ) : undefined const merkleProof = leaf ? merkleTree.getHexProof(leaf) : undefined diff --git a/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useClaimCallback.ts b/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useClaimCallback.ts index 57013b7b7198..158dcbd4f95c 100644 --- a/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useClaimCallback.ts +++ b/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useClaimCallback.ts @@ -1,4 +1,4 @@ -import type { NetworkPluginID } from '@masknet/shared-base' +import { toHex, type NetworkPluginID } from '@masknet/shared-base' import type { HappyRedPacketV1 } from '@masknet/web3-contracts/types/HappyRedPacketV1.js' import type { HappyRedPacketV4 } from '@masknet/web3-contracts/types/HappyRedPacketV4.js' import { useChainContext } from '@masknet/web3-hooks-base' @@ -6,9 +6,9 @@ import { EVMChainResolver, EVMWeb3 } from '@masknet/web3-providers' import type { RedPacketJSONPayload } from '@masknet/web3-providers/types' import { type ChainId, ContractTransaction } from '@masknet/web3-shared-evm' import { useAsyncFn } from 'react-use' -import defer * as web3_utils from 'web3-utils' import { useRedPacketContract } from './useRedPacketContract.js' import { useSignedMessage } from './useSignedMessage.js' +import { keccak256 } from 'viem' /** * Claim fungible token red packet. @@ -45,7 +45,7 @@ export function useClaimCallback(account: string, payload: RedPacketJSONPayload rpid, signedMsg, account, - web3_utils.sha3(account)!, + keccak256(toHex(account)), ), config, ) diff --git a/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useCreateCallback.tsx b/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useCreateCallback.tsx index c1c9af70cdd5..35c77b326ca5 100644 --- a/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useCreateCallback.tsx +++ b/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useCreateCallback.tsx @@ -1,8 +1,7 @@ import { useCallback } from 'react' import { useAsync, useAsyncFn } from 'react-use' -import defer * as web3_utils from 'web3-utils' import { omit } from 'lodash-es' -import { NetworkPluginID } from '@masknet/shared-base' +import { NetworkPluginID, toHex } from '@masknet/shared-base' import { useChainContext, useEnvironmentContext } from '@masknet/web3-hooks-base' import type { HappyRedPacketV4 } from '@masknet/web3-contracts/types/HappyRedPacketV4.js' import { type FungibleToken, isLessThan, toFixed } from '@masknet/web3-shared-base' @@ -18,6 +17,7 @@ import { } from '@masknet/web3-shared-evm' import { EVMWeb3 } from '@masknet/web3-providers' import { getRedPacketContractAbi, useRedPacketContract } from './useRedPacketContract.js' +import { keccak256 } from 'viem' export interface RedPacketSettings { shares: number @@ -93,7 +93,7 @@ function useCreateParamsCallback( shares, isRandom, duration, - seed: web3_utils.sha3(seed)!, + seed: keccak256(toHex(seed)), message, name, tokenType, diff --git a/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useCreateNftRedpacketCallback.ts b/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useCreateNftRedpacketCallback.ts index 70e958ae0946..a3ba0391007e 100644 --- a/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useCreateNftRedpacketCallback.ts +++ b/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useCreateNftRedpacketCallback.ts @@ -1,4 +1,4 @@ -import type { NetworkPluginID } from '@masknet/shared-base' +import { toHex, type NetworkPluginID } from '@masknet/shared-base' import { NftRedPacketAbi, type NftRedPacket } from '@masknet/web3-contracts/types/NftRedPacket.js' import { useChainContext } from '@masknet/web3-hooks-base' import { useGasConfig } from '@masknet/web3-hooks-evm' @@ -16,8 +16,8 @@ import { useQuery } from '@tanstack/react-query' import { BigNumber } from 'bignumber.js' import { useMemo } from 'react' import { useAsyncFn } from 'react-use' -import defer * as web3_utils from 'web3-utils' import { createNftRedpacketContract } from './useNftRedPacketContract.js' +import { keccak256 } from 'viem' interface Options { publicKey: string @@ -43,7 +43,7 @@ export function useCreateNftRedpacketCallback({ return [ publicKey, duration, - web3_utils.sha3(Math.random().toString())!, + keccak256(toHex(Math.random().toString())), message, creator, contractAddress, diff --git a/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useCreateNftRedpacketGas.ts b/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useCreateNftRedpacketGas.ts index ea1a23fbb852..17981c7285e9 100644 --- a/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useCreateNftRedpacketGas.ts +++ b/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useCreateNftRedpacketGas.ts @@ -1,12 +1,12 @@ import { useMemo } from 'react' -import defer * as web3_utils from 'web3-utils' -import type { NetworkPluginID } from '@masknet/shared-base' +import { toHex, type NetworkPluginID } from '@masknet/shared-base' import type { NftRedPacket } from '@masknet/web3-contracts/types/NftRedPacket.js' import { useChainContext } from '@masknet/web3-hooks-base' import { toFixed } from '@masknet/web3-shared-base' import { EVMWeb3 } from '@masknet/web3-providers' import { useNftRedPacketContract } from './useNftRedPacketContract.js' import { useQuery } from '@tanstack/react-query' +import { keccak256 } from 'viem' export function useCreateNFTRedpacketGas( message: string, @@ -39,7 +39,7 @@ export function useCreateNFTRedpacketGas( const params: FillMethodParameters = [ publicKey, 60 * 60 * 24, - web3_utils.sha3(Math.random().toString())!, + keccak256(toHex(Math.random().toString())), message, name, contractAddress, diff --git a/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useDefaultCreateGas.ts b/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useDefaultCreateGas.ts index ea29a7e6a5b2..82e54bb1c709 100644 --- a/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useDefaultCreateGas.ts +++ b/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useDefaultCreateGas.ts @@ -1,13 +1,13 @@ import { useAsync } from 'react-use' -import defer * as web3_utils from 'web3-utils' import { omit } from 'lodash-es' -import type { NetworkPluginID } from '@masknet/shared-base' +import { toHex, type NetworkPluginID } from '@masknet/shared-base' import { ZERO, toFixed } from '@masknet/web3-shared-base' import { useChainContext } from '@masknet/web3-hooks-base' import type { HappyRedPacketV4 } from '@masknet/web3-contracts/types/HappyRedPacketV4.js' import { SchemaType, useTokenConstants } from '@masknet/web3-shared-evm' import { checkParams, type RedPacketSettings, type ParamsObjType, type MethodParameters } from './useCreateCallback.js' import { useRedPacketContract } from './useRedPacketContract.js' +import { keccak256 } from 'viem' export function useDefaultCreateGas( redPacketSettings: RedPacketSettings | undefined, @@ -34,7 +34,7 @@ export function useDefaultCreateGas( shares, isRandom, duration, - seed: web3_utils.sha3(seed)!, + seed: keccak256(toHex(seed)), message, name, tokenType, diff --git a/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useHandleCreateOrSelect.ts b/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useHandleCreateOrSelect.ts index 32c45426b853..cacc5e0ad319 100644 --- a/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useHandleCreateOrSelect.ts +++ b/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useHandleCreateOrSelect.ts @@ -1,15 +1,15 @@ import { ApplicationBoardModal } from '@masknet/shared' -import { RedPacketMetaKey, type NetworkPluginID } from '@masknet/shared-base' +import { RedPacketMetaKey, toHex, type NetworkPluginID } from '@masknet/shared-base' import { useChainContext } from '@masknet/web3-hooks-base' import { EVMWeb3 } from '@masknet/web3-providers' import type { FireflyRedPacketAPI, RedPacketJSONPayload } from '@masknet/web3-providers/types' import { Telemetry } from '@masknet/web3-telemetry' import { EventID, EventType } from '@masknet/web3-telemetry/types' import { useCallback, useContext } from 'react' -import defer * as web3_utils from 'web3-utils' import { openComposition } from '../openComposition.js' import { reduceUselessPayloadInfo } from '../helpers/reduceUselessPayloadInfo.js' import { CompositionTypeContext } from '../contexts/CompositionTypeContext.js' +import { keccak256 } from 'viem' interface Options { senderName?: string @@ -34,13 +34,9 @@ export function useHandleCreateOrSelect({ senderName, onClose }: Options) { payload.password = prompt('Please enter the password of the lucky drop:', '') ?? '' } else if (payload.contract_version > 1 && payload.contract_version < 4) { // just sign out the password if it is lost. - payload.password = await EVMWeb3.signMessage( - 'message', - web3_utils.sha3(payload.sender.message) ?? '', - { - account, - }, - ) + payload.password = await EVMWeb3.signMessage('message', keccak256(toHex(payload.sender.message)), { + account, + }) payload.password = payload.password.slice(2) } } diff --git a/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useNftRedPacketContract.ts b/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useNftRedPacketContract.ts index c7c9f06ed601..8b51166a5753 100644 --- a/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useNftRedPacketContract.ts +++ b/packages/plugins/RedPacket/src/SiteAdaptor/hooks/useNftRedPacketContract.ts @@ -12,9 +12,5 @@ export function useNftRedPacketContract(chainId?: ChainId) { export function createNftRedpacketContract(chainId: ChainId | undefined) { const RED_PACKET_NFT_ADDRESS = getNftRedPacketConstant(chainId ?? ChainId.Mainnet, 'RED_PACKET_NFT_ADDRESS') - return createContract( - EVMWeb3.getWeb3({ chainId }), - RED_PACKET_NFT_ADDRESS, - NftRedPacketABI as AbiItem[], - ) + return createContract(EVMWeb3.getWeb3({ chainId }), RED_PACKET_NFT_ADDRESS, NftRedPacketABI) } diff --git a/packages/plugins/Tips/src/components/TokenSection/useGasLimit.ts b/packages/plugins/Tips/src/components/TokenSection/useGasLimit.ts index efcac410eff6..a69fcabfaaba 100644 --- a/packages/plugins/Tips/src/components/TokenSection/useGasLimit.ts +++ b/packages/plugins/Tips/src/components/TokenSection/useGasLimit.ts @@ -1,8 +1,7 @@ import { useAsync } from 'react-use' -import defer * as web3_utils from 'web3-utils' import { EVMContract } from '@masknet/web3-providers' import { useChainContext } from '@masknet/web3-hooks-base' -import type { NetworkPluginID } from '@masknet/shared-base' +import { toHex, type NetworkPluginID } from '@masknet/shared-base' import { TokenType } from '@masknet/web3-shared-base' import { isNativeTokenAddress } from '@masknet/web3-shared-evm' import { useTip } from '../../contexts/index.js' @@ -25,7 +24,7 @@ export function useGasLimit(fallback = DEFAULT_GAS_LIMIT) { chainId, account, }) - const tx = contract?.methods.transfer(recipientAddress, web3_utils.toHex(amount)) + const tx = contract?.methods.transfer(recipientAddress, toHex(amount)) const estimated = await tx?.estimateGas({ from: account, }) diff --git a/packages/shared-base/src/helpers/pvtsutils.ts b/packages/shared-base/src/helpers/pvtsutils.ts index 4693e3d90901..71c34acc118d 100644 --- a/packages/shared-base/src/helpers/pvtsutils.ts +++ b/packages/shared-base/src/helpers/pvtsutils.ts @@ -1,4 +1,5 @@ import { Convert } from 'pvtsutils' +import { toHex as viem_toHex, type ByteArray } from 'viem' export function fromBase64URL(x: string) { return new Uint8Array(Convert.FromBase64Url(x)) @@ -12,8 +13,12 @@ export function toBase64(x: BufferSource) { return Convert.ToBase64(x) } -export function toHex(x: BufferSource) { - return Convert.ToHex(x) +export function toHex(value: string | number | bigint | boolean | ByteArray) { + if (typeof value === 'string') { + // convert hex to number first, to normalize hex like 0x02 to 0x2 + if (/^\d+$/u.test(value) || /^0x[0-9a-fA-F]+$/u.test(value)) return viem_toHex(BigInt(value)) + } + return viem_toHex(value) } export function fromHex(x: string) { diff --git a/packages/shared/src/UI/components/SettingsBoard/Context.tsx b/packages/shared/src/UI/components/SettingsBoard/Context.tsx index ea6753068a56..c3b3eca1ca9a 100644 --- a/packages/shared/src/UI/components/SettingsBoard/Context.tsx +++ b/packages/shared/src/UI/components/SettingsBoard/Context.tsx @@ -1,18 +1,19 @@ import { useCallback, useEffect, useState } from 'react' import { createContainer } from '@masknet/shared-base-ui' -import { useGasOptions, useNetworkContext, useChainContext, useWeb3Utils } from '@masknet/web3-hooks-base' +import { useGasOptions, useNetworkContext, useChainContext } from '@masknet/web3-hooks-base' import type { Web3Helper } from '@masknet/web3-helpers' import { GasOptionType } from '@masknet/web3-shared-base' import type { NetworkPluginID } from '@masknet/shared-base' import { GasSettingsType } from './types/index.js' import { useLingui } from '@lingui/react/macro' +import stringify from 'json-stable-stringify' const DEFAULT_SLIPPAGE_TOLERANCE = 0.5 const DEFAULT_SLIPPAGE_TOLERANCES = [0.5, 1, 2, 5] const IN_MEMORY_CACHE: { - lastNetworkSignature?: string - lastTransactionSignature?: string + lastNetworkCacheKey?: string + lastTransactionCacheKey?: string lastSelectedGasOptionType: GasOptionType lastSelectedGasSettingsType: GasSettingsType } = { @@ -34,18 +35,17 @@ function useSettingsContext(initial?: { const { chainId } = useChainContext({ chainId: initial?.chainId, }) - const Utils = useWeb3Utils(pluginID) const [transactionOptions, setTransactionOptions] = useState< Web3Helper.Definition[typeof pluginID]['Transaction'] | undefined >(initial?.transaction) const [slippageTolerance, setSlippageTolerance] = useState(initial?.slippageTolerance ?? DEFAULT_SLIPPAGE_TOLERANCE) - const networkSignature = `${pluginID}_${chainId}` - const transactionSignature = Utils.getTransactionSignature!(chainId, transactionOptions) ?? '' + const networkCacheKey = `${pluginID}_${chainId}` + const transactionCacheKey = stringify([chainId, transactionOptions]) const needToResetByNetwork = - !!IN_MEMORY_CACHE.lastNetworkSignature && IN_MEMORY_CACHE.lastNetworkSignature !== networkSignature + !!IN_MEMORY_CACHE.lastNetworkCacheKey && IN_MEMORY_CACHE.lastNetworkCacheKey !== networkCacheKey const needToResetByTransaction = - !!IN_MEMORY_CACHE.lastTransactionSignature && IN_MEMORY_CACHE.lastTransactionSignature !== transactionSignature + !!IN_MEMORY_CACHE.lastTransactionCacheKey && IN_MEMORY_CACHE.lastTransactionCacheKey !== transactionCacheKey const [gasSettingsType, setGasSettingsType] = useState( needToResetByNetwork || needToResetByTransaction ? GasSettingsType.Basic @@ -66,8 +66,8 @@ function useSettingsContext(initial?: { const onClearInMemoryCache = useCallback(() => { // eslint-disable-next-line react-compiler/react-compiler - delete IN_MEMORY_CACHE.lastNetworkSignature - delete IN_MEMORY_CACHE.lastTransactionSignature + delete IN_MEMORY_CACHE.lastNetworkCacheKey + delete IN_MEMORY_CACHE.lastTransactionCacheKey IN_MEMORY_CACHE.lastSelectedGasOptionType = GasOptionType.NORMAL IN_MEMORY_CACHE.lastSelectedGasSettingsType = GasSettingsType.Basic }, []) @@ -82,11 +82,11 @@ function useSettingsContext(initial?: { // sync in-memory cache useEffect(() => { - IN_MEMORY_CACHE.lastNetworkSignature = networkSignature - IN_MEMORY_CACHE.lastTransactionSignature = transactionSignature + IN_MEMORY_CACHE.lastNetworkCacheKey = networkCacheKey + IN_MEMORY_CACHE.lastTransactionCacheKey = transactionCacheKey IN_MEMORY_CACHE.lastSelectedGasOptionType = gasOptionType IN_MEMORY_CACHE.lastSelectedGasSettingsType = gasSettingsType - }, [gasOptionType, gasSettingsType, networkSignature, transactionSignature]) + }, [gasOptionType, gasSettingsType, networkCacheKey, transactionCacheKey]) return { DEFAULT_SLIPPAGE_TOLERANCE, diff --git a/packages/shared/src/UI/modals/GasSettingModal/Prior1559GasSetting.tsx b/packages/shared/src/UI/modals/GasSettingModal/Prior1559GasSetting.tsx index 598ad935c43c..22e2d018e365 100644 --- a/packages/shared/src/UI/modals/GasSettingModal/Prior1559GasSetting.tsx +++ b/packages/shared/src/UI/modals/GasSettingModal/Prior1559GasSetting.tsx @@ -2,7 +2,6 @@ import { memo, useCallback, useEffect, useMemo, useState } from 'react' import { useUpdateEffect } from 'react-use' import { Controller, useForm } from 'react-hook-form' import { isEmpty, noop } from 'lodash-es' -import defer * as web3_utils from 'web3-utils' import { z as zod } from 'zod' import { BigNumber } from 'bignumber.js' import { zodResolver } from '@hookform/resolvers/zod' @@ -20,6 +19,7 @@ import { ActionButton, makeStyles, MaskColorVar } from '@masknet/theme' import { Typography } from '@mui/material' import type { GasSettingProps } from './types.js' import { Trans, useLingui } from '@lingui/react/macro' +import { parseGwei } from 'viem' const minGasPriceOfChain: ChainIdOptionalRecord = { [ChainId.BSC]: pow10(9).multipliedBy(5), @@ -172,7 +172,7 @@ export const Prior1559GasSetting = memo( (data: zod.infer) => { onConfirm({ gasLimit: data.gasLimit as any, - gasPrice: web3_utils.toWei(data.gasPrice, 'gwei'), + gasPrice: parseGwei(data.gasPrice).toString(), gasOption: selectedGasOption, }) }, diff --git a/packages/web3-hooks/evm/src/useContract.ts b/packages/web3-hooks/evm/src/useContract.ts index 5c5a936a850d..ba58f583f9bc 100644 --- a/packages/web3-hooks/evm/src/useContract.ts +++ b/packages/web3-hooks/evm/src/useContract.ts @@ -1,38 +1,17 @@ import { useMemo } from 'react' -import type { AbiItem } from 'web3-utils' import { EMPTY_LIST } from '@masknet/shared-base' import { EVMWeb3 } from '@masknet/web3-providers' import { type ChainId, createContract } from '@masknet/web3-shared-evm' import type { BaseContract } from '@masknet/web3-contracts/types/types.js' +import type { Abi } from 'viem' /** * Create a contract which will forward its all transactions to the * EthereumService in the background page and decode the result of calls automatically * @param address - * @param ABI + * @param abi * @param chainId */ -export function useContract(chainId?: ChainId, address = '', ABI: AbiItem[] = EMPTY_LIST) { - return useMemo(() => createContract(EVMWeb3.getWeb3({ chainId }), address, ABI), [address, ABI]) -} - -/** - * Create many contracts with same ABI - * @param listOfAddress - * @param ABI - * @param chainId - */ -export function useContracts( - chainId?: ChainId, - listOfAddress: string[] = EMPTY_LIST, - ABI: AbiItem[] = EMPTY_LIST, -) { - return useMemo( - () => - listOfAddress - .map((address) => createContract(EVMWeb3.getWeb3({ chainId }), address, ABI)) - .filter(Boolean) as T[], - // eslint-disable-next-line react-compiler/react-compiler - [JSON.stringify(listOfAddress), ABI], - ) +export function useContract(chainId?: ChainId, address = '', abi: Abi = EMPTY_LIST) { + return useMemo(() => createContract(EVMWeb3.getWeb3({ chainId }), address, abi), [address, abi]) } diff --git a/packages/web3-providers/package.json b/packages/web3-providers/package.json index 8fbe49daded8..81a9efcf3204 100644 --- a/packages/web3-providers/package.json +++ b/packages/web3-providers/package.json @@ -66,6 +66,7 @@ "buffer": "^6.0.3", "date-fns": "^3.6.0", "fuse.js": "^7.0.0", + "json-stable-stringify": "^1.1.1", "graphql-request": "^7.0.1", "immer": "^10.1.1", "lru-cache": "^10.3.0", @@ -85,6 +86,7 @@ "devDependencies": { "@types/bn.js": "^5.1.5", "@types/bs58": "^4.0.4", + "@types/json-stable-stringify": "^1.0.36", "@types/socket.io-client": "^1.4.36", "@types/twitter-text": "^3.1.10", "@types/use-subscription": "^1.0.2", diff --git a/packages/web3-providers/src/Alchemy/helpers.ts b/packages/web3-providers/src/Alchemy/helpers.ts index 41af975aeb86..456656e55b5d 100644 --- a/packages/web3-providers/src/Alchemy/helpers.ts +++ b/packages/web3-providers/src/Alchemy/helpers.ts @@ -1,7 +1,7 @@ -import defer * as web3_utils from 'web3-utils' +import { isHex } from 'viem' export function formatAlchemyTokenId(tokenId: string) { - return web3_utils.isHex(tokenId) && tokenId.startsWith('0x') ? web3_utils.hexToNumberString(tokenId) : tokenId + return isHex(tokenId) ? Number(tokenId).toString() : tokenId } export function formatAlchemyTokenAddress(address: string, identifier: string) { diff --git a/packages/web3-providers/src/Web3/Base/apis/Utils.ts b/packages/web3-providers/src/Web3/Base/apis/Utils.ts index 5a87340f3528..90cd72bcb677 100644 --- a/packages/web3-providers/src/Web3/Base/apis/Utils.ts +++ b/packages/web3-providers/src/Web3/Base/apis/Utils.ts @@ -1,56 +1,28 @@ -import type { NetworkPluginID } from '@masknet/shared-base' -import { type FungibleToken, type NonFungibleToken } from '@masknet/web3-shared-base' -import type { ProviderResolver } from './ProviderResolver.js' import type { NetworkResolver } from './NetworkExplorer.js' import type { ChainResolver } from './ChainResolver.js' import type { ExplorerResolver } from './ExplorerResolver.js' -export interface BaseUtils { +export interface BaseUtils { readonly chainResolver: ChainResolver readonly explorerResolver: ExplorerResolver - readonly providerResolver: ProviderResolver readonly networkResolver: NetworkResolver - getNetworkPluginID(): NetworkPluginID - getDefaultChainId(): ChainId - getInvalidChainId?(): ChainId - - getDefaultNetworkType(): NetworkType - - getDefaultProviderType(): ProviderType - - getZeroAddress(): string | undefined - getNativeTokenAddress(chainId?: ChainId): string | undefined getMaskTokenAddress(chainId?: ChainId): string | undefined getAverageBlockDelay?(chainId: ChainId, scale?: number): number - getTransactionSignature?(chainId?: ChainId, transaction?: Transaction | undefined): string | undefined - - isSameAddress(address?: string | undefined, otherAddress?: string | undefined): boolean - - isZeroAddress(address?: string): boolean - isNativeTokenAddress(address?: string): boolean - isValidChain?(chainId: ChainId, testnet?: boolean): boolean - isValidChainId(chainId: ChainId): boolean isValidDomain(domain: string): boolean isValidAddress(address: string): boolean - isNativeTokenSchemaType(schemaType?: SchemaType | undefined): boolean - - isFungibleTokenSchemaType(schemaType?: SchemaType | undefined): boolean - - isNonFungibleTokenSchemaType(schemaType?: SchemaType | undefined): boolean - formatAddress(address: string, size?: number | undefined): string formatTokenId(id?: string | undefined, size?: number | undefined): string @@ -58,27 +30,4 @@ export interface BaseUtils - - createFungibleToken( - chainId: ChainId, - schemaType: SchemaType, - address: string, - name?: string, - symbol?: string, - decimals?: number, - logoURI?: string, - ): FungibleToken - - createNonFungibleToken( - chainId: ChainId, - address: string, - schemaType: SchemaType, - tokenId: string, - ownerId?: string, - metadata?: NonFungibleToken['metadata'], - contract?: NonFungibleToken['contract'], - collection?: NonFungibleToken['collection'], - ): NonFungibleToken } diff --git a/packages/web3-providers/src/Web3/EVM/apis/ConnectionAPI.ts b/packages/web3-providers/src/Web3/EVM/apis/ConnectionAPI.ts index 08f2c4fcc04f..de74618987a0 100644 --- a/packages/web3-providers/src/Web3/EVM/apis/ConnectionAPI.ts +++ b/packages/web3-providers/src/Web3/EVM/apis/ConnectionAPI.ts @@ -1,6 +1,5 @@ -import defer * as web3_utils from 'web3-utils' import { delay } from '@masknet/kit' -import { NetworkPluginID } from '@masknet/shared-base' +import { NetworkPluginID, toHex } from '@masknet/shared-base' import type { Account } from '@masknet/shared-base' import { type AddressType, @@ -100,7 +99,7 @@ export class ConnectionAPI // ERC20 return new ContractTransaction(this.Contract.getERC20Contract(address, options)).send( - (x) => x?.methods.approve(recipient, web3_utils.toHex(amount)), + (x) => x?.methods.approve(recipient, toHex(amount)), options.overrides, ) } @@ -138,8 +137,8 @@ export class ConnectionAPI const tx: Transaction = { from: options.account, to: recipient, - value: web3_utils.toHex(amount), - data: memo ? web3_utils.toHex(memo) : undefined, + value: toHex(amount), + data: memo ? toHex(memo) : undefined, } return this.sendTransaction( { @@ -152,7 +151,7 @@ export class ConnectionAPI // ERC20 return new ContractTransaction(this.Contract.getERC20Contract(address, options)).send( - (x) => x?.methods.transfer(recipient, web3_utils.toHex(amount)), + (x) => x?.methods.transfer(recipient, toHex(amount)), options.overrides, ) } diff --git a/packages/web3-providers/src/Web3/EVM/apis/ConnectionReadonlyAPI.ts b/packages/web3-providers/src/Web3/EVM/apis/ConnectionReadonlyAPI.ts index 262f7d4ce30a..eddee833ad7b 100644 --- a/packages/web3-providers/src/Web3/EVM/apis/ConnectionReadonlyAPI.ts +++ b/packages/web3-providers/src/Web3/EVM/apis/ConnectionReadonlyAPI.ts @@ -1,4 +1,4 @@ -import type { Account, ECKeyIdentifier, Proof } from '@masknet/shared-base' +import { toHex, type Account, type ECKeyIdentifier, type Proof } from '@masknet/shared-base' import { queryClient } from '@masknet/shared-base-ui' import { createNonFungibleToken, @@ -40,7 +40,6 @@ import { type Web3, } from '@masknet/web3-shared-evm' import { first, omit, toNumber } from 'lodash-es' -import defer * as web3_utils from 'web3-utils' import type { BaseConnectionOptions } from '../../../entry-types.js' import { fetchJSON } from '../../../helpers/fetchJSON.js' import type { BaseConnection } from '../../Base/apis/Connection.js' @@ -466,7 +465,7 @@ export class EVMConnectionReadonlyAPI const balances = await contract?.methods.balances([options.account], listOfNonNativeAddress).call({ // cannot check the sender's balance in the same contract from: undefined, - chainId: web3_utils.numberToHex(options.chainId), + chainId: toHex(options.chainId), }) listOfNonNativeAddress.forEach((x, i) => { @@ -514,8 +513,8 @@ export class EVMConnectionReadonlyAPI return createERC20Token( options.chainId, address, - parseStringOrBytes32(name, nameBytes32, 'Unknown Token'), - parseStringOrBytes32(symbol, symbolBytes32, 'UNKNOWN'), + parseStringOrBytes32(name, toHex(nameBytes32), 'Unknown Token'), + parseStringOrBytes32(symbol, toHex(symbolBytes32), 'UNKNOWN'), typeof decimals === 'string' ? Number.parseInt(decimals ? decimals : '0', 10) : decimals, ) } @@ -548,7 +547,7 @@ export class EVMConnectionReadonlyAPI return this.Request.request( { method: EthereumMethodType.eth_getBlockByNumber, - params: [web3_utils.toHex(noOrId), false], + params: [toHex(noOrId), false], }, initial, ) @@ -618,7 +617,7 @@ export class EVMConnectionReadonlyAPI options, ) } catch { - return web3_utils.toHex(fallback) + return toHex(fallback) } } diff --git a/packages/web3-providers/src/Web3/EVM/apis/ContractReadonlyAPI.ts b/packages/web3-providers/src/Web3/EVM/apis/ContractReadonlyAPI.ts index ca04b4458cb0..7aa654868eda 100644 --- a/packages/web3-providers/src/Web3/EVM/apis/ContractReadonlyAPI.ts +++ b/packages/web3-providers/src/Web3/EVM/apis/ContractReadonlyAPI.ts @@ -1,4 +1,3 @@ -import type { AbiItem } from 'web3-utils' import { isUndefined, omitBy } from 'lodash-es' import { createContract } from '@masknet/web3-shared-evm' import type { BalanceChecker } from '@masknet/web3-contracts/types/BalanceChecker.js' @@ -22,6 +21,7 @@ import { WalletAbi as WalletABI } from '@masknet/web3-contracts/types/Wallet.js' import { EVMRequestReadonlyAPI } from './RequestReadonlyAPI.js' import type { EVMConnectionOptions } from '../types/index.js' +import type { Abi } from 'viem' export class EVMContractReadonlyAPI { static Default = new EVMContractReadonlyAPI() @@ -30,11 +30,7 @@ export class EVMContractReadonlyAPI { } protected Request - getWeb3Contract( - address: string | undefined, - ABI: AbiItem[], - initial?: EVMConnectionOptions, - ) { + getWeb3Contract(address: string | undefined, abi: Abi, initial?: EVMConnectionOptions) { const web3 = this.Request.getWeb3(initial) const options = omitBy( { @@ -42,7 +38,7 @@ export class EVMContractReadonlyAPI { }, isUndefined, ) - return createContract(web3, address, ABI, options) + return createContract(web3, address, abi, options) } getERC20Contract(address: string | undefined, initial?: EVMConnectionOptions) { diff --git a/packages/web3-providers/src/Web3/EVM/apis/SignerAPI.ts b/packages/web3-providers/src/Web3/EVM/apis/SignerAPI.ts index 00bbdd10e7b4..7a64d78b141c 100644 --- a/packages/web3-providers/src/Web3/EVM/apis/SignerAPI.ts +++ b/packages/web3-providers/src/Web3/EVM/apis/SignerAPI.ts @@ -2,7 +2,6 @@ import defer * as _metamask_eth_sig_util from '@metamask/eth-sig-util' import { signTransaction } from '@masknet/web3-shared-evm' import { type SignMessage, SignType, toHex } from '@masknet/shared-base' import { unreachable } from '@masknet/kit' -import type { Hex } from 'viem' export class Signer { static async sign({ type, data }: SignMessage, key: Buffer): Promise { @@ -24,7 +23,7 @@ export class Signer { const chainId = transaction.chainId if (!chainId) throw new Error('Invalid chain id.') - const rawTransaction = await signTransaction(transaction, toHex(key) as Hex) + const rawTransaction = await signTransaction(transaction, toHex(key)) if (!rawTransaction) throw new Error('Failed to sign transaction.') return rawTransaction diff --git a/packages/web3-providers/src/Web3/EVM/apis/Utils.ts b/packages/web3-providers/src/Web3/EVM/apis/Utils.ts index bbff9e6d2a7d..e0a4f9a65398 100644 --- a/packages/web3-providers/src/Web3/EVM/apis/Utils.ts +++ b/packages/web3-providers/src/Web3/EVM/apis/Utils.ts @@ -1,27 +1,14 @@ -import { createFungibleToken, createNonFungibleToken, isSameAddress } from '@masknet/web3-shared-base' import { isValidDomain, isValidAddress, - isZeroAddress, isNativeTokenAddress, - isNativeTokenSchemaType, - isFungibleTokenSchemaType, - isNonFungibleTokenSchemaType, formatEthereumAddress, formatDomainName, formatTokenId, - getTransactionSignature, type ChainId, - type ProviderType, type NetworkType, - type Transaction, type SchemaType, - getNetworkPluginID, getDefaultChainId, - getInvalidChainId, - getDefaultNetworkType, - getDefaultProviderType, - getZeroAddress, getMaskTokenAddress, getNativeTokenAddress, getAverageBlockDelay, @@ -29,42 +16,25 @@ import { isValidChainId, } from '@masknet/web3-shared-evm' import type { BaseUtils } from '../../Base/apis/Utils.js' -import { EVMChainResolver, EVMExplorerResolver, EVMProviderResolver, EVMNetworkResolver } from './ResolverAPI.js' +import { EVMChainResolver, EVMExplorerResolver, EVMNetworkResolver } from './ResolverAPI.js' export const EVMUtils = { - isSameAddress, chainResolver: EVMChainResolver, explorerResolver: EVMExplorerResolver, - providerResolver: EVMProviderResolver, networkResolver: EVMNetworkResolver, isValidDomain, isValidChainId, isValidAddress, - isZeroAddress, isNativeTokenAddress, - isNativeTokenSchemaType, - isFungibleTokenSchemaType, - isNonFungibleTokenSchemaType, - getNetworkPluginID, getDefaultChainId, - getInvalidChainId, - getDefaultNetworkType, - getDefaultProviderType, - getZeroAddress, getMaskTokenAddress, getNativeTokenAddress, - getTransactionSignature, getAverageBlockDelay, formatAddress: formatEthereumAddress, formatTokenId, formatDomainName, formatSchemaType, - createNativeToken(chainId: ChainId) { - return EVMChainResolver.nativeCurrency(chainId) - }, - createFungibleToken, - createNonFungibleToken, -} satisfies BaseUtils +} satisfies BaseUtils diff --git a/packages/web3-providers/src/Web3/EVM/interceptors/MaskWallet.ts b/packages/web3-providers/src/Web3/EVM/interceptors/MaskWallet.ts index 207132ada0d6..ac792a81f3c3 100644 --- a/packages/web3-providers/src/Web3/EVM/interceptors/MaskWallet.ts +++ b/packages/web3-providers/src/Web3/EVM/interceptors/MaskWallet.ts @@ -1,5 +1,4 @@ -import defer * as web3_utils from 'web3-utils' -import type { Wallet } from '@masknet/shared-base' +import { toHex, type Wallet } from '@masknet/shared-base' import { EthereumMethodType, type Middleware, isValidAddress } from '@masknet/web3-shared-evm' import type { ConnectionContext } from '../libs/ConnectionContext.js' import { MaskWalletProviderInstance } from '../providers/index.js' @@ -17,7 +16,7 @@ export class MaskWallet implements Middleware { switch (context.request.method) { case EthereumMethodType.eth_chainId: - context.write(web3_utils.toHex(provider.hostedChainId)) + context.write(toHex(provider.hostedChainId)) break case EthereumMethodType.eth_accounts: context.write([provider.hostedAccount]) diff --git a/packages/web3-providers/src/Web3/EVM/interceptors/WalletConnect.ts b/packages/web3-providers/src/Web3/EVM/interceptors/WalletConnect.ts index 7406b94b27ec..40ded4db28b1 100644 --- a/packages/web3-providers/src/Web3/EVM/interceptors/WalletConnect.ts +++ b/packages/web3-providers/src/Web3/EVM/interceptors/WalletConnect.ts @@ -1,6 +1,6 @@ -import defer * as web3_utils from 'web3-utils' import { EthereumMethodType, type Middleware } from '@masknet/web3-shared-evm' import type { ConnectionContext } from '../libs/ConnectionContext.js' +import { toHex } from '@masknet/shared-base' export class WalletConnect implements Middleware { async fn(context: ConnectionContext, next: () => Promise) { @@ -20,7 +20,7 @@ export class WalletConnect implements Middleware { switch (context.request.method) { case EthereumMethodType.eth_chainId: if (typeof context.result === 'number') { - context.result = web3_utils.toHex(context.result) + context.result = toHex(context.result) } break default: diff --git a/packages/web3-providers/src/Web3/EVM/middleware/Nonce.ts b/packages/web3-providers/src/Web3/EVM/middleware/Nonce.ts index 69864f3387cc..595bfdfa12b5 100644 --- a/packages/web3-providers/src/Web3/EVM/middleware/Nonce.ts +++ b/packages/web3-providers/src/Web3/EVM/middleware/Nonce.ts @@ -1,4 +1,3 @@ -import defer * as web3_utils from 'web3-utils' import { type ChainId, EthereumMethodType, @@ -8,6 +7,7 @@ import { } from '@masknet/web3-shared-evm' import type { ConnectionContext } from '../libs/ConnectionContext.js' import { EVMWeb3Readonly } from '../apis/ConnectionReadonlyAPI.js' +import { toHex } from '@masknet/shared-base' class NonceAPI implements Middleware { static INITIAL_NONCE = -1 @@ -48,9 +48,7 @@ class NonceAPI implements Middleware { params: [ { ...context.config, - nonce: web3_utils.toHex( - await this.syncRemoteNonce(context.chainId, context.account, context.providerURL), - ), + nonce: toHex(await this.syncRemoteNonce(context.chainId, context.account, context.providerURL)), }, ], } diff --git a/packages/web3-providers/src/Web3/EVM/providers/Base.ts b/packages/web3-providers/src/Web3/EVM/providers/Base.ts index 50d9f0fc5782..4a77713e1fec 100644 --- a/packages/web3-providers/src/Web3/EVM/providers/Base.ts +++ b/packages/web3-providers/src/Web3/EVM/providers/Base.ts @@ -1,5 +1,4 @@ import { first } from 'lodash-es' -import defer * as web3_utils from 'web3-utils' import { Emitter } from '@servie/events' import { delay } from '@masknet/kit' import { @@ -10,7 +9,7 @@ import { type RequestArguments, isValidChainId, } from '@masknet/web3-shared-evm' -import { type Account, type Wallet, EMPTY_LIST, createConstantSubscription } from '@masknet/shared-base' +import { type Account, type Wallet, EMPTY_LIST, createConstantSubscription, toHex } from '@masknet/shared-base' import { EVMChainResolver } from '../apis/ResolverAPI.js' import { createWeb3ProviderFromRequest } from '../../../helpers/createWeb3ProviderFromRequest.js' import type { WalletAPI } from '../../../entry-types.js' @@ -51,7 +50,7 @@ export abstract class BaseEVMWalletProvider implements EVMWalletProvider { method: EthereumMethodType.wallet_switchEthereumChain, params: [ { - chainId: web3_utils.toHex(chainId), + chainId: toHex(chainId), }, ], }) @@ -70,7 +69,7 @@ export abstract class BaseEVMWalletProvider implements EVMWalletProvider { method: EthereumMethodType.wallet_addEthereumChain, params: [ { - chainId: web3_utils.toHex(chainId), + chainId: toHex(chainId), chainName: EVMChainResolver.chainFullName(chainId) ?? EVMChainResolver.chainName(chainId), nativeCurrency: EVMChainResolver.nativeCurrency(chainId), rpcUrls: [ProviderURL.fromOfficial(chainId)], diff --git a/packages/web3-providers/src/Web3/EVM/providers/BaseHosted.ts b/packages/web3-providers/src/Web3/EVM/providers/BaseHosted.ts index b15dedbdff13..05739dc14c88 100644 --- a/packages/web3-providers/src/Web3/EVM/providers/BaseHosted.ts +++ b/packages/web3-providers/src/Web3/EVM/providers/BaseHosted.ts @@ -1,7 +1,12 @@ import { uniqWith } from 'lodash-es' -import defer * as web3_utils from 'web3-utils' import { delay } from '@masknet/kit' -import { type StorageObject, type UpdatableWallet, type Wallet, CrossIsolationMessages } from '@masknet/shared-base' +import { + type StorageObject, + type UpdatableWallet, + type Wallet, + CrossIsolationMessages, + toHex, +} from '@masknet/shared-base' import { isSameAddress } from '@masknet/web3-shared-base' import { isValidAddress, formatEthereumAddress, type ChainId, type ProviderType } from '@masknet/web3-shared-evm' import { BaseEVMWalletProvider } from './Base.js' @@ -141,12 +146,12 @@ export abstract class BaseHostedProvider extends BaseEVMWalletProvider { this.emitter.emit('accounts', [this.hostedAccount]) await delay(100) - this.emitter.emit('chainId', web3_utils.toHex(this.hostedChainId)) + this.emitter.emit('chainId', toHex(this.hostedChainId)) } private async onChainChanged() { await this.walletStorage.chainId.initializedPromise - if (this.hostedChainId) this.emitter.emit('chainId', web3_utils.toHex(this.hostedChainId)) + if (this.hostedChainId) this.emitter.emit('chainId', toHex(this.hostedChainId)) } async switchAccount(account?: string) { diff --git a/packages/web3-providers/src/Web3/EVM/providers/Opera.ts b/packages/web3-providers/src/Web3/EVM/providers/Opera.ts index 9342bbda4b02..3da4187b86bb 100644 --- a/packages/web3-providers/src/Web3/EVM/providers/Opera.ts +++ b/packages/web3-providers/src/Web3/EVM/providers/Opera.ts @@ -1,5 +1,4 @@ -import defer * as web3_utils from 'web3-utils' -import { Sniffings } from '@masknet/shared-base' +import { Sniffings, toHex } from '@masknet/shared-base' import { injectedOperaProvider } from '@masknet/injected-script' import { type ChainId, EthereumMethodType, ProviderType, isValidChainId } from '@masknet/web3-shared-evm' import { EVMInjectedWalletProvider } from './BaseInjected.js' @@ -26,7 +25,7 @@ export class OperaProvider extends EVMInjectedWalletProvider { method: EthereumMethodType.wallet_switchEthereumChain, params: [ { - chainId: web3_utils.toHex(chainId), + chainId: toHex(chainId), }, ], }) diff --git a/packages/web3-providers/src/Web3/EVM/providers/WalletConnect.ts b/packages/web3-providers/src/Web3/EVM/providers/WalletConnect.ts index a1c35c211c84..385d09eb1437 100644 --- a/packages/web3-providers/src/Web3/EVM/providers/WalletConnect.ts +++ b/packages/web3-providers/src/Web3/EVM/providers/WalletConnect.ts @@ -1,10 +1,9 @@ import { first } from 'lodash-es' -import defer * as web3_utils from 'web3-utils' import type { Emitter } from '@servie/events' import { getSdkError } from '@walletconnect/utils' import { SignClient } from '@walletconnect/sign-client' import { Flags } from '@masknet/flags' -import type { UnboxPromise } from '@masknet/shared-base' +import { toHex, type UnboxPromise } from '@masknet/shared-base' import { ProviderType, ChainId, @@ -49,7 +48,7 @@ class Client { this.client.on('session_update', () => { if (!this.account) return - this.emitter.emit('chainId', web3_utils.toHex(this.account.chainId)) + this.emitter.emit('chainId', toHex(this.account.chainId)) this.emitter.emit('accounts', [this.account.account]) }) diff --git a/packages/web3-providers/src/Web3/EVM/state/TransactionWatcher/checkers/AccountChecker.ts b/packages/web3-providers/src/Web3/EVM/state/TransactionWatcher/checkers/AccountChecker.ts index 07783bffe506..3081f043efcd 100644 --- a/packages/web3-providers/src/Web3/EVM/state/TransactionWatcher/checkers/AccountChecker.ts +++ b/packages/web3-providers/src/Web3/EVM/state/TransactionWatcher/checkers/AccountChecker.ts @@ -1,8 +1,8 @@ -import defer * as web3_utils from 'web3-utils' import { type TransactionChecker, TransactionStatusType } from '@masknet/web3-shared-base' import type { ChainId, Transaction } from '@masknet/web3-shared-evm' import { EtherscanExplorer } from '../../../../../Etherscan/index.js' import type { ExplorerAPI } from '../../../../../entry-types.js' +import { toHex } from '@masknet/shared-base' class TTL { private cache: Record = {} @@ -30,16 +30,15 @@ class AccountCheckerAPI implements TransactionChecker { private ttl = new TTL() - private getExplorerTransactionId(transaction: ExplorerAPI.Transaction | null) { + private getTransactionCacheKey(transaction: ExplorerAPI.Transaction | Transaction | null) { if (!transaction) return '' - const { from, to, input, value } = transaction - return web3_utils.sha3([from, to, input || '0x0', web3_utils.toHex(value || '0x0') || '0x0'].join('_')) ?? '' - } - - private getTransactionId(transaction: Transaction) { - const { from, to, data = '0x0', value = '0x0' } = transaction - if (!from || !to) return '' - return web3_utils.sha3([from, to, data, value].join('_')) ?? '' + const { from, to, value = '0' } = transaction + return JSON.stringify([ + from, + to, + 'input' in transaction ? transaction.input : transaction.data || '0x0', + toHex(value || '0'), + ]) } private async fetchLatestTransactions(chainId: ChainId, account: string) { @@ -58,8 +57,8 @@ class AccountCheckerAPI implements TransactionChecker { const account = transaction.from if (!account) throw new Error('Cannot found account.') const latestTransactions = await this.fetchLatestTransactions(chainId, account) - const txId = this.getTransactionId(transaction) - const tx = latestTransactions.find((x) => x.hash === id || this.getExplorerTransactionId(x) === txId) + const txId = this.getTransactionCacheKey(transaction) + const tx = latestTransactions.find((x) => x.hash === id || this.getTransactionCacheKey(x) === txId) if (!tx) return TransactionStatusType.NOT_DEPEND // '1' for successful transactions and '0' for failed transactions. return tx.status === '1' ? TransactionStatusType.SUCCEED : TransactionStatusType.FAILED diff --git a/packages/web3-providers/src/Web3/EVM/translators/Astar.ts b/packages/web3-providers/src/Web3/EVM/translators/Astar.ts index a157eea2b5e5..3b4684841fc8 100644 --- a/packages/web3-providers/src/Web3/EVM/translators/Astar.ts +++ b/packages/web3-providers/src/Web3/EVM/translators/Astar.ts @@ -1,7 +1,7 @@ import { ChainId } from '@masknet/web3-shared-evm' import type { ConnectionContext } from '../libs/ConnectionContext.js' import { BaseTranslator } from './Base.js' -import defer * as web3_utils from 'web3-utils' +import { toHex } from '@masknet/shared-base' export class AstarTranslator extends BaseTranslator { override async encode(context: ConnectionContext): Promise { @@ -11,9 +11,9 @@ export class AstarTranslator extends BaseTranslator { context.config = { ...context.config, - maxFeePerGas: context.config.maxFeePerGas ? web3_utils.toHex(context.config.maxFeePerGas) : undefined, + maxFeePerGas: context.config.maxFeePerGas ? toHex(context.config.maxFeePerGas) : undefined, maxPriorityFeePerGas: - context.config.maxPriorityFeePerGas ? web3_utils.toHex(context.config.maxPriorityFeePerGas) : undefined, + context.config.maxPriorityFeePerGas ? toHex(context.config.maxPriorityFeePerGas) : undefined, // rpc hack, alchemy rpc must pass gas parameter gas: '0x135168', } diff --git a/packages/web3-providers/src/Web3/EVM/translators/Base.ts b/packages/web3-providers/src/Web3/EVM/translators/Base.ts index ee0974ce3353..41276fea34ff 100644 --- a/packages/web3-providers/src/Web3/EVM/translators/Base.ts +++ b/packages/web3-providers/src/Web3/EVM/translators/Base.ts @@ -1,10 +1,10 @@ import { BigNumber } from 'bignumber.js' -import defer * as web3_utils from 'web3-utils' import { GasOptionType, isLessThan, toFixed } from '@masknet/web3-shared-base' import { ChainId, formatWeiToGwei, PayloadEditor, ProviderType, type Translator } from '@masknet/web3-shared-evm' import type { ConnectionContext } from '../libs/ConnectionContext.js' import { EVMHub } from '../apis/HubAPI.js' import { EVMChainResolver } from '../apis/ResolverAPI.js' +import { toHex } from '@masknet/shared-base' export abstract class BaseTranslator implements Translator { async encode(context: ConnectionContext) { @@ -16,14 +16,13 @@ export abstract class BaseTranslator implements Translator { // add gas margin if (config.gas) { if (context.providerType !== ProviderType.MaskWallet) { - config.gas = web3_utils.toHex( - BigNumber.max( - web3_utils.toHex(config.gas), - context.chainId === ChainId.Optimism ? 25000 : 21000, - ).toFixed(), + config.gas = toHex( + BigNumber.max(toHex(config.gas), context.chainId === ChainId.Optimism ? 25000 : 21000).toFixed( + 0, + ), ) } else { - config.gas = web3_utils.toHex(config.gas) + config.gas = toHex(config.gas) } } @@ -47,17 +46,15 @@ export abstract class BaseTranslator implements Translator { slowOption.suggestedMaxPriorityFeePerGas, ) ) { - config.maxFeePerGas = web3_utils.toHex(toFixed(normalOption.suggestedMaxFeePerGas, 0)) - config.maxPriorityFeePerGas = web3_utils.toHex( - toFixed(normalOption.suggestedMaxPriorityFeePerGas, 0), - ) + config.maxFeePerGas = toHex(toFixed(normalOption.suggestedMaxFeePerGas, 0)) + config.maxPriorityFeePerGas = toHex(toFixed(normalOption.suggestedMaxPriorityFeePerGas, 0)) } } else { delete config.maxFeePerGas delete config.maxPriorityFeePerGas if (slowOption && normalOption && isLessThan(config.gasPrice ?? 0, slowOption.suggestedMaxFeePerGas)) { - config.gasPrice = web3_utils.toHex(toFixed(normalOption.suggestedMaxFeePerGas, 0)) + config.gasPrice = toHex(toFixed(normalOption.suggestedMaxFeePerGas, 0)) } } } catch (err) { @@ -70,12 +67,10 @@ export abstract class BaseTranslator implements Translator { context.config = { ...config, - maxFeePerGas: overrideMaxFeePerGas ? web3_utils.toHex(overrideMaxFeePerGas) : config.maxFeePerGas, + maxFeePerGas: overrideMaxFeePerGas ? toHex(overrideMaxFeePerGas) : config.maxFeePerGas, maxPriorityFeePerGas: - overrideMaxPriorityFeePerGas ? - web3_utils.toHex(overrideMaxPriorityFeePerGas) - : config.maxPriorityFeePerGas, - gasPrice: overrideGasPrice ? web3_utils.toHex(overrideGasPrice) : config.gasPrice, + overrideMaxPriorityFeePerGas ? toHex(overrideMaxPriorityFeePerGas) : config.maxPriorityFeePerGas, + gasPrice: overrideGasPrice ? toHex(overrideGasPrice) : config.gasPrice, } // #endregion } diff --git a/packages/web3-providers/src/Web3/Flow/apis/ResolverAPI.ts b/packages/web3-providers/src/Web3/Flow/apis/ResolverAPI.ts index 72254f824e33..1d032f03903b 100644 --- a/packages/web3-providers/src/Web3/Flow/apis/ResolverAPI.ts +++ b/packages/web3-providers/src/Web3/Flow/apis/ResolverAPI.ts @@ -1,7 +1,6 @@ -import { PROVIDER_DESCRIPTORS, NETWORK_DESCRIPTORS, CHAIN_DESCRIPTORS } from '@masknet/web3-shared-flow' +import { NETWORK_DESCRIPTORS, CHAIN_DESCRIPTORS } from '@masknet/web3-shared-flow' import { ChainResolver } from '../../Base/apis/ChainResolver.js' import { ExplorerResolver } from '../../Base/apis/ExplorerResolver.js' -import { ProviderResolver } from '../../Base/apis/ProviderResolver.js' import { NetworkResolver } from '../../Base/apis/NetworkExplorer.js' export const FlowChainResolver = new ChainResolver(() => CHAIN_DESCRIPTORS) @@ -11,5 +10,4 @@ export const FlowExplorerResolver = new ExplorerResolver(() => CHAIN_DESCRIPTORS fungibleTokenPathname: '/contract/:address', nonFungibleTokenPathname: '/contract/:address', }) -export const FlowProviderResolver = new ProviderResolver(() => PROVIDER_DESCRIPTORS) export const FlowNetworkResolver = new NetworkResolver(() => NETWORK_DESCRIPTORS) diff --git a/packages/web3-providers/src/Web3/Flow/apis/Utils.ts b/packages/web3-providers/src/Web3/Flow/apis/Utils.ts index aa20bf0d9b1f..6736b915f86f 100644 --- a/packages/web3-providers/src/Web3/Flow/apis/Utils.ts +++ b/packages/web3-providers/src/Web3/Flow/apis/Utils.ts @@ -1,56 +1,33 @@ -import { createFungibleToken, createNonFungibleToken, isSameAddress } from '@masknet/web3-shared-base' import { isValidDomain, isValidAddress, - isZeroAddress, isNativeTokenAddress, - isNativeTokenSchemaType, - isFungibleTokenSchemaType, - isNonFungibleTokenSchemaType, type ChainId, formatAddress, formatDomainName, - type ProviderType, type NetworkType, - type Transaction, type SchemaType, getDefaultChainId, - getInvalidChainId, - getDefaultNetworkType, - getDefaultProviderType, - getZeroAddress, getMaskTokenAddress, getNativeTokenAddress, formatSchemaType, formatTokenId, isValidChainId, - getNetworkPluginID, } from '@masknet/web3-shared-flow' import { type BaseUtils } from '../../Base/apis/Utils.js' -import { FlowChainResolver, FlowExplorerResolver, FlowProviderResolver, FlowNetworkResolver } from './ResolverAPI.js' +import { FlowChainResolver, FlowExplorerResolver, FlowNetworkResolver } from './ResolverAPI.js' export const FlowUtils = { - isSameAddress, chainResolver: FlowChainResolver, explorerResolver: FlowExplorerResolver, - providerResolver: FlowProviderResolver, networkResolver: FlowNetworkResolver, isValidDomain, isValidChainId, isValidAddress, - isZeroAddress, isNativeTokenAddress, - isNativeTokenSchemaType, - isFungibleTokenSchemaType, - isNonFungibleTokenSchemaType, - getNetworkPluginID, getDefaultChainId, - getInvalidChainId, - getDefaultNetworkType, - getDefaultProviderType, - getZeroAddress, getNativeTokenAddress, getMaskTokenAddress, @@ -58,9 +35,4 @@ export const FlowUtils = { formatDomainName, formatTokenId, formatSchemaType, - createNativeToken(chainId: ChainId) { - return FlowChainResolver.nativeCurrency(chainId) - }, - createFungibleToken, - createNonFungibleToken, -} satisfies BaseUtils +} satisfies BaseUtils diff --git a/packages/web3-providers/src/Web3/Router/types/index.ts b/packages/web3-providers/src/Web3/Router/types/index.ts index 78d5e82524de..16ad2cc49879 100644 --- a/packages/web3-providers/src/Web3/Router/types/index.ts +++ b/packages/web3-providers/src/Web3/Router/types/index.ts @@ -60,7 +60,5 @@ export interface Utils extends BaseUtils< Web3Helper.Definition[T]['ChainId'], Web3Helper.Definition[T]['SchemaType'], - Web3Helper.Definition[T]['ProviderType'], - Web3Helper.Definition[T]['NetworkType'], - Web3Helper.Definition[T]['Transaction'] + Web3Helper.Definition[T]['NetworkType'] > {} diff --git a/packages/web3-providers/src/Web3/Solana/apis/ResolverAPI.ts b/packages/web3-providers/src/Web3/Solana/apis/ResolverAPI.ts index 75fd5d873880..c5e32907f7f5 100644 --- a/packages/web3-providers/src/Web3/Solana/apis/ResolverAPI.ts +++ b/packages/web3-providers/src/Web3/Solana/apis/ResolverAPI.ts @@ -1,10 +1,8 @@ -import { PROVIDER_DESCRIPTORS, NETWORK_DESCRIPTORS, CHAIN_DESCRIPTORS } from '@masknet/web3-shared-solana' +import { NETWORK_DESCRIPTORS, CHAIN_DESCRIPTORS } from '@masknet/web3-shared-solana' import { ChainResolver } from '../../Base/apis/ChainResolver.js' import { ExplorerResolver } from '../../Base/apis/ExplorerResolver.js' -import { ProviderResolver } from '../../Base/apis/ProviderResolver.js' import { NetworkResolver } from '../../Base/apis/NetworkExplorer.js' export const SolanaChainResolver = new ChainResolver(() => CHAIN_DESCRIPTORS) export const SolanaExplorerResolver = new ExplorerResolver(() => CHAIN_DESCRIPTORS) -export const SolanaProviderResolver = new ProviderResolver(() => PROVIDER_DESCRIPTORS) export const SolanaNetworkResolver = new NetworkResolver(() => NETWORK_DESCRIPTORS) diff --git a/packages/web3-providers/src/Web3/Solana/apis/Utils.ts b/packages/web3-providers/src/Web3/Solana/apis/Utils.ts index 4afbf3da7f98..d609f94e5f3f 100644 --- a/packages/web3-providers/src/Web3/Solana/apis/Utils.ts +++ b/packages/web3-providers/src/Web3/Solana/apis/Utils.ts @@ -2,11 +2,7 @@ import { formatDomainName } from '@masknet/web3-shared-evm' import { isValidDomain, isValidAddress, - isZeroAddress, isNativeTokenAddress, - isNativeTokenSchemaType, - isFungibleTokenSchemaType, - isNonFungibleTokenSchemaType, type ChainId, type ProviderType, type NetworkType, @@ -14,49 +10,26 @@ import { type SchemaType, formatAddress, formatTokenId, - getNetworkPluginID, getDefaultChainId, - getInvalidChainId, - getDefaultNetworkType, - getDefaultProviderType, - getZeroAddress, getMaskTokenAddress, getNativeTokenAddress, formatSchemaType, isValidChainId, } from '@masknet/web3-shared-solana' -import { createFungibleToken, createNonFungibleToken, isSameAddress } from '@masknet/web3-shared-base' import { type BaseUtils } from '../../Base/apis/Utils.js' -import { - SolanaChainResolver, - SolanaExplorerResolver, - SolanaProviderResolver, - SolanaNetworkResolver, -} from './ResolverAPI.js' +import { SolanaChainResolver, SolanaExplorerResolver, SolanaNetworkResolver } from './ResolverAPI.js' export const SolanaUtils = { - isSameAddress, chainResolver: SolanaChainResolver, explorerResolver: SolanaExplorerResolver, - providerResolver: SolanaProviderResolver, networkResolver: SolanaNetworkResolver, isValidDomain, isValidChainId, isValidAddress, - isZeroAddress, isNativeTokenAddress, - isNativeTokenSchemaType, - isFungibleTokenSchemaType, - isNonFungibleTokenSchemaType, - - getNetworkPluginID, getDefaultChainId, - getInvalidChainId, - getDefaultNetworkType, - getDefaultProviderType, - getZeroAddress, getMaskTokenAddress, getNativeTokenAddress, @@ -64,9 +37,4 @@ export const SolanaUtils = { formatDomainName, formatTokenId, formatSchemaType, - createNativeToken(chainId: ChainId) { - return SolanaChainResolver.nativeCurrency(chainId) - }, - createFungibleToken, - createNonFungibleToken, -} satisfies BaseUtils +} satisfies BaseUtils diff --git a/packages/web3-providers/src/helpers/fetchJsonRpcResponse.ts b/packages/web3-providers/src/helpers/fetchJsonRpcResponse.ts index f4275229bb6e..2a6a9cd90631 100644 --- a/packages/web3-providers/src/helpers/fetchJsonRpcResponse.ts +++ b/packages/web3-providers/src/helpers/fetchJsonRpcResponse.ts @@ -1,11 +1,11 @@ import type { JsonRpcRequest, JsonRpcResponse } from 'web3-types' -import { RequestID } from '@masknet/web3-shared-evm' import { fetchSquashedJSON } from './fetchJSON.js' +import stringify from 'json-stable-stringify' async function resolveRequestKey(request: Request) { try { const body: JsonRpcRequest = await request.json() - return RequestID.fromPayload(request.url, body).ID ?? '' + return stringify([request.url, body.method, body.params]) } catch { return '' } diff --git a/packages/web3-shared/evm/src/helpers/address.ts b/packages/web3-shared/evm/src/helpers/address.ts index 11aa9bd584de..1a16d00e75d0 100644 --- a/packages/web3-shared/evm/src/helpers/address.ts +++ b/packages/web3-shared/evm/src/helpers/address.ts @@ -1,5 +1,4 @@ import { memoize } from 'lodash-es' -import defer * as web3_utils from 'web3-utils' import { isSameAddress } from '@masknet/web3-shared-base' import { ChainIdList, @@ -12,24 +11,19 @@ import { ZERO_ADDRESS, } from '../constants/index.js' import { ChainId } from '../types/index.js' +import { isAddress, type Hex } from 'viem' -export function checksumAddress(address: string) { - return web3_utils.toChecksumAddress(address) -} +export { getAddress as checksumAddress } from 'viem' export function isEmptyHex(hex?: string): hex is undefined { return !hex || ['0x', '0x0'].includes(hex) } -export function isZeroString(str?: string): str is undefined { - return !str || str === '0' -} - export const isValidAddress: (address?: string) => address is string = memoize(function isValidAddress( address?: string, -): address is string { +): address is Hex { if (!address) return false - return web3_utils.isAddress(address) + return isAddress(address) }) export function isZeroAddress(address?: string): address is '0x0000000000000000000000000000000000000000' { @@ -70,10 +64,6 @@ export function isRedPacketAddress(address: string, version?: 1 | 2 | 3 | 4) { } } -export function getZeroAddress() { - return ZERO_ADDRESS -} - export const getNativeTokenAddress: (chainId: ChainId) => string = memoize((chainId = ChainId.Mainnet) => { return getTokenConstant(chainId, 'NATIVE_TOKEN_ADDRESS') ?? ZERO_ADDRESS }) diff --git a/packages/web3-shared/evm/src/helpers/createContract.ts b/packages/web3-shared/evm/src/helpers/createContract.ts index 52022ed1c376..99933a14b810 100644 --- a/packages/web3-shared/evm/src/helpers/createContract.ts +++ b/packages/web3-shared/evm/src/helpers/createContract.ts @@ -1,15 +1,15 @@ -import type { AbiItem } from 'web3-utils' import type { ContractOptions } from 'web3-eth-contract' import type { BaseContract } from '@masknet/web3-contracts/types/types.js' import { isValidAddress } from './address.js' import type { Web3 } from '../libs/index.js' +import { type Abi } from 'viem' export function createContract( web3: Web3 | null, address: string | undefined, - ABI: AbiItem[], + abi: Abi, options?: ContractOptions, ) { if (!address || !isValidAddress(address) || !web3) return null - return new web3.eth.Contract(ABI, address, options) as unknown as T + return new web3.eth.Contract(abi as any, address, options) as unknown as T } diff --git a/packages/web3-shared/evm/src/helpers/getTransactionSignature.ts b/packages/web3-shared/evm/src/helpers/getTransactionSignature.ts deleted file mode 100644 index 0ebdb70650d3..000000000000 --- a/packages/web3-shared/evm/src/helpers/getTransactionSignature.ts +++ /dev/null @@ -1,12 +0,0 @@ -import defer * as web3_utils from 'web3-utils' -import type { Transaction, ChainId } from '../types/index.js' - -export function getTransactionSignature(chainId?: ChainId, transaction?: Partial) { - if (!chainId || !transaction) return - const { from, to, data, value } = transaction - return ( - web3_utils.sha3( - [chainId, from, to, data || '0x0', web3_utils.toHex((value as string) || '0x0') || '0x0'].join('_'), - ) ?? undefined - ) -} diff --git a/packages/web3-shared/evm/src/helpers/pack.ts b/packages/web3-shared/evm/src/helpers/pack.ts deleted file mode 100644 index 84140a314767..000000000000 --- a/packages/web3-shared/evm/src/helpers/pack.ts +++ /dev/null @@ -1,31 +0,0 @@ -import defer * as web3_utils from 'web3-utils' - -export function pack(types: string[], values: any[]) { - if (types.length !== values.length) { - throw new Error('Number of types does not match number of values.') - } - - let result = '0x' - - for (let i = 0; i < types.length; i += 1) { - switch (types[i]) { - case 'address': - result += values[i].slice(2).padStart(40, '0') - break - case 'uint256': - result += BigInt(values[i]).toString(16).padStart(64, '0') - break - case 'bytes32': - result += web3_utils.utf8ToHex(values[i]).slice(2).padStart(64, '0') - break - case 'bool': - result += values[i] ? '01' : '00' - break - // ... you can continue adding more cases for other data types - default: - throw new Error(`Unsupported type ${types[i]}`) - } - } - - return result -} diff --git a/packages/web3-shared/evm/src/helpers/parseStringOrBytes32.ts b/packages/web3-shared/evm/src/helpers/parseStringOrBytes32.ts index c614b709123d..c442e2d7e463 100644 --- a/packages/web3-shared/evm/src/helpers/parseStringOrBytes32.ts +++ b/packages/web3-shared/evm/src/helpers/parseStringOrBytes32.ts @@ -1,18 +1,13 @@ -import defer * as web3_utils from 'web3-utils' +import { hexToBytes, type Hex, hexToString } from 'viem' // parse a name or symbol from a token response const BYTES32_REGEX = /^0x[\dA-Fa-f]{64}$/u -export function parseStringOrBytes32( - str: string | undefined, - bytes32: string | undefined, - defaultValue: string, -): string { +export function parseStringOrBytes32(str: string | undefined, bytes32: Hex | undefined, defaultValue: string): string { return ( str && str.length > 0 ? str // need to check for proper bytes string and valid terminator - : bytes32 && BYTES32_REGEX.test(bytes32) && web3_utils.hexToBytes(bytes32)[31] === 0 ? - web3_utils.toAscii(bytes32) - : defaultValue + : bytes32 && BYTES32_REGEX.test(bytes32) && hexToBytes(bytes32)[31] === 0 ? hexToString(bytes32) + : defaultValue ) } diff --git a/packages/web3-shared/evm/src/helpers/resolveNonFungibleTokenIdFromEnsDomain.ts b/packages/web3-shared/evm/src/helpers/resolveNonFungibleTokenIdFromEnsDomain.ts index 58630fc8fc1f..945ed7d80c87 100644 --- a/packages/web3-shared/evm/src/helpers/resolveNonFungibleTokenIdFromEnsDomain.ts +++ b/packages/web3-shared/evm/src/helpers/resolveNonFungibleTokenIdFromEnsDomain.ts @@ -1,6 +1,5 @@ -import defer * as web3_utils from 'web3-utils' -import { BigNumber } from 'bignumber.js' +import { keccak256, type Hex } from 'viem' export function resolveNonFungibleTokenIdFromEnsDomain(domain: string): string { - return new BigNumber(web3_utils.keccak256(domain.replace(/\.\w+$/u, ''))).toFixed() + return BigInt(keccak256(domain.replace(/\.\w+$/u, '') as Hex)).toString() } diff --git a/packages/web3-shared/evm/src/helpers/splitSignature.ts b/packages/web3-shared/evm/src/helpers/splitSignature.ts index 8d48381dbf69..b71bdc96663c 100644 --- a/packages/web3-shared/evm/src/helpers/splitSignature.ts +++ b/packages/web3-shared/evm/src/helpers/splitSignature.ts @@ -1,4 +1,4 @@ -import defer * as web3_utils from 'web3-utils' +import { hexToNumber } from 'viem' export function splitSignature(signature: string) { if (signature.length !== 132 && !signature.startsWith('0x')) { @@ -8,7 +8,7 @@ export function splitSignature(signature: string) { // Extracting r, s, v from the signature const r = signature.slice(0, 66) const s = '0x' + signature.slice(66, 130) - const v = web3_utils.toDecimal('0x' + signature.slice(130, 132)) + const v = hexToNumber(`0x${signature.slice(130, 132)}`) return { r, s, v } } diff --git a/packages/web3-shared/evm/src/helpers/token.ts b/packages/web3-shared/evm/src/helpers/token.ts index 453df243a6bf..885b117b5074 100644 --- a/packages/web3-shared/evm/src/helpers/token.ts +++ b/packages/web3-shared/evm/src/helpers/token.ts @@ -34,15 +34,3 @@ export const createERC20Tokens = createFungibleTokensFromConstants { - // fix an abnormal hex value like: 0x02c68af0bb140000 - if (typeof value === 'string' && value.length > 3 && value.startsWith('0x0')) - return web3_utils.toHex(new BigNumber(value).toFixed()) - return web3_utils.toHex(value) -}) +import { toHex } from '@masknet/shared-base' export class AccountTransaction { constructor(private transaction?: Transaction) {} @@ -68,12 +60,12 @@ export class AccountTransaction { from, to, data, - value: value ? normalizeHex(value) : undefined, - chainId: chainId && chainId !== ChainId.Astar ? normalizeHex(chainId) : undefined, - gas: gas ? normalizeHex(gas) : undefined, - gasPrice: gasPrice ? normalizeHex(gasPrice) : undefined, - maxPriorityFeePerGas: maxPriorityFeePerGas ? normalizeHex(maxPriorityFeePerGas) : undefined, - maxFeePerGas: maxFeePerGas ? normalizeHex(maxFeePerGas) : undefined, + value: value ? toHex(value) : undefined, + chainId: chainId && chainId !== ChainId.Astar ? toHex(chainId) : undefined, + gas: gas ? toHex(gas) : undefined, + gasPrice: gasPrice ? toHex(gasPrice) : undefined, + maxPriorityFeePerGas: maxPriorityFeePerGas ? toHex(maxPriorityFeePerGas) : undefined, + maxFeePerGas: maxFeePerGas ? toHex(maxFeePerGas) : undefined, nonce, _disableSuccessSnackbar, _disableSnackbar, diff --git a/packages/web3-shared/evm/src/libs/ContractTransaction.ts b/packages/web3-shared/evm/src/libs/ContractTransaction.ts index 964fad25a964..c2ae605e8a0f 100644 --- a/packages/web3-shared/evm/src/libs/ContractTransaction.ts +++ b/packages/web3-shared/evm/src/libs/ContractTransaction.ts @@ -1,6 +1,5 @@ import { identity, pickBy } from 'lodash-es' -import defer * as web3_utils from 'web3-utils' -import { type Unresolved, resolve } from '@masknet/shared-base' +import { type Unresolved, resolve, toHex } from '@masknet/shared-base' import type { BaseContract, PayableTx, @@ -31,14 +30,14 @@ export class ContractTransaction { from: overrides?.from ?? this.contract?.defaultAccount ?? this.contract?.options.from ?? '', to: this.contract?.options.address, data: transaction?.encodeABI(), - value: overrides?.value ? web3_utils.toHex(overrides.value) : undefined, - gas: overrides?.gas ? web3_utils.toHex(overrides.gas) : undefined, - gasPrice: overrides?.gasPrice ? web3_utils.toHex(overrides.gasPrice) : undefined, + value: overrides?.value ? toHex(overrides.value) : undefined, + gas: overrides?.gas ? toHex(overrides.gas) : undefined, + gasPrice: overrides?.gasPrice ? toHex(overrides.gasPrice) : undefined, maxPriorityFeePerGas: - overrides?.maxPriorityFeePerGas ? web3_utils.toHex(overrides.maxPriorityFeePerGas) : undefined, - maxFeePerGas: overrides?.maxFeePerGas ? web3_utils.toHex(overrides.maxFeePerGas) : undefined, - nonce: overrides?.nonce ? web3_utils.toHex(overrides.nonce) : undefined, - chainId: overrides?.chainId ? web3_utils.toHex(overrides.chainId) : undefined, + overrides?.maxPriorityFeePerGas ? toHex(overrides.maxPriorityFeePerGas) : undefined, + maxFeePerGas: overrides?.maxFeePerGas ? toHex(overrides.maxFeePerGas) : undefined, + nonce: overrides?.nonce ? toHex(overrides.nonce) : undefined, + chainId: overrides?.chainId ? toHex(overrides.chainId) : undefined, }, identity, ) @@ -65,7 +64,7 @@ export class ContractTransaction { if (!gas) throw new Error('Estimate gas failed') - transactionEncoded.gas = web3_utils.toHex(gas) + transactionEncoded.gas = toHex(gas) } return transactionEncoded diff --git a/packages/web3-shared/evm/src/libs/GasEditor.ts b/packages/web3-shared/evm/src/libs/GasEditor.ts index ce670c94950d..4c3449742639 100644 --- a/packages/web3-shared/evm/src/libs/GasEditor.ts +++ b/packages/web3-shared/evm/src/libs/GasEditor.ts @@ -1,4 +1,3 @@ -import defer * as web3_utils from 'web3-utils' import { GasOptionType, isZero, multipliedBy, toFixed } from '@masknet/web3-shared-base' import { formatWeiToEther } from '../helpers/formatter.js' import type { @@ -10,6 +9,7 @@ import type { Transaction, } from '../types/index.js' import { CHAIN_DESCRIPTORS } from '../constants/descriptors.js' +import { toHex } from '@masknet/shared-base' export class GasEditor { constructor( @@ -46,16 +46,14 @@ export class GasEditor { const config = fallback as EIP1559GasConfig | undefined return { gasPrice: undefined, - maxFeePerGas: - web3_utils.toHex(this.EIP1559GasOptionConfig.maxFeePerGas) || - web3_utils.toHex(config?.maxFeePerGas || '0'), + maxFeePerGas: toHex(this.EIP1559GasOptionConfig.maxFeePerGas) || toHex(config?.maxFeePerGas || '0'), maxPriorityFeePerGas: - web3_utils.toHex(this.EIP1559GasOptionConfig.maxPriorityFeePerGas) || - web3_utils.toHex(config?.maxPriorityFeePerGas || '1'), + toHex(this.EIP1559GasOptionConfig.maxPriorityFeePerGas) || + toHex(config?.maxPriorityFeePerGas || '1'), gasCurrency: this.EIP1559GasOptionConfig.gasCurrency || fallback?.gasCurrency, gas: this.EIP1559GasOptionConfig.gas && !isZero(this.EIP1559GasOptionConfig.gas) ? - web3_utils.toHex(this.EIP1559GasOptionConfig.gas) + toHex(this.EIP1559GasOptionConfig.gas) : undefined, gasOptionType: this.config.gasOptionType ?? config?.gasOptionType, } @@ -64,9 +62,7 @@ export class GasEditor { const priorConfig = fallback as PriorEIP1559GasConfig | undefined return { - gasPrice: - web3_utils.toHex(this.priorEIP1559GasOptionConfig.gasPrice) || - web3_utils.toHex(priorConfig?.gasPrice || '0'), + gasPrice: toHex(this.priorEIP1559GasOptionConfig.gasPrice) || toHex(priorConfig?.gasPrice || '0'), maxFeePerGas: undefined, maxPriorityFeePerGas: undefined, gasOptionType: this.config.gasOptionType ?? priorConfig?.gasOptionType, diff --git a/packages/web3-shared/evm/src/libs/RequestID.ts b/packages/web3-shared/evm/src/libs/RequestID.ts deleted file mode 100644 index cfba53191dc5..000000000000 --- a/packages/web3-shared/evm/src/libs/RequestID.ts +++ /dev/null @@ -1,75 +0,0 @@ -import defer * as web3_utils from 'web3-utils' -import type { TransactionConfig } from 'web3-core' -import type { JsonRpcRequest } from 'web3-types' -import { EthereumMethodType, type RequestArguments } from '../types/index.js' - -export class RequestID { - /** - * @deprecated Don't new RequestID() - * Use RequestID.from(requestArguments) stead. - */ - constructor( - private url: string, - private requestArguments: RequestArguments, - ) {} - - get ID() { - const { method, params } = this.requestArguments - switch (method) { - case EthereumMethodType.eth_getCode: { - const [address, tag = 'latest'] = params as [string, string] - return web3_utils.sha3([this.url, method, address, tag].join(',')) - } - case EthereumMethodType.eth_blockNumber: { - return web3_utils.sha3([this.url, method].join(',')) - } - case EthereumMethodType.eth_getBlockByNumber: { - const [number, full] = params as [string, boolean] - return web3_utils.sha3([this.url, method, number, full].join(',')) - } - case EthereumMethodType.eth_getBlockByHash: { - const [hash] = params as [string] - return web3_utils.sha3([this.url, method, hash].join(',')) - } - case EthereumMethodType.eth_gasPrice: { - return web3_utils.sha3([this.url, method].join(',')) - } - case EthereumMethodType.eth_getBalance: { - const [account, tag = 'latest'] = params as [string, string] - return web3_utils.sha3([this.url, method, account, tag].join(',')) - } - case EthereumMethodType.eth_getTransactionCount: { - const [account, tag = 'latest'] = params as [string, string] - return web3_utils.sha3([this.url, method, account, tag].join(',')) - } - case EthereumMethodType.eth_call: { - const [config, tag = 'latest'] = params as [TransactionConfig, string] - return web3_utils.sha3([this.url, method, JSON.stringify(config), tag].join(',')) - } - case EthereumMethodType.eth_estimateGas: { - const [config, tag = 'latest'] = params as [TransactionConfig, string] - return web3_utils.sha3([this.url, method, JSON.stringify(config), tag].join(',')) - } - case EthereumMethodType.eth_getTransactionReceipt: { - const [hash] = params as [string] - return web3_utils.sha3([this.url, method, hash].join(',')) - } - case EthereumMethodType.eth_getTransactionByHash: - const [hash] = params as [string] - return web3_utils.sha3([this.url, method, hash].join(',')) - default: - return - } - } - - static from(url: string, requestArguments: RequestArguments) { - return new RequestID(url, requestArguments) - } - - static fromPayload(url: string, payload: JsonRpcRequest) { - return new RequestID(url, { - method: payload.method as EthereumMethodType, - params: payload.params ?? [], - }) - } -} diff --git a/packages/web3-shared/evm/src/libs/index.ts b/packages/web3-shared/evm/src/libs/index.ts index a8b5ba6e1c2b..e6141ae8286e 100644 --- a/packages/web3-shared/evm/src/libs/index.ts +++ b/packages/web3-shared/evm/src/libs/index.ts @@ -7,5 +7,4 @@ export * from './EtherscanURL.js' export * from './GasEditor.js' export * from './PayloadEditor.js' export * from './ProviderURL.js' -export * from './RequestID.js' export * from './Web3.js' diff --git a/packages/web3-shared/evm/tests/helpers/pack.ts b/packages/web3-shared/evm/tests/helpers/pack.ts deleted file mode 100644 index 42da27ff241c..000000000000 --- a/packages/web3-shared/evm/tests/helpers/pack.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { describe, expect, test } from 'vitest' -import { pack } from '../../src/helpers/pack.js' - -const ADDRESS = '0x1234567890123456789012345678901234567890' -const UINT256 = 1 - -const ADDRESS_PACKED = '0x12345678901234567890123456789012345678901234567890123456789012345678901234567890' -const ADDRESS_UINT256_PACKED = - '0x12345678901234567890123456789012345678900000000000000000000000000000000000000000000000000000000000000001' - -describe('pack', () => { - test('should pack address', () => { - expect(pack(['address', 'address'], [ADDRESS, ADDRESS])).toBe(ADDRESS_PACKED) - }) - - test('should pack unit256', () => { - expect(pack(['address', 'uint256'], [ADDRESS, UINT256])).toBe(ADDRESS_UINT256_PACKED) - }) -}) diff --git a/packages/web3-shared/flow/src/helpers/address.ts b/packages/web3-shared/flow/src/helpers/address.ts index 9b69a80e2049..e7aefb70b734 100644 --- a/packages/web3-shared/flow/src/helpers/address.ts +++ b/packages/web3-shared/flow/src/helpers/address.ts @@ -56,10 +56,6 @@ export function getDefaultProviderType() { return ProviderType.None } -export function getZeroAddress() { - return ZERO_ADDRESS -} - export function getContractAddress(address: string) { if (isValidContractAddress(address)) { const [_, contractAddress, ...identifierFragments] = address.split(/\./gu) diff --git a/packages/web3-shared/flow/src/helpers/token.ts b/packages/web3-shared/flow/src/helpers/token.ts index 62a1230fae54..df3630e57aed 100644 --- a/packages/web3-shared/flow/src/helpers/token.ts +++ b/packages/web3-shared/flow/src/helpers/token.ts @@ -43,16 +43,3 @@ export function createFungibleAsset( }, } } - -export function isNativeTokenSchemaType(schemaType?: SchemaType) { - // there is no native token schema on flow network - return false -} - -export function isFungibleTokenSchemaType(schemaType?: SchemaType) { - return schemaType === SchemaType.Fungible -} - -export function isNonFungibleTokenSchemaType(schemaType?: SchemaType) { - return schemaType === SchemaType.NonFungible -} diff --git a/packages/web3-shared/solana/src/helpers/address.ts b/packages/web3-shared/solana/src/helpers/address.ts index 2579991d81c3..8fa6e9cfb6ed 100644 --- a/packages/web3-shared/solana/src/helpers/address.ts +++ b/packages/web3-shared/solana/src/helpers/address.ts @@ -86,10 +86,6 @@ export function getDefaultProviderType() { return ProviderType.None } -export function getZeroAddress() { - return ZERO_ADDRESS -} - export function getMaskTokenAddress(chainId = ChainId.Mainnet) { return '' } diff --git a/packages/web3-shared/solana/src/helpers/token.ts b/packages/web3-shared/solana/src/helpers/token.ts deleted file mode 100644 index ba16d6c0895d..000000000000 --- a/packages/web3-shared/solana/src/helpers/token.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { SchemaType } from '../types.js' - -export function isNativeTokenSchemaType(schemaType?: SchemaType) { - // there is no native token schema on solana network - return false -} - -export function isFungibleTokenSchemaType(schemaType?: SchemaType) { - return schemaType === SchemaType.Fungible -} - -export function isNonFungibleTokenSchemaType(schemaType?: SchemaType) { - return schemaType === SchemaType.NonFungible -} diff --git a/packages/web3-shared/solana/src/index.ts b/packages/web3-shared/solana/src/index.ts index 0f453320c7bb..c494421cc9b7 100644 --- a/packages/web3-shared/solana/src/index.ts +++ b/packages/web3-shared/solana/src/index.ts @@ -6,7 +6,6 @@ export * from './constants/descriptors.js' export * from './constants/primitives.js' export * from './helpers/address.js' -export * from './helpers/token.js' export * from './helpers/domain.js' export * from './helpers/serializeTransaction.js' export * from './helpers/recoverTransaction.js' diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 049b437e62d2..044000a939f1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2833,6 +2833,9 @@ importers: immer: specifier: ^10.1.1 version: 10.1.1 + json-stable-stringify: + specifier: ^1.1.1 + version: 1.1.1 lru-cache: specifier: ^10.3.0 version: 10.3.0 @@ -2879,6 +2882,9 @@ importers: '@types/bs58': specifier: ^4.0.4 version: 4.0.4 + '@types/json-stable-stringify': + specifier: ^1.0.36 + version: 1.0.36 '@types/socket.io-client': specifier: ^1.4.36 version: 1.4.36 From 256d7bbd49d408ca4900aa6552a6328269ec2a74 Mon Sep 17 00:00:00 2001 From: Jack-Works Date: Wed, 25 Mar 2026 05:58:49 +0000 Subject: [PATCH 3/3] fix: eslint --- packages/web3-providers/src/Web3/Solana/apis/Utils.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/web3-providers/src/Web3/Solana/apis/Utils.ts b/packages/web3-providers/src/Web3/Solana/apis/Utils.ts index d609f94e5f3f..14ea80997e01 100644 --- a/packages/web3-providers/src/Web3/Solana/apis/Utils.ts +++ b/packages/web3-providers/src/Web3/Solana/apis/Utils.ts @@ -4,9 +4,7 @@ import { isValidAddress, isNativeTokenAddress, type ChainId, - type ProviderType, type NetworkType, - type Transaction, type SchemaType, formatAddress, formatTokenId,