thirdweb 5.60.1 → 5.61.0

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 (154) hide show
  1. package/dist/cjs/contract/deployment/utils/create-2-factory.js +53 -46
  2. package/dist/cjs/contract/deployment/utils/create-2-factory.js.map +1 -1
  3. package/dist/cjs/event/actions/get-events.js +4 -4
  4. package/dist/cjs/event/actions/get-events.js.map +1 -1
  5. package/dist/cjs/exports/extensions/unstoppable-domains.js +10 -0
  6. package/dist/cjs/exports/extensions/unstoppable-domains.js.map +1 -0
  7. package/dist/cjs/exports/react.js +4 -2
  8. package/dist/cjs/exports/react.js.map +1 -1
  9. package/dist/cjs/exports/react.native.js +3 -1
  10. package/dist/cjs/exports/react.native.js.map +1 -1
  11. package/dist/cjs/exports/wallets.js.map +1 -1
  12. package/dist/cjs/exports/wallets.native.js.map +1 -1
  13. package/dist/cjs/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/getMany.js +122 -0
  14. package/dist/cjs/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/getMany.js.map +1 -0
  15. package/dist/cjs/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/namehash.js +115 -0
  16. package/dist/cjs/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/namehash.js.map +1 -0
  17. package/dist/cjs/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/reverseNameOf.js +115 -0
  18. package/dist/cjs/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/reverseNameOf.js.map +1 -0
  19. package/dist/cjs/extensions/unstoppable-domains/consts.js +5 -0
  20. package/dist/cjs/extensions/unstoppable-domains/consts.js.map +1 -0
  21. package/dist/cjs/extensions/unstoppable-domains/read/resolveAddress.js +77 -0
  22. package/dist/cjs/extensions/unstoppable-domains/read/resolveAddress.js.map +1 -0
  23. package/dist/cjs/extensions/unstoppable-domains/read/resolveName.js +60 -0
  24. package/dist/cjs/extensions/unstoppable-domains/read/resolveName.js.map +1 -0
  25. package/dist/cjs/react/native/hooks/wallets/useLinkProfile.js +92 -0
  26. package/dist/cjs/react/native/hooks/wallets/useLinkProfile.js.map +1 -0
  27. package/dist/cjs/react/native/hooks/wallets/useProfiles.js +3 -4
  28. package/dist/cjs/react/native/hooks/wallets/useProfiles.js.map +1 -1
  29. package/dist/cjs/react/web/hooks/wallets/useLinkProfile.js +91 -0
  30. package/dist/cjs/react/web/hooks/wallets/useLinkProfile.js.map +1 -0
  31. package/dist/cjs/react/web/hooks/wallets/useProfiles.js +3 -4
  32. package/dist/cjs/react/web/hooks/wallets/useProfiles.js.map +1 -1
  33. package/dist/cjs/utils/any-evm/zksync/isZkSyncChain.js +2 -1
  34. package/dist/cjs/utils/any-evm/zksync/isZkSyncChain.js.map +1 -1
  35. package/dist/cjs/version.js +1 -1
  36. package/dist/cjs/wallets/in-app/core/users/getUser.js +11 -8
  37. package/dist/cjs/wallets/in-app/core/users/getUser.js.map +1 -1
  38. package/dist/cjs/wallets/in-app/native/native-connector.js +1 -0
  39. package/dist/cjs/wallets/in-app/native/native-connector.js.map +1 -1
  40. package/dist/cjs/wallets/in-app/web/lib/auth/index.js +23 -16
  41. package/dist/cjs/wallets/in-app/web/lib/auth/index.js.map +1 -1
  42. package/dist/cjs/wallets/in-app/web/lib/web-connector.js +1 -0
  43. package/dist/cjs/wallets/in-app/web/lib/web-connector.js.map +1 -1
  44. package/dist/esm/contract/deployment/utils/create-2-factory.js +53 -46
  45. package/dist/esm/contract/deployment/utils/create-2-factory.js.map +1 -1
  46. package/dist/esm/event/actions/get-events.js +4 -4
  47. package/dist/esm/event/actions/get-events.js.map +1 -1
  48. package/dist/esm/exports/extensions/unstoppable-domains.js +4 -0
  49. package/dist/esm/exports/extensions/unstoppable-domains.js.map +1 -0
  50. package/dist/esm/exports/react.js +1 -0
  51. package/dist/esm/exports/react.js.map +1 -1
  52. package/dist/esm/exports/react.native.js +1 -0
  53. package/dist/esm/exports/react.native.js.map +1 -1
  54. package/dist/esm/exports/wallets.js.map +1 -1
  55. package/dist/esm/exports/wallets.native.js.map +1 -1
  56. package/dist/esm/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/getMany.js +114 -0
  57. package/dist/esm/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/getMany.js.map +1 -0
  58. package/dist/esm/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/namehash.js +107 -0
  59. package/dist/esm/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/namehash.js.map +1 -0
  60. package/dist/esm/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/reverseNameOf.js +107 -0
  61. package/dist/esm/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/reverseNameOf.js.map +1 -0
  62. package/dist/esm/extensions/unstoppable-domains/consts.js +2 -0
  63. package/dist/esm/extensions/unstoppable-domains/consts.js.map +1 -0
  64. package/dist/esm/extensions/unstoppable-domains/read/resolveAddress.js +74 -0
  65. package/dist/esm/extensions/unstoppable-domains/read/resolveAddress.js.map +1 -0
  66. package/dist/esm/extensions/unstoppable-domains/read/resolveName.js +57 -0
  67. package/dist/esm/extensions/unstoppable-domains/read/resolveName.js.map +1 -0
  68. package/dist/esm/react/native/hooks/wallets/useLinkProfile.js +89 -0
  69. package/dist/esm/react/native/hooks/wallets/useLinkProfile.js.map +1 -0
  70. package/dist/esm/react/native/hooks/wallets/useProfiles.js +3 -4
  71. package/dist/esm/react/native/hooks/wallets/useProfiles.js.map +1 -1
  72. package/dist/esm/react/web/hooks/wallets/useLinkProfile.js +88 -0
  73. package/dist/esm/react/web/hooks/wallets/useLinkProfile.js.map +1 -0
  74. package/dist/esm/react/web/hooks/wallets/useProfiles.js +3 -4
  75. package/dist/esm/react/web/hooks/wallets/useProfiles.js.map +1 -1
  76. package/dist/esm/utils/any-evm/zksync/isZkSyncChain.js +2 -1
  77. package/dist/esm/utils/any-evm/zksync/isZkSyncChain.js.map +1 -1
  78. package/dist/esm/version.js +1 -1
  79. package/dist/esm/wallets/in-app/core/users/getUser.js +11 -8
  80. package/dist/esm/wallets/in-app/core/users/getUser.js.map +1 -1
  81. package/dist/esm/wallets/in-app/native/native-connector.js +1 -0
  82. package/dist/esm/wallets/in-app/native/native-connector.js.map +1 -1
  83. package/dist/esm/wallets/in-app/web/lib/auth/index.js +23 -16
  84. package/dist/esm/wallets/in-app/web/lib/auth/index.js.map +1 -1
  85. package/dist/esm/wallets/in-app/web/lib/web-connector.js +1 -0
  86. package/dist/esm/wallets/in-app/web/lib/web-connector.js.map +1 -1
  87. package/dist/types/contract/deployment/utils/create-2-factory.d.ts.map +1 -1
  88. package/dist/types/exports/extensions/unstoppable-domains.d.ts +4 -0
  89. package/dist/types/exports/extensions/unstoppable-domains.d.ts.map +1 -0
  90. package/dist/types/exports/react.d.ts +1 -0
  91. package/dist/types/exports/react.d.ts.map +1 -1
  92. package/dist/types/exports/react.native.d.ts +1 -0
  93. package/dist/types/exports/react.native.d.ts.map +1 -1
  94. package/dist/types/exports/wallets.d.ts +1 -0
  95. package/dist/types/exports/wallets.d.ts.map +1 -1
  96. package/dist/types/exports/wallets.native.d.ts +1 -0
  97. package/dist/types/exports/wallets.native.d.ts.map +1 -1
  98. package/dist/types/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/getMany.d.ts +90 -0
  99. package/dist/types/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/getMany.d.ts.map +1 -0
  100. package/dist/types/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/namehash.d.ts +83 -0
  101. package/dist/types/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/namehash.d.ts.map +1 -0
  102. package/dist/types/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/reverseNameOf.d.ts +83 -0
  103. package/dist/types/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/reverseNameOf.d.ts.map +1 -0
  104. package/dist/types/extensions/unstoppable-domains/consts.d.ts +2 -0
  105. package/dist/types/extensions/unstoppable-domains/consts.d.ts.map +1 -0
  106. package/dist/types/extensions/unstoppable-domains/read/resolveAddress.d.ts +45 -0
  107. package/dist/types/extensions/unstoppable-domains/read/resolveAddress.d.ts.map +1 -0
  108. package/dist/types/extensions/unstoppable-domains/read/resolveName.d.ts +43 -0
  109. package/dist/types/extensions/unstoppable-domains/read/resolveName.d.ts.map +1 -0
  110. package/dist/types/react/native/hooks/wallets/useLinkProfile.d.ts +74 -0
  111. package/dist/types/react/native/hooks/wallets/useLinkProfile.d.ts.map +1 -0
  112. package/dist/types/react/native/hooks/wallets/useProfiles.d.ts +3 -4
  113. package/dist/types/react/native/hooks/wallets/useProfiles.d.ts.map +1 -1
  114. package/dist/types/react/web/hooks/wallets/useLinkProfile.d.ts +73 -0
  115. package/dist/types/react/web/hooks/wallets/useLinkProfile.d.ts.map +1 -0
  116. package/dist/types/react/web/hooks/wallets/useProfiles.d.ts +3 -4
  117. package/dist/types/react/web/hooks/wallets/useProfiles.d.ts.map +1 -1
  118. package/dist/types/utils/any-evm/zksync/isZkSyncChain.d.ts.map +1 -1
  119. package/dist/types/version.d.ts +1 -1
  120. package/dist/types/wallets/in-app/core/authentication/types.d.ts.map +1 -1
  121. package/dist/types/wallets/in-app/core/users/getUser.d.ts +8 -6
  122. package/dist/types/wallets/in-app/core/users/getUser.d.ts.map +1 -1
  123. package/dist/types/wallets/in-app/native/native-connector.d.ts.map +1 -1
  124. package/dist/types/wallets/in-app/web/lib/auth/index.d.ts +23 -16
  125. package/dist/types/wallets/in-app/web/lib/auth/index.d.ts.map +1 -1
  126. package/dist/types/wallets/in-app/web/lib/web-connector.d.ts.map +1 -1
  127. package/package.json +1 -1
  128. package/src/contract/deployment/utils/create-2-factory.ts +70 -57
  129. package/src/event/actions/get-events.ts +4 -4
  130. package/src/exports/extensions/unstoppable-domains.ts +9 -0
  131. package/src/exports/react.native.ts +1 -0
  132. package/src/exports/react.ts +1 -0
  133. package/src/exports/wallets.native.ts +1 -0
  134. package/src/exports/wallets.ts +1 -0
  135. package/src/extensions/thirdweb/write/publish.test.ts +20 -12
  136. package/src/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/getMany.ts +130 -0
  137. package/src/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/namehash.ts +124 -0
  138. package/src/extensions/unstoppable-domains/__generated__/UnstoppableDomains/read/reverseNameOf.ts +126 -0
  139. package/src/extensions/unstoppable-domains/consts.ts +1 -0
  140. package/src/extensions/unstoppable-domains/read/resolveAddress.test.ts +18 -0
  141. package/src/extensions/unstoppable-domains/read/resolveAddress.ts +96 -0
  142. package/src/extensions/unstoppable-domains/read/resolveName.test.ts +16 -0
  143. package/src/extensions/unstoppable-domains/read/resolveName.ts +77 -0
  144. package/src/react/native/hooks/wallets/useLinkProfile.ts +92 -0
  145. package/src/react/native/hooks/wallets/useProfiles.ts +3 -4
  146. package/src/react/web/hooks/wallets/useLinkProfile.ts +91 -0
  147. package/src/react/web/hooks/wallets/useProfiles.ts +3 -4
  148. package/src/utils/any-evm/zksync/isZkSyncChain.ts +2 -1
  149. package/src/version.ts +1 -1
  150. package/src/wallets/in-app/core/authentication/types.ts +1 -0
  151. package/src/wallets/in-app/core/users/getUser.ts +14 -7
  152. package/src/wallets/in-app/native/native-connector.ts +1 -0
  153. package/src/wallets/in-app/web/lib/auth/index.ts +23 -16
  154. package/src/wallets/in-app/web/lib/web-connector.ts +1 -0
@@ -0,0 +1 @@
1
+ export const UD_POLYGON_MAINNET = "0xa9a6A3626993D487d2Dbda3173cf58cA1a9D9e9f";
@@ -0,0 +1,18 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { TEST_CLIENT } from "~test/test-clients.js";
3
+ import { resolveAddress } from "./resolveAddress.js";
4
+
5
+ // Double check: https://unstoppabledomains.com/d/thirdwebsdk.unstoppable
6
+
7
+ describe("Unstoppable Domain: resolve address", () => {
8
+ it("should resolve address", async () => {
9
+ expect(
10
+ (
11
+ await resolveAddress({
12
+ name: "thirdwebsdk.unstoppable",
13
+ client: TEST_CLIENT,
14
+ })
15
+ ).toLowerCase(),
16
+ ).toBe("0x12345674b599ce99958242b3D3741e7b01841DF3".toLowerCase());
17
+ });
18
+ });
@@ -0,0 +1,96 @@
1
+ import { polygon } from "../../../chains/chain-definitions/polygon.js";
2
+ import type { Chain } from "../../../chains/types.js";
3
+ import type { ThirdwebClient } from "../../../client/client.js";
4
+ import { getContract } from "../../../contract/contract.js";
5
+ import { getAddress, isAddress } from "../../../utils/address.js";
6
+ import { withCache } from "../../../utils/promise/withCache.js";
7
+ import { getMany } from "../__generated__/UnstoppableDomains/read/getMany.js";
8
+ import { namehash } from "../__generated__/UnstoppableDomains/read/namehash.js";
9
+ import { UD_POLYGON_MAINNET } from "../consts.js";
10
+
11
+ /**
12
+ * @extension UNSTOPPABLE-DOMAINS
13
+ */
14
+ export type ResolveAddressOptions = {
15
+ client: ThirdwebClient;
16
+ name: string;
17
+ resolverAddress?: string;
18
+ resolverChain?: Chain;
19
+ };
20
+
21
+ /**
22
+ * Resolve an Unstoppable-Domain domain to an Ethereum address
23
+ * @param options - The options for resolving an UD domain
24
+ * @returns The Ethereum address associated with the domain name. [Learn more](https://docs.unstoppabledomains.com/reverse-resolution/)
25
+ * @example
26
+ *
27
+ * ### Basic usage
28
+ * ```ts
29
+ * import { resolveAddress } from "thirdweb/extension/unstoppable-domains";
30
+ *
31
+ * const address = await resolveAddress({
32
+ * client,
33
+ * name: "thirdweb.crypto",
34
+ * });
35
+ * ```
36
+ *
37
+ * ### Custom resolver
38
+ * By default this extension will try to resolve the name on Polygon mainnet,
39
+ * you can decide to customize the resolver contract by specifying `resolverAddress` and `resolverChain`
40
+ * ```ts
41
+ * import { ethereum } from "thirdweb/chains";
42
+ *
43
+ * const address = await resolveAddress({
44
+ * client,
45
+ * name: "thirdweb.crypto",
46
+ * resolverAddress: "0x...",
47
+ * resolverChain: ethereum,
48
+ * });
49
+ * ```
50
+ *
51
+ * @extension UNSTOPPABLE-DOMAINS
52
+ */
53
+ export async function resolveAddress(
54
+ options: ResolveAddressOptions,
55
+ ): Promise<string> {
56
+ const { client, name, resolverAddress, resolverChain } = options;
57
+ if (isAddress(name)) {
58
+ return getAddress(name);
59
+ }
60
+ return withCache(
61
+ async () => {
62
+ const contract = getContract({
63
+ client,
64
+ chain: resolverChain || polygon,
65
+ address: resolverAddress || UD_POLYGON_MAINNET,
66
+ });
67
+
68
+ // Get namehash
69
+ const possibleTokenId = await namehash({
70
+ contract,
71
+ labels: name.split("."),
72
+ });
73
+
74
+ // Resolve ETH address from the tokenId
75
+ const resolved = await getMany({
76
+ contract,
77
+ tokenId: possibleTokenId,
78
+ // note that you can also retrieve the (BTC, SOL, etc.) address by using "crypto.<symbol>.address" (should that become useful one day)
79
+ keys: ["crypto.ETH.address"],
80
+ });
81
+
82
+ const possibleETHAddress = resolved[0];
83
+ if (!possibleETHAddress) {
84
+ throw new Error(
85
+ `Could not retrieve any ETH address associated with domain name: ${name}. Make sure you have set the base EVM address for your domain here: https://unstoppabledomains.com/manage?page=crypto&domain=<your-domain>`,
86
+ );
87
+ }
88
+ return possibleETHAddress;
89
+ },
90
+ {
91
+ cacheKey: `unstoppable-domain:addr:${resolverChain?.id || 1}:${name}`,
92
+ // 1min cache
93
+ cacheTime: 60 * 1000,
94
+ },
95
+ );
96
+ }
@@ -0,0 +1,16 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { TEST_CLIENT } from "~test/test-clients.js";
3
+ import { resolveName } from "./resolveName.js";
4
+
5
+ // Double check: https://unstoppabledomains.com/d/thirdwebsdk.unstoppable
6
+
7
+ describe("Unstoppable Domain: resolve name", () => {
8
+ it("should resolve name", async () => {
9
+ expect(
10
+ await resolveName({
11
+ address: "0x12345674b599ce99958242b3D3741e7b01841DF3",
12
+ client: TEST_CLIENT,
13
+ }),
14
+ ).toBe("thirdwebsdk.unstoppable");
15
+ });
16
+ });
@@ -0,0 +1,77 @@
1
+ import { polygon } from "../../../chains/chain-definitions/polygon.js";
2
+ import type { Chain } from "../../../chains/types.js";
3
+ import type { ThirdwebClient } from "../../../client/client.js";
4
+ import { getContract } from "../../../contract/contract.js";
5
+ import { withCache } from "../../../utils/promise/withCache.js";
6
+ import { reverseNameOf } from "../__generated__/UnstoppableDomains/read/reverseNameOf.js";
7
+ import { UD_POLYGON_MAINNET } from "../consts.js";
8
+
9
+ /**
10
+ * @extension UNSTOPPABLE-DOMAINS
11
+ */
12
+ export type ResolveUDNameOptions = {
13
+ client: ThirdwebClient;
14
+ address: string;
15
+ resolverAddress?: string;
16
+ resolverChain?: Chain;
17
+ };
18
+
19
+ /**
20
+ * Resolves the primary Untoppable-Domains name for a specified address.
21
+ * @param options - The options for resolving an UD domain
22
+ * @example
23
+ *
24
+ * ### Basic usage
25
+ * ```ts
26
+ * import { resolveName } from "thirdweb/extension/unstoppable-domains";
27
+ *
28
+ * const name = await resolveName({
29
+ * client,
30
+ * address: "0x...",
31
+ * });
32
+ * ```
33
+ *
34
+ * ### Custom resolver
35
+ * By default this extension will try to resolve the address on Polygon mainnet,
36
+ * you can decide to customize the resolver contract by specifying `resolverAddress` and `resolverChain`
37
+ * ```ts
38
+ * import { ethereum } from "thirdweb/chains";
39
+ *
40
+ * const address = await resolveName({
41
+ * client,
42
+ * address: "0x...",
43
+ * resolverAddress: "0x...",
44
+ * resolverChain: ethereum,
45
+ * });
46
+ * ```
47
+ * @extension UNSTOPPABLE-DOMAINS
48
+ */
49
+ export async function resolveName(
50
+ options: ResolveUDNameOptions,
51
+ ): Promise<string> {
52
+ const { client, address, resolverAddress, resolverChain } = options;
53
+ return withCache(
54
+ async () => {
55
+ const contract = getContract({
56
+ client,
57
+ chain: resolverChain || polygon,
58
+ address: resolverAddress || UD_POLYGON_MAINNET,
59
+ });
60
+
61
+ // Note: if the given wallet address does not have any UD name, `reverseNameOf` will return an empty string
62
+ // This can still happen if you have transfered a domain to a new address, and forgot to set up the Reverse Resolution on the new address
63
+ const domain = await reverseNameOf({ contract, addr: address });
64
+ if (!domain) {
65
+ throw new Error(
66
+ `Failed to retrieve domain for address: ${address}. Make sure you have set the Reverse Resolution address for your domain at https://unstoppabledomains.com/manage?page=reverseResolution&domain=your-domain`,
67
+ );
68
+ }
69
+ return domain;
70
+ },
71
+ {
72
+ cacheKey: `unstoppable-domain:name:${resolverChain?.id || 1}:${address}`,
73
+ // 1min cache
74
+ cacheTime: 60 * 1000,
75
+ },
76
+ );
77
+ }
@@ -0,0 +1,92 @@
1
+ import { useMutation } from "@tanstack/react-query";
2
+ import { isEcosystemWallet } from "../../../../wallets/ecosystem/is-ecosystem-wallet.js";
3
+ import type { AuthArgsType } from "../../../../wallets/in-app/core/authentication/types.js";
4
+ import type { Ecosystem } from "../../../../wallets/in-app/core/wallet/types.js";
5
+ import { linkProfile } from "../../../../wallets/in-app/web/lib/auth/index.js";
6
+ import { useAdminWallet } from "../../../core/hooks/wallets/useAdminWallet.js";
7
+
8
+ /**
9
+ * Links a web2 or web3 profile to the connected in-app or ecosystem account.
10
+ *
11
+ * **When a profile is linked to the account, that profile can then be used to sign into the same account.**
12
+ *
13
+ * @example
14
+ *
15
+ * ### Linking a social profile
16
+ *
17
+ * ```jsx
18
+ * import { useLinkProfile } from "thirdweb/react";
19
+ *
20
+ * const { mutate: linkProfile } = useLinkProfile();
21
+ *
22
+ * const onClick = () => {
23
+ * linkProfile({
24
+ * client,
25
+ * strategy: "discord", // or "google", "x", "telegram", etc
26
+ * });
27
+ * };
28
+ * ```
29
+ *
30
+ * ### Linking an email
31
+ *
32
+ * ```jsx
33
+ * import { useLinkProfile } from "thirdweb/react";
34
+ * import { preAuthenticate } from "thirdweb/wallets";
35
+ *
36
+ * const { mutate: linkProfile } = useLinkProfile();
37
+ *
38
+ * // send a verification email first
39
+ * const sendEmail = async () => {
40
+ * const email = await preAuthenticate({
41
+ * client,
42
+ * strategy: "email",
43
+ * email: "john.doe@example.com",
44
+ * });
45
+ * };
46
+ *
47
+ * // then link the profile with the verification code
48
+ * const onClick = (code: string) => {
49
+ * linkProfile({
50
+ * client,
51
+ * strategy: "email",
52
+ * email: "john.doe@example.com",
53
+ * verificationCode: code,
54
+ * });
55
+ * };
56
+ * ```
57
+ *
58
+ * The same process can be used for phone and email, simply swap out the `strategy` parameter.
59
+ *
60
+ * ### Linking a wallet
61
+ *
62
+ * ```jsx
63
+ * import { useLinkProfile } from "thirdweb/react";
64
+ *
65
+ * const { mutate: linkProfile } = useLinkProfile();
66
+ *
67
+ * const onClick = () => {
68
+ * linkProfile({
69
+ * client,
70
+ * strategy: "wallet",
71
+ * wallet: createWallet("io.metamask"), // autocompletion for 400+ wallet ids
72
+ * chain: sepolia, // any chain works, needed for SIWE signature
73
+ * });
74
+ * };
75
+ * ```
76
+ *
77
+ * @wallet
78
+ */
79
+ export function useLinkProfile() {
80
+ const wallet = useAdminWallet();
81
+ return useMutation({
82
+ mutationKey: ["profiles"],
83
+ mutationFn: async (options: Omit<AuthArgsType, "ecosystem">) => {
84
+ const ecosystem: Ecosystem | undefined =
85
+ wallet && isEcosystemWallet(wallet)
86
+ ? { id: wallet.id, partnerId: wallet.getConfig()?.partnerId }
87
+ : undefined;
88
+ const optionsWithEcosystem = { ...options, ecosystem } as AuthArgsType;
89
+ return linkProfile(optionsWithEcosystem);
90
+ },
91
+ });
92
+ }
@@ -7,11 +7,10 @@ import { getProfiles } from "../../../../wallets/in-app/web/lib/auth/index.js";
7
7
  import { useAdminWallet } from "../../../core/hooks/wallets/useAdminWallet.js";
8
8
 
9
9
  /**
10
- * Retrieves all linked profiles of the connected in-app or ecosystem wallet.
10
+ * Retrieves all linked profiles of the connected in-app or ecosystem account.
11
11
  *
12
- * @returns A React Query result containing the linked profiles for the connected in-app wallet.
13
- *
14
- * @note This hook will only run if the connected wallet supports multi-auth (in-app wallets).
12
+ * @returns A React Query result containing the linked profiles for the connected in-app account.
13
+ * @note This hook will only run if the connected wallet supports account linking.
15
14
  *
16
15
  * @example
17
16
  * ```jsx
@@ -0,0 +1,91 @@
1
+ import { useMutation } from "@tanstack/react-query";
2
+ import { isEcosystemWallet } from "../../../../wallets/ecosystem/is-ecosystem-wallet.js";
3
+ import type { AuthArgsType } from "../../../../wallets/in-app/core/authentication/types.js";
4
+ import type { Ecosystem } from "../../../../wallets/in-app/core/wallet/types.js";
5
+ import { linkProfile } from "../../../../wallets/in-app/web/lib/auth/index.js";
6
+ import { useAdminWallet } from "../../../core/hooks/wallets/useAdminWallet.js";
7
+
8
+ /**
9
+ * Links a web2 or web3 profile to the connected in-app or ecosystem account.
10
+ * **When a profile is linked to the account, that profile can then be used to sign into the same account.**
11
+ *
12
+ * @example
13
+ *
14
+ * ### Linking a social profile
15
+ *
16
+ * ```jsx
17
+ * import { useLinkProfile } from "thirdweb/react";
18
+ *
19
+ * const { mutate: linkProfile } = useLinkProfile();
20
+ *
21
+ * const onClick = () => {
22
+ * linkProfile({
23
+ * client,
24
+ * strategy: "discord", // or "google", "x", "telegram", etc
25
+ * });
26
+ * };
27
+ * ```
28
+ *
29
+ * ### Linking an email
30
+ *
31
+ * ```jsx
32
+ * import { useLinkProfile } from "thirdweb/react";
33
+ * import { preAuthenticate } from "thirdweb/wallets";
34
+ *
35
+ * const { mutate: linkProfile } = useLinkProfile();
36
+ *
37
+ * // send a verification email first
38
+ * const sendEmail = async () => {
39
+ * const email = await preAuthenticate({
40
+ * client,
41
+ * strategy: "email",
42
+ * email: "john.doe@example.com",
43
+ * });
44
+ * };
45
+ *
46
+ * // then link the profile with the verification code
47
+ * const onClick = (code: string) => {
48
+ * linkProfile({
49
+ * client,
50
+ * strategy: "email",
51
+ * email: "john.doe@example.com",
52
+ * verificationCode: code,
53
+ * });
54
+ * };
55
+ * ```
56
+ *
57
+ * The same process can be used for phone and email, simply swap out the `strategy` parameter.
58
+ *
59
+ * ### Linking a wallet
60
+ *
61
+ * ```jsx
62
+ * import { useLinkProfile } from "thirdweb/react";
63
+ *
64
+ * const { mutate: linkProfile } = useLinkProfile();
65
+ *
66
+ * const onClick = () => {
67
+ * linkProfile({
68
+ * client,
69
+ * strategy: "wallet",
70
+ * wallet: createWallet("io.metamask"), // autocompletion for 400+ wallet ids
71
+ * chain: sepolia, // any chain works, needed for SIWE signature
72
+ * });
73
+ * };
74
+ * ```
75
+ *
76
+ * @wallet
77
+ */
78
+ export function useLinkProfile() {
79
+ const wallet = useAdminWallet();
80
+ return useMutation({
81
+ mutationKey: ["profiles"],
82
+ mutationFn: async (options: AuthArgsType) => {
83
+ const ecosystem: Ecosystem | undefined =
84
+ wallet && isEcosystemWallet(wallet)
85
+ ? { id: wallet.id, partnerId: wallet.getConfig()?.partnerId }
86
+ : undefined;
87
+ const optionsWithEcosystem = { ...options, ecosystem } as AuthArgsType;
88
+ return linkProfile(optionsWithEcosystem);
89
+ },
90
+ });
91
+ }
@@ -7,11 +7,10 @@ import { getProfiles } from "../../../../wallets/in-app/web/lib/auth/index.js";
7
7
  import { useAdminWallet } from "../../../core/hooks/wallets/useAdminWallet.js";
8
8
 
9
9
  /**
10
- * Retrieves all linked profiles of the connected in-app or ecosystem wallet.
10
+ * Retrieves all linked profiles of the connected in-app or ecosystem account.
11
11
  *
12
- * @returns A React Query result containing the linked profiles for the connected in-app wallet.
13
- *
14
- * @note This hook will only run if the connected wallet supports multi-auth (in-app wallets).
12
+ * @returns A React Query result containing the linked profiles for the connected in-app account.
13
+ * @note This hook will only run if the connected wallet supports account linking.
15
14
  *
16
15
  * @example
17
16
  * ```jsx
@@ -15,7 +15,8 @@ export async function isZkSyncChain(chain: Chain) {
15
15
  chain.id === 282 ||
16
16
  chain.id === 388 ||
17
17
  chain.id === 4654 ||
18
- chain.id === 333271
18
+ chain.id === 333271 ||
19
+ chain.id === 37111
19
20
  ) {
20
21
  return true;
21
22
  }
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = "5.60.1";
1
+ export const version = "5.61.0";
@@ -91,6 +91,7 @@ export type OAuthRedirectObject = {
91
91
  redirectUrl: string;
92
92
  };
93
93
 
94
+ // TODO: type this better for each auth provider
94
95
  export type Profile = {
95
96
  type: AuthOption | "wallet";
96
97
  details: {
@@ -3,6 +3,7 @@ import { getThirdwebBaseUrl } from "../../../../utils/domains.js";
3
3
  import { getClientFetch } from "../../../../utils/fetch.js";
4
4
  import type { OneOf, Prettify } from "../../../../utils/type-utils.js";
5
5
  import type { Profile } from "../authentication/types.js";
6
+ import type { Ecosystem } from "../wallet/types.js";
6
7
 
7
8
  export type GetUserResult = {
8
9
  userId: string;
@@ -17,24 +18,23 @@ export type GetUserResult = {
17
18
  * Gets user based on the provided query parameters.
18
19
  * @note This function is only available on the server (a secret key is required in the client).
19
20
  *
20
- * @param options - The options for the find users function.
21
+ * @param options - The options for the get user function.
21
22
  * @param options.client - The Thirdweb client with a secret key included.
22
- * @param [options.walletAddress] - The wallet address to query by.
23
+ * @param [options.walletAddress] - The wallet address generated by thirdweb to query by.
23
24
  * @param [options.email] - The email to query by.
24
25
  * @param [options.phone] - The phone number to query by.
25
26
  * @param [options.id] - The user ID to query by.
27
+ * @param [options.externalWalletAddress] - The linked external wallet address to query by.
26
28
  *
27
- * @returns An array of user objects.
29
+ * @returns A user object or null if not found.
28
30
  *
29
31
  * @example
30
- * ```ts
31
32
  * import { getUser } from "thirdweb/wallets";
32
33
  *
33
34
  * const user = await getUser({
34
35
  * client,
35
36
  * walletAddress: "0x123...",
36
37
  * });
37
- * ```
38
38
  *
39
39
  * @wallet
40
40
  */
@@ -44,14 +44,18 @@ export async function getUser({
44
44
  email,
45
45
  phone,
46
46
  id,
47
+ externalWalletAddress,
48
+ ecosystem,
47
49
  }: Prettify<
48
50
  {
49
51
  client: ThirdwebClient;
52
+ ecosystem?: Ecosystem;
50
53
  } & OneOf<{
51
54
  walletAddress?: string;
52
55
  email?: string;
53
56
  phone?: string;
54
57
  id?: string;
58
+ externalWalletAddress?: string;
55
59
  }>
56
60
  >): Promise<GetUserResult | null> {
57
61
  if (!client.secretKey) {
@@ -76,13 +80,16 @@ export async function getUser({
76
80
  } else if (id) {
77
81
  url.searchParams.set("queryBy", "id");
78
82
  url.searchParams.set("id", id);
83
+ } else if (externalWalletAddress) {
84
+ url.searchParams.set("queryBy", "externalWalletAddress");
85
+ url.searchParams.set("externalWalletAddress", externalWalletAddress);
79
86
  } else {
80
87
  throw new Error(
81
- "Please provide a walletAddress, email, phone, or id to query for users.",
88
+ "Please provide a walletAddress, email, phone, id, or externalWalletAddress to query for users.",
82
89
  );
83
90
  }
84
91
 
85
- const clientFetch = getClientFetch(client);
92
+ const clientFetch = getClientFetch(client, ecosystem);
86
93
 
87
94
  const res = await clientFetch(url.toString());
88
95
 
@@ -288,6 +288,7 @@ export class InAppNativeConnector implements InAppConnector {
288
288
  client: args.client,
289
289
  tokenToLink: storedToken.cookieString,
290
290
  storage: this.localStorage,
291
+ ecosystem: args.ecosystem || this.ecosystem,
291
292
  });
292
293
  }
293
294
 
@@ -152,9 +152,9 @@ export async function authenticate(args: AuthArgsType) {
152
152
  * @returns A promise that resolves to the authentication result.
153
153
  * @example
154
154
  * ```ts
155
- * import { authenticate } from "thirdweb/wallets/in-app";
155
+ * import { authenticateWithRedirect } from "thirdweb/wallets/in-app";
156
156
  *
157
- * const result = await authenticate({
157
+ * const result = await authenticateWithRedirect({
158
158
  * client,
159
159
  * strategy: "google",
160
160
  * mode: "redirect",
@@ -180,25 +180,21 @@ export async function authenticateWithRedirect(
180
180
  }
181
181
 
182
182
  /**
183
- * Connects a new profile (authentication method) to the current user.
184
- * The connected profile can be any valid in-app wallet including email, phone, passkey, etc.
185
- * The inputs mirror those used when authenticating normally.
183
+ * Connects a new profile (and new authentication method) to the current user.
186
184
  *
187
- * **When a profile is linked to the account, that profile can then be used to sign into the account.**
185
+ * Requires a connected in-app or ecosystem account.
188
186
  *
189
- * This method is only available for in-app wallets.
187
+ * **When a profile is linked to the account, that profile can then be used to sign into the same account.**
190
188
  *
191
- * @param wallet - The wallet to link an additional profile to.
192
189
  * @param auth - The authentications options to add the new profile.
193
190
  * @returns A promise that resolves to the currently linked profiles when the connection is successful.
194
191
  * @throws If the connection fails, if the profile is already linked to the account, or if the profile is already associated with another account.
195
192
  *
196
193
  * @example
197
194
  * ```ts
198
- * const wallet = inAppWallet();
195
+ * import { linkProfile } from "thirdweb/wallets";
199
196
  *
200
- * await wallet.connect({ client, strategy: "google" });
201
- * const profiles = await linkProfile({ client, strategy: "discord" });
197
+ * await linkProfile({ client, strategy: "discord" });
202
198
  * ```
203
199
  * @wallet
204
200
  */
@@ -214,17 +210,28 @@ export async function linkProfile(args: AuthArgsType) {
214
210
  *
215
211
  * @example
216
212
  * ```ts
217
- * import { inAppWallet } from "thirdweb/wallets";
218
- *
219
- * const wallet = inAppWallet();
220
- * wallet.connect({ strategy: "google" });
213
+ * import { getProfiles } from "thirdweb/wallets";
221
214
  *
222
215
  * const profiles = await getProfiles({
223
216
  * client,
224
217
  * });
225
218
  *
226
- * console.log(profiles[0].type);
219
+ * console.log(profiles[0].type); // will be "email", "phone", "google", "discord", etc
227
220
  * console.log(profiles[0].details.email);
221
+ * console.log(profiles[0].details.phone);
222
+ * ```
223
+ *
224
+ * ### Getting profiles for a ecosystem user
225
+ *
226
+ * ```ts
227
+ * import { getProfiles } from "thirdweb/wallets/in-app";
228
+ *
229
+ * const profiles = await getProfiles({
230
+ * client,
231
+ * ecosystem: {
232
+ * id: "ecosystem.your-ecosystem-id",
233
+ * },
234
+ * });
228
235
  * ```
229
236
  * @wallet
230
237
  */
@@ -444,6 +444,7 @@ export class InAppWebConnector implements InAppConnector {
444
444
  client: args.client,
445
445
  tokenToLink: storedToken.cookieString,
446
446
  storage: this.localStorage,
447
+ ecosystem: args.ecosystem || this.ecosystem,
447
448
  });
448
449
  }
449
450