diff --git a/packages/mask/src/extension/popups/pages/Wallet/ContractInteraction/index.tsx b/packages/mask/src/extension/popups/pages/Wallet/ContractInteraction/index.tsx
index 1f1b915f7a3d..b3d8ffcf90dc 100644
--- a/packages/mask/src/extension/popups/pages/Wallet/ContractInteraction/index.tsx
+++ b/packages/mask/src/extension/popups/pages/Wallet/ContractInteraction/index.tsx
@@ -181,7 +181,7 @@ const ContractInteraction = memo(() => {
for (const method of methods) {
const parameters = method.parameters
- if (method.name === 'approve' && parameters?.value) {
+ if (method.name === 'approve' || method.name === 'setApprovalForAll') {
return {
isNativeTokenInteraction: false,
typeName: request.formatterTransaction?.title,
diff --git a/packages/plugins/Debugger/src/SNSAdaptor/components/ConsoleContent.tsx b/packages/plugins/Debugger/src/SNSAdaptor/components/ConsoleContent.tsx
index c9e158ea9ec3..c94174ec8b38 100644
--- a/packages/plugins/Debugger/src/SNSAdaptor/components/ConsoleContent.tsx
+++ b/packages/plugins/Debugger/src/SNSAdaptor/components/ConsoleContent.tsx
@@ -61,6 +61,7 @@ export function ConsoleContent(props: ConsoleContentProps) {
const { value: balance = '0' } = useBalance()
const { value: blockNumber = 0 } = useBlockNumber()
const { value: blockTimestamp = 0 } = useBlockTimestamp()
+
const onTransferCallback = useCallback(() => {
if (!NATIVE_TOKEN_ADDRESS) return
return connection.transferFungibleToken(
@@ -70,6 +71,26 @@ export function ConsoleContent(props: ConsoleContentProps) {
)
}, [connection])
+ const onApproveFungibleTokenCallback = useCallback(() => {
+ if (pluginID !== NetworkPluginID.PLUGIN_EVM) return
+ if (chainId !== ChainId.Mainnet) return
+ return connection.approveFungibleToken(
+ '0x6B175474E89094C44Da98b954EedeAC495271d0F',
+ '0x31f42841c2db5173425b5223809cf3a38fede360',
+ '1',
+ )
+ }, [pluginID, connection])
+
+ const onApproveNonFungibleTokenCallback = useCallback(() => {
+ if (pluginID !== NetworkPluginID.PLUGIN_EVM) return
+ if (chainId !== ChainId.Mainnet) return
+ return connection.approveNonFungibleToken(
+ '0xd945f759d422ae30a6166838317b937de08380e3',
+ '0x31f42841c2db5173425b5223809cf3a38fede360',
+ '71050',
+ )
+ }, [pluginID, connection])
+
const onSignMessage = useCallback(
async (type?: string) => {
const message = 'Hello World'
@@ -210,6 +231,30 @@ export function ConsoleContent(props: ConsoleContentProps) {
+
+
+
+ Approve Fungible Token
+
+
+
+
+
+
+
+
+
+ Approve Non-Fungible Token
+
+
+
+
+
+
diff --git a/packages/plugins/EVM/src/state/Connection/connection.ts b/packages/plugins/EVM/src/state/Connection/connection.ts
index cd439da4730d..56f6d443bbb8 100644
--- a/packages/plugins/EVM/src/state/Connection/connection.ts
+++ b/packages/plugins/EVM/src/state/Connection/connection.ts
@@ -337,26 +337,30 @@ class Connection implements EVM_Connection {
const ERC721_ENUMERABLE_INTERFACE_ID = '0x780e9d63'
const ERC1155_ENUMERABLE_INTERFACE_ID = '0xd9b67a26'
- const erc165Contract = await this.getWeb3Contract(address, ERC165ABI as AbiItem[], options)
+ try {
+ const erc165Contract = await this.getWeb3Contract(address, ERC165ABI as AbiItem[], options)
- const isERC165 = await erc165Contract?.methods
- .supportsInterface(ERC165_INTERFACE_ID)
- .call({ from: options.account })
+ const isERC165 = await erc165Contract?.methods
+ .supportsInterface(ERC165_INTERFACE_ID)
+ .call({ from: options.account })
- const isERC721 = await erc165Contract?.methods
- .supportsInterface(ERC721_ENUMERABLE_INTERFACE_ID)
- .call({ from: options.account })
- if (isERC165 && isERC721) return SchemaType.ERC721
+ const isERC721 = await erc165Contract?.methods
+ .supportsInterface(ERC721_ENUMERABLE_INTERFACE_ID)
+ .call({ from: options.account })
+ if (isERC165 && isERC721) return SchemaType.ERC721
- const isERC1155 = await erc165Contract?.methods
- .supportsInterface(ERC1155_ENUMERABLE_INTERFACE_ID)
- .call({ from: options.account })
- if (isERC165 && isERC1155) return SchemaType.ERC1155
+ const isERC1155 = await erc165Contract?.methods
+ .supportsInterface(ERC1155_ENUMERABLE_INTERFACE_ID)
+ .call({ from: options.account })
+ if (isERC165 && isERC1155) return SchemaType.ERC1155
- const isERC20 = (await this.getCode(address, options)) !== '0x'
- if (isERC20) return SchemaType.ERC20
+ const isERC20 = (await this.getCode(address, options)) !== '0x'
+ if (isERC20) return SchemaType.ERC20
- return
+ return
+ } catch {
+ return
+ }
}
async getNonFungibleToken(
address: string,
diff --git a/packages/plugins/EVM/src/state/TransactionFormatter/descriptors/ERC20.ts b/packages/plugins/EVM/src/state/TransactionFormatter/descriptors/ERC20.ts
index cd6a08c79c1d..6ce497bb421d 100644
--- a/packages/plugins/EVM/src/state/TransactionFormatter/descriptors/ERC20.ts
+++ b/packages/plugins/EVM/src/state/TransactionFormatter/descriptors/ERC20.ts
@@ -14,6 +14,7 @@ export class ERC20Descriptor implements TransactionDescriptor {
})
for (const method of context.methods) {
const parameters = method.parameters
+
switch (method.name) {
case 'approve':
if (parameters?.spender === undefined || parameters?.value === undefined) break
diff --git a/packages/plugins/EVM/src/state/TransactionFormatter/descriptors/ERC721.ts b/packages/plugins/EVM/src/state/TransactionFormatter/descriptors/ERC721.ts
index bcbf4dea0356..71e6cb0eb5cf 100644
--- a/packages/plugins/EVM/src/state/TransactionFormatter/descriptors/ERC721.ts
+++ b/packages/plugins/EVM/src/state/TransactionFormatter/descriptors/ERC721.ts
@@ -1,8 +1,17 @@
import type { TransactionContext } from '@masknet/web3-shared-base'
import type { ChainId, TransactionParameter } from '@masknet/web3-shared-evm'
+import { Web3StateSettings } from '../../../settings'
import type { TransactionDescriptor } from '../types'
export class ERC721Descriptor implements TransactionDescriptor {
+ async getContractSymbol(chainId: ChainId, address: string) {
+ const connection = await Web3StateSettings.value.Connection?.getConnection?.({
+ chainId: chainId,
+ })
+ const contract = await connection?.getNonFungibleTokenContract(address)
+ return contract?.symbol
+ }
+
async compute(context: TransactionContext) {
if (!context.methods?.length) return
@@ -10,16 +19,31 @@ export class ERC721Descriptor implements TransactionDescriptor {
const parameters = method.parameters
switch (method.name) {
- case 'setApprovalForAll':
+ case 'approve': {
+ if (parameters?.to === undefined || parameters?.tokenId === undefined) break
+
+ const symbol = await this.getContractSymbol(context.chainId, context.to)
+
+ return {
+ chainId: context.chainId,
+ title: `Unlock ${symbol ?? 'token'} contract`,
+ description: `Unlock ${symbol ?? 'token'} contract`,
+ successfulDescription: `${symbol ?? 'token'} is unlocked successfully.`,
+ }
+ }
+ case 'setApprovalForAll': {
if (parameters?.operator === undefined || parameters?.approved === undefined) break
+
+ const action = parameters?.approved === false ? 'Revoke' : 'Unlock'
+ const symbol = await this.getContractSymbol(context.chainId, context.to)
+
return {
chainId: context.chainId,
- title: parameters?.approved === false ? 'Revoke' : 'Unlock',
- description: `${
- parameters?.approved === false ? 'Revoke the approval for' : 'Unlock'
- } the token.`,
- successfulDescription: 'Revoke the approval successfully.',
+ title: `${action} ${symbol ?? 'token'} contract`,
+ description: `${action} ${symbol ?? 'token'} contract`,
+ successfulDescription: `${action} the approval successfully.`,
}
+ }
default:
return