40 lines
1.1 KiB
TypeScript
40 lines
1.1 KiB
TypeScript
|
|
import { requestWalletNonce, verifyWalletSignature } from "./api";
|
||
|
|
|
||
|
|
export type EthereumProvider = {
|
||
|
|
request: <T = unknown>(args: {
|
||
|
|
method: string;
|
||
|
|
params?: unknown[];
|
||
|
|
}) => Promise<T>;
|
||
|
|
};
|
||
|
|
|
||
|
|
export function getInjectedEthereum(): EthereumProvider | null {
|
||
|
|
if (typeof window === "undefined") return null;
|
||
|
|
const maybeWindow = window as typeof window & { ethereum?: EthereumProvider };
|
||
|
|
return maybeWindow.ethereum ?? null;
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function signInWithInjectedWallet(): Promise<{
|
||
|
|
token: string;
|
||
|
|
wallet: string;
|
||
|
|
}> {
|
||
|
|
const ethereum = getInjectedEthereum();
|
||
|
|
if (!ethereum) throw new Error("No injected wallet found");
|
||
|
|
|
||
|
|
const accounts = await ethereum.request<string[]>({
|
||
|
|
method: "eth_requestAccounts",
|
||
|
|
});
|
||
|
|
const address = accounts[0];
|
||
|
|
if (!address) throw new Error("No wallet account returned");
|
||
|
|
|
||
|
|
const nonce = await requestWalletNonce(address);
|
||
|
|
const signature = await ethereum.request<string>({
|
||
|
|
method: "personal_sign",
|
||
|
|
params: [nonce.message, address],
|
||
|
|
});
|
||
|
|
return verifyWalletSignature({
|
||
|
|
address,
|
||
|
|
message: nonce.message,
|
||
|
|
signature,
|
||
|
|
});
|
||
|
|
}
|