@@ -136,6 +136,60 @@ describe('OfcSignPayload codec tests', function () {
136136 assert . ok ( decodedResponse ) ;
137137 } ) ;
138138
139+ it ( 'should not double-stringify a stringified JSON payload' , async function ( ) {
140+ const originalPayload = '{"coin":"ofctbtc","recipients":[{"address":"abc123","amount":"1000"}]}' ;
141+ const requestBody = {
142+ walletId : 'ofc-wallet-id-123' ,
143+ payload : originalPayload ,
144+ walletPassphrase : 'test_passphrase' ,
145+ } ;
146+
147+ const mockTradingAccount = {
148+ signPayload : sinon . stub ( ) . resolves ( mockSignPayloadResponse . signature ) ,
149+ } ;
150+
151+ const mockWallet = {
152+ id : ( ) => requestBody . walletId ,
153+ toTradingAccount : sinon . stub ( ) . returns ( mockTradingAccount ) ,
154+ } ;
155+
156+ const walletsGetStub = sinon . stub ( ) . resolves ( mockWallet ) ;
157+ const mockWallets = { get : walletsGetStub } ;
158+ const mockCoin = { wallets : sinon . stub ( ) . returns ( mockWallets ) } ;
159+ sinon . stub ( BitGo . prototype , 'coin' ) . returns ( mockCoin as any ) ;
160+
161+ const result = await agent
162+ . post ( '/api/v2/ofc/signPayload' )
163+ . set ( 'Authorization' , 'Bearer test_access_token_12345' )
164+ . set ( 'Content-Type' , 'application/json' )
165+ . send ( requestBody ) ;
166+
167+ assert . strictEqual ( result . status , 200 ) ;
168+ const decodedResponse = assertDecode ( OfcSignPayloadResponse200 , result . body ) ;
169+
170+ // The returned payload must not be double-stringified.
171+ // A double-stringified payload would start with a quote character and contain escaped quotes.
172+ assert . strictEqual (
173+ decodedResponse . payload . startsWith ( '"' ) ,
174+ false ,
175+ 'payload was double-stringified: starts with a quote character'
176+ ) ;
177+ assert . strictEqual (
178+ decodedResponse . payload . includes ( '\\"' ) ,
179+ false ,
180+ 'payload was double-stringified: contains escaped quotes'
181+ ) ;
182+
183+ // The payload passed to tradingAccount.signPayload must match the original string
184+ const signCall = mockTradingAccount . signPayload . getCall ( 0 ) ;
185+ assert . ok ( signCall , 'tradingAccount.signPayload should have been called' ) ;
186+ assert . strictEqual (
187+ signCall . args [ 0 ] . payload ,
188+ originalPayload ,
189+ 'tradingAccount.signPayload received a different payload than the original'
190+ ) ;
191+ } ) ;
192+
139193 it ( 'should successfully sign payload without walletPassphrase (uses env)' , async function ( ) {
140194 const requestBody = {
141195 walletId : 'ofc-wallet-id-123' ,
0 commit comments