Move from web3modal to walletconnect v2 (#64)

Co-authored-by: Gregorio Granado Magalhaes <greg.magalhaes@gmail.com>
This commit is contained in:
Simon Bihel 2023-06-22 17:21:15 +01:00 committed by GitHub
parent 3278ff752a
commit 1c29815376
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 4650 additions and 18750 deletions

View File

@ -14,9 +14,7 @@ COPY --from=dep_planner /siwe-oidc/recipe.json recipe.json
RUN cargo chef cook --release --recipe-path recipe.json
FROM node:16-alpine as node_builder
ENV FORTMATIC_KEY=""
ENV INFURA_ID=""
ENV PORTIS_ID=""
ENV PROJECT_ID=""
ADD --chown=node:node ./static /siwe-oidc/static
ADD --chown=node:node ./js/ui /siwe-oidc/js/ui
WORKDIR /siwe-oidc/js/ui

View File

@ -6,6 +6,10 @@ Two versions are available, a stand-alone binary (using Axum and Redis) and a
Cloudflare Worker. They use the same code base and are selected at compile time
(compiling for `wasm32` will make the Worker version).
> The front-end depends on WalletConnect, meaning you will need to create a
> project with them and have the environment variable `PROJECT_ID` set when you
> build the front-end.
### Cloudflare Worker
You will need [`wrangler`](https://github.com/cloudflare/wrangler).
@ -52,8 +56,9 @@ siweoidc.example.com/.w*
### Stand-Alone Binary
> Note that currently the published Docker image doesn't support all wallets due
> to the need of bundling secrets for web3modal at compile-time.
> **WARNING - ** Due to the reliance on WalletConnect, and the project ID being
> loaded at compile-time, the current version of the Docker image won't have a
> working web app.
#### Dependencies

23226
js/ui/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -33,12 +33,12 @@
"svelte": "^3.49.0",
"svelte-check": "^2.2.11",
"svelte-loader": "^3.0.0",
"svelte-preprocess": "^4.3.0",
"svelte-preprocess": "^5.0.4",
"svg-url-loader": "^7.1.1",
"tailwindcss": "^3.0.9",
"ts-loader": "^9.2.6",
"tslib": "^2.0.1",
"typescript": "^4.0.3",
"typescript": "^5.1.3",
"webpack": "^5.76.0",
"webpack-cli": "^4.4.0",
"webpack-dev-server": "^4.6.0"
@ -49,12 +49,12 @@
"validate": "svelte-check"
},
"dependencies": {
"@coinbase/wallet-sdk": "^3.0.5",
"@portis/web3": "^4.0.6",
"@spruceid/siwe-web3modal": "^0.1.11",
"@toruslabs/torus-embed": "^1.21.0",
"@walletconnect/web3-provider": "^1.7.7",
"fortmatic": "^2.2.1",
"url": "^0.11.0"
"@wagmi/core": "^1.2.0",
"@web3modal/ethereum": "^2.4.5",
"@web3modal/html": "^2.4.5",
"js-cookie": "^3.0.5",
"siwe": "^2.1.4",
"url": "^0.11.0",
"viem": "^1.0.6"
}
}

View File

@ -1,11 +1,12 @@
<script lang="ts">
import Portis from '@portis/web3';
import { Client } from '@spruceid/siwe-web3modal';
import Torus from '@toruslabs/torus-embed';
import WalletConnectProvider from '@walletconnect/web3-provider';
import Fortmatic from 'fortmatic';
import { onMount } from 'svelte';
import CoinbaseWalletSDK from "@coinbase/wallet-sdk";
import { EthereumClient, w3mConnectors, w3mProvider } from '@web3modal/ethereum';
import { Web3Modal } from '@web3modal/html';
import { configureChains, createConfig } from '@wagmi/core';
import { arbitrum, mainnet, polygon } from '@wagmi/core/chains';
import { getAccount } from '@wagmi/core';
import { SiweMessage } from 'siwe';
import Cookies from 'js-cookie';
// TODO: REMOVE DEFAULTS:
// main.ts will parse the params from the server
@ -15,57 +16,20 @@
export let state: string;
export let oidc_nonce: string;
export let client_id: string;
// Could be exposed in the future.
export let useENS: boolean = true;
const projectId: string = process.env.PROJECT_ID;
$: status = 'Not Logged In';
let client = new Client({
session: {
domain: window.location.host,
uri: window.location.origin,
useENS,
version: '1',
// TODO: Vet this as the default statement.
statement: `You are signing-in to ${domain}.`,
resources: [redirect],
},
modal: {
theme: 'dark',
providerOptions: {
walletconnect: {
package: WalletConnectProvider,
options: {
infuraId: process.env.INFURA_ID,
pollingInterval: 100000,
},
},
torus: {
package: Torus,
},
portis: {
package: Portis,
options: {
id: process.env.PORTIS_ID,
},
},
fortmatic: {
package: Fortmatic,
options: {
key: process.env.FORTMATIC_KEY,
},
},
walletlink: {
package: CoinbaseWalletSDK,
options: {
appName: "Sign-In with Ethereum",
infuraId: process.env.INFURA_ID
}
},
},
},
const chains = [arbitrum, mainnet, polygon];
const { publicClient } = configureChains(chains, [w3mProvider({ projectId })]);
const wagmiConfig = createConfig({
autoConnect: true,
connectors: w3mConnectors({ projectId, version: 1, chains }),
publicClient,
});
const ethereumClient = new EthereumClient(wagmiConfig, chains);
const web3modal = new Web3Modal({ projectId }, ethereumClient);
let client_metadata = {};
onMount(async () => {
@ -75,19 +39,58 @@
console.error(e);
}
});
web3modal.subscribeModal(async () => {
const account = getAccount();
if (account.isConnected) {
try {
const expirationTime = new Date(
new Date().getTime() + (2 * 24 * 60 * 60 * 1000) // 48h
);
const signMessage = new SiweMessage({
domain: window.location.host,
address: account.address,
chainId: await account.connector.getChainId(),
expirationTime: expirationTime.toISOString(),
uri: window.location.origin,
version: '1',
statement: `You are signing-in to ${window.location.host}.`,
nonce,
resources: [redirect],
}).prepareMessage();
const signature = await (
await account.connector.getWalletClient()
).signMessage({
account: account.address,
message: signMessage,
});
const message = new SiweMessage(signMessage);
const session = {
message,
raw: signMessage,
signature,
};
Cookies.set('siwe', JSON.stringify(session), {
expires: expirationTime,
});
window.location.replace(
`/sign_in?redirect_uri=${encodeURI(redirect)}&state=${encodeURI(state)}&client_id=${encodeURI(
client_id,
)}${encodeURI(oidc_nonce_param)}`,
);
return;
} catch (e) {
console.error(e);
}
}
});
let oidc_nonce_param = '';
if (oidc_nonce != null && oidc_nonce != '') {
oidc_nonce_param = `&oidc_nonce=${oidc_nonce}`;
}
client.on('signIn', (result) => {
console.log(result);
window.location.replace(
`/sign_in?redirect_uri=${encodeURI(redirect)}&state=${encodeURI(state)}&client_id=${encodeURI(
client_id,
)}${encodeURI(oidc_nonce_param)}`,
);
});
</script>
<div
@ -111,9 +114,7 @@
<button
class="h-12 border hover:scale-105 justify-evenly shadow-xl border-white mt-4 duration-100 ease-in-out transition-all transform flex items-center"
on:click={() => {
client.signIn(nonce).catch((e) => {
console.error(e);
});
web3modal.openModal();
}}
>
<svg

View File

@ -3,6 +3,7 @@
"include": ["src/**/*", "src/node_modules/**/*"],
"exclude": ["node_modules/*", "__sapper__/*", "static/*"],
"compilerOptions": {
"types": ["node", "svelte"]
"types": ["node", "svelte"],
"ignoreDeprecations": "5.0"
}
}

View File

@ -8,7 +8,7 @@ const prod = mode === 'production';
module.exports = {
entry: {
'build/bundle': ['./src/main.ts']
'bundle': ['./src/main.ts']
},
resolve: {
alias: {
@ -31,8 +31,12 @@ module.exports = {
// util: false,
}
},
optimization: {
runtimeChunk: 'single',
},
output: {
path: path.join(__dirname, '../../static'),
path: path.join(__dirname, '../../static/build'),
publicPath: "/build/",
filename: '[name].js',
chunkFilename: '[name].[id].js'
},
@ -96,7 +100,7 @@ module.exports = {
new MiniCssExtractPlugin({
filename: '[name].css'
}),
new webpack.EnvironmentPlugin(prod ? ['INFURA_ID', 'PORTIS_ID', 'FORTMATIC_KEY'] : []),
new webpack.EnvironmentPlugin(prod ? ['PROJECT_ID'] : []),
],
devtool: prod ? false : 'source-map',
devServer: {

View File

@ -10,6 +10,7 @@
<link rel="stylesheet" href="/build/bundle.css" />
<script defer src="/build/bundle.js"></script>
<script defer src="/build/runtime.js"></script>
<link
href="https://api.fontshare.com/css?f[]=satoshi@300,301,400,401,500,501,700,701,900,901,1,2&display=swap"
rel="stylesheet"