Transaction building
Stellar caps a transaction at 100 operations. Sendall's core problem is paying more recipients than that with a single wallet signature, since asking someone to review and sign four separate 100-payment transactions defeats the point of a bulk-payment tool. The logic lives in src/lib/stellar/txBuilder.ts.
The simple case: 100 recipients or fewer
One transaction, one payment operation per recipient, one signature. Nothing unusual here.
Beyond 100: a master transaction with pre-authorized chunks
When a batch needs more than one transaction, Sendall builds the payment chunks first (each a normal payment transaction, one per group of up to 100 recipients), then a small master transaction containing only SetOptions operations: one per chunk, each installing that chunk's transaction hash as a preAuthTx signer on the source account.
The wallet only ever signs the master transaction. Every payment chunk is submitted unsigned, right after, in sequence order. Stellar accepts an unsigned transaction if its hash matches a preAuthTx signer already on the source account, so each chunk is authorized directly by the master transaction, not by the chunk before it. The protocol removes a preAuthTx signer automatically once its matching transaction lands, so there's nothing to clean up afterward.
The alternative (asking the wallet to sign every chunk individually) is worse for a reason beyond convenience: most wallets run their own destination and malicious-transaction checks per signature request, so reviewing 4 separate 100-operation payment transactions is both slower and a worse trust story than reviewing one small transaction that says, plainly, "these five hashes are allowed to execute."
Sequence numbers
Each chunk needs its own sequence number, and they have to be submitted in the order they were built, since Stellar processes an account's transactions strictly in sequence order. The master transaction takes the account's current sequence number; each payment chunk takes the next one after that, in the order Sendall built them. buildPaymentChunks requires a freshly loaded Account (fetched immediately before calling it) for exactly this reason: a stale sequence number would make every chunk after the first invalid.
Native XLM to a new account
A native-XLM payment to an address that doesn't exist yet uses createAccount instead of payment, since Stellar has no other way to fund an account into existence. Sendall's balance check (see Check balance) flags this case ahead of time, and the amount has to clear the network's minimum account reserve or the row is marked not ready.
What this means for issued assets
An issued asset (anything with a code and issuer, like USDC) can only be paid to an account that already holds a trustline for it, since there's no createAccount-equivalent for trustlines. Sendall's bulk check confirms both the trustline's existence and that the payment won't push the recipient over their trustline limit, before the recipient is marked Ready.