@@ -26,7 +26,7 @@ export class Transaction extends BaseTransaction {
2626 protected _chainName : string ;
2727 protected _sender : string ;
2828
29- private static FAKE_SIGNATURE = `0x${ Buffer . from ( new Uint8Array ( 256 ) . fill ( 1 ) ) . toString ( 'hex' ) } ` ;
29+ private static FAKE_SIGNATURE = `0x${ Buffer . from ( new Uint8Array ( 256 ) . fill ( 1 ) ) . toString ( 'hex' ) } ` as HexString ;
3030
3131 constructor ( coinConfig : Readonly < CoinConfig > ) {
3232 super ( coinConfig ) ;
@@ -77,7 +77,7 @@ export class Transaction extends BaseTransaction {
7777 addSignature ( signature : string ) : void {
7878 this . _signedTransaction = utils . serializeSignedTransaction (
7979 this . _substrateTransaction ,
80- signature ,
80+ signature as HexString ,
8181 this . _substrateTransaction . metadataRpc ,
8282 this . _registry
8383 ) ;
@@ -177,6 +177,11 @@ export class Transaction extends BaseTransaction {
177177 result . to = keypairDest . getAddress ( this . getAddressFormat ( ) ) ;
178178 result . amount = txMethod . amountStaked . toString ( ) ;
179179 result . netuid = txMethod . netuid ;
180+ } else if ( utils . isBond ( txMethod ) ) {
181+ result . amount = txMethod . value ;
182+ result . payee = typeof txMethod . payee === 'string' ? txMethod . payee : txMethod . payee . Account ;
183+ } else if ( utils . isBondExtra ( txMethod ) ) {
184+ result . amount = txMethod . maxAdditional ;
180185 }
181186 } else if ( this . type === TransactionType . StakingDeactivate ) {
182187 if ( utils . isRemoveStake ( txMethod ) ) {
@@ -187,6 +192,28 @@ export class Transaction extends BaseTransaction {
187192 result . to = keypairDest . getAddress ( this . getAddressFormat ( ) ) ;
188193 result . amount = txMethod . amountUnstaked . toString ( ) ;
189194 result . netuid = txMethod . netuid ;
195+ } else if ( utils . isUnbond ( txMethod ) ) {
196+ result . amount = txMethod . value ;
197+ } else if ( utils . isWithdrawUnbonded ( txMethod ) ) {
198+ result . numSlashingSpans = txMethod . numSlashingSpans ;
199+ }
200+ } else if ( this . type === TransactionType . Batch ) {
201+ if ( utils . isBatch ( txMethod ) ) {
202+ result . batchCalls = txMethod . calls ;
203+ // Extract amount from batch calls for display
204+ if ( txMethod . calls && txMethod . calls . length === 2 ) {
205+ const firstCall = txMethod . calls [ 0 ] ;
206+ const secondCall = txMethod . calls [ 1 ] ;
207+ if ( firstCall . method === 'bond' && secondCall . method === 'nominate' ) {
208+ // Staking batch: bond + nominate
209+ const bondArgs = firstCall . args as Record < string , unknown > ;
210+ result . amount = bondArgs . value as string ;
211+ } else if ( firstCall . method === 'chill' && secondCall . method === 'unbond' ) {
212+ // Unstaking batch: chill + unbond
213+ const unbondArgs = secondCall . args as Record < string , unknown > ;
214+ result . amount = unbondArgs . value as string ;
215+ }
216+ }
190217 }
191218 }
192219
@@ -277,6 +304,8 @@ export class Transaction extends BaseTransaction {
277304 this . decodeInputsAndOutputsForStakingActivate ( decodedTx ) ;
278305 } else if ( this . type === TransactionType . StakingDeactivate ) {
279306 this . decodeInputsAndOutputsForStakingDeactivate ( decodedTx ) ;
307+ } else if ( this . type === TransactionType . Batch ) {
308+ this . decodeInputsAndOutputsForBatch ( decodedTx ) ;
280309 }
281310 }
282311
@@ -331,6 +360,14 @@ export class Transaction extends BaseTransaction {
331360 to = keypairDest . getAddress ( this . getAddressFormat ( ) ) ;
332361 value = txMethod . amountStaked . toString ( ) ;
333362 from = decodedTx . address ;
363+ } else if ( utils . isBond ( txMethod ) ) {
364+ to = decodedTx . address ; // For bond, funds are locked in the same account
365+ value = txMethod . value ;
366+ from = decodedTx . address ;
367+ } else if ( utils . isBondExtra ( txMethod ) ) {
368+ to = decodedTx . address ; // For bond extra, funds are locked in the same account
369+ value = txMethod . maxAdditional ;
370+ from = decodedTx . address ;
334371 } else {
335372 throw new ParseTransactionError ( `Loading inputs of unknown StakingActivate type parameters` ) ;
336373 }
@@ -363,6 +400,14 @@ export class Transaction extends BaseTransaction {
363400 to = keypairDest . getAddress ( this . getAddressFormat ( ) ) ;
364401 value = txMethod . amountUnstaked . toString ( ) ;
365402 from = decodedTx . address ;
403+ } else if ( utils . isUnbond ( txMethod ) ) {
404+ to = decodedTx . address ; // For unbond, funds are unlocked from the same account
405+ value = txMethod . value ;
406+ from = decodedTx . address ;
407+ } else if ( utils . isWithdrawUnbonded ( txMethod ) ) {
408+ to = decodedTx . address ; // For withdraw unbonded, funds are returned to the same account
409+ value = '0' ; // Amount is not specified in withdraw unbonded
410+ from = decodedTx . address ;
366411 } else {
367412 throw new ParseTransactionError ( `Loading inputs of unknown StakingDeactivate type parameters` ) ;
368413 }
@@ -383,6 +428,83 @@ export class Transaction extends BaseTransaction {
383428 ] ;
384429 }
385430
431+ private decodeInputsAndOutputsForBatch ( decodedTx : DecodedTx ) {
432+ const txMethod = decodedTx . method . args ;
433+ const sender = decodedTx . address ;
434+ this . _inputs = [ ] ;
435+ this . _outputs = [ ] ;
436+
437+ if ( utils . isBatch ( txMethod ) ) {
438+ if ( ! txMethod . calls ) {
439+ throw new InvalidTransactionError ( 'failed to decode calls from batch transaction' ) ;
440+ }
441+ // Handle different types of batch operations
442+ let totalStakingValue = '0' ;
443+ let hasStakingOperations = false ;
444+ let hasUnstakingOperations = false ;
445+
446+ for ( const call of txMethod . calls ) {
447+ // Handle both possible formats: simple method names or callIndex with registry lookup
448+ let methodName : string ;
449+
450+ if ( typeof call . method === 'string' ) {
451+ methodName = call . method ;
452+ } else {
453+ try {
454+ const callIndex = call . method as string ;
455+ const decodedCall = this . _registry . findMetaCall (
456+ new Uint8Array ( Buffer . from ( callIndex . replace ( '0x' , '' ) , 'hex' ) )
457+ ) ;
458+ methodName = decodedCall . method ;
459+ } catch ( e ) {
460+ methodName = call . method as string ;
461+ }
462+ }
463+
464+ if ( methodName === 'bond' ) {
465+ const args = call . args as Record < string , unknown > ;
466+ const value = ( args . value as string ) || '0' ;
467+ totalStakingValue = value ;
468+ hasStakingOperations = true ;
469+ } else if ( methodName === 'chill' ) {
470+ hasUnstakingOperations = true ;
471+ } else if ( methodName === 'unbond' ) {
472+ const args = call . args as Record < string , unknown > ;
473+ const value = ( args . value as string ) || '0' ;
474+ totalStakingValue = value ;
475+ hasUnstakingOperations = true ;
476+ }
477+ }
478+
479+ // For staking batch operations (bond + nominate or bondExtra + nominate)
480+ if ( hasStakingOperations && ! hasUnstakingOperations ) {
481+ this . _inputs . push ( {
482+ address : sender ,
483+ value : totalStakingValue ,
484+ coin : this . _coinConfig . name ,
485+ } ) ;
486+ this . _outputs . push ( {
487+ address : sender , // For staking, funds are locked in the same account
488+ value : totalStakingValue ,
489+ coin : this . _coinConfig . name ,
490+ } ) ;
491+ }
492+ // For unstaking batch operations (chill + unbond)
493+ else if ( hasUnstakingOperations && ! hasStakingOperations ) {
494+ this . _inputs . push ( {
495+ address : sender ,
496+ value : totalStakingValue ,
497+ coin : this . _coinConfig . name ,
498+ } ) ;
499+ this . _outputs . push ( {
500+ address : sender , // For unstaking, funds are unlocked from the same account
501+ value : totalStakingValue ,
502+ coin : this . _coinConfig . name ,
503+ } ) ;
504+ }
505+ }
506+ }
507+
386508 /**
387509 * Constructs a signed payload using construct.signTx
388510 * This method will be called during the build step if a TSS signature
0 commit comments