mirror of
https://github.com/acid-info/Kurate.git
synced 2025-02-20 19:48:16 +00:00
feat: generate anonymous identity (#88)
This commit is contained in:
parent
1f40f7ce3a
commit
3cd5e0fdbc
6373
package-lock.json
generated
6373
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -13,14 +13,18 @@
|
||||
"format": "prettier --plugin-search-dir . --write . && eslint . --fix"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@esbuild-plugins/node-globals-polyfill": "^0.1.1",
|
||||
"@esbuild-plugins/node-modules-polyfill": "^0.1.4",
|
||||
"@fontsource/source-code-pro": "^4.5.12",
|
||||
"@fontsource/source-sans-pro": "^4.5.11",
|
||||
"@fontsource/source-serif-pro": "^4.5.9",
|
||||
"@playwright/test": "1.28.1",
|
||||
"@semaphore-protocol/identity": "^2.6.1",
|
||||
"@sveltejs/adapter-static": "^1.0.0",
|
||||
"@sveltejs/kit": "^1.0.0-next.578",
|
||||
"@typescript-eslint/eslint-plugin": "^5.46.1",
|
||||
"@typescript-eslint/parser": "^5.46.1",
|
||||
"big-integer": "^1.6.51",
|
||||
"eslint": "^8.29.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-svelte3": "^4.0.0",
|
||||
|
20
packages/ui/src/lib/services/index.ts
Normal file
20
packages/ui/src/lib/services/index.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { providers } from 'ethers'
|
||||
import { Identity } from '@semaphore-protocol/identity'
|
||||
|
||||
type WindowWithEthereum = Window &
|
||||
typeof globalThis & { ethereum: providers.ExternalProvider | providers.JsonRpcFetchFunc }
|
||||
|
||||
export async function connectWallet(network?: providers.Networkish) {
|
||||
const provider = new providers.Web3Provider((window as WindowWithEthereum).ethereum, network)
|
||||
await provider.send('eth_requestAccounts', [])
|
||||
return provider.getSigner()
|
||||
}
|
||||
|
||||
export function canConnectWallet() {
|
||||
return Boolean((window as WindowWithEthereum)?.ethereum)
|
||||
}
|
||||
|
||||
export async function createIdentity(signer: providers.JsonRpcSigner, secret: string) {
|
||||
const identitySeed = await signer.signMessage(secret)
|
||||
return new Identity(identitySeed)
|
||||
}
|
@ -1,47 +1,16 @@
|
||||
import { writable, type Writable } from 'svelte/store'
|
||||
import type { User } from './user'
|
||||
import { providers } from 'ethers'
|
||||
|
||||
type WindowWithEthereum = Window &
|
||||
typeof globalThis & { ethereum: providers.ExternalProvider | providers.JsonRpcFetchFunc }
|
||||
import type { providers } from 'ethers'
|
||||
import type { Identity } from '@semaphore-protocol/identity'
|
||||
|
||||
export interface Profile {
|
||||
signer?: providers.JsonRpcSigner
|
||||
error?: Error
|
||||
profiles: User[]
|
||||
active?: User
|
||||
identities: Record<string, Identity>
|
||||
}
|
||||
|
||||
export interface ProfileStore extends Writable<Profile> {
|
||||
setActive: (user: User) => void
|
||||
getSigner: (network?: providers.Networkish) => Promise<void>
|
||||
}
|
||||
|
||||
export const canConnect = () => Boolean((window as WindowWithEthereum).ethereum)
|
||||
export type ProfileStore = Writable<Profile>
|
||||
|
||||
function createProfileStore(): ProfileStore {
|
||||
const store = writable<Profile>({ profiles: [], active: undefined })
|
||||
|
||||
return {
|
||||
...store,
|
||||
setActive: (user: User) => {
|
||||
store.update((profile) => ({ ...profile, active: user }))
|
||||
},
|
||||
getSigner: async (network) => {
|
||||
try {
|
||||
const provider = new providers.Web3Provider(
|
||||
(window as WindowWithEthereum).ethereum,
|
||||
network,
|
||||
)
|
||||
await provider.send('eth_requestAccounts', [])
|
||||
const signer = provider.getSigner()
|
||||
|
||||
store.update((profile) => ({ ...profile, signer, error: undefined }))
|
||||
} catch (error) {
|
||||
store.update((profile) => ({ ...profile, signer: undefined, error: error as Error }))
|
||||
}
|
||||
},
|
||||
}
|
||||
return writable<Profile>({ identities: {} })
|
||||
}
|
||||
|
||||
export const profile = createProfileStore()
|
||||
|
@ -1,10 +1,31 @@
|
||||
<script lang="ts">
|
||||
import { browser } from '$app/environment'
|
||||
import Button from '$lib/components/button.svelte'
|
||||
import Logout from '$lib/components/icons/logout.svelte'
|
||||
import Undo from '$lib/components/icons/undo.svelte'
|
||||
import Wallet from '$lib/components/icons/wallet.svelte'
|
||||
import Input from '$lib/components/input.svelte'
|
||||
import { canConnect, profile } from '$lib/stores/profile'
|
||||
import { connectWallet, canConnectWallet, createIdentity } from '$lib/services'
|
||||
import { profile } from '$lib/stores/profile'
|
||||
|
||||
let error: Error | undefined = undefined
|
||||
let hasWallet = browser && canConnectWallet()
|
||||
|
||||
const handleConnect = async () => {
|
||||
try {
|
||||
$profile.signer = await connectWallet()
|
||||
|
||||
const defaultIdentity = 'anonymous'
|
||||
|
||||
const identity = await createIdentity($profile.signer, defaultIdentity)
|
||||
|
||||
$profile.identities = { ...$profile.identities, [defaultIdentity]: identity }
|
||||
} catch (err) {
|
||||
error = err as Error
|
||||
}
|
||||
}
|
||||
|
||||
$: console.log($profile.identities)
|
||||
</script>
|
||||
|
||||
<div class="header">
|
||||
@ -21,18 +42,18 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="content">
|
||||
{#if !canConnect()}
|
||||
{#if !hasWallet}
|
||||
<span>Your browser does not have web3 wallet access.</span>
|
||||
{:else if $profile.signer === undefined}
|
||||
<Button
|
||||
variant="primary"
|
||||
icon={Wallet}
|
||||
label="Connect wallet to post"
|
||||
on:click={() => profile.getSigner()}
|
||||
on:click={handleConnect}
|
||||
/>
|
||||
<span>Connect a wallet to access or create your account.</span>
|
||||
{#if $profile.error !== undefined}
|
||||
<span>Failed to connect {$profile.error.message}</span>
|
||||
{#if error !== undefined}
|
||||
<span>Failed to connect {error.message}</span>
|
||||
{/if}
|
||||
{:else}
|
||||
<span>Wallet & Identity</span>
|
||||
@ -48,6 +69,13 @@
|
||||
</span>
|
||||
</Input>
|
||||
{/if}
|
||||
|
||||
{#each Object.entries($profile.identities) as [name, identity]}
|
||||
<div>{name}</div>
|
||||
<div>commitment: {identity.getCommitment().toString(16)}</div>
|
||||
<div>nullifier: {identity.getNullifier().toString(16)}</div>
|
||||
<div>trapdoor: {identity.getTrapdoor().toString(16)}</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
|
@ -1,8 +1,38 @@
|
||||
import { sveltekit } from '@sveltejs/kit/vite'
|
||||
import type { UserConfig } from 'vite'
|
||||
import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'
|
||||
import { NodeModulesPolyfillPlugin } from '@esbuild-plugins/node-modules-polyfill'
|
||||
import rollupNodePolyFill from 'rollup-plugin-node-polyfills'
|
||||
|
||||
const config: UserConfig = {
|
||||
plugins: [sveltekit()],
|
||||
|
||||
// For more info see https://medium.com/@ftaioli/using-node-js-builtin-modules-with-vite-6194737c2cd2
|
||||
optimizeDeps: {
|
||||
esbuildOptions: {
|
||||
// Node.js global to browser globalThis
|
||||
define: {
|
||||
global: 'globalThis',
|
||||
},
|
||||
// Enable esbuild polyfill plugins
|
||||
plugins: [
|
||||
NodeGlobalsPolyfillPlugin({
|
||||
process: true,
|
||||
buffer: true,
|
||||
}),
|
||||
NodeModulesPolyfillPlugin(),
|
||||
],
|
||||
},
|
||||
},
|
||||
build: {
|
||||
rollupOptions: {
|
||||
plugins: [
|
||||
// Enable rollup polyfills plugin
|
||||
// used during production bundling
|
||||
rollupNodePolyFill() as any,
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default config
|
||||
|
Loading…
x
Reference in New Issue
Block a user