From abcb6f0cc753a04fb764ecac2a508361b48b0626 Mon Sep 17 00:00:00 2001 From: Lutra23 Date: Sun, 22 Feb 2026 20:46:29 +0800 Subject: [PATCH] fix(mcp): require strict CDP wallet network match --- .../payment-strategies/cdp-strategy.ts | 54 +++---------------- 1 file changed, 7 insertions(+), 47 deletions(-) diff --git a/apps/mcp/src/lib/3rd-parties/payment-strategies/cdp-strategy.ts b/apps/mcp/src/lib/3rd-parties/payment-strategies/cdp-strategy.ts index 5dea2f7..164da8e 100644 --- a/apps/mcp/src/lib/3rd-parties/payment-strategies/cdp-strategy.ts +++ b/apps/mcp/src/lib/3rd-parties/payment-strategies/cdp-strategy.ts @@ -1,4 +1,3 @@ -import { getCDPNetworks, type UnifiedNetwork } from "../cdp/wallet/networks.js"; import { createSignerFromViemAccount } from "mcpay/utils"; import { getCDPAccount } from "../cdp/wallet/index.js"; import { txOperations, Wallet } from "../../db/actions.js"; @@ -27,12 +26,12 @@ export class CDPSigningStrategy implements PaymentSigningStrategy { const activeWallets = cdpWallets.filter(w => w.isActive); const compatibleWallets = activeWallets.filter(wallet => { const walletNetwork = (wallet.walletMetadata as unknown as CDPWalletMetadata)?.cdpNetwork; - return walletNetwork === network || this.isNetworkCompatible(walletNetwork, network); + return walletNetwork === network; }); console.log(`[CDP Strategy] Found ${compatibleWallets.length} compatible wallets for user ${context.user!.id}`); - const canSign = compatibleWallets.length > 0 || activeWallets.length > 0; + const canSign = compatibleWallets.length > 0; console.log(`[CDP Strategy] Can sign: ${canSign} (compatible: ${compatibleWallets.length}, active: ${activeWallets.length})`); return canSign; } catch (error) { @@ -65,22 +64,19 @@ export class CDPSigningStrategy implements PaymentSigningStrategy { const activeWallets = cdpWallets.filter(w => w.isActive); const compatibleWallets = activeWallets.filter(wallet => { const walletNetwork = (wallet.walletMetadata as unknown as CDPWalletMetadata)?.cdpNetwork; - return walletNetwork === network || this.isNetworkCompatible(walletNetwork, network); + return walletNetwork === network; }); - // If none are compatible by family, fall back to any active CDP wallet - const candidateWallets = compatibleWallets.length > 0 ? compatibleWallets : activeWallets; - - if (candidateWallets.length === 0) { + if (compatibleWallets.length === 0) { return { success: false, - error: `No active CDP wallets available for user` + error: `No active CDP wallet found on network "${network}". Please create or activate a wallet on this network.` }; } // Prefer smart accounts (gas-sponsored) over regular accounts - const smartWallets = candidateWallets.filter(w => (w.walletMetadata as unknown as CDPWalletMetadata)?.isSmartAccount); - const regularWallets = candidateWallets.filter(w => !(w.walletMetadata as unknown as CDPWalletMetadata)?.isSmartAccount); + const smartWallets = compatibleWallets.filter(w => (w.walletMetadata as unknown as CDPWalletMetadata)?.isSmartAccount); + const regularWallets = compatibleWallets.filter(w => !(w.walletMetadata as unknown as CDPWalletMetadata)?.isSmartAccount); const walletsToTry = [...smartWallets, ...regularWallets]; @@ -120,42 +116,6 @@ export class CDPSigningStrategy implements PaymentSigningStrategy { } } - private isNetworkCompatible(walletNetwork: string | undefined, targetNetwork: UnifiedNetwork): boolean { - if (!walletNetwork) return false; - - // Normalize to unified network names if possible - const cdpNetworks = getCDPNetworks(); - const normalizedWallet = cdpNetworks.includes(walletNetwork as CDPNetwork) - ? (walletNetwork as UnifiedNetwork) - : (walletNetwork as unknown as UnifiedNetwork); - - // Direct match - if (normalizedWallet === targetNetwork) return true; - - // Family pairing: treat testnets as compatible with their mainnet family - const family = (n: UnifiedNetwork | string) => { - switch (n) { - case 'polygon': - case 'polygon-amoy': - return 'polygon'; - case 'base': - case 'base-sepolia': - return 'base'; - case 'ethereum': - case 'ethereum-sepolia': - return 'ethereum'; - case 'arbitrum': - return 'arbitrum'; - case 'sei-testnet': - return 'sei'; - default: - return String(n); - } - }; - - return family(normalizedWallet) === family(targetNetwork); - } - private async signWithCDPWallet( wallet: Wallet, paymentRequirement: PaymentRequirements,