Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed6c54f20d | ||
|
|
26116a6f63 | ||
|
|
f11a2719ff | ||
|
|
ef27aad0aa | ||
|
|
b03a902145 | ||
|
|
340605b507 | ||
|
|
15f8006e1f | ||
|
|
811c5a1166 |
@@ -9,10 +9,10 @@ runs:
|
||||
with:
|
||||
node-version: 16
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
# cache: "yarn"
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: yarn install --frozen-lockfile
|
||||
run: yarn install
|
||||
env:
|
||||
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "1"
|
||||
|
||||
@@ -14,8 +14,7 @@ jobs:
|
||||
build:
|
||||
name: Build and Test
|
||||
# timeout-minutes: 15
|
||||
# try out buildjet to speed up build and test
|
||||
runs-on: buildjet-32vcpu-ubuntu-2204
|
||||
runs-on: ubuntu-latest-32
|
||||
# To use Remote Caching, uncomment the next lines and follow the steps below.
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
|
||||
@@ -13,8 +13,7 @@ concurrency:
|
||||
jobs:
|
||||
integration-tests:
|
||||
timeout-minutes: 60
|
||||
# try out buildjet to speed up build and test
|
||||
runs-on: buildjet-32vcpu-ubuntu-2204
|
||||
runs-on: ubuntu-latest-32
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
@@ -28,9 +27,3 @@ jobs:
|
||||
run: yarn e2e
|
||||
env:
|
||||
NODE_OPTIONS: "--max_old_space_size=4096"
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: always()
|
||||
with:
|
||||
name: playwright-report
|
||||
path: packages/react/playwright-report/
|
||||
retention-days: 30
|
||||
|
||||
@@ -40,8 +40,7 @@ jobs:
|
||||
comment_body: ${{ github.event.comment.body }}
|
||||
|
||||
deploy:
|
||||
# try out buildjet to speed up build and test
|
||||
runs-on: buildjet-32vcpu-ubuntu-2204
|
||||
runs-on: ubuntu-latest-32
|
||||
needs: deploy-check
|
||||
if: needs.deploy-check.outputs.triggered == 'true'
|
||||
steps:
|
||||
|
||||
@@ -14,8 +14,7 @@ concurrency:
|
||||
jobs:
|
||||
release:
|
||||
name: Release
|
||||
# try out buildjet to speed up build and test
|
||||
runs-on: buildjet-32vcpu-ubuntu-2204
|
||||
runs-on: ubuntu-latest-32
|
||||
steps:
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v3
|
||||
|
||||
@@ -4,8 +4,7 @@ on: [pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# try out buildjet to speed up build and test
|
||||
runs-on: buildjet-32vcpu-ubuntu-2204
|
||||
runs-on: ubuntu-latest-32
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
+5
-1
@@ -12,4 +12,8 @@ server/dist
|
||||
public/dist
|
||||
.turbo
|
||||
./packages/contracts-js/abis
|
||||
.idea/
|
||||
.idea/
|
||||
.yalc/
|
||||
yalc.lock
|
||||
build/
|
||||
playwright-report/
|
||||
@@ -1,4 +1,3 @@
|
||||
lib
|
||||
node_modules
|
||||
dist
|
||||
contracts-js
|
||||
|
||||
+2
-6
@@ -8,7 +8,8 @@
|
||||
"private": true,
|
||||
"workspaces": {
|
||||
"packages": [
|
||||
"packages/*"
|
||||
"packages/*",
|
||||
"test/**/*"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
@@ -29,11 +30,6 @@
|
||||
"release:nightly": "node ./scripts/pre-release.mjs && changeset publish --tag nightly",
|
||||
"push": "turbo run push"
|
||||
},
|
||||
"preconstruct": {
|
||||
"packages": [
|
||||
"packages/*"
|
||||
]
|
||||
},
|
||||
"packageManager": "[email protected]",
|
||||
"dependencies": {
|
||||
"@changesets/changelog-github": "^0.4.6",
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @thirdweb-dev/auth
|
||||
|
||||
## 2.0.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#327](https://github.com/thirdweb-dev/js/pull/327) [`ef27aad`](https://github.com/thirdweb-dev/js/commit/ef27aad0aafc4577e85f44dc77dfbe880bd239b5) Thanks [@jnsdls](https://github.com/jnsdls)! - enable e2e testing
|
||||
|
||||
## 2.0.20
|
||||
|
||||
## 2.0.19
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/auth",
|
||||
"version": "2.0.20",
|
||||
"version": "2.0.21",
|
||||
"exports": {
|
||||
"./next": {
|
||||
"module": "./next/dist/thirdweb-dev-auth-next.esm.js",
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# thirdweb
|
||||
|
||||
## 0.8.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#327](https://github.com/thirdweb-dev/js/pull/327) [`ef27aad`](https://github.com/thirdweb-dev/js/commit/ef27aad0aafc4577e85f44dc77dfbe880bd239b5) Thanks [@jnsdls](https://github.com/jnsdls)! - enable e2e testing
|
||||
|
||||
- Updated dependencies [[`340605b`](https://github.com/thirdweb-dev/js/commit/340605b507f384fbd2999b9c16542af3c53e84a9), [`26116a6`](https://github.com/thirdweb-dev/js/commit/26116a6f637ee845f7bd17f20ffe17caf184658e), [`15f8006`](https://github.com/thirdweb-dev/js/commit/15f8006e1fb22333b7ee239b45e7b1b12d6dccc8), [`ef27aad`](https://github.com/thirdweb-dev/js/commit/ef27aad0aafc4577e85f44dc77dfbe880bd239b5)]:
|
||||
- @thirdweb-dev/sdk@3.4.0
|
||||
|
||||
## 0.8.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "thirdweb",
|
||||
"main": "dist/cli/index.js",
|
||||
"version": "0.8.6",
|
||||
"version": "0.8.7",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -40,7 +40,7 @@ $$$$$$\\ $$$$$$$\\ $$\\ $$$$$$\\ $$$$$$$ |$$\\ $$\\ $$\\ $$$$$$\\ $$$$
|
||||
.version(cliVersion, "-v, --version");
|
||||
|
||||
program
|
||||
.command("create")
|
||||
.command("create [projectPath]")
|
||||
.description(
|
||||
"Create a web3 app from any of our official templates: https://github.com/thirdweb-example/",
|
||||
)
|
||||
@@ -66,8 +66,8 @@ $$$$$$\\ $$$$$$$\\ $$\\ $$$$$$\\ $$$$$$$ |$$\\ $$\\ $$\\ $$$$$$\\ $$$$
|
||||
"-t, --template [name]",
|
||||
`A template to start your project from. You can use an template repository name from the official thirdweb-example org.`,
|
||||
)
|
||||
.action(async (options) => {
|
||||
await twCreate(options);
|
||||
.action(async (path, options) => {
|
||||
await twCreate(path, options);
|
||||
});
|
||||
|
||||
program
|
||||
|
||||
@@ -17,9 +17,9 @@ let language: string = "";
|
||||
let baseContract: string = "";
|
||||
/* let createType: string = "app"; */
|
||||
|
||||
export async function twCreate(options: any) {
|
||||
if (typeof projectPath === "string") {
|
||||
projectPath = projectPath.trim();
|
||||
export async function twCreate(pPath: string = "", options: any) {
|
||||
if (typeof pPath === "string") {
|
||||
projectPath = pPath;
|
||||
}
|
||||
|
||||
if (options.app) {
|
||||
|
||||
@@ -1,5 +1,47 @@
|
||||
# @thirdweb-dev/react
|
||||
|
||||
## 3.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#327](https://github.com/thirdweb-dev/js/pull/327) [`ef27aad`](https://github.com/thirdweb-dev/js/commit/ef27aad0aafc4577e85f44dc77dfbe880bd239b5) Thanks [@jnsdls](https://github.com/jnsdls)! - Gnosis Safe and Magic Link connectors are no longer included in the default export. They are now available as named exports instead.
|
||||
|
||||
## Gnosis Safe
|
||||
|
||||
### Connector
|
||||
|
||||
```diff
|
||||
- import { GnosisSafeConnector } from "@thirdweb-dev/react";
|
||||
+ import { GnosisSafeConnector } from "@thirdweb-dev/react/evm/connectors/gnosis-safe";
|
||||
```
|
||||
|
||||
### Hook
|
||||
|
||||
```diff
|
||||
- import { useGnosis } from "@thirdweb-dev/react";
|
||||
+ import { useGnosis } from "@thirdweb-dev/react/evm/connectors/gnosis-safe";
|
||||
```
|
||||
|
||||
## Magic Link
|
||||
|
||||
### Connector
|
||||
|
||||
```diff
|
||||
- import { MagicLink } from "@thirdweb-dev/react";
|
||||
+ import { MagicConnector } from "@thirdweb-dev/react/evm/connectors/magic";
|
||||
```
|
||||
|
||||
### Hook
|
||||
|
||||
```diff
|
||||
- import { useMagic } from "@thirdweb-dev/react";
|
||||
+ import { useMagic } from "@thirdweb-dev/react/evm/connectors/magic";
|
||||
```
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#339](https://github.com/thirdweb-dev/js/pull/339) [`b03a902`](https://github.com/thirdweb-dev/js/commit/b03a9021451b79f802f682f66e5ae8e9355d7e6f) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - Fix docs for some functions
|
||||
|
||||
## 3.3.1
|
||||
|
||||
## 3.3.0
|
||||
|
||||
@@ -26,11 +26,11 @@ The `useContractCall` hook to call a smart contract function has been renamed to
|
||||
|
||||
### Prebuilt Contract Hooks
|
||||
|
||||
Hooks to connect to prebuilt contracts such as `useNFTDrop` and `useMarketplace` are now deprecated in favour of using the generic `useContract` hook:
|
||||
Hooks to connect to prebuilt contracts such as `useNFTDrop` and `useMarketplace` are now deprecated in favour of using the generic `useContract` hook followed by the contract type:
|
||||
|
||||
```diff
|
||||
- const contract = useNFTDrop("0x...")
|
||||
+ const { contract } = useContract("0x...")
|
||||
+ const { contract } = useContract("0x...", "nft-drop")
|
||||
```
|
||||
|
||||
You can currently still continue to use the prebuilt hooks, however they provide a warning in the console informing you of their deprecation. We will likely remove these hooks in a future version of the SDK.
|
||||
|
||||
@@ -191,7 +191,7 @@ export default function Home() {
|
||||
<div>
|
||||
{nfts.map((nft) => (
|
||||
<ThirdwebNftMedia
|
||||
key={nft.tokenId}
|
||||
key={nft.metadata.id}
|
||||
metadata={nft.metadata}
|
||||
height={200}
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"main": "dist/thirdweb-dev-react-evm-connectors-gnosis-safe.cjs.js",
|
||||
"module": "dist/thirdweb-dev-react-evm-connectors-gnosis-safe.esm.js"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"main": "dist/thirdweb-dev-react-evm-connectors-magic.cjs.js",
|
||||
"module": "dist/thirdweb-dev-react-evm-connectors-magic.esm.js"
|
||||
}
|
||||
+19
-18
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react",
|
||||
"version": "3.3.1",
|
||||
"version": "3.4.0",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
@@ -20,6 +20,14 @@
|
||||
"module": "./solana/dist/thirdweb-dev-react-solana.esm.js",
|
||||
"default": "./solana/dist/thirdweb-dev-react-solana.cjs.js"
|
||||
},
|
||||
"./evm/connectors/magic": {
|
||||
"module": "./evm/connectors/magic/dist/thirdweb-dev-react-evm-connectors-magic.esm.js",
|
||||
"default": "./evm/connectors/magic/dist/thirdweb-dev-react-evm-connectors-magic.cjs.js"
|
||||
},
|
||||
"./evm/connectors/gnosis-safe": {
|
||||
"module": "./evm/connectors/gnosis-safe/dist/thirdweb-dev-react-evm-connectors-gnosis-safe.esm.js",
|
||||
"default": "./evm/connectors/gnosis-safe/dist/thirdweb-dev-react-evm-connectors-gnosis-safe.cjs.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"files": [
|
||||
@@ -31,7 +39,8 @@
|
||||
"entrypoints": [
|
||||
"index.ts",
|
||||
"solana/index.ts",
|
||||
"evm/index.ts"
|
||||
"evm/index.ts",
|
||||
"evm/connectors/**.ts"
|
||||
],
|
||||
"___experimentalFlags_WILL_CHANGE_IN_PATCH": {
|
||||
"exports": true
|
||||
@@ -49,8 +58,6 @@
|
||||
"generate-docs:solana": "api-extractor run --local --config ./config/api-extractor-solana.json && api-documenter markdown -i ./temp -o ./docs/solana && rm -rf ./temp-solana && mv ./temp ./temp-solana",
|
||||
"generate-snippets": "node ./scripts/generate-snippets-evm.mjs && node ./scripts/generate-snippets-solana.mjs && node ./scripts/generate-feature-snippets-evm.mjs",
|
||||
"build": "tsc && preconstruct build",
|
||||
"e2e": "yarn test-ct",
|
||||
"test-ct": "playwright test -c playwright-ct.config.ts",
|
||||
"push": "yalc push"
|
||||
},
|
||||
"sideEffects:": false,
|
||||
@@ -63,15 +70,11 @@
|
||||
"@microsoft/api-documenter": "^7.19.4",
|
||||
"@microsoft/api-extractor": "^7.29.2",
|
||||
"@microsoft/tsdoc": "^0.14.1",
|
||||
"@playwright/experimental-ct-react": "1.25.1",
|
||||
"@playwright/test": "1.25.1",
|
||||
"@preconstruct/cli": "^2.2.1",
|
||||
"@solana/wallet-adapter-base": "^0.9.17",
|
||||
"@solana/wallet-adapter-react": "^0.15.19",
|
||||
"@solana/wallet-adapter-wallets": "^0.19.0",
|
||||
"@solana/web3.js": "^1.63.0",
|
||||
"@solana/web3.js": "^1.62.0",
|
||||
"@thirdweb-dev/sdk": "*",
|
||||
"@thirdweb-dev/solana": "*",
|
||||
"@types/color": "^3.0.3",
|
||||
"@types/mime": "^3.0.1",
|
||||
"@types/react": "^18.0.5",
|
||||
@@ -93,13 +96,14 @@
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.10.0",
|
||||
"@emotion/styled": "^11.10.0",
|
||||
"@gnosis.pm/safe-core-sdk": "2.1.0",
|
||||
"@gnosis.pm/safe-ethers-adapters": "0.1.0-alpha.9",
|
||||
"@gnosis.pm/safe-ethers-lib": "1.1.0",
|
||||
"@gnosis.pm/safe-core-sdk": "^3.1.1",
|
||||
"@gnosis.pm/safe-ethers-adapters": "0.1.0-alpha.11",
|
||||
"@gnosis.pm/safe-ethers-lib": "^1.6.1",
|
||||
"@react-icons/all-files": "^4.1.0",
|
||||
"@solana/wallet-adapter-phantom": "^0.9.17",
|
||||
"@tanstack/react-query": "^4.0.10",
|
||||
"@zag-js/menu": "0.1.14",
|
||||
"@zag-js/react": "0.1.16",
|
||||
"@zag-js/menu": "^0.1.16",
|
||||
"@zag-js/react": "^0.1.18",
|
||||
"buffer": "^6.0.3",
|
||||
"color": "^4.2.3",
|
||||
"copy-to-clipboard": "^3.3.2",
|
||||
@@ -114,7 +118,7 @@
|
||||
"@solana/wallet-adapter-base": "^0.9.17",
|
||||
"@solana/wallet-adapter-react": "^0.15.19",
|
||||
"@solana/wallet-adapter-wallets": "^0.19.0",
|
||||
"@solana/web3.js": "^1.63.0",
|
||||
"@solana/web3.js": "^1.62.0",
|
||||
"@thirdweb-dev/sdk": "*",
|
||||
"ethers": ">=5.5.1",
|
||||
"react": ">=18.0.0",
|
||||
@@ -136,9 +140,6 @@
|
||||
},
|
||||
"@solana/web3.js": {
|
||||
"optional": true
|
||||
},
|
||||
"@thirdweb-dev/solana": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
import type { PlaywrightTestConfig } from "@playwright/experimental-ct-react";
|
||||
import { devices } from "@playwright/experimental-ct-react";
|
||||
|
||||
/**
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
const config: PlaywrightTestConfig = {
|
||||
testDir: "./",
|
||||
/* The base directory, relative to the config file, for snapshot files created with toMatchSnapshot and toHaveScreenshot. */
|
||||
snapshotDir: "./__snapshots__",
|
||||
/* Maximum time one test can run for. */
|
||||
timeout: 10 * 1000,
|
||||
/* Run tests in files in parallel */
|
||||
fullyParallel: true,
|
||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||
forbidOnly: !!process.env.CI,
|
||||
/* Retry on CI only */
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
/* Opt out of parallel tests on CI. */
|
||||
// workers: process.env.CI ? 1 : undefined,
|
||||
// we can use parallel tests because we have more cores now
|
||||
workers: undefined,
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: "html",
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: "on-first-retry",
|
||||
|
||||
/* Port to use for Playwright component endpoint. */
|
||||
ctPort: 3100,
|
||||
},
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
projects: [
|
||||
{
|
||||
name: "chromium",
|
||||
use: {
|
||||
...devices["Desktop Chrome"],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "firefox",
|
||||
use: {
|
||||
...devices["Desktop Firefox"],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "webkit",
|
||||
use: {
|
||||
...devices["Desktop Safari"],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -1,4 +0,0 @@
|
||||
// Import styles, initialize component theme here.
|
||||
// import '../src/common.css';
|
||||
|
||||
export {};
|
||||
@@ -1,15 +0,0 @@
|
||||
import { ConnectWallet } from ".";
|
||||
import { ThirdwebProvider } from "../../providers/full";
|
||||
import { test, expect } from "@playwright/experimental-ct-react";
|
||||
|
||||
test.use({ viewport: { width: 500, height: 500 } });
|
||||
|
||||
test("should render the connect wallet button", async ({ mount }) => {
|
||||
const component = await mount(
|
||||
<ThirdwebProvider desiredChainId={1}>
|
||||
<ConnectWallet />
|
||||
</ThirdwebProvider>,
|
||||
);
|
||||
|
||||
await expect(component).toContainText("Connect Wallet");
|
||||
});
|
||||
@@ -144,7 +144,7 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = ({
|
||||
},
|
||||
connect,
|
||||
] = useConnect();
|
||||
const disconnect = useDisconnect({ reconnectAfterGnosis: false });
|
||||
const disconnect = useDisconnect({ reconnectPrevious: false });
|
||||
|
||||
const supportedConnectors = connectors.filter((c) =>
|
||||
SUPPORTED_CONNECTORS.includes(c.id as typeof SUPPORTED_CONNECTORS[number]),
|
||||
|
||||
@@ -13,12 +13,14 @@ export interface ThirdwebNftMediaProps extends SharedMediaProps {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* This component can be used to render NFTs from the thirdweb SDK.
|
||||
* Props: {@link ThirdwebNftMediaProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* import { ThirdwebNftMedia, useNFTCollection, useNFT } from "@thirdweb-dev/react";
|
||||
* import { ThirdwebNftMedia, useContract, useNFT } from "@thirdweb-dev/react";
|
||||
* export default function NFTCollectionRender() {
|
||||
* const contract = useNFTCollection(<your-contract-address>);
|
||||
* const { contract } = useContract(<your-contract-address>);
|
||||
* const { data: nft, isLoading } = useNFT(contract, 0);
|
||||
*
|
||||
* return (
|
||||
@@ -32,11 +34,6 @@ export interface ThirdwebNftMediaProps extends SharedMediaProps {
|
||||
* );
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Use this to get the primary sales recipient of your {@link SmartContract}
|
||||
* @param contract - an instance of a {@link SmartContract}
|
||||
* @returns the wallet address of the primary sales recipient
|
||||
* @beta
|
||||
*/
|
||||
export const ThirdwebNftMedia = React.forwardRef<
|
||||
HTMLMediaElement,
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import { Web3Button } from ".";
|
||||
import { ThirdwebProvider } from "../../providers/full";
|
||||
import { test, expect } from "@playwright/experimental-ct-react";
|
||||
|
||||
test.use({ viewport: { width: 500, height: 500 } });
|
||||
|
||||
test("should render the connect wallet button", async ({ mount }) => {
|
||||
const component = await mount(
|
||||
<ThirdwebProvider desiredChainId={1}>
|
||||
<Web3Button contractAddress="0x123" action={() => undefined}>
|
||||
Do the thing
|
||||
</Web3Button>
|
||||
</ThirdwebProvider>,
|
||||
);
|
||||
await expect(component).toContainText("Connect Wallet");
|
||||
});
|
||||
@@ -1,13 +1,23 @@
|
||||
import { ChainId } from "@thirdweb-dev/sdk";
|
||||
import { useConnect } from "../hooks/wagmi-required/useConnect";
|
||||
import { Signer, ethers, utils } from "ethers";
|
||||
import invariant from "tiny-invariant";
|
||||
import { Chain, Connector, ConnectorData, normalizeChainId } from "wagmi";
|
||||
import {
|
||||
Chain,
|
||||
Connector,
|
||||
ConnectorData,
|
||||
normalizeChainId,
|
||||
useContext as useWagmiContext,
|
||||
} from "wagmi";
|
||||
|
||||
const CHAIN_ID_TO_GNOSIS_SERVER_URL = {
|
||||
[ChainId.Mainnet]: "https://safe-transaction.mainnet.gnosis.io",
|
||||
[ChainId.Avalanche]: "https://safe-transaction.avalanche.gnosis.io",
|
||||
[ChainId.Polygon]: "https://safe-transaction.polygon.gnosis.io",
|
||||
[ChainId.Goerli]: "https://safe-transaction.goerli.gnosis.io",
|
||||
// mainnet
|
||||
1: "https://safe-transaction.mainnet.gnosis.io",
|
||||
// avalanche
|
||||
43114: "https://safe-transaction.avalanche.gnosis.io",
|
||||
// polygon
|
||||
137: "https://safe-transaction.polygon.gnosis.io",
|
||||
// goerli
|
||||
5: "https://safe-transaction.goerli.gnosis.io",
|
||||
};
|
||||
|
||||
export interface GnosisConnectorArguments {
|
||||
@@ -163,3 +173,67 @@ export class GnosisSafeConnector extends Connector {
|
||||
this.config = config;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for connecting to a Gnosis Safe. This enables multisig wallets to connect to your application and sing transactions.
|
||||
*
|
||||
* ```javascript
|
||||
* import { useGnosis } from "@thirdweb-dev/react"
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* import { useGnosis } from "@thirdweb-dev/react"
|
||||
*
|
||||
* const App = () => {
|
||||
* const connectWithGnosis = useGnosis()
|
||||
*
|
||||
* return (
|
||||
* <button onClick={() => connectWithGnosis({ safeAddress: "0x...", safeChainId: 1 })}>
|
||||
* Connect Gnosis Safe
|
||||
* </button>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function useGnosis() {
|
||||
const wagmiContext = useWagmiContext();
|
||||
invariant(
|
||||
wagmiContext,
|
||||
`useGnosis() can only be used inside <ThirdwebProvider />. If you are using <ThirdwebSDKProvider /> you will have to use your own wallet-connection logic.`,
|
||||
);
|
||||
const [connectors, connect] = useConnect();
|
||||
if (connectors.loading) {
|
||||
return () => Promise.reject("Gnosis connector not ready to be used, yet");
|
||||
}
|
||||
const connector = connectors.data.connectors.find((c) => c.id === "gnosis");
|
||||
invariant(
|
||||
connector,
|
||||
"Gnosis connector not found, please make sure it is provided to your <ThirdwebProvider />",
|
||||
);
|
||||
|
||||
return async (config: GnosisConnectorArguments) => {
|
||||
const previousConnector = connectors.data.connector;
|
||||
const previousConnectorChain = await previousConnector?.getChainId();
|
||||
invariant(
|
||||
!!previousConnector,
|
||||
"Cannot connect to Gnosis Safe without first being connected to a personal wallet.",
|
||||
);
|
||||
invariant(
|
||||
previousConnectorChain === config.safeChainId,
|
||||
"Gnosis safe chain id must match personal wallet chain id.",
|
||||
);
|
||||
invariant(
|
||||
utils.isAddress(config.safeAddress),
|
||||
"Gnosis safe address must be a valid address.",
|
||||
);
|
||||
(connector as GnosisSafeConnector).setConfiguration(
|
||||
previousConnector,
|
||||
config,
|
||||
);
|
||||
return connect(connector);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useConnect } from "../hooks/wagmi-required/useConnect";
|
||||
import { providers, utils } from "ethers";
|
||||
import type {
|
||||
LoginWithMagicLinkConfiguration,
|
||||
@@ -5,7 +6,12 @@ import type {
|
||||
MagicSDKAdditionalConfiguration,
|
||||
} from "magic-sdk";
|
||||
import invariant from "tiny-invariant";
|
||||
import { Chain, Connector, normalizeChainId } from "wagmi";
|
||||
import {
|
||||
Chain,
|
||||
Connector,
|
||||
normalizeChainId,
|
||||
useContext as useWagmiContext,
|
||||
} from "wagmi";
|
||||
|
||||
export interface MagicConnectorArguments
|
||||
extends MagicSDKAdditionalConfiguration {
|
||||
@@ -186,3 +192,89 @@ export class MagicConnector extends Connector {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for connecting to an email wallet using magic link.
|
||||
* This enables users without their own wallets to connect to your application and sign transactions securely using their email.
|
||||
*
|
||||
* ```javascript
|
||||
* import { useMagic } from "@thirdweb-dev/react"
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* Before using this hook, you first need to set up the magic configuration in your `ThirdwebProvider`, including your magic API key.
|
||||
*
|
||||
* ```javascript
|
||||
* // Add the magic configuration object to your wallet connectors
|
||||
* const connectors = [
|
||||
* "metamask",
|
||||
* "walletConnect",
|
||||
* "walletLink",
|
||||
* {
|
||||
* name: "magic",
|
||||
* options: {
|
||||
* apiKey: "your-magic-api-key",
|
||||
* }
|
||||
* }
|
||||
* ]
|
||||
*
|
||||
* // Add the above to the walletConnectors prop of your <ThirdwebProvider />
|
||||
* const Provider = ({ children }) => (
|
||||
* return (
|
||||
* <ThirdwebProvider
|
||||
* walletConnectors={connectors}
|
||||
* // Specify remaining parameters
|
||||
* ...
|
||||
* >
|
||||
* {children}
|
||||
* </ThirdwebProvider>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* In order to use the hook to connect users with magic link, you just need to provide the users email to the connect function.
|
||||
*
|
||||
* You can setup the hook with the following configuration:
|
||||
* ```javascript
|
||||
* import { useMagic } from "@thirdweb-dev/react"
|
||||
* import { useState } from "react"
|
||||
*
|
||||
* const LoginWithMagicLink = () => {
|
||||
* const connectWithMagic = useMagic()
|
||||
* const [email, setEmail] = useState()
|
||||
*
|
||||
* return (
|
||||
* <div>
|
||||
* <input value={email} onChange={(e) => setEmail(e.target.value)} />
|
||||
* <button onClick={() => connectWithMagic({ email })}>Login</button>
|
||||
* </div>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function useMagic() {
|
||||
const wagmiContext = useWagmiContext();
|
||||
invariant(
|
||||
wagmiContext,
|
||||
`useMagic() can only be used inside <ThirdwebProvider />. If you are using <ThirdwebSDKProvider /> you will have to use your own wallet-connection logic.`,
|
||||
);
|
||||
const [connectors, connect] = useConnect();
|
||||
if (connectors.loading) {
|
||||
return () => Promise.reject("Magic connector not ready to be used, yet");
|
||||
}
|
||||
|
||||
const connector = connectors.data.connectors.find((c) => c.id === "magic");
|
||||
|
||||
invariant(
|
||||
connector,
|
||||
"Magic connector not found, please make sure it is provided to your <ThirdwebProvider />",
|
||||
);
|
||||
|
||||
return (configuration: LoginWithMagicLinkConfiguration) => {
|
||||
(connector as MagicConnector).setConfiguration(configuration);
|
||||
return connect(connector);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -542,7 +542,7 @@ export function useTransferNFT<TContract extends NFTContract>(
|
||||
* @example
|
||||
* ```jsx
|
||||
* const Component = () => {
|
||||
* const editionDrop = useEditionDrop(<ContractAddress>);
|
||||
* const editionDrop = useContract(<ContractAddress>, "edition-drop");
|
||||
* const {
|
||||
* mutate: airdropNFT,
|
||||
* isLoading,
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
import {
|
||||
GnosisConnectorArguments,
|
||||
GnosisSafeConnector,
|
||||
} from "../../connectors/gnosis-safe";
|
||||
import { useConnect } from "../wagmi-required/useConnect";
|
||||
import { utils } from "ethers";
|
||||
import invariant from "tiny-invariant";
|
||||
import { useContext as useWagmiContext } from "wagmi";
|
||||
|
||||
/**
|
||||
* Hook for connecting to a Gnosis Safe. This enables multisig wallets to connect to your application and sing transactions.
|
||||
*
|
||||
* ```javascript
|
||||
* import { useGnosis } from "@thirdweb-dev/react"
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* import { useGnosis } from "@thirdweb-dev/react"
|
||||
*
|
||||
* const App = () => {
|
||||
* const connectWithGnosis = useGnosis()
|
||||
*
|
||||
* return (
|
||||
* <button onClick={() => connectWithGnosis({ safeAddress: "0x...", safeChainId: 1 })}>
|
||||
* Connect Gnosis Safe
|
||||
* </button>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function useGnosis() {
|
||||
const wagmiContext = useWagmiContext();
|
||||
invariant(
|
||||
wagmiContext,
|
||||
`useGnosis() can only be used inside <ThirdwebProvider />. If you are using <ThirdwebSDKProvider /> you will have to use your own wallet-connection logic.`,
|
||||
);
|
||||
const [connectors, connect] = useConnect();
|
||||
if (connectors.loading) {
|
||||
return () => Promise.reject("Gnosis connector not ready to be used, yet");
|
||||
}
|
||||
const connector = connectors.data.connectors.find((c) => c.id === "gnosis");
|
||||
invariant(
|
||||
connector,
|
||||
"Gnosis connector not found, please make sure it is provided to your <ThirdwebProvider />",
|
||||
);
|
||||
|
||||
return async (config: GnosisConnectorArguments) => {
|
||||
const previousConnector = connectors.data.connector;
|
||||
const previousConnectorChain = await previousConnector?.getChainId();
|
||||
invariant(
|
||||
!!previousConnector,
|
||||
"Cannot connect to Gnosis Safe without first being connected to a personal wallet.",
|
||||
);
|
||||
invariant(
|
||||
previousConnectorChain === config.safeChainId,
|
||||
"Gnosis safe chain id must match personal wallet chain id.",
|
||||
);
|
||||
invariant(
|
||||
utils.isAddress(config.safeAddress),
|
||||
"Gnosis safe address must be a valid address.",
|
||||
);
|
||||
(connector as GnosisSafeConnector).setConfiguration(
|
||||
previousConnector,
|
||||
config,
|
||||
);
|
||||
return connect(connector);
|
||||
};
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
import { MagicConnector } from "../../connectors/magic";
|
||||
import { useConnect } from "../wagmi-required/useConnect";
|
||||
import { LoginWithMagicLinkConfiguration } from "magic-sdk";
|
||||
import invariant from "tiny-invariant";
|
||||
import { useContext as useWagmiContext } from "wagmi";
|
||||
|
||||
/**
|
||||
* Hook for connecting to an email wallet using magic link.
|
||||
* This enables users without their own wallets to connect to your application and sign transactions securely using their email.
|
||||
*
|
||||
* ```javascript
|
||||
* import { useMagic } from "@thirdweb-dev/react"
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* Before using this hook, you first need to set up the magic configuration in your `ThirdwebProvider`, including your magic API key.
|
||||
*
|
||||
* ```javascript
|
||||
* // Add the magic configuration object to your wallet connectors
|
||||
* const connectors = [
|
||||
* "metamask",
|
||||
* "walletConnect",
|
||||
* "walletLink",
|
||||
* {
|
||||
* name: "magic",
|
||||
* options: {
|
||||
* apiKey: "your-magic-api-key",
|
||||
* }
|
||||
* }
|
||||
* ]
|
||||
*
|
||||
* // Add the above to the walletConnectors prop of your <ThirdwebProvider />
|
||||
* const Provider = ({ children }) => (
|
||||
* return (
|
||||
* <ThirdwebProvider
|
||||
* walletConnectors={connectors}
|
||||
* // Specify remaining parameters
|
||||
* ...
|
||||
* >
|
||||
* {children}
|
||||
* </ThirdwebProvider>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* In order to use the hook to connect users with magic link, you just need to provide the users email to the connect function.
|
||||
*
|
||||
* You can setup the hook with the following configuration:
|
||||
* ```javascript
|
||||
* import { useMagic } from "@thirdweb-dev/react"
|
||||
* import { useState } from "react"
|
||||
*
|
||||
* const LoginWithMagicLink = () => {
|
||||
* const connectWithMagic = useMagic()
|
||||
* const [email, setEmail] = useState()
|
||||
*
|
||||
* return (
|
||||
* <div>
|
||||
* <input value={email} onChange={(e) => setEmail(e.target.value)} />
|
||||
* <button onClick={() => connectWithMagic({ email })}>Login</button>
|
||||
* </div>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function useMagic() {
|
||||
const wagmiContext = useWagmiContext();
|
||||
invariant(
|
||||
wagmiContext,
|
||||
`useMagic() can only be used inside <ThirdwebProvider />. If you are using <ThirdwebSDKProvider /> you will have to use your own wallet-connection logic.`,
|
||||
);
|
||||
const [connectors, connect] = useConnect();
|
||||
if (connectors.loading) {
|
||||
return () => Promise.reject("Magic connector not ready to be used, yet");
|
||||
}
|
||||
|
||||
const connector = connectors.data.connectors.find((c) => c.id === "magic");
|
||||
|
||||
invariant(
|
||||
connector,
|
||||
"Magic connector not found, please make sure it is provided to your <ThirdwebProvider />",
|
||||
);
|
||||
|
||||
return (configuration: LoginWithMagicLinkConfiguration) => {
|
||||
(connector as MagicConnector).setConfiguration(configuration);
|
||||
return connect(connector);
|
||||
};
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useConnect } from "../wagmi-required/useConnect";
|
||||
import { Buffer } from "buffer";
|
||||
import invariant from "tiny-invariant";
|
||||
import { useContext as useWagmiContext } from "wagmi";
|
||||
|
||||
if (!globalThis.Buffer) {
|
||||
globalThis.Buffer = require("buffer/").Buffer;
|
||||
}
|
||||
globalThis.Buffer = Buffer;
|
||||
|
||||
/**
|
||||
* Hook for connecting to a mobile wallet with Wallet Connect
|
||||
*
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useConnect } from "../wagmi-required/useConnect";
|
||||
import { Buffer } from "buffer";
|
||||
import invariant from "tiny-invariant";
|
||||
import { useContext as useWagmiContext } from "wagmi";
|
||||
|
||||
if (!globalThis.Buffer) {
|
||||
globalThis.Buffer = require("buffer/").Buffer;
|
||||
}
|
||||
globalThis.Buffer = Buffer;
|
||||
|
||||
/**
|
||||
* Hook for connecting to a Coinbase wallet.
|
||||
*
|
||||
|
||||
@@ -28,8 +28,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const edition = await sdk.useEdition("0x1234...");
|
||||
* + const edition = await sdk.useContract("0x1234...", "edition").contract;
|
||||
* - const edition = useEdition("0x1234...");
|
||||
* + const edition = useContract("0x1234...", "edition").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useEdition(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -27,8 +27,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const editionDrop = await sdk.useEditionDrop("0x1234...");
|
||||
* + const editionDrop = await sdk.useContract("0x1234...", "edition-drop").contract;
|
||||
* - const editionDrop = useEditionDrop("0x1234...");
|
||||
* + const editionDrop = useContract("0x1234...", "edition-drop").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useEditionDrop(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -28,8 +28,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const marketplace = await sdk.useMarketplace("0x1234...");
|
||||
* + const marketplace = await sdk.useContract("0x1234...", "marketplace").contract;
|
||||
* - const marketplace = useMarketplace("0x1234...");
|
||||
* + const marketplace = useContract("0x1234...", "marketplace").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useMarketplace(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -27,8 +27,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const multiwrap = await sdk.useMultiwrap("0x1234...");
|
||||
* + const multiwrap = await sdk.useContract("0x1234...", "multiwrap").contract;
|
||||
* - const multiwrap = useMultiwrap("0x1234...");
|
||||
* + const multiwrap = useContract("0x1234...", "multiwrap").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useMultiwrap(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -28,8 +28,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const nftCollection = await sdk.useNFTCollection("0x1234...");
|
||||
* + const nftCollection = await sdk.useContract("0x1234...", "nft-collection").contract;
|
||||
* - const nftCollection = useNFTCollection("0x1234...");
|
||||
* + const nftCollection = useContract("0x1234...", "nft-collection").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useNFTCollection(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -27,8 +27,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const nftDrop = await sdk.useNFTDrop("0x1234...");
|
||||
* + const nftDrop = await sdk.useContract("0x1234...", "nft-drop").contract;
|
||||
* - const nftDrop = useNFTDrop("0x1234...");
|
||||
* + const nftDrop = useContract("0x1234...", "nft-drop").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useNFTDrop(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -28,8 +28,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const pack = await sdk.usePack("0x1234...");
|
||||
* + const pack = await sdk.useContract("0x1234...", "pack").contract;
|
||||
* - const pack = usePack("0x1234...");
|
||||
* + const pack = useContract("0x1234...", "pack").contract;
|
||||
* ```
|
||||
*/
|
||||
export function usePack(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -27,8 +27,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const signatureDrop = await sdk.useSignatureDrop("0x1234...");
|
||||
* + const signatureDrop = await sdk.useContract("0x1234...", "signature-drop").contract;
|
||||
* - const signatureDrop = useSignatureDrop("0x1234...");
|
||||
* + const signatureDrop = useContract("0x1234...", "signature-drop").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useSignatureDrop(contractAddress?: RequiredParam<string>) {
|
||||
|
||||
@@ -28,8 +28,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const split = await sdk.useSplit("0x1234...");
|
||||
* + const split = await sdk.useContract("0x1234...", "split").contract;
|
||||
* - const split = useSplit("0x1234...");
|
||||
* + const split = useContract("0x1234...", "split").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useSplit(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -28,8 +28,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const token = await sdk.useToken("0x1234...");
|
||||
* + const token = await sdk.useContract("0x1234...", "token").contract;
|
||||
* - const token = useToken("0x1234...");
|
||||
* + const token = useContract("0x1234...", "token").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useToken(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -28,8 +28,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const token = await sdk.useTokenDrop("0x1234...");
|
||||
* + const token = await sdk.useContract("0x1234...", "token-drop").contract;
|
||||
* - const token = useTokenDrop("0x1234...");
|
||||
* + const token = useContract("0x1234...", "token-drop").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useTokenDrop(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -28,8 +28,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const vote = await sdk.useVote("0x1234...");
|
||||
* + const vote = await sdk.useContract("0x1234...", "vote").contract;
|
||||
* - const vote = useVote("0x1234...");
|
||||
* + const vote = useContract("0x1234...", "vote").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useVote(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { GnosisSafeConnector } from "../../connectors/gnosis-safe";
|
||||
import { useConnect } from "./useConnect";
|
||||
import invariant from "tiny-invariant";
|
||||
import { useAccount, useContext as useWagmiContext } from "wagmi";
|
||||
import { Connector, useAccount, useContext as useWagmiContext } from "wagmi";
|
||||
|
||||
/**
|
||||
* Hook for disconnecting the currently connected wallet
|
||||
@@ -31,23 +30,22 @@ import { useAccount, useContext as useWagmiContext } from "wagmi";
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function useDisconnect(options?: { reconnectAfterGnosis?: boolean }) {
|
||||
export function useDisconnect(options?: { reconnectPrevious?: boolean }) {
|
||||
const wagmiContext = useWagmiContext();
|
||||
invariant(
|
||||
wagmiContext,
|
||||
`useDisconnect() can only be used inside <ThirdwebProvider />. If you are using <ThirdwebSDKProvider /> you will have to use your own connection logic.`,
|
||||
);
|
||||
const optsWithDefaults = { ...{ reconnectAfterGnosis: true }, ...options };
|
||||
const optsWithDefaults = { ...{ reconnectPrevious: true }, ...options };
|
||||
const [, connect] = useConnect();
|
||||
const [data, disconnect] = useAccount();
|
||||
|
||||
return async () => {
|
||||
const previousConnector =
|
||||
(data.data?.connector instanceof GnosisSafeConnector &&
|
||||
data.data.connector.previousConnector) ||
|
||||
undefined;
|
||||
// if there is a previous connector get it
|
||||
const previousConnector: Connector | undefined =
|
||||
(data?.data?.connector as any)?.previousConnector || undefined;
|
||||
// if it's gnosis, just connect the previous connector
|
||||
if (optsWithDefaults.reconnectAfterGnosis && previousConnector) {
|
||||
if (optsWithDefaults.reconnectPrevious && previousConnector) {
|
||||
try {
|
||||
return await connect(previousConnector);
|
||||
} catch (err) {
|
||||
|
||||
@@ -31,8 +31,6 @@ export * from "./hooks/wagmi-required/useConnect";
|
||||
export * from "./hooks/connectors/useMetamask";
|
||||
export * from "./hooks/connectors/useWalletConnect";
|
||||
export * from "./hooks/connectors/useWalletLink";
|
||||
export * from "./hooks/connectors/useGnosis";
|
||||
export * from "./hooks/connectors/useMagic";
|
||||
|
||||
// re-exports
|
||||
export { ChainId } from "@thirdweb-dev/sdk";
|
||||
|
||||
@@ -1,90 +1,93 @@
|
||||
import { useState, useCallback, useLayoutEffect, useEffect, useRef, PropsWithChildren } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import {
|
||||
useState,
|
||||
useCallback,
|
||||
useLayoutEffect,
|
||||
useEffect,
|
||||
useRef,
|
||||
PropsWithChildren,
|
||||
} from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
|
||||
|
||||
function canUseDOM() {
|
||||
function canUseDOM() {
|
||||
return !!(
|
||||
typeof window !== "undefined" &&
|
||||
window.document &&
|
||||
window.document.createElement
|
||||
);
|
||||
typeof window !== "undefined" &&
|
||||
window.document &&
|
||||
window.document.createElement
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces a re-render, similar to `forceUpdate` in class components.
|
||||
*/
|
||||
function useForceUpdate() {
|
||||
const [, dispatch] = useState<{}>(Object.create(null));
|
||||
return useCallback(() => {
|
||||
dispatch(Object.create(null));
|
||||
}, []);
|
||||
const [, dispatch] = useState<{}>(Object.create(null));
|
||||
return useCallback(() => {
|
||||
dispatch(Object.create(null));
|
||||
}, []);
|
||||
}
|
||||
|
||||
|
||||
const useIsomorphicLayoutEffect = canUseDOM() ? useLayoutEffect : useEffect;
|
||||
|
||||
/**
|
||||
* Portal from `@reach/portal`
|
||||
*
|
||||
* @see Docs https://reach.tech/portal#portal
|
||||
*/
|
||||
const PortalImpl: React.FC<PortalProps> = ({
|
||||
children,
|
||||
type = "reach-portal",
|
||||
containerRef,
|
||||
}) => {
|
||||
const mountNode = useRef<HTMLDivElement | null>(null);
|
||||
const portalNode = useRef<HTMLElement | null>(null);
|
||||
const forceUpdate = useForceUpdate();
|
||||
|
||||
/**
|
||||
* Portal from `@reach/portal`
|
||||
*
|
||||
* @see Docs https://reach.tech/portal#portal
|
||||
*/
|
||||
const PortalImpl: React.FC<PortalProps> = ({
|
||||
children,
|
||||
type = "reach-portal",
|
||||
containerRef,
|
||||
}) => {
|
||||
const mountNode = useRef<HTMLDivElement | null>(null);
|
||||
const portalNode = useRef<HTMLElement | null>(null);
|
||||
const forceUpdate = useForceUpdate();
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
// This ref may be null when a hot-loader replaces components on the page
|
||||
if (!mountNode.current) {
|
||||
return;
|
||||
}
|
||||
// It's possible that the content of the portal has, itself, been portaled.
|
||||
// In that case, it's important to append to the correct document element.
|
||||
const ownerDocument = mountNode.current.ownerDocument;
|
||||
const body = containerRef?.current || ownerDocument.body;
|
||||
portalNode.current = ownerDocument?.createElement(type);
|
||||
body.appendChild(portalNode.current);
|
||||
forceUpdate();
|
||||
return () => {
|
||||
if (portalNode.current && body) {
|
||||
body.removeChild(portalNode.current);
|
||||
}
|
||||
};
|
||||
}, [type, forceUpdate, containerRef]);
|
||||
|
||||
return portalNode.current ? (
|
||||
createPortal(children, portalNode.current)
|
||||
) : (
|
||||
<span ref={mountNode} />
|
||||
);
|
||||
};
|
||||
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
// This ref may be null when a hot-loader replaces components on the page
|
||||
if (!mountNode.current) {return;}
|
||||
// It's possible that the content of the portal has, itself, been portaled.
|
||||
// In that case, it's important to append to the correct document element.
|
||||
const ownerDocument = mountNode.current.ownerDocument;
|
||||
const body = containerRef?.current || ownerDocument.body;
|
||||
portalNode.current = ownerDocument?.createElement(type);
|
||||
body.appendChild(portalNode.current);
|
||||
forceUpdate();
|
||||
return () => {
|
||||
if (portalNode.current && body) {
|
||||
body.removeChild(portalNode.current);
|
||||
}
|
||||
};
|
||||
}, [type, forceUpdate, containerRef]);
|
||||
export const Portal: React.FC<PortalProps> = ({
|
||||
unstable_skipInitialRender,
|
||||
...props
|
||||
}) => {
|
||||
const [hydrated, setHydrated] = useState(false);
|
||||
useEffect(() => {
|
||||
if (unstable_skipInitialRender) {
|
||||
setHydrated(true);
|
||||
}
|
||||
}, [unstable_skipInitialRender]);
|
||||
if (unstable_skipInitialRender && !hydrated) {
|
||||
return null;
|
||||
}
|
||||
return <PortalImpl {...props} />;
|
||||
};
|
||||
|
||||
return portalNode.current ? (
|
||||
createPortal(children, portalNode.current)
|
||||
) : (
|
||||
<span ref={mountNode} />
|
||||
);
|
||||
};
|
||||
|
||||
export const Portal: React.FC<PortalProps> = ({
|
||||
unstable_skipInitialRender,
|
||||
...props
|
||||
}) => {
|
||||
const [hydrated, setHydrated] = useState(false);
|
||||
useEffect(() => {
|
||||
if (unstable_skipInitialRender) {
|
||||
setHydrated(true);
|
||||
}
|
||||
}, [unstable_skipInitialRender]);
|
||||
if (unstable_skipInitialRender && !hydrated) {
|
||||
return null;
|
||||
}
|
||||
return <PortalImpl {...props} />;
|
||||
};
|
||||
|
||||
|
||||
export type PortalProps = PropsWithChildren<{
|
||||
type?: string;
|
||||
containerRef?: React.RefObject<Node>;
|
||||
unstable_skipInitialRender?: boolean;
|
||||
}>;
|
||||
|
||||
Portal.displayName = "Portal";
|
||||
export type PortalProps = PropsWithChildren<{
|
||||
type?: string;
|
||||
containerRef?: React.RefObject<Node>;
|
||||
unstable_skipInitialRender?: boolean;
|
||||
}>;
|
||||
|
||||
Portal.displayName = "Portal";
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import {
|
||||
GnosisConnectorArguments,
|
||||
GnosisSafeConnector,
|
||||
} from "../connectors/gnosis-safe";
|
||||
import { MagicConnector, MagicConnectorArguments } from "../connectors/magic";
|
||||
import type { GnosisSafeConnector } from "../connectors/gnosis-safe";
|
||||
import type { MagicConnector } from "../connectors/magic";
|
||||
import {
|
||||
Chain,
|
||||
SupportedChain,
|
||||
@@ -25,6 +22,7 @@ import {
|
||||
ProviderProps as WagmiproviderProps,
|
||||
useProvider,
|
||||
useSigner,
|
||||
Connector,
|
||||
} from "wagmi";
|
||||
import { CoinbaseWalletConnector } from "wagmi/connectors/coinbaseWallet";
|
||||
import { InjectedConnector } from "wagmi/connectors/injected";
|
||||
@@ -56,26 +54,6 @@ export type WalletLinkConnectorType =
|
||||
options: CoinbaseWalletConnector["options"];
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export type MagicConnectorType =
|
||||
| "magic"
|
||||
| {
|
||||
name: "magic";
|
||||
options: Omit<MagicConnectorArguments, "network">;
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export type GnosisConnectorType =
|
||||
| "gnosis"
|
||||
| {
|
||||
name: "gnosis";
|
||||
options: GnosisConnectorArguments;
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
@@ -83,8 +61,8 @@ export type WalletConnector =
|
||||
| InjectedConnectorType
|
||||
| WalletConnectConnectorType
|
||||
| WalletLinkConnectorType
|
||||
| MagicConnectorType
|
||||
| GnosisConnectorType;
|
||||
| GnosisSafeConnector
|
||||
| MagicConnector;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@@ -280,6 +258,9 @@ export const ThirdwebProvider = <
|
||||
connectors: ({ chainId }: { chainId?: number }) => {
|
||||
return walletConnectors
|
||||
.map((connector) => {
|
||||
if (connector instanceof Connector) {
|
||||
return connector;
|
||||
}
|
||||
// injected connector
|
||||
if (
|
||||
(typeof connector === "string" &&
|
||||
@@ -344,25 +325,7 @@ export const ThirdwebProvider = <
|
||||
},
|
||||
});
|
||||
}
|
||||
if (typeof connector === "object" && connector.name === "magic") {
|
||||
const jsonRpcUrl = _rpcUrlMap[chainId || desiredChainId || 1];
|
||||
return new MagicConnector({
|
||||
chains: _supporrtedChains,
|
||||
options: {
|
||||
...connector.options,
|
||||
network: { rpcUrl: jsonRpcUrl, chainId: desiredChainId || 1 },
|
||||
rpcUrls: _rpcUrlMap,
|
||||
},
|
||||
});
|
||||
}
|
||||
if (
|
||||
(typeof connector === "string" && connector === "gnosis") ||
|
||||
(typeof connector === "object" && connector.name === "gnosis")
|
||||
) {
|
||||
return new GnosisSafeConnector({
|
||||
chains: _supporrtedChains,
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
.filter((c) => c !== null);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// at the moment we'll re-export everything from the ethereum package (only!)
|
||||
// at the moment we'll re-export everything from the ethereum package
|
||||
export * from "./evm";
|
||||
|
||||
// core exports
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { ThirdwebAuthConfig } from "../contexts/thirdweb-auth";
|
||||
import { ThirdwebSDKProvider } from "./base";
|
||||
import type { WalletAdapter } from "@solana/wallet-adapter-base";
|
||||
import { PhantomWalletAdapter } from "@solana/wallet-adapter-phantom";
|
||||
import {
|
||||
ConnectionProvider,
|
||||
useWallet,
|
||||
WalletProvider,
|
||||
} from "@solana/wallet-adapter-react";
|
||||
import { PhantomWalletAdapter } from "@solana/wallet-adapter-wallets";
|
||||
import { getUrlForNetwork, Network } from "@thirdweb-dev/sdk/solana";
|
||||
import { PropsWithChildren } from "react";
|
||||
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
# @thirdweb-dev/sdk
|
||||
|
||||
## 3.4.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#337](https://github.com/thirdweb-dev/js/pull/337) [`340605b`](https://github.com/thirdweb-dev/js/commit/340605b507f384fbd2999b9c16542af3c53e84a9) Thanks [@adam-maj](https://github.com/adam-maj)! - Clean native token address in listing
|
||||
|
||||
- [#342](https://github.com/thirdweb-dev/js/pull/342) [`26116a6`](https://github.com/thirdweb-dev/js/commit/26116a6f637ee845f7bd17f20ffe17caf184658e) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Add new univeral RPC urls
|
||||
|
||||
- [#335](https://github.com/thirdweb-dev/js/pull/335) [`15f8006`](https://github.com/thirdweb-dev/js/commit/15f8006e1fb22333b7ee239b45e7b1b12d6dccc8) Thanks [@adam-maj](https://github.com/adam-maj)! - Export smart contract
|
||||
|
||||
- [#327](https://github.com/thirdweb-dev/js/pull/327) [`ef27aad`](https://github.com/thirdweb-dev/js/commit/ef27aad0aafc4577e85f44dc77dfbe880bd239b5) Thanks [@jnsdls](https://github.com/jnsdls)! - enable e2e testing
|
||||
|
||||
- Updated dependencies [[`ef27aad`](https://github.com/thirdweb-dev/js/commit/ef27aad0aafc4577e85f44dc77dfbe880bd239b5)]:
|
||||
- @thirdweb-dev/storage@1.0.6
|
||||
|
||||
## 3.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/sdk",
|
||||
"version": "3.3.1",
|
||||
"version": "3.4.0",
|
||||
"description": "The main thirdweb SDK.",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/sdk",
|
||||
"license": "Apache-2.0",
|
||||
@@ -65,8 +65,8 @@
|
||||
"push": "yalc push"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@metaplex-foundation/amman": "^0.10.0",
|
||||
"@metaplex-foundation/amman-client": "^0.2.1",
|
||||
"@metaplex-foundation/amman": "0.10.0",
|
||||
"@metaplex-foundation/amman-client": "0.2.1",
|
||||
"@microsoft/api-documenter": "^7.19.4",
|
||||
"@microsoft/api-extractor": "^7.29.2",
|
||||
"@microsoft/tsdoc": "^0.14.1",
|
||||
@@ -99,11 +99,11 @@
|
||||
"ethers": "^5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@metaplex-foundation/js": "^0.15.0",
|
||||
"@metaplex-foundation/mpl-token-metadata": "^2.2.2",
|
||||
"@project-serum/anchor": "^0.25.0",
|
||||
"@solana/spl-token": "^0.2.0",
|
||||
"@solana/web3.js": "^1.50.1",
|
||||
"@metaplex-foundation/js": "0.15.0",
|
||||
"@metaplex-foundation/mpl-token-metadata": "2.2.2",
|
||||
"@project-serum/anchor": "0.25.0",
|
||||
"@solana/spl-token": "0.2.0",
|
||||
"@solana/web3.js": "1.62.0",
|
||||
"@thirdweb-dev/contracts-js": "*",
|
||||
"@thirdweb-dev/storage": "*",
|
||||
"bn.js": "^5.2.1",
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
export const DEFAULT_API_KEY =
|
||||
"c6634ad2d97b74baf15ff556016830c251050e6c36b9da508ce3ec80095d3dc1";
|
||||
|
||||
export function getRpcUrl(network: string) {
|
||||
return `https://${network}.rpc.thirdweb.com/${DEFAULT_API_KEY}`;
|
||||
}
|
||||
@@ -26,6 +26,13 @@ export function isNativeToken(tokenAddress: string): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
export function cleanCurrencyAddress(currencyAddress: string): string {
|
||||
if (isNativeToken(currencyAddress)) {
|
||||
return NATIVE_TOKEN_ADDRESS;
|
||||
}
|
||||
return currencyAddress;
|
||||
}
|
||||
|
||||
export async function normalizePriceValue(
|
||||
provider: providers.Provider,
|
||||
inputPrice: Price,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { getRpcUrl } from "../../core/constants/urls";
|
||||
import { SignerOrProvider } from "../core/types";
|
||||
import { StaticJsonRpcBatchProvider } from "../lib/static-batch-rpc";
|
||||
import { ChainId, SUPPORTED_CHAIN_ID, SUPPORTED_CHAIN_IDS } from "./chains";
|
||||
@@ -7,39 +8,16 @@ import { ethers, providers } from "ethers";
|
||||
* @internal
|
||||
*/
|
||||
export const DEFAULT_IPFS_GATEWAY = "https://gateway.ipfscdn.io/ipfs/";
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const PUBLIC_GATEWAYS = [
|
||||
"https://gateway.ipfscdn.io/ipfs/",
|
||||
"https://cloudflare-ipfs.com/ipfs/",
|
||||
"https://ipfs.io/ipfs/",
|
||||
];
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const TW_IPFS_SERVER_URL = "https://upload.nftlabs.co";
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const PINATA_IPFS_URL = `https://api.pinata.cloud/pinning/pinFileToIPFS`;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* This is a community API key that is subject to rate limiting. Please use your own key.
|
||||
*/
|
||||
const DEFAULT_API_KEY = "_gg7wSSi0KMBsdKnGVfHDueq6xMB9EkC";
|
||||
|
||||
type ChainNames =
|
||||
| "mumbai"
|
||||
| "polygon"
|
||||
// common alias for `polygon`
|
||||
| "matic"
|
||||
| "goerli"
|
||||
| "mainnet"
|
||||
// common alias for `mainnet`
|
||||
| "ethereum"
|
||||
| "goerli"
|
||||
| "polygon"
|
||||
// common alias for `polygon`
|
||||
| "matic"
|
||||
| "mumbai"
|
||||
| "fantom"
|
||||
| "fantom-testnet"
|
||||
| "avalanche"
|
||||
@@ -105,49 +83,37 @@ export function getProviderForNetwork(network: ChainOrRpc | SignerOrProvider) {
|
||||
return network;
|
||||
}
|
||||
switch (network) {
|
||||
case "mumbai":
|
||||
return `https://polygon-mumbai.g.alchemy.com/v2/${DEFAULT_API_KEY}`;
|
||||
case "rinkeby":
|
||||
return `https://eth-rinkeby.g.alchemy.com/v2/${DEFAULT_API_KEY}`;
|
||||
case "goerli":
|
||||
return `https://eth-goerli.g.alchemy.com/v2/${DEFAULT_API_KEY}`;
|
||||
case "polygon":
|
||||
case "matic":
|
||||
return `https://polygon-mainnet.g.alchemy.com/v2/${DEFAULT_API_KEY}`;
|
||||
case "mainnet":
|
||||
case "ethereum":
|
||||
return `https://eth-mainnet.g.alchemy.com/v2/${DEFAULT_API_KEY}`;
|
||||
return getRpcUrl("ethereum");
|
||||
case "goerli":
|
||||
return getRpcUrl("goerli");
|
||||
case "polygon":
|
||||
case "matic":
|
||||
return getRpcUrl("polygon");
|
||||
case "mumbai":
|
||||
return getRpcUrl("mumbai");
|
||||
case "optimism":
|
||||
// TODO test this RPC
|
||||
return `https://opt-mainnet.g.alchemy.com/v2/${DEFAULT_API_KEY}`;
|
||||
case "optimism-kovan":
|
||||
// alchemy optimism kovan rpc doesn't link to the testnet sequencer...
|
||||
return "https://kovan.optimism.io";
|
||||
return getRpcUrl("optimism");
|
||||
case "optimism-goerli":
|
||||
// TODO test this RPC
|
||||
return `https://opt-goerli.g.alchemy.com/v2/${DEFAULT_API_KEY}`;
|
||||
return getRpcUrl("optimism-goerli");
|
||||
case "arbitrum":
|
||||
// TODO test this RPC
|
||||
return `https://arb-mainnet.g.alchemy.com/v2/${DEFAULT_API_KEY}`;
|
||||
case "arbitrum-rinkeby":
|
||||
// TODO test this RPC
|
||||
return `https://arb-rinkeby.g.alchemy.com/v2/${DEFAULT_API_KEY}`;
|
||||
return getRpcUrl("arbitrum");
|
||||
case "arbitrum-goerli":
|
||||
// TODO test this RPC
|
||||
return `https://arb-goerli.g.alchemy.com/v2/${DEFAULT_API_KEY}`;
|
||||
return getRpcUrl("arbitrum-goerli");
|
||||
case "fantom":
|
||||
return "https://rpc.ftm.tools";
|
||||
return getRpcUrl("fantom");
|
||||
case "fantom-testnet":
|
||||
return "https://rpc.testnet.fantom.network/";
|
||||
return getRpcUrl("fantom-testnet");
|
||||
case "avalanche":
|
||||
return "https://api.avax.network/ext/bc/C/rpc";
|
||||
return getRpcUrl("avalanche");
|
||||
case "avalanche-testnet":
|
||||
case "avalanche-fuji":
|
||||
return "https://api.avax-test.network/ext/bc/C/rpc";
|
||||
return getRpcUrl("avalanche-fuji");
|
||||
case "binance":
|
||||
return "https://bsc-dataseed1.binance.org";
|
||||
return getRpcUrl("binance");
|
||||
case "binance-testnet":
|
||||
return "https://data-seed-prebsc-1-s1.binance.org:8545";
|
||||
return getRpcUrl("binance-testnet");
|
||||
default:
|
||||
if (network.startsWith("http") || network.startsWith("ws")) {
|
||||
return network;
|
||||
|
||||
@@ -159,6 +159,34 @@ export class Erc1155SignatureMintable implements DetectableFeature {
|
||||
* Verify that a payload is correctly signed
|
||||
* @param signedPayload - the payload to verify
|
||||
* @twfeature ERC1155SignatureMintable
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const nftMetadata = {
|
||||
* name: "Cool NFT #1",
|
||||
* description: "This is a cool NFT",
|
||||
* image: fs.readFileSync("path/to/image.png"), // This can be an image url or file
|
||||
* };
|
||||
*
|
||||
* const startTime = new Date();
|
||||
* const endTime = new Date(Date.now() + 60 * 60 * 24 * 1000);
|
||||
* const payload = {
|
||||
* metadata: nftMetadata, // The NFT to mint
|
||||
* to: {{wallet_address}}, // Who will receive the NFT (or AddressZero for anyone)
|
||||
* quantity: 2, // the quantity of NFTs to mint
|
||||
* price: 0.5, // the price per NFT
|
||||
* currencyAddress: NATIVE_TOKEN_ADDRESS, // the currency to pay with
|
||||
* mintStartTime: startTime, // can mint anytime from now
|
||||
* mintEndTime: endTime, // to 24h from now
|
||||
* royaltyRecipient: "0x...", // custom royalty recipient for this NFT
|
||||
* royaltyBps: 100, // custom royalty fees for this NFT (in bps)
|
||||
* primarySaleRecipient: "0x...", // custom sale recipient for this NFT
|
||||
* };
|
||||
*
|
||||
* const signedPayload = contract.erc1155.signature.generate(payload);
|
||||
* // Now you can verify that the payload is valid
|
||||
* const isValid = await contract.erc1155.signature.verify(signedPayload);
|
||||
* ```
|
||||
*/
|
||||
public async verify(signedPayload: SignedPayload1155): Promise<boolean> {
|
||||
const mintRequest = signedPayload.payload;
|
||||
@@ -197,7 +225,7 @@ export class Erc1155SignatureMintable implements DetectableFeature {
|
||||
* primarySaleRecipient: "0x...", // custom sale recipient for this NFT
|
||||
* };
|
||||
*
|
||||
* const signedPayload = contract.erc1155.signature.generate(payload);
|
||||
* const signedPayload = await contract.erc1155.signature.generate(payload);
|
||||
* // now anyone can use these to mint the NFT using `contract.erc1155.signature.mint(signedPayload)`
|
||||
* ```
|
||||
* @param payloadToSign - the payload to sign
|
||||
@@ -242,7 +270,7 @@ export class Erc1155SignatureMintable implements DetectableFeature {
|
||||
* primarySaleRecipient: "0x...", // custom sale recipient for this NFT
|
||||
* };
|
||||
*
|
||||
* const signedPayload = contract.erc1155.signature.generate(payload);
|
||||
* const signedPayload = await contract.erc1155.signature.generateFromTokenId(payload);
|
||||
* // now anyone can use these to mint the NFT using `contract.erc1155.signature.mint(signedPayload)`
|
||||
* ```
|
||||
* @param payloadToSign - the payload to sign
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
import { normalizePriceValue, setErc20Allowance } from "../../common/currency";
|
||||
import { FEATURE_TOKEN_SIGNATURE_MINTABLE } from "../../constants/erc20-features";
|
||||
import type { TokenInitializer } from "../../contracts";
|
||||
import { FilledSignaturePayload20, MintRequest20, PayloadToSign20, PayloadWithUri20, Signature20PayloadInput, Signature20PayloadOutput, SignedPayload20 } from "../../schema/contracts/common/signature";
|
||||
import {
|
||||
FilledSignaturePayload20,
|
||||
MintRequest20,
|
||||
PayloadToSign20,
|
||||
PayloadWithUri20,
|
||||
Signature20PayloadInput,
|
||||
Signature20PayloadOutput,
|
||||
SignedPayload20,
|
||||
} from "../../schema/contracts/common/signature";
|
||||
import { DetectableFeature } from "../interfaces/DetectableFeature";
|
||||
import { TransactionResult } from "../types";
|
||||
import { ContractRoles } from "./contract-roles";
|
||||
@@ -10,7 +18,6 @@ import type { ITokenERC20, TokenERC20 } from "@thirdweb-dev/contracts-js";
|
||||
import { BigNumber, ethers } from "ethers";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
|
||||
/**
|
||||
* Enables generating ERC20 Tokens with rules and an associated signature, which can then be minted by anyone securely
|
||||
* @public
|
||||
@@ -110,6 +117,24 @@ export class Erc20SignatureMintable implements DetectableFeature {
|
||||
* Verify that a payload is correctly signed
|
||||
* @param signedPayload - the payload to verify
|
||||
* @twfeature ERC20SignatureMintable
|
||||
*
|
||||
* ```javascript
|
||||
* const startTime = new Date();
|
||||
* const endTime = new Date(Date.now() + 60 * 60 * 24 * 1000);
|
||||
* const payload = {
|
||||
* quantity: 4.2, // The quantity of tokens to be minted
|
||||
* to: {{wallet_address}}, // Who will receive the tokens (or AddressZero for anyone)
|
||||
* price: 0.5, // the price to pay for minting those tokens
|
||||
* currencyAddress: NATIVE_TOKEN_ADDRESS, // the currency to pay with
|
||||
* mintStartTime: startTime, // can mint anytime from now
|
||||
* mintEndTime: endTime, // to 24h from now,
|
||||
* primarySaleRecipient: "0x...", // custom sale recipient for this token mint
|
||||
* };
|
||||
*
|
||||
* const signedPayload = await contract.erc20.signature.generate(payload);
|
||||
* // Now you can verify if the signed payload is valid
|
||||
* const isValid = await contract.erc20.signature.verify(signedPayload);
|
||||
* ```
|
||||
*/
|
||||
public async verify(signedPayload: SignedPayload20): Promise<boolean> {
|
||||
const mintRequest = signedPayload.payload;
|
||||
@@ -139,7 +164,7 @@ export class Erc20SignatureMintable implements DetectableFeature {
|
||||
* primarySaleRecipient: "0x...", // custom sale recipient for this token mint
|
||||
* };
|
||||
*
|
||||
* const signedPayload = contract.erc20.signature.generate(payload);
|
||||
* const signedPayload = await contract.erc20.signature.generate(payload);
|
||||
* // now anyone can use these to mint the NFT using `contract.erc20.signature.mint(signedPayload)`
|
||||
* ```
|
||||
* @param mintRequest - the payload to sign
|
||||
@@ -237,4 +262,4 @@ export class Erc20SignatureMintable implements DetectableFeature {
|
||||
uid: mintRequest.uid,
|
||||
} as ITokenERC20.MintRequestStructOutput;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,6 +177,34 @@ export class Erc721WithQuantitySignatureMintable implements DetectableFeature {
|
||||
* Verify that a payload is correctly signed
|
||||
* @param signedPayload - the payload to verify
|
||||
* @twfeature ERC721SignatureMint
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const nftMetadata = {
|
||||
* name: "Cool NFT #1",
|
||||
* description: "This is a cool NFT",
|
||||
* image: fs.readFileSync("path/to/image.png"), // This can be an image url or file
|
||||
* };
|
||||
*
|
||||
* const startTime = new Date();
|
||||
* const endTime = new Date(Date.now() + 60 * 60 * 24 * 1000);
|
||||
* const payload = {
|
||||
* metadata: nftMetadata, // The NFT to mint
|
||||
* to: {{wallet_address}}, // Who will receive the NFT (or AddressZero for anyone)
|
||||
* quantity: 2, // the quantity of NFTs to mint
|
||||
* price: 0.5, // the price per NFT
|
||||
* currencyAddress: NATIVE_TOKEN_ADDRESS, // the currency to pay with
|
||||
* mintStartTime: startTime, // can mint anytime from now
|
||||
* mintEndTime: endTime, // to 24h from now
|
||||
* royaltyRecipient: "0x...", // custom royalty recipient for this NFT
|
||||
* royaltyBps: 100, // custom royalty fees for this NFT (in bps)
|
||||
* primarySaleRecipient: "0x...", // custom sale recipient for this NFT
|
||||
* };
|
||||
*
|
||||
* const signedPayload = await contract.erc721.signature.generate(payload);
|
||||
* // Now you can verify if the signed payload is valid
|
||||
* const isValid = await contract.erc721.signature.verify(signedPayload);
|
||||
* ```
|
||||
*/
|
||||
public async verify(
|
||||
signedPayload: SignedPayload721WithQuantitySignature,
|
||||
@@ -230,7 +258,7 @@ export class Erc721WithQuantitySignatureMintable implements DetectableFeature {
|
||||
* primarySaleRecipient: "0x...", // custom sale recipient for this NFT
|
||||
* };
|
||||
*
|
||||
* const signedPayload = contract.erc721.signature.generate(payload);
|
||||
* const signedPayload = await contract.erc721.signature.generate(payload);
|
||||
* // now anyone can use these to mint the NFT using `contract.erc721.signature.mint(signedPayload)`
|
||||
* ```
|
||||
* @param mintRequest - the payload to sign
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
WrongListingTypeError,
|
||||
} from "../../common";
|
||||
import {
|
||||
cleanCurrencyAddress,
|
||||
fetchCurrencyMetadata,
|
||||
fetchCurrencyValue,
|
||||
normalizePriceValue,
|
||||
@@ -233,7 +234,9 @@ export class MarketplaceAuction {
|
||||
assetContract: listing.assetContractAddress,
|
||||
tokenId: listing.tokenId,
|
||||
buyoutPricePerToken: normalizedPricePerToken,
|
||||
currencyToAccept: listing.currencyContractAddress,
|
||||
currencyToAccept: cleanCurrencyAddress(
|
||||
listing.currencyContractAddress,
|
||||
),
|
||||
listingType: ListingType.Auction,
|
||||
quantityToList: listing.quantity,
|
||||
reservePricePerToken: normalizedReservePrice,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ListingNotFoundError, WrongListingTypeError } from "../../common";
|
||||
import {
|
||||
cleanCurrencyAddress,
|
||||
fetchCurrencyValue,
|
||||
isNativeToken,
|
||||
normalizePriceValue,
|
||||
@@ -188,7 +189,9 @@ export class MarketplaceDirect {
|
||||
assetContract: listing.assetContractAddress,
|
||||
tokenId: listing.tokenId,
|
||||
buyoutPricePerToken: normalizedPricePerToken,
|
||||
currencyToAccept: listing.currencyContractAddress,
|
||||
currencyToAccept: cleanCurrencyAddress(
|
||||
listing.currencyContractAddress,
|
||||
),
|
||||
listingType: ListingType.Direct,
|
||||
quantityToList: listing.quantity,
|
||||
reservePricePerToken: normalizedPricePerToken,
|
||||
|
||||
@@ -44,3 +44,4 @@ export type { Split } from "./contracts/prebuilt-implementations/split";
|
||||
export type { Token } from "./contracts/prebuilt-implementations/token";
|
||||
export type { TokenDrop } from "./contracts/prebuilt-implementations/token-drop";
|
||||
export type { Vote } from "./contracts/prebuilt-implementations/vote";
|
||||
export type { SmartContract } from "./contracts/smart-contract";
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const DEFAULT_IPFS_GATEWAY = "https://gateway.ipfscdn.io/ipfs/";
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const PUBLIC_GATEWAYS = [
|
||||
"https://gateway.ipfscdn.io/ipfs/",
|
||||
"https://cloudflare-ipfs.com/ipfs/",
|
||||
"https://ipfs.io/ipfs/",
|
||||
];
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const TW_IPFS_SERVER_URL = "https://upload.nftlabs.co";
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const PINATA_IPFS_URL = `https://api.pinata.cloud/pinning/pinFileToIPFS`;
|
||||
@@ -1,13 +1,8 @@
|
||||
import { getRpcUrl } from "../../core/constants/urls";
|
||||
import { Network } from "../types/index";
|
||||
import { Metaplex } from "@metaplex-foundation/js";
|
||||
import { Cluster, clusterApiUrl } from "@solana/web3.js";
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* This is a community API key that is subject to rate limiting. Please use your own key.
|
||||
*/
|
||||
const DEFAULT_API_KEY = "_gg7wSSi0KMBsdKnGVfHDueq6xMB9EkC";
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
@@ -18,9 +13,9 @@ export function getUrlForNetwork(network: Network) {
|
||||
case "testnet":
|
||||
return clusterApiUrl(network as Cluster);
|
||||
case "mainnet-beta":
|
||||
return `https://solana-mainnet.g.alchemy.com/v2/${DEFAULT_API_KEY}`;
|
||||
return getRpcUrl("solana");
|
||||
case "devnet":
|
||||
return `https://solana-devnet.g.alchemy.com/v2/${DEFAULT_API_KEY}`;
|
||||
return getRpcUrl("solana-devnet");
|
||||
default:
|
||||
return network;
|
||||
}
|
||||
|
||||
@@ -203,6 +203,23 @@ describe("Marketplace Contract", async () => {
|
||||
await marketplaceContract.auction.makeBid(id, 0.1);
|
||||
});
|
||||
|
||||
it("Should list with native currency address", async () => {
|
||||
const { id: listingId } = await marketplaceContract.direct.createListing({
|
||||
assetContractAddress: dummyNftContract.getAddress(),
|
||||
buyoutPricePerToken: 0.1,
|
||||
currencyContractAddress: "0x0000000000000000000000000000000000000000",
|
||||
startTimestamp: new Date(0), // start date can be in the past
|
||||
listingDurationInSeconds: 60 * 60 * 24,
|
||||
tokenId: 0,
|
||||
quantity: 1,
|
||||
});
|
||||
|
||||
const listing = await marketplaceContract.getListing(listingId);
|
||||
expect(listing.currencyContractAddress.toLowerCase()).to.equal(
|
||||
NATIVE_TOKEN_ADDRESS.toLowerCase(),
|
||||
);
|
||||
});
|
||||
|
||||
it("should list direct listings with 1155s", async () => {
|
||||
const listingId = await createDirectListing(
|
||||
dummyBundleContract.getAddress(),
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @thirdweb-dev/storage
|
||||
|
||||
## 1.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#327](https://github.com/thirdweb-dev/js/pull/327) [`ef27aad`](https://github.com/thirdweb-dev/js/commit/ef27aad0aafc4577e85f44dc77dfbe880bd239b5) Thanks [@jnsdls](https://github.com/jnsdls)! - enable e2e testing
|
||||
|
||||
## 1.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/storage",
|
||||
"version": "1.0.5",
|
||||
"version": "1.0.6",
|
||||
"main": "dist/thirdweb-dev-storage.cjs.js",
|
||||
"module": "dist/thirdweb-dev-storage.esm.js",
|
||||
"exports": {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# e2e-cra-5
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ef27aad`](https://github.com/thirdweb-dev/js/commit/ef27aad0aafc4577e85f44dc77dfbe880bd239b5), [`340605b`](https://github.com/thirdweb-dev/js/commit/340605b507f384fbd2999b9c16542af3c53e84a9), [`26116a6`](https://github.com/thirdweb-dev/js/commit/26116a6f637ee845f7bd17f20ffe17caf184658e), [`15f8006`](https://github.com/thirdweb-dev/js/commit/15f8006e1fb22333b7ee239b45e7b1b12d6dccc8), [`ef27aad`](https://github.com/thirdweb-dev/js/commit/ef27aad0aafc4577e85f44dc77dfbe880bd239b5), [`b03a902`](https://github.com/thirdweb-dev/js/commit/b03a9021451b79f802f682f66e5ae8e9355d7e6f)]:
|
||||
- @thirdweb-dev/react@3.4.0
|
||||
- @thirdweb-dev/sdk@3.4.0
|
||||
@@ -0,0 +1,8 @@
|
||||
import { test, expect } from "@playwright/test";
|
||||
|
||||
test("should work", async ({ page }, testInfo) => {
|
||||
await page.goto("http://localhost:" + testInfo.config.webServer!.port);
|
||||
|
||||
const connectWalletEl = page.getByText("Connect Wallet");
|
||||
await expect(connectWalletEl).toBeVisible();
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"name": "e2e-cra-5",
|
||||
"version": "0.1.1",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@thirdweb-dev/react": "*",
|
||||
"@thirdweb-dev/sdk": "*",
|
||||
"ethers": "^5.7.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-scripts": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "react-scripts build",
|
||||
"e2e": "npx playwright test"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.27.1",
|
||||
"serve": "^14.0.1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
import type { PlaywrightTestConfig } from "@playwright/test";
|
||||
import { devices } from "@playwright/test";
|
||||
|
||||
/**
|
||||
* Read environment variables from file.
|
||||
* https://github.com/motdotla/dotenv
|
||||
*/
|
||||
// require('dotenv').config();
|
||||
|
||||
/**
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
const config: PlaywrightTestConfig = {
|
||||
testDir: "./fixtures",
|
||||
/* Maximum time one test can run for. */
|
||||
timeout: 30 * 1000,
|
||||
expect: {
|
||||
/**
|
||||
* Maximum time expect() should wait for the condition to be met.
|
||||
* For example in `await expect(locator).toHaveText();`
|
||||
*/
|
||||
// timeout: 5000,
|
||||
},
|
||||
/* Run tests in files in parallel */
|
||||
fullyParallel: true,
|
||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||
forbidOnly: !!process.env.CI,
|
||||
/* Retry on CI only */
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
/* Opt out of parallel tests on CI. */
|
||||
workers: undefined,
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: "html",
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
|
||||
actionTimeout: 0,
|
||||
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||
// baseURL: 'http://localhost:3000',
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: "on-first-retry",
|
||||
},
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
projects: [
|
||||
{
|
||||
name: "chromium",
|
||||
use: {
|
||||
...devices["Desktop Chrome"],
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "firefox",
|
||||
use: {
|
||||
...devices["Desktop Firefox"],
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "webkit",
|
||||
use: {
|
||||
...devices["Desktop Safari"],
|
||||
},
|
||||
},
|
||||
|
||||
/* Test against mobile viewports. */
|
||||
// {
|
||||
// name: 'Mobile Chrome',
|
||||
// use: {
|
||||
// ...devices['Pixel 5'],
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: 'Mobile Safari',
|
||||
// use: {
|
||||
// ...devices['iPhone 12'],
|
||||
// },
|
||||
// },
|
||||
|
||||
/* Test against branded browsers. */
|
||||
// {
|
||||
// name: 'Microsoft Edge',
|
||||
// use: {
|
||||
// channel: 'msedge',
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: 'Google Chrome',
|
||||
// use: {
|
||||
// channel: 'chrome',
|
||||
// },
|
||||
// },
|
||||
],
|
||||
|
||||
/* Folder for test artifacts such as screenshots, videos, traces, etc. */
|
||||
// outputDir: 'test-results/',
|
||||
|
||||
/* Run your local dev server before starting the tests */
|
||||
webServer: {
|
||||
command: "yarn serve -s build -p 3040",
|
||||
port: 3040,
|
||||
// its static so yeah go for it
|
||||
reuseExistingServer: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,26 @@
|
||||
import { ConnectWallet, ThirdwebProvider } from "@thirdweb-dev/react";
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
|
||||
const KitchenSink = () => {
|
||||
return (
|
||||
<ThirdwebProvider>
|
||||
<WrappedKitchenSink />
|
||||
</ThirdwebProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const WrappedKitchenSink = () => {
|
||||
return (
|
||||
<div id="kitchen-sink">
|
||||
<ConnectWallet />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById("root"));
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<KitchenSink />
|
||||
</React.StrictMode>,
|
||||
);
|
||||
@@ -0,0 +1,9 @@
|
||||
# e2e-next-12
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ef27aad`](https://github.com/thirdweb-dev/js/commit/ef27aad0aafc4577e85f44dc77dfbe880bd239b5), [`340605b`](https://github.com/thirdweb-dev/js/commit/340605b507f384fbd2999b9c16542af3c53e84a9), [`26116a6`](https://github.com/thirdweb-dev/js/commit/26116a6f637ee845f7bd17f20ffe17caf184658e), [`15f8006`](https://github.com/thirdweb-dev/js/commit/15f8006e1fb22333b7ee239b45e7b1b12d6dccc8), [`ef27aad`](https://github.com/thirdweb-dev/js/commit/ef27aad0aafc4577e85f44dc77dfbe880bd239b5), [`b03a902`](https://github.com/thirdweb-dev/js/commit/b03a9021451b79f802f682f66e5ae8e9355d7e6f)]:
|
||||
- @thirdweb-dev/react@3.4.0
|
||||
- @thirdweb-dev/sdk@3.4.0
|
||||
@@ -0,0 +1,8 @@
|
||||
import { test, expect } from "@playwright/test";
|
||||
|
||||
test("should work", async ({ page }, testInfo) => {
|
||||
await page.goto("http://localhost:" + testInfo.config.webServer!.port);
|
||||
|
||||
const connectWalletEl = page.getByText("Connect Wallet");
|
||||
await expect(connectWalletEl).toBeVisible();
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "e2e-next-12",
|
||||
"version": "0.1.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"e2e": "npx playwright test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@thirdweb-dev/react": "*",
|
||||
"@thirdweb-dev/sdk": "*",
|
||||
"ethers": "^5.7.2",
|
||||
"next": "^12",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.27.1",
|
||||
"eslint": "8.25.0",
|
||||
"eslint-config-next": "12.3.1"
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import { devices } from "@playwright/test";
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
const config: PlaywrightTestConfig = {
|
||||
testDir: "./e2e",
|
||||
testDir: "./fixtures",
|
||||
/* Maximum time one test can run for. */
|
||||
timeout: 30 * 1000,
|
||||
expect: {
|
||||
@@ -19,7 +19,7 @@ const config: PlaywrightTestConfig = {
|
||||
* Maximum time expect() should wait for the condition to be met.
|
||||
* For example in `await expect(locator).toHaveText();`
|
||||
*/
|
||||
timeout: 5000,
|
||||
// timeout: 5000,
|
||||
},
|
||||
/* Run tests in files in parallel */
|
||||
fullyParallel: true,
|
||||
@@ -28,7 +28,7 @@ const config: PlaywrightTestConfig = {
|
||||
/* Retry on CI only */
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
/* Opt out of parallel tests on CI. */
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
workers: undefined,
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: "html",
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
@@ -98,10 +98,12 @@ const config: PlaywrightTestConfig = {
|
||||
// outputDir: 'test-results/',
|
||||
|
||||
/* Run your local dev server before starting the tests */
|
||||
// webServer: {
|
||||
// command: 'npm run start',
|
||||
// port: 3000,
|
||||
// },
|
||||
webServer: {
|
||||
command: "yarn start -p 3050",
|
||||
port: 3050,
|
||||
// its static so yeah go for it
|
||||
reuseExistingServer: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -0,0 +1,21 @@
|
||||
import { ConnectWallet, ThirdwebProvider } from "@thirdweb-dev/react";
|
||||
|
||||
export const KitchenSink = () => {
|
||||
return (
|
||||
<ThirdwebProvider>
|
||||
<WrappedKitchenSink />
|
||||
</ThirdwebProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const WrappedKitchenSink = () => {
|
||||
return (
|
||||
<div id="kitchen-sink">
|
||||
<ConnectWallet />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default function Home() {
|
||||
return <KitchenSink />;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
# e2e-vite-3
|
||||
|
||||
## 0.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ef27aad`](https://github.com/thirdweb-dev/js/commit/ef27aad0aafc4577e85f44dc77dfbe880bd239b5), [`340605b`](https://github.com/thirdweb-dev/js/commit/340605b507f384fbd2999b9c16542af3c53e84a9), [`26116a6`](https://github.com/thirdweb-dev/js/commit/26116a6f637ee845f7bd17f20ffe17caf184658e), [`15f8006`](https://github.com/thirdweb-dev/js/commit/15f8006e1fb22333b7ee239b45e7b1b12d6dccc8), [`ef27aad`](https://github.com/thirdweb-dev/js/commit/ef27aad0aafc4577e85f44dc77dfbe880bd239b5), [`b03a902`](https://github.com/thirdweb-dev/js/commit/b03a9021451b79f802f682f66e5ae8e9355d7e6f)]:
|
||||
- @thirdweb-dev/react@3.4.0
|
||||
- @thirdweb-dev/sdk@3.4.0
|
||||
@@ -0,0 +1,8 @@
|
||||
import { test, expect } from "@playwright/test";
|
||||
|
||||
test("should work", async ({ page }, testInfo) => {
|
||||
await page.goto("http://localhost:" + testInfo.config.webServer!.port);
|
||||
|
||||
const connectWalletEl = page.getByText("Connect Wallet");
|
||||
await expect(connectWalletEl).toBeVisible();
|
||||
});
|
||||
@@ -3,10 +3,10 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Testing Page</title>
|
||||
<title>Vite + React</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/playwright/index.ts"></script>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "e2e-vite-3",
|
||||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
"e2e": "npx playwright test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@thirdweb-dev/react": "*",
|
||||
"@thirdweb-dev/sdk": "*",
|
||||
"ethers": "^5.7.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-react": "^2",
|
||||
"vite": "^3",
|
||||
"serve": "^14.0.1",
|
||||
"@playwright/test": "^1.27.1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
import type { PlaywrightTestConfig } from "@playwright/test";
|
||||
import { devices } from "@playwright/test";
|
||||
|
||||
/**
|
||||
* Read environment variables from file.
|
||||
* https://github.com/motdotla/dotenv
|
||||
*/
|
||||
// require('dotenv').config();
|
||||
|
||||
/**
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
const config: PlaywrightTestConfig = {
|
||||
testDir: "./fixtures",
|
||||
/* Maximum time one test can run for. */
|
||||
timeout: 30 * 1000,
|
||||
expect: {
|
||||
/**
|
||||
* Maximum time expect() should wait for the condition to be met.
|
||||
* For example in `await expect(locator).toHaveText();`
|
||||
*/
|
||||
// timeout: 5000,
|
||||
},
|
||||
/* Run tests in files in parallel */
|
||||
fullyParallel: true,
|
||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||
forbidOnly: !!process.env.CI,
|
||||
/* Retry on CI only */
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
/* Opt out of parallel tests on CI. */
|
||||
workers: undefined,
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: "html",
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
|
||||
actionTimeout: 0,
|
||||
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||
// baseURL: 'http://localhost:3000',
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: "on-first-retry",
|
||||
},
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
projects: [
|
||||
{
|
||||
name: "chromium",
|
||||
use: {
|
||||
...devices["Desktop Chrome"],
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "firefox",
|
||||
use: {
|
||||
...devices["Desktop Firefox"],
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "webkit",
|
||||
use: {
|
||||
...devices["Desktop Safari"],
|
||||
},
|
||||
},
|
||||
|
||||
/* Test against mobile viewports. */
|
||||
// {
|
||||
// name: 'Mobile Chrome',
|
||||
// use: {
|
||||
// ...devices['Pixel 5'],
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: 'Mobile Safari',
|
||||
// use: {
|
||||
// ...devices['iPhone 12'],
|
||||
// },
|
||||
// },
|
||||
|
||||
/* Test against branded browsers. */
|
||||
// {
|
||||
// name: 'Microsoft Edge',
|
||||
// use: {
|
||||
// channel: 'msedge',
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: 'Google Chrome',
|
||||
// use: {
|
||||
// channel: 'chrome',
|
||||
// },
|
||||
// },
|
||||
],
|
||||
|
||||
/* Folder for test artifacts such as screenshots, videos, traces, etc. */
|
||||
// outputDir: 'test-results/',
|
||||
|
||||
/* Run your local dev server before starting the tests */
|
||||
webServer: {
|
||||
command: "yarn serve -s dist -p 3060",
|
||||
port: 3060,
|
||||
// its static so yeah go for it
|
||||
reuseExistingServer: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ConnectWallet, ThirdwebProvider } from "@thirdweb-dev/react";
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
|
||||
export const KitchenSink = () => {
|
||||
return (
|
||||
<ThirdwebProvider>
|
||||
<WrappedKitchenSink />
|
||||
</ThirdwebProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const WrappedKitchenSink = () => {
|
||||
return (
|
||||
<div id="kitchen-sink">
|
||||
<ConnectWallet />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")).render(
|
||||
<React.StrictMode>
|
||||
<KitchenSink />
|
||||
</React.StrictMode>,
|
||||
);
|
||||
@@ -0,0 +1,11 @@
|
||||
import react from "@vitejs/plugin-react";
|
||||
import { defineConfig } from "vite";
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
define: {
|
||||
global: "globalThis",
|
||||
"process.env": {},
|
||||
},
|
||||
});
|
||||
+15
-4
@@ -41,15 +41,26 @@
|
||||
"inputs": ["src/**"],
|
||||
"dependsOn": ["build"]
|
||||
},
|
||||
"e2e:e2e-cra-5": {
|
||||
"outputs": ["build"],
|
||||
"inputs": ["src/**", "fixtures/**"],
|
||||
"dependsOn": ["build"]
|
||||
},
|
||||
"e2e:e2e-next-12": {
|
||||
"outputs": [".next"],
|
||||
"inputs": ["src/**", "fixtures/**"],
|
||||
"dependsOn": ["build"]
|
||||
},
|
||||
"e2e:e2e-vite-3": {
|
||||
"outputs": ["dist"],
|
||||
"inputs": ["src/**", "fixtures/**"],
|
||||
"dependsOn": ["build"]
|
||||
},
|
||||
"thirdweb#e2e": {
|
||||
"outputs": [],
|
||||
"inputs": ["src/**", "e2e/**"],
|
||||
"dependsOn": ["build"]
|
||||
},
|
||||
"@thirdweb-dev/react#e2e": {
|
||||
"inputs": ["src/**", "playwright/index.ts", "playwright/index.html"],
|
||||
"dependsOn": ["build"]
|
||||
},
|
||||
"lint": {
|
||||
"outputs": []
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user