mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-06-24 07:31:02 +00:00
fix: require all chains in WC session and use correct chainId
Three fixes for WC signing: 1. Changed optionalNamespaces to requiredNamespaces so wallet MUST approve all Pezkuwi chains (relay, asset hub, people) or reject. 2. Restored payload-based chainId in signPayload — wallet validates that WC chainId matches the transaction payload's genesisHash and rejects mismatches with "Wrong chain id passed by dApp". 3. Added session validation on restore — old sessions missing required chains are discarded, forcing a fresh session with all chains included.
This commit is contained in:
@@ -18,6 +18,13 @@ const WC_SESSION_KEY = 'wc_session_topic';
|
|||||||
const POLKADOT_METHODS = ['polkadot_signTransaction', 'polkadot_signMessage'];
|
const POLKADOT_METHODS = ['polkadot_signTransaction', 'polkadot_signMessage'];
|
||||||
const POLKADOT_EVENTS = ['chainChanged', 'accountsChanged'];
|
const POLKADOT_EVENTS = ['chainChanged', 'accountsChanged'];
|
||||||
|
|
||||||
|
// All Pezkuwi chain IDs that must be in the session for cross-chain signing
|
||||||
|
const REQUIRED_CHAIN_IDS = [
|
||||||
|
'polkadot:1aa94987791a5544e9667ec249d2cef1', // Relay
|
||||||
|
'polkadot:e7c15092dcbe3f320260ddbbc685bfce', // Asset Hub
|
||||||
|
'polkadot:69a8d025ab7b63363935d7d9397e0f65', // People Chain
|
||||||
|
];
|
||||||
|
|
||||||
let signClient: SignClient | null = null;
|
let signClient: SignClient | null = null;
|
||||||
let initPromise: Promise<SignClient> | null = null;
|
let initPromise: Promise<SignClient> | null = null;
|
||||||
let currentSession: SessionTypes.Struct | null = null;
|
let currentSession: SessionTypes.Struct | null = null;
|
||||||
@@ -130,7 +137,7 @@ export async function connectWithQR(genesisHash: string, additionalGenesisHashes
|
|||||||
console.warn('[WC] Methods:', POLKADOT_METHODS);
|
console.warn('[WC] Methods:', POLKADOT_METHODS);
|
||||||
|
|
||||||
const { uri, approval } = await client.connect({
|
const { uri, approval } = await client.connect({
|
||||||
optionalNamespaces: {
|
requiredNamespaces: {
|
||||||
polkadot: {
|
polkadot: {
|
||||||
methods: POLKADOT_METHODS,
|
methods: POLKADOT_METHODS,
|
||||||
chains: chainIds,
|
chains: chainIds,
|
||||||
@@ -239,9 +246,10 @@ export function createWCSigner(defaultGenesisHash: string, address: string) {
|
|||||||
throw new Error('WalletConnect session expired. Please reconnect your wallet.');
|
throw new Error('WalletConnect session expired. Please reconnect your wallet.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always use a chainId approved in the WC session for protocol compliance.
|
// Use the payload's genesisHash to derive the correct chainId.
|
||||||
// The wallet determines actual signing chain from the payload's genesisHash.
|
// The wallet validates this matches the payload — mismatches are rejected.
|
||||||
const chainId = getApprovedChainId(defaultChainId);
|
// Session must include all chains (enforced via requiredNamespaces).
|
||||||
|
const chainId = payload.genesisHash ? buildChainId(payload.genesisHash) : defaultChainId;
|
||||||
|
|
||||||
const id = ++requestId;
|
const id = ++requestId;
|
||||||
|
|
||||||
@@ -317,6 +325,22 @@ export async function restoreSession(): Promise<SessionTypes.Struct | null> {
|
|||||||
// Check if session is not expired
|
// Check if session is not expired
|
||||||
const now = Math.floor(Date.now() / 1000);
|
const now = Math.floor(Date.now() / 1000);
|
||||||
if (session.expiry > now) {
|
if (session.expiry > now) {
|
||||||
|
// Validate session has all required chains for cross-chain signing
|
||||||
|
const ns = session.namespaces['polkadot'];
|
||||||
|
const sessionChains = ns?.chains || ns?.accounts?.map(a => {
|
||||||
|
const parts = a.split(':');
|
||||||
|
return `${parts[0]}:${parts[1]}`;
|
||||||
|
}) || [];
|
||||||
|
const hasAllChains = REQUIRED_CHAIN_IDS.every(c => sessionChains.includes(c));
|
||||||
|
|
||||||
|
if (!hasAllChains) {
|
||||||
|
// Old session missing chains — discard so a new session with all chains is created
|
||||||
|
console.warn('[WC] Session missing required chains, discarding. Has:', sessionChains);
|
||||||
|
try { await client.disconnect({ topic: session.topic, reason: { code: 6000, message: 'Session missing required chains' } }); } catch {}
|
||||||
|
localStorage.removeItem(WC_SESSION_KEY);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
currentSession = session;
|
currentSession = session;
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user