Compare commits

...
Author SHA1 Message Date
github-actions[bot]andGitHub 2f1155239d Version Packages (#223) 2022-09-27 22:20:38 -07:00
Jonas DanielsandGitHub c295a47144 [SDK, React] - fix esm exports (#221) 2022-09-28 04:41:53 +00:00
Joaquim VergesandGitHub 0dade96d0d [SDK] Check that proxy/factory deploy flag properly is set (#224) 2022-09-28 04:17:41 +00:00
Joaquim VergesandGitHub 666ff5f694 [SOL] expose ThirdwebSDK.fromPrivateKey convenience static method (#222) 2022-09-28 02:50:38 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
8bc41cdc60 Version Packages (#214)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-27 18:08:47 -07:00
Joaquim VergesandGitHub 37a707f98c [React] lock zag version (#220) 2022-09-27 17:58:44 -07:00
Joaquim VergesandGitHub 3c8f6205e9 [SDK] expose proxy deploy for released contracts (#217) 2022-09-27 17:10:48 -07:00
Jonas DanielsandGitHub 1eaedc262f [React] - allow null and undefined for RequiredParam (#218) 2022-09-27 22:10:05 +00:00
e187d21e12 [SDK] Merge solana package into main SDK (#213)
Co-authored-by: Jonas Daniels <[email protected]>
2022-09-27 13:36:29 -07:00
YashandGitHub b030a86608 [SDK] Update addresses (#216) 2022-09-27 11:10:11 -07:00
acbabc8999 [SDK] - Relayer gas override (#206)
Co-authored-by: Jarrod Watts <[email protected]>
2022-09-27 19:05:29 +05:30
Jonas DanielsandGitHub 196195e2f9 [React] - fix small discrepancies (#215) 2022-09-27 10:27:32 +00:00
Jonas DanielsandGitHub 7c86babb86 [React] - subdivide react sdk (#208) 2022-09-27 09:35:45 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
36f2b70d57 Version Packages (#207)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-27 02:13:05 -07:00
Jarrod WattsandGitHub 849146bf5c [SDK] Docs: Update getContract snippet to use await (#212) 2022-09-27 03:41:12 +00:00
Jarrod WattsandGitHub 4cac79c45d [REACT] Docs: Remove broken link from migration guide (#210) 2022-09-27 02:17:13 +00:00
Jonas DanielsandGitHub 1bda83b114 Jd/fix react effect warning (#209) 2022-09-26 22:40:48 +00:00
Joaquim VergesandGitHub ce05bfd861 [SDK] Remove usages of Buffer to decode bytecodes (#205) 2022-09-26 13:29:24 -07:00
Jarrod WattsandGitHub d982a98b0c Jw/fix signature mint snipptes (#203) 2022-09-26 06:51:50 +00:00
Jarrod WattsandGitHub b983087101 Jw/fix signature mint snipptes (#202) 2022-09-26 05:23:08 +00:00
Jarrod WattsandGitHub b25789fa46 Jw/migration guide (#200) 2022-09-26 14:42:26 +10:00
github-actions[bot]andGitHub e39b66f309 Version Packages (#198) 2022-09-23 19:34:55 -07:00
5f5ab015e1 [SDK, SOL] Fixes for getOwned and solana balance (#199)
Co-authored-by: Jonas Daniels <[email protected]>
2022-09-24 02:11:58 +00:00
Jonas DanielsandGitHub f4f05bd9a4 [React] - make web3 button network switch obvious (#197) 2022-09-24 00:16:56 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
2f5b66bef9 Version Packages (#193)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-23 15:27:49 -07:00
63258bc9c3 [React] Expose simple provider and useSDK hook for solana (#179)
Co-authored-by: Jonas Daniels <[email protected]>
2022-09-23 19:12:24 +00:00
Jonas DanielsandGitHub a80fc97b6a [SDK] - update prebuilt contract roles to match contracts (#195) 2022-09-23 18:49:41 +00:00
Adam MajmudarandGitHub 24f66e38c2 Switch to using XHR with timeout (#192) 2022-09-23 05:32:45 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
b5bfaefa85 Version Packages (#157)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-22 17:11:41 -07:00
Adam MajmudarandGitHub 493ebf032e Add upload with gateway url for URIs (#190) 2022-09-22 17:06:59 -07:00
Adam MajmudarandGitHub d608cea197 Add progress tracking to file upload (#189) 2022-09-22 15:15:00 -07:00
Adam MajmudarandGitHub a9ec190ff9 Remove JSON types (#188) 2022-09-22 21:27:43 +00:00
3edec391be [CLI] thirdweb deploy redirects to contract deploy page if no contracts detected (#177)
Co-authored-by: Jonas Daniels <[email protected]>
Co-authored-by: Joaquim Verges <[email protected]>
2022-09-22 14:07:32 -07:00
bdec5a59af [CLI] Fix "Invalid Project name" when a project with a capital letter is entered (#184)
Co-authored-by: Jonas Daniels <[email protected]>
2022-09-22 20:20:15 +00:00
Jonas DanielsandGitHub 9d03619aab fix some lint issues (#187) 2022-09-22 19:02:22 +00:00
Jonas DanielsandGitHub 0ccbca78dc [Storage] - handle special chars (#185) 2022-09-22 11:29:42 -07:00
Adam MajmudarandGitHub 75c752cc14 Fix tests (#186) 2022-09-22 11:06:55 -07:00
Jonas DanielsandGitHub 3580182fa9 [Storage] - allow uploading the same file multiple times in uploadBatch if it is *the same file* (#183) 2022-09-22 09:33:24 +00:00
b54f95dc90 Update expected input types for storage (#163)
Co-authored-by: Jonas Daniels <[email protected]>
2022-09-22 08:12:52 +00:00
Adam MajmudarandGitHub f4074ddadc Replace schemes after replacing files (#180) 2022-09-22 06:43:22 +00:00
Jonas DanielsandGitHub 208b0389a5 [React] - use internal Signer (#168) 2022-09-22 06:04:27 +00:00
3b877ba221 [SDK] Ozdefender EOA forwarder option (#174)
Co-authored-by: Joaquim Verges <[email protected]>
2022-09-22 04:47:00 +00:00
Adam MajmudarandGitHub 45a400fd92 Change API for instantiating storage (#178) 2022-09-21 21:09:11 -07:00
Adam MajmudarandGitHub 3332fa5697 Split create contract flow into steps (#175) 2022-09-21 22:51:47 +00:00
Joaquim VergesandGitHub fdda564b1e [SOL] Fix browser build (#173) 2022-09-21 14:35:19 -07:00
Adam MajmudarandGitHub 89db3db7ff Add changeset for CLI (#172) 2022-09-21 20:15:09 +00:00
Adam MajmudarandGitHub bd9c705571 Add thirdweb deploy to end of thirdweb detect (#171) 2022-09-21 19:55:54 +00:00
Adam MajmudarandGitHub 0ad0f21bcd Display yarn build command at the end of thirdweb create --contract (#169) 2022-09-21 19:18:42 +00:00
Joaquim VergesandGitHub 4169b9428f [SDK] Syntax fixes for react native support (#167) 2022-09-21 09:35:22 -07:00
Jarrod WattsandGitHub 2f9e8aaab4 Jw/lazymintabletwfeature (#165) 2022-09-21 04:17:11 +00:00
Adam MajmudarandGitHub 421461ece0 Add README for Solana and Storage (#164) 2022-09-21 02:39:12 +00:00
Jarrod WattsandGitHub 485ebc8400 [REACT] - Feature snippet generation logic (#155) 2022-09-21 10:40:41 +10:00
Joaquim VergesandGitHub 772f8431e3 [SDK] Catch gas estimate errors in gasless tx (#162) 2022-09-20 23:00:12 +00:00
Joaquim VergesandGitHub 5345479922 [SDK] Allow forcing direct deploys to deploy implementations from release flow (#161) 2022-09-20 15:19:18 -07:00
Adam MajmudarandGitHub cfe8bbafa4 Add resolveScheme method to storage (#156) 2022-09-20 18:31:56 +00:00
Adam MajmudarandGitHub 18dc8d33ed Fix nft collection docs (#159) 2022-09-20 18:07:30 +00:00
Jonas DanielsandGitHub f8ab4779bb init paper checkout in v3 (#154) 2022-09-20 05:41:20 +00:00
Adam MajmudarandGitHub 6fe16c5bf2 Add documentation for Solana (#152) 2022-09-19 22:13:25 -07:00
Adam MajmudarandGitHub ba0e169654 Add support for string with name (#151) 2022-09-19 18:08:55 -07:00
Jarrod WattsandGitHub 27b869ed93 Update README.md (#150) 2022-09-20 00:25:11 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
091ce2eb45 Version Packages (#149)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-19 16:08:23 -07:00
Joaquim Verges e24a371508 fix changeset 2022-09-19 16:03:14 -07:00
Adam MajmudarandGitHub b86afb4b09 Add documentation for storage (#147) 2022-09-19 22:26:44 +00:00
Joaquim VergesandGitHub 964add6f20 [CLI, Storage] Fix deploy/release uploads via CLI (#148) 2022-09-19 14:56:42 -07:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
ec414bbc42 Version Packages (#136)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-19 11:11:34 -07:00
Joaquim VergesandGitHub 51dde28224 [SDK, React] Fix using external signers with ThirdwebSDKProvider (#143) 2022-09-19 18:03:39 +00:00
Adam MajmudarandGitHub 57432d21c4 Update Storage SDK (#139) 2022-09-19 16:58:12 +00:00
Jarrod WattsandGitHub 19d87c2885 Jw/react readme (#144) 2022-09-19 07:20:08 +00:00
Joaquim VergesandGitHub 68812e9d27 Update README.md 2022-09-17 11:29:03 -07:00
Joaquim VergesandGitHub 90c53475f0 Update README.md 2022-09-17 11:23:54 -07:00
Joaquim VergesandGitHub 5a52585a7a [SOL] More solana integration (#140) 2022-09-16 19:15:35 -07:00
Joaquim VergesandGitHub 6b48b9288b [SOL] solana dashboard integration (#138) 2022-09-16 13:19:17 -07:00
Joaquim VergesandGitHub 9d74a43aac [SDK] Make contract events generic for better DX (#133) 2022-09-16 05:51:23 +00:00
Jonas DanielsandGitHub 9c7e5518ff [SOL] - enforce owner when deploying (#137) 2022-09-15 22:24:05 -07:00
Jonas DanielsandGitHub b234c58d44 [SDK] - less rpc calls = good (#135) 2022-09-16 03:43:24 +00:00
Adam MajmudarandGitHub b1ae844e8b Reorder CLI commands (#134) 2022-09-15 20:20:43 -07:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
78bae497ba Version Packages (#126)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-15 14:00:20 -07:00
Joaquim VergesandGitHub 3e425bf8e6 [SOL] get account type for a given address (#132) 2022-09-15 20:54:45 +00:00
Jarrod WattsandGitHub 4dca5b21a6 Change feature detection URLs (#128) 2022-09-15 13:45:04 -07:00
Joaquim VergesandGitHub 42c79e93dc [SDK] fix editing releases from the dashboard (#131) 2022-09-15 19:17:02 +00:00
Joaquim VergesandGitHub 2951b5533c [SOL] New return type for registry.getAccountsForWallet (#130) 2022-09-15 18:09:52 +00:00
Joaquim VergesandGitHub fe8751eeae [SDK] add ownable feature detection (#124) 2022-09-15 17:41:32 +00:00
Jonas DanielsandGitHub a0cd47ec35 [SOL] - explicitly export the missing schemata (#129) 2022-09-15 17:13:20 +00:00
Jarrod WattsandGitHub 3902e7aba4 Update read and write hook names for snippet generation (#127) 2022-09-15 17:36:23 +10:00
464 changed files with 11214 additions and 6667 deletions
+2 -1
View File
@@ -9,7 +9,8 @@
"updateInternalDependencies": "patch",
"ignore": [],
"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
"updateInternalDependents": "always"
"updateInternalDependents": "always",
"onlyUpdatePeerDependentsWhenOutOfRange": true
},
"snapshot": {
"useCalculatedVersion": true,
+60 -56
View File
@@ -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
View File
@@ -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"
+53
View File
@@ -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
+3 -3
View File
@@ -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": {
+77
View File
@@ -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
+2 -1
View File
@@ -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 = {
+4 -1
View File
@@ -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 -2
View File
@@ -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"
},
+46 -46
View File
@@ -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
+3 -3
View File
@@ -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 });
+24 -2
View File
@@ -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(``);
});
}
+36 -12
View File
@@ -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");
+2 -2
View File
@@ -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";
+40 -11
View File
@@ -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
);
}
+2 -1
View File
@@ -3,4 +3,5 @@ export type ProjectType =
| "foundry"
| "hardhat"
| "truffle"
| "unknown";
| "solc"
| "none";
+57 -26
View File
@@ -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();
+2 -2
View File
@@ -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",
+87
View File
@@ -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
+69
View File
@@ -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
View File
@@ -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"
+4
View File
@@ -0,0 +1,4 @@
{
"main": "dist/thirdweb-dev-react-evm.cjs.js",
"module": "dist/thirdweb-dev-react-evm.esm.js"
}
+59 -9
View File
@@ -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),
);
+2 -2
View File
@@ -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 = [
+4
View File
@@ -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>
>;
+6
View File
@@ -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;
@@ -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");
});
@@ -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,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 } });
@@ -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);
}
@@ -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: () => {
@@ -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");
@@ -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();
@@ -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();
@@ -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);
@@ -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(
@@ -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,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";
@@ -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");
@@ -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");
@@ -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 =
@@ -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 () =>
@@ -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");
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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>,
@@ -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;
}
@@ -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(
+10
View File
@@ -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