├── platforms ├── src │ ├── ETH │ │ ├── Shared.ts │ │ ├── index.ts │ │ └── App-Bindings.ts │ ├── Ens │ │ ├── Shared.ts │ │ ├── Providers │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── Providers-config.ts │ │ └── App-Bindings.ts │ ├── Lens │ │ ├── Shared.ts │ │ ├── index.ts │ │ ├── Providers-config.ts │ │ └── App-Bindings.ts │ ├── POAP │ │ ├── Shared.ts │ │ ├── index.ts │ │ ├── App-Bindings.ts │ │ └── Providers-config.ts │ ├── Brightid │ │ ├── Shared.ts │ │ ├── index.ts │ │ └── Providers-config.ts │ ├── Civic │ │ ├── Shared.ts │ │ ├── index.ts │ │ └── Providers │ │ │ └── types.ts │ ├── Coinbase │ │ ├── Shared.ts │ │ ├── index.ts │ │ └── Providers-config.ts │ ├── Twitter │ │ ├── Shared.ts │ │ ├── index.ts │ │ ├── Providers-config.ts │ │ └── App-Bindings.ts │ ├── GnosisSafe │ │ ├── Providers │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── Providers-config.ts │ │ └── App-Bindings.ts │ ├── TrustaLabs │ │ ├── Providers │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── Providers-config.ts │ │ └── App-Bindings.tsx │ ├── Holonym │ │ ├── Providers │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── Providers-config.ts │ │ └── App-Bindings.tsx │ ├── Snapshot │ │ ├── Providers │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── App-Bindings.ts │ │ └── Providers-config.ts │ ├── Gitcoin │ │ ├── Providers │ │ │ ├── index.ts │ │ │ ├── gitcoinGrantsContributorStatistics.ts │ │ │ └── __tests__ │ │ │ │ └── gitcoinGrantsContributorStatistics.test.ts │ │ └── index.ts │ ├── Github │ │ ├── index.ts │ │ ├── App-Bindings.ts │ │ └── Providers-config.ts │ ├── ClearText │ │ └── index.ts │ ├── NFT │ │ ├── index.ts │ │ ├── Providers │ │ │ └── index.ts │ │ └── App-Bindings.ts │ ├── Outdid │ │ ├── index.ts │ │ ├── procedures │ │ │ └── outdidVerification.ts │ │ └── Providers-config.ts │ ├── Discord │ │ ├── index.ts │ │ ├── Providers-config.ts │ │ └── App-Bindings.ts │ ├── Google │ │ ├── index.js │ │ ├── Providers-config.ts │ │ └── App-Bindings.ts │ ├── Linkedin │ │ ├── index.ts │ │ ├── Providers-config.ts │ │ └── App-Bindings.ts │ ├── ZkSync │ │ ├── index.ts │ │ └── App-Bindings.ts │ ├── GuildXYZ │ │ ├── index.ts │ │ ├── App-Bindings.ts │ │ └── Providers-config.ts │ ├── GtcStaking │ │ ├── Providers │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── __tests__ │ │ │ └── gtcStaking.test.ts │ │ └── App-Bindings.tsx │ ├── Idena │ │ ├── index.ts │ │ ├── README.md │ │ ├── Providers-config.ts │ │ └── App-Bindings.ts │ └── utils │ │ ├── handleProviderAxiosError.ts │ │ ├── errors.ts │ │ ├── __tests__ │ │ └── passport-cache.test.ts │ │ ├── simpleEvmProvider.ts │ │ ├── clearTextSimpleProvider.ts │ │ ├── handleAxiosError.ts │ │ └── simpleProvider.ts ├── .prettierrc.js ├── .prettierignore ├── .eslintignore ├── jest.config.js ├── jest.config.cjs ├── .gitignore ├── testSetup.js ├── tsconfig.json └── package.json ├── app ├── public │ ├── assets │ │ ├── arb-logo.svg │ │ ├── pgn-logo.svg │ │ ├── pgn-logo.png │ │ ├── welcome.png │ │ ├── linea-logo.png │ │ ├── onboarding.webm │ │ ├── backgroundRock.png │ │ ├── optimism_logo.png │ │ ├── welcome-back.png │ │ ├── splashPageLogo.webm │ │ ├── splashPageTexture.png │ │ ├── welcome-get-started.png │ │ ├── dashboardIllustration.png │ │ ├── welcome-passport-scoring.png │ │ ├── logoLine.svg │ │ ├── plus-icon.svg │ │ ├── x-mark-icon.svg │ │ ├── arrow-left-icon.svg │ │ ├── arrow-right-icon.svg │ │ ├── clock-icon.svg │ │ ├── ethLogo.svg │ │ ├── goerli-base-logo.svg │ │ ├── information-circle-icon.svg │ │ ├── ethStampIcon.svg │ │ ├── linkedinStampIcon.svg │ │ ├── check-icon.svg │ │ ├── check-icon-grey.svg │ │ ├── purple-check-icon.svg │ │ ├── white-check-icon.svg │ │ ├── shield-exclamation-icon.svg │ │ ├── shield-exclamation-icon-warning.svg │ │ ├── x-icon.svg │ │ ├── x-icon-black.svg │ │ ├── civicStampIcon.svg │ │ ├── verification-failed-bright.svg │ │ ├── verifiedShield.svg │ │ ├── brightidStampIcon.svg │ │ ├── gtcStakingLogoIcon.svg │ │ ├── shield-alert.svg │ │ ├── trustaLabsStampIcon.svg │ │ ├── personIcon.svg │ │ ├── whiteBgShieldExclamation.svg │ │ ├── githubWhiteStampIcon.svg │ │ ├── check-icon2.svg │ │ ├── verification-failed.svg │ │ ├── facebookStampIcon.svg │ │ ├── snapshotStampIcon.svg │ │ ├── twitterStampIcon.svg │ │ ├── coinbaseStampIcon.svg │ │ ├── phiLogoIcon.svg │ │ ├── googleStampIcon.svg │ │ ├── hexagonIcon.svg │ │ └── lockIcon.svg │ └── favicon.ico ├── __mocks__ │ ├── fileMock.js │ ├── @didtools │ │ ├── pkh-ethereum.js │ │ └── cacao.js │ ├── did-session │ │ └── index.js │ ├── @web3-onboard │ │ ├── common.js │ │ └── react.js │ ├── @self.id │ │ ├── web │ │ │ └── index.js │ │ └── framework │ │ │ └── index.js │ ├── broadcast-channel.js │ ├── @gitcoin │ │ ├── passport-identity │ │ │ └── index.js │ │ └── passport-database-client │ │ │ └── index.js │ └── @adraffy │ │ └── ens-normalize.js ├── .prettierignore ├── .prettierrc.js ├── postcss.config.js ├── .eslintignore ├── config │ ├── customization_config.ts │ ├── platforms.ts │ ├── providers.ts │ ├── filters.ts │ ├── feature_flags.ts │ └── stamp_config.ts ├── utils │ ├── onChainStatus.ts │ ├── __mocks__ │ │ └── onboard.ts │ ├── theme │ │ ├── index.tsx │ │ ├── chakra │ │ │ ├── Modal.tsx │ │ │ └── Menu.tsx │ │ ├── palette.tsx │ │ ├── types.tsx │ │ ├── themes.tsx │ │ ├── setCustomizationTheme.tsx │ │ └── setTheme.tsx │ └── onboard.ts ├── .eslintrc ├── next-env.d.ts ├── components │ ├── PageRoot.tsx │ ├── HeaderContentFooterGrid.tsx │ ├── LoadingScreen.tsx │ ├── BodyWrapper.tsx │ ├── OnchainTag.tsx │ ├── LoadButton.tsx │ ├── WebmVideo.tsx │ ├── GenericBanner.tsx │ ├── SupportBanner.tsx │ ├── PageWidthGrid.tsx │ ├── InitiateOnChainButton.tsx │ ├── ProcessingPopup.tsx │ ├── Checkbox.tsx │ ├── MinimalHeader.tsx │ ├── DropDownIcon.tsx │ ├── Toggle.tsx │ ├── Warning.tsx │ ├── LoadingCard.tsx │ ├── SIWEButton.tsx │ ├── Header.tsx │ └── Button.tsx ├── types.ts ├── README.md ├── next.config.js ├── __test-fixtures__ │ ├── toastTestHelpers.tsx │ └── onboardHookValues.ts ├── .gitignore ├── context │ ├── testModeState.tsx │ └── userState.tsx ├── tsconfig.json ├── jest.config.ts ├── jest.setup.ts ├── __tests__ │ ├── utils │ │ └── helpers.test.ts │ ├── components │ │ ├── NetworkCard.test.tsx │ │ └── JsonOutputModal.test.tsx │ └── pages │ │ └── app.test.tsx ├── styles │ └── globals.css └── pages │ └── privacy.tsx ├── iam ├── .prettierignore ├── .prettierrc.cjs ├── .eslintignore ├── __mocks__ │ ├── key-did-resolver │ │ └── index.js │ ├── dids │ │ └── index.js │ └── @gitcoin │ │ └── passport-identity │ │ └── index.js ├── Dockerfile ├── jest.config.cjs ├── .gitignore ├── src │ ├── types.d.ts │ ├── main.ts │ ├── issuers.ts │ ├── scripts │ │ └── buildProviderBitMapInfo.ts │ └── utils │ │ └── scorerService.ts ├── babel.config.json ├── tsconfig.json └── jest.setup.cjs ├── infra ├── aws │ ├── .gitignore │ ├── Pulumi.review.yaml │ ├── Pulumi.staging.yaml │ ├── Pulumi.yaml │ └── tsconfig.json ├── .gitignore ├── package.json └── README.md ├── .dockerignore ├── schemas ├── src │ └── index.ts ├── .env-example.env ├── tsconfig.json ├── .gitignore └── README.md ├── .vscode └── settings.json ├── .husky ├── pre-commit ├── commit-msg └── pre-push ├── commitlint.config.js ├── identity ├── .prettierrc.js ├── .prettierignore ├── src │ └── index.ts ├── .eslintignore ├── jest.config.js ├── README.md ├── .gitignore ├── tsconfig.json ├── package.json └── __mocks__ │ ├── didkit.js │ └── axios.js ├── types ├── .prettierrc.js ├── README.md ├── tsconfig.json ├── package.json └── src │ └── brightid.d.ts ├── funding.json ├── database-client ├── src │ ├── index.ts │ ├── logger.ts │ ├── utils.ts │ └── types.ts ├── jest.integration.config.js ├── jest.config.cjs ├── __tests__ │ └── integration-test-model-aliases.json ├── integration-tests │ ├── integration-test-model-aliases.json │ └── run-ceramic-tests.sh ├── tsconfig.json ├── .gitignore ├── composedb.config.json ├── README.md └── package.json ├── js-ceramic ├── Dockerfile ├── README.md └── ceramic │ └── daemon.config.json ├── tsconfig.json ├── lerna.json ├── .prettierrc.js ├── tsconfig.settings.json ├── .gitignore ├── .github ├── workflows │ ├── add-issue-to-project.yml │ ├── app-cd-review.yml │ ├── signer-cd-review.yml │ ├── app-promote-staging.yml │ ├── app-promote-production.yml │ ├── signer-promote-staging.yml │ ├── signer-promote-production.yml │ ├── deploy_to_branch.yml │ ├── ceramic-promote-staging.yml │ └── ceramic-promote-production.yml ├── ISSUE_TEMPLATE │ ├── _feature-request.md │ └── bug_report.md └── actions │ └── check-provider-bitmaps │ └── action.yml └── docker-compose.yml /platforms/src/ETH/Shared.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /platforms/src/Ens/Shared.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /platforms/src/Lens/Shared.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /platforms/src/POAP/Shared.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/public/assets/arb-logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/public/assets/pgn-logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /platforms/src/Brightid/Shared.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /platforms/src/Civic/Shared.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /platforms/src/Coinbase/Shared.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /platforms/src/Twitter/Shared.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /iam/.prettierignore: -------------------------------------------------------------------------------- 1 | /dist/* 2 | /coverage/* -------------------------------------------------------------------------------- /infra/aws/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | -------------------------------------------------------------------------------- /infra/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /node_modules/ 3 | -------------------------------------------------------------------------------- /app/__mocks__/fileMock.js: -------------------------------------------------------------------------------- 1 | module.exports = "test-file-stub"; 2 | -------------------------------------------------------------------------------- /infra/aws/Pulumi.review.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | aws:region: us-west-2 3 | -------------------------------------------------------------------------------- /infra/aws/Pulumi.staging.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | aws:region: us-west-2 3 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | **/.env 2 | **/node_modules 3 | **/dist 4 | **/.next 5 | *.md 6 | -------------------------------------------------------------------------------- /schemas/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./definitions/ts/gitcoin-passport-stamps"; 2 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib" 3 | } 4 | -------------------------------------------------------------------------------- /iam/.prettierrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require("../.prettierrc.js"), 3 | }; 4 | -------------------------------------------------------------------------------- /platforms/src/Ens/Providers/index.ts: -------------------------------------------------------------------------------- 1 | export { EnsProvider } from "./EnsProvider"; 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn run lint 5 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = {extends: ['@commitlint/config-conventional']}; 2 | -------------------------------------------------------------------------------- /identity/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require("../.prettierrc.js"), 3 | }; 4 | -------------------------------------------------------------------------------- /platforms/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require("../.prettierrc.js"), 3 | }; 4 | -------------------------------------------------------------------------------- /types/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require("../.prettierrc.js"), 3 | }; 4 | -------------------------------------------------------------------------------- /app/.prettierignore: -------------------------------------------------------------------------------- 1 | /dist/* 2 | /build/* 3 | /coverage/* 4 | /.next/* 5 | /out/* 6 | /public/* 7 | -------------------------------------------------------------------------------- /platforms/src/GnosisSafe/Providers/index.ts: -------------------------------------------------------------------------------- 1 | export { GnosisSafeProvider } from "./gnosisSafe"; 2 | -------------------------------------------------------------------------------- /platforms/src/TrustaLabs/Providers/index.ts: -------------------------------------------------------------------------------- 1 | export { TrustaLabsProvider } from "./TrustaLabs"; 2 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn commitlint --edit $1 5 | -------------------------------------------------------------------------------- /app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HowittColet/passport/HEAD/app/public/favicon.ico -------------------------------------------------------------------------------- /app/__mocks__/@didtools/pkh-ethereum.js: -------------------------------------------------------------------------------- 1 | export const EthereumWebAuth = { getAuthMethod: jest.fn() }; 2 | -------------------------------------------------------------------------------- /platforms/src/Holonym/Providers/index.ts: -------------------------------------------------------------------------------- 1 | export { HolonymGovIdProvider } from "./holonymGovIdProvider"; 2 | -------------------------------------------------------------------------------- /app/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ...require("../.prettierrc.js"), 3 | singleQuote: false, 4 | }; 5 | -------------------------------------------------------------------------------- /app/public/assets/pgn-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HowittColet/passport/HEAD/app/public/assets/pgn-logo.png -------------------------------------------------------------------------------- /app/public/assets/welcome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HowittColet/passport/HEAD/app/public/assets/welcome.png -------------------------------------------------------------------------------- /platforms/src/Snapshot/Providers/index.ts: -------------------------------------------------------------------------------- 1 | export { SnapshotProposalsProvider } from "./snapshotProposalsProvider"; 2 | -------------------------------------------------------------------------------- /schemas/.env-example.env: -------------------------------------------------------------------------------- 1 | SEED="YOUR_BASE16_SEED_HERE" 2 | CERAMIC_CLIENT_URL=https://ceramic-clay.3boxlabs.com 3 | -------------------------------------------------------------------------------- /app/__mocks__/@didtools/cacao.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // Mocked implementation of the @didtools/cacao module 3 | }; 4 | -------------------------------------------------------------------------------- /app/public/assets/linea-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HowittColet/passport/HEAD/app/public/assets/linea-logo.png -------------------------------------------------------------------------------- /app/public/assets/onboarding.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HowittColet/passport/HEAD/app/public/assets/onboarding.webm -------------------------------------------------------------------------------- /identity/.prettierignore: -------------------------------------------------------------------------------- 1 | /dist/* 2 | /coverage/* 3 | /node_modules/* 4 | /src/didkit-node/* 5 | /src/didkit-browser/* 6 | -------------------------------------------------------------------------------- /platforms/.prettierignore: -------------------------------------------------------------------------------- 1 | /dist/* 2 | /coverage/* 3 | /node_modules/* 4 | /src/didkit-node/* 5 | /src/didkit-browser/* 6 | -------------------------------------------------------------------------------- /app/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /app/public/assets/backgroundRock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HowittColet/passport/HEAD/app/public/assets/backgroundRock.png -------------------------------------------------------------------------------- /app/public/assets/optimism_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HowittColet/passport/HEAD/app/public/assets/optimism_logo.png -------------------------------------------------------------------------------- /app/public/assets/welcome-back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HowittColet/passport/HEAD/app/public/assets/welcome-back.png -------------------------------------------------------------------------------- /iam/.eslintignore: -------------------------------------------------------------------------------- 1 | /*.js 2 | /*.ts 3 | /dist/* 4 | /coverage/* 5 | /node_modules/* 6 | /__mocks__/**/* 7 | /__tests__/**/* 8 | -------------------------------------------------------------------------------- /app/__mocks__/did-session/index.js: -------------------------------------------------------------------------------- 1 | export class DIDSession { 2 | authorize() { 3 | return "some-session-str"; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /app/public/assets/splashPageLogo.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HowittColet/passport/HEAD/app/public/assets/splashPageLogo.webm -------------------------------------------------------------------------------- /identity/src/index.ts: -------------------------------------------------------------------------------- 1 | // export credential tooling 2 | export * from "./credentials"; 3 | export * from "./signingDocuments"; 4 | -------------------------------------------------------------------------------- /app/public/assets/splashPageTexture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HowittColet/passport/HEAD/app/public/assets/splashPageTexture.png -------------------------------------------------------------------------------- /app/public/assets/welcome-get-started.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HowittColet/passport/HEAD/app/public/assets/welcome-get-started.png -------------------------------------------------------------------------------- /app/.eslintignore: -------------------------------------------------------------------------------- 1 | /*.js 2 | /*.ts 3 | /test/* 4 | /dist/* 5 | /.next/* 6 | /coverage/* 7 | /node_modules/* 8 | /__mocks__/**/*.js 9 | /out/* -------------------------------------------------------------------------------- /app/__mocks__/@web3-onboard/common.js: -------------------------------------------------------------------------------- 1 | const common = jest.createMockFromModule("@web3-onboard/common"); 2 | 3 | module.exports = common; 4 | -------------------------------------------------------------------------------- /app/public/assets/dashboardIllustration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HowittColet/passport/HEAD/app/public/assets/dashboardIllustration.png -------------------------------------------------------------------------------- /funding.json: -------------------------------------------------------------------------------- 1 | { 2 | "opRetro": { 3 | "projectId": "0x120cdd8e43ae1efbafdf02eda876e1952c05a52870c8d5a8f56d9ec0f79f586d" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /app/config/customization_config.ts: -------------------------------------------------------------------------------- 1 | export const CUSTOMIZATION_ENDPOINT = `${process.env.NEXT_PUBLIC_SCORER_ENDPOINT}/account/customization`; 2 | -------------------------------------------------------------------------------- /app/public/assets/welcome-passport-scoring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HowittColet/passport/HEAD/app/public/assets/welcome-passport-scoring.png -------------------------------------------------------------------------------- /app/utils/onChainStatus.ts: -------------------------------------------------------------------------------- 1 | export enum OnChainStatus { 2 | LOADING, 3 | NOT_MOVED, 4 | MOVED_OUT_OF_DATE, 5 | MOVED_UP_TO_DATE, 6 | } 7 | -------------------------------------------------------------------------------- /iam/__mocks__/key-did-resolver/index.js: -------------------------------------------------------------------------------- 1 | const keyDidResolver = { 2 | getResolver: jest.fn(), 3 | }; 4 | 5 | module.exports = keyDidResolver; 6 | -------------------------------------------------------------------------------- /platforms/src/Gitcoin/Providers/index.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | export { GitcoinContributorStatisticsProvider } from "./gitcoinGrantsContributorStatistics"; 3 | -------------------------------------------------------------------------------- /app/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["plugin:testing-library/react", "next", "prettier"], 3 | "rules": { 4 | "@next/next/no-img-element": "off" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /platforms/src/Github/index.ts: -------------------------------------------------------------------------------- 1 | export { GithubPlatform } from "./App-Bindings"; 2 | export { ProviderConfig, PlatformDetails, providers } from "./Providers-config"; 3 | -------------------------------------------------------------------------------- /database-client/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./logger"; 2 | export * from "./passportScorerClient"; 3 | export * from "./composeDatabase"; 4 | export * from "./types"; 5 | -------------------------------------------------------------------------------- /iam/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:20.11 2 | WORKDIR /usr/src 3 | 4 | COPY . . 5 | 6 | RUN yarn 7 | 8 | EXPOSE 80 443 9 | CMD [ "node", "iam/dist/iam/src/main.js" ] 10 | -------------------------------------------------------------------------------- /infra/aws/Pulumi.yaml: -------------------------------------------------------------------------------- 1 | name: passport 2 | runtime: 3 | name: nodejs 4 | options: 5 | typescript: true 6 | description: A minimal AWS JavaScript Pulumi program 7 | -------------------------------------------------------------------------------- /iam/__mocks__/dids/index.js: -------------------------------------------------------------------------------- 1 | const dids = { 2 | DID: jest.fn().mockImplementation(() => ({ 3 | verifyJWS: jest.fn(), 4 | })), 5 | }; 6 | 7 | module.exports = dids; 8 | -------------------------------------------------------------------------------- /app/utils/__mocks__/onboard.ts: -------------------------------------------------------------------------------- 1 | export const RINKEBY_RPC_URL = "https://rinkeby.infura.io/v3/someApiKey"; 2 | export const MAINNET_RPC_URL = "https://rinkeby.infura.io/v3/someApiKey"; 3 | -------------------------------------------------------------------------------- /app/__mocks__/@self.id/web/index.js: -------------------------------------------------------------------------------- 1 | export default class EthereumAuthProvider { 2 | constructor() { 3 | console.log("Mock EthereumAuthProvider: constructor was called"); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /identity/.eslintignore: -------------------------------------------------------------------------------- 1 | /*.js 2 | /*.ts 3 | /dist/* 4 | /coverage/* 5 | /node_modules/* 6 | /src/didkit-node/* 7 | /src/didkit-browser/* 8 | /__mocks__/**/* 9 | /__tests__/**/* 10 | -------------------------------------------------------------------------------- /platforms/.eslintignore: -------------------------------------------------------------------------------- 1 | /*.js 2 | /*.ts 3 | /dist/* 4 | /coverage/* 5 | /node_modules/* 6 | /src/didkit-node/* 7 | /src/didkit-browser/* 8 | /__mocks__/**/* 9 | /__tests__/**/* 10 | -------------------------------------------------------------------------------- /platforms/src/ClearText/index.ts: -------------------------------------------------------------------------------- 1 | export { ClearTextGithubOrgProvider } from "./Providers/clearTextGithubOrg"; 2 | export { ClearTextTwitterProvider } from "./Providers/clearTextTwitter"; 3 | -------------------------------------------------------------------------------- /platforms/src/Twitter/index.ts: -------------------------------------------------------------------------------- 1 | // Twitter Platform 2 | export { TwitterPlatform } from "./App-Bindings"; 3 | export { PlatformDetails, ProviderConfig, providers } from "./Providers-config"; 4 | -------------------------------------------------------------------------------- /iam/jest.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | modulePathIgnorePatterns: ["/dist/"], 3 | setupFiles: ["dotenv/config", "/jest.setup.cjs"], 4 | testEnvironment: "node", 5 | }; 6 | -------------------------------------------------------------------------------- /identity/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testEnvironment: "node", 3 | transform: { 4 | "^.+\\.tsx?$": "ts-jest", 5 | }, 6 | modulePathIgnorePatterns: ["/dist/"], 7 | }; 8 | -------------------------------------------------------------------------------- /database-client/jest.integration.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | transform: {}, 3 | testMatch: ["**/integration-tests/**/*.js"], 4 | extensionsToTreatAsEsm: [".ts"], 5 | testTimeout: 10000, 6 | }; 7 | -------------------------------------------------------------------------------- /platforms/src/NFT/index.ts: -------------------------------------------------------------------------------- 1 | export { NFTPlatform } from "./App-Bindings"; 2 | export { NFTProvider } from "./Providers"; 3 | export { PlatformDetails, ProviderConfig, providers } from "./Providers-config"; 4 | -------------------------------------------------------------------------------- /app/public/assets/logoLine.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /platforms/src/NFT/Providers/index.ts: -------------------------------------------------------------------------------- 1 | export { NFTProvider } from "./nft"; 2 | export { DigitalCollectorProvider, ArtAficionadoProvider, NftVisionaryProvider, NftCollectorBaseProvider } from "./collectors_journey"; 3 | -------------------------------------------------------------------------------- /platforms/src/POAP/index.ts: -------------------------------------------------------------------------------- 1 | export { POAPPlatform } from "./App-Bindings"; 2 | export { PlatformDetails, ProviderConfig, providers } from "./Providers-config"; 3 | export { POAPProvider } from "./Providers/poap"; 4 | -------------------------------------------------------------------------------- /platforms/src/Ens/index.ts: -------------------------------------------------------------------------------- 1 | export { EnsPlatform } from "./App-Bindings"; 2 | export { PlatformDetails, ProviderConfig, providers } from "./Providers-config"; 3 | export { EnsProvider } from "./Providers/EnsProvider"; 4 | -------------------------------------------------------------------------------- /platforms/src/Lens/index.ts: -------------------------------------------------------------------------------- 1 | export { LensPlatform } from "./App-Bindings"; 2 | export { PlatformDetails, ProviderConfig, providers } from "./Providers-config"; 3 | export { LensProfileProvider } from "./Providers/lens"; 4 | -------------------------------------------------------------------------------- /platforms/src/Outdid/index.ts: -------------------------------------------------------------------------------- 1 | export { OutdidPlatform } from "./App-Bindings"; 2 | export { ProviderConfig, PlatformDetails, providers } from "./Providers-config"; 3 | export { OutdidProvider } from "./Providers/outdid"; -------------------------------------------------------------------------------- /js-ceramic/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ceramicnetwork/js-ceramic:3.2.0 2 | 3 | COPY ceramic/daemon.config.json /ceramic/daemon.config.json 4 | 5 | RUN mkdir /ceramic/statestore 6 | 7 | CMD ["--config", "/ceramic/daemon.config.json"] 8 | -------------------------------------------------------------------------------- /platforms/src/Civic/index.ts: -------------------------------------------------------------------------------- 1 | export { CivicPlatform } from "./App-Bindings"; 2 | export { PlatformDetails, ProviderConfig, providers } from "./Providers-config"; 3 | export { CivicPassProvider } from "./Providers/civic"; 4 | -------------------------------------------------------------------------------- /platforms/src/Discord/index.ts: -------------------------------------------------------------------------------- 1 | export { DiscordPlatform } from "./App-Bindings"; 2 | export { ProviderConfig, PlatformDetails, providers } from "./Providers-config"; 3 | export { DiscordProvider } from "./Providers/discord"; 4 | -------------------------------------------------------------------------------- /platforms/src/Google/index.js: -------------------------------------------------------------------------------- 1 | export { GooglePlatform } from "./App-Bindings"; 2 | export { ProviderConfig, PlatformDetails, providers } from "./Providers-config"; 3 | export { GoogleProvider } from "./Providers/google"; 4 | -------------------------------------------------------------------------------- /platforms/src/Brightid/index.ts: -------------------------------------------------------------------------------- 1 | export { BrightidPlatform } from "./App-Bindings"; 2 | export { PlatformDetails, ProviderConfig, providers } from "./Providers-config"; 3 | export { BrightIdProvider } from "./Providers/brightid"; 4 | -------------------------------------------------------------------------------- /platforms/src/Coinbase/index.ts: -------------------------------------------------------------------------------- 1 | export { CoinbasePlatform } from "./App-Bindings"; 2 | export { ProviderConfig, PlatformDetails, providers } from "./Providers-config"; 3 | export { CoinbaseProvider } from "./Providers/coinbase"; 4 | -------------------------------------------------------------------------------- /platforms/src/GnosisSafe/index.ts: -------------------------------------------------------------------------------- 1 | export { GnosisSafePlatform } from "./App-Bindings"; 2 | export { GnosisSafeProvider } from "./Providers"; 3 | export { PlatformDetails, ProviderConfig, providers } from "./Providers-config"; 4 | -------------------------------------------------------------------------------- /platforms/src/Linkedin/index.ts: -------------------------------------------------------------------------------- 1 | export { LinkedinProvider } from "./Providers/linkedin"; 2 | export { PlatformDetails, ProviderConfig, providers } from "./Providers-config"; 3 | export { LinkedinPlatform } from "./App-Bindings"; 4 | -------------------------------------------------------------------------------- /platforms/src/Snapshot/index.ts: -------------------------------------------------------------------------------- 1 | export { SnapshotPlatform } from "./App-Bindings"; 2 | export { PlatformDetails, ProviderConfig, providers } from "./Providers-config"; 3 | export { SnapshotProposalsProvider } from "./Providers"; 4 | -------------------------------------------------------------------------------- /app/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /platforms/src/ZkSync/index.ts: -------------------------------------------------------------------------------- 1 | export { ZkSyncEraProvider } from "./Providers/zkSyncEra"; 2 | 3 | export { PlatformDetails, ProviderConfig, providers } from "./Providers-config"; 4 | export { ZkSyncPlatform } from "./App-Bindings"; 5 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "app" }, 5 | { "path": "iam" }, 6 | { "path": "identity" }, 7 | { "path": "types" } 8 | ], 9 | "exclude": ["node_modules"] 10 | } 11 | -------------------------------------------------------------------------------- /platforms/src/Gitcoin/index.ts: -------------------------------------------------------------------------------- 1 | export { GitcoinPlatform } from "./App-Bindings"; 2 | export { ProviderConfig, PlatformDetails, providers } from "./Providers-config"; 3 | export { GitcoinContributorStatisticsProvider } from "./Providers"; 4 | -------------------------------------------------------------------------------- /platforms/src/TrustaLabs/index.ts: -------------------------------------------------------------------------------- 1 | export { TrustaLabsPlatform } from "./App-Bindings"; 2 | export { ProviderConfig, PlatformDetails, providers } from "./Providers-config"; 3 | export { TrustaLabsProvider } from "./Providers/TrustaLabs"; 4 | -------------------------------------------------------------------------------- /platforms/src/Holonym/index.ts: -------------------------------------------------------------------------------- 1 | export { HolonymPlatform } from "./App-Bindings"; 2 | export { PlatformDetails, ProviderConfig, providers } from "./Providers-config"; 3 | export { HolonymGovIdProvider } from "./Providers/holonymGovIdProvider"; 4 | -------------------------------------------------------------------------------- /.husky/pre-push: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn run test 5 | # yarn run test:ceramic-integration 6 | # disabled integration test May 30 2023 7 | # it was causing too many errors and is 8 | # addressed during build anyway <3MSG -------------------------------------------------------------------------------- /platforms/src/ETH/index.ts: -------------------------------------------------------------------------------- 1 | export { ETHPlatform } from "./App-Bindings"; 2 | export { PlatformDetails, ProviderConfig, providers } from "./Providers-config"; 3 | export { ETHAdvocateProvider, ETHMaxiProvider } from "./Providers/accountAnalysis"; 4 | -------------------------------------------------------------------------------- /app/public/assets/plus-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /platforms/src/GuildXYZ/index.ts: -------------------------------------------------------------------------------- 1 | export { GuildXYZPlatform } from "./App-Bindings"; 2 | export { PlatformDetails, ProviderConfig, providers } from "./Providers-config"; 3 | export { GuildAdminProvider, GuildPassportMemberProvider } from "./Providers/guildXYZ"; 4 | -------------------------------------------------------------------------------- /app/public/assets/x-mark-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /platforms/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testEnvironment: "node", 3 | transform: { 4 | "^.+\\.tsx?$": "ts-jest", 5 | }, 6 | modulePathIgnorePatterns: ["/dist/"], 7 | setupFiles: ["dotenv/config", "../platforms/testSetup.js"], 8 | }; 9 | -------------------------------------------------------------------------------- /app/utils/theme/index.tsx: -------------------------------------------------------------------------------- 1 | export { default as ThemeWrapper } from "./themeWrapper"; 2 | export { default as palette } from "./palette"; 3 | export * as themes from "./themes"; 4 | export { default as setTheme } from "./setTheme"; 5 | export type { Theme } from "./types"; 6 | -------------------------------------------------------------------------------- /app/components/PageRoot.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const PageRoot = ({ children, className }: { children: React.ReactNode; className?: string }) => ( 4 |
{children}
5 | ); 6 | 7 | export default PageRoot; 8 | -------------------------------------------------------------------------------- /app/public/assets/arrow-left-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/public/assets/arrow-right-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /types/README.md: -------------------------------------------------------------------------------- 1 | # @gitcoin/passport-types 2 | 3 | Shared types for the Gitcoin Passport repo. 4 | 5 | Instructions: 6 | 7 | - Ensure @gitcoin/passport-types is included as a package dependency 8 | - Import like so: `import { VerifiableCredential } from "@gitcoin/passport-types"` 9 | -------------------------------------------------------------------------------- /platforms/jest.config.cjs: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ 2 | 3 | module.exports = { 4 | // [...] 5 | preset: "ts-jest", 6 | extensionsToTreatAsEsm: [".ts"], 7 | globals: { 8 | "ts-jest": { 9 | useESM: true, 10 | }, 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /app/public/assets/clock-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/public/assets/ethLogo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /platforms/src/GtcStaking/Providers/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | BeginnerCommunityStakerProvider, 3 | ExperiencedCommunityStakerProvider, 4 | TrustedCitizenProvider, 5 | } from "./communityStaking"; 6 | export { SelfStakingBronzeProvider, SelfStakingGoldProvider, SelfStakingSilverProvider } from "./selfStaking"; 7 | -------------------------------------------------------------------------------- /app/components/HeaderContentFooterGrid.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const HeaderContentFooterGrid = ({ children }: { children: React.ReactNode }) => ( 4 |
{children}
5 | ); 6 | 7 | export default HeaderContentFooterGrid; 8 | -------------------------------------------------------------------------------- /identity/README.md: -------------------------------------------------------------------------------- 1 | # @gitcoin/passport-identity 2 | 3 | Shared identity management tools for the Gitcoin Passport repo. 4 | 5 | Instructions: 6 | 7 | - Ensure @gitcoin/passport-identity is included as a package dependency 8 | - Import like so: `import { issueHashedCredential, verifyCredential } from "@gitcoin/passport-identity"` 9 | -------------------------------------------------------------------------------- /app/types.ts: -------------------------------------------------------------------------------- 1 | import { Passport, Stamp, DID } from "@gitcoin/passport-types"; 2 | 3 | // Class used as a base for each DataStorage Type 4 | export abstract class DataStorageBase { 5 | abstract createPassport(): DID; 6 | abstract getPassport(did: DID): Passport | undefined; 7 | abstract addStamp(did: DID, stamp: Stamp): void; 8 | } 9 | -------------------------------------------------------------------------------- /database-client/src/logger.ts: -------------------------------------------------------------------------------- 1 | export type Logger = { 2 | error: (msg: string, context?: object) => void; 3 | log: (msg: string, context?: object) => void; 4 | warn: (msg: string, context?: object) => void; 5 | debug: (msg: string, context?: object) => void; 6 | info: (msg: string, context?: object) => void; 7 | }; 8 | 9 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "app", 4 | "database-client", 5 | "iam", 6 | "identity", 7 | "schemas", 8 | "types", 9 | "platforms" 10 | ], 11 | "npmClient": "yarn", 12 | "version": "independent", 13 | "useWorkspaces": true, 14 | "stream": true, 15 | "changelogPreset": "angular" 16 | } 17 | -------------------------------------------------------------------------------- /database-client/jest.config.cjs: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ 2 | 3 | module.exports = { 4 | transform: { 5 | "^.+\\.tsx?$": [ 6 | "ts-jest", 7 | { 8 | useESM: true, 9 | }, 10 | ], 11 | }, 12 | preset: "ts-jest", 13 | extensionsToTreatAsEsm: [".ts"], 14 | }; 15 | -------------------------------------------------------------------------------- /platforms/src/Idena/index.ts: -------------------------------------------------------------------------------- 1 | // Idena Platform 2 | export { IdenaPlatform } from "./App-Bindings"; 3 | export { 4 | IdenaStateNewbieProvider, 5 | IdenaStateVerifiedProvider, 6 | IdenaStateHumanProvider, 7 | } from "./Providers/IdenaStateProvider"; 8 | 9 | export { PlatformDetails, ProviderConfig, providers } from "./Providers-config"; 10 | -------------------------------------------------------------------------------- /app/__mocks__/broadcast-channel.js: -------------------------------------------------------------------------------- 1 | const constructor = jest.fn(); 2 | const postMessage = jest.fn(); 3 | const close = jest.fn(); 4 | 5 | export class BroadcastChannel { 6 | constructor() { 7 | return constructor(); 8 | } 9 | postMessage() { 10 | return postMessage(); 11 | } 12 | close() { 13 | return close(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | overrides: [ 3 | { 4 | files: ["**/*.js", "**/*.ts", "**/*.tsx"], 5 | options: { 6 | bracketSpacing: true, 7 | trailingComma: "es5", 8 | tabWidth: 2, 9 | printWidth: 120, 10 | singleQuote: false, 11 | semi: true, 12 | }, 13 | }, 14 | ], 15 | }; 16 | -------------------------------------------------------------------------------- /app/config/platforms.ts: -------------------------------------------------------------------------------- 1 | import { PlatformSpec, platforms } from "@gitcoin/passport-platforms"; 2 | 3 | export const getPlatformSpec = (platformName: string): PlatformSpec | undefined => { 4 | return platforms[platformName]?.PlatformDetails; 5 | }; 6 | 7 | export const PLATFORMS: PlatformSpec[] = Object.values(platforms).map((platform) => platform.PlatformDetails); 8 | -------------------------------------------------------------------------------- /infra/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "infra", 3 | "devDependencies": { 4 | "@types/node": "^14" 5 | }, 6 | "dependencies": { 7 | "@pulumi/aws": "^5.0.0", 8 | "@pulumi/awsx": "^0.40.0", 9 | "@pulumi/cloudflare": "^5.26.0", 10 | "@pulumi/github": "^6.1.0", 11 | "@pulumi/pulumi": "^3.0.0", 12 | "@pulumi/std": "^1.6.2" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /platforms/src/utils/handleProviderAxiosError.ts: -------------------------------------------------------------------------------- 1 | import { handleAxiosError } from "./handleAxiosError"; 2 | import { ProviderExternalVerificationError } from "../types"; 3 | 4 | export const handleProviderAxiosError = (error: any, label: string, secretsToHide?: string[]) => { 5 | return handleAxiosError(error, label, ProviderExternalVerificationError, secretsToHide); 6 | }; 7 | -------------------------------------------------------------------------------- /app/public/assets/goerli-base-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /types/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.settings.json", 3 | "compilerOptions": { 4 | "target": "ES2022", 5 | "composite": true, 6 | "declaration": true, 7 | "rootDir": ".", 8 | "types": ["node"], 9 | "outDir": "/tmp/tsc-output", 10 | "skipLibCheck": true, 11 | "noImplicitAny": true 12 | }, 13 | "include": ["src"] 14 | } 15 | -------------------------------------------------------------------------------- /app/__mocks__/@gitcoin/passport-identity/index.js: -------------------------------------------------------------------------------- 1 | // mock everything that we're using in @gitcoin/passport-identity/src into an object and export it 2 | const identity = {}; 3 | 4 | // always verifies 5 | identity.verifyCredential = jest.fn(() => true); 6 | identity.fetchVerifiableCredential = jest.fn(() => true); 7 | 8 | // return full mock 9 | module.exports = identity; 10 | -------------------------------------------------------------------------------- /app/public/assets/information-circle-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/README.md: -------------------------------------------------------------------------------- 1 | # @gitcoin/passport-app 2 | 3 | This will be the web app allowing users to interact with their Gitcoin Passport. 4 | 5 | ```bash 6 | yarn start 7 | ``` 8 | 9 | Set the `NEXT_PUBLIC_CERAMIC_CLIENT_URL` environment variable to change the Ceramic node to run against - the Ceramic 10 | host defaults to the community node `https://ceramic-clay.3boxlabs.com` if not provided. 11 | -------------------------------------------------------------------------------- /iam/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | /dist 12 | /coverage 13 | dist-ssr 14 | *.local 15 | 16 | # Editor directories and files 17 | .vscode/* 18 | !.vscode/extensions.json 19 | .idea 20 | .DS_Store 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw? 26 | -------------------------------------------------------------------------------- /tsconfig.settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "noImplicitAny": false, 6 | "removeComments": true, 7 | "noLib": false, 8 | "emitDecoratorMetadata": true, 9 | "experimentalDecorators": true, 10 | "target": "es6", 11 | "sourceMap": true, 12 | "lib": [ 13 | "es6" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /identity/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | /dist 12 | /coverage 13 | dist-ssr 14 | *.local 15 | 16 | # Editor directories and files 17 | .vscode/* 18 | !.vscode/extensions.json 19 | .idea 20 | .DS_Store 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw? 26 | -------------------------------------------------------------------------------- /platforms/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | /dist 12 | /coverage 13 | dist-ssr 14 | *.local 15 | 16 | # Editor directories and files 17 | .vscode/* 18 | !.vscode/extensions.json 19 | .idea 20 | .DS_Store 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw? 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | .nvmrc 4 | .yarnrc 5 | 6 | # Logs 7 | logs 8 | *.log 9 | npm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | pnpm-debug.log* 13 | lerna-debug.log* 14 | 15 | # Editor directories and files 16 | .yarn/* 17 | .vscode/* 18 | !.vscode/extensions.json 19 | .idea 20 | .DS_Store 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw? 26 | 27 | schemas/.env.yarn -------------------------------------------------------------------------------- /app/__mocks__/@adraffy/ens-normalize.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ens_beautify: jest.fn(), 3 | ens_emoji: jest.fn(), 4 | ens_normalize: jest.fn(), 5 | ens_normalize_fragment: jest.fn(), 6 | ens_split: jest.fn(), 7 | ens_tokenize: jest.fn(), 8 | is_combining_mark: jest.fn(), 9 | nfc: jest.fn(), 10 | nfd: jest.fn(), 11 | safe_str_from_cps: jest.fn(), 12 | should_escape: jest.fn(), 13 | }; 14 | -------------------------------------------------------------------------------- /iam/src/types.d.ts: -------------------------------------------------------------------------------- 1 | import { ProviderContext, RequestPayload, VerifiedPayload } from "@gitcoin/passport-types"; 2 | 3 | // All Identity Providers should implement Provider 4 | export interface Provider { 5 | type: string; 6 | verify: (payload: RequestPayload, context?: ProviderContext) => Promise; 7 | } 8 | 9 | // Use unknown 10 | export type ProviderOptions = Record; 11 | -------------------------------------------------------------------------------- /js-ceramic/README.md: -------------------------------------------------------------------------------- 1 | # Instructions for building & running docker image 2 | 3 | - build docker image: `docker build . --tag gitcoinpassport/js-ceramic:` 4 | - push docker image: `docker push gitcoinpassport/js-ceramic:` 5 | - running `ceramicnetwork/js-ceramic` directly on local with: `docker run --rm -v $(pwd)/ceramic:/ceramic ceramicnetwork/js-ceramic:3.2.0 --config /ceramic/daemon.config.json` 6 | -------------------------------------------------------------------------------- /platforms/src/GtcStaking/index.ts: -------------------------------------------------------------------------------- 1 | export { GTCStakingPlatform } from "./App-Bindings"; 2 | export { PlatformDetails, ProviderConfig, providers } from "./Providers-config"; 3 | export { 4 | SelfStakingBronzeProvider, 5 | SelfStakingGoldProvider, 6 | SelfStakingSilverProvider, 7 | BeginnerCommunityStakerProvider, 8 | ExperiencedCommunityStakerProvider, 9 | TrustedCitizenProvider, 10 | } from "./Providers"; 11 | -------------------------------------------------------------------------------- /app/components/LoadingScreen.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const LoadingScreen = () => { 4 | return ( 5 |
6 | Loading... 7 | Gitcoin Logo 8 |
9 | ); 10 | }; 11 | 12 | export default LoadingScreen; 13 | -------------------------------------------------------------------------------- /iam/babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-typescript", 4 | ["@babel/preset-env", { "targets": { "node": "current" } }] 5 | ], 6 | "plugins": [ 7 | "@babel/plugin-syntax-import-assertions", 8 | "babel-plugin-transform-import-meta", 9 | ["babel-plugin-replace-import-extension", { "extMapping": { ".js": "" } }], 10 | "@babel/plugin-transform-modules-commonjs" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /app/public/assets/ethStampIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/__mocks__/@self.id/framework/index.js: -------------------------------------------------------------------------------- 1 | const framework = {}; 2 | 3 | const mockConnectFn = jest.fn(() => new Promise((resolve) => resolve())); 4 | const mockDisconnectFn = jest.fn(() => new Promise((resolve) => resolve())); 5 | 6 | const viewerConnection = { 7 | status: "idle", 8 | }; 9 | 10 | framework.useViewerConnection = () => [viewerConnection, mockConnectFn, mockDisconnectFn]; 11 | 12 | module.exports = framework; 13 | -------------------------------------------------------------------------------- /app/__mocks__/@web3-onboard/react.js: -------------------------------------------------------------------------------- 1 | const react = {}; 2 | 3 | const mockConnectFn = jest.fn(() => new Promise((resolve) => resolve())); 4 | const mockDisconnectFn = jest.fn(() => new Promise((resolve) => resolve())); 5 | const mockUseConnectWallet = () => [{ wallet: {} }, mockConnectFn, mockDisconnectFn]; 6 | 7 | react.useConnectWallet = mockUseConnectWallet; 8 | 9 | react.useWallets = () => []; 10 | 11 | module.exports = react; 12 | -------------------------------------------------------------------------------- /database-client/__tests__/integration-test-model-aliases.json: -------------------------------------------------------------------------------- 1 | {"definitions":{"Passport":"kjzl6cwe1jw145znqlxwwar1crvgsm3wf56vcnxo6bu87fqsi6519eypjnzs7mu","VerifiableCredential":"kjzl6cwe1jw149zuvayqa89nhmlvwm0pkdkj0awlxhmtbbay6i972xuwy14jg4f"},"schemas":{"Passport":"ceramic://k3y52l7qbv1fryatc5h4xpnusk6vw8pmle6duu11djx2dke2senbiecu1fw1wrif4","VerifiableCredential":"ceramic://k3y52l7qbv1fry8pdl0tpicir0jxfwktanqceca89gsvy9geg7o2cd4b6hdr33uv4"},"tiles":{}} -------------------------------------------------------------------------------- /platforms/src/POAP/App-Bindings.ts: -------------------------------------------------------------------------------- 1 | import { AppContext, ProviderPayload } from "../types"; 2 | import { Platform } from "../utils/platform"; 3 | 4 | export class POAPPlatform extends Platform { 5 | platformId = "POAP"; 6 | path = "POAP"; 7 | isEVM = true; 8 | 9 | async getProviderPayload(appContext: AppContext): Promise { 10 | const result = await Promise.resolve({}); 11 | return result; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/utils/theme/chakra/Modal.tsx: -------------------------------------------------------------------------------- 1 | import type { ComponentStyleConfig } from "@chakra-ui/theme"; 2 | 3 | const Modal: ComponentStyleConfig = { 4 | parts: ["dialog"], 5 | baseStyle: { 6 | dialog: { 7 | marginTop: "5rem", 8 | bg: "rgb(var(--color-background))", 9 | color: "rgb(var(--color-text-1))", 10 | border: "solid 1px rgb(var(--color-foreground-6))", 11 | }, 12 | }, 13 | }; 14 | 15 | export default Modal; 16 | -------------------------------------------------------------------------------- /database-client/integration-tests/integration-test-model-aliases.json: -------------------------------------------------------------------------------- 1 | {"definitions":{"Passport":"kjzl6cwe1jw145znqlxwwar1crvgsm3wf56vcnxo6bu87fqsi6519eypjnzs7mu","VerifiableCredential":"kjzl6cwe1jw149zuvayqa89nhmlvwm0pkdkj0awlxhmtbbay6i972xuwy14jg4f"},"schemas":{"Passport":"ceramic://k3y52l7qbv1fryatc5h4xpnusk6vw8pmle6duu11djx2dke2senbiecu1fw1wrif4","VerifiableCredential":"ceramic://k3y52l7qbv1fry8pdl0tpicir0jxfwktanqceca89gsvy9geg7o2cd4b6hdr33uv4"},"tiles":{}} -------------------------------------------------------------------------------- /app/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | module.exports = { 3 | output: "export", 4 | exportPathMap: function () { 5 | return { 6 | "/": { page: "/" }, 7 | }; 8 | }, 9 | reactStrictMode: true, 10 | webpack: function (config, { _isServer }) { 11 | config.experiments = { asyncWebAssembly: true }; 12 | config.resolve.fallback = { fs: false, net: false, tls: false }; 13 | return config; 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /.github/workflows/add-issue-to-project.yml: -------------------------------------------------------------------------------- 1 | name: Add issues to passport project 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | 8 | jobs: 9 | add-to-project: 10 | name: Add issue to project 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/add-to-project@v0.1.0 14 | with: 15 | project-url: https://github.com/orgs/gitcoinco/projects/6 16 | github-token: ${{ secrets.ADD_ISSUE_TO_PROJECT_PAT }} 17 | -------------------------------------------------------------------------------- /app/__test-fixtures__/toastTestHelpers.tsx: -------------------------------------------------------------------------------- 1 | import { screen, waitForElementToBeRemoved } from "@testing-library/react"; 2 | import { toastStore } from "@chakra-ui/toast/dist/toast.store"; 3 | 4 | export const closeAllToasts = async () => { 5 | // close all toasts before each tests and wait for them to be removed 6 | toastStore.closeAll(); 7 | const toasts = screen.queryAllByRole("listitem"); 8 | await Promise.all(toasts.map((toasts) => waitForElementToBeRemoved(toasts))); 9 | }; 10 | -------------------------------------------------------------------------------- /app/components/BodyWrapper.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { PAGE_PADDING, CONTENT_MAX_WIDTH_INCLUDING_PADDING } from "./PageWidthGrid"; 3 | 4 | const BodyWrapper = ({ children, className }: { children: React.ReactNode; className?: string }) => ( 5 |
8 | {children} 9 |
10 | ); 11 | 12 | export default BodyWrapper; 13 | -------------------------------------------------------------------------------- /platforms/src/utils/errors.ts: -------------------------------------------------------------------------------- 1 | export type ProviderError = { 2 | name?: string; 3 | message?: string; 4 | response?: { 5 | status?: number; 6 | statusText?: string; 7 | data: unknown; 8 | }; 9 | }; 10 | 11 | export function getErrorString(error: ProviderError): string { 12 | return `${error.name} - ${error.message}|\ 13 | response: Status ${error.response?.status} - ${error.response?.statusText}|\ 14 | response data: ${JSON.stringify(error?.response?.data)}`; 15 | } 16 | -------------------------------------------------------------------------------- /app/public/assets/linkedinStampIcon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/_feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: _Feature request 3 | about: Suggest an idea for this project 4 | title: "[to be defined]" 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### User Story: 11 | As a ... 12 | I want to ... 13 | So that I can ... 14 | 15 | ### Acceptance Criteria 16 | GIVEN ... 17 | WHEN ... 18 | THEN ... 19 | 20 | #### Product & Design Links: 21 | 22 | 23 | #### Tech Details: 24 | 25 | #### Open Questions: 26 | 27 | #### Notes/Assumptions: 28 | -------------------------------------------------------------------------------- /app/public/assets/check-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/public/assets/check-icon-grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/public/assets/purple-check-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/public/assets/white-check-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /platforms/testSetup.js: -------------------------------------------------------------------------------- 1 | process.env.ZKSYNC_ERA_MAINNET_ENDPOINT = "https://zksync-era-api-endpoint.io"; 2 | process.env.PASSPORT_SCORER_BACKEND = "https://scorer-gtc.com"; 3 | process.env.SCORER_API_KEY = "abcdefg12345567"; 4 | 5 | jest.mock("redis", () => { 6 | // Import your mock Redis client here, so that it doesn't interfere with other mocks 7 | const { createClient } = require("./src/__tests__/mocks/redis"); 8 | return { 9 | createClient: jest.fn().mockImplementation(createClient), 10 | }; 11 | }); 12 | -------------------------------------------------------------------------------- /identity/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.settings.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "esModuleInterop": true, 6 | "declaration": true, 7 | "allowSyntheticDefaultImports": true, 8 | "target": "ES2022", 9 | "noImplicitAny": true, 10 | "moduleResolution": "node", 11 | "sourceMap": true, 12 | "outDir": "dist/commonjs", 13 | "allowJs": true, 14 | "baseUrl": "src", 15 | "skipLibCheck": true 16 | }, 17 | "include": ["src/**/*"] 18 | } 19 | -------------------------------------------------------------------------------- /schemas/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.settings.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "esModuleInterop": true, 6 | "declaration": true, 7 | "allowSyntheticDefaultImports": true, 8 | "target": "ES2022", 9 | "noImplicitAny": true, 10 | "moduleResolution": "node", 11 | "sourceMap": true, 12 | "outDir": "dist/commonjs", 13 | "allowJs": true, 14 | "baseUrl": "src", 15 | "skipLibCheck": true 16 | }, 17 | "include": ["src/**/*"] 18 | } 19 | -------------------------------------------------------------------------------- /types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gitcoin/passport-types", 3 | "version": "1.0.0", 4 | "license": "MIT", 5 | "types": "src/index.d.ts", 6 | "scripts": { 7 | "build": "tsc -b .", 8 | "clean": "rimraf dist *.tsbuildinfo", 9 | "lint": "tsc --noEmit && eslint --ext .ts,.js,.tsx .", 10 | "prettier": "prettier --write .", 11 | "precommit": "lint-staged", 12 | "ethers": "^5.0.32" 13 | }, 14 | "devDependencies": { 15 | "tslint": "^6.1.3", 16 | "typescript": "^5.3.3" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/components/OnchainTag.tsx: -------------------------------------------------------------------------------- 1 | import { Tag, TagLabel } from "@chakra-ui/react"; 2 | 3 | export function OnchainTag({ marginLeft }: { marginLeft?: string }) { 4 | return ( 5 | 15 | Onchain 16 | 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /app/components/LoadButton.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Button, ButtonProps } from "./Button"; 3 | import { Spinner } from "@chakra-ui/react"; 4 | 5 | export type LoadingButtonProps = ButtonProps & { 6 | isLoading?: boolean; 7 | }; 8 | 9 | export const LoadButton = ({ isLoading, disabled, children, ...props }: LoadingButtonProps) => { 10 | return ( 11 | 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /infra/aws/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "outDir": "bin", 5 | "target": "es2016", 6 | "module": "commonjs", 7 | "moduleResolution": "node", 8 | "sourceMap": true, 9 | "experimentalDecorators": true, 10 | "pretty": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "noImplicitReturns": true, 13 | "forceConsistentCasingInFileNames": true 14 | }, 15 | "files": [ 16 | "index.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /platforms/src/Twitter/Providers-config.ts: -------------------------------------------------------------------------------- 1 | import { PlatformSpec, PlatformGroupSpec, Provider } from "../types"; 2 | 3 | export const PlatformDetails: PlatformSpec = { 4 | icon: "./assets/twitterStampIcon.svg", 5 | platform: "Twitter", 6 | name: "Twitter", 7 | description: "Connect to Twitter to verify your social media presence.", 8 | connectMessage: "Connect Account", 9 | website: "https://twitter.com/", 10 | }; 11 | 12 | export const ProviderConfig: PlatformGroupSpec[] = []; 13 | 14 | export const providers: Provider[] = []; 15 | -------------------------------------------------------------------------------- /app/components/WebmVideo.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | // WebmVideo is a component that renders a video element with a fallback & loading image 4 | export const WebmVideo = ({ 5 | src, 6 | fallbackSrc, 7 | className, 8 | alt, 9 | }: { 10 | src: string; 11 | fallbackSrc: string; 12 | alt: string; 13 | className?: string; 14 | }) => ( 15 | 19 | ); 20 | -------------------------------------------------------------------------------- /.github/workflows/app-cd-review.yml: -------------------------------------------------------------------------------- 1 | name: Deploy App to Review 2 | on: 3 | push: 4 | branches: [main] 5 | 6 | jobs: 7 | deploy-app: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v3 11 | - name: Checkout review-app 12 | run: | 13 | git fetch 14 | git checkout -b review-app origin/review-app 15 | git reset --hard origin/main 16 | git remote set-url origin https://${{ secrets.GITHUB_TOKEN }}@github.com/gitcoinco/passport.git 17 | git push origin review-app -f 18 | -------------------------------------------------------------------------------- /platforms/src/Gitcoin/Providers/gitcoinGrantsContributorStatistics.ts: -------------------------------------------------------------------------------- 1 | // ----- Types 2 | import { ProviderOptions } from "../../types"; 3 | import { GitcoinGrantStatisticsProvider } from "./gitcoinGrantsStatistics"; 4 | 5 | // Export a Gitcoin Provider 6 | export class GitcoinContributorStatisticsProvider extends GitcoinGrantStatisticsProvider { 7 | // construct the provider instance with supplied options 8 | constructor(options: ProviderOptions = {}) { 9 | super("GitcoinContributorStatistics", options); 10 | this.urlPath = "/contributor_statistics"; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/utils/theme/chakra/Menu.tsx: -------------------------------------------------------------------------------- 1 | import type { ComponentStyleConfig } from "@chakra-ui/theme"; 2 | 3 | const hoverStyle = { 4 | bg: "rgb(var(--color-background-3))", 5 | color: "rgb(var(--color-text-1))", 6 | }; 7 | 8 | const Menu: ComponentStyleConfig = { 9 | parts: ["item", "list"], 10 | baseStyle: { 11 | item: { 12 | _hover: hoverStyle, 13 | _focus: hoverStyle, 14 | }, 15 | list: { 16 | background: "rgb(var(--color-background))", 17 | borderColor: "rgb(var(--color-background-3))", 18 | }, 19 | }, 20 | }; 21 | 22 | export default Menu; 23 | -------------------------------------------------------------------------------- /app/public/assets/shield-exclamation-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/components/GenericBanner.tsx: -------------------------------------------------------------------------------- 1 | import { PlatformBanner } from "@gitcoin/passport-platforms"; 2 | 3 | export function GenericBanner({ banner }: { banner: PlatformBanner }) { 4 | return ( 5 |
6 | {banner.heading &&

{banner.heading}

} 7 |

{banner.content}

8 | {banner.cta && ( 9 | 10 | {banner.cta.label} → 11 | 12 | )} 13 |
14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /iam/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.settings.json", 3 | "compilerOptions": { 4 | "module": "esnext", 5 | "esModuleInterop": true, 6 | "allowSyntheticDefaultImports": true, 7 | "allowJs": true, 8 | "target": "es6", 9 | "noImplicitAny": true, 10 | "moduleResolution": "node", 11 | "sourceMap": true, 12 | "outDir": "dist", 13 | "baseUrl": ".", 14 | "resolveJsonModule": true, 15 | "paths": { 16 | "*": ["../node_modules/*", "node_modules/*"] 17 | }, 18 | "skipLibCheck": true 19 | }, 20 | "include": ["src/**/*", "__tests__/**/*"] 21 | } 22 | -------------------------------------------------------------------------------- /app/public/assets/shield-exclamation-icon-warning.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.9" 2 | services: 3 | ceramic-integration-test: 4 | image: node:16 5 | volumes: 6 | - ./database-client:/passport/database-client 7 | - ./schemas:/passport/schemas 8 | - ./types:/passport/types 9 | - ./lerna.json:/passport/lerna.json 10 | - ./package.json:/passport/package.json 11 | - ./tsconfig.json:/passport/tsconfig.json 12 | - ./tsconfig.settings.json:/passport/tsconfig.settings.json 13 | - ./yarn.lock:/passport/yarn.lock 14 | entrypoint: 15 | ["sh", "/passport/database-client/integration-tests/run-ceramic-tests.sh"] 16 | -------------------------------------------------------------------------------- /.github/workflows/signer-cd-review.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Signer to Review 2 | on: 3 | push: 4 | branches: [main] 5 | paths: 6 | - "signer/**" 7 | jobs: 8 | deploy-signer: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | - name: Checkout review-signer 13 | run: | 14 | git fetch 15 | git checkout -b review-signer origin/review-signer 16 | git reset --hard origin/main 17 | git remote set-url origin https://${{ secrets.GITHUB_TOKEN }}@github.com/gitcoinco/passport.git 18 | git push origin review-signer -f 19 | -------------------------------------------------------------------------------- /app/components/SupportBanner.tsx: -------------------------------------------------------------------------------- 1 | import Warning from "./Warning"; 2 | import { SupportBannerProps } from "../hooks/useSupportBanners"; 3 | 4 | export function SupportBanner({ banners }: { banners: SupportBannerProps[] }): JSX.Element { 5 | return ( 6 | <> 7 | {banners.map((banner) => ( 8 | 14 | ))} 15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | public/stampMetadata.json 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env.local 30 | .env.development.local 31 | .env.test.local 32 | .env.production.local 33 | 34 | # vercel 35 | .vercel 36 | 37 | # typescript 38 | *.tsbuildinfo 39 | -------------------------------------------------------------------------------- /app/components/PageWidthGrid.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const PAGE_PADDING = "px-4 md:px-10 lg:px-20"; 4 | export const CONTENT_MAX_WIDTH_INCLUDING_PADDING = "max-w-[1440px]"; 5 | export const CONTENT_MAX_WIDTH = "max-w-screen-xl"; 6 | 7 | const PageWidthGrid = ({ children, className }: { children: React.ReactNode; className?: string }) => ( 8 |
12 | {children} 13 |
14 | ); 15 | 16 | export default PageWidthGrid; 17 | -------------------------------------------------------------------------------- /app/context/testModeState.tsx: -------------------------------------------------------------------------------- 1 | // This file provides a minimal import to see whether or not the app is in test mode, 2 | // and a toggle function which reloads the page in the opposite mode. 3 | 4 | // This is only set on page load (required to support wallet modal config) 5 | export const TEST_MODE = typeof window !== "undefined" && window.sessionStorage.getItem("testMode") === "on"; 6 | 7 | export const toggleTestMode = () => { 8 | if (TEST_MODE) { 9 | window.sessionStorage.setItem("testMode", "off"); 10 | } else { 11 | window.sessionStorage.setItem("testMode", "on"); 12 | } 13 | window.location.reload(); 14 | }; 15 | -------------------------------------------------------------------------------- /platforms/src/Twitter/App-Bindings.ts: -------------------------------------------------------------------------------- 1 | import { Platform } from "../utils/platform"; 2 | import axios from "axios"; 3 | 4 | type TwitterProcResponse = { 5 | data: { 6 | authUrl: string; 7 | }; 8 | }; 9 | export class TwitterPlatform extends Platform { 10 | platformId = "Twitter"; 11 | path = "twitter"; 12 | 13 | async getOAuthUrl(): Promise { 14 | // Fetch data from external API 15 | const res: TwitterProcResponse = await axios.post( 16 | `${process.env.NEXT_PUBLIC_PASSPORT_PROCEDURE_URL?.replace(/\/*?$/, "")}/twitter/generateAuthUrl` 17 | ); 18 | return res.data.authUrl; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /database-client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.settings.json", 3 | "compilerOptions": { 4 | "module": "esnext", 5 | "esModuleInterop": true, 6 | "declaration": true, 7 | "allowSyntheticDefaultImports": true, 8 | "target": "es5", 9 | "moduleResolution": "node", 10 | "sourceMap": true, 11 | "outDir": "dist/esm", 12 | "allowJs": true, 13 | "baseUrl": "src", 14 | "paths": { 15 | "*": ["../node_modules/*", "node_modules/*"] 16 | }, 17 | "skipLibCheck": true, 18 | "resolveJsonModule": true 19 | }, 20 | "include": ["src/*", "___test___", "integration-tests"] 21 | } 22 | -------------------------------------------------------------------------------- /database-client/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | pnpm-debug.log* 10 | lerna-debug.log* 11 | 12 | # dependencies 13 | /node_modules 14 | /.pnp 15 | .pnp.js 16 | 17 | # build 18 | /dist 19 | 20 | # testing 21 | /coverage 22 | 23 | # production 24 | /build 25 | 26 | # ceramic 27 | .pinning.store 28 | 29 | # misc 30 | .DS_Store 31 | .env 32 | .env.local 33 | .env.development.local 34 | .env.test.local 35 | .env.production.local 36 | .eslintcache 37 | 38 | npm-debug.log* 39 | yarn-debug.log* 40 | yarn-error.log* 41 | -------------------------------------------------------------------------------- /platforms/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.settings.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "esModuleInterop": true, 6 | "declaration": true, 7 | "allowSyntheticDefaultImports": true, 8 | "target": "ES2022", 9 | "skipLibCheck": true, 10 | "noImplicitAny": true, 11 | "moduleResolution": "node", 12 | "sourceMap": true, 13 | "outDir": "dist/commonjs", 14 | "allowJs": true, 15 | "baseUrl": "src", 16 | "paths": { 17 | "*": ["../node_modules/*", "node_modules/*"] 18 | }, 19 | "jsx": "react", 20 | "lib": ["es6", "dom"] 21 | }, 22 | "include": ["src/**/*", "__tests__/**/*"] 23 | } 24 | -------------------------------------------------------------------------------- /app/__test-fixtures__/onboardHookValues.ts: -------------------------------------------------------------------------------- 1 | import { Account, ConnectedChain, WalletState } from "@web3-onboard/core/dist/types"; 2 | 3 | const sepoliaChainId = "0xaa36a7"; 4 | export const mockAddress = "0xmyAddress"; 5 | export const mockAccount: Account = { 6 | address: mockAddress, 7 | ens: null, 8 | uns: null, 9 | balance: null, 10 | }; 11 | export const mockWallet: WalletState = { 12 | label: "myWallet", 13 | icon: "", 14 | provider: { on: jest.fn(), removeListener: jest.fn(), request: jest.fn() }, 15 | accounts: [mockAccount], 16 | chains: [ 17 | [ 18 | { 19 | id: sepoliaChainId, 20 | }, 21 | ] as unknown as ConnectedChain, 22 | ], 23 | }; 24 | -------------------------------------------------------------------------------- /app/public/assets/x-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /platforms/src/Snapshot/App-Bindings.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import { AppContext, ProviderPayload } from "../types"; 3 | import { Platform } from "../utils/platform"; 4 | 5 | export class SnapshotPlatform extends Platform { 6 | platformId = "Snapshot"; 7 | path = "Snapshot"; 8 | isEVM = true; 9 | banner = { 10 | cta: { 11 | label: "Learn more", 12 | url: "https://support.passport.xyz/passport-knowledge-base/stamps/how-do-i-add-passport-stamps/connecting-snapshot-to-passport", 13 | }, 14 | }; 15 | async getProviderPayload(appContext: AppContext): Promise { 16 | const result = await Promise.resolve({}); 17 | return result; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/public/assets/x-icon-black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /platforms/src/Google/Providers-config.ts: -------------------------------------------------------------------------------- 1 | import { PlatformSpec, PlatformGroupSpec, Provider } from "../types"; 2 | import { GoogleProvider } from "./Providers/google"; 3 | 4 | export const PlatformDetails: PlatformSpec = { 5 | icon: "./assets/googleStampIcon.svg", 6 | platform: "Google", 7 | name: "Google", 8 | description: "Connect to Google to verify your email address.", 9 | connectMessage: "Connect Account", 10 | website: "https://www.google.com/", 11 | }; 12 | 13 | export const ProviderConfig: PlatformGroupSpec[] = [ 14 | { platformGroup: "Account Name", providers: [{ title: "Google", name: "Google" }] }, 15 | ]; 16 | 17 | export const providers: Provider[] = [new GoogleProvider()]; 18 | -------------------------------------------------------------------------------- /platforms/src/Linkedin/Providers-config.ts: -------------------------------------------------------------------------------- 1 | import { PlatformSpec, PlatformGroupSpec, Provider } from "../types"; 2 | import { LinkedinProvider } from "./Providers/linkedin"; 3 | 4 | export const PlatformDetails: PlatformSpec = { 5 | icon: "./assets/linkedinStampIcon.svg", 6 | platform: "Linkedin", 7 | name: "Linkedin", 8 | description: "Connect your existing Linkedin account to verify.", 9 | connectMessage: "Connect Account", 10 | }; 11 | 12 | export const ProviderConfig: PlatformGroupSpec[] = [ 13 | { 14 | platformGroup: "Account Name", 15 | providers: [{ title: "Encrypted", name: "Linkedin" }], 16 | }, 17 | ]; 18 | 19 | export const providers: Provider[] = [new LinkedinProvider()]; 20 | -------------------------------------------------------------------------------- /schemas/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | pnpm-debug.log* 10 | lerna-debug.log* 11 | 12 | # dependencies 13 | /node_modules 14 | /.pnp 15 | .pnp.js 16 | 17 | # testing 18 | /coverage 19 | 20 | # production 21 | /build 22 | 23 | # ceramic 24 | .pinning.store 25 | scripts/create-model.json 26 | scripts/publish-model.json 27 | 28 | # misc 29 | .DS_Store 30 | .env 31 | .env.local 32 | .env.development.local 33 | .env.test.local 34 | .env.production.local 35 | .eslintcache 36 | 37 | npm-debug.log* 38 | yarn-debug.log* 39 | yarn-error.log* 40 | 41 | /dist -------------------------------------------------------------------------------- /platforms/src/GnosisSafe/Providers-config.ts: -------------------------------------------------------------------------------- 1 | import { PlatformSpec, PlatformGroupSpec, Provider } from "../types"; 2 | import { GnosisSafeProvider } from "./Providers"; 3 | 4 | export const PlatformDetails: PlatformSpec = { 5 | icon: "./assets/gnosisSafeStampIcon.svg", 6 | platform: "GnosisSafe", 7 | name: "Gnosis Safe", 8 | description: "Gnosis Safe Signer/Owner Verification", 9 | connectMessage: "Verify Account", 10 | isEVM: true, 11 | }; 12 | 13 | export const ProviderConfig: PlatformGroupSpec[] = [ 14 | { 15 | platformGroup: "Account Name", 16 | providers: [{ title: "Encrypted", name: "GnosisSafe" }], 17 | }, 18 | ]; 19 | 20 | export const providers: Provider[] = [new GnosisSafeProvider()]; 21 | -------------------------------------------------------------------------------- /platforms/src/Ens/Providers-config.ts: -------------------------------------------------------------------------------- 1 | import { PlatformSpec, PlatformGroupSpec, Provider } from "../types"; 2 | import { EnsProvider } from "./Providers"; 3 | 4 | export const PlatformDetails: PlatformSpec = { 5 | icon: "./assets/ensStampIcon.svg", 6 | platform: "Ens", 7 | name: "ENS", 8 | description: "Connect to ENS to verify your ownership of your web3 domain name.", 9 | connectMessage: "Connect Account", 10 | isEVM: true, 11 | website: "https://ens.domains/", 12 | }; 13 | 14 | export const ProviderConfig: PlatformGroupSpec[] = [ 15 | { 16 | platformGroup: "Account Name", 17 | providers: [{ title: "Encrypted", name: "Ens" }], 18 | }, 19 | ]; 20 | 21 | export const providers: Provider[] = [new EnsProvider()]; 22 | -------------------------------------------------------------------------------- /platforms/src/POAP/Providers-config.ts: -------------------------------------------------------------------------------- 1 | import { PlatformSpec, PlatformGroupSpec, Provider } from "../types"; 2 | import { POAPProvider } from "./Providers/poap"; 3 | 4 | export const PlatformDetails: PlatformSpec = { 5 | icon: "./assets/poapStampIcon.svg", 6 | platform: "POAP", 7 | name: "POAP", 8 | description: "Connect an account to a POAP owned for over 15 days.", 9 | connectMessage: "Connect to POAP", 10 | isEVM: true, 11 | }; 12 | 13 | export const ProviderConfig: PlatformGroupSpec[] = [ 14 | { 15 | platformGroup: "Account Name", 16 | providers: [{ title: "Connect an account to a POAP owned for over 15 days.", name: "POAP" }], 17 | }, 18 | ]; 19 | 20 | export const providers: Provider[] = [new POAPProvider()]; 21 | -------------------------------------------------------------------------------- /.github/workflows/app-promote-staging.yml: -------------------------------------------------------------------------------- 1 | name: Deploy App to Staging 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | # commit hash (for frontend deploy to fleek) 6 | commit: 7 | description: "Branch/Commit ref" 8 | default: "origin/main" 9 | type: string 10 | jobs: 11 | deploy-app: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v3 15 | - name: Checkout staging-app 16 | run: | 17 | git fetch 18 | git checkout -b staging-app origin/staging-app 19 | git reset --hard ${{ github.event.inputs.commit }} 20 | git remote set-url origin https://${{ secrets.GITHUB_TOKEN }}@github.com/gitcoinco/passport.git 21 | git push origin staging-app -f 22 | -------------------------------------------------------------------------------- /platforms/src/Lens/Providers-config.ts: -------------------------------------------------------------------------------- 1 | import { PlatformSpec, PlatformGroupSpec, Provider } from "../types"; 2 | import { LensProfileProvider } from "./Providers/lens"; 3 | 4 | export const PlatformDetails: PlatformSpec = { 5 | icon: "./assets/lensWhiteStampIcon.svg", 6 | platform: "Lens", 7 | name: "Lens", 8 | description: "Connect to Lens to verify your social media presence on Web3.", 9 | connectMessage: "Verify Account", 10 | isEVM: true, 11 | website: "https://lens.xyz/", 12 | }; 13 | 14 | export const ProviderConfig: PlatformGroupSpec[] = [ 15 | { 16 | platformGroup: "Lens Handle", 17 | providers: [{ title: "At least 1 Lens Handle", name: "Lens" }], 18 | }, 19 | ]; 20 | 21 | export const providers: Provider[] = [new LensProfileProvider()]; 22 | -------------------------------------------------------------------------------- /app/components/InitiateOnChainButton.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable react-hooks/exhaustive-deps */ 2 | // --- React Methods 3 | import React, { useState } from "react"; 4 | 5 | // --- Style Components 6 | import { OnchainSidebar } from "./OnchainSidebar"; 7 | import { Button } from "./Button"; 8 | 9 | const InitiateOnChainButton = ({ className }: { className?: string }) => { 10 | const [showSidebar, setShowSidebar] = useState(false); 11 | 12 | return ( 13 | <> 14 | 17 | setShowSidebar(false)} /> 18 | 19 | ); 20 | }; 21 | 22 | export default InitiateOnChainButton; 23 | -------------------------------------------------------------------------------- /app/public/assets/civicStampIcon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /platforms/src/TrustaLabs/Providers-config.ts: -------------------------------------------------------------------------------- 1 | import { PlatformSpec, PlatformGroupSpec, Provider } from "../types"; 2 | import { TrustaLabsProvider } from "./Providers/TrustaLabs"; 3 | 4 | export const PlatformDetails: PlatformSpec = { 5 | icon: "./assets/trustaLabsStampIcon.svg", 6 | platform: "TrustaLabs", 7 | name: "Trusta Labs", 8 | description: "Connect to Trusta Labs to verify your identity and reputation on Web3.", 9 | connectMessage: "Connect Account", 10 | website: "https://www.trustalabs.ai/", 11 | }; 12 | 13 | export const ProviderConfig: PlatformGroupSpec[] = [ 14 | { platformGroup: "Trusta Labs", providers: [{ title: "TrustScan Non-Sybil Account", name: "TrustaLabs" }] }, 15 | ]; 16 | 17 | export const providers: Provider[] = [new TrustaLabsProvider()]; 18 | -------------------------------------------------------------------------------- /.github/actions/check-provider-bitmaps/action.yml: -------------------------------------------------------------------------------- 1 | name: "Check Provider Bitmaps" 2 | description: "Checkout that the onchai provider bitmaps are in sync with the configuration in the code" 3 | 4 | inputs: 5 | ALCHEMY_API_KEY_OP: 6 | description: "Alchemy API key for Optimism" 7 | required: true 8 | 9 | ALCHEMY_API_KEY_OP_SEPOLIA: 10 | description: "Alchemy API key for Optimism Sepolia" 11 | required: true 12 | 13 | runs: 14 | using: "composite" 15 | steps: 16 | - name: Check Optimism Onchain Provider Bitmaps 17 | run: | 18 | echo "📋📋📋 Check Optimism Onchain Provider Bitmaps" 19 | yarn workspace @gitcoin/passport-iam checkProviders:op 20 | shell: bash 21 | env: 22 | ALCHEMY_API_KEY: ${{ inputs.ALCHEMY_API_KEY_OP }} 23 | -------------------------------------------------------------------------------- /platforms/src/Discord/Providers-config.ts: -------------------------------------------------------------------------------- 1 | import { PlatformSpec, PlatformGroupSpec, Provider } from "../types"; 2 | import { DiscordProvider } from "./Providers/discord"; 3 | 4 | export const PlatformDetails: PlatformSpec = { 5 | icon: "./assets/discordStampIcon.svg", 6 | platform: "Discord", 7 | name: "Discord", 8 | description: "Connect your Discord account to Gitcoin Passport to identity and reputation in Web3 communities.", 9 | connectMessage: "Connect Account", 10 | website: "https://discord.com/", 11 | }; 12 | 13 | export const ProviderConfig: PlatformGroupSpec[] = [ 14 | { 15 | platformGroup: "Account Name", 16 | providers: [{ title: "Encrypted", name: "Discord" }], 17 | }, 18 | ]; 19 | 20 | export const providers: Provider[] = [new DiscordProvider()]; 21 | -------------------------------------------------------------------------------- /.github/workflows/app-promote-production.yml: -------------------------------------------------------------------------------- 1 | name: Deploy App to Production 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | # commit hash (for frontend deploy to fleek) 6 | commit: 7 | description: "Branch/Commit ref" 8 | default: "origin/main" 9 | type: string 10 | jobs: 11 | deploy-app: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v3 15 | - name: Checkout production-app 16 | run: | 17 | git fetch 18 | git checkout -b production-app origin/production-app 19 | git reset --hard ${{ github.event.inputs.commit }} 20 | git remote set-url origin https://${{ secrets.GITHUB_TOKEN }}@github.com/gitcoinco/passport.git 21 | git push origin production-app -f 22 | -------------------------------------------------------------------------------- /.github/workflows/signer-promote-staging.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Signer to Staging 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | # commit hash (for frontend deploy to fleek) 6 | commit: 7 | description: "Branch/Commit ref" 8 | default: "origin/main" 9 | type: string 10 | jobs: 11 | deploy-signer: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v3 15 | - name: Checkout staging-signer 16 | run: | 17 | git fetch 18 | git checkout -b staging-signer origin/staging-signer 19 | git reset --hard ${{ github.event.inputs.commit }} 20 | git remote set-url origin https://${{ secrets.GITHUB_TOKEN }}@github.com/gitcoinco/passport.git 21 | git push origin staging-signer -f 22 | -------------------------------------------------------------------------------- /app/public/assets/verification-failed-bright.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /platforms/src/Idena/README.md: -------------------------------------------------------------------------------- 1 | # Idena Platform Stamp 2 | 3 | Guide to working with the Idena stamps. 4 | 5 | ## Local Testing 6 | 7 | You must run the idena server locally 8 | 9 | ``` 10 | git clone https://github.com/idena-network/idena-web 11 | cd idena-web 12 | npm i --force 13 | npx next dev -p 3004 14 | ``` 15 | 16 | Add the following to your app/.env 17 | 18 | ``` 19 | NEXT_PUBLIC_FF_IDENA_STAMP=on 20 | NEXT_PUBLIC_PASSPORT_IDENA_WEB_APP=http://localhost:3004/ 21 | NEXT_PUBLIC_PASSPORT_IDENA_CALLBACK=http://localhost:3000/ 22 | ``` 23 | 24 | You must log in to Idena with a real account. Gitcoin has been provided a test 25 | account, ask for details. 26 | 27 | Note that even though the frontend makes the call to the local server, the IAM 28 | will still call the real Idena API. 29 | -------------------------------------------------------------------------------- /iam/src/main.ts: -------------------------------------------------------------------------------- 1 | import "dotenv/config"; 2 | 3 | // ---- Main App from index 4 | import { app } from "./index.js"; 5 | import Moralis from "moralis"; 6 | 7 | // default port to listen on 8 | const port = process.env.IAM_PORT || 80; 9 | 10 | const startServer = async (): Promise => { 11 | await Moralis.start({ 12 | apiKey: process.env.MORALIS_API_KEY, 13 | }); 14 | 15 | const server = app.listen(port, () => { 16 | // eslint-disable-next-line no-console 17 | console.log(`server started at http://localhost:${port}`); 18 | }); 19 | 20 | // This should be > the ELB idle timeout, which is 60 seconds 21 | server.keepAliveTimeout = 61 * 1000; 22 | }; 23 | 24 | startServer().catch((error) => { 25 | // eslint-disable-next-line no-console 26 | console.error(error); 27 | }); 28 | -------------------------------------------------------------------------------- /.github/workflows/signer-promote-production.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Signer to Production 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | # commit hash (for frontend deploy to fleek) 6 | commit: 7 | description: "Branch/Commit ref" 8 | default: "origin/main" 9 | type: string 10 | jobs: 11 | deploy-signer: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v3 15 | - name: Checkout production-signer 16 | run: | 17 | git fetch 18 | git checkout -b production-signer origin/production-signer 19 | git reset --hard ${{ github.event.inputs.commit }} 20 | git remote set-url origin https://${{ secrets.GITHUB_TOKEN }}@github.com/gitcoinco/passport.git 21 | git push origin production-signer -f 22 | -------------------------------------------------------------------------------- /platforms/src/Brightid/Providers-config.ts: -------------------------------------------------------------------------------- 1 | import { PlatformSpec, PlatformGroupSpec, Provider } from "../types"; 2 | import { BrightIdProvider } from "./Providers/brightid"; 3 | 4 | export const PlatformDetails: PlatformSpec = { 5 | icon: "./assets/brightidStampIcon.svg", 6 | platform: "Brightid", 7 | name: "BrightID", 8 | description: "Connect to BrightID to verify your identity on Web3 without revealing any personal information.", 9 | connectMessage: "Connect Account", 10 | isEVM: true, 11 | website: "https://brightid.org/", 12 | }; 13 | 14 | export const ProviderConfig: PlatformGroupSpec[] = [ 15 | { 16 | platformGroup: "Account Name", 17 | providers: [{ title: "Encrypted", name: "Brightid" }], 18 | }, 19 | ]; 20 | 21 | export const providers: Provider[] = [new BrightIdProvider()]; 22 | -------------------------------------------------------------------------------- /app/public/assets/verifiedShield.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG] " 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Overview** 11 | Details, details, details 12 | 13 | **Steps To Reproduce** 14 | 1. Go to '...' 15 | 2. Click on '....' 16 | 3. Scroll down to '....' 17 | 4. See error 18 | 19 | **Observed behavior** 20 | A clear and concise description of what the observed behavior of the system. 21 | 22 | **Expected behavior** 23 | A clear and concise description of what you expected the system to do. 24 | 25 | **Screenshots** 26 | If applicable, add screenshots to help explain your problem. 27 | 28 | **Additional context** 29 | Add any other context about the problem here that will assist in triaging the bug. I.e. Browser information, unique identifiers, etc. 30 | -------------------------------------------------------------------------------- /platforms/src/Outdid/procedures/outdidVerification.ts: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | type OutdidVerificationResponse = { successRedirect: string, verificationID: string, userDid?: string }; 4 | 5 | export const outdidRequestVerification = async (userDid: string, redirect: string): Promise => { 6 | // request a verification containing a unique user identifier 7 | return await axios.post(`https://api.outdid.io/v1/verification-request?apiKey=${process.env.OUTDID_API_KEY}&apiSecret=${process.env.OUTDID_API_SECRET}`, { 8 | verificationParameters: { uniqueness: true }, 9 | verificationType: "icao", 10 | verificationName: userDid, 11 | redirect, 12 | }).then((response: { data: OutdidVerificationResponse }) => { 13 | return response.data; 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /iam/__mocks__/@gitcoin/passport-identity/index.js: -------------------------------------------------------------------------------- 1 | const realIdentity = require("@gitcoin/passport-identity"); 2 | 3 | // mock everything that we're using in @gitcoin/passport-identity/dist/commonjs into an object and export it 4 | const identity = {}; 5 | 6 | // always returns dummy challenge 7 | identity.issueChallengeCredential = jest.fn(async (DIDKit, key, record) => ({ 8 | credential: { 9 | issuer: "empty", 10 | credentialSubject: { 11 | id: `did:pkh:eip155:1:${record.address}`, 12 | provider: `challenge-${record.type}`, 13 | challenge: "123456789ABDEFGHIJKLMNOPQRSTUVWXYZ", 14 | }, 15 | }, 16 | })); 17 | 18 | // always verifies 19 | identity.verifyCredential = jest.fn(async () => true); 20 | 21 | // return full mock 22 | module.exports = { 23 | ...realIdentity, 24 | ...identity, 25 | realIdentity, 26 | }; 27 | -------------------------------------------------------------------------------- /platforms/src/GnosisSafe/App-Bindings.ts: -------------------------------------------------------------------------------- 1 | import { AppContext, ProviderPayload } from "../types"; 2 | import { Platform } from "../utils/platform"; 3 | 4 | export class GnosisSafePlatform extends Platform { 5 | platformId = "GnosisSafe"; 6 | path = "GnosisSafe"; 7 | isEVM = true; 8 | 9 | banner = { 10 | heading: 11 | "Currently, we only recognize Gnosis Safes on the Ethereum main network. So you can't get that stamp through your Gnosis Safes on other networks.", 12 | cta: { 13 | label: "Learn more", 14 | url: "https://support.passport.xyz/passport-knowledge-base/stamps/how-do-i-add-passport-stamps/gnosis-safe-stamp", 15 | }, 16 | }; 17 | 18 | async getProviderPayload(appContext: AppContext): Promise { 19 | const result = await Promise.resolve({}); 20 | return result; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/public/assets/brightidStampIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/utils/theme/palette.tsx: -------------------------------------------------------------------------------- 1 | export const palette = Object.entries({ 2 | black: "#000000", 3 | white: "#ffffff", 4 | gray: "#6d6d6d", 5 | nightBlue: "#122b33", 6 | ironGray: "#4b5f65", 7 | iris: "#4a47d3", 8 | seaFoam: "#6cB6ad", 9 | green: "#22645c", 10 | darkPurple: "#08205f", 11 | iceBlue: "#c1f6ff", 12 | turquoise: "#074853", 13 | paleYellow: "#d2dc95", 14 | red: "#ff5c00", 15 | }).reduce( 16 | (rgbPalette, [name, hex]) => { 17 | rgbPalette[name] = hexToRGB(hex); 18 | return rgbPalette; 19 | }, 20 | {} as Record 21 | ); 22 | 23 | export function hexToRGB(hex: string) { 24 | const r = parseInt(hex.slice(1, 3), 16) || 0, 25 | g = parseInt(hex.slice(3, 5), 16) || 0, 26 | b = parseInt(hex.slice(5, 7), 16) || 0; 27 | 28 | return "" + r + " " + g + " " + b; 29 | } 30 | 31 | export default palette; 32 | -------------------------------------------------------------------------------- /app/utils/theme/types.tsx: -------------------------------------------------------------------------------- 1 | export type Theme = { 2 | colors: { 3 | background: string; 4 | background2: string; 5 | background3: string; 6 | background4: string; 7 | foreground: string; 8 | foreground2: string; 9 | foreground3: string; 10 | foreground4: string; 11 | foreground5: string; 12 | foreground6: string; 13 | foreground7: string; 14 | text1: string; 15 | text2: string; 16 | text3: string; 17 | text4: string; 18 | text5: string; 19 | text6: string; 20 | focus: string; 21 | }; 22 | fonts: { 23 | body: string; 24 | heading: string; 25 | alt: string; 26 | }; 27 | }; 28 | 29 | export type CustomizationTheme = { 30 | colors: { 31 | customizationBackground1: string; 32 | customizationBackground2: string; 33 | customizationForeground1: string; 34 | }; 35 | }; 36 | -------------------------------------------------------------------------------- /app/components/ProcessingPopup.tsx: -------------------------------------------------------------------------------- 1 | export default function ProcessingPopup({ children, ...props }: { children: React.ReactNode }) { 2 | return ( 3 |
4 |
5 | 6 | 7 | 8 | 9 |
{children}
10 |
11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /app/public/assets/gtcStakingLogoIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/public/assets/shield-alert.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/public/assets/trustaLabsStampIcon.svg: -------------------------------------------------------------------------------- 1 | 资源 1 -------------------------------------------------------------------------------- /platforms/src/Holonym/Providers-config.ts: -------------------------------------------------------------------------------- 1 | import { PlatformSpec, PlatformGroupSpec, Provider } from "../types"; 2 | import { HolonymGovIdProvider } from "./Providers/holonymGovIdProvider"; 3 | 4 | export const PlatformDetails: PlatformSpec = { 5 | icon: "./assets/holonymStampIcon.svg", 6 | platform: "Holonym", 7 | name: "Holonym", 8 | description: "Connect to Holonym to verify your identity without revealing any personal information.", 9 | connectMessage: "Connect Account", 10 | isEVM: true, 11 | website: "https://holonym.id/", 12 | }; 13 | 14 | export const ProviderConfig: PlatformGroupSpec[] = [ 15 | { 16 | platformGroup: "Government ID", 17 | providers: [{ title: "Proven uniqueness using Holonym with government ID", name: "HolonymGovIdProvider" }], 18 | }, 19 | ]; 20 | 21 | export const providers: Provider[] = [new HolonymGovIdProvider()]; 22 | -------------------------------------------------------------------------------- /platforms/src/utils/__tests__/passport-cache.test.ts: -------------------------------------------------------------------------------- 1 | import { PassportCache } from "../passport-cache"; 2 | 3 | describe("PassportCache", () => { 4 | let passportCache: PassportCache; 5 | 6 | beforeEach(() => { 7 | passportCache = new PassportCache(); 8 | }); 9 | 10 | afterAll(async () => { 11 | await passportCache.disconnect(); 12 | }); 13 | 14 | it("should set a key-value pair", async () => { 15 | await passportCache.set("some_key", "some_value"); 16 | expect(await passportCache.get("some_key")).toBe("some_value"); 17 | }); 18 | it("should set a key-value hash", async () => { 19 | await passportCache.setHash("some_key", "some_field", "400"); 20 | // eslint-disable-next-line prettier/prettier 21 | expect(JSON.stringify(await passportCache.getHash("some_key"))).toBe(JSON.stringify({ some_field: "400" })); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /platforms/src/Ens/App-Bindings.ts: -------------------------------------------------------------------------------- 1 | import { AppContext, ProviderPayload } from "../types"; 2 | import { Platform } from "../utils/platform"; 3 | 4 | export class EnsPlatform extends Platform { 5 | platformId = "Ens"; 6 | path = "Ens"; 7 | clientId: string = null; 8 | redirectUri: string = null; 9 | isEVM = true; 10 | 11 | banner = { 12 | heading: 13 | "The ENS stamp only recognizes ENS domains if they are set to your account as primary ENS (or reverse record).", 14 | cta: { 15 | label: "Learn more", 16 | url: "https://support.passport.xyz/passport-knowledge-base/stamps/how-do-i-add-passport-stamps/connecting-an-ens-account-to-passport", 17 | }, 18 | }; 19 | 20 | async getProviderPayload(appContext: AppContext): Promise { 21 | const result = await Promise.resolve({}); 22 | return result; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "target": "ES2022", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "allowJs": false, 7 | "skipLibCheck": true, 8 | "strict": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "noEmit": true, 11 | "esModuleInterop": true, 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "jsx": "preserve", 17 | "incremental": true, 18 | }, 19 | "include": [ 20 | "next-env.d.ts", 21 | "**/*.ts", 22 | "**/*.tsx", 23 | "./*.tsx", 24 | "jest.config.ts", 25 | "jest.setup.ts", 26 | ], 27 | "exclude": ["node_modules"], 28 | "ts-node": { 29 | "esm": true, 30 | "compilerOptions": { 31 | "module": "nodenext", 32 | }, 33 | }, 34 | } 35 | -------------------------------------------------------------------------------- /app/public/assets/personIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /platforms/src/Snapshot/Providers-config.ts: -------------------------------------------------------------------------------- 1 | import { PlatformSpec, PlatformGroupSpec, Provider } from "../types"; 2 | import { SnapshotProposalsProvider } from "./Providers"; 3 | 4 | export const PlatformDetails: PlatformSpec = { 5 | icon: "./assets/snapshotStampIcon.svg", 6 | platform: "Snapshot", 7 | name: "Snapshot", 8 | description: "Connect to Snapshot to verify your DAO voting power.", 9 | connectMessage: "Verify Account", 10 | isEVM: true, 11 | website: "https://snapshot.org/", 12 | }; 13 | 14 | export const ProviderConfig: PlatformGroupSpec[] = [ 15 | { 16 | platformGroup: "Snapshot Proposal Creator", 17 | providers: [ 18 | { title: "Created a DAO proposal that was voted on by at least 1 account", name: "SnapshotProposalsProvider" }, 19 | ], 20 | }, 21 | ]; 22 | 23 | export const providers: Provider[] = [new SnapshotProposalsProvider()]; 24 | -------------------------------------------------------------------------------- /iam/jest.setup.cjs: -------------------------------------------------------------------------------- 1 | const DIDKit = require("@spruceid/didkit-wasm-node"); 2 | 3 | process.env.IAM_JWK = DIDKit.generateEd25519Key(); 4 | process.env.IAM_JWK_EIP712 = 5 | '{"kty":"EC","crv":"secp256k1","x":"PdB2nS-knyAxc6KPuxBr65vRpW-duAXwpeXlwGJ03eU","y":"MwoGZ08hF5uv-_UEC9BKsYdJVSbJNHcFhR1BZWer5RQ","d":"z9VrSNNZXf9ywUx3v_8cLDhSw8-pvAT9qu_WZmqqfWM"}'; 6 | process.env.ATTESTATION_SIGNER_PRIVATE_KEY = 7 | "0x04d16281ff3bf268b29cdd684183f72542757d24ae9fdfb863e7c755e599163a"; 8 | process.env.TESTNET_ATTESTATION_SIGNER_PRIVATE_KEY = 9 | "0x04d16281ff3bf268b29cdd684183f72542757d24ae9fdfb863e7c755e599163a"; 10 | process.env.GITCOIN_VERIFIER_CHAIN_ID = "84531"; 11 | process.env.ALLO_SCORER_ID = "1"; 12 | process.env.SCORER_ENDPOINT = "http://127.0.0.1:8002"; 13 | process.env.SCORER_API_KEY = "abcd"; 14 | process.env.MORALIS_API_KEY = "abcd"; 15 | process.env.EAS_GITCOIN_STAMP_SCHEMA = "0x"; 16 | -------------------------------------------------------------------------------- /platforms/src/GuildXYZ/App-Bindings.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import { AppContext, Platform, PlatformOptions, ProviderPayload } from "../types"; 3 | 4 | export class GuildXYZPlatform implements Platform { 5 | platformId = "GuildXYZ"; 6 | path = "GuildXYZ"; 7 | isEVM = true; 8 | clientId: string = null; 9 | redirectUri: string = null; 10 | 11 | banner = { 12 | heading: "*Qualifying guilds have more than 250 members", 13 | cta: { 14 | label: "Learn more", 15 | url: "https://support.passport.xyz/passport-knowledge-base/stamps/how-do-i-add-passport-stamps/guide-to-add-guild-stamp-to-passport", 16 | }, 17 | }; 18 | 19 | async getProviderPayload(appContext: AppContext): Promise { 20 | return {}; 21 | } 22 | 23 | getOAuthUrl(state: string): Promise { 24 | throw new Error("Method not implemented."); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /types/src/brightid.d.ts: -------------------------------------------------------------------------------- 1 | export type FailResponse = { 2 | status?: number; 3 | statusText?: string; 4 | data?: { 5 | error: boolean; 6 | errorNum: number; 7 | errorMessage: string; 8 | contextIds?: string[]; 9 | code: number; 10 | }; 11 | }; 12 | 13 | export type SponsorshipSuccessResponse = { 14 | status: string; 15 | statusReason: string; 16 | }; 17 | 18 | export type VerificationSuccessResponse = { 19 | unique?: boolean; 20 | app?: string; 21 | context?: string; 22 | contextIds?: string[]; 23 | }; 24 | 25 | export type BrightIdVerificationResponse = FailResponse | VerificationSuccessResponse; 26 | 27 | export type BrightIdSponsorshipResponse = FailResponse | SponsorshipSuccessResponse; 28 | 29 | export type BrightIdProcedureResponse = { 30 | valid: boolean; 31 | result?: BrightIdSponsorshipResponse | BrightIdVerificationResponse; 32 | error?: string; 33 | }; 34 | -------------------------------------------------------------------------------- /database-client/integration-tests/run-ceramic-tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # === preliminary installs === 4 | yarn global add lerna 5 | cd passport 6 | lerna bootstrap -- --ignore-scripts # skipping pre/postinstall scripts 7 | yarn build:database-client 8 | 9 | export CERAMIC_CLIENT_URL="https://ceramic-clay.3boxlabs.com" 10 | 11 | # === start up ceramic in background === 12 | until $(curl --output /dev/null --silent --head --fail $CERAMIC_CLIENT_URL/api/v0/node/healthcheck); do 13 | printf '... waiting for Ceramic daemon ...' 14 | sleep 5 15 | done 16 | 17 | # === fetch passport and VC definitions === 18 | curl $CERAMIC_CLIENT_URL/api/v0/streams/kjzl6cwe1jw145znqlxwwar1crvgsm3wf56vcnxo6bu87fqsi6519eypjnzs7mu 19 | curl $CERAMIC_CLIENT_URL/api/v0/streams/kjzl6cwe1jw149zuvayqa89nhmlvwm0pkdkj0awlxhmtbbay6i972xuwy14jg4f 20 | 21 | # === run ceramic integration tests === 22 | yarn test:ceramic-integration -------------------------------------------------------------------------------- /identity/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gitcoin/passport-identity", 3 | "version": "1.0.0", 4 | "license": "MIT", 5 | "main": "dist/commonjs/index.js", 6 | "directories": { 7 | "src": "src", 8 | "dist": "dist" 9 | }, 10 | "files": [ 11 | "src", 12 | "dist" 13 | ], 14 | "publishConfig": { 15 | "access": "public" 16 | }, 17 | "dependencies": { 18 | "@ethersproject/base64": "^5.6.1", 19 | "@ethersproject/providers": "^5.6.2", 20 | "@gitcoin/passport-types": "^1.0.0", 21 | "axios": "^0.26.1" 22 | }, 23 | "devDependencies": { 24 | "jest": "^27.5.1", 25 | "ts-jest": "^27.1.4", 26 | "typescript": "^5.3.3" 27 | }, 28 | "scripts": { 29 | "clean": "rimraf dist node_modules", 30 | "build": "tsc", 31 | "test": "jest --verbose", 32 | "lint": "tsc --noEmit && eslint --ext .ts,.js,.tsx .", 33 | "prettier": "prettier --write ." 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /platforms/src/Gitcoin/Providers/__tests__/gitcoinGrantsContributorStatistics.test.ts: -------------------------------------------------------------------------------- 1 | // ----- Libs 2 | import { GitcoinContributorStatisticsProvider } from "../gitcoinGrantsContributorStatistics"; 3 | /* eslint-disable no-use-before-define */ 4 | describe("GitcoinContributorStatisticsProvider class", function () { 5 | it("should be properly initialized", function () { 6 | const threshold = 193; 7 | const receivingAttribute = "aaa"; 8 | const recordAttribute = "bbb"; 9 | const gitcoin = new GitcoinContributorStatisticsProvider({ 10 | threshold, 11 | receivingAttribute, 12 | recordAttribute, 13 | }); 14 | 15 | expect(gitcoin.type).toEqual(`GitcoinContributorStatistics#${recordAttribute}#${threshold}`); 16 | expect(gitcoin.urlPath).toEqual("/contributor_statistics"); 17 | expect(gitcoin._options).toEqual({ threshold, receivingAttribute, recordAttribute }); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /app/utils/theme/themes.tsx: -------------------------------------------------------------------------------- 1 | import { Theme } from "./types"; 2 | import palette from "./palette"; 3 | 4 | export const LUNARPUNK_DARK_MODE: Theme = { 5 | colors: { 6 | background: palette.black, 7 | background2: palette.darkPurple, 8 | background3: palette.iris, 9 | background4: palette.nightBlue, 10 | foreground: palette.white, 11 | foreground2: palette.iceBlue, 12 | foreground3: palette.ironGray, 13 | foreground4: palette.seaFoam, 14 | foreground5: palette.green, 15 | foreground6: palette.turquoise, 16 | foreground7: palette.paleYellow, 17 | text1: palette.white, 18 | text2: palette.seaFoam, 19 | text3: palette.nightBlue, 20 | text4: palette.black, 21 | text5: palette.gray, 22 | text6: palette.iceBlue, 23 | focus: palette.red, 24 | }, 25 | fonts: { 26 | body: "futura-pt", 27 | heading: "futura-pt", 28 | alt: "DM Mono", 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /app/config/providers.ts: -------------------------------------------------------------------------------- 1 | import { PLATFORM_ID } from "@gitcoin/passport-types"; 2 | import { platforms, ProviderSpec, PlatformGroupSpec } from "@gitcoin/passport-platforms"; 3 | export type { ProviderSpec, PlatformGroupSpec }; 4 | 5 | export type UpdatedPlatforms = { 6 | [key: string]: boolean; 7 | }; 8 | 9 | // Platform -> Provider[] 10 | export type Providers = { 11 | [platform in PLATFORM_ID]: PlatformGroupSpec[]; 12 | }; 13 | 14 | const providerConfigs = Object.entries(platforms).reduce( 15 | (configs, [platformName, platform]) => ({ 16 | ...configs, 17 | [platformName]: platform?.ProviderConfig, 18 | }), 19 | {} as Record 20 | ); 21 | 22 | export const STAMP_PROVIDERS: Readonly = { 23 | ...providerConfigs, 24 | Signer: [ 25 | { 26 | platformGroup: "Account Name", 27 | providers: [{ title: "Encrypted", name: "Signer" }], 28 | }, 29 | ], 30 | }; 31 | -------------------------------------------------------------------------------- /iam/src/issuers.ts: -------------------------------------------------------------------------------- 1 | import * as DIDKit from "@spruceid/didkit-wasm-node"; 2 | 3 | const key = process.env.IAM_JWK; 4 | const __issuer = DIDKit.keyToDID("key", key); 5 | const eip712Key = process.env.IAM_JWK_EIP712; 6 | const __eip712Issuer = DIDKit.keyToDID("ethr", eip712Key); 7 | 8 | const validIssuers = new Set([__issuer, __eip712Issuer]); 9 | 10 | export function getEd25519IssuerKey(): string { 11 | return key; 12 | } 13 | 14 | export function getEd25519Issuer(): string { 15 | return __issuer; 16 | } 17 | 18 | export function getEip712IssuerKey(): string { 19 | return eip712Key; 20 | } 21 | 22 | export function getEip712Issuer(): string { 23 | return __eip712Issuer; 24 | } 25 | 26 | export function getIssuerKey(signatureType: string): string { 27 | return signatureType === "EIP712" ? eip712Key : key; 28 | } 29 | 30 | export function hasValidIssuer(issuer: string): boolean { 31 | return validIssuers.has(issuer); 32 | } 33 | -------------------------------------------------------------------------------- /platforms/src/NFT/App-Bindings.ts: -------------------------------------------------------------------------------- 1 | import { AppContext, ProviderPayload } from "../types"; 2 | import { Platform } from "../utils/platform"; 3 | 4 | export class NFTPlatform extends Platform { 5 | platformId = "NFT"; 6 | path = "NFT"; 7 | isEVM = true; 8 | 9 | banner = { 10 | content: 11 | "Click verify to process your Ethereum Mainnet NFTs. Passport uses a constantly evolving model to review your NFT activity and compare against known Sybil behavior. The number of points you'll receive is based on many factors related to the overall NFT portfolio of the address.", 12 | cta: { 13 | label: "Learn more", 14 | url: "https://support.passport.xyz/passport-knowledge-base/how-do-i-add-passport-stamps/nft-stamp", 15 | }, 16 | }; 17 | 18 | async getProviderPayload(appContext: AppContext): Promise { 19 | const result = await Promise.resolve({}); 20 | return result; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/public/assets/whiteBgShieldExclamation.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /platforms/src/ZkSync/App-Bindings.ts: -------------------------------------------------------------------------------- 1 | import { AppContext, ProviderPayload } from "../types"; 2 | import { Platform } from "../utils/platform"; 3 | export class ZkSyncPlatform extends Platform { 4 | platformId = "ZkSync"; 5 | path = "ZkSync"; 6 | isEVM = true; 7 | 8 | banner = { 9 | content: 10 | "Click verify to process your zkSync Era transactions. Passport uses a constantly evolving model to review your transaction history and compare against known Sybil behavior. The number of points you'll receive is based on many factors related to the overall activity of the address.", 11 | cta: { 12 | label: "Learn more", 13 | url: "https://support.passport.xyz/passport-knowledge-base/how-do-i-add-passport-stamps/zksync-stamp", 14 | }, 15 | }; 16 | 17 | async getProviderPayload(appContext: AppContext): Promise { 18 | const result = await Promise.resolve({}); 19 | return result; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/jest.config.ts: -------------------------------------------------------------------------------- 1 | const nextJest = require("next/jest"); 2 | global.TextDecoder = require("util").TextDecoder; 3 | 4 | const createJestConfig = nextJest({ 5 | // Provide the path to your Next.js app to load next.config.js and .env files in your test environment 6 | dir: "./", 7 | }); 8 | 9 | // Add any custom config to be passed to Jest 10 | const customJestConfig = { 11 | testEnvironment: "jest-environment-jsdom", 12 | testEnvironmentOptions: {}, 13 | moduleNameMapper: { 14 | "\\.(gif|ttf|eot|svg|png)$": "/__mocks__/fileMock.js", 15 | "\\.(css|less|sass|scss)$": "identity-obj-proxy", 16 | // Handle module aliases 17 | "^@/components/(.*)$": "/components/$1", 18 | "^@/pages/(.*)$": "/pages/$1", 19 | }, 20 | setupFilesAfterEnv: ["/jest.setup.ts"], 21 | setupFiles: ["jest-localstorage-mock"], 22 | resetMocks: false, 23 | }; 24 | 25 | export default createJestConfig(customJestConfig); 26 | -------------------------------------------------------------------------------- /app/context/userState.tsx: -------------------------------------------------------------------------------- 1 | // --- React Methods 2 | import React from "react"; 3 | 4 | // --- Utils & configs 5 | import { atom } from "jotai"; 6 | 7 | type UserWarningName = "expiredStamp" | "cacaoError"; 8 | 9 | export interface UserWarning { 10 | content: React.ReactNode; 11 | icon?: React.ReactNode; 12 | name?: UserWarningName; 13 | dismissible?: boolean; 14 | link?: string; 15 | } 16 | 17 | export const userWarningAtom = atom(undefined); 18 | 19 | export interface UserVerification { 20 | loading: boolean; 21 | success: boolean; 22 | error?: string; 23 | } 24 | 25 | export const userVerificationAtom = atom({ 26 | loading: false, 27 | success: false, 28 | error: undefined, 29 | }); 30 | 31 | export const mutableUserVerificationAtom = atom( 32 | (get) => get(userVerificationAtom), 33 | (_get, set, newState: UserVerification) => { 34 | set(userVerificationAtom, newState); 35 | } 36 | ); 37 | -------------------------------------------------------------------------------- /app/public/assets/githubWhiteStampIcon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /database-client/composedb.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "anchor": {}, 3 | "http-api": { 4 | "cors-allowed-origins": [".*"], 5 | "admin-dids": [ 6 | "did:key:z6MknU3gBqubYTbXbHnHzpJurGyrssbpLdS7Mbz1uHdGdzdo", 7 | "did:key:z6Mki9zj9fFYxBbQcaC6EJvST8XHv7i4iXsP281gJV5nM5Hy#z6Mki9zj9fFYxBbQcaC6EJvST8XHv7i4iXsP281gJV5nM5Hy" 8 | ] 9 | }, 10 | "ipfs": { "mode": "bundled" }, 11 | "logger": { "log-level": 2, "log-to-files": false }, 12 | "metrics": { "metrics-exporter-enabled": false, "metrics-port": 9090 }, 13 | "network": { "name": "inmemory" }, 14 | "node": {}, 15 | "state-store": { 16 | "mode": "fs", 17 | "local-directory": "/Users/timschultz/repos/compose-db/ceramic-app/ceramic-app-app/.ceramic/.ceramic/statestore/" 18 | }, 19 | "indexing": { 20 | "db": "sqlite:///Users/timschultz/repos/compose-db/ceramic-app/ceramic-app-app/.ceramic/indexing.sqlite", 21 | "allow-queries-before-historical-sync": true, 22 | "models": [] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/jest.setup.ts: -------------------------------------------------------------------------------- 1 | import "@testing-library/jest-dom"; 2 | import { TextDecoder, TextEncoder } from "util"; 3 | global.TextDecoder = TextDecoder as any; 4 | global.TextEncoder = TextEncoder as any; 5 | 6 | const mockWallet = { 7 | address: "0xfF7edbD01e9d044486781ff52c42EA7a01612644", 8 | chain: "0xa", 9 | provider: jest.fn(), 10 | }; 11 | 12 | jest.mock("@web3-onboard/react", () => ({ 13 | init: () => ({ 14 | connectWallet: () => Promise.resolve([mockWallet]), 15 | disconnectWallet: () => Promise.resolve(), 16 | state: { 17 | select: () => ({ 18 | subscribe: () => {}, 19 | }), 20 | }, 21 | }), 22 | useConnectWallet: () => [{ wallet: mockWallet }, () => Promise.resolve([mockWallet]), jest.fn()], 23 | })); 24 | 25 | jest.mock("@web3-onboard/injected-wallets", () => ({ 26 | __esModule: true, 27 | default: () => {}, 28 | })); 29 | 30 | jest.mock("@web3-onboard/walletconnect", () => ({ 31 | __esModule: true, 32 | default: () => {}, 33 | })); 34 | -------------------------------------------------------------------------------- /platforms/src/Coinbase/Providers-config.ts: -------------------------------------------------------------------------------- 1 | import { PlatformSpec, PlatformGroupSpec, Provider } from "../types"; 2 | import { CoinbaseProvider } from "./Providers/coinbase"; 3 | 4 | export const PlatformDetails: PlatformSpec = { 5 | icon: "./assets/coinbaseStampIcon.svg", 6 | platform: "Coinbase", 7 | name: "Coinbase", 8 | description: "Confirm Your Coinbase Verified ID", 9 | connectMessage: "Connect Account", 10 | website: "https://www.coinbase.com/onchain-verify", 11 | }; 12 | 13 | export const ProviderConfig: PlatformGroupSpec[] = [ 14 | { 15 | platformGroup: "Account & Onchain Identity", 16 | providers: [ 17 | { 18 | title: "Privacy-First Verification", 19 | description: 20 | "Your privacy is paramount. We only retain a unique hash to acknowledge your account's verification.", 21 | name: "CoinbaseDualVerification", 22 | }, 23 | ], 24 | }, 25 | ]; 26 | 27 | export const providers: Provider[] = [new CoinbaseProvider()]; 28 | -------------------------------------------------------------------------------- /app/components/Checkbox.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Switch } from "@headlessui/react"; 3 | import { CheckIcon } from "@heroicons/react/24/outline"; 4 | 5 | type CheckboxProps = { 6 | onChange: (checked: boolean) => void; 7 | className?: string; 8 | checked?: boolean; 9 | disabled?: boolean; 10 | id?: string; 11 | }; 12 | 13 | const Checkbox = ({ className, ...props }: CheckboxProps) => { 14 | return ( 15 | 23 | 24 | 25 | ); 26 | }; 27 | 28 | export default Checkbox; 29 | -------------------------------------------------------------------------------- /app/public/assets/check-icon2.svg: -------------------------------------------------------------------------------- 1 | 2 | 11 | 13 | 19 | 26 | 27 | -------------------------------------------------------------------------------- /database-client/src/utils.ts: -------------------------------------------------------------------------------- 1 | import { Stamp, VerifiableCredential } from "@gitcoin/passport-types"; 2 | 3 | export function getTilesToCreate(stamps: Stamp[], did: string, existingStamps?: Stamp[]) { 4 | const existingStampIdentifiers = existingStamps.map((s) => { 5 | const credential: VerifiableCredential = s.credential; 6 | return { hash: credential.credentialSubject.hash, issuanceDate: credential.issuanceDate } 7 | }); 8 | 9 | const stampsToSave = stamps.filter((s) => { 10 | const identifier = { hash: s.credential.credentialSubject.hash, issuanceDate: s.credential.issuanceDate }; 11 | // Check that stamp is not already saved and that the DID matches the passport DID 12 | return !existingStampIdentifiers.some(existingIdentifier => ( 13 | existingIdentifier.hash === identifier.hash && 14 | existingIdentifier.issuanceDate === identifier.issuanceDate 15 | )) && s.credential.issuer.toLocaleLowerCase() === did; 16 | }); 17 | 18 | return stampsToSave 19 | } 20 | -------------------------------------------------------------------------------- /identity/__mocks__/didkit.js: -------------------------------------------------------------------------------- 1 | const keyToDID = jest.fn(() => Promise.resolve("did:key:PUBLIC_KEY")); 2 | 3 | const keyToVerificationMethod = jest.fn(() => Promise.resolve("did:key:PUBLIC_KEY#PUBLIC_KEY")); 4 | 5 | const issueCredential = jest.fn((credential) => 6 | Promise.resolve( 7 | JSON.stringify({ 8 | ...JSON.parse(credential), 9 | proof: {}, 10 | }) 11 | ) 12 | ); 13 | const verifyCredential = jest.fn(() => 14 | Promise.resolve( 15 | JSON.stringify({ 16 | checks: [], 17 | warnings: [], 18 | errors: [], 19 | }) 20 | ) 21 | ); 22 | 23 | const clearDidkitMocks = () => { 24 | keyToDID.mockClear(); 25 | keyToVerificationMethod.mockClear(); 26 | issueCredential.mockClear(); 27 | verifyCredential.mockClear(); 28 | }; 29 | 30 | // ---- Generate & Verify methods 31 | module.exports = { 32 | keyToDID, 33 | keyToVerificationMethod, 34 | issueCredential, 35 | verifyCredential, 36 | 37 | /* Mock helpers */ 38 | clearDidkitMocks, 39 | }; 40 | -------------------------------------------------------------------------------- /app/public/assets/verification-failed.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /js-ceramic/ceramic/daemon.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "anchor": { 3 | "auth-method": "did" 4 | }, 5 | "http-api": { 6 | "cors-allowed-origins": [".*"], 7 | "admin-dids": ["did:key:z6MkgUzNYV8J1yw43wj9K2CbhTZoN25uZ6TJ3Gi4cYVpZyDb"] 8 | }, 9 | "ipfs": { 10 | "mode": "bundled", 11 | "disable-peer-data-sync": false 12 | }, 13 | "logger": { 14 | "log-level": 2, 15 | "log-to-files": false 16 | }, 17 | "metrics": { 18 | "metrics-exporter-enabled": false 19 | }, 20 | "network": { 21 | "name": "testnet-clay" 22 | }, 23 | "node": { 24 | "private-seed-url": "inplace:ed25519#b7d1fc8db6162b7fd9ab19a5486d9c5f8f0134ac87932266033732d5fb5f1c26" 25 | }, 26 | "state-store": { 27 | "mode": "fs", 28 | "local-directory": "/ceramic/statestore/" 29 | }, 30 | "indexing": { 31 | "db": "sqlite:///ceramic/indexing.sqlite", 32 | "allow-queries-before-historical-sync": true, 33 | "disable-composedb": false, 34 | "enable-historical-sync": false 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /iam/src/scripts/buildProviderBitMapInfo.ts: -------------------------------------------------------------------------------- 1 | import dotenv from "dotenv"; 2 | import { writeFileSync } from "fs"; 3 | import { join } from "path"; 4 | import axios from "axios"; 5 | 6 | import { StampMetadata, mapBitMapInfo } from "../utils/easPassportSchema"; 7 | 8 | dotenv.config(); 9 | 10 | const stampMetadataEndpoint = process.env.PASSPORT_STAMP_METADATA_PATH || ""; 11 | 12 | const formatProviderBitMapInfo = async (): Promise => { 13 | const stampMetadata: { 14 | data: StampMetadata; 15 | } = await axios.get(stampMetadataEndpoint); 16 | 17 | const bitMapInfo = mapBitMapInfo(stampMetadata.data); 18 | 19 | const outPath = join(__dirname, "..", "static", "providerBitMapInfo.json"); 20 | console.log(`Saving platform info to JSON file at ${outPath}`); 21 | 22 | writeFileSync(outPath, JSON.stringify(bitMapInfo)); 23 | }; 24 | 25 | formatProviderBitMapInfo() 26 | .catch((err) => { 27 | console.error(err); 28 | }) 29 | .finally(() => { 30 | console.log("Done! BitMap info saved"); 31 | }); 32 | -------------------------------------------------------------------------------- /infra/README.md: -------------------------------------------------------------------------------- 1 | ## New Stack 2 | ```sh 3 | pulumi stack init gitcoin/dpopp/stackName 4 | ``` 5 | 6 | ## AWS Configuration 7 | ```sh 8 | # set aws profile credentials 9 | aws configure --profile user1 10 | ``` 11 | *Note* you will also need to select this profile in your env: 12 | ```sh 13 | export AWS_PROFILE=user1 14 | ``` 15 | 16 | ## Configure environment 17 | 18 | Before we can run `pulumi up`, there are a few resources that need to be built/pushed to the aws environment, such as the secret manager, Route53 Hosted Zone, and iam-server docker image. Once these are present on aws, we must reference them in our local environment in order for pulumi to be aware of them: 19 | 20 | ```sh 21 | # set route53 zone 22 | export ROUTE_53_ZONE=... 23 | # set environment-specific domain 24 | export DOMAIN=... 25 | # secrets manager resource ARN 26 | export IAM_SERVER_SSM_ARN=... 27 | # iam-server docker image in ECR 28 | export DOCKER_GTC_PASSPORT_IAM_IMAGE=... 29 | ``` 30 | 31 | ## Pulumi deploy 32 | ```sh 33 | pulumi up 34 | ``` 35 | -------------------------------------------------------------------------------- /app/public/assets/facebookStampIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /platforms/src/utils/simpleEvmProvider.ts: -------------------------------------------------------------------------------- 1 | // ----- Types 2 | import type { Provider, ProviderOptions } from "../types"; 3 | import type { RequestPayload, VerifiedPayload } from "@gitcoin/passport-types"; 4 | 5 | // Export a simple Provider as an example 6 | export class SimpleEvmProvider implements Provider { 7 | // Give the provider a type so that we can select it with a payload 8 | type = "SimpleEvm"; 9 | // Options can be set here and/or via the constructor 10 | _options = { 11 | valid: "true", 12 | }; 13 | 14 | // construct the provider instance with supplied options 15 | constructor(options: ProviderOptions = {}) { 16 | this._options = { ...this._options, ...options }; 17 | } 18 | 19 | // verify that the proof object contains valid === "true" 20 | verify(payload: RequestPayload): Promise { 21 | return Promise.resolve({ 22 | valid: payload?.proofs?.valid === this._options.valid, 23 | record: { 24 | address: payload.address, 25 | }, 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /database-client/README.md: -------------------------------------------------------------------------------- 1 | # database-client 2 | 3 | ## Running the Ceramic integration tests locally 4 | 5 | > Start up the Ceramic daemon in another thread 6 | 7 | ```bash 8 | yarn run ceramic 9 | ``` 10 | 11 | > Run the integration tests 12 | 13 | ```bash 14 | yarn run test:integration 15 | ``` 16 | 17 | **Note:** Use the `CERAMIC_CLIENT_URL` env variable (like `export CERAMIC_CLIENT_URL=http://127.0.0.1:7007`) to change the ceramic client URL for the integration tests if required. 18 | 19 | ## Running the Ceramic integration tests in Docker 20 | 21 | IMPORTANT this will overwrite your `schemas/scripts/create-model.json` and `schemas/scripts/publish-model.json` files! Make a backup of these files! 22 | 23 | ```bash 24 | docker-compose up -d 25 | ``` 26 | 27 | Tests are flaky the first time, possibly due to connection issues with the Ceramic node. If tests fail due to an error like `request to http://localhost:7007/api/v0/streams failed, reason: connect ECONNREFUSED 127.0.0.1:7007`, try running `docker-compose up -d` again to re-run the tests. 28 | -------------------------------------------------------------------------------- /platforms/src/Outdid/Providers-config.ts: -------------------------------------------------------------------------------- 1 | import { PlatformSpec, PlatformGroupSpec, Provider } from "../types"; 2 | import { OutdidProvider } from "./Providers/outdid"; 3 | 4 | export const PlatformDetails: PlatformSpec = { 5 | icon: "./assets/outdidStampIcon.svg", 6 | platform: "Outdid", 7 | name: "Outdid", 8 | description: "Outdid's free ZK ID verification brings a strong sybil signal with complete privacy and anonymity.", 9 | connectMessage: "Connect Account", 10 | website: "https://outdid.io/", 11 | }; 12 | 13 | export const ProviderConfig: PlatformGroupSpec[] = [ 14 | { 15 | platformGroup: "Name of the Stamp platform group", 16 | providers: [ 17 | { 18 | title: "ZK-prove your identity with Outdid", 19 | description: "Outdid uses zero-knowledge cryptography to ensure you are a unique human without revealing any personal information.", 20 | name: "Outdid", 21 | }, 22 | ] 23 | }, 24 | ]; 25 | 26 | export const providers: Provider[] = [new OutdidProvider()] -------------------------------------------------------------------------------- /app/config/filters.ts: -------------------------------------------------------------------------------- 1 | export const STAMP_FILTERS: { 2 | [key: string]: { 3 | name: string; 4 | stamps: { 5 | [key: string]: string[]; 6 | }; 7 | }; 8 | } = { 9 | "bankless-academy": { 10 | name: "Bankless Academy", 11 | stamps: { 12 | Google: ["Account Name"], 13 | Ens: ["Account Name"], 14 | Poh: ["Account Name"], 15 | Twitter: ["Account Name"], 16 | Brightid: ["Account Name"], 17 | Linkedin: ["Account Name"], 18 | Discord: ["Account Name"], 19 | }, 20 | }, 21 | }; 22 | 23 | export const getStampProviderFilters = (filter: string): any => { 24 | let stampFilters: any = false; 25 | if (Object.keys(STAMP_FILTERS).includes(filter)) { 26 | stampFilters = STAMP_FILTERS[filter].stamps; 27 | } 28 | return stampFilters; 29 | }; 30 | 31 | export const getFilterName = (filter: string): any => { 32 | let filterName: any = false; 33 | if (Object.keys(STAMP_FILTERS).includes(filter)) { 34 | filterName = STAMP_FILTERS[filter].name; 35 | } 36 | return filterName; 37 | }; 38 | -------------------------------------------------------------------------------- /app/components/MinimalHeader.tsx: -------------------------------------------------------------------------------- 1 | // --- React methods 2 | import React, { useMemo } from "react"; 3 | 4 | type MinimalHeaderProps = { 5 | className?: string; 6 | }; 7 | 8 | const getAssets = () => { 9 | return { 10 | passportLogo: "/assets/passportLogoWhite.svg", 11 | gitcoinLogo: "/assets/gitcoinLogoWhite.svg", 12 | logoLine: "/assets/logoLine.svg", 13 | emphasisColor: "white", 14 | }; 15 | }; 16 | 17 | const MinimalHeader = ({ className }: MinimalHeaderProps): JSX.Element => { 18 | const assets = useMemo(() => getAssets(), []); 19 | 20 | return ( 21 |
22 |
23 | Gitcoin Logo 24 | Logo Line 25 | Passport Logo 26 |
Passport
27 |
28 |
29 | ); 30 | }; 31 | 32 | export default MinimalHeader; 33 | -------------------------------------------------------------------------------- /platforms/src/ETH/App-Bindings.ts: -------------------------------------------------------------------------------- 1 | import { AppContext, ProviderPayload } from "../types"; 2 | import { Platform } from "../utils/platform"; 3 | export class ETHPlatform extends Platform { 4 | platformId = "ETH"; 5 | path = "ETH"; 6 | clientId: string = null; 7 | redirectUri: string = null; 8 | isEVM = true; 9 | 10 | banner = { 11 | heading: ` 12 | Click verify to process your Ethereum L1 transactions. Gitcoin uses a constantly 13 | evolving model to review your transaction history and compare against known Sybil 14 | behavior. The number of points you'll receive is based on many factors related to 15 | the overall activity of the address. 16 | `, 17 | cta: { 18 | label: "Learn more", 19 | url: "https://support.passport.xyz/passport-knowledge-base/stamps/how-do-i-add-passport-stamps/verifying-ethereum-transactions-to-passport", 20 | }, 21 | }; 22 | 23 | async getProviderPayload(appContext: AppContext): Promise { 24 | const result = await Promise.resolve({}); 25 | return result; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /platforms/src/Linkedin/App-Bindings.ts: -------------------------------------------------------------------------------- 1 | import { PlatformOptions } from "../types"; 2 | import { Platform } from "../utils/platform"; 3 | export class LinkedinPlatform extends Platform { 4 | platformId = "Linkedin"; 5 | path = "linkedin"; 6 | 7 | constructor(options: PlatformOptions = {}) { 8 | super(); 9 | this.clientId = options.clientId as string; 10 | this.redirectUri = options.redirectUri as string; 11 | this.state = options.state as string; 12 | this.banner = { 13 | cta: { 14 | label: "Learn more", 15 | url: "https://support.passport.xyz/passport-knowledge-base/stamps/how-do-i-add-passport-stamps/guide-to-add-a-linkedin-stamp-to-passport", 16 | }, 17 | } 18 | } 19 | 20 | async getOAuthUrl(state: string): Promise { 21 | const linkedinUrl = await Promise.resolve( 22 | `https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=${this.clientId}&redirect_uri=${this.redirectUri}&state=${state}&scope=r_emailaddress%20r_liteprofile` 23 | ); 24 | return linkedinUrl; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /platforms/src/utils/clearTextSimpleProvider.ts: -------------------------------------------------------------------------------- 1 | // ----- Types 2 | import type { Provider, ProviderOptions } from "../types"; 3 | import type { RequestPayload, VerifiedPayload } from "@gitcoin/passport-types"; 4 | 5 | // Export a simple Provider as an example 6 | export class ClearTextSimpleProvider implements Provider { 7 | // Give the provider a type so that we can select it with a payload 8 | type = "ClearTextSimple"; 9 | // Options can be set here and/or via the constructor 10 | _options = { 11 | valid: "true", 12 | }; 13 | 14 | // construct the provider instance with supplied options 15 | constructor(options: ProviderOptions = {}) { 16 | this._options = { ...this._options, ...options }; 17 | } 18 | 19 | // verify that the proof object contains valid === "true" 20 | verify(payload: RequestPayload): Promise { 21 | return Promise.resolve({ 22 | valid: payload?.proofs?.valid === this._options.valid, 23 | record: { 24 | username: payload?.proofs?.username || "", 25 | pii: "Username", 26 | }, 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /platforms/src/Idena/Providers-config.ts: -------------------------------------------------------------------------------- 1 | import { PlatformSpec, PlatformGroupSpec, Provider } from "../types"; 2 | import { 3 | IdenaStateNewbieProvider, 4 | IdenaStateVerifiedProvider, 5 | IdenaStateHumanProvider, 6 | } from "./Providers/IdenaStateProvider"; 7 | 8 | export const PlatformDetails: PlatformSpec = { 9 | icon: "./assets/idenaStampIcon.svg", 10 | platform: "Idena", 11 | name: "Idena", 12 | description: "Connect to Idena to verify your human identity.", 13 | connectMessage: "Verify Identity", 14 | enablePlatformCardUpdate: true, 15 | website: "https://idena.io/", 16 | }; 17 | 18 | export const ProviderConfig: PlatformGroupSpec[] = [ 19 | { 20 | platformGroup: "Identity State", 21 | providers: [ 22 | { title: "Newbie", name: "IdenaState#Newbie" }, 23 | { title: "Verified", name: "IdenaState#Verified" }, 24 | { title: "Human", name: "IdenaState#Human" }, 25 | ], 26 | }, 27 | ]; 28 | 29 | export const providers: Provider[] = [ 30 | new IdenaStateNewbieProvider(), 31 | new IdenaStateVerifiedProvider(), 32 | new IdenaStateHumanProvider(), 33 | ]; 34 | -------------------------------------------------------------------------------- /platforms/src/Lens/App-Bindings.ts: -------------------------------------------------------------------------------- 1 | import { AppContext, ProviderPayload } from "../types"; 2 | import { Platform } from "../utils/platform"; 3 | 4 | export class LensPlatform extends Platform { 5 | platformId = "Lens"; 6 | path = "Lens"; 7 | clientId: string = null; 8 | redirectUri: string = null; 9 | isEVM = true; 10 | 11 | banner = { 12 | content: `To add the Lens Stamp to your Gitcoin Passport, ensure you're using 13 | your Lens Handle, not your profile. A Lens Handle is your unique identifier on 14 | Lens, required for verification. Obtain a Handle either through the Lens beta or 15 | by purchasing one from NFT marketplaces. Note: Verification may be delayed after 16 | claiming your Handle.`, 17 | cta: { 18 | label: "Learn more", 19 | url: "https://support.passport.xyz/passport-knowledge-base/stamps/how-do-i-add-passport-stamps/guide-to-add-lens-stamp-to-gitcoin-passport", 20 | }, 21 | }; 22 | 23 | async getProviderPayload(appContext: AppContext): Promise { 24 | const result = await Promise.resolve({}); 25 | return result; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /platforms/src/GuildXYZ/Providers-config.ts: -------------------------------------------------------------------------------- 1 | import { PlatformSpec, PlatformGroupSpec, Provider } from "../types"; 2 | import { GuildAdminProvider, GuildPassportMemberProvider } from "./Providers/guildXYZ"; 3 | 4 | export const PlatformDetails: PlatformSpec = { 5 | icon: "./assets/guildXYZStampIcon.svg", 6 | platform: "GuildXYZ", 7 | name: "Guild Membership and Roles", 8 | description: "Connect to Guild to verify your membership in open source communities.", 9 | connectMessage: "Verify Guilds", 10 | isEVM: true, 11 | website: "https://guild.xyz/", 12 | }; 13 | 14 | export const ProviderConfig: PlatformGroupSpec[] = [ 15 | { 16 | platformGroup: "Guild Admin", 17 | providers: [ 18 | { 19 | title: "Owner or Administrator of one or more guilds*", 20 | name: "GuildAdmin", 21 | }, 22 | ], 23 | }, 24 | { 25 | platformGroup: "Guild Passport Member", 26 | providers: [{ title: "Member with 1 or more roles in Gitcoin Passport Guild", name: "GuildPassportMember" }], 27 | }, 28 | ]; 29 | 30 | export const providers: Provider[] = [new GuildAdminProvider(), new GuildPassportMemberProvider()]; 31 | -------------------------------------------------------------------------------- /app/components/DropDownIcon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const DropDownIcon = ({ 4 | isOpen, 5 | className, 6 | width, 7 | height, 8 | }: { 9 | isOpen: boolean; 10 | className?: string; 11 | width?: string; 12 | height?: string; 13 | }) => ( 14 |
15 | 23 | 27 | 28 |
29 | ); 30 | -------------------------------------------------------------------------------- /.github/workflows/deploy_to_branch.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to Branch (Release Frontend) 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | refspec: 7 | required: true 8 | type: string 9 | owner: 10 | required: true 11 | type: string 12 | repo: 13 | required: true 14 | type: string 15 | destination_branch: 16 | required: true 17 | type: string 18 | 19 | 20 | permissions: write-all 21 | jobs: 22 | deploy_to_branch: 23 | name: Deploy to Branch 24 | runs-on: ubuntu-latest 25 | steps: 26 | - uses: actions/checkout@v3 27 | with: 28 | token: ${{ secrets.github_token }} 29 | ref: main 30 | fetch-depth: 0 31 | - name: Push to Branch 32 | run: | 33 | git fetch 34 | git checkout -b ${{ inputs.destination_branch }} 35 | git reset --hard ${{ inputs.refspec }} 36 | git reset HEAD -- .github/workflows 37 | git remote set-url origin https://${{ secrets.github_token }}@github.com/${{ inputs.owner }}/${{ inputs.repo }}.git 38 | git push origin ${{ inputs.destination_branch }} -f 39 | -------------------------------------------------------------------------------- /platforms/src/Discord/App-Bindings.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import { AccessTokenResult, AppContext, ProviderPayload, PlatformOptions } from "../types"; 3 | import { Platform } from "../utils/platform"; 4 | 5 | export class DiscordPlatform extends Platform { 6 | path = "discord"; 7 | platformId = "Discord"; 8 | 9 | clientId: string = null; 10 | redirectUri: string = null; 11 | 12 | constructor(options: PlatformOptions = {}) { 13 | super(); 14 | this.clientId = options.clientId as string; 15 | this.redirectUri = options.redirectUri as string; 16 | this.banner = { 17 | cta: { 18 | label: "Learn more", 19 | url: "https://support.passport.xyz/passport-knowledge-base/stamps/how-do-i-add-passport-stamps/connecting-a-discord-account-to-passport", 20 | }, 21 | }; 22 | } 23 | 24 | async getOAuthUrl(state: string): Promise { 25 | const authUrl = `https://discord.com/api/oauth2/authorize?response_type=code&scope=identify&client_id=${process.env.NEXT_PUBLIC_PASSPORT_DISCORD_CLIENT_ID}&state=${state}&redirect_uri=${process.env.NEXT_PUBLIC_PASSPORT_DISCORD_CALLBACK}`; 26 | return authUrl; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/components/Toggle.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Switch } from "@headlessui/react"; 3 | import { CheckIcon, XMarkIcon } from "@heroicons/react/24/outline"; 4 | 5 | const toggleIconClassName = "relative left-[2px] top-[2px] h-4 w-4 stroke-[3]"; 6 | 7 | type ToggleProps = { 8 | className?: string; 9 | checked?: boolean; 10 | onChange: (checked: boolean) => void; 11 | disabled?: boolean; 12 | id?: string; 13 | }; 14 | 15 | const Toggle = ({ className, ...props }: ToggleProps) => { 16 | return ( 17 | 21 | 22 | 23 | 24 | 25 | 26 | ); 27 | }; 28 | 29 | export default Toggle; 30 | -------------------------------------------------------------------------------- /app/config/feature_flags.ts: -------------------------------------------------------------------------------- 1 | export type FEATURE_FLAG_TYPE = "FF_CHAIN_SYNC"; 2 | 3 | export let FeatureFlags: Record = { 4 | FF_CHAIN_SYNC: false, 5 | }; 6 | 7 | function configureFeatureFlag( 8 | queryString: URLSearchParams, 9 | featureFlag: FEATURE_FLAG_TYPE, 10 | envVar: string | undefined 11 | ) { 12 | // We want to allow the user to override feature flags in URLs 13 | const urlValue = queryString.get(featureFlag); 14 | 15 | if (urlValue && ["on", "off"].includes(urlValue)) { 16 | FeatureFlags[featureFlag] = urlValue === "on"; 17 | } else { 18 | FeatureFlags[featureFlag] = envVar === "on"; 19 | } 20 | } 21 | 22 | // FeatureFlags need to reliably be set before the chains are configured, and chains 23 | // must be configured before web3Onboard which must be initialized before any 24 | // React code, so we'll do it here. 25 | 26 | if (typeof window !== "undefined") { 27 | const queryString = new URLSearchParams(window?.location?.search); 28 | 29 | // The env var names can't be dynamic due to the way Next.js works 30 | configureFeatureFlag(queryString, "FF_CHAIN_SYNC", process.env.NEXT_PUBLIC_FF_CHAIN_SYNC); 31 | } 32 | -------------------------------------------------------------------------------- /app/public/assets/snapshotStampIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | icon 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /platforms/src/utils/handleAxiosError.ts: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | // Based on https://axios-http.com/docs/handling_errors 4 | export const handleAxiosError = ( 5 | error: any, 6 | label: string, 7 | // Accept any child class of Error 8 | ErrorClass: new (...args: any[]) => T, 9 | secretsToHide?: string[] 10 | ) => { 11 | if (axios.isAxiosError(error)) { 12 | let message = `Error making ${label} request, `; 13 | if (error.response) { 14 | // Received a non 2xx response 15 | const { data, status, headers } = error.response; 16 | message += `received error response with code ${status}: ${JSON.stringify(data)}, headers: ${JSON.stringify( 17 | headers 18 | )}`; 19 | } else if (error.request) { 20 | // No response received 21 | message += "no response received, " + error.message; 22 | } else { 23 | // Something happened in setting up the request that triggered an Error 24 | message += error.message; 25 | } 26 | secretsToHide?.forEach((secret) => { 27 | message = message.replace(secret, "[SECRET]"); 28 | }); 29 | throw new ErrorClass(message); 30 | } 31 | throw error; 32 | }; 33 | -------------------------------------------------------------------------------- /app/components/Warning.tsx: -------------------------------------------------------------------------------- 1 | import { ExclamationCircleIcon } from "@heroicons/react/24/solid"; 2 | 3 | import { CONTENT_MAX_WIDTH } from "./PageWidthGrid"; 4 | 5 | import { UserWarning } from "../context/userState"; 6 | 7 | export default function Warning({ 8 | userWarning, 9 | onDismiss, 10 | className, 11 | }: { 12 | userWarning: UserWarning; 13 | onDismiss: () => void; 14 | className?: string; 15 | }) { 16 | const { content, dismissible, icon, link } = userWarning; 17 | return ( 18 |
21 | {icon || ( 22 |
23 | 24 |
25 | )} 26 | {content}{" "} 27 | {link && ( 28 | 29 | More information. 30 | 31 | )} 32 | {dismissible && ( 33 | 36 | )} 37 |
38 | ); 39 | } 40 | -------------------------------------------------------------------------------- /app/public/assets/twitterStampIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /identity/__mocks__/axios.js: -------------------------------------------------------------------------------- 1 | // IAM challenge response 2 | const MOCK_CHALLENGE_VALUE = "this is a challenge"; 3 | const MOCK_CHALLENGE_CREDENTIAL = { 4 | credentialSubject: { 5 | challenge: "this is a challenge", 6 | }, 7 | }; 8 | const MOCK_CHALLENGE_RESPONSE_BODY = { 9 | credential: MOCK_CHALLENGE_CREDENTIAL, 10 | }; 11 | 12 | // IAM verify response 13 | const MOCK_VERIFY_RESPONSE_BODY = { 14 | credential: { type: ["VerifiableCredential"] }, 15 | record: { 16 | type: "test", 17 | address: "0xmyAddress", 18 | }, 19 | }; 20 | 21 | const clearAxiosMocks = () => { 22 | post.mockClear(); 23 | }; 24 | 25 | const post = jest.fn(async (url, data) => { 26 | if (url.endsWith("/challenge")) { 27 | return { 28 | data: MOCK_CHALLENGE_RESPONSE_BODY, 29 | }; 30 | } 31 | 32 | if (url.endsWith("/verify")) { 33 | return { 34 | data: MOCK_VERIFY_RESPONSE_BODY, 35 | }; 36 | } 37 | 38 | throw Error("This endpoint is not set up!"); 39 | }); 40 | 41 | module.exports = { 42 | post, 43 | 44 | /* Mock values and helpers */ 45 | clearAxiosMocks, 46 | MOCK_CHALLENGE_VALUE, 47 | MOCK_CHALLENGE_CREDENTIAL, 48 | MOCK_CHALLENGE_RESPONSE_BODY, 49 | MOCK_VERIFY_RESPONSE_BODY, 50 | }; 51 | -------------------------------------------------------------------------------- /app/__tests__/utils/helpers.test.ts: -------------------------------------------------------------------------------- 1 | import { createSignedPayload } from "../../utils/helpers"; 2 | import { Cacao } from "@didtools/cacao"; 3 | 4 | jest.mock("@didtools/cacao", () => ({ 5 | Cacao: { 6 | fromBlockBytes: jest.fn().mockImplementation((_) => { 7 | return { 8 | p: { 9 | iss: "did:ethr:0x123", 10 | }, 11 | }; 12 | }), 13 | }, 14 | })); 15 | 16 | describe("createSignedPayload", () => { 17 | it("should sign", async () => { 18 | const mockDid = { 19 | createDagJWS: () => ({ 20 | jws: { 21 | link: { 22 | bytes: [7, 8, 9], 23 | }, 24 | payload: { 25 | hello: "world", 26 | }, 27 | signatures: ["0x123"], 28 | }, 29 | cacaoBlock: [0, 1, 2], 30 | }), 31 | }; 32 | 33 | const signedPayload = await createSignedPayload(mockDid as any, { hello: "world" }); 34 | 35 | expect(Cacao.fromBlockBytes).toHaveBeenCalledWith([0, 1, 2]); 36 | 37 | expect(signedPayload).toEqual({ 38 | signatures: ["0x123"], 39 | payload: { hello: "world" }, 40 | cid: [7, 8, 9], 41 | cacao: [0, 1, 2], 42 | issuer: "did:ethr:0x123", 43 | }); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /app/public/assets/coinbaseStampIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/public/assets/phiLogoIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | phi logo bold 8080ff-white@1x 4 | 5 | 12 | 13 | -------------------------------------------------------------------------------- /schemas/README.md: -------------------------------------------------------------------------------- 1 | # Gitcoin Passport Ceramic Ceramic Compose DB Setup 2 | 3 | ## Setup 4 | 5 | - `yarn install` 6 | - `yarn start:ceramic` to start local ceramic node 7 | 8 | ## GraphQL 9 | 10 | - Run the following commands to compile and deploy the schemas. I was unable to run them via yarn and had to run them from the command line. Will need ti fix passing the arguments via yarn. 11 | 12 | ````bash 13 | TODO: Fix 14 | 15 | ```bash 16 | composedb composite:create models/passportStamps.graphql --output=composites/gitcoin-passport-stamps-composite.json --did-private-key=${PRIVAKE_KEY} 17 | 18 | 19 | composedb composite:deploy composites/gitcoin-passport-stamps-composite.json --ceramic-url=${CERAMIC_URL} --did-private-key=${PRIVAKE_KEY} 20 | 21 | 22 | composedb composite:compile composites/gitcoin-passport-stamps-composite.json definitions/gitcoin-passport-stamps.ts --ceramic-url=${CERAMIC_URL} 23 | ```` 24 | 25 | - Open `schemas/definitions/gitcoin-passport-stamps.ts` and copy the `definition` object into `schemas/composites/gitcoin-passport-stamps-composite.json` 26 | - run `yarn composedb graphql:server --ceramic-url=${CERAMIC_URL} --graphiql composites/gitcoin-passport-stamps-composite.json --did-private-key=${PRIVAKE_KEY} --port=5005` 27 | -------------------------------------------------------------------------------- /app/public/assets/googleStampIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /platforms/src/GtcStaking/__tests__/gtcStaking.test.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import { GtcStakingProvider } from "../Providers/GtcStaking"; 3 | 4 | describe("GtcStakingProvider", () => { 5 | beforeAll(() => { 6 | process.env.GTC_STAKING_ROUNDS = 7 | // eslint-disable-next-line prettier/prettier, quotes 8 | '[{"id": 4, "start": 1693526400, "duration": 7592340}, {"id": 5, "start": 1701118741, "duration": 8157658}]'; 9 | }); 10 | afterEach(() => { 11 | jest.restoreAllMocks(); 12 | }); 13 | it("should get round 4 based on timestamp", () => { 14 | jest.spyOn(Date, "now").mockImplementation(() => new Date("2023-11-15T00:00:00Z").getTime()); 15 | const provider = new GtcStakingProvider({ type: "SelfStakingBronze", thresholdAmount: new BigNumber(5) }); 16 | 17 | const round = provider.getCurrentRound(); 18 | expect(round).toEqual(4); 19 | }); 20 | it("should get round 5 based on timestamp", () => { 21 | jest.spyOn(Date, "now").mockImplementation(() => new Date("2023-11-28T00:00:00Z").getTime()); 22 | const provider = new GtcStakingProvider({ type: "SelfStakingBronze", thresholdAmount: new BigNumber(5) }); 23 | 24 | const round = provider.getCurrentRound(); 25 | expect(round).toEqual(5); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /platforms/src/Holonym/App-Bindings.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import React from "react"; 3 | import { AppContext, Platform, ProviderPayload } from "../types"; 4 | 5 | export class HolonymPlatform implements Platform { 6 | platformId = "Holonym"; 7 | path = "Holonym"; 8 | 9 | banner = { 10 | heading: "To add the Holonym Stamp to your Gitcoin Passport...", 11 | content: ( 12 |
    13 |
  • Have a smartphone, valid ID, and an Ethereum wallet with ~$10 in ETH or AVAX.
  • 14 |
  • 15 | Go to Holonym's page, verify your ID by connecting your wallet, pay the verification fee, and follow prompts 16 | to take ID and selfie photos. 17 |
  • 18 |
  • After verification, mint the SBT to your wallet, then link it to your Gitcoin Passport by verifying it.
  • 19 |
20 | ), 21 | cta: { 22 | label: "Learn more", 23 | url: "https://support.passport.xyz/passport-knowledge-base/stamps/how-do-i-add-passport-stamps/guide-to-add-holonym-stamp-to-gitcoin-passport", 24 | }, 25 | }; 26 | 27 | async getProviderPayload(appContext: AppContext): Promise { 28 | const result = await Promise.resolve({}); 29 | return result; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /platforms/src/Google/App-Bindings.ts: -------------------------------------------------------------------------------- 1 | // For details on the google oauth2 flow, please check the following ressources: 2 | // - https://developers.google.com/identity/protocols/oauth2 3 | // - https://developers.google.com/oauthplayground/ 4 | 5 | import { PlatformOptions } from "../types"; 6 | import { Platform } from "../utils/platform"; 7 | 8 | export class GooglePlatform extends Platform { 9 | platformId = "Google"; 10 | path = "Google"; 11 | clientId: string = null; 12 | redirectUri: string = null; 13 | 14 | constructor(options: PlatformOptions = {}) { 15 | super(); 16 | this.clientId = options.clientId as string; 17 | this.redirectUri = options.redirectUri as string; 18 | this.banner = { 19 | cta: { 20 | label: "Learn more", 21 | url: "https://support.passport.xyz/passport-knowledge-base/stamps/how-do-i-add-passport-stamps/connecting-a-google-account-to-passport", 22 | }, 23 | }; 24 | } 25 | 26 | getOAuthUrl(state: string): Promise { 27 | return new Promise((resolve) => { 28 | resolve( 29 | `https://accounts.google.com/o/oauth2/v2/auth?redirect_uri=${this.redirectUri}&prompt=consent&response_type=code&client_id=${this.clientId}&scope=email+profile&access_type=offline&state=${state}` 30 | ); 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /platforms/src/utils/simpleProvider.ts: -------------------------------------------------------------------------------- 1 | // ----- Types 2 | import type { Provider, ProviderOptions } from "../types"; 3 | import type { RequestPayload, VerifiedPayload } from "@gitcoin/passport-types"; 4 | 5 | // Export a simple Provider as an example 6 | export class SimpleProvider implements Provider { 7 | // Give the provider a type so that we can select it with a payload 8 | type = "Simple"; 9 | // Options can be set here and/or via the constructor 10 | _options = { 11 | valid: "true", 12 | }; 13 | 14 | // construct the provider instance with supplied options 15 | constructor(options: ProviderOptions = {}) { 16 | this._options = { ...this._options, ...options }; 17 | } 18 | 19 | // verify that the proof object contains valid === "true" 20 | verify(payload: RequestPayload): Promise { 21 | return Promise.resolve(verifySimpleProvider(payload)); 22 | } 23 | } 24 | 25 | // This is pulled out to allow easier mocking in tests 26 | export const verifySimpleProvider = (payload: RequestPayload): VerifiedPayload => { 27 | const valid = payload?.proofs?.valid === "true"; 28 | const errors = valid ? [] : ["Proof is not valid"]; 29 | return { 30 | valid, 31 | errors, 32 | record: { 33 | username: payload?.proofs?.username || "", 34 | }, 35 | }; 36 | }; 37 | -------------------------------------------------------------------------------- /app/components/LoadingCard.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const LoadingCard = ({ className }: { className?: string }): JSX.Element => { 4 | return ( 5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | 20 |
21 |
22 |
23 |
24 |
25 | ); 26 | }; 27 | -------------------------------------------------------------------------------- /app/config/stamp_config.ts: -------------------------------------------------------------------------------- 1 | import { SignatureType } from "@gitcoin/passport-types"; 2 | 3 | export const IAM_SIGNATURE_TYPE: SignatureType = 4 | process.env.NEXT_PUBLIC_PASSPORT_IAM_SIGNATURE_TYPE?.toLowerCase() === "eip712" ? "EIP712" : "Ed25519"; 5 | 6 | // Change of plan. We should not use stamps v2. 7 | // The diferentiation of what exact stamp format is used can be made based on data in the stamp itself. 8 | // There is no need to store additional metadata. 9 | // References to STAMPS_V2 shall be deleted in the future. 10 | // const USE_STAMPS_V2 = IAM_SIGNATURE_TYPE === "EIP712"; 11 | const USE_STAMPS_V2 = false; 12 | 13 | const CERAMIC_CACHE_ENDPOINT_V1 = process.env.NEXT_PUBLIC_CERAMIC_CACHE_ENDPOINT; 14 | const CERAMIC_CACHE_ENDPOINT_V2 = process.env.NEXT_PUBLIC_CERAMIC_CACHE_ENDPOINT_V2; 15 | export const CERAMIC_CACHE_ENDPOINT = USE_STAMPS_V2 ? CERAMIC_CACHE_ENDPOINT_V2 : CERAMIC_CACHE_ENDPOINT_V1; 16 | 17 | const IAM_ISSUER_DID_V1 = process.env.NEXT_PUBLIC_PASSPORT_IAM_ISSUER_DID || ""; 18 | const IAM_ISSUER_DID_V2 = process.env.NEXT_PUBLIC_PASSPORT_IAM_ISSUER_DID_V2 || ""; 19 | 20 | // We are going tu support multiple valid issuers 21 | export const IAM_VALID_ISSUER_DIDS = new Set([IAM_ISSUER_DID_V2, IAM_ISSUER_DID_V1]); 22 | 23 | export const iamUrl = process.env.NEXT_PUBLIC_PASSPORT_IAM_URL || "http://localhost:80/api/"; 24 | -------------------------------------------------------------------------------- /app/__mocks__/@gitcoin/passport-database-client/index.js: -------------------------------------------------------------------------------- 1 | export const createPassportMock = jest.fn(); 2 | export const getPassportMock = jest.fn().mockImplementation(() => { 3 | return { 4 | passport: { 5 | stamps: [], 6 | }, 7 | errorDetails: {}, 8 | status: "Success", 9 | }; 10 | }); 11 | export const addStampMock = jest.fn(); 12 | export const addStampsMock = jest.fn(); 13 | export const deleteStampMock = jest.fn(); 14 | export const deleteStampsMock = jest.fn(); 15 | 16 | export const CeramicDatabase = jest.fn().mockImplementation(() => { 17 | return { 18 | constructor() { 19 | return { 20 | createPassport: createPassportMock, 21 | getPassport: getPassportMock, 22 | addStamp: addStampMock, 23 | addStamps: addStampMock, 24 | deleteStamp: deleteStampMock, 25 | deleteStamps: deleteStampsMock, 26 | }; 27 | }, 28 | }; 29 | }); 30 | 31 | export const PassportDatabase = jest.fn().mockImplementation(() => { 32 | return { 33 | constructor() { 34 | return { 35 | createPassport: createPassportMock, 36 | getPassport: getPassportMock, 37 | addStamp: addStampMock, 38 | addStamps: addStampMock, 39 | deleteStamp: deleteStampMock, 40 | deleteStamps: deleteStampsMock, 41 | }; 42 | }, 43 | }; 44 | }); 45 | -------------------------------------------------------------------------------- /platforms/src/Github/App-Bindings.ts: -------------------------------------------------------------------------------- 1 | import { PlatformOptions } from "../types"; 2 | import { Platform } from "../utils/platform"; 3 | export class GithubPlatform extends Platform { 4 | platformId = "Github"; 5 | path = "github"; 6 | clientId: string = null; 7 | redirectUri: string = null; 8 | 9 | constructor(options: PlatformOptions = {}) { 10 | super(); 11 | this.clientId = options.clientId as string; 12 | this.redirectUri = options.redirectUri as string; 13 | this.banner = { 14 | heading: "Verifying Contribution Activity", 15 | content: 16 | "For the Contribution Activity credentials, make sure your contribution data is public. Go to Settings > Public Profile > Contributions & Activity and uncheck 'Make profile private and hide activity'. Verify your contribution history with your Gitcoin Passport!", 17 | cta: { 18 | label: "Learn more", 19 | url: "https://support.passport.xyz/passport-knowledge-base/stamps/how-do-i-add-passport-stamps/connecting-a-github-account-to-passport", 20 | }, 21 | }; 22 | } 23 | 24 | async getOAuthUrl(state: string): Promise { 25 | const githubUrl = await Promise.resolve( 26 | `https://github.com/login/oauth/authorize?client_id=${this.clientId}&redirect_uri=${this.redirectUri}&state=${state}` 27 | ); 28 | return githubUrl; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/components/SIWEButton.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Button, ButtonProps } from "./Button"; 3 | 4 | const SIWEButton = (props: ButtonProps & { enableEthBranding: boolean }) => { 5 | const { enableEthBranding, ...rest } = props; 6 | return ( 7 | 23 | ); 24 | }; 25 | 26 | export default SIWEButton; 27 | -------------------------------------------------------------------------------- /app/components/Header.tsx: -------------------------------------------------------------------------------- 1 | // --- React methods 2 | import React, { useEffect } from "react"; 3 | import { userWarningAtom } from "../context/userState"; 4 | import { PAGE_PADDING } from "./PageWidthGrid"; 5 | import Warning from "./Warning"; 6 | import MinimalHeader from "./MinimalHeader"; 7 | import { SupportBanner } from "../components/SupportBanner"; 8 | import { useAtom } from "jotai"; 9 | import { useSupportBanners } from "../hooks/useSupportBanners"; 10 | 11 | const Header = (): JSX.Element => { 12 | const [userWarning, setUserWarning] = useAtom(userWarningAtom); 13 | const { banners, loadBanners } = useSupportBanners(); 14 | 15 | useEffect(() => { 16 | loadBanners(); 17 | }, [loadBanners]); 18 | 19 | return ( 20 |
21 |
22 | 23 |
24 | {!(userWarning || banners.length) && ( 25 |
26 | )} 27 |
28 | {userWarning && setUserWarning(undefined)} />} 29 |
30 |
31 | 32 |
33 |
34 | ); 35 | }; 36 | 37 | export default Header; 38 | -------------------------------------------------------------------------------- /app/utils/theme/setCustomizationTheme.tsx: -------------------------------------------------------------------------------- 1 | import { hexToRGB } from "./palette"; 2 | import { CustomizationTheme } from "./types"; 3 | 4 | export const setCustomizationTheme = ({ colors }: CustomizationTheme) => { 5 | const r = document.documentElement; 6 | 7 | // We can do this for every sort of tailwind class and CSS prop, 8 | // for example if we need a dynamic caption size we can do... 9 | // (note: this is untested and just an example, but it should work) 10 | // r.style.setProperty("--font-customization-caption-size", font.customizationCaptionSize); 11 | // we'd set it to something like 1.5rem or 24px 12 | // and then in tailwind config... 13 | // fontSize: { "customization-caption-size": "var(--font-customization-caption-size)" } 14 | // and then we can use it in our components... 15 | //

Hello world

16 | 17 | r.style.setProperty("--color-customization-background-1", convertHexToRGB(colors.customizationBackground1)); 18 | r.style.setProperty("--color-customization-background-2", convertHexToRGB(colors.customizationBackground2)); 19 | r.style.setProperty("--color-customization-foreground-1", convertHexToRGB(colors.customizationForeground1)); 20 | }; 21 | 22 | const convertHexToRGB = (color: string) => { 23 | if (color.startsWith("#")) { 24 | return hexToRGB(color); 25 | } 26 | return color; 27 | }; 28 | -------------------------------------------------------------------------------- /app/public/assets/hexagonIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/public/assets/lockIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/styles/globals.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=DM+Mono&display=swap"); 2 | 3 | /* This sources Adobe CC fonts */ 4 | @import url("https://use.typekit.net/tdl1ktm.css"); 5 | 6 | @tailwind base; 7 | @tailwind components; 8 | @tailwind utilities; 9 | 10 | @layer components { 11 | .verify-btn { 12 | @apply w-full border-t border-accent-2 p-2 hover:text-accent-3; 13 | } 14 | .verify-btn:disabled { 15 | @apply text-gray-400; 16 | } 17 | } 18 | 19 | .step-icon-inner { 20 | width: 0.625rem; 21 | height: 0.625rem; 22 | 23 | animation-duration: 1s; 24 | animation-name: step-icon-loading; 25 | animation-iteration-count: infinite; 26 | animation-direction: alternate; 27 | animation-timing-function: ease; 28 | } 29 | 30 | :root { 31 | --onboard-shadow-3: none; 32 | --account-center-position-top: -14px; 33 | --account-center-position-right: 4.1rem; 34 | --account-center-border-radius: 16px; 35 | --onboard-action-required-btn-text-color: #fff; 36 | --onboard-font-family-normal: var(--font-body); 37 | } 38 | 39 | .override-text-color * { 40 | color: inherit !important; 41 | } 42 | 43 | @media (max-width: 1020px /* md */) { 44 | :root { 45 | --account-center-position-right: 24px; 46 | } 47 | } 48 | 49 | @media (max-width: 480px /* base */) { 50 | :root { 51 | --account-center-position-right: 0px; 52 | --onboard-modal-top: 0; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/components/Button.tsx: -------------------------------------------------------------------------------- 1 | import React, { ButtonHTMLAttributes, useMemo } from "react"; 2 | 3 | export type ButtonProps = ButtonHTMLAttributes & { 4 | variant?: "primary" | "secondary" | "custom"; 5 | }; 6 | 7 | // Children are centered and spaced out with gap-4. 8 | // If your button just contains text, simply use the text 9 | // e.g. 10 | // If your button has an icon or other elements, just include both elements 11 | // e.g. 12 | export const Button = ({ variant, className, ...props }: ButtonProps) => { 13 | const variantClassName = useMemo(() => { 14 | if (variant === "custom") { 15 | return ""; 16 | } else if (variant === "secondary") { 17 | return "text-color-1 bg-background border border-foreground-3 hover:border-foreground-4"; 18 | } else { 19 | // primary, default 20 | return "text-color-4 bg-gradient-to-r from-foreground-2 to-foreground-2 hover:to-foreground-4"; 21 | } 22 | }, [variant]); 23 | 24 | return ( 25 |