@@ -789,16 +789,16 @@ export const getDecodedWithdrawalCurrency = (
789789 }
790790} ;
791791
792- const decodeERC20TransferAmount = ( data : string ) => {
792+ const decodeERC20TransferParams = ( data : string ) => {
793793 // ERC20 / TRC20 `transfer(address,uint256)` selector is 0xa9059cbb
794794 const TRANSFER_SELECTOR = "0xa9059cbb" ;
795795 if ( data . toLowerCase ( ) . startsWith ( TRANSFER_SELECTOR . toLowerCase ( ) ) ) {
796796 const paramsData = ( "0x" + data . slice ( TRANSFER_SELECTOR . length ) ) as Hex ;
797- const [ amount ] = decodeAbiParameters (
797+ const params = decodeAbiParameters (
798798 parseAbiParameters ( [ "address" , "uint256" ] ) ,
799799 paramsData
800800 ) ;
801- return amount ;
801+ return params ;
802802 } else {
803803 throw new Error ( `Unsupported function call data: ${ data } ` ) ;
804804 }
@@ -813,7 +813,8 @@ export const getDecodedWithdrawalAmount = (
813813 if ( firstCall . data === "0x" ) {
814814 return firstCall . value ;
815815 } else {
816- return decodeERC20TransferAmount ( firstCall . data ) ;
816+ const [ , amount ] = decodeERC20TransferParams ( firstCall . data ) ;
817+ return amount . toString ( ) ;
817818 }
818819 }
819820
@@ -822,7 +823,8 @@ export const getDecodedWithdrawalAmount = (
822823 if ( firstCall . data === "0x" ) {
823824 return firstCall . value ;
824825 } else {
825- return decodeERC20TransferAmount ( firstCall . data ) ;
826+ const [ , amount ] = decodeERC20TransferParams ( firstCall . data ) ;
827+ return amount . toString ( ) ;
826828 }
827829 }
828830
@@ -859,3 +861,67 @@ export const getDecodedWithdrawalAmount = (
859861 throw new Error ( "Unsupported vm type" ) ;
860862 }
861863} ;
864+
865+ export const getDecodedWithdrawalRecipient = (
866+ decodedWithdrawal : DecodedWithdrawal
867+ ) : string => {
868+ switch ( decodedWithdrawal . vmType ) {
869+ case "ethereum-vm" : {
870+ const firstCall = decodedWithdrawal . withdrawal . calls [ 0 ] ;
871+ if ( firstCall . data === "0x" ) {
872+ return firstCall . to ;
873+ } else {
874+ const [ to ] = decodeERC20TransferParams ( firstCall . data ) ;
875+ return to ;
876+ }
877+ }
878+
879+ case "tron-vm" : {
880+ const firstCall = decodedWithdrawal . withdrawal . calls [ 0 ] ;
881+ if ( firstCall . data === "0x" ) {
882+ return firstCall . to ;
883+ } else {
884+ const [ to ] = decodeERC20TransferParams ( firstCall . data ) ;
885+ return to ;
886+ }
887+ }
888+
889+ case "solana-vm" : {
890+ return decodedWithdrawal . withdrawal . recipient ;
891+ }
892+
893+ case "sui-vm" : {
894+ return decodedWithdrawal . withdrawal . recipient ;
895+ }
896+
897+ case "bitcoin-vm" : {
898+ try {
899+ const psbt = bitcoin . Psbt . fromHex ( decodedWithdrawal . withdrawal . psbt ) ;
900+ const tx = psbt . extractTransaction ( false ) ;
901+ if ( tx . outs . length === 0 ) {
902+ throw new Error ( "Transaction has no outputs" ) ;
903+ }
904+ // Extract address from the first output
905+ const firstOutput = tx . outs [ 0 ] ;
906+ const address = bitcoin . address . fromOutputScript (
907+ firstOutput . script ,
908+ bitcoin . networks . bitcoin
909+ ) ;
910+ return address ;
911+ } catch ( error ) {
912+ throw new Error (
913+ `Failed to decode PSBT: ${
914+ error instanceof Error ? error . message : String ( error )
915+ } `
916+ ) ;
917+ }
918+ }
919+
920+ case "hyperliquid-vm" : {
921+ return decodedWithdrawal . withdrawal . parameters . destination ;
922+ }
923+
924+ default :
925+ throw new Error ( "Unsupported vm type" ) ;
926+ }
927+ } ;
0 commit comments