@@ -4,6 +4,7 @@ import { accounts } from '../../../test/src/constants.js'
44import { mainnet } from '../../chains/index.js'
55import { createClient } from '../../clients/createClient.js'
66import { custom } from '../../clients/transports/custom.js'
7+ import { BundleFailedError } from '../../errors/calls.js'
78import { RpcRequestError } from '../../errors/request.js'
89import type {
910 WalletCallReceipt ,
@@ -238,3 +239,119 @@ test('behavior: `wallet_getCallsStatus` failure', async () => {
238239 } ) ,
239240 ) . rejects . toThrowError ( 'RPC Request failed.' )
240241} )
242+
243+ test ( 'behavior: throwOnFailure = true with failed bundle' , async ( ) => {
244+ const client = createClient ( {
245+ pollingInterval : 100 ,
246+ transport : custom ( {
247+ async request ( { params } ) {
248+ return {
249+ atomic : false ,
250+ chainId : '0x1' ,
251+ id : params [ 0 ] ,
252+ receipts : [ ] ,
253+ status : 400 ,
254+ version : '2.0.0' ,
255+ } satisfies WalletGetCallsStatusReturnType
256+ } ,
257+ } ) ,
258+ } )
259+
260+ try {
261+ await waitForCallsStatus ( client , {
262+ id : 'test-bundle-id' ,
263+ throwOnFailure : true ,
264+ } )
265+ } catch ( e ) {
266+ const error = e as BundleFailedError
267+ expect ( error ) . toBeInstanceOf ( BundleFailedError )
268+ expect ( ( error as BundleFailedError ) . name ) . toBe ( 'BundleFailedError' )
269+ expect ( ( error as BundleFailedError ) . result . status ) . toBe ( 'failure' )
270+ expect ( ( error as BundleFailedError ) . result . statusCode ) . toBe ( 400 )
271+ }
272+ } )
273+
274+ test ( 'behavior: throwOnFailure = false with failed bundle (default)' , async ( ) => {
275+ const client = createClient ( {
276+ pollingInterval : 100 ,
277+ transport : custom ( {
278+ async request ( { params } ) {
279+ return {
280+ atomic : false ,
281+ chainId : '0x1' ,
282+ id : params [ 0 ] ,
283+ receipts : [ ] ,
284+ status : 400 ,
285+ version : '2.0.0' ,
286+ } satisfies WalletGetCallsStatusReturnType
287+ } ,
288+ } ) ,
289+ } )
290+
291+ const id = 'test-bundle-id'
292+
293+ // Should not throw by default (throwOnFailure = false)
294+ const result = await waitForCallsStatus ( client , {
295+ id,
296+ } )
297+
298+ expect ( result . status ) . toBe ( 'failure' )
299+ expect ( result . statusCode ) . toBe ( 400 )
300+ expect ( result . id ) . toBe ( id )
301+ } )
302+
303+ test ( 'behavior: throwOnFailure = false explicitly with failed bundle' , async ( ) => {
304+ const client = createClient ( {
305+ pollingInterval : 100 ,
306+ transport : custom ( {
307+ async request ( { params } ) {
308+ return {
309+ atomic : false ,
310+ chainId : '0x1' ,
311+ id : params [ 0 ] ,
312+ receipts : [ ] ,
313+ status : 500 ,
314+ version : '2.0.0' ,
315+ } satisfies WalletGetCallsStatusReturnType
316+ } ,
317+ } ) ,
318+ } )
319+
320+ const id = 'test-bundle-id'
321+
322+ const result = await waitForCallsStatus ( client , {
323+ id,
324+ throwOnFailure : false ,
325+ } )
326+
327+ expect ( result . status ) . toBe ( 'failure' )
328+ expect ( result . statusCode ) . toBe ( 500 )
329+ expect ( result . id ) . toBe ( id )
330+ } )
331+
332+ test ( 'behavior: throwOnFailure = true with successful bundle' , async ( ) => {
333+ const client = getClient ( )
334+
335+ const { id } = await sendCalls ( client , {
336+ account : accounts [ 0 ] . address ,
337+ calls : [
338+ {
339+ to : accounts [ 1 ] . address ,
340+ value : parseEther ( '1' ) ,
341+ } ,
342+ ] ,
343+ chain : mainnet ,
344+ } )
345+
346+ expect ( id ) . toBeDefined ( )
347+
348+ await mine ( testClient , { blocks : 1 } )
349+
350+ const result = await waitForCallsStatus ( client , {
351+ id,
352+ throwOnFailure : true ,
353+ } )
354+
355+ expect ( result . status ) . toBe ( 'success' )
356+ expect ( result . statusCode ) . toBe ( 200 )
357+ } )
0 commit comments