Compare commits
21
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
61760a180f | ||
|
|
a3f3e160e0 | ||
|
|
b1190914a9 | ||
|
|
e79a952061 | ||
|
|
480ed721d1 | ||
|
|
42c7436827 | ||
|
|
16e9e8b64d | ||
|
|
23ab897e32 | ||
|
|
6fcdec7c12 | ||
|
|
b734f05525 | ||
|
|
30ea9c6bf7 | ||
|
|
6de3a19b86 | ||
|
|
06e59cf916 | ||
|
|
3f3a484a3a | ||
|
|
05e52114bf | ||
|
|
1a421d3b5d | ||
|
|
97fdbc8f64 | ||
|
|
ebf4025718 | ||
|
|
a81a5285b7 | ||
|
|
95c9d56ea4 | ||
|
|
18552f3a22 |
@@ -1,5 +1,21 @@
|
||||
# @thirdweb-dev/auth
|
||||
|
||||
## 4.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`6fcdec7c`](https://github.com/thirdweb-dev/js/commit/6fcdec7c12e4a3c0d10f3a67771e19cfad5c8ab5), [`42c74368`](https://github.com/thirdweb-dev/js/commit/42c743682739de77c264c11cc1692ed752f929a6), [`480ed721`](https://github.com/thirdweb-dev/js/commit/480ed721d1c736049fa8b6ee4cbdbdf3cce18abd), [`16e9e8b6`](https://github.com/thirdweb-dev/js/commit/16e9e8b64d7d1a97a5b32fc855479e992b7ed3a8), [`b1190914`](https://github.com/thirdweb-dev/js/commit/b1190914a97a9c4d9019c4ce8ee49ad345aed18c)]:
|
||||
- @thirdweb-dev/wallets@2.1.3
|
||||
|
||||
## 4.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1927](https://github.com/thirdweb-dev/js/pull/1927) [`05e52114`](https://github.com/thirdweb-dev/js/commit/05e52114bf4f0ee352f393ed20115a904a18c310) Thanks [@alecananian](https://github.com/alecananian)! - Update Fastify login route response to match Express/Next
|
||||
|
||||
- Updated dependencies [[`3f3a484a`](https://github.com/thirdweb-dev/js/commit/3f3a484a3aa6e9f784e4d44458461bac0d3d4c6b), [`a81a5285`](https://github.com/thirdweb-dev/js/commit/a81a5285b7ef4ddf47fd2779ab80ebbef4bd9e0e), [`30ea9c6b`](https://github.com/thirdweb-dev/js/commit/30ea9c6bf74b483a98592a1d8d64589b7f1b22a3), [`97fdbc8f`](https://github.com/thirdweb-dev/js/commit/97fdbc8f6443dcd08a7610e4437bd4c9d6b0e8c8)]:
|
||||
- @thirdweb-dev/wallets@2.1.2
|
||||
|
||||
## 4.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/auth",
|
||||
"version": "4.1.4",
|
||||
"version": "4.1.6",
|
||||
"main": "dist/thirdweb-dev-auth.cjs.js",
|
||||
"module": "dist/thirdweb-dev-auth.esm.js",
|
||||
"browser": {
|
||||
|
||||
@@ -22,7 +22,9 @@ export const loginHandler = (
|
||||
schema: {
|
||||
body: LoginPayloadBodySchema,
|
||||
response: {
|
||||
200: z.any(),
|
||||
200: z.object({
|
||||
token: z.string(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
handler: async (req, res) => {
|
||||
@@ -104,7 +106,8 @@ export const loginHandler = (
|
||||
},
|
||||
);
|
||||
|
||||
return res.status(200).send({ success: true });
|
||||
// Send token in body and as cookie for frontend and backend use cases
|
||||
return res.status(200).send({ token });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
# thirdweb
|
||||
|
||||
## 0.13.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`23ab897e`](https://github.com/thirdweb-dev/js/commit/23ab897e329cdd5b316fbe554ea0f64add91f2b4), [`a3f3e160`](https://github.com/thirdweb-dev/js/commit/a3f3e160e07328655a4f0332f41f4edd210a1a8a), [`6fcdec7c`](https://github.com/thirdweb-dev/js/commit/6fcdec7c12e4a3c0d10f3a67771e19cfad5c8ab5), [`42c74368`](https://github.com/thirdweb-dev/js/commit/42c743682739de77c264c11cc1692ed752f929a6), [`6fcdec7c`](https://github.com/thirdweb-dev/js/commit/6fcdec7c12e4a3c0d10f3a67771e19cfad5c8ab5), [`480ed721`](https://github.com/thirdweb-dev/js/commit/480ed721d1c736049fa8b6ee4cbdbdf3cce18abd), [`16e9e8b6`](https://github.com/thirdweb-dev/js/commit/16e9e8b64d7d1a97a5b32fc855479e992b7ed3a8), [`b1190914`](https://github.com/thirdweb-dev/js/commit/b1190914a97a9c4d9019c4ce8ee49ad345aed18c)]:
|
||||
- @thirdweb-dev/sdk@4.0.13
|
||||
- @thirdweb-dev/storage@2.0.4
|
||||
- @thirdweb-dev/wallets@2.1.3
|
||||
- @thirdweb-dev/auth@4.1.6
|
||||
|
||||
## 0.13.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1918](https://github.com/thirdweb-dev/js/pull/1918) [`95c9d56e`](https://github.com/thirdweb-dev/js/commit/95c9d56ea47ef57113679196efe8f9114c6fbb21) Thanks [@saminacodes](https://github.com/saminacodes)! - Fix url redirect for pre-built deploy command
|
||||
|
||||
- Updated dependencies [[`3f3a484a`](https://github.com/thirdweb-dev/js/commit/3f3a484a3aa6e9f784e4d44458461bac0d3d4c6b), [`05e52114`](https://github.com/thirdweb-dev/js/commit/05e52114bf4f0ee352f393ed20115a904a18c310), [`a81a5285`](https://github.com/thirdweb-dev/js/commit/a81a5285b7ef4ddf47fd2779ab80ebbef4bd9e0e), [`30ea9c6b`](https://github.com/thirdweb-dev/js/commit/30ea9c6bf74b483a98592a1d8d64589b7f1b22a3), [`97fdbc8f`](https://github.com/thirdweb-dev/js/commit/97fdbc8f6443dcd08a7610e4437bd4c9d6b0e8c8), [`3f3a484a`](https://github.com/thirdweb-dev/js/commit/3f3a484a3aa6e9f784e4d44458461bac0d3d4c6b)]:
|
||||
- @thirdweb-dev/wallets@2.1.2
|
||||
- @thirdweb-dev/auth@4.1.5
|
||||
- @thirdweb-dev/storage@2.0.3
|
||||
- @thirdweb-dev/sdk@4.0.12
|
||||
|
||||
## 0.13.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "thirdweb",
|
||||
"main": "dist/cli/index.js",
|
||||
"version": "0.13.12",
|
||||
"version": "0.13.14",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -30,7 +30,7 @@ export default function generateDashboardUrl(
|
||||
const foundMapping = mapping[name as keyof typeof mapping];
|
||||
|
||||
return foundMapping
|
||||
? `https://thirdweb.com/dashboard/${foundMapping}`
|
||||
? `https://thirdweb.com/thirdweb.eth/${foundMapping}`
|
||||
: undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: ["thirdweb"],
|
||||
plugins: ["better-tree-shaking"],
|
||||
plugins: ["better-tree-shaking", "eslint-plugin-tsdoc"],
|
||||
rules: {
|
||||
"tsdoc/syntax": "error",
|
||||
"better-tree-shaking/no-top-level-side-effects": "error",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
# @thirdweb-dev/react-core
|
||||
|
||||
## 4.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1951](https://github.com/thirdweb-dev/js/pull/1951) [`e79a9520`](https://github.com/thirdweb-dev/js/commit/e79a95206116ea09de0126fdbe30fb4413fdff28) Thanks [@kien-ngo](https://github.com/kien-ngo)! - Fix caching issue with useTotalCirculatingSupply
|
||||
|
||||
- [#1944](https://github.com/thirdweb-dev/js/pull/1944) [`6fcdec7c`](https://github.com/thirdweb-dev/js/commit/6fcdec7c12e4a3c0d10f3a67771e19cfad5c8ab5) Thanks [@iketw](https://github.com/iketw)! - Adds tsdoc warnings to enforce a common comments format
|
||||
|
||||
- [#1950](https://github.com/thirdweb-dev/js/pull/1950) [`b1190914`](https://github.com/thirdweb-dev/js/commit/b1190914a97a9c4d9019c4ce8ee49ad345aed18c) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Smart Wallet autoconnect fixes and performance improvements
|
||||
|
||||
- Updated dependencies [[`23ab897e`](https://github.com/thirdweb-dev/js/commit/23ab897e329cdd5b316fbe554ea0f64add91f2b4), [`a3f3e160`](https://github.com/thirdweb-dev/js/commit/a3f3e160e07328655a4f0332f41f4edd210a1a8a), [`6fcdec7c`](https://github.com/thirdweb-dev/js/commit/6fcdec7c12e4a3c0d10f3a67771e19cfad5c8ab5), [`42c74368`](https://github.com/thirdweb-dev/js/commit/42c743682739de77c264c11cc1692ed752f929a6), [`6fcdec7c`](https://github.com/thirdweb-dev/js/commit/6fcdec7c12e4a3c0d10f3a67771e19cfad5c8ab5), [`480ed721`](https://github.com/thirdweb-dev/js/commit/480ed721d1c736049fa8b6ee4cbdbdf3cce18abd), [`16e9e8b6`](https://github.com/thirdweb-dev/js/commit/16e9e8b64d7d1a97a5b32fc855479e992b7ed3a8), [`b1190914`](https://github.com/thirdweb-dev/js/commit/b1190914a97a9c4d9019c4ce8ee49ad345aed18c)]:
|
||||
- @thirdweb-dev/sdk@4.0.13
|
||||
- @thirdweb-dev/storage@2.0.4
|
||||
- @thirdweb-dev/wallets@2.1.3
|
||||
- @thirdweb-dev/auth@4.1.6
|
||||
|
||||
## 4.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1943](https://github.com/thirdweb-dev/js/pull/1943) [`30ea9c6b`](https://github.com/thirdweb-dev/js/commit/30ea9c6bf74b483a98592a1d8d64589b7f1b22a3) Thanks [@iketw](https://github.com/iketw)! - Adds tsdoc warnings to enforce a common comments format
|
||||
|
||||
- [#1929](https://github.com/thirdweb-dev/js/pull/1929) [`06e59cf9`](https://github.com/thirdweb-dev/js/commit/06e59cf91647e4080829d49f8cb91a4d8fdc87f7) Thanks [@iketw](https://github.com/iketw)! - Move addresses' utils to the core package
|
||||
|
||||
- Updated dependencies [[`3f3a484a`](https://github.com/thirdweb-dev/js/commit/3f3a484a3aa6e9f784e4d44458461bac0d3d4c6b), [`05e52114`](https://github.com/thirdweb-dev/js/commit/05e52114bf4f0ee352f393ed20115a904a18c310), [`a81a5285`](https://github.com/thirdweb-dev/js/commit/a81a5285b7ef4ddf47fd2779ab80ebbef4bd9e0e), [`30ea9c6b`](https://github.com/thirdweb-dev/js/commit/30ea9c6bf74b483a98592a1d8d64589b7f1b22a3), [`97fdbc8f`](https://github.com/thirdweb-dev/js/commit/97fdbc8f6443dcd08a7610e4437bd4c9d6b0e8c8), [`3f3a484a`](https://github.com/thirdweb-dev/js/commit/3f3a484a3aa6e9f784e4d44458461bac0d3d4c6b)]:
|
||||
- @thirdweb-dev/wallets@2.1.2
|
||||
- @thirdweb-dev/auth@4.1.5
|
||||
- @thirdweb-dev/storage@2.0.3
|
||||
- @thirdweb-dev/sdk@4.0.12
|
||||
|
||||
## 4.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-core",
|
||||
"version": "4.1.2",
|
||||
"version": "4.1.4",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-core",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -335,7 +335,7 @@ export function ThirdwebWalletProvider(
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
console.error("Failed to auto connect wallet");
|
||||
console.error("Failed to auto connect personal wallet");
|
||||
console.error(e);
|
||||
setConnectionStatus("disconnected");
|
||||
return;
|
||||
@@ -366,9 +366,14 @@ export function ThirdwebWalletProvider(
|
||||
} catch (e) {
|
||||
console.error("Failed to auto connect wallet");
|
||||
console.error(e);
|
||||
lastConnectedWalletStorage.removeItem(
|
||||
LAST_CONNECTED_WALLET_STORAGE_KEY,
|
||||
);
|
||||
if (
|
||||
e instanceof Error &&
|
||||
e.message === autoConnectTimeoutErrorMessage
|
||||
) {
|
||||
lastConnectedWalletStorage.removeItem(
|
||||
LAST_CONNECTED_WALLET_STORAGE_KEY,
|
||||
);
|
||||
}
|
||||
setConnectionStatus("disconnected");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,13 +43,13 @@ export type WalletConfig<I extends WalletInstance = WalletInstance> = {
|
||||
|
||||
/**
|
||||
* If true, this wallet will be tagged as "recommended" in ConnectWallet Modal and will be shown at the top of the list
|
||||
* @default false
|
||||
* @defaultValue false
|
||||
*/
|
||||
recommended?: boolean;
|
||||
|
||||
/**
|
||||
* If the wallet can sign transactions without user interaction, set this to true.
|
||||
* @default false
|
||||
* @defaultValue false
|
||||
*/
|
||||
isHeadless?: boolean;
|
||||
};
|
||||
@@ -154,7 +154,7 @@ export type ConnectUIProps<I extends WalletInstance = WalletInstance> = {
|
||||
/**
|
||||
* Called when the wallet is connected but it's
|
||||
* part of another wallet's connection flow.
|
||||
* @param walleInstance the instance of the connected wallet
|
||||
* @param walleInstance - the instance of the connected wallet
|
||||
*/
|
||||
onLocallyConnected?: (walleInstance: WalletInstance) => void;
|
||||
};
|
||||
|
||||
@@ -28,7 +28,7 @@ import { constants, utils } from "ethers";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
/**
|
||||
* The options to be passed as the second parameter to the {@link useClaimIneligibilityReasons}` hook.
|
||||
* The options to be passed as the second parameter to the {@link useClaimIneligibilityReasons} hook.
|
||||
*
|
||||
* @beta
|
||||
*/
|
||||
|
||||
@@ -193,7 +193,10 @@ export function useTotalCirculatingSupply(
|
||||
const { erc721, erc1155 } = getErcs(contract);
|
||||
|
||||
return useQueryWithNetwork<BigNumber>(
|
||||
cacheKeys.contract.nft.query.totalCirculatingSupply(contractAddress),
|
||||
cacheKeys.contract.nft.query.totalCirculatingSupply(
|
||||
contractAddress,
|
||||
tokenId ?? undefined,
|
||||
),
|
||||
async () => {
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
|
||||
@@ -718,7 +721,7 @@ export function useBurnNFT<TContract extends NFTContract>(
|
||||
/**
|
||||
* Set shared metadata
|
||||
* TODO add docs
|
||||
* @private
|
||||
* @internal
|
||||
*/
|
||||
export function useSetSharedMetadata<TContract extends NFTContract>(
|
||||
contract: RequiredParam<TContract>,
|
||||
|
||||
@@ -257,6 +257,13 @@ export type { ThirdwebSDKProviderProps } from "./providers/types";
|
||||
|
||||
// utils
|
||||
export { invalidateContractAndBalances } from "./utils/cache-keys";
|
||||
export {
|
||||
isEnsName,
|
||||
isPossibleEVMAddress,
|
||||
shortenAddress,
|
||||
shortenIfAddress,
|
||||
shortenString,
|
||||
} from "./utils/addresses";
|
||||
|
||||
// types
|
||||
export type {
|
||||
|
||||
@@ -1,12 +1,33 @@
|
||||
import { utils } from "ethers";
|
||||
|
||||
export function shortenString(str: string, extraShort?: true) {
|
||||
export function shortenString(str: string, extraShort: boolean = true) {
|
||||
return `${str.substring(0, extraShort ? 4 : 6)}...${str.substring(
|
||||
str.length - (extraShort ? 3 : 4),
|
||||
)}`;
|
||||
}
|
||||
|
||||
export function shortenAddress(address: string, extraShort?: true): string {
|
||||
/**
|
||||
* This function shortens an address if it is a valid EVM address.
|
||||
*
|
||||
* @param address - The address to shorten
|
||||
* @param extraShort - If true, show the first 4 and last 3 characters
|
||||
* @returns The shortened address
|
||||
*
|
||||
* @remarks
|
||||
* Note that this function will not check if the address is an ENS.
|
||||
*
|
||||
* @example Calling shortenAddress with extraShort set to true
|
||||
* ```ts
|
||||
* const address = shortenIfAddress("0x1234567890123456789012345678901234567890", true); // result will be "0x1234...890"
|
||||
* ```
|
||||
*/
|
||||
export function shortenAddress(
|
||||
address?: string,
|
||||
extraShort: boolean = true,
|
||||
): string {
|
||||
if (!address) {
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
const formattedAddress = utils.getAddress(address);
|
||||
return shortenString(formattedAddress, extraShort);
|
||||
@@ -17,10 +38,24 @@ export function shortenAddress(address: string, extraShort?: true): string {
|
||||
|
||||
export function shortenIfAddress(
|
||||
address?: string | null | false,
|
||||
extraShort?: true,
|
||||
extraShort: boolean = true,
|
||||
): string {
|
||||
if (typeof address === "string" && address.length > 0) {
|
||||
if (address && utils.isAddress(address)) {
|
||||
return shortenAddress(address, extraShort);
|
||||
}
|
||||
return address || "";
|
||||
}
|
||||
|
||||
export function isEnsName(name: string): boolean {
|
||||
return name?.endsWith(".eth");
|
||||
}
|
||||
|
||||
export function isPossibleEVMAddress(address?: string, ignoreEns?: boolean) {
|
||||
if (!address) {
|
||||
return false;
|
||||
}
|
||||
if (isEnsName(address) && !ignoreEns) {
|
||||
return true;
|
||||
}
|
||||
return utils.isAddress(address);
|
||||
}
|
||||
|
||||
@@ -182,10 +182,12 @@ export const cacheKeys = {
|
||||
),
|
||||
totalCirculatingSupply: (
|
||||
contractAddress: RequiredParam<ContractAddress>,
|
||||
tokenId?: BigNumberish,
|
||||
) =>
|
||||
createContractCacheKey(contractAddress, [
|
||||
"query",
|
||||
"totalCirculatingSupply",
|
||||
tokenId ?? "0",
|
||||
]),
|
||||
totalCount: (contractAddress: RequiredParam<ContractAddress>) =>
|
||||
createContractCacheKey(contractAddress, ["query", "totalCount"]),
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# @thirdweb-dev/react-native-compat
|
||||
|
||||
## 0.4.4
|
||||
|
||||
## 0.4.3
|
||||
|
||||
## 0.4.2
|
||||
|
||||
## 0.4.1
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-native-compat",
|
||||
"description": "Shims for Thirdweb in React Native Projects",
|
||||
"version": "0.4.2",
|
||||
"version": "0.4.4",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native-compat",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: ["thirdweb"],
|
||||
plugins: ["i18next"],
|
||||
plugins: ["i18next", "eslint-plugin-tsdoc"],
|
||||
rules: {
|
||||
"tsdoc/syntax": "error",
|
||||
"i18next/no-literal-string": 2,
|
||||
},
|
||||
settings: {
|
||||
|
||||
@@ -1,5 +1,94 @@
|
||||
# @thirdweb-dev/react-native
|
||||
|
||||
## 0.4.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1944](https://github.com/thirdweb-dev/js/pull/1944) [`6fcdec7c`](https://github.com/thirdweb-dev/js/commit/6fcdec7c12e4a3c0d10f3a67771e19cfad5c8ab5) Thanks [@iketw](https://github.com/iketw)! - Adds tsdoc warnings to enforce a common comments format
|
||||
|
||||
- Updated dependencies [[`23ab897e`](https://github.com/thirdweb-dev/js/commit/23ab897e329cdd5b316fbe554ea0f64add91f2b4), [`a3f3e160`](https://github.com/thirdweb-dev/js/commit/a3f3e160e07328655a4f0332f41f4edd210a1a8a), [`e79a9520`](https://github.com/thirdweb-dev/js/commit/e79a95206116ea09de0126fdbe30fb4413fdff28), [`6fcdec7c`](https://github.com/thirdweb-dev/js/commit/6fcdec7c12e4a3c0d10f3a67771e19cfad5c8ab5), [`42c74368`](https://github.com/thirdweb-dev/js/commit/42c743682739de77c264c11cc1692ed752f929a6), [`6fcdec7c`](https://github.com/thirdweb-dev/js/commit/6fcdec7c12e4a3c0d10f3a67771e19cfad5c8ab5), [`480ed721`](https://github.com/thirdweb-dev/js/commit/480ed721d1c736049fa8b6ee4cbdbdf3cce18abd), [`16e9e8b6`](https://github.com/thirdweb-dev/js/commit/16e9e8b64d7d1a97a5b32fc855479e992b7ed3a8), [`b1190914`](https://github.com/thirdweb-dev/js/commit/b1190914a97a9c4d9019c4ce8ee49ad345aed18c)]:
|
||||
- @thirdweb-dev/sdk@4.0.13
|
||||
- @thirdweb-dev/react-core@4.1.4
|
||||
- @thirdweb-dev/storage@2.0.4
|
||||
- @thirdweb-dev/wallets@2.1.3
|
||||
|
||||
## 0.4.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1908](https://github.com/thirdweb-dev/js/pull/1908) [`18552f3a`](https://github.com/thirdweb-dev/js/commit/18552f3a225d1c46f0ff19c2b1c9cc44f84e33ac) Thanks [@kien-ngo](https://github.com/kien-ngo)! - Add `hideSwitchToPersonalWallet` prop on `ConnectWallet` component to hide the "Switch to Personal wallet" option in the ConnectWallet modal which is shown when wallet is connected as a Smart Wallet
|
||||
|
||||
- [#1912](https://github.com/thirdweb-dev/js/pull/1912) [`1a421d3b`](https://github.com/thirdweb-dev/js/commit/1a421d3b5d837eade5b7344118a7148ddea35517) Thanks [@iketw](https://github.com/iketw)! - Adds Apple as a social sign in option for EmbeddedWallet
|
||||
|
||||
You can now do:
|
||||
|
||||
```typescript
|
||||
embeddedWallet({
|
||||
auth: {
|
||||
options: ['apple'],
|
||||
redirectUrl: 'your-apps-redirect-url://',
|
||||
},
|
||||
}),
|
||||
```
|
||||
|
||||
- [#1943](https://github.com/thirdweb-dev/js/pull/1943) [`30ea9c6b`](https://github.com/thirdweb-dev/js/commit/30ea9c6bf74b483a98592a1d8d64589b7f1b22a3) Thanks [@iketw](https://github.com/iketw)! - Adds tsdoc warnings to enforce a common comments format
|
||||
|
||||
- [#1929](https://github.com/thirdweb-dev/js/pull/1929) [`06e59cf9`](https://github.com/thirdweb-dev/js/commit/06e59cf91647e4080829d49f8cb91a4d8fdc87f7) Thanks [@iketw](https://github.com/iketw)! - Move addresses' utils to the core package
|
||||
|
||||
- [#1925](https://github.com/thirdweb-dev/js/pull/1925) [`97fdbc8f`](https://github.com/thirdweb-dev/js/commit/97fdbc8f6443dcd08a7610e4437bd4c9d6b0e8c8) Thanks [@iketw](https://github.com/iketw)! - [RN] Adds walletConnectReceiver prop to EmbeddedWallet and SmartWallet
|
||||
|
||||
You can pass your own WalletConnect projectId and metadata (highly recommended):
|
||||
|
||||
```typescript
|
||||
embeddedWallet({
|
||||
auth: {
|
||||
options: ['email', 'google'],
|
||||
redirectUrl: 'redirect-url',
|
||||
},
|
||||
walletConnectReceiver: {
|
||||
walletConnectWalletMetadata?: WCMetadata;
|
||||
walletConnectV2ProjectId?: string;
|
||||
walletConnectV2RelayUrl?: string;
|
||||
},
|
||||
}),
|
||||
|
||||
smartWallet(localWallet(), {
|
||||
factoryAddress: 'factory-address',
|
||||
gasless: true,
|
||||
walletConnectReceiver: {
|
||||
walletConnectWalletMetadata?: WCMetadata;
|
||||
walletConnectV2ProjectId?: string;
|
||||
walletConnectV2RelayUrl?: string;
|
||||
},
|
||||
}),
|
||||
```
|
||||
|
||||
You can just pass `true` to the prop and these props will default to our internal WalletConnect projectId and metadata.
|
||||
|
||||
```typescript
|
||||
embeddedWallet({
|
||||
auth: {
|
||||
options: ['email', 'google'],
|
||||
redirectUrl: 'redirect-url',
|
||||
},
|
||||
walletConnectReceiver: true
|
||||
}),
|
||||
|
||||
smartWallet(localWallet(), {
|
||||
factoryAddress: 'factory-address',
|
||||
gasless: true,
|
||||
walletConnectReceiver: true
|
||||
}),
|
||||
```
|
||||
|
||||
- [#1942](https://github.com/thirdweb-dev/js/pull/1942) [`6de3a19b`](https://github.com/thirdweb-dev/js/commit/6de3a19b86476cf5f7d67223a366379c4fdb9b74) Thanks [@iketw](https://github.com/iketw)! - Updated react-native-safe-area-context to 4.74
|
||||
|
||||
- Updated dependencies [[`3f3a484a`](https://github.com/thirdweb-dev/js/commit/3f3a484a3aa6e9f784e4d44458461bac0d3d4c6b), [`a81a5285`](https://github.com/thirdweb-dev/js/commit/a81a5285b7ef4ddf47fd2779ab80ebbef4bd9e0e), [`30ea9c6b`](https://github.com/thirdweb-dev/js/commit/30ea9c6bf74b483a98592a1d8d64589b7f1b22a3), [`06e59cf9`](https://github.com/thirdweb-dev/js/commit/06e59cf91647e4080829d49f8cb91a4d8fdc87f7), [`97fdbc8f`](https://github.com/thirdweb-dev/js/commit/97fdbc8f6443dcd08a7610e4437bd4c9d6b0e8c8), [`3f3a484a`](https://github.com/thirdweb-dev/js/commit/3f3a484a3aa6e9f784e4d44458461bac0d3d4c6b)]:
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
|
||||
## 0.4.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-native",
|
||||
"version": "0.4.2",
|
||||
"version": "0.4.4",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
@@ -70,6 +70,7 @@
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-inclusive-language": "^2.2.0",
|
||||
"eslint-plugin-prettier": "^5.0.0",
|
||||
"eslint-plugin-tsdoc": "^0.2.16",
|
||||
"ethers": "^5.7.2",
|
||||
"expo": "^47.0.14",
|
||||
"jest": "^29.6.2",
|
||||
@@ -79,7 +80,7 @@
|
||||
"react-native-camera": "^4.2.1",
|
||||
"react-native-device-info": "10.6.0",
|
||||
"react-native-mmkv": "2.5.1",
|
||||
"react-native-safe-area-context": "4.5.3",
|
||||
"react-native-safe-area-context": "4.7.4",
|
||||
"react-native-webview": "12.1.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"typedoc": "^0.25.2",
|
||||
@@ -93,7 +94,7 @@
|
||||
"react-native-inappbrowser-reborn": "^3.7.0",
|
||||
"react-native-quick-base64": "^2.0.7",
|
||||
"react-native-quick-crypto": "^0.6.1",
|
||||
"react-native-safe-area-context": "4.5.3",
|
||||
"react-native-safe-area-context": "4.7.4",
|
||||
"react-native-webview": "12.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -73,7 +73,7 @@ export class noopStorage implements IAsyncStorage {
|
||||
/**
|
||||
* Returns a new instance of AsyncLocalStorage
|
||||
*
|
||||
* @param name Name to namespace the storage with
|
||||
* @param name - Name to namespace the storage with
|
||||
* @returns A new instance of AsyncLocalStorage
|
||||
*/
|
||||
export function createAsyncLocalStorage(name: string) {
|
||||
@@ -83,7 +83,7 @@ export function createAsyncLocalStorage(name: string) {
|
||||
/**
|
||||
* Returns a new instance of LocalStorage
|
||||
*
|
||||
* @param name Name to namespace the storage with
|
||||
* @param name - Name to namespace the storage with
|
||||
* @returns A new instance of LocalStorage
|
||||
*/
|
||||
export function createSyncStorage(name: string) {
|
||||
|
||||
@@ -31,7 +31,7 @@ export class SecureStorage implements ISecureStorage {
|
||||
/**
|
||||
* Returns a new instance of SecureStorage implemented by Expo SecureStore
|
||||
*
|
||||
* @param name Name to namespace the storage with
|
||||
* @param name - Name to namespace the storage with
|
||||
* @returns A new instance of SecureStorage
|
||||
*/
|
||||
export function createSecureStorage(name: string) {
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
export const APPLE_ICON = `<svg fill="#959CA0" height="40px" width="40px" version="1.1" id="Capa_1" viewBox="0 0 24 24" xml:space="preserve" stroke="#959CA0"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <g> <g> <path d="M15.769,0c0.053,0,0.106,0,0.162,0c0.13,1.606-0.483,2.806-1.228,3.675c-0.731,0.863-1.732,1.7-3.351,1.573 c-0.108-1.583,0.506-2.694,1.25-3.561C13.292,0.879,14.557,0.16,15.769,0z"></path> <path d="M20.67,16.716c0,0.016,0,0.03,0,0.045c-0.455,1.378-1.104,2.559-1.896,3.655c-0.723,0.995-1.609,2.334-3.191,2.334 c-1.367,0-2.275-0.879-3.676-0.903c-1.482-0.024-2.297,0.735-3.652,0.926c-0.155,0-0.31,0-0.462,0 c-0.995-0.144-1.798-0.932-2.383-1.642c-1.725-2.098-3.058-4.808-3.306-8.276c0-0.34,0-0.679,0-1.019 c0.105-2.482,1.311-4.5,2.914-5.478c0.846-0.52,2.009-0.963,3.304-0.765c0.555,0.086,1.122,0.276,1.619,0.464 c0.471,0.181,1.06,0.502,1.618,0.485c0.378-0.011,0.754-0.208,1.135-0.347c1.116-0.403,2.21-0.865,3.652-0.648 c1.733,0.262,2.963,1.032,3.723,2.22c-1.466,0.933-2.625,2.339-2.427,4.74C17.818,14.688,19.086,15.964,20.67,16.716z"></path> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> </g> </g></svg>`;
|
||||
|
||||
export const FACEBOOK_ICON = `<svg xml:space="preserve" viewBox="0 0 40 40">
|
||||
<linearGradient id="a" x1="-277.375" x2="-277.375" y1="406.6018" y2="407.5726" gradientTransform="matrix(40 0 0 -39.7778 11115.001 16212.334)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#0062e0"/>
|
||||
<stop offset="1" stop-color="#19afff"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#a)" d="M16.7 39.8C7.2 38.1 0 29.9 0 20 0 9 9 0 20 0s20 9 20 20c0 9.9-7.2 18.1-16.7 19.8l-1.1-.9h-4.4l-1.1.9z"/>
|
||||
<path fill="#fff" d="m27.8 25.6.9-5.6h-5.3v-3.9c0-1.6.6-2.8 3-2.8H29V8.2c-1.4-.2-3-.4-4.4-.4-4.6 0-7.8 2.8-7.8 7.8V20h-5v5.6h5v14.1c1.1.2 2.2.3 3.3.3 1.1 0 2.2-.1 3.3-.3V25.6h4.4z"/>
|
||||
</svg>`;
|
||||
|
||||
export const GOOGLE_ICON = `<svg height={height} viewBox="0 0 24 24" width={width}>
|
||||
<path
|
||||
d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
|
||||
|
||||
@@ -36,7 +36,7 @@ export type ConnectWalletProps = {
|
||||
/**
|
||||
* Hide option to request testnet funds for testnets in dropdown
|
||||
*
|
||||
* @default false
|
||||
* @defaultValue false
|
||||
*/
|
||||
hideTestnetFaucet?: boolean;
|
||||
|
||||
@@ -47,7 +47,7 @@ export type ConnectWalletProps = {
|
||||
* Please, note that if you support multiple networks in your app this prop should
|
||||
* be set to `false` to allow users to switch between networks.
|
||||
*
|
||||
* @default false
|
||||
* @defaultValue false
|
||||
*/
|
||||
switchToActiveChain?: boolean;
|
||||
|
||||
@@ -69,6 +69,13 @@ export type ConnectWalletProps = {
|
||||
* ```
|
||||
*/
|
||||
displayBalanceToken?: Record<number, string>;
|
||||
|
||||
/**
|
||||
* Hide the "switch to Personal wallet" option in the wallet modal which is shown when wallet is connected to a Smart Wallet
|
||||
*
|
||||
* @defaultValue false
|
||||
*/
|
||||
hideSwitchToPersonalWallet?: boolean;
|
||||
} & ConnectWalletButtonProps;
|
||||
|
||||
export const ConnectWallet = ({
|
||||
@@ -84,6 +91,7 @@ export const ConnectWallet = ({
|
||||
termsOfServiceUrl,
|
||||
privacyPolicyUrl,
|
||||
supportedTokens,
|
||||
hideSwitchToPersonalWallet,
|
||||
}: ConnectWalletProps) => {
|
||||
const globalTheme = useGlobalTheme();
|
||||
const l = useLocale();
|
||||
@@ -163,6 +171,7 @@ export const ConnectWallet = ({
|
||||
hideTestnetFaucet={hideTestnetFaucet}
|
||||
supportedTokens={supportedTokensMemo}
|
||||
displayBalanceToken={displayBalanceToken}
|
||||
hideSwitchToPersonalWallet={hideSwitchToPersonalWallet}
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useWallet } from "@thirdweb-dev/react-core";
|
||||
import { IWalletConnectReceiver } from "@thirdweb-dev/wallets";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import Box from "../base/Box";
|
||||
import BaseButton from "../base/BaseButton";
|
||||
@@ -14,8 +13,13 @@ import WalletConnectIcon from "../../assets/wallet-connect";
|
||||
import QrCodeIcon from "../../assets/qr-code";
|
||||
import { QRCodeScan } from "./QRCodeScan";
|
||||
import { useLocale } from "../../providers/ui-context-provider";
|
||||
import { useWalletConnectHandler } from "../../providers/context-provider";
|
||||
|
||||
const ConnectAppField = () => {
|
||||
const ConnectAppField = ({
|
||||
onConnectAppTriggered,
|
||||
}: {
|
||||
onConnectAppTriggered?: () => void;
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const l = useLocale();
|
||||
const [showWCInput, setShowWCInput] = useState(false);
|
||||
@@ -24,22 +28,19 @@ const ConnectAppField = () => {
|
||||
const wallet = useWallet();
|
||||
const [showQRCodeScan, setShowQRCodeScan] = useState(false);
|
||||
const wcUriRef = useRef<string | undefined>();
|
||||
const walletConnectHandler = useWalletConnectHandler();
|
||||
|
||||
const getAppMeta = useCallback(() => {
|
||||
if (wallet && "isWCReceiverEnabled" in wallet) {
|
||||
const sessions = (
|
||||
wallet as unknown as IWalletConnectReceiver
|
||||
).getActiveSessions();
|
||||
if (Object.keys(sessions).length > 0) {
|
||||
setAppMeta({
|
||||
name: sessions[0].peer.metadata.name,
|
||||
iconUrl: sessions[0].peer.metadata.icons[0],
|
||||
});
|
||||
}
|
||||
const sessions = walletConnectHandler?.getActiveSessions();
|
||||
if (sessions && Object.keys(sessions).length > 0) {
|
||||
setAppMeta({
|
||||
name: sessions[0].peer.metadata.name,
|
||||
iconUrl: sessions[0].peer.metadata.icons[0],
|
||||
});
|
||||
}
|
||||
}, [wallet]);
|
||||
}, [walletConnectHandler]);
|
||||
|
||||
const onSmartWalletWCMessage = useCallback(
|
||||
const onWalletConnectMessage = useCallback(
|
||||
({ type }: { type: string }) => {
|
||||
if (type === "session_approved") {
|
||||
getAppMeta();
|
||||
@@ -52,22 +53,22 @@ const ConnectAppField = () => {
|
||||
|
||||
useEffect(() => {
|
||||
if (wallet) {
|
||||
wallet.addListener("message", onSmartWalletWCMessage);
|
||||
wallet.addListener("message", onWalletConnectMessage);
|
||||
|
||||
getAppMeta();
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (wallet) {
|
||||
wallet.removeListener("message", onSmartWalletWCMessage);
|
||||
wallet.removeListener("message", onWalletConnectMessage);
|
||||
}
|
||||
};
|
||||
}, [getAppMeta, onSmartWalletWCMessage, wallet]);
|
||||
}, [getAppMeta, onWalletConnectMessage, wallet]);
|
||||
|
||||
const onConnectDappPress = () => {
|
||||
if (appMeta) {
|
||||
reset();
|
||||
(wallet as unknown as IWalletConnectReceiver).disconnectSession();
|
||||
walletConnectHandler?.disconnectSession();
|
||||
} else {
|
||||
setShowWCInput(true);
|
||||
}
|
||||
@@ -103,10 +104,14 @@ const ConnectAppField = () => {
|
||||
|
||||
const uriToUse = uri || wcUri;
|
||||
|
||||
if (uriToUse?.startsWith("wc:")) {
|
||||
(wallet as unknown as IWalletConnectReceiver).connectApp(uriToUse);
|
||||
if (!uriToUse?.startsWith("wc:")) {
|
||||
return;
|
||||
}
|
||||
|
||||
onConnectAppTriggered?.();
|
||||
|
||||
walletConnectHandler?.connectApp(uriToUse);
|
||||
|
||||
setWCUri(undefined);
|
||||
wcUriRef.current = undefined;
|
||||
};
|
||||
@@ -135,6 +140,7 @@ const ConnectAppField = () => {
|
||||
style: {
|
||||
color: theme.colors.textPrimary,
|
||||
fontFamily: theme.textVariants.defaults.fontFamily,
|
||||
flex: 1,
|
||||
},
|
||||
}}
|
||||
containerProps={{
|
||||
|
||||
+16
-4
@@ -30,6 +30,8 @@ import { SupportedTokens } from "../SendFunds/defaultTokens";
|
||||
import { ActiveDot } from "../base";
|
||||
import { EmbeddedWallet } from "../../wallets/wallets/embedded/EmbeddedWallet";
|
||||
import { useLocale } from "../../providers/ui-context-provider";
|
||||
import { isWalletConnectReceiverEnabled } from "../../wallets/utils";
|
||||
import ConnectAppField from "./ConnectAppField";
|
||||
|
||||
const MODAL_HEIGHT = Dimensions.get("window").height * 0.7;
|
||||
const DEVICE_WIDTH = Dimensions.get("window").width;
|
||||
@@ -42,6 +44,7 @@ export const ConnectWalletDetailsModal = ({
|
||||
hideTestnetFaucet,
|
||||
supportedTokens,
|
||||
displayBalanceToken,
|
||||
hideSwitchToPersonalWallet,
|
||||
}: {
|
||||
isVisible: boolean;
|
||||
onClosePress: () => void;
|
||||
@@ -50,6 +53,7 @@ export const ConnectWalletDetailsModal = ({
|
||||
hideTestnetFaucet?: boolean;
|
||||
supportedTokens: SupportedTokens;
|
||||
displayBalanceToken?: Record<number, string>;
|
||||
hideSwitchToPersonalWallet?: boolean;
|
||||
}) => {
|
||||
const l = useLocale();
|
||||
const [isExportModalVisible, setIsExportModalVisible] = useState(false);
|
||||
@@ -131,6 +135,7 @@ export const ConnectWalletDetailsModal = ({
|
||||
return (
|
||||
<SmartWalletAdditionalActions
|
||||
onExportPress={onExportLocalWalletPress}
|
||||
hideSwitchToPersonalWallet={hideSwitchToPersonalWallet}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -203,11 +208,15 @@ export const ConnectWalletDetailsModal = ({
|
||||
return null;
|
||||
}, [
|
||||
activeWallet?.walletId,
|
||||
isImportModalVisible,
|
||||
onExportLocalWalletPress,
|
||||
onWalletImported,
|
||||
smartWallet,
|
||||
l,
|
||||
onExportLocalWalletPress,
|
||||
l.connect_wallet_details.additional_actions,
|
||||
l.connect_wallet_details.backup_wallet,
|
||||
l.connect_wallet_details.import_wallet,
|
||||
l.local_wallet.this_is_a_temporary_wallet,
|
||||
isImportModalVisible,
|
||||
onWalletImported,
|
||||
hideSwitchToPersonalWallet,
|
||||
]);
|
||||
|
||||
return (
|
||||
@@ -296,6 +305,9 @@ export const ConnectWalletDetailsModal = ({
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{isWalletConnectReceiverEnabled(activeWallet) ? (
|
||||
<ConnectAppField onConnectAppTriggered={onClosePress} />
|
||||
) : null}
|
||||
{getAdditionalActions()}
|
||||
{extraRows ? extraRows({}) : null}
|
||||
{addressCopied === true ? (
|
||||
|
||||
+6
-3
@@ -10,12 +10,15 @@ import { useState } from "react";
|
||||
import BaseButton from "../base/BaseButton";
|
||||
import Box from "../base/Box";
|
||||
import { ModalHeaderTextClose } from "../base/modal/ModalHeaderTextClose";
|
||||
import { useAddress, useWallet } from "@thirdweb-dev/react-core";
|
||||
import {
|
||||
shortenAddress,
|
||||
useAddress,
|
||||
useWallet,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { PasswordInput } from "../PasswordInput";
|
||||
import * as FileSystem from "expo-file-system";
|
||||
import { SmartWallet } from "@thirdweb-dev/wallets";
|
||||
import { usePersonalWalletAddress } from "../../wallets/hooks/usePersonalWalletAddress";
|
||||
import { shortenWalletAddress } from "../../utils/addresses";
|
||||
import { LocalWallet } from "../../wallets/wallets/LocalWallet";
|
||||
import { TWModal } from "../base/modal/TWModal";
|
||||
import { useLocale } from "../../providers/ui-context-provider";
|
||||
@@ -162,7 +165,7 @@ export const ExportLocalWalletModal = ({
|
||||
{l.local_wallet.wallet_address}
|
||||
</Text>
|
||||
<Text variant="bodySmallSecondary">
|
||||
{shortenWalletAddress(
|
||||
{shortenAddress(
|
||||
personalWalletAddress ? personalWalletAddress : address,
|
||||
)}
|
||||
</Text>
|
||||
|
||||
+4
-5
@@ -2,18 +2,19 @@ import { useWallet } from "@thirdweb-dev/react-core";
|
||||
import Box from "../base/Box";
|
||||
import BaseButton from "../base/BaseButton";
|
||||
import Text from "../base/Text";
|
||||
import { IWalletConnectReceiver } from "@thirdweb-dev/wallets";
|
||||
import {
|
||||
CLOSE_MODAL_STATE,
|
||||
WalletConnectSessionProposalModal,
|
||||
} from "../../utils/modalTypes";
|
||||
import { useLocale, useModalState } from "../../providers/ui-context-provider";
|
||||
import { useWalletConnectHandler } from "../../providers/context-provider";
|
||||
|
||||
export const SessionProposalModal = () => {
|
||||
const l = useLocale();
|
||||
const { modalState, setModalState } = useModalState();
|
||||
const { data: proposalData } =
|
||||
modalState as WalletConnectSessionProposalModal;
|
||||
const walletConnectHandler = useWalletConnectHandler();
|
||||
|
||||
const wallet = useWallet();
|
||||
|
||||
@@ -41,7 +42,7 @@ export const SessionProposalModal = () => {
|
||||
minWidth={100}
|
||||
borderColor="border"
|
||||
onPress={async () => {
|
||||
(wallet as unknown as IWalletConnectReceiver).rejectSession();
|
||||
walletConnectHandler?.rejectSession();
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
@@ -61,9 +62,7 @@ export const SessionProposalModal = () => {
|
||||
if (!wallet) {
|
||||
throw new Error("Wallet not connected.");
|
||||
}
|
||||
await (
|
||||
wallet as unknown as IWalletConnectReceiver
|
||||
).approveSession();
|
||||
await walletConnectHandler?.approveSession();
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
|
||||
+11
-15
@@ -1,19 +1,16 @@
|
||||
import { useChain, useWallet } from "@thirdweb-dev/react-core";
|
||||
import { shortenAddress, useChain, useWallet } from "@thirdweb-dev/react-core";
|
||||
import Box from "../base/Box";
|
||||
import BaseButton from "../base/BaseButton";
|
||||
import Text from "../base/Text";
|
||||
import {
|
||||
EIP155_SIGNING_METHODS,
|
||||
IWalletConnectReceiver,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
import { EIP155_SIGNING_METHODS } from "@thirdweb-dev/wallets";
|
||||
import { useLocale, useModalState } from "../../providers/ui-context-provider";
|
||||
import {
|
||||
CLOSE_MODAL_STATE,
|
||||
WalletConnectSessionRequestModal,
|
||||
} from "../../utils/modalTypes";
|
||||
import { ActivityIndicator, Dimensions } from "react-native";
|
||||
import { shortenWalletAddress } from "../../utils/addresses";
|
||||
import { useCallback, useState } from "react";
|
||||
import { useWalletConnectHandler } from "../../providers/context-provider";
|
||||
|
||||
const getTitle = (method: string) => {
|
||||
switch (method) {
|
||||
@@ -34,6 +31,7 @@ export const SessionRequestModal = () => {
|
||||
const { modalState, setModalState } = useModalState();
|
||||
const { data: requestData } = modalState as WalletConnectSessionRequestModal;
|
||||
const [approvingRequest, setApprovingRequest] = useState(false);
|
||||
const walletConnectHandler = useWalletConnectHandler();
|
||||
|
||||
const wallet = useWallet();
|
||||
const chain = useChain();
|
||||
@@ -48,12 +46,10 @@ export const SessionRequestModal = () => {
|
||||
}
|
||||
|
||||
setApprovingRequest(true);
|
||||
(wallet as unknown as IWalletConnectReceiver)
|
||||
.approveRequest()
|
||||
.finally(() => {
|
||||
setApprovingRequest(false);
|
||||
onClose();
|
||||
});
|
||||
walletConnectHandler?.approveEIP155Request().finally(() => {
|
||||
setApprovingRequest(false);
|
||||
onClose();
|
||||
});
|
||||
};
|
||||
|
||||
const getContent = useCallback(() => {
|
||||
@@ -86,10 +82,10 @@ export const SessionRequestModal = () => {
|
||||
return (
|
||||
<Box>
|
||||
<Text variant="bodySmall" textAlign="left">
|
||||
{`${l.common.from}: ${shortenWalletAddress(from)}`}
|
||||
{`${l.common.from}: ${shortenAddress(from)}`}
|
||||
</Text>
|
||||
<Text variant="bodySmall" textAlign="left" mt="sm">
|
||||
{`${l.common.to}: ${shortenWalletAddress(to)}`}
|
||||
{`${l.common.to}: ${shortenAddress(to)}`}
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
@@ -126,7 +122,7 @@ export const SessionRequestModal = () => {
|
||||
minWidth={100}
|
||||
borderColor="border"
|
||||
onPress={async () => {
|
||||
(wallet as unknown as IWalletConnectReceiver).rejectRequest();
|
||||
walletConnectHandler?.rejectEIP155Request();
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
|
||||
+20
-20
@@ -11,15 +11,16 @@ import { useWalletContext, useWallet } from "@thirdweb-dev/react-core";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useSmartWallet } from "../../providers/context-provider";
|
||||
import RightArrowIcon from "../../assets/right-arrow";
|
||||
import ConnectAppField from "./ConnectAppField";
|
||||
import DisconnectIcon from "../../assets/disconnect";
|
||||
import { IconTextButton } from "../base/IconTextButton";
|
||||
import { useGlobalTheme, useLocale } from "../../providers/ui-context-provider";
|
||||
|
||||
export const SmartWalletAdditionalActions = ({
|
||||
onExportPress,
|
||||
hideSwitchToPersonalWallet,
|
||||
}: {
|
||||
onExportPress: () => void;
|
||||
hideSwitchToPersonalWallet?: boolean;
|
||||
}) => {
|
||||
const l = useLocale();
|
||||
const { setConnectedWallet } = useWalletContext();
|
||||
@@ -61,25 +62,24 @@ export const SmartWalletAdditionalActions = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<IconTextButton
|
||||
mt="xs"
|
||||
text={
|
||||
showSmartWallet
|
||||
? l.smart_wallet.switch_to_smart
|
||||
: l.smart_wallet.switch_to_personal
|
||||
}
|
||||
icon={
|
||||
<DisconnectIcon
|
||||
width={14}
|
||||
height={14}
|
||||
color={theme.colors.iconPrimary}
|
||||
/>
|
||||
}
|
||||
onPress={onWalletPress}
|
||||
/>
|
||||
{!showSmartWallet && smartWallet?.enableConnectApp ? (
|
||||
<ConnectAppField />
|
||||
) : null}
|
||||
{(showSmartWallet || !hideSwitchToPersonalWallet) && (
|
||||
<IconTextButton
|
||||
mt="xs"
|
||||
text={
|
||||
showSmartWallet
|
||||
? l.smart_wallet.switch_to_smart
|
||||
: l.smart_wallet.switch_to_personal
|
||||
}
|
||||
icon={
|
||||
<DisconnectIcon
|
||||
width={14}
|
||||
height={14}
|
||||
color={theme.colors.iconPrimary}
|
||||
/>
|
||||
}
|
||||
onPress={onWalletPress}
|
||||
/>
|
||||
)}
|
||||
{wallet?.walletId === walletIds.localWallet ||
|
||||
activeWallet?.walletId === walletIds.localWallet ? (
|
||||
<>
|
||||
|
||||
@@ -36,6 +36,12 @@ export type ConnectWalletDetailsProps = {
|
||||
* ```
|
||||
*/
|
||||
displayBalanceToken?: Record<number, string>;
|
||||
/**
|
||||
* Hide the "switch to Personal wallet" option in the dropdown which is shown when wallet is connected to a Smart Wallet
|
||||
*
|
||||
* @defaultValue false
|
||||
*/
|
||||
hideSwitchToPersonalWallet?: boolean;
|
||||
};
|
||||
|
||||
export const WalletDetailsButton = ({
|
||||
@@ -45,6 +51,7 @@ export const WalletDetailsButton = ({
|
||||
hideTestnetFaucet,
|
||||
supportedTokens,
|
||||
displayBalanceToken,
|
||||
hideSwitchToPersonalWallet,
|
||||
}: ConnectWalletDetailsProps) => {
|
||||
const l = useLocale();
|
||||
const activeWallet = useWallet();
|
||||
@@ -76,6 +83,7 @@ export const WalletDetailsButton = ({
|
||||
hideTestnetFaucet={hideTestnetFaucet}
|
||||
supportedTokens={supportedTokens}
|
||||
displayBalanceToken={displayBalanceToken}
|
||||
hideSwitchToPersonalWallet={hideSwitchToPersonalWallet}
|
||||
/>
|
||||
{detailsButton ? (
|
||||
detailsButton({ onPress })
|
||||
|
||||
@@ -13,12 +13,12 @@ export type ConnectWalletButtonProps = {
|
||||
theme?: ThemeProviderProps["theme"];
|
||||
/**
|
||||
* Set a custom title for the button
|
||||
* @default "Connect Wallet"
|
||||
* @defaultValue "Connect Wallet"
|
||||
*/
|
||||
buttonTitle?: string;
|
||||
/**
|
||||
* Set a custom title for the Connect Wallet modal
|
||||
* @default "Choose your wallet"
|
||||
* @defaultValue "Choose your wallet"
|
||||
*/
|
||||
modalTitle?: string;
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { shortenAddress } from "@thirdweb-dev/react-core";
|
||||
import { Theme } from "../../styles/theme";
|
||||
import { shortenWalletAddress } from "../../utils/addresses";
|
||||
import Text from "./Text";
|
||||
|
||||
type AddressProps = {
|
||||
@@ -16,7 +16,7 @@ export const AddressDisplay = ({
|
||||
}: AddressProps) => {
|
||||
return (
|
||||
<Text variant={variant} {...props}>
|
||||
{shortenWalletAddress(address, extraShort)}
|
||||
{shortenAddress(address, extraShort)}
|
||||
</Text>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import BaseButton from "./BaseButton";
|
||||
import Box from "./Box";
|
||||
import ImageSvgUri from "./ImageSvgUri";
|
||||
import Text from "./Text";
|
||||
|
||||
type SquareButtonProps = {
|
||||
onPress: () => void;
|
||||
iconUrl: string;
|
||||
size: number;
|
||||
name?: string;
|
||||
} & (typeof BaseButton)["arguments"];
|
||||
|
||||
export const SquareButton = ({
|
||||
onPress,
|
||||
iconUrl,
|
||||
name,
|
||||
size,
|
||||
...props
|
||||
}: SquareButtonProps) => {
|
||||
return (
|
||||
<BaseButton
|
||||
flexDirection="column"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
borderWidth={0}
|
||||
borderRadius="sm"
|
||||
width={size}
|
||||
height={size}
|
||||
onPress={onPress}
|
||||
{...props}
|
||||
>
|
||||
<Box borderWidth={0} borderRadius="lg">
|
||||
<ImageSvgUri imageUrl={iconUrl} width={size} height={size} />
|
||||
</Box>
|
||||
{name ? (
|
||||
<Text
|
||||
variant="bodySmallSecondary"
|
||||
numberOfLines={1}
|
||||
mt="xs"
|
||||
fontSize={14}
|
||||
lineHeight={16}
|
||||
>
|
||||
{name}
|
||||
</Text>
|
||||
) : null}
|
||||
</BaseButton>
|
||||
);
|
||||
};
|
||||
@@ -1,53 +0,0 @@
|
||||
import { useGlobalTheme } from "../../providers/ui-context-provider";
|
||||
import BaseButton from "./BaseButton";
|
||||
import Box from "./Box";
|
||||
import ImageSvgUri from "./ImageSvgUri";
|
||||
import Text from "./Text";
|
||||
|
||||
type WalletButtonSquareProps = {
|
||||
onPress: () => void;
|
||||
walletIconUrl: string;
|
||||
size: number;
|
||||
name: string;
|
||||
} & (typeof BaseButton)["arguments"];
|
||||
|
||||
export const WalletButtonSquare = ({
|
||||
onPress,
|
||||
walletIconUrl,
|
||||
name,
|
||||
size,
|
||||
}: WalletButtonSquareProps) => {
|
||||
const theme = useGlobalTheme();
|
||||
|
||||
const marginVertical = theme.spacing.xs;
|
||||
return (
|
||||
<BaseButton
|
||||
flexDirection="column"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
marginVertical="xxs"
|
||||
borderWidth={0}
|
||||
borderRadius="sm"
|
||||
width={size - marginVertical * 2}
|
||||
height={size - marginVertical * 2}
|
||||
onPress={onPress}
|
||||
>
|
||||
<Box borderWidth={0} borderRadius="lg">
|
||||
<ImageSvgUri
|
||||
imageUrl={walletIconUrl}
|
||||
width={size * 0.6}
|
||||
height={size * 0.6}
|
||||
/>
|
||||
</Box>
|
||||
<Text
|
||||
variant="bodySmallSecondary"
|
||||
numberOfLines={1}
|
||||
mt="xs"
|
||||
fontSize={14}
|
||||
lineHeight={16}
|
||||
>
|
||||
{name}
|
||||
</Text>
|
||||
</BaseButton>
|
||||
);
|
||||
};
|
||||
@@ -74,6 +74,9 @@ export const _en = {
|
||||
request_new_code: "Request new code",
|
||||
sign_in: "Sign In",
|
||||
sign_in_google: "Sign in with Google",
|
||||
sign_in_facebook: "Sign in with Facebook",
|
||||
sign_in_apple: "Sign in with Apple",
|
||||
sign_in_email: "Sign in with Email",
|
||||
enter_your_email: "Enter your email address",
|
||||
forgot_password: "Forgot password",
|
||||
enter_account_recovery_code: "Enter account recovery code",
|
||||
|
||||
@@ -74,6 +74,9 @@ export const _es = {
|
||||
request_new_code: "Solicitar nuevo código",
|
||||
sign_in: "Iniciar Sesión",
|
||||
sign_in_google: "Iniciar sesión con Google",
|
||||
sign_in_facebook: "Iniciar sesión con Facebook",
|
||||
sign_in_apple: "Iniciar sesión con Apple",
|
||||
sign_in_email: "Iniciar sesión con Email",
|
||||
enter_your_email: "Ingresa tu dirección de correo electrónico",
|
||||
forgot_password: "Olvidé mi contraseña",
|
||||
enter_account_recovery_code: "Ingresa el código de recuperación de cuenta",
|
||||
|
||||
@@ -75,6 +75,9 @@ export const _ja = {
|
||||
request_new_code: "新しいコードをリクエスト",
|
||||
sign_in: "サインイン",
|
||||
sign_in_google: "Googleでサインイン",
|
||||
sign_in_facebook: "Facebookでサインイン",
|
||||
sign_in_apple: "Appleでサインイン",
|
||||
sign_in_email: "メールアドレスでサインイン",
|
||||
enter_your_email: "メールアドレスを入力",
|
||||
forgot_password: "パスワードを忘れた場合",
|
||||
enter_account_recovery_code: "アカウント回復コードを入力",
|
||||
|
||||
@@ -42,7 +42,6 @@ export { Web3Button } from "./components/Web3Button";
|
||||
|
||||
// utilities
|
||||
export * from "./utils/uri";
|
||||
export * from "./utils/addresses";
|
||||
export { createSyncStorage as createLocalStorage } from "../core/AsyncStorage";
|
||||
export { createAsyncLocalStorage } from "../core/AsyncStorage";
|
||||
export { createSecureStorage } from "../core/SecureStorage";
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import { SmartWallet, walletIds } from "@thirdweb-dev/wallets";
|
||||
import {
|
||||
SmartWallet,
|
||||
WalletConnectHandler,
|
||||
WalletConnectReceiverConfig,
|
||||
WalletConnectV2Handler,
|
||||
walletIds,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
import {
|
||||
createContext,
|
||||
useCallback,
|
||||
@@ -8,13 +14,15 @@ import {
|
||||
} from "react";
|
||||
import { useWalletConnectListener } from "../wallets/hooks/useWalletConnectListener";
|
||||
import { MagicLink } from "../wallets/wallets/MagicLink";
|
||||
import { useWalletContext } from "@thirdweb-dev/react-core";
|
||||
import { useWallet, useWalletContext } from "@thirdweb-dev/react-core";
|
||||
import { isWalletConnectReceiverEnabled } from "../wallets/utils";
|
||||
|
||||
type DappContextType = {
|
||||
smartWallet?: SmartWallet;
|
||||
setSmartWallet?: (value?: SmartWallet) => void;
|
||||
magicLink?: MagicLink;
|
||||
setMagicLink?: (value?: MagicLink) => void;
|
||||
walletConnectHandler?: WalletConnectHandler;
|
||||
};
|
||||
|
||||
const DappContext = createContext<DappContextType>({});
|
||||
@@ -22,15 +30,50 @@ const DappContext = createContext<DappContextType>({});
|
||||
export const DappContextProvider = (props: React.PropsWithChildren) => {
|
||||
const [smartWallet, setSmartWallet] = useState<SmartWallet | undefined>();
|
||||
const [magicLink, setMagicLink] = useState<MagicLink | undefined>();
|
||||
const [walletConnectHandler, setWalletConnectHandler] =
|
||||
useState<WalletConnectHandler>();
|
||||
const createdWalletInstance = useWalletContext().createdWalletInstance;
|
||||
const activeWallet = useWallet();
|
||||
|
||||
useEffect(() => {
|
||||
if (createdWalletInstance?.walletId === walletIds.magicLink) {
|
||||
if (!createdWalletInstance) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (createdWalletInstance.walletId === walletIds.magicLink) {
|
||||
setMagicLink(createdWalletInstance as MagicLink);
|
||||
}
|
||||
}, [createdWalletInstance, setMagicLink]);
|
||||
|
||||
useWalletConnectListener();
|
||||
useEffect(() => {
|
||||
if (!activeWallet) {
|
||||
return;
|
||||
}
|
||||
|
||||
const initWCHandler = async () => {
|
||||
const wcReceiverOptions =
|
||||
activeWallet?.getOptions() as WalletConnectReceiverConfig;
|
||||
|
||||
const handler = new WalletConnectV2Handler(
|
||||
{
|
||||
walletConnectReceiver: {
|
||||
...(wcReceiverOptions?.walletConnectReceiver === true
|
||||
? {}
|
||||
: wcReceiverOptions?.walletConnectReceiver),
|
||||
},
|
||||
},
|
||||
activeWallet,
|
||||
);
|
||||
await handler.init();
|
||||
setWalletConnectHandler(handler);
|
||||
};
|
||||
|
||||
if (isWalletConnectReceiverEnabled(activeWallet)) {
|
||||
initWCHandler();
|
||||
}
|
||||
}, [activeWallet]);
|
||||
|
||||
useWalletConnectListener(walletConnectHandler);
|
||||
|
||||
const magicSDK = useCallback(() => {
|
||||
if (magicLink) {
|
||||
@@ -48,6 +91,7 @@ export const DappContextProvider = (props: React.PropsWithChildren) => {
|
||||
setSmartWallet,
|
||||
magicLink: magicLink,
|
||||
setMagicLink: setMagicLink,
|
||||
walletConnectHandler: walletConnectHandler,
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
@@ -74,3 +118,9 @@ export const useMagicLink = () => {
|
||||
setMagicLink: context.setMagicLink,
|
||||
} as const;
|
||||
};
|
||||
|
||||
export const useWalletConnectHandler = () => {
|
||||
const context = useContext(DappContext);
|
||||
|
||||
return context.walletConnectHandler;
|
||||
};
|
||||
|
||||
@@ -52,7 +52,7 @@ interface ThirdwebProviderProps<TChains extends Chain[]>
|
||||
* />
|
||||
* ```
|
||||
*
|
||||
* * ```jsx
|
||||
* ```jsx
|
||||
* import { en } from "@thirdweb-dev/react-native";
|
||||
*
|
||||
* <ThirdwebProvider
|
||||
@@ -86,6 +86,7 @@ interface ThirdwebProviderProps<TChains extends Chain[]>
|
||||
* @example
|
||||
* You can wrap your application with the provider as follows:
|
||||
*
|
||||
* ```jsx
|
||||
* import { ThirdwebProvider } from "@thirdweb-dev/react-native";
|
||||
*
|
||||
* const App = () => {
|
||||
@@ -95,7 +96,7 @@ interface ThirdwebProviderProps<TChains extends Chain[]>
|
||||
* </ThirdwebProvider>
|
||||
* );
|
||||
* };
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
export const ThirdwebProvider = <
|
||||
TChains extends Chain[] = typeof defaultChains,
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
import { utils } from "ethers";
|
||||
|
||||
/**
|
||||
* Shortens an EVM compatible address to show the first 6 and last 4 characters
|
||||
*
|
||||
* @param str The address to shorten
|
||||
* @param extraShort If true, show the first 4 and last 3 characters
|
||||
* @returns The shortened address
|
||||
*/
|
||||
export function shortenWalletAddress(str?: string, extraShort = true) {
|
||||
if (!str) {
|
||||
return str;
|
||||
}
|
||||
|
||||
return `${str.substring(0, extraShort ? 4 : 6)}...${str.substring(
|
||||
str.length - (extraShort ? 3 : 4),
|
||||
)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function shortens an address if it is a valid EVM address.
|
||||
*
|
||||
* @param address The address to shorten
|
||||
* @param extraShort If true, show the first 4 and last 3 characters
|
||||
* @returns The shortened address
|
||||
* @example
|
||||
* ```ts
|
||||
* const address = shortenIfAddress("0x1234567890123456789012345678901234567890", true); // result will be "0x1234...890"
|
||||
* ```
|
||||
*/
|
||||
export function shortenIfAddress(address?: string, extraShort?: true): string {
|
||||
if (!address) {
|
||||
return "";
|
||||
}
|
||||
if (isPossibleEVMAddress(address, true)) {
|
||||
return shortenWalletAddress(address, extraShort) || "";
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
export function isEnsName(name: string): boolean {
|
||||
return name?.endsWith(".eth");
|
||||
}
|
||||
|
||||
// if a string is a valid address or ens name
|
||||
export function isPossibleEVMAddress(address?: string, ignoreEns?: boolean) {
|
||||
if (!address) {
|
||||
return false;
|
||||
}
|
||||
if (isEnsName(address) && !ignoreEns) {
|
||||
return true;
|
||||
}
|
||||
return utils.isAddress(address);
|
||||
}
|
||||
@@ -4,8 +4,8 @@ import { WCMeta } from "../wallets/types/wc";
|
||||
/**
|
||||
* Build a WalletConnect display URI from a wc:// uri + a wallet specific link
|
||||
*
|
||||
* @param uri The wc:// uri
|
||||
* @param links The wallet specific links
|
||||
* @param uri - The wc:// uri
|
||||
* @param links - The wallet specific links
|
||||
* @returns The WalletConnect display URI
|
||||
*/
|
||||
export function formatWalletConnectDisplayUri(
|
||||
|
||||
@@ -23,12 +23,12 @@ export type CoinbaseWalletConnectorOptions = WalletMobileSDKProviderOptions &
|
||||
ConfigurationParams & {
|
||||
/**
|
||||
* Fallback Ethereum JSON RPC URL
|
||||
* @default ""
|
||||
* @defaultValue ""
|
||||
*/
|
||||
jsonRpcUrl?: string;
|
||||
/**
|
||||
* Fallback Ethereum Chain ID
|
||||
* @default 1
|
||||
* @defaultValue 1
|
||||
*/
|
||||
chainId?: number;
|
||||
};
|
||||
|
||||
+14
-2
@@ -81,6 +81,18 @@ export class EmbeddedWalletConnector extends Connector<EmbeddedWalletConnectionA
|
||||
redirectUrl: params.redirectUrl,
|
||||
});
|
||||
}
|
||||
case "facebook": {
|
||||
return this.socialLogin({
|
||||
provider: AuthProvider.FACEBOOK,
|
||||
redirectUrl: params.redirectUrl,
|
||||
});
|
||||
}
|
||||
case "apple": {
|
||||
return this.socialLogin({
|
||||
provider: AuthProvider.APPLE,
|
||||
redirectUrl: params.redirectUrl,
|
||||
});
|
||||
}
|
||||
case "jwt": {
|
||||
return this.customJwt({
|
||||
jwt: params.jwt,
|
||||
@@ -179,11 +191,11 @@ export class EmbeddedWalletConnector extends Connector<EmbeddedWalletConnectionA
|
||||
);
|
||||
if (error instanceof Error) {
|
||||
throw new Error(
|
||||
`Error logging in with ${oauthOption.provider}: ${error.message}`,
|
||||
`Error signing in with ${oauthOption.provider}: ${error.message}`,
|
||||
);
|
||||
} else {
|
||||
throw new Error(
|
||||
`An unknown error occurred logging in with ${oauthOption.provider}`,
|
||||
`An unknown error occurred signing in with ${oauthOption.provider}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import { isDeviceSharePresentForUser } from "./helpers/storage/local";
|
||||
import { Auth } from "aws-amplify";
|
||||
import {
|
||||
ROUTE_AUTH_JWT_CALLBACK,
|
||||
ROUTE_HEADLESS_GOOGLE_LOGIN,
|
||||
ROUTE_HEADLESS_OAUTH_LOGIN,
|
||||
} from "./helpers/constants";
|
||||
import { AuthOptions, OauthOption, VerifiedTokenResponse } from "../types";
|
||||
import { InAppBrowser } from "react-native-inappbrowser-reborn";
|
||||
@@ -171,17 +171,16 @@ export async function validateEmailOTP(options: {
|
||||
}
|
||||
|
||||
export async function socialLogin(oauthOptions: OauthOption, clientId: string) {
|
||||
const headlessLoginLinkWithParams = `${ROUTE_HEADLESS_GOOGLE_LOGIN}?authProvider=${encodeURIComponent(
|
||||
oauthOptions.provider,
|
||||
)}&baseUrl=${encodeURIComponent(
|
||||
"https://embedded-wallet.thirdweb.com",
|
||||
const encodedProvider = encodeURIComponent(oauthOptions.provider);
|
||||
const headlessLoginLinkWithParams = `${ROUTE_HEADLESS_OAUTH_LOGIN}?authProvider=${encodedProvider}&baseUrl=${encodeURIComponent(
|
||||
`https://embedded-wallet.thirdweb.com`,
|
||||
)}&platform=${encodeURIComponent("mobile")}`;
|
||||
|
||||
const resp = await fetch(headlessLoginLinkWithParams);
|
||||
|
||||
if (!resp.ok) {
|
||||
const error = await resp.json();
|
||||
throw new Error(`Error getting headless login link: ${error.message}`);
|
||||
throw new Error(`Error getting headless sign in link: ${error.message}`);
|
||||
}
|
||||
|
||||
const json = await resp.json();
|
||||
@@ -192,7 +191,7 @@ export async function socialLogin(oauthOptions: OauthOption, clientId: string) {
|
||||
clientId || "",
|
||||
)}&platform=${encodeURIComponent("mobile")}&redirectUrl=${encodeURIComponent(
|
||||
oauthOptions.redirectUrl,
|
||||
)}`;
|
||||
)}&authOption=${encodedProvider}`;
|
||||
|
||||
const result = await InAppBrowser.openAuth(
|
||||
completeLoginUrl,
|
||||
@@ -207,16 +206,23 @@ export async function socialLogin(oauthOptions: OauthOption, clientId: string) {
|
||||
},
|
||||
);
|
||||
|
||||
if (result.type === "cancel") {
|
||||
throw new Error(`Sign in cancelled`);
|
||||
}
|
||||
|
||||
if (result.type !== "success") {
|
||||
throw new Error("Error signing in. Please try again later.");
|
||||
throw new Error(`Can't sign in with ${oauthOptions.provider}: ${result}`);
|
||||
}
|
||||
|
||||
const decodedUrl = decodeURIComponent(result.url);
|
||||
|
||||
const parts = decodedUrl.split("?authResult=");
|
||||
if (parts.length < 2) {
|
||||
throw new Error("Malformed response from the login redirect");
|
||||
// assume error
|
||||
const error = decodedUrl.split("?error=")?.[1];
|
||||
throw new Error(`Something went wrong. Please, try again later: ${error}`);
|
||||
}
|
||||
|
||||
const authResult = parts[1];
|
||||
const { storedToken } = JSON.parse(authResult);
|
||||
|
||||
|
||||
+1
-1
@@ -35,6 +35,6 @@ export const ROUTE_USER_MANAGED_OTP = `${ROUTE_2023_10_20_API_BASE_PATH}/embedde
|
||||
export const ROUTE_VALIDATE_USER_MANAGED_OTP = `${ROUTE_2023_10_20_API_BASE_PATH}/embedded-wallet/validate-thirdweb-email-otp`;
|
||||
export const ROUTE_IS_VALID_USER_MANAGED_OTP = `${ROUTE_2023_10_20_API_BASE_PATH}/embedded-wallet/is-thirdweb-email-otp-valid`;
|
||||
|
||||
export const ROUTE_HEADLESS_GOOGLE_LOGIN = `${ROUTE_2023_10_20_API_BASE_PATH}/embedded-wallet/headless-oauth-login-link`;
|
||||
export const ROUTE_HEADLESS_OAUTH_LOGIN = `${ROUTE_2023_10_20_API_BASE_PATH}/embedded-wallet/headless-oauth-login-link`;
|
||||
|
||||
export const ROUTE_AUTH_COGNITO_ID_TOKEN = `${ROUTE_2023_10_20_API_BASE_PATH}/embedded-wallet/cognito-id-token`;
|
||||
|
||||
+3
-3
@@ -91,9 +91,9 @@ function createWalletShares(): {
|
||||
|
||||
/**
|
||||
* Store user's wallet shares. Encrypts authShare and recoveryShare as given clientSide as well.
|
||||
* @param {string} walletAddress the user's wallet address. Note that for each logged in user and clientId, we have a single walletAddress. This will error if we attempt to store shares for user's with an existing wallet different from the walletAddress
|
||||
* @param {string} authShare the *unencrypted* authShare for the user
|
||||
* @param {string} recoveryShare the *unencrypted* recovery share for the user
|
||||
* @param walletAddress - the user's wallet address. Note that for each logged in user and clientId, we have a single walletAddress. This will error if we attempt to store shares for user's with an existing wallet different from the walletAddress
|
||||
* @param authShare - the *unencrypted* authShare for the user
|
||||
* @param recoveryShare - the *unencrypted* recovery share for the user
|
||||
* @throws if another walletAddress already exists
|
||||
*/
|
||||
export async function storeShares<R extends string | undefined>({
|
||||
|
||||
+2
-2
@@ -46,9 +46,9 @@ export async function getExistingUserEtherJsWallet(clientId: string) {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param deviceShare retrieves the current share associated with the user's device.
|
||||
* @param deviceShare - retrieves the current share associated with the user's device.
|
||||
* @returns the requested shares
|
||||
* @throws if attempting to get {@param deviceShare} when it's not present
|
||||
* @throws if attempting to get deviceShare when it's not present
|
||||
*/
|
||||
export async function getShares<
|
||||
A extends boolean,
|
||||
|
||||
@@ -62,8 +62,8 @@ type EmailVerificationAuthParams = {
|
||||
recoveryCode?: string;
|
||||
};
|
||||
|
||||
type GoogleAuthParams = {
|
||||
strategy: "google";
|
||||
type SocialAuthParams = {
|
||||
strategy: "google" | "facebook" | "apple";
|
||||
redirectUrl: string;
|
||||
};
|
||||
|
||||
@@ -76,7 +76,7 @@ type JwtAuthParams = {
|
||||
// this is the input to 'authenticate'
|
||||
export type AuthParams =
|
||||
| EmailVerificationAuthParams
|
||||
| GoogleAuthParams
|
||||
| SocialAuthParams
|
||||
| JwtAuthParams;
|
||||
|
||||
// TODO typed based off AuthParams["strategy"]
|
||||
|
||||
@@ -8,7 +8,7 @@ import { useCoinbaseWalletListener } from "./useCoinbaseWalletListener";
|
||||
* const connect = useCoinbaseWallet('org.reactjs.native.example.test15://');
|
||||
* connect();
|
||||
*
|
||||
* @param callbackURL The Universal Link used by Coinbase Wallet to return responses to your application.
|
||||
* @param callbackURL - The Universal Link used by Coinbase Wallet to return responses to your application.
|
||||
* @returns connect function to connect to the Coinbase wallet
|
||||
*/
|
||||
export function useCoinbaseWallet(callbackURL: URL) {
|
||||
|
||||
@@ -2,63 +2,79 @@ import { useWallet } from "@thirdweb-dev/react-core";
|
||||
import { useCallback, useEffect } from "react";
|
||||
import { useModalState } from "../../providers/ui-context-provider";
|
||||
import {
|
||||
IWalletConnectReceiver,
|
||||
WCProposal,
|
||||
WCRequest,
|
||||
WalletConnectHandler,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
|
||||
/**
|
||||
* Registers listeners for wallet connect if the active wallet
|
||||
* is a smart wallet and has connect to app enabled
|
||||
* is also a WalletConnectReceiver
|
||||
*/
|
||||
export function useWalletConnectListener() {
|
||||
export function useWalletConnectListener(
|
||||
walletConnectHandler?: WalletConnectHandler,
|
||||
) {
|
||||
const activeWallet = useWallet();
|
||||
const { setModalState } = useModalState();
|
||||
|
||||
const onSmartWalletWCMessage = useCallback(
|
||||
({ type, data }: { type: string; data?: unknown }) => {
|
||||
switch (type) {
|
||||
case "session_proposal":
|
||||
setModalState({
|
||||
view: "WalletConnectSessionProposalModal",
|
||||
caller: "WCSessionProposalListener",
|
||||
data: data as WCProposal,
|
||||
isOpen: true,
|
||||
isSheet: false,
|
||||
});
|
||||
break;
|
||||
case "session_delete":
|
||||
// reset();
|
||||
break;
|
||||
case "session_request":
|
||||
setModalState({
|
||||
view: "WalletConnectSessionRequestModal",
|
||||
caller: "WCSessionRequestListener",
|
||||
data: data as WCRequest,
|
||||
isOpen: true,
|
||||
isSheet: false,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
// method not implemented
|
||||
}
|
||||
const onSessionProposal = useCallback(
|
||||
(proposal: WCProposal) => {
|
||||
setModalState({
|
||||
view: "WalletConnectSessionProposalModal",
|
||||
caller: "WCSessionProposalListener",
|
||||
data: proposal,
|
||||
isOpen: true,
|
||||
isSheet: false,
|
||||
});
|
||||
},
|
||||
[setModalState],
|
||||
);
|
||||
|
||||
const onSessionRequest = useCallback(
|
||||
(proposal: WCRequest) => {
|
||||
setModalState({
|
||||
view: "WalletConnectSessionRequestModal",
|
||||
caller: "WCSessionRequestListener",
|
||||
data: proposal,
|
||||
isOpen: true,
|
||||
isSheet: false,
|
||||
});
|
||||
},
|
||||
[setModalState],
|
||||
);
|
||||
|
||||
const onSessionDelete = useCallback(() => {
|
||||
// consider clearing local storage
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
activeWallet &&
|
||||
"isWCReceiverEnabled" in activeWallet &&
|
||||
(activeWallet as unknown as IWalletConnectReceiver).isWCReceiverEnabled()
|
||||
) {
|
||||
activeWallet.addListener("message", onSmartWalletWCMessage);
|
||||
if (!walletConnectHandler) {
|
||||
return;
|
||||
}
|
||||
|
||||
walletConnectHandler.addListener("session_proposal", onSessionProposal);
|
||||
walletConnectHandler.addListener("session_delete", onSessionDelete);
|
||||
walletConnectHandler.addListener("session_request", onSessionRequest);
|
||||
// consider adding switch_chain as well
|
||||
|
||||
return () => {
|
||||
if (activeWallet) {
|
||||
activeWallet.removeListener("message", onSmartWalletWCMessage);
|
||||
if (walletConnectHandler) {
|
||||
walletConnectHandler.removeListener(
|
||||
"session_proposal",
|
||||
onSessionProposal,
|
||||
);
|
||||
walletConnectHandler.removeListener("session_delete", onSessionDelete);
|
||||
walletConnectHandler.removeListener(
|
||||
"session_request",
|
||||
onSessionRequest,
|
||||
);
|
||||
}
|
||||
};
|
||||
}, [activeWallet, onSmartWalletWCMessage]);
|
||||
}, [
|
||||
activeWallet,
|
||||
onSessionDelete,
|
||||
onSessionProposal,
|
||||
onSessionRequest,
|
||||
walletConnectHandler,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { APPLE_ICON, EMAIL_WALLET_ICON, GOOGLE_ICON } from "../../assets";
|
||||
import { LocaleType } from "../../i18n/types";
|
||||
|
||||
export type AuthOption = "email" | SocialLogin;
|
||||
|
||||
export type SocialLogin = "google" | "apple";
|
||||
|
||||
export type AuthOptionDictionary = Record<AuthOption, string>;
|
||||
|
||||
export const AUTH_OPTIONS_ICONS: AuthOptionDictionary = {
|
||||
google: GOOGLE_ICON,
|
||||
email: EMAIL_WALLET_ICON,
|
||||
apple: APPLE_ICON,
|
||||
};
|
||||
|
||||
export const AUTH_OPTIONS_TEXT: Record<
|
||||
AuthOption,
|
||||
keyof LocaleType["embedded_wallet"]
|
||||
> = {
|
||||
google: "sign_in_google",
|
||||
email: "sign_in_email",
|
||||
apple: "sign_in_apple",
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
import { WalletInstance } from "@thirdweb-dev/react-core";
|
||||
|
||||
export const isWalletConnectReceiverEnabled = (wallet?: WalletInstance) => {
|
||||
const options = wallet?.getOptions();
|
||||
return options && "walletConnectReceiver" in options;
|
||||
};
|
||||
@@ -10,14 +10,18 @@ import Box from "../../../components/base/Box";
|
||||
import Text from "../../../components/base/Text";
|
||||
import BaseButton from "../../../components/base/BaseButton";
|
||||
import { TextInput } from "../../../components/base/TextInput";
|
||||
import { GOOGLE_ICON } from "../../../assets/svgs";
|
||||
import { WalletButton } from "../../../components/base/WalletButton";
|
||||
import {
|
||||
useGlobalTheme,
|
||||
useLocale,
|
||||
} from "../../../providers/ui-context-provider";
|
||||
import { EmbeddedWalletConfig } from "./embedded-wallet";
|
||||
import { AuthProvider } from "@thirdweb-dev/wallets";
|
||||
import {
|
||||
AUTH_OPTIONS_ICONS,
|
||||
AUTH_OPTIONS_TEXT,
|
||||
AuthOption,
|
||||
} from "../../types/embedded-wallet";
|
||||
import { SquareButton } from "../../../components/base/SquareButton";
|
||||
|
||||
/**
|
||||
* UI for selecting wallet - this UI is rendered in the wallet selection screen
|
||||
@@ -37,7 +41,8 @@ export const EmailSelectionUI: React.FC<
|
||||
const supportedWallets = useWallets();
|
||||
|
||||
const isEmailEnabled = auth?.options.includes("email");
|
||||
const isGoogleEnabled = auth?.options.includes("google");
|
||||
const socialLogins = auth?.options.filter((o) => o !== "email");
|
||||
const isSocialLoginsEnabled = socialLogins && socialLogins.length > 0;
|
||||
|
||||
useEffect(() => {
|
||||
const emailWalletInstance = createWalletInstance(
|
||||
@@ -81,12 +86,12 @@ export const EmailSelectionUI: React.FC<
|
||||
}
|
||||
};
|
||||
|
||||
const onGoogleSignInPress = () => {
|
||||
const onProviderPress = (authOption: Omit<AuthOption, "email">) => {
|
||||
onSelect({
|
||||
email: emailInput,
|
||||
emailWallet,
|
||||
oauthOptions: {
|
||||
provider: AuthProvider.GOOGLE,
|
||||
provider: authOption,
|
||||
redirectUrl: auth?.redirectUrl,
|
||||
},
|
||||
});
|
||||
@@ -94,21 +99,36 @@ export const EmailSelectionUI: React.FC<
|
||||
|
||||
return (
|
||||
<Box paddingHorizontal="xl" mt="lg">
|
||||
{isGoogleEnabled ? (
|
||||
{isSocialLoginsEnabled ? (
|
||||
<Box justifyContent="center">
|
||||
<WalletButton
|
||||
iconHeight={28}
|
||||
iconWidth={28}
|
||||
borderRadius="lg"
|
||||
borderWidth={1}
|
||||
borderColor="buttonBackgroundColor"
|
||||
backgroundColor="buttonBackgroundColor"
|
||||
nameColor="buttonTextColor"
|
||||
justifyContent="center"
|
||||
name={l.embedded_wallet.sign_in_google}
|
||||
walletIconUrl={GOOGLE_ICON}
|
||||
onPress={onGoogleSignInPress}
|
||||
/>
|
||||
<Box justifyContent="center" flexDirection="row">
|
||||
{socialLogins.length === 1 ? (
|
||||
<WalletButton
|
||||
iconHeight={28}
|
||||
iconWidth={28}
|
||||
borderRadius="lg"
|
||||
borderWidth={1}
|
||||
borderColor="buttonBackgroundColor"
|
||||
backgroundColor="buttonBackgroundColor"
|
||||
nameColor="buttonTextColor"
|
||||
flex={1}
|
||||
justifyContent="center"
|
||||
name={l.embedded_wallet[AUTH_OPTIONS_TEXT[socialLogins[0]]]}
|
||||
walletIconUrl={AUTH_OPTIONS_ICONS[socialLogins[0]]}
|
||||
onPress={() => onProviderPress(socialLogins[0])}
|
||||
/>
|
||||
) : (
|
||||
socialLogins.map((provider, index) => (
|
||||
<SquareButton
|
||||
key={provider}
|
||||
ml={index === 0 ? 0 : "md"}
|
||||
onPress={() => onProviderPress(provider)}
|
||||
iconUrl={AUTH_OPTIONS_ICONS[provider]}
|
||||
size={40}
|
||||
/>
|
||||
))
|
||||
)}
|
||||
</Box>
|
||||
{isEmailEnabled && supportedWallets.length === 1 ? (
|
||||
<Box
|
||||
mb="md"
|
||||
|
||||
+19
-12
@@ -7,9 +7,9 @@ import {
|
||||
useSetConnectedWallet,
|
||||
useSetConnectionStatus,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { GOOGLE_ICON } from "../../../assets";
|
||||
import { ConnectWalletHeader } from "../../../components/ConnectWalletFlow/ConnectingWallet/ConnectingWalletHeader";
|
||||
import { Box, Text, WalletButton } from "../../../components/base";
|
||||
import { AUTH_OPTIONS_ICONS, SocialLogin } from "../../types/embedded-wallet";
|
||||
|
||||
export const EmbeddedSocialConnection: React.FC<
|
||||
ConnectUIProps<EmbeddedWallet>
|
||||
@@ -18,19 +18,19 @@ export const EmbeddedSocialConnection: React.FC<
|
||||
const setConnectionStatus = useSetConnectionStatus();
|
||||
const [errorMessage, setErrorMessage] = useState<string>();
|
||||
|
||||
const handleGoogleLogin = useCallback(() => {
|
||||
const handleSocialLogin = useCallback(() => {
|
||||
setErrorMessage("");
|
||||
|
||||
setTimeout(async () => {
|
||||
const emailWallet = selectionData.emailWallet as EmbeddedWallet;
|
||||
const embeddedWallet = selectionData.emailWallet as EmbeddedWallet;
|
||||
|
||||
try {
|
||||
const authResult = await emailWallet.authenticate({
|
||||
strategy: "google",
|
||||
const authResult = await embeddedWallet.authenticate({
|
||||
strategy: selectionData.oauthOptions?.provider as SocialLogin,
|
||||
redirectUrl: selectionData.oauthOptions?.redirectUrl,
|
||||
});
|
||||
|
||||
const response = await emailWallet.connect({ authResult });
|
||||
const response = await embeddedWallet.connect({ authResult });
|
||||
|
||||
if (response) {
|
||||
if (onLocallyConnected) {
|
||||
@@ -41,12 +41,15 @@ export const EmbeddedSocialConnection: React.FC<
|
||||
}
|
||||
} else {
|
||||
setErrorMessage(
|
||||
response || "Error login in. Please try again later.",
|
||||
response || "Error signing in. Please try again later.",
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error logging in with google: ", error);
|
||||
setErrorMessage(`Error login in. ${error}`);
|
||||
console.error(
|
||||
`Error signing in with ${selectionData.oauthOptions?.provider}: `,
|
||||
error,
|
||||
);
|
||||
setErrorMessage(`${error}`);
|
||||
}
|
||||
}, 0);
|
||||
}, [
|
||||
@@ -58,8 +61,8 @@ export const EmbeddedSocialConnection: React.FC<
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
handleGoogleLogin();
|
||||
}, [handleGoogleLogin]);
|
||||
handleSocialLogin();
|
||||
}, [handleSocialLogin]);
|
||||
|
||||
return (
|
||||
<Box marginHorizontal="xl" height={200}>
|
||||
@@ -71,7 +74,11 @@ export const EmbeddedSocialConnection: React.FC<
|
||||
borderRadius="lg"
|
||||
justifyContent="center"
|
||||
name="Sign In"
|
||||
walletIconUrl={GOOGLE_ICON}
|
||||
walletIconUrl={
|
||||
AUTH_OPTIONS_ICONS[
|
||||
selectionData.oauthOptions?.provider as SocialLogin
|
||||
]
|
||||
}
|
||||
/>
|
||||
}
|
||||
subHeaderText={""}
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
AbstractClientWallet,
|
||||
EmbeddedWalletAdditionalOptions,
|
||||
walletIds,
|
||||
WalletConnectReceiverConfig,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
import type { EmbeddedWalletConnector } from "../../connectors/embedded-wallet/embedded-connector";
|
||||
import {
|
||||
@@ -11,8 +12,9 @@ import {
|
||||
} from "../../connectors/embedded-wallet/types";
|
||||
import { EMAIL_WALLET_ICON } from "../../../assets/svgs";
|
||||
|
||||
export type EmbeddedWalletOptions =
|
||||
WalletOptions<EmbeddedWalletAdditionalOptions>;
|
||||
export type EmbeddedWalletOptions = WalletOptions<
|
||||
EmbeddedWalletAdditionalOptions & WalletConnectReceiverConfig
|
||||
>;
|
||||
|
||||
export class EmbeddedWallet extends AbstractClientWallet<
|
||||
EmbeddedWalletOptions,
|
||||
|
||||
@@ -50,7 +50,7 @@ export const EnterPassword = ({
|
||||
};
|
||||
|
||||
const onForgotPress = () => {
|
||||
// console.log("[TODO] Implement", setErrorMessage);
|
||||
// [TODO] Forgot password
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -6,15 +6,15 @@ import {
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { EmbeddedConnectionUI } from "./EmbeddedConnectionUI";
|
||||
import { EmailSelectionUI } from "./EmbeddedSelectionUI";
|
||||
|
||||
type AuthOption = "email" | "google";
|
||||
import { AuthOption } from "../../types/embedded-wallet";
|
||||
import { WalletConnectReceiverConfig } from "@thirdweb-dev/wallets";
|
||||
|
||||
export type EmbeddedWalletConfig = {
|
||||
auth?: {
|
||||
options: AuthOption[];
|
||||
redirectUrl?: string;
|
||||
};
|
||||
};
|
||||
} & WalletConnectReceiverConfig;
|
||||
|
||||
export const embeddedWallet = (
|
||||
config?: EmbeddedWalletConfig,
|
||||
@@ -36,6 +36,7 @@ export const embeddedWallet = (
|
||||
create(options: WalletOptions) {
|
||||
return new EmbeddedWallet({
|
||||
...options,
|
||||
...config,
|
||||
clientId: options.clientId || "",
|
||||
});
|
||||
},
|
||||
|
||||
@@ -23,7 +23,7 @@ import { useGlobalTheme, useLocale } from "../../providers/ui-context-provider";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param magicLinkOptions Options available to create a magic link wallet
|
||||
* @param magicLinkOptions - Options available to create a magic link wallet
|
||||
* @returns A WalletConfig<MagicLink> object
|
||||
*
|
||||
* @deprecated We have deprecated magicLink in favor of our embeddedWallet which adds support for more sign in methods.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { WalletConfig, WalletOptions } from "@thirdweb-dev/react-core";
|
||||
import { SmartWallet, createAsyncLocalStorage } from "@thirdweb-dev/wallets";
|
||||
import { createSyncStorage } from "../../../core/AsyncStorage";
|
||||
import { SmartWalletConfig } from "../types/smart-wallet";
|
||||
import { SmartWalletFlow } from "../../components/ConnectWalletFlow/SmartWallet/SmartWalletFlow";
|
||||
|
||||
@@ -17,7 +16,6 @@ export const smartWallet = (
|
||||
...options,
|
||||
...config,
|
||||
walletStorage: createAsyncLocalStorage("smart-wallet"),
|
||||
wcStorage: createSyncStorage("smart-wallet"),
|
||||
}),
|
||||
connectUI(props) {
|
||||
return <SmartWalletFlow {...props} personalWalletConfig={wallet} />;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: ["thirdweb", "plugin:i18next/recommended"],
|
||||
plugins: ["better-tree-shaking"],
|
||||
plugins: ["better-tree-shaking", "eslint-plugin-tsdoc"],
|
||||
rules: {
|
||||
"tsdoc/syntax": "error",
|
||||
"@next/next/no-img-element": "off",
|
||||
"better-tree-shaking/no-top-level-side-effects": "error",
|
||||
"i18next/no-literal-string": 2,
|
||||
|
||||
@@ -1,5 +1,45 @@
|
||||
# @thirdweb-dev/react
|
||||
|
||||
## 4.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1944](https://github.com/thirdweb-dev/js/pull/1944) [`6fcdec7c`](https://github.com/thirdweb-dev/js/commit/6fcdec7c12e4a3c0d10f3a67771e19cfad5c8ab5) Thanks [@iketw](https://github.com/iketw)! - Adds tsdoc warnings to enforce a common comments format
|
||||
|
||||
- [#1948](https://github.com/thirdweb-dev/js/pull/1948) [`42c74368`](https://github.com/thirdweb-dev/js/commit/42c743682739de77c264c11cc1692ed752f929a6) Thanks [@iketw](https://github.com/iketw)! - Deprecates PaperWallet in favor of EmbeddedWallet
|
||||
|
||||
- Updated dependencies [[`23ab897e`](https://github.com/thirdweb-dev/js/commit/23ab897e329cdd5b316fbe554ea0f64add91f2b4), [`a3f3e160`](https://github.com/thirdweb-dev/js/commit/a3f3e160e07328655a4f0332f41f4edd210a1a8a), [`e79a9520`](https://github.com/thirdweb-dev/js/commit/e79a95206116ea09de0126fdbe30fb4413fdff28), [`6fcdec7c`](https://github.com/thirdweb-dev/js/commit/6fcdec7c12e4a3c0d10f3a67771e19cfad5c8ab5), [`42c74368`](https://github.com/thirdweb-dev/js/commit/42c743682739de77c264c11cc1692ed752f929a6), [`6fcdec7c`](https://github.com/thirdweb-dev/js/commit/6fcdec7c12e4a3c0d10f3a67771e19cfad5c8ab5), [`480ed721`](https://github.com/thirdweb-dev/js/commit/480ed721d1c736049fa8b6ee4cbdbdf3cce18abd), [`16e9e8b6`](https://github.com/thirdweb-dev/js/commit/16e9e8b64d7d1a97a5b32fc855479e992b7ed3a8), [`b1190914`](https://github.com/thirdweb-dev/js/commit/b1190914a97a9c4d9019c4ce8ee49ad345aed18c)]:
|
||||
- @thirdweb-dev/sdk@4.0.13
|
||||
- @thirdweb-dev/react-core@4.1.4
|
||||
- @thirdweb-dev/wallets@2.1.3
|
||||
|
||||
## 4.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1943](https://github.com/thirdweb-dev/js/pull/1943) [`30ea9c6b`](https://github.com/thirdweb-dev/js/commit/30ea9c6bf74b483a98592a1d8d64589b7f1b22a3) Thanks [@iketw](https://github.com/iketw)! - Adds tsdoc warnings to enforce a common comments format
|
||||
|
||||
- [#1929](https://github.com/thirdweb-dev/js/pull/1929) [`06e59cf9`](https://github.com/thirdweb-dev/js/commit/06e59cf91647e4080829d49f8cb91a4d8fdc87f7) Thanks [@iketw](https://github.com/iketw)! - Move addresses' utils to the core package
|
||||
|
||||
- [#1920](https://github.com/thirdweb-dev/js/pull/1920) [`a81a5285`](https://github.com/thirdweb-dev/js/commit/a81a5285b7ef4ddf47fd2779ab80ebbef4bd9e0e) Thanks [@ElasticBottle](https://github.com/ElasticBottle)! - feat: add apple auth to embedded wallet
|
||||
|
||||
```
|
||||
<ThirdwebProvider
|
||||
supportedWallets={[
|
||||
embeddedWallet({
|
||||
auth: {
|
||||
options: ["google", "email", "apple"], // <- new apple option!
|
||||
}
|
||||
})
|
||||
]}
|
||||
>
|
||||
```
|
||||
|
||||
- Updated dependencies [[`3f3a484a`](https://github.com/thirdweb-dev/js/commit/3f3a484a3aa6e9f784e4d44458461bac0d3d4c6b), [`a81a5285`](https://github.com/thirdweb-dev/js/commit/a81a5285b7ef4ddf47fd2779ab80ebbef4bd9e0e), [`30ea9c6b`](https://github.com/thirdweb-dev/js/commit/30ea9c6bf74b483a98592a1d8d64589b7f1b22a3), [`06e59cf9`](https://github.com/thirdweb-dev/js/commit/06e59cf91647e4080829d49f8cb91a4d8fdc87f7), [`97fdbc8f`](https://github.com/thirdweb-dev/js/commit/97fdbc8f6443dcd08a7610e4437bd4c9d6b0e8c8), [`3f3a484a`](https://github.com/thirdweb-dev/js/commit/3f3a484a3aa6e9f784e4d44458461bac0d3d4c6b)]:
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
- @thirdweb-dev/[email protected]
|
||||
|
||||
## 4.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react",
|
||||
"version": "4.1.2",
|
||||
"version": "4.1.4",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -64,6 +64,14 @@ export const Button = styled.button<{
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
if (p.variant === "secondary") {
|
||||
return `
|
||||
&:hover {
|
||||
background: ${p.theme.colors.secondaryButtonHoverBg};
|
||||
}
|
||||
`;
|
||||
}
|
||||
}}
|
||||
|
||||
${(p) => {
|
||||
|
||||
@@ -197,14 +197,16 @@ export function enDefault() {
|
||||
},
|
||||
embeddedWallet: {
|
||||
signInWithGoogle: "Sign in with Google",
|
||||
signInWithFacebook: "Sign in with Facebook",
|
||||
signInWithApple: "Sign in with Apple",
|
||||
emailPlaceholder: "Enter your email address",
|
||||
submitEmail: "Continue",
|
||||
signIn: "Sign in",
|
||||
emailRequired: "Email address is required",
|
||||
invalidEmail: "Invalid email address",
|
||||
googleLoginScreen: {
|
||||
socialLoginScreen: {
|
||||
title: "Sign in",
|
||||
instruction: "Select your Google account in the pop-up",
|
||||
instruction: "Sign into your account in the pop-up",
|
||||
failed: "Failed to sign in",
|
||||
retry: "Retry",
|
||||
},
|
||||
|
||||
@@ -201,14 +201,16 @@ export function esDefault(): ThirdwebLocale {
|
||||
},
|
||||
embeddedWallet: {
|
||||
signInWithGoogle: "Iniciar sesión con Google",
|
||||
signInWithFacebook: "Iniciar sesión con Facebook",
|
||||
signInWithApple: "Iniciar sesión con Apple",
|
||||
emailPlaceholder: "Ingresa tu dirección de correo electrónico",
|
||||
submitEmail: "Continuar",
|
||||
signIn: "Iniciar sesión",
|
||||
emailRequired: "Se requiere dirección de correo electrónico",
|
||||
invalidEmail: "Dirección de correo electrónico inválida",
|
||||
googleLoginScreen: {
|
||||
socialLoginScreen: {
|
||||
title: "Iniciar sesión",
|
||||
instruction: "Selecciona tu cuenta de Google en la ventana emergente",
|
||||
instruction: "Inicie sesión en su cuenta en la ventana abierta",
|
||||
failed: "Error al iniciar sesión",
|
||||
retry: "Reintentar",
|
||||
},
|
||||
|
||||
@@ -200,14 +200,16 @@ export function jaDefault(): ThirdwebLocale {
|
||||
},
|
||||
embeddedWallet: {
|
||||
signInWithGoogle: "Googleでサインイン",
|
||||
signInWithFacebook: "Facebookでサインイン",
|
||||
signInWithApple: "Appleでサインイン",
|
||||
emailPlaceholder: "メールアドレスを入力してください",
|
||||
submitEmail: "続ける",
|
||||
emailRequired: "メールアドレスが必要です",
|
||||
invalidEmail: "無効なメールアドレス",
|
||||
signIn: "サインイン",
|
||||
googleLoginScreen: {
|
||||
socialLoginScreen: {
|
||||
title: "サインイン",
|
||||
instruction: "ポップアップ内でGoogleアカウントを選択してください",
|
||||
instruction: "ポップアップウィンドウでアカウントにサインインします", // TODO: check if this is correct
|
||||
failed: "サインインに失敗しました",
|
||||
retry: "再試行",
|
||||
},
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import { utils } from "ethers";
|
||||
|
||||
export function shortenString(str: string, extraShort?: true) {
|
||||
return `${str.substring(0, extraShort ? 4 : 6)}...${str.substring(
|
||||
str.length - (extraShort ? 3 : 4),
|
||||
)}`;
|
||||
}
|
||||
|
||||
export function shortenAddress(address: string, extraShort?: true): string {
|
||||
try {
|
||||
const formattedAddress = utils.getAddress(address);
|
||||
return shortenString(formattedAddress, extraShort);
|
||||
} catch {
|
||||
return address;
|
||||
}
|
||||
}
|
||||
|
||||
export function shortenIfAddress(
|
||||
address?: string | null | false,
|
||||
extraShort?: true,
|
||||
): string {
|
||||
if (typeof address === "string" && address.length > 0) {
|
||||
return shortenAddress(address, extraShort);
|
||||
}
|
||||
return address || "";
|
||||
}
|
||||
@@ -5,8 +5,8 @@ export type DeepPartial<T extends Record<string, any>> = {
|
||||
/**
|
||||
* Create a new object with given overrides object applied on top of given base object without mutating the base and overrides object
|
||||
*
|
||||
* @param defaultObj the object to use as the base object
|
||||
* @param overrides the object to use as the overrides
|
||||
* @param defaultObj - the object to use as the base object
|
||||
* @param overrides - the object to use as the overrides
|
||||
*/
|
||||
export function immutableOverride<T extends Record<string, any>>(
|
||||
defaultObj: T,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* if the `options.for` promise takes longer than the `options.moreThan` time, `options.do` callback function will be called
|
||||
*
|
||||
* this is useful to prevent showing the loading animation for a super short time that looks like flickering
|
||||
* @param options
|
||||
* @param options - Options for the ifWaiting function
|
||||
*/
|
||||
export async function ifWaiting(options: {
|
||||
for: Promise<any>;
|
||||
|
||||
@@ -42,7 +42,7 @@ export type ConnectWalletProps = {
|
||||
btnTitle?: string;
|
||||
/**
|
||||
* Set a custom title for the modal
|
||||
* @default "Connect"
|
||||
* @defaultValue "Connect"
|
||||
*/
|
||||
modalTitle?: string;
|
||||
|
||||
@@ -74,7 +74,7 @@ export type ConnectWalletProps = {
|
||||
/**
|
||||
* Hide option to request testnet funds for testnets in dropdown
|
||||
*
|
||||
* @default false
|
||||
* @defaultValue false
|
||||
*/
|
||||
hideTestnetFaucet?: boolean;
|
||||
|
||||
@@ -85,7 +85,7 @@ export type ConnectWalletProps = {
|
||||
* Please, note that if you support multiple networks in your app this prop should
|
||||
* be set to `false` to allow users to switch between networks.
|
||||
*
|
||||
* @default false
|
||||
* @defaultValue false
|
||||
*/
|
||||
switchToActiveChain?: boolean;
|
||||
|
||||
@@ -94,7 +94,7 @@ export type ConnectWalletProps = {
|
||||
*
|
||||
* Modal size is always `compact` on mobile
|
||||
*
|
||||
* @default "wide"
|
||||
* @defaultValue "wide"
|
||||
*/
|
||||
modalSize?: "compact" | "wide";
|
||||
|
||||
@@ -139,7 +139,7 @@ export type ConnectWalletProps = {
|
||||
/**
|
||||
* Hide the "switch to Personal wallet" option in the dropdown which is shown when wallet is connected to either Smart Wallet or Safe
|
||||
*
|
||||
* @default false
|
||||
* @defaultValue false
|
||||
*/
|
||||
hideSwitchToPersonalWallet?: boolean;
|
||||
};
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
spacing,
|
||||
Theme,
|
||||
} from "../../design-system";
|
||||
import { shortenString } from "../../evm/utils/addresses";
|
||||
import { isMobile } from "../../evm/utils/isMobile";
|
||||
import { NetworkSelector, type NetworkSelectorProps } from "./NetworkSelector";
|
||||
import { ExitIcon } from "./icons/ExitIcon";
|
||||
@@ -61,6 +60,7 @@ import { SupportedTokens } from "./defaultTokens";
|
||||
import { ReceiveFunds } from "./ReceiveFunds";
|
||||
import { smartWalletIcon } from "./icons/dataUris";
|
||||
import { useTWLocale } from "../../evm/providers/locale-provider";
|
||||
import { shortenString } from "@thirdweb-dev/react-core";
|
||||
|
||||
export type DropDownPosition = {
|
||||
side: "top" | "bottom" | "left" | "right";
|
||||
|
||||
@@ -2,7 +2,6 @@ import { useAddress } from "@thirdweb-dev/react-core";
|
||||
import { Spacer } from "../../components/Spacer";
|
||||
import { Container, ModalHeader } from "../../components/basic";
|
||||
import { Text } from "../../components/text";
|
||||
import { shortenString } from "../../evm/utils/addresses";
|
||||
import { CopyIcon } from "../../components/CopyIcon";
|
||||
import styled from "@emotion/styled";
|
||||
import { Theme, iconSize, radius, spacing } from "../../design-system";
|
||||
@@ -10,6 +9,7 @@ import { QRCode } from "../../components/QRCode";
|
||||
import { Img } from "../../components/Img";
|
||||
import { useClipboard } from "../../evm/components/hooks/useCopyClipboard";
|
||||
import { useTWLocale } from "../../evm/providers/locale-provider";
|
||||
import { shortenString } from "@thirdweb-dev/react-core";
|
||||
|
||||
export function ReceiveFunds(props: { iconUrl: string }) {
|
||||
const address = useAddress();
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
import { IconFC } from "./types";
|
||||
|
||||
export const GoogleIcon: IconFC = (props) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
height={props.size}
|
||||
viewBox="0 0 24 24"
|
||||
width={props.size}
|
||||
>
|
||||
<path
|
||||
d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
|
||||
fill="#4285F4"
|
||||
/>
|
||||
<path
|
||||
d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
|
||||
fill="#34A853"
|
||||
/>
|
||||
<path
|
||||
d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
|
||||
fill="#FBBC05"
|
||||
/>
|
||||
<path
|
||||
d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
|
||||
fill="#EA4335"
|
||||
/>
|
||||
<path d="M1 1h22v22H1z" fill="none" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
export const googleIconUri =
|
||||
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDUuNiIgaGVpZ2h0PSI3MjAiIHZpZXdCb3g9IjAgMCAxODYuNjkgMTkwLjUiIHhtbG5zOnY9Imh0dHBzOi8vdmVjdGEuaW8vbmFubyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTE4NC41ODMgNzY1LjE3MSkiPjxwYXRoIGNsaXAtcGF0aD0ibm9uZSIgbWFzaz0ibm9uZSIgZD0iTS0xMDg5LjMzMy02ODcuMjM5djM2Ljg4OGg1MS4yNjJjLTIuMjUxIDExLjg2My05LjAwNiAyMS45MDgtMTkuMTM3IDI4LjY2MmwzMC45MTMgMjMuOTg2YzE4LjAxMS0xNi42MjUgMjguNDAyLTQxLjA0NCAyOC40MDItNzAuMDUyIDAtNi43NTQtLjYwNi0xMy4yNDktMS43MzItMTkuNDgzeiIgZmlsbD0iIzQyODVmNCIvPjxwYXRoIGNsaXAtcGF0aD0ibm9uZSIgbWFzaz0ibm9uZSIgZD0iTS0xMTQyLjcxNC02NTEuNzkxbC02Ljk3MiA1LjMzNy0yNC42NzkgMTkuMjIzaDBjMTUuNjczIDMxLjA4NiA0Ny43OTYgNTIuNTYxIDg1LjAzIDUyLjU2MSAyNS43MTcgMCA0Ny4yNzgtOC40ODYgNjMuMDM4LTIzLjAzM2wtMzAuOTEzLTIzLjk4NmMtOC40ODYgNS43MTUtMTkuMzEgOS4xNzktMzIuMTI1IDkuMTc5LTI0Ljc2NSAwLTQ1LjgwNi0xNi43MTItNTMuMzQtMzkuMjI2eiIgZmlsbD0iIzM0YTg1MyIvPjxwYXRoIGNsaXAtcGF0aD0ibm9uZSIgbWFzaz0ibm9uZSIgZD0iTS0xMTc0LjM2NS03MTIuNjFjLTYuNDk0IDEyLjgxNS0xMC4yMTcgMjcuMjc2LTEwLjIxNyA0Mi42ODlzMy43MjMgMjkuODc0IDEwLjIxNyA0Mi42ODljMCAuMDg2IDMxLjY5My0yNC41OTIgMzEuNjkzLTI0LjU5Mi0xLjkwNS01LjcxNS0zLjAzMS0xMS43NzYtMy4wMzEtMTguMDk4czEuMTI2LTEyLjM4MyAzLjAzMS0xOC4wOTh6IiBmaWxsPSIjZmJiYzA1Ii8+PHBhdGggZD0iTS0xMDg5LjMzMy03MjcuMjQ0YzE0LjAyOCAwIDI2LjQ5NyA0Ljg0OSAzNi40NTUgMTQuMjAxbDI3LjI3Ni0yNy4yNzZjLTE2LjUzOS0xNS40MTMtMzguMDEzLTI0Ljg1Mi02My43MzEtMjQuODUyLTM3LjIzNCAwLTY5LjM1OSAyMS4zODgtODUuMDMyIDUyLjU2MWwzMS42OTIgMjQuNTkyYzcuNTMzLTIyLjUxNCAyOC41NzUtMzkuMjI2IDUzLjM0LTM5LjIyNnoiIGZpbGw9IiNlYTQzMzUiIGNsaXAtcGF0aD0ibm9uZSIgbWFzaz0ibm9uZSIvPjwvZz48L3N2Zz4=";
|
||||
export const facebookIconUri =
|
||||
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGRhdGEtbmFtZT0iRWJlbmUgMSIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgaWQ9ImZhY2Vib29rLWxvZ28tMjAxOSI+PHBhdGggZmlsbD0iIzE4NzdmMiIgZD0iTTEwMjQsNTEyQzEwMjQsMjI5LjIzMDE2LDc5NC43Njk3OCwwLDUxMiwwUzAsMjI5LjIzMDE2LDAsNTEyYzAsMjU1LjU1NCwxODcuMjMxLDQ2Ny4zNzAxMiw0MzIsNTA1Ljc3Nzc3VjY2MEgzMDJWNTEySDQzMlYzOTkuMkM0MzIsMjcwLjg3OTgyLDUwOC40Mzg1NCwyMDAsNjI1LjM4OTIyLDIwMCw2ODEuNDA3NjUsMjAwLDc0MCwyMTAsNzQwLDIxMFYzMzZINjc1LjQzNzEzQzYxMS44MzUwOCwzMzYsNTkyLDM3NS40NjY2Nyw1OTIsNDE1Ljk1NzI4VjUxMkg3MzRMNzExLjMsNjYwSDU5MnYzNTcuNzc3NzdDODM2Ljc2OSw5NzkuMzcwMTIsMTAyNCw3NjcuNTU0LDEwMjQsNTEyWiI+PC9wYXRoPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik03MTEuMyw2NjAsNzM0LDUxMkg1OTJWNDE1Ljk1NzI4QzU5MiwzNzUuNDY2NjcsNjExLjgzNTA4LDMzNiw2NzUuNDM3MTMsMzM2SDc0MFYyMTBzLTU4LjU5MjM1LTEwLTExNC42MTA3OC0xMEM1MDguNDM4NTQsMjAwLDQzMiwyNzAuODc5ODIsNDMyLDM5OS4yVjUxMkgzMDJWNjYwSDQzMnYzNTcuNzc3NzdhNTE3LjM5NjE5LDUxNy4zOTYxOSwwLDAsMCwxNjAsMFY2NjBaIj48L3BhdGg+PC9zdmc+";
|
||||
export const twitterIconUri =
|
||||
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiIgaWQ9InR3aXR0ZXIiPjxwYXRoIGZpbGw9IiMwM0E5RjQiIGQ9Ik0xNiAzLjUzOWE2LjgzOSA2LjgzOSAwIDAgMS0xLjg5LjUxOCAzLjI2MiAzLjI2MiAwIDAgMCAxLjQ0My0xLjgxMyA2LjU1NSA2LjU1NSAwIDAgMS0yLjA4Ljc5NCAzLjI4IDMuMjggMCAwIDAtNS42NzQgMi4yNDNjMCAuMjYuMDIyLjUxLjA3Ni43NDhhOS4yODQgOS4yODQgMCAwIDEtNi43NjEtMy40MzEgMy4yODUgMy4yODUgMCAwIDAgMS4wMDggNC4zODRBMy4yNCAzLjI0IDAgMCAxIC42NCA2LjU3OHYuMDM2YTMuMjk1IDMuMjk1IDAgMCAwIDIuNjI4IDMuMjIzIDMuMjc0IDMuMjc0IDAgMCAxLS44Ni4xMDggMi45IDIuOSAwIDAgMS0uNjIxLS4wNTYgMy4zMTEgMy4zMTEgMCAwIDAgMy4wNjUgMi4yODUgNi41OSA2LjU5IDAgMCAxLTQuMDY3IDEuMzk5Yy0uMjY5IDAtLjUyNy0uMDEyLS43ODUtLjA0NUE5LjIzNCA5LjIzNCAwIDAgMCA1LjAzMiAxNWM2LjAzNiAwIDkuMzM2LTUgOS4zMzYtOS4zMzQgMC0uMTQ1LS4wMDUtLjI4NS0uMDEyLS40MjRBNi41NDQgNi41NDQgMCAwIDAgMTYgMy41Mzl6Ij48L3BhdGg+PC9zdmc+";
|
||||
export const githubIconUri =
|
||||
"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzEwXzIpIj4KPHBhdGggZD0iTTcuOTk5IDBDMy41ODIwMSAwIDQuNjE2NDhlLTA2IDMuNTk2IDQuNjE2NDhlLTA2IDguMDMyQy0wLjAwMTggOS43MTU1NSAwLjUyNTUxOSAxMS4zNTcxIDEuNTA3NDQgMTIuNzI0NkMyLjQ4OTM1IDE0LjA5MjIgMy44NzYyMSAxNS4xMTY2IDUuNDcyIDE1LjY1M0M1Ljg3MiAxNS43MjcgNi4wMTggMTUuNDc5IDYuMDE4IDE1LjI2NkM2LjAxOCAxNS4wNzUgNi4wMTEgMTQuNTcgNi4wMDcgMTMuOUMzLjc4MiAxNC4zODUgMy4zMTIgMTIuODIzIDMuMzEyIDEyLjgyM0MyLjk0OSAxMS44OTUgMi40MjQgMTEuNjQ4IDIuNDI0IDExLjY0OEMxLjY5NyAxMS4xNSAyLjQ3OCAxMS4xNiAyLjQ3OCAxMS4xNkMzLjI4MSAxMS4yMTcgMy43MDMgMTEuOTg4IDMuNzAzIDExLjk4OEM0LjQxNyAxMy4yMTUgNS41NzYgMTIuODYxIDYuMDMyIDEyLjY1NUM2LjEwNCAxMi4xMzYgNi4zMTEgMTEuNzgyIDYuNTQgMTEuNTgxQzQuNzY0IDExLjM3OCAyLjg5NiAxMC42ODkgMi44OTYgNy42MTJDMi44OTYgNi43MzUgMy4yMDggNi4wMTggMy43MiA1LjQ1NkMzLjYzNyA1LjI1MyAzLjM2MyA0LjQzNiAzLjc5OCAzLjMzMUMzLjc5OCAzLjMzMSA0LjQ3IDMuMTE1IDUuOTk4IDQuMTU0QzYuNjUwNzUgMy45NzU2MSA3LjMyNDMyIDMuODg0ODIgOC4wMDEwMSAzLjg4NEM4LjY3NzcyIDMuODg1MzQgOS4zNTEyNiAzLjk3NjQ3IDEwLjAwNCA0LjE1NUMxMS41MzEgMy4xMTYgMTIuMjAyIDMuMzMyIDEyLjIwMiAzLjMzMkMxMi42MzggNC40MzggMTIuMzY0IDUuMjU0IDEyLjI4MiA1LjQ1N0MxMi43OTUgNi4wMTkgMTMuMTA0IDYuNzM2IDEzLjEwNCA3LjYxM0MxMy4xMDQgMTAuNjk4IDExLjIzNCAxMS4zNzcgOS40NTIgMTEuNTc2QzkuNzM5IDExLjgyNCA5Ljk5NSAxMi4zMTQgOS45OTUgMTMuMDYzQzkuOTk1IDE0LjEzNyA5Ljk4NSAxNS4wMDMgOS45ODUgMTUuMjY2QzkuOTg1IDE1LjQ4MSAxMC4xMjkgMTUuNzMxIDEwLjUzNSAxNS42NTJDMTIuMTI5MiAxNS4xMTQzIDEzLjUxNDQgMTQuMDg5NSAxNC40OTQ5IDEyLjcyMjNDMTUuNDc1NSAxMS4zNTUxIDE2LjAwMTkgOS43MTQ0OCAxNiA4LjAzMkMxNiAzLjU5NiAxMi40MTggMCA3Ljk5OSAwWiIgZmlsbD0iIzhCOEI4QiIvPgo8L2c+CjxkZWZzPgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzEwXzIiPgo8cmVjdCB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIGZpbGw9IndoaXRlIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg==";
|
||||
export const appleIconUri =
|
||||
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDM4IiBoZWlnaHQ9IjI1MDAiIHZpZXdCb3g9IjAgMCA0OTYuMjU1IDYwOC43MjgiIGlkPSJhcHBsZSI+PHBhdGggZmlsbD0iIzk5OSIgZD0iTTI3My44MSA1Mi45NzNDMzEzLjgwNi4yNTcgMzY5LjQxIDAgMzY5LjQxIDBzOC4yNzEgNDkuNTYyLTMxLjQ2MyA5Ny4zMDZjLTQyLjQyNiA1MC45OC05MC42NDkgNDIuNjM4LTkwLjY0OSA0Mi42MzhzLTkuMDU1LTQwLjA5NCAyNi41MTItODYuOTcxek0yNTIuMzg1IDE3NC42NjJjMjAuNTc2IDAgNTguNzY0LTI4LjI4NCAxMDguNDcxLTI4LjI4NCA4NS41NjIgMCAxMTkuMjIyIDYwLjg4MyAxMTkuMjIyIDYwLjg4M3MtNjUuODMzIDMzLjY1OS02NS44MzMgMTE1LjMzMWMwIDkyLjEzMyA4Mi4wMSAxMjMuODg1IDgyLjAxIDEyMy44ODVzLTU3LjMyOCAxNjEuMzU3LTEzNC43NjIgMTYxLjM1N2MtMzUuNTY1IDAtNjMuMjE1LTIzLjk2Ny0xMDAuNjg4LTIzLjk2Ny0zOC4xODggMC03Ni4wODQgMjQuODYxLTEwMC43NjYgMjQuODYxQzg5LjMzIDYwOC43MyAwIDQ1NS42NjYgMCAzMzIuNjI4YzAtMTIxLjA1MiA3NS42MTItMTg0LjU1NCAxNDYuNTMzLTE4NC41NTQgNDYuMTA1IDAgODEuODgzIDI2LjU4OCAxMDUuODUyIDI2LjU4OHoiPjwvcGF0aD48L3N2Zz4=";
|
||||
export const linkedinIconUri =
|
||||
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NCIgaGVpZ2h0PSI0MCIgaWQ9ImxpbmtlZGluIj48cGF0aCBmaWxsPSIjMDA3RUJCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00NCA0MGgtOS43MjVWMjUuOTM4YzAtMy42OC0xLjUyLTYuMTkzLTQuODY2LTYuMTkzLTIuNTU4IDAtMy45ODEgMS42OTYtNC42NDMgMy4zMy0uMjQ5LjU4Ni0uMjEgMS40MDMtLjIxIDIuMjJWNDBoLTkuNjM0cy4xMjQtMjQuOTA5IDAtMjcuMTczaDkuNjM0djQuMjY1Yy41Ny0xLjg2NSAzLjY0OC00LjUyNiA4LjU2LTQuNTI2QzM5LjIxMSAxMi41NjYgNDQgMTYuNDc0IDQ0IDI0Ljg5MVY0MHpNNS4xOCA5LjQyOGgtLjA2M0MyLjAxMyA5LjQyOCAwIDcuMzUxIDAgNC43MTggMCAyLjAzNCAyLjA3MiAwIDUuMjM5IDBjMy4xNjQgMCA1LjExIDIuMDI5IDUuMTcxIDQuNzEgMCAyLjYzMy0yLjAwNyA0LjcxOC01LjIzIDQuNzE4em0tNC4wNyAzLjM5OWg4LjU3NlY0MEgxLjExVjEyLjgyN3oiPjwvcGF0aD48L3N2Zz4=";
|
||||
export const bitbucketIconUri =
|
||||
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgaWQ9ImJpdGJ1Y2tldCI+PHBhdGggZmlsbD0iIzI2ODBGOCIgZD0iTTQuMjk3IDIzaDE1LjY1OWEuNzc2Ljc3NiAwIDAgMCAuNzY5LS42NTdMMjMuOTkgMS45MTZhLjc4Ljc4IDAgMCAwLS42MzUtLjg5NyAxLjEzIDEuMTMgMCAwIDAtLjEzNC0uMDA5TC43NzkgMUEuNzc1Ljc3NSAwIDAgMCAwIDEuNzc1YzAgLjA0NC4wMDUuMDkzLjAwOS4xMzdsMy4yNjUgMjAuMTk2Yy4wODIuNTA5LjUxNS44ODcgMS4wMjMuODkyek0xNS43MzYgOC4zOTFsLTEuMjExIDcuMjA1aC01TDguMTczIDguMzkxaDcuNTYzeiI+PC9wYXRoPjwvc3ZnPg==";
|
||||
export const gitlabIconUri =
|
||||
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNTAwIiBoZWlnaHQ9IjIzMDUiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaW5ZTWluIG1lZXQiIHZpZXdCb3g9IjAgMCAyNTYgMjM2IiBpZD0iZ2l0bGFiIj48cGF0aCBmaWxsPSIjRTI0MzI5IiBkPSJNMTI4LjA3NSAyMzYuMDc1bDQ3LjEwNC0xNDQuOTdIODAuOTdsNDcuMTA0IDE0NC45N3oiPjwvcGF0aD48cGF0aCBmaWxsPSIjRkM2RDI2IiBkPSJNMTI4LjA3NSAyMzYuMDc0TDgwLjk3IDkxLjEwNEgxNC45NTZsMTEzLjExOSAxNDQuOTd6Ij48L3BhdGg+PHBhdGggZmlsbD0iI0ZDQTMyNiIgZD0iTTE0Ljk1NiA5MS4xMDRMLjY0MiAxMzUuMTZhOS43NTIgOS43NTIgMCAwIDAgMy41NDIgMTAuOTAzbDEyMy44OTEgOTAuMDEyLTExMy4xMi0xNDQuOTd6Ij48L3BhdGg+PHBhdGggZmlsbD0iI0UyNDMyOSIgZD0iTTE0Ljk1NiA5MS4xMDVIODAuOTdMNTIuNjAxIDMuNzljLTEuNDYtNC40OTMtNy44MTYtNC40OTItOS4yNzUgMGwtMjguMzcgODcuMzE1eiI+PC9wYXRoPjxwYXRoIGZpbGw9IiNGQzZEMjYiIGQ9Ik0xMjguMDc1IDIzNi4wNzRsNDcuMTA0LTE0NC45N2g2Ni4wMTVsLTExMy4xMiAxNDQuOTd6Ij48L3BhdGg+PHBhdGggZmlsbD0iI0ZDQTMyNiIgZD0iTTI0MS4xOTQgOTEuMTA0bDE0LjMxNCA0NC4wNTZhOS43NTIgOS43NTIgMCAwIDEtMy41NDMgMTAuOTAzbC0xMjMuODkgOTAuMDEyIDExMy4xMTktMTQ0Ljk3eiI+PC9wYXRoPjxwYXRoIGZpbGw9IiNFMjQzMjkiIGQ9Ik0yNDEuMTk0IDkxLjEwNWgtNjYuMDE1bDI4LjM3LTg3LjMxNWMxLjQ2LTQuNDkzIDcuODE2LTQuNDkyIDkuMjc1IDBsMjguMzcgODcuMzE1eiI+PC9wYXRoPjwvc3ZnPg==";
|
||||
export const twitchIconUri =
|
||||
"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgdmlld0JveD0iMCAwIDExMS43ODY2NyAxMjcuMzg2NjciCiAgIGhlaWdodD0iMTI3LjM4NjY3IgogICB3aWR0aD0iMTExLjc4NjY3IgogICB4bWw6c3BhY2U9InByZXNlcnZlIgogICB2ZXJzaW9uPSIxLjEiCiAgIGlkPSJzdmczMzU1IgogICBzb2RpcG9kaTpkb2NuYW1lPSJUd2l0Y2hfbG9nby5zdmciCiAgIGlua3NjYXBlOnZlcnNpb249IjEuMS4xICgzYmY1YWUwZDI1LCAyMDIxLTA5LTIwKSIKICAgeG1sbnM6aW5rc2NhcGU9Imh0dHA6Ly93d3cuaW5rc2NhcGUub3JnL25hbWVzcGFjZXMvaW5rc2NhcGUiCiAgIHhtbG5zOnNvZGlwb2RpPSJodHRwOi8vc29kaXBvZGkuc291cmNlZm9yZ2UubmV0L0RURC9zb2RpcG9kaS0wLmR0ZCIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZGVmcwogICBpZD0iZGVmczI5Ij4KICAgIAogICAgCiAgPC9kZWZzPjxzb2RpcG9kaTpuYW1lZHZpZXcKICAgaWQ9Im5hbWVkdmlldzI3IgogICBwYWdlY29sb3I9IiNmZmZmZmYiCiAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICBib3JkZXJvcGFjaXR5PSIxLjAiCiAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwLjAiCiAgIGlua3NjYXBlOnBhZ2VjaGVja2VyYm9hcmQ9IjAiCiAgIHNob3dncmlkPSJmYWxzZSIKICAgaW5rc2NhcGU6em9vbT0iNC4xOTkyMjg0IgogICBpbmtzY2FwZTpjeD0iLTUwLjYwNDUzNSIKICAgaW5rc2NhcGU6Y3k9IjE0MC4zODI5MyIKICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIyNTYwIgogICBpbmtzY2FwZTp3aW5kb3ctaGVpZ2h0PSIxMzg3IgogICBpbmtzY2FwZTp3aW5kb3cteD0iMTkxMiIKICAgaW5rc2NhcGU6d2luZG93LXk9Ii04IgogICBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIxIgogICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJzdmczMzU1IiAvPgogIDxnCiAgIHRyYW5zZm9ybT0ibWF0cml4KDEuMzMzMzMzMywwLDAsLTEuMzMzMzMzMywxMDEuMzkzMzMsNjcuNTg5MzMyKSIKICAgaWQ9ImczMzY1Ij4KICAgICAgPHBhdGgKICAgaWQ9InBhdGgzMzY3IgogICBzdHlsZT0iZmlsbDojNjQ0MWE1O2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpldmVub2RkO3N0cm9rZTpub25lIgogICBkPSJtIDAsMCAtMTMuNjUyLC0xMy42NTEgaCAtMjEuNDQ1IGwgLTExLjY5OSwtMTEuNjk3IHYgMTEuNjk3IEggLTY0LjM0NCBWIDQyLjg5MyBIIDAgWiBtIC03Mi4xNDYsNTAuNjkyIC0zLjg5OSwtMTUuNTk5IHYgLTcwLjE5IGggMTcuNTUgdiAtOS43NTEgaCA5Ljc0NiBsIDkuNzUyLDkuNzUxIGggMTUuNTk2IEwgNy43OTUsLTMuOTA1IHYgNTQuNTk3IHoiIC8+CiAgICA8L2c+PHBhdGgKICAgaWQ9InBhdGgzMzY5IgogICBzdHlsZT0iZmlsbDojNjQ0MWE1O2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpldmVub2RkO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDoxLjMzMzMzIgogICBkPSJtIDQ0LjE5NzMzMSw2Mi4zOTQyNjYgaCAxMC4zOTg2NyBWIDMxLjE5MjkzMyBoIC0xMC4zOTg2NyB6IG0gMjguNTk0NjcsMCBoIDEwLjM5ODY2IFYgMzEuMTkyOTMzIGggLTEwLjM5ODY2IHoiIC8+Cjwvc3ZnPgo=";
|
||||
export const discordIconUri =
|
||||
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDEwMCAxMDAiIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBpZD0iZGlzY29yZCI+PHBhdGggZmlsbD0iIzY2NjVkMiIgZD0iTTg1LjIyLDI0Ljk1OGMtMTEuNDU5LTguNTc1LTIyLjQzOC04LjMzNC0yMi40MzgtOC4zMzRsLTEuMTIyLDEuMjgyCgkJCQljMTMuNjIzLDQuMDg3LDE5Ljk1NCwxMC4wOTcsMTkuOTU0LDEwLjA5N2MtMTkuNDkxLTEwLjczMS00NC4zMTctMTAuNjU0LTY0LjU5LDBjMCwwLDYuNTcxLTYuMzMxLDIwLjk5Ni0xMC40MThsLTAuODAxLTAuOTYyCgkJCQljMCwwLTEwLjg5OS0wLjI0LTIyLjQzOCw4LjMzNGMwLDAtMTEuNTQsMjAuNzU1LTExLjU0LDQ2LjMxOWMwLDAsNi43MzIsMTEuNTQsMjQuNDQyLDEyLjEwMWMwLDAsMi45NjUtMy41MjYsNS4zNjktNi41NzEKCQkJCWMtMTAuMTc3LTMuMDQ1LTE0LjAyNC05LjM3Ni0xNC4wMjQtOS4zNzZjNi4zOTQsNC4wMDEsMTIuODU5LDYuNTA1LDIwLjkxNiw4LjA5NGMxMy4xMDgsMi42OTgsMjkuNDEzLTAuMDc2LDQxLjU5MS04LjA5NAoJCQkJYzAsMC00LjAwNyw2LjQ5MS0xNC41MDUsOS40NTZjMi40MDQsMi45NjUsNS4yODksNi40MTEsNS4yODksNi40MTFjMTcuNzEtMC41NjEsMjQuNDQxLTEyLjEwMSwyNC40NDEtMTIuMDIKCQkJCUM5Ni43NTksNDUuNzEzLDg1LjIyLDI0Ljk1OCw4NS4yMiwyNC45NTh6IE0zNS4wNTUsNjMuODI0Yy00LjQ4OCwwLTguMTc0LTMuOTI3LTguMTc0LTguODE1CgkJCQljMC4zMjgtMTEuNzA3LDE2LjEwMi0xMS42NzEsMTYuMzQ4LDBDNDMuMjI5LDU5Ljg5NywzOS42MjIsNjMuODI0LDM1LjA1NSw2My44MjR6IE02NC4zMDQsNjMuODI0CgkJCQljLTQuNDg4LDAtOC4xNzQtMy45MjctOC4xNzQtOC44MTVjMC4zNi0xMS42ODQsMTUuOTM3LTExLjY4OSwxNi4zNDgsMEM3Mi40NzgsNTkuODk3LDY4Ljg3Miw2My44MjQsNjQuMzA0LDYzLjgyNHoiPjwvcGF0aD48L3N2Zz4=";
|
||||
export const microsoftIconUri =
|
||||
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciICB2aWV3Qm94PSIwIDAgNDggNDgiIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiPjxwYXRoIGZpbGw9IiNmZjU3MjIiIGQ9Ik02IDZIMjJWMjJINnoiIHRyYW5zZm9ybT0icm90YXRlKC0xODAgMTQgMTQpIi8+PHBhdGggZmlsbD0iIzRjYWY1MCIgZD0iTTI2IDZINDJWMjJIMjZ6IiB0cmFuc2Zvcm09InJvdGF0ZSgtMTgwIDM0IDE0KSIvPjxwYXRoIGZpbGw9IiNmZmMxMDciIGQ9Ik0yNiAyNkg0MlY0MkgyNnoiIHRyYW5zZm9ybT0icm90YXRlKC0xODAgMzQgMzQpIi8+PHBhdGggZmlsbD0iIzAzYTlmNCIgZD0iTTYgMjZIMjJWNDJINnoiIHRyYW5zZm9ybT0icm90YXRlKC0xODAgMTQgMzQpIi8+PC9zdmc+";
|
||||
+30
-6
@@ -1,9 +1,32 @@
|
||||
import { EmbeddedWalletOauthStrategy } from "@thirdweb-dev/wallets";
|
||||
import { Theme } from "../../design-system";
|
||||
|
||||
export function openGoogleSignInWindow(themeObj: Theme) {
|
||||
function getBodyTitle(authOption: EmbeddedWalletOauthStrategy) {
|
||||
switch (authOption) {
|
||||
case "google":
|
||||
return "Sign In - Google Accounts";
|
||||
default:
|
||||
return `Sign In - ${authOption
|
||||
.slice(0, 1)
|
||||
.toUpperCase()}${authOption.slice(1)}`;
|
||||
}
|
||||
}
|
||||
|
||||
function getWidthAndHeight(authOption: EmbeddedWalletOauthStrategy) {
|
||||
switch (authOption) {
|
||||
// case "facebook":
|
||||
// return { width: 715, height: 555 };
|
||||
default:
|
||||
return { width: 350, height: 500 };
|
||||
}
|
||||
}
|
||||
|
||||
export function openOauthSignInWindow(
|
||||
authOption: EmbeddedWalletOauthStrategy,
|
||||
themeObj: Theme,
|
||||
) {
|
||||
// open the popup in the center of the screen
|
||||
const width = 350;
|
||||
const height = 500;
|
||||
const { height, width } = getWidthAndHeight(authOption);
|
||||
const top = (window.innerHeight - height) / 2;
|
||||
const left = (window.innerWidth - width) / 2;
|
||||
|
||||
@@ -13,7 +36,8 @@ export function openGoogleSignInWindow(themeObj: Theme) {
|
||||
`width=${width}, height=${height}, top=${top}, left=${left}`,
|
||||
);
|
||||
if (win) {
|
||||
win.document.title = "Sign In - Google Accounts";
|
||||
const title = getBodyTitle(authOption);
|
||||
win.document.title = title;
|
||||
win.document.body.innerHTML = spinnerWindowHtml;
|
||||
win.document.body.style.background = themeObj.colors.modalBg;
|
||||
win.document.body.style.color = themeObj.colors.accentText;
|
||||
@@ -56,8 +80,8 @@ const spinnerWindowHtml = `
|
||||
}
|
||||
|
||||
.loader {
|
||||
width: 15vw;
|
||||
height: 15vw;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import { useEffect, useRef } from "react";
|
||||
type CoinbaseWalletOptions = {
|
||||
/**
|
||||
* Whether to use the Coinbase's default QR Code modal or show the custom UI in ConnectWallet Modal
|
||||
* @default "custom"
|
||||
* @defaultValue "custom"
|
||||
*/
|
||||
qrmodal?: "coinbase" | "custom";
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useTheme } from "@emotion/react";
|
||||
import styled from "@emotion/styled";
|
||||
import {
|
||||
WalletConfig,
|
||||
@@ -5,23 +6,27 @@ import {
|
||||
useSetConnectedWallet,
|
||||
useSetConnectionStatus,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { EmbeddedWallet } from "@thirdweb-dev/wallets";
|
||||
import {
|
||||
EmbeddedWallet,
|
||||
EmbeddedWalletOauthStrategy,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
import { Img } from "../../../components/Img";
|
||||
import { Spacer } from "../../../components/Spacer";
|
||||
import { TextDivider } from "../../../components/TextDivider";
|
||||
import { Container, ModalHeader } from "../../../components/basic";
|
||||
import { Button } from "../../../components/buttons";
|
||||
import { Theme, iconSize, spacing } from "../../../design-system";
|
||||
import { GoogleIcon } from "../../ConnectWallet/icons/GoogleIcon";
|
||||
import { InputSelectionUI } from "../InputSelectionUI";
|
||||
import type { EmbeddedWalletLoginType, AuthOption } from "./types";
|
||||
import { TextDivider } from "../../../components/TextDivider";
|
||||
import { openGoogleSignInWindow } from "../../utils/openGoogleSignInWindow";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { Theme, fontSize, iconSize, spacing } from "../../../design-system";
|
||||
import { useTWLocale } from "../../../evm/providers/locale-provider";
|
||||
import { openOauthSignInWindow } from "../../utils/openOauthSignInWindow";
|
||||
import { InputSelectionUI } from "../InputSelectionUI";
|
||||
import { socialIcons } from "./socialIcons";
|
||||
import type { AuthOption, EmbeddedWalletLoginType } from "./types";
|
||||
|
||||
export const EmbeddedWalletFormUI = (props: {
|
||||
onSelect: (loginType: EmbeddedWalletLoginType) => void;
|
||||
walletConfig: WalletConfig<EmbeddedWallet>;
|
||||
authOptions: AuthOption[];
|
||||
modalSize?: "compact" | "wide";
|
||||
}) => {
|
||||
const twLocale = useTWLocale();
|
||||
const locale = twLocale.wallets.embeddedWallet;
|
||||
@@ -30,22 +35,33 @@ export const EmbeddedWalletFormUI = (props: {
|
||||
const setConnectedWallet = useSetConnectedWallet();
|
||||
const themeObj = useTheme() as Theme;
|
||||
|
||||
const enableGoogleLogin = props.authOptions.includes("google");
|
||||
const loginMethodsLabel: Record<EmbeddedWalletOauthStrategy, string> = {
|
||||
google: locale.signInWithGoogle,
|
||||
// facebook: locale.signInWithFacebook,
|
||||
apple: locale.signInWithApple,
|
||||
};
|
||||
|
||||
const enableEmailLogin = props.authOptions.includes("email");
|
||||
|
||||
// Need to trigger google login on button click to avoid popup from being blocked
|
||||
const googleLogin = async () => {
|
||||
const socialLogins = props.authOptions.filter(
|
||||
(x) => x !== "email",
|
||||
) as EmbeddedWalletOauthStrategy[];
|
||||
|
||||
const hasSocialLogins = socialLogins.length > 0;
|
||||
|
||||
// Need to trigger login on button click to avoid popup from being blocked
|
||||
const socialLogin = async (strategy: EmbeddedWalletOauthStrategy) => {
|
||||
try {
|
||||
const embeddedWallet = createWalletInstance(props.walletConfig);
|
||||
setConnectionStatus("connecting");
|
||||
|
||||
const googleWindow = openGoogleSignInWindow(themeObj);
|
||||
if (!googleWindow) {
|
||||
throw new Error("Failed to open google login window");
|
||||
const socialLoginWindow = openOauthSignInWindow(strategy, themeObj);
|
||||
if (!socialLoginWindow) {
|
||||
throw new Error("Failed to open login window");
|
||||
}
|
||||
const authResult = await embeddedWallet.authenticate({
|
||||
strategy: "google",
|
||||
openedWindow: googleWindow,
|
||||
strategy: strategy,
|
||||
openedWindow: socialLoginWindow,
|
||||
closeOpenedWindow: (openedWindow) => {
|
||||
openedWindow.close();
|
||||
},
|
||||
@@ -60,26 +76,44 @@ export const EmbeddedWalletFormUI = (props: {
|
||||
}
|
||||
};
|
||||
|
||||
const showOnlyIcons = socialLogins.length > 2;
|
||||
|
||||
return (
|
||||
<div>
|
||||
{enableGoogleLogin && (
|
||||
<>
|
||||
<SocialButton
|
||||
variant="secondary"
|
||||
fullWidth
|
||||
onClick={() => {
|
||||
googleLogin();
|
||||
props.onSelect({ google: true });
|
||||
}}
|
||||
>
|
||||
<GoogleIcon size={iconSize.md} />
|
||||
{locale.signInWithGoogle}
|
||||
</SocialButton>
|
||||
</>
|
||||
<Container flex="column" gap="lg">
|
||||
{/* Social Login */}
|
||||
{hasSocialLogins && (
|
||||
<Container flex={showOnlyIcons ? "row" : "column"} center="x" gap="sm">
|
||||
{socialLogins.map((loginMethod) => {
|
||||
const imgIconSize = showOnlyIcons ? iconSize.lg : iconSize.md;
|
||||
return (
|
||||
<SocialButton
|
||||
aria-label={`Login with ${loginMethod}`}
|
||||
data-variant={showOnlyIcons ? "icon" : "full"}
|
||||
key={loginMethod}
|
||||
variant={showOnlyIcons ? "outline" : "secondary"}
|
||||
fullWidth={!showOnlyIcons}
|
||||
onClick={() => {
|
||||
socialLogin(loginMethod);
|
||||
props.onSelect(loginMethod);
|
||||
}}
|
||||
>
|
||||
<Img
|
||||
src={socialIcons[loginMethod]}
|
||||
width={imgIconSize}
|
||||
height={imgIconSize}
|
||||
/>
|
||||
{!showOnlyIcons && loginMethodsLabel[loginMethod]}
|
||||
</SocialButton>
|
||||
);
|
||||
})}
|
||||
</Container>
|
||||
)}
|
||||
{enableGoogleLogin && enableEmailLogin && (
|
||||
<TextDivider text={twLocale.connectWallet.or} py="lg" />
|
||||
|
||||
{props.modalSize === "wide" && hasSocialLogins && enableEmailLogin && (
|
||||
<TextDivider text={twLocale.connectWallet.or} />
|
||||
)}
|
||||
|
||||
{/* Email Login */}
|
||||
{enableEmailLogin && (
|
||||
<InputSelectionUI
|
||||
onSelect={(email) => props.onSelect({ email })}
|
||||
@@ -99,7 +133,7 @@ export const EmbeddedWalletFormUI = (props: {
|
||||
submitButtonText={locale.submitEmail}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -132,6 +166,7 @@ export const EmbeddedWalletFormUIScreen: React.FC<{
|
||||
p={isCompact ? undefined : "lg"}
|
||||
>
|
||||
<EmbeddedWalletFormUI
|
||||
modalSize={props.modalSize}
|
||||
authOptions={props.authOptions}
|
||||
walletConfig={props.walletConfig}
|
||||
onSelect={props.onSelect}
|
||||
@@ -142,7 +177,18 @@ export const EmbeddedWalletFormUIScreen: React.FC<{
|
||||
};
|
||||
|
||||
const SocialButton = /* @__PURE__ */ styled(Button)<{ theme?: Theme }>`
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: ${spacing.sm};
|
||||
&[data-variant="full"] {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
gap: ${spacing.md};
|
||||
font-size: ${fontSize.md};
|
||||
transition: background-color 0.2s ease;
|
||||
&:active {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
&[data-variant="icon"] {
|
||||
padding: ${spacing.sm};
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useTheme } from "@emotion/react";
|
||||
import {
|
||||
ConnectUIProps,
|
||||
useConnectionStatus,
|
||||
@@ -5,24 +6,26 @@ import {
|
||||
useSetConnectedWallet,
|
||||
useSetConnectionStatus,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { EmbeddedWallet } from "@thirdweb-dev/wallets";
|
||||
import {
|
||||
EmbeddedWallet,
|
||||
EmbeddedWalletOauthStrategy,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
import { useEffect } from "react";
|
||||
import { Spacer } from "../../../components/Spacer";
|
||||
import { Spinner } from "../../../components/Spinner";
|
||||
import { Container, ModalHeader } from "../../../components/basic";
|
||||
import { Button } from "../../../components/buttons";
|
||||
import { ModalTitle } from "../../../components/modalElements";
|
||||
import { Text } from "../../../components/text";
|
||||
import { Theme, iconSize } from "../../../design-system";
|
||||
import { GoogleIcon } from "../../ConnectWallet/icons/GoogleIcon";
|
||||
import { openGoogleSignInWindow } from "../../utils/openGoogleSignInWindow";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { Theme } from "../../../design-system";
|
||||
import { useTWLocale } from "../../../evm/providers/locale-provider";
|
||||
import { openOauthSignInWindow } from "../../utils/openOauthSignInWindow";
|
||||
|
||||
export const EmbeddedWalletGoogleLogin = (
|
||||
props: ConnectUIProps<EmbeddedWallet>,
|
||||
export const EmbeddedWalletSocialLogin = (
|
||||
props: ConnectUIProps<EmbeddedWallet> & {
|
||||
strategy: EmbeddedWalletOauthStrategy;
|
||||
},
|
||||
) => {
|
||||
const locale = useTWLocale().wallets.embeddedWallet.googleLoginScreen;
|
||||
const locale = useTWLocale().wallets.embeddedWallet.socialLoginScreen;
|
||||
const { goBack, modalSize } = props;
|
||||
const createWalletInstance = useCreateWalletInstance();
|
||||
const setConnectionStatus = useSetConnectionStatus();
|
||||
@@ -34,7 +37,7 @@ export const EmbeddedWalletGoogleLogin = (
|
||||
try {
|
||||
const embeddedWallet = createWalletInstance(props.walletConfig);
|
||||
setConnectionStatus("connecting");
|
||||
const googleWindow = openGoogleSignInWindow(themeObj);
|
||||
const googleWindow = openOauthSignInWindow("google", themeObj);
|
||||
if (!googleWindow) {
|
||||
throw new Error("Failed to open google login window");
|
||||
}
|
||||
@@ -74,15 +77,7 @@ export const EmbeddedWalletGoogleLogin = (
|
||||
paddingBottom: 0,
|
||||
}}
|
||||
>
|
||||
<ModalHeader
|
||||
title={
|
||||
<Container flex="row" center="both" gap="xs">
|
||||
<GoogleIcon size={iconSize.md} />
|
||||
<ModalTitle> {locale.title} </ModalTitle>
|
||||
</Container>
|
||||
}
|
||||
onBack={goBack}
|
||||
/>
|
||||
<ModalHeader title={locale.title} onBack={goBack} />
|
||||
|
||||
{modalSize === "compact" ? <Spacer y="xl" /> : null}
|
||||
|
||||
|
||||
@@ -10,16 +10,24 @@ import { useScreenContext } from "../../ConnectWallet/Modal/screen";
|
||||
import { WalletEntryButton } from "../../ConnectWallet/WalletSelector";
|
||||
import { reservedScreens } from "../../ConnectWallet/constants";
|
||||
import { emailIcon } from "../../ConnectWallet/icons/dataUris";
|
||||
import { PaperLoginType } from "../paper/types";
|
||||
import {
|
||||
EmbeddedWalletFormUI,
|
||||
EmbeddedWalletFormUIScreen,
|
||||
} from "./EmbeddedWalletFormUI";
|
||||
import { EmbeddedWalletGoogleLogin } from "./EmbeddedWalletGoogleLogin";
|
||||
import { EmbeddedWalletSocialLogin } from "./EmbeddedWalletGoogleLogin";
|
||||
import { EmbeddedWalletOTPLoginUI } from "./EmbeddedWalletOTPLoginUI";
|
||||
import { EmbeddedWalletConfig, AuthOption } from "./types";
|
||||
import {
|
||||
AuthOption,
|
||||
EmbeddedWalletConfig,
|
||||
EmbeddedWalletLoginType,
|
||||
} from "./types";
|
||||
|
||||
const DEFAULT_AUTH_OPTIONS: AuthOption[] = ["email", "google"];
|
||||
const DEFAULT_AUTH_OPTIONS: AuthOption[] = [
|
||||
"email",
|
||||
"google",
|
||||
"apple",
|
||||
// "facebook",
|
||||
];
|
||||
|
||||
export const embeddedWallet = (
|
||||
_config?: EmbeddedWalletConfig,
|
||||
@@ -112,9 +120,9 @@ const EmbeddedWalletConnectUI = (
|
||||
authOptions: AuthOption[];
|
||||
},
|
||||
) => {
|
||||
const [loginType, setLoginType] = useState<PaperLoginType | undefined>(
|
||||
props.selectionData as PaperLoginType,
|
||||
);
|
||||
const [loginType, setLoginType] = useState<
|
||||
EmbeddedWalletLoginType | undefined
|
||||
>(props.selectionData as EmbeddedWalletLoginType);
|
||||
|
||||
if (loginType) {
|
||||
const handleBack = () => {
|
||||
@@ -129,7 +137,7 @@ const EmbeddedWalletConnectUI = (
|
||||
}
|
||||
};
|
||||
|
||||
if ("email" in loginType) {
|
||||
if (typeof loginType !== "string") {
|
||||
return (
|
||||
<EmbeddedWalletOTPLoginUI
|
||||
{...props}
|
||||
@@ -139,20 +147,19 @@ const EmbeddedWalletConnectUI = (
|
||||
);
|
||||
}
|
||||
|
||||
// google
|
||||
else if (props.authOptions?.includes("google")) {
|
||||
return <EmbeddedWalletGoogleLogin {...props} goBack={handleBack} />;
|
||||
}
|
||||
|
||||
return null;
|
||||
return (
|
||||
<EmbeddedWalletSocialLogin
|
||||
{...props}
|
||||
goBack={handleBack}
|
||||
strategy={loginType}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<EmbeddedWalletFormUIScreen
|
||||
modalSize={props.modalSize}
|
||||
onSelect={(_loginType) => {
|
||||
setLoginType(_loginType);
|
||||
}}
|
||||
onSelect={setLoginType}
|
||||
walletConfig={props.walletConfig}
|
||||
onBack={props.goBack}
|
||||
authOptions={props.authOptions}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { EmbeddedWalletOauthStrategy } from "@thirdweb-dev/wallets";
|
||||
import {
|
||||
appleIconUri,
|
||||
googleIconUri,
|
||||
} from "../../ConnectWallet/icons/socialLogins";
|
||||
|
||||
export const socialIcons: Record<EmbeddedWalletOauthStrategy, string> = {
|
||||
google: googleIconUri,
|
||||
apple: appleIconUri,
|
||||
// facebook: facebookIconUri,
|
||||
};
|
||||
@@ -1,6 +1,9 @@
|
||||
import type { EmbeddedWalletAdditionalOptions } from "@thirdweb-dev/wallets";
|
||||
import type {
|
||||
EmbeddedWalletAdditionalOptions,
|
||||
EmbeddedWalletOauthStrategy,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
|
||||
export type AuthOption = "google" | "email";
|
||||
export type AuthOption = EmbeddedWalletOauthStrategy | "email";
|
||||
|
||||
export type EmbeddedWalletConfig = Omit<
|
||||
EmbeddedWalletAdditionalOptions,
|
||||
@@ -13,11 +16,13 @@ export type EmbeddedWalletConfig = Omit<
|
||||
|
||||
/**
|
||||
* Choose which auth providers to show in the wallet connection UI
|
||||
* @default { providers: ["email", "google"] }
|
||||
* @defaultValue `auth: { options: ["email", "google", "apple"] }`
|
||||
*/
|
||||
auth?: {
|
||||
options: AuthOption[];
|
||||
};
|
||||
};
|
||||
|
||||
export type EmbeddedWalletLoginType = { email: string } | { google: true };
|
||||
export type EmbeddedWalletLoginType =
|
||||
| { email: string }
|
||||
| EmbeddedWalletOauthStrategy;
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
} from "@radix-ui/react-icons";
|
||||
import { FormFieldWithIconButton } from "../../../components/formFields";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { shortenAddress } from "../../../evm/utils/addresses";
|
||||
import { LocalWallet } from "@thirdweb-dev/wallets";
|
||||
import type { WalletData } from "@thirdweb-dev/wallets/evm/wallets/local-wallet";
|
||||
import { Spinner } from "../../../components/Spinner";
|
||||
@@ -23,6 +22,7 @@ import {
|
||||
ScreenBottomContainer,
|
||||
} from "../../../components/basic";
|
||||
import {
|
||||
shortenAddress,
|
||||
useAddress,
|
||||
useCreateWalletInstance,
|
||||
useWallet,
|
||||
|
||||
@@ -2,12 +2,15 @@ import { Spacer } from "../../../components/Spacer";
|
||||
import { Button } from "../../../components/buttons";
|
||||
import { FormFieldWithIconButton } from "../../../components/formFields";
|
||||
import { EyeClosedIcon, EyeOpenIcon } from "@radix-ui/react-icons";
|
||||
import { WalletConfig, useWalletContext } from "@thirdweb-dev/react-core";
|
||||
import {
|
||||
WalletConfig,
|
||||
shortenAddress,
|
||||
useWalletContext,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { useState } from "react";
|
||||
import { Label } from "../../../components/formElements";
|
||||
import { spacing } from "../../../design-system";
|
||||
import { Spinner } from "../../../components/Spinner";
|
||||
import { shortenAddress } from "../../../evm/utils/addresses";
|
||||
import { Text } from "../../../components/text";
|
||||
import { CreateLocalWallet_Password } from "./CreateLocalWallet";
|
||||
import { OverrideConfirmation } from "./overrideConfirmation";
|
||||
|
||||
@@ -9,7 +9,7 @@ export type LocalWalletConfigOptions = {
|
||||
* If `false`, wallet will not be stored, and no password will be required to connect.
|
||||
* the wallet will be lost when the user leaves or reloads the page.
|
||||
*
|
||||
* @default true
|
||||
* @defaultValue true
|
||||
*/
|
||||
persist?: boolean;
|
||||
};
|
||||
|
||||
@@ -27,6 +27,19 @@ import { useScreenContext } from "../../ConnectWallet/Modal/screen";
|
||||
import { reservedScreens } from "../../ConnectWallet/constants";
|
||||
import { Spacer } from "../../../components/Spacer";
|
||||
import { useTWLocale } from "../../../evm/providers/locale-provider";
|
||||
import {
|
||||
appleIconUri,
|
||||
bitbucketIconUri,
|
||||
discordIconUri,
|
||||
facebookIconUri,
|
||||
githubIconUri,
|
||||
gitlabIconUri,
|
||||
googleIconUri,
|
||||
linkedinIconUri,
|
||||
microsoftIconUri,
|
||||
twitchIconUri,
|
||||
twitterIconUri,
|
||||
} from "../../ConnectWallet/icons/socialLogins";
|
||||
|
||||
export function magicLink(
|
||||
config: MagicLinkAdditionalOptions & {
|
||||
@@ -220,14 +233,14 @@ const MagicUI: React.FC<{
|
||||
)}`}
|
||||
sideOffset={15}
|
||||
>
|
||||
<div>
|
||||
<Container flex="row" center="both">
|
||||
<Img
|
||||
src={providerImages[provider]}
|
||||
width={iconSize.lg}
|
||||
height={iconSize.lg}
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
</Container>
|
||||
</ToolTip>
|
||||
</SocialIconButton>
|
||||
);
|
||||
@@ -477,28 +490,17 @@ const MagicConnectionUIScreen: React.FC<
|
||||
};
|
||||
|
||||
const providerImages: Record<OauthProvider, string> = {
|
||||
google:
|
||||
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDUuNiIgaGVpZ2h0PSI3MjAiIHZpZXdCb3g9IjAgMCAxODYuNjkgMTkwLjUiIHhtbG5zOnY9Imh0dHBzOi8vdmVjdGEuaW8vbmFubyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTE4NC41ODMgNzY1LjE3MSkiPjxwYXRoIGNsaXAtcGF0aD0ibm9uZSIgbWFzaz0ibm9uZSIgZD0iTS0xMDg5LjMzMy02ODcuMjM5djM2Ljg4OGg1MS4yNjJjLTIuMjUxIDExLjg2My05LjAwNiAyMS45MDgtMTkuMTM3IDI4LjY2MmwzMC45MTMgMjMuOTg2YzE4LjAxMS0xNi42MjUgMjguNDAyLTQxLjA0NCAyOC40MDItNzAuMDUyIDAtNi43NTQtLjYwNi0xMy4yNDktMS43MzItMTkuNDgzeiIgZmlsbD0iIzQyODVmNCIvPjxwYXRoIGNsaXAtcGF0aD0ibm9uZSIgbWFzaz0ibm9uZSIgZD0iTS0xMTQyLjcxNC02NTEuNzkxbC02Ljk3MiA1LjMzNy0yNC42NzkgMTkuMjIzaDBjMTUuNjczIDMxLjA4NiA0Ny43OTYgNTIuNTYxIDg1LjAzIDUyLjU2MSAyNS43MTcgMCA0Ny4yNzgtOC40ODYgNjMuMDM4LTIzLjAzM2wtMzAuOTEzLTIzLjk4NmMtOC40ODYgNS43MTUtMTkuMzEgOS4xNzktMzIuMTI1IDkuMTc5LTI0Ljc2NSAwLTQ1LjgwNi0xNi43MTItNTMuMzQtMzkuMjI2eiIgZmlsbD0iIzM0YTg1MyIvPjxwYXRoIGNsaXAtcGF0aD0ibm9uZSIgbWFzaz0ibm9uZSIgZD0iTS0xMTc0LjM2NS03MTIuNjFjLTYuNDk0IDEyLjgxNS0xMC4yMTcgMjcuMjc2LTEwLjIxNyA0Mi42ODlzMy43MjMgMjkuODc0IDEwLjIxNyA0Mi42ODljMCAuMDg2IDMxLjY5My0yNC41OTIgMzEuNjkzLTI0LjU5Mi0xLjkwNS01LjcxNS0zLjAzMS0xMS43NzYtMy4wMzEtMTguMDk4czEuMTI2LTEyLjM4MyAzLjAzMS0xOC4wOTh6IiBmaWxsPSIjZmJiYzA1Ii8+PHBhdGggZD0iTS0xMDg5LjMzMy03MjcuMjQ0YzE0LjAyOCAwIDI2LjQ5NyA0Ljg0OSAzNi40NTUgMTQuMjAxbDI3LjI3Ni0yNy4yNzZjLTE2LjUzOS0xNS40MTMtMzguMDEzLTI0Ljg1Mi02My43MzEtMjQuODUyLTM3LjIzNCAwLTY5LjM1OSAyMS4zODgtODUuMDMyIDUyLjU2MWwzMS42OTIgMjQuNTkyYzcuNTMzLTIyLjUxNCAyOC41NzUtMzkuMjI2IDUzLjM0LTM5LjIyNnoiIGZpbGw9IiNlYTQzMzUiIGNsaXAtcGF0aD0ibm9uZSIgbWFzaz0ibm9uZSIvPjwvZz48L3N2Zz4=",
|
||||
facebook:
|
||||
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGRhdGEtbmFtZT0iRWJlbmUgMSIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgaWQ9ImZhY2Vib29rLWxvZ28tMjAxOSI+PHBhdGggZmlsbD0iIzE4NzdmMiIgZD0iTTEwMjQsNTEyQzEwMjQsMjI5LjIzMDE2LDc5NC43Njk3OCwwLDUxMiwwUzAsMjI5LjIzMDE2LDAsNTEyYzAsMjU1LjU1NCwxODcuMjMxLDQ2Ny4zNzAxMiw0MzIsNTA1Ljc3Nzc3VjY2MEgzMDJWNTEySDQzMlYzOTkuMkM0MzIsMjcwLjg3OTgyLDUwOC40Mzg1NCwyMDAsNjI1LjM4OTIyLDIwMCw2ODEuNDA3NjUsMjAwLDc0MCwyMTAsNzQwLDIxMFYzMzZINjc1LjQzNzEzQzYxMS44MzUwOCwzMzYsNTkyLDM3NS40NjY2Nyw1OTIsNDE1Ljk1NzI4VjUxMkg3MzRMNzExLjMsNjYwSDU5MnYzNTcuNzc3NzdDODM2Ljc2OSw5NzkuMzcwMTIsMTAyNCw3NjcuNTU0LDEwMjQsNTEyWiI+PC9wYXRoPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik03MTEuMyw2NjAsNzM0LDUxMkg1OTJWNDE1Ljk1NzI4QzU5MiwzNzUuNDY2NjcsNjExLjgzNTA4LDMzNiw2NzUuNDM3MTMsMzM2SDc0MFYyMTBzLTU4LjU5MjM1LTEwLTExNC42MTA3OC0xMEM1MDguNDM4NTQsMjAwLDQzMiwyNzAuODc5ODIsNDMyLDM5OS4yVjUxMkgzMDJWNjYwSDQzMnYzNTcuNzc3NzdhNTE3LjM5NjE5LDUxNy4zOTYxOSwwLDAsMCwxNjAsMFY2NjBaIj48L3BhdGg+PC9zdmc+",
|
||||
twitter:
|
||||
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAxNiIgaWQ9InR3aXR0ZXIiPjxwYXRoIGZpbGw9IiMwM0E5RjQiIGQ9Ik0xNiAzLjUzOWE2LjgzOSA2LjgzOSAwIDAgMS0xLjg5LjUxOCAzLjI2MiAzLjI2MiAwIDAgMCAxLjQ0My0xLjgxMyA2LjU1NSA2LjU1NSAwIDAgMS0yLjA4Ljc5NCAzLjI4IDMuMjggMCAwIDAtNS42NzQgMi4yNDNjMCAuMjYuMDIyLjUxLjA3Ni43NDhhOS4yODQgOS4yODQgMCAwIDEtNi43NjEtMy40MzEgMy4yODUgMy4yODUgMCAwIDAgMS4wMDggNC4zODRBMy4yNCAzLjI0IDAgMCAxIC42NCA2LjU3OHYuMDM2YTMuMjk1IDMuMjk1IDAgMCAwIDIuNjI4IDMuMjIzIDMuMjc0IDMuMjc0IDAgMCAxLS44Ni4xMDggMi45IDIuOSAwIDAgMS0uNjIxLS4wNTYgMy4zMTEgMy4zMTEgMCAwIDAgMy4wNjUgMi4yODUgNi41OSA2LjU5IDAgMCAxLTQuMDY3IDEuMzk5Yy0uMjY5IDAtLjUyNy0uMDEyLS43ODUtLjA0NUE5LjIzNCA5LjIzNCAwIDAgMCA1LjAzMiAxNWM2LjAzNiAwIDkuMzM2LTUgOS4zMzYtOS4zMzQgMC0uMTQ1LS4wMDUtLjI4NS0uMDEyLS40MjRBNi41NDQgNi41NDQgMCAwIDAgMTYgMy41Mzl6Ij48L3BhdGg+PC9zdmc+",
|
||||
github:
|
||||
"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzEwXzIpIj4KPHBhdGggZD0iTTcuOTk5IDBDMy41ODIwMSAwIDQuNjE2NDhlLTA2IDMuNTk2IDQuNjE2NDhlLTA2IDguMDMyQy0wLjAwMTggOS43MTU1NSAwLjUyNTUxOSAxMS4zNTcxIDEuNTA3NDQgMTIuNzI0NkMyLjQ4OTM1IDE0LjA5MjIgMy44NzYyMSAxNS4xMTY2IDUuNDcyIDE1LjY1M0M1Ljg3MiAxNS43MjcgNi4wMTggMTUuNDc5IDYuMDE4IDE1LjI2NkM2LjAxOCAxNS4wNzUgNi4wMTEgMTQuNTcgNi4wMDcgMTMuOUMzLjc4MiAxNC4zODUgMy4zMTIgMTIuODIzIDMuMzEyIDEyLjgyM0MyLjk0OSAxMS44OTUgMi40MjQgMTEuNjQ4IDIuNDI0IDExLjY0OEMxLjY5NyAxMS4xNSAyLjQ3OCAxMS4xNiAyLjQ3OCAxMS4xNkMzLjI4MSAxMS4yMTcgMy43MDMgMTEuOTg4IDMuNzAzIDExLjk4OEM0LjQxNyAxMy4yMTUgNS41NzYgMTIuODYxIDYuMDMyIDEyLjY1NUM2LjEwNCAxMi4xMzYgNi4zMTEgMTEuNzgyIDYuNTQgMTEuNTgxQzQuNzY0IDExLjM3OCAyLjg5NiAxMC42ODkgMi44OTYgNy42MTJDMi44OTYgNi43MzUgMy4yMDggNi4wMTggMy43MiA1LjQ1NkMzLjYzNyA1LjI1MyAzLjM2MyA0LjQzNiAzLjc5OCAzLjMzMUMzLjc5OCAzLjMzMSA0LjQ3IDMuMTE1IDUuOTk4IDQuMTU0QzYuNjUwNzUgMy45NzU2MSA3LjMyNDMyIDMuODg0ODIgOC4wMDEwMSAzLjg4NEM4LjY3NzcyIDMuODg1MzQgOS4zNTEyNiAzLjk3NjQ3IDEwLjAwNCA0LjE1NUMxMS41MzEgMy4xMTYgMTIuMjAyIDMuMzMyIDEyLjIwMiAzLjMzMkMxMi42MzggNC40MzggMTIuMzY0IDUuMjU0IDEyLjI4MiA1LjQ1N0MxMi43OTUgNi4wMTkgMTMuMTA0IDYuNzM2IDEzLjEwNCA3LjYxM0MxMy4xMDQgMTAuNjk4IDExLjIzNCAxMS4zNzcgOS40NTIgMTEuNTc2QzkuNzM5IDExLjgyNCA5Ljk5NSAxMi4zMTQgOS45OTUgMTMuMDYzQzkuOTk1IDE0LjEzNyA5Ljk4NSAxNS4wMDMgOS45ODUgMTUuMjY2QzkuOTg1IDE1LjQ4MSAxMC4xMjkgMTUuNzMxIDEwLjUzNSAxNS42NTJDMTIuMTI5MiAxNS4xMTQzIDEzLjUxNDQgMTQuMDg5NSAxNC40OTQ5IDEyLjcyMjNDMTUuNDc1NSAxMS4zNTUxIDE2LjAwMTkgOS43MTQ0OCAxNiA4LjAzMkMxNiAzLjU5NiAxMi40MTggMCA3Ljk5OSAwWiIgZmlsbD0iIzhCOEI4QiIvPgo8L2c+CjxkZWZzPgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzEwXzIiPgo8cmVjdCB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIGZpbGw9IndoaXRlIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg==",
|
||||
apple:
|
||||
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDM4IiBoZWlnaHQ9IjI1MDAiIHZpZXdCb3g9IjAgMCA0OTYuMjU1IDYwOC43MjgiIGlkPSJhcHBsZSI+PHBhdGggZmlsbD0iIzk5OSIgZD0iTTI3My44MSA1Mi45NzNDMzEzLjgwNi4yNTcgMzY5LjQxIDAgMzY5LjQxIDBzOC4yNzEgNDkuNTYyLTMxLjQ2MyA5Ny4zMDZjLTQyLjQyNiA1MC45OC05MC42NDkgNDIuNjM4LTkwLjY0OSA0Mi42MzhzLTkuMDU1LTQwLjA5NCAyNi41MTItODYuOTcxek0yNTIuMzg1IDE3NC42NjJjMjAuNTc2IDAgNTguNzY0LTI4LjI4NCAxMDguNDcxLTI4LjI4NCA4NS41NjIgMCAxMTkuMjIyIDYwLjg4MyAxMTkuMjIyIDYwLjg4M3MtNjUuODMzIDMzLjY1OS02NS44MzMgMTE1LjMzMWMwIDkyLjEzMyA4Mi4wMSAxMjMuODg1IDgyLjAxIDEyMy44ODVzLTU3LjMyOCAxNjEuMzU3LTEzNC43NjIgMTYxLjM1N2MtMzUuNTY1IDAtNjMuMjE1LTIzLjk2Ny0xMDAuNjg4LTIzLjk2Ny0zOC4xODggMC03Ni4wODQgMjQuODYxLTEwMC43NjYgMjQuODYxQzg5LjMzIDYwOC43MyAwIDQ1NS42NjYgMCAzMzIuNjI4YzAtMTIxLjA1MiA3NS42MTItMTg0LjU1NCAxNDYuNTMzLTE4NC41NTQgNDYuMTA1IDAgODEuODgzIDI2LjU4OCAxMDUuODUyIDI2LjU4OHoiPjwvcGF0aD48L3N2Zz4=",
|
||||
linkedin:
|
||||
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NCIgaGVpZ2h0PSI0MCIgaWQ9ImxpbmtlZGluIj48cGF0aCBmaWxsPSIjMDA3RUJCIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00NCA0MGgtOS43MjVWMjUuOTM4YzAtMy42OC0xLjUyLTYuMTkzLTQuODY2LTYuMTkzLTIuNTU4IDAtMy45ODEgMS42OTYtNC42NDMgMy4zMy0uMjQ5LjU4Ni0uMjEgMS40MDMtLjIxIDIuMjJWNDBoLTkuNjM0cy4xMjQtMjQuOTA5IDAtMjcuMTczaDkuNjM0djQuMjY1Yy41Ny0xLjg2NSAzLjY0OC00LjUyNiA4LjU2LTQuNTI2QzM5LjIxMSAxMi41NjYgNDQgMTYuNDc0IDQ0IDI0Ljg5MVY0MHpNNS4xOCA5LjQyOGgtLjA2M0MyLjAxMyA5LjQyOCAwIDcuMzUxIDAgNC43MTggMCAyLjAzNCAyLjA3MiAwIDUuMjM5IDBjMy4xNjQgMCA1LjExIDIuMDI5IDUuMTcxIDQuNzEgMCAyLjYzMy0yLjAwNyA0LjcxOC01LjIzIDQuNzE4em0tNC4wNyAzLjM5OWg4LjU3NlY0MEgxLjExVjEyLjgyN3oiPjwvcGF0aD48L3N2Zz4=",
|
||||
bitbucket:
|
||||
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgaWQ9ImJpdGJ1Y2tldCI+PHBhdGggZmlsbD0iIzI2ODBGOCIgZD0iTTQuMjk3IDIzaDE1LjY1OWEuNzc2Ljc3NiAwIDAgMCAuNzY5LS42NTdMMjMuOTkgMS45MTZhLjc4Ljc4IDAgMCAwLS42MzUtLjg5NyAxLjEzIDEuMTMgMCAwIDAtLjEzNC0uMDA5TC43NzkgMUEuNzc1Ljc3NSAwIDAgMCAwIDEuNzc1YzAgLjA0NC4wMDUuMDkzLjAwOS4xMzdsMy4yNjUgMjAuMTk2Yy4wODIuNTA5LjUxNS44ODcgMS4wMjMuODkyek0xNS43MzYgOC4zOTFsLTEuMjExIDcuMjA1aC01TDguMTczIDguMzkxaDcuNTYzeiI+PC9wYXRoPjwvc3ZnPg==",
|
||||
gitlab:
|
||||
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNTAwIiBoZWlnaHQ9IjIzMDUiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaW5ZTWluIG1lZXQiIHZpZXdCb3g9IjAgMCAyNTYgMjM2IiBpZD0iZ2l0bGFiIj48cGF0aCBmaWxsPSIjRTI0MzI5IiBkPSJNMTI4LjA3NSAyMzYuMDc1bDQ3LjEwNC0xNDQuOTdIODAuOTdsNDcuMTA0IDE0NC45N3oiPjwvcGF0aD48cGF0aCBmaWxsPSIjRkM2RDI2IiBkPSJNMTI4LjA3NSAyMzYuMDc0TDgwLjk3IDkxLjEwNEgxNC45NTZsMTEzLjExOSAxNDQuOTd6Ij48L3BhdGg+PHBhdGggZmlsbD0iI0ZDQTMyNiIgZD0iTTE0Ljk1NiA5MS4xMDRMLjY0MiAxMzUuMTZhOS43NTIgOS43NTIgMCAwIDAgMy41NDIgMTAuOTAzbDEyMy44OTEgOTAuMDEyLTExMy4xMi0xNDQuOTd6Ij48L3BhdGg+PHBhdGggZmlsbD0iI0UyNDMyOSIgZD0iTTE0Ljk1NiA5MS4xMDVIODAuOTdMNTIuNjAxIDMuNzljLTEuNDYtNC40OTMtNy44MTYtNC40OTItOS4yNzUgMGwtMjguMzcgODcuMzE1eiI+PC9wYXRoPjxwYXRoIGZpbGw9IiNGQzZEMjYiIGQ9Ik0xMjguMDc1IDIzNi4wNzRsNDcuMTA0LTE0NC45N2g2Ni4wMTVsLTExMy4xMiAxNDQuOTd6Ij48L3BhdGg+PHBhdGggZmlsbD0iI0ZDQTMyNiIgZD0iTTI0MS4xOTQgOTEuMTA0bDE0LjMxNCA0NC4wNTZhOS43NTIgOS43NTIgMCAwIDEtMy41NDMgMTAuOTAzbC0xMjMuODkgOTAuMDEyIDExMy4xMTktMTQ0Ljk3eiI+PC9wYXRoPjxwYXRoIGZpbGw9IiNFMjQzMjkiIGQ9Ik0yNDEuMTk0IDkxLjEwNWgtNjYuMDE1bDI4LjM3LTg3LjMxNWMxLjQ2LTQuNDkzIDcuODE2LTQuNDkyIDkuMjc1IDBsMjguMzcgODcuMzE1eiI+PC9wYXRoPjwvc3ZnPg==",
|
||||
twitch:
|
||||
"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgdmlld0JveD0iMCAwIDExMS43ODY2NyAxMjcuMzg2NjciCiAgIGhlaWdodD0iMTI3LjM4NjY3IgogICB3aWR0aD0iMTExLjc4NjY3IgogICB4bWw6c3BhY2U9InByZXNlcnZlIgogICB2ZXJzaW9uPSIxLjEiCiAgIGlkPSJzdmczMzU1IgogICBzb2RpcG9kaTpkb2NuYW1lPSJUd2l0Y2hfbG9nby5zdmciCiAgIGlua3NjYXBlOnZlcnNpb249IjEuMS4xICgzYmY1YWUwZDI1LCAyMDIxLTA5LTIwKSIKICAgeG1sbnM6aW5rc2NhcGU9Imh0dHA6Ly93d3cuaW5rc2NhcGUub3JnL25hbWVzcGFjZXMvaW5rc2NhcGUiCiAgIHhtbG5zOnNvZGlwb2RpPSJodHRwOi8vc29kaXBvZGkuc291cmNlZm9yZ2UubmV0L0RURC9zb2RpcG9kaS0wLmR0ZCIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZGVmcwogICBpZD0iZGVmczI5Ij4KICAgIAogICAgCiAgPC9kZWZzPjxzb2RpcG9kaTpuYW1lZHZpZXcKICAgaWQ9Im5hbWVkdmlldzI3IgogICBwYWdlY29sb3I9IiNmZmZmZmYiCiAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICBib3JkZXJvcGFjaXR5PSIxLjAiCiAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PSIwLjAiCiAgIGlua3NjYXBlOnBhZ2VjaGVja2VyYm9hcmQ9IjAiCiAgIHNob3dncmlkPSJmYWxzZSIKICAgaW5rc2NhcGU6em9vbT0iNC4xOTkyMjg0IgogICBpbmtzY2FwZTpjeD0iLTUwLjYwNDUzNSIKICAgaW5rc2NhcGU6Y3k9IjE0MC4zODI5MyIKICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIyNTYwIgogICBpbmtzY2FwZTp3aW5kb3ctaGVpZ2h0PSIxMzg3IgogICBpbmtzY2FwZTp3aW5kb3cteD0iMTkxMiIKICAgaW5rc2NhcGU6d2luZG93LXk9Ii04IgogICBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIxIgogICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJzdmczMzU1IiAvPgogIDxnCiAgIHRyYW5zZm9ybT0ibWF0cml4KDEuMzMzMzMzMywwLDAsLTEuMzMzMzMzMywxMDEuMzkzMzMsNjcuNTg5MzMyKSIKICAgaWQ9ImczMzY1Ij4KICAgICAgPHBhdGgKICAgaWQ9InBhdGgzMzY3IgogICBzdHlsZT0iZmlsbDojNjQ0MWE1O2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpldmVub2RkO3N0cm9rZTpub25lIgogICBkPSJtIDAsMCAtMTMuNjUyLC0xMy42NTEgaCAtMjEuNDQ1IGwgLTExLjY5OSwtMTEuNjk3IHYgMTEuNjk3IEggLTY0LjM0NCBWIDQyLjg5MyBIIDAgWiBtIC03Mi4xNDYsNTAuNjkyIC0zLjg5OSwtMTUuNTk5IHYgLTcwLjE5IGggMTcuNTUgdiAtOS43NTEgaCA5Ljc0NiBsIDkuNzUyLDkuNzUxIGggMTUuNTk2IEwgNy43OTUsLTMuOTA1IHYgNTQuNTk3IHoiIC8+CiAgICA8L2c+PHBhdGgKICAgaWQ9InBhdGgzMzY5IgogICBzdHlsZT0iZmlsbDojNjQ0MWE1O2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpldmVub2RkO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDoxLjMzMzMzIgogICBkPSJtIDQ0LjE5NzMzMSw2Mi4zOTQyNjYgaCAxMC4zOTg2NyBWIDMxLjE5MjkzMyBoIC0xMC4zOTg2NyB6IG0gMjguNTk0NjcsMCBoIDEwLjM5ODY2IFYgMzEuMTkyOTMzIGggLTEwLjM5ODY2IHoiIC8+Cjwvc3ZnPgo=",
|
||||
discord:
|
||||
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDEwMCAxMDAiIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBpZD0iZGlzY29yZCI+PHBhdGggZmlsbD0iIzY2NjVkMiIgZD0iTTg1LjIyLDI0Ljk1OGMtMTEuNDU5LTguNTc1LTIyLjQzOC04LjMzNC0yMi40MzgtOC4zMzRsLTEuMTIyLDEuMjgyCgkJCQljMTMuNjIzLDQuMDg3LDE5Ljk1NCwxMC4wOTcsMTkuOTU0LDEwLjA5N2MtMTkuNDkxLTEwLjczMS00NC4zMTctMTAuNjU0LTY0LjU5LDBjMCwwLDYuNTcxLTYuMzMxLDIwLjk5Ni0xMC40MThsLTAuODAxLTAuOTYyCgkJCQljMCwwLTEwLjg5OS0wLjI0LTIyLjQzOCw4LjMzNGMwLDAtMTEuNTQsMjAuNzU1LTExLjU0LDQ2LjMxOWMwLDAsNi43MzIsMTEuNTQsMjQuNDQyLDEyLjEwMWMwLDAsMi45NjUtMy41MjYsNS4zNjktNi41NzEKCQkJCWMtMTAuMTc3LTMuMDQ1LTE0LjAyNC05LjM3Ni0xNC4wMjQtOS4zNzZjNi4zOTQsNC4wMDEsMTIuODU5LDYuNTA1LDIwLjkxNiw4LjA5NGMxMy4xMDgsMi42OTgsMjkuNDEzLTAuMDc2LDQxLjU5MS04LjA5NAoJCQkJYzAsMC00LjAwNyw2LjQ5MS0xNC41MDUsOS40NTZjMi40MDQsMi45NjUsNS4yODksNi40MTEsNS4yODksNi40MTFjMTcuNzEtMC41NjEsMjQuNDQxLTEyLjEwMSwyNC40NDEtMTIuMDIKCQkJCUM5Ni43NTksNDUuNzEzLDg1LjIyLDI0Ljk1OCw4NS4yMiwyNC45NTh6IE0zNS4wNTUsNjMuODI0Yy00LjQ4OCwwLTguMTc0LTMuOTI3LTguMTc0LTguODE1CgkJCQljMC4zMjgtMTEuNzA3LDE2LjEwMi0xMS42NzEsMTYuMzQ4LDBDNDMuMjI5LDU5Ljg5NywzOS42MjIsNjMuODI0LDM1LjA1NSw2My44MjR6IE02NC4zMDQsNjMuODI0CgkJCQljLTQuNDg4LDAtOC4xNzQtMy45MjctOC4xNzQtOC44MTVjMC4zNi0xMS42ODQsMTUuOTM3LTExLjY4OSwxNi4zNDgsMEM3Mi40NzgsNTkuODk3LDY4Ljg3Miw2My44MjQsNjQuMzA0LDYzLjgyNHoiPjwvcGF0aD48L3N2Zz4=",
|
||||
microsoft:
|
||||
"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciICB2aWV3Qm94PSIwIDAgNDggNDgiIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiPjxwYXRoIGZpbGw9IiNmZjU3MjIiIGQ9Ik02IDZIMjJWMjJINnoiIHRyYW5zZm9ybT0icm90YXRlKC0xODAgMTQgMTQpIi8+PHBhdGggZmlsbD0iIzRjYWY1MCIgZD0iTTI2IDZINDJWMjJIMjZ6IiB0cmFuc2Zvcm09InJvdGF0ZSgtMTgwIDM0IDE0KSIvPjxwYXRoIGZpbGw9IiNmZmMxMDciIGQ9Ik0yNiAyNkg0MlY0MkgyNnoiIHRyYW5zZm9ybT0icm90YXRlKC0xODAgMzQgMzQpIi8+PHBhdGggZmlsbD0iIzAzYTlmNCIgZD0iTTYgMjZIMjJWNDJINnoiIHRyYW5zZm9ybT0icm90YXRlKC0xODAgMTQgMzQpIi8+PC9zdmc+",
|
||||
google: googleIconUri,
|
||||
facebook: facebookIconUri,
|
||||
twitter: twitterIconUri,
|
||||
github: githubIconUri,
|
||||
apple: appleIconUri,
|
||||
linkedin: linkedinIconUri,
|
||||
bitbucket: bitbucketIconUri,
|
||||
gitlab: gitlabIconUri,
|
||||
twitch: twitchIconUri,
|
||||
discord: discordIconUri,
|
||||
microsoft: microsoftIconUri,
|
||||
};
|
||||
|
||||
function upperCaseFirstLetter(string: string) {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { ConnectUIProps, useConnect } from "@thirdweb-dev/react-core";
|
||||
import { ConnectingScreen } from "../../ConnectWallet/screens/ConnectingScreen";
|
||||
import { isMobile } from "../../../evm/utils/isMobile";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { OKXScan } from "./OKXScan";
|
||||
import { GetStartedScreen } from "../../ConnectWallet/screens/GetStartedScreen";
|
||||
import type { OKXWallet } from "@thirdweb-dev/wallets";
|
||||
import { wait } from "../../../utils/wait";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { useTWLocale } from "../../../evm/providers/locale-provider";
|
||||
import { isMobile } from "../../../evm/utils/isMobile";
|
||||
import { wait } from "../../../utils/wait";
|
||||
import { ConnectingScreen } from "../../ConnectWallet/screens/ConnectingScreen";
|
||||
import { GetStartedScreen } from "../../ConnectWallet/screens/GetStartedScreen";
|
||||
import { OKXScan } from "./OKXScan";
|
||||
|
||||
export const OKXConnectUI = (props: ConnectUIProps<OKXWallet>) => {
|
||||
const [screen, setScreen] = useState<
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useTheme } from "@emotion/react";
|
||||
import styled from "@emotion/styled";
|
||||
import {
|
||||
WalletConfig,
|
||||
@@ -7,16 +8,16 @@ import {
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { PaperWallet } from "@thirdweb-dev/wallets";
|
||||
import { Spacer } from "../../../components/Spacer";
|
||||
import { TextDivider } from "../../../components/TextDivider";
|
||||
import { Container, ModalHeader } from "../../../components/basic";
|
||||
import { Button } from "../../../components/buttons";
|
||||
import { Theme, iconSize, spacing } from "../../../design-system";
|
||||
import { GoogleIcon } from "../../ConnectWallet/icons/GoogleIcon";
|
||||
import { useTWLocale } from "../../../evm/providers/locale-provider";
|
||||
import { openOauthSignInWindow } from "../../utils/openOauthSignInWindow";
|
||||
import { InputSelectionUI } from "../InputSelectionUI";
|
||||
import { PaperLoginType } from "./types";
|
||||
import { TextDivider } from "../../../components/TextDivider";
|
||||
import { openGoogleSignInWindow } from "../../utils/openGoogleSignInWindow";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { useTWLocale } from "../../../evm/providers/locale-provider";
|
||||
import { Img } from "../../../components/Img";
|
||||
import { googleIconUri } from "../../ConnectWallet/icons/socialLogins";
|
||||
|
||||
export const PaperFormUI = (props: {
|
||||
onSelect: (loginType: PaperLoginType) => void;
|
||||
@@ -35,7 +36,7 @@ export const PaperFormUI = (props: {
|
||||
try {
|
||||
const paperWallet = createWalletInstance(props.walletConfig);
|
||||
setConnectionStatus("connecting");
|
||||
const googleWindow = openGoogleSignInWindow(themeObj);
|
||||
const googleWindow = openOauthSignInWindow("google", themeObj);
|
||||
if (!googleWindow) {
|
||||
throw new Error("Failed to open google login window");
|
||||
}
|
||||
@@ -66,7 +67,7 @@ export const PaperFormUI = (props: {
|
||||
props.onSelect({ google: true });
|
||||
}}
|
||||
>
|
||||
<GoogleIcon size={iconSize.md} />
|
||||
<Img src={googleIconUri} width={iconSize.md} height={iconSize.md} />
|
||||
{locale.signInWithGoogle}
|
||||
</SocialButton>
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useTheme } from "@emotion/react";
|
||||
import {
|
||||
ConnectUIProps,
|
||||
useConnectionStatus,
|
||||
@@ -14,10 +15,10 @@ import { Button } from "../../../components/buttons";
|
||||
import { ModalTitle } from "../../../components/modalElements";
|
||||
import { Text } from "../../../components/text";
|
||||
import { Theme, iconSize } from "../../../design-system";
|
||||
import { GoogleIcon } from "../../ConnectWallet/icons/GoogleIcon";
|
||||
import { openGoogleSignInWindow } from "../../utils/openGoogleSignInWindow";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { useTWLocale } from "../../../evm/providers/locale-provider";
|
||||
import { openOauthSignInWindow } from "../../utils/openOauthSignInWindow";
|
||||
import { Img } from "../../../components/Img";
|
||||
import { googleIconUri } from "../../ConnectWallet/icons/socialLogins";
|
||||
|
||||
export const PaperGoogleLogin = (props: ConnectUIProps<PaperWallet>) => {
|
||||
const { goBack, modalSize, connected } = props;
|
||||
@@ -34,7 +35,7 @@ export const PaperGoogleLogin = (props: ConnectUIProps<PaperWallet>) => {
|
||||
try {
|
||||
const paperWallet = createWalletInstance(props.walletConfig);
|
||||
setConnectionStatus("connecting");
|
||||
const googleWindow = openGoogleSignInWindow(themeObj);
|
||||
const googleWindow = openOauthSignInWindow("google", themeObj);
|
||||
if (!googleWindow) {
|
||||
throw new Error("Failed to open google login window");
|
||||
}
|
||||
@@ -74,7 +75,11 @@ export const PaperGoogleLogin = (props: ConnectUIProps<PaperWallet>) => {
|
||||
<ModalHeader
|
||||
title={
|
||||
<Container flex="row" center="both" gap="xs">
|
||||
<GoogleIcon size={iconSize.md} />
|
||||
<Img
|
||||
src={googleIconUri}
|
||||
width={iconSize.md}
|
||||
height={iconSize.md}
|
||||
/>
|
||||
<ModalTitle> {locale.title} </ModalTitle>
|
||||
</Container>
|
||||
}
|
||||
|
||||
@@ -20,6 +20,15 @@ import { useScreenContext } from "../../ConnectWallet/Modal/screen";
|
||||
import { PaperGoogleLogin } from "./PaperGoogleLogin";
|
||||
import { emailIcon } from "../../ConnectWallet/icons/dataUris";
|
||||
|
||||
/**
|
||||
* Paper Wallet
|
||||
*
|
||||
* @param _config - Options available to create a paper wallet
|
||||
* @returns The WalletConfig<PaperWallet> object
|
||||
*
|
||||
* @deprecated We have deprecated PaperWallet in favor of our {@link EmbeddedWallet} which adds support for more sign in methods.
|
||||
* Learn more here: https://portal.thirdweb.com/embedded-wallet
|
||||
*/
|
||||
export const paperWallet = (
|
||||
_config?: PaperConfig,
|
||||
): WalletConfig<PaperWallet> => {
|
||||
|
||||
@@ -13,7 +13,7 @@ export type PaperConfig = Omit<
|
||||
|
||||
/**
|
||||
* Enable or Disable OAuth logins and specify which providers to use for OAuth
|
||||
* @default { providers: ["google"] }
|
||||
* @defaultValue `{ providers: ["google"] }`
|
||||
*/
|
||||
oauthOptions?:
|
||||
| {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: ["thirdweb"],
|
||||
plugins: ["better-tree-shaking"],
|
||||
plugins: ["better-tree-shaking", "eslint-plugin-tsdoc"],
|
||||
rules: {
|
||||
"tsdoc/syntax": "error",
|
||||
"better-tree-shaking/no-top-level-side-effects": "error",
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# @thirdweb-dev/sdk
|
||||
|
||||
## 4.0.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1947](https://github.com/thirdweb-dev/js/pull/1947) [`23ab897e`](https://github.com/thirdweb-dev/js/commit/23ab897e329cdd5b316fbe554ea0f64add91f2b4) Thanks [@adam-maj](https://github.com/adam-maj)! - Add support for EIP-2612 permit to engine relayer
|
||||
|
||||
- [#1936](https://github.com/thirdweb-dev/js/pull/1936) [`a3f3e160`](https://github.com/thirdweb-dev/js/commit/a3f3e160e07328655a4f0332f41f4edd210a1a8a) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Improvements for auto resolving contracts:
|
||||
|
||||
- ~10x performance improvements using shared caching layer at the edge
|
||||
- auto resolves any verified contract on etherscan on supported chains
|
||||
|
||||
- [#1944](https://github.com/thirdweb-dev/js/pull/1944) [`6fcdec7c`](https://github.com/thirdweb-dev/js/commit/6fcdec7c12e4a3c0d10f3a67771e19cfad5c8ab5) Thanks [@iketw](https://github.com/iketw)! - Fixes all tsdoc comments warnings
|
||||
|
||||
- [#1949](https://github.com/thirdweb-dev/js/pull/1949) [`480ed721`](https://github.com/thirdweb-dev/js/commit/480ed721d1c736049fa8b6ee4cbdbdf3cce18abd) Thanks [@iketw](https://github.com/iketw)! - Enforces the tsdoc/syntax rule
|
||||
|
||||
- Updated dependencies [[`6fcdec7c`](https://github.com/thirdweb-dev/js/commit/6fcdec7c12e4a3c0d10f3a67771e19cfad5c8ab5), [`480ed721`](https://github.com/thirdweb-dev/js/commit/480ed721d1c736049fa8b6ee4cbdbdf3cce18abd)]:
|
||||
- @thirdweb-dev/storage@2.0.4
|
||||
|
||||
## 4.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1937](https://github.com/thirdweb-dev/js/pull/1937) [`3f3a484a`](https://github.com/thirdweb-dev/js/commit/3f3a484a3aa6e9f784e4d44458461bac0d3d4c6b) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Standardize large number formatting
|
||||
|
||||
- Updated dependencies [[`30ea9c6b`](https://github.com/thirdweb-dev/js/commit/30ea9c6bf74b483a98592a1d8d64589b7f1b22a3)]:
|
||||
- @thirdweb-dev/storage@2.0.3
|
||||
|
||||
## 4.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/sdk",
|
||||
"version": "4.0.11",
|
||||
"version": "4.0.13",
|
||||
"description": "The main thirdweb SDK.",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/sdk",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -27,7 +27,7 @@ export const CUSTOM_GAS_FOR_CHAIN: Record<number, CustomChain> = {
|
||||
},
|
||||
[71402]: {
|
||||
name: "Godwoken Mainnet",
|
||||
gasPrice: 40_000 * 10 ** 9,
|
||||
gasPrice: 40000 * 10 ** 9,
|
||||
},
|
||||
[1351057110]: {
|
||||
name: "Chaos (SKALE Testnet)",
|
||||
@@ -55,17 +55,17 @@ export const CUSTOM_GAS_FOR_CHAIN: Record<number, CustomChain> = {
|
||||
},
|
||||
[199]: {
|
||||
name: "BitTorrent Chain",
|
||||
gasPrice: 300_000 * 10 ** 9,
|
||||
gasPrice: 300000 * 10 ** 9,
|
||||
},
|
||||
[88882]: {
|
||||
name: "Spicy Chain",
|
||||
gasPrice: 2500 * 10 ** 9,
|
||||
gasLimit: 200_000,
|
||||
gasLimit: 200000,
|
||||
},
|
||||
[88888]: {
|
||||
name: "Chiliz Chain",
|
||||
gasPrice: 2500 * 10 ** 9,
|
||||
gasLimit: 200_000,
|
||||
gasLimit: 200000,
|
||||
},
|
||||
};
|
||||
/* eslint-enable no-useless-computed-key */
|
||||
|
||||
@@ -6,9 +6,9 @@ import { computeDeploymentInfo } from "./computeDeploymentInfo";
|
||||
/**
|
||||
*
|
||||
* @internal
|
||||
* @param provider
|
||||
* @param storage
|
||||
* @param create2Factory
|
||||
* @param provider - The provider to use
|
||||
* @param storage - The storage to use
|
||||
* @param create2Factory - The create2 factory to use
|
||||
*/
|
||||
export async function computeCloneFactoryAddress(
|
||||
provider: providers.Provider,
|
||||
|
||||
@@ -5,9 +5,9 @@ import { getSaltHash } from "./getSaltHash";
|
||||
* Pre-compute a contract's deployment address for a CREATE2 deployment.
|
||||
*
|
||||
* @public
|
||||
* @param bytecode: Creation bytecode of the contract to deploy
|
||||
* @param encodedArgs: Abi-encoded constructor params
|
||||
* @param create2FactoryAddress
|
||||
* @param bytecode - Creation bytecode of the contract to deploy
|
||||
* @param encodedArgs - Abi-encoded constructor params
|
||||
* @param create2FactoryAddress - The create2 factory address to use
|
||||
*/
|
||||
export function computeDeploymentAddress(
|
||||
bytecode: string,
|
||||
|
||||
@@ -6,9 +6,9 @@ import { computeDeploymentInfo } from "./computeDeploymentInfo";
|
||||
/**
|
||||
*
|
||||
* @internal
|
||||
* @param provider
|
||||
* @param storage
|
||||
* @param create2Factory
|
||||
* @param provider - The provider to use
|
||||
* @param storage - The storage to use
|
||||
* @param create2Factory - The create2 factory to use
|
||||
*/
|
||||
export async function computeEOAForwarderAddress(
|
||||
provider: providers.Provider,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user