Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c710fc1c62 | ||
|
|
f41ee6fb1c | ||
|
|
513c332ed0 | ||
|
|
693f349db2 | ||
|
|
63ad0050f0 | ||
|
|
dcdb0dcb83 | ||
|
|
b3b9edca29 | ||
|
|
1fbbc2d27d | ||
|
|
4b98e487d4 | ||
|
|
95380eaed4 | ||
|
|
1f3c64d361 | ||
|
|
bb1666b92b | ||
|
|
0f12d1f903 | ||
|
|
74941603a9 |
@@ -1,5 +1,12 @@
|
||||
# @thirdweb-dev/auth
|
||||
|
||||
## 4.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`74941603`](https://github.com/thirdweb-dev/js/commit/74941603a96456da46a47147f67c98235ac55022), [`4b98e487`](https://github.com/thirdweb-dev/js/commit/4b98e487d4b47225d7095e5444dc5e7608db48a3), [`dcdb0dcb`](https://github.com/thirdweb-dev/js/commit/dcdb0dcb838168a22c8335738852316dfb6e6fc9), [`b3b9edca`](https://github.com/thirdweb-dev/js/commit/b3b9edca29e7d4053b14270a61caa89c34fecf9e)]:
|
||||
- @thirdweb-dev/wallets@2.0.2
|
||||
|
||||
## 4.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/auth",
|
||||
"version": "4.0.1",
|
||||
"version": "4.0.2",
|
||||
"main": "dist/thirdweb-dev-auth.cjs.js",
|
||||
"module": "dist/thirdweb-dev-auth.esm.js",
|
||||
"browser": {
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# thirdweb
|
||||
|
||||
## 0.13.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`1f3c64d3`](https://github.com/thirdweb-dev/js/commit/1f3c64d3618903b9008cc7b633ea890b508e7800), [`74941603`](https://github.com/thirdweb-dev/js/commit/74941603a96456da46a47147f67c98235ac55022), [`4b98e487`](https://github.com/thirdweb-dev/js/commit/4b98e487d4b47225d7095e5444dc5e7608db48a3), [`693f349d`](https://github.com/thirdweb-dev/js/commit/693f349db2478e1cd0fc82a9ef9882f46832b125), [`dcdb0dcb`](https://github.com/thirdweb-dev/js/commit/dcdb0dcb838168a22c8335738852316dfb6e6fc9), [`0f12d1f9`](https://github.com/thirdweb-dev/js/commit/0f12d1f90320923309f085c372d3a5ed01dd4606), [`b3b9edca`](https://github.com/thirdweb-dev/js/commit/b3b9edca29e7d4053b14270a61caa89c34fecf9e), [`63ad0050`](https://github.com/thirdweb-dev/js/commit/63ad0050f0a24ec15b90933b5664d697618cf2d0)]:
|
||||
- @thirdweb-dev/sdk@4.0.1
|
||||
- @thirdweb-dev/wallets@2.0.2
|
||||
- @thirdweb-dev/auth@4.0.2
|
||||
|
||||
## 0.13.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "thirdweb",
|
||||
"main": "dist/cli/index.js",
|
||||
"version": "0.13.1",
|
||||
"version": "0.13.2",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @thirdweb-dev/contracts-js
|
||||
|
||||
## 1.3.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1757](https://github.com/thirdweb-dev/js/pull/1757) [`63ad0050`](https://github.com/thirdweb-dev/js/commit/63ad0050f0a24ec15b90933b5664d697618cf2d0) Thanks [@kumaryash90](https://github.com/kumaryash90)! - Update deployment and tests for MarketplaceV3 latest
|
||||
|
||||
## 1.3.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/contracts-js",
|
||||
"version": "1.3.13",
|
||||
"version": "1.3.14",
|
||||
"main": "dist/thirdweb-dev-contracts-js.cjs.js",
|
||||
"module": "dist/thirdweb-dev-contracts-js.esm.js",
|
||||
"browser": {
|
||||
@@ -10,7 +10,7 @@
|
||||
"license": "Apache-2.0",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/contracts-js",
|
||||
"dependencies": {
|
||||
"@thirdweb-dev/contracts": "3.10.1-0"
|
||||
"@thirdweb-dev/contracts": "3.10.2-3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/preset-env": "^7.22.9",
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# @thirdweb-dev/react-core
|
||||
|
||||
## 4.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`1f3c64d3`](https://github.com/thirdweb-dev/js/commit/1f3c64d3618903b9008cc7b633ea890b508e7800), [`74941603`](https://github.com/thirdweb-dev/js/commit/74941603a96456da46a47147f67c98235ac55022), [`4b98e487`](https://github.com/thirdweb-dev/js/commit/4b98e487d4b47225d7095e5444dc5e7608db48a3), [`693f349d`](https://github.com/thirdweb-dev/js/commit/693f349db2478e1cd0fc82a9ef9882f46832b125), [`dcdb0dcb`](https://github.com/thirdweb-dev/js/commit/dcdb0dcb838168a22c8335738852316dfb6e6fc9), [`0f12d1f9`](https://github.com/thirdweb-dev/js/commit/0f12d1f90320923309f085c372d3a5ed01dd4606), [`b3b9edca`](https://github.com/thirdweb-dev/js/commit/b3b9edca29e7d4053b14270a61caa89c34fecf9e), [`63ad0050`](https://github.com/thirdweb-dev/js/commit/63ad0050f0a24ec15b90933b5664d697618cf2d0)]:
|
||||
- @thirdweb-dev/sdk@4.0.1
|
||||
- @thirdweb-dev/wallets@2.0.2
|
||||
- @thirdweb-dev/auth@4.0.2
|
||||
|
||||
## 4.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-core",
|
||||
"version": "4.0.1",
|
||||
"version": "4.0.2",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-core",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# @thirdweb-dev/react-native-compat
|
||||
|
||||
## 0.3.7
|
||||
|
||||
## 0.3.6
|
||||
|
||||
## 0.3.5
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-native-compat",
|
||||
"description": "Shims for Thirdweb in React Native Projects",
|
||||
"version": "0.3.6",
|
||||
"version": "0.3.7",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native-compat",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @thirdweb-dev/react-native
|
||||
|
||||
## 0.3.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1754](https://github.com/thirdweb-dev/js/pull/1754) [`dcdb0dcb`](https://github.com/thirdweb-dev/js/commit/dcdb0dcb838168a22c8335738852316dfb6e6fc9) Thanks [@iketw](https://github.com/iketw)! - Fix typos in SmartWallet api
|
||||
|
||||
- [#1760](https://github.com/thirdweb-dev/js/pull/1760) [`f41ee6fb`](https://github.com/thirdweb-dev/js/commit/f41ee6fb1cc3b1e58cc273fa45087d4c92ff97d1) Thanks [@iketw](https://github.com/iketw)! - Correctly pass theme via ConnectWallet
|
||||
|
||||
- [#1753](https://github.com/thirdweb-dev/js/pull/1753) [`b3b9edca`](https://github.com/thirdweb-dev/js/commit/b3b9edca29e7d4053b14270a61caa89c34fecf9e) Thanks [@iketw](https://github.com/iketw)! - Minor bug and UI fix for connecting an external app to a smart wallet
|
||||
|
||||
- [#1759](https://github.com/thirdweb-dev/js/pull/1759) [`513c332e`](https://github.com/thirdweb-dev/js/commit/513c332ed02df4ac316076cc03178a4702b12110) Thanks [@iketw](https://github.com/iketw)! - Fixes bug when passing only one wallet as a supportedWallet. The selectUI component must be displayed.
|
||||
|
||||
- Updated dependencies [[`1f3c64d3`](https://github.com/thirdweb-dev/js/commit/1f3c64d3618903b9008cc7b633ea890b508e7800), [`74941603`](https://github.com/thirdweb-dev/js/commit/74941603a96456da46a47147f67c98235ac55022), [`4b98e487`](https://github.com/thirdweb-dev/js/commit/4b98e487d4b47225d7095e5444dc5e7608db48a3), [`693f349d`](https://github.com/thirdweb-dev/js/commit/693f349db2478e1cd0fc82a9ef9882f46832b125), [`dcdb0dcb`](https://github.com/thirdweb-dev/js/commit/dcdb0dcb838168a22c8335738852316dfb6e6fc9), [`0f12d1f9`](https://github.com/thirdweb-dev/js/commit/0f12d1f90320923309f085c372d3a5ed01dd4606), [`b3b9edca`](https://github.com/thirdweb-dev/js/commit/b3b9edca29e7d4053b14270a61caa89c34fecf9e), [`63ad0050`](https://github.com/thirdweb-dev/js/commit/63ad0050f0a24ec15b90933b5664d697618cf2d0)]:
|
||||
- @thirdweb-dev/sdk@4.0.1
|
||||
- @thirdweb-dev/wallets@2.0.2
|
||||
- @thirdweb-dev/react-core@4.0.2
|
||||
|
||||
## 0.3.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-native",
|
||||
"version": "0.3.6",
|
||||
"version": "0.3.7",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useWallet } from "@thirdweb-dev/react-core";
|
||||
import { IWalletConnectReceiver } from "@thirdweb-dev/wallets";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import Box from "../base/Box";
|
||||
import BaseButton from "../base/BaseButton";
|
||||
import DisconnectIcon from "../../assets/disconnect";
|
||||
@@ -21,6 +21,7 @@ const ConnectAppField = () => {
|
||||
const [appMeta, setAppMeta] = useState<{ name: string; iconUrl: string }>();
|
||||
const wallet = useWallet();
|
||||
const [showQRCodeScan, setShowQRCodeScan] = useState(false);
|
||||
const wcUriRef = useRef<string | undefined>();
|
||||
|
||||
const getAppMeta = useCallback(() => {
|
||||
if (wallet && "isWCReceiverEnabled" in wallet) {
|
||||
@@ -80,9 +81,10 @@ const ConnectAppField = () => {
|
||||
};
|
||||
|
||||
const onQRCodeScan = (data: string) => {
|
||||
if (wcUri !== data && data.startsWith("wc:")) {
|
||||
if (wcUriRef.current !== data && data.startsWith("wc:")) {
|
||||
setWCUri(data);
|
||||
setShowQRCodeScan(false);
|
||||
wcUriRef.current = data;
|
||||
|
||||
onWCPress(data);
|
||||
}
|
||||
@@ -102,6 +104,9 @@ const ConnectAppField = () => {
|
||||
if (uriToUse?.startsWith("wc:")) {
|
||||
(wallet as unknown as IWalletConnectReceiver).connectApp(uriToUse);
|
||||
}
|
||||
|
||||
setWCUri(undefined);
|
||||
wcUriRef.current = undefined;
|
||||
};
|
||||
|
||||
const onScanQRPress = () => {
|
||||
@@ -124,9 +129,11 @@ const ConnectAppField = () => {
|
||||
value: wcUri,
|
||||
placeholder: "wc://...",
|
||||
placeholderTextColor: theme.colors.textSecondary,
|
||||
numberOfLines: 1,
|
||||
}}
|
||||
containerProps={{
|
||||
flex: 1,
|
||||
pl: "xxs",
|
||||
}}
|
||||
/>
|
||||
<BaseButton
|
||||
@@ -164,12 +171,12 @@ const ConnectAppField = () => {
|
||||
>
|
||||
<>
|
||||
{appMeta?.iconUrl ? (
|
||||
<WalletIcon size={32} iconUri={appMeta.iconUrl} />
|
||||
<WalletIcon size={24} iconUri={appMeta.iconUrl} />
|
||||
) : (
|
||||
<WalletConnectIcon width={16} height={16} />
|
||||
<WalletConnectIcon width={24} height={24} />
|
||||
)}
|
||||
<View style={styles.exportWalletInfo}>
|
||||
<Text variant="bodySmall">
|
||||
<Text variant="bodySmall" numberOfLines={1}>
|
||||
{appMeta ? appMeta.name : "Connect app"}
|
||||
</Text>
|
||||
</View>
|
||||
@@ -215,8 +222,9 @@ const styles = StyleSheet.create({
|
||||
justifyContent: "flex-start",
|
||||
alignItems: "flex-start",
|
||||
alignContent: "center",
|
||||
flexDirection: "column",
|
||||
flexDirection: "row",
|
||||
marginLeft: 8,
|
||||
marginRight: 8,
|
||||
},
|
||||
exportWallet: {
|
||||
display: "flex",
|
||||
|
||||
+2
-2
@@ -12,9 +12,9 @@ import { useEffect, useState } from "react";
|
||||
import { useSmartWallet } from "../../providers/context-provider";
|
||||
import RightArrowIcon from "../../assets/right-arrow";
|
||||
import ConnectAppField from "./ConnectAppField";
|
||||
import { useAppTheme } from "../../styles/hooks";
|
||||
import DisconnectIcon from "../../assets/disconnect";
|
||||
import { IconTextButton } from "../base/IconTextButton";
|
||||
import { useGlobalTheme } from "../../providers/ui-context-provider";
|
||||
|
||||
export const SmartWalletAdditionalActions = ({
|
||||
onExportPress,
|
||||
@@ -26,7 +26,7 @@ export const SmartWalletAdditionalActions = ({
|
||||
const [smartWalletAddress, setSmartWalletAddress] = useState<string>("");
|
||||
const [showSmartWallet, setShowSmartWallet] = useState(false);
|
||||
const activeWallet = useWallet();
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
|
||||
const wallet = showSmartWallet
|
||||
? smartWallet
|
||||
|
||||
+2
-2
@@ -1,5 +1,4 @@
|
||||
import { Icon } from "../../assets/icon";
|
||||
import { useAppTheme } from "../../styles/hooks";
|
||||
import { AddressDisplay } from "../base/AddressDisplay";
|
||||
import BaseButton from "../base/BaseButton";
|
||||
import { WalletIcon } from "../base/WalletIcon";
|
||||
@@ -13,6 +12,7 @@ import { TextBalance } from "../base/TextBalance";
|
||||
import { walletIds } from "@thirdweb-dev/wallets";
|
||||
import { SMART_WALLET_ICON } from "../../assets/svgs";
|
||||
import Text from "../base/Text";
|
||||
import { useGlobalTheme } from "../../providers/ui-context-provider";
|
||||
|
||||
interface WalletDetailsModalHeaderProps {
|
||||
address?: string;
|
||||
@@ -28,7 +28,7 @@ export const WalletDetailsModalHeader = ({
|
||||
onAddressCopied,
|
||||
tokenAddress,
|
||||
}: WalletDetailsModalHeaderProps) => {
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
const activeWallet = useWallet();
|
||||
const [showLoading, setShowLoading] = useState(false);
|
||||
const ensQuery = useENS();
|
||||
|
||||
+2
-2
@@ -5,11 +5,11 @@ import { ReactNode, useState } from "react";
|
||||
import Box from "../../base/Box";
|
||||
import Text from "../../base/Text";
|
||||
import ThirdwebLogo from "../../../assets/thirdweb-logo";
|
||||
import { useAppTheme } from "../../../styles/hooks";
|
||||
import { ChooseWalletContent } from "./ChooseWalletContent";
|
||||
import { BaseButton, ImageSvgUri, WalletButton } from "../../base";
|
||||
import { ActivityIndicator, Linking } from "react-native";
|
||||
import { useTheme } from "@shopify/restyle";
|
||||
import { useGlobalTheme } from "../../../providers/ui-context-provider";
|
||||
|
||||
export type ChooseWalletProps = {
|
||||
headerText?: ReactNode | string;
|
||||
@@ -34,7 +34,7 @@ export function ChooseWallet({
|
||||
termsOfServiceUrl,
|
||||
privacyPolicyUrl,
|
||||
}: ChooseWalletProps) {
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
const themeLightDark = useTheme();
|
||||
const [isConnecting, setIsConnecting] = useState(false);
|
||||
const [isConnectAWalletEnabled, setIsConnectAWalletEnabled] = useState(false);
|
||||
|
||||
@@ -2,9 +2,11 @@ import { ActivityIndicator, StyleSheet } from "react-native";
|
||||
import { BaseButton, Text } from "../base";
|
||||
import { useConnectionStatus, useWallets } from "@thirdweb-dev/react-core";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useModalState } from "../../providers/ui-context-provider";
|
||||
import {
|
||||
useGlobalTheme,
|
||||
useModalState,
|
||||
} from "../../providers/ui-context-provider";
|
||||
import { ThemeProvider, ThemeProviderProps } from "../../styles/ThemeProvider";
|
||||
import { useAppTheme } from "../../styles/hooks";
|
||||
|
||||
export type ConnectWalletButtonProps = {
|
||||
theme?: ThemeProviderProps["theme"];
|
||||
@@ -43,7 +45,7 @@ export const ConnectWalletButton = ({
|
||||
buttonTitle,
|
||||
theme,
|
||||
}: ConnectWalletButtonProps) => {
|
||||
const appTheme = useAppTheme();
|
||||
const appTheme = useGlobalTheme();
|
||||
const connectionStatus = useConnectionStatus();
|
||||
const isWalletConnecting = connectionStatus === "connecting";
|
||||
|
||||
|
||||
@@ -5,14 +5,16 @@ import { WalletConfig, useConnect, useWallets } from "@thirdweb-dev/react-core";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { walletIds } from "@thirdweb-dev/wallets";
|
||||
import { useColorScheme } from "react-native";
|
||||
import { useModalState } from "../../providers/ui-context-provider";
|
||||
import {
|
||||
useGlobalTheme,
|
||||
useModalState,
|
||||
} from "../../providers/ui-context-provider";
|
||||
import {
|
||||
CLOSE_MODAL_STATE,
|
||||
ConnectWalletFlowModal,
|
||||
} from "../../utils/modalTypes";
|
||||
import Box from "../base/Box";
|
||||
import { ThemeProvider } from "../../styles/ThemeProvider";
|
||||
import { useAppTheme } from "../../styles/hooks";
|
||||
|
||||
export const ConnectWalletFlow = () => {
|
||||
const { modalState, setModalState } = useModalState();
|
||||
@@ -30,7 +32,7 @@ export const ConnectWalletFlow = () => {
|
||||
const [selectionData, setSelectionData] = useState<any>();
|
||||
const supportedWallets = useWallets();
|
||||
const theme = useColorScheme();
|
||||
const appTheme = useAppTheme();
|
||||
const appTheme = useGlobalTheme();
|
||||
const connect = useConnect();
|
||||
|
||||
const onClose = useCallback(
|
||||
@@ -74,13 +76,19 @@ export const ConnectWalletFlow = () => {
|
||||
useEffect(() => {
|
||||
// case when only one wallet is passed in supportedWallets
|
||||
if (walletConfig) {
|
||||
if (walletConfig.connectUI) {
|
||||
// if there's a connection UI, then show it
|
||||
setActiveWallet(walletConfig);
|
||||
} else {
|
||||
// if there's no connection UI, then connect the wallet
|
||||
onChooseWallet(walletConfig);
|
||||
// if there's a selection UI, then continue with the flow
|
||||
if (walletConfig.selectUI) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (walletConfig.connectUI) {
|
||||
// if there's a connection UI and no selection UI, then show it
|
||||
setActiveWallet(walletConfig);
|
||||
return;
|
||||
}
|
||||
|
||||
// if there's no connection UI or selectionUI, then automatically select it
|
||||
onChooseWallet(walletConfig);
|
||||
}
|
||||
}, [onChooseWallet, walletConfig]);
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
import { Icon } from "../../../assets/icon";
|
||||
import { useAppTheme } from "../../../styles/hooks";
|
||||
import { useGlobalTheme } from "../../../providers/ui-context-provider";
|
||||
import Text from "../../base/Text";
|
||||
import { FlexAlignType, StyleSheet, View } from "react-native";
|
||||
|
||||
@@ -20,7 +20,7 @@ export const ConnectWalletHeader = ({
|
||||
onClose,
|
||||
onBackPress,
|
||||
}: ConnectWalletHeaderProps) => {
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
return (
|
||||
<>
|
||||
<View style={styles.header}>
|
||||
|
||||
+2
-2
@@ -16,7 +16,7 @@ import * as FileSystem from "expo-file-system";
|
||||
import { TWModal } from "../base/modal/TWModal";
|
||||
import { localWallet } from "../../wallets/wallets/local-wallet";
|
||||
import { TextInput } from "../base";
|
||||
import { useAppTheme } from "../../styles/hooks";
|
||||
import { useGlobalTheme } from "../../providers/ui-context-provider";
|
||||
|
||||
export type LocalWalletImportModalProps = {
|
||||
isVisible: boolean;
|
||||
@@ -37,7 +37,7 @@ export const LocalWalletImportModal = ({
|
||||
const [error, setError] = useState<string | undefined>();
|
||||
const [isImporting, setIsImporting] = useState<boolean>(false);
|
||||
const createWalletInstance = useCreateWalletInstance();
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
|
||||
const createLocalWalletFromJsonFile = async () => {
|
||||
if (!jsonFile || !password) {
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@ import WalletLoadingThumbnail from "../../../wallets/wallets/wallet-connect/Wall
|
||||
import ImageSvgUri from "../../base/ImageSvgUri";
|
||||
import Box from "../../base/Box";
|
||||
import { ConnectWalletHeader } from "../ConnectingWallet/ConnectingWalletHeader";
|
||||
import { useAppTheme } from "../../../styles/hooks";
|
||||
import { useGlobalTheme } from "../../../providers/ui-context-provider";
|
||||
|
||||
export const SmartWalletFlow = ({
|
||||
connected,
|
||||
@@ -24,7 +24,7 @@ export const SmartWalletFlow = ({
|
||||
personalWalletConfig,
|
||||
...props
|
||||
}: ConnectUIProps<SmartWallet> & { personalWalletConfig: WalletConfig }) => {
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
const [connectedPersonalWallet, setConnectedPersonalWallet] =
|
||||
useState<WalletInstance>();
|
||||
const [personalWalletChainId, setPersonalWalletChaindId] = useState<
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { useModalState } from "../providers/ui-context-provider";
|
||||
import {
|
||||
useGlobalTheme,
|
||||
useModalState,
|
||||
} from "../providers/ui-context-provider";
|
||||
import { ConnectWalletFlow } from "./ConnectWalletFlow/ConnectWalletFlow";
|
||||
import { Dimensions, StyleSheet, View } from "react-native";
|
||||
import { useMemo } from "react";
|
||||
@@ -7,13 +10,13 @@ import { SessionRequestModal } from "./ConnectWalletDetails/SessionRequestModal"
|
||||
import { SessionProposalModal } from "./ConnectWalletDetails/SessionProposalModal";
|
||||
import { TWModal } from "./base/modal/TWModal";
|
||||
import Box from "./base/Box";
|
||||
import { useAppTheme } from "../styles/hooks";
|
||||
// import { useAppTheme } from "../styles/hooks";
|
||||
|
||||
const MODAL_HEIGHT = Dimensions.get("window").height * 0.6;
|
||||
const DEVICE_WIDTH = Dimensions.get("window").width;
|
||||
|
||||
export const MainModal = () => {
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
const { modalState } = useModalState();
|
||||
|
||||
const { isOpen, isSheet } = modalState;
|
||||
|
||||
@@ -3,14 +3,14 @@ import Box from "./base/Box";
|
||||
import { useState } from "react";
|
||||
import EyeClosed from "../assets/eye-closed";
|
||||
import EyeOpened from "../assets/eye-opened";
|
||||
import { useAppTheme } from "../styles/hooks";
|
||||
import { useGlobalTheme } from "../providers/ui-context-provider";
|
||||
|
||||
export const PasswordInput = ({
|
||||
onChangeText,
|
||||
}: {
|
||||
onChangeText: TextInput["props"]["onChangeText"];
|
||||
}) => {
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
|
||||
const onPressEyeIcon = () => {
|
||||
|
||||
@@ -2,7 +2,6 @@ import React, { useEffect, useState } from "react";
|
||||
import { IconTextButton } from "./base/IconTextButton";
|
||||
import { useAddress } from "@thirdweb-dev/react-core";
|
||||
import { Dimensions, KeyboardAvoidingView } from "react-native";
|
||||
import { useAppTheme } from "../styles/hooks";
|
||||
import {
|
||||
TWModal,
|
||||
Box,
|
||||
@@ -15,9 +14,10 @@ import {
|
||||
import DownloadIcon from "../assets/download";
|
||||
import CopyIcon from "../assets/copy";
|
||||
import QRCode from "react-native-qrcode-svg";
|
||||
import { useGlobalTheme } from "../providers/ui-context-provider";
|
||||
|
||||
export const ReceiveButton = () => {
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
const [isModalVisible, setIsModalVisible] = useState(false);
|
||||
|
||||
const onClose = () => {
|
||||
@@ -60,7 +60,7 @@ export const ReceiveFundsModal = ({
|
||||
isVisible,
|
||||
onClose,
|
||||
}: ReceiveFundsModalProps) => {
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
const address = useAddress();
|
||||
const [addressCopied, setAddressCopied] = useState(false);
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { useAppTheme } from "../../styles/hooks";
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
import SendIcon from "../../assets/send";
|
||||
import {
|
||||
@@ -30,13 +29,14 @@ import { utils } from "ethers";
|
||||
import LoadingTextAnimation from "../base/LoadingTextAnimation";
|
||||
import CheckIcon from "../../assets/check";
|
||||
import { TokenSelector } from "./TokenSelector";
|
||||
import { useGlobalTheme } from "../../providers/ui-context-provider";
|
||||
|
||||
export const SendButton = ({
|
||||
supportedTokens,
|
||||
}: {
|
||||
supportedTokens: SupportedTokens;
|
||||
}) => {
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
const [isModalVisible, setIsModalVisible] = useState(false);
|
||||
|
||||
const onClose = () => {
|
||||
@@ -139,7 +139,7 @@ const SendFundsForm = ({
|
||||
onTokenSelectorPress: () => void;
|
||||
token?: TokenInfo;
|
||||
}) => {
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
const chain = useChain();
|
||||
const wallet = useWallet();
|
||||
const chainId = useChainId();
|
||||
@@ -352,7 +352,7 @@ const SendFundsForm = ({
|
||||
) : showIcon ? (
|
||||
<CheckIcon width={20} height={13} color={theme.colors.textPrimary} />
|
||||
) : (
|
||||
<Text variant="bodySmall" mr="sm">
|
||||
<Text variant="bodySmall" color="accentButtonTextColor" mr="sm">
|
||||
Send
|
||||
</Text>
|
||||
)}
|
||||
|
||||
@@ -15,10 +15,10 @@ import {
|
||||
ScrollView,
|
||||
TextInput,
|
||||
} from "react-native";
|
||||
import { useAppTheme } from "../../styles/hooks";
|
||||
import { SelectTokenButton } from "./SelectTokenButton";
|
||||
import CloseIcon from "../../assets/close";
|
||||
import Text from "../base/Text";
|
||||
import { useGlobalTheme } from "../../providers/ui-context-provider";
|
||||
|
||||
export function useToken(tokenAddress: string): {
|
||||
isLoading: boolean;
|
||||
@@ -82,7 +82,7 @@ export function TokenSelector(props: {
|
||||
onBack: () => void;
|
||||
supportedTokens: SupportedTokens;
|
||||
}) {
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
const [input, setInput] = useState("");
|
||||
const chainId = useChainId();
|
||||
const nativeTokenInfo = useNativeToken();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useCallback, useEffect, useRef } from "react";
|
||||
import { View, Animated, Easing, StyleSheet } from "react-native";
|
||||
import { baseTheme } from "../../styles/theme";
|
||||
import { useAppTheme } from "../../styles/hooks";
|
||||
import { useGlobalTheme } from "../../providers/ui-context-provider";
|
||||
|
||||
type LoadingTextAnimationProps = {
|
||||
text: string;
|
||||
@@ -13,7 +13,7 @@ const LoadingTextAnimation = ({
|
||||
textVariant,
|
||||
}: LoadingTextAnimationProps) => {
|
||||
const fadeAnim = useRef(new Animated.Value(0)).current;
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
|
||||
const fadeInOut = useCallback(() => {
|
||||
Animated.loop(
|
||||
|
||||
@@ -14,8 +14,8 @@ import { useSwitchChain, useSupportedChains } from "@thirdweb-dev/react-core";
|
||||
import Box from "./Box";
|
||||
import { ModalHeaderTextClose } from "./modal/ModalHeaderTextClose";
|
||||
import { TWModal } from "./modal/TWModal";
|
||||
import { useAppTheme } from "../../styles/hooks";
|
||||
import { Chain } from "@thirdweb-dev/chains";
|
||||
import { useGlobalTheme } from "../../providers/ui-context-provider";
|
||||
|
||||
type NetworkButtonProps = {
|
||||
chain?: Chain;
|
||||
@@ -35,7 +35,7 @@ export const NetworkButton = ({
|
||||
padding,
|
||||
...props
|
||||
}: NetworkButtonProps) => {
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
const [isModalVisible, setIsModalVisible] = useState(false);
|
||||
const [switchError, setSwitchError] = useState<string | undefined>();
|
||||
const [isSwitching, setIsSwitching] = useState(false);
|
||||
|
||||
@@ -2,7 +2,7 @@ import { ReactElement, useEffect, useRef } from "react";
|
||||
import { Theme } from "../../styles/theme";
|
||||
import Text from "./Text";
|
||||
import { Animated, StyleSheet } from "react-native";
|
||||
import { useAppTheme } from "../../styles/hooks";
|
||||
import { useGlobalTheme } from "../../providers/ui-context-provider";
|
||||
|
||||
export const TOAST_HEIGHT = 45;
|
||||
|
||||
@@ -19,7 +19,7 @@ export function Toast({
|
||||
backgroundColor,
|
||||
translateY = TOAST_HEIGHT,
|
||||
}: ToastProps) {
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
|
||||
const translateYRef = useRef(new Animated.Value(translateY)).current;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useAppTheme } from "../../styles/hooks";
|
||||
import { useGlobalTheme } from "../../providers/ui-context-provider";
|
||||
import BaseButton from "./BaseButton";
|
||||
import Box from "./Box";
|
||||
import ImageSvgUri from "./ImageSvgUri";
|
||||
@@ -17,7 +17,7 @@ export const WalletButtonSquare = ({
|
||||
name,
|
||||
size,
|
||||
}: WalletButtonSquareProps) => {
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
|
||||
const marginVertical = theme.spacing.xs;
|
||||
return (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useGlobalTheme } from "../../../providers/ui-context-provider";
|
||||
import Text from "../Text";
|
||||
import { TouchableOpacity, StyleSheet, ActivityIndicator } from "react-native";
|
||||
import { useAppTheme } from "../../../styles/hooks";
|
||||
|
||||
export const ModalFooter = ({
|
||||
footer,
|
||||
@@ -11,7 +11,7 @@ export const ModalFooter = ({
|
||||
isLoading?: boolean;
|
||||
onPress?: () => void;
|
||||
}) => {
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
|
||||
return (
|
||||
<TouchableOpacity style={styles.footer} onPress={onPress}>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { View } from "react-native";
|
||||
import { Icon } from "../../../assets/icon";
|
||||
import { useAppTheme } from "../../../styles/hooks";
|
||||
import Box from "../Box";
|
||||
import Text from "../Text";
|
||||
import { ReactNode } from "react";
|
||||
import { useGlobalTheme } from "../../../providers/ui-context-provider";
|
||||
|
||||
interface ModalHeaderTextCloseProps {
|
||||
onClose?: () => void;
|
||||
@@ -19,7 +19,7 @@ export const ModalHeaderTextClose = ({
|
||||
onBackPress,
|
||||
...props
|
||||
}: ModalHeaderTextCloseProps & React.ComponentProps<typeof Box>) => {
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -78,7 +78,7 @@ export const useGlobalTheme = (theme?: ThemeProviderProps["theme"]): Theme => {
|
||||
const appTheme = useTheme();
|
||||
|
||||
const resultTheme = useMemo(() => {
|
||||
const resp = getThemeObj(theme) || getThemeObj(context.theme) || appTheme;
|
||||
const resp = getThemeObj(context.theme) || getThemeObj(theme) || appTheme;
|
||||
return resp;
|
||||
}, [theme, context, appTheme]);
|
||||
|
||||
|
||||
@@ -12,12 +12,12 @@ import {
|
||||
TextInput,
|
||||
TextInputKeyPressEventData,
|
||||
} from "react-native";
|
||||
import { useAppTheme } from "../../../styles/hooks";
|
||||
import { ConnectWalletHeader } from "../../../components/ConnectWalletFlow/ConnectingWallet/ConnectingWalletHeader";
|
||||
import Box from "../../../components/base/Box";
|
||||
import Text from "../../../components/base/Text";
|
||||
import BaseButton from "../../../components/base/BaseButton";
|
||||
import * as Clipboard from "expo-clipboard";
|
||||
import { useGlobalTheme } from "../../../providers/ui-context-provider";
|
||||
|
||||
const OTP_LENGTH = 6;
|
||||
|
||||
@@ -27,7 +27,7 @@ export const EmbeddedConnectionUI: React.FC<ConnectUIProps<EmbeddedWallet>> = ({
|
||||
selectionData,
|
||||
onLocallyConnected,
|
||||
}) => {
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
const inputRefs = useRef<(TextInput | null)[]>([]);
|
||||
const [values, setValues] = useState<string[]>(
|
||||
new Array(OTP_LENGTH).fill(""),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { EmbeddedWallet } from "./EmbeddedWallet";
|
||||
import { ActivityIndicator } from "react-native";
|
||||
import { useAppTheme } from "../../../styles/hooks";
|
||||
import {
|
||||
SelectUIProps,
|
||||
useCreateWalletInstance,
|
||||
@@ -10,6 +9,7 @@ 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 { useGlobalTheme } from "../../../providers/ui-context-provider";
|
||||
|
||||
/**
|
||||
* UI for selecting wallet - this UI is rendered in the wallet selection screen
|
||||
@@ -18,7 +18,7 @@ export const EmailSelectionUI: React.FC<SelectUIProps<EmbeddedWallet>> = ({
|
||||
onSelect,
|
||||
walletConfig,
|
||||
}) => {
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
const [email, setEmail] = useState<string>("");
|
||||
const [errorMessage, setErrorMessage] = useState<string>("");
|
||||
const [isFetching, setIsFetching] = useState<boolean>(false);
|
||||
|
||||
@@ -17,9 +17,9 @@ import { TextInput } from "../../components/base/TextInput";
|
||||
import Text from "../../components/base/Text";
|
||||
import { useMagicLink } from "../../providers/context-provider";
|
||||
import BaseButton from "../../components/base/BaseButton";
|
||||
import { useAppTheme } from "../../styles/hooks";
|
||||
import React from "react";
|
||||
import { ConnectingWallet } from "../../components/ConnectWalletFlow/ConnectingWallet/ConnectingWallet";
|
||||
import { useGlobalTheme } from "../../providers/ui-context-provider";
|
||||
|
||||
export const magicLink = (
|
||||
magicLinkOptions: MagicLinkOptions & { recommended?: boolean },
|
||||
@@ -54,7 +54,7 @@ export const magicLink = (
|
||||
};
|
||||
|
||||
const MagicSelectionUI: React.FC<SelectUIProps<MagicLink>> = (props) => {
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
const [email, setEmail] = React.useState("");
|
||||
|
||||
const onContinuePress = () => {
|
||||
|
||||
@@ -19,9 +19,9 @@ import {
|
||||
useSetConnectionStatus,
|
||||
} from "@thirdweb-dev/react-core";
|
||||
import { WalletConnect } from "./WalletConnect";
|
||||
import { useAppTheme } from "../../../styles/hooks";
|
||||
import { WalletConnectButton } from "./WalletConnectButton";
|
||||
import { ModalHeaderTextClose } from "../../../components/base";
|
||||
import { useGlobalTheme } from "../../../providers/ui-context-provider";
|
||||
|
||||
type WCWallet = {
|
||||
iconURL: string;
|
||||
@@ -41,7 +41,7 @@ export function WalletConnectUI({
|
||||
goBack,
|
||||
projectId,
|
||||
}: ConnectUIProps<WalletConnect> & { projectId: string }) {
|
||||
const theme = useAppTheme();
|
||||
const theme = useGlobalTheme();
|
||||
const [wallets, setWallets] = useState<WCWallet[]>([]);
|
||||
const [error, setError] = useState<string | undefined>();
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import { Animated, Easing, StyleSheet, View } from "react-native";
|
||||
import Svg, { Rect } from "react-native-svg";
|
||||
import { useAppTheme } from "../../../styles/hooks";
|
||||
import { useGlobalTheme } from "../../../providers/ui-context-provider";
|
||||
|
||||
const AnimatedRect = Animated.createAnimatedComponent(Rect);
|
||||
|
||||
@@ -19,7 +19,7 @@ function WalletLoadingThumbnail({
|
||||
showError,
|
||||
imageSize = 50,
|
||||
}: Props) {
|
||||
const Theme = useAppTheme();
|
||||
const Theme = useGlobalTheme();
|
||||
const spinValue = useRef(new Animated.Value(0));
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
# @thirdweb-dev/react
|
||||
|
||||
## 4.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1750](https://github.com/thirdweb-dev/js/pull/1750) [`bb1666b9`](https://github.com/thirdweb-dev/js/commit/bb1666b92b5e151d78ea7dae6831297fb947d954) Thanks [@MananTank](https://github.com/MananTank)! - ConnectWallet UI tweaks/fixes
|
||||
|
||||
- Updated dependencies [[`1f3c64d3`](https://github.com/thirdweb-dev/js/commit/1f3c64d3618903b9008cc7b633ea890b508e7800), [`74941603`](https://github.com/thirdweb-dev/js/commit/74941603a96456da46a47147f67c98235ac55022), [`4b98e487`](https://github.com/thirdweb-dev/js/commit/4b98e487d4b47225d7095e5444dc5e7608db48a3), [`693f349d`](https://github.com/thirdweb-dev/js/commit/693f349db2478e1cd0fc82a9ef9882f46832b125), [`dcdb0dcb`](https://github.com/thirdweb-dev/js/commit/dcdb0dcb838168a22c8335738852316dfb6e6fc9), [`0f12d1f9`](https://github.com/thirdweb-dev/js/commit/0f12d1f90320923309f085c372d3a5ed01dd4606), [`b3b9edca`](https://github.com/thirdweb-dev/js/commit/b3b9edca29e7d4053b14270a61caa89c34fecf9e), [`63ad0050`](https://github.com/thirdweb-dev/js/commit/63ad0050f0a24ec15b90933b5664d697618cf2d0)]:
|
||||
- @thirdweb-dev/sdk@4.0.1
|
||||
- @thirdweb-dev/wallets@2.0.2
|
||||
- @thirdweb-dev/react-core@4.0.2
|
||||
|
||||
## 4.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react",
|
||||
"version": "4.0.1",
|
||||
"version": "4.0.2",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -1,7 +1,22 @@
|
||||
import styled from "@emotion/styled";
|
||||
import { fontSize, Theme } from "../design-system";
|
||||
import { fontSize, spacing, Theme } from "../design-system";
|
||||
|
||||
export const TextDivider = styled.div<{ theme?: Theme }>`
|
||||
export const TextDivider = (props: {
|
||||
text: string;
|
||||
py?: keyof typeof spacing;
|
||||
}) => {
|
||||
return (
|
||||
<TextDividerEl
|
||||
style={{
|
||||
paddingBlock: props.py ? spacing[props.py] : 0,
|
||||
}}
|
||||
>
|
||||
<span> {props.text}</span>
|
||||
</TextDividerEl>
|
||||
);
|
||||
};
|
||||
|
||||
export const TextDividerEl = styled.div<{ theme?: Theme }>`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: ${(p) => p.theme.colors.secondaryText};
|
||||
|
||||
@@ -63,13 +63,13 @@ function createThemeObj(colors: typeof darkColors) {
|
||||
scrollbarBg: colors.base2,
|
||||
walletSelectorButtonHoverBg: colors.base2,
|
||||
|
||||
separatorLine: colors.base3,
|
||||
separatorLine: colors.base4,
|
||||
|
||||
secondaryIconColor: colors.secondaryText,
|
||||
secondaryIconHoverBg: colors.base3,
|
||||
secondaryIconHoverColor: colors.primaryText,
|
||||
|
||||
borderColor: colors.base3,
|
||||
borderColor: colors.base4,
|
||||
skeletonBg: colors.base3,
|
||||
|
||||
selectedTextColor: colors.base1,
|
||||
|
||||
@@ -62,4 +62,5 @@ export {
|
||||
MagicLink,
|
||||
SignerWallet,
|
||||
InjectedWallet,
|
||||
setWalletAnalyticsEnabled,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
|
||||
@@ -290,7 +290,7 @@ export function SendFundsForm(props: {
|
||||
</CurrencyBadge>
|
||||
</Container>
|
||||
|
||||
<Spacer y="xl" />
|
||||
<Spacer y="xxl" />
|
||||
|
||||
{/* Submit */}
|
||||
<Button
|
||||
@@ -307,6 +307,7 @@ export function SendFundsForm(props: {
|
||||
style={{
|
||||
alignItems: "center",
|
||||
gap: spacing.sm,
|
||||
padding: spacing.md,
|
||||
}}
|
||||
>
|
||||
{sendTokenMutation.isLoading ? "Sending" : "Send"}
|
||||
|
||||
@@ -56,20 +56,6 @@ export const WalletSelector: React.FC<{
|
||||
nonLocalWalletConfigs.filter((w) => w.category !== "socialLogin"),
|
||||
);
|
||||
|
||||
const showNewToWallets =
|
||||
isCompact && (socialWallets.length === 0 || isWalletGroupExpanded);
|
||||
|
||||
// groups UI is showing a social login + grouping all eoa wallets together in a group
|
||||
// do this if there is social login and more than 2 eoa wallets
|
||||
const showGroupsUI =
|
||||
isCompact && socialWallets.length >= 1 && eoaWallets.length >= 2;
|
||||
|
||||
const showTOS = isCompact && (termsOfServiceUrl || privacyPolicyUrl);
|
||||
|
||||
const showFooter = Boolean(
|
||||
(!showGroupsUI && localWalletConfig) || showNewToWallets,
|
||||
);
|
||||
|
||||
const continueAsGuest = localWalletConfig && (
|
||||
<Button
|
||||
fullWidth
|
||||
@@ -138,7 +124,217 @@ export const WalletSelector: React.FC<{
|
||||
props.selectWallet(wallet);
|
||||
};
|
||||
|
||||
const showSeperatorLine = showNewToWallets && !continueAsGuest && showTOS;
|
||||
const connectAWallet = (
|
||||
<Button
|
||||
fullWidth
|
||||
variant="outline"
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
gap: spacing.sm,
|
||||
padding: spacing.md,
|
||||
}}
|
||||
onClick={() => {
|
||||
setIsWalletGroupExpanded(true);
|
||||
}}
|
||||
>
|
||||
<Container flex="row" gap="xxs">
|
||||
{eoaWallets.slice(0, 2).map((w) => (
|
||||
<Img
|
||||
key={w.id}
|
||||
width={iconSize.sm}
|
||||
height={iconSize.sm}
|
||||
src={w.meta.iconURL}
|
||||
/>
|
||||
))}
|
||||
</Container>
|
||||
Connect a wallet
|
||||
</Button>
|
||||
);
|
||||
|
||||
const newToWallets = (
|
||||
<Container
|
||||
flex="row"
|
||||
style={{
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<Text color="secondaryText" size="sm" weight={500}>
|
||||
New to wallets?
|
||||
</Text>
|
||||
<Link
|
||||
weight={500}
|
||||
size="sm"
|
||||
target="_blank"
|
||||
href="https://blog.thirdweb.com/web3-wallet/"
|
||||
>
|
||||
Get started
|
||||
</Link>
|
||||
</Container>
|
||||
);
|
||||
|
||||
const tos =
|
||||
termsOfServiceUrl || privacyPolicyUrl ? (
|
||||
<TOS
|
||||
termsOfServiceUrl={termsOfServiceUrl}
|
||||
privacyPolicyUrl={privacyPolicyUrl}
|
||||
/>
|
||||
) : undefined;
|
||||
|
||||
let topSection: React.ReactNode;
|
||||
let bottomSection: React.ReactNode;
|
||||
|
||||
// wide modal
|
||||
if (!isCompact) {
|
||||
topSection = (
|
||||
<WalletSelection
|
||||
walletConfigs={nonLocalWalletConfigs}
|
||||
selectWallet={handleSelect}
|
||||
/>
|
||||
);
|
||||
|
||||
if (continueAsGuest) {
|
||||
bottomSection = (
|
||||
<ScreenBottomContainer>{continueAsGuest}</ScreenBottomContainer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// compact
|
||||
else {
|
||||
// no social logins
|
||||
if (socialWallets.length === 0) {
|
||||
topSection = (
|
||||
<WalletSelection
|
||||
walletConfigs={nonLocalWalletConfigs}
|
||||
selectWallet={handleSelect}
|
||||
/>
|
||||
);
|
||||
|
||||
bottomSection = (
|
||||
<>
|
||||
<Line />
|
||||
<Container flex="column" p="lg" gap="lg">
|
||||
{newToWallets}
|
||||
{continueAsGuest}
|
||||
</Container>
|
||||
{!continueAsGuest && <Line />}
|
||||
{tos && (
|
||||
<Container
|
||||
px="md"
|
||||
style={{
|
||||
paddingBottom: spacing.md,
|
||||
paddingTop: continueAsGuest ? 0 : spacing.md,
|
||||
}}
|
||||
>
|
||||
{tos}
|
||||
</Container>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
// social logins
|
||||
else {
|
||||
// not expanded state
|
||||
if (!isWalletGroupExpanded) {
|
||||
topSection = (
|
||||
<Container px="xs">
|
||||
<WalletSelection
|
||||
walletConfigs={socialWallets}
|
||||
selectWallet={handleSelect}
|
||||
/>
|
||||
{eoaWallets.length > 0 && (
|
||||
<>
|
||||
<TextDivider text="OR" />
|
||||
<Spacer y="lg" />
|
||||
</>
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
|
||||
// only social login - no eoa wallets
|
||||
if (eoaWallets.length === 0) {
|
||||
bottomSection = tos ? (
|
||||
<>
|
||||
<Spacer y="md" />
|
||||
<Line />
|
||||
{continueAsGuest && (
|
||||
<Container p="lg"> {continueAsGuest}</Container>
|
||||
)}
|
||||
{tos && <Container p="md"> {tos} </Container>}
|
||||
</>
|
||||
) : (
|
||||
<Spacer y="sm" />
|
||||
);
|
||||
}
|
||||
|
||||
// social login + eoa wallets
|
||||
else {
|
||||
// social login + More than 1 eoa wallets
|
||||
if (eoaWallets.length > 1) {
|
||||
bottomSection = (
|
||||
<Container flex="column" gap="sm">
|
||||
<Container px="lg" flex="column" gap="md">
|
||||
{connectAWallet}
|
||||
{continueAsGuest}
|
||||
</Container>
|
||||
|
||||
{tos ? (
|
||||
<Container p="md"> {tos} </Container>
|
||||
) : (
|
||||
<Spacer y="md" />
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
// social login + single eoa wallet
|
||||
else {
|
||||
bottomSection = (
|
||||
<>
|
||||
<Container px="lg">
|
||||
<WalletSelection
|
||||
walletConfigs={eoaWallets}
|
||||
selectWallet={handleSelect}
|
||||
/>
|
||||
</Container>
|
||||
|
||||
{continueAsGuest && (
|
||||
<Container flex="column" px="lg" gap="lg">
|
||||
{continueAsGuest}
|
||||
</Container>
|
||||
)}
|
||||
|
||||
{tos ? (
|
||||
<>
|
||||
{continueAsGuest ? <Spacer y="md" /> : <Line />}
|
||||
<Container p="md"> {tos} </Container>
|
||||
</>
|
||||
) : (
|
||||
<>{continueAsGuest && <Spacer y="xl" />}</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// expanded state
|
||||
else {
|
||||
topSection = (
|
||||
<WalletSelection
|
||||
walletConfigs={eoaWallets}
|
||||
selectWallet={handleSelect}
|
||||
/>
|
||||
);
|
||||
|
||||
bottomSection = (
|
||||
<ScreenBottomContainer>{newToWallets}</ScreenBottomContainer>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Container scrollY flex="column" animate="fadein" fullHeight>
|
||||
@@ -160,130 +356,15 @@ export const WalletSelector: React.FC<{
|
||||
<Container
|
||||
expand
|
||||
scrollY
|
||||
px={nonLocalWalletConfigs.length === 1 ? "lg" : "md"}
|
||||
px="md"
|
||||
style={{
|
||||
paddingTop: "2px",
|
||||
}}
|
||||
>
|
||||
{showGroupsUI ? (
|
||||
<>
|
||||
{/* list of EOA wallets */}
|
||||
{isWalletGroupExpanded ? (
|
||||
<WalletSelection
|
||||
walletConfigs={eoaWallets}
|
||||
selectWallet={handleSelect}
|
||||
/>
|
||||
) : (
|
||||
<Container px="xs">
|
||||
<WalletSelection
|
||||
walletConfigs={socialWallets}
|
||||
selectWallet={handleSelect}
|
||||
/>
|
||||
|
||||
<TextDivider>
|
||||
<span> OR </span>
|
||||
</TextDivider>
|
||||
|
||||
<Spacer y="lg" />
|
||||
|
||||
{/* connect a wallet */}
|
||||
<Button
|
||||
fullWidth
|
||||
variant="outline"
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
gap: spacing.sm,
|
||||
padding: spacing.md,
|
||||
}}
|
||||
onClick={() => {
|
||||
setIsWalletGroupExpanded(true);
|
||||
}}
|
||||
>
|
||||
<Container flex="row" gap="xxs">
|
||||
{eoaWallets.slice(0, 2).map((w) => (
|
||||
<Img
|
||||
key={w.id}
|
||||
width={iconSize.sm}
|
||||
height={iconSize.sm}
|
||||
src={w.meta.iconURL}
|
||||
/>
|
||||
))}
|
||||
</Container>
|
||||
Connect a wallet
|
||||
</Button>
|
||||
|
||||
{continueAsGuest ? (
|
||||
<>
|
||||
<Spacer y="md" />
|
||||
{continueAsGuest}
|
||||
<Spacer y="xl" />
|
||||
</>
|
||||
) : (
|
||||
<Spacer y="xl" />
|
||||
)}
|
||||
</Container>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<WalletSelection
|
||||
walletConfigs={nonLocalWalletConfigs}
|
||||
selectWallet={handleSelect}
|
||||
/>
|
||||
)}
|
||||
{topSection}
|
||||
</Container>
|
||||
|
||||
{/* Footer */}
|
||||
{showFooter && (
|
||||
<ScreenBottomContainer>
|
||||
{showNewToWallets && (
|
||||
<Container
|
||||
flex="row"
|
||||
style={{
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<Text color="secondaryText" size="sm" weight={500}>
|
||||
New to wallets?
|
||||
</Text>
|
||||
<Link
|
||||
weight={500}
|
||||
size="sm"
|
||||
target="_blank"
|
||||
href="https://blog.thirdweb.com/web3-wallet/"
|
||||
>
|
||||
Get started
|
||||
</Link>
|
||||
</Container>
|
||||
)}
|
||||
|
||||
{!showGroupsUI && continueAsGuest}
|
||||
</ScreenBottomContainer>
|
||||
)}
|
||||
|
||||
{showTOS && !isWalletGroupExpanded && (
|
||||
<div>
|
||||
{showSeperatorLine && <Line />}
|
||||
|
||||
<Container
|
||||
p="md"
|
||||
style={
|
||||
!showSeperatorLine
|
||||
? {
|
||||
paddingTop: 0,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
{isCompact && (
|
||||
<TOS
|
||||
termsOfServiceUrl={termsOfServiceUrl}
|
||||
privacyPolicyUrl={privacyPolicyUrl}
|
||||
/>
|
||||
)}
|
||||
</Container>
|
||||
</div>
|
||||
)}
|
||||
{bottomSection}
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
@@ -383,7 +464,7 @@ const WalletList = styled.ul<{ theme?: Theme }>`
|
||||
margin: -2px;
|
||||
padding-bottom: 0;
|
||||
margin-bottom: 0;
|
||||
padding-bottom: ${spacing.xl};
|
||||
padding-bottom: ${spacing.lg};
|
||||
`;
|
||||
|
||||
const WalletButton = styled.button<{ theme?: Theme }>`
|
||||
@@ -428,7 +509,7 @@ function sortWalletConfigs(walletConfigs: WalletConfig[]) {
|
||||
}
|
||||
return 0;
|
||||
})
|
||||
// show the reccomended wallets even before that
|
||||
// show the recommended wallets even before that
|
||||
.sort((a, b) => {
|
||||
if (a.recommended && !b.recommended) {
|
||||
return -1;
|
||||
|
||||
@@ -64,15 +64,7 @@ export const EmbeddedWalletFormUI = (props: {
|
||||
<GoogleIcon size={iconSize.md} />
|
||||
Sign in with Google
|
||||
</SocialButton>
|
||||
|
||||
<Spacer y="lg" />
|
||||
|
||||
<TextDivider>
|
||||
<span>OR</span>
|
||||
</TextDivider>
|
||||
|
||||
<Spacer y="lg" />
|
||||
|
||||
<TextDivider text="OR" py="lg" />
|
||||
<InputSelectionUI
|
||||
onSelect={(email) => props.onSelect({ email })}
|
||||
placeholder="Enter your email address"
|
||||
|
||||
@@ -114,10 +114,10 @@ export const EmbeddedWalletOTPLoginUI: React.FC<
|
||||
}}
|
||||
>
|
||||
{!isWideModal && <Spacer y="xl" />}
|
||||
<Text>Enter the OTP sent to</Text>
|
||||
<Text>Enter the verification code sent to</Text>
|
||||
<Spacer y="sm" />
|
||||
<Text color="primaryText">{email}</Text>
|
||||
<Spacer y="xxl" />
|
||||
<Spacer y="xl" />
|
||||
</div>
|
||||
|
||||
<OTPInput
|
||||
@@ -138,12 +138,12 @@ export const EmbeddedWalletOTPLoginUI: React.FC<
|
||||
<FadeIn>
|
||||
<Spacer y="md" />
|
||||
<Text size="sm" color="danger" center>
|
||||
Invalid OTP
|
||||
Invalid verification code
|
||||
</Text>
|
||||
</FadeIn>
|
||||
)}
|
||||
|
||||
<Spacer y="xxl" />
|
||||
<Spacer y="xl" />
|
||||
|
||||
<Container px={isWideModal ? "xxl" : "lg"}>
|
||||
{verifyStatus === "verifying" ? (
|
||||
@@ -168,7 +168,7 @@ export const EmbeddedWalletOTPLoginUI: React.FC<
|
||||
)}
|
||||
</Container>
|
||||
|
||||
<Spacer y="xxl" />
|
||||
<Spacer y="xl" />
|
||||
|
||||
{!isWideModal && <Line />}
|
||||
|
||||
@@ -176,7 +176,7 @@ export const EmbeddedWalletOTPLoginUI: React.FC<
|
||||
{sendEmailOtpStatus === "error" && (
|
||||
<>
|
||||
<Text size="sm" center color="danger">
|
||||
Failed to send OTP
|
||||
Failed to send verification code
|
||||
</Text>
|
||||
</>
|
||||
)}
|
||||
@@ -190,14 +190,14 @@ export const EmbeddedWalletOTPLoginUI: React.FC<
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
<Text size="sm">Sending OTP</Text>
|
||||
<Text size="sm">Sending verification code</Text>
|
||||
<Spinner size="xs" color="secondaryText" />
|
||||
</Container>
|
||||
)}
|
||||
|
||||
{sendEmailOtpStatus === "sent" && (
|
||||
<LinkButton onClick={sendEmail} type="button">
|
||||
Resend OTP
|
||||
Resend verification code
|
||||
</LinkButton>
|
||||
)}
|
||||
</Container>
|
||||
|
||||
@@ -256,11 +256,7 @@ const MagicUI: React.FC<{
|
||||
|
||||
{showInputUI && (
|
||||
<>
|
||||
{showSeparator && (
|
||||
<TextDivider>
|
||||
<span> OR </span>
|
||||
</TextDivider>
|
||||
)}
|
||||
{showSeparator && <TextDivider text="OR" />}
|
||||
<InputSelectionUI
|
||||
onSelect={props.onSelect}
|
||||
placeholder={placeholder}
|
||||
|
||||
@@ -67,13 +67,7 @@ export const PaperFormUI = (props: {
|
||||
Sign in with Google
|
||||
</SocialButton>
|
||||
|
||||
<Spacer y="lg" />
|
||||
|
||||
<TextDivider>
|
||||
<span>OR</span>
|
||||
</TextDivider>
|
||||
|
||||
<Spacer y="lg" />
|
||||
<TextDivider text="OR" py="lg" />
|
||||
</>
|
||||
)}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import styled from "@emotion/styled";
|
||||
import { ConnectUIProps, useWalletContext } from "@thirdweb-dev/react-core";
|
||||
import { PaperWallet } from "@thirdweb-dev/wallets";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { FadeIn } from "../../../components/FadeIn";
|
||||
import { OTPInput } from "../../../components/OTPInput";
|
||||
import { Spacer } from "../../../components/Spacer";
|
||||
import { Spinner } from "../../../components/Spinner";
|
||||
@@ -135,7 +134,7 @@ export const PaperOTPLoginUI: React.FC<PaperOTPLoginUIProps> = (props) => {
|
||||
}}
|
||||
>
|
||||
{!isWideModal && <Spacer y="lg" />}
|
||||
<Text>Enter the OTP sent to</Text>
|
||||
<Text>Enter the verification code sent to</Text>
|
||||
<Spacer y="sm" />
|
||||
<Text color="primaryText">{email}</Text>
|
||||
<Spacer y="xl" />
|
||||
@@ -159,6 +158,7 @@ export const PaperOTPLoginUI: React.FC<PaperOTPLoginUIProps> = (props) => {
|
||||
|
||||
{recoveryCodeRequired && (
|
||||
<Container
|
||||
animate="fadein"
|
||||
px="lg"
|
||||
style={{
|
||||
textAlign: "center",
|
||||
@@ -197,15 +197,16 @@ export const PaperOTPLoginUI: React.FC<PaperOTPLoginUIProps> = (props) => {
|
||||
)}
|
||||
|
||||
{verifyStatus === "invalid" && (
|
||||
<FadeIn>
|
||||
<Container animate="fadein">
|
||||
<Spacer y="md" />
|
||||
<Text size="sm" color="danger" center>
|
||||
Invalid OTP {recoveryCodeRequired ? "or recovery code" : ""}
|
||||
Invalid verification code{" "}
|
||||
{recoveryCodeRequired ? "or recovery code" : ""}
|
||||
</Text>
|
||||
</FadeIn>
|
||||
</Container>
|
||||
)}
|
||||
|
||||
<Spacer y={recoveryCodeRequired ? "xl" : "xxl"} />
|
||||
<Spacer y="xl" />
|
||||
|
||||
<Container px={isWideModal ? "xxl" : "lg"}>
|
||||
{verifyStatus === "verifying" ? (
|
||||
@@ -230,15 +231,15 @@ export const PaperOTPLoginUI: React.FC<PaperOTPLoginUIProps> = (props) => {
|
||||
)}
|
||||
</Container>
|
||||
|
||||
<Spacer y={recoveryCodeRequired ? "xl" : "xxl"} />
|
||||
<Spacer y={"xl"} />
|
||||
|
||||
{!isWideModal && <Line />}
|
||||
|
||||
<Container p={isWideModal ? undefined : "lg"}>
|
||||
<Container p={isWideModal ? undefined : "lg"} animate="fadein">
|
||||
{sendEmailStatus === "error" && (
|
||||
<>
|
||||
<Text size="sm" center color="danger">
|
||||
Failed to send OTP
|
||||
Failed to send verification code
|
||||
</Text>
|
||||
</>
|
||||
)}
|
||||
@@ -252,14 +253,14 @@ export const PaperOTPLoginUI: React.FC<PaperOTPLoginUIProps> = (props) => {
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
<Text size="sm">Sending OTP</Text>
|
||||
<Text size="sm">Sending verification code</Text>
|
||||
<Spinner size="xs" color="secondaryText" />
|
||||
</Container>
|
||||
)}
|
||||
|
||||
{typeof sendEmailStatus !== "string" && (
|
||||
<LinkButton onClick={sendEmail} type="button">
|
||||
Resend OTP
|
||||
Resend verification code
|
||||
</LinkButton>
|
||||
)}
|
||||
</Container>
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# @thirdweb-dev/sdk
|
||||
|
||||
## 4.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1747](https://github.com/thirdweb-dev/js/pull/1747) [`1f3c64d3`](https://github.com/thirdweb-dev/js/commit/1f3c64d3618903b9008cc7b633ea890b508e7800) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Handle upgradeable proxies and optimize proxy resolution
|
||||
|
||||
- [#1695](https://github.com/thirdweb-dev/js/pull/1695) [`693f349d`](https://github.com/thirdweb-dev/js/commit/693f349db2478e1cd0fc82a9ef9882f46832b125) Thanks [@kien-ngo](https://github.com/kien-ngo)! - Add optional pagination to getOwned NFTs
|
||||
|
||||
- [#1746](https://github.com/thirdweb-dev/js/pull/1746) [`0f12d1f9`](https://github.com/thirdweb-dev/js/commit/0f12d1f90320923309f085c372d3a5ed01dd4606) Thanks [@farhanW3](https://github.com/farhanW3)! - Fix for RPC Override Implementation to get user provided Url and not default RPC Url for the chain
|
||||
|
||||
- [#1757](https://github.com/thirdweb-dev/js/pull/1757) [`63ad0050`](https://github.com/thirdweb-dev/js/commit/63ad0050f0a24ec15b90933b5664d697618cf2d0) Thanks [@kumaryash90](https://github.com/kumaryash90)! - Update deployment and tests for MarketplaceV3 latest
|
||||
|
||||
- Updated dependencies [[`63ad0050`](https://github.com/thirdweb-dev/js/commit/63ad0050f0a24ec15b90933b5664d697618cf2d0)]:
|
||||
- @thirdweb-dev/contracts-js@1.3.14
|
||||
|
||||
## 4.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/sdk",
|
||||
"version": "4.0.0",
|
||||
"version": "4.0.1",
|
||||
"description": "The main thirdweb SDK.",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/sdk",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -135,7 +135,7 @@ export async function encodeConstructorParamsForImplementation(
|
||||
compilerMetadata.abi,
|
||||
);
|
||||
const constructorParamTypes = constructorParams.map((p) => {
|
||||
if (p.type === "tuple[]") {
|
||||
if (p.type === "tuple[]" || p.type === "tuple") {
|
||||
return utils.ParamType.from(p);
|
||||
} else {
|
||||
return p.type;
|
||||
@@ -156,31 +156,13 @@ export async function encodeConstructorParamsForImplementation(
|
||||
return constructorParamMap[p.name].value;
|
||||
}
|
||||
if (p.name && p.name.includes("nativeTokenWrapper")) {
|
||||
const chainId = (await provider.getNetwork()).chainId;
|
||||
let nativeTokenWrapperAddress =
|
||||
getNativeTokenByChainId(chainId).wrapped.address;
|
||||
|
||||
if (nativeTokenWrapperAddress === constants.AddressZero) {
|
||||
const deploymentInfo = await computeDeploymentInfo(
|
||||
"infra",
|
||||
provider,
|
||||
storage,
|
||||
create2Factory,
|
||||
{
|
||||
contractName: "WETH9",
|
||||
},
|
||||
clientId,
|
||||
secretKey,
|
||||
);
|
||||
if (!caches.deploymentPresets["WETH9"]) {
|
||||
caches.deploymentPresets["WETH9"] = deploymentInfo;
|
||||
}
|
||||
|
||||
nativeTokenWrapperAddress =
|
||||
deploymentInfo.transaction.predictedAddress;
|
||||
}
|
||||
|
||||
return nativeTokenWrapperAddress;
|
||||
return await nativeTokenInputArg(
|
||||
provider,
|
||||
storage,
|
||||
create2Factory,
|
||||
clientId,
|
||||
secretKey,
|
||||
);
|
||||
} else if (p.name && p.name.includes("trustedForwarder")) {
|
||||
if (compilerMetadata.name === "Pack") {
|
||||
// EOAForwarder for Pack
|
||||
@@ -220,6 +202,27 @@ export async function encodeConstructorParamsForImplementation(
|
||||
} else if (p.name && p.name.includes("royaltyEngineAddress")) {
|
||||
const chainId = (await provider.getNetwork()).chainId;
|
||||
return getRoyaltyEngineV1ByChainId(chainId);
|
||||
} else if (p.name && p.name.includes("marketplaceV3Params")) {
|
||||
const chainId = (await provider.getNetwork()).chainId;
|
||||
const royaltyEngineAddress = getRoyaltyEngineV1ByChainId(chainId);
|
||||
|
||||
const nativeTokenWrapper = await nativeTokenInputArg(
|
||||
provider,
|
||||
storage,
|
||||
create2Factory,
|
||||
clientId,
|
||||
secretKey,
|
||||
);
|
||||
|
||||
const extensions = constructorParamMap
|
||||
? constructorParamMap["_extensions"].value
|
||||
: [];
|
||||
|
||||
return {
|
||||
extensions: extensions,
|
||||
royaltyEngineAddress: royaltyEngineAddress,
|
||||
nativeTokenWrapper: nativeTokenWrapper,
|
||||
};
|
||||
} else {
|
||||
throw new Error("Can't resolve constructor arguments");
|
||||
}
|
||||
@@ -232,3 +235,36 @@ export async function encodeConstructorParamsForImplementation(
|
||||
);
|
||||
return encodedArgs;
|
||||
}
|
||||
|
||||
async function nativeTokenInputArg(
|
||||
provider: providers.Provider,
|
||||
storage: ThirdwebStorage,
|
||||
create2Factory: string,
|
||||
clientId?: string,
|
||||
secretKey?: string,
|
||||
): Promise<string> {
|
||||
const chainId = (await provider.getNetwork()).chainId;
|
||||
let nativeTokenWrapperAddress =
|
||||
getNativeTokenByChainId(chainId).wrapped.address;
|
||||
|
||||
if (nativeTokenWrapperAddress === constants.AddressZero) {
|
||||
const deploymentInfo = await computeDeploymentInfo(
|
||||
"infra",
|
||||
provider,
|
||||
storage,
|
||||
create2Factory,
|
||||
{
|
||||
contractName: "WETH9",
|
||||
},
|
||||
clientId,
|
||||
secretKey,
|
||||
);
|
||||
if (!caches.deploymentPresets["WETH9"]) {
|
||||
caches.deploymentPresets["WETH9"] = deploymentInfo;
|
||||
}
|
||||
|
||||
nativeTokenWrapperAddress = deploymentInfo.transaction.predictedAddress;
|
||||
}
|
||||
|
||||
return nativeTokenWrapperAddress;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BigNumber, providers, constants, utils } from "ethers";
|
||||
import { BigNumber, providers, constants, utils, Contract } from "ethers";
|
||||
import { extractIPFSHashFromBytecode } from "./extractIPFSHashFromBytecode";
|
||||
import { extractMinimalProxyImplementationAddress } from "./extractMinimalProxyImplementationAddress";
|
||||
|
||||
@@ -33,32 +33,65 @@ export async function resolveImplementation(
|
||||
address: string,
|
||||
provider: providers.Provider,
|
||||
): Promise<{ address: string; bytecode: string }> {
|
||||
let bytecode;
|
||||
const bytecode = await fetchBytecode(address, provider);
|
||||
|
||||
// check minimal proxy first synchronously
|
||||
const minimalProxyImplementationAddress =
|
||||
extractMinimalProxyImplementationAddress(bytecode);
|
||||
if (minimalProxyImplementationAddress) {
|
||||
return {
|
||||
address: minimalProxyImplementationAddress,
|
||||
bytecode: await fetchBytecode(
|
||||
minimalProxyImplementationAddress,
|
||||
provider,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
// check other proxy types
|
||||
const impl = await Promise.all([
|
||||
getImplementationFromStorageSlot(address, provider),
|
||||
getImplementationFromContractCall(address, provider),
|
||||
]);
|
||||
|
||||
for (const implementationAddress of impl) {
|
||||
if (
|
||||
implementationAddress &&
|
||||
utils.isAddress(implementationAddress) &&
|
||||
implementationAddress !== constants.AddressZero
|
||||
) {
|
||||
return {
|
||||
address: implementationAddress,
|
||||
bytecode: await fetchBytecode(implementationAddress, provider),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return { address, bytecode };
|
||||
}
|
||||
|
||||
async function fetchBytecode(
|
||||
address: string,
|
||||
provider: providers.Provider,
|
||||
): Promise<string> {
|
||||
try {
|
||||
bytecode = await provider.getCode(address);
|
||||
const bytecode = await provider.getCode(address);
|
||||
if (bytecode === "0x") {
|
||||
const chain = await provider.getNetwork();
|
||||
throw new Error(
|
||||
`Contract at ${address} does not exist on chain '${chain.name}' (chainId: ${chain.chainId})`,
|
||||
);
|
||||
}
|
||||
return bytecode;
|
||||
} catch (e) {
|
||||
throw new Error(`Failed to get bytecode for address ${address}: ${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (bytecode === "0x") {
|
||||
const chain = await provider.getNetwork();
|
||||
throw new Error(
|
||||
`Contract at ${address} does not exist on chain '${chain.name}' (chainId: ${chain.chainId})`,
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
// TODO support other types of proxies
|
||||
const implementationAddress =
|
||||
extractMinimalProxyImplementationAddress(bytecode);
|
||||
if (implementationAddress) {
|
||||
return await resolveImplementation(implementationAddress, provider);
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
// EIP-1967 proxy storage slots - https://eips.ethereum.org/EIPS/eip-1967
|
||||
async function getImplementationFromStorageSlot(
|
||||
address: string,
|
||||
provider: providers.Provider,
|
||||
): Promise<string | undefined> {
|
||||
try {
|
||||
const proxyStorage = await provider.getStorageAt(
|
||||
address,
|
||||
@@ -66,18 +99,36 @@ export async function resolveImplementation(
|
||||
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc",
|
||||
),
|
||||
);
|
||||
const implementationAddress = `0x${proxyStorage.slice(-40)}`;
|
||||
if (
|
||||
utils.isAddress(implementationAddress) &&
|
||||
implementationAddress !== constants.AddressZero
|
||||
) {
|
||||
return await resolveImplementation(implementationAddress, provider);
|
||||
}
|
||||
return `0x${proxyStorage.slice(-40)}`;
|
||||
} catch (e) {
|
||||
// ignore
|
||||
return undefined;
|
||||
}
|
||||
if (!bytecode) {
|
||||
throw new Error(`Error fetching bytecode for ${address}`);
|
||||
}
|
||||
return { address, bytecode };
|
||||
}
|
||||
|
||||
async function getImplementationFromContractCall(
|
||||
address: string,
|
||||
provider: providers.Provider,
|
||||
): Promise<string | undefined> {
|
||||
try {
|
||||
const proxy = new Contract(address, UPGRADEABLE_PROXY_ABI, provider);
|
||||
return await proxy.implementation();
|
||||
} catch (e) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
const UPGRADEABLE_PROXY_ABI = [
|
||||
{
|
||||
type: "function",
|
||||
name: "implementation",
|
||||
inputs: [],
|
||||
outputs: [
|
||||
{
|
||||
type: "address",
|
||||
name: "",
|
||||
internalType: "address",
|
||||
},
|
||||
],
|
||||
stateMutability: "view",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -14,7 +14,7 @@ import IMintableERC721Abi from "@thirdweb-dev/contracts-js/dist/abis/IMintableER
|
||||
import MulticallAbi from "@thirdweb-dev/contracts-js/dist/abis/IMulticall.json";
|
||||
import SignatureMintERC721Abi from "@thirdweb-dev/contracts-js/dist/abis/ISignatureMintERC721.json";
|
||||
import SignatureMintERC721_V1Abi from "@thirdweb-dev/contracts-js/dist/abis/ISignatureMintERC721_V1.json";
|
||||
import TieredDropAbi from "@thirdweb-dev/contracts-js/dist/abis/LazyMintWithTier.json";
|
||||
import TieredDropAbi from "@thirdweb-dev/contracts-js/dist/abis/LazyMintWithTier_V1.json";
|
||||
import SharedMetadataAbi from "@thirdweb-dev/contracts-js/dist/abis/SharedMetadata.json";
|
||||
import zora_IDropERC721 from "@thirdweb-dev/contracts-js/dist/abis/zora_IERC721Drop.json";
|
||||
import ILoyaltyCardAbi from "@thirdweb-dev/contracts-js/dist/abis/ILoyaltyCard.json";
|
||||
|
||||
@@ -44,7 +44,7 @@ export function getChainProvider(
|
||||
options.supportedChains = [
|
||||
// @ts-expect-error - we know this is a chain and it will work to build the map
|
||||
network,
|
||||
...options.supportedChains.filter((c) => c.chainId !== network.chainId),
|
||||
...options.supportedChains.filter((c) => c.chainId === network.chainId),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -216,8 +216,11 @@ export class EditionDrop extends StandardErc1155<PrebuiltEditionDrop> {
|
||||
*
|
||||
* @returns The NFT metadata for all NFTs in the contract.
|
||||
*/
|
||||
public async getOwned(walletAddress?: AddressOrEns): Promise<NFT[]> {
|
||||
return this.erc1155.getOwned(walletAddress);
|
||||
public async getOwned(
|
||||
walletAddress?: AddressOrEns,
|
||||
queryParams?: QueryAllParams,
|
||||
): Promise<NFT[]> {
|
||||
return this.erc1155.getOwned(walletAddress, queryParams);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -190,8 +190,11 @@ export class Edition extends StandardErc1155<TokenERC1155> {
|
||||
*
|
||||
* @returns The NFT metadata for all NFTs in the contract.
|
||||
*/
|
||||
public async getOwned(walletAddress?: AddressOrEns): Promise<NFT[]> {
|
||||
return this.erc1155.getOwned(walletAddress);
|
||||
public async getOwned(
|
||||
walletAddress?: AddressOrEns,
|
||||
queryParams?: QueryAllParams,
|
||||
): Promise<NFT[]> {
|
||||
return this.erc1155.getOwned(walletAddress, queryParams);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -102,7 +102,10 @@ export class Erc1155Enumerable implements DetectableFeature {
|
||||
*
|
||||
* @returns The NFT metadata for all NFTs in the contract.
|
||||
*/
|
||||
public async owned(walletAddress?: AddressOrEns): Promise<NFT[]> {
|
||||
public async owned(
|
||||
walletAddress?: AddressOrEns,
|
||||
queryParams?: QueryAllParams,
|
||||
): Promise<NFT[]> {
|
||||
const [address, maxId] = await Promise.all([
|
||||
resolveAddress(
|
||||
walletAddress || (await this.contractWrapper.getSignerAddress()),
|
||||
@@ -114,7 +117,7 @@ export class Erc1155Enumerable implements DetectableFeature {
|
||||
Array.from(Array(maxId.toNumber()).keys()),
|
||||
]);
|
||||
|
||||
const ownedBalances = balances
|
||||
let ownedBalances = balances
|
||||
.map((b, i) => {
|
||||
return {
|
||||
tokenId: i,
|
||||
@@ -122,6 +125,11 @@ export class Erc1155Enumerable implements DetectableFeature {
|
||||
};
|
||||
})
|
||||
.filter((b) => b.balance.gt(0));
|
||||
if (queryParams) {
|
||||
const start = queryParams?.start || 0;
|
||||
const count = queryParams?.count || DEFAULT_QUERY_ALL_COUNT;
|
||||
ownedBalances = ownedBalances.slice(start, start + count);
|
||||
}
|
||||
const nfts = (
|
||||
await Promise.all(
|
||||
ownedBalances.map((item) => this.erc1155.get(item.tokenId.toString())),
|
||||
|
||||
@@ -494,12 +494,16 @@ export class Erc1155<
|
||||
* @returns The NFT metadata for all NFTs in the contract.
|
||||
* @twfeature ERC1155Enumerable
|
||||
*/
|
||||
public async getOwned(walletAddress?: AddressOrEns): Promise<NFT[]> {
|
||||
public async getOwned(
|
||||
walletAddress?: AddressOrEns,
|
||||
queryParams?: QueryAllParams,
|
||||
): Promise<NFT[]> {
|
||||
if (walletAddress) {
|
||||
walletAddress = await resolveAddress(walletAddress);
|
||||
}
|
||||
return assertEnabled(this.query, FEATURE_EDITION_ENUMERABLE).owned(
|
||||
walletAddress,
|
||||
queryParams,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,10 @@ import type { BaseERC721 } from "../../types/eips";
|
||||
import { DetectableFeature } from "../interfaces/DetectableFeature";
|
||||
import type { ContractWrapper } from "./contract-wrapper";
|
||||
import type { Erc721 } from "./erc-721";
|
||||
import {
|
||||
DEFAULT_QUERY_ALL_COUNT,
|
||||
QueryAllParams,
|
||||
} from "../../../core/schema/QueryParams";
|
||||
|
||||
/**
|
||||
* List owned ERC721 NFTs
|
||||
@@ -46,10 +50,19 @@ export class Erc721Enumerable implements DetectableFeature {
|
||||
* const nfts = await contract.nft.query.owned.all(address);
|
||||
* ```
|
||||
* @param walletAddress - the wallet address to query, defaults to the connected wallet
|
||||
* @param queryParams - optional filtering to only fetch a subset of results.
|
||||
* @returns The NFT metadata for all NFTs in the contract.
|
||||
*/
|
||||
public async all(walletAddress?: AddressOrEns): Promise<NFT[]> {
|
||||
const tokenIds = await this.tokenIds(walletAddress);
|
||||
public async all(
|
||||
walletAddress?: AddressOrEns,
|
||||
queryParams?: QueryAllParams,
|
||||
): Promise<NFT[]> {
|
||||
let tokenIds = await this.tokenIds(walletAddress);
|
||||
if (queryParams) {
|
||||
const start = queryParams?.start || 0;
|
||||
const count = queryParams?.count || DEFAULT_QUERY_ALL_COUNT;
|
||||
tokenIds = tokenIds.slice(start, start + count);
|
||||
}
|
||||
return await Promise.all(
|
||||
tokenIds.map((tokenId) => this.erc721.get(tokenId.toString())),
|
||||
);
|
||||
|
||||
@@ -95,13 +95,17 @@ export class StandardErc721<
|
||||
* console.log(nfts);
|
||||
* ```
|
||||
* @param walletAddress - the wallet address to query, defaults to the connected wallet
|
||||
* @param queryParams - optional filtering to only fetch a subset of results.
|
||||
* @returns The NFT metadata for all NFTs in the contract.
|
||||
*/
|
||||
public async getOwned(walletAddress?: AddressOrEns): Promise<NFT[]> {
|
||||
public async getOwned(
|
||||
walletAddress?: AddressOrEns,
|
||||
queryParams?: QueryAllParams,
|
||||
): Promise<NFT[]> {
|
||||
if (walletAddress) {
|
||||
walletAddress = await resolveAddress(walletAddress);
|
||||
}
|
||||
return this.erc721.getOwned(walletAddress);
|
||||
return this.erc721.getOwned(walletAddress, queryParams);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,7 +17,10 @@ import type {
|
||||
} from "@thirdweb-dev/contracts-js";
|
||||
import type { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import { BigNumber, BigNumberish, constants } from "ethers";
|
||||
import type { QueryAllParams } from "../../../core/schema/QueryParams";
|
||||
import {
|
||||
DEFAULT_QUERY_ALL_COUNT,
|
||||
type QueryAllParams,
|
||||
} from "../../../core/schema/QueryParams";
|
||||
import type {
|
||||
NFT,
|
||||
NFTMetadata,
|
||||
@@ -415,25 +418,35 @@ export class Erc721<
|
||||
* console.log(nfts);
|
||||
* ```
|
||||
* @param walletAddress - the wallet address to query, defaults to the connected wallet
|
||||
* @param queryParams - optional filtering to only fetch a subset of results.
|
||||
* @returns The NFT metadata for all NFTs in the contract.
|
||||
* @twfeature ERC721Supply | ERC721Enumerable
|
||||
*/
|
||||
public async getOwned(walletAddress?: AddressOrEns) {
|
||||
public async getOwned(
|
||||
walletAddress?: AddressOrEns,
|
||||
queryParams?: QueryAllParams,
|
||||
) {
|
||||
if (walletAddress) {
|
||||
walletAddress = await resolveAddress(walletAddress);
|
||||
}
|
||||
|
||||
if (this.query?.owned) {
|
||||
return this.query.owned.all(walletAddress);
|
||||
return this.query.owned.all(walletAddress, queryParams);
|
||||
} else {
|
||||
const [address, allOwners] = await Promise.all([
|
||||
walletAddress || this.contractWrapper.getSignerAddress(),
|
||||
this.getAllOwners(),
|
||||
]);
|
||||
let ownedTokens = (allOwners || []).filter(
|
||||
(i) => address?.toLowerCase() === i.owner?.toLowerCase(),
|
||||
);
|
||||
if (queryParams) {
|
||||
const start = queryParams?.start || 0;
|
||||
const count = queryParams?.count || DEFAULT_QUERY_ALL_COUNT;
|
||||
ownedTokens = ownedTokens.slice(start, start + count);
|
||||
}
|
||||
return await Promise.all(
|
||||
(allOwners || [])
|
||||
.filter((i) => address?.toLowerCase() === i.owner?.toLowerCase())
|
||||
.map((i) => this.get(i.tokenId)),
|
||||
ownedTokens.map(async (i) => this.get(i.tokenId)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@ import type { BaseERC721 } from "../../types/eips";
|
||||
import { DetectableFeature } from "../interfaces/DetectableFeature";
|
||||
import type { ContractWrapper } from "./contract-wrapper";
|
||||
import type { Erc721 } from "./erc-721";
|
||||
import {
|
||||
DEFAULT_QUERY_ALL_COUNT,
|
||||
QueryAllParams,
|
||||
} from "../../../core/schema/QueryParams";
|
||||
|
||||
/**
|
||||
* List owned ERC721 NFTs
|
||||
@@ -50,8 +54,16 @@ export class Erc721AQueryable implements DetectableFeature {
|
||||
* @param walletAddress - the wallet address to query, defaults to the connected wallet
|
||||
* @returns The NFT metadata for all NFTs in the contract.
|
||||
*/
|
||||
public async all(walletAddress?: AddressOrEns): Promise<NFT[]> {
|
||||
const tokenIds = await this.tokenIds(walletAddress);
|
||||
public async all(
|
||||
walletAddress?: AddressOrEns,
|
||||
queryParams?: QueryAllParams,
|
||||
): Promise<NFT[]> {
|
||||
let tokenIds = await this.tokenIds(walletAddress);
|
||||
if (queryParams) {
|
||||
const start = queryParams?.start || 0;
|
||||
const count = queryParams?.count || DEFAULT_QUERY_ALL_COUNT;
|
||||
tokenIds = tokenIds.slice(start, start + count);
|
||||
}
|
||||
return await Promise.all(
|
||||
tokenIds.map((tokenId) => this.erc721.get(tokenId.toString())),
|
||||
);
|
||||
|
||||
@@ -61,7 +61,7 @@ export class ContractFactory extends ContractWrapper<TWFactory> {
|
||||
[VoteInitializer.contractType]: 1,
|
||||
[SplitInitializer.contractType]: 1,
|
||||
[MarketplaceInitializer.contractType]: 2,
|
||||
[MarketplaceV3Initializer.contractType]: 1,
|
||||
[MarketplaceV3Initializer.contractType]: 3,
|
||||
[PackInitializer.contractType]: 2,
|
||||
};
|
||||
|
||||
|
||||
@@ -890,7 +890,7 @@ function addChainToSupportedChains(
|
||||
options = {
|
||||
...options,
|
||||
// @ts-expect-error - we know that the network is assignable despite the readonly mismatch
|
||||
supportedChains: [...(options?.supportedChains || []), network],
|
||||
supportedChains: [network, ...(options?.supportedChains || [])],
|
||||
};
|
||||
}
|
||||
return options;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { ThirdwebSDK } from "../../src/evm";
|
||||
import { SmartContract } from "../../src/evm/contracts/smart-contract";
|
||||
import {
|
||||
extendedMetadataMock,
|
||||
@@ -14,19 +13,19 @@ import {
|
||||
tieredDropBytecode,
|
||||
tieredDropCompilerMetadata,
|
||||
} from "./mock/tieredDropMetadata";
|
||||
import {
|
||||
DirectListingsLogic__factory,
|
||||
EnglishAuctionsLogic__factory,
|
||||
OffersLogic__factory,
|
||||
} from "@thirdweb-dev/contracts-js";
|
||||
import {
|
||||
marketplaceV3Bytecode,
|
||||
marketplaceV3CompilerMetadata,
|
||||
} from "./mock/marketplaceV3Metadata";
|
||||
import {
|
||||
pluginMapBytecode,
|
||||
pluginMapCompilerMetadata,
|
||||
} from "./mock/pluginMapMetadata";
|
||||
directListingsBytecode,
|
||||
directListingsCompilerMetadata,
|
||||
} from "./mock/directListingsMetadata";
|
||||
import { offersBytecode, offersCompilerMetadata } from "./mock/offersMetadata";
|
||||
import {
|
||||
englishAuctionsBytecode,
|
||||
englishAuctionsCompilerMetadata,
|
||||
} from "./mock/englishAuctionsMetadata";
|
||||
|
||||
const itIf = (condition: boolean) => (condition ? it : it.skip);
|
||||
|
||||
@@ -112,7 +111,7 @@ describe("Any EVM Keyless Deploy", async () => {
|
||||
{
|
||||
...extendedMetadataMock,
|
||||
deployType: "autoFactory",
|
||||
routerType: "plugin",
|
||||
routerType: "dynamic",
|
||||
defaultExtensions: [
|
||||
{
|
||||
extensionName: "DirectListingsLogic",
|
||||
@@ -136,7 +135,7 @@ describe("Any EVM Keyless Deploy", async () => {
|
||||
},
|
||||
publisher: await adminWallet.getAddress(),
|
||||
},
|
||||
"ipfs://QmaE7HVb4nwHp96omxmyPc7nKPZqsGB7ZbW6psznN6cSMk",
|
||||
"ipfs://QmWrPyWEMDjnR3a5zp1rJHzU1EUGx6DR2hPBVHAkGGjhgm/0",
|
||||
);
|
||||
transactionCount = (await sdk.deployer.getTransactionsForDeploy(publishUri))
|
||||
.length;
|
||||
@@ -145,7 +144,7 @@ describe("Any EVM Keyless Deploy", async () => {
|
||||
publishUri,
|
||||
[
|
||||
walletAddress, // defaultAdmin
|
||||
"ipfs://QmP2QPzc81zg5rqhU9u7cDeSyD4aZH8RdVF8Nuh6rCCgxV", // contractUri
|
||||
"ipfs://QmWrPyWEMDjnR3a5zp1rJHzU1EUGx6DR2hPBVHAkGGjhgm/0", // contractUri
|
||||
[], // trustedForwarders
|
||||
walletAddress, // platform fee recipient
|
||||
0, // platform fee bps
|
||||
@@ -167,27 +166,10 @@ describe("Any EVM Keyless Deploy", async () => {
|
||||
before(async () => {
|
||||
[adminWallet, claimerWallet] = signers;
|
||||
|
||||
await mockUploadMetadataWithBytecode(
|
||||
"PluginMap",
|
||||
pluginMapCompilerMetadata.output.abi,
|
||||
pluginMapBytecode,
|
||||
"",
|
||||
{
|
||||
...extendedMetadataMock,
|
||||
deployType: "standard",
|
||||
networksForDeployment: {
|
||||
allNetworks: true,
|
||||
networksEnabled: [],
|
||||
},
|
||||
publisher: adminWallet.address,
|
||||
},
|
||||
"ipfs://QmQHyopzH41En8KxvYrmATLCyuTMu8Hv5TEaxLc7gWJkLm/0",
|
||||
);
|
||||
|
||||
await mockUploadMetadataWithBytecode(
|
||||
"DirectListingsLogic",
|
||||
DirectListingsLogic__factory.abi,
|
||||
DirectListingsLogic__factory.bytecode,
|
||||
directListingsCompilerMetadata.output.abi,
|
||||
directListingsBytecode,
|
||||
"",
|
||||
{
|
||||
...extendedMetadataMock,
|
||||
@@ -203,8 +185,8 @@ describe("Any EVM Keyless Deploy", async () => {
|
||||
|
||||
await mockUploadMetadataWithBytecode(
|
||||
"OffersLogic",
|
||||
OffersLogic__factory.abi,
|
||||
OffersLogic__factory.bytecode,
|
||||
offersCompilerMetadata.output.abi,
|
||||
offersBytecode,
|
||||
"",
|
||||
{
|
||||
...extendedMetadataMock,
|
||||
@@ -220,8 +202,8 @@ describe("Any EVM Keyless Deploy", async () => {
|
||||
|
||||
await mockUploadMetadataWithBytecode(
|
||||
"EnglishAuctionsLogic",
|
||||
EnglishAuctionsLogic__factory.abi,
|
||||
EnglishAuctionsLogic__factory.bytecode,
|
||||
englishAuctionsCompilerMetadata.output.abi,
|
||||
englishAuctionsBytecode,
|
||||
"",
|
||||
{
|
||||
...extendedMetadataMock,
|
||||
@@ -256,20 +238,22 @@ describe("Any EVM Keyless Deploy", async () => {
|
||||
});
|
||||
|
||||
// can only work if secret key is set, skip otherwise
|
||||
itIf(process.env.TW_SECRET_KEY)("deploy marketplacev3", async () => {
|
||||
it("deploy marketplacev3", async () => {
|
||||
notificationCounter = 0;
|
||||
transactionCount = 0;
|
||||
const marketplace = await deployMarketplaceV3();
|
||||
expect(notificationCounter).to.greaterThanOrEqual(12);
|
||||
expect(transactionCount).to.greaterThanOrEqual(6);
|
||||
|
||||
let plugins = await marketplace.call("getAllPlugins");
|
||||
let allPlugins = plugins.map((item: any) => item.pluginAddress);
|
||||
let pluginsAddresses = Array.from(new Set(allPlugins));
|
||||
let extensions = await marketplace.call("getAllExtensions");
|
||||
let allExtensions = extensions.map(
|
||||
(item: any) => item.metadata.implementation,
|
||||
);
|
||||
let extensionAddresses = Array.from(new Set(allExtensions));
|
||||
|
||||
expect(pluginsAddresses.length).to.equal(3);
|
||||
expect(extensionAddresses.length).to.equal(3);
|
||||
|
||||
pluginsAddresses.forEach(async (address) => {
|
||||
extensionAddresses.forEach(async (address) => {
|
||||
expect(address).to.not.equal(ethers.constants.AddressZero);
|
||||
const code = await adminWallet.provider?.getCode(address as string);
|
||||
expect(code?.length).to.be.greaterThan(2);
|
||||
@@ -282,13 +266,13 @@ describe("Any EVM Keyless Deploy", async () => {
|
||||
expect(notificationCounter).to.equal(2);
|
||||
expect(transactionCount).to.equal(1);
|
||||
|
||||
plugins = await marketplace2.call("getAllPlugins");
|
||||
allPlugins = plugins.map((item: any) => item.pluginAddress);
|
||||
pluginsAddresses = Array.from(new Set(allPlugins));
|
||||
extensions = await marketplace2.call("getAllExtensions");
|
||||
allExtensions = extensions.map((item: any) => item.metadata.implementation);
|
||||
extensionAddresses = Array.from(new Set(allExtensions));
|
||||
|
||||
expect(pluginsAddresses.length).to.equal(3);
|
||||
expect(extensionAddresses.length).to.equal(3);
|
||||
|
||||
pluginsAddresses.forEach(async (address) => {
|
||||
extensionAddresses.forEach(async (address) => {
|
||||
expect(address).to.not.equal(ethers.constants.AddressZero);
|
||||
const code = await adminWallet.provider?.getCode(address as string);
|
||||
expect(code?.length).to.be.greaterThan(2);
|
||||
|
||||
@@ -63,12 +63,20 @@ import {
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import { constants, ContractInterface, ethers } from "ethers";
|
||||
import hardhat from "hardhat";
|
||||
import { generatePluginFunctions } from "../../src/evm/common/plugin/generatePluginFunctions";
|
||||
import {
|
||||
generateExtensionFunctions,
|
||||
generatePluginFunctions,
|
||||
} from "../../src/evm/common/plugin/generatePluginFunctions";
|
||||
import { mockUploadMetadataWithBytecode } from "./utils";
|
||||
import {
|
||||
bytecode as TWCloneFactoryBytecode,
|
||||
abi as TWCloneFactoryAbi,
|
||||
} from "./metadata/TWCloneFactory";
|
||||
import {
|
||||
Extension,
|
||||
ExtensionFunction,
|
||||
ExtensionMetadata,
|
||||
} from "../../src/evm/types/extensions";
|
||||
|
||||
// it's there, trust me bro
|
||||
const hardhatEthers = (hardhat as any).ethers;
|
||||
@@ -359,48 +367,68 @@ async function setupMultichainRegistry(
|
||||
|
||||
// Setup marketplace-v3 for tests
|
||||
async function setupMarketplaceV3(): Promise<string> {
|
||||
let extensions: Extension[] = [];
|
||||
|
||||
// Direct Listings
|
||||
const directListingsPluginAddress = await deployContractAndUploadMetadata(
|
||||
const directListingsExtensionAddress = await deployContractAndUploadMetadata(
|
||||
DirectListingsLogic__factory.abi,
|
||||
DirectListingsLogic__factory.bytecode,
|
||||
signer,
|
||||
[mock_weth_address],
|
||||
);
|
||||
const pluginsDirectListings: Plugin[] = generatePluginFunctions(
|
||||
directListingsPluginAddress,
|
||||
AbiSchema.parse(DirectListingsLogic__factory.abi),
|
||||
);
|
||||
const directListingsFunctions: ExtensionFunction[] =
|
||||
generateExtensionFunctions(
|
||||
AbiSchema.parse(DirectListingsLogic__factory.abi),
|
||||
);
|
||||
const directListingsExtensionMetadata: ExtensionMetadata = {
|
||||
name: "DirectListingsLogic",
|
||||
metadataURI: "",
|
||||
implementation: directListingsExtensionAddress,
|
||||
};
|
||||
extensions.push({
|
||||
metadata: directListingsExtensionMetadata,
|
||||
functions: directListingsFunctions,
|
||||
});
|
||||
|
||||
// English Auctions
|
||||
const englishAuctionPluginAddress = await deployContractAndUploadMetadata(
|
||||
const englishAuctionExtensionAddress = await deployContractAndUploadMetadata(
|
||||
EnglishAuctionsLogic__factory.abi,
|
||||
EnglishAuctionsLogic__factory.bytecode,
|
||||
signer,
|
||||
[mock_weth_address],
|
||||
);
|
||||
const pluginsEnglishAuctions: Plugin[] = generatePluginFunctions(
|
||||
englishAuctionPluginAddress,
|
||||
AbiSchema.parse(EnglishAuctionsLogic__factory.abi),
|
||||
);
|
||||
const englishAuctionsFunctions: ExtensionFunction[] =
|
||||
generateExtensionFunctions(
|
||||
AbiSchema.parse(EnglishAuctionsLogic__factory.abi),
|
||||
);
|
||||
const englishAuctionsExtensionMetadata: ExtensionMetadata = {
|
||||
name: "EnglishAuctionsLogic",
|
||||
metadataURI: "",
|
||||
implementation: englishAuctionExtensionAddress,
|
||||
};
|
||||
extensions.push({
|
||||
metadata: englishAuctionsExtensionMetadata,
|
||||
functions: englishAuctionsFunctions,
|
||||
});
|
||||
|
||||
// Offers
|
||||
const offersLogicPluginAddress = await deployContractAndUploadMetadata(
|
||||
const offersLogicExtensionAddress = await deployContractAndUploadMetadata(
|
||||
OffersLogic__factory.abi,
|
||||
OffersLogic__factory.bytecode,
|
||||
signer,
|
||||
);
|
||||
const pluginsOffers: Plugin[] = generatePluginFunctions(
|
||||
offersLogicPluginAddress,
|
||||
const offersFunctions: ExtensionFunction[] = generateExtensionFunctions(
|
||||
AbiSchema.parse(OffersLogic__factory.abi),
|
||||
);
|
||||
|
||||
// Map
|
||||
const pluginMapAddress = await deployContractAndUploadMetadata(
|
||||
PluginMap__factory.abi,
|
||||
PluginMap__factory.bytecode,
|
||||
signer,
|
||||
[[...pluginsDirectListings, ...pluginsEnglishAuctions, ...pluginsOffers]],
|
||||
);
|
||||
const offersExtensionMetadata: ExtensionMetadata = {
|
||||
name: "OffersLogic",
|
||||
metadataURI: "",
|
||||
implementation: offersLogicExtensionAddress,
|
||||
};
|
||||
extensions.push({
|
||||
metadata: offersExtensionMetadata,
|
||||
functions: offersFunctions,
|
||||
});
|
||||
|
||||
// Router
|
||||
const royaltyEngineAddress = constants.AddressZero;
|
||||
@@ -408,7 +436,13 @@ async function setupMarketplaceV3(): Promise<string> {
|
||||
MarketplaceV3__factory.abi,
|
||||
MarketplaceV3__factory.bytecode,
|
||||
signer,
|
||||
[pluginMapAddress, royaltyEngineAddress],
|
||||
[
|
||||
{
|
||||
extensions: extensions,
|
||||
royaltyEngineAddress: royaltyEngineAddress,
|
||||
nativeTokenWrapper: mock_weth_address,
|
||||
},
|
||||
],
|
||||
"MarketplaceV3",
|
||||
);
|
||||
return marketplaceV3Address;
|
||||
|
||||
@@ -287,4 +287,100 @@ describe("Edition Contract", async () => {
|
||||
expect(nfts[0].supply).to.be.equal("5");
|
||||
expect(nfts[0].metadata.id).to.be.equal("1");
|
||||
});
|
||||
|
||||
it("should respect pagination for getOwned (for edition.ts)", async () => {
|
||||
const nfts = [] as { metadata: { name: string }; supply: number }[];
|
||||
for (let i = 0; i < 10; i++) {
|
||||
nfts.push({
|
||||
metadata: { name: `Test${i}` },
|
||||
supply: 10,
|
||||
});
|
||||
}
|
||||
await bundleContract.mintBatch(nfts);
|
||||
const total = await bundleContract.getTotalCount();
|
||||
expect(total.toNumber()).to.eq(10);
|
||||
const nftPage1 = await bundleContract.getOwned(adminWallet.address, {
|
||||
count: 2,
|
||||
start: 0,
|
||||
});
|
||||
expect(nftPage1).to.be.an("array").length(2);
|
||||
expect(nftPage1[0].metadata.id).to.eq("0");
|
||||
expect(nftPage1[1].metadata.id).to.eq("1");
|
||||
|
||||
const nftPage2 = await bundleContract.getOwned(adminWallet.address, {
|
||||
count: 3,
|
||||
start: 2,
|
||||
});
|
||||
expect(nftPage2).to.be.an("array").length(3);
|
||||
expect(nftPage2[0].metadata.id).to.eq("2");
|
||||
expect(nftPage2[1].metadata.id).to.eq("3");
|
||||
expect(nftPage2[2].metadata.id).to.eq("4");
|
||||
});
|
||||
|
||||
it("should respect pagination for getOwned (for erc-1155.ts)", async () => {
|
||||
const nfts = [] as { metadata: { name: string }; supply: number }[];
|
||||
for (let i = 0; i < 10; i++) {
|
||||
nfts.push({
|
||||
metadata: { name: `Test${i}` },
|
||||
supply: 10,
|
||||
});
|
||||
}
|
||||
await bundleContract.mintBatch(nfts);
|
||||
const total = await bundleContract.getTotalCount();
|
||||
expect(total.toNumber()).to.eq(10);
|
||||
const nftPage1 = await bundleContract.erc1155.getOwned(
|
||||
adminWallet.address,
|
||||
{
|
||||
count: 2,
|
||||
start: 0,
|
||||
},
|
||||
);
|
||||
expect(nftPage1).to.be.an("array").length(2);
|
||||
expect(nftPage1[0].metadata.id).to.eq("0");
|
||||
expect(nftPage1[1].metadata.id).to.eq("1");
|
||||
|
||||
const nftPage2 = await bundleContract.erc1155.getOwned(
|
||||
adminWallet.address,
|
||||
{
|
||||
count: 3,
|
||||
start: 2,
|
||||
},
|
||||
);
|
||||
expect(nftPage2).to.be.an("array").length(3);
|
||||
expect(nftPage2[0].metadata.id).to.eq("2");
|
||||
expect(nftPage2[1].metadata.id).to.eq("3");
|
||||
expect(nftPage2[2].metadata.id).to.eq("4");
|
||||
});
|
||||
|
||||
it("getOwned should return all items when queryParams.count is greater than the total supply (edition.ts)", async () => {
|
||||
const nfts = [] as { metadata: { name: string }; supply: number }[];
|
||||
for (let i = 0; i < 10; i++) {
|
||||
nfts.push({
|
||||
metadata: { name: `Test${i}` },
|
||||
supply: 10,
|
||||
});
|
||||
}
|
||||
await bundleContract.mintBatch(nfts);
|
||||
const items = await bundleContract.getOwned(undefined, {
|
||||
count: 1000,
|
||||
start: 0,
|
||||
});
|
||||
expect(items).to.be.an("array").length(nfts.length);
|
||||
});
|
||||
|
||||
it("getOwned should return all items when queryParams.count is greater than the total supply (erc-1155.ts)", async () => {
|
||||
const nfts = [] as { metadata: { name: string }; supply: number }[];
|
||||
for (let i = 0; i < 10; i++) {
|
||||
nfts.push({
|
||||
metadata: { name: `Test${i}` },
|
||||
supply: 10,
|
||||
});
|
||||
}
|
||||
await bundleContract.mintBatch(nfts);
|
||||
const items = await bundleContract.getOwned(undefined, {
|
||||
count: 1000,
|
||||
start: 0,
|
||||
});
|
||||
expect(items).to.be.an("array").length(nfts.length);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -46,11 +46,11 @@ describe("Marketplace V3", async () => {
|
||||
MarketplaceV3Initializer.contractType,
|
||||
{
|
||||
name: "Test Marketplace",
|
||||
platform_fee_recipient: adminWallet.address,
|
||||
},
|
||||
),
|
||||
"marketplace-v3",
|
||||
);
|
||||
|
||||
dummyNftContract = await sdk.getNFTCollection(
|
||||
await sdk.deployer.deployBuiltInContract(
|
||||
NFTCollectionInitializer.contractType,
|
||||
@@ -228,8 +228,9 @@ describe("Marketplace V3", async () => {
|
||||
isReservedListing: false,
|
||||
});
|
||||
|
||||
const listing =
|
||||
await marketplaceContract.directListings.getListing(listingId);
|
||||
const listing = await marketplaceContract.directListings.getListing(
|
||||
listingId,
|
||||
);
|
||||
expect(listing.currencyContractAddress.toLowerCase()).to.equal(
|
||||
NATIVE_TOKEN_ADDRESS.toLowerCase(),
|
||||
);
|
||||
@@ -374,10 +375,12 @@ describe("Marketplace V3", async () => {
|
||||
});
|
||||
|
||||
it("should return correct listing", async () => {
|
||||
const listingOne =
|
||||
await marketplaceContract.directListings.getListing(directListingOneId);
|
||||
const listingTwo =
|
||||
await marketplaceContract.directListings.getListing(directListingTwoId);
|
||||
const listingOne = await marketplaceContract.directListings.getListing(
|
||||
directListingOneId,
|
||||
);
|
||||
const listingTwo = await marketplaceContract.directListings.getListing(
|
||||
directListingTwoId,
|
||||
);
|
||||
assert.equal(listingOne.tokenId.toString(), "0");
|
||||
assert.equal(listingOne.asset.id.toString(), "0");
|
||||
assert.equal(listingOne.asset.name, "Test 0");
|
||||
@@ -463,8 +466,9 @@ describe("Marketplace V3", async () => {
|
||||
});
|
||||
|
||||
it("should correctly cancel a direct listing", async () => {
|
||||
const listing =
|
||||
await marketplaceContract.directListings.getListing(directListingId);
|
||||
const listing = await marketplaceContract.directListings.getListing(
|
||||
directListingId,
|
||||
);
|
||||
assert.equal(listing.quantity.toString(), "1");
|
||||
await marketplaceContract.directListings.cancelListing(directListingId);
|
||||
|
||||
@@ -646,10 +650,12 @@ describe("Marketplace V3", async () => {
|
||||
});
|
||||
|
||||
it("should return correct auction", async () => {
|
||||
const auctionOne =
|
||||
await marketplaceContract.englishAuctions.getAuction(auctionOneId);
|
||||
const auctionTwo =
|
||||
await marketplaceContract.englishAuctions.getAuction(auctionTwoId);
|
||||
const auctionOne = await marketplaceContract.englishAuctions.getAuction(
|
||||
auctionOneId,
|
||||
);
|
||||
const auctionTwo = await marketplaceContract.englishAuctions.getAuction(
|
||||
auctionTwoId,
|
||||
);
|
||||
assert.equal(auctionOne.tokenId.toString(), "2");
|
||||
assert.equal(auctionOne.asset.id.toString(), "2");
|
||||
assert.equal(auctionOne.asset.name, "Test 3");
|
||||
@@ -692,8 +698,9 @@ describe("Marketplace V3", async () => {
|
||||
await sdk.updateSignerOrProvider(bobWallet);
|
||||
await marketplaceContract.englishAuctions.makeBid(auctionId, 0.3);
|
||||
|
||||
let winningBid =
|
||||
await marketplaceContract.englishAuctions.getWinningBid(auctionId);
|
||||
let winningBid = await marketplaceContract.englishAuctions.getWinningBid(
|
||||
auctionId,
|
||||
);
|
||||
|
||||
assert.equal(winningBid?.bidderAddress, bobWallet.address);
|
||||
assert.equal(
|
||||
@@ -706,8 +713,9 @@ describe("Marketplace V3", async () => {
|
||||
await sdk.updateSignerOrProvider(samWallet);
|
||||
await marketplaceContract.englishAuctions.makeBid(auctionId, 0.6);
|
||||
|
||||
winningBid =
|
||||
await marketplaceContract.englishAuctions.getWinningBid(auctionId);
|
||||
winningBid = await marketplaceContract.englishAuctions.getWinningBid(
|
||||
auctionId,
|
||||
);
|
||||
assert.equal(winningBid?.bidderAddress, samWallet.address);
|
||||
assert.equal(
|
||||
winningBid?.bidAmount.toString(),
|
||||
@@ -1095,8 +1103,9 @@ describe("Marketplace V3", async () => {
|
||||
it("should not allow you to update an active direct listing", async () => {
|
||||
const pricePerToken = ethers.utils.parseUnits("0.1");
|
||||
|
||||
const directListing =
|
||||
await marketplaceContract.directListings.getListing(directListingId);
|
||||
const directListing = await marketplaceContract.directListings.getListing(
|
||||
directListingId,
|
||||
);
|
||||
assert.equal(
|
||||
directListing.pricePerToken.toString(),
|
||||
pricePerToken.toString(),
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -285,4 +285,70 @@ describe("NFT Contract", async () => {
|
||||
expect(records[0].tokenId).to.eq(1);
|
||||
expect(records[1].tokenId).to.eq(2);
|
||||
});
|
||||
|
||||
it("should respect pagination for getOwned (erc-721-standard.ts)", async () => {
|
||||
const _tokenIds: number[] = Array.from({ length: 11 }, (_, index) => index); // [0, 1, ... 10]
|
||||
const metadata = _tokenIds.map((num) => ({ name: `Test${num}` }));
|
||||
await nftContract.mintBatch(metadata);
|
||||
const nftPage1 = await nftContract.getOwned(undefined, {
|
||||
count: 2,
|
||||
start: 0,
|
||||
});
|
||||
expect(nftPage1).to.be.an("array").length(2);
|
||||
expect(nftPage1[0].metadata.id).to.eq("0");
|
||||
expect(nftPage1[1].metadata.id).to.eq("1");
|
||||
|
||||
const nftPage2 = await nftContract.getOwned(undefined, {
|
||||
count: 3,
|
||||
start: 2,
|
||||
});
|
||||
expect(nftPage2).to.be.an("array").length(3);
|
||||
expect(nftPage2[0].metadata.id).to.eq("2");
|
||||
expect(nftPage2[1].metadata.id).to.eq("3");
|
||||
expect(nftPage2[2].metadata.id).to.eq("4");
|
||||
});
|
||||
|
||||
it("should respect pagination for getOwned (erc-721.ts)", async () => {
|
||||
const _tokenIds: number[] = Array.from({ length: 11 }, (_, index) => index); // [0, 1, ... 10]
|
||||
const metadata = _tokenIds.map((num) => ({ name: `Test${num}` }));
|
||||
await nftContract.mintBatch(metadata);
|
||||
const nftPage1 = await nftContract.erc721.getOwned(undefined, {
|
||||
count: 2,
|
||||
start: 0,
|
||||
});
|
||||
expect(nftPage1).to.be.an("array").length(2);
|
||||
expect(nftPage1[0].metadata.id).to.eq("0");
|
||||
expect(nftPage1[1].metadata.id).to.eq("1");
|
||||
|
||||
const nftPage2 = await nftContract.erc721.getOwned(undefined, {
|
||||
count: 3,
|
||||
start: 2,
|
||||
});
|
||||
expect(nftPage2).to.be.an("array").length(3);
|
||||
expect(nftPage2[0].metadata.id).to.eq("2");
|
||||
expect(nftPage2[1].metadata.id).to.eq("3");
|
||||
expect(nftPage2[2].metadata.id).to.eq("4");
|
||||
});
|
||||
|
||||
it("getOwned should return all item when queryParams.count is greater than the total supply (erc-721-standard.ts)", async () => {
|
||||
const _tokenIds: number[] = Array.from({ length: 11 }, (_, index) => index); // [0, 1, ... 10]
|
||||
const metadata = _tokenIds.map((num) => ({ name: `Test${num}` }));
|
||||
await nftContract.mintBatch(metadata);
|
||||
const nfts = await nftContract.getOwned(undefined, {
|
||||
count: 1000,
|
||||
start: 0,
|
||||
});
|
||||
expect(nfts).to.be.an("array").length(_tokenIds.length);
|
||||
});
|
||||
|
||||
it("getOwned should return all items when queryParams.count is greater than the total supply (erc-721.ts)", async () => {
|
||||
const _tokenIds: number[] = Array.from({ length: 11 }, (_, index) => index); // [0, 1, ... 10]
|
||||
const metadata = _tokenIds.map((num) => ({ name: `Test${num}` }));
|
||||
await nftContract.mintBatch(metadata);
|
||||
const nfts = await nftContract.erc721.getOwned(undefined, {
|
||||
count: 1000,
|
||||
start: 0,
|
||||
});
|
||||
expect(nfts).to.be.an("array").length(_tokenIds.length);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @thirdweb-dev/service-utils
|
||||
|
||||
## 0.4.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1752](https://github.com/thirdweb-dev/js/pull/1752) [`1fbbc2d2`](https://github.com/thirdweb-dev/js/commit/1fbbc2d27d88af6029267e6993dd79e077a60ab2) Thanks [@ElasticBottle](https://github.com/ElasticBottle)! - chore(service-utils): add `redirecrUrls` type to `ApiKeyMetadata`
|
||||
|
||||
- [#1751](https://github.com/thirdweb-dev/js/pull/1751) [`95380eae`](https://github.com/thirdweb-dev/js/commit/95380eaed4aad93d47ece4da2b45fdbba2d14205) Thanks [@arcoraven](https://github.com/arcoraven)! - Add walletType to usage payload
|
||||
|
||||
## 0.4.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/service-utils",
|
||||
"version": "0.4.6",
|
||||
"version": "0.4.7",
|
||||
"main": "dist/thirdweb-dev-service-utils.cjs.js",
|
||||
"module": "dist/thirdweb-dev-service-utils.esm.js",
|
||||
"exports": {
|
||||
|
||||
@@ -35,6 +35,7 @@ const usageEventSchema = z.object({
|
||||
creatorWalletAddress: z.string().optional(),
|
||||
clientId: z.string().optional(),
|
||||
walletAddress: z.string().optional(),
|
||||
walletType: z.string().optional(),
|
||||
chainId: z.number().int().positive().optional(),
|
||||
provider: z.string().optional(),
|
||||
mimeType: z.string().optional(),
|
||||
|
||||
@@ -29,6 +29,7 @@ export type ApiKeyMetadata = {
|
||||
walletAddresses: string[];
|
||||
domains: string[];
|
||||
bundleIds: string[];
|
||||
redirectUrls: string[];
|
||||
services: {
|
||||
name: string;
|
||||
targetAddresses: string[];
|
||||
|
||||
@@ -8,6 +8,7 @@ export const validApiKeyMeta: ApiKeyMetadata = {
|
||||
walletAddresses: [],
|
||||
domains: ["example.com", "*.example.com"],
|
||||
bundleIds: [],
|
||||
redirectUrls: [],
|
||||
accountId: "test-account-id",
|
||||
accountStatus: "noCustomer",
|
||||
accountPlan: "free",
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# @thirdweb-dev/unity-js-bridge
|
||||
|
||||
## 0.2.88
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`1f3c64d3`](https://github.com/thirdweb-dev/js/commit/1f3c64d3618903b9008cc7b633ea890b508e7800), [`74941603`](https://github.com/thirdweb-dev/js/commit/74941603a96456da46a47147f67c98235ac55022), [`4b98e487`](https://github.com/thirdweb-dev/js/commit/4b98e487d4b47225d7095e5444dc5e7608db48a3), [`693f349d`](https://github.com/thirdweb-dev/js/commit/693f349db2478e1cd0fc82a9ef9882f46832b125), [`dcdb0dcb`](https://github.com/thirdweb-dev/js/commit/dcdb0dcb838168a22c8335738852316dfb6e6fc9), [`0f12d1f9`](https://github.com/thirdweb-dev/js/commit/0f12d1f90320923309f085c372d3a5ed01dd4606), [`b3b9edca`](https://github.com/thirdweb-dev/js/commit/b3b9edca29e7d4053b14270a61caa89c34fecf9e), [`63ad0050`](https://github.com/thirdweb-dev/js/commit/63ad0050f0a24ec15b90933b5664d697618cf2d0)]:
|
||||
- @thirdweb-dev/sdk@4.0.1
|
||||
- @thirdweb-dev/wallets@2.0.2
|
||||
- @thirdweb-dev/auth@4.0.2
|
||||
|
||||
## 0.2.87
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/unity-js-bridge",
|
||||
"version": "0.2.87",
|
||||
"version": "0.2.88",
|
||||
"main": "dist/thirdweb-unity-bridge.js",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/unity-js-bridge",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# @thirdweb-dev/wallets
|
||||
|
||||
## 2.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1744](https://github.com/thirdweb-dev/js/pull/1744) [`74941603`](https://github.com/thirdweb-dev/js/commit/74941603a96456da46a47147f67c98235ac55022) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Fix executeBatch() type mismatches
|
||||
|
||||
- [#1730](https://github.com/thirdweb-dev/js/pull/1730) [`4b98e487`](https://github.com/thirdweb-dev/js/commit/4b98e487d4b47225d7095e5444dc5e7608db48a3) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Add wallet analytics
|
||||
|
||||
- [#1754](https://github.com/thirdweb-dev/js/pull/1754) [`dcdb0dcb`](https://github.com/thirdweb-dev/js/commit/dcdb0dcb838168a22c8335738852316dfb6e6fc9) Thanks [@iketw](https://github.com/iketw)! - Fix typos in SmartWallet api
|
||||
|
||||
- [#1753](https://github.com/thirdweb-dev/js/pull/1753) [`b3b9edca`](https://github.com/thirdweb-dev/js/commit/b3b9edca29e7d4053b14270a61caa89c34fecf9e) Thanks [@iketw](https://github.com/iketw)! - Minor bug and UI fix for connecting an external app to a smart wallet
|
||||
|
||||
- Updated dependencies [[`1f3c64d3`](https://github.com/thirdweb-dev/js/commit/1f3c64d3618903b9008cc7b633ea890b508e7800), [`693f349d`](https://github.com/thirdweb-dev/js/commit/693f349db2478e1cd0fc82a9ef9882f46832b125), [`0f12d1f9`](https://github.com/thirdweb-dev/js/commit/0f12d1f90320923309f085c372d3a5ed01dd4606), [`63ad0050`](https://github.com/thirdweb-dev/js/commit/63ad0050f0a24ec15b90933b5664d697618cf2d0)]:
|
||||
- @thirdweb-dev/sdk@4.0.1
|
||||
- @thirdweb-dev/contracts-js@1.3.14
|
||||
|
||||
## 2.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/wallets",
|
||||
"version": "2.0.1",
|
||||
"version": "2.0.2",
|
||||
"main": "dist/thirdweb-dev-wallets.cjs.js",
|
||||
"module": "dist/thirdweb-dev-wallets.esm.js",
|
||||
"types": "dist/thirdweb-dev-wallets.cjs.d.ts",
|
||||
|
||||
@@ -44,7 +44,7 @@ export class WalletConnectV2Handler extends WalletConnectHandler {
|
||||
};
|
||||
|
||||
this.#core = new Core({
|
||||
projectId: options?.walletConenctV2ProjectId || TW_WC_PROJECT_ID,
|
||||
projectId: options?.walletConnectV2ProjectId || TW_WC_PROJECT_ID,
|
||||
relayUrl: options?.walletConnectV2RelayUrl || WC_RELAY_URL,
|
||||
});
|
||||
}
|
||||
@@ -177,6 +177,7 @@ export class WalletConnectV2Handler extends WalletConnectHandler {
|
||||
|
||||
const signature = await signerSign.signTransaction(signTransaction);
|
||||
response = formatJsonRpcResult(id, signature);
|
||||
break;
|
||||
default:
|
||||
const error = {
|
||||
id,
|
||||
|
||||
@@ -8,9 +8,8 @@ export type WalletConnectMetadata = IWeb3Wallet["metadata"];
|
||||
// connect dapp support through wcv2 protocol
|
||||
export type WalletConnectReceiverConfig = {
|
||||
enableConnectApp?: boolean;
|
||||
wcVersion?: "v1" | "v2";
|
||||
walletConnectWalletMetadata?: WCMetadata;
|
||||
walletConenctV2ProjectId?: string;
|
||||
walletConnectV2ProjectId?: string;
|
||||
walletConnectV2RelayUrl?: string;
|
||||
wcStorage?: SyncStorage;
|
||||
};
|
||||
|
||||
@@ -186,7 +186,9 @@ export class SmartWalletConnector extends Connector<SmartWalletConnectionArgs> {
|
||||
* @param transactions
|
||||
* @returns the transaction receipt
|
||||
*/
|
||||
async executeBatch(transactions: Transaction[]): Promise<TransactionResult> {
|
||||
async executeBatch(
|
||||
transactions: Transaction<any>[],
|
||||
): Promise<TransactionResult> {
|
||||
if (!this.accountApi) {
|
||||
throw new Error("Personal wallet not connected");
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ export { getInjectedPhantomProvider } from "./connectors/phantom/getInjectedPhan
|
||||
export { getInjectedRainbowProvider } from "./connectors/rainbow/getInjectedRainbowProvider";
|
||||
export { getInjectedCoinbaseProvider } from "./connectors/coinbase-wallet/getInjectedCoinbaseProvider";
|
||||
export { assertWindowEthereum } from "./utils/assertWindowEthereum";
|
||||
export * from "./utils/setWalletAnaltyicsEnabled";
|
||||
|
||||
// ThirdwebEmbeddedWalletSdk
|
||||
export * from "./connectors/embedded-wallet/implementations";
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { isWalletAnalyticsEnabled } from "./setWalletAnaltyicsEnabled";
|
||||
|
||||
const ANALYTICS_ENDPOINT = "https://c.thirdweb.com/event";
|
||||
|
||||
export function track(args: {
|
||||
clientId: string;
|
||||
source: string;
|
||||
action: string;
|
||||
walletType: string;
|
||||
walletAddress: string;
|
||||
}) {
|
||||
if (!isWalletAnalyticsEnabled()) {
|
||||
return;
|
||||
}
|
||||
const { clientId, walletType, walletAddress, source, action } = args;
|
||||
const body = {
|
||||
source,
|
||||
action,
|
||||
walletAddress,
|
||||
walletType,
|
||||
};
|
||||
// don't block on analytic calls
|
||||
fetch(ANALYTICS_ENDPOINT, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"x-client-id": clientId,
|
||||
},
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
let walletAnalyticsEnabled = true;
|
||||
|
||||
export function isWalletAnalyticsEnabled() {
|
||||
return walletAnalyticsEnabled;
|
||||
}
|
||||
|
||||
export function setWalletAnalyticsEnabled(enabled: boolean) {
|
||||
walletAnalyticsEnabled = enabled;
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { DEFAULT_DAPP_META } from "../constants/dappMeta";
|
||||
import { EVMWallet } from "../interfaces";
|
||||
import { ConnectParams, Connector } from "../interfaces/connector";
|
||||
import { AbstractWallet } from "./abstract";
|
||||
import { track } from "../utils/analytics";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export type WalletOptions<TOpts extends Record<string, any> = {}> = {
|
||||
@@ -13,6 +14,7 @@ export type WalletOptions<TOpts extends Record<string, any> = {}> = {
|
||||
walletStorage?: AsyncStorage;
|
||||
dappMetadata?: DAppMetaData;
|
||||
clientId?: string;
|
||||
analytics?: "enabled" | "disabled";
|
||||
} & TOpts;
|
||||
|
||||
export type WalletMeta = {
|
||||
@@ -113,6 +115,7 @@ export abstract class AbstractClientWallet<
|
||||
chainId: await this.getChainId(),
|
||||
});
|
||||
|
||||
this.#trackConnection(address);
|
||||
return address;
|
||||
}
|
||||
|
||||
@@ -122,12 +125,23 @@ export abstract class AbstractClientWallet<
|
||||
|
||||
try {
|
||||
const address = await connector.connect(connectOptions);
|
||||
this.#trackConnection(address);
|
||||
return address;
|
||||
} catch (error) {
|
||||
throw new Error((error as Error).message);
|
||||
}
|
||||
}
|
||||
|
||||
#trackConnection(address: string) {
|
||||
track({
|
||||
clientId: this.options?.clientId || "",
|
||||
source: "connectWallet",
|
||||
action: "connect",
|
||||
walletType: this.walletId,
|
||||
walletAddress: address,
|
||||
});
|
||||
}
|
||||
|
||||
async #subscribeToEvents(connector: Connector) {
|
||||
// subscribe to connector for events
|
||||
connector.on("connect", (data) => {
|
||||
|
||||
@@ -67,7 +67,7 @@ export class SmartWallet
|
||||
this.#wcWallet = this.enableConnectApp
|
||||
? new WalletConnectV2Handler({
|
||||
walletConnectWalletMetadata: options?.walletConnectWalletMetadata,
|
||||
walletConenctV2ProjectId: options?.walletConenctV2ProjectId,
|
||||
walletConnectV2ProjectId: options?.walletConnectV2ProjectId,
|
||||
walletConnectV2RelayUrl: options?.walletConnectV2RelayUrl,
|
||||
})
|
||||
: new NoOpWalletConnectHandler();
|
||||
@@ -120,7 +120,9 @@ export class SmartWallet
|
||||
* @param transactions
|
||||
* @returns the transaction receipt
|
||||
*/
|
||||
async executeBatch(transactions: Transaction[]): Promise<TransactionResult> {
|
||||
async executeBatch(
|
||||
transactions: Transaction<any>[],
|
||||
): Promise<TransactionResult> {
|
||||
const connector = await this.getConnector();
|
||||
return connector.executeBatch(transactions);
|
||||
}
|
||||
|
||||
Generated
+5
-5
@@ -380,8 +380,8 @@ importers:
|
||||
packages/contracts-js:
|
||||
dependencies:
|
||||
'@thirdweb-dev/contracts':
|
||||
specifier: 3.10.1-0
|
||||
version: 3.10.1-0([email protected])
|
||||
specifier: 3.10.2-3
|
||||
version: 3.10.2-3([email protected])
|
||||
devDependencies:
|
||||
'@babel/preset-env':
|
||||
specifier: ^7.22.9
|
||||
@@ -12030,8 +12030,8 @@ packages:
|
||||
use-sync-external-store: 1.2.0([email protected])
|
||||
dev: false
|
||||
|
||||
/@thirdweb-dev/[email protected].1-0([email protected]):
|
||||
resolution: {integrity: sha512-s+Wj0hZ6OFu2B+iykEf8N+7uyCUzLQHVQYGWYPiuMwqi0urYiiJyseRe1/jhZ9IkXD+RA4pCOyYrtXfT6r8m3Q==}
|
||||
/@thirdweb-dev/[email protected].2-3([email protected]):
|
||||
resolution: {integrity: sha512-QWO9HT4k3s86oMyE/SbDWhgm/Na9FnxOkVjhyuOigmrwq5NlNp7NCcmecQgILxvUiLXO9if9OeFlYCFGsJinng==}
|
||||
dependencies:
|
||||
'@chainlink/contracts': 0.6.1([email protected])
|
||||
'@openzeppelin/contracts': 4.9.3
|
||||
@@ -25539,7 +25539,7 @@ packages:
|
||||
engines: {node: '>=12.0.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
protobufjs: '>=7.2.4'
|
||||
protobufjs: ^7.0.0
|
||||
dependencies:
|
||||
chalk: 4.1.2
|
||||
escodegen: 1.14.3
|
||||
|
||||
Reference in New Issue
Block a user