@mezo-org/passport 0.4.0-dev.0 → 0.4.0-dev.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/dist/src/api/auth.d.ts +73 -0
  2. package/dist/src/api/auth.d.ts.map +1 -0
  3. package/dist/src/api/auth.js +108 -0
  4. package/dist/src/api/auth.js.map +1 -0
  5. package/dist/src/hooks/constants.d.ts +7 -0
  6. package/dist/src/hooks/constants.d.ts.map +1 -0
  7. package/dist/src/hooks/constants.js +7 -0
  8. package/dist/src/hooks/constants.js.map +1 -0
  9. package/dist/src/hooks/index.d.ts +13 -0
  10. package/dist/src/hooks/index.d.ts.map +1 -1
  11. package/dist/src/hooks/index.js +13 -0
  12. package/dist/src/hooks/index.js.map +1 -1
  13. package/dist/src/hooks/useAuthApiClient.d.ts +2 -0
  14. package/dist/src/hooks/useAuthApiClient.d.ts.map +1 -0
  15. package/dist/src/hooks/useAuthApiClient.js +6 -0
  16. package/dist/src/hooks/useAuthApiClient.js.map +1 -0
  17. package/dist/src/hooks/useCreateAccount.d.ts +204 -0
  18. package/dist/src/hooks/useCreateAccount.d.ts.map +1 -0
  19. package/dist/src/hooks/useCreateAccount.js +23 -0
  20. package/dist/src/hooks/useCreateAccount.js.map +1 -0
  21. package/dist/src/hooks/useCreateSession.d.ts +246 -0
  22. package/dist/src/hooks/useCreateSession.d.ts.map +1 -0
  23. package/dist/src/hooks/useCreateSession.js +35 -0
  24. package/dist/src/hooks/useCreateSession.js.map +1 -0
  25. package/dist/src/hooks/useGetAccountByAddress.d.ts +6 -0
  26. package/dist/src/hooks/useGetAccountByAddress.d.ts.map +1 -0
  27. package/dist/src/hooks/useGetAccountByAddress.js +18 -0
  28. package/dist/src/hooks/useGetAccountByAddress.js.map +1 -0
  29. package/dist/src/hooks/useGetAccountByMezoId.d.ts +6 -0
  30. package/dist/src/hooks/useGetAccountByMezoId.d.ts.map +1 -0
  31. package/dist/src/hooks/useGetAccountByMezoId.js +18 -0
  32. package/dist/src/hooks/useGetAccountByMezoId.js.map +1 -0
  33. package/dist/src/hooks/useGetCurrentAccount.d.ts +12 -0
  34. package/dist/src/hooks/useGetCurrentAccount.d.ts.map +1 -0
  35. package/dist/src/hooks/useGetCurrentAccount.js +15 -0
  36. package/dist/src/hooks/useGetCurrentAccount.js.map +1 -0
  37. package/dist/src/hooks/useGetSession.d.ts +21 -0
  38. package/dist/src/hooks/useGetSession.d.ts.map +1 -0
  39. package/dist/src/hooks/useGetSession.js +15 -0
  40. package/dist/src/hooks/useGetSession.js.map +1 -0
  41. package/dist/src/hooks/useLinkAccount.d.ts +178 -0
  42. package/dist/src/hooks/useLinkAccount.d.ts.map +1 -0
  43. package/dist/src/hooks/useLinkAccount.js +32 -0
  44. package/dist/src/hooks/useLinkAccount.js.map +1 -0
  45. package/dist/src/hooks/usePassportContext.d.ts +3 -0
  46. package/dist/src/hooks/usePassportContext.d.ts.map +1 -0
  47. package/dist/src/hooks/usePassportContext.js +10 -0
  48. package/dist/src/hooks/usePassportContext.js.map +1 -0
  49. package/dist/src/hooks/useSignInWithDiscord.d.ts +242 -0
  50. package/dist/src/hooks/useSignInWithDiscord.d.ts.map +1 -0
  51. package/dist/src/hooks/useSignInWithDiscord.js +36 -0
  52. package/dist/src/hooks/useSignInWithDiscord.js.map +1 -0
  53. package/dist/src/hooks/useSignInWithWallet.d.ts +242 -0
  54. package/dist/src/hooks/useSignInWithWallet.d.ts.map +1 -0
  55. package/dist/src/hooks/useSignInWithWallet.js +49 -0
  56. package/dist/src/hooks/useSignInWithWallet.js.map +1 -0
  57. package/dist/src/hooks/useSignOut.d.ts +88 -0
  58. package/dist/src/hooks/useSignOut.d.ts.map +1 -0
  59. package/dist/src/hooks/useSignOut.js +17 -0
  60. package/dist/src/hooks/useSignOut.js.map +1 -0
  61. package/dist/src/hooks/useUpdateMezoId.d.ts +160 -0
  62. package/dist/src/hooks/useUpdateMezoId.d.ts.map +1 -0
  63. package/dist/src/hooks/useUpdateMezoId.js +23 -0
  64. package/dist/src/hooks/useUpdateMezoId.js.map +1 -0
  65. package/dist/src/index.d.ts +1 -0
  66. package/dist/src/index.d.ts.map +1 -1
  67. package/dist/src/index.js +1 -0
  68. package/dist/src/index.js.map +1 -1
  69. package/dist/src/provider.d.ts +20 -0
  70. package/dist/src/provider.d.ts.map +1 -0
  71. package/dist/src/provider.js +25 -0
  72. package/dist/src/provider.js.map +1 -0
  73. package/dist/src/utils/siww.d.ts +4 -0
  74. package/dist/src/utils/siww.d.ts.map +1 -0
  75. package/dist/src/utils/siww.js +19 -0
  76. package/dist/src/utils/siww.js.map +1 -0
  77. package/dist/src/utils/time.d.ts +5 -0
  78. package/dist/src/utils/time.d.ts.map +1 -0
  79. package/dist/src/utils/time.js +5 -0
  80. package/dist/src/utils/time.js.map +1 -0
  81. package/package.json +8 -4
  82. package/src/api/auth.ts +203 -0
  83. package/src/hooks/constants.ts +6 -0
  84. package/src/hooks/index.ts +13 -0
  85. package/src/hooks/useAuthApiClient.ts +6 -0
  86. package/src/hooks/useCreateAccount.ts +27 -0
  87. package/src/hooks/useCreateSession.ts +38 -0
  88. package/src/hooks/useGetAccountByAddress.ts +19 -0
  89. package/src/hooks/useGetAccountByMezoId.ts +19 -0
  90. package/src/hooks/useGetCurrentAccount.ts +16 -0
  91. package/src/hooks/useGetSession.ts +15 -0
  92. package/src/hooks/useLinkAccount.ts +45 -0
  93. package/src/hooks/usePassportContext.ts +11 -0
  94. package/src/hooks/useSignInWithDiscord.ts +44 -0
  95. package/src/hooks/useSignInWithWallet.ts +62 -0
  96. package/src/hooks/useSignOut.ts +19 -0
  97. package/src/hooks/useUpdateMezoId.ts +25 -0
  98. package/src/index.ts +1 -0
  99. package/src/provider.ts +57 -0
  100. package/src/utils/siww.ts +31 -0
  101. package/src/utils/time.ts +4 -0
@@ -0,0 +1,38 @@
1
+ import { useQueryClient, useMutation } from "@tanstack/react-query"
2
+ import { useAuthApiClient } from "./useAuthApiClient"
3
+ import { CreateSessionRequest } from "../api/auth"
4
+ import { QUERY_KEYS } from "./constants"
5
+
6
+ /**
7
+ * This hook is not exposed for external consumers. For creating session they
8
+ * should use `useSignIn` hook related to the authentication method.
9
+ */
10
+ export function useCreateSession(useMutationOptions = {}) {
11
+ const queryClient = useQueryClient()
12
+ const authApiClient = useAuthApiClient()
13
+
14
+ const { mutate, mutateAsync, ...rest } = useMutation({
15
+ mutationFn: (createSessionRequest: CreateSessionRequest) =>
16
+ authApiClient.createSession(createSessionRequest),
17
+ onSuccess: (data) => {
18
+ // Since `getSession` query also has code in it's query keys we can't
19
+ // set query data for a specific query, because we don't know if the
20
+ // code was used or not. Because of that we just reset all getSession
21
+ // queries
22
+ queryClient.resetQueries({
23
+ queryKey: [QUERY_KEYS.SESSION],
24
+ exact: false,
25
+ })
26
+ if ("user" in data) {
27
+ queryClient.setQueryData([QUERY_KEYS.CURRENT_ACCOUNT], data.user)
28
+ } else {
29
+ queryClient.resetQueries({
30
+ queryKey: [QUERY_KEYS.CURRENT_ACCOUNT],
31
+ })
32
+ }
33
+ },
34
+ ...useMutationOptions,
35
+ })
36
+
37
+ return { createSession: mutate, createSessionAsync: mutateAsync, ...rest }
38
+ }
@@ -0,0 +1,19 @@
1
+ import { useQuery, skipToken } from "@tanstack/react-query"
2
+ import { useAuthApiClient } from "./useAuthApiClient"
3
+ import { QUERY_KEYS } from "./constants"
4
+ import { ONE_MINUTE_MS } from "../utils/time"
5
+
6
+ export function useGetAccountByAddress(address?: string, useQueryOptions = {}) {
7
+ const authApiClient = useAuthApiClient()
8
+
9
+ return useQuery({
10
+ queryKey: [QUERY_KEYS.ACCOUNT_BY_ADDRESS, address],
11
+ queryFn: address
12
+ ? () => authApiClient.getAccountByMezoIdOrAddress(address)
13
+ : skipToken,
14
+ staleTime: ONE_MINUTE_MS,
15
+ retry: 1,
16
+ enabled: !!address,
17
+ ...useQueryOptions,
18
+ })
19
+ }
@@ -0,0 +1,19 @@
1
+ import { useQuery, skipToken } from "@tanstack/react-query"
2
+ import { useAuthApiClient } from "./useAuthApiClient"
3
+ import { QUERY_KEYS } from "./constants"
4
+ import { ONE_MINUTE_MS } from "../utils/time"
5
+
6
+ export function useGetAccountByMezoId(mezoId?: string, useQueryOptions = {}) {
7
+ const authApiClient = useAuthApiClient()
8
+
9
+ return useQuery({
10
+ queryKey: [QUERY_KEYS.ACCOUNT_BY_MEZO_ID, mezoId],
11
+ queryFn: mezoId
12
+ ? () => authApiClient.getAccountByMezoIdOrAddress(mezoId)
13
+ : skipToken,
14
+ staleTime: ONE_MINUTE_MS,
15
+ retry: 1,
16
+ enabled: !!mezoId,
17
+ ...useQueryOptions,
18
+ })
19
+ }
@@ -0,0 +1,16 @@
1
+ import { useQuery } from "@tanstack/react-query"
2
+ import { useAuthApiClient } from "./useAuthApiClient"
3
+ import { QUERY_KEYS } from "./constants"
4
+ import { ONE_MINUTE_MS } from "../utils/time"
5
+
6
+ export function useGetCurrentAccount(useQueryOptions = {}) {
7
+ const authApiClient = useAuthApiClient()
8
+
9
+ return useQuery({
10
+ queryKey: [QUERY_KEYS.CURRENT_ACCOUNT],
11
+ queryFn: () => authApiClient.getCurrentAccount(),
12
+ staleTime: ONE_MINUTE_MS,
13
+ retry: 1,
14
+ ...useQueryOptions,
15
+ })
16
+ }
@@ -0,0 +1,15 @@
1
+ import { useQuery } from "@tanstack/react-query"
2
+ import { useAuthApiClient } from "./useAuthApiClient"
3
+ import { QUERY_KEYS } from "./constants"
4
+ import { ONE_MINUTE_MS } from "../utils/time"
5
+
6
+ export function useGetSession(code?: string, useQueryOptions = {}) {
7
+ const authApiClient = useAuthApiClient()
8
+ return useQuery({
9
+ queryKey: [QUERY_KEYS.SESSION, code],
10
+ queryFn: () => authApiClient.getSession(code),
11
+ staleTime: ONE_MINUTE_MS,
12
+ retry: 1,
13
+ ...useQueryOptions,
14
+ })
15
+ }
@@ -0,0 +1,45 @@
1
+ import { useQueryClient, useMutation } from "@tanstack/react-query"
2
+ import { useAuthApiClient } from "./useAuthApiClient"
3
+ import { LinkAccountRequest } from "../api/auth"
4
+ import { QUERY_KEYS } from "./constants"
5
+
6
+ export function useLinkAccount(useMutationOptions = {}) {
7
+ const queryClient = useQueryClient()
8
+ const authApiClient = useAuthApiClient()
9
+
10
+ const { mutate, mutateAsync, ...rest } = useMutation({
11
+ mutationFn: (linkAccountRequest: LinkAccountRequest) =>
12
+ authApiClient.linkAccount(linkAccountRequest),
13
+ onSuccess: (data) => {
14
+ if ("user_metadata" in data) {
15
+ if (data.user_metadata.mezoId) {
16
+ queryClient.setQueryData(
17
+ [QUERY_KEYS.ACCOUNT_BY_MEZO_ID, data.user_metadata.mezoId],
18
+ data,
19
+ )
20
+ }
21
+
22
+ queryClient.setQueryData(
23
+ [QUERY_KEYS.ACCOUNT_BY_ADDRESS, data.user_metadata.btcAddress],
24
+ data,
25
+ )
26
+ queryClient.setQueryData(
27
+ [QUERY_KEYS.ACCOUNT_BY_ADDRESS, data.user_metadata.evmAddress],
28
+ data,
29
+ )
30
+ } else {
31
+ queryClient.resetQueries({
32
+ queryKey: [QUERY_KEYS.ACCOUNT_BY_MEZO_ID],
33
+ exact: false,
34
+ })
35
+ queryClient.resetQueries({
36
+ queryKey: [QUERY_KEYS.ACCOUNT_BY_ADDRESS],
37
+ exact: false,
38
+ })
39
+ }
40
+ },
41
+ ...useMutationOptions,
42
+ })
43
+
44
+ return { linkAccount: mutate, linkAccountAsync: mutateAsync, ...rest }
45
+ }
@@ -0,0 +1,11 @@
1
+ import { useContext } from "react"
2
+ import { PassportContext, PassportContextValue } from "../provider"
3
+
4
+ export function usePassportContext(): PassportContextValue {
5
+ const passportContext = useContext(PassportContext)
6
+ if (!passportContext) {
7
+ throw new Error("usePassportContext must be used within PassportProvider!")
8
+ }
9
+
10
+ return passportContext
11
+ }
@@ -0,0 +1,44 @@
1
+ import { useAccount } from "wagmi"
2
+ import { useMutation } from "@tanstack/react-query"
3
+ import { useGetSession } from "./useGetSession"
4
+ import { useCreateSession } from "./useCreateSession"
5
+
6
+ function useSignInWithDiscord() {
7
+ const { address } = useAccount()
8
+ const { refetch: getSession } = useGetSession(undefined, {
9
+ enabled: false,
10
+ })
11
+ const { createSessionAsync } = useCreateSession()
12
+
13
+ const { mutate, mutateAsync, ...signInMutationRestParameters } = useMutation({
14
+ mutationFn: async () => {
15
+ if (!address) {
16
+ throw new Error("Sign in error: User not connected!")
17
+ }
18
+
19
+ const getSessionResult = await getSession()
20
+
21
+ // TODO: We should create a separate endpoint that will always return nonce
22
+ if (!getSessionResult.data || !("nonce" in getSessionResult.data)) {
23
+ if (getSessionResult.error) {
24
+ throw new Error(`Sign in error: ${getSessionResult.error}`)
25
+ }
26
+ throw new Error(
27
+ "Sign in error: Nonce not available! Remove the session first.",
28
+ )
29
+ }
30
+
31
+ return createSessionAsync({
32
+ type: "discord",
33
+ })
34
+ },
35
+ })
36
+
37
+ return {
38
+ signIn: mutate,
39
+ signInAsync: mutateAsync,
40
+ ...signInMutationRestParameters,
41
+ }
42
+ }
43
+
44
+ export { useSignInWithDiscord }
@@ -0,0 +1,62 @@
1
+ import { useAccount, useSignMessage } from "wagmi"
2
+ import { useBitcoinAccount } from "@mezo-org/orangekit"
3
+ import { useMutation } from "@tanstack/react-query"
4
+ import { useGetSession } from "./useGetSession"
5
+ import { useCreateSession } from "./useCreateSession"
6
+ import { createSignInWithWalletMessage } from "../utils/siww"
7
+
8
+ function useSignInWithWallet() {
9
+ console.log("use sign int with wallet broooo")
10
+ const { chainId, address, connector } = useAccount()
11
+ const { btcAddress } = useBitcoinAccount()
12
+ const { refetch: getSession } = useGetSession(undefined, {
13
+ enabled: false,
14
+ })
15
+ const { createSessionAsync } = useCreateSession()
16
+ const { signMessageAsync } = useSignMessage()
17
+
18
+ const { mutate, mutateAsync, ...signInMutationRestParameters } = useMutation({
19
+ mutationFn: async () => {
20
+ if (!address) {
21
+ throw new Error("Sign in error: User not connected!")
22
+ }
23
+
24
+ const getSessionResult = await getSession()
25
+
26
+ // TODO: We should create a separate endpoint that will always return nonce
27
+ if (!getSessionResult.data || !("nonce" in getSessionResult.data)) {
28
+ if (getSessionResult.error) {
29
+ throw new Error(`Sign in error: ${getSessionResult.error}`)
30
+ }
31
+ throw new Error(
32
+ "Sign in error: Nonce not available! Remove the session first.",
33
+ )
34
+ }
35
+
36
+ const networkFamily = btcAddress ? "bitcoin" : "evm"
37
+ const messageResult = createSignInWithWalletMessage(
38
+ btcAddress ? btcAddress! : address!,
39
+ getSessionResult.data.nonce,
40
+ networkFamily,
41
+ chainId,
42
+ )
43
+ const signatureResult = await signMessageAsync({
44
+ message: messageResult,
45
+ connector,
46
+ })
47
+ return createSessionAsync({
48
+ type: "wallet",
49
+ message: messageResult,
50
+ signature: signatureResult,
51
+ })
52
+ },
53
+ })
54
+
55
+ return {
56
+ signIn: mutate,
57
+ signInAsync: mutateAsync,
58
+ ...signInMutationRestParameters,
59
+ }
60
+ }
61
+
62
+ export { useSignInWithWallet }
@@ -0,0 +1,19 @@
1
+ import { useMutation, useQueryClient } from "@tanstack/react-query"
2
+ import { useAuthApiClient } from "./useAuthApiClient"
3
+ import { QUERY_KEYS } from "./constants"
4
+
5
+ export function useSignOut(useMutationOptions = {}) {
6
+ const queryClient = useQueryClient()
7
+ const authApiClient = useAuthApiClient()
8
+
9
+ const { mutate, mutateAsync, ...rest } = useMutation({
10
+ mutationFn: () => authApiClient.deleteSession(),
11
+ onSuccess: () => {
12
+ queryClient.resetQueries({ queryKey: [QUERY_KEYS.SESSION], exact: false })
13
+ queryClient.resetQueries({ queryKey: [QUERY_KEYS.CURRENT_ACCOUNT] })
14
+ },
15
+ ...useMutationOptions,
16
+ })
17
+
18
+ return { signOut: mutate, signOutAsync: mutateAsync, ...rest }
19
+ }
@@ -0,0 +1,25 @@
1
+ import { useQueryClient, useMutation } from "@tanstack/react-query"
2
+ import { useAuthApiClient } from "./useAuthApiClient"
3
+ import { QUERY_KEYS } from "./constants"
4
+
5
+ export function useUpdateMezoId(useMutationOptions = {}) {
6
+ const queryClient = useQueryClient()
7
+ const authApiClient = useAuthApiClient()
8
+
9
+ const { mutate, mutateAsync, ...rest } = useMutation({
10
+ mutationFn: (newMezoId: string) => authApiClient.updateMezoId(newMezoId),
11
+ onSuccess: () => {
12
+ queryClient.resetQueries({
13
+ queryKey: [QUERY_KEYS.ACCOUNT_BY_ADDRESS],
14
+ exact: false,
15
+ })
16
+ queryClient.resetQueries({
17
+ queryKey: [QUERY_KEYS.ACCOUNT_BY_MEZO_ID],
18
+ exact: false,
19
+ })
20
+ },
21
+ ...useMutationOptions,
22
+ })
23
+
24
+ return { updateMezoId: mutate, updateMezoIdAsync: mutateAsync, ...rest }
25
+ }
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./config"
2
2
  export * from "./constants"
3
3
  export * from "./hooks"
4
+ export * from "./provider"
4
5
  export * from "./wallet"
@@ -0,0 +1,57 @@
1
+ import { createContext, createElement, useMemo } from "react"
2
+ import { API_ENDPOINTS_BY_ENV, AuthApiClient } from "./api/auth"
3
+
4
+ export interface PassportContextValue {
5
+ authApiClient: AuthApiClient
6
+ }
7
+
8
+ export const PassportContext = createContext<PassportContextValue | undefined>(
9
+ undefined,
10
+ )
11
+
12
+ interface PassportProviderProps {
13
+ // eslint-disable-next-line react/require-default-props
14
+ options: {
15
+ environment?: keyof typeof API_ENDPOINTS_BY_ENV
16
+ apiUrl?: string
17
+ } & (
18
+ | {
19
+ environment: keyof typeof API_ENDPOINTS_BY_ENV
20
+ }
21
+ | {
22
+ apiUrl: string
23
+ }
24
+ )
25
+ children: React.ReactNode
26
+ }
27
+
28
+ export function PassportProvider({ options, children }: PassportProviderProps) {
29
+ const { environment, apiUrl } = options
30
+
31
+ const finalApiUrl = useMemo(() => {
32
+ if (!environment && !apiUrl) {
33
+ throw new Error(
34
+ "Neither apiUrl or environment are specified in Passport Provider",
35
+ )
36
+ }
37
+ if (apiUrl) return apiUrl
38
+
39
+ if (!(environment! in API_ENDPOINTS_BY_ENV)) {
40
+ throw new Error("Wrong environment passed to PassportProvider.")
41
+ }
42
+
43
+ return API_ENDPOINTS_BY_ENV[environment!]
44
+ }, [environment, apiUrl])
45
+
46
+ return createElement(
47
+ PassportContext.Provider,
48
+ {
49
+ value: finalApiUrl
50
+ ? {
51
+ authApiClient: new AuthApiClient(finalApiUrl),
52
+ }
53
+ : undefined,
54
+ },
55
+ children,
56
+ )
57
+ }
@@ -0,0 +1,31 @@
1
+ import { SignInWithWalletMessage } from "@mezo-org/sign-in-with-wallet"
2
+ import { ONE_DAY_MS } from "./time"
3
+
4
+ const SESSION_EXPIRATION_DURATION_MS = 14 * ONE_DAY_MS
5
+
6
+ type NetworkFamily = "evm" | "bitcoin"
7
+
8
+ export function createSignInWithWalletMessage(
9
+ address: string,
10
+ nonce: string,
11
+ networkFamily: NetworkFamily,
12
+ chainId?: number,
13
+ ) {
14
+ const { host: domain, origin: uri } = window.location
15
+
16
+ const message = new SignInWithWalletMessage({
17
+ domain,
18
+ address, // if "bitcoin" this should be btc address, not underlaying eth address
19
+ uri,
20
+ nonce,
21
+ issuedAt: new Date().toISOString(),
22
+ expirationTime: new Date(
23
+ Date.now() + SESSION_EXPIRATION_DURATION_MS,
24
+ ).toISOString(),
25
+ version: "1",
26
+ chainId: networkFamily === "evm" ? chainId : undefined,
27
+ networkFamily,
28
+ })
29
+
30
+ return message.prepareMessage()
31
+ }
@@ -0,0 +1,4 @@
1
+ export const ONE_SECOND_MS = 1000
2
+ export const ONE_MINUTE_MS = 60 * ONE_SECOND_MS
3
+ export const ONE_HOUR_MS = 60 * ONE_MINUTE_MS
4
+ export const ONE_DAY_MS = 24 * ONE_HOUR_MS