@@ -51,6 +51,8 @@ import {
5151 ERC1155SafeTransferTypes ,
5252 ERC721SafeTransferTypeMethodId ,
5353 ERC721SafeTransferTypes ,
54+ ERC721TransferFromMethodId ,
55+ ERC721TransferFromTypes ,
5456 flushCoinsMethodId ,
5557 flushCoinsTypes ,
5658 flushForwarderTokensMethodId ,
@@ -84,6 +86,18 @@ import {
8486} from './walletUtil' ;
8587import { EthTransactionData } from './types' ;
8688
89+ /**
90+ * Check if an EVM address is an HTS (Hedera Token Service) native address.
91+ * HTS entities on Hedera EVM use "long-zero" addresses where the first 12 bytes are all zeros
92+ * and the entity number occupies the last 8 bytes (e.g. 0x00000000000000000000000000000000007ac203).
93+ * Standard Solidity contracts have normal EVM addresses derived from public key hashes.
94+ */
95+ export function isHtsEvmAddress ( address : string ) : boolean {
96+ const normalized = address . toLowerCase ( ) ;
97+ // First 12 bytes (24 hex chars) after '0x' prefix are all zeros
98+ return / ^ 0 x 0 { 24 } [ 0 - 9 a - f ] { 16 } $ / . test ( normalized ) ;
99+ }
100+
87101/**
88102 * @param network
89103 */
@@ -509,26 +523,46 @@ export function decodeERC721TransferData(data: string): ERC721TransferData {
509523 ) ;
510524
511525 const internalDataHex = bufferToHex ( internalData as Buffer ) ;
512- if ( ! internalDataHex . startsWith ( ERC721SafeTransferTypeMethodId ) ) {
513- throw new BuildTransactionError ( `Invalid transfer bytecode: ${ data } ` ) ;
526+
527+ if ( internalDataHex . startsWith ( ERC721SafeTransferTypeMethodId ) ) {
528+ const [ from , receiver , tokenId , userSentData ] = getRawDecoded (
529+ ERC721SafeTransferTypes ,
530+ getBufferedByteCode ( ERC721SafeTransferTypeMethodId , internalDataHex )
531+ ) ;
532+
533+ return {
534+ to : addHexPrefix ( receiver as string ) ,
535+ from : addHexPrefix ( from as string ) ,
536+ expireTime : bufferToInt ( expireTime as Buffer ) ,
537+ amount : new BigNumber ( bufferToHex ( amount as Buffer ) ) . toFixed ( ) ,
538+ tokenId : new BigNumber ( bufferToHex ( tokenId as Buffer ) ) . toFixed ( ) ,
539+ sequenceId : bufferToInt ( sequenceId as Buffer ) ,
540+ signature : bufferToHex ( signature as Buffer ) ,
541+ tokenContractAddress : addHexPrefix ( to as string ) ,
542+ userData : bufferToHex ( userSentData as Buffer ) ,
543+ } ;
514544 }
515545
516- const [ from , receiver , tokenId , userSentData ] = getRawDecoded (
517- ERC721SafeTransferTypes ,
518- getBufferedByteCode ( ERC721SafeTransferTypeMethodId , internalDataHex )
519- ) ;
546+ if ( internalDataHex . startsWith ( ERC721TransferFromMethodId ) ) {
547+ const [ from , receiver , tokenId ] = getRawDecoded (
548+ ERC721TransferFromTypes ,
549+ getBufferedByteCode ( ERC721TransferFromMethodId , internalDataHex )
550+ ) ;
520551
521- return {
522- to : addHexPrefix ( receiver as string ) ,
523- from : addHexPrefix ( from as string ) ,
524- expireTime : bufferToInt ( expireTime as Buffer ) ,
525- amount : new BigNumber ( bufferToHex ( amount as Buffer ) ) . toFixed ( ) ,
526- tokenId : new BigNumber ( bufferToHex ( tokenId as Buffer ) ) . toFixed ( ) ,
527- sequenceId : bufferToInt ( sequenceId as Buffer ) ,
528- signature : bufferToHex ( signature as Buffer ) ,
529- tokenContractAddress : addHexPrefix ( to as string ) ,
530- userData : bufferToHex ( userSentData as Buffer ) ,
531- } ;
552+ return {
553+ to : addHexPrefix ( receiver as string ) ,
554+ from : addHexPrefix ( from as string ) ,
555+ expireTime : bufferToInt ( expireTime as Buffer ) ,
556+ amount : new BigNumber ( bufferToHex ( amount as Buffer ) ) . toFixed ( ) ,
557+ tokenId : new BigNumber ( bufferToHex ( tokenId as Buffer ) ) . toFixed ( ) ,
558+ sequenceId : bufferToInt ( sequenceId as Buffer ) ,
559+ signature : bufferToHex ( signature as Buffer ) ,
560+ tokenContractAddress : addHexPrefix ( to as string ) ,
561+ userData : '' ,
562+ } ;
563+ }
564+
565+ throw new BuildTransactionError ( `Invalid transfer bytecode: ${ data } ` ) ;
532566}
533567
534568export function decodeERC1155TransferData ( data : string ) : ERC1155TransferData {
0 commit comments