Frontend Development
Building decentralized applications (dApps) on Splendor is straightforward due to our full compatibility with the Ethereum ecosystem. This page provides guidance for frontend developers integrating with Splendor V3 (Tokio).
Web3 Libraries
Splendor works seamlessly with all major Ethereum frontend libraries:
ethers.js
ethers.js  is a complete and compact library for interacting with the Ethereum Blockchain and its ecosystem.
// Example using ethers.js to connect to Splendor
import { ethers } from 'ethers';
// Connect to Splendor Mainnet
const provider = new ethers.JsonRpcProvider('https://chain.splendor.org');
// Get the latest block number
const getBlockNumber = async () => {
const blockNumber = await provider.getBlockNumber();
console.log(`Current block number: ${blockNumber}`);
return blockNumber;
};
web3.js
web3.js  is a collection of libraries that allow you to interact with a local or remote ethereum node using HTTP, IPC or WebSocket.
// Example using web3.js to connect to Splendor
import Web3 from 'web3';
// Connect to Splendor Mainnet
const web3 = new Web3('https://chain.splendor.org');
// Get the latest block number
const getBlockNumber = async () => {
const blockNumber = await web3.eth.getBlockNumber();
console.log(`Current block number: ${blockNumber}`);
return blockNumber;
};
React Integration with Wagmi
Wagmi  is a collection of React Hooks for working with Ethereum. It’s modular, efficient, and has great developer experience.
Installation
npm install wagmi viem@2.x
# or
yarn add wagmi viem@2.x
Configuration
// config.ts
import { http, createConfig } from 'wagmi'
import { mainnet, sepolia } from 'wagmi/chains'
import { defineChain } from 'viem'
// Define Splendor chains
export const splendorMainnet = defineChain({
id: 232,
name: 'Splendor',
nativeCurrency: {
decimals: 18,
name: 'Splendor',
symbol: 'SPL',
},
rpcUrls: {
default: { http: ['https://chain.splendor.org'] },
},
})
export const splendorTestnet = defineChain({
id: 231,
name: 'Splendor Testnet',
nativeCurrency: {
decimals: 18,
name: 'Splendor',
symbol: 'SPL',
},
rpcUrls: {
default: { http: ['https://testchain.splendor.org'] },
},
})
// Create wagmi config
export const config = createConfig({
chains: [splendorMainnet, splendorTestnet, mainnet, sepolia],
transports: {
[splendorMainnet.id]: http(),
[splendorTestnet.id]: http(),
[mainnet.id]: http(),
[sepolia.id]: http(),
},
})
React Components
// App.tsx
import { WagmiProvider } from 'wagmi'
import { config } from './config'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { ConnectButton } from './components/ConnectButton'
import { Account } from './components/Account'
import { Balance } from './components/Balance'
const queryClient = new QueryClient()
export function App() {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<div>
<h1>Splendor dApp Example</h1>
<ConnectButton />
<Account />
<Balance />
</div>
</QueryClientProvider>
</WagmiProvider>
)
}
ConnectButton Component
// components/ConnectButton.tsx
import { useConnect } from 'wagmi'
import { injected } from 'wagmi/connectors'
export function ConnectButton() {
const { connect, isPending } = useConnect()
return (
<button
onClick={() => connect({ connector: injected() })}
disabled={isPending}
>
{isPending ? 'Connecting...' : 'Connect Wallet'}
</button>
)
}
Account Component
// components/Account.tsx
import { useAccount, useDisconnect } from 'wagmi'
export function Account() {
const { address, isConnected } = useAccount()
const { disconnect } = useDisconnect()
if (!isConnected) return null
return (
<div>
<div>Connected to {address}</div>
<button onClick={() => disconnect()}>Disconnect</button>
</div>
)
}
Balance Component
// components/Balance.tsx
import { useAccount, useBalance } from 'wagmi'
export function Balance() {
const { address, isConnected } = useAccount()
const { data } = useBalance({
address,
})
if (!isConnected) return null
return (
<div>
Balance: {data?.formatted} {data?.symbol}
</div>
)
}
Wallets Integration
MetaMask
The most popular Ethereum wallet that works perfectly with Splendor. Learn how to add Splendor to MetaMask.
WalletConnect
Integrate WalletConnect to allow users to connect with multiple wallets:
npm install @web3modal/wagmi
// config.ts
import { http, createConfig } from 'wagmi'
import { mainnet } from 'wagmi/chains'
import { w3mConnectors } from '@web3modal/wagmi'
import { splendorMainnet, splendorTestnet } from './chains'
export const config = createConfig({
chains: [splendorMainnet, splendorTestnet, mainnet],
transports: {
[splendorMainnet.id]: http(),
[splendorTestnet.id]: http(),
[mainnet.id]: http(),
},
connectors: w3mConnectors({
projectId: 'YOUR_PROJECT_ID',
chains: [splendorMainnet, splendorTestnet, mainnet],
}),
})
Data Fetching
Fetch on-chain data with Wagmi hooks:
// Token balance example
import { useReadContract } from 'wagmi'
import { erc20Abi } from 'wagmi/abi'
export function TokenBalance({ tokenAddress }: { tokenAddress: string }) {
const { address } = useAccount()
const { data, isLoading } = useReadContract({
address: tokenAddress,
abi: erc20Abi,
functionName: 'balanceOf',
args: [address],
})
if (isLoading) return <div>Loading...</div>
if (!data) return <div>No data</div>
return (
<div>
Token Balance: {data.toString()}
</div>
)
}
Sending Transactions
import { useWriteContract } from 'wagmi'
import { erc20Abi } from 'wagmi/abi'
import { parseEther } from 'viem'
export function SendToken({ tokenAddress }: { tokenAddress: string }) {
const { writeContract, isPending, isSuccess } = useWriteContract()
const handleSend = () => {
writeContract({
address: tokenAddress,
abi: erc20Abi,
functionName: 'transfer',
args: ['0xRecipientAddress', parseEther('1')],
})
}
return (
<div>
<button onClick={handleSend} disabled={isPending}>
{isPending ? 'Sending...' : 'Send 1 Token'}
</button>
{isSuccess && <div>Transaction successful!</div>}
</div>
)
}
Best Practices
- Error Handling: Implement robust error handling for transactions and blockchain interactions
- Loading States: Always show loading indicators during pending transactions
- Gas Estimation: Estimate gas before submitting transactions to avoid failures
- Account Handling: Properly manage connected/disconnected states
- Network Detection: Detect and handle network changes gracefully
- Block Confirmations: Wait for sufficient block confirmations for important transactions
User Experience Tips
- Provide clear feedback for transaction states (pending, success, failed)
- Implement proper error messages that users can understand
- Consider using progressive disclosure for complex blockchain operations
- Provide transaction history and status
- Use optimistic UI updates when appropriate
Testing
Use tools like Hardhat  or Foundry  with local networks for testing before deploying to Splendor Testnet.