Skip to content

Commit 675dd70

Browse files
committed
fix: add worldcoin biometric full flow
1 parent e13f86e commit 675dd70

File tree

15 files changed

+92
-95
lines changed

15 files changed

+92
-95
lines changed

space-config/synaps/main.ts

+5-7
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export const synapsConfigMain: SpaceConfig = {
1414
},
1515
apps: [
1616
{
17-
type: "zkCustom",
17+
type: "custom",
1818
metadata: {
1919
name: "Liveness Verification",
2020
description: "Perform liveness verification with Synaps to join the 'Proof of Liveness' Data Group and access Sismo Apps that request to be part of it. This liveness session stores no personal data.",
@@ -29,12 +29,10 @@ export const synapsConfigMain: SpaceConfig = {
2929
authRequests: [{ authType: 0 }],
3030
},
3131
templateConfig: {
32-
extraData: {
33-
api: "https://synaps-integration.vercel.app/api/proof-of-liveness",
34-
congratulationsMessage: {
35-
title: "Congratulations",
36-
description: "You have successfully proven your liveliness. Your proof of liveliness will be available in your Sismo Vault within 24 hours.",
37-
}
32+
api: "https://synaps-integration.vercel.app/api/proof-of-liveness",
33+
congratulationsMessage: {
34+
title: "Congratulations",
35+
description: "You have successfully proven your liveliness. Your proof of liveliness will be available in your Sismo Vault within 24 hours.",
3836
}
3937
}
4038
}

space-config/synaps/proof-of-liveness/components/Congratulations.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client'
22

3-
import { ZkCustomAppConfig } from "@/space-config/types";
3+
import { CustomAppConfig } from "@/space-config/types";
44
import Button3D from "@/src/ui/Button3D";
55
import { useRouter } from "next/navigation";
66
import React from "react";
@@ -28,7 +28,7 @@ const Subtitle = styled.div`
2828
`
2929

3030
type Props = {
31-
app: ZkCustomAppConfig
31+
app: CustomAppConfig
3232
}
3333

3434
export default function Congratulations({ app }: Props): JSX.Element {

space-config/synaps/proof-of-liveness/components/ProveEligibility.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { styled } from "styled-components";
66
import HoverTooltip from "@/src/ui/HoverTooltip";
77
import { Info } from "phosphor-react";
88
import colors from "@/src/themes/colors";
9-
import { ZkCustomAppConfig } from "@/space-config/types";
9+
import { CustomAppConfig } from "@/space-config/types";
1010

1111
const Container = styled.div``;
1212

@@ -38,7 +38,7 @@ const Bold = styled.span`
3838
`;
3939

4040
type Props = {
41-
app: ZkCustomAppConfig;
41+
app: CustomAppConfig;
4242
onEligible: (response) => void;
4343
};
4444

space-config/synaps/proof-of-liveness/index.tsx

+6-6
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import ProveEligibility from "./components/ProveEligibility";
88
import Button from "@/src/ui/Button";
99
import SynapsModal from "./components/SynapsModal";
1010
import { synapsConfigMain } from "@/space-config/synaps/main";
11-
import { ZkCustomAppConfig } from "@/space-config/types";
11+
import { CustomAppConfig } from "@/space-config/types";
1212
import Button3D from "@/src/ui/Button3D";
1313
import { useRouter } from "next/navigation";
14-
import { ZkCustomAppContainer } from "@/src/components/ZkCustomAppContainer";
14+
import { CustomAppContainer } from "@/src/components/CustomAppContainer";
1515

1616

1717
const AlreadyRegistered = styled.div`
@@ -41,9 +41,9 @@ const ErrorMsg = styled.div`
4141
`
4242

4343
export default function SynapsProofOfLivenessCustomApp(): JSX.Element {
44-
const app = synapsConfigMain.apps[0] as ZkCustomAppConfig;
44+
const app = synapsConfigMain.apps[0] as CustomAppConfig;
4545
const router = useRouter();
46-
const api = app.templateConfig.extraData.api;
46+
const api = app.templateConfig.api;
4747
const [response, setResponse] = useState();
4848
const [alreadySubscribed, setAlreadySubscribed] = useState(false);
4949
const [domReady, setDomReady] = React.useState(false);
@@ -104,7 +104,7 @@ export default function SynapsProofOfLivenessCustomApp(): JSX.Element {
104104

105105
return <>
106106
<SynapsModal sessionId={sessionId} isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} onFinish={() => onFinish()}/>
107-
<ZkCustomAppContainer>
107+
<CustomAppContainer>
108108
{
109109
!finished && <>
110110
<Section number={1} isOpen={!response} title="Sign in with Sismo" style={{marginBottom: 16}} success={Boolean(response)}>
@@ -143,6 +143,6 @@ export default function SynapsProofOfLivenessCustomApp(): JSX.Element {
143143
{
144144
finished && <Congratulations app={app}/>
145145
}
146-
</ZkCustomAppContainer>
146+
</CustomAppContainer>
147147
</>;
148148
}

space-config/types.ts

+4-6
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export type AppConfig =
2626
| ExternalAppConfig
2727
| ZkBadgeAppConfig
2828
| ZkTelegramBotAppConfig
29-
| ZkCustomAppConfig
29+
| CustomAppConfig
3030

3131
type SocialType = "twitter" | "discord" | "link" | "github" | "telegram";
3232

@@ -87,11 +87,9 @@ export type ZkDropAppConfig = AppCommonConfig & {
8787
};
8888
};
8989

90-
export type ZkCustomAppConfig = AppCommonConfig & {
91-
type: "zkCustom";
92-
templateConfig: {
93-
extraData: any;
94-
}
90+
export type CustomAppConfig = AppCommonConfig & {
91+
type: "custom";
92+
templateConfig: any
9593
};
9694

9795
export type ZkBadgeAppConfig = AppCommonConfig & {

space-config/worldcoin/main.ts

+5-7
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export const worldcoinConfigMain: SpaceConfig = {
1414
},
1515
apps: [
1616
{
17-
type: "zkCustom",
17+
type: "custom",
1818
metadata: {
1919
name: "Proof of personhood",
2020
description: "World ID is a digital passport that lets you prove you are a unique and real person while remaining anonymous.",
@@ -29,12 +29,10 @@ export const worldcoinConfigMain: SpaceConfig = {
2929
authRequests: [{ authType: 0 }],
3030
},
3131
templateConfig: {
32-
extraData: {
33-
api: "https://worldcoin-app-backend.vercel.app/api/proof-of-personhood",
34-
congratulationsMessage: {
35-
title: "Congratulations",
36-
description: "You have successfully proven your personhood. Your proof of personhood will be available in your Sismo Vault within 24 hours.",
37-
}
32+
api: "https://worldcoin-app-backend.vercel.app/api/proof-of-personhood",
33+
congratulationsMessage: {
34+
title: "Congratulations",
35+
description: "You have successfully proven your personhood. Your proof of personhood will be available in your Sismo Vault within 24 hours.",
3836
}
3937
}
4038
}

space-config/worldcoin/proof-of-personhood/components/Congratulations.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client'
22

3-
import { ZkCustomAppConfig } from "@/space-config/types";
3+
import { CustomAppConfig } from "@/space-config/types";
44
import Button3D from "@/src/ui/Button3D";
55
import { useRouter } from "next/navigation";
66
import React from "react";
@@ -28,7 +28,7 @@ const Subtitle = styled.div`
2828
`
2929

3030
type Props = {
31-
app: ZkCustomAppConfig
31+
app: CustomAppConfig
3232
}
3333

3434
export default function Congratulations({ app }: Props): JSX.Element {

space-config/worldcoin/proof-of-personhood/components/ProveEligibility.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { styled } from "styled-components";
66
import HoverTooltip from "@/src/ui/HoverTooltip";
77
import { Info } from "phosphor-react";
88
import colors from "@/src/themes/colors";
9-
import { ZkCustomAppConfig } from "@/space-config/types";
9+
import { CustomAppConfig } from "@/space-config/types";
1010

1111
const Container = styled.div``;
1212

@@ -38,7 +38,7 @@ const Bold = styled.span`
3838
`;
3939

4040
type Props = {
41-
app: ZkCustomAppConfig;
41+
app: CustomAppConfig;
4242
onEligible: (response) => void;
4343
};
4444

space-config/worldcoin/proof-of-personhood/components/Section.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const Container = styled.div`
77
border: 1px solid #4F5B7E;
88
border-radius: 4px;
99
padding: 16px;
10+
position: relative;
1011
`
1112

1213

space-config/worldcoin/proof-of-personhood/index.tsx

+51-49
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,12 @@ import Congratulations from "./components/Congratulations";
66
import Section from "./components/Section";
77
import ProveEligibility from "./components/ProveEligibility";
88
import Button from "@/src/ui/Button";
9-
import { ZkCustomAppConfig } from "@/space-config/types";
9+
import { CustomAppConfig } from "@/space-config/types";
1010
import Button3D from "@/src/ui/Button3D";
1111
import { useRouter } from "next/navigation";
1212
import { worldcoinConfigMain } from "../main";
1313
import { CredentialType, IDKitWidget } from "@worldcoin/idkit";
14-
import { ZkCustomAppContainer } from "@/src/components/ZkCustomAppContainer";
15-
16-
const Title = styled.div`
17-
margin-bottom: 16px;
18-
font-family: ${props => props.theme.fonts.semibold};
19-
color: ${props => props.theme.colors.neutral1};
20-
font-size: 32px;
21-
`
22-
23-
const Description = styled.div`
24-
margin-bottom: 32px;
25-
font-family: ${props => props.theme.fonts.regular};
26-
color: ${props => props.theme.colors.neutral3};
27-
font-size: 16px;
28-
`
14+
import { CustomAppContainer } from "@/src/components/CustomAppContainer";
2915

3016
const AlreadyRegistered = styled.div`
3117
color: ${props => props.theme.colors.neutral1};
@@ -40,10 +26,6 @@ const AlreadyRegistered = styled.div`
4026
border-radius: 4px;
4127
`
4228

43-
const Content = styled.div`
44-
max-width: 580px;
45-
`
46-
4729
const Bottom = styled.div`
4830
width: 100%;
4931
display: flex;
@@ -55,25 +37,35 @@ const Bottom = styled.div`
5537
const ErrorMsg = styled.div`
5638
color: ${props => props.theme.colors.error};
5739
font-family: ${props => props.theme.fonts.regular};
40+
position: absolute;
41+
bottom: -35px;
42+
left: 0px;
43+
`
44+
45+
const Verifications = styled.div`
46+
display: flex;
47+
gap: 10px;
48+
align-items: center;
49+
margin-top: 24px;
5850
`
5951

6052
export default function WorldcoinProofOfPersonhoodCustomApp(): JSX.Element {
6153
const router = useRouter();
62-
const app = worldcoinConfigMain.apps[0] as ZkCustomAppConfig;
63-
const api = app.templateConfig.extraData.api;
54+
const app = worldcoinConfigMain.apps[0] as CustomAppConfig;
55+
const api = app.templateConfig.api;
6456
const [alreadySubscribed, setAlreadySubscribed] = useState(false);
6557
const [domReady, setDomReady] = React.useState(false);
66-
const [verifying, setVerifying] = useState(false);
6758
const [finished, setFinished] = useState(false);
6859
const [error, setError] = useState(null);
69-
const [loading, setLoading] = useState(false);
7060
const [redirect, setRedirect] = useState(null);
61+
const [verifyingOrb, setVerifyingOrb] = useState(false);
62+
const [verifyingPhone, setVerifyingPhone] = useState(false);
7163

7264
const [sismoResponse, setSismoResponse] = useState(null);
7365

74-
const onFinish = async (worldcoinResult) => {
75-
setVerifying(true);
76-
setLoading(true);
66+
const onFinish = async (worldcoinResult, type: "orb" | "phone") => {
67+
if (type === "orb") setVerifyingOrb(true);
68+
if (type === "phone") setVerifyingPhone(true);
7769
const body = JSON.stringify({
7870
result: worldcoinResult,
7971
response: sismoResponse
@@ -82,21 +74,20 @@ export default function WorldcoinProofOfPersonhoodCustomApp(): JSX.Element {
8274
method: "POST",
8375
body
8476
});
85-
setVerifying(false);
86-
if (!res.ok) {
87-
throw new Error("Error while verifying Worldcoin proof");
88-
}
77+
setVerifyingOrb(false);
78+
setVerifyingPhone(false);
8979
const data = await res.json();
80+
9081
if (data.success) {
9182
setFinished(true);
9283
}
9384

9485
switch (data.code) {
9586
case "sismo-response-invalid":
96-
setError("Server error [Sismo response invalid]. Please contact us or retry later.");
87+
setError("Server error: Sismo response invalid. Please contact us or retry later.");
9788
break;
9889
case "worldcoin-result-invalid":
99-
setError("Server error [Worldcoin result invalid]. Please contact us or retry later.");
90+
setError("Server error: Worldcoin result invalid. Please contact us or retry later.");
10091
break;
10192
case "worldcoin-proof-already-verified":
10293
setAlreadySubscribed(true);
@@ -132,7 +123,7 @@ export default function WorldcoinProofOfPersonhoodCustomApp(): JSX.Element {
132123

133124
if (!domReady) return;
134125

135-
return <ZkCustomAppContainer>
126+
return <CustomAppContainer>
136127
{
137128
!finished && <>
138129
<Section number={1} isOpen={!sismoResponse} title="Sign in with Sismo" style={{marginBottom: 16}} success={Boolean(sismoResponse)}>
@@ -145,28 +136,39 @@ export default function WorldcoinProofOfPersonhoodCustomApp(): JSX.Element {
145136
You already registered.
146137
</AlreadyRegistered>
147138
:
148-
<>
139+
<Verifications>
149140
<IDKitWidget
150141
app_id="app_staging_9aa79aedb09dc9224e0b85c36133278b"
151-
action="proof-of-personhood"
142+
action="proof-of-personhood-orb"
152143
signal="main"
153-
credential_types={[CredentialType.Phone, CredentialType.Orb]}
154-
onSuccess={(result) => onFinish(result)}
144+
credential_types={[CredentialType.Orb]}
145+
onSuccess={(result) => onFinish(result, "orb")}
155146
>
156-
{({ open }) => <Button onClick={open} loading={verifying || loading} style={{ width: "100%", marginTop: 16}}>
157-
{verifying ? "Verifying..." : "Prove you are unique" }
147+
{({ open }) => <Button onClick={open} loading={verifyingOrb} style={{ width: "100%" }}>
148+
{verifyingOrb ? "Verifying Biometric..." : "Biometric verification" }
158149
</Button>}
159150
</IDKitWidget>
160-
{
161-
error &&
162-
<ErrorMsg>
163-
{error}
164-
</ErrorMsg>
165-
}
166-
</>
151+
{/* <IDKitWidget
152+
app_id="app_staging_9aa79aedb09dc9224e0b85c36133278b"
153+
action="proof-of-personhood-phone"
154+
signal="main"
155+
credential_types={[CredentialType.Phone]}
156+
onSuccess={(result) => onFinish(result, "phone")}
157+
>
158+
{({ open }) => <Button onClick={open} loading={verifyingPhone} style={{ width: "100%" }}>
159+
{verifyingPhone ? "Verifying Biometric..." : "Phone verification" }
160+
</Button>}
161+
</IDKitWidget> */}
162+
</Verifications>
163+
}
164+
{
165+
error &&
166+
<ErrorMsg>
167+
{error}
168+
</ErrorMsg>
167169
}
168170
</Section>
169-
{Boolean(sismoResponse) &&
171+
{alreadySubscribed &&
170172
<Bottom>
171173
<Button3D onClick={() => redirect ? window.location.href : router.push(`/${worldcoinConfigMain.metadata.slug}`)} secondary>
172174
{ redirect ? "Back to the Vault App" : "Back to the space" }
@@ -178,5 +180,5 @@ export default function WorldcoinProofOfPersonhoodCustomApp(): JSX.Element {
178180
{
179181
finished && <Congratulations app={app}/>
180182
}
181-
</ZkCustomAppContainer>;
183+
</CustomAppContainer>;
182184
}

space-config/zk-custom-apps.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import SynapsProofOfLivenessCustomApp from "./synaps/proof-of-liveness"
44
import WorldcoinProofOfPersonhoodCustomApp from "./worldcoin/proof-of-personhood"
55

66

7-
export const zkCustomApps = {
7+
export const customApps = {
88
"worldcoin": {
99
"proof-of-personhood": <WorldcoinProofOfPersonhoodCustomApp />,
1010
},

0 commit comments

Comments
 (0)