galaxis-web3-adapter
v0.4.4
Published
Web3 adapter for Galaxis applications with wagmi/viem/RainbowKit
Readme
Galaxis Web3 Adapter
A modern Web3 integration layer that simplifies blockchain interactions for Galaxis applications, providing a unified API across different underlying libraries.
Overview
The Galaxis Web3 Adapter offers a standardized way to interact with blockchain networks by wrapping around wagmi, viem, and RainbowKit while maintaining backward compatibility with ethers.js v5.
This adapter simplifies the transition from ethers.js to the wagmi+viem ecosystem, allowing both paradigms to work side-by-side during migration.
Features
- ✅ Modern React Hooks: Comprehensive set of typed React hooks for wallet connection and contract interactions
- ✅ Multi-chain Support: Connect to and interact with multiple blockchain networks
- ✅ Service Layer: Specialized services for common blockchain operations (registry, tokens, etc.)
- ✅ Backward Compatibility: Ethers.js v5 compatibility for legacy code
- ✅ Centralized ABIs: Single source of truth for contract ABIs
- ✅ TypeScript Support: Full TypeScript integration with proper types throughout
- ✅ Transaction Handling: Simplified transaction submission with status tracking
- ✅ Batch Operations: Efficient batched contract reads for better performance
- ✅ Particle Wallet Integration: Support for email and social login via Particle Network
Installation
npm install galaxis-web3-adapter
# or
yarn add galaxis-web3-adapterPeer Dependencies
This package requires the following peer dependencies:
{
"react": ">=18.0.0",
"react-dom": ">=18.0.0",
"wagmi": ">=2.14.11",
"@rainbow-me/rainbowkit": ">=2.0.0",
"@tanstack/react-query": ">=5.0.0",
"viem": ">=2.0.0",
"@mui/material": ">=5.6.4",
"ethers": ">=5.7.0 <6.0.0"
}Make sure to install these dependencies in your project:
npm install react react-dom wagmi @rainbow-me/rainbowkit @tanstack/react-query viem ethers@5
# or
yarn add react react-dom wagmi @rainbow-me/rainbowkit @tanstack/react-query viem ethers@5Note that the package specifically requires ethers v5 (not v6) for backward compatibility.
Quick Start
Setting Up the Provider
import { Web3Provider } from "galaxis-web3-adapter";
// Configuration
const config = {
projectId: "your-wallet-connect-project-id",
appName: "Your App Name",
};
// Chain information
const chainsInfo = [
{
id: 1,
name: "Ethereum",
native_currency: {
name: "Ether",
symbol: "ETH",
decimals: 18,
},
free_rpc: "https://eth.llamarpc.com",
public_rpc: "https://mainnet.infura.io/v3/your-key",
explorer_url: "https://etherscan.io",
},
// Add more chains as needed
];
function App() {
return (
<Web3Provider config={config} chainsInfo={chainsInfo}>
<YourApplication />
</Web3Provider>
);
}Using the Wallet Hook
import { useWallet } from "galaxis-web3-adapter";
function ConnectWallet() {
const { address, isConnected, handleConnect, handleDisconnect, chain } =
useWallet();
return (
<div>
{isConnected ? (
<>
<p>
Connected to {chain?.name} with address {address}
</p>
<button onClick={handleDisconnect}>Disconnect</button>
</>
) : (
<button onClick={handleConnect}>Connect Wallet</button>
)}
</div>
);
}Reading from a Contract
import { readContract } from "galaxis-web3-adapter";
import { ERC20_ABI } from "galaxis-web3-adapter";
import { useWallet } from "galaxis-web3-adapter";
function TokenBalance({ tokenAddress }) {
const [balance, setBalance] = useState("0");
const { wagmiConfig, address, isConnected, chainId } = useWallet();
useEffect(() => {
async function getBalance() {
if (isConnected && address) {
try {
const result = await readContract(wagmiConfig, {
address: tokenAddress,
abi: ERC20_ABI,
functionName: "balanceOf",
args: [address],
chainId,
});
setBalance(result.toString());
} catch (error) {
console.error("Error fetching balance:", error);
}
}
}
getBalance();
}, [wagmiConfig, address, isConnected, chainId, tokenAddress]);
return <div>Balance: {balance}</div>;
}Writing to a Contract
import { transactionWriteContract } from "galaxis-web3-adapter";
import { ERC20_ABI } from "galaxis-web3-adapter";
import { useWallet } from "galaxis-web3-adapter";
import { useState } from "react";
function TransferToken({ tokenAddress }) {
const [recipient, setRecipient] = useState("");
const [amount, setAmount] = useState("");
const [isSending, setIsSending] = useState(false);
const { wagmiConfig, chainId, switchChain } = useWallet();
const handleTransfer = async () => {
if (!recipient || !amount) return;
setIsSending(true);
try {
await transactionWriteContract(wagmiConfig, switchChain, {
address: tokenAddress,
abi: ERC20_ABI,
functionName: "transfer",
args: [recipient, BigInt(amount)],
chainId,
onTxSubmitted: (hash) => {
console.log("Transaction submitted:", hash);
},
onTxConfirmed: (receipt) => {
console.log("Transaction confirmed:", receipt);
if (receipt.status === "success") {
alert("Transfer successful!");
}
},
onError: (error) => {
console.error("Transfer error:", error);
alert("Transfer failed");
},
});
} catch (error) {
console.error("Error:", error);
} finally {
setIsSending(false);
}
};
return (
<div>
<input
value={recipient}
onChange={(e) => setRecipient(e.target.value)}
placeholder="Recipient address"
/>
<input
value={amount}
onChange={(e) => setAmount(e.target.value)}
placeholder="Amount"
type="number"
/>
<button onClick={handleTransfer} disabled={isSending}>
{isSending ? "Sending..." : "Transfer"}
</button>
</div>
);
}Using Service Layer
import { useRegistryService, useTokenService } from "galaxis-web3-adapter";
function CommunityDetails({ communityId, chainId }) {
const registryService = useRegistryService();
const [communityData, setCommunityData] = useState(null);
useEffect(() => {
async function fetchCommunityData() {
// Get community registry address
const registryAddress =
await registryService.getCommunityRegistryAddress(
communityId,
chainId
);
if (registryAddress) {
// Get token count for this community
const tokenCount = await registryService.getTokenCount(
registryAddress,
chainId
);
setCommunityData({
registryAddress,
tokenCount,
});
}
}
fetchCommunityData();
}, [communityId, chainId, registryService]);
if (!communityData) return <div>Loading community data...</div>;
return (
<div>
<p>Registry address: {communityData.registryAddress}</p>
<p>Token count: {communityData.tokenCount}</p>
</div>
);
}Batch Contract Reads
import { batchReadContracts } from "galaxis-web3-adapter";
import { ERC721_ABI } from "galaxis-web3-adapter";
import { useWallet } from "galaxis-web3-adapter";
function NFTCollection({ tokenAddresses }) {
const [tokenNames, setTokenNames] = useState([]);
const { wagmiConfig, chainId } = useWallet();
useEffect(() => {
async function getTokenNames() {
// Create contract calls for each token address
const contractCalls = tokenAddresses.map((address) => ({
address,
abi: ERC721_ABI,
functionName: "name",
args: [],
chainId,
}));
// Execute all calls in a single batch
const results = await batchReadContracts(
wagmiConfig,
contractCalls
);
// Process results
const names = results
.filter((result) => result.status === "success")
.map((result) => result.result);
setTokenNames(names);
}
getTokenNames();
}, [tokenAddresses, wagmiConfig, chainId]);
return (
<ul>
{tokenNames.map((name, index) => (
<li key={index}>{name}</li>
))}
</ul>
);
}Legacy Support (Ethers.js)
The adapter provides compatibility hooks for ethers.js v5 code:
import { useEthersProvider, useEthersContract } from "galaxis-web3-adapter";
import { ERC20_ABI } from "galaxis-web3-adapter";
function LegacyComponent({ tokenAddress }) {
// Get ethers provider for current or specified chain
const provider = useEthersProvider();
// Create ethers contract instance
const tokenContract = useEthersContract(tokenAddress, ERC20_ABI, provider);
useEffect(() => {
async function fetchTotalSupply() {
if (tokenContract) {
const supply = await tokenContract.totalSupply();
console.log("Total supply:", supply.toString());
}
}
fetchTotalSupply();
}, [tokenContract]);
// Rest of your component...
}Available Hooks
useWallet()- Access wallet state and connection methodsuseContractRead()- Read data from contracts (wagmi-style)useContractWrite()- Write to contracts (wagmi-style)useContract()- Get contract objects for interactionuseTransactionWrite()- Enhanced transaction writing with status trackinguseEthersProvider()- Get ethers.js provider for compatibilityuseEthersContract()- Get ethers.js contract for compatibilityuseLegacyWallet()- Access wallet functions in ethers.js styleuseRegistryService()- Get registry service instanceuseTokenService()- Get token service instance
Key Utility Functions
readContract()- Read from contractsbatchReadContracts()- Batch multiple contract readswriteContract()- Write to contractstransactionWriteContract()- Write with transaction tracking and status callbacksgetProviderOrSigner()- Get provider or signer based on requirementsgetContract()- Get contract instancesgetEthersProviderFromWalletClient()- Convert viem wallet client to ethers providerbuildLoginMessage()- Create signature messagespersonalSign()- Sign messages
Architecture
The web3-adapter is organized into several layers:
Provider Layer - Sets up the blockchain environment
Web3Provider: Root provider that configures wagmi, RainbowKit and chainsWalletManager: Manages wallet connections and provides context
Hook Layer - React hooks for convenient access to blockchain functionality
- Modern hooks using wagmi/viem
- Legacy hooks for ethers.js compatibility
Service Layer - Domain-specific services for common operations
RegistryService: Registry contract interactionsTokenService: Token-related operations
Utility Layer - Helper functions for common operations
- Contract interaction utilities
- Signature utilities
- Conversion utilities
Data Layer - Contract ABIs and types
- Centralized ABIs for all contracts
- TypeScript types for blockchain data
Particle Wallet Integration
The web3-adapter provides built-in support for Particle Wallet, allowing users to connect via email and social logins.
Setup Particle Wallet
- Import the necessary components and CSS:
import {
particleWallet,
particleGoogleWallet,
particleTwitterWallet,
} from "galaxis-web3-adapter/particle";
import "galaxis-web3-adapter/particle/particle.css";- Create a Particle configuration:
const PARTICLE_CONFIG = {
projectId: "your-particle-project-id",
clientKey: "your-particle-client-key",
appId: "your-particle-app-id",
authTypes: [
AuthType.email,
AuthType.google,
AuthType.twitter,
AuthType.apple,
],
themeType: "dark",
customStyle: {
zIndex: 2147483650,
},
wallet: {
themeType: "dark",
visible: true,
entryPosition: EntryPosition.BL,
},
};- Pass the configuration to the Web3Provider:
<Web3Provider
config={{
projectId: "your-wallet-connect-project-id",
appName: "Your App Name",
defaultChainId: 1,
connectors: [
{
groupName: "Particle Connectors",
wallets: [
particleWallet,
particleGoogleWallet,
particleTwitterWallet,
],
},
// Other connector groups
],
}}
chainsInfo={chainsInfo}
particleConfig={PARTICLE_CONFIG} // Pass the Particle config here
>
{/* Your app content */}
</Web3Provider>When particleConfig is present, the Web3Provider will be automatically wrapped with ParticleAuthCoreProvider and ParticleAuthSetup, enabling Particle Wallet functionality.
Using ParticleEntryButton
The package includes a ParticleEntryButton component that allows users to open the Particle wallet modal directly:
import { ParticleEntryButton } from "galaxis-web3-adapter/particle";
// In your component:
<ParticleEntryButton
size="medium"
tooltipTitle="Open Wallet"
sx={{ marginLeft: 2 }}
/>;The button will only be visible when a user is connected via Particle Wallet.
ParticleEntryButton Props
| Prop | Type | Default | Description | | ------------ | ------------------------------ | ---------------------- | -------------------------------------------- | | size | "small" | "medium" | "large" | "medium" | Size of the button | | tooltipTitle | string | "Open Particle Wallet" | Text displayed in the tooltip | | sx | SxProps | {} | Additional MUI styles to apply to the button |
Available Exports
Web3Provider: Main provider componentparticleWallet: Particle wallet connectorparticleGoogleWallet: Google social login connectorparticleTwitterWallet: Twitter social login connectorParticleEntryButton: Button component to open Particle walletParticleAuthSetup: Component to handle Particle Auth connection
Publishing
This package is automatically published to npm when changes are pushed with a version tag.
To publish a new version:
Make sure you're on the correct branch:
git checkout feature/web3-adapterMake and commit your changes:
git add . git commit -m "Update for version x.y.z"Create and push a tag with the new version:
git tag web3-adapter-v0.1.0 git push origin web3-adapter-v0.1.0The GitHub Actions workflow will automatically build and publish the package to npm
License
MIT
