@@ -326,4 +326,76 @@ describe('ADA Token Operations', async () => {
326326
327327 await txBuilder . build ( ) . should . not . be . rejected ( ) ;
328328 } ) ;
329+
330+ it ( `should build a sponsored token transaction where fee address sponsors min ADA for receiver` , async ( ) => {
331+ const feeAddress =
332+ 'addr_test1qz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3jcu5d8ps7zex2k2xt3uqxgjqnnj83ws8lhrn648jjxtwq2ytjqp' ;
333+ const quantity = '20' ;
334+ const senderInputBalance = 5000000 ;
335+ const feeAddressInputBalance = 20000000 ; // Fee address has enough ADA to sponsor
336+ const totalAssetList = {
337+ [ fingerprint ] : {
338+ quantity : '100' ,
339+ policy_id : policyId ,
340+ asset_name : asciiEncodedName ,
341+ } ,
342+ } ;
343+
344+ const txBuilder = factory . getTransferBuilder ( ) ;
345+ // Sender input (has tokens)
346+ txBuilder . input ( {
347+ transaction_id : '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba21' ,
348+ transaction_index : 1 ,
349+ } ) ;
350+ // Fee address input (sponsors fees and min ADA)
351+ txBuilder . input ( {
352+ transaction_id : '3677e75c7ba699bfdc6cd57d42f246f86f63aefd76025006ac78313fad2bba22' ,
353+ transaction_index : 0 ,
354+ } ) ;
355+
356+ txBuilder . output ( {
357+ address : receiverAddress ,
358+ amount : '0' , // Set ADA amount to 0 for token transfer (min ADA is handled by fee address)
359+ multiAssets : {
360+ asset_name : asciiEncodedName ,
361+ policy_id : policyId ,
362+ quantity,
363+ fingerprint,
364+ } ,
365+ } ) ;
366+
367+ txBuilder . changeAddress ( senderAddress , senderInputBalance . toString ( ) , totalAssetList ) ;
368+ txBuilder . sponsorshipInfo ( {
369+ feeAddress : feeAddress ,
370+ feeAddressInputBalance : feeAddressInputBalance . toString ( ) ,
371+ } ) ;
372+ txBuilder . ttl ( 800000000 ) ;
373+ txBuilder . isTokenTransaction ( ) ;
374+ const tx = ( await txBuilder . build ( ) ) as Transaction ;
375+
376+ should . equal ( tx . type , TransactionType . Send ) ;
377+ const txData = tx . toJson ( ) ;
378+
379+ txData . inputs . length . should . equal ( 2 ) ;
380+ txData . outputs . length . should . equal ( 4 ) ;
381+
382+ // Validate receiver output - min ADA should be sponsored by fee address
383+ const receiverOutput = txData . outputs . filter ( ( output ) => output . address === receiverAddress ) ;
384+ receiverOutput . length . should . equal ( 1 ) ;
385+ receiverOutput [ 0 ] . amount . should . equal ( '1500000' ) ; // Minimum ADA for asset output (sponsored by fee address)
386+ ( receiverOutput [ 0 ] . multiAssets ! as CardanoWasm . MultiAsset )
387+ . get_asset ( policyScriptHash , CardanoWasm . AssetName . new ( Buffer . from ( asciiEncodedName , 'hex' ) ) )
388+ . to_str ( )
389+ . should . equal ( quantity ) ;
390+
391+ // Validate sender change output - should have full sender balance (tokens only, no ADA deduction for receiver)
392+ const senderChangeOutput = txData . outputs . filter ( ( output ) => output . address === senderAddress ) ;
393+ senderChangeOutput . length . should . be . equal ( 2 ) ;
394+
395+ // Validate fee address change output - should have remaining ADA after fees and min ADA for receiver
396+ const feeAddressChangeOutput = txData . outputs . filter ( ( output ) => output . address === feeAddress ) ;
397+ feeAddressChangeOutput . length . should . equal ( 1 ) ;
398+ // Fee address change should not have any tokens
399+ should . not . exist ( feeAddressChangeOutput [ 0 ] . multiAssets ) ;
400+ } ) ;
329401} ) ;
0 commit comments