Target End State
- All transactions originate client-side and can be submitted through the authenticated World App RPC.
- Users can pick a paymaster or opt to pay their own gas.
- Transaction metadata exposed by the app backend is sourced from an on-chain indexer rather than custom DB rows.
- No on-chain operation needs backend-specific handling or trust; Bedrock fully operates calldata/signatures.
- Importing Safe wallets deployed elsewhere is conceptually possible.
Technical Details
Definitions
UserOperation: an ERC-4337 UserOperation.
Supported Flows
- Bedrock crafts every user-signature transaction client-side; vault withdraw, wallet deployment, and OP migration may temporarily follow legacy flows while we finalize gas-cost tradeoffs.
- ERC-4337 becomes the default for all users, so there is one path for crafting and submitting transactions.
Architecture Overview
- A World App RPC endpoint in the backend processes whitelisted
UserOperations, routes them to our providers, and supports botheth_sendUserOperationand a sponsorship helper. - World App uses Bedrock helpers (for transfers, swaps, mini apps, etc.) to build calldata, sign locally, and submit to
/v1/rpc.
World App RPC
/v1/rpcis authenticated, mirrors Ethereum JSON-RPC conventions.- Only whitelisted operations are relayed in V1; requests outside that list are rejected.
- Mini App submissions use a simulation step during sponsorship (see below) so the user can confirm results; Bedrock-native flows skip extra simulation because calldata is deterministic and already surfaced in the checkout UI.
- The second parameter is the EntryPoint contract.
eip7702Authis optional but accepted so we can submit to 7702-enabled networks without rejecting extra authorization data.- Backends persist pending transactions today (queue + DB) but will defer to the shared indexer once it lands.
- Native apps add a
provider-nameheader (any,alchemy, orpimlico) so/v1/rpc/{network}can steer sponsorship and relaying to a specific bundler if needed. - We expose
wa_getUserOperationReceiptto retrieve high-level status (pending,error,mined_success,mined_revert) and metadata such assourceId,selfSponsorToken,selfSponsorAmount, andtransactionHashonce available. This replaces one-off/statusendpoints per transaction type.
wa_sponsorUserOperation
- Invoked via
wa_sponsorUserOperationon/v1/rpcto fetch paymaster data, updated gas limits, and provider metadata before Bedrock finalizes theUserOperation. - Backend selects between our paymaster providers (Alchemy, Pimlico, etc.), requests sponsorship data, and receives a simulation result that also guards against low balances.
- An optional third param
{ token: <address> }lets clients request self-sponsored gas by identifying which ERC-20 they plan to spend; backend responds withfee.token/fee.amountdescribing that path. - Mini App sponsorship also runs a provider simulation; results are forwarded to World App so the user can explicitly consent before signing.
- Response fields include:
paymaster,paymasterData,preVerificationGas,verificationGasLimit,callGasLimit,paymasterVerificationGasLimit,paymasterPostOpGasLimit,maxPriorityFeePerGas,maxFeePerGas,providerName, and a fee descriptor (e.g.,{ token: "ETH", amount: "0", reason: "disabled" }). - Bedrock appends
paymasterAndData, signs locally, and replays the send: the backend cannot tamper with calldata between sponsorship and submission.
Nonces & nonceKey
- With ERC-4337 we avoid sequential Safe nonces and instead follow RIP-7712, using
0for the sequence while encoding uniqueness into a 24-bytenonceKey. - Format (all fields
big-endian):
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 1 B | typeId | Stable TransactionType enum (1–255). 0x00 reserved for legacy v0 nonces. |
| 1–5 | 5 B | magic | Constant 0x626472636b ("bdrck"). Distinguishes Bedrock-built operations; collision probability . |
| 6 | 1 B | instruction | Reserved bitfield (currently 0). Used later by the indexer. |
| 7–16 | 10 B | subtype | Transaction-type metadata (e.g., first 10 bytes of hashed miniAppId). Parsed per typeId. |
| 17–23 | 7 B | random | 56 bits of entropy; collision risk for 1M tx in a bucket . |
- If
magicis missing, the indexer treats the transaction as external/unknown and falls back to legacy parsing. TransactionTypeordering must never change; add new IDs at the tail.
Duplicate-mitigation UX
- High network fees trigger an automatic warning on the wallet home and all checkout surfaces with ETA guidance.
- Bedrock inspects pending transactions and warns the user if a similar action is already queued:
- Second transfer to the same destination
- Another swap over the same route
- Any transaction toward the same Mini App
- Duplicate off-ramps
Wallet Upgrades
- Safe accounts must be on Safe v1.4.0 with the 4337 module enabled; otherwise,
wa_sponsorUserOperationsimulations revert. - On every app launch we call
/world-chain, which returnsrequiresUpgrade. Iftrue, the UI blocks until the user runs the combined Safe upgrade + 4337 module enablement flow.