diff --git a/web/src/contexts/PezkuwiContext.tsx b/web/src/contexts/PezkuwiContext.tsx index 76bca74c..43769da2 100644 --- a/web/src/contexts/PezkuwiContext.tsx +++ b/web/src/contexts/PezkuwiContext.tsx @@ -496,9 +496,14 @@ export const PezkuwiProvider: React.FC = ({ setError(null); const genesisHash = api.genesisHash.toHex(); + // Include Asset Hub and People Chain in WC session so cross-chain TX signing works + const additionalHashes: string[] = []; + if (assetHubApi?.isConnected) additionalHashes.push(assetHubApi.genesisHash.toHex()); + if (peopleApi?.isConnected) additionalHashes.push(peopleApi.genesisHash.toHex()); + try { await initWalletConnect(); - const { uri, approval } = await connectWithQR(genesisHash); + const { uri, approval } = await connectWithQR(genesisHash, additionalHashes); // Start approval listener in background approval().then((session) => { diff --git a/web/src/contexts/WalletContext.tsx b/web/src/contexts/WalletContext.tsx index b31f0974..74170112 100644 --- a/web/src/contexts/WalletContext.tsx +++ b/web/src/contexts/WalletContext.tsx @@ -263,6 +263,7 @@ export const WalletProvider: React.FC<{ children: React.ReactNode }> = ({ childr } if (import.meta.env.DEV) console.log('[WC] Using WalletConnect for transaction signing'); + // Default genesis hash for signRaw; signPayload auto-detects from TX payload const genesisHash = pezkuwi.api.genesisHash.toHex(); const wcSigner = createWCSigner(genesisHash, pezkuwi.selectedAccount.address); diff --git a/web/src/lib/walletconnect-service.ts b/web/src/lib/walletconnect-service.ts index 0b5105c6..ca8a2468 100644 --- a/web/src/lib/walletconnect-service.ts +++ b/web/src/lib/walletconnect-service.ts @@ -91,22 +91,27 @@ export function buildChainId(genesisHash: string): string { * Start a WalletConnect pairing session * Returns the URI for QR code display */ -export async function connectWithQR(genesisHash: string): Promise<{ +export async function connectWithQR(genesisHash: string, additionalGenesisHashes?: string[]): Promise<{ uri: string; approval: () => Promise; }> { const client = await initWalletConnect(); - const chainId = buildChainId(genesisHash); + const chainIds = [buildChainId(genesisHash)]; + if (additionalGenesisHashes) { + for (const gh of additionalGenesisHashes) { + const cid = buildChainId(gh); + if (!chainIds.includes(cid)) chainIds.push(cid); + } + } - console.warn('[WC] Session proposal chain ID:', chainId); - console.warn('[WC] Genesis hash:', genesisHash); + console.warn('[WC] Session proposal chain IDs:', chainIds); console.warn('[WC] Methods:', POLKADOT_METHODS); const { uri, approval } = await client.connect({ optionalNamespaces: { polkadot: { methods: POLKADOT_METHODS, - chains: [chainId], + chains: chainIds, events: POLKADOT_EVENTS, }, }, @@ -182,9 +187,8 @@ export function validateSession(): boolean { * Create a Signer adapter compatible with @pezkuwi/api's Signer interface * Routes signPayload and signRaw through WalletConnect */ -export function createWCSigner(genesisHash: string, address: string) { - const chainId = buildChainId(genesisHash); - const wcAccount = `polkadot:${chainId.split(':')[1]}:${address}`; +export function createWCSigner(defaultGenesisHash: string, address: string) { + const defaultChainId = buildChainId(defaultGenesisHash); return { signPayload: async (payload: { @@ -211,6 +215,15 @@ export function createWCSigner(genesisHash: string, address: string) { throw new Error('WalletConnect session expired. Please reconnect your wallet.'); } + // Derive chainId from the payload's own genesisHash (set by the TX's API) + // This ensures Asset Hub TXs use Asset Hub chainId, relay TXs use relay chainId, etc. + const chainId = payload.genesisHash ? buildChainId(payload.genesisHash) : defaultChainId; + const wcAccount = `polkadot:${chainId.split(':')[1]}:${address}`; + + if (import.meta.env.DEV) { + console.log('[WC] signPayload chainId:', chainId, 'from payload genesis:', payload.genesisHash); + } + const id = ++requestId; const result = await signClient.request<{ signature: string }>({ @@ -246,11 +259,12 @@ export function createWCSigner(genesisHash: string, address: string) { throw new Error('WalletConnect session expired. Please reconnect your wallet.'); } + const wcAccount = `polkadot:${defaultChainId.split(':')[1]}:${address}`; const id = ++requestId; const result = await signClient.request<{ signature: string }>({ topic: currentSession.topic, - chainId, + chainId: defaultChainId, request: { method: 'polkadot_signMessage', params: {