Skip to content

Conversation

@developerfred
Copy link
Owner

@developerfred developerfred commented Jun 16, 2025

User description

Description

  • rewrite useChainStore
  • unify util explorer url resolver
  • update presets

enable xcm bridge on paseo parachains


PR Type

Enhancement, Bug fix


Description

• Enhanced XCM (Cross-Chain Message) support with comprehensive Paseo testnet integration and barrier compliance
• Added dynamic network-aware destination filtering and asset selection for safer cross-chain transfers
• Improved chain connection stability with better error handling for ChainHead disjoint errors and graceful disconnection
• Enhanced explorer URL builder with support for multiple URL types (block, extrinsic, account, runtime)
• Optimized transaction state management with batched updates using requestAnimationFrame
• Added comprehensive XCM validation functions and network-specific configuration filtering
• Improved blockchain dashboard connection management with proper provider event handling
• Fixed author email typo in package.json


Changes walkthrough 📝

Relevant files
Enhancement
5 files
presets.ts
Enhanced XCM configuration with Paseo and Westend support

src/components/blockchain/builder/constants/presets.ts

• Added Westend system parachains (westend_asset_hub,
westend_bridge_hub, etc.) to XCM_DESTINATIONS
• Enhanced
detectNetworkType function with improved pattern matching and logging

• Added comprehensive helper functions for network filtering
(getDestinationsByNetwork, getSystemParachains, getParachains)

Updated XCM_NETWORK_CONFIG to enable full support for Paseo testnet
with strict filtering
• Added extensive XCM validation and suggestion
functions for safer cross-chain transfers

+618/-533
explorer.ts
Enhanced explorer URL builder with multiple types support

src/lib/utils/explorer.ts

• Enhanced buildSubscanUrl function to support multiple URL types
(block, extrinsic, account, runtime)
• Added robust fallback
mechanisms for invalid or missing explorer URLs
• Improved URL
validation and network name extraction for better explorer link
generation

+88/-8   
useTransactionState.ts
Optimized transaction state management with batched updates

src/components/blockchain/builder/hooks/useTransactionState.ts

• Improved batched state updates with requestAnimationFrame for better
performance
• Added proper cleanup and queue management for state
updates
• Enhanced state synchronization with refs to prevent stale
closures

+10/-15 
ArgumentInput.tsx
Enhanced argument input with dynamic network-aware features

src/components/blockchain/builder/components/ArgumentInput.tsx

• Added dynamic XCM destination filtering based on selected network
compatibility
• Implemented network-specific asset selection with
proper symbol mapping
• Added network status indicators and enhanced
UI context for better user experience
• Integrated with networkManager
for dynamic network configuration

+229/-76
TransactionBuilder.tsx
Enhanced XCM Cross-Chain Transaction Support with Barrier Compliance

src/components/blockchain/components/TransactionBuilder.tsx

• Added comprehensive XCM (Cross-Chain Message) support with barrier
compliance and network-specific validation
• Implemented
XcmTypeDetector class for network type detection, trust relationships,
and destination validation
• Enhanced transaction building with proper
XCM type handling and error messages with troubleshooting guidance

Replaced WalletConnector singleton with direct
web3Enable/web3FromAddress usage for wallet integration

+1262/-541
Bug fix
2 files
useChainStore.ts
Improved chain connection stability and error handling     

src/store/useChainStore.ts

• Added comprehensive error handling for ChainHead disjoint errors
with isDisjointError helper
• Implemented proper cleanup mechanisms
with destroy$ subject and takeUntil operators
• Enhanced connection
management with better error recovery and graceful disconnection

Added global unhandled rejection handler for disjoint errors to
prevent console spam

+261/-147
BlockchainDashboard.tsx
Improved blockchain dashboard connection management           

src/components/blockchain/BlockchainDashboard.tsx

• Improved provider event handling with proper type checking before
attaching listeners
• Enhanced cleanup procedures for API connections
and providers
• Refactored status indicator component with better
configuration mapping

+36/-53 
Miscellaneous
4 files
BlockExplorer.tsx
Added explorer URL utility import                                               

src/components/blockchain/components/BlockExplorer.tsx

• Added import for buildSubscanUrl utility function

+1/-23   
EventMonitor.tsx
Added explorer URL utility import                                               

src/components/blockchain/EventMonitor.tsx

• Added import for buildSubscanUrl utility function

+1/-22   
AccountBalance.tsx
Added explorer URL utility import                                               

src/components/blockchain/components/AccountBalance.tsx

• Added import for buildSubscanUrl utility function

+1/-11   
package.json
Fixed author email typo                                                                   

package.json

• Fixed typo in author email from "codinsh@pm.me" to "codingsh@pm.me"

+1/-1     

Need help?
  • Type /help how to ... in the comments thread for any questions about Qodo Merge usage.
  • Check out the documentation for more information.
  • * rewrite useChainStore
    * unify util explorer url resolver
    * update presets
    @vercel
    Copy link

    vercel bot commented Jun 16, 2025

    The latest updates on your projects. Learn more about Vercel for Git ↗︎

    Name Status Preview Comments Updated (UTC)
    papi-simulator ❌ Failed (Inspect) Jun 16, 2025 10:48am

    @qodo-code-review
    Copy link

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 4 🔵🔵🔵🔵⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Code Quality

    Excessive console logging throughout the code that should be removed or made conditional for production. Multiple functions have verbose logging that could impact performance and clutter logs.

    console.log(`🔍 Detecting network type from terms:`, searchTerms);
    
    
    for (const [networkType, patterns] of Object.entries(NETWORK_PATTERNS)) {
        for (const term of searchTerms) {
    
            if (patterns.includes(term)) {
                console.log(`✅ Exact match found: ${networkType} from "${term}"`);
                return networkType;
            }
    
    
            if (patterns.some(pattern => term.includes(pattern))) {
                console.log(`🎯 Pattern match found: ${networkType} from "${term}"`);
                return networkType;
            }
        }
    }
    
    
    if (networkSymbol === 'PAS') return 'paseo';
    if (networkSymbol === 'DOT') return 'polkadot';
    if (networkSymbol === 'KSM') return 'kusama';
    if (networkSymbol === 'WND') return 'westend';
    
    
    if (networkName?.toLowerCase().includes('paseo')) return 'paseo';
    if (networkName?.toLowerCase().includes('polkadot')) return 'polkadot';
    if (networkName?.toLowerCase().includes('kusama')) return 'kusama';
    if (networkName?.toLowerCase().includes('westend')) return 'westend';
    
    console.warn(`❌ Unable to detect network type for: name="${networkName}", symbol="${networkSymbol}", relay="${relay}"`);
    return 'unknown';
    Error Handling

    Complex error handling logic for disjoint errors that may mask legitimate errors. The isDisjointError function and related error suppression could hide important debugging information.

    const isDisjointError = (error: unknown): boolean => {
    	if (error instanceof Error) {
    		return error.message.includes('ChainHead disjointed') ||
    			error.message.includes('DisjointError') ||
    			error.name === 'DisjointError';
    	}
    	return false;
    };
    Logic Complexity

    Overly complex URL building logic with multiple fallback mechanisms and duplicated code. The function has nested conditionals and repeated URL construction patterns that could be simplified.

    export const buildSubscanUrl = (
        network: Network,
        type: 'block' | 'extrinsic' | 'account' | 'runtime',
        identifier?: string | number
    ): string => {
        // Verificação de segurança inicial
        if (!network) {
            console.warn('Network object is null or undefined');
            return `https://polkadot.subscan.io/${type}${identifier ? `/${identifier}` : ''}`;
        }
    
        // Validação robusta do explorer URL
        const explorerUrl = network.explorer;
    
        // Verifica se o explorer URL é válido
        if (!explorerUrl ||
            typeof explorerUrl !== 'string' ||
            explorerUrl.trim() === '' ||
            explorerUrl === 'undefined' ||
            explorerUrl === 'null') {
    
            console.debug('Using fallback explorer URL for network:', network.name, 'explorer was:', explorerUrl);
    
            // Fallback usando o nome da rede
            const networkName = network.name?.toLowerCase()?.replace(/\s+/g, '-') || 'polkadot';
            const fallbackUrl = `https://${networkName}.subscan.io`;
    
            // Retorna URL baseado no tipo
            switch (type) {
                case 'block':
                    return identifier ? `${fallbackUrl}/block/${identifier}` : `${fallbackUrl}/blocks`;
                case 'extrinsic':
                    return identifier ? `${fallbackUrl}/extrinsic/${identifier}` : `${fallbackUrl}/extrinsics`;
                case 'account':
                    return identifier ? `${fallbackUrl}/account/${identifier}` : fallbackUrl;
                case 'runtime':
                    return fallbackUrl;
                default:
                    return fallbackUrl;
            }
        }
    
        // Remove barra final do URL base
        const baseUrl = explorerUrl.replace(/\/$/, '');
    
        // Verifica se é um URL válido do Subscan
        if (!baseUrl.includes('subscan.io')) {
            console.debug('Explorer URL is not a Subscan URL, creating fallback:', baseUrl);
    
            // Tenta extrair o nome da rede do URL ou usa o nome da rede
            let networkName = 'polkadot';
    
            try {
                const urlObj = new URL(baseUrl);
                const subdomain = urlObj.hostname.split('.')[0];
                networkName = subdomain || network.name?.toLowerCase()?.replace(/\s+/g, '-') || 'polkadot';
            } catch {
                networkName = network.name?.toLowerCase()?.replace(/\s+/g, '-') || 'polkadot';
            }
    
            const fallbackUrl = `https://${networkName}.subscan.io`;
    
            // Retorna URL baseado no tipo
            switch (type) {
                case 'block':
                    return identifier ? `${fallbackUrl}/block/${identifier}` : `${fallbackUrl}/blocks`;
                case 'extrinsic':
                    return identifier ? `${fallbackUrl}/extrinsic/${identifier}` : `${fallbackUrl}/extrinsics`;
                case 'account':
                    return identifier ? `${fallbackUrl}/account/${identifier}` : fallbackUrl;
                case 'runtime':
                    return fallbackUrl;
                default:
                    return fallbackUrl;
            }
        }
    
        // URL válido do Subscan - constrói o URL final
        switch (type) {
            case 'block':
                return identifier ? `${baseUrl}/block/${identifier}` : `${baseUrl}/blocks`;
            case 'extrinsic':
                return identifier ? `${baseUrl}/extrinsic/${identifier}` : `${baseUrl}/extrinsics`;
            case 'account':
                return identifier ? `${baseUrl}/account/${identifier}` : baseUrl;
            case 'runtime':
                return baseUrl;
            default:
                return baseUrl;
        }
    };

    @qodo-code-review
    Copy link

    qodo-code-review bot commented Jun 16, 2025

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    Possible issue
    Fix floating point precision error

    Using Math.floor with floating point arithmetic can introduce precision errors
    when converting to BigInt. This could result in incorrect token amounts being
    transferred.

    src/components/blockchain/components/TransactionBuilder.tsx [338]

    -const planckAmount = BigInt(Math.floor(numAmount * Math.pow(10, decimals)));
    +const planckAmount = BigInt(Math.round(numAmount * Math.pow(10, decimals)));
    • Apply / Chat
    Suggestion importance[1-10]: 8

    __

    Why: This suggestion correctly identifies a potential precision issue when converting token amounts. Using Math.floor can truncate values due to floating-point inaccuracies, leading to incorrect transaction amounts. Changing to Math.round is a more appropriate method for financial calculations and prevents potential loss of funds.

    Medium
    Validate value before string operations

    The value.split('|')[0] operation could throw an error if value is null,
    undefined, or not a string. Add proper validation before attempting to split the
    value.

    src/components/blockchain/builder/components/ArgumentInput.tsx [359-366]

     {(() => {
    +  if (!value || typeof value !== 'string') return networkSymbol;
       const assetKey = value.split('|')[0];
       if (assetKey === 'native') {
         return selectedNetwork?.symbol || networkSymbol;
       }
       const asset = availableAssets.find(a => a.key === assetKey);
       return asset?.symbol || assetKey.toUpperCase();
     })()}
    • Apply / Chat
    Suggestion importance[1-10]: 7

    __

    Why: The suggestion correctly identifies that the value prop, typed as any, could be null or not a string, which would cause value.split('|') to throw a runtime error. Adding a type check for value before performing string operations makes the component more robust.

    Medium
    General
    Fix fallback URL construction pattern
    Suggestion Impact:The suggestion was implemented through a complete refactoring that addresses the core issue. The commit replaced the problematic single-line fallback URL construction with a proper switch-based approach using helper functions like buildUrlPath() and createFallbackUrl(), ensuring correct URL patterns for each type

    code diff:

    +const buildUrlPath = (type: UrlType, identifier?: string | number): string => {
    +    const { singular, plural } = URL_PATHS[type];
    +
    +    if (!identifier) {
    +        return plural ? `/${plural}` : '';
    +    }
    +
    +    return singular ? `/${singular}/${identifier}` : '';
    +};
    +
    +
    +const createFallbackUrl = (
    +    networkName: string,
    +    type: UrlType,
         identifier?: string | number
     ): string => {
    -    // Verificação de segurança inicial
    +    const baseUrl = `https://${networkName}.${SUBSCAN_DOMAIN}`;
    +    return `${baseUrl}${buildUrlPath(type, identifier)}`;
    +};
    +
    +
    +const resolveBaseUrl = (network: Network): string => {
    +    if (!isValidExplorerUrl(network.explorer)) {
    +        console.debug('Using fallback explorer URL for network:', network.name, 'explorer was:', network.explorer);
    +        return `https://${normalizeNetworkName(network.name)}.${SUBSCAN_DOMAIN}`;
    +    }
    +
    +    const baseUrl = network.explorer.replace(/\/$/, '');
    +
    +    if (!baseUrl.includes(SUBSCAN_DOMAIN)) {
    +        console.debug('Explorer URL is not a Subscan URL, creating fallback:', baseUrl);
    +        const networkName = extractNetworkFromUrl(baseUrl, network.name);
    +        return `https://${networkName}.${SUBSCAN_DOMAIN}`;
    +    }
    +
    +    return baseUrl;
    +};
    +
    +/**
    + * Builds Subscan URL for different resource types
    + * 
    + * @param network - Network configuration object
    + * @param type - Type of resource to link to
    + * @param identifier - Optional identifier for the resource
    + * @returns Complete Subscan URL
    + */
    +export const buildSubscanUrl = (
    +    network: Network | null | undefined,
    +    type: UrlType,
    +    identifier?: string | number
    +): string => {    
         if (!network) {
             console.warn('Network object is null or undefined');
    -        return `https://polkadot.subscan.io/${type}${identifier ? `/${identifier}` : ''}`;
    +        return `${DEFAULT_FALLBACK_URL}${buildUrlPath(type, identifier)}`;

    The fallback URL construction doesn't properly handle the different URL patterns
    for each type. This could result in malformed URLs when the network is null.

    src/lib/utils/explorer.ts [16-19]

     if (!network) {
         console.warn('Network object is null or undefined');
    -    return `https://polkadot.subscan.io/${type}${identifier ? `/${identifier}` : ''}`;
    +    const fallbackUrl = 'https://polkadot.subscan.io';
    +    switch (type) {
    +        case 'block':
    +            return identifier ? `${fallbackUrl}/block/${identifier}` : `${fallbackUrl}/blocks`;
    +        case 'extrinsic':
    +            return identifier ? `${fallbackUrl}/extrinsic/${identifier}` : `${fallbackUrl}/extrinsics`;
    +        case 'account':
    +            return identifier ? `${fallbackUrl}/account/${identifier}` : fallbackUrl;
    +        case 'runtime':
    +            return fallbackUrl;
    +        default:
    +            return fallbackUrl;
    +    }
     }

    [Suggestion processed]

    Suggestion importance[1-10]: 7

    __

    Why: The suggestion correctly points out that the fallback URL construction is flawed. The original code does not correctly handle different URL patterns for types like block (which needs /blocks if no identifier is present) or account. The improved_code provides a robust switch statement that correctly constructs the fallback URL for all supported types, improving the reliability of the function.

    Medium
    Add null safety for network properties

    The network type detection logic could fail if selectedNetwork.relay or
    selectedNetwork.name are undefined or null. Add proper null checks to prevent
    runtime errors.

    src/components/blockchain/builder/components/ArgumentInput.tsx [109-118]

     const getCurrentNetworkType = () => {
       if (!selectedNetwork) return 'all';
     
    -  if (selectedNetwork.relay === 'Polkadot' || selectedNetwork.name === 'Polkadot') return 'polkadot';
    -  if (selectedNetwork.relay === 'Kusama' || selectedNetwork.name === 'Kusama') return 'kusama';
    -  if (selectedNetwork.relay === 'Paseo' || selectedNetwork.name === 'Paseo') return 'paseo';
    -  if (selectedNetwork.name === 'Westend') return 'westend';
    +  const relay = selectedNetwork.relay?.toLowerCase();
    +  const name = selectedNetwork.name?.toLowerCase();
    +
    +  if (relay === 'polkadot' || name === 'polkadot') return 'polkadot';
    +  if (relay === 'kusama' || name === 'kusama') return 'kusama';
    +  if (relay === 'paseo' || name === 'paseo') return 'paseo';
    +  if (name === 'westend') return 'westend';
     
       return 'all';
     };
    • Apply / Chat
    Suggestion importance[1-10]: 7

    __

    Why: The suggestion correctly points out a potential issue if selectedNetwork.relay or selectedNetwork.name are not guaranteed to be strings. Adding optional chaining (?.) and case-insensitive comparisons with toLowerCase() makes the function more robust and prevents potential runtime errors.

    Medium
    Add network object validation

    The network detection logic is fragile and could fail with unexpected network
    configurations. Add validation to ensure the network parameter has the expected
    structure before accessing its properties.

    src/components/blockchain/components/TransactionBuilder.tsx [47-57]

     private detectNetworkType(network: any): string {
    +  if (!network || typeof network !== 'object') {
    +    console.warn('Invalid network object provided to detectNetworkType');
    +    return 'unknown';
    +  }
    +  
       const name = network?.name?.toLowerCase() || '';
       const symbol = network?.symbol?.toLowerCase() || '';
     
       if (name.includes('paseo') || symbol === 'pas') return 'paseo';
       if (name.includes('westend') || symbol === 'wnd') return 'westend';
       if (name.includes('kusama') || symbol === 'ksm') return 'kusama';
       if (name.includes('polkadot') || symbol === 'dot') return 'polkadot';
     
       return 'unknown';
     }
    • Apply / Chat
    Suggestion importance[1-10]: 5

    __

    Why: The suggestion correctly points out that the network parameter of type any could be problematic. While the existing optional chaining (?.) prevents a crash, adding an explicit check for the object type and a warning improves the code's robustness and provides better feedback for developers.

    Low
    Avoid object mutation during filtering

    The code mutates the destinations object after filtering, which can cause
    unexpected behavior. Instead of deleting keys from the original object, create a
    new filtered object to avoid side effects.

    src/components/blockchain/builder/constants/presets.ts [181-187]

     const invalidDestinations = Object.entries(destinations)
         .filter(([_, dest]) => dest.network !== networkType);
     
     if (invalidDestinations.length > 0) {
    -    console.error(`🚨 ERRO: Destinos inválidos encontrados para ${networkType}:`, invalidDestinations);    
    -    invalidDestinations.forEach(([key]) => delete destinations[key]);
    +    console.error(`🚨 ERRO: Destinos inválidos encontrados para ${networkType}:`, invalidDestinations);
    +    const validDestinations = Object.entries(destinations)
    +        .filter(([_, dest]) => dest.network === networkType)
    +        .reduce((acc, [key, dest]) => ({ ...acc, [key]: dest }), {});
    +    return validDestinations;
     }
    • Apply / Chat
    Suggestion importance[1-10]: 3

    __

    Why: The suggestion correctly identifies object mutation (delete destinations[key]) and proposes an immutable approach, which is a good practice. However, the targeted code block is a defensive check that is unlikely to be executed, as destinations is already filtered by networkType. Therefore, the impact of this change is low.

    Low
    • Update

    @developerfred developerfred merged commit 8c6526f into main Jun 16, 2025
    2 of 3 checks passed
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Projects

    None yet

    Development

    Successfully merging this pull request may close these issues.

    2 participants