@@ -306,4 +306,157 @@ describe('Iota Transfer Builder', () => {
306306 should ( ( ) => factory . from ( 'invalidRawTransaction' ) ) . throwError ( ) ;
307307 } ) ;
308308 } ) ;
309+
310+ describe ( 'Transaction Signing' , ( ) => {
311+ it ( 'should build transaction with sender signature' , async function ( ) {
312+ const txBuilder = factory . getTransferBuilder ( ) ;
313+ txBuilder . sender ( testData . sender . address ) ;
314+ txBuilder . recipients ( testData . recipients ) ;
315+ txBuilder . paymentObjects ( testData . paymentObjects ) ;
316+ txBuilder . gasData ( testData . gasData ) ;
317+
318+ const tx = ( await txBuilder . build ( ) ) as TransferTransaction ;
319+
320+ // Add signature
321+ tx . addSignature ( testData . testSignature . publicKey , testData . testSignature . signature ) ;
322+
323+ // Rebuild to trigger serialization
324+ await tx . build ( ) ;
325+
326+ should . exist ( tx . serializedSignature ) ;
327+ should . equal ( tx . serializedSignature ! . length > 0 , true ) ;
328+ } ) ;
329+
330+ it ( 'should build transaction with gas sponsor signature' , async function ( ) {
331+ const txBuilder = factory . getTransferBuilder ( ) ;
332+ txBuilder . sender ( testData . sender . address ) ;
333+ txBuilder . recipients ( testData . recipients ) ;
334+ txBuilder . paymentObjects ( testData . paymentObjects ) ;
335+ txBuilder . gasData ( testData . gasData ) ;
336+ txBuilder . gasSponsor ( testData . gasSponsor . address ) ;
337+
338+ const tx = ( await txBuilder . build ( ) ) as TransferTransaction ;
339+
340+ // Add gas sponsor signature
341+ tx . addGasSponsorSignature ( testData . testGasSponsorSignature . publicKey , testData . testGasSponsorSignature . signature ) ;
342+
343+ // Rebuild to trigger serialization
344+ await tx . build ( ) ;
345+
346+ should . exist ( tx . serializedGasSponsorSignature ) ;
347+ should . equal ( tx . serializedGasSponsorSignature ! . length > 0 , true ) ;
348+ } ) ;
349+
350+ it ( 'should build transaction with both sender and gas sponsor signatures' , async function ( ) {
351+ const txBuilder = factory . getTransferBuilder ( ) ;
352+ txBuilder . sender ( testData . sender . address ) ;
353+ txBuilder . recipients ( testData . recipients ) ;
354+ txBuilder . paymentObjects ( testData . paymentObjects ) ;
355+ txBuilder . gasData ( testData . gasData ) ;
356+ txBuilder . gasSponsor ( testData . gasSponsor . address ) ;
357+
358+ const tx = ( await txBuilder . build ( ) ) as TransferTransaction ;
359+
360+ // Add both signatures
361+ tx . addSignature ( testData . testSignature . publicKey , testData . testSignature . signature ) ;
362+ tx . addGasSponsorSignature ( testData . testGasSponsorSignature . publicKey , testData . testGasSponsorSignature . signature ) ;
363+
364+ // Rebuild to trigger serialization
365+ await tx . build ( ) ;
366+
367+ should . exist ( tx . serializedSignature ) ;
368+ should . exist ( tx . serializedGasSponsorSignature ) ;
369+ tx . signature . length . should . equal ( 2 ) ;
370+ } ) ;
371+
372+ it ( 'should add signature through builder and serialize correctly' , async function ( ) {
373+ const txBuilder = factory . getTransferBuilder ( ) ;
374+ txBuilder . sender ( testData . sender . address ) ;
375+ txBuilder . recipients ( testData . recipients ) ;
376+ txBuilder . paymentObjects ( testData . paymentObjects ) ;
377+ txBuilder . gasData ( testData . gasData ) ;
378+
379+ // Add signature through builder
380+ txBuilder . addSignature ( testData . testSignature . publicKey , testData . testSignature . signature ) ;
381+
382+ const tx = ( await txBuilder . build ( ) ) as TransferTransaction ;
383+
384+ should . exist ( tx . serializedSignature ) ;
385+ should . equal ( typeof tx . serializedSignature , 'string' ) ;
386+ // Verify signature array is populated
387+ tx . signature . length . should . equal ( 1 ) ;
388+ } ) ;
389+
390+ it ( 'should add gas sponsor signature through builder and serialize correctly' , async function ( ) {
391+ const txBuilder = factory . getTransferBuilder ( ) ;
392+ txBuilder . sender ( testData . sender . address ) ;
393+ txBuilder . recipients ( testData . recipients ) ;
394+ txBuilder . paymentObjects ( testData . paymentObjects ) ;
395+ txBuilder . gasData ( testData . gasData ) ;
396+ txBuilder . gasSponsor ( testData . gasSponsor . address ) ;
397+
398+ // Add gas sponsor signature through builder
399+ txBuilder . addGasSponsorSignature (
400+ testData . testGasSponsorSignature . publicKey ,
401+ testData . testGasSponsorSignature . signature
402+ ) ;
403+
404+ const tx = ( await txBuilder . build ( ) ) as TransferTransaction ;
405+
406+ should . exist ( tx . serializedGasSponsorSignature ) ;
407+ should . equal ( typeof tx . serializedGasSponsorSignature , 'string' ) ;
408+ // Verify signature array is populated
409+ tx . signature . length . should . equal ( 1 ) ;
410+ } ) ;
411+
412+ it ( 'should serialize signatures in correct order' , async function ( ) {
413+ const txBuilder = factory . getTransferBuilder ( ) ;
414+ txBuilder . sender ( testData . sender . address ) ;
415+ txBuilder . recipients ( testData . recipients ) ;
416+ txBuilder . paymentObjects ( testData . paymentObjects ) ;
417+ txBuilder . gasData ( testData . gasData ) ;
418+ txBuilder . gasSponsor ( testData . gasSponsor . address ) ;
419+
420+ // Add signatures through builder
421+ txBuilder . addSignature ( testData . testSignature . publicKey , testData . testSignature . signature ) ;
422+ txBuilder . addGasSponsorSignature (
423+ testData . testGasSponsorSignature . publicKey ,
424+ testData . testGasSponsorSignature . signature
425+ ) ;
426+
427+ const tx = ( await txBuilder . build ( ) ) as TransferTransaction ;
428+
429+ // Verify signatures are in correct order: sender first, gas sponsor second
430+ tx . signature . length . should . equal ( 2 ) ;
431+ tx . signature [ 0 ] . should . equal ( tx . serializedSignature ) ;
432+ tx . signature [ 1 ] . should . equal ( tx . serializedGasSponsorSignature ) ;
433+ } ) ;
434+
435+ it ( 'should fail to add invalid sender signature via builder' , function ( ) {
436+ const txBuilder = factory . getTransferBuilder ( ) ;
437+ txBuilder . sender ( testData . sender . address ) ;
438+ txBuilder . recipients ( testData . recipients ) ;
439+ txBuilder . paymentObjects ( testData . paymentObjects ) ;
440+ txBuilder . gasData ( testData . gasData ) ;
441+
442+ // Builder should validate and throw when adding invalid signature
443+ should ( ( ) => txBuilder . addSignature ( { pub : 'tooshort' } , testData . testSignature . signature ) ) . throwError (
444+ 'Invalid transaction signature'
445+ ) ;
446+ } ) ;
447+
448+ it ( 'should fail to add invalid gas sponsor signature via builder' , function ( ) {
449+ const txBuilder = factory . getTransferBuilder ( ) ;
450+ txBuilder . sender ( testData . sender . address ) ;
451+ txBuilder . recipients ( testData . recipients ) ;
452+ txBuilder . paymentObjects ( testData . paymentObjects ) ;
453+ txBuilder . gasData ( testData . gasData ) ;
454+ txBuilder . gasSponsor ( testData . gasSponsor . address ) ;
455+
456+ // Builder should validate and throw when adding invalid signature
457+ should ( ( ) =>
458+ txBuilder . addGasSponsorSignature ( testData . testGasSponsorSignature . publicKey , Buffer . from ( 'invalid' ) )
459+ ) . throwError ( 'Invalid transaction signature' ) ;
460+ } ) ;
461+ } ) ;
309462} ) ;
0 commit comments