From a8af86b5b9c47dd25f4e49c87873adf6c486eeee Mon Sep 17 00:00:00 2001 From: aurel-fr <105201452+aurel-fr@users.noreply.github.com> Date: Thu, 28 Aug 2025 10:37:02 -0700 Subject: [PATCH 1/7] docs: transactions --- world-app/transactions.mdx | 81 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 world-app/transactions.mdx diff --git a/world-app/transactions.mdx b/world-app/transactions.mdx new file mode 100644 index 0000000..7a2e795 --- /dev/null +++ b/world-app/transactions.mdx @@ -0,0 +1,81 @@ +--- +title: "Client-side transactions" +description: "Spec for client-side transaction architecture, World App RPC, nonces, and related details." +--- + +## Definitions + +- `UserOperation`: Refers to an ERC-4337 [UserOperation](https://docs.erc4337.io/). + +## V1 Technical Details + +### High-level Overview + +**What we support:** + +- All transactions crafted client-side through Bedrock. +- All main transactions in World App that require a user signature will use ERC-4337 for all users. + +**How?** + +1. A **World App RPC** endpoint in our backend processes whitelisted `UserOperation`s, routing them to our RPC providers. It behaves similarly to a standard Ethereum JSON-RPC, supporting `eth_sendUserOperation`, and exposes a custom sponsorship method. + +2. World App (through Bedrock) exposes methods to craft transactions for supported operations. Crafted transactions are signed client-side and submitted to the World App RPC endpoint. + +```mermaid +sequenceDiagram + actor User + User->>WorldApp: Request token transfer (taps checkout button) + WorldApp->>Bedrock: .transfer(token, amount, to) + Bedrock->>Bedrock: Perform basic validation (params, min balance, sender != receiver, ...) + Bedrock->>Bedrock: Prepare ERC-20 token transfer + Bedrock->>Bedrock: Prepare UserOperation with dummy signature + Bedrock->>WorldAppBackend: /v1/rpc with wa_sponsorUserOperation (see below) + WorldAppBackend->>WorldAppBackend: Check internal daily limits + WorldAppBackend->>WorldAppBackend: Sanctions check + WorldAppBackend->>WorldAppBackend: Select Paymaster + WorldAppBackend->>Alchemy/Pimlico: Get Paymaster Data (includes simulation) + Note over WorldAppBackend,Alchemy/Pimlico: Simulation will also ensure user has enough balance + alt has simulationResult? + Bedrock->>WorldApp: simulationResult + WorldApp->>User: Prompt for additional consent + User ->> WorldApp: Consent + WorldApp ->> Bedrock: execute() + end + Bedrock->>Bedrock: Append paymasterAndData to construct final UserOperation + Note over Bedrock: Critical Bedrock does this. No way for the backend to tamper. + Bedrock->>Bedrock: Sign transaction + Bedrock->>WorldAppBackend: Submit UserOperation to /v1/rpc + WorldAppBackend->>Alchemy/Pimlico: Relay tx (through a queue) + WorldAppBackend->>Bedrock: Ack receipt + Bedrock->>WorldApp: Return H(UserOperation) +``` + +### World App RPC + +1. The _World App RPC_ is an authenticated endpoint that aligns with Ethereum JSON-RPC conventions and supports `eth_sendUserOperation`. +2. Initially, only whitelisted operations are accepted; other operations are rejected. +3. Following existing patterns, only Mini App transactions are additionally simulated via `wa_sponsorUserOperation` to analyze common attack vectors. + 1. When a simulation is run, results are presented to the user, who must confirm before the transaction is signed and relayed. + 2. **Why only Mini App transactions?** Other operations are hard-coded in Bedrock; outcomes are deterministic and already displayed in the checkout UI. + +#### SponsorUserOperation + +To request TFH sponsorship and fully craft an ERC-4337 `UserOperation`, the RPC exposes `wa_sponsorUserOperation`. It returns paymaster data and gas parameters (e.g., `paymaster`, `paymasterData`, `preVerificationGas`, `verificationGasLimit`, `callGasLimit`, fee caps). Bedrock appends `paymasterAndData` client-side before signing and submission. + +### Nonces + +With ERC-4337, nonce handling is more flexible. World App transactions define unique nonces per operation while using a `0` sequence for most flows. This reduces latency (no extra on-chain nonce read) and allows safe parallelism. + +This is how nonces are constructed (following [RIP-7712](https://docs.erc4337.io/core-standards/rip-7712)): + +To mitigate users accidentally submitting duplicate transactions during high congestion (e.g., Alice pays Bob $1, realizes the transaction is pending after a few minutes, gets frustrated and submits a second $1 payment; when gas fees drop, both transactions execute), we take the following actions: + +1. When fees are high, a **warning** message informing users of network congestion and explaining potential delays and ETAs is automatically shown on: + 1. The wallet home screen + 2. All checkout screens +2. The app detects potential undesired duplicates by checking pending transactions and shows a modal warning when similar actions are already queued: + 1. If the user attempts another transfer to the same destination address. + 2. If the user attempts a swap in the same route. + 3. If the user attempts any transaction to the same Mini App. + 4. If the user attempts another off-ramp operation. From e891b13f6ccdcb431667c649fdfbe9326d3b0452 Mon Sep 17 00:00:00 2001 From: aurel-fr <105201452+aurel-fr@users.noreply.github.com> Date: Thu, 28 Aug 2025 10:39:54 -0700 Subject: [PATCH 2/7] docs --- world-app/transactions.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/world-app/transactions.mdx b/world-app/transactions.mdx index 7a2e795..dd9c80d 100644 --- a/world-app/transactions.mdx +++ b/world-app/transactions.mdx @@ -61,13 +61,13 @@ sequenceDiagram #### SponsorUserOperation -To request TFH sponsorship and fully craft an ERC-4337 `UserOperation`, the RPC exposes `wa_sponsorUserOperation`. It returns paymaster data and gas parameters (e.g., `paymaster`, `paymasterData`, `preVerificationGas`, `verificationGasLimit`, `callGasLimit`, fee caps). Bedrock appends `paymasterAndData` client-side before signing and submission. +To request TFH sponsorship and fully craft an ERC-4337 `UserOperation`, the RPC exposes `wa_sponsorUserOperation`. It returns paymaster data and gas parameters (e.g., `paymaster`, `paymasterData`, `preVerificationGas`, `verificationGasLimit`, `callGasLimit`, fee caps). ### Nonces With ERC-4337, nonce handling is more flexible. World App transactions define unique nonces per operation while using a `0` sequence for most flows. This reduces latency (no extra on-chain nonce read) and allows safe parallelism. -This is how nonces are constructed (following [RIP-7712](https://docs.erc4337.io/core-standards/rip-7712)): +This is how nonces are constructed (following [RIP-7712](https://docs.erc4337.io/core-standards/rip-7712)) To mitigate users accidentally submitting duplicate transactions during high congestion (e.g., Alice pays Bob $1, realizes the transaction is pending after a few minutes, gets frustrated and submits a second $1 payment; when gas fees drop, both transactions execute), we take the following actions: From c4d3e7badef38cb987caf305260220f254a9518f Mon Sep 17 00:00:00 2001 From: pd Date: Thu, 19 Feb 2026 14:04:37 -0800 Subject: [PATCH 3/7] updates 1 --- world-app/transactions.mdx | 148 +++++++++++++++++++++++++++++-------- 1 file changed, 117 insertions(+), 31 deletions(-) diff --git a/world-app/transactions.mdx b/world-app/transactions.mdx index dd9c80d..d218e18 100644 --- a/world-app/transactions.mdx +++ b/world-app/transactions.mdx @@ -1,26 +1,35 @@ ---- title: "Client-side transactions" -description: "Spec for client-side transaction architecture, World App RPC, nonces, and related details." +description: "Spec for client-side transaction architecture, World App RPC, nonce layout, and wallet readiness." + --- -## Definitions +## Context & Goals + +- Part of **Protocolization** for World App: all signature-requiring flows are crafted client-side via open-source Bedrock, minimizing trust in the TFH backend. + +## Target End State -- `UserOperation`: Refers to an ERC-4337 [UserOperation](https://docs.erc4337.io/). +1. All transactions originate client-side and can be submitted through the authenticated World App RPC. +2. Users can pick a paymaster or opt to pay their own gas. +3. Transaction metadata exposed by the app backend is sourced from an on-chain indexer rather than custom DB rows. +4. No on-chain operation needs backend-specific handling or trust; Bedrock fully operates calldata/signatures. +5. Importing Safe wallets deployed elsewhere is conceptually possible. -## V1 Technical Details +## Technical Details -### High-level Overview +### Definitions -**What we support:** +- `UserOperation`: an ERC-4337 [UserOperation](https://docs.erc4337.io/). -- All transactions crafted client-side through Bedrock. -- All main transactions in World App that require a user signature will use ERC-4337 for all users. +### Supported Flows -**How?** +- 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. -1. A **World App RPC** endpoint in our backend processes whitelisted `UserOperation`s, routing them to our RPC providers. It behaves similarly to a standard Ethereum JSON-RPC, supporting `eth_sendUserOperation`, and exposes a custom sponsorship method. +### Architecture Overview -2. World App (through Bedrock) exposes methods to craft transactions for supported operations. Crafted transactions are signed client-side and submitted to the World App RPC endpoint. +1. A **World App RPC** endpoint in the backend processes whitelisted `UserOperation`s, routes them to our providers, and supports both `eth_sendUserOperation` and a sponsorship helper. +2. World App uses Bedrock helpers (for transfers, swaps, mini apps, etc.) to build calldata, sign locally, and submit to `/v1/rpc`. ```mermaid sequenceDiagram @@ -53,29 +62,106 @@ sequenceDiagram ### World App RPC -1. The _World App RPC_ is an authenticated endpoint that aligns with Ethereum JSON-RPC conventions and supports `eth_sendUserOperation`. -2. Initially, only whitelisted operations are accepted; other operations are rejected. -3. Following existing patterns, only Mini App transactions are additionally simulated via `wa_sponsorUserOperation` to analyze common attack vectors. - 1. When a simulation is run, results are presented to the user, who must confirm before the transaction is signed and relayed. - 2. **Why only Mini App transactions?** Other operations are hard-coded in Bedrock; outcomes are deterministic and already displayed in the checkout UI. +1. `/v1/rpc` is authenticated, mirrors Ethereum JSON-RPC conventions. +2. Only whitelisted operations are relayed in V1; requests outside that list are rejected. +3. 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. + +Example payload: + +```json +POST /v1/rpc +{ + "jsonrpc": "2.0", + "id": "tx_", + "method": "eth_sendUserOperation", + "params": [ + { + "sender": "0x...", + "nonce": "0x626472636b...", + "factory": "0x...", + "factoryData": "0x...", + "callData": "0x...", + "callGasLimit": "0x13880", + "verificationGasLimit": "0x60B01", + "preVerificationGas": "0xD3E3", + "maxPriorityFeePerGas": "0x3B9ACA00", + "maxFeePerGas": "0x7A5CF70D5", + "paymaster": "0x...", + "paymasterVerificationGasLimit": "0x0", + "paymasterPostOpGasLimit": "0x0", + "paymasterData": null, + "signature": "0x...", + "eip7702Auth": { "address": "0x...", "chainId": "0x1", "nonce": "0x1", "r": "0x...", "s": "0x...", "v": "0x1b" } + }, + "0x0000000071727De22E5E9d8BAf0edAc6f37da032" + ] +} +``` + +- The second parameter is the EntryPoint contract. +- `eip7702Auth` is 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-name` header (`any`, `alchemy`, or `pimlico`) so `/v1/rpc/{network}` can steer sponsorship and relaying to a specific bundler if needed. +- We expose `wa_getUserOperationReceipt` to retrieve high-level status (`pending`, `error`, `mined_success`, `mined_revert`) and metadata such as `sourceId`, `selfSponsorToken`, `selfSponsorAmount`, and `transactionHash` once available. This replaces one-off `/status` endpoints per transaction type. + +### `wa_sponsorUserOperation` + +- Invoked via `wa_sponsorUserOperation` on `/v1/rpc` to fetch paymaster data, updated gas limits, and provider metadata before Bedrock finalizes the `UserOperation`. +- 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:
}` lets clients request **self-sponsored** gas by identifying which ERC-20 they plan to spend; backend responds with `fee.token`/`fee.amount` describing 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. + +Example: + +```json +{ + "jsonrpc": "2.0", + "result": { + "paymaster": "0x0000000000000039cd5e8aE05257CE51C473ddd1", + "paymasterData": "0x01000066d1...", + "preVerificationGas": "0x350f7", + "verificationGasLimit": "0x501ab", + "callGasLimit": "0x212df", + "paymasterVerificationGasLimit": "0x6dae", + "paymasterPostOpGasLimit": "0x706e", + "maxPriorityFeePerGas": "0x3B9ACA00", + "maxFeePerGas": "0x7A5CF70D5", + "providerName": "alchemy", + "fee": { "token": "ETH", "amount": "0", "reason": "disabled" } + }, + "id": "tx_" +} +``` + +### Nonces & `nonceKey` -#### SponsorUserOperation +- With ERC-4337 we avoid sequential Safe nonces and instead follow [RIP-7712](https://docs.erc4337.io/core-standards/rip-7712), using `0` for the sequence while encoding uniqueness into a 24-byte `nonceKey`. +- Format (all fields `big-endian`): -To request TFH sponsorship and fully craft an ERC-4337 `UserOperation`, the RPC exposes `wa_sponsorUserOperation`. It returns paymaster data and gas parameters (e.g., `paymaster`, `paymasterData`, `preVerificationGas`, `verificationGasLimit`, `callGasLimit`, fee caps). +| 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 ≈ 9.1×10⁻¹³. | +| 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 ≈ 0.0007%. | -### Nonces +- If `magic` is missing, the indexer treats the transaction as external/unknown and falls back to legacy parsing. +- `TransactionType` ordering must never change; add new IDs at the tail. -With ERC-4337, nonce handling is more flexible. World App transactions define unique nonces per operation while using a `0` sequence for most flows. This reduces latency (no extra on-chain nonce read) and allows safe parallelism. +### Duplicate-mitigation UX -This is how nonces are constructed (following [RIP-7712](https://docs.erc4337.io/core-standards/rip-7712)) +- 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 -To mitigate users accidentally submitting duplicate transactions during high congestion (e.g., Alice pays Bob $1, realizes the transaction is pending after a few minutes, gets frustrated and submits a second $1 payment; when gas fees drop, both transactions execute), we take the following actions: +### Wallet Upgrades -1. When fees are high, a **warning** message informing users of network congestion and explaining potential delays and ETAs is automatically shown on: - 1. The wallet home screen - 2. All checkout screens -2. The app detects potential undesired duplicates by checking pending transactions and shows a modal warning when similar actions are already queued: - 1. If the user attempts another transfer to the same destination address. - 2. If the user attempts a swap in the same route. - 3. If the user attempts any transaction to the same Mini App. - 4. If the user attempts another off-ramp operation. +- Safe accounts must be on Safe v1.4.0 with the 4337 module enabled; otherwise, `wa_sponsorUserOperation` simulations revert. +- On every app launch we call `/world-chain`, which now returns `requiresUpgrade`. If `true`, the UI blocks until the user runs the combined Safe upgrade + 4337 module enablement flow. +- Wallet upgrades also prepare the ground for Project Safeguard and future Safe import functionality. From 696511d8727d85a06157f9514ecdade592322ec5 Mon Sep 17 00:00:00 2001 From: pd Date: Thu, 19 Feb 2026 14:06:25 -0800 Subject: [PATCH 4/7] clean up --- world-app/transactions.mdx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/world-app/transactions.mdx b/world-app/transactions.mdx index d218e18..5a6ac90 100644 --- a/world-app/transactions.mdx +++ b/world-app/transactions.mdx @@ -142,8 +142,8 @@ Example: | 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 ≈ 9.1×10⁻¹³. | +| 0 | 1 B | `typeId` | Stable [`TransactionType`](https://github.com/worldcoin/bedrock/blob/main/bedrock/src/smart_account/nonce.rs#L18) enum (1–255). `0x00` reserved for legacy v0 nonces. | +| 1–5 | 5 B | `magic` | Constant `0x626472636b` (`"bdrck"`). Distinguishes Bedrock-built operations; collision probability $P = \frac{1}{2^{40}} ≈ 9.1 × 10^{-13}$. | | 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 ≈ 0.0007%. | @@ -163,5 +163,4 @@ Example: ### Wallet Upgrades - Safe accounts must be on Safe v1.4.0 with the 4337 module enabled; otherwise, `wa_sponsorUserOperation` simulations revert. -- On every app launch we call `/world-chain`, which now returns `requiresUpgrade`. If `true`, the UI blocks until the user runs the combined Safe upgrade + 4337 module enablement flow. -- Wallet upgrades also prepare the ground for Project Safeguard and future Safe import functionality. +- On every app launch we call `/world-chain`, which returns `requiresUpgrade`. If `true`, the UI blocks until the user runs the combined Safe upgrade + 4337 module enablement flow. From 762b09ae193ce69fdb1020b4bc87ec754a732c23 Mon Sep 17 00:00:00 2001 From: pd Date: Thu, 19 Feb 2026 14:08:20 -0800 Subject: [PATCH 5/7] Update transactions.mdx --- world-app/transactions.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/world-app/transactions.mdx b/world-app/transactions.mdx index 5a6ac90..c166900 100644 --- a/world-app/transactions.mdx +++ b/world-app/transactions.mdx @@ -146,7 +146,7 @@ Example: | 1–5 | 5 B | `magic` | Constant `0x626472636b` (`"bdrck"`). Distinguishes Bedrock-built operations; collision probability $P = \frac{1}{2^{40}} ≈ 9.1 × 10^{-13}$. | | 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 ≈ 0.0007%. | +| 17–23 | 7 B | `random` | 56 bits of entropy; collision risk for 1M tx in a bucket $P = \frac{n^2}{2^{57}} = \frac{(10^6)^2}{2^{57}} \approx 0.0007\%$. | - If `magic` is missing, the indexer treats the transaction as external/unknown and falls back to legacy parsing. - `TransactionType` ordering must never change; add new IDs at the tail. From f61f79bcc4866951fe9fec8a08862ef1bc05d991 Mon Sep 17 00:00:00 2001 From: pd Date: Thu, 19 Feb 2026 14:10:07 -0800 Subject: [PATCH 6/7] improvements --- cspell.json | 11 +++++------ world-app/transactions.mdx | 4 ---- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/cspell.json b/cspell.json index 515e766..f0410f8 100644 --- a/cspell.json +++ b/cspell.json @@ -10,7 +10,9 @@ "jsx", "tsx", "cspell", - "spellcheck" + "spellcheck", + "pimlico", + "bdrock" ], "ignorePaths": [ "node_modules", @@ -20,10 +22,7 @@ "build", ".vscode" ], - "ignoreRegExpList": [ - "/\\b[A-Z]{2,}\\b/g", - "/\\b[a-f0-9]{6,}\\b/gi" - ], + "ignoreRegExpList": ["/\\b[A-Z]{2,}\\b/g", "/\\b[a-f0-9]{6,}\\b/gi"], "allowCompoundWords": true, "dictionaries": [ "en_US", @@ -35,4 +34,4 @@ "bash", "softwareTerms" ] -} \ No newline at end of file +} diff --git a/world-app/transactions.mdx b/world-app/transactions.mdx index c166900..240d97e 100644 --- a/world-app/transactions.mdx +++ b/world-app/transactions.mdx @@ -3,10 +3,6 @@ description: "Spec for client-side transaction architecture, World App RPC, nonc --- -## Context & Goals - -- Part of **Protocolization** for World App: all signature-requiring flows are crafted client-side via open-source Bedrock, minimizing trust in the TFH backend. - ## Target End State 1. All transactions originate client-side and can be submitted through the authenticated World App RPC. From fa0b32de6337df4a8d0a6a0b0cac028df937fa50 Mon Sep 17 00:00:00 2001 From: pd Date: Thu, 19 Feb 2026 14:13:08 -0800 Subject: [PATCH 7/7] don't forget the menu --- docs.json | 7 +++++-- world-app/transactions.mdx | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs.json b/docs.json index b996895..6788466 100644 --- a/docs.json +++ b/docs.json @@ -40,6 +40,10 @@ "pages": [ "world-app/index", "world-app/bedrock", + { + "group": "Transactions", + "pages": ["world-app/transactions/index"] + }, { "group": "Backup & Recovery", "pages": [ @@ -70,8 +74,7 @@ "primary": { "type": "button", "label": "Developer Portal", - "href": "https://developer.worldcoin.org", - "target": "_blank" + "href": "https://developer.worldcoin.org" } }, "footer": { diff --git a/world-app/transactions.mdx b/world-app/transactions.mdx index 240d97e..ff9eecb 100644 --- a/world-app/transactions.mdx +++ b/world-app/transactions.mdx @@ -1,4 +1,4 @@ -title: "Client-side transactions" +title: "Client-side Transactions" description: "Spec for client-side transaction architecture, World App RPC, nonce layout, and wallet readiness." ---