@ -1,6 +1,6 @@
import { isHexString } from 'ethereumjs-util' ;
import { ethers } from 'ethers' ;
import abi from 'human-standard-token-abi ' ;
import { abiERC721 , abiERC20 , abiERC1155 } from '@metamask/metamask-eth-abis ' ;
import log from 'loglevel' ;
import { TOKEN _STANDARDS } from '../../ui/helpers/constants/common' ;
import { ASSET _TYPES , TRANSACTION _TYPES } from '../constants/transaction' ;
@ -19,7 +19,22 @@ import { isEqualCaseInsensitive } from './string-utils';
* code
* /
const hstInterface = new ethers . utils . Interface ( abi ) ;
/ * *
* @ typedef EthersContractCall
* @ type object
* @ property { any [ ] } args - The args / params to the function call .
* An array - like object with numerical and string indices .
* @ property { string } name - The name of the function .
* @ property { string } signature - The function signature .
* @ property { string } sighash - The function signature hash .
* @ property { EthersBigNumber } value - The ETH value associated with the call .
* @ property { FunctionFragment } functionFragment - The Ethers function fragment
* representation of the function .
* /
const erc20Interface = new ethers . utils . Interface ( abiERC20 ) ;
const erc721Interface = new ethers . utils . Interface ( abiERC721 ) ;
const erc1155Interface = new ethers . utils . Interface ( abiERC1155 ) ;
export function transactionMatchesNetwork ( transaction , chainId , networkId ) {
if ( typeof transaction . chainId !== 'undefined' ) {
@ -83,6 +98,36 @@ export function txParamsAreDappSuggested(transaction) {
) ;
}
/ * *
* Attempts to decode transaction data using ABIs for three different token standards : ERC20 , ERC721 , ERC1155 .
* The data will decode correctly if the transaction is an interaction with a contract that matches one of these
* contract standards
*
* @ param data - encoded transaction data
* @ returns { EthersContractCall | undefined }
* /
export function parseStandardTokenTransactionData ( data ) {
try {
return erc20Interface . parseTransaction ( { data } ) ;
} catch {
// ignore and next try to parse with erc721 ABI
}
try {
return erc721Interface . parseTransaction ( { data } ) ;
} catch {
// ignore and next try to parse with erc1155 ABI
}
try {
return erc1155Interface . parseTransaction ( { data } ) ;
} catch {
// ignore and return undefined
}
return undefined ;
}
/ * *
* Determines the type of the transaction by analyzing the txParams .
* This method will return one of the types defined in shared / constants / transactions
@ -98,7 +143,7 @@ export async function determineTransactionType(txParams, query) {
const { data , to } = txParams ;
let name ;
try {
name = data && hstInterface . parseTransaction ( { data } ) . name ;
( { name } = data && parseStandardTokenTransactionData ( data ) ) ;
} catch ( error ) {
log . debug ( 'Failed to parse transaction data.' , error , data ) ;
}
@ -107,6 +152,7 @@ export async function determineTransactionType(txParams, query) {
TRANSACTION _TYPES . TOKEN _METHOD _APPROVE ,
TRANSACTION _TYPES . TOKEN _METHOD _TRANSFER ,
TRANSACTION _TYPES . TOKEN _METHOD _TRANSFER _FROM ,
TRANSACTION _TYPES . TOKEN _METHOD _SAFE _TRANSFER _FROM ,
] . find ( ( methodName ) => isEqualCaseInsensitive ( methodName , name ) ) ;
let result ;