A React application that allows users to verify their EVM addresses by submitting them to the Autonomys Network through a system.remark
transaction. This creates a permanent on-chain record linking a Substrate wallet to an EVM address for verification purposes.
✅ EVM Address Verification - Submit EVM addresses to Autonomys Network via system.remark
transactions
✅ Address Validation - Full EIP-55 checksum validation for EVM addresses
✅ Transaction Tracking - Real-time status updates and transaction hash display
✅ Network Integration - Direct connection to Autonomys Network mainnet
✅ Multi-wallet support - Talisman, SubWallet, and Polkadot.js extensions
✅ Persistent connections - Auto-reconnect on page reload
✅ Multi-account management - Easy account switching
✅ Transaction signing - Secure transaction signing through wallet extensions
✅ Error handling - Comprehensive error handling and user-friendly messages
✅ TypeScript support - Full type safety throughout the application
✅ Modern React patterns - Hooks, functional components, Zustand state management
✅ Responsive UI - Built with Tailwind CSS and Radix UI components
- Node.js 18+
- Yarn 4+
- At least one Substrate wallet extension installed:
# Install dependencies
yarn install
# Start development server
yarn dev
# Build for production
yarn build
# Preview production build
yarn preview
The app will be available at http://localhost:5173
- Connect Wallet: Connect your Substrate wallet (Talisman, SubWallet, or Polkadot.js)
- Enter EVM Address: Input your EVM address with automatic checksum validation
- Submit Transaction: Sign and submit a
system.remark
transaction to Autonomys Network - Get Transaction Hash: Receive the transaction hash as proof of verification
- Share with Team: Send the transaction hash to the project team for validation
- The application creates a
system.remark
extrinsic with a structured association record - This transaction is permanently recorded on the Autonomys blockchain
- The transaction links your Substrate account to your EVM address with full audit trail
- The transaction hash serves as cryptographic proof of this link
SUBSPACE_ASSOC:v1
ss58=5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
evm=0x742d35Cc6634C0532925a3b8D4e5D7e78c7c8e5B
scope=beneficiary
nonce=550e8400-e29b-41d4-a716-446655440000
ts=2024-01-15T10:30:00.000Z
Schema Details:
SUBSPACE_ASSOC:v1
- Stable prefix and version for reliable parsingss58
- Your Substrate address (automatically filled)evm
- Your EVM address with EIP-55 checksum validationscope=beneficiary
- Indicates this is for beneficiary verificationnonce
- UUIDv4 for replay protectionts
- ISO8601 timestamp for audit trail
Successful transactions can be viewed on the Autonomys Network explorer:
https://autonomys.subscan.io/extrinsic/[transaction-hash]
src/
├── components/
│ ├── ui/ # Base UI components (Button, Dialog, Alert)
│ └── wallet/ # Wallet-specific components
│ ├── wallet-button.tsx # Connect button with account dropdown
│ ├── wallet-modal.tsx # Connection modal
│ ├── wallet-option.tsx # Individual wallet option
│ └── index.ts # Component exports
├── hooks/
│ └── use-wallet.ts # Main wallet hook
├── stores/
│ └── wallet-store.ts # Zustand store for wallet state
├── types/
│ └── wallet.ts # TypeScript interfaces
├── constants/
│ └── wallets.ts # Wallet configuration
├── lib/
│ └── utils.ts # Utility functions
├── App.tsx # Main application component
├── main.tsx # Application entry point
└── index.css # Global styles
- State Management: Uses Zustand with persistence middleware
- Wallet Detection: Automatically detects installed wallet extensions
- Connection Flow: Handles wallet connection, account selection, and error states
- Persistence: Saves wallet preferences and auto-reconnects on page load
- Address Formatting: Converts addresses to the correct SS58 format
useWallet
Hook: Primary interface for wallet functionalityWalletButton
: Connect button that shows account info when connectedWalletModal
: Modal for selecting and connecting to walletsuseWalletStore
: Zustand store managing all wallet state
- User clicks "Connect Wallet"
- Modal opens showing available wallets
- User selects a wallet extension
- Extension prompts for authorization
- App receives account list and selects first account
- Connection state is persisted for future sessions
-
Update Address Format: Modify the
address()
function call inwallet-store.ts
:// Change from Autonomys format (6094) to your chain's SS58 format address: address(account.address, YOUR_CHAIN_SS58_PREFIX)
-
Update Chain Configuration: Modify constants in
constants/wallets.ts
:export const DAPP_NAME = 'Your DApp Name'; export const WALLET_STORAGE_KEY = 'your-dapp-wallet-preferences';
-
Add Custom Wallets: Add new wallet extensions to the supported list:
export const SUPPORTED_WALLET_EXTENSIONS = [ 'talisman', 'subwallet-js', 'polkadot-js', 'your-custom-wallet' ] as const;
- Styling: Modify Tailwind classes in components
- Colors: Update CSS custom properties in
index.css
- Layout: Customize the
App.tsx
component structure
-
Copy Core Files:
src/stores/wallet-store.ts src/hooks/use-wallet.ts src/types/wallet.ts src/constants/wallets.ts
-
Install Dependencies:
yarn add @talismn/connect-wallets @autonomys/auto-utils zustand
-
Use in Components:
import { useWallet } from './hooks/use-wallet'; function MyComponent() { const { isConnected, selectedAccount, connectWallet } = useWallet(); // Your component logic }
const {
// State
isConnected: boolean;
isLoading: boolean;
connectionError: string | null;
selectedAccount: WalletAccount | null;
accounts: WalletAccount[];
injector: InjectedExtension | null;
availableWallets: Wallet[];
// Actions
connectWallet: (extensionName: string) => Promise<void>;
disconnectWallet: () => void;
selectAccount: (address: string) => void;
clearError: () => void;
// Computed
hasWallets: boolean;
selectedAddress: string | null;
isConnecting: boolean;
isInitializing: boolean;
canConnect: boolean;
} = useWallet();
-
"No wallets detected"
- Ensure wallet extensions are installed and enabled
- Refresh the page after installing extensions
-
"Connection timeout"
- Check if wallet popup was blocked
- Try approving the connection request faster
-
"Account no longer exists"
- Account was removed from the wallet extension
- Clear browser storage and reconnect
# Type checking
yarn type-check
# Linting (if configured)
yarn lint
# Clean build
rm -rf dist node_modules && yarn install
@talismn/connect-wallets
- Wallet connection library@autonomys/auto-utils
- Autonomys network utilitieszustand
- State managementreact
&react-dom
- React framework
@radix-ui/react-dialog
- Modal componenttailwindcss
- Styling frameworklucide-react
- Icons
This demo project is based on code from the Autonomys staking portal. Check the original repository for license information.
This is a demo project extracted for educational purposes. For production use, consider:
- Adding comprehensive error handling
- Implementing proper logging
- Adding unit tests
- Customizing for your specific chain requirements
- Transaction Signing: Use the
injector
to sign and submit transactions - Balance Integration: Add balance fetching for connected accounts
- Chain Integration: Connect to your specific Substrate chain
- Advanced Features: Add features like account creation, backup, etc.
For questions or issues, refer to the original Autonomys staking portal repository or Substrate wallet documentation.