eip155:.
Batch UserOperations require Account Abstraction to be enabled for your organization and client.
Prerequisites
Before using batch UserOperations, ensure you have:- A properly initialized Portal client (see Getting Started)
- An Account Abstraction-enabled client with a smart contract wallet (see Account abstraction)
- An active wallet funded with the token(s) you intend to batch, on an
eip155:chain
sendBatchUserOp
Builds, signs, and broadcasts a batch of token transfers as a single UserOperation. Portal’s paymaster sponsors the gas; the user pays nothing in native tokens.result.data.userOpHash is a UserOperation hash, not an on-chain transaction hash — it will not resolve on a block explorer such as Etherscan or Monadscan. To wait for on-chain inclusion, call portal.waitForConfirmation(result.data.userOpHash, params.chain).Parameters
SendBatchUserOpRequest:
SendBatchUserOpTransaction:
Returns
Promise<BroadcastBatchedUserOpResponse>:
sendBatchedAssets
LikesendBatchUserOp, but appends a gas-reimbursement transfer to the batch. The paymaster still sponsors the gas; the reimbursement call recovers that cost from the user’s smart account, in a fee token of your choice (e.g. USDC).
The method runs a two-pass build: the first pass builds the user’s calls plus a placeholder fee call and estimates the gas cost of the full batch (metadata.estimatedGasCostWei); the second pass builds the final batch with the real fee amount.
GasReimbursement fields
Low-level primitives
If you need direct control over the build/sign/broadcast cycle, use the low-level methods. Unlike the Web SDK, signing auserOpHash on React Native does not require a PortalCurve argument — portal.rawSign takes the message and an optional chain ID instead.
buildBatchedUserOp returns metadata.estimatedGasCostWei — a build-time upper bound (totalGas × maxFeePerGas). This value is '0' on chains where the UserOperation carries no on-chain fee. metadata.totalGas and metadata.maxFeePerGas may also be undefined on backends that predate these fields.buildBatchedUserOp
buildBatchedUserOp(params: BuildBatchedUserOpRequest, traceId?: string): Promise<BuildBatchedUserOpResponse>
UserOperationCall:
broadcastBatchedUserOp
broadcastBatchedUserOp(params: BroadcastBatchedUserOpRequest, traceId?: string): Promise<BroadcastBatchedUserOpResponse>
Error handling
sendBatchUserOp and sendBatchedAssets validate their input before doing any async work, and wrap downstream failures with context about which step failed:
The low-level
buildBatchedUserOp and broadcastBatchedUserOp methods validate their own required fields (chain, calls/userOperation/signature) the same way, throwing before making a network request if any are missing.
Limitations
- Batch UserOperations are only supported on
eip155:(EVM) chains — there is no Solana or other non-EVM equivalent. - Requires Account Abstraction to be enabled for your organization and client; standard MPC wallets cannot batch calls into a single UserOperation.
sendBatchedAssetsrequires the target chain/bundler to report a non-zeroestimatedGasCostWei. UsesendBatchUserOpon chains where gas is fully sponsored with no on-chain fee.
Differences from the Web SDK
The request/response shapes and method names are identical to the Web SDK’s batch UserOperations, including validation rules and thesendBatchedAssets two-pass build/estimate flow. Two things differ:
- Signing the
userOpHash: The Web SDK signs viaportal.rawSign(PortalCurve.SECP256K1, hashToSign). React Native’sportal.rawSigndoesn’t take aPortalCurve— call it asportal.rawSign(hashToSign, chain, options?)instead. waitForConfirmation: On Web,waitForConfirmationroutes anyeip155:chain through the connected provider automatically. On React Native, it resolves an RPC URL fromgatewayConfigfirst — see the warning undersendBatchUserOpabove.
Best practices
- Use
sendBatchUserOp/sendBatchedAssetsfor the common case; drop to the low-levelbuildBatchedUserOp/rawSign/broadcastBatchedUserOpflow only when you need to inspect or modify the UserOperation before it’s signed. - Pass your own
traceIdwhen you need to correlate a batch’sbuildTransaction, build, sign, and broadcast calls with your own logs — otherwise the SDK generates one automatically. - Use
signatureApprovalMemoto tell users what they’re approving, especially forsendBatchedAssets, where the batch includes a fee transfer the user didn’t explicitly request. - Call
portal.waitForConfirmation(result.data.userOpHash, chain)after broadcasting if a subsequent step depends on on-chain inclusion — broadcasting only confirms the bundler accepted the UserOperation, not that it landed on-chain. - For gas reimbursement, keep
convertGasToFeeAmountfast and resilient (it runs mid-flow, between the estimate and final build) and apply abufferBpsmargin to absorb gas-price drift between the two passes.