Link to minimal reproducible example
https://drive.google.com/file/d/17iU7UQ8VL5oRjzI9TrIQrstPNQKJVuVt/view?usp=sharing
Steps to Reproduce
- enable
siwx on AppKit - for my example, I only have BSC testnet in my networks field
- connect a wallet that does not support BSC testnet - I used Phantom
My code is below:
siwx.ts
import { ConstantsUtil } from "@reown/appkit-common";
import {
DefaultSIWX,
InformalMessenger,
type SIWXSession,
SIWXVerifier,
} from "@reown/appkit-siwx";
import { AppKitNetwork, bscTestnet } from "@reown/appkit/networks";
import { isNil } from "es-toolkit";
import { toast } from "sonner";
import { createBrowserClient } from "@/lib/supabase/browser";
export const siwxNetworks = [bscTestnet] as const satisfies [
AppKitNetwork,
...AppKitNetwork[],
];
class SIWXEip155Verifier extends SIWXVerifier {
public readonly chainNamespace = ConstantsUtil.CHAIN.EVM;
public override shouldVerify(session: SIWXSession): boolean {
const parts = session.data.chainId.split(":");
if (parts[0] !== this.chainNamespace) {
return false;
}
// const numericChainId = parseInt(parts.slice(1).join(":"));
const numericChainId = parseInt(parts[1]);
const isValidChainId = siwxNetworks.some(
(network) => network.id === numericChainId,
);
if (!isValidChainId) {
const validChainNames = siwxNetworks
.map((network) => network.name)
.join(", ");
toast.error("Error Signing Message", {
id: "invalid-chain",
description: `Your wallet must support the following network(s): ${validChainNames}. Please add it to your wallet, click "Cancel", then refresh the page.`,
duration: Infinity,
dismissible: true,
closeButton: true,
action: {
label: "Refresh",
onClick: () => window.location.reload(),
},
});
}
return isValidChainId;
}
public async verify(session: SIWXSession): Promise<boolean> {
try {
const response = await fetch("/api/v1/siwx/verify", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
message: session.message,
signature: session.signature,
address: session.data.accountAddress,
}),
});
if (!response.ok) {
return false;
}
const result = await response.json();
if (isNil(result) || typeof result !== "object") {
return false;
}
if (
"access_token" in result &&
typeof result.access_token === "string" &&
"refresh_token" in result &&
typeof result.refresh_token === "string"
) {
const supabase = createBrowserClient();
const { error } = await supabase.auth.setSession({
access_token: result.access_token,
refresh_token: result.refresh_token,
});
if (error) {
console.error("Error setting session:", error);
return false;
}
return true;
}
return false;
} catch (error) {
console.error("SIWX verification error:", error);
return false;
}
}
}
// Create the SIWX configuration
export const siwxConfig = new DefaultSIWX({
messenger: new InformalMessenger({
domain: process.env.NODE_ENV === "production" ? "twin.fun" : "localhost",
uri:
process.env.NODE_ENV === "production"
? "https://www.twin.fun"
: "http://localhost:3000",
getNonce: async () => Date.now().toString(),
}),
verifiers: [new SIWXEip155Verifier()],
required: true,
});
AppKitProvider.tsx
import { WagmiAdapter } from "@reown/appkit-adapter-wagmi";
import { AppKitNetwork } from "@reown/appkit/networks";
import { createAppKit } from "@reown/appkit/react";
import { WagmiProvider } from "wagmi";
import { siwxConfig, siwxNetworks } from "@/config/siwx";
const projectId = "xxxxxxxxxxxxxxxxxx";
const networks = [...siwxNetworks] as const satisfies [
AppKitNetwork,
...AppKitNetwork[],
];
const wagmiAdapter = new WagmiAdapter({
networks,
projectId,
ssr: true,
});
createAppKit({
adapters: [wagmiAdapter],
networks,
projectId,
siwx: siwxConfig,
});
export function AppKitProvider({ children }: { children: React.ReactNode }) {
return (
<WagmiProvider config={wagmiAdapter.wagmiConfig}>{children}</WagmiProvider>
);
}
Summary
Bug 1
If you look closely, the Switch Network dialog flashes briefly before the App needs to connect your wallet dialog. Even though the network is unsupported, it still prompts the user to sign the message. This shouldn't happen - it doesn't make any sense to still ask the user to sign the message when the network isn't supported.
Bug 2
Without my custom shouldVerify implementation, it automatically assigns another chain (one that isn't supported by my app) to the SIWX message. Then, it allows the user to sign the message - and they would be logged in on the wrong network. This happens even if I set createAppKit → allowUnsupportedChain: false.
I was able to prevent this with overriding shouldVerify and manually checking the chain ID. But, this should definitely not happen. Otherwise, users who are able to log in with a network that my app doesn't support will not be able to make transactions anyways.
Bug 3
If you follow these steps:
- connect a wallet that does not support your app's networks
- click "Cancel" on the
App needs to connect your wallet dialog
- refresh the page
This causes the Switch Network dialog to pop-up on load, and I'm unable to close out of it. The x and Disconnect buttons do not work. The only way to close out of it is to click into one one of the network names - and exit out of that.
List of related npm package versions
{
"@reown/appkit": "^1.8.11",
"@reown/appkit-adapter-wagmi": "^1.8.11",
"@reown/appkit-siwe": "^1.8.11",
"@reown/appkit-siwx": "^1.8.11",
"viem": "^2.38.3",
"wagmi": "^2.18.1",
}
Node.js Version
v24.4.0
Package Manager
npm@11.4.2
Link to minimal reproducible example
https://drive.google.com/file/d/17iU7UQ8VL5oRjzI9TrIQrstPNQKJVuVt/view?usp=sharing
Steps to Reproduce
siwxon AppKit - for my example, I only have BSC testnet in my networks fieldMy code is below:
siwx.ts
AppKitProvider.tsx
Summary
Bug 1
If you look closely, the
Switch Networkdialog flashes briefly before theApp needs to connect your walletdialog. Even though the network is unsupported, it still prompts the user to sign the message. This shouldn't happen - it doesn't make any sense to still ask the user to sign the message when the network isn't supported.Bug 2
Without my custom
shouldVerifyimplementation, it automatically assigns another chain (one that isn't supported by my app) to the SIWX message. Then, it allows the user to sign the message - and they would be logged in on the wrong network. This happens even if I setcreateAppKit→allowUnsupportedChain: false.I was able to prevent this with overriding
shouldVerifyand manually checking the chain ID. But, this should definitely not happen. Otherwise, users who are able to log in with a network that my app doesn't support will not be able to make transactions anyways.Bug 3
If you follow these steps:
App needs to connect your walletdialogThis causes the
Switch Networkdialog to pop-up on load, and I'm unable to close out of it. ThexandDisconnectbuttons do not work. The only way to close out of it is to click into one one of the network names - and exit out of that.List of related npm package versions
{ "@reown/appkit": "^1.8.11", "@reown/appkit-adapter-wagmi": "^1.8.11", "@reown/appkit-siwe": "^1.8.11", "@reown/appkit-siwx": "^1.8.11", "viem": "^2.38.3", "wagmi": "^2.18.1", }Node.js Version
v24.4.0
Package Manager
npm@11.4.2