@@ -926,5 +926,138 @@ describe('ADA Token Operations', async () => {
926926 } )
927927 . should . be . rejectedWith ( 'tx outputs does not match with expected address' ) ;
928928 } ) ;
929+
930+ it ( 'should verify sponsored token consolidation when fee address output is present' , async ( ) => {
931+ const feeAddress =
932+ 'addr_test1qz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3jcu5d8ps7zex2k2xt3uqxgjqnnj83ws8lhrn648jjxtwq2ytjqp' ;
933+ const quantity = '100' ;
934+ const senderInputBalance = 5000000 ;
935+ const feeAddressInputBalance = 20000000 ;
936+ const totalAssetList = {
937+ [ fingerprint ] : {
938+ quantity : '100' ,
939+ policy_id : policyId ,
940+ asset_name : asciiEncodedName ,
941+ } ,
942+ } ;
943+
944+ // Build a sponsored token consolidation: tokens go back to senderAddress, fee sponsor gets ADA change
945+ const txBuilder = factory . getTransferBuilder ( ) ;
946+ txBuilder . input ( {
947+ transaction_id : '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21' ,
948+ transaction_index : 1 ,
949+ } ) ;
950+ txBuilder . input ( {
951+ transaction_id : '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba22' ,
952+ transaction_index : 0 ,
953+ } ) ;
954+
955+ // Consolidation output: tokens go back to the sender's base address
956+ txBuilder . output ( {
957+ address : senderAddress ,
958+ amount : '0' ,
959+ multiAssets : {
960+ asset_name : asciiEncodedName ,
961+ policy_id : policyId ,
962+ quantity,
963+ fingerprint,
964+ } ,
965+ } ) ;
966+
967+ txBuilder . changeAddress ( senderAddress , senderInputBalance . toString ( ) , totalAssetList ) ;
968+ txBuilder . sponsorshipInfo ( {
969+ feeAddress : feeAddress ,
970+ feeAddressInputBalance : feeAddressInputBalance . toString ( ) ,
971+ } ) ;
972+ txBuilder . ttl ( 800000000 ) ;
973+ txBuilder . isTokenTransaction ( ) ;
974+ const tx = ( await txBuilder . build ( ) ) as Transaction ;
975+ const txHex = tx . toBroadcastFormat ( ) ;
976+
977+ const mockWallet = {
978+ coinSpecific : ( ) => ( {
979+ baseAddress : senderAddress ,
980+ } ) ,
981+ } ;
982+
983+ const txParams = { recipients : undefined } ;
984+ const txPrebuild = { txHex, txInfo : { feeAddress } } ;
985+ const verification = { consolidationToBaseAddress : true } ;
986+
987+ const isVerified = await adaToken . verifyTransaction ( {
988+ txParams,
989+ txPrebuild,
990+ verification,
991+ wallet : mockWallet as any ,
992+ } ) ;
993+ isVerified . should . equal ( true ) ;
994+ } ) ;
995+
996+ it ( 'should fail sponsored token consolidation when output goes to unexpected third-party address' , async ( ) => {
997+ const feeAddress =
998+ 'addr_test1qz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3jcu5d8ps7zex2k2xt3uqxgjqnnj83ws8lhrn648jjxtwq2ytjqp' ;
999+ const quantity = '100' ;
1000+ const senderInputBalance = 5000000 ;
1001+ const feeAddressInputBalance = 20000000 ;
1002+ const totalAssetList = {
1003+ [ fingerprint ] : {
1004+ quantity : '100' ,
1005+ policy_id : policyId ,
1006+ asset_name : asciiEncodedName ,
1007+ } ,
1008+ } ;
1009+
1010+ // Build transaction where token output goes to an unexpected third-party address
1011+ const txBuilder = factory . getTransferBuilder ( ) ;
1012+ txBuilder . input ( {
1013+ transaction_id : '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21' ,
1014+ transaction_index : 1 ,
1015+ } ) ;
1016+ txBuilder . input ( {
1017+ transaction_id : '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba22' ,
1018+ transaction_index : 0 ,
1019+ } ) ;
1020+
1021+ // Output goes to receiverAddress (third party), not the base address
1022+ txBuilder . output ( {
1023+ address : receiverAddress ,
1024+ amount : '0' ,
1025+ multiAssets : {
1026+ asset_name : asciiEncodedName ,
1027+ policy_id : policyId ,
1028+ quantity,
1029+ fingerprint,
1030+ } ,
1031+ } ) ;
1032+
1033+ txBuilder . changeAddress ( senderAddress , senderInputBalance . toString ( ) , totalAssetList ) ;
1034+ txBuilder . sponsorshipInfo ( {
1035+ feeAddress : feeAddress ,
1036+ feeAddressInputBalance : feeAddressInputBalance . toString ( ) ,
1037+ } ) ;
1038+ txBuilder . ttl ( 800000000 ) ;
1039+ txBuilder . isTokenTransaction ( ) ;
1040+ const tx = ( await txBuilder . build ( ) ) as Transaction ;
1041+ const txHex = tx . toBroadcastFormat ( ) ;
1042+
1043+ const mockWallet = {
1044+ coinSpecific : ( ) => ( {
1045+ baseAddress : senderAddress ,
1046+ } ) ,
1047+ } ;
1048+
1049+ const txParams = { recipients : undefined } ;
1050+ const txPrebuild = { txHex, txInfo : { feeAddress } } ;
1051+ const verification = { consolidationToBaseAddress : true } ;
1052+
1053+ await adaToken
1054+ . verifyTransaction ( {
1055+ txParams,
1056+ txPrebuild,
1057+ verification,
1058+ wallet : mockWallet as any ,
1059+ } )
1060+ . should . be . rejectedWith ( 'tx outputs does not match with expected address' ) ;
1061+ } ) ;
9291062 } ) ;
9301063} ) ;
0 commit comments