# Radius Documentation
> Developer documentation for the Radius Network - Stablecoin-native EVM with sub-second finality.
import { Callout } from 'vocs/components';
## Pay-per-Visit Content \[Enable micropayment-based content access. Users pay cents per article instead of monthly subscriptions.]
### Problem statement
Traditional content monetization forces creators into difficult trade-offs:
* **Subscriptions** force users to pay for content they don't consume. Most readers abandon paywalls rather than commit to a monthly subscription for a single article, leaving the content provider with a missed connection with a potential user.
* **Ads** damage user experience, raise privacy concerns, and are increasingly under strain with the rise of web crawlers.
* **Freemium models** leave money on the table from engaged users willing to pay for premium content.
Radius solves this with pay-per-visit micropayments—users pay exactly for what they read, watch, or download. No subscriptions. No trackers. Instant access.
### How it works
The user journey is frictionless:
1. **User lands on premium content** and sees a paywall
2. **Clicks "Unlock" and chooses a micropayment amount** (0.05 USD, 0.10 USD, 0.25 USD, etc.)
3. **Confirms payment in their wallet** (MetaMask, Rainbow, etc.)
4. **Content unlocks instantly** after payment confirmation—no waiting, no email verification
5. **Payment settles instantly** to your account in stablecoins
Behind the scenes, Radius handles the heavy lifting: gas fees are paid in stablecoins via Turnstile, transactions settle in seconds, and there's no intermediary taking a cut.
Radius processes transactions with instant finality. Users see content appear immediately after they confirm payment—no "waiting for confirmation" screens.
### Implementation example
Here's a complete React component that implements a content paywall with Radius micropayments:
#### Step 1: Paywall component
```typescript
import { useState } from 'react';
import { parseEther } from 'viem';
import { useAccount, useWriteContract, useWaitForTransactionReceipt } from 'wagmi';
interface ContentPaywallProps {
contentId: string;
title: string;
amount: string; // e.g., "0.10" (USD)
children: React.ReactNode;
}
export function ContentPaywall({
contentId,
title,
amount,
children,
}: ContentPaywallProps) {
const { address, isConnected } = useAccount();
const [isUnlocked, setIsUnlocked] = useState(false);
const [isPaying, setIsPaying] = useState(false);
const { data: hash, writeContract, isPending } = useWriteContract();
const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({
hash,
});
const handleUnlock = async () => {
if (!address) return;
setIsPaying(true);
try {
// Send payment to content owner address
const contentOwner = '0x742d35Cc6634C0532925a3b844Bc9e7595f7E9F1';
writeContract({
to: contentOwner,
account: address,
value: parseEther(amount),
});
} catch (error) {
console.error('Payment failed:', error);
setIsPaying(false);
}
};
// Once payment is confirmed, unlock content
if (isSuccess && !isUnlocked) {
setIsUnlocked(true);
setIsPaying(false);
}
if (!isConnected) {
return (
{title}
Connect your wallet to unlock this content.
);
}
if (isUnlocked) {
return
{children}
;
}
return (
{title}
This premium content costs {amount} USD to unlock.
One-time payment. No subscription. Instant access.
);
}
```
### Benefits of Radius micropayments
#### For users
* **Lower barrier than subscriptions** — Pay 0.10 USD for one article instead of 15 USDC/month
* **No tracking required** — Stablecoins provide value; ads and trackers don't
* **Global access** — Pay with Radius in any country; instant settlement
* **Instant access** — Content unlocks immediately after payment confirmation
#### For creators
* **Higher effective revenue** — Every engaged reader becomes a paying user
* **No chargeback risk** — Stablecoin transactions are final; no refund disputes
* **Direct payment** — Money goes directly to you; no subscription platform taking 30%
* **Flexible pricing** — Set different prices for articles, videos, research—whatever works for your audience
#### For both
* **No intermediaries** — Direct creator-to-reader transactions
* **Instant settlement** — Money available immediately, not locked up for 30 days
* **Low transaction cost** — Radius handles gas via Turnstile; you pay almost nothing per transaction
* **Works globally** — Stablecoins work in any country; currency conversion handled on-chain
**With Radius, a creator earning 0.10 USD per article only needs 100 readers per day to generate 1000 USD/month.** That's achievable for most niche content creators.
### Use cases
Micropayments work for any content creators want compensation for:
* **News & Journalism** — Articles, investigations, breaking news
* **Video Content** — Tutorials, documentaries, educational videos
* **Research & Data** — Academic papers, market research, whitepapers
* **Premium Tutorials** — In-depth guides, programming courses, design resources
* **Podcasts** — Individual episode access or full-library unlock
* **Photography & Art** — High-resolution downloads, exclusive collections
* **Gaming Content** — Cosmetics, level packs, exclusive streams
* **Expert Advice** — Consultations, AMA sessions, email support tiers
### Getting started
#### 1. Install dependencies
```bash
pnpm add @radiustechsystems/sdk wagmi viem @tanstack/react-query
```
#### 2. Configure Wagmi
```typescript
import { WagmiProvider, createConfig, http } from 'wagmi';
import { radiusTestnet } from '@radiustechsystems/sdk';
import { injected } from 'wagmi/connectors';
const config = createConfig({
chains: [radiusTestnet],
connectors: [injected()],
transports: {
[radiusTestnet.id]: http(),
},
});
export function App({ children }) {
return {children};
}
```
#### 3. Wrap your app
```typescript
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
export default function RootApp() {
return (
);
}
```
#### 4. Deploy and test
Test with Radius Testnet before going live:
```bash
# Get free test tokens from the faucet
# https://testnet.radiustech.xyz/testnet/faucet
# Deploy your dapp and test payments
# Once verified, switch to mainnet
```
Always test payments on Radius Testnet first. Use the faucet to get free test USD tokens: [https://testnet.radiustech.xyz/testnet/faucet](https://testnet.radiustech.xyz/testnet/faucet)
### Best practices
1. **Show the price upfront** — Users hate surprises. Display the cost before they click "unlock"
2. **Make wallet connection obvious** — If not connected, guide users to connect before payment
3. **Handle network errors gracefully** — Show retry buttons if payment fails
4. **Store payment receipts** — Keep transaction hashes for support and analytics
5. **Offer value for the price** — 0.10 USD articles should be substantial; avoid paywalling single paragraphs
6. **Test on testnet first** — Always verify payment flow before production
7. **Monitor gas costs** — Radius fees are low, but still track transaction costs
### Scaling considerations
* **Batch settlements** — Collect multiple payments, settle once daily to save costs
* **Tiered content** — Use content length/quality to justify different price points
* **Bundle offers** — Sell article packs ("10 articles for 0.50 USD") to increase AOV
* **Incentivize loyalty** — Offer discounts to frequent readers or newsletter subscribers
* **Track conversion** — Monitor which price points convert best for different content types
Radius transactions cost nearly nothing to process. A 0.10 USD article payment costs less than 0.01 USD in fees, so almost all revenue goes to the creator.
### What's next
* **[Quick Start - First Payment](/getting-started/claim-and-transact)** — Send your first transaction in 5 minutes
***
**Ready to monetize?** Build your first paywall, test on testnet, and start earning from every engaged reader.
import { TX_FEE } from '../../constants'
## Real-time API Metering
### Problem statement
Conventional API billing relies on monthly invoices processed with credit card rails. In practice, this means API providers are extending credit for services rendered for 30+ days and while also paying 2.9% +$0.30 in transaction fees. For agents procuring services in real-time for sporadic, bursty workloads, this model is insufficient.
Radius solves this with real-time, per-request billing. Each API call includes payment that settles instantly. No credit card fees. No counterparty risk. No intermediaries.
### How it works
When a client calls your API:
1. **Client sends payment proof** — The client constructs a micro-transaction on Radius and includes proof in the API request
2. **Server verifies payment** — Your API server verifies the payment on Radius in milliseconds
3. **Request executes** — If payment is valid, your API processes the request
4. **Instant settlement** — The payment is finalized within seconds, and you control the tokens immediately
Total latency: sub-second verification + your API response time. No batch processes. No waiting for settlement.
### Implementation example
Below is a complete, production-ready example: an Express.js API that charges per request using Radius.
#### Server setup
Create a new project:
```bash
mkdir radius-api && cd radius-api
pnpm init
```
Add `"type": "module"` to `package.json`:
```json
{
"name": "radius-api",
"type": "module",
"dependencies": {
"express": "^4.18.2",
"@radiustechsystems/sdk": "latest",
"viem": "latest"
}
}
```
Install dependencies:
```bash
pnpm add express @radiustechsystems/sdk viem
```
#### Server implementation
Create `api-server.ts`:
```typescript
import express, { Request, Response } from 'express';
import { createPublicClient, createWalletClient, http, parseEther, isAddress } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { radiusTestnet, radiusWalletActions } from '@radiustechsystems/sdk';
import type { Address, Hash } from 'viem';
// Create account from server's private key
const serverAccount = privateKeyToAccount(
process.env.SERVER_PRIVATE_KEY as `0x${string}`
);
// Create clients
const publicClient = createPublicClient({
chain: radiusTestnet,
transport: http(),
});
const walletClient = createWalletClient({
account: serverAccount,
chain: radiusTestnet,
transport: http(),
}).extend(radiusWalletActions());
// Configuration
const COST_PER_REQUEST = parseEther('0.001'); // 0.001 USD per request
const app = express();
app.use(express.json());
/**
* Verify that a payment transaction was sent by the client
* Returns the sender's address if valid, null otherwise
*/
async function verifyPayment(
transactionHash: Hash,
expectedAmount: bigint,
expectedRecipient: Address
): Promise {
try {
const receipt = await publicClient.waitForTransactionReceipt({
hash: transactionHash,
});
// Check transaction success
if (receipt.status !== 'success') {
return null;
}
// Get transaction details
const tx = await publicClient.getTransaction({
hash: transactionHash,
});
// Verify recipient and amount
if (
!tx.to ||
tx.to.toLowerCase() !== expectedRecipient.toLowerCase() ||
tx.value < expectedAmount
) {
return null;
}
// Payment is valid
return tx.from;
} catch (error) {
console.error('Payment verification failed:', error);
return null;
}
}
/**
* Protected API endpoint that requires payment
*/
app.post('/api/query', async (req: Request, res: Response) => {
const { paymentHash, query } = req.body;
if (!paymentHash || !query) {
return res.status(400).json({
error: 'Missing paymentHash or query',
});
}
// Verify the payment
const payer = await verifyPayment(
paymentHash as Hash,
COST_PER_REQUEST,
serverAccount.address
);
if (!payer) {
return res.status(402).json({
error: 'Payment verification failed or insufficient amount',
});
}
// Log the payment for your records
console.log(`Query from ${payer}: ${query}`);
// Process the actual API request
// (In a real app, this would be your business logic)
const result = {
query,
result: `Processing query: "${query}"`,
processedAt: new Date().toISOString(),
paidBy: payer,
};
return res.json({
success: true,
data: result,
});
});
/**
* Health check endpoint (no payment required)
*/
app.get('/health', (_req: Request, res: Response) => {
res.json({ status: 'ok', serverAddress: serverAccount.address });
});
// Start server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`API server running on http://localhost:${PORT}`);
console.log(`Server receives payments at: ${serverAccount.address}`);
});
```
#### Client implementation
Create `api-client.ts`:
```typescript
import { createPublicClient, createWalletClient, http, parseEther } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { radiusTestnet, radiusWalletActions } from '@radiustechsystems/sdk';
import type { Address } from 'viem';
// Client configuration
const apiServerUrl = 'http://localhost:3000';
const serverAddress: Address = process.env.SERVER_ADDRESS as `0x${string}`;
const clientPrivateKey = process.env.CLIENT_PRIVATE_KEY as `0x${string}`;
// Create client account
const clientAccount = privateKeyToAccount(clientPrivateKey);
// Create clients
const publicClient = createPublicClient({
chain: radiusTestnet,
transport: http(),
});
const walletClient = createWalletClient({
account: clientAccount,
chain: radiusTestnet,
transport: http(),
}).extend(radiusWalletActions());
const COST_PER_REQUEST = parseEther('0.001');
/**
* Make a metered API call
* 1. Send payment to the server
* 2. Use the transaction hash as proof of payment
* 3. Call the API with the payment proof
*/
async function callMeteredAPI(query: string): Promise {
console.log(`\nCalling API with query: "${query}"`);
// Step 1: Send payment to the server
console.log('Sending payment...');
const paymentHash = await walletClient.sendTransaction({
to: serverAddress,
value: COST_PER_REQUEST,
});
console.log(`Payment sent: ${paymentHash}`);
// Step 2: Call the API with the payment proof
console.log('Calling API endpoint...');
const response = await fetch(`${apiServerUrl}/api/query`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
paymentHash,
query,
}),
});
if (!response.ok) {
const error = await response.json();
console.error(`API error (${response.status}):`, error);
return;
}
const result = await response.json();
console.log('API response:', result.data);
}
// Example usage
async function main() {
try {
// Check client balance
const balance = await publicClient.getBalance({
address: clientAccount.address,
});
console.log(`Client balance: ${balance.toString()} wei`);
// Make a few metered API calls
await callMeteredAPI('What is 2 + 2?');
await callMeteredAPI('What is the capital of France?');
} catch (error) {
console.error('Error:', error);
}
}
main();
```
### Running the example
#### Setup environment
Create `.env`:
```bash
# Server wallet (receives payments)
SERVER_PRIVATE_KEY=0x...
# Client wallet (sends payments)
CLIENT_PRIVATE_KEY=0x...
# For client: server's address (where to send payments)
SERVER_ADDRESS=0x...
```
Get testnet tokens from the [Radius Faucet](https://testnet.radiustech.xyz/testnet/faucet) for both wallets.
#### Run server
```bash
node --env-file=.env --import=tsx api-server.ts
```
You'll see:
```
API server running on http://localhost:3000
Server receives payments at: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
```
#### Run client
In another terminal:
```bash
node --env-file=.env --import=tsx api-client.ts
```
You'll see:
```
Client balance: 10000000000000000000 wei
Calling API with query: "What is 2 + 2?"
Payment sent: 0xabcd...
Calling API endpoint...
API response: { query: 'What is 2 + 2?', ... }
Calling API with query: "What is the capital of France?"
Payment sent: 0xdef0...
Calling API endpoint...
API response: { query: 'What is the capital of France?', ... }
```
### Real-world implementation notes
#### Payment verification
In production, consider:
* **Nonce tracking** — Store processed transaction hashes to prevent replay attacks
* **Timeout handling** — If a transaction takes too long to finalize, retry or fail gracefully
* **Rate limiting** — Limit requests per wallet to prevent spam
* **Amount validation** — Verify the payment amount exactly matches your pricing
#### Pricing strategies
```typescript
// Fixed rate per request
const COST_PER_REQUEST = parseEther('0.001');
// Tiered pricing based on request type
const PRICING = {
basic: parseEther('0.001'),
premium: parseEther('0.005'),
enterprise: parseEther('0.01'),
};
// Per-token pricing for AI/ML APIs
const COST_PER_TOKEN = parseEther('0.000001');
```
#### Monitoring and analytics
Track payments to understand your revenue:
```typescript
interface PaymentRecord {
timestamp: Date;
payer: Address;
amount: bigint;
query: string;
transactionHash: string;
}
const payments: PaymentRecord[] = [];
// Record each successful payment
payments.push({
timestamp: new Date(),
payer,
amount: COST_PER_REQUEST,
query,
transactionHash: paymentHash,
});
```
### Benefits over traditional API billing
| Feature | Traditional | Radius |
| ----------------------- | ------------------------ | --------------------------- |
| **Payment fees** | 2.9% + 0.30 USD | \~0.000001 USD per transfer |
| **Settlement time** | 30+ days | Seconds |
| **Chargebacks** | Common, costly | Impossible (on-chain) |
| **Global access** | Credit card required | Wallet + USD only |
| **Minimum transaction** | 5–10 USD | {TX_FEE} |
| **Revenue control** | Intermediary takes a cut | You control 100% |
### Use cases
#### AI/ML APIs
Charge per inference or per token. Users pay only for what they use, instantly:
```typescript
const costPerToken = parseEther('0.000001'); // Per token charged
const tokensGenerated = 150;
const totalCost = BigInt(tokensGenerated) * costPerToken;
// Client pays before using the API
const hash = await walletClient.sendTransaction({
to: apiServer,
value: totalCost,
});
```
#### Premium data feeds
Real-time stock prices, weather data, sports stats—charge per request:
```typescript
app.post('/api/stock-price', async (req, res) => {
const { symbol, paymentHash } = req.body;
// Verify payment for premium data
const payer = await verifyPayment(
paymentHash,
PREMIUM_DATA_COST,
serverAccount.address
);
if (!payer) {
return res.status(402).json({ error: 'Payment required' });
}
// Return premium stock price data
res.json({ symbol, price: 123.45, timestamp: Date.now() });
});
```
#### Content APIs
Charge for access to paywalled articles, ebooks, or videos:
```typescript
// Client pays for each piece of content
const contentId = '123-article-slug';
const hash = await walletClient.sendTransaction({
to: publisherAddress,
value: ARTICLE_COST,
});
// Request with proof of payment
const content = await fetch('/api/articles/' + contentId, {
headers: { 'X-Payment-Hash': hash },
});
```
### Best practices
* **Show pricing upfront** — Let users know the cost before sending payment
* **Batch requests** — Allow clients to send multiple queries in one payment
* **Discounts for volume** — Offer lower per-request costs for bulk prepayment
* **Error handling** — Handle failed payments gracefully; return 402 Payment Required
* **Monitoring** — Track payment success rates and processing times
### FAQ
**How long does payment verification take?**
Sub-second. Radius achieves near-instant finality, so payment verification completes in milliseconds.
**Can clients batch multiple requests into one payment?**
Yes. You can structure pricing around request batches or data volume rather than individual calls.
**What if a payment transaction fails?**
The transaction fails on-chain with no side effects. Your API returns 402 Payment Required, and the client can retry.
**Do I need a smart contract?**
No. Native token transfers work perfectly. Only use smart contracts if you need complex payment logic (for example, split payments, conditional refunds).
**Can I refund payments?**
Yes, by sending tokens back to the client. You control the server wallet and can execute refund transactions directly.
**How do I handle pricing changes?**
Update your server code and redeploy. Clients see the new pricing immediately. Consider a grace period for old prices.
### Next steps
* **[Quick Start](/getting-started/claim-and-transact)** — Send your first transaction on Radius
* **[JSON-RPC API](/developer-resources/json-rpc-api)** — Low-level RPC reference for advanced use cases
import { Callout } from 'vocs/components';
import { TESTNET_RPC_URL, TESTNET_CHAIN_ID, NATIVE_TOKEN, FAUCET_URL } from '../../constants';
## Streaming Payments \[Enable continuous, per-second billing for compute, bandwidth, and content delivery.]
### Problem statement
Traditional billing models create friction for both service providers and consumers:
* **Upfront payment risk**: Users pre-pay without knowing exact consumption, risking overpayment and fund lockup
* **Invoice-based delays**: Providers wait days or weeks to get paid, exposing themselves to default risk
* **Coarse billing granularity**: Services charge by month or hour, forcing users to pay for unused capacity
Radius solves this with **continuous micropayments**—pay-as-you-consume settlement at second-level granularity, eliminating both payment and credit risk entirely.
### How it works
Streaming payments establish an ongoing payment loop between client and server:
1. **Client initiates a session** with the server, providing an account with available funds
2. **Payments flow at regular intervals** (every second, every minute) based on service consumption
3. **Service continues uninterrupted** as long as payments arrive on schedule
4. **Either party can terminate** anytime—the client stops payments, or the server stops service
This creates a natural "circuit breaker": if the client runs out of funds or the server detects payment failure, service halts immediately.
### Benefits
Streaming payments unlock several key advantages:
| Benefit | Impact |
| ----------------------- | ----------------------------------------------------- |
| **No overpayment** | Pay only for what you consume, down to the second |
| **No credit risk** | Real-time settlement eliminates provider default risk |
| **Granular billing** | Per-second pricing enables precise cost-matching |
| **Instant termination** | Service stops immediately on payment failure |
| **Predictable costs** | Linear per-unit pricing with no hidden fees |
| **Improved UX** | Users pay gradually instead of upfront |
### Use cases
Streaming payments are ideal for:
#### Cloud compute
**Pay-per-second VMs and container instances**
* Traditional: Monthly subscriptions for over-provisioned capacity
* Streaming: Micro-VM charges by the second, scale up/down instantly
* Example: 0.0001 USD per second per vCPU
#### Video/content streaming
**Pay-per-minute or per-gigabyte**
* Traditional: Tiered monthly plans with bandwidth caps
* Streaming: Continuous payment as bytes flow, no caps or surprises
* Example: 0.00001 USD per MB of video data
#### WiFi and network access
**Pay-per-minute connectivity**
* Traditional: 24-hour passes or monthly contracts
* Streaming: Micropayments per minute of active connection
* Example: 0.0001 USD per minute of active connection
#### AI inference and APIs
**Pay-per-token or per-request**
* Traditional: Throttled APIs with prepaid tokens
* Streaming: Continuous settlement as tokens are generated
* Example: 0.00001 USD per 1,000 tokens generated
### Network configuration
**Radius Testnet:**
* RPC Endpoint: {TESTNET_RPC_URL}
* Chain ID: {TESTNET_CHAIN_ID}
* Native Token: {NATIVE_TOKEN}
* Block time: \~2-3 seconds
Testnet is perfect for experimenting with streaming payment patterns. Get free RUSD tokens from the [Radius Testnet Faucet](https://testnet.radiustech.xyz/testnet/faucet).
### What's next?
Learn more about building on Radius:
* **[Quick Start - First Payment](/getting-started/claim-and-transact)** — Send your first transaction
***
## Bridge stablecoins to Radius \[Transfer USDC or SBC from Ethereum or Base to Radius Network]
:::tip
**This guide uses Radius Network (mainnet) with real money.**
If you want to test without real money, the same process works on [Radius Testnet](https://testnet.radiustech.xyz).
:::
### Overview
Stablecoin transfers on Radius use SBC, a payments-focused stablecoin issued by Brale in partnership with Stable Coin Inc.
Bridge SBC or USDC from Ethereum or Base to SBC on Radius.
### Get stablecoins to bridge
You don't need to acquire SBC first. If you have USDC on Ethereum or Base, you can send it directly and receive SBC on Radius.
* **[Brale IO Onramp](https://brale.io/)** — Use a simple onramp to turn fiat into SBC in a few quick steps
* **[Brale Business Accounts](https://brale.xyz/blog/introducing-brale-business-accounts)** — Open a business account to hold, move, and convert SBC for operations
* **[Uniswap on Solana](https://app.uniswap.org/explore/tokens/solana/DBAzBUXaLj1qANCseUPZz4sp9F8d2sc78C4vKjhbTGMA?inputCurrency=NATIVE)** — Swap supported Solana tokens for SBC using the Uniswap decentralized exchange
* **[Orca on Solana](https://www.orca.so/pools/6qBVw2qtSsf4cAT572dKS629SMWCLjnFX4d4WkySLFZ7)** — Trade Solana tokens for SBC through Orca liquidity pools and their swap UI
### Prerequisites
* Wallet with USDC or SBC on a supported network
* ETH or Base ETH for source network gas fees
:::note
You don't need RUSD on Radius — the Turnstile auto-converts SBC to pay gas. Read more about [Turnstile](https://docs.radiustech.xyz/developer-resources/fees#turnstile).
:::
### Bridge steps
#### Step 1: Use your wallet (embedded or external)
Visit the dashboard:
* **Mainnet:** [network.radiustech.xyz](https://network.radiustech.xyz)
* **Testnet:** [testnet.radiustech.xyz](https://testnet.radiustech.xyz)
Ensure your wallet has USDC or SBC and ETH or Base ETH for source network gas fees.
#### Step 2: Select networks
* **Source:** Ethereum, Base, Sepolia, or Base Sepolia
* **Destination:** Radius (mainnet or testnet)
* **Token:** USDC or SBC
#### Step 3: Enter amount
Enter the amount to bridge to Radius. USDC is automatically converted to SBC on arrival.
#### Step 4: Approve conversion
Approve the transfer on the source chain.
**Bridge times:**
* Ethereum: \~5-10 minutes
* Base: \~1-2 minutes
* Sepolia/Base Sepolia: \~2-10 minutes
#### Step 5: Verify on Radius
Check your SBC balance on Radius:
* **Mainnet explorer:** [network.radiustech.xyz/explorer](https://network.radiustech.xyz/explorer)
* **Testnet explorer:** [testnet.radiustech.xyz/testnet/explorer](https://testnet.radiustech.xyz/testnet/explorer)
### Ready to transact
You can transact immediately after bridging.
### Further reading
* [Claim SBC on Radius](/getting-started/claim-and-transact) — Get free SBC directly on Radius
* [Network configuration](/developer-resources/network-configuration) — RPC endpoints and chain IDs
* [Fees and Turnstile](/developer-resources/fees) — How gas fees work
```
```
## Claim SBC and Transact \[Sign up, claim SBC, and send your first transaction on Radius Network]
:::tip
**This guide uses Radius Network (mainnet) with real money.**
If you want to test without real money, the same process works on [Radius Testnet](https://testnet.radiustech.xyz).
:::
### What you'll do
1. Sign up at network.radiustech.xyz (no existing wallet necessary)
2. Claim free SBC
3. Send a test transaction
4. View the transaction on the explorer
### Prerequisites
* An email address or social account
* 2 minutes
### Step 1: Sign up and get a wallet
Visit [network.radiustech.xyz](https://network.radiustech.xyz) and sign up.
Radius uses Privy to create an embedded wallet for you automatically. No browser extension needed.
After signup, you'll have:
* A Radius wallet address
* Access to the dashboard
* Access to claim SBC
### Step 2: Claim SBC
In the dashboard, click Add Funds and claim SBC.
**This is a real dollar pegged stablecoin (ERC-20 token) pegged 1:1 to USD.** Use it for transactions on Radius Bridged to other networks (Ethereum, Base)
### Step 3: Send a transaction
#### Dashboard Instructions
1. Click Send funds
2. Enter the recipient address and amount of SBC ("stablecoin") you want to send
3. Click Send
#### Programmatic Instructions
Alternatively, use viem (TypeScript):
```typescript
import { createWalletClient, http, parseUnits } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
// Define Radius Network (mainnet)
const radius = {
id: 723,
name: 'Radius',
nativeCurrency: { name: 'RUSD', symbol: 'RUSD', decimals: 18 },
rpcUrls: {
default: { http: ['https://rpc.radiustech.xyz'] },
},
}
// Your Privy wallet's private key (export from dashboard)
const account = privateKeyToAccount('{{PRIVATE_KEY}}')
const client = createWalletClient({
account,
chain: radius,
transport: http(),
})
// Send SBC (ERC-20 transfer)
const hash = await client.writeContract({
address: '0x33ad9e4bd16b69b5bfded37d8b5d9ff9aba014fb', // SBC contract
abi: [{
name: 'transfer',
type: 'function',
inputs: [
{ name: 'to', type: 'address' },
{ name: 'amount', type: 'uint256' }
],
outputs: [{ name: '', type: 'bool' }],
stateMutability: 'nonpayable',
}],
functionName: 'transfer',
args: ['0xRecipientAddress', parseUnits('1', 6)], // 1 SBC (6 decimals)
})
console.log('Transaction hash:', hash)
```
import { FeatureCards } from '../../components/FeatureCards'
## Getting Started \[Choose how you want to start]
Radius Network is a stablecoin-native EVM network with sub-second finality and 2.5M TPS through sharding.
### Transact on Radius Network with stablecoins
:::info
SBC ([https://stablecoin.xyz/](https://stablecoin.xyz/)) is the first stablecoin available on Radius Network.
To get started, either bridge your existing USDC or SBC from Ethereum or Base to Radius Network, or claim 1 USD in SBC directly in the dashboard.
:::
### Want to do something else?
import { TX_FEE, THROUGHPUT, DASHBOARD_URL } from '../../constants'
### Linear Scalability
Traditional blockchains hit throughput ceilings. Adding more nodes doesn't help because every node must process every transaction in sequence. Radius takes a different approach: sharded state with parallel execution.
#### State sharding model
State consists of `key : value` pairs representing data elements used with Radius Network, including smart contract code, their "data", and account balances. Radius distributes distinct state elements across multiple independent shard clusters:
Each shard:
* Runs as a 3-node Raft cluster (tolerates 1 node failure)
* Stores a partition of the global state
* Processes transactions independently of other shards
#### Why this scales linearly
| Shards | Keyspace per shard | Throughput |
| ------ | ------------------ | ---------- |
| 1 | 100% | 1x |
| 2 | 50% each | \~2x |
| 4 | 25% each | \~4x |
| N | 1/N each | \~Nx |
Double the shards, approximately double the throughput for non-conflicting workloads. The system supports up to **16.7 million shards** (24-bit shard indexing).
### How sharding works
#### State Partitioning
Keys are hashed and distributed across shards via a prefix tree. When the system scales:
1. New shard cluster starts
2. Routing table updates with new keyspace assignment
3. Keys migrate lazily on first access
4. Old shard forwards lookups to new location
#### Zero-Downtime Scaling
Scaling operations happen without interrupting service:
```mermaid
sequenceDiagram
participant Agent
participant Router
participant OldShard as Shard 0
participant NewShard as Shard 1
Note over Router: Keyspace split: Shard 1 now owns 800000-ffffff
Agent->>Router: Where is key ABC (hash: 9f...)?
Router->>Agent: [Shard 1, Shard 0] (new first, old as fallback)
Agent->>NewShard: try_lock ABC
NewShard->>Agent: Empty (not migrated yet)
Agent->>OldShard: try_lock ABC
OldShard->>Agent: value: 0x55b3f5f2
Note over Agent: Migrate key to new shard
Agent->>NewShard: prepare(ABC = 0x55b3f5f2)
Agent->>OldShard: prepare(ABC = Migrated(Shard 1))
Agent->>NewShard: commit
Agent->>OldShard: commit
```
#### Parallel Execution
Transactions accessing different keys execute simultaneously. No global ordering required:
Only transactions touching the same keys require coordination.
### The Architecture
Radius uses a distributed architecture based on [PArSEC](https://dci.mit.edu/s/p.pdf) (Parallel Sharded Transactions with Contracts):
#### Why No Blocks?
Traditional blockchains batch transactions into blocks for consensus and propagation. Radius eliminates these constraints:
| Aspect | Blockchain | Radius |
| ----------- | -------------------------------------- | -------------------------------- |
| Consensus | Global (all nodes agree on block) | Per-shard (Raft replication) |
| Ordering | Sequential (one block at a time) | Parallel (independent shards) |
| Propagation | Broadcast blocks to all nodes | Direct writes to relevant shards |
| Finality | Probabilistic (wait for confirmations) | Immediate |
#### Per-Shard Consensus
Instead of global consensus on a block of transactions, Radius achieves consensus per-shard using Raft. Each shard independently replicates its state changes. This means:
* No mining or proof-of-work
* No validator coordination overhead
* No block production delays
* Immediate finality once Raft commits
### Congestion Control
When multiple transactions compete for the same key, Radius uses intelligent batching:
1. **Detection**: Shards track which keys cause transaction conflicts
2. **Routing**: Frontend routes conflicting transactions to the same backend
3. **Batching**: Backend executes conflicting transactions sequentially within a single batch
4. **Efficiency**: One lock acquisition serves the entire batch
```mermaid
flowchart LR
subgraph Without["Without Batching"]
direction TB
T1["Tx1"] --> Lock1["Lock X"]
T2["Tx2"] --> Lock1
T3["Tx3"] --> Lock1
Lock1 -->|"conflicts"| X1["❌"]
end
subgraph With["With Batching"]
direction TB
Batch["Batch: Tx1, Tx2, Tx3"] -->|"single lock"| Lock2["Lock X"]
Lock2 -->|"execute sequentially"| OK["✓ No conflicts"]
end
```
### Specialized Shards
Radius supports heterogeneous shard configurations for different access patterns:
| Shard Type | Purpose | Use Case |
| ----------- | ----------------------- | ------------------------ |
| **Regular** | General state storage | Default workloads |
| **Receipt** | Transaction receipts | Append-heavy, read-light |
| **Edge** | Specific contracts/keys | High-traffic contracts |
Edge shards allow routing high-traffic contracts to dedicated infrastructure without affecting the rest of the system.
### Live Metrics
Track real-time network performance:
* [Dashboard →](https://network.radiustech.xyz/) — Live TPS, settlement times, shard health
### Compared to Other Approaches
| Approach | Scaling Method | Consistency | Complexity |
| ----------------- | ----------------------- | ------------------- | ----------- |
| **L1 Blockchain** | Vertical (bigger nodes) | Global ordering | Low |
| **Rollups/L2** | Multiple chains | Bridge-dependent | High |
| **Radius** | Horizontal (add shards) | Per-shard consensus | Transparent |
### Next Steps
* [Designed for the Internet of Tomorrow](/differentiators/designed-for-internet-of-tomorrow) — EVM compatibility and differences
* [JSON-RPC API](/developer-resources/json-rpc-api) — Complete API reference
* [Quick Start](/getting-started/claim-and-transact) — Get from zero to first transaction
import { TX_FEE, TESTNET_RPC_URL, TESTNET_CHAIN_ID, NATIVE_TOKEN, HARDFORK, GAS_PRICE } from '../../constants'
## Designed for the Internet of Tomorrow \[EVM-compatible with different economics and architecture. Deploy Solidity contracts unchanged, use Foundry and viem.]
### What works
Your existing Ethereum development workflow transfers directly to Radius:
| Tool/Framework | Status |
| ------------------------ | -------------------------------------------- |
| **Solidity** | Fully supported (Validated up to {HARDFORK}) |
| **wagmi** | Compatible |
| **viem** | Compatible |
| **OpenZeppelin** | Compatible |
| **Foundry** | Compatible |
| **Standard precompiles** | Compatible (Validated up to {HARDFORK}) |
### What's different from other EVMs
Radius optimizes for payments. This means deliberate differences from standard Ethereum behavior:
#### Predictable fees (not market-dependent)
Traditional blockchain fees fluctuate with network demand. Radius charges a fixed {TX_FEE} per transaction—predictable, auditable, and calculable.
#### Stablecoin Fees
| Ethereum | Radius |
| ---------------------------------- | ------------------------------ |
| Fees paid in ETH | Fees paid in stablecoins (USD) |
| Must hold native token | No separate gas token needed |
| `eth_gasPrice` returns market rate | Returns {GAS_PRICE} ({TX_FEE}) |
#### Faster Finality
| Ethereum | Radius |
| -------------------------------- | ---------------------- |
| \~12 minutes for high confidence | Immediate |
| 12+ confirmations recommended | 0 confirmations needed |
| Reorgs possible | No reorgs |
### Key Differences from Ethereum
| Feature | Ethereum | Radius |
| ------------------- | --------------------------- | --------------------------- |
| **Fee model** | Market-based (ETH bids) | Fixed {TX_FEE} |
| **Settlement time** | 12+ minutes | Instant (milliseconds) |
| **Failed txs** | Charge gas even if reverted | Charge only on success |
| **Required token** | Must hold ETH | Optional (stablecoins work) |
#### Practical Implications
**Your contracts work unchanged:**
```solidity
// Standard ERC-20 interactions
IERC20(token).transfer(recipient, amount);
// Storage operations
mapping(address => uint256) balances;
balances[msg.sender] = 100;
// Events
emit Transfer(from, to, amount);
```
**Avoid native balance patterns:**
```solidity
// Don't do this (always returns 0)
require(address(this).balance > 0);
// Do this instead
require(IERC20(feeToken).balanceOf(address(this)) > 0);
```
### How Radius ensures data integrity
Radius uses operator trust + replication rather than decentralized consensus:
* 3-node clusters provide fault tolerance (operator nodes replicate data)
* Cryptographic signing prevents tampering
* Deterministic execution ensures consistency
This trade-off (known operators for instant finality) is appropriate for payment infrastructure.
### Future-Proofing
#### Real-time autonomous payments
AI agents need to pay for services (APIs, data, compute) instantly. Traditional payment processors require 30+ day settlement. Radius provides:
* **Instant settlement** — Agent gets confirmation in milliseconds
* **Sub-cent costs** — Enables per-request pricing
* **Stablecoin support** — Agents don't need volatile assets
#### Micropayments
When transactions cost $0.0001, new business models become viable:
* **Per-request API billing**: Charge per call, not monthly
* **Content micropayments**: Pay per article, not subscription
* **Streaming payments**: Pay by the second for compute
Traditional payment processors (Stripe, PayPal) can't economically support these patterns. Radius can.
#### EIP Support ({HARDFORK})
Radius tracks the {HARDFORK} hardfork via Revm 33.1.0:
| EIP | Support |
| -------- | ------------------------------------ |
| EIP-7702 | Set EOA account code |
| EIP-1559 | Fee market (adapted for stablecoins) |
| EIP-2930 | Access lists |
| EIP-4844 | Blob transactions |
#### Precompiles
All standard precompiles plus Radius extensions:
| Address | Precompile |
| --------------- | ----------------------------- |
| `0x01` - `0x0a` | Standard Ethereum precompiles |
| `0x4Db27Fa...` | Radius Edge (external data) |
| `0x07a2bA2...` | Debug utilities |
### Network Configuration
```
Network Name: Radius Testnet
RPC URL: {TESTNET_RPC_URL}
Chain ID: {TESTNET_CHAIN_ID}
Currency Symbol: {NATIVE_TOKEN}
```
### Next Steps
* [Divergence from Ethereum](/developer-resources/ethereum-divergence) — Deep dive into block handling, coinbase, and other technical differences
* [Network Configuration](/developer-resources/network-configuration) — RPC endpoints, chain ID, and wallet setup
* [Fees](/developer-resources/fees) — How stablecoin fees and the Turnstile work
## Contract Addresses \[Deployed contracts on Radius Testnet]
### Core Contracts
#### radUSD Token
**Address:**
```
0xF966020a30946A64B39E2e243049036367590858
```
Stablecoin used for gas fees on Radius Testnet.
### Utility Contracts
Standard Ethereum contracts deployed at their canonical addresses for developer convenience.
| Contract | Address | Description |
| -------------------------------------------------------------------------------------- | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| [Arachnid Create2 Factory](https://github.com/Arachnid/deterministic-deployment-proxy) | `0x4e59b44847b379578588920cA78FbF26c0B4956C` | Deploy contracts to deterministic addresses using CREATE2. Enables predictable addresses across chains and upgrade patterns. |
| [CreateX](https://github.com/pcaversaccio/createx) | `0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed` | Advanced deployment factory supporting CREATE, CREATE2, and CREATE3. Includes cross-chain address prediction and salt mining utilities. |
| [Multicall3](https://github.com/mds1/multicall) | `0xcA11bde05977b3631167028862bE2a173976CA11` | Aggregate multiple contract reads into a single RPC call. Reduces latency and enables atomic state snapshots for frontends and indexers. |
| [Permit2](https://github.com/Uniswap/permit2) | `0x000000000022D473030F116dDEE9F6B43aC78BA3` | Unified token approval system from Uniswap. Enables gasless approvals via signatures and batched transfers across multiple tokens. |
***
**Note:** Mainnet contract addresses are added once Radius launches on mainnet.
import { Callout } from 'vocs/components';
## Divergence from Ethereum
### Overview
Radius diverges from standard Ethereum behavior in several key ways. This section outlines the most significant differences.
### Blocks
Radius does not inherently rely on blocks, in that it does not require batches of transactions to be grouped together and agreed on accordingly. Instead, the atomic unit of execution is a single transaction.
So long as the transaction is valid at the time of execution, it is executed.
However, given that Radius is EVM-compatible, and it is designed to support the Ethereum JSON-RPC API, block-oriented RPC methods, and block-related opcodes are still supported, just with some differences worth noting.
A primary difference is that blocks are not stored as part of the Radius state during execution. Instead, a block is generated on-the-fly as needed, when responding to a block-related RPC request. See [Block Hashes](#block-hashes) for more details on how this block differs from a standard Ethereum block.
#### Block Numbers
{/* should I refer to "agents" directly? Is "execution layer" better? */}
Block numbers in Radius correspond to timetstamps in milliseconds. Therefore, the block number of a transaction is the time at which it occurred, and a "block" contains all of the transactions that occurred within that millisecond.
When requested, this block is reconstructed by the execution layer, but it is otherwise not stored in block form as part of the Radius state. This is in part due to optimizing for speed, and also because there is no consensus step for a "block" that would allow for a real-time consistent view of what a "block" is.
Moreover, blocks after a certain point will not be re-constructed with particularly old transactions. The length of time is dependent on the volume of transactions processed by the system.
Block numbers retrieved by [eth\_blockNumber](/developer-resources/json-rpc-api#eth_blocknumber) return the current timestamp in milliseconds, as this is the current block number.
#### Block Hashes
The block hash is the same as the block number for a given block. This, again, is due to the fact that there is no real time consistent view of what transactions are in a block.
Additionally, given that blocks are not an official part of the Radius state, we do not generate a hash for each block after the fact, as at least in Ethereum is based on the previous block hash, so there is a dependency chain that is not maintained.
#### `BLOCKHASH (0x40)`
The `BLOCKHASH` opcode is supported, but given that the hash is a timestamp, it may not be suitable for use in contracts leveraging it for pseudorandomness [^1].
[^1]: This is mentioned as a naïve example in the [Ethereum Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf).
Contract authors should be aware and act accordingly.
{/* Maybe this is not suitable for dev-docs */}
Additionally, if there is sufficient demand, Radius could support precompiles to provide pseudorandomness.
#### Beneficiaries and `COINBASE (0x41)`
Gas fees in Radius are paid to a specific set of beneficiary addresses, and the number of beneficiary addresses available is known at any given time.
However, reads of the balance or state of any of the beneficiary addresses are not guaranteed to be fresh.
The rationale for this is at high volumes, the beneficiary addresses are updated frequently, and requiring every transaction to lock the beneficiary address would be too expensive computationally.
So, as a concession, reads of the beneficiary address within contract execution return an empty account.
Calls to `eth_getBalance` return a view of the beneficiary address balance, though it is read ephemerally and may be stale.
The `COINBASE` opcode faithfully returns the beneficiary address corresponding to the execution environment of the current transaction. However,
if the account state is read as a part of the same transaction, it returns an empty account. This is also true for any reads of other beneficiary addresses.
Reading the coinbase account state within the transaction does not appear to be a common pattern, but it is worth being well aware of as a developer.
#### Stored transaction data
Receipts in Radius are largely the same as in Ethereum, however the `transactionIndex` field is not necessarily accurate.
If multiple transactions occur within the same millisecond timestamp, the resultant constructed pseudo-block will contain multiple transactions, but the receipt
for each will have the same `transactionIndex` (0).
Since we do not sequence transactions into a block, we cannot faithfully denote the transaction index in the receipt in all cases.
So, this field while present, can be disregarded and should not be relied on.
import { TESTNET_RPC_URL, TESTNET_CHAIN_ID, FEE_CONTRACT, FAUCET_URL } from '../../constants'
## JSON-RPC API \[Compatible with Ethereum tooling, accessible over HTTP and WebSocket]
Radius exposes a JSON-RPC 2.0 API compatible with standard Ethereum tooling and development libraries.
### Network Configuration
| Network | RPC Endpoint | Chain ID |
| ------- | ----------------- | ------------------ |
| Testnet | {TESTNET_RPC_URL} | {TESTNET_CHAIN_ID} |
### Quick Start
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'
```
Response:
```json
{
"jsonrpc": "2.0",
"id": 1,
"result": "0x11a98"
}
```
***
### eth\_\* Methods
Standard Ethereum JSON-RPC methods for account queries, transactions, and state access.
#### eth\_chainId
Get the chain ID of the network.
**Parameters:** None
**Returns:** `string` - The chain ID as a hex string
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'
```
```json
{"jsonrpc":"2.0","id":1,"result":"0x11a98"}
```
***
#### eth\_blockNumber
Get the current block number.
**Parameters:** None
**Returns:** `string` - The current block number as a hex string
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
```
***
#### eth\_getBalance
Get the balance of an address.
:::info
On Radius, fees are paid in stablecoins (USD) rather than a native gas token. This method returns your actual native balance plus the maximum native token you could receive by converting your USD through the Turnstile mechanism. This supports wallets that check balance before allowing transactions.
:::
**Parameters:**
| Name | Type | Description |
| ------- | -------- | ----------------------------------------------------- |
| address | `string` | The address to query (20 bytes, hex encoded) |
| block | `string` | Block number or tag (`latest`, `earliest`, `pending`) |
**Returns:** `string` - The balance in wei as a hex string
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0x0000000000000000000000000000000000000000","latest"],"id":1}'
```
***
#### eth\_getTransactionCount
Get the transaction count (nonce) for an address.
**Parameters:**
| Name | Type | Description |
| ------- | -------- | ----------------------------------------------------- |
| address | `string` | The address to query |
| block | `string` | Block number or tag (`latest`, `earliest`, `pending`) |
**Returns:** `string` - The transaction count as a hex string
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_getTransactionCount","params":["0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18","latest"],"id":1}'
```
***
#### eth\_sendRawTransaction
Submit a signed transaction to the network.
**Parameters:**
| Name | Type | Description |
| ---- | -------- | ---------------------------------------------- |
| data | `string` | The signed transaction data (RLP encoded, hex) |
**Returns:** `string` - The transaction hash (32 bytes, hex encoded)
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":["0x02f8..."],"id":1}'
```
***
#### eth\_call
Execute a call without creating a transaction (dry run).
**Parameters:**
| Name | Type | Description |
| ----------- | -------- | ------------------------------ |
| transaction | `object` | Transaction call object |
| block | `string` | Block number or tag (optional) |
Transaction call object:
| Field | Type | Description |
| ----- | -------- | ------------------------- |
| from | `string` | Sender address (optional) |
| to | `string` | Contract address |
| data | `string` | Encoded function call |
| value | `string` | Value to send (optional) |
| gas | `string` | Gas limit (optional) |
**Returns:** `string` - The return value of the executed contract call
**Example:**
```bash
# Query USD token name
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"method":"eth_call",
"params":[{
"to":"0xF966020a30946A64B39E2e243049036367590858",
"data":"0x06fdde03"
},"latest"],
"id":1
}'
```
***
#### eth\_estimateGas
Estimate the gas required for a transaction.
**Parameters:**
| Name | Type | Description |
| ----------- | -------- | ------------------------------------------- |
| transaction | `object` | Transaction call object (same as eth\_call) |
**Returns:** `string` - Estimated gas as a hex string
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"method":"eth_estimateGas",
"params":[{
"from":"0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18",
"to":"0xF966020a30946A64B39E2e243049036367590858",
"data":"0xa9059cbb..."
}],
"id":1
}'
```
***
#### eth\_gasPrice
:::info
We set the gas price to allow for 100,000 transactions / dollar, derived from the expected gas consumption of the Turnstile asset.
:::
Get the current gas price.
**Parameters:** None
**Returns:** `string` - Gas price in wei as a hex string
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_gasPrice","params":[],"id":1}'
```
```json
{"jsonrpc":"2.0","id":1,"result":"0x653b9cf"}
```
***
#### eth\_getCode
Get the bytecode at a given address.
**Parameters:**
| Name | Type | Description |
| ------- | -------- | ------------------------------ |
| address | `string` | Contract address |
| block | `string` | Block number or tag (optional) |
**Returns:** `string` - The bytecode at the address
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_getCode","params":["0xF966020a30946A64B39E2e243049036367590858","latest"],"id":1}'
```
***
#### eth\_getStorageAt
Get the value of a storage slot at a given address.
**Parameters:**
| Name | Type | Description |
| -------- | -------- | ------------------------------ |
| address | `string` | Contract address |
| position | `string` | Storage slot position (hex) |
| block | `string` | Block number or tag (optional) |
**Returns:** `string` - The storage value (32 bytes, hex)
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_getStorageAt","params":["0xF966020a30946A64B39E2e243049036367590858","0x0","latest"],"id":1}'
```
***
#### eth\_getTransactionByHash
Get transaction details by hash.
**Parameters:**
| Name | Type | Description |
| ---- | -------- | -------------------------------- |
| hash | `string` | Transaction hash (32 bytes, hex) |
**Returns:** `object | null` - Transaction object or null if not found
Transaction object fields:
| Field | Type | Description |
| ----------- | -------- | ----------------- |
| hash | `string` | Transaction hash |
| blockHash | `string` | Block hash |
| blockNumber | `string` | Block number |
| from | `string` | Sender address |
| to | `string` | Recipient address |
| value | `string` | Value transferred |
| input | `string` | Transaction data |
| nonce | `string` | Sender nonce |
| gas | `string` | Gas limit |
| type | `string` | Transaction type |
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_getTransactionByHash","params":["0x..."],"id":1}'
```
***
#### eth\_getTransactionReceipt
Get the receipt of a transaction.
**Parameters:**
| Name | Type | Description |
| ---- | -------- | -------------------------------- |
| hash | `string` | Transaction hash (32 bytes, hex) |
**Returns:** `object | null` - Receipt object or null if not found
Receipt object fields:
| Field | Type | Description |
| --------------- | -------- | ---------------------------------------- |
| transactionHash | `string` | Transaction hash |
| blockHash | `string` | Block hash |
| blockNumber | `string` | Block number |
| from | `string` | Sender address |
| to | `string` | Recipient address |
| status | `string` | `0x1` for success, `0x0` for failure |
| gasUsed | `string` | Gas used |
| logs | `array` | Array of log objects |
| contractAddress | `string` | Created contract address (if deployment) |
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["0x..."],"id":1}'
```
***
#### eth\_getLogs
Get logs matching a filter.
**Parameters:**
| Name | Type | Description |
| ------ | -------- | ------------- |
| filter | `object` | Filter object |
Filter object:
| Field | Type | Description | |
| --------- | -------- | ---------------------- | -------------------- |
| fromBlock | `string` | Start block (optional) | |
| toBlock | `string` | End block (optional) | |
| address | \`string | array\` | Contract address(es) |
| topics | `array` | Topic filters | |
**Returns:** `array` - Array of log objects
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"method":"eth_getLogs",
"params":[{
"address":"0xF966020a30946A64B39E2e243049036367590858",
"fromBlock":"0x0",
"toBlock":"latest"
}],
"id":1
}'
```
***
#### eth\_getBlockByNumber
Get block information by block number.
**Parameters:**
| Name | Type | Description |
| ----- | --------- | ----------------------------------------- |
| block | `string` | Block number or tag |
| full | `boolean` | If true, returns full transaction objects |
**Returns:** `object` - Block object
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",false],"id":1}'
```
***
#### eth\_getBlockByHash
Get block information by block hash.
:::info
This is pseudo-supported. Radius does not index blocks by hash in the traditional sense.
:::
**Parameters:**
| Name | Type | Description |
| ---- | --------- | ----------------------------------------- |
| hash | `string` | Block hash |
| full | `boolean` | If true, returns full transaction objects |
**Returns:** `object` - Block object
***
#### eth\_accounts
Get the list of accounts managed by the node.
**Note:** Radius does not manage accounts. This method always returns an empty array.
**Parameters:** None
**Returns:** `array` - Empty array `[]`
***
#### eth\_maxPriorityFeePerGas
Get the suggested priority fee.
**Note:** Returns `0x0` because Radius does not use priority fee bidding for transaction inclusion.
**Parameters:** None
**Returns:** `string` - Priority fee (always `0x0`)
***
#### eth\_feeHistory
Get historical fee data.
**Note:** Pseudo-supported. Radius uses stablecoin fees rather than dynamic gas pricing.
**Parameters:** See Ethereum JSON-RPC specification
**Returns:** `object` - Fee history object
***
#### eth\_mining
Get whether the node is actively mining.
**Parameters:** None
**Returns:** `boolean` - Always `true` (agents are always accepting transactions)
***
#### eth\_syncing
Get the sync status.
**Parameters:** None
**Returns:** `boolean` - Always `false` (no syncing in Radius architecture)
***
#### eth\_hashrate
Get the current hashrate.
**Parameters:** None
**Returns:** `string` - Always `0x0` (Radius does not use proof-of-work)
***
#### eth\_createAccessList
Create an access list for a transaction.
**Parameters:**
| Name | Type | Description |
| ----------- | -------- | ------------------------------ |
| transaction | `object` | Transaction call object |
| block | `string` | Block number or tag (optional) |
**Returns:** `object` - Access list result with `accessList` and `gasUsed`
***
#### eth\_subscribe
Create a subscription for real-time log events (WebSocket only).
**Parameters:**
| Name | Type | Description |
| ------ | -------- | --------------------------------------- |
| type | `string` | Subscription type (for example, `logs`) |
| filter | `object` | Filter object |
**Returns:** `string` - Subscription ID
***
#### eth\_uninstallFilter
Uninstall a filter.
**Note:** Radius does not persist filters. This method always returns `true`.
**Parameters:**
| Name | Type | Description |
| -------- | -------- | ----------- |
| filterId | `string` | Filter ID |
**Returns:** `boolean` - Always `true`
***
### web3\_\* Methods
Web3 utility methods.
#### web3\_clientVersion
Get the client version string.
**Parameters:** None
**Returns:** `string` - Client version
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":1}'
```
```json
{"jsonrpc":"2.0","id":1,"result":"0.1.0"}
```
***
#### web3\_sha3
Get the Keccak-256 hash of the given data.
**Parameters:**
| Name | Type | Description |
| ---- | -------- | -------------------------- |
| data | `string` | Data to hash (hex encoded) |
**Returns:** `string` - Keccak-256 hash (32 bytes, hex)
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"web3_sha3","params":["0x68656c6c6f"],"id":1}'
```
***
### net\_\* Methods
Network information methods.
#### net\_version
Get the network ID.
**Parameters:** None
**Returns:** `string` - Network ID (same as chain ID: {TESTNET_CHAIN_ID})
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"net_version","params":[],"id":1}'
```
```json
{"jsonrpc":"2.0","id":1,"result":"72344"}
```
***
#### net\_listening
Get whether the node is listening for peers.
**Parameters:** None
**Returns:** `boolean` - Always `false` (Radius does not use peer-to-peer networking)
***
#### net\_peerCount
Get the number of connected peers.
**Parameters:** None
**Returns:** `string` - Always `0x0` (Radius does not use peer-to-peer networking)
***
### dash\_\* Methods
Radius Dashboard methods for monitoring and analytics.
#### dash\_globalGasUsage
Get the total gas usage across the system.
**Parameters:** None
**Returns:** `number` - Total gas usage as a floating-point number
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"dash_globalGasUsage","params":[],"id":1}'
```
***
#### dash\_globalTps
Get the current transactions per second across the system.
**Parameters:** None
**Returns:** `number` - TPS as a floating-point number
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"dash_globalTps","params":[],"id":1}'
```
```json
{"jsonrpc":"2.0","id":1,"result":26.486095339407825}
```
***
#### dash\_latestTransactions
Get the most recent transactions.
**Parameters:**
| Name | Type | Description |
| ----- | -------- | -------------------------------- |
| count | `number` | Number of transactions to return |
**Returns:** `array` - Array of compact transaction objects
Transaction object:
| Field | Type | Description |
| ------- | -------- | -------------------- |
| hash | `string` | Transaction hash |
| from | `string` | Sender address |
| to | `string` | Recipient address |
| value | `string` | Value transferred |
| ts | `string` | Timestamp |
| success | `number` | Status (1 = success) |
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"dash_latestTransactions","params":[10],"id":1}'
```
***
#### dash\_findTransactionsByAddress
Get transactions involving a specific address.
**Parameters:**
| Name | Type | Description |
| ------- | -------- | ---------------- |
| address | `string` | Address to query |
**Returns:** `array` - Array of compact transaction objects
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"dash_findTransactionsByAddress","params":["0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18"],"id":1}'
```
***
### rad\_\* Methods
Radius-specific debugging and utility methods.
#### rad\_decodeKey
Decode a hashed key by monitoring broker operations and returning the matching raw key.
**Parameters:**
| Name | Type | Description |
| ---- | -------- | -------------------- |
| key | `string` | Hashed key to decode |
**Returns:** `string` - The decoded raw key
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"rad_decodeKey","params":["0x..."],"id":1}'
```
***
### trace\_\* Methods
Transaction tracing methods (Parity-compatible).
#### trace\_call
Execute a call and retrieve detailed trace information.
**Parameters:**
| Name | Type | Description |
| -------------- | -------- | ----------------------------------------------------------- |
| call | `object` | Transaction call object |
| traceTypes | `array` | Types of traces to return (`trace`, `vmTrace`, `stateDiff`) |
| blockId | `string` | Block number or tag (optional) |
| stateOverrides | `object` | State overrides (optional) |
| blockOverrides | `object` | Block overrides (optional) |
**Returns:** `object` - Trace results object
**Example:**
```bash
curl -X POST https://rpc.testnet.radiustech.xyz \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"method":"trace_call",
"params":[
{"to":"0xF966020a30946A64B39E2e243049036367590858","data":"0x06fdde03"},
["trace"],
"latest"
],
"id":1
}'
```
***
### Error Codes
Radius uses standard JSON-RPC 2.0 error codes:
| Code | Message | Description |
| ------ | ------------------ | --------------------------- |
| -32700 | Parse error | Invalid JSON |
| -32600 | Invalid request | Invalid request object |
| -32601 | Method not found | Method does not exist |
| -32602 | Invalid params | Invalid method parameters |
| -32603 | Internal error | Internal JSON-RPC error |
| 3 | Execution reverted | Contract execution reverted |
***
### Contract Addresses
#### Testnet
| Contract | Address |
| -------------------- | -------------------------------------------- |
| USD (Fee Token) | {FEE_CONTRACT} |
| EntryPoint v0.7 | `0x9b443e4bd122444852B52331f851a000164Cc83F` |
| SimpleAccountFactory | `0x4DEbDe0Be05E51432D9afAf61D84F7F0fEA63495` |
***
### Resources
* [Faucet](https://testnet.radiustech.xyz/testnet/faucet) - Get testnet USD tokens
* [EVM Compatibility](/differentiators/designed-for-internet-of-tomorrow) - Differences from standard Ethereum
import { TESTNET_RPC_URL, TESTNET_CHAIN_ID, NATIVE_TOKEN, FAUCET_URL, EXPLORER_URL } from '../../constants'
## Network Configuration
The Radius Network is a public production network with live stablecoin transfers. Radius also maintains an open testnet for experimentation.
### Radius Network
| Setting | Value |
| ------------------- | ----------------------------------------------- |
| **Network Name** | Radius Mainnet |
| **RPC Endpoint** | `https://rpc.radiustech.xyz` |
| **Chain ID** | `723` |
| **Currency Symbol** | RUSD |
| **Block Explorer** | `https://network.radiustech.xyz` |
| **Faucet** | `https://network.radiustech.xyz/testnet/faucet` |
### Radius Testnet
| Setting | Value |
| ------------------- | ------------------ |
| **Network Name** | Radius Testnet |
| **RPC Endpoint** | {TESTNET_RPC_URL} |
| **Chain ID** | {TESTNET_CHAIN_ID} |
| **Currency Symbol** | {NATIVE_TOKEN} |
| **Block Explorer** | {EXPLORER_URL} |
| **Faucet** | {FAUCET_URL} |
### Add to wallet
#### MetaMask
1. Open MetaMask and select **Add Network**
2. Enter the settings from the table above
3. Save and switch to Radius
#### Programmatic (viem)
```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',
},
},
})
```
### Get testnet funds
Visit the [Radius Faucet](https://testnet.radiustech.xyz/testnet/faucet) to receive testnet USD for development.
***
## Rate limiting
### Overview
This page covers rate limits for the Radius Network RPC and best practices for handling them.
### Rate Limiting "Gas"
Radius Network tracks the number of requests made to the RPC url per API key. Users who do not use an API key get a lower threshold of requests per second.
API keys default to 10MGas/s. For higher rate limits, please contact Radius at [support@radiustech.xyz](mailto\:support@radiustech.xyz).
The "Gas" in this context includes any RPC call, but also is incremented by gas consumed by transactions.