or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

account.mdadvanced.mdbatch.mdblockchain.mdcontracts.mdens.mdgas-fees.mdindex.mdsigning.mdtransactions.mdwatch.md

batch.mddocs/

0

# Atomic Batch Transactions

1

2

EIP-5792 atomic batch transaction support for executing multiple operations as a single unit. This module provides comprehensive functionality for atomic batch transactions, allowing multiple contract calls to be executed together with guaranteed atomicity.

3

4

## Capabilities

5

6

### useSendCalls

7

8

Hook to send multiple calls atomically using EIP-5792 batch transaction standard.

9

10

```typescript { .api }

11

/**

12

* Hook to send multiple calls atomically

13

* @param parameters - Atomic batch calls configuration with mutation callbacks

14

* @returns Send calls mutation with batch transaction state

15

*/

16

function useSendCalls<config = Config, context = unknown>(

17

parameters?: UseSendCallsParameters<config, context>

18

): UseSendCallsReturnType<config, context>;

19

20

interface UseSendCallsParameters<config = Config, context = unknown> {

21

config?: Config | config;

22

mutation?: {

23

onMutate?: (variables: SendCallsVariables) => Promise<context> | context;

24

onError?: (error: SendCallsErrorType, variables: SendCallsVariables, context?: context) => Promise<void> | void;

25

onSuccess?: (data: SendCallsData, variables: SendCallsVariables, context?: context) => Promise<void> | void;

26

onSettled?: (data?: SendCallsData, error?: SendCallsErrorType, variables?: SendCallsVariables, context?: context) => Promise<void> | void;

27

};

28

}

29

30

interface UseSendCallsReturnType<config = Config, context = unknown> {

31

/** Send atomic batch calls */

32

sendCalls: (variables: SendCallsVariables, options?: SendCallsMutateOptions) => void;

33

/** Async version of sendCalls */

34

sendCallsAsync: (variables: SendCallsVariables, options?: SendCallsMutateAsyncOptions) => Promise<SendCallsData>;

35

/** Batch transaction data */

36

data?: SendCallsData;

37

/** Send calls error */

38

error: SendCallsErrorType | null;

39

/** Send calls status flags */

40

isError: boolean;

41

isIdle: boolean;

42

isPending: boolean;

43

isSuccess: boolean;

44

/** Reset send calls state */

45

reset: () => void;

46

/** Current status */

47

status: 'error' | 'idle' | 'pending' | 'success';

48

/** Additional variables */

49

variables?: SendCallsVariables;

50

}

51

52

interface SendCallsVariables {

53

/** Array of calls to execute atomically */

54

calls: Call[];

55

/** Batch execution capabilities */

56

capabilities?: WalletCapabilities;

57

/** Chain ID for the batch */

58

chainId?: number;

59

/** Version of the batch call standard */

60

version?: string;

61

}

62

63

interface Call {

64

/** Target contract address */

65

to?: Address;

66

/** Call data */

67

data?: Hex;

68

/** Value to send with call */

69

value?: bigint;

70

/** Gas limit for this call */

71

gas?: bigint;

72

/** Chain ID for this specific call */

73

chainId?: number;

74

}

75

76

interface SendCallsData {

77

/** Batch identifier */

78

id: string;

79

}

80

```

81

82

**Usage Example:**

83

84

```typescript

85

import { useSendCalls, useAccount } from "wagmi";

86

import { encodeFunctionData, erc20Abi } from "viem";

87

88

function BatchTransfer() {

89

const { address } = useAccount();

90

const { sendCalls, data: batchId, isPending } = useSendCalls();

91

92

const handleBatchTransfer = () => {

93

if (!address) return;

94

95

// Encode transfer calls

96

const transferCall1 = encodeFunctionData({

97

abi: erc20Abi,

98

functionName: 'transfer',

99

args: ['0x742d35Cc6634C0532925a3b8D', 1000000000000000000n], // 1 token

100

});

101

102

const transferCall2 = encodeFunctionData({

103

abi: erc20Abi,

104

functionName: 'transfer',

105

args: ['0x8ba1f109551bD432803012645Hac136c', 500000000000000000n], // 0.5 tokens

106

});

107

108

sendCalls({

109

calls: [

110

{

111

to: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // DAI

112

data: transferCall1,

113

},

114

{

115

to: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // DAI

116

data: transferCall2,

117

},

118

],

119

});

120

};

121

122

return (

123

<div>

124

<button onClick={handleBatchTransfer} disabled={!address || isPending}>

125

{isPending ? 'Sending Batch...' : 'Send Batch Transfers'}

126

</button>

127

{batchId && <p>Batch ID: {batchId}</p>}

128

</div>

129

);

130

}

131

```

132

133

### useCallsStatus

134

135

Hook to check the status of batched calls by their batch ID.

136

137

```typescript { .api }

138

/**

139

* Hook to check status of batched calls

140

* @param parameters - Calls status query parameters

141

* @returns Current status of the batched calls

142

*/

143

function useCallsStatus<config = Config, selectData = UseCallsStatusReturnType>(

144

parameters: UseCallsStatusParameters<config, selectData>

145

): UseCallsStatusReturnType<selectData>;

146

147

interface UseCallsStatusParameters<config = Config, selectData = UseCallsStatusReturnType> {

148

/** Batch ID to check status for */

149

id: string;

150

/** Chain ID where batch was submitted */

151

chainId?: config['chains'][number]['id'];

152

config?: Config | config;

153

query?: {

154

enabled?: boolean;

155

staleTime?: number;

156

gcTime?: number;

157

refetchInterval?: number;

158

select?: (data: UseCallsStatusReturnType) => selectData;

159

};

160

}

161

162

interface UseCallsStatusReturnType {

163

/** Current batch status */

164

status: 'PENDING' | 'CONFIRMED' | 'FAILED';

165

/** Individual call receipts */

166

receipts?: CallReceipt[];

167

}

168

169

interface CallReceipt {

170

/** Transaction hash for this call */

171

transactionHash: Hash;

172

/** Block hash */

173

blockHash: Hash;

174

/** Block number */

175

blockNumber: bigint;

176

/** Gas used */

177

gasUsed: bigint;

178

/** Call status */

179

status: 'success' | 'reverted';

180

/** Event logs */

181

logs: Log[];

182

}

183

```

184

185

### useWaitForCallsStatus

186

187

Hook to wait for batched calls to complete with polling support.

188

189

```typescript { .api }

190

/**

191

* Hook to wait for calls to complete

192

* @param parameters - Wait for calls parameters

193

* @returns Final status when calls complete

194

*/

195

function useWaitForCallsStatus<config = Config, selectData = UseWaitForCallsStatusReturnType>(

196

parameters: UseWaitForCallsStatusParameters<config, selectData>

197

): UseWaitForCallsStatusReturnType<selectData>;

198

199

interface UseWaitForCallsStatusParameters<config = Config, selectData = UseWaitForCallsStatusReturnType> {

200

/** Batch ID to wait for */

201

id: string;

202

/** Chain ID */

203

chainId?: config['chains'][number]['id'];

204

/** Polling interval in milliseconds */

205

pollingInterval?: number;

206

/** Timeout in milliseconds */

207

timeout?: number;

208

config?: Config | config;

209

query?: {

210

enabled?: boolean;

211

gcTime?: number;

212

refetchInterval?: number;

213

retry?: boolean | number;

214

select?: (data: UseWaitForCallsStatusReturnType) => selectData;

215

};

216

}

217

218

type UseWaitForCallsStatusReturnType = UseCallsStatusReturnType;

219

```

220

221

**Usage Example:**

222

223

```typescript

224

import { useSendCalls, useWaitForCallsStatus } from "wagmi";

225

226

function BatchWithStatus() {

227

const { sendCalls, data: batchId } = useSendCalls();

228

229

const {

230

data: status,

231

isLoading,

232

isSuccess,

233

isError

234

} = useWaitForCallsStatus({

235

id: batchId || '',

236

query: { enabled: !!batchId }

237

});

238

239

const handleBatch = () => {

240

sendCalls({

241

calls: [

242

{ to: '0x742d35Cc6634C0532925a3b8D', value: 1000000000000000000n },

243

{ to: '0x8ba1f109551bD432803012645Hac136c', value: 500000000000000000n },

244

],

245

});

246

};

247

248

return (

249

<div>

250

<button onClick={handleBatch}>Send Batch</button>

251

252

{batchId && (

253

<div>

254

<p>Batch ID: {batchId}</p>

255

{isLoading && <p>Waiting for confirmation...</p>}

256

{isSuccess && (

257

<div>

258

<p>Status: {status?.status}</p>

259

<p>Receipts: {status?.receipts?.length || 0}</p>

260

</div>

261

)}

262

{isError && <p>Batch failed</p>}

263

</div>

264

)}

265

</div>

266

);

267

}

268

```

269

270

### useShowCallsStatus

271

272

Hook to show calls status in the wallet UI for user visibility.

273

274

```typescript { .api }

275

/**

276

* Hook to show calls status in wallet UI

277

* @param parameters - Show calls status configuration

278

* @returns Show calls status mutation

279

*/

280

function useShowCallsStatus<config = Config, context = unknown>(

281

parameters?: UseShowCallsStatusParameters<config, context>

282

): UseShowCallsStatusReturnType<config, context>;

283

284

interface UseShowCallsStatusParameters<config = Config, context = unknown> {

285

config?: Config | config;

286

mutation?: {

287

onMutate?: (variables: ShowCallsStatusVariables) => Promise<context> | context;

288

onError?: (error: ShowCallsStatusErrorType, variables: ShowCallsStatusVariables, context?: context) => Promise<void> | void;

289

onSuccess?: (data: ShowCallsStatusData, variables: ShowCallsStatusVariables, context?: context) => Promise<void> | void;

290

onSettled?: (data?: ShowCallsStatusData, error?: ShowCallsStatusErrorType, variables?: ShowCallsStatusVariables, context?: context) => Promise<void> | void;

291

};

292

}

293

294

interface UseShowCallsStatusReturnType<config = Config, context = unknown> {

295

/** Show calls status in wallet */

296

showCallsStatus: (variables: ShowCallsStatusVariables, options?: ShowCallsStatusMutateOptions) => void;

297

/** Async version of showCallsStatus */

298

showCallsStatusAsync: (variables: ShowCallsStatusVariables, options?: ShowCallsStatusMutateAsyncOptions) => Promise<ShowCallsStatusData>;

299

/** Show calls status data */

300

data?: ShowCallsStatusData;

301

/** Show calls status error */

302

error: ShowCallsStatusErrorType | null;

303

/** Show calls status flags */

304

isError: boolean;

305

isIdle: boolean;

306

isPending: boolean;

307

isSuccess: boolean;

308

/** Reset show calls status state */

309

reset: () => void;

310

/** Current status */

311

status: 'error' | 'idle' | 'pending' | 'success';

312

/** Additional variables */

313

variables?: ShowCallsStatusVariables;

314

}

315

316

interface ShowCallsStatusVariables {

317

/** Batch ID to show status for */

318

id: string;

319

}

320

321

type ShowCallsStatusData = boolean; // Whether wallet showed the status

322

```

323

324

### useCapabilities

325

326

Hook to get wallet capabilities for batch transaction support.

327

328

```typescript { .api }

329

/**

330

* Hook to get wallet capabilities

331

* @param parameters - Capabilities query parameters

332

* @returns Available wallet capabilities

333

*/

334

function useCapabilities<config = Config, selectData = UseCapabilitiesReturnType>(

335

parameters?: UseCapabilitiesParameters<config, selectData>

336

): UseCapabilitiesReturnType<selectData>;

337

338

interface UseCapabilitiesParameters<config = Config, selectData = UseCapabilitiesReturnType> {

339

/** Account to get capabilities for */

340

account?: Address;

341

/** Chain ID */

342

chainId?: config['chains'][number]['id'];

343

config?: Config | config;

344

query?: {

345

enabled?: boolean;

346

staleTime?: number;

347

gcTime?: number;

348

select?: (data: UseCapabilitiesReturnType) => selectData;

349

};

350

}

351

352

interface UseCapabilitiesReturnType {

353

[chainId: number]: WalletCapabilities;

354

}

355

356

interface WalletCapabilities {

357

/** Atomic batch transaction support */

358

atomicBatch?: {

359

supported: boolean;

360

};

361

/** Paymaster support */

362

paymasterService?: {

363

supported: boolean;

364

};

365

/** Session key support */

366

sessionKeys?: {

367

supported: boolean;

368

};

369

/** Additional capabilities */

370

[key: string]: unknown;

371

}

372

```

373

374

**Usage Example:**

375

376

```typescript

377

import { useCapabilities, useAccount } from "wagmi";

378

379

function CapabilitiesChecker() {

380

const { address } = useAccount();

381

const { data: capabilities, isLoading } = useCapabilities({

382

account: address,

383

});

384

385

if (isLoading) return <div>Checking capabilities...</div>;

386

387

return (

388

<div>

389

<h3>Wallet Capabilities</h3>

390

{capabilities && Object.entries(capabilities).map(([chainId, caps]) => (

391

<div key={chainId}>

392

<h4>Chain {chainId}</h4>

393

<p>Atomic Batch: {caps.atomicBatch?.supported ? '✅' : '❌'}</p>

394

<p>Paymaster: {caps.paymasterService?.supported ? '✅' : '❌'}</p>

395

<p>Session Keys: {caps.sessionKeys?.supported ? '✅' : '❌'}</p>

396

</div>

397

))}

398

</div>

399

);

400

}

401

```

402

403

### useCall

404

405

Hook to execute a single call (part of the batch transaction system).

406

407

```typescript { .api }

408

/**

409

* Hook to execute a single call

410

* @param parameters - Call execution parameters

411

* @returns Call result

412

*/

413

function useCall<config = Config, selectData = UseCallReturnType>(

414

parameters: UseCallParameters<config, selectData>

415

): UseCallReturnType<selectData>;

416

417

interface UseCallParameters<config = Config, selectData = UseCallReturnType> {

418

/** Target address */

419

to?: Address;

420

/** Call data */

421

data?: Hex;

422

/** Value to send */

423

value?: bigint;

424

/** Account to call from */

425

account?: Address;

426

/** Block number to call at */

427

blockNumber?: bigint;

428

blockTag?: 'latest' | 'earliest' | 'pending' | 'safe' | 'finalized';

429

/** Chain ID */

430

chainId?: config['chains'][number]['id'];

431

/** Gas limit */

432

gas?: bigint;

433

/** Gas price */

434

gasPrice?: bigint;

435

/** Max fee per gas */

436

maxFeePerGas?: bigint;

437

/** Max priority fee per gas */

438

maxPriorityFeePerGas?: bigint;

439

config?: Config | config;

440

query?: {

441

enabled?: boolean;

442

staleTime?: number;

443

select?: (data: UseCallReturnType) => selectData;

444

};

445

}

446

447

type UseCallReturnType = Hex | undefined;

448

```

449

450

## Advanced Batch Transaction Patterns

451

452

### Multi-Token Batch Operations

453

454

```typescript

455

import { useSendCalls, useCapabilities } from "wagmi";

456

import { encodeFunctionData, erc20Abi, parseEther } from "viem";

457

458

function MultiTokenBatch() {

459

const { data: capabilities } = useCapabilities();

460

const { sendCalls, isPending } = useSendCalls();

461

462

const canBatch = capabilities?.[1]?.atomicBatch?.supported;

463

464

const handleComplexBatch = () => {

465

if (!canBatch) {

466

alert('Wallet does not support atomic batch transactions');

467

return;

468

}

469

470

// Create multiple token operations

471

const approveUSDC = encodeFunctionData({

472

abi: erc20Abi,

473

functionName: 'approve',

474

args: ['0x7f39C581F595B53c5cb19bD0b3f8DA6c935E2Ca0', parseEther('1000')],

475

});

476

477

const transferDAI = encodeFunctionData({

478

abi: erc20Abi,

479

functionName: 'transfer',

480

args: ['0x742d35Cc6634C0532925a3b8D', parseEther('500')],

481

});

482

483

const transferUSDC = encodeFunctionData({

484

abi: erc20Abi,

485

functionName: 'transfer',

486

args: ['0x8ba1f109551bD432803012645Hac136c', 1000000000n], // 1000 USDC

487

});

488

489

sendCalls({

490

calls: [

491

{

492

to: '0xA0b86a33E6417C90CC5F6d2c4a29f9D7e5D8ecf0', // USDC

493

data: approveUSDC,

494

},

495

{

496

to: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // DAI

497

data: transferDAI,

498

},

499

{

500

to: '0xA0b86a33E6417C90CC5F6d2c4a29f9D7e5D8ecf0', // USDC

501

data: transferUSDC,

502

},

503

],

504

});

505

};

506

507

return (

508

<div>

509

<p>Batch Support: {canBatch ? '✅' : '❌'}</p>

510

<button

511

onClick={handleComplexBatch}

512

disabled={!canBatch || isPending}

513

>

514

{isPending ? 'Processing...' : 'Execute Multi-Token Batch'}

515

</button>

516

</div>

517

);

518

}

519

```

520

521

### Batch Status Monitor

522

523

```typescript

524

import {

525

useSendCalls,

526

useCallsStatus,

527

useShowCallsStatus

528

} from "wagmi";

529

import { useState } from "react";

530

531

function BatchStatusMonitor() {

532

const [batchIds, setBatchIds] = useState<string[]>([]);

533

534

const { sendCalls } = useSendCalls({

535

mutation: {

536

onSuccess(data) {

537

setBatchIds(prev => [...prev, data.id]);

538

},

539

},

540

});

541

542

const { showCallsStatus } = useShowCallsStatus();

543

544

return (

545

<div>

546

<h3>Batch Status Monitor</h3>

547

548

<button onClick={() => sendCalls({

549

calls: [

550

{ to: '0x742d35Cc6634C0532925a3b8D', value: parseEther('0.01') }

551

]

552

})}>

553

Send New Batch

554

</button>

555

556

<div>

557

<h4>Active Batches ({batchIds.length})</h4>

558

{batchIds.map(id => (

559

<BatchStatusItem

560

key={id}

561

batchId={id}

562

onShowStatus={() => showCallsStatus({ id })}

563

/>

564

))}

565

</div>

566

</div>

567

);

568

}

569

570

function BatchStatusItem({

571

batchId,

572

onShowStatus

573

}: {

574

batchId: string;

575

onShowStatus: () => void;

576

}) {

577

const { data: status, isLoading } = useCallsStatus({ id: batchId });

578

579

return (

580

<div style={{ border: '1px solid #ccc', padding: '8px', margin: '4px' }}>

581

<p>ID: {batchId}</p>

582

<p>Status: {isLoading ? 'Loading...' : status?.status}</p>

583

<p>Receipts: {status?.receipts?.length || 0}</p>

584

<button onClick={onShowStatus}>Show in Wallet</button>

585

</div>

586

);

587

}

588

```

589

590

## Common Types

591

592

```typescript { .api }

593

type Address = `0x${string}`;

594

type Hash = `0x${string}`;

595

type Hex = `0x${string}`;

596

597

interface Log {

598

address: Address;

599

topics: readonly Hash[];

600

data: Hex;

601

blockHash?: Hash;

602

blockNumber?: bigint;

603

transactionHash?: Hash;

604

transactionIndex?: number;

605

logIndex?: number;

606

removed?: boolean;

607

}

608

609

interface SendCallsMutateOptions {

610

onError?: (error: Error, variables: SendCallsVariables, context?: unknown) => void;

611

onSuccess?: (data: SendCallsData, variables: SendCallsVariables, context?: unknown) => void;

612

onSettled?: (data?: SendCallsData, error?: Error, variables?: SendCallsVariables, context?: unknown) => void;

613

}

614

615

interface ShowCallsStatusMutateOptions {

616

onError?: (error: Error, variables: ShowCallsStatusVariables, context?: unknown) => void;

617

onSuccess?: (data: boolean, variables: ShowCallsStatusVariables, context?: unknown) => void;

618

onSettled?: (data?: boolean, error?: Error, variables?: ShowCallsStatusVariables, context?: unknown) => void;

619

}

620

621

type SendCallsErrorType = Error;

622

type ShowCallsStatusErrorType = Error;

623

624

interface BatchTransactionSummary {

625

id: string;

626

status: 'PENDING' | 'CONFIRMED' | 'FAILED';

627

callCount: number;

628

successCount: number;

629

failureCount: number;

630

totalGasUsed?: bigint;

631

blockNumber?: bigint;

632

}

633

```