Compare commits
84
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f1155239d | ||
|
|
c295a47144 | ||
|
|
0dade96d0d | ||
|
|
666ff5f694 | ||
|
|
8bc41cdc60 | ||
|
|
37a707f98c | ||
|
|
3c8f6205e9 | ||
|
|
1eaedc262f | ||
|
|
e187d21e12 | ||
|
|
b030a86608 | ||
|
|
acbabc8999 | ||
|
|
196195e2f9 | ||
|
|
7c86babb86 | ||
|
|
36f2b70d57 | ||
|
|
849146bf5c | ||
|
|
4cac79c45d | ||
|
|
1bda83b114 | ||
|
|
ce05bfd861 | ||
|
|
d982a98b0c | ||
|
|
b983087101 | ||
|
|
b25789fa46 | ||
|
|
e39b66f309 | ||
|
|
5f5ab015e1 | ||
|
|
f4f05bd9a4 | ||
|
|
2f5b66bef9 | ||
|
|
63258bc9c3 | ||
|
|
a80fc97b6a | ||
|
|
24f66e38c2 | ||
|
|
b5bfaefa85 | ||
|
|
493ebf032e | ||
|
|
d608cea197 | ||
|
|
a9ec190ff9 | ||
|
|
3edec391be | ||
|
|
bdec5a59af | ||
|
|
9d03619aab | ||
|
|
0ccbca78dc | ||
|
|
75c752cc14 | ||
|
|
3580182fa9 | ||
|
|
b54f95dc90 | ||
|
|
f4074ddadc | ||
|
|
208b0389a5 | ||
|
|
3b877ba221 | ||
|
|
45a400fd92 | ||
|
|
3332fa5697 | ||
|
|
fdda564b1e | ||
|
|
89db3db7ff | ||
|
|
bd9c705571 | ||
|
|
0ad0f21bcd | ||
|
|
4169b9428f | ||
|
|
2f9e8aaab4 | ||
|
|
421461ece0 | ||
|
|
485ebc8400 | ||
|
|
772f8431e3 | ||
|
|
5345479922 | ||
|
|
cfe8bbafa4 | ||
|
|
18dc8d33ed | ||
|
|
f8ab4779bb | ||
|
|
6fe16c5bf2 | ||
|
|
ba0e169654 | ||
|
|
27b869ed93 | ||
|
|
091ce2eb45 | ||
|
|
e24a371508 | ||
|
|
b86afb4b09 | ||
|
|
964add6f20 | ||
|
|
ec414bbc42 | ||
|
|
51dde28224 | ||
|
|
57432d21c4 | ||
|
|
19d87c2885 | ||
|
|
68812e9d27 | ||
|
|
90c53475f0 | ||
|
|
5a52585a7a | ||
|
|
6b48b9288b | ||
|
|
9d74a43aac | ||
|
|
9c7e5518ff | ||
|
|
b234c58d44 | ||
|
|
b1ae844e8b | ||
|
|
78bae497ba | ||
|
|
3e425bf8e6 | ||
|
|
4dca5b21a6 | ||
|
|
42c79e93dc | ||
|
|
2951b5533c | ||
|
|
fe8751eeae | ||
|
|
a0cd47ec35 | ||
|
|
3902e7aba4 |
@@ -9,7 +9,8 @@
|
||||
"updateInternalDependencies": "patch",
|
||||
"ignore": [],
|
||||
"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
|
||||
"updateInternalDependents": "always"
|
||||
"updateInternalDependents": "always",
|
||||
"onlyUpdatePeerDependentsWhenOutOfRange": true
|
||||
},
|
||||
"snapshot": {
|
||||
"useCalculatedVersion": true,
|
||||
|
||||
+60
-56
@@ -1,5 +1,9 @@
|
||||
# Contributing to thirdweb
|
||||
|
||||
You can find a full video tutorial on how to contribute to thirdweb below:
|
||||
|
||||
https://www.youtube.com/watch?v=TXsQ3qok3B0
|
||||
|
||||
## Getting Started
|
||||
|
||||
To get started, read the [How this repo works](#how-this-repo-works) section below to learn about the structure of this repo.
|
||||
@@ -16,7 +20,7 @@ If you have any questions about the issue, feel free to ask on our [Discord serv
|
||||
|
||||
We use [Turborepo](https://turborepo.org/docs/getting-started) to manage the monorepo, and help speed up the [CI/CD](https://www.atlassian.com/continuous-delivery/principles/continuous-integration-vs-delivery-vs-deployment) pipeline to ship to production faster 🚢.
|
||||
|
||||
You can see a quick outline of each of the projects within this repo below, which each live within the [/packages](/packages) directory:
|
||||
You can see a quick outline of each of the projects within this repo below, each living within the [/packages](/packages) directory:
|
||||
|
||||
| Package | Description | Latest Version |
|
||||
| ------------------------------ | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
@@ -58,75 +62,75 @@ To begin:
|
||||
|
||||
Now you have got the repo on your local machine, and you're ready to start making your changes!
|
||||
|
||||
### Test Your Changes
|
||||
|
||||
We use [yalc](https://github.com/wclr/yalc) to test changes locally.
|
||||
|
||||
Install the yalc CLI globally:
|
||||
|
||||
```bash
|
||||
yarn global add yalc
|
||||
```
|
||||
|
||||
First, create a test project where you can experiment with your changes:
|
||||
|
||||
You can create a basic starter project with the `sdk` and `react` packages installed using the CLI:
|
||||
|
||||
```bash
|
||||
npx thirdweb create --app
|
||||
```
|
||||
|
||||
Use `yalc` to link your local changes in the monorepo to the test project, by running the following command from your test repo:
|
||||
|
||||
```bash
|
||||
yalc add @thirdweb-dev/react # Link the react package
|
||||
yalc add @thirdweb-dev/sdk # Link the sdk package
|
||||
# etc...
|
||||
```
|
||||
|
||||
From the monorepo, run the following command to publish your local changes to the test project:
|
||||
|
||||
```bash
|
||||
yarn push
|
||||
```
|
||||
|
||||
Now, each time you make a change to the monorepo, you can run `yarn push` to publish your changes to the test project.
|
||||
|
||||
In your test project, you need to:
|
||||
|
||||
1. Delete the dependencies cache. If you're using Next.js, that is the `.next` directory, and if you're using CRA, that is the `node_modules/.cache` directory.
|
||||
2. Restart the development server.
|
||||
|
||||
<br/>
|
||||
|
||||
### Publish Your Changes
|
||||
|
||||
Once you're satisfied with your changes, you are ready to submit them for review!
|
||||
|
||||
1. Use [changeset](https://github.com/changesets/changesets) to generate a changeset file:
|
||||
|
||||
```
|
||||
yarn changeset
|
||||
```
|
||||
```
|
||||
yarn changeset
|
||||
```
|
||||
|
||||
We follow [semantic versioning](https://semver.org/) for generating versioned releases of our packages (i.e. version = `MAJOR.MINOR.PATCH`)
|
||||
We follow [semantic versioning](https://semver.org/) for generating versioned releases of our packages (i.e. version = `MAJOR.MINOR.PATCH`)
|
||||
|
||||
- Update `major` for breaking changes
|
||||
- Update `minor` for new features,
|
||||
- Update `patch` for non-breaking bug fixes, etc)
|
||||
- Update `major` for breaking changes
|
||||
- Update `minor` for new features,
|
||||
- Update `patch` for non-breaking bug fixes, etc)
|
||||
|
||||
2. Commit the changeset along with your changes:
|
||||
|
||||
```
|
||||
git commit -am "My commit message"
|
||||
```
|
||||
```
|
||||
git commit -am "My commit message"
|
||||
```
|
||||
|
||||
3. Push your changes to the SDK:
|
||||
|
||||
```
|
||||
git push origin MY_BRANCH_NAME
|
||||
```
|
||||
```
|
||||
git push origin MY_BRANCH_NAME
|
||||
```
|
||||
|
||||
4. Create a [pull request](https://www.atlassian.com/git/tutorials/making-a-pull-request) to the `main` branch of the official (not your fork) SDK repo.
|
||||
|
||||
It's helpful to tag PRs with `[SDK]`, `[REACT]`, `[AUTH]`, (the name of the package you're modifying) to indicate the package that you are engaging with.
|
||||
|
||||
<br/>
|
||||
|
||||
### Testing Your Changes
|
||||
|
||||
When you make a pull request, your changes will be tested automatically by our CI/CD pipeline using [GitHub Actions](https://github.com/features/actions).
|
||||
|
||||
On your pull request, you can release your changes to a `dev` version by adding a **comment** with the following text:
|
||||
|
||||
```
|
||||
/release-pr
|
||||
```
|
||||
|
||||
This comment triggers the `release-pr` GitHub Action that publishes your changes to a `dev` version of the package(s) you are modifying.
|
||||
|
||||
Once this is done, you can test your changes by installing the `dev` version of the package(s).
|
||||
|
||||
If you don't already have a test project, you can use the [CLI](https://github.com/thirdweb-dev/thirdweb-cli) to create one:
|
||||
|
||||
```bash
|
||||
npx thirdweb create
|
||||
```
|
||||
|
||||
Inside your test project, you can install the `dev` version of the package(s) you are modifying.
|
||||
|
||||
For example, if you are modifying the `@thirdweb-dev/react` package, you can install the `dev` version of the package by running:
|
||||
|
||||
```
|
||||
yarn add @thirdweb-dev/sdk@dev
|
||||
```
|
||||
|
||||
This will install the `dev` version of the `@thirdweb-dev/react` package in your project, as you can see in the `package.json` file:
|
||||
|
||||
```diff
|
||||
"dependencies": {
|
||||
- "@thirdweb-dev/react": "^2",
|
||||
+ "@thirdweb-dev/react": "^2.9.7-dev-b073878",
|
||||
}
|
||||
```
|
||||
|
||||
You can now test your changes in your test project!
|
||||
It's helpful to tag PRs with `[SDK]`, `[REACT]`, `[AUTH]`, (the name of the package you're modifying) to indicate the package that you are engaging with.
|
||||
|
||||
+5
-3
@@ -12,7 +12,7 @@
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"test": "turbo run test",
|
||||
"test": "turbo run test && turbo run test:evm && turbo run test:solana",
|
||||
"e2e": "turbo run e2e",
|
||||
"build": "turbo run build",
|
||||
"build:release": "turbo run build --force",
|
||||
@@ -26,7 +26,8 @@
|
||||
"version-packages": "changeset version",
|
||||
"release": "node ./scripts/pre-release.mjs && changeset publish",
|
||||
"version-packages:nightly": "changeset version --snapshot nightly",
|
||||
"release:nightly": "node ./scripts/pre-release.mjs && changeset publish --tag nightly"
|
||||
"release:nightly": "node ./scripts/pre-release.mjs && changeset publish --tag nightly",
|
||||
"push": "turbo run push"
|
||||
},
|
||||
"preconstruct": {
|
||||
"packages": [
|
||||
@@ -43,7 +44,8 @@
|
||||
"eslint": "^8.21.0",
|
||||
"postinstall-postinstall": "^2.1.0",
|
||||
"prettier": "^2.7.1",
|
||||
"turbo": "latest"
|
||||
"turbo": "^1.4.6",
|
||||
"yalc": "^1.0.0-pre.53"
|
||||
},
|
||||
"manypkg": {
|
||||
"defaultBranch": "main"
|
||||
|
||||
@@ -1,5 +1,58 @@
|
||||
# @thirdweb-dev/auth
|
||||
|
||||
## 2.0.10
|
||||
|
||||
## 2.0.9
|
||||
|
||||
## 2.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ce05bfd`](https://github.com/thirdweb-dev/js/commit/ce05bfd8615a9c79664856bce53de8b43bed5c87)]:
|
||||
- @thirdweb-dev/sdk@3.0.8
|
||||
|
||||
## 2.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5f5ab01`](https://github.com/thirdweb-dev/js/commit/5f5ab015e1dd3c471d6affe995ef36ec88932b3c)]:
|
||||
- @thirdweb-dev/sdk@3.0.7
|
||||
|
||||
## 2.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a80fc97`](https://github.com/thirdweb-dev/js/commit/a80fc97b6a1e72ed46a400b4b602e180947fb870)]:
|
||||
- @thirdweb-dev/sdk@3.0.6
|
||||
|
||||
## 2.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`4169b94`](https://github.com/thirdweb-dev/js/commit/4169b9428f9001b7cad259a4e56fe610316cd191), [`3b877ba`](https://github.com/thirdweb-dev/js/commit/3b877ba221acfd85f80b99e1bc382055217f0a39), [`b54f95d`](https://github.com/thirdweb-dev/js/commit/b54f95dc906928ff2f9251748f254a16fe1f2cee), [`f8ab477`](https://github.com/thirdweb-dev/js/commit/f8ab4779bb2d6d66200e1e8fd558e0ac069a2f54), [`772f843`](https://github.com/thirdweb-dev/js/commit/772f8431e3a62d0ded62dae90a43e9a7edd5b1a2), [`a9ec190`](https://github.com/thirdweb-dev/js/commit/a9ec190ff99d2714cef2500d20ea0f3f73f07be3), [`208b038`](https://github.com/thirdweb-dev/js/commit/208b0389a50ea48bbb9600fec60fec2f1671d4b9), [`5345479`](https://github.com/thirdweb-dev/js/commit/534547992243bdd3a77e34ec2b2487b5adab366a)]:
|
||||
- @thirdweb-dev/sdk@3.0.5
|
||||
|
||||
## 2.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/sdk@3.0.4
|
||||
|
||||
## 2.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`51dde28`](https://github.com/thirdweb-dev/js/commit/51dde28224209f1b8b26f436c204a5e702281564), [`9d74a43`](https://github.com/thirdweb-dev/js/commit/9d74a43aac21448beba63ba4e2637945965a3634), [`b234c58`](https://github.com/thirdweb-dev/js/commit/b234c58d44d8322e44b2d2ba87ad4ec7d699e961)]:
|
||||
- @thirdweb-dev/sdk@3.0.3
|
||||
|
||||
## 2.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`42c79e9`](https://github.com/thirdweb-dev/js/commit/42c79e93dc958ca46a55d705aeea44ffdbbcc5f6), [`fe8751e`](https://github.com/thirdweb-dev/js/commit/fe8751eeae7ad013b890a8092ddbd091ecbd6708)]:
|
||||
- @thirdweb-dev/sdk@3.0.2
|
||||
|
||||
## 2.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/auth",
|
||||
"version": "2.0.1",
|
||||
"version": "2.0.10",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
"./express": {
|
||||
@@ -60,7 +60,7 @@
|
||||
"eslint-plugin-tsdoc": "^0.2.16",
|
||||
"ethers": "^5.7.0",
|
||||
"express": "^4.18.1",
|
||||
"next": "12.2.0",
|
||||
"next": "^12.2.0",
|
||||
"next-auth": "^4.10.3",
|
||||
"prettier": "^2.7.1",
|
||||
"typescript": "^4.7.4"
|
||||
@@ -69,7 +69,7 @@
|
||||
"@thirdweb-dev/sdk": "*",
|
||||
"ethers": ">=5.5.1",
|
||||
"express": "^4.18.1",
|
||||
"next": "12.2.0",
|
||||
"next": "^12.2.0",
|
||||
"next-auth": "^4.10.3"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
|
||||
@@ -1,5 +1,82 @@
|
||||
# thirdweb
|
||||
|
||||
## 0.7.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`666ff5f`](https://github.com/thirdweb-dev/js/commit/666ff5f694f1e146150ddb9fa3233f00533b6d60), [`0dade96`](https://github.com/thirdweb-dev/js/commit/0dade96d0d2553d25b386d822e534eb7ed0aefa9), [`c295a47`](https://github.com/thirdweb-dev/js/commit/c295a47144cd722c6f8861c1ec567b53a05ea0bf)]:
|
||||
- @thirdweb-dev/sdk@3.1.1
|
||||
|
||||
## 0.7.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3c8f620`](https://github.com/thirdweb-dev/js/commit/3c8f6205e9b49ae9fea1f9629678210c6c9c36e6), [`e187d21`](https://github.com/thirdweb-dev/js/commit/e187d21e123a506fac0459da18f2d4fc94abae29), [`acbabc8`](https://github.com/thirdweb-dev/js/commit/acbabc8999b2b7b6e0eb89cae97e2f1ef7143501), [`b030a86`](https://github.com/thirdweb-dev/js/commit/b030a866080953bbf4e504ddc41d7050b250d2d7)]:
|
||||
- @thirdweb-dev/sdk@3.1.0
|
||||
|
||||
## 0.7.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ce05bfd`](https://github.com/thirdweb-dev/js/commit/ce05bfd8615a9c79664856bce53de8b43bed5c87)]:
|
||||
- @thirdweb-dev/sdk@3.0.8
|
||||
|
||||
## 0.7.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5f5ab01`](https://github.com/thirdweb-dev/js/commit/5f5ab015e1dd3c471d6affe995ef36ec88932b3c)]:
|
||||
- @thirdweb-dev/sdk@3.0.7
|
||||
|
||||
## 0.7.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a80fc97`](https://github.com/thirdweb-dev/js/commit/a80fc97b6a1e72ed46a400b4b602e180947fb870)]:
|
||||
- @thirdweb-dev/sdk@3.0.6
|
||||
|
||||
## 0.7.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#172](https://github.com/thirdweb-dev/js/pull/172) [`89db3db`](https://github.com/thirdweb-dev/js/commit/89db3db7ff3d5af7e7a7b5f25e299b9faad44eb0) Thanks [@adam-maj](https://github.com/adam-maj)! - Add thirdweb deploy to end of thirdweb detect and yarn build to thirdweb create
|
||||
|
||||
- [#175](https://github.com/thirdweb-dev/js/pull/175) [`3332fa5`](https://github.com/thirdweb-dev/js/commit/3332fa5697b9ff2a4ded1f2c508304f59f434be2) Thanks [@adam-maj](https://github.com/adam-maj)! - Split create contract flow into two steps
|
||||
|
||||
- [#177](https://github.com/thirdweb-dev/js/pull/177) [`3edec39`](https://github.com/thirdweb-dev/js/commit/3edec391be169453aaee412846005a820939fab0) Thanks [@adam-maj](https://github.com/adam-maj)! - thirdweb deploy redirects to contract deploy page if no contracts detected
|
||||
|
||||
- [#184](https://github.com/thirdweb-dev/js/pull/184) [`bdec5a5`](https://github.com/thirdweb-dev/js/commit/bdec5a59af680802e206e3025b2c463fc7dcb740) Thanks [@aeither](https://github.com/aeither)! - Fix "Invalid Project name" when a project with a capital letter is entered
|
||||
|
||||
- Updated dependencies [[`4169b94`](https://github.com/thirdweb-dev/js/commit/4169b9428f9001b7cad259a4e56fe610316cd191), [`3b877ba`](https://github.com/thirdweb-dev/js/commit/3b877ba221acfd85f80b99e1bc382055217f0a39), [`b54f95d`](https://github.com/thirdweb-dev/js/commit/b54f95dc906928ff2f9251748f254a16fe1f2cee), [`f8ab477`](https://github.com/thirdweb-dev/js/commit/f8ab4779bb2d6d66200e1e8fd558e0ac069a2f54), [`772f843`](https://github.com/thirdweb-dev/js/commit/772f8431e3a62d0ded62dae90a43e9a7edd5b1a2), [`a9ec190`](https://github.com/thirdweb-dev/js/commit/a9ec190ff99d2714cef2500d20ea0f3f73f07be3), [`208b038`](https://github.com/thirdweb-dev/js/commit/208b0389a50ea48bbb9600fec60fec2f1671d4b9), [`5345479`](https://github.com/thirdweb-dev/js/commit/534547992243bdd3a77e34ec2b2487b5adab366a)]:
|
||||
- @thirdweb-dev/sdk@3.0.5
|
||||
|
||||
## 0.7.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#148](https://github.com/thirdweb-dev/js/pull/148) [`964add6`](https://github.com/thirdweb-dev/js/commit/964add6f205577298b8f4b9ce7298e5bf09e88e7) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Fix deploy/release CLI uploads
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/sdk@3.0.4
|
||||
|
||||
## 0.7.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#134](https://github.com/thirdweb-dev/js/pull/134) [`b1ae844`](https://github.com/thirdweb-dev/js/commit/b1ae844e8bbed59c0225b32f4115ae384fa23ef5) Thanks [@adam-maj](https://github.com/adam-maj)! - Update ordering of commands in npx thirdweb
|
||||
|
||||
- Updated dependencies [[`51dde28`](https://github.com/thirdweb-dev/js/commit/51dde28224209f1b8b26f436c204a5e702281564), [`9d74a43`](https://github.com/thirdweb-dev/js/commit/9d74a43aac21448beba63ba4e2637945965a3634), [`b234c58`](https://github.com/thirdweb-dev/js/commit/b234c58d44d8322e44b2d2ba87ad4ec7d699e961)]:
|
||||
- @thirdweb-dev/sdk@3.0.3
|
||||
|
||||
## 0.7.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#128](https://github.com/thirdweb-dev/js/pull/128) [`4dca5b2`](https://github.com/thirdweb-dev/js/commit/4dca5b21a66fe8ff4c4b24663e1b9ad6c446b7e2) Thanks [@jarrodwatts](https://github.com/jarrodwatts)! - Add new documentation for detectable features
|
||||
|
||||
- Updated dependencies [[`42c79e9`](https://github.com/thirdweb-dev/js/commit/42c79e93dc958ca46a55d705aeea44ffdbbcc5f6), [`fe8751e`](https://github.com/thirdweb-dev/js/commit/fe8751eeae7ad013b890a8092ddbd091ecbd6708)]:
|
||||
- @thirdweb-dev/sdk@3.0.2
|
||||
|
||||
## 0.7.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -3,7 +3,8 @@ export const CREATE_MESSAGES = {
|
||||
projectName: "What is your project named?",
|
||||
framework: "What framework do you want to use?",
|
||||
language: "What language do you want to use?",
|
||||
contract: "What contract do you want to start from?",
|
||||
contract: "What type of contract do you want to start from?",
|
||||
extensions: "What extensions do you want to add to your contract?",
|
||||
} as const;
|
||||
|
||||
export const ERROR_MESSAGES = {
|
||||
|
||||
@@ -20,9 +20,12 @@ describe("npx thirdweb detect", () => {
|
||||
// select hardhat
|
||||
await create.pressKey("enter");
|
||||
await create.waitForText(CREATE_MESSAGES.contract);
|
||||
// select ERC721Base
|
||||
// select ERC721
|
||||
await create.pressKey("arrowDown");
|
||||
await create.pressKey("enter");
|
||||
await create.waitForText(CREATE_MESSAGES.extensions);
|
||||
// select no extra extensions
|
||||
await create.pressKey("enter");
|
||||
|
||||
// wait for program to finish
|
||||
await create.waitForFinish();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "thirdweb",
|
||||
"main": "dist/cli/index.js",
|
||||
"version": "0.7.12",
|
||||
"version": "0.7.21",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
@@ -25,7 +25,6 @@
|
||||
"prettier": "^2.7.1",
|
||||
"ts-jest": "^28.0.8",
|
||||
"ts-node": "^10.7.0",
|
||||
"tsc": "^2.0.4",
|
||||
"tsup": "^6.2.3",
|
||||
"typescript": "^4.7.4"
|
||||
},
|
||||
|
||||
@@ -39,31 +39,34 @@ $$$$$$\\ $$$$$$$\\ $$\\ $$$$$$\\ $$$$$$$ |$$\\ $$\\ $$\\ $$$$$$\\ $$$$
|
||||
.version(cliVersion, "-v, --version");
|
||||
|
||||
program
|
||||
.command("detect")
|
||||
.command("create")
|
||||
.description(
|
||||
"Compile contracts and detect implemented thirdweb contract extensions",
|
||||
"Create a thirdweb app from any of our official templates. Checkout some examples you can use here: https://github.com/thirdweb-example/",
|
||||
)
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option("-d, --debug", "show debug logs")
|
||||
.option("-a, --all", "run detection on all contracts")
|
||||
.action(async (options) => {
|
||||
await detectExtensions(options);
|
||||
});
|
||||
|
||||
program
|
||||
.command("release")
|
||||
.description(
|
||||
"Release contracts, making them available for others to deploy and unlocking SDKs, Dashboards and Analytics.",
|
||||
.option("--app", `Create a thirdweb app.`)
|
||||
.option("--contract", `Create a thirdweb contracts project.`)
|
||||
.option("--ts, --typescript", `Initialize as a TypeScript project.`)
|
||||
.option("--js, --javascript", `Initialize as a JavaScript project.`)
|
||||
.option("--forge", `Initialize as a Forge project.`)
|
||||
.option("--hardhat", `Initialize as a Hardhat project.`)
|
||||
.option("--cra", `Initialize as a Create React App project.`)
|
||||
.option("--next", `Initialize as a Next.js project.`)
|
||||
.option("--vite", `Initialize as a Vite project.`)
|
||||
.option(
|
||||
"--use-npm",
|
||||
`Explicitly tell the CLI to bootstrap the app using npm`,
|
||||
)
|
||||
.option(
|
||||
"--use-pnpm",
|
||||
`Explicitly tell the CLI to bootstrap the app using pnpm`,
|
||||
)
|
||||
.option("--framework [name]", `The preferred framework.`)
|
||||
.option(
|
||||
"-t, --template [name]",
|
||||
`A template to start your project from. You can use an template repository name from the official thirdweb-example org.`,
|
||||
)
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option("--dry-run", "dry run (skip actually publishing)")
|
||||
.option("-d, --debug", "show debug logs")
|
||||
.option("--ci", "Continuous Integration mode")
|
||||
.action(async (options) => {
|
||||
const url = await processProject(options, "release");
|
||||
info(`Open this link to release your contracts:`);
|
||||
logger.info(chalk.blueBright(url.toString()));
|
||||
open(url.toString());
|
||||
await twCreate(options);
|
||||
});
|
||||
|
||||
program
|
||||
@@ -111,34 +114,31 @@ $$$$$$\\ $$$$$$$\\ $$\\ $$$$$$\\ $$$$$$$ |$$\\ $$\\ $$\\ $$$$$$\\ $$$$
|
||||
});
|
||||
|
||||
program
|
||||
.command("create")
|
||||
.command("release")
|
||||
.description(
|
||||
"Create a thirdweb app from any of our official templates. Checkout some examples you can use here: https://github.com/thirdweb-example/",
|
||||
)
|
||||
.option("--app", `Create a thirdweb app.`)
|
||||
.option("--contract", `Create a thirdweb contracts project.`)
|
||||
.option("--ts, --typescript", `Initialize as a TypeScript project.`)
|
||||
.option("--js, --javascript", `Initialize as a JavaScript project.`)
|
||||
.option("--forge", `Initialize as a Forge project.`)
|
||||
.option("--hardhat", `Initialize as a Hardhat project.`)
|
||||
.option("--cra", `Initialize as a Create React App project.`)
|
||||
.option("--next", `Initialize as a Next.js project.`)
|
||||
.option("--vite", `Initialize as a Vite project.`)
|
||||
.option(
|
||||
"--use-npm",
|
||||
`Explicitly tell the CLI to bootstrap the app using npm`,
|
||||
)
|
||||
.option(
|
||||
"--use-pnpm",
|
||||
`Explicitly tell the CLI to bootstrap the app using pnpm`,
|
||||
)
|
||||
.option("--framework [name]", `The preferred framework.`)
|
||||
.option(
|
||||
"-t, --template [name]",
|
||||
`A template to start your project from. You can use an template repository name from the official thirdweb-example org.`,
|
||||
"Release contracts, making them available for others to deploy and unlocking SDKs, Dashboards and Analytics.",
|
||||
)
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option("--dry-run", "dry run (skip actually publishing)")
|
||||
.option("-d, --debug", "show debug logs")
|
||||
.option("--ci", "Continuous Integration mode")
|
||||
.action(async (options) => {
|
||||
await twCreate(options);
|
||||
const url = await processProject(options, "release");
|
||||
info(`Open this link to release your contracts:`);
|
||||
logger.info(chalk.blueBright(url.toString()));
|
||||
open(url.toString());
|
||||
});
|
||||
|
||||
program
|
||||
.command("detect")
|
||||
.description(
|
||||
"Compile contracts and detect implemented thirdweb contract extensions",
|
||||
)
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option("-d, --debug", "show debug logs")
|
||||
.option("-a, --all", "run detection on all contracts")
|
||||
.action(async (options) => {
|
||||
await detectExtensions(options);
|
||||
});
|
||||
|
||||
program
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { spinner } from "../core/helpers/logger";
|
||||
import { IpfsStorage } from "@thirdweb-dev/storage";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import { existsSync, mkdirSync, writeFileSync } from "fs";
|
||||
import path, { join } from "path";
|
||||
|
||||
@@ -13,10 +13,10 @@ export async function installGithubAction(options: any) {
|
||||
: path.resolve(`${projectPath}/${options.path}`);
|
||||
projectPath = resolvedPath;
|
||||
}
|
||||
const storage = new IpfsStorage();
|
||||
const storage = new ThirdwebStorage();
|
||||
const log = spinner("Installing thirdweb Github Action...");
|
||||
try {
|
||||
const ghActionData = await storage.getRaw(ghActionHash);
|
||||
const ghActionData = await (await storage.download(ghActionHash)).text();
|
||||
const dir = join(projectPath, ".github/workflows");
|
||||
if (!existsSync(dir)) {
|
||||
mkdirSync(dir, { recursive: true });
|
||||
|
||||
@@ -5,8 +5,10 @@ import { logger, spinner } from "../core/helpers/logger";
|
||||
import { createContractsPrompt } from "../core/helpers/selector";
|
||||
import { ContractFeatures, Feature } from "../core/interfaces/ContractFeatures";
|
||||
import { ContractPayload } from "../core/interfaces/ContractPayload";
|
||||
import { getPkgManager } from "../create/helpers/get-pkg-manager";
|
||||
import { detectFeatures, FeatureWithEnabled } from "@thirdweb-dev/sdk";
|
||||
import chalk from "chalk";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import ora from "ora";
|
||||
import path from "path";
|
||||
|
||||
@@ -70,13 +72,13 @@ export async function detectExtensions(options: any) {
|
||||
const enabledFeatures: Feature[] = features.enabledFeatures.map(
|
||||
(feature) => ({
|
||||
name: feature.name,
|
||||
reference: `https://portal.thirdweb.com/contracts/${feature.docLinks.contracts}`,
|
||||
reference: `https://portal.thirdweb.com/extensions/${feature.name.toLowerCase()}`,
|
||||
}),
|
||||
);
|
||||
const suggestedFeatures: Feature[] = features.suggestedFeatures.map(
|
||||
(feature) => ({
|
||||
name: feature.name,
|
||||
reference: `https://portal.thirdweb.com/contracts/${feature.docLinks.contracts}`,
|
||||
reference: `https://portal.thirdweb.com/extensions/${feature.name.toLowerCase()}`,
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -113,6 +115,26 @@ export async function detectExtensions(options: any) {
|
||||
)} - ${chalk.dim(chalk.gray(feature.reference))}`,
|
||||
);
|
||||
});
|
||||
|
||||
let deployCmd = `npx thirdweb@latest deploy`;
|
||||
if (existsSync(projectPath + "/package.json")) {
|
||||
const packageManager = getPkgManager();
|
||||
const useYarn = packageManager === "yarn";
|
||||
const pkgJson = JSON.parse(
|
||||
readFileSync(projectPath + "/package.json", "utf-8"),
|
||||
);
|
||||
if (pkgJson?.scripts?.deploy === deployCmd) {
|
||||
deployCmd = `${packageManager}${useYarn ? "" : " run"} deploy`;
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(``);
|
||||
ora(
|
||||
`Once you're done writing your contracts, you can run the following command to deploy them:`,
|
||||
).info();
|
||||
logger.info(``);
|
||||
logger.info(` ${chalk.cyan(deployCmd)}`);
|
||||
logger.info(``);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { THIRDWEB_URL, cliVersion } from "../constants/urls";
|
||||
import { cliVersion, THIRDWEB_URL } from "../constants/urls";
|
||||
import build from "../core/builder/build";
|
||||
import detect from "../core/detection/detect";
|
||||
import { execute } from "../core/helpers/exec";
|
||||
import { error, info, logger, spinner } from "../core/helpers/logger";
|
||||
import { createContractsPrompt } from "../core/helpers/selector";
|
||||
import { ContractPayload } from "../core/interfaces/ContractPayload";
|
||||
import { IpfsStorage } from "@thirdweb-dev/storage";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import chalk from "chalk";
|
||||
import { readFileSync } from "fs";
|
||||
import ora from "ora";
|
||||
import path from "path";
|
||||
|
||||
export async function processProject(
|
||||
@@ -15,7 +16,7 @@ export async function processProject(
|
||||
command: "deploy" | "release",
|
||||
) {
|
||||
// TODO: allow overriding the default storage
|
||||
const storage = new IpfsStorage();
|
||||
const storage = new ThirdwebStorage();
|
||||
|
||||
logger.setSettings({
|
||||
minLevel: options.debug ? "debug" : "info",
|
||||
@@ -35,6 +36,27 @@ export async function processProject(
|
||||
|
||||
const projectType = await detect(projectPath, options);
|
||||
|
||||
if (projectType === "none") {
|
||||
if (command === "deploy") {
|
||||
info(
|
||||
"No contracts detected in this directory. Redirecting to the thirdweb contract deployment page.",
|
||||
);
|
||||
return "https://thirdweb.com/contracts";
|
||||
}
|
||||
|
||||
error("No detected contracts in this directory.");
|
||||
logger.info(``);
|
||||
ora(
|
||||
`Detected contract files must end with the '.sol' extension and exist in this directory or the '/contracts' subdirectory`,
|
||||
).info();
|
||||
logger.info(``);
|
||||
ora("To create a new contracts project, run the following command:").info();
|
||||
logger.info(``);
|
||||
logger.info(` ${chalk.cyan(`npx thirdweb@latest create --contract`)}`);
|
||||
logger.info(``);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (options.ci) {
|
||||
logger.info("Installing dependencies...");
|
||||
try {
|
||||
@@ -129,7 +151,9 @@ export async function processProject(
|
||||
if (file.includes(soliditySDKPackage)) {
|
||||
usesSoliditySDK = true;
|
||||
}
|
||||
return await storage.uploadSingle(file);
|
||||
return await storage.upload(file, {
|
||||
uploadWithoutDirectory: true,
|
||||
});
|
||||
}),
|
||||
);
|
||||
}
|
||||
@@ -140,14 +164,15 @@ export async function processProject(
|
||||
const metadataURIs = await Promise.all(
|
||||
selectedContracts.map(async (c) => {
|
||||
logger.debug(`Uploading ${c.name}...`);
|
||||
const hash = await storage.uploadSingle(c.metadata);
|
||||
return `ipfs://${hash}`;
|
||||
return await storage.upload(JSON.parse(c.metadata), {
|
||||
uploadWithoutDirectory: true,
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
// Upload batch all bytecodes
|
||||
const bytecodes = selectedContracts.map((c) => c.bytecode);
|
||||
const { uris: bytecodeURIs } = await storage.uploadBatch(bytecodes);
|
||||
const bytecodeURIs = await storage.uploadBatch(bytecodes);
|
||||
|
||||
const combinedContents = selectedContracts.map((c, i) => {
|
||||
// attach analytics blob to metadata
|
||||
@@ -169,14 +194,13 @@ export async function processProject(
|
||||
let combinedURIs: string[] = [];
|
||||
if (combinedContents.length === 1) {
|
||||
// use upload single if only one contract to get a clean IPFS hash
|
||||
const metadataUri = await storage.uploadSingle(
|
||||
JSON.stringify(combinedContents[0]),
|
||||
);
|
||||
const metadataUri = await storage.upload(combinedContents[0], {
|
||||
uploadWithoutDirectory: true,
|
||||
});
|
||||
combinedURIs.push(metadataUri);
|
||||
} else {
|
||||
// otherwise upload batch
|
||||
const { uris } = await storage.uploadMetadataBatch(combinedContents);
|
||||
combinedURIs = uris;
|
||||
combinedURIs = await storage.uploadBatch(combinedContents);
|
||||
}
|
||||
|
||||
loader.succeed("Upload successful");
|
||||
|
||||
@@ -21,7 +21,7 @@ contract Contract is ERC721Base {
|
||||
{}
|
||||
|
||||
}`,
|
||||
ERC721Signature: `// SPDX-License-Identifier: Apache-2.0
|
||||
ERC721SignatureMint: `// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC721SignatureMint.sol";
|
||||
@@ -113,7 +113,7 @@ contract Contract is ERC1155Base {
|
||||
{}
|
||||
|
||||
}`,
|
||||
ERC1155Signature: `// SPDX-License-Identifier: Apache-2.0
|
||||
ERC1155SignatureMint: `// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC1155SignatureMint.sol";
|
||||
|
||||
@@ -5,7 +5,9 @@ import { Detector } from "./detector";
|
||||
import FoundryDetector from "./foundry";
|
||||
import HardhatDetector from "./hardhat";
|
||||
import TruffleDetector from "./truffle";
|
||||
import fs, { existsSync } from "fs";
|
||||
import inquirer from "inquirer";
|
||||
import { parse } from "path";
|
||||
|
||||
const { Confirm } = require("enquirer");
|
||||
|
||||
@@ -26,18 +28,24 @@ export default async function detect(
|
||||
|
||||
//if there is no project returned at all then just return unknown}
|
||||
if (!possibleProjectTypes.length) {
|
||||
warn(`${ERROR_MESSAGES.noConfiguration} ${path}`);
|
||||
const prompt = new Confirm({
|
||||
name: "continue",
|
||||
message:
|
||||
"Do you want to continue and compile this project with solc instead?",
|
||||
});
|
||||
const shouldCompile = await prompt.run();
|
||||
if (!shouldCompile) {
|
||||
logger.warn("Aborted contract compilation");
|
||||
process.exit(1);
|
||||
const canCompile = hasContracts(path);
|
||||
|
||||
if (canCompile) {
|
||||
warn(`${ERROR_MESSAGES.noConfiguration} ${path}`);
|
||||
const prompt = new Confirm({
|
||||
name: "continue",
|
||||
message:
|
||||
"Do you want to continue and compile this project with solc instead?",
|
||||
});
|
||||
const shouldCompile = await prompt.run();
|
||||
if (!shouldCompile) {
|
||||
logger.warn("Aborted contract compilation");
|
||||
process.exit(1);
|
||||
}
|
||||
return "solc";
|
||||
} else {
|
||||
return "none";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
//if there is only one possible option just return it
|
||||
if (possibleProjectTypes.length === 1) {
|
||||
@@ -64,3 +72,24 @@ export default async function detect(
|
||||
return answer[question];
|
||||
}
|
||||
}
|
||||
|
||||
// Check if a directory has any .sol files or a /contracts folder with .sol files
|
||||
function hasContracts(path: any) {
|
||||
return (
|
||||
["", "/contracts"].filter((p) => {
|
||||
const dirPath = path + p;
|
||||
|
||||
if (!existsSync(dirPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const files = fs.readdirSync(dirPath);
|
||||
const contracts = files.filter((filePath) => {
|
||||
const { ext } = parse(filePath);
|
||||
return ext === ".sol";
|
||||
});
|
||||
|
||||
return contracts.length > 0;
|
||||
}).length > 0
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,4 +3,5 @@ export type ProjectType =
|
||||
| "foundry"
|
||||
| "hardhat"
|
||||
| "truffle"
|
||||
| "unknown";
|
||||
| "solc"
|
||||
| "none";
|
||||
|
||||
@@ -90,8 +90,11 @@ export async function twCreate(options: any) {
|
||||
name: "path",
|
||||
message: CREATE_MESSAGES.projectName,
|
||||
initial: options.template || defaultName,
|
||||
validate: (name) => {
|
||||
const validation = validateNpmName(path.basename(path.resolve(name)));
|
||||
format: (name: string) => name.toLowerCase(),
|
||||
validate: (name: string) => {
|
||||
const validation = validateNpmName(
|
||||
path.basename(path.resolve(name.toLowerCase())),
|
||||
);
|
||||
if (validation.valid) {
|
||||
return true;
|
||||
}
|
||||
@@ -175,36 +178,64 @@ export async function twCreate(options: any) {
|
||||
|
||||
// Select base contract
|
||||
if (projectType === "contract" && !baseContract) {
|
||||
const res = await prompts({
|
||||
let standard = "none";
|
||||
const standardPrompt = await prompts({
|
||||
type: "select",
|
||||
name: "baseContract",
|
||||
name: "standard",
|
||||
message: CREATE_MESSAGES.contract,
|
||||
choices: [
|
||||
{ title: "Empty Contract", value: "" },
|
||||
{ title: "ERC721 Base", value: "ERC721Base" },
|
||||
{ title: "ERC721 + Signature Mint", value: "ERC721Signature" },
|
||||
{ title: "ERC721 + Lazy Mint", value: "ERC721LazyMint" },
|
||||
{ title: "ERC721 + Delayed Reveal", value: "ERC721DelayedReveal" },
|
||||
{ title: "ERC721 + Drop", value: "ERC721Drop" },
|
||||
{ title: "ERC1155 Base", value: "ERC1155Base" },
|
||||
{ title: "ERC1155 + Signature Mint", value: "ERC1155Signature" },
|
||||
{ title: "ERC1155 + Lazy Mint", value: "ERC1155LazyMint" },
|
||||
{ title: "ERC1155 + Delayed Reveal", value: "ERC1155DelayedReveal" },
|
||||
{ title: "ERC1155 + Drop", value: "ERC1155Drop" },
|
||||
{ title: "ERC20 Base", value: "ERC20Base" },
|
||||
{ title: "ERC20 + Vote", value: "ERC20Vote" },
|
||||
{ title: "ERC20 + Signature Mint", value: "ERC20SignatureMint" },
|
||||
{
|
||||
title: "ERC20 + Vote + Signature Mint",
|
||||
value: "ERC20SignatureMintVote",
|
||||
},
|
||||
{ title: "ERC20 + Drop", value: "ERC20Drop" },
|
||||
{ title: "ERC20 + Vote + Drop", value: "ERC20DropVote" },
|
||||
{ title: "Empty Contract", value: "none" },
|
||||
{ title: "ERC721", value: "erc721" },
|
||||
{ title: "ERC20", value: "erc20" },
|
||||
{ title: "ERC1155", value: "erc1155" },
|
||||
],
|
||||
});
|
||||
|
||||
if (typeof res.baseContract === "string") {
|
||||
baseContract = res.baseContract.trim();
|
||||
if (typeof standardPrompt.standard === "string") {
|
||||
standard = standardPrompt.standard.trim();
|
||||
}
|
||||
|
||||
if (standard === "none") {
|
||||
baseContract = "";
|
||||
} else {
|
||||
let choices: prompts.Choice[] = [];
|
||||
if (standard === "erc721") {
|
||||
choices = [
|
||||
{ title: "None", value: "ERC721Base" },
|
||||
{ title: "Signature Mint", value: "ERC721SignatureMint" },
|
||||
{ title: "Lazy Mint", value: "ERC721LazyMint" },
|
||||
{ title: "Delayed Reveal", value: "ERC721DelayedReveal" },
|
||||
{ title: "Drop", value: "ERC721Drop" },
|
||||
];
|
||||
} else if (standard === "erc20") {
|
||||
choices = [
|
||||
{ title: "None", value: "ERC20Base" },
|
||||
{ title: "Vote", value: "ERC20Vote" },
|
||||
{ title: "Signature Mint", value: "ERC20SignatureMint" },
|
||||
{ title: "Vote + Signature Mint", value: "ERC20SignatureMintVote" },
|
||||
{ title: "Drop", value: "ERC20Drop" },
|
||||
{ title: "Vote + Drop", value: "ERC20DropVote" },
|
||||
];
|
||||
} else if (standard === "erc1155") {
|
||||
choices = [
|
||||
{ title: "None", value: "ERC1155Base" },
|
||||
{ title: "Signature Mint", value: "ERC1155SignatureMint" },
|
||||
{ title: "Lazy Mint", value: "ERC1155LazyMint" },
|
||||
{ title: "Delayed Reveal", value: "ERC1155DelayedReveal" },
|
||||
{ title: "Drop", value: "ERC1155Drop" },
|
||||
];
|
||||
}
|
||||
|
||||
const res = await prompts({
|
||||
type: "select",
|
||||
name: "baseContract",
|
||||
message: CREATE_MESSAGES.extensions,
|
||||
choices: choices,
|
||||
});
|
||||
|
||||
if (typeof res.baseContract === "string") {
|
||||
baseContract = res.baseContract.trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -145,15 +145,21 @@ export async function createContract({
|
||||
console.log(
|
||||
`${chalk.green("Success!")} Created ${projectName} at ${contractPath}`,
|
||||
);
|
||||
console.log();
|
||||
console.log("Inside that directory, you can run several commands:");
|
||||
console.log();
|
||||
console.log(chalk.cyan(` ${packageManager} ${useYarn ? "" : "run"} deploy`));
|
||||
console.log(chalk.cyan(` ${packageManager}${useYarn ? "" : " run"} build`));
|
||||
console.log(
|
||||
" Compiles your contracts and detects thirdweb extensions implemented on them.",
|
||||
);
|
||||
console.log();
|
||||
console.log(chalk.cyan(` ${packageManager}${useYarn ? "" : " run"} deploy`));
|
||||
console.log(" Deploys your contracts with the thirdweb deploy flow.");
|
||||
console.log();
|
||||
console.log(
|
||||
chalk.cyan(` ${packageManager} ${useYarn ? "" : "run"} release`),
|
||||
chalk.cyan(` ${packageManager}${useYarn ? "" : " run"} release`),
|
||||
);
|
||||
console.log(" Releases your contracts with the thirdweb release flow..");
|
||||
console.log(" Releases your contracts with the thirdweb release flow.");
|
||||
console.log();
|
||||
console.log("We suggest that you begin by typing:");
|
||||
console.log();
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
"main": "index.js",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^5.36.2",
|
||||
"@typescript-eslint/parser": "^5.36.2",
|
||||
"@typescript-eslint/eslint-plugin": "^5.33.0",
|
||||
"@typescript-eslint/parser": "^5.33.0",
|
||||
"eslint-config-next": "^12.0.8",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-config-turbo": "latest",
|
||||
|
||||
@@ -1,5 +1,92 @@
|
||||
# @thirdweb-dev/react
|
||||
|
||||
## 3.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#221](https://github.com/thirdweb-dev/js/pull/221) [`c295a47`](https://github.com/thirdweb-dev/js/commit/c295a47144cd722c6f8861c1ec567b53a05ea0bf) Thanks [@jnsdls](https://github.com/jnsdls)! - fix esm exports
|
||||
|
||||
## 3.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#213](https://github.com/thirdweb-dev/js/pull/213) [`e187d21`](https://github.com/thirdweb-dev/js/commit/e187d21e123a506fac0459da18f2d4fc94abae29) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - New @thirdweb-dev/react/solana entrypoint
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#208](https://github.com/thirdweb-dev/js/pull/208) [`7c86bab`](https://github.com/thirdweb-dev/js/commit/7c86babb86e02f08a630ed7578036202eb3dbe66) Thanks [@jnsdls](https://github.com/jnsdls)! - add a bunch of initial solana hooks
|
||||
|
||||
- [#218](https://github.com/thirdweb-dev/js/pull/218) [`1eaedc2`](https://github.com/thirdweb-dev/js/commit/1eaedc262f0665de2a6a0446402b570371136e05) Thanks [@jnsdls](https://github.com/jnsdls)! - allow both `null` and `undefined` to be passed as a `RequiredParam`
|
||||
|
||||
- [#220](https://github.com/thirdweb-dev/js/pull/220) [`37a707f`](https://github.com/thirdweb-dev/js/commit/37a707f98c00140ddedb1d876a4b2f99fe25556a) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Fix chakra zag-menu breaking update
|
||||
|
||||
## 3.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#209](https://github.com/thirdweb-dev/js/pull/209) [`1bda83b`](https://github.com/thirdweb-dev/js/commit/1bda83b1142406892acfb64576fce25d2647afa7) Thanks [@jnsdls](https://github.com/jnsdls)! - fix useLayoutEffect during SSR warning
|
||||
|
||||
- Updated dependencies [[`ce05bfd`](https://github.com/thirdweb-dev/js/commit/ce05bfd8615a9c79664856bce53de8b43bed5c87)]:
|
||||
- @thirdweb-dev/sdk@3.0.8
|
||||
|
||||
## 3.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#197](https://github.com/thirdweb-dev/js/pull/197) [`f4f05bd`](https://github.com/thirdweb-dev/js/commit/f4f05bd9a4ec98e9abc6716006353f330b7be055) Thanks [@jnsdls](https://github.com/jnsdls)! - make it obvious when the <Web3Button /> will trigger a network switch
|
||||
|
||||
- Updated dependencies [[`5f5ab01`](https://github.com/thirdweb-dev/js/commit/5f5ab015e1dd3c471d6affe995ef36ec88932b3c), [`5f5ab01`](https://github.com/thirdweb-dev/js/commit/5f5ab015e1dd3c471d6affe995ef36ec88932b3c)]:
|
||||
- @thirdweb-dev/sdk@3.0.7
|
||||
- @thirdweb-dev/solana@0.2.15
|
||||
|
||||
## 3.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#179](https://github.com/thirdweb-dev/js/pull/179) [`63258bc`](https://github.com/thirdweb-dev/js/commit/63258bc9c3443db7d12fc1dc6fbd483926c92d3e) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Expose simple provider and useSDK hooks for Solana
|
||||
|
||||
- Updated dependencies [[`a80fc97`](https://github.com/thirdweb-dev/js/commit/a80fc97b6a1e72ed46a400b4b602e180947fb870)]:
|
||||
- @thirdweb-dev/sdk@3.0.6
|
||||
- @thirdweb-dev/solana@0.2.14
|
||||
|
||||
## 3.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#167](https://github.com/thirdweb-dev/js/pull/167) [`4169b94`](https://github.com/thirdweb-dev/js/commit/4169b9428f9001b7cad259a4e56fe610316cd191) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Syntax changes for react native support
|
||||
|
||||
- [#168](https://github.com/thirdweb-dev/js/pull/168) [`208b038`](https://github.com/thirdweb-dev/js/commit/208b0389a50ea48bbb9600fec60fec2f1671d4b9) Thanks [@jnsdls](https://github.com/jnsdls)! - use internals wherever possible to allow wider usecases with `<ThirdwebSDKProvider>` & add invariants to catch improper use of functionality that requires the full `<ThirdwebProvider` earlier
|
||||
|
||||
- [#168](https://github.com/thirdweb-dev/js/pull/168) [`208b038`](https://github.com/thirdweb-dev/js/commit/208b0389a50ea48bbb9600fec60fec2f1671d4b9) Thanks [@jnsdls](https://github.com/jnsdls)! - fix case where `<ConnectWallet />` button would get stuck when user cancels connection
|
||||
|
||||
- [#168](https://github.com/thirdweb-dev/js/pull/168) [`208b038`](https://github.com/thirdweb-dev/js/commit/208b0389a50ea48bbb9600fec60fec2f1671d4b9) Thanks [@jnsdls](https://github.com/jnsdls)! - allow passing `className` to `<ConnectWallet />` and `<Web3Button />` for possible style overrides
|
||||
|
||||
- Updated dependencies [[`4169b94`](https://github.com/thirdweb-dev/js/commit/4169b9428f9001b7cad259a4e56fe610316cd191), [`3b877ba`](https://github.com/thirdweb-dev/js/commit/3b877ba221acfd85f80b99e1bc382055217f0a39), [`b54f95d`](https://github.com/thirdweb-dev/js/commit/b54f95dc906928ff2f9251748f254a16fe1f2cee), [`f8ab477`](https://github.com/thirdweb-dev/js/commit/f8ab4779bb2d6d66200e1e8fd558e0ac069a2f54), [`772f843`](https://github.com/thirdweb-dev/js/commit/772f8431e3a62d0ded62dae90a43e9a7edd5b1a2), [`a9ec190`](https://github.com/thirdweb-dev/js/commit/a9ec190ff99d2714cef2500d20ea0f3f73f07be3), [`208b038`](https://github.com/thirdweb-dev/js/commit/208b0389a50ea48bbb9600fec60fec2f1671d4b9), [`5345479`](https://github.com/thirdweb-dev/js/commit/534547992243bdd3a77e34ec2b2487b5adab366a)]:
|
||||
- @thirdweb-dev/sdk@3.0.5
|
||||
|
||||
## 3.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/sdk@3.0.4
|
||||
|
||||
## 3.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#143](https://github.com/thirdweb-dev/js/pull/143) [`51dde28`](https://github.com/thirdweb-dev/js/commit/51dde28224209f1b8b26f436c204a5e702281564) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Fix using external signers with ThirdwebSDKProvider
|
||||
|
||||
- Updated dependencies [[`51dde28`](https://github.com/thirdweb-dev/js/commit/51dde28224209f1b8b26f436c204a5e702281564), [`9d74a43`](https://github.com/thirdweb-dev/js/commit/9d74a43aac21448beba63ba4e2637945965a3634), [`b234c58`](https://github.com/thirdweb-dev/js/commit/b234c58d44d8322e44b2d2ba87ad4ec7d699e961)]:
|
||||
- @thirdweb-dev/sdk@3.0.3
|
||||
|
||||
## 3.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`42c79e9`](https://github.com/thirdweb-dev/js/commit/42c79e93dc958ca46a55d705aeea44ffdbbcc5f6), [`fe8751e`](https://github.com/thirdweb-dev/js/commit/fe8751eeae7ad013b890a8092ddbd091ecbd6708)]:
|
||||
- @thirdweb-dev/sdk@3.0.2
|
||||
|
||||
## 3.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
# Migration Guide
|
||||
|
||||
If you are looking to upgrade from an earlier version of the React SDK, below are the breaking changes that you should be aware of between each version.
|
||||
|
||||
## Upgrading to Version 3
|
||||
|
||||
Version 3 of the React SDK introduces a significant (87%) reduction in package size and first-class support for using custom contracts with the SDK. Learn more about why we made these changes and how it improves the SDK in our [blog post](https://blog.thirdweb.com/sdk-major-update/).
|
||||
|
||||
### useContractData
|
||||
|
||||
The `useContractData` hook to read data from a smart contract has been renamed to `useContractRead`.
|
||||
|
||||
```diff
|
||||
- const { data } = useContractData(contract, 'name')
|
||||
+ const { data } = useContractRead(contract, 'name')
|
||||
```
|
||||
|
||||
### useContractCall
|
||||
|
||||
The `useContractCall` hook to call a smart contract function has been renamed to `useContractWrite`.
|
||||
|
||||
```diff
|
||||
- const { mutate } = useContractCall(contract, 'setName')
|
||||
+ const { mutate } = useContractWrite(contract, 'setName')
|
||||
```
|
||||
|
||||
### 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:
|
||||
|
||||
```diff
|
||||
- const contract = useNFTDrop("0x...")
|
||||
+ const { contract } = useContract("0x...")
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
### New Contract Namespaces
|
||||
|
||||
When working with contracts using the `useContract` hook, we now expose all the convenient high level APIs for each ERC standard top level.
|
||||
Calling a function that is not supported in your contract will give you an error with instructions on how to unlock that functionality.
|
||||
|
||||
```diff
|
||||
// ERC721 contracts
|
||||
- const contract.nft?.drop?.claim?.to(...)
|
||||
+ const contract.erc721.claimTo(...)
|
||||
- const contract.nft?.drop?.claim?.conditions.set(...)
|
||||
+ const contract.erc721.claimConditions.set(...)
|
||||
|
||||
// ERC1155 contracts
|
||||
- const contract.edition?.mint?.to(...)
|
||||
+ const contract.erc1155.mintTo(...)
|
||||
|
||||
// ERC20 contracts
|
||||
- const contract.token?.burn.tokens(...)
|
||||
+ const contract.erc20.burn(...)
|
||||
```
|
||||
|
||||
The `Web3Button`'s `contract` benefits from these changes as well:
|
||||
|
||||
```diff jsx
|
||||
<Web3Button
|
||||
contractAddress={...}
|
||||
- action={(contract) => contract.nft?.drop?.claim?.to(...)}
|
||||
+ action={(contract) => contract.erc721.claim(...)}
|
||||
>
|
||||
Claim
|
||||
</Web3Button>
|
||||
```
|
||||
+177
-54
@@ -13,9 +13,17 @@
|
||||
<p align="center"><strong>Ultimate collection of React hooks for your web3 apps</strong></p>
|
||||
<br />
|
||||
|
||||
<br />
|
||||
|
||||
## Installation
|
||||
|
||||
You can install this SDK with either `npm` or `yarn`:
|
||||
The easiest way to get started with the React SDK is to use the CLI:
|
||||
|
||||
```sh
|
||||
npx thirdweb create --app
|
||||
```
|
||||
|
||||
Alternatively, you can install the SDK into your existing project using npm or yarn:
|
||||
|
||||
```sh
|
||||
npm install @thirdweb-dev/react @thirdweb-dev/sdk ethers
|
||||
@@ -25,21 +33,19 @@ npm install @thirdweb-dev/react @thirdweb-dev/sdk ethers
|
||||
yarn add @thirdweb-dev/react @thirdweb-dev/sdk ethers
|
||||
```
|
||||
|
||||
## Starter Templates
|
||||
<br />
|
||||
|
||||
We provide template repositories that already have the thirdweb React SDK setup and ready-to-go to help you get started with thirdweb quickly. You can find all the available starter respositories below.
|
||||
## Getting Started
|
||||
|
||||
- Next.js ([typescript](https://github.com/thirdweb-example/next-typescript-starter) / [javascript](https://github.com/thirdweb-example/next-javascript-starter))
|
||||
- Create React App ([typescript](https://github.com/thirdweb-example/cra-typescript-starter) / [javascript](https://github.com/thirdweb-example/cra-javascript-starter))
|
||||
- Vite ([typescript](https://github.com/thirdweb-example/vite-typescript-starter) / [javascript](https://github.com/thirdweb-example/vite-javascript-starter))
|
||||
Our SDK uses a [Provider Pattern](https://flexiple.com/react/provider-pattern-with-react-context-api/); meaning any component within the `ThirdwebProvider` will have access to the SDK. If you use the CLI to initialize your project, this is already set up for you.
|
||||
|
||||
## Quick Start
|
||||
Let's take a look at a typical setup:
|
||||
|
||||
**Configure the thirdweb Provider**
|
||||
<br />
|
||||
|
||||
In order to use the hooks offered by the React SDK, you need to first setup a `ThirdwebProvider` for your app which lets you optionally configure your app. You can use this configuration to control what networks you want users to connect to, what types of wallets can connect to your app, and the settings for the [Typescript SDK](https://docs.thirdweb.com/typescript).
|
||||
### Configure the `ThirdwebProvider`
|
||||
|
||||
At the top level of your application, add a `ThirdwebProvider` as follows:
|
||||
Specify the network your smart contracts are deployed to in the `desiredChainId` prop and wrap your application like so:
|
||||
|
||||
```jsx title="App.jsx"
|
||||
import { ChainId, ThirdwebProvider } from "@thirdweb-dev/react";
|
||||
@@ -53,79 +59,196 @@ const App = () => {
|
||||
};
|
||||
```
|
||||
|
||||
Now you'll be able to use all the hooks provided by the React SDK! Let's take a look.
|
||||
Below are examples of where to set this up in your application:
|
||||
|
||||
**Let Users Connect Wallets**
|
||||
<p>
|
||||
<a href="https://github.com/thirdweb-example/cra-javascript-starter/blob/main/src/index.js">Create React App</a> •
|
||||
<a href="https://github.com/thirdweb-example/next-javascript-starter/blob/main/pages/_app.js">Next.js</a> •
|
||||
<a href="https://github.com/thirdweb-example/vite-javascript-starter/blob/main/src/main.jsx">Vite</a>
|
||||
</p>
|
||||
|
||||
Next, we'll add a button to our app which will let users connect their wallets. For now, we'll make it so that users with MetaMask wallets can connect.
|
||||
<br />
|
||||
|
||||
### Connect to a User's Wallet
|
||||
|
||||
Now the provider is set up, we can use all of the hooks and UI components available in the SDK, such as the [ConnectWallet](https://portal.thirdweb.com/sdk/ui-components/connectwalletbutton) component.
|
||||
|
||||
Once the user has connected their wallet, all the calls we make to interact with contracts using the SDK will be on behalf of the user.
|
||||
|
||||
```jsx title="ConnectMetamaskButton.jsx"
|
||||
import { useAddress, useDisconnect, useMetamask } from "@thirdweb-dev/react";
|
||||
import { ConnectWallet, useAddress } from "@thirdweb-dev/react";
|
||||
|
||||
export const ConnectMetamaskButtonComponent = () => {
|
||||
const connectWithMetamask = useMetamask();
|
||||
export const YourApp = () => {
|
||||
const address = useAddress();
|
||||
return (
|
||||
<div>
|
||||
{address ? (
|
||||
<h4>Connected as {address}</h4>
|
||||
<ConnectWallet />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
The `ConnectWallet` component handles everything for us, including switching networks, accounts, displaying balances and more.
|
||||
|
||||
We can then get the connected address using the `useAddress` hook anywhere in the app.
|
||||
|
||||
<br/>
|
||||
|
||||
### Interact With Contracts
|
||||
|
||||
Connect to your smart contract using the [`useContract`](https://portal.thirdweb.com/sdk/interacting-with-contracts/custom-contracts/getting-a-contract#connect-to-a-contract)
|
||||
hook like so:
|
||||
|
||||
```jsx title="pages/index.jsx"
|
||||
import { useContract } from "@thirdweb-dev/react";
|
||||
|
||||
export default function Home() {
|
||||
const { contract } = useContract("<CONTRACT_ADDRESS>");
|
||||
|
||||
// Now you can use the contract in the rest of the component!
|
||||
}
|
||||
```
|
||||
|
||||
You can then use [`useContractRead`](https://portal.thirdweb.com/sdk/interacting-with-contracts/custom-contracts/using-contracts) and [`useContractWrite`](https://portal.thirdweb.com/sdk/interacting-with-contracts/custom-contracts/using-contracts) to read data and write transactions to the contract.
|
||||
|
||||
You pass the `contract` object returned from `useContract` to these hooks as the first parameter and the name of the function (or view/mapping, etc.) on your smart contract as the second parameter. If your function requires parameters, you can pass them as additional arguments.
|
||||
|
||||
For example, we can read the `name` of our contract like so:
|
||||
|
||||
```jsx title="pages/index.jsx"
|
||||
import {
|
||||
useContract,
|
||||
useContractRead,
|
||||
useContractWrite,
|
||||
} from "@thirdweb-dev/react";
|
||||
|
||||
export default function Home() {
|
||||
const { contract } = useContract("<CONTRACT_ADDRESS>");
|
||||
const { data: name, isLoading: loadingName } = useContractRead(
|
||||
contract,
|
||||
"name", // The name of the view/mapping/variable on your contract
|
||||
);
|
||||
const { mutate: setName, isLoading: settingName } = useContractWrite(
|
||||
contract,
|
||||
"setName", // The name of the function on your contract
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
<br />
|
||||
|
||||
### Using Extensions
|
||||
|
||||
Each [extension](https://portal.thirdweb.com/extensions) you implement in your smart contract unlocks new functionality in the SDK.
|
||||
|
||||
These hooks make it easy to interact with your smart contracts by implementing the complex logic for you under the hood.
|
||||
|
||||
For example, if your smart contract implements [ERC721Supply](https://portal.thirdweb.com/extensions/erc721supply#unlocked-features), you unlock the ability to [view all NFTs](https://portal.thirdweb.com/sdk/interacting-with-contracts/erc721supply#get-all-minted-nfts) on that contract using the SDK; which fetches all of your NFT metadata and the current owner of each NFT in parallel. In the React SDK, that is available using `useNFTs`:
|
||||
|
||||
```jsx
|
||||
import { useContract, useNFTs } from "@thirdweb-dev/react";
|
||||
|
||||
export default function Home() {
|
||||
const { contract } = useContract("<CONTRACT_ADDRESS>");
|
||||
const { data: nfts, isLoading: isReadingNfts } = useNFTs(contract);
|
||||
}
|
||||
```
|
||||
|
||||
If we want to mint an NFT and our contract implements [ERC721Mintable](https://portal.thirdweb.com/extensions/erc721mintable#unlocked-features), we can use the [`useMintNFT`](https://portal.thirdweb.com/sdk/interacting-with-contracts/erc721mintable) hook to mint an NFT from the connected wallet; handling all of the logic of uploading and pinning the metadata to IPFS for us behind the scenes.
|
||||
|
||||
```jsx
|
||||
import { useContract, useNFTs, useMintNFT } from "@thirdweb-dev/react";
|
||||
|
||||
export default function Home() {
|
||||
const { contract } = useContract("<CONTRACT_ADDRESS>");
|
||||
const { data: nfts, isLoading: isReadingNfts } = useNFTs(contract);
|
||||
const { mutate: mintNFT, isLoading: isMintingNFT } = useMintNFT(contract);
|
||||
}
|
||||
```
|
||||
|
||||
<br />
|
||||
|
||||
### UI Components
|
||||
|
||||
The SDK provides many UI components to help you build your application.
|
||||
|
||||
For example, we can render each of the NFTs using the [`NFT Media Renderer`](https://portal.thirdweb.com/sdk/ui-components/nft-renderer)
|
||||
component, making use of the loading state from `useNFTs`:
|
||||
|
||||
```jsx title="pages/index.jsx"
|
||||
import { useContract, useNFTs, ThirdwebNftMedia } from "@thirdweb-dev/react";
|
||||
|
||||
export default function Home() {
|
||||
const { contract } = useContract("<CONTRACT_ADDRESS>");
|
||||
const { data: nfts, isLoading: isReadingNfts } = useNFTs(contract);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2>My NFTs</h2>
|
||||
{isReadingNfts ? (
|
||||
<p>Loading...</p>
|
||||
) : (
|
||||
<button onClick={connectWithMetamask}>Connect Metamask Wallet</button>
|
||||
<div>
|
||||
{nfts.map((nft) => (
|
||||
<ThirdwebNftMedia
|
||||
key={nft.tokenId}
|
||||
metadata={nft.metadata}
|
||||
height={200}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Here, we use the `useMetamask` hook to handle metamask connection. When a user clicks the button, we'll call the `connectWithMetamask` function, which will prompt users to connect their metamask wallet.
|
||||
The [`Web3Button`](https://portal.thirdweb.com/sdk/ui-components/web3button) component ensures the user has connected their wallet and is currently configured to the same network as your smart contract before calling the function. It also has access to the `contract` directly, allowing you to perform any action on your smart contract when the button is clicked.
|
||||
|
||||
**Interact With Contracts**
|
||||
For example, we can mint an NFT like so:
|
||||
|
||||
The thirdweb React SDK also enables you to interact directly with contracts through simple hooks!
|
||||
```jsx title="pages/index.jsx"
|
||||
import {
|
||||
useContract,
|
||||
useNFTs,
|
||||
ThirdwebNftMedia,
|
||||
Web3Button,
|
||||
} from "@thirdweb-dev/react";
|
||||
|
||||
Let's setup a simple component to interact with an NFT Collection contract and get the data of all the NFTs on the contract.
|
||||
|
||||
```jsx title="NFTList.jsx"
|
||||
import { useMintNFT, useNFTCollection, useNFTs } from "@thirdweb-dev/react";
|
||||
|
||||
const NFTListComponent = () => {
|
||||
const address = useAddress();
|
||||
const nftCollection = useNFTCollection("<NFT-COLLECTION-CONTRACT-ADDRESS>");
|
||||
const { data: nfts } = useNFTs(nftCollection);
|
||||
const { mutate: mintNFT } = useMintNFT(nftCollection);
|
||||
|
||||
const mint = () => {
|
||||
mintNFT({
|
||||
to: address,
|
||||
metadata: {
|
||||
name: "Cool NFT",
|
||||
description: "Minted from react",
|
||||
},
|
||||
});
|
||||
};
|
||||
const contractAddress = "<CONTRACT_ADDRESS>";
|
||||
export default function Home() {
|
||||
const { contract } = useContract(contractAddress);
|
||||
const { data: nfts, isLoading: isReadingNfts } = useNFTs(contract);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button onClick={mint}>Mint</button>
|
||||
<ul>
|
||||
{nfts?.map((nft) => (
|
||||
<li key={nft.metadata.id.toString()}>{nft.metadata.name}</li>
|
||||
))}
|
||||
</ul>
|
||||
{/* ... Existing Display Logic here ... */}
|
||||
|
||||
<Web3Button
|
||||
contractAddress={contractAddress}
|
||||
action={(contract) =>
|
||||
contract.erc721.mint({
|
||||
name: "Hello world!",
|
||||
image:
|
||||
// You can use a file or URL here!
|
||||
"ipfs://QmZbovNXznTHpYn2oqgCFQYP4ZCpKDquenv5rFCX8irseo/0.png",
|
||||
})
|
||||
}
|
||||
>
|
||||
Mint NFT
|
||||
</Web3Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Here, we get an `NFT Collection` contract instance from the [TypeScript SDK](https://docs.thirdweb.com/typescript). We can then use all the methods on this thirdweb contract SDK instance - here we use the `mintTo` method to mint an NFT on the contract, and we use `useNFTList` to display all the NFTs in the collection on the page.
|
||||
|
||||
And that's all for the setup! Just like that, you can setup a `ThirdwebProvider` and use all the hooks of the SDK, allowing you to let users connect wallets, interact with contracts, and more!
|
||||
<br />
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
The `ThirdwebProvider` offers a number of configuration options to control the behavior of the React and Typescript SDK.
|
||||
|
||||
These all the configuration options of the `<ThirdwebProvider />`.
|
||||
These are all the configuration options of the `<ThirdwebProvider />`.
|
||||
We provide defaults for all of these, but you customize them to suit your needs.
|
||||
|
||||
```jsx title="App.jsx"
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"main": "dist/thirdweb-dev-react-evm.cjs.js",
|
||||
"module": "dist/thirdweb-dev-react-evm.esm.js"
|
||||
}
|
||||
@@ -1,28 +1,52 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react",
|
||||
"version": "3.0.1",
|
||||
"version": "3.1.1",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
"main": "dist/thirdweb-dev-react.cjs.js",
|
||||
"types": "dist/thirdweb-dev-react.cjs.d.ts",
|
||||
"module": "dist/thirdweb-dev-react.esm.js",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"module": "./dist/thirdweb-dev-react.esm.js",
|
||||
"default": "./dist/thirdweb-dev-react.cjs.js"
|
||||
},
|
||||
"./solana": {
|
||||
"module": "./solana/dist/thirdweb-dev-react-solana.esm.js",
|
||||
"default": "./solana/dist/thirdweb-dev-react-solana.cjs.js"
|
||||
},
|
||||
"./evm": {
|
||||
"module": "./evm/dist/thirdweb-dev-react-evm.esm.js",
|
||||
"default": "./evm/dist/thirdweb-dev-react-evm.cjs.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist/**/*",
|
||||
"patches/**/*"
|
||||
"dist/",
|
||||
"evm/",
|
||||
"solana/"
|
||||
],
|
||||
"preconstruct": {
|
||||
"entrypoints": [
|
||||
"index.ts",
|
||||
"solana/index.ts",
|
||||
"evm/index.ts"
|
||||
]
|
||||
},
|
||||
"private": false,
|
||||
"scripts": {
|
||||
"format": "prettier --write 'src/**/*'",
|
||||
"lint": "eslint src/",
|
||||
"fix": "eslint src/ --fix",
|
||||
"clean": "rm -rf dist/",
|
||||
"extract-api": "api-extractor run --local",
|
||||
"generate-docs": "api-extractor run --local && yarn api-documenter markdown -i ./temp -o ./docs && yarn generate-snippets",
|
||||
"generate:md-docs": "yarn api-documenter markdown -i ./temp -o ./docs",
|
||||
"generate-snippets": "node ./scripts/generate-snippets.mjs",
|
||||
"generate-snippets": "node ./scripts/generate-snippets.mjs && node ./scripts/generate-feature-snippets.mjs",
|
||||
"build": "tsc && preconstruct build",
|
||||
"e2e": "yarn test-ct",
|
||||
"test-ct": "playwright test -c playwright-ct.config.ts"
|
||||
"test-ct": "playwright test -c playwright-ct.config.ts",
|
||||
"push": "yalc push"
|
||||
},
|
||||
"sideEffects:": false,
|
||||
"devDependencies": {
|
||||
@@ -33,10 +57,15 @@
|
||||
"@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",
|
||||
"@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",
|
||||
"@thirdweb-dev/sdk": "*",
|
||||
"@thirdweb-dev/solana": "*",
|
||||
"@types/color": "^3.0.3",
|
||||
"@types/mime": "^3.0.1",
|
||||
"@types/react": "^18.0.5",
|
||||
@@ -63,7 +92,7 @@
|
||||
"@gnosis.pm/safe-ethers-lib": "1.1.0",
|
||||
"@react-icons/all-files": "^4.1.0",
|
||||
"@tanstack/react-query": "^4.0.10",
|
||||
"@zag-js/menu": "^0.1.11",
|
||||
"@zag-js/menu": "0.1.14",
|
||||
"@zag-js/react": "0.1.16",
|
||||
"color": "^4.2.3",
|
||||
"copy-to-clipboard": "^3.3.2",
|
||||
@@ -75,6 +104,10 @@
|
||||
"wagmi": "^0.2.28"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@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",
|
||||
"@thirdweb-dev/sdk": "*",
|
||||
"ethers": ">=5.5.1",
|
||||
"react": ">=18.0.0",
|
||||
@@ -83,5 +116,22 @@
|
||||
"resolutions": {
|
||||
"ansi-regex": "^6.0.1",
|
||||
"typescript": "^4.6.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@solana/wallet-adapter-base": {
|
||||
"optional": true
|
||||
},
|
||||
"@solana/wallet-adapter-react": {
|
||||
"optional": true
|
||||
},
|
||||
"@solana/wallet-adapter-wallets": {
|
||||
"optional": true
|
||||
},
|
||||
"@solana/web3.js": {
|
||||
"optional": true
|
||||
},
|
||||
"@thirdweb-dev/solana": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
import {
|
||||
TSDocParser,
|
||||
DocExcerpt,
|
||||
TSDocConfiguration,
|
||||
TSDocTagSyntaxKind,
|
||||
TSDocTagDefinition,
|
||||
} from "@microsoft/tsdoc";
|
||||
import fs from "fs";
|
||||
|
||||
/**
|
||||
* This is a simplistic solution until we implement proper DocNode rendering APIs.
|
||||
*/
|
||||
export class Formatter {
|
||||
static renderDocNode(docNode) {
|
||||
let result = "";
|
||||
if (docNode) {
|
||||
if (docNode instanceof DocExcerpt) {
|
||||
result += docNode.content.toString();
|
||||
}
|
||||
for (const childNode of docNode.getChildNodes()) {
|
||||
result += Formatter.renderDocNode(childNode);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static renderDocNodes(docNodes) {
|
||||
let result = "";
|
||||
for (const docNode of docNodes) {
|
||||
result += Formatter.renderDocNode(docNode);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
const config = new TSDocConfiguration();
|
||||
const tag = new TSDocTagDefinition({
|
||||
tagName: "@twfeature",
|
||||
allowMultiple: true,
|
||||
syntaxKind: TSDocTagSyntaxKind.BlockTag,
|
||||
});
|
||||
config.addTagDefinition(tag);
|
||||
config.setSupportForTag(tag, true);
|
||||
const tsdocParser = new TSDocParser(config);
|
||||
|
||||
const json = JSON.parse(
|
||||
fs.readFileSync(`${process.cwd()}/temp/react.api.json`, "utf8"),
|
||||
);
|
||||
|
||||
function languageNameToKey(languageName) {
|
||||
switch (languageName) {
|
||||
case "js":
|
||||
case "jsx":
|
||||
return "javascript";
|
||||
case "ts":
|
||||
case "tsx":
|
||||
return "tyepscript";
|
||||
default:
|
||||
return languageName;
|
||||
}
|
||||
}
|
||||
|
||||
// Get all the DetectableFeature classes
|
||||
const classes = json.members[0].members;
|
||||
const features = {};
|
||||
|
||||
function parseExampleTag(docComment) {
|
||||
const exampleBlocks = docComment._customBlocks.filter(
|
||||
(b) => b._blockTag._tagName === "@example",
|
||||
);
|
||||
|
||||
const examplesString = Formatter.renderDocNodes(exampleBlocks);
|
||||
|
||||
const regex = /```([a-zA-Z]*)\n([\S\s]*?)\n```/g;
|
||||
|
||||
let matches;
|
||||
|
||||
const examples = {};
|
||||
|
||||
while ((matches = regex.exec(examplesString)) !== null) {
|
||||
// This is necessary to avoid infinite loops with zero-width matches
|
||||
if (matches.index === regex.lastIndex) {
|
||||
regex.lastIndex++;
|
||||
}
|
||||
examples[languageNameToKey(matches[1])] = matches[2];
|
||||
}
|
||||
return examples;
|
||||
}
|
||||
|
||||
function parseTWFeatureTag(docComment) {
|
||||
const featureBlocks = docComment._customBlocks.filter(
|
||||
(b) => b._blockTag._tagName === "@twfeature",
|
||||
);
|
||||
|
||||
const featuresString = Formatter.renderDocNodes(featureBlocks);
|
||||
return featuresString.split(" | ").map((f) =>
|
||||
f
|
||||
.trim()
|
||||
.replace(/\\n/g, "")
|
||||
.replace("\n\n", "")
|
||||
.replace(/`/g, "")
|
||||
.replace(/@twfeature/g, ""),
|
||||
);
|
||||
}
|
||||
|
||||
const baseDocUrl = "https://docs.thirdweb.com/react/react.";
|
||||
|
||||
const extractReferenceLink = (m, kind, contractName) => {
|
||||
if (kind === "Property") {
|
||||
return m.excerptTokens
|
||||
.filter((e) => e.kind === "Reference")
|
||||
.map((e) => `${baseDocUrl}${e.text.toLowerCase()}`)[0];
|
||||
}
|
||||
if (kind === "Method") {
|
||||
return `${baseDocUrl}${contractName}.${m.name}`.toLowerCase();
|
||||
}
|
||||
return `${baseDocUrl}${m.name}`.toLowerCase();
|
||||
};
|
||||
|
||||
const parseMembers = (members, kind, contractName) => {
|
||||
if (!members) {
|
||||
return [];
|
||||
}
|
||||
|
||||
members = [members];
|
||||
|
||||
const validMembers = members.filter((m) => m.kind === kind);
|
||||
return validMembers
|
||||
.map((m) => {
|
||||
const parserContext = tsdocParser.parseString(m.docComment);
|
||||
const docComment = parserContext.docComment;
|
||||
const featureNames = parseTWFeatureTag(docComment);
|
||||
if (featureNames.length > 0) {
|
||||
for (const feature of featureNames) {
|
||||
const examples = parseExampleTag(docComment);
|
||||
if (Object.keys(examples).length > 0) {
|
||||
const example = {
|
||||
name: m.name,
|
||||
summary: Formatter.renderDocNode(docComment.summarySection),
|
||||
remarks: docComment.remarksBlock
|
||||
? Formatter.renderDocNode(docComment.remarksBlock.content)
|
||||
: null,
|
||||
examples,
|
||||
reference: {
|
||||
javascript: extractReferenceLink(m, kind, contractName),
|
||||
},
|
||||
};
|
||||
features[feature] = features[feature]
|
||||
? features[feature].concat(example)
|
||||
: [example];
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.filter((m) => !!m);
|
||||
};
|
||||
|
||||
classes.forEach((m) => {
|
||||
parseMembers(m, "Function", m.name);
|
||||
});
|
||||
|
||||
fs.writeFileSync(
|
||||
`${process.cwd()}/docs/feature_snippets.json`,
|
||||
JSON.stringify(features, null, 2),
|
||||
);
|
||||
@@ -115,13 +115,13 @@ const NETWORK_INFO_HOOKS = ["useChainId", "useNetwork", "useNetworkMismatch"];
|
||||
|
||||
const CUSTOM_CONTRACT_HOOKS = [
|
||||
"useContract",
|
||||
"useContractData",
|
||||
"useContractRead",
|
||||
"useContractWrite",
|
||||
"useAllContractEvents",
|
||||
"useContractEvents",
|
||||
"useContractType",
|
||||
"useContractPublishMetadata",
|
||||
"useContractMetadata",
|
||||
"useContractCall",
|
||||
];
|
||||
|
||||
const CONTRACT_SETTINGS_HOOKS = [
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"main": "dist/thirdweb-dev-react-solana.cjs.js",
|
||||
"module": "dist/thirdweb-dev-react-solana.esm.js"
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export function useIsMounted() {
|
||||
const [isMounted, setIsMounted] = useState(false);
|
||||
useEffect(() => {
|
||||
setIsMounted(true);
|
||||
}, []);
|
||||
return isMounted;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { useAddress } from "../../hooks/useAddress";
|
||||
import { useIsMounted } from "./useIsMounted";
|
||||
import { useMemo } from "react";
|
||||
|
||||
export function useMountedAddress() {
|
||||
const isMounted = useIsMounted();
|
||||
const address = useAddress();
|
||||
|
||||
return useMemo(() => {
|
||||
return isMounted ? address || null : null;
|
||||
}, [address, isMounted]);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { ComponentWithChildren } from "../types/component";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { useMemo } from "react";
|
||||
|
||||
export interface QueryClientProviderProps {
|
||||
queryClient?: QueryClient;
|
||||
}
|
||||
|
||||
export const QueryClientProviderWithDefault: ComponentWithChildren<
|
||||
QueryClientProviderProps
|
||||
> = ({ queryClient, children }) => {
|
||||
const queryClientWithDefault: QueryClient = useMemo(() => {
|
||||
return queryClient ? queryClient : new QueryClient();
|
||||
}, [queryClient]);
|
||||
|
||||
return (
|
||||
<QueryClientProvider client={queryClientWithDefault}>
|
||||
{children}
|
||||
</QueryClientProvider>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,68 @@
|
||||
import { RequiredParam } from "../types/shared";
|
||||
import { QueryKey } from "@tanstack/react-query";
|
||||
import type { ChainId } from "@thirdweb-dev/sdk";
|
||||
import type {
|
||||
Network,
|
||||
NFTCollection,
|
||||
NFTDrop,
|
||||
Token,
|
||||
} from "@thirdweb-dev/sdk/solana";
|
||||
|
||||
// we prefix all our query keys with this to avoid possible collisions with user-defined queries that share the same query client
|
||||
const TW_QUERY_KEY_PREFIX = "__tw__";
|
||||
// marker to make sure the query will not get stored in local storage by a query persister
|
||||
const NEVER_PERSIST_QUERY_POSTFIX = { persist: false } as const;
|
||||
|
||||
function ensureTWPrefix<TKey extends QueryKey>(key: TKey) {
|
||||
if (key[0] === TW_QUERY_KEY_PREFIX) {
|
||||
return key as unknown as Readonly<[typeof TW_QUERY_KEY_PREFIX, ...TKey]>;
|
||||
}
|
||||
return [TW_QUERY_KEY_PREFIX, ...key] as const;
|
||||
}
|
||||
|
||||
export function neverPersist<TKey extends QueryKey>(key: TKey) {
|
||||
return [...key, NEVER_PERSIST_QUERY_POSTFIX] as const;
|
||||
}
|
||||
|
||||
export function shouldNeverPersistQuery<TKey extends QueryKey>(
|
||||
key: TKey,
|
||||
): boolean {
|
||||
return key[key.length] === NEVER_PERSIST_QUERY_POSTFIX;
|
||||
}
|
||||
|
||||
// EVM
|
||||
|
||||
export function createEVMQueryKey<TKey extends QueryKey>(key: TKey) {
|
||||
return ensureTWPrefix(["evm", ...key] as const);
|
||||
}
|
||||
export function createEVMQueryKeyWithChain<TKey extends QueryKey>(
|
||||
key: TKey,
|
||||
chainId: RequiredParam<ChainId>,
|
||||
) {
|
||||
return ensureTWPrefix([chainId, ...key] as const);
|
||||
}
|
||||
|
||||
// SOL
|
||||
|
||||
export function createSOLQueryKey<TKey extends QueryKey>(key: TKey) {
|
||||
return ensureTWPrefix(["sol", ...key] as const);
|
||||
}
|
||||
|
||||
export function createSOLQueryKeyWithNetwork<TKey extends QueryKey>(
|
||||
key: TKey,
|
||||
network: RequiredParam<Network>,
|
||||
) {
|
||||
return createSOLQueryKey([network, ...key] as const);
|
||||
}
|
||||
|
||||
export function createSOLProgramQueryKey<TKey extends QueryKey>(
|
||||
program: RequiredParam<NFTCollection | NFTDrop | Token>,
|
||||
key: TKey = [] as unknown as TKey,
|
||||
) {
|
||||
const network = program?.network;
|
||||
const address = program?.publicKey.toBase58();
|
||||
return createSOLQueryKeyWithNetwork(
|
||||
["program", address, ...key] as const,
|
||||
network || null,
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import React from "react";
|
||||
|
||||
export type ComponentWithChildren<P = unknown> = React.FC<
|
||||
React.PropsWithChildren<P>
|
||||
>;
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Makes a parameter required to be passed, but still allowes it to be null or undefined.
|
||||
*
|
||||
* @beta
|
||||
*/
|
||||
export type RequiredParam<T> = T | null | undefined;
|
||||
+2
-1
@@ -1,5 +1,5 @@
|
||||
import { ConnectWallet } from ".";
|
||||
import { ThirdwebProvider } from "../..";
|
||||
import { ThirdwebProvider } from "../../providers/full";
|
||||
import { test, expect } from "@playwright/experimental-ct-react";
|
||||
|
||||
test.use({ viewport: { width: 500, height: 500 } });
|
||||
@@ -10,5 +10,6 @@ test("should render the connect wallet button", async ({ mount }) => {
|
||||
<ConnectWallet />
|
||||
</ThirdwebProvider>,
|
||||
);
|
||||
|
||||
await expect(component).toContainText("Connect Wallet");
|
||||
});
|
||||
+32
-29
@@ -1,16 +1,13 @@
|
||||
import { useThirdwebAuthConfig } from "../../contexts/thirdweb-auth";
|
||||
import { useBalance } from "../../hooks/async/wallet";
|
||||
import { LoginConfig, useAuth } from "../../hooks/auth";
|
||||
import { useMetamask } from "../../hooks/connectors/useMetamask";
|
||||
import { useAddress } from "../../hooks/useAddress";
|
||||
import { useChainId } from "../../hooks/useChainId";
|
||||
import { useConnect } from "../../hooks/useConnect";
|
||||
import { useDisconnect } from "../../hooks/useDisconnect";
|
||||
import { useNetwork } from "../../hooks/useNetwork";
|
||||
import { useConnect } from "../../hooks/wagmi-required/useConnect";
|
||||
import { useDisconnect } from "../../hooks/wagmi-required/useDisconnect";
|
||||
import { useNetwork } from "../../hooks/wagmi-required/useNetwork";
|
||||
import { useAddress, useBalance, useChainId } from "../../hooks/wallet";
|
||||
import { Portal } from "../../lib/portal";
|
||||
import { shortenIfAddress } from "../../utils/addresses";
|
||||
import { useClipboard } from "../hooks/useCopyClipboard";
|
||||
import { useIsMounted } from "../hooks/useIsMounted";
|
||||
import { Box } from "../shared/Box";
|
||||
import { Button } from "../shared/Button";
|
||||
import { Icon } from "../shared/Icon";
|
||||
@@ -30,8 +27,8 @@ import { FiXCircle } from "@react-icons/all-files/fi/FiXCircle";
|
||||
import { ChainId, LoginOptions, SUPPORTED_CHAIN_ID } from "@thirdweb-dev/sdk";
|
||||
import * as menu from "@zag-js/menu";
|
||||
import { normalizeProps, useMachine } from "@zag-js/react";
|
||||
import React, { useId, useMemo } from "react";
|
||||
import { Connector } from "wagmi";
|
||||
import React, { useId } from "react";
|
||||
import type { Connector } from "wagmi";
|
||||
|
||||
const SUPPORTED_CONNECTORS = [
|
||||
"injected",
|
||||
@@ -65,6 +62,7 @@ interface ConnectWalletProps extends ThemeProviderProps {
|
||||
loginConfig?: LoginConfig;
|
||||
loginOptional?: boolean;
|
||||
};
|
||||
className?: string;
|
||||
}
|
||||
|
||||
let connecting = false;
|
||||
@@ -124,15 +122,12 @@ const chainIdToCurrencyMap: Record<
|
||||
*/
|
||||
export const ConnectWallet: React.FC<ConnectWalletProps> = ({
|
||||
auth,
|
||||
className,
|
||||
...themeProps
|
||||
}) => {
|
||||
const id = useId();
|
||||
const isMounted = useIsMounted();
|
||||
const address = useAddress();
|
||||
|
||||
const mountedAddress = useMemo(() => {
|
||||
return isMounted ? address : null;
|
||||
}, [address, isMounted]);
|
||||
const walletAddress = useAddress();
|
||||
|
||||
const [state, send] = useMachine(
|
||||
menu.machine({
|
||||
@@ -165,24 +160,26 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = ({
|
||||
|
||||
const balanceQuery = useBalance();
|
||||
|
||||
const { onCopy, hasCopied } = useClipboard(mountedAddress || "");
|
||||
const { onCopy, hasCopied } = useClipboard(walletAddress || "");
|
||||
|
||||
const authConfig = useThirdwebAuthConfig();
|
||||
const { user, isLoading, login, logout } = useAuth(auth?.loginConfig);
|
||||
|
||||
const requiresSignIn = auth?.loginOptional
|
||||
? false
|
||||
: !!authConfig?.authUrl && !!mountedAddress && !user?.address;
|
||||
: !!authConfig?.authUrl && !!walletAddress && !user?.address;
|
||||
|
||||
return (
|
||||
<ThemeProvider {...themeProps}>
|
||||
<div
|
||||
style={{
|
||||
position: "relative",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
style={{ height: "50px", minWidth: "200px" }}
|
||||
className={className}
|
||||
style={{ height: "50px", minWidth: "200px", width: "100%" }}
|
||||
onClick={async (e) => {
|
||||
if (requiresSignIn) {
|
||||
e.preventDefault();
|
||||
@@ -204,7 +201,7 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = ({
|
||||
) : (
|
||||
<FiLock />
|
||||
)
|
||||
) : mountedAddress && chainId && chainId in chainIdToCurrencyMap ? (
|
||||
) : walletAddress && chainId && chainId in chainIdToCurrencyMap ? (
|
||||
<Icon
|
||||
boxSize="1.5em"
|
||||
name={chainIdToCurrencyMap[chainId as SUPPORTED_CHAIN_ID]}
|
||||
@@ -225,7 +222,7 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = ({
|
||||
)
|
||||
}
|
||||
>
|
||||
{mountedAddress ? (
|
||||
{walletAddress ? (
|
||||
requiresSignIn ? (
|
||||
<span style={{ whiteSpace: "nowrap" }}>Sign in</span>
|
||||
) : (
|
||||
@@ -249,7 +246,7 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = ({
|
||||
)}
|
||||
</span>
|
||||
<span style={{ fontSize: "0.9em" }}>
|
||||
{shortenIfAddress(mountedAddress)}
|
||||
{shortenIfAddress(walletAddress)}
|
||||
</span>
|
||||
</span>
|
||||
)
|
||||
@@ -267,7 +264,7 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = ({
|
||||
}}
|
||||
>
|
||||
<Menu {...api.contentProps}>
|
||||
{!api.isOpen ? null : mountedAddress ? (
|
||||
{!api.isOpen ? null : walletAddress ? (
|
||||
<>
|
||||
{authConfig?.authUrl && !user?.address && !requiresSignIn ? (
|
||||
<MenuItem
|
||||
@@ -396,10 +393,13 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = ({
|
||||
})}
|
||||
onClick={async () => {
|
||||
if (!connecting) {
|
||||
connecting = true;
|
||||
await connectWithMetamask();
|
||||
connecting = false;
|
||||
api.close();
|
||||
try {
|
||||
connecting = true;
|
||||
await connectWithMetamask();
|
||||
api.close();
|
||||
} finally {
|
||||
connecting = false;
|
||||
}
|
||||
}
|
||||
}}
|
||||
leftElement={<Icon boxSize="1.5em" name="metamask" />}
|
||||
@@ -421,10 +421,13 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = ({
|
||||
})}
|
||||
onClick={async () => {
|
||||
if (!connecting) {
|
||||
connecting = true;
|
||||
await connect(c);
|
||||
connecting = false;
|
||||
api.close();
|
||||
try {
|
||||
connecting = true;
|
||||
await connect(c);
|
||||
api.close();
|
||||
} finally {
|
||||
connecting = false;
|
||||
}
|
||||
}
|
||||
}}
|
||||
leftElement={getIconForConnector(c)}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { Web3Button } from ".";
|
||||
import { ThirdwebProvider } from "../..";
|
||||
import { ThirdwebProvider } from "../../providers/full";
|
||||
import { test, expect } from "@playwright/experimental-ct-react";
|
||||
|
||||
test.use({ viewport: { width: 500, height: 500 } });
|
||||
+26
-11
@@ -1,8 +1,8 @@
|
||||
import { useActiveChainId } from "../../Provider";
|
||||
import { useContract } from "../../hooks/async/contracts";
|
||||
import { useAddress } from "../../hooks/useAddress";
|
||||
import { useChainId } from "../../hooks/useChainId";
|
||||
import { useNetwork } from "../../hooks/useNetwork";
|
||||
import { useNetworkMismatch } from "../../hooks/useNetworkMismatch";
|
||||
import { useNetwork } from "../../hooks/wagmi-required/useNetwork";
|
||||
import { useAddress, useChainId } from "../../hooks/wallet";
|
||||
import { useSDKChainId } from "../../providers/base";
|
||||
import {
|
||||
createCacheKeyWithNetwork,
|
||||
createContractCacheKey,
|
||||
@@ -10,8 +10,9 @@ import {
|
||||
import { ConnectWallet } from "../ConnectWallet";
|
||||
import { Button } from "../shared/Button";
|
||||
import { ThemeProvider, ThemeProviderProps } from "../shared/ThemeProvider";
|
||||
import { FiWifi } from "@react-icons/all-files/fi/FiWifi";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import type { SmartContract } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/smart-contract";
|
||||
import type { SmartContract } from "@thirdweb-dev/sdk/dist/declarations/src/evm/contracts/smart-contract";
|
||||
import type { CallOverrides } from "ethers";
|
||||
import { PropsWithChildren, useMemo } from "react";
|
||||
import invariant from "tiny-invariant";
|
||||
@@ -20,6 +21,7 @@ type ActionFn = (contract: SmartContract) => any;
|
||||
|
||||
interface Web3ButtonProps<TActionFn extends ActionFn>
|
||||
extends ThemeProviderProps {
|
||||
className?: string;
|
||||
contractAddress: `0x${string}` | `${string}.eth` | string;
|
||||
|
||||
overrides?: CallOverrides;
|
||||
@@ -64,15 +66,18 @@ export const Web3Button = <TAction extends ActionFn>({
|
||||
isDisabled,
|
||||
children,
|
||||
action,
|
||||
className,
|
||||
...themeProps
|
||||
}: PropsWithChildren<Web3ButtonProps<TAction>>) => {
|
||||
const address = useAddress();
|
||||
const walletChainId = useChainId();
|
||||
const sdkChainId = useActiveChainId();
|
||||
const sdkChainId = useSDKChainId();
|
||||
const [, switchNetwork] = useNetwork();
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const hasMismatch = useNetworkMismatch();
|
||||
|
||||
const switchToChainId = useMemo(() => {
|
||||
if (sdkChainId && walletChainId && sdkChainId !== walletChainId) {
|
||||
return sdkChainId;
|
||||
@@ -87,7 +92,7 @@ export const Web3Button = <TAction extends ActionFn>({
|
||||
if (switchToChainId) {
|
||||
if (switchNetwork) {
|
||||
await switchNetwork(switchToChainId);
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
return "__NETWORK_SWITCHED__";
|
||||
} else {
|
||||
throw new Error(
|
||||
"need to switch chain but connected wallet does not support switching",
|
||||
@@ -99,10 +104,14 @@ export const Web3Button = <TAction extends ActionFn>({
|
||||
if (onSubmit) {
|
||||
onSubmit();
|
||||
}
|
||||
|
||||
return await action(contract);
|
||||
},
|
||||
{
|
||||
onSuccess: (res) => {
|
||||
if (res === "__NETWORK_SWITCHED__") {
|
||||
return;
|
||||
}
|
||||
if (onSuccess) {
|
||||
onSuccess(res);
|
||||
}
|
||||
@@ -122,18 +131,24 @@ export const Web3Button = <TAction extends ActionFn>({
|
||||
},
|
||||
);
|
||||
if (!address) {
|
||||
return <ConnectWallet {...themeProps} />;
|
||||
return <ConnectWallet className={className} {...themeProps} />;
|
||||
}
|
||||
|
||||
const willSwitchNetwork = hasMismatch && !!switchNetwork;
|
||||
|
||||
return (
|
||||
<ThemeProvider {...themeProps}>
|
||||
<Button
|
||||
style={{ height: "50px" }}
|
||||
className={className}
|
||||
style={{ height: "50px", minWidth: "200px", width: "100%" }}
|
||||
isLoading={mutation.isLoading || !contract}
|
||||
onClick={() => mutation.mutate()}
|
||||
isDisabled={isDisabled}
|
||||
isDisabled={willSwitchNetwork ? false : isDisabled}
|
||||
leftElement={
|
||||
willSwitchNetwork ? <FiWifi width="1em" height="1em" /> : undefined
|
||||
}
|
||||
>
|
||||
{children}
|
||||
{willSwitchNetwork ? "Switch Network" : children}
|
||||
</Button>
|
||||
</ThemeProvider>
|
||||
);
|
||||
@@ -0,0 +1,2 @@
|
||||
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
||||
export const __DEV__ = process.env.NODE_ENV !== "production";
|
||||
@@ -0,0 +1,86 @@
|
||||
import { __DEV__ } from "../constants/runtime";
|
||||
import { useThirdwebConfigContext } from "./thirdweb-config";
|
||||
import { UserWallet } from "@thirdweb-dev/sdk";
|
||||
import { Signer } from "ethers";
|
||||
import React, {
|
||||
PropsWithChildren,
|
||||
createContext,
|
||||
useContext,
|
||||
useState,
|
||||
useEffect,
|
||||
} from "react";
|
||||
|
||||
interface ThirdwebConnectedWalletContext {
|
||||
wallet: UserWallet | undefined;
|
||||
address: string | undefined;
|
||||
chainId: number | undefined;
|
||||
signer: Signer | undefined;
|
||||
}
|
||||
|
||||
const INITIAL_CONTEXT_VALUE: ThirdwebConnectedWalletContext = {
|
||||
wallet: undefined,
|
||||
address: undefined,
|
||||
chainId: undefined,
|
||||
signer: undefined,
|
||||
};
|
||||
|
||||
const ThirdwebConnectedWalletContext =
|
||||
createContext<ThirdwebConnectedWalletContext>(INITIAL_CONTEXT_VALUE);
|
||||
|
||||
export const ThirdwebConnectedWalletProvider: React.FC<
|
||||
PropsWithChildren<{ signer?: Signer }>
|
||||
> = ({ signer, children }) => {
|
||||
const { rpcUrlMap } = useThirdwebConfigContext();
|
||||
|
||||
const [contextValue, setContextValue] =
|
||||
useState<ThirdwebConnectedWalletContext>(INITIAL_CONTEXT_VALUE);
|
||||
|
||||
useEffect(() => {
|
||||
let s = signer;
|
||||
if (signer) {
|
||||
// just get both of these up front and keep them around with the context
|
||||
Promise.all([signer.getAddress(), signer.getChainId()])
|
||||
.then(([address, chainId]) => {
|
||||
const rpcUrl = rpcUrlMap[chainId];
|
||||
// only if the signer is still the same!
|
||||
if (signer === s) {
|
||||
const wallet = new UserWallet(signer, {
|
||||
readonlySettings: rpcUrl
|
||||
? {
|
||||
rpcUrl,
|
||||
chainId,
|
||||
}
|
||||
: undefined,
|
||||
});
|
||||
setContextValue({ wallet, address, chainId, signer });
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
if (__DEV__) {
|
||||
console.warn(
|
||||
"failed to get wallet instance in `<ThirdwebConnectedWalletProvider />`",
|
||||
err,
|
||||
);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// if signer is not provided, re-set the context value to initial values
|
||||
setContextValue(INITIAL_CONTEXT_VALUE);
|
||||
}
|
||||
return () => {
|
||||
// set the previous signer to undefined because it is invalid now
|
||||
s = undefined;
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [signer]);
|
||||
|
||||
return (
|
||||
<ThirdwebConnectedWalletContext.Provider value={contextValue}>
|
||||
{children}
|
||||
</ThirdwebConnectedWalletContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export function useThirdwebConnectedWalletContext() {
|
||||
return useContext(ThirdwebConnectedWalletContext);
|
||||
}
|
||||
+15
-17
@@ -1,10 +1,6 @@
|
||||
import { useActiveChainId } from "../../Provider";
|
||||
import {
|
||||
getErcs,
|
||||
DropContract,
|
||||
RequiredParam,
|
||||
WalletAddress,
|
||||
} from "../../types";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { useSDKChainId } from "../../providers/base";
|
||||
import { getErcs, DropContract, WalletAddress } from "../../types";
|
||||
import {
|
||||
cacheKeys,
|
||||
invalidateContractAndBalances,
|
||||
@@ -60,7 +56,7 @@ export type SetClaimConditionsParams = {
|
||||
* @param contract - an instance of a contract that extends the ERC721 or ERC1155 spec and implements the `claimConditions` extension.
|
||||
* @param tokenId - the id of the token to fetch the claim conditions for (if the contract is an ERC1155 contract)
|
||||
* @returns a response object with the currently active claim condition
|
||||
*
|
||||
* @twfeature ERC721ClaimableWithConditions | ERC1155ClaimableWithConditions | ERC20ClaimableWithConditions
|
||||
* @beta
|
||||
*/
|
||||
export function useActiveClaimCondition(
|
||||
@@ -83,7 +79,7 @@ export function useActiveClaimCondition(
|
||||
if (erc20) {
|
||||
return erc20.claimConditions.getActive();
|
||||
}
|
||||
return undefined;
|
||||
throw new Error("Contract must be ERC721, ERC1155 or ERC20");
|
||||
},
|
||||
{
|
||||
// Checks that happen here:
|
||||
@@ -113,7 +109,7 @@ export function useActiveClaimCondition(
|
||||
* @param contract - an instance of a contract that extends the ERC721 or ERC1155 spec and implements the `claimConditions` extension.
|
||||
* @param tokenId - the id of the token to fetch the claim conditions for (if the contract is an ERC1155 contract)
|
||||
* @returns a response object with the list of claim conditions
|
||||
*
|
||||
* @twfeature ERC721ClaimableWithConditions | ERC1155ClaimableWithConditions | ERC20ClaimableWithConditions
|
||||
* @beta
|
||||
*/
|
||||
export function useClaimConditions(
|
||||
@@ -136,7 +132,7 @@ export function useClaimConditions(
|
||||
if (erc20) {
|
||||
return erc20.claimConditions.getAll();
|
||||
}
|
||||
return undefined;
|
||||
throw new Error("Contract must be ERC721, ERC1155 or ERC20");
|
||||
},
|
||||
{
|
||||
// Checks that happen here:
|
||||
@@ -166,7 +162,7 @@ export function useClaimConditions(
|
||||
* @param eligibilityParams - the parameters for the eligibility check, see: {@link ClaimIneligibilityParams}
|
||||
* @param tokenId - the id of the token to fetch the claim conditions for (if the contract is an ERC1155 contract)
|
||||
* @returns a response object with the resons for the claim ineligibility
|
||||
*
|
||||
* @twfeature ERC721ClaimableWithConditions | ERC1155ClaimableWithConditions | ERC20ClaimableWithConditions
|
||||
* @beta
|
||||
*/
|
||||
export function useClaimIneligibilityReasons(
|
||||
@@ -207,7 +203,7 @@ export function useClaimIneligibilityReasons(
|
||||
params.walletAddress,
|
||||
);
|
||||
}
|
||||
return undefined;
|
||||
throw new Error("Contract must be ERC721, ERC1155 or ERC20");
|
||||
},
|
||||
{
|
||||
// Checks that happen here:
|
||||
@@ -257,13 +253,14 @@ export function useClaimIneligibilityReasons(
|
||||
*
|
||||
* @param contract - an instance of a {@link DropContract}
|
||||
* @returns a mutation object that can be used to set claim conditions
|
||||
* @twfeature ERC721ClaimableWithConditions | ERC1155ClaimableWithConditions | ERC20ClaimableWithConditions
|
||||
* @beta
|
||||
*/
|
||||
export function useSetClaimConditions(
|
||||
contract: RequiredParam<DropContract>,
|
||||
tokenId?: BigNumberish,
|
||||
) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
const { erc1155, erc721, erc20 } = getErcs(contract);
|
||||
@@ -283,7 +280,7 @@ export function useSetClaimConditions(
|
||||
if (erc20) {
|
||||
return erc20.claimConditions.set(phases, reset);
|
||||
}
|
||||
return undefined;
|
||||
throw new Error("Contract must be ERC721, ERC1155 or ERC20");
|
||||
},
|
||||
{
|
||||
onSettled: () => {
|
||||
@@ -327,13 +324,14 @@ export function useSetClaimConditions(
|
||||
*
|
||||
* @param contract - an instance of a {@link DropContract}
|
||||
* @returns a mutation object that can be used to reset claim conditions
|
||||
* @twfeature ERC721ClaimableWithConditions | ERC1155ClaimableWithConditions | ERC20ClaimableWithConditions
|
||||
* @beta
|
||||
*/
|
||||
export function useResetClaimConditions(
|
||||
contract: RequiredParam<DropContract>,
|
||||
tokenId?: BigNumberish,
|
||||
) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
const { erc1155, erc721, erc20 } = getErcs(contract);
|
||||
@@ -372,7 +370,7 @@ export function useResetClaimConditions(
|
||||
true,
|
||||
);
|
||||
}
|
||||
return undefined;
|
||||
throw new Error("Contract must be ERC721, ERC1155 or ERC20");
|
||||
},
|
||||
{
|
||||
onSettled: () => {
|
||||
+15
-6
@@ -1,5 +1,6 @@
|
||||
import { useActiveChainId } from "../../Provider";
|
||||
import { RequiredParam, WalletAddress } from "../../types";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { useSDKChainId } from "../../providers/base";
|
||||
import { WalletAddress } from "../../types";
|
||||
import {
|
||||
cacheKeys,
|
||||
invalidateContractAndBalances,
|
||||
@@ -24,6 +25,7 @@ import invariant from "tiny-invariant";
|
||||
* 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
|
||||
* @twfeature PrimarySale
|
||||
* @beta
|
||||
*/
|
||||
export function usePrimarySaleRecipient(
|
||||
@@ -73,6 +75,7 @@ export function usePrimarySaleRecipient(
|
||||
*
|
||||
* @param contract - an instance of a {@link SmartContract}
|
||||
* @returns a mutation object that can be used to update the primary sales recipient
|
||||
* @twfeature PrimarySale
|
||||
* @beta
|
||||
*/
|
||||
export function useUpdatePrimarySaleRecipient(
|
||||
@@ -80,7 +83,7 @@ export function useUpdatePrimarySaleRecipient(
|
||||
) {
|
||||
const queryClient = useQueryClient();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
return useMutation(
|
||||
(newRecipient: WalletAddress) => {
|
||||
invariant(contract, "No contract provided");
|
||||
@@ -115,6 +118,7 @@ export function useUpdatePrimarySaleRecipient(
|
||||
*
|
||||
* @param contract - an instance of a {@link SmartContract}
|
||||
* @returns an object containing recipient address and the royalty basis points
|
||||
* @twfeature Royalty
|
||||
* @beta
|
||||
*/
|
||||
export function useRoyaltySettings(
|
||||
@@ -164,6 +168,7 @@ export function useRoyaltySettings(
|
||||
*
|
||||
* @param contract - an instance of a {@link SmartContract}
|
||||
* @returns a mutation object that can be used to update the royalty settings
|
||||
* @twfeature Royalty
|
||||
* @beta
|
||||
*/
|
||||
export function useUpdateRoyaltySettings(
|
||||
@@ -171,7 +176,7 @@ export function useUpdateRoyaltySettings(
|
||||
) {
|
||||
const queryClient = useQueryClient();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
return useMutation(
|
||||
(updatePayload: {
|
||||
seller_fee_basis_points?: number;
|
||||
@@ -209,6 +214,7 @@ export function useUpdateRoyaltySettings(
|
||||
*
|
||||
* @param contract - an instance of a {@link SmartContract}
|
||||
* @returns an object containing the platform fee basis points and the fee recipient address
|
||||
* @twfeature PlatformFee
|
||||
* @beta
|
||||
*/
|
||||
export function usePlatformFees(
|
||||
@@ -257,6 +263,7 @@ export function usePlatformFees(
|
||||
* ```
|
||||
* @param contract - an instance of a {@link SmartContract}
|
||||
* @returns a mutation object that can be used to update the platform fees settings
|
||||
* @twfeature PlatformFee
|
||||
* @beta
|
||||
*/
|
||||
export function useUpdatePlatformFees(
|
||||
@@ -264,7 +271,7 @@ export function useUpdatePlatformFees(
|
||||
) {
|
||||
const queryClient = useQueryClient();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
return useMutation(
|
||||
(updatePayload: {
|
||||
platform_fee_basis_points?: number;
|
||||
@@ -302,6 +309,7 @@ export function useUpdatePlatformFees(
|
||||
*
|
||||
* @param contract - an instance of a {@link SmartContract}
|
||||
* @returns a {@link CustomContractMetadata} object containing the metadata
|
||||
* @twfeature ContractMetadata
|
||||
* @beta
|
||||
*/
|
||||
export function useMetadata(contract: RequiredParam<ValidContractInstance>) {
|
||||
@@ -347,6 +355,7 @@ export function useMetadata(contract: RequiredParam<ValidContractInstance>) {
|
||||
* ```
|
||||
* @param contract - an instance of a {@link SmartContract}
|
||||
* @returns a mutation object that can be used to update the metadata
|
||||
* @twfeature ContractMetadata
|
||||
* @beta
|
||||
*/
|
||||
export function useUpdateMetadata(
|
||||
@@ -354,7 +363,7 @@ export function useUpdateMetadata(
|
||||
) {
|
||||
const queryClient = useQueryClient();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
return useMutation(
|
||||
(updatePayload: CustomContractMetadata) => {
|
||||
invariant(contract, "No contract provided");
|
||||
+20
-14
@@ -1,13 +1,14 @@
|
||||
import { useActiveChainId, useSDK } from "../../Provider";
|
||||
import { ContractAddress, RequiredParam } from "../../types";
|
||||
import { neverPersist } from "../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { useSDK, useSDKChainId } from "../../providers/base";
|
||||
import { ContractAddress } from "../../types";
|
||||
import {
|
||||
cacheKeys,
|
||||
createCacheKeyWithNetwork,
|
||||
createContractCacheKey,
|
||||
} from "../../utils/cache-keys";
|
||||
import { useQueryWithNetwork } from "../query-utils/useQueryWithNetwork";
|
||||
import { useAddress } from "../useAddress";
|
||||
import { useChainId } from "../useChainId";
|
||||
import { useAddress, useChainId } from "../wallet";
|
||||
import {
|
||||
useMutation,
|
||||
useQuery,
|
||||
@@ -22,7 +23,7 @@ import {
|
||||
ThirdwebSDK,
|
||||
ValidContractInstance,
|
||||
} from "@thirdweb-dev/sdk";
|
||||
import type { SmartContract } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/smart-contract";
|
||||
import type { SmartContract } from "@thirdweb-dev/sdk/dist/declarations/src/evm/contracts/smart-contract";
|
||||
import { CallOverrides } from "ethers";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import invariant from "tiny-invariant";
|
||||
@@ -151,7 +152,7 @@ export function useContract<
|
||||
>(contractAddress: RequiredParam<ContractAddress>) {
|
||||
const sdk = useSDK();
|
||||
const queryClient = useQueryClient();
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const wallet = useAddress();
|
||||
const walletChainId = useChainId();
|
||||
|
||||
@@ -160,11 +161,11 @@ export function useContract<
|
||||
|
||||
const contractQuery = useQueryWithNetwork(
|
||||
// need to add the wallet and walletChainId into the query key so this gets refreshed when the wallet / chain changes!
|
||||
[
|
||||
neverPersist([
|
||||
"contract-instance",
|
||||
contractAddress,
|
||||
{ wallet, walletChainId, sdkTimestamp },
|
||||
],
|
||||
]),
|
||||
async () => {
|
||||
invariant(contractAddress, "contract address is required");
|
||||
invariant(sdk, "SDK not initialized");
|
||||
@@ -223,12 +224,17 @@ export function useContract<
|
||||
*
|
||||
* @param contract - the {@link ValidContractInstance} instance of the contract to get the metadata for
|
||||
* @returns a response object that includes the contract metadata of the deployed contract
|
||||
* @twfeature ContractMetadata
|
||||
* @beta
|
||||
*/
|
||||
export function useContractMetadata(
|
||||
contract: RequiredParam<ValidContractInstance>,
|
||||
export function useContractMetadata<TContract extends ValidContractInstance>(
|
||||
contract: RequiredParam<TContract>,
|
||||
) {
|
||||
return useQueryWithNetwork(
|
||||
return useQueryWithNetwork<
|
||||
typeof contract extends undefined
|
||||
? undefined
|
||||
: Awaited<ReturnType<TContract["metadata"]["get"]>>
|
||||
>(
|
||||
cacheKeys.contract.metadata(contract?.getAddress()),
|
||||
async () => {
|
||||
invariant(contract, "contract is required");
|
||||
@@ -246,7 +252,7 @@ export function useContractMetadata(
|
||||
export function useContractMetadataUpdate(
|
||||
contract: RequiredParam<ValidContractInstance>,
|
||||
) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -291,7 +297,7 @@ export function useContractEvents(
|
||||
const contractAddress = contract?.getAddress();
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
|
||||
const cacheKey = useMemo(
|
||||
() =>
|
||||
@@ -420,7 +426,7 @@ export function useContractWrite(
|
||||
contract: RequiredParam<ValidContractInstance>,
|
||||
functionName: RequiredParam<string>,
|
||||
) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
+19
-8
@@ -1,10 +1,10 @@
|
||||
import { useActiveChainId } from "../../Provider";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { useSDKChainId } from "../../providers/base";
|
||||
import {
|
||||
ClaimNFTParams,
|
||||
ClaimNFTReturnType,
|
||||
DelayedRevealLazyMintInput,
|
||||
DropContract,
|
||||
RequiredParam,
|
||||
RevealLazyMintInput,
|
||||
getErcs,
|
||||
NFTContract,
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
QueryAllParams,
|
||||
UploadProgressEvent,
|
||||
} from "@thirdweb-dev/sdk";
|
||||
import { NFTDropImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/nft-drop";
|
||||
import { NFTDrop } from "@thirdweb-dev/sdk/dist/declarations/src/evm/contracts/prebuilt-implementations/nft-drop";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
/** **********************/
|
||||
@@ -40,10 +40,11 @@ import invariant from "tiny-invariant";
|
||||
* @param contract - an instance of a contract that extends the Erc721 spec (nft drop, custom contract that follows the Erc721 & drop spec)
|
||||
* @param queryParams - query params to pass to the query for the sake of pagination
|
||||
* @returns a response object that includes an array of NFTs that are unclaimed
|
||||
* @twfeature ERC721LazyMintable | ERC1155LazyMintable
|
||||
* @beta
|
||||
*/
|
||||
export function useUnclaimedNFTs(
|
||||
contract: RequiredParam<NFTDropImpl>,
|
||||
contract: RequiredParam<NFTDrop>,
|
||||
queryParams?: QueryAllParams,
|
||||
) {
|
||||
const contractAddress = contract?.getAddress();
|
||||
@@ -75,6 +76,7 @@ export function useUnclaimedNFTs(
|
||||
* @param contract - an instance of a {@link DropContract}
|
||||
* @param queryParams - query params to pass to the query for the sake of pagination
|
||||
* @returns a response object that includes an array of NFTs that are claimed
|
||||
* @twfeature ERC721LazyMintable | ERC1155LazyMintable
|
||||
* @beta
|
||||
*/
|
||||
export function useClaimedNFTs(
|
||||
@@ -83,10 +85,12 @@ export function useClaimedNFTs(
|
||||
) {
|
||||
return useNFTs(contract, queryParams);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param contract - an instance of a {@link NFTDrop}
|
||||
* @returns a response object that includes the number of NFTs that are unclaimed
|
||||
* @twfeature ERC721LazyMintable | ERC1155LazyMintable
|
||||
*/
|
||||
export function useUnclaimedNFTSupply(contract: RequiredParam<DropContract>) {
|
||||
const contractAddress = contract?.getAddress();
|
||||
@@ -106,9 +110,11 @@ export function useUnclaimedNFTSupply(contract: RequiredParam<DropContract>) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
*
|
||||
* @param contract - an instance of a {@link DropContract}
|
||||
* @returns a response object that includes the number of NFTs that are claimed
|
||||
* @twfeature ERC721LazyMintable | ERC1155LazyMintable
|
||||
*/
|
||||
export function useClaimedNFTSupply(contract: RequiredParam<DropContract>) {
|
||||
const contractAddress = contract?.getAddress();
|
||||
@@ -131,6 +137,7 @@ export function useClaimedNFTSupply(contract: RequiredParam<DropContract>) {
|
||||
*
|
||||
* @param contract - an instance of a {@link RevealableContract}
|
||||
* @returns a response object that gets the batches to still be revealed
|
||||
* @twfeature ERC721Revealable | ERC1155Revealable
|
||||
*/
|
||||
export function useBatchesToReveal<TContract extends RevealableContract>(
|
||||
contract: RequiredParam<TContract>,
|
||||
@@ -185,12 +192,13 @@ export function useBatchesToReveal<TContract extends RevealableContract>(
|
||||
*
|
||||
* @param contract - an instance of a {@link DropContract}
|
||||
* @returns a mutation object that can be used to claim a NFT to the wallet specificed in the params
|
||||
* @twfeature ERC721Claimable | ERC1155Claimable
|
||||
* @beta
|
||||
*/
|
||||
export function useClaimNFT<TContract extends DropContract>(
|
||||
contract: RequiredParam<TContract>,
|
||||
) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -236,13 +244,14 @@ export function useClaimNFT<TContract extends DropContract>(
|
||||
* @param contract - an instance of a {@link NFTContract} with the drop extension
|
||||
* @param onProgress - an optional callback that will be called with the progress of the upload
|
||||
* @returns a mutation object that can be used to lazy mint a batch of NFTs
|
||||
* @twfeature ERC721LazyMintable | ERC1155LazyMintable
|
||||
* @beta
|
||||
*/
|
||||
export function useLazyMint<TContract extends DropContract>(
|
||||
contract: RequiredParam<TContract>,
|
||||
onProgress?: (progress: UploadProgressEvent) => void,
|
||||
) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
const { erc721, erc1155 } = getErcs(contract);
|
||||
@@ -282,13 +291,14 @@ export function useLazyMint<TContract extends DropContract>(
|
||||
* @param contract - an instance of a {@link DropContract}
|
||||
* @param onProgress - an optional callback that will be called with the progress of the upload
|
||||
* @returns a mutation object that can be used to lazy mint a batch of NFTs
|
||||
* @twfeature ERC721Revealable | ERC1155Revealable
|
||||
* @beta
|
||||
*/
|
||||
export function useDelayedRevealLazyMint<TContract extends RevealableContract>(
|
||||
contract: RequiredParam<TContract>,
|
||||
onProgress?: (progress: UploadProgressEvent) => void,
|
||||
) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -336,12 +346,13 @@ export function useDelayedRevealLazyMint<TContract extends RevealableContract>(
|
||||
*
|
||||
* @param contract - an instance of a {@link RevealableContract}
|
||||
* @returns a mutation object that can be used to reveal a batch of delayed reveal NFTs
|
||||
* @twfeature ERC721Revealable | ERC1155Revealable
|
||||
* @beta
|
||||
*/
|
||||
export function useRevealLazyMint<TContract extends RevealableContract>(
|
||||
contract: RequiredParam<TContract>,
|
||||
) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
+22
-25
@@ -1,11 +1,12 @@
|
||||
import { useActiveChainId } from "../../Provider";
|
||||
import { BuyNowParams, MakeBidParams, RequiredParam } from "../../types";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { useSDKChainId } from "../../providers/base";
|
||||
import { BuyNowParams, MakeBidParams } from "../../types";
|
||||
import {
|
||||
cacheKeys,
|
||||
invalidateContractAndBalances,
|
||||
} from "../../utils/cache-keys";
|
||||
import { useQueryWithNetwork } from "../query-utils/useQueryWithNetwork";
|
||||
import { useAddress } from "../useAddress";
|
||||
import { useAddress } from "../wallet";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import type {
|
||||
AuctionListing,
|
||||
@@ -15,7 +16,7 @@ import type {
|
||||
NewDirectListing,
|
||||
} from "@thirdweb-dev/sdk";
|
||||
import { ListingType } from "@thirdweb-dev/sdk";
|
||||
import { MarketplaceImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/marketplace";
|
||||
import { Marketplace } from "@thirdweb-dev/sdk/dist/declarations/src/evm/contracts/prebuilt-implementations/marketplace";
|
||||
import { BigNumber, BigNumberish } from "ethers";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
@@ -37,7 +38,7 @@ import invariant from "tiny-invariant";
|
||||
* @beta
|
||||
*/
|
||||
export function useListing(
|
||||
contract: RequiredParam<MarketplaceImpl>,
|
||||
contract: RequiredParam<Marketplace>,
|
||||
listingId: RequiredParam<BigNumberish>,
|
||||
) {
|
||||
const contractAddress = contract?.getAddress();
|
||||
@@ -68,7 +69,7 @@ export function useListing(
|
||||
* @beta
|
||||
*/
|
||||
export function useListings(
|
||||
contract: RequiredParam<MarketplaceImpl>,
|
||||
contract: RequiredParam<Marketplace>,
|
||||
filter?: MarketplaceFilter,
|
||||
) {
|
||||
const contractAddress = contract?.getAddress();
|
||||
@@ -97,7 +98,7 @@ export function useListings(
|
||||
* @returns a response object that includes an array of listings
|
||||
* @beta
|
||||
*/
|
||||
export function useListingsCount(contract: RequiredParam<MarketplaceImpl>) {
|
||||
export function useListingsCount(contract: RequiredParam<Marketplace>) {
|
||||
const contractAddress = contract?.getAddress();
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.marketplace.getTotalCount(contractAddress),
|
||||
@@ -125,7 +126,7 @@ export function useListingsCount(contract: RequiredParam<MarketplaceImpl>) {
|
||||
* @beta
|
||||
*/
|
||||
export function useActiveListings(
|
||||
contract: RequiredParam<MarketplaceImpl>,
|
||||
contract: RequiredParam<Marketplace>,
|
||||
filter?: MarketplaceFilter,
|
||||
) {
|
||||
const contractAddress = contract?.getAddress();
|
||||
@@ -157,7 +158,7 @@ export function useActiveListings(
|
||||
* @beta
|
||||
*/
|
||||
export function useWinningBid(
|
||||
contract: RequiredParam<MarketplaceImpl>,
|
||||
contract: RequiredParam<Marketplace>,
|
||||
listingId: RequiredParam<BigNumberish>,
|
||||
) {
|
||||
const contractAddress = contract?.getAddress();
|
||||
@@ -190,7 +191,7 @@ export function useWinningBid(
|
||||
* @beta
|
||||
*/
|
||||
export function useAuctionWinner(
|
||||
contract: RequiredParam<MarketplaceImpl>,
|
||||
contract: RequiredParam<Marketplace>,
|
||||
listingId: RequiredParam<BigNumberish>,
|
||||
) {
|
||||
const contractAddress = contract?.getAddress();
|
||||
@@ -232,7 +233,7 @@ export function useAuctionWinner(
|
||||
* @returns a response object that includes an array of listings
|
||||
* @beta
|
||||
*/
|
||||
export function useBidBuffer(contract: RequiredParam<MarketplaceImpl>) {
|
||||
export function useBidBuffer(contract: RequiredParam<Marketplace>) {
|
||||
const contractAddress = contract?.getAddress();
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.marketplace.getBidBufferBps(contractAddress),
|
||||
@@ -281,10 +282,8 @@ export function useBidBuffer(contract: RequiredParam<MarketplaceImpl>) {
|
||||
* @returns a mutation object that can be used to create a new direct listing
|
||||
* @beta
|
||||
*/
|
||||
export function useCreateDirectListing(
|
||||
contract: RequiredParam<MarketplaceImpl>,
|
||||
) {
|
||||
const activeChainId = useActiveChainId();
|
||||
export function useCreateDirectListing(contract: RequiredParam<Marketplace>) {
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
const walletAddress = useAddress();
|
||||
@@ -339,10 +338,8 @@ export function useCreateDirectListing(
|
||||
* @returns a mutation object that can be used to create a new auction listing
|
||||
* @beta
|
||||
*/
|
||||
export function useCreateAuctionListing(
|
||||
contract: RequiredParam<MarketplaceImpl>,
|
||||
) {
|
||||
const activeChainId = useActiveChainId();
|
||||
export function useCreateAuctionListing(contract: RequiredParam<Marketplace>) {
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
const walletAddress = useAddress();
|
||||
@@ -397,8 +394,8 @@ export function useCreateAuctionListing(
|
||||
* @returns a mutation object that can be used to create a new auction listing
|
||||
* @beta
|
||||
*/
|
||||
export function useCancelListing(contract: RequiredParam<MarketplaceImpl>) {
|
||||
const activeChainId = useActiveChainId();
|
||||
export function useCancelListing(contract: RequiredParam<Marketplace>) {
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation(
|
||||
@@ -451,8 +448,8 @@ export function useCancelListing(contract: RequiredParam<MarketplaceImpl>) {
|
||||
* @returns a mutation object that can be used to make a bid on an auction listing
|
||||
* @beta
|
||||
*/
|
||||
export function useMakeBid(contract: RequiredParam<MarketplaceImpl>) {
|
||||
const activeChainId = useActiveChainId();
|
||||
export function useMakeBid(contract: RequiredParam<Marketplace>) {
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
const walletAddress = useAddress();
|
||||
@@ -507,8 +504,8 @@ export function useMakeBid(contract: RequiredParam<MarketplaceImpl>) {
|
||||
* @returns a mutation object that can be used to buy out an auction listing
|
||||
* @beta
|
||||
*/
|
||||
export function useBuyNow(contract: RequiredParam<MarketplaceImpl>) {
|
||||
const activeChainId = useActiveChainId();
|
||||
export function useBuyNow(contract: RequiredParam<Marketplace>) {
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
const walletAddress = useAddress();
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useActiveChainId } from "../../Provider";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { useSDKChainId } from "../../providers/base";
|
||||
import {
|
||||
AirdropNFTParams,
|
||||
BurnNFTParams,
|
||||
@@ -6,7 +7,6 @@ import {
|
||||
MintNFTReturnType,
|
||||
MintNFTSupplyParams,
|
||||
NFT,
|
||||
RequiredParam,
|
||||
TransferNFTParams,
|
||||
WalletAddress,
|
||||
Erc721OrErc1155,
|
||||
@@ -75,6 +75,7 @@ export function convertResponseToNFTTypeArray(
|
||||
* @param tokenId - the tokenId to look up
|
||||
* @returns a response object that includes the metadata for the given tokenId
|
||||
* @beta
|
||||
* @twfeature ERC721 | ERC1155
|
||||
*/
|
||||
export function useNFT<TContract extends NFTContract>(
|
||||
contract: RequiredParam<TContract>,
|
||||
@@ -122,6 +123,7 @@ export function useNFT<TContract extends NFTContract>(
|
||||
* @param contract - an instance of a {@link NFTContract}
|
||||
* @param queryParams - query params to pass to the query for the sake of pagination
|
||||
* @returns a response object that includes an array of NFTs
|
||||
* @twfeature ERC721Supply | ERC1155Enumerable
|
||||
* @beta
|
||||
*/
|
||||
export function useNFTs<TContract extends NFTContract>(
|
||||
@@ -170,6 +172,7 @@ export function useNFTs<TContract extends NFTContract>(
|
||||
* @param contract - an instance of a {@link NFTContract}
|
||||
* @returns a response object that includes the total count of NFTs
|
||||
* @beta
|
||||
* @twfeature ERC721Supply | ERC1155Enumerable
|
||||
*/
|
||||
export function useTotalCount<TContract extends NFTContract>(
|
||||
contract: RequiredParam<TContract>,
|
||||
@@ -216,10 +219,11 @@ export function useTotalCount<TContract extends NFTContract>(
|
||||
* @param contract - an instance of a {@link NFTContract}
|
||||
* @returns a response object that incudes the total minted supply
|
||||
* @beta
|
||||
* @twfeature ERC721Supply | ERC1155Enumerable
|
||||
*/
|
||||
export function useTotalCirculatingSupply(
|
||||
contract: RequiredParam<NFTContract>,
|
||||
tokenId: BigNumberish,
|
||||
tokenId: RequiredParam<BigNumberish>,
|
||||
) {
|
||||
const contractAddress = contract?.getAddress();
|
||||
const { erc721, erc1155 } = getErcs(contract);
|
||||
@@ -234,6 +238,7 @@ export function useTotalCirculatingSupply(
|
||||
erc1155.totalCirculatingSupply,
|
||||
"Contract instance does not support totalCirculatingSupply",
|
||||
);
|
||||
invariant(tokenId, "No tokenId provided");
|
||||
return await erc1155.totalCirculatingSupply(tokenId);
|
||||
}
|
||||
if (erc721) {
|
||||
@@ -246,7 +251,7 @@ export function useTotalCirculatingSupply(
|
||||
invariant(false, "Unknown NFT type");
|
||||
},
|
||||
{
|
||||
enabled: !!erc721 || !!erc1155,
|
||||
enabled: !!erc721 || (!!erc1155 && tokenId !== undefined),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -264,6 +269,7 @@ export function useTotalCirculatingSupply(
|
||||
* @param ownerWalletAddress - the wallet adress to get owned tokens for
|
||||
* @returns a response object that includes the list of owned tokens
|
||||
* @beta
|
||||
* @twfeature ERC721Enumerable | ERC1155Enumerable
|
||||
*/
|
||||
export function useOwnedNFTs<TContract extends NFTContract>(
|
||||
contract: RequiredParam<TContract>,
|
||||
@@ -276,6 +282,7 @@ export function useOwnedNFTs<TContract extends NFTContract>(
|
||||
cacheKeys.contract.nft.query.owned.all(contractAddress, ownerWalletAddress),
|
||||
async () => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
invariant(ownerWalletAddress, "No wallet address provided");
|
||||
if (erc721) {
|
||||
return convertResponseToNFTTypeArray(
|
||||
erc721,
|
||||
@@ -308,6 +315,7 @@ export function useOwnedNFTs<TContract extends NFTContract>(
|
||||
* @param contract - an instance of a {@link NFTContract}
|
||||
* @param ownerWalletAddress - the wallet adress to check the balance of
|
||||
* @returns a response object that includes the total balance of the owner
|
||||
* @twfeature ERC721 | ERC1155
|
||||
* @beta
|
||||
*/
|
||||
export function useNFTBalance(
|
||||
@@ -409,11 +417,12 @@ export function useNFTBalance(
|
||||
* @param contract - an instance of a {@link NFTContract}
|
||||
* @returns a mutation object that can be used to mint a new NFT token to the connected wallet
|
||||
* @beta
|
||||
* @twfeature ERC721Mintable | ERC1155Mintable
|
||||
*/
|
||||
export function useMintNFT<TContract extends NFTContract>(
|
||||
contract: RequiredParam<TContract>,
|
||||
) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
const { erc1155, erc721 } = getErcs(contract);
|
||||
@@ -480,9 +489,10 @@ export function useMintNFT<TContract extends NFTContract>(
|
||||
* @param contract - an instance of a {@link Erc1155}
|
||||
* @returns a mutation object that can be used to mint a more supply of a token id to the provided wallet
|
||||
* @beta
|
||||
* @twfeature ERC1155Mintable
|
||||
*/
|
||||
export function useMintNFTSupply(contract: Erc1155) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -542,11 +552,12 @@ export function useMintNFTSupply(contract: Erc1155) {
|
||||
* @param contract - an instance of a {@link NFTContract}
|
||||
* @returns a mutation object that can be used to transfer NFTs
|
||||
* @beta
|
||||
* @twfeature ERC721 | ERC1155
|
||||
*/
|
||||
export function useTransferNFT<TContract extends NFTContract>(
|
||||
contract: RequiredParam<TContract>,
|
||||
) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
const { erc1155, erc721 } = getErcs(contract);
|
||||
@@ -636,10 +647,11 @@ export function useTransferNFT<TContract extends NFTContract>(
|
||||
*
|
||||
* @param contract - an instance of a {@link Erc1155}
|
||||
* @returns a mutation object that can be used to transfer batch NFTs
|
||||
* @twfeature ERC1155
|
||||
* @beta
|
||||
*/
|
||||
export function useAirdropNFT(contract: Erc1155) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -718,12 +730,13 @@ export function useAirdropNFT(contract: Erc1155) {
|
||||
*
|
||||
* @param contract - an instance of a {@link NFTContract}
|
||||
* @returns a mutation object that can be used to burn an NFT token from the connected wallet
|
||||
* @twfeature ERC721Burnable | ERC1155Burnable
|
||||
* @beta
|
||||
*/
|
||||
export function useBurnNFT<TContract extends NFTContract>(
|
||||
contract: RequiredParam<TContract>,
|
||||
) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
const { erc1155, erc721 } = getErcs(contract);
|
||||
+15
-8
@@ -1,5 +1,6 @@
|
||||
import { useActiveChainId } from "../../Provider";
|
||||
import { RequiredParam, WalletAddress } from "../../types";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { useSDKChainId } from "../../providers/base";
|
||||
import { WalletAddress } from "../../types";
|
||||
import {
|
||||
cacheKeys,
|
||||
invalidateContractAndBalances,
|
||||
@@ -7,8 +8,8 @@ import {
|
||||
import { useQueryWithNetwork } from "../query-utils/useQueryWithNetwork";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import type { Role, ValidContractInstance } from "@thirdweb-dev/sdk";
|
||||
import type { VoteImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/vote";
|
||||
import type { SmartContract } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/smart-contract";
|
||||
import type { Vote } from "@thirdweb-dev/sdk/dist/declarations/src/evm/contracts/prebuilt-implementations/vote";
|
||||
import type { SmartContract } from "@thirdweb-dev/sdk/dist/declarations/src/evm/contracts/smart-contract";
|
||||
import { constants } from "ethers";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
@@ -19,7 +20,7 @@ import invariant from "tiny-invariant";
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export type ContractWithRoles = Exclude<ValidContractInstance, VoteImpl>;
|
||||
export type ContractWithRoles = Exclude<ValidContractInstance, Vote>;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@@ -50,6 +51,7 @@ type GetAllReturnType<TContract extends ContractWithRoles> = Promise<
|
||||
*
|
||||
* @param contract - an instance of a {@link SmartContract}
|
||||
* @returns a list of addresses for all supported roles on the contract.
|
||||
* @twfeature PermissionsEnumerable
|
||||
* @beta
|
||||
*/
|
||||
export function useAllRoleMembers<TContract extends ContractWithRoles>(
|
||||
@@ -81,6 +83,7 @@ export function useAllRoleMembers<TContract extends ContractWithRoles>(
|
||||
* @param contract - an instance of a {@link SmartContract}
|
||||
* @param role - the role to get the members of, see {@link Role}
|
||||
* @returns a list of addresses that are members of the role
|
||||
* @twfeature PermissionsEnumerable
|
||||
* @beta
|
||||
*/
|
||||
export function useRoleMembers<TContract extends ContractWithRoles>(
|
||||
@@ -113,6 +116,7 @@ export function useRoleMembers<TContract extends ContractWithRoles>(
|
||||
* @param role - the role to check the member against, see {@link Role}
|
||||
* @param walletAddress - the address to check
|
||||
* @returns true if the address is a member of the role, or false if not
|
||||
* @twfeature Permissions
|
||||
* @beta
|
||||
*/
|
||||
export function useIsAddressRole<TContract extends ContractWithRoles>(
|
||||
@@ -174,12 +178,13 @@ export function useIsAddressRole<TContract extends ContractWithRoles>(
|
||||
*
|
||||
* @param contract - an instance of a {@link SmartContract}
|
||||
* @returns a mutation object that can be used to overwrite all roles on the contract
|
||||
* @twfeature PermissionsEnumerable
|
||||
* @beta
|
||||
*/
|
||||
export function useSetAllRoleMembers<TContract extends ContractWithRoles>(
|
||||
contract: RequiredParam<TContract>,
|
||||
) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -233,12 +238,13 @@ export function useSetAllRoleMembers<TContract extends ContractWithRoles>(
|
||||
*
|
||||
* @param contract - an instance of a {@link SmartContract}
|
||||
* @returns a mutation object that can be used to grant a member of a role on the contract
|
||||
* @twfeature Permissions
|
||||
* @beta
|
||||
*/
|
||||
export function useGrantRole<TContract extends ContractWithRoles>(
|
||||
contract: RequiredParam<TContract>,
|
||||
) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -291,12 +297,13 @@ export function useGrantRole<TContract extends ContractWithRoles>(
|
||||
*
|
||||
* @param contract - an instance of a {@link SmartContract}
|
||||
* @returns a mutation object that can be used to revoke a role from a member on the contract
|
||||
* @twfeature Permissions
|
||||
* @beta
|
||||
*/
|
||||
export function useRevokeRole<TContract extends ContractWithRoles>(
|
||||
contract: RequiredParam<TContract>,
|
||||
) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation(
|
||||
+15
-7
@@ -1,7 +1,7 @@
|
||||
import { useActiveChainId } from "../../Provider";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { useSDKChainId } from "../../providers/base";
|
||||
import {
|
||||
ClaimTokenParams,
|
||||
RequiredParam,
|
||||
TokenBurnParams,
|
||||
TokenParams,
|
||||
WalletAddress,
|
||||
@@ -29,6 +29,7 @@ import invariant from "tiny-invariant";
|
||||
*
|
||||
* @param contract - an instance of a ERC20 contract.
|
||||
* @returns a response object that incudes the total minted supply
|
||||
* @twfeature ERC20
|
||||
* @beta
|
||||
*/
|
||||
export function useTokenSupply(contract: RequiredParam<Erc20>) {
|
||||
@@ -55,6 +56,7 @@ export function useTokenSupply(contract: RequiredParam<Erc20>) {
|
||||
*
|
||||
* @param contract - an instance of a ERC20 contract.
|
||||
* @returns a response object that includes the balance of the address
|
||||
* @twfeature ERC20
|
||||
* @beta
|
||||
*/
|
||||
export function useTokenBalance(
|
||||
@@ -85,6 +87,7 @@ export function useTokenBalance(
|
||||
*
|
||||
* @param contract - an instance of an ERC20 contract.
|
||||
* @returns a response object that includes the decimals of the ERC20 token
|
||||
* @twfeature ERC20
|
||||
* @beta
|
||||
*/
|
||||
export function useTokenDecimals(contract: RequiredParam<Erc20>) {
|
||||
@@ -134,10 +137,11 @@ export function useTokenDecimals(contract: RequiredParam<Erc20>) {
|
||||
*
|
||||
* @param contract - an instance of a contract that extends the ERC20 spec (token, token drop, custom contract that follows the ERC20 spec)
|
||||
* @returns a mutation object that can be used to mint new tokens to the connected wallet
|
||||
* @twfeature ERC20Mintable
|
||||
* @beta
|
||||
*/
|
||||
export function useMintToken(contract: RequiredParam<Erc20>) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -187,12 +191,13 @@ export function useMintToken(contract: RequiredParam<Erc20>) {
|
||||
*
|
||||
* @param contract - an instance of a {@link Erc20}
|
||||
* @returns a mutation object that can be used to tokens to the wallet specificed in the params
|
||||
* @twfeature ERC20ClaimableWithConditions
|
||||
* @beta
|
||||
*/
|
||||
export function useClaimToken<TContract extends Erc20>(
|
||||
contract: RequiredParam<TContract>,
|
||||
) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -246,10 +251,11 @@ export function useClaimToken<TContract extends Erc20>(
|
||||
*
|
||||
* @param contract - an instance of a contract that extends the ERC20 spec (token, token drop, custom contract that follows the ERC20 spec)
|
||||
* @returns a mutation object that can be used to transfer tokens
|
||||
* @twfeature ERC20
|
||||
* @beta
|
||||
*/
|
||||
export function useTransferToken(contract: RequiredParam<Erc20>) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -299,10 +305,11 @@ export function useTransferToken(contract: RequiredParam<Erc20>) {
|
||||
*
|
||||
* @param contract - an instance of a contract that extends the ERC20 spec (token, token drop, custom contract that follows the ERC20 spec)
|
||||
* @returns a mutation object that can be used to transfer batch tokens
|
||||
* @twfeature ERC20
|
||||
* @beta
|
||||
*/
|
||||
export function useTransferBatchToken(contract: RequiredParam<Erc20>) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@@ -359,10 +366,11 @@ export function useTransferBatchToken(contract: RequiredParam<Erc20>) {
|
||||
*
|
||||
* @param contract - an instance of a contract that extends the ERC20 spec (token, token drop, custom contract that follows the ERC20 spec)
|
||||
* @returns a mutation object that can be used to burn tokens from the connected wallet
|
||||
* @twfeature ERC20Burnable
|
||||
* @beta
|
||||
*/
|
||||
export function useBurnToken(contract: RequiredParam<Erc20>) {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
const contractAddress = contract?.getAddress();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { useSDK } from "../../Provider";
|
||||
import { useThirdwebAuthConfig } from "../../contexts/thirdweb-auth";
|
||||
import { useSDK } from "../../providers/base";
|
||||
import { cacheKeys } from "../../utils/cache-keys";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { LoginOptions } from "@thirdweb-dev/sdk";
|
||||
+7
-1
@@ -2,9 +2,10 @@ import {
|
||||
GnosisConnectorArguments,
|
||||
GnosisSafeConnector,
|
||||
} from "../../connectors/gnosis-safe";
|
||||
import { useConnect } from "../useConnect";
|
||||
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.
|
||||
@@ -32,6 +33,11 @@ import invariant from "tiny-invariant";
|
||||
* @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");
|
||||
+7
-1
@@ -1,7 +1,8 @@
|
||||
import { MagicConnector } from "../../connectors/magic";
|
||||
import { useConnect } from "../useConnect";
|
||||
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.
|
||||
@@ -66,6 +67,11 @@ import invariant from "tiny-invariant";
|
||||
* @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");
|
||||
+7
-1
@@ -1,6 +1,7 @@
|
||||
import { isMobile } from "../../utils/isMobile";
|
||||
import { useConnect } from "../useConnect";
|
||||
import { useConnect } from "../wagmi-required/useConnect";
|
||||
import invariant from "tiny-invariant";
|
||||
import { useContext as useWagmiContext } from "wagmi";
|
||||
|
||||
/**
|
||||
* Hook for connecting to a Metamask wallet.
|
||||
@@ -31,6 +32,11 @@ import invariant from "tiny-invariant";
|
||||
* @public
|
||||
*/
|
||||
export function useMetamask() {
|
||||
const wagmiContext = useWagmiContext();
|
||||
invariant(
|
||||
wagmiContext,
|
||||
`useMetamask() 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();
|
||||
|
||||
const isMetaMaskInjected =
|
||||
+7
-1
@@ -1,5 +1,6 @@
|
||||
import { useConnect } from "../useConnect";
|
||||
import { useConnect } from "../wagmi-required/useConnect";
|
||||
import invariant from "tiny-invariant";
|
||||
import { useContext as useWagmiContext } from "wagmi";
|
||||
|
||||
/**
|
||||
* Hook for connecting to a mobile wallet with Wallet Connect
|
||||
@@ -31,6 +32,11 @@ import invariant from "tiny-invariant";
|
||||
* @public
|
||||
*/
|
||||
export function useWalletConnect() {
|
||||
const wagmiContext = useWagmiContext();
|
||||
invariant(
|
||||
wagmiContext,
|
||||
`useWalletConnect() 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 () =>
|
||||
+7
-1
@@ -1,5 +1,6 @@
|
||||
import { useConnect } from "../useConnect";
|
||||
import { useConnect } from "../wagmi-required/useConnect";
|
||||
import invariant from "tiny-invariant";
|
||||
import { useContext as useWagmiContext } from "wagmi";
|
||||
|
||||
/**
|
||||
* Hook for connecting to a Coinbase wallet.
|
||||
@@ -31,6 +32,11 @@ import invariant from "tiny-invariant";
|
||||
* @public
|
||||
*/
|
||||
export function useCoinbaseWallet() {
|
||||
const wagmiContext = useWagmiContext();
|
||||
invariant(
|
||||
wagmiContext,
|
||||
`useCoinbaseWallet() 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("Coinbase connector not ready to be used, yet");
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
import { EditionImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/edition";
|
||||
import { Edition } from "@thirdweb-dev/sdk/dist/declarations/src/evm/contracts/prebuilt-implementations/edition";
|
||||
|
||||
/**
|
||||
* Hook for getting an instance of an `Edition` contract. This contract is used to interface with ERC1155 compliant NFTs.
|
||||
@@ -25,9 +25,9 @@ import { EditionImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/p
|
||||
* }
|
||||
* ```
|
||||
* @public
|
||||
* @depreated use `useContract()` instead
|
||||
* @deprecated use `useContract()` instead
|
||||
*/
|
||||
export function useEdition(contractAddress?: string) {
|
||||
showDeprecationWarning("useEdition()", "useContract<Edition>()");
|
||||
return useContract<EditionImpl>(contractAddress).contract;
|
||||
return useContract<Edition>(contractAddress).contract;
|
||||
}
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
import { EditionDropImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/edition-drop";
|
||||
import { EditionDrop } from "@thirdweb-dev/sdk/dist/declarations/src/evm/contracts/prebuilt-implementations/edition-drop";
|
||||
|
||||
/**
|
||||
* Hook for getting an instance of an `EditionDrop` contract. This conract is used to interface with ERC1155 compliant NFTs that can be lazily minted.
|
||||
@@ -24,9 +24,9 @@ import { EditionDropImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contrac
|
||||
* }
|
||||
* ```
|
||||
* @public
|
||||
* @depreated use `useContract()` instead
|
||||
* @deprecated use `useContract()` instead
|
||||
*/
|
||||
export function useEditionDrop(contractAddress?: string) {
|
||||
showDeprecationWarning("useEditionDrop()", "useContract<EditionDrop>()");
|
||||
return useContract<EditionDropImpl>(contractAddress).contract;
|
||||
return useContract<EditionDrop>(contractAddress).contract;
|
||||
}
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
import { MarketplaceImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/marketplace";
|
||||
import { Marketplace } from "@thirdweb-dev/sdk/dist/declarations/src/evm/contracts/prebuilt-implementations/marketplace";
|
||||
|
||||
/**
|
||||
* Hook for getting an instance of a `Marketplace` contract. This contract is used to support marketplace for purchase and sale of on-chain assets.
|
||||
@@ -25,9 +25,9 @@ import { MarketplaceImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contrac
|
||||
* }
|
||||
* ```
|
||||
* @public
|
||||
* @depreated use `useContract()` instead
|
||||
* @deprecated use `useContract()` instead
|
||||
*/
|
||||
export function useMarketplace(contractAddress?: string) {
|
||||
showDeprecationWarning("useMarketplace()", "useContract<Marketplace>()");
|
||||
return useContract<MarketplaceImpl>(contractAddress).contract;
|
||||
return useContract<Marketplace>(contractAddress).contract;
|
||||
}
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
import { MultiwrapImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/multiwrap";
|
||||
import { Multiwrap } from "@thirdweb-dev/sdk/dist/declarations/src/evm/contracts/prebuilt-implementations/multiwrap";
|
||||
|
||||
/**
|
||||
* Hook for getting an instance of an `Multiwrap` contract. This contract is an ERC721 in which you can wrap ERC721, ERC1155 and ERC20 tokens.
|
||||
@@ -24,9 +24,9 @@ import { MultiwrapImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts
|
||||
* }
|
||||
* ```
|
||||
* @public
|
||||
* @depreated use `useContract()` instead
|
||||
* @deprecated use `useContract()` instead
|
||||
*/
|
||||
export function useMultiwrap(contractAddress?: string) {
|
||||
showDeprecationWarning("useMultiwrap()", "useContract<Multiwrap>()");
|
||||
return useContract<MultiwrapImpl>(contractAddress).contract;
|
||||
return useContract<Multiwrap>(contractAddress).contract;
|
||||
}
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
import { NFTCollectionImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/nft-collection";
|
||||
import { NFTCollection } from "@thirdweb-dev/sdk/dist/declarations/src/evm/contracts/prebuilt-implementations/nft-collection";
|
||||
|
||||
/**
|
||||
* Hook for getting an instance of an `NFTCollection` contract. This contract is meant to interface with ERC721 compliant NFTs.
|
||||
@@ -25,9 +25,9 @@ import { NFTCollectionImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contr
|
||||
* }
|
||||
* ```
|
||||
* @public
|
||||
* @depreated use `useContract()` instead
|
||||
* @deprecated use `useContract()` instead
|
||||
*/
|
||||
export function useNFTCollection(contractAddress?: string) {
|
||||
showDeprecationWarning("useNFTCollection()", "useContract<NFTCollection>()");
|
||||
return useContract<NFTCollectionImpl>(contractAddress).contract;
|
||||
return useContract<NFTCollection>(contractAddress).contract;
|
||||
}
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
import { NFTDropImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/nft-drop";
|
||||
import { NFTDrop } from "@thirdweb-dev/sdk/dist/declarations/src/evm/contracts/prebuilt-implementations/nft-drop";
|
||||
|
||||
/**
|
||||
* Hook for getting an instance of an `NFTDrop` contract. This contract is meant to interface with ERC721 compliant NFTs that can be lazily minted.
|
||||
@@ -24,9 +24,9 @@ import { NFTDropImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/p
|
||||
* }
|
||||
* ```
|
||||
* @public
|
||||
* @depreated use `useContract()` instead
|
||||
* @deprecated use `useContract()` instead
|
||||
*/
|
||||
export function useNFTDrop(contractAddress?: string) {
|
||||
showDeprecationWarning("useNFTDrop()", "useContract<NFTDrop>()");
|
||||
return useContract<NFTDropImpl>(contractAddress).contract;
|
||||
return useContract<NFTDrop>(contractAddress).contract;
|
||||
}
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
import { PackImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/pack";
|
||||
import { Pack } from "@thirdweb-dev/sdk/dist/declarations/src/evm/contracts/prebuilt-implementations/pack";
|
||||
|
||||
/**
|
||||
* Hook for getting an instance of a `Pack` contract. This contract supports the creation of on-chain luck-based lootboxes.
|
||||
@@ -25,9 +25,9 @@ import { PackImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/preb
|
||||
* }
|
||||
* ```
|
||||
* @public
|
||||
* @depreated use `useContract()` instead
|
||||
* @deprecated use `useContract()` instead
|
||||
*/
|
||||
export function usePack(contractAddress?: string) {
|
||||
showDeprecationWarning("usePack()", "useContract<Pack>()");
|
||||
return useContract<PackImpl>(contractAddress).contract;
|
||||
return useContract<Pack>(contractAddress).contract;
|
||||
}
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
import { SignatureDropImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/signature-drop";
|
||||
import { SignatureDrop } from "@thirdweb-dev/sdk/dist/declarations/src/evm/contracts/prebuilt-implementations/signature-drop";
|
||||
|
||||
/**
|
||||
* Hook for getting an instance of an `SignatureDrop` contract. This contract is meant to interface with ERC721 compliant NFTs that can be lazily minted.
|
||||
@@ -24,9 +24,9 @@ import { SignatureDropImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contr
|
||||
* }
|
||||
* ```
|
||||
* @public
|
||||
* @depreated use `useContract()` instead
|
||||
* @deprecated use `useContract()` instead
|
||||
*/
|
||||
export function useSignatureDrop(contractAddress?: string) {
|
||||
showDeprecationWarning("useSignatureDrop()", "useContract<SignatureDrop>()");
|
||||
return useContract<SignatureDropImpl>(contractAddress).contract;
|
||||
return useContract<SignatureDrop>(contractAddress).contract;
|
||||
}
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
import { SplitImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/split";
|
||||
import { Split } from "@thirdweb-dev/sdk/dist/declarations/src/evm/contracts/prebuilt-implementations/split";
|
||||
|
||||
/**
|
||||
* Hook for getting an instance of a `Split` contract. This contract supports fund distribution to multiple parties.
|
||||
@@ -25,9 +25,9 @@ import { SplitImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/pre
|
||||
* }
|
||||
* ```
|
||||
* @public
|
||||
* @depreated use `useContract()` instead
|
||||
* @deprecated use `useContract()` instead
|
||||
*/
|
||||
export function useSplit(contractAddress?: string) {
|
||||
showDeprecationWarning("useSplit()", "useContract<Split>()");
|
||||
return useContract<SplitImpl>(contractAddress).contract;
|
||||
return useContract<Split>(contractAddress).contract;
|
||||
}
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
import { TokenImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/token";
|
||||
import { Token } from "@thirdweb-dev/sdk/dist/declarations/src/evm/contracts/prebuilt-implementations/token";
|
||||
|
||||
/**
|
||||
* Hook for getting an instance of a `Token` contract. This contract supports ERC20 compliant tokens.
|
||||
@@ -25,9 +25,9 @@ import { TokenImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/pre
|
||||
* }
|
||||
* ```
|
||||
* @public
|
||||
* @depreated use `useContract()` instead
|
||||
* @deprecated use `useContract()` instead
|
||||
*/
|
||||
export function useToken(contractAddress?: string) {
|
||||
showDeprecationWarning("useToken()", "useContract<Token>()");
|
||||
return useContract<TokenImpl>(contractAddress).contract;
|
||||
return useContract<Token>(contractAddress).contract;
|
||||
}
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
import { TokenDropImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/token-drop";
|
||||
import { TokenDrop } from "@thirdweb-dev/sdk/dist/declarations/src/evm/contracts/prebuilt-implementations/token-drop";
|
||||
|
||||
/**
|
||||
* Hook for getting an instance of a `Token Drop` contract.
|
||||
@@ -25,9 +25,9 @@ import { TokenDropImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts
|
||||
* }
|
||||
* ```
|
||||
* @public
|
||||
* @depreated use `useContract()` instead
|
||||
* @deprecated use `useContract()` instead
|
||||
*/
|
||||
export function useTokenDrop(contractAddress?: string) {
|
||||
showDeprecationWarning("useTokenDrop()", "useContract<TokenDrop>()");
|
||||
return useContract<TokenDropImpl>(contractAddress).contract;
|
||||
return useContract<TokenDrop>(contractAddress).contract;
|
||||
}
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
import { VoteImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/vote";
|
||||
import { Vote } from "@thirdweb-dev/sdk/dist/declarations/src/evm/contracts/prebuilt-implementations/vote";
|
||||
|
||||
/**
|
||||
* Hook for getting an instance of an `Vote` contract. This contract enables fully featured voting-based decentralized governance systems.
|
||||
@@ -25,9 +25,9 @@ import { VoteImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/preb
|
||||
* }
|
||||
* ```
|
||||
* @public
|
||||
* @depreated use `useContract()` instead
|
||||
* @deprecated use `useContract()` instead
|
||||
*/
|
||||
export function useVote(contractAddress?: string) {
|
||||
showDeprecationWarning("useVote()", "useContract<Vote>()");
|
||||
return useContract<VoteImpl>(contractAddress).contract;
|
||||
return useContract<Vote>(contractAddress).contract;
|
||||
}
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
import { useActiveChainId } from "../../Provider";
|
||||
import { useSDKChainId } from "../../providers/base";
|
||||
import { createCacheKeyWithNetwork } from "../../utils/cache-keys";
|
||||
import {
|
||||
QueryFunction,
|
||||
@@ -22,7 +22,7 @@ export function useQueryWithNetwork<
|
||||
"queryKey" | "queryFn"
|
||||
>,
|
||||
): UseQueryResult<TData, TError> {
|
||||
const activeChainId = useActiveChainId();
|
||||
const activeChainId = useSDKChainId();
|
||||
|
||||
const mergedOptions: Omit<
|
||||
UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
import { useDesiredChainId } from "../Provider";
|
||||
import { useChainId } from "./useChainId";
|
||||
import { useDesiredChainId } from "../providers/base";
|
||||
import { useChainId } from "./wallet";
|
||||
|
||||
/**
|
||||
* Hook for checking whether the connected wallet is on the correct network specified by the `desiredChainId` passed to the `<ThirdwebProvider />`.
|
||||
@@ -28,16 +28,16 @@ import { useChainId } from "./useChainId";
|
||||
*/
|
||||
export function useNetworkMismatch() {
|
||||
const desiredChainId = useDesiredChainId();
|
||||
const activeChainId = useChainId();
|
||||
const walletChainId = useChainId();
|
||||
|
||||
if (desiredChainId === -1) {
|
||||
// means no desiredChainId is set in the <ThirdwebProvider />, so we don't care about the network mismatch
|
||||
return false;
|
||||
}
|
||||
if (!activeChainId) {
|
||||
if (!walletChainId) {
|
||||
// means no wallet is connected yet, so we don't care about the network mismatch
|
||||
return false;
|
||||
}
|
||||
// check if the chainIds are different
|
||||
return desiredChainId !== activeChainId;
|
||||
return desiredChainId !== walletChainId;
|
||||
}
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
import { SDKOptions, ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
import type { IStorage } from "@thirdweb-dev/storage";
|
||||
import type { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import { useMemo } from "react";
|
||||
|
||||
/**
|
||||
@@ -8,7 +8,7 @@ import { useMemo } from "react";
|
||||
export function useReadonlySDK(
|
||||
readonlyRpcUrl: string,
|
||||
sdkOptions: SDKOptions,
|
||||
storageInterface?: IStorage,
|
||||
storageInterface?: ThirdwebStorage,
|
||||
): ThirdwebSDK {
|
||||
return useMemo(() => {
|
||||
return new ThirdwebSDK(
|
||||
@@ -0,0 +1,10 @@
|
||||
import { useThirdwebConnectedWalletContext } from "../contexts/thirdweb-wallet";
|
||||
import type { Signer } from "ethers";
|
||||
|
||||
/**
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export function useSigner(): Signer | undefined {
|
||||
return useThirdwebConnectedWalletContext().signer;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import invariant from "tiny-invariant";
|
||||
import {
|
||||
useAccount as useWagmiAccount,
|
||||
useContext as useWagmiContext,
|
||||
} from "wagmi";
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function useAccount() {
|
||||
const wagmiContext = useWagmiContext();
|
||||
invariant(
|
||||
wagmiContext,
|
||||
`useNetwork() can only be used inside <ThirdwebProvider />. If you are using <ThirdwebSDKProvider /> you will have to use your own network logic.`,
|
||||
);
|
||||
return useWagmiAccount();
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user