radius-dev
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseRadius Development Skill
Radius开发技能指南
What this Skill is for
本技能指南适用场景
Use this Skill when the user asks for:
- Radius dApp UI work (React / Next.js with wagmi)
- Wallet connection + transaction signing on Radius
- Smart contract deployment to Radius (Foundry / Solidity)
- Micropayment patterns (pay-per-visit content, API metering, streaming payments)
- x402 protocol integration (per-request API billing, facilitator patterns)
- TypeScript integration with viem (clients, transactions, contract interaction, events)
- EVM compatibility questions specific to Radius
- Stablecoin-native fee model and Turnstile mechanism
- Radius network configuration, RPC endpoints, contract addresses
- Production gotchas (wallet compatibility, nonce management, decimal handling)
当用户询问以下内容时,可使用本指南:
- Radius dApp UI开发(基于React / Next.js与wagmi)
- Radius上的钱包连接与交易签名
- 向Radius部署智能合约(Foundry / Solidity)
- 微支付模式(按次付费内容、API计量、流支付)
- x402协议集成(按请求API计费、服务商模式)
- 基于viem的TypeScript集成(客户端、交易、合约交互、事件)
- Radius特有的EVM兼容性问题
- 原生稳定币手续费模型与Turnstile机制
- Radius网络配置、RPC端点、合约地址
- 生产环境注意事项(钱包兼容性、nonce管理、小数位处理)
Default stack decisions (opinionated)
默认技术栈决策(主观推荐)
- TypeScript: viem (directly, no wrapper SDK)
- Use from viem to create the Radius chain definition with
defineChain.fees.estimateFeesPerGas() - Use for reads,
createPublicClientfor writes.createWalletClient - Use viem's native ,
watchContractEvent, andgetLogsfor event monitoring.watchBlockNumber - Do NOT use — it is deprecated. Use plain viem for everything.
@radiustechsystems/sdk
- UI: wagmi + @tanstack/react-query for React apps
- Define the Radius chain via and pass it to wagmi's
defineChain.createConfig - Use connector for MetaMask and EIP-1193 wallets.
injected() - Standard wagmi hooks: ,
useAccount,useConnect,useSendTransaction.useWaitForTransactionReceipt
- Smart contracts: Foundry
- for direct deployment,
forge createfor scripted deploys.forge script - for reads,
cast callfor writes.cast send - OpenZeppelin for standard patterns (ERC-20, ERC-721, access control).
- Solidity 0.8.x, Osaka hardfork support via Revm 33.1.0.
- Chain: Radius Testnet (default) + Radius Network (mainnet)
| Setting | Testnet | Mainnet |
|---|---|---|
| Chain ID | | |
| RPC | | |
| Native currency | RUSD (18 decimals) | RUSD (18 decimals) |
| SBC token (ERC-20) | — | |
| Explorer | | |
| Faucet | | Not available |
| Transaction cost API | | |
- Fees: Stablecoin-native via Turnstile
- Users pay gas in stablecoins (USD). No separate gas token needed.
- Fixed cost: ~0.0001 USD per standard ERC-20 transfer.
- Fixed gas price: RUSD per gas (~986M wei, ~1 gwei).
9.85998816e-10 - returns the fixed gas price (NOT zero).
eth_gasPrice - returns
eth_maxPriorityFeePerGas(no priority fee bidding).0x0 - Failed transactions do NOT charge gas.
- If a sender has SBC but not enough RUSD, Turnstile converts SBC → RUSD inline.
- TypeScript:直接使用viem(无封装SDK)
- 使用viem中的创建Radius链定义,并搭配
defineChain。fees.estimateFeesPerGas() - 使用执行读操作,
createPublicClient执行写操作。createWalletClient - 使用viem原生的、
watchContractEvent和getLogs进行事件监控。watchBlockNumber - 请勿使用——该SDK已废弃。所有操作均直接使用viem。
@radiustechsystems/sdk
- UI:React应用使用wagmi + @tanstack/react-query
- 通过定义Radius链,并将其传入wagmi的
defineChain。createConfig - 使用连接器适配MetaMask与EIP-1193标准钱包。
injected() - 使用标准wagmi钩子:、
useAccount、useConnect、useSendTransaction。useWaitForTransactionReceipt
- 智能合约:Foundry
- 使用直接部署合约,使用
forge create执行脚本化部署。forge script - 使用执行读操作,
cast call执行写操作。cast send - 使用OpenZeppelin实现标准模式(ERC-20、ERC-721、权限控制)。
- 使用Solidity 0.8.x版本,通过Revm 33.1.0支持Osaka硬分叉。
- 链环境:默认Radius测试网 + Radius主网
| 配置项 | 测试网 | 主网 |
|---|---|---|
| 链ID | | |
| RPC地址 | | |
| 原生代币 | RUSD(18位小数) | RUSD(18位小数) |
| SBC代币(ERC-20) | — | |
| 区块浏览器 | | |
| 水龙头 | | 无 |
| 交易成本API | | |
- 手续费:通过Turnstile收取原生稳定币
- 用户以稳定币(USD)支付Gas费,无需单独的Gas代币。
- 固定成本:每笔标准ERC-20转账约0.0001美元。
- 固定Gas价格:RUSD每Gas(约986M wei,即1 gwei)。
9.85998816e-10 - 返回固定Gas价格(而非0)。
eth_gasPrice - 返回
eth_maxPriorityFeePerGas(无优先级费用竞价)。0x0 - 失败交易不收取Gas费。
- 若发送者持有SBC但RUSD不足,Turnstile会自动将SBC转换为RUSD。
Canonical chain definitions
标准链定义
Always define the chain with — never rely on viem defaults:
fees.estimateFeesPerGas()typescript
import { defineChain } from 'viem';
export const radiusTestnet = defineChain({
id: 72344,
name: 'Radius Testnet',
nativeCurrency: { decimals: 18, name: 'RUSD', symbol: 'RUSD' },
rpcUrls: { default: { http: ['https://rpc.testnet.radiustech.xyz'] } },
blockExplorers: {
default: { name: 'Radius Explorer', url: 'https://testnet.radiustech.xyz' },
},
fees: {
async estimateFeesPerGas() {
const res = await fetch(
'https://testnet.radiustech.xyz/api/v1/network/transaction-cost'
);
const { gas_price_wei } = await res.json();
return { gasPrice: BigInt(gas_price_wei) };
},
},
});
export const radiusMainnet = defineChain({
id: 723,
name: 'Radius Network',
nativeCurrency: { decimals: 18, name: 'RUSD', symbol: 'RUSD' },
rpcUrls: { default: { http: ['https://rpc.radiustech.xyz'] } },
blockExplorers: {
default: { name: 'Radius Explorer', url: 'https://network.radiustech.xyz' },
},
fees: {
async estimateFeesPerGas() {
const res = await fetch(
'https://network.radiustech.xyz/api/v1/network/transaction-cost'
);
const { gas_price_wei } = await res.json();
return { gasPrice: BigInt(gas_price_wei) };
},
},
});请始终使用定义链——切勿依赖viem的默认值:
fees.estimateFeesPerGas()typescript
import { defineChain } from 'viem';
export const radiusTestnet = defineChain({
id: 72344,
name: 'Radius Testnet',
nativeCurrency: { decimals: 18, name: 'RUSD', symbol: 'RUSD' },
rpcUrls: { default: { http: ['https://rpc.testnet.radiustech.xyz'] } },
blockExplorers: {
default: { name: 'Radius Explorer', url: 'https://testnet.radiustech.xyz' },
},
fees: {
async estimateFeesPerGas() {
const res = await fetch(
'https://testnet.radiustech.xyz/api/v1/network/transaction-cost'
);
const { gas_price_wei } = await res.json();
return { gasPrice: BigInt(gas_price_wei) };
},
},
});
export const radiusMainnet = defineChain({
id: 723,
name: 'Radius Network',
nativeCurrency: { decimals: 18, name: 'RUSD', symbol: 'RUSD' },
rpcUrls: { default: { http: ['https://rpc.radiustech.xyz'] } },
blockExplorers: {
default: { name: 'Radius Explorer', url: 'https://network.radiustech.xyz' },
},
fees: {
async estimateFeesPerGas() {
const res = await fetch(
'https://network.radiustech.xyz/api/v1/network/transaction-cost'
);
const { gas_price_wei } = await res.json();
return { gasPrice: BigInt(gas_price_wei) };
},
},
});Critical Radius differences from Ethereum
Radius与以太坊的关键差异
Always keep these in mind when writing code for Radius:
| Feature | Ethereum | Radius |
|---|---|---|
| Fee model | Market-based ETH gas bids | Fixed ~0.0001 USD via Turnstile |
| Settlement | ~12 minutes (12+ confirmations) | Sub-second (~500ms finality) |
| Failed txs | Charge gas even if reverted | Charge only on success |
| Required token | Must hold ETH for gas | Stablecoins only (USD) |
| Reorgs | Possible | Impossible |
| Market rate | Fixed gas price (~986M wei) |
| Suggested priority fee | Always |
| Native ETH balance | Native + convertible USD balance |
| Monotonic block height | Current timestamp in milliseconds |
| Block hash | Hash of block header | Equals block number (timestamp-based) |
| Position in block | Can be |
| SBC decimals | — | 6 decimals (NOT 18) |
Solidity patterns to watch:
solidity
// DON'T — native balance behaves differently on Radius
require(address(this).balance > 0);
// DO — use ERC-20 balance instead
require(IERC20(feeToken).balanceOf(address(this)) > 0);SBC decimal handling — always use 6:
typescript
import { parseUnits, formatUnits } from 'viem';
// CORRECT
const amount = parseUnits('1.0', 6); // 1_000_000n
const display = formatUnits(balance, 6); // "1.0"
// WRONG — this is the most common mistake
const wrong = parseUnits('1.0', 18); // 1_000_000_000_000_000_000n (1e12x too large!)Standard ERC-20 interactions, storage operations, and events work unchanged.
为Radius编写代码时,请始终牢记以下差异:
| 特性 | 以太坊 | Radius |
|---|---|---|
| 手续费模型 | 基于市场的ETH Gas竞价 | 通过Turnstile收取固定约0.0001美元 |
| 结算时间 | ~12分钟(12+次确认) | 亚秒级(约500ms最终确定性) |
| 失败交易 | 即使回滚也收取Gas费 | 仅成功交易收取费用 |
| 必需代币 | 必须持有ETH用于Gas费 | 仅需稳定币(USD) |
| 链重组 | 可能发生 | 不可能发生 |
| 市场价格 | 固定Gas价格(约986M wei) |
| 建议优先级费用 | 始终返回 |
| 原生ETH余额 | 原生代币+可转换USD余额 |
| 单调递增的区块高度 | 当前时间戳(毫秒级) |
| 区块哈希 | 区块头的哈希值 | 等于区块编号(基于时间戳) |
| 交易在区块中的位置 | 同一毫秒内的多笔交易可能均为 |
| SBC小数位 | — | 6位小数(非18位) |
需要注意的Solidity模式:
solidity
// 错误示例——Radius上的原生代币余额表现不同
require(address(this).balance > 0);
// 正确示例——改用ERC-20余额
require(IERC20(feeToken).balanceOf(address(this)) > 0);SBC小数位处理——始终使用6位:
typescript
import { parseUnits, formatUnits } from 'viem';
// 正确写法
const amount = parseUnits('1.0', 6); // 1_000_000n
const display = formatUnits(balance, 6); // "1.0"
// 错误写法——这是最常见的错误
const wrong = parseUnits('1.0', 18); // 1_000_000_000_000_000_000n(比实际大1e12倍!)标准ERC-20交互、存储操作和事件可直接使用,无需修改。
Operating procedure (how to execute tasks)
操作流程(任务执行步骤)
1. Classify the task layer
1. 任务分层归类
- UI/wallet layer — React components, wallet connection, transaction UX
- TypeScript/scripts layer — Backend scripts, server-side verification, event monitoring
- Smart contract layer — Solidity contracts, deployment, testing
- Micropayment layer — Pay-per-visit, API metering, streaming payments
- x402 layer — HTTP-native micropayments, facilitator integration
- UI/钱包层——React组件、钱包连接、交易用户体验
- TypeScript/脚本层——后端脚本、服务端验证、事件监控
- 智能合约层——Solidity合约、部署、测试
- 微支付层——按次付费、API计量、流支付
- x402层——HTTP原生微支付、服务商集成
2. Pick the right building blocks
2. 选择合适的构建模块
- UI: wagmi + Radius chain via + React hooks
defineChain - Scripts/backends: plain viem (,
createPublicClient,createWalletClient)defineChain - Smart contracts: Foundry (/
forge) + OpenZeppelincast - Micropayments: viem + server-side verification + wallet integration
- x402: Middleware pattern with Radius facilitator for settlement
- UI:wagmi + 通过定义的Radius链 + React钩子
defineChain - 脚本/后端:原生viem(、
createPublicClient、createWalletClient)defineChain - 智能合约:Foundry(/
forge) + OpenZeppelincast - 微支付:viem + 服务端验证 + 钱包集成
- x402:搭配Radius服务商的中间件模式进行结算
3. Implement with Radius-specific correctness
3. 确保Radius特有的代码正确性
Always be explicit about:
- Defining the Radius chain with including
defineChainfees.estimateFeesPerGas() - Using for reads and
createPublicClientfor writes (plain viem)createWalletClient - Stablecoin fee model (no ETH needed, no gas price bidding)
- Sub-second finality (no need to wait for multiple confirmations)
- SBC uses 6 decimals (use , NOT
parseUnits(amount, 6))parseEther - RUSD (native token) uses 18 decimals (use for native transfers)
parseEther - Environment variables for private keys (never hardcode)
- Gas price comes from transaction cost API, not from defaults
请始终明确以下事项:
- 使用定义Radius链,并包含
defineChainfees.estimateFeesPerGas() - 使用执行读操作,
createPublicClient执行写操作(原生viem)createWalletClient - 稳定币手续费模型(无需ETH,无Gas价格竞价)
- 亚秒级最终确定性(无需等待多笔确认)
- SBC使用6位小数(使用,而非
parseUnits(amount, 6))parseEther - RUSD(原生代币)使用18位小数(原生转账使用)
parseEther - 使用环境变量存储私钥(切勿硬编码)
- Gas价格来自交易成本API,而非默认值
4. Watch for production gotchas
4. 注意生产环境陷阱
Before shipping, review gotchas.md for:
- Wallet compatibility (MetaMask is the only wallet that reliably adds Radius)
- Nonce collision handling under concurrent load
- Block number is a timestamp (use BigInt, never parseInt)
- Transaction receipts can be null even for confirmed transactions
- EIP-2612 permit domain must match exactly:
{ name: "SBC", version: "1" }
上线前,请查阅gotchas.md了解:
- 钱包兼容性(仅MetaMask可稳定添加Radius网络)
- 并发负载下的nonce冲突处理
- 区块编号为时间戳(使用BigInt,切勿使用parseInt)
- 已确认交易的收据可能为null
- EIP-2612 permit域必须完全匹配:
{ name: "SBC", version: "1" }
5. Test
5. 测试
- Smart contracts: locally, then deploy to Radius Testnet
forge test - TypeScript scripts: Run against testnet RPC with funded test accounts
- Get testnet tokens from
https://testnet.radiustech.xyz/testnet/faucet - Verify deployments:
cast code <address> --rpc-url https://rpc.testnet.radiustech.xyz
- 智能合约:本地执行,然后部署到Radius测试网
forge test - TypeScript脚本:使用已充值的测试账户对接测试网RPC
- 从获取测试网代币
https://testnet.radiustech.xyz/testnet/faucet - 验证部署结果:
cast code <address> --rpc-url https://rpc.testnet.radiustech.xyz
6. Deliverables expectations
6. 交付物要求
When you implement changes, provide:
- Exact files changed + diffs (or patch-style output)
- Commands to install dependencies, build, and test
- A short "risk notes" section for anything touching signing, fees, payments, or token transfers
实现变更后,请提供:
- 具体修改的文件 + 差异内容(或补丁格式输出)
- 安装依赖、构建和测试的命令
- 简短的「风险说明」部分,涵盖签名、手续费、支付或代币转账相关内容
Progressive disclosure (read when needed)
渐进式参考文档(按需查阅)
- TypeScript reference (viem): typescript-viem.md
- Event watching + historical queries (viem): events-viem.md
- Smart contract deployment (Foundry): smart-contracts.md
- Wallet integration (wagmi / viem / MetaMask): wallet-integration.md
- Micropayment patterns: micropayments.md
- x402 protocol integration: x402-integration.md
- EVM differences + Turnstile + architecture: evm-differences.md
- Network config + contract addresses + RPC reference: network-config.md
- Production gotchas: gotchas.md
- Security checklist: security.md
- Curated reference links: resources.md
- TypeScript参考(viem):typescript-viem.md
- 事件监听 + 历史查询(viem):events-viem.md
- 智能合约部署(Foundry):smart-contracts.md
- 钱包集成(wagmi / viem / MetaMask):wallet-integration.md
- 微支付模式:micropayments.md
- x402协议集成:x402-integration.md
- EVM差异 + Turnstile + 架构:evm-differences.md
- 网络配置 + 合约地址 + RPC参考:network-config.md
- 生产环境陷阱:gotchas.md
- 安全检查清单:security.md
- 精选参考链接:resources.md