From 892d7c0aad83f7b3df418fcbc31de1398fec47c6 Mon Sep 17 00:00:00 2001 From: Nicolas Burtey Date: Sun, 23 Jul 2023 11:55:21 +0100 Subject: [PATCH] feat: hydra integration chore: renaming folder chore: moving some of the change to the rest layer instead of graphql chore: some iteration on hydra feat: adding scope middleware chore: testing client credentials chore: adding appId to know whether a request comes from hydra or kratos chore: update docs fix: test? --- .env | 1 + apps/consent/.env.test | 3 + apps/consent/.eslintrc.json | 3 + apps/consent/.gitignore | 35 + apps/consent/README.md | 24 + .../button/primary-button-component.tsx | 32 + .../button/secondary-button-component.tsx | 28 + .../components/captcha-challenge/index.tsx | 57 + .../app/components/card/card.module.css | 19 + apps/consent/app/components/card/index.tsx | 12 + .../consent/app/components/form-component.tsx | 18 + apps/consent/app/components/heading.tsx | 11 + .../app/components/input-component.tsx | 21 + apps/consent/app/components/loader/index.tsx | 18 + .../app/components/loader/loader.module.css | 17 + apps/consent/app/components/logo/index.tsx | 12 + .../app/components/main-container/index.tsx | 15 + .../scope-item/scope-item.module.css | 21 + .../app/components/scope-item/scope-item.tsx | 21 + apps/consent/app/components/separator.tsx | 23 + apps/consent/app/components/sub-heading.tsx | 14 + .../two-fa-verification-code-form.tsx | 37 + .../verification-code-form.tsx | 58 + apps/consent/app/consent/page.tsx | 202 + apps/consent/app/error.tsx | 22 + apps/consent/app/favicon.ico | Bin 0 -> 36843 bytes apps/consent/app/globals.css | 56 + apps/consent/app/graphql/apollo-config.ts | 15 + apps/consent/app/graphql/generated.ts | 1874 ++++++ .../queries/get-supported-countries.ts | 35 + apps/consent/app/graphql/queries/me-query.ts | 27 + apps/consent/app/index.types.ts | 10 + apps/consent/app/layout.tsx | 41 + apps/consent/app/loading.tsx | 12 + apps/consent/app/login/email-login.types.ts | 4 + apps/consent/app/login/page.tsx | 185 + apps/consent/app/login/phone/form.tsx | 118 + apps/consent/app/login/phone/page.tsx | 66 + .../app/login/phone/phone-login.types.ts | 19 + .../consent/app/login/phone/server-actions.ts | 131 + apps/consent/app/login/verification/form.tsx | 70 + apps/consent/app/login/verification/page.tsx | 59 + .../app/login/verification/server-actions.ts | 156 + apps/consent/app/logout/page.tsx | 76 + apps/consent/app/oidc-cert.ts | 89 + apps/consent/app/page.tsx | 15 + apps/consent/codegen.yml | 60 + apps/consent/cypress.config.ts | 23 + .../e2e/email-sign-in/login-email.cy.ts | 28 + .../e2e/phone-sign-in/login-phone.cy.ts | 46 + .../e2e/phone-sign-in/verification.cy.ts | 22 + apps/consent/cypress/e2e/spec.cy.ts | 2 + apps/consent/cypress/support/commands.ts | 71 + apps/consent/cypress/support/e2e.ts | 20 + apps/consent/cypress/support/test-config.ts | 21 + apps/consent/dev/get-email-code.sh | 0 apps/consent/dev/get-url.sh | 18 + apps/consent/dev/script.log | 12 + apps/consent/dev/setup-user.sh | 41 + apps/consent/env.ts | 17 + apps/consent/next.config.js | 7 + apps/consent/package.json | 51 + apps/consent/postcss.config.js | 6 + apps/consent/public/blink_logo.svg | 51 + apps/consent/public/gt.js | 389 ++ apps/consent/public/next.svg | 1 + apps/consent/public/vercel.svg | 1 + .../services/galoy-auth/auth-instance.ts | 9 + apps/consent/services/galoy-auth/index.ts | 67 + apps/consent/services/hydra.ts | 10 + apps/consent/tailwind.config.ts | 20 + apps/consent/tsconfig.json | 27 + apps/consent/yarn.lock | 5883 +++++++++++++++++ apps/dashboard/.env | 5 + apps/dashboard/.eslintrc.json | 3 + apps/dashboard/.gitignore | 35 + apps/dashboard/README.md | 36 + .../app/api/auth/[...nextauth]/route.ts | 53 + apps/dashboard/app/favicon.ico | Bin 0 -> 25931 bytes apps/dashboard/app/globals.css | 27 + apps/dashboard/app/graphql/config.ts | 4 + apps/dashboard/app/graphql/generated.ts | 3362 ++++++++++ apps/dashboard/app/graphql/index.ts | 26 + apps/dashboard/app/layout.tsx | 22 + apps/dashboard/app/page.tsx | 56 + apps/dashboard/bun.lockb | Bin 0 -> 302628 bytes apps/dashboard/codegen.yml | 66 + apps/dashboard/next.config.js | 4 + apps/dashboard/package.json | 40 + apps/dashboard/postcss.config.js | 6 + apps/dashboard/public/next.svg | 1 + apps/dashboard/public/vercel.svg | 1 + apps/dashboard/tailwind.config.ts | 20 + apps/dashboard/tsconfig.json | 27 + core/api/.eslintrc.json | 2 +- core/api/dev/ory/oathkeeper.yml | 2 +- core/api/dev/ory/oathkeeper_rules.yaml | 18 +- .../src/app/authentication/index.types.d.ts | 4 +- core/api/src/app/authentication/login.ts | 16 +- core/api/src/graphql/index.ts | 6 +- core/api/src/servers/authorization/index.ts | 9 +- core/api/src/servers/graphql-main-server.ts | 12 +- core/api/src/servers/graphql-server.ts | 14 +- core/api/src/servers/index.files.d.ts | 7 +- core/api/src/servers/middlewares/scope.ts | 78 + core/api/src/servers/middlewares/session.ts | 7 +- 106 files changed, 14630 insertions(+), 24 deletions(-) create mode 100644 apps/consent/.env.test create mode 100644 apps/consent/.eslintrc.json create mode 100644 apps/consent/.gitignore create mode 100644 apps/consent/README.md create mode 100644 apps/consent/app/components/button/primary-button-component.tsx create mode 100644 apps/consent/app/components/button/secondary-button-component.tsx create mode 100644 apps/consent/app/components/captcha-challenge/index.tsx create mode 100644 apps/consent/app/components/card/card.module.css create mode 100644 apps/consent/app/components/card/index.tsx create mode 100644 apps/consent/app/components/form-component.tsx create mode 100644 apps/consent/app/components/heading.tsx create mode 100644 apps/consent/app/components/input-component.tsx create mode 100644 apps/consent/app/components/loader/index.tsx create mode 100644 apps/consent/app/components/loader/loader.module.css create mode 100644 apps/consent/app/components/logo/index.tsx create mode 100644 apps/consent/app/components/main-container/index.tsx create mode 100644 apps/consent/app/components/scope-item/scope-item.module.css create mode 100644 apps/consent/app/components/scope-item/scope-item.tsx create mode 100644 apps/consent/app/components/separator.tsx create mode 100644 apps/consent/app/components/sub-heading.tsx create mode 100644 apps/consent/app/components/varification-components/two-fa-verification-code-form.tsx create mode 100644 apps/consent/app/components/varification-components/verification-code-form.tsx create mode 100644 apps/consent/app/consent/page.tsx create mode 100644 apps/consent/app/error.tsx create mode 100644 apps/consent/app/favicon.ico create mode 100644 apps/consent/app/globals.css create mode 100644 apps/consent/app/graphql/apollo-config.ts create mode 100644 apps/consent/app/graphql/generated.ts create mode 100644 apps/consent/app/graphql/queries/get-supported-countries.ts create mode 100644 apps/consent/app/graphql/queries/me-query.ts create mode 100644 apps/consent/app/index.types.ts create mode 100644 apps/consent/app/layout.tsx create mode 100644 apps/consent/app/loading.tsx create mode 100644 apps/consent/app/login/email-login.types.ts create mode 100644 apps/consent/app/login/page.tsx create mode 100644 apps/consent/app/login/phone/form.tsx create mode 100644 apps/consent/app/login/phone/page.tsx create mode 100644 apps/consent/app/login/phone/phone-login.types.ts create mode 100644 apps/consent/app/login/phone/server-actions.ts create mode 100644 apps/consent/app/login/verification/form.tsx create mode 100644 apps/consent/app/login/verification/page.tsx create mode 100644 apps/consent/app/login/verification/server-actions.ts create mode 100644 apps/consent/app/logout/page.tsx create mode 100644 apps/consent/app/oidc-cert.ts create mode 100644 apps/consent/app/page.tsx create mode 100644 apps/consent/codegen.yml create mode 100644 apps/consent/cypress.config.ts create mode 100644 apps/consent/cypress/e2e/email-sign-in/login-email.cy.ts create mode 100644 apps/consent/cypress/e2e/phone-sign-in/login-phone.cy.ts create mode 100644 apps/consent/cypress/e2e/phone-sign-in/verification.cy.ts create mode 100644 apps/consent/cypress/e2e/spec.cy.ts create mode 100644 apps/consent/cypress/support/commands.ts create mode 100644 apps/consent/cypress/support/e2e.ts create mode 100644 apps/consent/cypress/support/test-config.ts create mode 100755 apps/consent/dev/get-email-code.sh create mode 100644 apps/consent/dev/get-url.sh create mode 100644 apps/consent/dev/script.log create mode 100755 apps/consent/dev/setup-user.sh create mode 100644 apps/consent/env.ts create mode 100644 apps/consent/next.config.js create mode 100644 apps/consent/package.json create mode 100644 apps/consent/postcss.config.js create mode 100644 apps/consent/public/blink_logo.svg create mode 100644 apps/consent/public/gt.js create mode 100644 apps/consent/public/next.svg create mode 100644 apps/consent/public/vercel.svg create mode 100644 apps/consent/services/galoy-auth/auth-instance.ts create mode 100644 apps/consent/services/galoy-auth/index.ts create mode 100644 apps/consent/services/hydra.ts create mode 100644 apps/consent/tailwind.config.ts create mode 100644 apps/consent/tsconfig.json create mode 100644 apps/consent/yarn.lock create mode 100755 apps/dashboard/.env create mode 100644 apps/dashboard/.eslintrc.json create mode 100644 apps/dashboard/.gitignore create mode 100644 apps/dashboard/README.md create mode 100644 apps/dashboard/app/api/auth/[...nextauth]/route.ts create mode 100644 apps/dashboard/app/favicon.ico create mode 100644 apps/dashboard/app/globals.css create mode 100644 apps/dashboard/app/graphql/config.ts create mode 100644 apps/dashboard/app/graphql/generated.ts create mode 100644 apps/dashboard/app/graphql/index.ts create mode 100644 apps/dashboard/app/layout.tsx create mode 100644 apps/dashboard/app/page.tsx create mode 100755 apps/dashboard/bun.lockb create mode 100644 apps/dashboard/codegen.yml create mode 100644 apps/dashboard/next.config.js create mode 100644 apps/dashboard/package.json create mode 100644 apps/dashboard/postcss.config.js create mode 100644 apps/dashboard/public/next.svg create mode 100644 apps/dashboard/public/vercel.svg create mode 100644 apps/dashboard/tailwind.config.ts create mode 100644 apps/dashboard/tsconfig.json create mode 100644 core/api/src/servers/middlewares/scope.ts diff --git a/.env b/.env index d98d12a90f8..d793718b5e4 100644 --- a/.env +++ b/.env @@ -107,6 +107,7 @@ export MATTERMOST_WEBHOOK_URL="https://chat.galoy.io/hooks/sometoken" export KRATOS_PG_CON="postgres://dbuser:secret@localhost:5433/default?sslmode=disable" + export UNSECURE_DEFAULT_LOGIN_CODE="000000" export UNSECURE_IP_FROM_REQUEST_OBJECT=true diff --git a/apps/consent/.env.test b/apps/consent/.env.test new file mode 100644 index 00000000000..3c9fa2d343d --- /dev/null +++ b/apps/consent/.env.test @@ -0,0 +1,3 @@ +export CLIENT_ID=569c1e70-7875-47af-a6b5-1e1bf3a7b905 +export CLIENT_SECRET=oWSmag.dm~EGsl7iCj8groGVjZ +export AUTHORIZATION_URL=http://127.0.0.1:4444/oauth2/auth?client_id=569c1e70-7875-47af-a6b5-1e1bf3a7b905&scope=offline%20transactions:read&response_type=code&redirect_uri=http://localhost:3000/&state=kfISr3GhH0rqheByU6A6hqIG_f14pCGkZLSCUTHnvlI diff --git a/apps/consent/.eslintrc.json b/apps/consent/.eslintrc.json new file mode 100644 index 00000000000..bffb357a712 --- /dev/null +++ b/apps/consent/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/apps/consent/.gitignore b/apps/consent/.gitignore new file mode 100644 index 00000000000..8f322f0d8f4 --- /dev/null +++ b/apps/consent/.gitignore @@ -0,0 +1,35 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/apps/consent/README.md b/apps/consent/README.md new file mode 100644 index 00000000000..721ef44079f --- /dev/null +++ b/apps/consent/README.md @@ -0,0 +1,24 @@ +# login-consent-provider + +This is the User Login and Consent flow for the Galoy stack over the OAuth2 service (Hydra) in NextJs. + +## Local set up: +Install dependencies using +``` + yarn install +``` + +Run next.js app in dev mode +```bash + npm run dev + # or + yarn dev + # or + pnpm dev +``` + +###Environment variables +``` + AUTH_URL + HYDRA_ADMIN_URL +``` \ No newline at end of file diff --git a/apps/consent/app/components/button/primary-button-component.tsx b/apps/consent/app/components/button/primary-button-component.tsx new file mode 100644 index 00000000000..adcf9edbca1 --- /dev/null +++ b/apps/consent/app/components/button/primary-button-component.tsx @@ -0,0 +1,32 @@ +"use client"; +import React, { ButtonHTMLAttributes } from "react"; +import { experimental_useFormStatus as useFormStatus } from "react-dom"; +import Loader from "../loader"; + +interface PrimaryButtonProps extends ButtonHTMLAttributes { + label?: string; + children: React.ReactNode; + disabled?: boolean; +} + +const PrimaryButton: React.FC = ({ + children, + disabled = false, + ...buttonProps +}) => { + const { pending } = useFormStatus(); + const loadOrDisable = pending || disabled; + return ( + + ); +}; + +export default PrimaryButton; diff --git a/apps/consent/app/components/button/secondary-button-component.tsx b/apps/consent/app/components/button/secondary-button-component.tsx new file mode 100644 index 00000000000..9956e96bd28 --- /dev/null +++ b/apps/consent/app/components/button/secondary-button-component.tsx @@ -0,0 +1,28 @@ +"use client"; +import React, { ButtonHTMLAttributes } from "react"; +import { experimental_useFormStatus as useFormStatus } from "react-dom"; + +interface SecondaryButtonProps extends ButtonHTMLAttributes { + label?: string; + children: React.ReactNode; + disabled?: boolean; +} + +const SecondaryButton: React.FC = ({ + children, + disabled = false, + ...buttonProps +}) => { + const { pending } = useFormStatus(); + return ( + + ); +}; + +export default SecondaryButton; diff --git a/apps/consent/app/components/captcha-challenge/index.tsx b/apps/consent/app/components/captcha-challenge/index.tsx new file mode 100644 index 00000000000..4aa3548db60 --- /dev/null +++ b/apps/consent/app/components/captcha-challenge/index.tsx @@ -0,0 +1,57 @@ +"use client"; +import { sendPhoneCode } from "@/app/login/phone/server-actions"; +import { memo, useCallback, useEffect } from "react"; +import { toast } from "react-toastify"; + +const CaptchaChallengeComponent: React.FC<{ + id: string; + challenge: string; + formData: { + login_challenge: string; + phone: string; + remember: string; + }; +}> = ({ id, challenge, formData }) => { + console.log({ id, challenge, formData }); + + const captchaHandler = useCallback( + (captchaObj: any) => { + console.log("---------", captchaObj); + const onSuccess = async () => { + const result = captchaObj.getValidate(); + const res = await sendPhoneCode(result, formData); + if (res?.error) { + toast.error(res.message); + } + }; + captchaObj.appendTo("#captcha"); + captchaObj + .onReady(() => { + captchaObj.verify(); + }) + .onSuccess(onSuccess) + .onError((err: unknown) => { + console.debug("[Captcha error]:", err); + }); + }, + [formData] + ); + + useEffect(() => { + // @ts-ignore + window.initGeetest( + { + gt: id, + challenge: challenge, + offline: false, + new_captcha: true, + product: "bind", + lang: "en", + }, + captchaHandler + ); + }, [captchaHandler, id, challenge]); + + return
; +}; +export const CaptchaChallenge = memo(CaptchaChallengeComponent); diff --git a/apps/consent/app/components/card/card.module.css b/apps/consent/app/components/card/card.module.css new file mode 100644 index 00000000000..7e98888271e --- /dev/null +++ b/apps/consent/app/components/card/card.module.css @@ -0,0 +1,19 @@ +.card { + padding: 1.5rem; + margin: 0.5rem; + width: 91%; +} + +@media (min-width: 768px) { + .card { + background-color: white; + border-radius: 0.5rem; + box-shadow: + rgba(0, 0, 0, 0.144) 0px 1px 3px 0px, + rgba(27, 31, 35, 0.144) 0px 0px 0px 1px; + width: auto; + margin: auto; + width: 25em; + padding: 1.5em; + } +} diff --git a/apps/consent/app/components/card/index.tsx b/apps/consent/app/components/card/index.tsx new file mode 100644 index 00000000000..fe27909f5b6 --- /dev/null +++ b/apps/consent/app/components/card/index.tsx @@ -0,0 +1,12 @@ +import React, { ReactNode } from "react" +import styles from "./card.module.css" + +interface CardProps { + children: ReactNode +} + +const Card: React.FC = ({ children }) => { + return
{children}
+} + +export default Card diff --git a/apps/consent/app/components/form-component.tsx b/apps/consent/app/components/form-component.tsx new file mode 100644 index 00000000000..c05f27c06c8 --- /dev/null +++ b/apps/consent/app/components/form-component.tsx @@ -0,0 +1,18 @@ +import React, { FormEvent, ReactNode } from "react"; + +type FromProps = { + action?: (formData: FormData) => void; + onSubmit?: (e: React.FormEvent) => void; + children?: React.ReactNode; +}; + +function FormComponent({ action, children, onSubmit } : FromProps) { + return ( +
+ {children} +
+ ); +}; + +export default FormComponent; + diff --git a/apps/consent/app/components/heading.tsx b/apps/consent/app/components/heading.tsx new file mode 100644 index 00000000000..b6b3bd05c2d --- /dev/null +++ b/apps/consent/app/components/heading.tsx @@ -0,0 +1,11 @@ +import React, { Children } from "react"; + +interface headingProps { + children: React.ReactNode; +} + +function Heading({ children }: headingProps) { + return

{children}

; +} + +export default Heading; diff --git a/apps/consent/app/components/input-component.tsx b/apps/consent/app/components/input-component.tsx new file mode 100644 index 00000000000..52391564224 --- /dev/null +++ b/apps/consent/app/components/input-component.tsx @@ -0,0 +1,21 @@ +import React, { InputHTMLAttributes } from "react" + +interface InputProps extends InputHTMLAttributes { + label?: string + id: string +} + +const InputComponent: React.FC = ({ label, id, ...inputProps }) => { + return ( +
+ {label ? ( + + ) : null} + +
+ ) +} + +export default InputComponent diff --git a/apps/consent/app/components/loader/index.tsx b/apps/consent/app/components/loader/index.tsx new file mode 100644 index 00000000000..51b435ce563 --- /dev/null +++ b/apps/consent/app/components/loader/index.tsx @@ -0,0 +1,18 @@ +import React from "react"; +import styles from "./loader.module.css"; + +interface loaderProps { + size?: string; +} + +export default function loader({ size = "38px" }: loaderProps) { + return ( + + ); +} diff --git a/apps/consent/app/components/loader/loader.module.css b/apps/consent/app/components/loader/loader.module.css new file mode 100644 index 00000000000..c39148e35b7 --- /dev/null +++ b/apps/consent/app/components/loader/loader.module.css @@ -0,0 +1,17 @@ +.loader { + border: 3px solid #d3d3d3; + border-bottom-color: transparent; + border-radius: 50%; + display: inline-block; + box-sizing: border-box; + animation: rotation 1s linear infinite; +} + +@keyframes rotation { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} diff --git a/apps/consent/app/components/logo/index.tsx b/apps/consent/app/components/logo/index.tsx new file mode 100644 index 00000000000..9c860ca6af9 --- /dev/null +++ b/apps/consent/app/components/logo/index.tsx @@ -0,0 +1,12 @@ +import React from "react"; +import Image from "next/image"; + +const Logo: React.FC = () => { + return ( +
+ Galoy +
+ ); +}; + +export default Logo; diff --git a/apps/consent/app/components/main-container/index.tsx b/apps/consent/app/components/main-container/index.tsx new file mode 100644 index 00000000000..77fc3191663 --- /dev/null +++ b/apps/consent/app/components/main-container/index.tsx @@ -0,0 +1,15 @@ +import React, { ReactNode } from "react" + +interface MainContentProps { + children: ReactNode +} + +const MainContent: React.FC = ({ children }) => { + return ( +
+ {children} +
+ ) +} + +export default MainContent diff --git a/apps/consent/app/components/scope-item/scope-item.module.css b/apps/consent/app/components/scope-item/scope-item.module.css new file mode 100644 index 00000000000..66e3bc0922b --- /dev/null +++ b/apps/consent/app/components/scope-item/scope-item.module.css @@ -0,0 +1,21 @@ +.item_container { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + padding: 0.5rem; + background-color: var(--grey5); + border-radius: 0.5rem; + margin-bottom: 0.5em; + position: relative; +} + +.custom_label { + position: relative; + cursor: pointer; + flex-grow: 1; +} + +.text-gray-700 { + color: #4a4a4a; +} diff --git a/apps/consent/app/components/scope-item/scope-item.tsx b/apps/consent/app/components/scope-item/scope-item.tsx new file mode 100644 index 00000000000..ea8720f080f --- /dev/null +++ b/apps/consent/app/components/scope-item/scope-item.tsx @@ -0,0 +1,21 @@ +import React from "react" +import styles from "./scope-item.module.css" + +interface ScopeItemProps { + scope: string +} + +export const ScopeItem: React.FC = ({ scope }) => ( + +) + +export default ScopeItem diff --git a/apps/consent/app/components/separator.tsx b/apps/consent/app/components/separator.tsx new file mode 100644 index 00000000000..acb3af0da74 --- /dev/null +++ b/apps/consent/app/components/separator.tsx @@ -0,0 +1,23 @@ +import React, { ReactNode } from "react"; + +interface SeparatorProps { + children: ReactNode; +} + +const Separator: React.FC = ({ children }) => { + return ( +
+
+
+
+ + {children} + +
+
+
+
+ ); +}; + +export default Separator; diff --git a/apps/consent/app/components/sub-heading.tsx b/apps/consent/app/components/sub-heading.tsx new file mode 100644 index 00000000000..32984a128f7 --- /dev/null +++ b/apps/consent/app/components/sub-heading.tsx @@ -0,0 +1,14 @@ +import React from "react"; + +interface SubheadingProps { + children: React.ReactNode; +} +function SubHeading({ children }: SubheadingProps) { + return ( +
+
{children}
+
+ ); +} + +export default SubHeading; diff --git a/apps/consent/app/components/varification-components/two-fa-verification-code-form.tsx b/apps/consent/app/components/varification-components/two-fa-verification-code-form.tsx new file mode 100644 index 00000000000..7acf2adbb09 --- /dev/null +++ b/apps/consent/app/components/varification-components/two-fa-verification-code-form.tsx @@ -0,0 +1,37 @@ +import React from "react"; +import InputComponent from "@/app/components/input-component"; +import PrimaryButtonComponent from "@/app/components/button/primary-button-component"; + +interface TwoFaVerificationFormProps { + formActionTwoFA: any; + login_challenge: string; + authToken: string; +} + +const TwoFaVerificationForm: React.FC = ({ + formActionTwoFA, + login_challenge, + authToken, +}) => ( + <> +

+ Please Enter Authenticator Code +

+
+ + + + Submit + + +); + +export default TwoFaVerificationForm; diff --git a/apps/consent/app/components/varification-components/verification-code-form.tsx b/apps/consent/app/components/varification-components/verification-code-form.tsx new file mode 100644 index 00000000000..5d1ca1d153f --- /dev/null +++ b/apps/consent/app/components/varification-components/verification-code-form.tsx @@ -0,0 +1,58 @@ +import React from "react"; +import InputComponent from "@/app/components/input-component"; +import PrimaryButtonComponent from "@/app/components/button/primary-button-component"; + +interface VerificationCodeFormProps { + formAction: any; + login_challenge: string; + loginId: string; + remember: string; + loginType: string; + value: string; +} + +const VerificationCodeForm: React.FC = ({ + formAction, + login_challenge, + loginId, + remember, + loginType, + value, +}) => ( + <> +

+ Enter Verification Code +

+
+ + + + + +
+

+ The code was sent to your {loginType}{" "} +

+ {value} +
+ + + Submit + + + +); + +export default VerificationCodeForm; diff --git a/apps/consent/app/consent/page.tsx b/apps/consent/app/consent/page.tsx new file mode 100644 index 00000000000..8cb0e0a3c57 --- /dev/null +++ b/apps/consent/app/consent/page.tsx @@ -0,0 +1,202 @@ +import { redirect } from "next/navigation"; +import React from "react"; +import { hydraClient } from "../../services/hydra"; +import MainContent from "../components/main-container"; +import Card from "../components/card"; +import Logo from "../components/logo"; +import ScopeItem from "../components/scope-item/scope-item"; +import PrimaryButton from "../components/button/primary-button-component"; +import SecondaryButton from "../components/button/secondary-button-component"; +import { cookies } from "next/headers"; + +interface ConsentProps { + consent_challenge: string; +} + +const submitForm = async (form: FormData) => { + "use server"; + const consent_challenge = form.get("consent_challenge"); + const submitValue = form.get("submit"); + const remember = form.get("remember") === "1"; + const grantScope = form + .getAll("grant_scope") + .map((value) => value.toString()); + + if (!consent_challenge || typeof consent_challenge !== "string") { + console.error("INVALID PARAMS"); + return; + } + + if (submitValue === "Deny access") { + console.log("User denied access"); + let response; + response = await hydraClient.rejectOAuth2ConsentRequest({ + consentChallenge: consent_challenge, + rejectOAuth2Request: { + error: "access_denied", + error_description: "The resource owner denied the request", + }, + }); + redirect(response.data.redirect_to); + } + + let responseConfirm; + const responseInit = await hydraClient.getOAuth2ConsentRequest({ + consentChallenge: consent_challenge, + }); + + const body = responseInit.data; + responseConfirm = await hydraClient.acceptOAuth2ConsentRequest({ + consentChallenge: consent_challenge, + acceptOAuth2ConsentRequest: { + grant_scope: grantScope, + grant_access_token_audience: body.requested_access_token_audience, + remember: remember, + remember_for: 3600, + }, + }); + redirect(responseConfirm.data.redirect_to); +}; + +const Consent = async ({ searchParams }: { searchParams: ConsentProps }) => { + const { consent_challenge } = searchParams; + + if (!consent_challenge) { + throw new Error("Invalid Request"); + } + + const data = await hydraClient.getOAuth2ConsentRequest({ + consentChallenge: consent_challenge, + }); + + const body = data.data; + const login_challenge = data.data.login_challenge; + + if (!login_challenge) { + throw new Error("Login Challenge Not Found"); + } + + const cookieStore = cookies().get(login_challenge); + + if (!cookieStore) { + throw new Error("Cannot find cookies"); + } + + if (body.client?.skip_consent) { + let response; + response = await hydraClient.acceptOAuth2ConsentRequest({ + consentChallenge: consent_challenge, + acceptOAuth2ConsentRequest: { + grant_scope: body.requested_scope, + grant_access_token_audience: body.requested_access_token_audience, + }, + }); + redirect(String(response.data.redirect_to)); + } + + const user = body.subject; + const { client, requested_scope } = body; + + if (!user || !client || !requested_scope) { + throw new Error("Invalid Request "); + } + + return ( + + + + +
+

+ An application requests access to your data! +

+
+ +
+ + +

+ Hi {user}{" "} +

+

+ Application{" "} + {client.client_name || client.client_id} wants + access resources on your behalf and to: +

+ + {requested_scope.map((scope) => ( + + ))} + +

+ Do you want to be asked next time when this application wants to + access your data? +

+

+ The application will not be able to ask for more permissions without + your consent. +

+ +

+ + +

+
+ + Deny + + + + Allow + +
+ +
+
+ ); +}; +export default Consent; diff --git a/apps/consent/app/error.tsx b/apps/consent/app/error.tsx new file mode 100644 index 00000000000..82cbcdba0fe --- /dev/null +++ b/apps/consent/app/error.tsx @@ -0,0 +1,22 @@ +"use client" + +import Card from "./components/card" +import MainContent from "./components/main-container" + +export default function Error({ error, reset }: { error: Error; reset: () => void }) { + return ( + + +

Something went wrong!

+
+ +
+
+
+ ) +} diff --git a/apps/consent/app/favicon.ico b/apps/consent/app/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..06739ff07e4ddf46f6feb82073c4c03b2762fae1 GIT binary patch literal 36843 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

%evM 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 vYJX?j_v>r0=Zm&I+bc3(-| { + const httpLink = new HttpLink({ + uri: env.GRAPHQL_ENDPOINT, + fetchOptions: { cache: "no-store" }, + headers: authToken ? { authorization: `Bearer ${authToken}` } : undefined, + }); + + return new ApolloClient({ + cache: new InMemoryCache(), + link: httpLink, + }); +}; diff --git a/apps/consent/app/graphql/generated.ts b/apps/consent/app/graphql/generated.ts new file mode 100644 index 00000000000..593e1661185 --- /dev/null +++ b/apps/consent/app/graphql/generated.ts @@ -0,0 +1,1874 @@ +// this file is autogenerated by codegen +/* eslint-disable */ +import { gql } from '@apollo/client'; +import * as Apollo from '@apollo/client'; +export type Maybe = T | null; +export type InputMaybe = Maybe; +export type Exact = { [K in keyof T]: T[K] }; +export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; +export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; +export type MakeEmpty = { [_ in K]?: never }; +export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; +const defaultOptions = {} as const; +/** All built-in and custom scalars, mapped to their actual values */ +export type Scalars = { + ID: { input: string; output: string; } + String: { input: string; output: string; } + Boolean: { input: boolean; output: boolean; } + Int: { input: number; output: number; } + Float: { input: number; output: number; } + /** An Opaque Bearer token */ + AuthToken: { input: string; output: string; } + /** (Positive) Cent amount (1/100 of a dollar) */ + CentAmount: { input: number; output: number; } + /** An alias name that a user can set for a wallet (with which they have transactions) */ + ContactAlias: { input: string; output: string; } + /** A CCA2 country code (ex US, FR, etc) */ + CountryCode: { input: string; output: string; } + /** Display currency of an account */ + DisplayCurrency: { input: string; output: string; } + /** Email address */ + EmailAddress: { input: string; output: string; } + /** An id to be passed between registrationInitiate and registrationValidate for confirming email */ + EmailRegistrationId: { input: string; output: string; } + EndpointId: { input: string; output: string; } + /** Url that will be fetched on events for the account */ + EndpointUrl: { input: string; output: string; } + /** Feedback shared with our user */ + Feedback: { input: string; output: string; } + /** Hex-encoded string of 32 bytes */ + Hex32Bytes: { input: string; output: string; } + Language: { input: string; output: string; } + LnPaymentPreImage: { input: string; output: string; } + /** BOLT11 lightning invoice payment request with the amount included */ + LnPaymentRequest: { input: string; output: string; } + LnPaymentSecret: { input: string; output: string; } + /** Text field in a lightning payment transaction */ + Memo: { input: string; output: string; } + /** (Positive) amount of minutes */ + Minutes: { input: string; output: string; } + NotificationCategory: { input: string; output: string; } + /** An address for an on-chain bitcoin destination */ + OnChainAddress: { input: string; output: string; } + OnChainTxHash: { input: string; output: string; } + /** An authentication code valid for a single use */ + OneTimeAuthCode: { input: string; output: string; } + PaymentHash: { input: string; output: string; } + /** Phone number which includes country code */ + Phone: { input: string; output: string; } + /** Non-fractional signed whole numeric value between -(2^53) + 1 and 2^53 - 1 */ + SafeInt: { input: number; output: number; } + /** (Positive) Satoshi amount */ + SatAmount: { input: number; output: number; } + /** (Positive) amount of seconds */ + Seconds: { input: number; output: number; } + /** An amount (of a currency) that can be negative (e.g. in a transaction) */ + SignedAmount: { input: number; output: number; } + /** A string amount (of a currency) that can be negative (e.g. in a transaction) */ + SignedDisplayMajorAmount: { input: string; output: string; } + /** Timestamp field, serialized as Unix time (the number of seconds since the Unix epoch) */ + Timestamp: { input: number; output: number; } + /** A time-based one-time password */ + TotpCode: { input: string; output: string; } + /** An id to be passed between set and verify for confirming totp */ + TotpRegistrationId: { input: string; output: string; } + /** A secret to generate time-based one-time password */ + TotpSecret: { input: string; output: string; } + /** Unique identifier of a user */ + Username: { input: string; output: string; } + /** Unique identifier of a wallet */ + WalletId: { input: string; output: string; } +}; + +export type Account = { + readonly callbackEndpoints: ReadonlyArray; + readonly csvTransactions: Scalars['String']['output']; + readonly defaultWalletId: Scalars['WalletId']['output']; + readonly displayCurrency: Scalars['DisplayCurrency']['output']; + readonly id: Scalars['ID']['output']; + readonly level: AccountLevel; + readonly limits: AccountLimits; + readonly notificationSettings: NotificationSettings; + readonly realtimePrice: RealtimePrice; + readonly transactions?: Maybe; + readonly wallets: ReadonlyArray; +}; + + +export type AccountCsvTransactionsArgs = { + walletIds: ReadonlyArray; +}; + + +export type AccountTransactionsArgs = { + after?: InputMaybe; + before?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + walletIds?: InputMaybe>>; +}; + +export type AccountDeletePayload = { + readonly __typename: 'AccountDeletePayload'; + readonly errors: ReadonlyArray; + readonly success: Scalars['Boolean']['output']; +}; + +export type AccountDisableNotificationCategoryInput = { + readonly category: Scalars['NotificationCategory']['input']; + readonly channel?: InputMaybe; +}; + +export type AccountDisableNotificationChannelInput = { + readonly channel: NotificationChannel; +}; + +export type AccountEnableNotificationCategoryInput = { + readonly category: Scalars['NotificationCategory']['input']; + readonly channel?: InputMaybe; +}; + +export type AccountEnableNotificationChannelInput = { + readonly channel: NotificationChannel; +}; + +export const AccountLevel = { + One: 'ONE', + Two: 'TWO', + Zero: 'ZERO' +} as const; + +export type AccountLevel = typeof AccountLevel[keyof typeof AccountLevel]; +export type AccountLimit = { + /** The rolling time interval in seconds that the limits would apply for. */ + readonly interval?: Maybe; + /** The amount of cents remaining below the limit for the current 24 hour period. */ + readonly remainingLimit?: Maybe; + /** The current maximum limit for a given 24 hour period. */ + readonly totalLimit: Scalars['CentAmount']['output']; +}; + +export type AccountLimits = { + readonly __typename: 'AccountLimits'; + /** Limits for converting between currencies among a account's own wallets. */ + readonly convert: ReadonlyArray; + /** Limits for sending to other internal accounts. */ + readonly internalSend: ReadonlyArray; + /** Limits for withdrawing to external onchain or lightning destinations. */ + readonly withdrawal: ReadonlyArray; +}; + +export type AccountUpdateDefaultWalletIdInput = { + readonly walletId: Scalars['WalletId']['input']; +}; + +export type AccountUpdateDefaultWalletIdPayload = { + readonly __typename: 'AccountUpdateDefaultWalletIdPayload'; + readonly account?: Maybe; + readonly errors: ReadonlyArray; +}; + +export type AccountUpdateDisplayCurrencyInput = { + readonly currency: Scalars['DisplayCurrency']['input']; +}; + +export type AccountUpdateDisplayCurrencyPayload = { + readonly __typename: 'AccountUpdateDisplayCurrencyPayload'; + readonly account?: Maybe; + readonly errors: ReadonlyArray; +}; + +export type AccountUpdateNotificationSettingsPayload = { + readonly __typename: 'AccountUpdateNotificationSettingsPayload'; + readonly account?: Maybe; + readonly errors: ReadonlyArray; +}; + +export type AuthTokenPayload = { + readonly __typename: 'AuthTokenPayload'; + readonly authToken?: Maybe; + readonly errors: ReadonlyArray; + readonly totpRequired?: Maybe; +}; + +/** A wallet belonging to an account which contains a BTC balance and a list of transactions. */ +export type BtcWallet = Wallet & { + readonly __typename: 'BTCWallet'; + readonly accountId: Scalars['ID']['output']; + /** A balance stored in BTC. */ + readonly balance: Scalars['SignedAmount']['output']; + readonly id: Scalars['ID']['output']; + /** An unconfirmed incoming onchain balance. */ + readonly pendingIncomingBalance: Scalars['SignedAmount']['output']; + /** A list of BTC transactions associated with this wallet. */ + readonly transactions?: Maybe; + readonly transactionsByAddress?: Maybe; + readonly walletCurrency: WalletCurrency; +}; + + +/** A wallet belonging to an account which contains a BTC balance and a list of transactions. */ +export type BtcWalletTransactionsArgs = { + after?: InputMaybe; + before?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; +}; + + +/** A wallet belonging to an account which contains a BTC balance and a list of transactions. */ +export type BtcWalletTransactionsByAddressArgs = { + address: Scalars['OnChainAddress']['input']; + after?: InputMaybe; + before?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; +}; + +export type BuildInformation = { + readonly __typename: 'BuildInformation'; + readonly commitHash?: Maybe; + readonly helmRevision?: Maybe; +}; + +export type CallbackEndpoint = { + readonly __typename: 'CallbackEndpoint'; + readonly id: Scalars['EndpointId']['output']; + readonly url: Scalars['EndpointUrl']['output']; +}; + +export type CallbackEndpointAddInput = { + /** callback endpoint to be called */ + readonly url: Scalars['EndpointUrl']['input']; +}; + +export type CallbackEndpointAddPayload = { + readonly __typename: 'CallbackEndpointAddPayload'; + readonly errors: ReadonlyArray; + readonly id?: Maybe; +}; + +export type CallbackEndpointDeleteInput = { + readonly id: Scalars['EndpointId']['input']; +}; + +export type CaptchaCreateChallengePayload = { + readonly __typename: 'CaptchaCreateChallengePayload'; + readonly errors: ReadonlyArray; + readonly result?: Maybe; +}; + +export type CaptchaCreateChallengeResult = { + readonly __typename: 'CaptchaCreateChallengeResult'; + readonly challengeCode: Scalars['String']['output']; + readonly failbackMode: Scalars['Boolean']['output']; + readonly id: Scalars['String']['output']; + readonly newCaptcha: Scalars['Boolean']['output']; +}; + +export type CaptchaRequestAuthCodeInput = { + readonly challengeCode: Scalars['String']['input']; + readonly channel?: InputMaybe; + readonly phone: Scalars['Phone']['input']; + readonly secCode: Scalars['String']['input']; + readonly validationCode: Scalars['String']['input']; +}; + +export type CentAmountPayload = { + readonly __typename: 'CentAmountPayload'; + readonly amount?: Maybe; + readonly errors: ReadonlyArray; +}; + +export type ConsumerAccount = Account & { + readonly __typename: 'ConsumerAccount'; + readonly callbackEndpoints: ReadonlyArray; + /** return CSV stream, base64 encoded, of the list of transactions in the wallet */ + readonly csvTransactions: Scalars['String']['output']; + readonly defaultWalletId: Scalars['WalletId']['output']; + readonly displayCurrency: Scalars['DisplayCurrency']['output']; + readonly id: Scalars['ID']['output']; + readonly level: AccountLevel; + readonly limits: AccountLimits; + readonly notificationSettings: NotificationSettings; + /** List the quiz questions of the consumer account */ + readonly quiz: ReadonlyArray; + readonly realtimePrice: RealtimePrice; + /** A list of all transactions associated with walletIds optionally passed. */ + readonly transactions?: Maybe; + readonly wallets: ReadonlyArray; +}; + + +export type ConsumerAccountCsvTransactionsArgs = { + walletIds: ReadonlyArray; +}; + + +export type ConsumerAccountTransactionsArgs = { + after?: InputMaybe; + before?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; + walletIds?: InputMaybe>>; +}; + +export type Coordinates = { + readonly __typename: 'Coordinates'; + readonly latitude: Scalars['Float']['output']; + readonly longitude: Scalars['Float']['output']; +}; + +export type Country = { + readonly __typename: 'Country'; + readonly id: Scalars['CountryCode']['output']; + readonly supportedAuthChannels: ReadonlyArray; +}; + +export type Currency = { + readonly __typename: 'Currency'; + readonly flag: Scalars['String']['output']; + readonly fractionDigits: Scalars['Int']['output']; + readonly id: Scalars['ID']['output']; + readonly name: Scalars['String']['output']; + readonly symbol: Scalars['String']['output']; +}; + +export type DepositFeesInformation = { + readonly __typename: 'DepositFeesInformation'; + readonly minBankFee: Scalars['String']['output']; + /** below this amount minBankFee will be charged */ + readonly minBankFeeThreshold: Scalars['String']['output']; + /** ratio to charge as basis points above minBankFeeThreshold amount */ + readonly ratio: Scalars['String']['output']; +}; + +export type DeviceNotificationTokenCreateInput = { + readonly deviceToken: Scalars['String']['input']; +}; + +export type Email = { + readonly __typename: 'Email'; + readonly address?: Maybe; + readonly verified?: Maybe; +}; + +export type Error = { + readonly code?: Maybe; + readonly message: Scalars['String']['output']; + readonly path?: Maybe>>; +}; + +export const ExchangeCurrencyUnit = { + Btcsat: 'BTCSAT', + Usdcent: 'USDCENT' +} as const; + +export type ExchangeCurrencyUnit = typeof ExchangeCurrencyUnit[keyof typeof ExchangeCurrencyUnit]; +export type FeedbackSubmitInput = { + readonly feedback: Scalars['Feedback']['input']; +}; + +export type FeesInformation = { + readonly __typename: 'FeesInformation'; + readonly deposit: DepositFeesInformation; +}; + +/** Provides global settings for the application which might have an impact for the user. */ +export type Globals = { + readonly __typename: 'Globals'; + readonly buildInformation: BuildInformation; + readonly feesInformation: FeesInformation; + /** The domain name for lightning addresses accepted by this Galoy instance */ + readonly lightningAddressDomain: Scalars['String']['output']; + readonly lightningAddressDomainAliases: ReadonlyArray; + /** Which network (mainnet, testnet, regtest, signet) this instance is running on. */ + readonly network: Network; + /** + * A list of public keys for the running lightning nodes. + * This can be used to know if an invoice belongs to one of our nodes. + */ + readonly nodesIds: ReadonlyArray; + /** A list of countries and their supported auth channels */ + readonly supportedCountries: ReadonlyArray; +}; + +export type GraphQlApplicationError = Error & { + readonly __typename: 'GraphQLApplicationError'; + readonly code?: Maybe; + readonly message: Scalars['String']['output']; + readonly path?: Maybe>>; +}; + +export type InitiationVia = InitiationViaIntraLedger | InitiationViaLn | InitiationViaOnChain; + +export type InitiationViaIntraLedger = { + readonly __typename: 'InitiationViaIntraLedger'; + readonly counterPartyUsername?: Maybe; + readonly counterPartyWalletId?: Maybe; +}; + +export type InitiationViaLn = { + readonly __typename: 'InitiationViaLn'; + readonly paymentHash: Scalars['PaymentHash']['output']; +}; + +export type InitiationViaOnChain = { + readonly __typename: 'InitiationViaOnChain'; + readonly address: Scalars['OnChainAddress']['output']; +}; + +export type IntraLedgerPaymentSendInput = { + /** Amount in satoshis. */ + readonly amount: Scalars['SatAmount']['input']; + /** Optional memo to be attached to the payment. */ + readonly memo?: InputMaybe; + readonly recipientWalletId: Scalars['WalletId']['input']; + /** The wallet ID of the sender. */ + readonly walletId: Scalars['WalletId']['input']; +}; + +export type IntraLedgerUpdate = { + readonly __typename: 'IntraLedgerUpdate'; + readonly amount: Scalars['SatAmount']['output']; + readonly displayCurrencyPerSat: Scalars['Float']['output']; + readonly txNotificationType: TxNotificationType; + /** @deprecated updated over displayCurrencyPerSat */ + readonly usdPerSat: Scalars['Float']['output']; + readonly walletId: Scalars['WalletId']['output']; +}; + +export type IntraLedgerUsdPaymentSendInput = { + /** Amount in cents. */ + readonly amount: Scalars['CentAmount']['input']; + /** Optional memo to be attached to the payment. */ + readonly memo?: InputMaybe; + readonly recipientWalletId: Scalars['WalletId']['input']; + /** The wallet ID of the sender. */ + readonly walletId: Scalars['WalletId']['input']; +}; + +export const InvoicePaymentStatus = { + Expired: 'EXPIRED', + Paid: 'PAID', + Pending: 'PENDING' +} as const; + +export type InvoicePaymentStatus = typeof InvoicePaymentStatus[keyof typeof InvoicePaymentStatus]; +export type LnInvoice = { + readonly __typename: 'LnInvoice'; + readonly paymentHash: Scalars['PaymentHash']['output']; + readonly paymentRequest: Scalars['LnPaymentRequest']['output']; + readonly paymentSecret: Scalars['LnPaymentSecret']['output']; + readonly satoshis?: Maybe; +}; + +export type LnInvoiceCreateInput = { + /** Amount in satoshis. */ + readonly amount: Scalars['SatAmount']['input']; + /** Optional invoice expiration time in minutes. */ + readonly expiresIn?: InputMaybe; + /** Optional memo for the lightning invoice. */ + readonly memo?: InputMaybe; + /** Wallet ID for a BTC wallet belonging to the current account. */ + readonly walletId: Scalars['WalletId']['input']; +}; + +export type LnInvoiceCreateOnBehalfOfRecipientInput = { + /** Amount in satoshis. */ + readonly amount: Scalars['SatAmount']['input']; + readonly descriptionHash?: InputMaybe; + /** Optional invoice expiration time in minutes. */ + readonly expiresIn?: InputMaybe; + /** Optional memo for the lightning invoice. */ + readonly memo?: InputMaybe; + /** Wallet ID for a BTC wallet which belongs to any account. */ + readonly recipientWalletId: Scalars['WalletId']['input']; +}; + +export type LnInvoiceFeeProbeInput = { + readonly paymentRequest: Scalars['LnPaymentRequest']['input']; + readonly walletId: Scalars['WalletId']['input']; +}; + +export type LnInvoicePayload = { + readonly __typename: 'LnInvoicePayload'; + readonly errors: ReadonlyArray; + readonly invoice?: Maybe; +}; + +export type LnInvoicePaymentInput = { + /** Optional memo to associate with the lightning invoice. */ + readonly memo?: InputMaybe; + /** Payment request representing the invoice which is being paid. */ + readonly paymentRequest: Scalars['LnPaymentRequest']['input']; + /** Wallet ID with sufficient balance to cover amount of invoice. Must belong to the account of the current user. */ + readonly walletId: Scalars['WalletId']['input']; +}; + +export type LnInvoicePaymentStatusInput = { + readonly paymentRequest: Scalars['LnPaymentRequest']['input']; +}; + +export type LnInvoicePaymentStatusPayload = { + readonly __typename: 'LnInvoicePaymentStatusPayload'; + readonly errors: ReadonlyArray; + readonly status?: Maybe; +}; + +export type LnNoAmountInvoice = { + readonly __typename: 'LnNoAmountInvoice'; + readonly paymentHash: Scalars['PaymentHash']['output']; + readonly paymentRequest: Scalars['LnPaymentRequest']['output']; + readonly paymentSecret: Scalars['LnPaymentSecret']['output']; +}; + +export type LnNoAmountInvoiceCreateInput = { + /** Optional invoice expiration time in minutes. */ + readonly expiresIn?: InputMaybe; + /** Optional memo for the lightning invoice. */ + readonly memo?: InputMaybe; + /** ID for either a USD or BTC wallet belonging to the account of the current user. */ + readonly walletId: Scalars['WalletId']['input']; +}; + +export type LnNoAmountInvoiceCreateOnBehalfOfRecipientInput = { + /** Optional invoice expiration time in minutes. */ + readonly expiresIn?: InputMaybe; + /** Optional memo for the lightning invoice. */ + readonly memo?: InputMaybe; + /** ID for either a USD or BTC wallet which belongs to the account of any user. */ + readonly recipientWalletId: Scalars['WalletId']['input']; +}; + +export type LnNoAmountInvoiceFeeProbeInput = { + readonly amount: Scalars['SatAmount']['input']; + readonly paymentRequest: Scalars['LnPaymentRequest']['input']; + readonly walletId: Scalars['WalletId']['input']; +}; + +export type LnNoAmountInvoicePayload = { + readonly __typename: 'LnNoAmountInvoicePayload'; + readonly errors: ReadonlyArray; + readonly invoice?: Maybe; +}; + +export type LnNoAmountInvoicePaymentInput = { + /** Amount to pay in satoshis. */ + readonly amount: Scalars['SatAmount']['input']; + /** Optional memo to associate with the lightning invoice. */ + readonly memo?: InputMaybe; + /** Payment request representing the invoice which is being paid. */ + readonly paymentRequest: Scalars['LnPaymentRequest']['input']; + /** Wallet ID with sufficient balance to cover amount defined in mutation request. Must belong to the account of the current user. */ + readonly walletId: Scalars['WalletId']['input']; +}; + +export type LnNoAmountUsdInvoiceFeeProbeInput = { + readonly amount: Scalars['CentAmount']['input']; + readonly paymentRequest: Scalars['LnPaymentRequest']['input']; + readonly walletId: Scalars['WalletId']['input']; +}; + +export type LnNoAmountUsdInvoicePaymentInput = { + /** Amount to pay in USD cents. */ + readonly amount: Scalars['CentAmount']['input']; + /** Optional memo to associate with the lightning invoice. */ + readonly memo?: InputMaybe; + /** Payment request representing the invoice which is being paid. */ + readonly paymentRequest: Scalars['LnPaymentRequest']['input']; + /** Wallet ID with sufficient balance to cover amount defined in mutation request. Must belong to the account of the current user. */ + readonly walletId: Scalars['WalletId']['input']; +}; + +export type LnUpdate = { + readonly __typename: 'LnUpdate'; + readonly paymentHash: Scalars['PaymentHash']['output']; + readonly status: InvoicePaymentStatus; + readonly walletId: Scalars['WalletId']['output']; +}; + +export type LnUsdInvoiceBtcDenominatedCreateOnBehalfOfRecipientInput = { + /** Amount in satoshis. */ + readonly amount: Scalars['SatAmount']['input']; + readonly descriptionHash?: InputMaybe; + /** Optional invoice expiration time in minutes. */ + readonly expiresIn?: InputMaybe; + /** Optional memo for the lightning invoice. Acts as a note to the recipient. */ + readonly memo?: InputMaybe; + /** Wallet ID for a USD wallet which belongs to the account of any user. */ + readonly recipientWalletId: Scalars['WalletId']['input']; +}; + +export type LnUsdInvoiceCreateInput = { + /** Amount in USD cents. */ + readonly amount: Scalars['CentAmount']['input']; + /** Optional invoice expiration time in minutes. */ + readonly expiresIn?: InputMaybe; + /** Optional memo for the lightning invoice. */ + readonly memo?: InputMaybe; + /** Wallet ID for a USD wallet belonging to the current user. */ + readonly walletId: Scalars['WalletId']['input']; +}; + +export type LnUsdInvoiceCreateOnBehalfOfRecipientInput = { + /** Amount in USD cents. */ + readonly amount: Scalars['CentAmount']['input']; + readonly descriptionHash?: InputMaybe; + /** Optional invoice expiration time in minutes. */ + readonly expiresIn?: InputMaybe; + /** Optional memo for the lightning invoice. Acts as a note to the recipient. */ + readonly memo?: InputMaybe; + /** Wallet ID for a USD wallet which belongs to the account of any user. */ + readonly recipientWalletId: Scalars['WalletId']['input']; +}; + +export type LnUsdInvoiceFeeProbeInput = { + readonly paymentRequest: Scalars['LnPaymentRequest']['input']; + readonly walletId: Scalars['WalletId']['input']; +}; + +export type MapInfo = { + readonly __typename: 'MapInfo'; + readonly coordinates: Coordinates; + readonly title: Scalars['String']['output']; +}; + +export type MapMarker = { + readonly __typename: 'MapMarker'; + readonly mapInfo: MapInfo; + readonly username?: Maybe; +}; + +export type MobileVersions = { + readonly __typename: 'MobileVersions'; + readonly currentSupported: Scalars['Int']['output']; + readonly minSupported: Scalars['Int']['output']; + readonly platform: Scalars['String']['output']; +}; + +export type Mutation = { + readonly __typename: 'Mutation'; + readonly accountDelete: AccountDeletePayload; + readonly accountDisableNotificationCategory: AccountUpdateNotificationSettingsPayload; + readonly accountDisableNotificationChannel: AccountUpdateNotificationSettingsPayload; + readonly accountEnableNotificationCategory: AccountUpdateNotificationSettingsPayload; + readonly accountEnableNotificationChannel: AccountUpdateNotificationSettingsPayload; + readonly accountUpdateDefaultWalletId: AccountUpdateDefaultWalletIdPayload; + readonly accountUpdateDisplayCurrency: AccountUpdateDisplayCurrencyPayload; + readonly callbackEndpointAdd: CallbackEndpointAddPayload; + readonly callbackEndpointDelete: SuccessPayload; + readonly captchaCreateChallenge: CaptchaCreateChallengePayload; + readonly captchaRequestAuthCode: SuccessPayload; + readonly deviceNotificationTokenCreate: SuccessPayload; + readonly feedbackSubmit: SuccessPayload; + /** + * Actions a payment which is internal to the ledger e.g. it does + * not use onchain/lightning. Returns payment status (success, + * failed, pending, already_paid). + */ + readonly intraLedgerPaymentSend: PaymentSendPayload; + /** + * Actions a payment which is internal to the ledger e.g. it does + * not use onchain/lightning. Returns payment status (success, + * failed, pending, already_paid). + */ + readonly intraLedgerUsdPaymentSend: PaymentSendPayload; + /** + * Returns a lightning invoice for an associated wallet. + * When invoice is paid the value will be credited to a BTC wallet. + * Expires after 'expiresIn' or 24 hours. + */ + readonly lnInvoiceCreate: LnInvoicePayload; + /** + * Returns a lightning invoice for an associated wallet. + * When invoice is paid the value will be credited to a BTC wallet. + * Expires after 'expiresIn' or 24 hours. + */ + readonly lnInvoiceCreateOnBehalfOfRecipient: LnInvoicePayload; + readonly lnInvoiceFeeProbe: SatAmountPayload; + /** + * Pay a lightning invoice using a balance from a wallet which is owned by the account of the current user. + * Provided wallet can be USD or BTC and must have sufficient balance to cover amount in lightning invoice. + * Returns payment status (success, failed, pending, already_paid). + */ + readonly lnInvoicePaymentSend: PaymentSendPayload; + /** + * Returns a lightning invoice for an associated wallet. + * Can be used to receive any supported currency value (currently USD or BTC). + * Expires after 'expiresIn' or 24 hours for BTC invoices or 5 minutes for USD invoices. + */ + readonly lnNoAmountInvoiceCreate: LnNoAmountInvoicePayload; + /** + * Returns a lightning invoice for an associated wallet. + * Can be used to receive any supported currency value (currently USD or BTC). + * Expires after 'expiresIn' or 24 hours for BTC invoices or 5 minutes for USD invoices. + */ + readonly lnNoAmountInvoiceCreateOnBehalfOfRecipient: LnNoAmountInvoicePayload; + readonly lnNoAmountInvoiceFeeProbe: SatAmountPayload; + /** + * Pay a lightning invoice using a balance from a wallet which is owned by the account of the current user. + * Provided wallet must be BTC and must have sufficient balance to cover amount specified in mutation request. + * Returns payment status (success, failed, pending, already_paid). + */ + readonly lnNoAmountInvoicePaymentSend: PaymentSendPayload; + readonly lnNoAmountUsdInvoiceFeeProbe: CentAmountPayload; + /** + * Pay a lightning invoice using a balance from a wallet which is owned by the account of the current user. + * Provided wallet must be USD and have sufficient balance to cover amount specified in mutation request. + * Returns payment status (success, failed, pending, already_paid). + */ + readonly lnNoAmountUsdInvoicePaymentSend: PaymentSendPayload; + /** + * Returns a lightning invoice denominated in satoshis for an associated wallet. + * When invoice is paid the equivalent value at invoice creation will be credited to a USD wallet. + * Expires after 'expiresIn' or 5 minutes (short expiry time because there is a USD/BTC exchange rate + * associated with the amount). + */ + readonly lnUsdInvoiceBtcDenominatedCreateOnBehalfOfRecipient: LnInvoicePayload; + /** + * Returns a lightning invoice denominated in satoshis for an associated wallet. + * When invoice is paid the equivalent value at invoice creation will be credited to a USD wallet. + * Expires after 'expiresIn' or 5 minutes (short expiry time because there is a USD/BTC exchange rate + * associated with the amount). + */ + readonly lnUsdInvoiceCreate: LnInvoicePayload; + /** + * Returns a lightning invoice denominated in satoshis for an associated wallet. + * When invoice is paid the equivalent value at invoice creation will be credited to a USD wallet. + * Expires after 'expiresIn' or 5 minutes (short expiry time because there is a USD/BTC exchange rate + * associated with the amount). + */ + readonly lnUsdInvoiceCreateOnBehalfOfRecipient: LnInvoicePayload; + readonly lnUsdInvoiceFeeProbe: SatAmountPayload; + readonly onChainAddressCreate: OnChainAddressPayload; + readonly onChainAddressCurrent: OnChainAddressPayload; + readonly onChainPaymentSend: PaymentSendPayload; + readonly onChainPaymentSendAll: PaymentSendPayload; + readonly onChainUsdPaymentSend: PaymentSendPayload; + readonly onChainUsdPaymentSendAsBtcDenominated: PaymentSendPayload; + readonly quizCompleted: QuizCompletedPayload; + /** @deprecated will be moved to AccountContact */ + readonly userContactUpdateAlias: UserContactUpdateAliasPayload; + readonly userEmailDelete: UserEmailDeletePayload; + readonly userEmailRegistrationInitiate: UserEmailRegistrationInitiatePayload; + readonly userEmailRegistrationValidate: UserEmailRegistrationValidatePayload; + readonly userLogin: AuthTokenPayload; + readonly userLoginUpgrade: UpgradePayload; + readonly userLogout: SuccessPayload; + readonly userPhoneDelete: UserPhoneDeletePayload; + readonly userPhoneRegistrationInitiate: SuccessPayload; + readonly userPhoneRegistrationValidate: UserPhoneRegistrationValidatePayload; + /** @deprecated Use QuizCompletedMutation instead */ + readonly userQuizQuestionUpdateCompleted: UserQuizQuestionUpdateCompletedPayload; + readonly userTotpDelete: UserTotpDeletePayload; + readonly userTotpRegistrationInitiate: UserTotpRegistrationInitiatePayload; + readonly userTotpRegistrationValidate: UserTotpRegistrationValidatePayload; + readonly userUpdateLanguage: UserUpdateLanguagePayload; + /** @deprecated Username will be moved to @Handle in Accounts. Also SetUsername naming should be used instead of UpdateUsername to reflect the idempotency of Handles */ + readonly userUpdateUsername: UserUpdateUsernamePayload; +}; + + +export type MutationAccountDisableNotificationCategoryArgs = { + input: AccountDisableNotificationCategoryInput; +}; + + +export type MutationAccountDisableNotificationChannelArgs = { + input: AccountDisableNotificationChannelInput; +}; + + +export type MutationAccountEnableNotificationCategoryArgs = { + input: AccountEnableNotificationCategoryInput; +}; + + +export type MutationAccountEnableNotificationChannelArgs = { + input: AccountEnableNotificationChannelInput; +}; + + +export type MutationAccountUpdateDefaultWalletIdArgs = { + input: AccountUpdateDefaultWalletIdInput; +}; + + +export type MutationAccountUpdateDisplayCurrencyArgs = { + input: AccountUpdateDisplayCurrencyInput; +}; + + +export type MutationCallbackEndpointAddArgs = { + input: CallbackEndpointAddInput; +}; + + +export type MutationCallbackEndpointDeleteArgs = { + input: CallbackEndpointDeleteInput; +}; + + +export type MutationCaptchaRequestAuthCodeArgs = { + input: CaptchaRequestAuthCodeInput; +}; + + +export type MutationDeviceNotificationTokenCreateArgs = { + input: DeviceNotificationTokenCreateInput; +}; + + +export type MutationFeedbackSubmitArgs = { + input: FeedbackSubmitInput; +}; + + +export type MutationIntraLedgerPaymentSendArgs = { + input: IntraLedgerPaymentSendInput; +}; + + +export type MutationIntraLedgerUsdPaymentSendArgs = { + input: IntraLedgerUsdPaymentSendInput; +}; + + +export type MutationLnInvoiceCreateArgs = { + input: LnInvoiceCreateInput; +}; + + +export type MutationLnInvoiceCreateOnBehalfOfRecipientArgs = { + input: LnInvoiceCreateOnBehalfOfRecipientInput; +}; + + +export type MutationLnInvoiceFeeProbeArgs = { + input: LnInvoiceFeeProbeInput; +}; + + +export type MutationLnInvoicePaymentSendArgs = { + input: LnInvoicePaymentInput; +}; + + +export type MutationLnNoAmountInvoiceCreateArgs = { + input: LnNoAmountInvoiceCreateInput; +}; + + +export type MutationLnNoAmountInvoiceCreateOnBehalfOfRecipientArgs = { + input: LnNoAmountInvoiceCreateOnBehalfOfRecipientInput; +}; + + +export type MutationLnNoAmountInvoiceFeeProbeArgs = { + input: LnNoAmountInvoiceFeeProbeInput; +}; + + +export type MutationLnNoAmountInvoicePaymentSendArgs = { + input: LnNoAmountInvoicePaymentInput; +}; + + +export type MutationLnNoAmountUsdInvoiceFeeProbeArgs = { + input: LnNoAmountUsdInvoiceFeeProbeInput; +}; + + +export type MutationLnNoAmountUsdInvoicePaymentSendArgs = { + input: LnNoAmountUsdInvoicePaymentInput; +}; + + +export type MutationLnUsdInvoiceBtcDenominatedCreateOnBehalfOfRecipientArgs = { + input: LnUsdInvoiceBtcDenominatedCreateOnBehalfOfRecipientInput; +}; + + +export type MutationLnUsdInvoiceCreateArgs = { + input: LnUsdInvoiceCreateInput; +}; + + +export type MutationLnUsdInvoiceCreateOnBehalfOfRecipientArgs = { + input: LnUsdInvoiceCreateOnBehalfOfRecipientInput; +}; + + +export type MutationLnUsdInvoiceFeeProbeArgs = { + input: LnUsdInvoiceFeeProbeInput; +}; + + +export type MutationOnChainAddressCreateArgs = { + input: OnChainAddressCreateInput; +}; + + +export type MutationOnChainAddressCurrentArgs = { + input: OnChainAddressCurrentInput; +}; + + +export type MutationOnChainPaymentSendArgs = { + input: OnChainPaymentSendInput; +}; + + +export type MutationOnChainPaymentSendAllArgs = { + input: OnChainPaymentSendAllInput; +}; + + +export type MutationOnChainUsdPaymentSendArgs = { + input: OnChainUsdPaymentSendInput; +}; + + +export type MutationOnChainUsdPaymentSendAsBtcDenominatedArgs = { + input: OnChainUsdPaymentSendAsBtcDenominatedInput; +}; + + +export type MutationQuizCompletedArgs = { + input: QuizCompletedInput; +}; + + +export type MutationUserContactUpdateAliasArgs = { + input: UserContactUpdateAliasInput; +}; + + +export type MutationUserEmailRegistrationInitiateArgs = { + input: UserEmailRegistrationInitiateInput; +}; + + +export type MutationUserEmailRegistrationValidateArgs = { + input: UserEmailRegistrationValidateInput; +}; + + +export type MutationUserLoginArgs = { + input: UserLoginInput; +}; + + +export type MutationUserLoginUpgradeArgs = { + input: UserLoginUpgradeInput; +}; + + +export type MutationUserLogoutArgs = { + input?: InputMaybe; +}; + + +export type MutationUserPhoneRegistrationInitiateArgs = { + input: UserPhoneRegistrationInitiateInput; +}; + + +export type MutationUserPhoneRegistrationValidateArgs = { + input: UserPhoneRegistrationValidateInput; +}; + + +export type MutationUserQuizQuestionUpdateCompletedArgs = { + input: UserQuizQuestionUpdateCompletedInput; +}; + + +export type MutationUserTotpDeleteArgs = { + input: UserTotpDeleteInput; +}; + + +export type MutationUserTotpRegistrationInitiateArgs = { + input: UserTotpRegistrationInitiateInput; +}; + + +export type MutationUserTotpRegistrationValidateArgs = { + input: UserTotpRegistrationValidateInput; +}; + + +export type MutationUserUpdateLanguageArgs = { + input: UserUpdateLanguageInput; +}; + + +export type MutationUserUpdateUsernameArgs = { + input: UserUpdateUsernameInput; +}; + +export type MyUpdatesPayload = { + readonly __typename: 'MyUpdatesPayload'; + readonly errors: ReadonlyArray; + readonly me?: Maybe; + readonly update?: Maybe; +}; + +export const Network = { + Mainnet: 'mainnet', + Regtest: 'regtest', + Signet: 'signet', + Testnet: 'testnet' +} as const; + +export type Network = typeof Network[keyof typeof Network]; +export const NotificationChannel = { + Push: 'PUSH' +} as const; + +export type NotificationChannel = typeof NotificationChannel[keyof typeof NotificationChannel]; +export type NotificationChannelSettings = { + readonly __typename: 'NotificationChannelSettings'; + readonly disabledCategories: ReadonlyArray; + readonly enabled: Scalars['Boolean']['output']; +}; + +export type NotificationSettings = { + readonly __typename: 'NotificationSettings'; + readonly push: NotificationChannelSettings; +}; + +export type OnChainAddressCreateInput = { + readonly walletId: Scalars['WalletId']['input']; +}; + +export type OnChainAddressCurrentInput = { + readonly walletId: Scalars['WalletId']['input']; +}; + +export type OnChainAddressPayload = { + readonly __typename: 'OnChainAddressPayload'; + readonly address?: Maybe; + readonly errors: ReadonlyArray; +}; + +export type OnChainPaymentSendAllInput = { + readonly address: Scalars['OnChainAddress']['input']; + readonly memo?: InputMaybe; + readonly speed?: InputMaybe; + readonly walletId: Scalars['WalletId']['input']; +}; + +export type OnChainPaymentSendInput = { + readonly address: Scalars['OnChainAddress']['input']; + readonly amount: Scalars['SatAmount']['input']; + readonly memo?: InputMaybe; + readonly speed?: InputMaybe; + readonly walletId: Scalars['WalletId']['input']; +}; + +export type OnChainTxFee = { + readonly __typename: 'OnChainTxFee'; + readonly amount: Scalars['SatAmount']['output']; +}; + +export type OnChainUpdate = { + readonly __typename: 'OnChainUpdate'; + readonly amount: Scalars['SatAmount']['output']; + readonly displayCurrencyPerSat: Scalars['Float']['output']; + readonly txHash: Scalars['OnChainTxHash']['output']; + readonly txNotificationType: TxNotificationType; + /** @deprecated updated over displayCurrencyPerSat */ + readonly usdPerSat: Scalars['Float']['output']; + readonly walletId: Scalars['WalletId']['output']; +}; + +export type OnChainUsdPaymentSendAsBtcDenominatedInput = { + readonly address: Scalars['OnChainAddress']['input']; + readonly amount: Scalars['SatAmount']['input']; + readonly memo?: InputMaybe; + readonly speed?: InputMaybe; + readonly walletId: Scalars['WalletId']['input']; +}; + +export type OnChainUsdPaymentSendInput = { + readonly address: Scalars['OnChainAddress']['input']; + readonly amount: Scalars['CentAmount']['input']; + readonly memo?: InputMaybe; + readonly speed?: InputMaybe; + readonly walletId: Scalars['WalletId']['input']; +}; + +export type OnChainUsdTxFee = { + readonly __typename: 'OnChainUsdTxFee'; + readonly amount: Scalars['CentAmount']['output']; +}; + +export type OneDayAccountLimit = AccountLimit & { + readonly __typename: 'OneDayAccountLimit'; + /** The rolling time interval value in seconds for the current 24 hour period. */ + readonly interval?: Maybe; + /** The amount of cents remaining below the limit for the current 24 hour period. */ + readonly remainingLimit?: Maybe; + /** The current maximum limit for a given 24 hour period. */ + readonly totalLimit: Scalars['CentAmount']['output']; +}; + +/** Information about pagination in a connection. */ +export type PageInfo = { + readonly __typename: 'PageInfo'; + /** When paginating forwards, the cursor to continue. */ + readonly endCursor?: Maybe; + /** When paginating forwards, are there more items? */ + readonly hasNextPage: Scalars['Boolean']['output']; + /** When paginating backwards, are there more items? */ + readonly hasPreviousPage: Scalars['Boolean']['output']; + /** When paginating backwards, the cursor to continue. */ + readonly startCursor?: Maybe; +}; + +export type PaymentSendPayload = { + readonly __typename: 'PaymentSendPayload'; + readonly errors: ReadonlyArray; + readonly status?: Maybe; +}; + +export const PaymentSendResult = { + AlreadyPaid: 'ALREADY_PAID', + Failure: 'FAILURE', + Pending: 'PENDING', + Success: 'SUCCESS' +} as const; + +export type PaymentSendResult = typeof PaymentSendResult[keyof typeof PaymentSendResult]; +export const PayoutSpeed = { + Fast: 'FAST' +} as const; + +export type PayoutSpeed = typeof PayoutSpeed[keyof typeof PayoutSpeed]; +export const PhoneCodeChannelType = { + Sms: 'SMS', + Whatsapp: 'WHATSAPP' +} as const; + +export type PhoneCodeChannelType = typeof PhoneCodeChannelType[keyof typeof PhoneCodeChannelType]; +/** Price amount expressed in base/offset. To calculate, use: `base / 10^offset` */ +export type Price = { + readonly __typename: 'Price'; + readonly base: Scalars['SafeInt']['output']; + readonly currencyUnit: Scalars['String']['output']; + readonly formattedAmount: Scalars['String']['output']; + readonly offset: Scalars['Int']['output']; +}; + +/** The range for the X axis in the BTC price graph */ +export const PriceGraphRange = { + FiveYears: 'FIVE_YEARS', + OneDay: 'ONE_DAY', + OneMonth: 'ONE_MONTH', + OneWeek: 'ONE_WEEK', + OneYear: 'ONE_YEAR' +} as const; + +export type PriceGraphRange = typeof PriceGraphRange[keyof typeof PriceGraphRange]; +export type PriceInput = { + readonly amount: Scalars['SatAmount']['input']; + readonly amountCurrencyUnit: ExchangeCurrencyUnit; + readonly priceCurrencyUnit: ExchangeCurrencyUnit; +}; + +export type PriceInterface = { + readonly base: Scalars['SafeInt']['output']; + /** @deprecated Deprecated due to type renaming */ + readonly currencyUnit: Scalars['String']['output']; + readonly offset: Scalars['Int']['output']; +}; + +/** Price of 1 sat in base/offset. To calculate, use: `base / 10^offset` */ +export type PriceOfOneSatInMinorUnit = PriceInterface & { + readonly __typename: 'PriceOfOneSatInMinorUnit'; + readonly base: Scalars['SafeInt']['output']; + /** @deprecated Deprecated due to type renaming */ + readonly currencyUnit: Scalars['String']['output']; + readonly offset: Scalars['Int']['output']; +}; + +/** Price of 1 sat or 1 usd cent in base/offset. To calculate, use: `base / 10^offset` */ +export type PriceOfOneSettlementMinorUnitInDisplayMinorUnit = PriceInterface & { + readonly __typename: 'PriceOfOneSettlementMinorUnitInDisplayMinorUnit'; + readonly base: Scalars['SafeInt']['output']; + /** @deprecated Deprecated due to type renaming */ + readonly currencyUnit: Scalars['String']['output']; + /** @deprecated Deprecated please use `base / 10^offset` */ + readonly formattedAmount: Scalars['String']['output']; + readonly offset: Scalars['Int']['output']; +}; + +/** Price of 1 usd cent in base/offset. To calculate, use: `base / 10^offset` */ +export type PriceOfOneUsdCentInMinorUnit = PriceInterface & { + readonly __typename: 'PriceOfOneUsdCentInMinorUnit'; + readonly base: Scalars['SafeInt']['output']; + /** @deprecated Deprecated due to type renaming */ + readonly currencyUnit: Scalars['String']['output']; + readonly offset: Scalars['Int']['output']; +}; + +export type PricePayload = { + readonly __typename: 'PricePayload'; + readonly errors: ReadonlyArray; + readonly price?: Maybe; +}; + +export type PricePoint = { + readonly __typename: 'PricePoint'; + readonly price: Price; + /** Unix timestamp (number of seconds elapsed since January 1, 1970 00:00:00 UTC) */ + readonly timestamp: Scalars['Timestamp']['output']; +}; + +/** A public view of a generic wallet which stores value in one of our supported currencies. */ +export type PublicWallet = { + readonly __typename: 'PublicWallet'; + readonly id: Scalars['ID']['output']; + readonly walletCurrency: WalletCurrency; +}; + +export type Query = { + readonly __typename: 'Query'; + readonly accountDefaultWallet: PublicWallet; + /** @deprecated Deprecated in favor of realtimePrice */ + readonly btcPrice?: Maybe; + readonly btcPriceList?: Maybe>>; + readonly businessMapMarkers?: Maybe>>; + readonly currencyList: ReadonlyArray; + readonly globals?: Maybe; + readonly lnInvoicePaymentStatus: LnInvoicePaymentStatusPayload; + readonly me?: Maybe; + readonly mobileVersions?: Maybe>>; + readonly onChainTxFee: OnChainTxFee; + readonly onChainUsdTxFee: OnChainUsdTxFee; + readonly onChainUsdTxFeeAsBtcDenominated: OnChainUsdTxFee; + /** @deprecated TODO: remove. we don't need a non authenticated version of this query. the users can only do the query while authenticated */ + readonly quizQuestions?: Maybe>>; + /** Returns 1 Sat and 1 Usd Cent price for the given currency */ + readonly realtimePrice: RealtimePrice; + /** @deprecated will be migrated to AccountDefaultWalletId */ + readonly userDefaultWalletId: Scalars['WalletId']['output']; + readonly usernameAvailable?: Maybe; +}; + + +export type QueryAccountDefaultWalletArgs = { + username: Scalars['Username']['input']; + walletCurrency?: InputMaybe; +}; + + +export type QueryBtcPriceArgs = { + currency?: Scalars['DisplayCurrency']['input']; +}; + + +export type QueryBtcPriceListArgs = { + range: PriceGraphRange; +}; + + +export type QueryLnInvoicePaymentStatusArgs = { + input: LnInvoicePaymentStatusInput; +}; + + +export type QueryOnChainTxFeeArgs = { + address: Scalars['OnChainAddress']['input']; + amount: Scalars['SatAmount']['input']; + speed?: InputMaybe; + walletId: Scalars['WalletId']['input']; +}; + + +export type QueryOnChainUsdTxFeeArgs = { + address: Scalars['OnChainAddress']['input']; + amount: Scalars['CentAmount']['input']; + speed?: InputMaybe; + walletId: Scalars['WalletId']['input']; +}; + + +export type QueryOnChainUsdTxFeeAsBtcDenominatedArgs = { + address: Scalars['OnChainAddress']['input']; + amount: Scalars['SatAmount']['input']; + speed?: InputMaybe; + walletId: Scalars['WalletId']['input']; +}; + + +export type QueryRealtimePriceArgs = { + currency?: InputMaybe; +}; + + +export type QueryUserDefaultWalletIdArgs = { + username: Scalars['Username']['input']; +}; + + +export type QueryUsernameAvailableArgs = { + username: Scalars['Username']['input']; +}; + +export type Quiz = { + readonly __typename: 'Quiz'; + /** The reward in Satoshis for the quiz question */ + readonly amount: Scalars['SatAmount']['output']; + readonly completed: Scalars['Boolean']['output']; + readonly id: Scalars['ID']['output']; +}; + +export type QuizCompletedInput = { + readonly id: Scalars['ID']['input']; +}; + +export type QuizCompletedPayload = { + readonly __typename: 'QuizCompletedPayload'; + readonly errors: ReadonlyArray; + readonly quiz?: Maybe; +}; + +export type QuizQuestion = { + readonly __typename: 'QuizQuestion'; + /** The earn reward in Satoshis for the quiz question */ + readonly earnAmount: Scalars['SatAmount']['output']; + readonly id: Scalars['ID']['output']; +}; + +export type RealtimePrice = { + readonly __typename: 'RealtimePrice'; + readonly btcSatPrice: PriceOfOneSatInMinorUnit; + readonly denominatorCurrency: Scalars['DisplayCurrency']['output']; + readonly id: Scalars['ID']['output']; + /** Unix timestamp (number of seconds elapsed since January 1, 1970 00:00:00 UTC) */ + readonly timestamp: Scalars['Timestamp']['output']; + readonly usdCentPrice: PriceOfOneUsdCentInMinorUnit; +}; + +export type RealtimePriceInput = { + readonly currency?: InputMaybe; +}; + +export type RealtimePricePayload = { + readonly __typename: 'RealtimePricePayload'; + readonly errors: ReadonlyArray; + readonly realtimePrice?: Maybe; +}; + +export type SatAmountPayload = { + readonly __typename: 'SatAmountPayload'; + readonly amount?: Maybe; + readonly errors: ReadonlyArray; +}; + +export type SettlementVia = SettlementViaIntraLedger | SettlementViaLn | SettlementViaOnChain; + +export type SettlementViaIntraLedger = { + readonly __typename: 'SettlementViaIntraLedger'; + /** Settlement destination: Could be null if the payee does not have a username */ + readonly counterPartyUsername?: Maybe; + readonly counterPartyWalletId?: Maybe; +}; + +export type SettlementViaLn = { + readonly __typename: 'SettlementViaLn'; + /** @deprecated Shifting property to 'preImage' to improve granularity of the LnPaymentSecret type */ + readonly paymentSecret?: Maybe; + readonly preImage?: Maybe; +}; + +export type SettlementViaOnChain = { + readonly __typename: 'SettlementViaOnChain'; + readonly transactionHash?: Maybe; + readonly vout?: Maybe; +}; + +export type Subscription = { + readonly __typename: 'Subscription'; + readonly lnInvoicePaymentStatus: LnInvoicePaymentStatusPayload; + readonly myUpdates: MyUpdatesPayload; + readonly price: PricePayload; + /** Returns the price of 1 satoshi */ + readonly realtimePrice: RealtimePricePayload; +}; + + +export type SubscriptionLnInvoicePaymentStatusArgs = { + input: LnInvoicePaymentStatusInput; +}; + + +export type SubscriptionPriceArgs = { + input: PriceInput; +}; + + +export type SubscriptionRealtimePriceArgs = { + input: RealtimePriceInput; +}; + +export type SuccessPayload = { + readonly __typename: 'SuccessPayload'; + readonly errors: ReadonlyArray; + readonly success?: Maybe; +}; + +/** + * Give details about an individual transaction. + * Galoy have a smart routing system which is automatically + * settling intraledger when both the payer and payee use the same wallet + * therefore it's possible the transactions is being initiated onchain + * or with lightning but settled intraledger. + */ +export type Transaction = { + readonly __typename: 'Transaction'; + readonly createdAt: Scalars['Timestamp']['output']; + readonly direction: TxDirection; + readonly id: Scalars['ID']['output']; + /** From which protocol the payment has been initiated. */ + readonly initiationVia: InitiationVia; + readonly memo?: Maybe; + /** Amount of the settlement currency sent or received. */ + readonly settlementAmount: Scalars['SignedAmount']['output']; + /** Wallet currency for transaction. */ + readonly settlementCurrency: WalletCurrency; + readonly settlementDisplayAmount: Scalars['SignedDisplayMajorAmount']['output']; + readonly settlementDisplayCurrency: Scalars['DisplayCurrency']['output']; + readonly settlementDisplayFee: Scalars['SignedDisplayMajorAmount']['output']; + readonly settlementFee: Scalars['SignedAmount']['output']; + /** Price in WALLETCURRENCY/SETTLEMENTUNIT at time of settlement. */ + readonly settlementPrice: PriceOfOneSettlementMinorUnitInDisplayMinorUnit; + /** To which protocol the payment has settled on. */ + readonly settlementVia: SettlementVia; + readonly status: TxStatus; +}; + +/** A connection to a list of items. */ +export type TransactionConnection = { + readonly __typename: 'TransactionConnection'; + /** A list of edges. */ + readonly edges?: Maybe>; + /** Information to aid in pagination. */ + readonly pageInfo: PageInfo; +}; + +/** An edge in a connection. */ +export type TransactionEdge = { + readonly __typename: 'TransactionEdge'; + /** A cursor for use in pagination */ + readonly cursor: Scalars['String']['output']; + /** The item at the end of the edge */ + readonly node: Transaction; +}; + +export const TxDirection = { + Receive: 'RECEIVE', + Send: 'SEND' +} as const; + +export type TxDirection = typeof TxDirection[keyof typeof TxDirection]; +export const TxNotificationType = { + IntraLedgerPayment: 'IntraLedgerPayment', + IntraLedgerReceipt: 'IntraLedgerReceipt', + LnInvoicePaid: 'LnInvoicePaid', + OnchainPayment: 'OnchainPayment', + OnchainReceipt: 'OnchainReceipt', + OnchainReceiptPending: 'OnchainReceiptPending' +} as const; + +export type TxNotificationType = typeof TxNotificationType[keyof typeof TxNotificationType]; +export const TxStatus = { + Failure: 'FAILURE', + Pending: 'PENDING', + Success: 'SUCCESS' +} as const; + +export type TxStatus = typeof TxStatus[keyof typeof TxStatus]; +export type UpgradePayload = { + readonly __typename: 'UpgradePayload'; + readonly authToken?: Maybe; + readonly errors: ReadonlyArray; + readonly success: Scalars['Boolean']['output']; +}; + +/** A wallet belonging to an account which contains a USD balance and a list of transactions. */ +export type UsdWallet = Wallet & { + readonly __typename: 'UsdWallet'; + readonly accountId: Scalars['ID']['output']; + readonly balance: Scalars['SignedAmount']['output']; + readonly id: Scalars['ID']['output']; + /** An unconfirmed incoming onchain balance. */ + readonly pendingIncomingBalance: Scalars['SignedAmount']['output']; + readonly transactions?: Maybe; + readonly transactionsByAddress?: Maybe; + readonly walletCurrency: WalletCurrency; +}; + + +/** A wallet belonging to an account which contains a USD balance and a list of transactions. */ +export type UsdWalletTransactionsArgs = { + after?: InputMaybe; + before?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; +}; + + +/** A wallet belonging to an account which contains a USD balance and a list of transactions. */ +export type UsdWalletTransactionsByAddressArgs = { + address: Scalars['OnChainAddress']['input']; + after?: InputMaybe; + before?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; +}; + +export type User = { + readonly __typename: 'User'; + /** + * Get single contact details. + * Can include the transactions associated with the contact. + * @deprecated will be moved to Accounts + */ + readonly contactByUsername: UserContact; + /** + * Get full list of contacts. + * Can include the transactions associated with each contact. + * @deprecated will be moved to account + */ + readonly contacts: ReadonlyArray; + readonly createdAt: Scalars['Timestamp']['output']; + readonly defaultAccount: Account; + /** Email address */ + readonly email?: Maybe; + readonly id: Scalars['ID']['output']; + /** + * Preferred language for user. + * When value is 'default' the intent is to use preferred language from OS settings. + */ + readonly language: Scalars['Language']['output']; + /** Phone number with international calling code. */ + readonly phone?: Maybe; + /** + * List the quiz questions the user may have completed. + * @deprecated use Quiz from Account instead + */ + readonly quizQuestions: ReadonlyArray; + /** Whether TOTP is enabled for this user. */ + readonly totpEnabled: Scalars['Boolean']['output']; + /** + * Optional immutable user friendly identifier. + * @deprecated will be moved to @Handle in Account and Wallet + */ + readonly username?: Maybe; +}; + + +export type UserContactByUsernameArgs = { + username: Scalars['Username']['input']; +}; + +export type UserContact = { + readonly __typename: 'UserContact'; + /** + * Alias the user can set for this contact. + * Only the user can see the alias attached to their contact. + */ + readonly alias?: Maybe; + readonly id: Scalars['Username']['output']; + /** Paginated list of transactions sent to/from this contact. */ + readonly transactions?: Maybe; + readonly transactionsCount: Scalars['Int']['output']; + /** Actual identifier of the contact. */ + readonly username: Scalars['Username']['output']; +}; + + +export type UserContactTransactionsArgs = { + after?: InputMaybe; + before?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; +}; + +export type UserContactUpdateAliasInput = { + readonly alias: Scalars['ContactAlias']['input']; + readonly username: Scalars['Username']['input']; +}; + +export type UserContactUpdateAliasPayload = { + readonly __typename: 'UserContactUpdateAliasPayload'; + readonly contact?: Maybe; + readonly errors: ReadonlyArray; +}; + +export type UserEmailDeletePayload = { + readonly __typename: 'UserEmailDeletePayload'; + readonly errors: ReadonlyArray; + readonly me?: Maybe; +}; + +export type UserEmailRegistrationInitiateInput = { + readonly email: Scalars['EmailAddress']['input']; +}; + +export type UserEmailRegistrationInitiatePayload = { + readonly __typename: 'UserEmailRegistrationInitiatePayload'; + readonly emailRegistrationId?: Maybe; + readonly errors: ReadonlyArray; + readonly me?: Maybe; +}; + +export type UserEmailRegistrationValidateInput = { + readonly code: Scalars['OneTimeAuthCode']['input']; + readonly emailRegistrationId: Scalars['EmailRegistrationId']['input']; +}; + +export type UserEmailRegistrationValidatePayload = { + readonly __typename: 'UserEmailRegistrationValidatePayload'; + readonly errors: ReadonlyArray; + readonly me?: Maybe; +}; + +export type UserLoginInput = { + readonly code: Scalars['OneTimeAuthCode']['input']; + readonly phone: Scalars['Phone']['input']; +}; + +export type UserLoginUpgradeInput = { + readonly code: Scalars['OneTimeAuthCode']['input']; + readonly phone: Scalars['Phone']['input']; +}; + +export type UserLogoutInput = { + readonly deviceToken: Scalars['String']['input']; +}; + +export type UserPhoneDeletePayload = { + readonly __typename: 'UserPhoneDeletePayload'; + readonly errors: ReadonlyArray; + readonly me?: Maybe; +}; + +export type UserPhoneRegistrationInitiateInput = { + readonly channel?: InputMaybe; + readonly phone: Scalars['Phone']['input']; +}; + +export type UserPhoneRegistrationValidateInput = { + readonly code: Scalars['OneTimeAuthCode']['input']; + readonly phone: Scalars['Phone']['input']; +}; + +export type UserPhoneRegistrationValidatePayload = { + readonly __typename: 'UserPhoneRegistrationValidatePayload'; + readonly errors: ReadonlyArray; + readonly me?: Maybe; +}; + +export type UserQuizQuestion = { + readonly __typename: 'UserQuizQuestion'; + readonly completed: Scalars['Boolean']['output']; + readonly question: QuizQuestion; +}; + +export type UserQuizQuestionUpdateCompletedInput = { + readonly id: Scalars['ID']['input']; +}; + +export type UserQuizQuestionUpdateCompletedPayload = { + readonly __typename: 'UserQuizQuestionUpdateCompletedPayload'; + readonly errors: ReadonlyArray; + readonly userQuizQuestion?: Maybe; +}; + +export type UserTotpDeleteInput = { + readonly authToken: Scalars['AuthToken']['input']; +}; + +export type UserTotpDeletePayload = { + readonly __typename: 'UserTotpDeletePayload'; + readonly errors: ReadonlyArray; + readonly me?: Maybe; +}; + +export type UserTotpRegistrationInitiateInput = { + readonly authToken: Scalars['AuthToken']['input']; +}; + +export type UserTotpRegistrationInitiatePayload = { + readonly __typename: 'UserTotpRegistrationInitiatePayload'; + readonly errors: ReadonlyArray; + readonly totpRegistrationId?: Maybe; + readonly totpSecret?: Maybe; +}; + +export type UserTotpRegistrationValidateInput = { + readonly authToken: Scalars['AuthToken']['input']; + readonly totpCode: Scalars['TotpCode']['input']; + readonly totpRegistrationId: Scalars['TotpRegistrationId']['input']; +}; + +export type UserTotpRegistrationValidatePayload = { + readonly __typename: 'UserTotpRegistrationValidatePayload'; + readonly errors: ReadonlyArray; + readonly me?: Maybe; +}; + +export type UserUpdate = IntraLedgerUpdate | LnUpdate | OnChainUpdate | Price | RealtimePrice; + +export type UserUpdateLanguageInput = { + readonly language: Scalars['Language']['input']; +}; + +export type UserUpdateLanguagePayload = { + readonly __typename: 'UserUpdateLanguagePayload'; + readonly errors: ReadonlyArray; + readonly user?: Maybe; +}; + +export type UserUpdateUsernameInput = { + readonly username: Scalars['Username']['input']; +}; + +export type UserUpdateUsernamePayload = { + readonly __typename: 'UserUpdateUsernamePayload'; + readonly errors: ReadonlyArray; + readonly user?: Maybe; +}; + +/** A generic wallet which stores value in one of our supported currencies. */ +export type Wallet = { + readonly accountId: Scalars['ID']['output']; + readonly balance: Scalars['SignedAmount']['output']; + readonly id: Scalars['ID']['output']; + readonly pendingIncomingBalance: Scalars['SignedAmount']['output']; + /** + * Transactions are ordered anti-chronologically, + * ie: the newest transaction will be first + */ + readonly transactions?: Maybe; + /** + * Transactions are ordered anti-chronologically, + * ie: the newest transaction will be first + */ + readonly transactionsByAddress?: Maybe; + readonly walletCurrency: WalletCurrency; +}; + + +/** A generic wallet which stores value in one of our supported currencies. */ +export type WalletTransactionsArgs = { + after?: InputMaybe; + before?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; +}; + + +/** A generic wallet which stores value in one of our supported currencies. */ +export type WalletTransactionsByAddressArgs = { + address: Scalars['OnChainAddress']['input']; + after?: InputMaybe; + before?: InputMaybe; + first?: InputMaybe; + last?: InputMaybe; +}; + +export const WalletCurrency = { + Btc: 'BTC', + Usd: 'USD' +} as const; + +export type WalletCurrency = typeof WalletCurrency[keyof typeof WalletCurrency]; +export type CountryCodesQueryVariables = Exact<{ [key: string]: never; }>; + + +export type CountryCodesQuery = { readonly __typename: 'Query', readonly globals?: { readonly __typename: 'Globals', readonly supportedCountries: ReadonlyArray<{ readonly __typename: 'Country', readonly id: string, readonly supportedAuthChannels: ReadonlyArray }> } | null }; + +export type GetUserIdQueryVariables = Exact<{ [key: string]: never; }>; + + +export type GetUserIdQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string } | null }; + + +export const CountryCodesDocument = gql` + query CountryCodes { + globals { + supportedCountries { + id + supportedAuthChannels + } + } +} + `; + +/** + * __useCountryCodesQuery__ + * + * To run a query within a React component, call `useCountryCodesQuery` and pass it any options that fit your needs. + * When your component renders, `useCountryCodesQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useCountryCodesQuery({ + * variables: { + * }, + * }); + */ +export function useCountryCodesQuery(baseOptions?: Apollo.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(CountryCodesDocument, options); + } +export function useCountryCodesLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(CountryCodesDocument, options); + } +export type CountryCodesQueryHookResult = ReturnType; +export type CountryCodesLazyQueryHookResult = ReturnType; +export type CountryCodesQueryResult = Apollo.QueryResult; +export const GetUserIdDocument = gql` + query getUserId { + me { + id + } +} + `; + +/** + * __useGetUserIdQuery__ + * + * To run a query within a React component, call `useGetUserIdQuery` and pass it any options that fit your needs. + * When your component renders, `useGetUserIdQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useGetUserIdQuery({ + * variables: { + * }, + * }); + */ +export function useGetUserIdQuery(baseOptions?: Apollo.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(GetUserIdDocument, options); + } +export function useGetUserIdLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(GetUserIdDocument, options); + } +export type GetUserIdQueryHookResult = ReturnType; +export type GetUserIdLazyQueryHookResult = ReturnType; +export type GetUserIdQueryResult = Apollo.QueryResult; \ No newline at end of file diff --git a/apps/consent/app/graphql/queries/get-supported-countries.ts b/apps/consent/app/graphql/queries/get-supported-countries.ts new file mode 100644 index 00000000000..11b7b7b10d5 --- /dev/null +++ b/apps/consent/app/graphql/queries/get-supported-countries.ts @@ -0,0 +1,35 @@ +import { gql } from "@apollo/client"; +import { graphQlClient } from "../apollo-config"; +import { CountryCodesDocument, CountryCodesQuery } from "../generated"; + +gql` + query CountryCodes { + globals { + supportedCountries { + id + supportedAuthChannels + } + } + } +`; +export type AuthChannels = "SMS" | "WHATSAPP"; + +export interface SupportedCountry { + readonly id: string; + readonly supportedAuthChannels: readonly AuthChannels[]; +} + +export const getSupportedCountryCodes = async (): Promise< + readonly SupportedCountry[] | undefined +> => { + try { + const client = graphQlClient(); + const response = await client.query({ + query: CountryCodesDocument, + }); + return response.data?.globals?.supportedCountries; + } catch (err) { + console.error("error in 'me-query' ", err); + return undefined; + } +}; diff --git a/apps/consent/app/graphql/queries/me-query.ts b/apps/consent/app/graphql/queries/me-query.ts new file mode 100644 index 00000000000..a7619115cf9 --- /dev/null +++ b/apps/consent/app/graphql/queries/me-query.ts @@ -0,0 +1,27 @@ +import { gql } from "@apollo/client"; +import { graphQlClient } from "../apollo-config"; +import { GetUserIdDocument } from "../generated"; +import { GetUserIdQuery } from "../generated"; + +gql` + query getUserId { + me { + id + } + } +`; + +export const getUserId = async ( + authToken: string +): Promise => { + try { + const client = graphQlClient(authToken) + const response = await client.query({ + query: GetUserIdDocument, + }); + return response.data?.me?.id; + } catch (err) { + console.error("error in 'me-query' ", err); + return undefined; + } +}; diff --git a/apps/consent/app/index.types.ts b/apps/consent/app/index.types.ts new file mode 100644 index 00000000000..4918fe26fc1 --- /dev/null +++ b/apps/consent/app/index.types.ts @@ -0,0 +1,10 @@ +export enum LoginType { + phone = "Phone", + email = "Email", +} + +export interface ServerActionResponse { + error: boolean; + message: string; + responsePayload: ResponseBody; +} diff --git a/apps/consent/app/layout.tsx b/apps/consent/app/layout.tsx new file mode 100644 index 00000000000..6b5b11c09ab --- /dev/null +++ b/apps/consent/app/layout.tsx @@ -0,0 +1,41 @@ +import "./globals.css"; +import "react-toastify/dist/ReactToastify.css"; +import Script from "next/script"; +import type { Metadata } from "next"; +import { Inter_Tight } from "next/font/google"; +import { ToastContainer } from "react-toastify"; + +const inter = Inter_Tight({ subsets: ["latin"] }); +export const metadata: Metadata = { + title: "Create Next App", + description: "Generated by create next app", +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + <> + +