Skip to content

Commit 59ecb18

Browse files
committed
Merge remote-tracking branch 'origin/main' into tyler/pro-394-docs-no-safe-on-chain-randomness-document-mandate-vrforacle
# Conflicts: # plugins/radius/skills/radius-dev/SKILL.md
2 parents e07ae01 + eeb8b2e commit 59ecb18

5 files changed

Lines changed: 27 additions & 12 deletions

File tree

plugins/radius/skills/radius-dev/SKILL.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Use this Skill when the user asks for:
2020
- Radius network configuration, RPC endpoints, contract addresses
2121
- Production gotchas (wallet compatibility, nonce management, decimal handling)
2222
- Hardhat or ethers.js integration with Radius
23-
- JSON-RPC differences and Radius-specific extensions (EIP-7966, `rad_getBalanceRaw`)
23+
- JSON-RPC differences, the EIP-7966 sync method (`eth_sendRawTransactionSync`), and Radius-specific extensions (`rad_getBalanceRaw`)
2424

2525
## Default stack decisions (opinionated)
2626

@@ -158,10 +158,12 @@ Always keep these in mind when writing code for Radius:
158158
| `eth_blockNumber` | Monotonic block height | Current timestamp in milliseconds |
159159
| Reconstructed blocks | N/A | Contain all txs executed within the same ms |
160160
| Block hash | Hash of block header | Equals block number (timestamp-based) |
161-
| `transactionIndex` | Position in block | Can be `0` for multiple txs in same ms |
161+
| `transactionIndex` | Position in block | Receipt always reports `0` — not a unique key; use `transactionHash` |
162162
| On-chain randomness (`blockhash`, `prevrandao`, `difficulty`) | `prevrandao` carries RANDAO mix | Not a randomness source: `prevrandao`/`difficulty` = `0`, `blockhash` predictable, no EIP-2935 — use off-chain entropy |
163163
| `eth_getLogs` | Address filter optional | Address filter **required** (error `-33014`) |
164-
| `eth_sendRawTransactionSync` | N/A | EIP-7966: sync tx+receipt (~50% less latency) |
164+
| `eth_getProof` | Merkle state proofs | Unsupported (error `-33000`) — instant-final state model, no proofs needed |
165+
| `eth_getBlockReceipts` | All receipts in a block | Unsupported (error `-33000`) — txs executed individually, not in blocks |
166+
| `eth_sendRawTransactionSync` | EIP-7966 sync tx submission (returns the receipt directly) | On Radius the receipt is **instant + final** (~100ms, no reorg) vs an L2 inclusion receipt (~460ms, reorg-able) |
165167
| `rad_getBalanceRaw` | N/A | Raw RUSD only (excludes convertible SBC) |
166168
| State queries | Historical state by block tag | `latest`/`pending`/`safe`/`finalized` return current state; historical block numbers rejected (error `-32000`) |
167169
| SBC decimals || 6 decimals (NOT 18) |
@@ -220,7 +222,7 @@ Always be explicit about:
220222
### 4. Watch for production gotchas
221223
Before shipping, review [gotchas.md](references/gotchas.md) for:
222224
- Wallet compatibility (MetaMask is the only wallet that reliably adds Radius)
223-
- Nonce collision handling under concurrent load
225+
- Nonce management for unmanaged concurrent sends from one wallet (contiguous-nonce batches like `forge script --broadcast` need no special handling)
224226
- Block number is a timestamp (use BigInt, never parseInt)
225227
- Transaction receipts can be null even for confirmed transactions
226228
- EIP-2612 permit domain must match exactly: `{ name: "Stable Coin", version: "1" }`

plugins/radius/skills/radius-dev/references/gotchas.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,13 @@ if (!receipt) {
132132

133133
---
134134

135-
## 7. Nonce collisions under concurrent load
135+
## 7. Nonce management for concurrent sends from one wallet
136136

137-
When sending multiple transactions from the same wallet (hot wallet, settlement wallet), concurrent sends cause nonce errors. Radius enforces strict sequential nonces.
137+
Batches with pre-assigned contiguous nonces land fine — Radius's pseudo-mempool accepts and orders them. A single `forge script --broadcast` deploying many contracts confirms all of them in one run (verified: a 29-transaction script landed with contiguous nonces, 29/29 successful). **You do not need to deploy one contract at a time, run `--slow`, or add fixed delays between transactions.**
138138

139-
**Solution: serial queue + nonce retry.**
139+
The one case that still needs care is firing *unmanaged concurrent* transactions from the same wallet — e.g. a hot/settlement wallet that calls `sendTransaction` from many requests at once without coordinating nonces. As on any EVM chain, those can race and collide because each read of the pending nonce returns the same value before the earlier tx is accounted for.
140+
141+
For that case, let viem manage nonces (it tracks them per account by default), or serialize sends through a queue and retry on the occasional collision:
140142

141143
```typescript
142144
function isNonceError(err: any): boolean {
@@ -172,7 +174,7 @@ async function sendWithRetry(
172174
}
173175
```
174176

175-
Also add a ~200ms delay between consecutive transactions. Without it, the RPC sometimes returns stale nonce values.
177+
This applies only to unmanaged concurrent sends from a single wallet — not to normal sequential sends or pre-signed contiguous-nonce batches, both of which land without special handling.
176178

177179
---
178180

@@ -422,6 +424,15 @@ Best practice: read chain ID dynamically from the connected provider rather than
422424

423425
---
424426

427+
## 22. Some standard read methods are unsupported (`eth_getProof`, `eth_getBlockReceipts`)
428+
429+
Two standard Ethereum read methods return error `-33000` on Radius:
430+
431+
- **`eth_getProof`** — Radius stores state across a parallelized, sharded infrastructure with no single global Merkle-Patricia trie, so it does not issue state proofs; its instant, deterministic finality removes the need for them. Read state directly with `eth_getBalance`, `eth_getCode`, and `eth_getStorageAt`.
432+
- **`eth_getBlockReceipts`** — Radius executes transactions individually, not in blocks (the block number is wall-clock time for tooling compatibility), so "every receipt in a block" is not a meaningful unit. To fetch a block's receipts, enumerate its transactions with `eth_getBlockByNumber` (full) and call `eth_getTransactionReceipt` for each; for event indexing of known contracts, use address-filtered `eth_getLogs` (see #18).
433+
434+
---
435+
425436
## Quick reference: environment variables
426437

427438
| Variable | Required | Description |

plugins/radius/skills/radius-dev/references/resources.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
- [EIP-2930](https://eips.ethereum.org/EIPS/eip-2930) — Access lists
8181
- [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) — Blob transactions
8282
- [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) — Set EOA account code
83-
- [EIP-7966](https://eips.ethereum.org/EIPS/eip-7966)`eth_sendRawTransactionSync` (synchronous tx submission; supported on Radius)
83+
- [EIP-7966](https://eips.ethereum.org/EIPS/eip-7966)`eth_sendRawTransactionSync` (synchronous tx submission; on Radius the sync receipt is instant + final, no reorg)
8484

8585
## Wallet Integration
8686

plugins/radius/skills/radius-dev/references/typescript-viem.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ const recipients = [
327327
'0x90F79bf6EB2c4f870365E785982E1f101E93b906',
328328
] as const;
329329

330-
// Send sequentially (saferavoids nonce collisions)
330+
// Send sequentially (simplestno nonce coordination needed)
331331
const hashes: `0x${string}`[] = [];
332332
for (const to of recipients) {
333333
const hash = await walletClient.sendTransaction({
@@ -343,7 +343,7 @@ const receipts = await Promise.all(
343343
);
344344
```
345345

346-
> **Gotcha:** If you send concurrent transactions from the same wallet, you will hit nonce collisions. Radius enforces strict sequential nonces. Always send sequentially from a single wallet, or use a nonce-aware queue. See [gotchas.md](gotchas.md#7-nonce-collisions-under-concurrent-load).
346+
> **Gotcha:** *Unmanaged* concurrent sends from the same wallet can collide on the nonce — as on any EVM chain, parallel calls may each read the same pending nonce before the earlier tx is accounted for. Let viem manage nonces (its default), serialize through a queue, or pre-assign contiguous nonces. Pre-signed contiguous-nonce batches (e.g. `forge script --broadcast`) land fine — you do **not** need to send one at a time or add delays. See [gotchas.md](gotchas.md#7-nonce-management-for-concurrent-sends-from-one-wallet).
347347
348348
For batching **reads**, use Multicall3 (deployed at `0xcA11bde05977b3631167028862bE2a173976CA11`):
349349

@@ -511,6 +511,8 @@ async function transfer(
511511

512512
Radius supports `eth_sendRawTransactionSync` (EIP-7966), which submits a transaction and waits for the receipt in a single RPC call — roughly 50% less latency than the standard `sendTransaction` + `waitForTransactionReceipt` polling pattern.
513513

514+
On Radius, what makes `eth_sendRawTransactionSync` valuable is what the returned receipt means: because Radius has instant finality, the sync receipt is fast **and final** (~100ms, no reorg). On a typical L2 the equivalent sync receipt reflects only inclusion (~460ms in our testing) and can reorg until it settles on L1.
515+
514516
```typescript
515517
import { serializeTransaction, signTransaction } from 'viem';
516518
import { privateKeyToAccount } from 'viem/accounts';

plugins/radius/skills/x402/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,4 +305,4 @@ network defaults for a local or custom environment.
305305
**Cross-references to other skills:**
306306
- Chain definitions, RPC, wallet conventions, general Radius dev: **radius-dev** skill
307307
- Get testnet/mainnet SBC tokens: **dripping-faucet** skill
308-
- Production gotchas (EIP-2612 domain, v-value, nonce collisions): radius-dev [gotchas.md](../radius-dev/references/gotchas.md)
308+
- Production gotchas (EIP-2612 domain, v-value, nonce management): radius-dev [gotchas.md](../radius-dev/references/gotchas.md)

0 commit comments

Comments
 (0)