@@ -115,6 +115,38 @@ describe('Tron AccountCreate builder', function () {
115115
116116 assert . equal ( tx2 . toJson ( ) . txID , originalTxId ) ;
117117 } ) ;
118+
119+ // Regression test: AccountCreateContract's enum value is 0, which is the
120+ // proto3 default for the outer Transaction.Contract.type field. When the
121+ // SDK explicitly encoded `type: 0`, the wire format included the 2-byte
122+ // tag `0800` inside the contract envelope. TRON's node re-serializes
123+ // raw_data from broadcast JSON and omits default-valued fields, producing
124+ // a 2-byte-shorter canonical raw_data_hex and a different txID. The TSS
125+ // signature was valid for the SDK's hash but recovered to a garbage
126+ // pubkey under TRON's canonical hash, so AccountCreate broadcasts failed
127+ // with SIGERROR "signed by <random T...> but not contained of permission".
128+ it ( 'produces raw_data_hex without the proto3 default-valued type field' , async ( ) => {
129+ const timestamp = 1779455020653 ;
130+ const expiration = 1779465820653 ;
131+ const txBuilder = initTxBuilder ( ) ;
132+ txBuilder . timestamp ( timestamp ) ;
133+ txBuilder . expiration ( expiration ) ;
134+ const tx = await txBuilder . build ( ) ;
135+ const rawDataHex = tx . toJson ( ) . raw_data_hex ;
136+
137+ // The buggy encoding had `5a68 0800 1264` (contract tag, length 0x68,
138+ // type=0, parameter tag, length 0x64). The canonical encoding TRON
139+ // re-serializes to drops the `0800` and decrements the contract length
140+ // by 2 -> `5a66 1264`.
141+ assert . ok (
142+ ! rawDataHex . includes ( '5a68080012' ) ,
143+ `raw_data_hex must not include the proto3-default \`type: 0\` tag (0800). Got: ${ rawDataHex } `
144+ ) ;
145+ assert . ok (
146+ rawDataHex . includes ( '5a661264' ) ,
147+ `raw_data_hex must use the canonical contract framing (5a66...1264). Got: ${ rawDataHex } `
148+ ) ;
149+ } ) ;
118150 } ) ;
119151
120152 describe ( 'should validate' , ( ) => {
0 commit comments