jubmoji initial integration

This commit is contained in:
AtHeartEngineer
2023-11-05 18:27:24 +03:00
parent 697a0f046e
commit 7241ae7a17
16 changed files with 1605 additions and 86 deletions

View File

@@ -1,6 +1,7 @@
<script lang="ts">
import { inviteCode } from '$lib/gateways/inviteCode';
import { alertQueue } from '$lib/stores';
import { alertQueue, configStore } from '$lib/stores';
import { onMount } from 'svelte';
export let code = '';
export let buttonText = 'Submit';
export let hideInput = false;
@@ -78,6 +79,11 @@
event.preventDefault();
}
}
onMount(() => {
if (code == $configStore.signUpStatus.inviteCode) {
addCode(code);
}
});
</script>
{#if !hideInput}

View File

@@ -0,0 +1,50 @@
<script lang="ts">
import { jubmojiRequest } from '$lib/gateways/jubmojis';
import type { JubmojiProofI } from '$lib/types';
import Creation from 'svelte-material-icons/Creation.svelte';
import MagicStaff from 'svelte-material-icons/MagicStaff.svelte';
import Loading from '$lib/components/Utils/Loading.svelte';
import { alertQueue, configStore } from '$lib/stores';
import { onMount } from 'svelte';
let loading = false;
function validateProof(proof: JubmojiProofI) {
loading = true;
jubmojiRequest(proof)
.then((acceptedRoomNames) => {
if (acceptedRoomNames) {
acceptedRoomNames = acceptedRoomNames;
}
})
.catch((err) => {
console.log(err);
alertQueue.enqueue(`Unexpected error: ${err.message}`, 'error');
})
.finally(() => {
loading = false;
});
}
onMount(() => {
if ($configStore.signUpStatus.jubmojiProof) {
validateProof($configStore.signUpStatus.jubmojiProof);
}
});
</script>
{#if $configStore.signUpStatus.jubmojiProof}
<h3 class="h4">Proof Found!</h3>
{#if !loading}
<div class="btn variant-ghost-secondary" on:click={() => validateProof(proof)}>
<Creation class="mr-2" />Prove Your Power<MagicStaff />
</div>
{:else}
<div class="text-primary">Proving Powers...</div>
<Loading />
{/if}
{:else}
<a class="btn variant-ghost-secondary" href="https://www.jubmoji.quest/powers"
><Creation class="mr-2" />Harness Your Power<MagicStaff /></a
>
{/if}

View File

@@ -4,23 +4,25 @@
import TheWord from '$lib/components/Gateways/TheWord.svelte';
import SelectServer from '$lib/components/Server/SelectServer.svelte';
import Card from '$lib/components/Utils/Card.svelte';
import BullHorn from 'svelte-material-icons/BullHorn.svelte';
import { configStore, numberServers } from '$lib/stores';
</script>
{#if $numberServers > 1}
<div class="variant-ghost-success p-4 rounded-token w-lg self-center">
<h3 class="h4">Select Server, or add a new Server:</h3>
<h3 class="h4">Select Server, or add a new Server</h3>
<SelectServer />
</div>
{/if}
<div id="gateway-cards" class="grid">
<Card>
<svelte:fragment slot="header">Join via invite code:</svelte:fragment>
<svelte:fragment slot="header">Join via invite code</svelte:fragment>
<svelte:fragment slot="description">If you were given an invite code, you can</svelte:fragment>
<InviteCodeGateway code={$configStore.signUpStatus.inviteCode} />
</Card>
<Card>
<svelte:fragment slot="header">Join Alpha Testers:</svelte:fragment>
<svelte:fragment slot="header">Join Alpha Testers</svelte:fragment>
<svelte:fragment slot="description"
>Test things out, let us know if you have any issues</svelte:fragment
>
@@ -40,18 +42,22 @@
>
</Card>
<Card>
<svelte:fragment slot="header">Join via Jubmoji:</svelte:fragment>
<svelte:fragment slot="description">Coming Soon!</svelte:fragment>
<svelte:fragment slot="header">Join via Jubmoji</svelte:fragment>
<svelte:fragment slot="description"
>Prove your collection and get access to special rooms</svelte:fragment
>
</Card>
<Card>
<svelte:fragment slot="header">Join via Ethereum:</svelte:fragment>
<svelte:fragment slot="header">Join via Ethereum</svelte:fragment>
<svelte:fragment slot="description"
>Are you a genesis staker? Stateful works funder? Join the conversation!
</svelte:fragment>
<EthereumGroupGateway />
</Card>
<Card>
<svelte:fragment slot="header">The Word</svelte:fragment>
<svelte:fragment slot="header"
><span class="flex gap-3">The Word <BullHorn /></span></svelte:fragment
>
<svelte:fragment slot="description"
>Do you know <a class="link" target="_blank" href="https://github.com/Mach-34/the-word/"
>the word</a

View File

@@ -0,0 +1,15 @@
import { postJubmojis } from '$lib/services/server';
import { configStore } from '$lib/stores';
import type { GatewayResultI, JubmojiProofI } from '$lib/types';
import { handleGatewayRequest } from './gatewayProcessor';
export async function jubmojiRequest(proof: JubmojiProofI): Promise<GatewayResultI> {
const result = await handleGatewayRequest({ proof }, postJubmojis);
if (result) {
configStore.update((store) => {
store['signUpStatus']['jubmojiProof'] = undefined;
return store;
});
}
return result;
}

View File

@@ -1,5 +1,5 @@
import type { MessageI, ServerI } from 'discreetly-interfaces';
import type { IdentityStoreI, Invites, JoinResponseI, RoomI } from '$lib/types';
import type { IdentityStoreI, Invites, JoinResponseI, JubmojiProofI, RoomI } from '$lib/types';
import { Prover } from 'idc-nullifier';
import type { Identity } from '@semaphore-protocol/identity';
import { get, getAuth, post, postAuth } from './api';
@@ -87,6 +87,17 @@ export async function postTheWord(
return response;
}
export async function postJubmojis(
serverUrl: string,
data: { proof: JubmojiProofI; idc: string }
): Promise<JoinResponseI> {
const response = post([serverUrl, 'gateway/jubmojis/join'], data) as unknown as JoinResponseI;
if (!response.status || !response.roomIds) {
throw new Error('Response does not match JoinResponseI interface');
}
return response;
}
export async function getMessages(serverUrl: string, roomId: string) {
return get([serverUrl, `room/${roomId}/messages`]) as Promise<MessageI[]>;
}

View File

@@ -44,6 +44,7 @@ export interface SignUpStatusI {
completedSignup: boolean;
identityBackedUp: boolean;
inviteCode?: string;
jubmojiProof?: JubmojiProofI;
}
export interface RoomFormData {
@@ -62,3 +63,9 @@ export interface SNARKProof {
proof: object;
publicSignals: string[];
}
export interface JubmojiProofI {
R: string;
msgHash: string;
zkp: SNARKProof;
}

View File

@@ -1,5 +1,4 @@
function hashToDarkHSL(hash: number, offset = 6): string {
console.log(hash);
const hue = (hash + offset) % 360; // Hue ranges from 0-359
const saturation = 22; // Full saturation
const lightness = 12; // Keeping lightness around 30% for darkness
@@ -7,8 +6,10 @@ function hashToDarkHSL(hash: number, offset = 6): string {
}
function stringToHash(str: string): number {
let hash = 0;
for (let i = 0; i < str.length; i++) {
hash += str.charCodeAt(i);
if (str !== '') {
for (let i = 0; i < str.length; i++) {
hash += str.charCodeAt(i);
}
}
return hash % 360;
}

View File

@@ -28,8 +28,17 @@
<span>Sign Up</span>
</Button>
{:else}
It looks like you are already signed up!
<Button link="/chat" cls="variant-ghost-success">Go Chat</Button>
<Button
link="https://discord.gg/brJQ36KVxk"
cls="variant-ghost-tertiary btn-lg m-2 sm:m-3 px-8 min-w-[12rem]"
>
<span><Help /></span>
<span>Join Our Discord</span></Button
>
<Button link="/chat" cls="variant-ghost-success btn-lg m-2 sm:m-3 px-8 min-w-[12rem]">
<span><Mask /></span>
<span>Go Chat</span>
</Button>
{/if}
</div>
</div>

View File

@@ -76,7 +76,7 @@
<div class="grid grid-flow-rows gap-7 my-5 max-w-md mx-auto">
{#each createdCodes as code}
<div class="grid grid-flow-rows gap-7 my-5 max-w-md mx-auto">
<i class="text-center">https://app.discreetly.chat/join/{Object.values(code)}</i>
<i class="text-center">https://app.discreetly.chat/signup/{Object.values(code)}</i>
</div>
{/each}
</div>

View File

@@ -6,6 +6,7 @@
onMount(() => {
if (!$identityExists) {
console.warn('Identity not detected, redirecting to signup page from /chat');
goto('/signup');
}
if (!Object.keys($serverStore).length) {

View File

@@ -32,8 +32,7 @@
}
onMount(() => {
scrollChatBottom('instant', 1);
console.log($currentRoomMessages);
scrollChatBottom('instant', 10);
});
</script>

View File

@@ -1,9 +1,26 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { page } from '$app/stores';
import { onMount } from 'svelte';
const encodedProof = $page.url.searchParams.get('proof')
const decodedProof = decodeURIComponent(encodedProof)
const proof = JSON.parse(decodedProof)
proof.serializedMembershipProof = JSON.parse(proof.serializedMembershipProof)
console.log(proof)
onMount(() => {
const encodedProof = $page.url.searchParams.get('proof');
if (encodedProof === null) {
console.error('No proof provided');
goto('/gateways');
} else {
const p = {
zkp: {},
R: '',
msghash: ''
};
const decodedProof = decodeURIComponent(encodedProof);
const step1 = JSON.parse(decodedProof);
const step2 = JSON.parse(step1.serializedMembershipProof);
p.zkp = step1.zkp;
p.R = step2.serializedMembershipProof.R;
p.msghash = step2.serializedMembershipProof.msghash;
step2.$configStore.signUpStatus.jubmojiProof = p;
}
});
</script>

View File

@@ -1,17 +0,0 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { page } from '$app/stores';
import { configStore, identityExists } from '$lib/stores';
import { onMount } from 'svelte';
$configStore.signUpStatus.inviteCode = $page.params.invite;
console.log(`Invited with code: ${$page.params.invite}`);
onMount(() => {
if ($identityExists) {
goto('/settings#join-more');
} else {
goto('/signup');
}
});
</script>

View File

@@ -9,7 +9,11 @@
onMount(() => {
if ($identityExists) {
goto('/settings#join-more');
console.warn('Invite code saved, routing to /gateways from /signup/[inviteCode]');
goto('/gateways');
} else {
console.warn('Identity not detected, redirecting to signup page from /signup/[inviteCode]');
goto('/signup');
}
});
</script>