Skip to content

Commit

Permalink
Merge pull request #11 from passportxyz/stamp-metadata
Browse files Browse the repository at this point in the history
feat(embed): retrieve stamps via metadata endpoint
  • Loading branch information
larisa17 authored Feb 5, 2025
2 parents e5184e6 + 8c3d63e commit 8fd806e
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 202 deletions.
10 changes: 4 additions & 6 deletions example/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@ const appQueryClient = new QueryClient({
const passportEmbedParams = {
apiKey: import.meta.env.VITE_API_KEY,
scorerId: import.meta.env.VITE_SCORER_ID,
overrideIamUrl: "https://embed.review.passport.xyz",
challengeSignatureUrl: "https://iam.review.passport.xyz/api/v0.0.0/challenge",
// challengeSignatureUrl: "http://localhost:8003/api/v0.0.0/challenge",
// oAuthPopUpUrl: "http://localhost:3010",
oAuthPopUpUrl:
"http://passport-embed-popup-review.s3-website-us-west-2.amazonaws.com",
// overrideIamUrl: "https://embed.review.passport.xyz",
overrideIamUrl: "http://localhost:8004",
// challengeSignatureUrl: "https://iam.review.passport.xyz/api/v0.0.0/challenge",
challengeSignatureUrl: "http://localhost:8003/api/v0.0.0/challenge",
};

const connectWallet = async () => {
Expand Down
1 change: 1 addition & 0 deletions example/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@
dependencies:
"@tanstack/react-query" "^5.62.11"
axios "^1.7.7"
buffer "^6.0.3"

"@rollup/[email protected]":
version "4.24.0"
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
},
"dependencies": {
"@tanstack/react-query": "^5.62.11",
"axios": "^1.7.7"
"axios": "^1.7.7",
"buffer": "^6.0.3"
}
}
}
11 changes: 5 additions & 6 deletions src/components/Body/PlatformVerification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import utilStyles from "../../utilStyles.module.css";
import { useEffect, useState } from "react";
import { Buffer } from "buffer";
import { Button } from "../Button";
import { Hyperlink, Platform, usePlatformStatus } from "./ScoreTooLowBody";
import { Hyperlink, usePlatformStatus } from "./ScoreTooLowBody";
import { Platform } from "../../hooks/useStampPages";
import { ScrollableDiv } from "../ScrollableDiv";
import {
useWidgetIsQuerying,
Expand All @@ -14,8 +15,6 @@ import { useQueryContext } from "../../contexts/QueryContext";
const DEFAULT_CHALLENGE_URL =
"https://iam.review.passport.xyz/api/v0.0.0/challenge";

const DEFAULT_OAUTH_POPUP = "https://embed-popup.passport.xyz";

const CloseIcon = () => (
<svg
width="12"
Expand Down Expand Up @@ -116,7 +115,7 @@ export const PlatformVerification = ({
and come back after.
</div>
) : (
platform.description
<div dangerouslySetInnerHTML={{ __html: platform.description}} />
)}
</ScrollableDiv>
<Button
Expand Down Expand Up @@ -158,10 +157,10 @@ export const PlatformVerification = ({
signature = await generateSignatureCallback(challengeToSign);
}

if (platform.oAuthPopup) {
if (platform.requiresPopup && platform.popUpUrl) {
// open the popup
const oAuthPopUpUrl = `${
queryProps.oAuthPopUpUrl || DEFAULT_OAUTH_POPUP
platform.popUpUrl
}?address=${encodeURIComponent(
queryProps.address || ""
)}&platform=${encodeURIComponent(
Expand Down
201 changes: 19 additions & 182 deletions src/components/Body/ScoreTooLowBody.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,22 @@
import { QueryClient } from "@tanstack/react-query";
import styles from "./Body.module.css";
import utilStyles from "../../utilStyles.module.css";
import { Button } from "../Button";
import { useEffect, useMemo, useState } from "react";
import { useHeaderControls } from "../../contexts/HeaderContext";
import { useWidgetPassportScore } from "../../hooks/usePassportScore";
import { usePaginatedStampPages, Platform } from "../../hooks/useStampPages";
import { TextButton } from "../TextButton";
import { displayNumber } from "../../utils";
import { RightArrow } from "../../assets/rightArrow";
import { ScrollableDiv } from "../ScrollableDiv";
import { PlatformVerification } from "./PlatformVerification";

// TODO should probably load this data from an API endpoint, so that
// if we need to add/change/remove stamps, integrators don't need to
// update the package and re-release their apps
// Also at least weights could be scorer-specific
import { useQueryContext } from "../../contexts/QueryContext";

type Credential = {
id: string;
weight: string;
};

export type Platform = {
name: string;
description: JSX.Element;
documentationLink: string;
credentials: Credential[];
displayWeight: string; // calculated
requireSignature?: boolean;
oAuthPopup?: boolean;
};

type StampPage = {
header: string;
platforms: Platform[];
Expand All @@ -56,151 +43,6 @@ export const Hyperlink = ({

const VISIT_PASSPORT_HEADER = "More Options";

const STAMP_PAGES: StampPage[] = [
{
header: "KYC verification",
platforms: [
{
name: "Binance",
description: (
<div>
If you do not have the Binance Account Bound Token (BABT), obtain it{" "}
<a
href="http://google.com"
style={{
color: "inherit",
fontWeight: "700",
textDecoration: "none",
}}
rel="noopener noreferrer"
target="_blank"
>
here
</a>{" "}
 by verifying your identity and logging into your Binance account.
Then return here and click Verify to claim this Stamp.
</div>
),
documentationLink: "https://google.com",
credentials: [
{
// id: "BinanceBABT2",
id: "NFT",
weight: "16",
},
],
},
{
name: "Holonym",
description: <div>TODO</div>,
documentationLink: "https://google.com",
credentials: [
{
id: "HolonymGovIdProvider",
weight: "16",
},
],
},
],
},
{
header: "Biometrics verification",
platforms: [
{
name: "Civic",
description: <div>TODO</div>,
documentationLink: "https://google.com",
credentials: [
{
id: "CivicCaptchaPass",
weight: "1",
},
{
id: "CivicUniquenessPass",
weight: "2",
},
{
id: "CivicLivenessPass",
weight: "3",
},
],
},
],
},
{
header: "Social & Professional Platforms",
platforms: [
{
name: "LinkedIn",
description: <div>Claim Linkedin stamp</div>,
documentationLink: "https://google.com",
requireSignature: true,
oAuthPopup: true,
credentials: [
{
id: "LinkedIn",
weight: "1",
},
],
},
{
name: "Discord",
description: <div>Coming soon</div>,
documentationLink: "https://google.com",
requireSignature: true,
oAuthPopup: true,
credentials: [
{
id: "Discord",
weight: "1",
},
],
},
// {
// name: "Github",
// description: <div>Coming soon</div>,
// documentationLink: "https://google.com",
// requireSignature: true,
// oAuthPopup: true,
// credentials: [
// {
// id: "Github",
// weight: "1",
// },
// ],
// },
{
name: "Google",
description: <div>Coming soon</div>,
documentationLink: "https://google.com",
requireSignature: true,
oAuthPopup: true,
credentials: [
{
id: "Google",
weight: "1",
},
],
},
],
},
{
header: VISIT_PASSPORT_HEADER,
platforms: [],
},
].map((page) => ({
...page,
platforms: page.platforms.map((platform) => ({
...platform,
displayWeight: displayNumber(
platform.credentials.reduce(
(acc, credential) => acc + parseFloat(credential.weight),
0
)
),
})),
}));

export const ScoreTooLowBody = ({
generateSignatureCallback,
}: {
Expand All @@ -215,20 +57,6 @@ export const ScoreTooLowBody = ({
);
};

const usePages = <T,>(pages: T[]) => {
const [idx, setIdx] = useState(0);

const nextPage = () => setIdx((prev) => Math.min(prev + 1, pages.length - 1));
const prevPage = () => setIdx((prev) => Math.max(prev - 1, 0));

const isFirstPage = idx === 0;
const isLastPage = idx === pages.length - 1;

const page = pages[idx];

return { page, nextPage, prevPage, isFirstPage, isLastPage };
};

const ClaimedIcon = () => (
<svg
width="16"
Expand Down Expand Up @@ -300,19 +128,28 @@ const AddStamps = ({
generateSignatureCallback: (message: string) => Promise<string | undefined>;
}) => {
const { setSubtitle } = useHeaderControls();
const { page, nextPage, prevPage, isFirstPage, isLastPage } =
usePages(STAMP_PAGES);

const queryProps = useQueryContext();
const { scorerId, apiKey, queryClient, overrideIamUrl } = queryProps;
const { page, nextPage, prevPage, isFirstPage, isLastPage, loading, error } =
usePaginatedStampPages({
apiKey: apiKey,
scorerId: scorerId,
overrideIamUrl: overrideIamUrl,
queryClient: queryClient,
});
const [openPlatform, setOpenPlatform] = useState<Platform | null>(null);

const { header, platforms } = page;

useEffect(() => {
setSubtitle("VERIFY STAMPS");
});
}, [setSubtitle]);

if (loading) return <div>Loading Stamps Metadata...</div>;
if (error) return <div>{error}</div>;
if (!page) return <div>No stamp metadata available</div>;

const { header, platforms } = page;

if (openPlatform) {
console.log("LARISA HELLO openPlatform", openPlatform);
return (
<PlatformVerification
platform={openPlatform}
Expand Down
4 changes: 0 additions & 4 deletions src/contexts/QueryContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ type QueryContextValue = Pick<
| "scorerId"
| "overrideIamUrl"
| "challengeSignatureUrl"
| "oAuthPopUpUrl"
> & {
queryClient: QueryClient; // This makes queryClient required
};
Expand All @@ -28,7 +27,6 @@ export const QueryContextProvider = ({
scorerId,
overrideIamUrl,
challengeSignatureUrl,
oAuthPopUpUrl,
queryClient,
}: {
children: React.ReactNode;
Expand All @@ -40,7 +38,6 @@ export const QueryContextProvider = ({
scorerId,
overrideIamUrl,
challengeSignatureUrl,
oAuthPopUpUrl,
// Use override if passed in, otherwise use the widget query client
queryClient: queryClient || widgetQueryClient,
}),
Expand All @@ -50,7 +47,6 @@ export const QueryContextProvider = ({
scorerId,
overrideIamUrl,
challengeSignatureUrl,
oAuthPopUpUrl,
queryClient,
]
);
Expand Down
3 changes: 1 addition & 2 deletions src/hooks/usePassportScore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import axios from "axios";
import { useQueryContext } from "../contexts/QueryContext";
import { useCallback } from "react";

const DEFAULT_IAM_URL = "https://embed.passport.xyz";
export const DEFAULT_IAM_URL = "https://embed.passport.xyz";

export type PassportEmbedProps = {
apiKey: string;
Expand All @@ -21,7 +21,6 @@ export type PassportEmbedProps = {
address?: string;
overrideIamUrl?: string;
challengeSignatureUrl?: string;
oAuthPopUpUrl?: string;
// Optional, allows you to share a queryClient between the
// widget(s) and the wider app
queryClient?: QueryClient;
Expand Down
Loading

0 comments on commit 8fd806e

Please sign in to comment.