Skip to content

Commit

Permalink
Merge pull request #1638 from kleros/fix/siwe-debug
Browse files Browse the repository at this point in the history
Fix for the Alchemy URL and SIWE verification for ERC-1271
  • Loading branch information
jaybuidl authored Jul 4, 2024
2 parents ad0154c + 11f5ace commit b5d6c95
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 21 deletions.
12 changes: 9 additions & 3 deletions web/netlify/functions/authUser.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import middy from "@middy/core";
import jsonBodyParser from "@middy/http-json-body-parser";
import { createClient } from "@supabase/supabase-js";
import { ethers } from "ethers";
import * as jwt from "jose";
import { SiweMessage } from "siwe";

import { ETH_SIGNATURE_REGEX, DEFAULT_CHAIN } from "consts/processEnvConsts";
import { ETH_SIGNATURE_REGEX, DEFAULT_CHAIN, isProductionDeployment } from "consts/processEnvConsts";

import { netlifyUri, netlifyDeployUri, netlifyDeployPrimeUri } from "src/generatedNetlifyInfo.json";
import { Database } from "src/types/supabase-notification";
Expand Down Expand Up @@ -73,9 +74,14 @@ const authUser = async (event) => {
}

try {
await siweMessage.verify({ signature, nonce: nonceData.nonce, time: new Date().toISOString() });
// If the main Alchemy API key is permissioned, it won't work in a Netlify Function so we use a dedicated API key
const alchemyApiKey = process.env.ALCHEMY_FUNCTIONS_API_KEY ?? process.env.ALCHEMY_API_KEY;
const alchemyChain = isProductionDeployment() ? "arb-mainnet" : "arb-sepolia";
const alchemyRpcURL = `https://${alchemyChain}.g.alchemy.com/v2/${alchemyApiKey}`;
const provider = new ethers.providers.JsonRpcProvider(alchemyRpcURL);
await siweMessage.verify({ signature, nonce: nonceData.nonce, time: new Date().toISOString() }, { provider });
} catch (err) {
throw new Error("Invalid signer");
throw new Error("Invalid signer: " + JSON.stringify(err));
}

const { error } = await supabase.from("user-nonce").delete().match({ address: lowerCaseAddress });
Expand Down
5 changes: 4 additions & 1 deletion web/src/consts/chains.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import { extractChain } from "viem";
import { Chain, arbitrum, mainnet, arbitrumSepolia, gnosisChiado } from "viem/chains";
import { Chain, arbitrum, mainnet, arbitrumSepolia, gnosis, gnosisChiado } from "viem/chains";

import { isProductionDeployment } from "./index";

export const DEFAULT_CHAIN = isProductionDeployment() ? arbitrum.id : arbitrumSepolia.id;

// Read/Write
export const SUPPORTED_CHAINS: Record<number, Chain> = {
[isProductionDeployment() ? arbitrum.id : arbitrumSepolia.id]: isProductionDeployment() ? arbitrum : arbitrumSepolia,
};

// Read Only
export const QUERY_CHAINS: Record<number, Chain> = {
[gnosisChiado.id]: gnosisChiado,
[gnosis.id]: gnosis,
[mainnet.id]: mainnet,
};

Expand Down
59 changes: 42 additions & 17 deletions web/src/context/Web3Provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,59 @@ import React from "react";
import { createWeb3Modal } from "@web3modal/wagmi/react";
import { type Chain } from "viem";
import { createConfig, fallback, http, WagmiProvider, webSocket } from "wagmi";
import { mainnet, arbitrumSepolia, arbitrum, gnosisChiado } from "wagmi/chains";
import { mainnet, arbitrumSepolia, arbitrum, gnosisChiado, gnosis, sepolia } from "wagmi/chains";
import { walletConnect } from "wagmi/connectors";

import { ALL_CHAINS } from "consts/chains";
import { ALL_CHAINS, DEFAULT_CHAIN } from "consts/chains";
import { isProductionDeployment } from "consts/index";

import { lightTheme } from "styles/themes";

const projectId = import.meta.env.WALLETCONNECT_PROJECT_ID ?? "";
export const alchemyApiKey = import.meta.env.ALCHEMY_API_KEY ?? "";
const alchemyApiKey = import.meta.env.ALCHEMY_API_KEY ?? "";
const isProduction = isProductionDeployment();

const chains = ALL_CHAINS as [Chain, ...Chain[]];
// https://github.com/alchemyplatform/alchemy-sdk-js/blob/96b3f62/src/types/types.ts#L98-L119
const alchemyToViemChain = {
[arbitrum.id]: "arb-mainnet",
[arbitrumSepolia.id]: "arb-sepolia",
[mainnet.id]: "eth-mainnet",
[sepolia.id]: "eth-sepolia",
};

type AlchemyProtocol = "https" | "wss";
type AlchemyChain = "arb-sepolia" | "eth-mainnet" | "arb";
const alchemyURL = (protocol: AlchemyProtocol, chain: AlchemyChain) =>
`${protocol}://${chain}.g.alchemy.com/v2/${alchemyApiKey}`;
const alchemyTransport = (chain: AlchemyChain) =>
fallback([webSocket(alchemyURL("wss", chain)), http(alchemyURL("https", chain))]);

const transports = {
[isProductionDeployment() ? arbitrum.id : arbitrumSepolia.id]: isProductionDeployment()
? alchemyTransport("arb")
: alchemyTransport("arb-sepolia"),
[mainnet.id]: alchemyTransport("eth-mainnet"),
[gnosisChiado.id]: fallback([webSocket("wss://rpc.chiadochain.net/wss"), http("https://rpc.chiadochain.net")]),

// https://github.com/alchemyplatform/alchemy-sdk-js/blob/96b3f62/src/util/const.ts#L16-L18
const alchemyURL = (protocol: AlchemyProtocol, chainId: number) =>
`${protocol}://${alchemyToViemChain[chainId]}.g.alchemy.com/v2/${alchemyApiKey}`;

export const getChainRpcUrl = (protocol: AlchemyProtocol, chainId: number) => {
return alchemyURL(protocol, chainId);
};

export const getDefaultChainRpcUrl = (protocol: AlchemyProtocol) => {
return getChainRpcUrl(protocol, DEFAULT_CHAIN);
};

export const getTransports = () => {
const alchemyTransport = (chain: Chain) =>
fallback([http(alchemyURL("https", chain.id)), webSocket(alchemyURL("wss", chain.id))]);
const defaultTransport = (chain: Chain) =>
fallback([http(chain.rpcUrls.default?.http?.[0]), webSocket(chain.rpcUrls.default?.webSocket?.[0])]);

return {
[isProduction ? arbitrum.id : arbitrumSepolia.id]: isProduction
? alchemyTransport(arbitrum)
: alchemyTransport(arbitrumSepolia),
[isProduction ? gnosis.id : gnosisChiado.id]: isProduction
? defaultTransport(gnosis)
: defaultTransport(gnosisChiado),
[mainnet.id]: alchemyTransport(mainnet), // Always enabled for ENS resolution
};
};

const chains = ALL_CHAINS as [Chain, ...Chain[]];
const transports = getTransports();
const projectId = import.meta.env.WALLETCONNECT_PROJECT_ID ?? "";
const wagmiConfig = createConfig({
chains,
transports,
Expand Down

0 comments on commit b5d6c95

Please sign in to comment.