Compare commits

...
Author SHA1 Message Date
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
197 changed files with 6693 additions and 1901 deletions
+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 -1
View File
@@ -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": [
@@ -47,5 +48,8 @@
},
"manypkg": {
"defaultBranch": "main"
},
"devDependencies": {
"yalc": "^1.0.0-pre.53"
}
}
+35
View File
@@ -1,5 +1,40 @@
# @thirdweb-dev/auth
## 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
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/auth",
"version": "2.0.3",
"version": "2.0.8",
"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": {
+45
View File
@@ -1,5 +1,50 @@
# thirdweb
## 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
+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();
+2 -3
View File
@@ -1,7 +1,7 @@
{
"name": "thirdweb",
"main": "dist/cli/index.js",
"version": "0.7.14",
"version": "0.7.19",
"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"
},
@@ -81,4 +80,4 @@
"sourcemap": true,
"clean": true
}
}
}
@@ -5,8 +5,10 @@ import { logger, spinner } from "../core/helpers/logger";
import { createContractsPrompt } from "../core/helpers/selector";
import { ContractFeatures, Feature } from "../core/interfaces/ContractFeatures";
import { ContractPayload } from "../core/interfaces/ContractPayload";
import { getPkgManager } from "../create/helpers/get-pkg-manager";
import { detectFeatures, FeatureWithEnabled } from "@thirdweb-dev/sdk";
import chalk from "chalk";
import { existsSync, readFileSync } from "fs";
import ora from "ora";
import path from "path";
@@ -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(``);
});
}
+28 -9
View File
@@ -1,4 +1,4 @@
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";
@@ -8,6 +8,7 @@ import { ContractPayload } from "../core/interfaces/ContractPayload";
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(
@@ -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 {
@@ -142,10 +164,9 @@ export async function processProject(
const metadataURIs = await Promise.all(
selectedContracts.map(async (c) => {
logger.debug(`Uploading ${c.name}...`);
const hash = await storage.upload(c.metadata, {
return await storage.upload(JSON.parse(c.metadata), {
uploadWithoutDirectory: true,
});
return `ipfs://${hash}`;
}),
);
@@ -173,15 +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.upload(
JSON.stringify(combinedContents[0]),
{ uploadWithoutDirectory: true },
);
const metadataUri = await storage.upload(combinedContents[0], {
uploadWithoutDirectory: true,
});
combinedURIs.push(metadataUri);
} else {
// otherwise upload batch
const uris = await storage.uploadBatch(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, { exists, 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",
+51
View File
@@ -1,5 +1,56 @@
# @thirdweb-dev/react
## 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
+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>
```
+1 -1
View File
@@ -143,7 +143,7 @@ Each [extension](https://portal.thirdweb.com/extensions) you implement in your s
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`:
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";
+41 -8
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react",
"version": "3.0.3",
"version": "3.0.8",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -8,21 +8,28 @@
"types": "dist/thirdweb-dev-react.cjs.d.ts",
"module": "dist/thirdweb-dev-react.esm.js",
"files": [
"dist/**/*",
"patches/**/*"
"dist/",
"solana/"
],
"preconstruct": {
"entrypoints": [
"index.ts",
"solana/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,9 +40,13 @@
"@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": "*",
"@types/color": "^3.0.3",
"@types/mime": "^3.0.1",
@@ -75,7 +86,12 @@
"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": "*",
"@thirdweb-dev/solana": "*",
"ethers": ">=5.5.1",
"react": ">=18.0.0",
"react-dom": ">=18.0.0"
@@ -83,5 +99,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),
);
+4
View File
@@ -0,0 +1,4 @@
{
"main": "dist/thirdweb-dev-react-solana.cjs.js",
"module": "dist/thirdweb-dev-react-solana.esm.js"
}
@@ -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,6 +10,7 @@ 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 { CallOverrides } from "ethers";
@@ -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>
);
@@ -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]);
}
+2
View File
@@ -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,4 +1,4 @@
import { useActiveChainId } from "../../Provider";
import { useSDKChainId } from "../../providers/base";
import {
getErcs,
DropContract,
@@ -60,7 +60,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 +83,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 +113,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 +136,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 +166,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 +207,7 @@ export function useClaimIneligibilityReasons(
params.walletAddress,
);
}
return undefined;
throw new Error("Contract must be ERC721, ERC1155 or ERC20");
},
{
// Checks that happen here:
@@ -257,13 +257,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 +284,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 +328,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 +374,7 @@ export function useResetClaimConditions(
true,
);
}
return undefined;
throw new Error("Contract must be ERC721, ERC1155 or ERC20");
},
{
onSettled: () => {
@@ -1,4 +1,4 @@
import { useActiveChainId } from "../../Provider";
import { useSDKChainId } from "../../providers/base";
import { RequiredParam, WalletAddress } from "../../types";
import {
cacheKeys,
@@ -24,6 +24,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 +74,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 +82,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 +117,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 +167,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 +175,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 +213,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 +262,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 +270,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 +308,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 +354,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 +362,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");
+16 -15
View File
@@ -1,9 +1,4 @@
import {
useActiveChainId,
useActiveSignerAddress,
useActiveSignerChainId,
useSDK,
} from "../../Provider";
import { useSDK, useSDKChainId } from "../../providers/base";
import { ContractAddress, RequiredParam } from "../../types";
import {
cacheKeys,
@@ -11,6 +6,7 @@ import {
createContractCacheKey,
} from "../../utils/cache-keys";
import { useQueryWithNetwork } from "../query-utils/useQueryWithNetwork";
import { useAddress, useChainId } from "../wallet";
import {
useMutation,
useQuery,
@@ -154,9 +150,9 @@ export function useContract<
>(contractAddress: RequiredParam<ContractAddress>) {
const sdk = useSDK();
const queryClient = useQueryClient();
const activeChainId = useActiveChainId();
const wallet = useActiveSignerAddress();
const walletChainId = useActiveSignerChainId();
const activeChainId = useSDKChainId();
const wallet = useAddress();
const walletChainId = useChainId();
// it's there because we put it there.
const sdkTimestamp = (sdk as any)?._constructedAt;
@@ -226,12 +222,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");
@@ -249,7 +250,7 @@ export function useContractMetadata(
export function useContractMetadataUpdate(
contract: RequiredParam<ValidContractInstance>,
) {
const activeChainId = useActiveChainId();
const activeChainId = useSDKChainId();
const contractAddress = contract?.getAddress();
const queryClient = useQueryClient();
@@ -294,7 +295,7 @@ export function useContractEvents(
const contractAddress = contract?.getAddress();
const queryClient = useQueryClient();
const activeChainId = useActiveChainId();
const activeChainId = useSDKChainId();
const cacheKey = useMemo(
() =>
@@ -423,7 +424,7 @@ export function useContractWrite(
contract: RequiredParam<ValidContractInstance>,
functionName: RequiredParam<string>,
) {
const activeChainId = useActiveChainId();
const activeChainId = useSDKChainId();
const contractAddress = contract?.getAddress();
const queryClient = useQueryClient();
+18 -7
View File
@@ -1,4 +1,4 @@
import { useActiveChainId } from "../../Provider";
import { useSDKChainId } from "../../providers/base";
import {
ClaimNFTParams,
ClaimNFTReturnType,
@@ -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/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();
+20 -24
View File
@@ -1,11 +1,11 @@
import { useActiveChainId } from "../../Provider";
import { useSDKChainId } from "../../providers/base";
import { BuyNowParams, MakeBidParams, RequiredParam } 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 +15,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/contracts/prebuilt-implementations/marketplace";
import { BigNumber, BigNumberish } from "ethers";
import invariant from "tiny-invariant";
@@ -37,7 +37,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 +68,7 @@ export function useListing(
* @beta
*/
export function useListings(
contract: RequiredParam<MarketplaceImpl>,
contract: RequiredParam<Marketplace>,
filter?: MarketplaceFilter,
) {
const contractAddress = contract?.getAddress();
@@ -97,7 +97,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 +125,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 +157,7 @@ export function useActiveListings(
* @beta
*/
export function useWinningBid(
contract: RequiredParam<MarketplaceImpl>,
contract: RequiredParam<Marketplace>,
listingId: RequiredParam<BigNumberish>,
) {
const contractAddress = contract?.getAddress();
@@ -190,7 +190,7 @@ export function useWinningBid(
* @beta
*/
export function useAuctionWinner(
contract: RequiredParam<MarketplaceImpl>,
contract: RequiredParam<Marketplace>,
listingId: RequiredParam<BigNumberish>,
) {
const contractAddress = contract?.getAddress();
@@ -232,7 +232,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 +281,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 +337,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 +393,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 +447,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 +503,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();
+20 -8
View File
@@ -1,4 +1,4 @@
import { useActiveChainId } from "../../Provider";
import { useSDKChainId } from "../../providers/base";
import {
AirdropNFTParams,
BurnNFTParams,
@@ -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>,
@@ -308,6 +314,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 +416,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 +488,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 +551,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 +646,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 +729,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);
+12 -6
View File
@@ -1,4 +1,4 @@
import { useActiveChainId } from "../../Provider";
import { useSDKChainId } from "../../providers/base";
import { RequiredParam, WalletAddress } from "../../types";
import {
cacheKeys,
@@ -7,7 +7,7 @@ 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 { Vote } 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 { constants } from "ethers";
import invariant from "tiny-invariant";
@@ -19,7 +19,7 @@ import invariant from "tiny-invariant";
/**
* @internal
*/
export type ContractWithRoles = Exclude<ValidContractInstance, VoteImpl>;
export type ContractWithRoles = Exclude<ValidContractInstance, Vote>;
/**
* @internal
@@ -50,6 +50,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 +82,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 +115,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 +177,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 +237,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 +296,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(
+14 -6
View File
@@ -1,4 +1,4 @@
import { useActiveChainId } from "../../Provider";
import { useSDKChainId } from "../../providers/base";
import {
ClaimTokenParams,
RequiredParam,
@@ -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();
-59
View File
@@ -1,59 +0,0 @@
import { SupportedChainId } from "../../constants/chain";
import { useThirdwebConfigContext } from "../../contexts/thirdweb-config";
import { ContractAddress } from "../../types";
import { cacheKeys } from "../../utils/cache-keys";
import { useAddress } from "../useAddress";
import { useChainId } from "../useChainId";
import { useSigner } from "../useSigner";
import { useQuery } from "@tanstack/react-query";
import { UserWallet } from "@thirdweb-dev/sdk";
import { useMemo } from "react";
/**
* A hook to get the native or (optional) ERC20 token balance of the connected wallet.
*
* @param tokenAddress - the address of the token contract, if empty will use the chain's native token
* @returns the balance of the connected wallet (native or ERC20)
* @beta
*/
export function useBalance(tokenAddress?: ContractAddress) {
const { rpcUrlMap } = useThirdwebConfigContext();
const chainId = useChainId() as SupportedChainId;
const signer = useSigner();
const walletAddress = useAddress();
const walletSDK = useMemo(() => {
if (signer) {
const rpcUrl = rpcUrlMap[chainId];
return new UserWallet(signer, {
readonlySettings: rpcUrl
? {
rpcUrl,
chainId,
}
: undefined,
});
}
return undefined;
// we're not apssing rpcUrlMap as a dependency because it should be constant anyways
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [signer, chainId]);
const cacheKey = useMemo(() => {
return cacheKeys.wallet.balance(chainId, walletAddress, tokenAddress);
}, [chainId, tokenAddress, walletAddress]);
return useQuery(
cacheKey,
() => {
return walletSDK?.balance(tokenAddress);
},
{
// if user is not logged in no reason to try to fetch
enabled: !!walletSDK && !!walletAddress,
retry: true,
keepPreviousData: false,
},
);
}
+1 -1
View File
@@ -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/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/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/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/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/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/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/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/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/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/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/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/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>,
-31
View File
@@ -1,31 +0,0 @@
import { useAccount } from "wagmi";
/**
* Hook for accessing the address of the connected wallet
*
* ```javascript
* import { useAddress } from "@thirdweb-dev/react"
* ```
*
*
* @example
* To get the address of the connected wallet, you can use the hook as follows:
*
* ```javascript
* import { useAddress } from "@thirdweb-dev/react"
*
* const App = () => {
* const address = useAddress()
*
* return <div>{address}</div>
* }
* ```
*
* The `address` variable will hold the address of the connected wallet if a user has connected using one of the supported wallet connection hooks.
*
* @public
*/
export function useAddress(): string | undefined {
const [account] = useAccount();
return account.data?.address;
}
-25
View File
@@ -1,25 +0,0 @@
import { useNetwork } from "wagmi";
/**
* Hook for accessing the chain ID of the network the current wallet is connected to
*
* ```javascript
* import { useChainId } from "@thirdweb-dev/react"
* ```
*
* @example
* You can get the chain ID of the connected wallet by using the hook as follows:
* ```javascript
* import { useChainId } from "@thirdweb-dev/react"
*
* const App = () => {
* const chainId = useChainId()
*
* return <div>{chainId}</div>
* }
* ```
* @public
*/
export function useChainId(): number | undefined {
return useNetwork()["0"].data.chain?.id;
}
-9
View File
@@ -1,9 +0,0 @@
import { useConnect as useWagmiConnect } from "wagmi";
/**
* for now just re-exported
* @internal
*/
export function useConnect() {
return useWagmiConnect();
}
@@ -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;
}
+4 -41
View File
@@ -1,47 +1,10 @@
import { Signer } from "ethers";
import { useEffect, useRef } from "react";
import { useAccount, useNetwork, useSigner as useWagmiSigner } from "wagmi";
import { useThirdwebConnectedWalletContext } from "../contexts/thirdweb-wallet";
import type { Signer } from "ethers";
/**
*
* @internal
*/
export function useSigner() {
const [signer, getSigner] = useWagmiSigner();
const [account] = useAccount();
const [network] = useNetwork();
const _getSignerPromise = useRef<ReturnType<typeof getSigner> | null>(null);
const address = account.data?.address;
const chainId = network.data.chain?.id;
const previousAddress = usePrevious(account.data?.address);
const previousChainId = usePrevious(network.data?.chain?.id);
useEffect(() => {
if (address !== previousAddress || chainId !== previousChainId) {
if (!_getSignerPromise.current) {
return;
} else {
_getSignerPromise.current = getSigner().finally(() => {
_getSignerPromise.current = null;
});
}
}
}, [address, chainId, getSigner, previousAddress, previousChainId]);
return Signer.isSigner(signer.data) ? signer.data : undefined;
}
function usePrevious<TVal>(value: TVal): TVal | undefined {
// The ref object is a generic container whose current property is mutable ...
// ... and can hold any value, similar to an instance property on a class
const ref = useRef<TVal>();
// Store current value in ref
useEffect(() => {
ref.current = value;
}, [value]); // Only re-run if value changes
// Return previous value (happens before update in useEffect above)
return ref.current;
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();
}
@@ -0,0 +1,18 @@
import invariant from "tiny-invariant";
import {
useConnect as useWagmiConnect,
useContext as useWagmiContext,
} from "wagmi";
/**
* for now just re-exported
* @internal
*/
export function useConnect() {
const wagmiContext = useWagmiContext();
invariant(
wagmiContext,
`useConnect() can only be used inside <ThirdwebProvider />. If you are using <ThirdwebSDKProvider /> you will have to use your own connection logic.`,
);
return useWagmiConnect();
}
@@ -1,6 +1,7 @@
import { GnosisSafeConnector } from "../connectors/gnosis-safe";
import { GnosisSafeConnector } from "../../connectors/gnosis-safe";
import { useConnect } from "./useConnect";
import { useAccount } from "wagmi";
import invariant from "tiny-invariant";
import { useAccount, useContext as useWagmiContext } from "wagmi";
/**
* Hook for disconnecting the currently connected wallet
@@ -31,6 +32,11 @@ import { useAccount } from "wagmi";
* @public
*/
export function useDisconnect(options?: { reconnectAfterGnosis?: boolean }) {
const wagmiContext = useWagmiContext();
invariant(
wagmiContext,
`useDisconnect() can only be used inside <ThirdwebProvider />. If you are using <ThirdwebSDKProvider /> you will have to use your own connection logic.`,
);
const optsWithDefaults = { ...{ reconnectAfterGnosis: true }, ...options };
const [, connect] = useConnect();
const [data, disconnect] = useAccount();
@@ -1,4 +1,8 @@
import { useNetwork as useWagmiNetwork } from "wagmi";
import invariant from "tiny-invariant";
import {
useNetwork as useWagmiNetwork,
useContext as useWagmiContext,
} from "wagmi";
/**
* Hook for getting metadata about the network the current wallet is connected to and switching networks
@@ -25,5 +29,10 @@ import { useNetwork as useWagmiNetwork } from "wagmi";
*/
export function useNetwork() {
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 useWagmiNetwork();
}
+95
View File
@@ -0,0 +1,95 @@
import { useThirdwebConnectedWalletContext } from "../contexts/thirdweb-wallet";
import { ContractAddress } from "../types";
import { cacheKeys } from "../utils/cache-keys";
import { useQuery } from "@tanstack/react-query";
import { useMemo } from "react";
/**
* A hook to get the native or (optional) ERC20 token balance of the connected wallet.
*
* @param tokenAddress - the address of the token contract, if empty will use the chain's native token
* @returns the balance of the connected wallet (native or ERC20)
* @beta
*/
export function useBalance(tokenAddress?: ContractAddress) {
const walletAddress = useAddress();
const { wallet, address, chainId } = useThirdwebConnectedWalletContext();
const cacheKey = useMemo(() => {
return cacheKeys.wallet.balance(chainId || -1, address, tokenAddress);
}, [chainId, tokenAddress, address]);
return useQuery(
cacheKey,
() => {
return wallet?.balance(tokenAddress);
},
{
// if user is not logged in no reason to try to fetch
enabled: !!wallet && !!walletAddress && !!chainId,
retry: true,
keepPreviousData: false,
},
);
}
/**
* @internal
*/
export function useConnectedWallet() {
return useThirdwebConnectedWalletContext().wallet;
}
/**
* Hook for accessing the address of the connected wallet
*
* ```javascript
* import { useAddress } from "@thirdweb-dev/react"
* ```
*
*
* @example
* To get the address of the connected wallet, you can use the hook as follows:
*
* ```javascript
* import { useAddress } from "@thirdweb-dev/react"
*
* const App = () => {
* const address = useAddress()
*
* return <div>{address}</div>
* }
* ```
*
* The `address` variable will hold the address of the connected wallet if a user has connected using one of the supported wallet connection hooks.
*
* @public
*/
export function useAddress(): string | undefined {
return useThirdwebConnectedWalletContext().address;
}
/**
* Hook for accessing the chain ID of the network the current wallet is connected to
*
* ```javascript
* import { useChainId } from "@thirdweb-dev/react"
* ```
*
* @example
* You can get the chain ID of the connected wallet by using the hook as follows:
* ```javascript
* import { useChainId } from "@thirdweb-dev/react"
*
* const App = () => {
* const chainId = useChainId()
*
* return <div>{chainId}</div>
* }
* ```
* @public
*/
export function useChainId(): number | undefined {
return useThirdwebConnectedWalletContext().chainId;
}
+27 -22
View File
@@ -1,36 +1,41 @@
// providers
export * from "./providers/base";
export * from "./providers/full";
// contract hooks
export * from "./Provider";
export * from "./hooks/auth";
export * from "./hooks/contracts";
export * from "./hooks/useDisconnect";
export * from "./hooks/useConnect";
export * from "./hooks/useSigner";
export * from "./hooks/useAddress";
export * from "./hooks/useReadonlySDK";
export * from "./hooks/connectors/useMetamask";
export * from "./hooks/connectors/useWalletConnect";
export * from "./hooks/connectors/useWalletLink";
export * from "./hooks/connectors/useGnosis";
export * from "./hooks/connectors/useMagic";
export * from "./hooks/useChainId";
export * from "./hooks/useNetworkMismatch";
export * from "./hooks/useNetwork";
// re-exports
export { defaultChains, defaultL2Chains, useAccount, useProvider } from "wagmi";
export { ChainId } from "@thirdweb-dev/sdk";
// async hooks
// async contract hooks
export * from "./hooks/async/contracts";
export * from "./hooks/async/nft";
export * from "./hooks/async/drop";
export * from "./hooks/async/marketplace";
export * from "./hooks/async/token";
export * from "./hooks/async/claim-conditions";
export * from "./hooks/async/wallet";
export * from "./hooks/async/contract-settings";
export * from "./hooks/async/roles";
// thirdweb hooks (work as long as at least `<ThirdwebSDkProvider>` is used)
export * from "./hooks/auth";
export * from "./hooks/useSigner";
export * from "./hooks/useReadonlySDK";
export * from "./hooks/useNetworkMismatch";
export * from "./hooks/wallet";
// require to be inside `<ThirdwebProvider />`
export * from "./hooks/wagmi-required/useAccount";
export * from "./hooks/wagmi-required/useNetwork";
export * from "./hooks/wagmi-required/useDisconnect";
export * from "./hooks/wagmi-required/useConnect";
export * from "./hooks/connectors/useMetamask";
export * from "./hooks/connectors/useWalletConnect";
export * from "./hooks/connectors/useWalletLink";
export * from "./hooks/connectors/useGnosis";
export * from "./hooks/connectors/useMagic";
// re-exports
export { ChainId } from "@thirdweb-dev/sdk";
// types
export * from "./types";
export type { ThirdwebAuthConfig } from "./contexts/thirdweb-auth";
+2 -2
View File
@@ -21,7 +21,7 @@ dispatch(Object.create(null));
}
export const useIsomorphicLayoutEffect = canUseDOM() ? useLayoutEffect : useEffect;
const useIsomorphicLayoutEffect = canUseDOM() ? useLayoutEffect : useEffect;
/**
@@ -39,7 +39,7 @@ export const useIsomorphicLayoutEffect = canUseDOM() ? useLayoutEffect : useEffe
const forceUpdate = useForceUpdate();
useLayoutEffect(() => {
useIsomorphicLayoutEffect(() => {
// This ref may be null when a hot-loader replaces components on the page
if (!mountNode.current) {return;}
// It's possible that the content of the portal has, itself, been portaled.
+164
View File
@@ -0,0 +1,164 @@
import {
ThirdwebAuthConfig,
ThirdwebAuthConfigProvider,
} from "../contexts/thirdweb-auth";
import {
ThirdwebConnectedWalletProvider,
useThirdwebConnectedWalletContext,
} from "../contexts/thirdweb-wallet";
import { RequiredParam } from "../types";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import {
ChainOrRpc,
SDKOptions,
SignerOrProvider,
SUPPORTED_CHAIN_ID,
ThirdwebSDK,
} from "@thirdweb-dev/sdk";
import { ThirdwebStorage } from "@thirdweb-dev/storage";
import { Signer } from "ethers";
import { createContext, useContext, useEffect, useMemo } from "react";
import invariant from "tiny-invariant";
interface TWSDKContext {
sdk?: ThirdwebSDK;
_inProvider?: true;
desiredChainId: number;
}
const ThirdwebSDKContext = createContext<TWSDKContext>({ desiredChainId: -1 });
export interface ThirdwebSDKProviderProps {
desiredChainId: RequiredParam<SUPPORTED_CHAIN_ID>;
provider: ChainOrRpc | SignerOrProvider;
signer?: Signer;
sdkOptions?: SDKOptions;
storageInterface?: ThirdwebStorage;
authConfig?: ThirdwebAuthConfig;
queryClient?: QueryClient;
}
/**
*
* @internal
*/
export const WrappedThirdwebSDKProvider: React.FC<
React.PropsWithChildren<Omit<ThirdwebSDKProviderProps, "signer">>
> = ({
sdkOptions,
desiredChainId,
storageInterface,
provider,
queryClient,
authConfig,
children,
}) => {
const queryClientWithDefault: QueryClient = useMemo(() => {
return queryClient ? queryClient : new QueryClient();
}, [queryClient]);
const { signer } = useThirdwebConnectedWalletContext();
const sdk = useMemo(() => {
if (!desiredChainId || typeof window === "undefined") {
return undefined;
}
const _sdk = new ThirdwebSDK(provider, sdkOptions, storageInterface);
(_sdk as any)._constructedAt = Date.now();
(_sdk as any)._chainId = desiredChainId;
return _sdk;
}, [provider, sdkOptions, storageInterface, desiredChainId]);
useEffect(() => {
if (signer && sdk && (sdk as any)._chainId === desiredChainId) {
sdk.updateSignerOrProvider(signer);
}
}, [signer, sdk, desiredChainId]);
const ctxValue = useMemo(
() => ({
sdk,
desiredChainId: desiredChainId || -1,
_inProvider: true as const,
}),
[desiredChainId, sdk],
);
return (
<ThirdwebAuthConfigProvider value={authConfig}>
<QueryClientProvider client={queryClientWithDefault}>
<ThirdwebSDKContext.Provider value={ctxValue}>
{children}
</ThirdwebSDKContext.Provider>
</QueryClientProvider>
</ThirdwebAuthConfigProvider>
);
};
/**
* A basic wrapper around the Thirdweb SDK.
*
* You can use this in order to be able to pass a provider & signer directly to the SDK.
*
* @remarks Utilizing this provider will mean hooks for wallet management are not available, if you need those please use the {@link ThirdwebProvider} instead.
*
* @public
*/
export const ThirdwebSDKProvider: React.FC<
React.PropsWithChildren<ThirdwebSDKProviderProps>
> = ({ signer, children, ...restProps }) => {
return (
<ThirdwebConnectedWalletProvider signer={signer}>
<WrappedThirdwebSDKProvider {...restProps}>
{children}
</WrappedThirdwebSDKProvider>
</ThirdwebConnectedWalletProvider>
);
};
/**
* @internal
*/
function useSDKContext(): TWSDKContext {
const ctx = useContext(ThirdwebSDKContext);
invariant(
ctx._inProvider,
"useSDK must be called from within a ThirdwebProvider, did you forget to wrap your app in a <ThirdwebProvider />?",
);
return ctx;
}
/**
*
* @returns {@link ThirdwebSDK}
* Access the instance of the thirdweb SDK created by the ThirdwebProvider
* to call methods using the connected wallet on the desiredChainId.
* @example
* ```javascript
* const sdk = useSDK();
* ```
*/
export function useSDK(): ThirdwebSDK | undefined {
const { sdk } = useSDKContext();
return sdk;
}
/**
* @internal
*/
export function useDesiredChainId(): number {
const { desiredChainId } = useSDKContext();
return desiredChainId;
}
/**
* @internal
*/
export function useSDKChainId(): SUPPORTED_CHAIN_ID | undefined {
const sdk = useSDK();
return (sdk as any)?._chainId;
}
@@ -1,40 +1,32 @@
import {
GnosisConnectorArguments,
GnosisSafeConnector,
} from "./connectors/gnosis-safe";
import { MagicConnector, MagicConnectorArguments } from "./connectors/magic";
} from "../connectors/gnosis-safe";
import { MagicConnector, MagicConnectorArguments } from "../connectors/magic";
import {
Chain,
SupportedChain,
defaultSupportedChains,
} from "./constants/chain";
import {
ThirdwebAuthConfig,
ThirdwebAuthConfigProvider,
} from "./contexts/thirdweb-auth";
} from "../constants/chain";
import { ThirdwebAuthConfig } from "../contexts/thirdweb-auth";
import {
ThirdwebConfigProvider,
defaultChainRpc,
} from "./contexts/thirdweb-config";
import { useSigner } from "./hooks/useSigner";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
} from "../contexts/thirdweb-config";
import { ThirdwebSDKProvider, ThirdwebSDKProviderProps } from "./base";
import { QueryClient } from "@tanstack/react-query";
import {
ChainOrRpc,
SDKOptions,
SUPPORTED_CHAIN_ID,
SignerOrProvider,
ThirdwebSDK,
getProviderForNetwork,
SDKOptionsOutput,
} from "@thirdweb-dev/sdk";
import type { ThirdwebStorage } from "@thirdweb-dev/storage";
import { Signer } from "ethers";
import React, { createContext, useEffect, useMemo, useState } from "react";
import invariant from "tiny-invariant";
import React, { useMemo } from "react";
import {
WagmiProvider,
ProviderProps as WagmiproviderProps,
useProvider,
useSigner,
} from "wagmi";
import { CoinbaseWalletConnector } from "wagmi/connectors/coinbaseWallet";
import { InjectedConnector } from "wagmi/connectors/injected";
@@ -447,194 +439,14 @@ export const ThirdwebProvider = <
);
};
export interface ThirdwebSDKProviderWagmiWrapper
extends Pick<
ThirdwebProviderProps,
"desiredChainId" | "sdkOptions" | "storageInterface" | "authConfig"
> {
signer?: Signer;
provider: ChainOrRpc | SignerOrProvider;
queryClient?: QueryClient;
}
const ThirdwebSDKProviderWagmiWrapper: React.FC<
React.PropsWithChildren<
Omit<ThirdwebSDKProviderWagmiWrapper, "signer" | "provider">
>
React.PropsWithChildren<Omit<ThirdwebSDKProviderProps, "signer" | "provider">>
> = ({ children, ...props }) => {
const provider = useProvider();
const signer = useSigner();
const [signer] = useSigner();
return (
<ThirdwebSDKProvider signer={signer} provider={provider} {...props}>
<ThirdwebSDKProvider signer={signer.data} provider={provider} {...props}>
{children}
</ThirdwebSDKProvider>
);
};
interface SDKContext {
sdk?: ThirdwebSDK;
_inProvider?: true;
desiredChainId: number;
}
const ThirdwebSDKContext = createContext<SDKContext>({ desiredChainId: -1 });
export interface ThirdwebSDKProviderProps
extends Omit<ThirdwebSDKProviderWagmiWrapper, "queryClient"> {
queryClient?: QueryClient;
}
/**
* A barebones wrapper around the Thirdweb SDK.
*
* You can use this in order to be able to pass a provider & signer directly to the SDK.
*
* @remarks Utilizing this provider will mean hooks for wallet management are not available, if you need those please use the {@link ThirdwebProvider} instead.
*
* @beta
*/
export const ThirdwebSDKProvider: React.FC<
React.PropsWithChildren<ThirdwebSDKProviderProps>
> = ({
sdkOptions,
desiredChainId,
storageInterface,
provider,
signer,
queryClient,
authConfig,
children,
}) => {
const queryClientWithDefault: QueryClient = useMemo(() => {
return queryClient ? queryClient : new QueryClient();
}, [queryClient]);
const sdk = useMemo(() => {
if (!desiredChainId || typeof window === "undefined") {
return undefined;
}
const _sdk = new ThirdwebSDK(provider, sdkOptions, storageInterface);
(_sdk as any)._constructedAt = Date.now();
(_sdk as any)._chainId = desiredChainId;
return _sdk;
}, [provider, sdkOptions, storageInterface, desiredChainId]);
useEffect(() => {
if (signer && sdk && (sdk as any)._chainId === desiredChainId) {
sdk.updateSignerOrProvider(signer);
}
}, [signer, sdk, desiredChainId]);
const ctxValue = useMemo(
() => ({
sdk,
desiredChainId: desiredChainId || -1,
_inProvider: true as const,
}),
[desiredChainId, sdk],
);
return (
<ThirdwebAuthConfigProvider value={authConfig}>
<QueryClientProvider client={queryClientWithDefault}>
<ThirdwebSDKContext.Provider value={ctxValue}>
{children}
</ThirdwebSDKContext.Provider>
</QueryClientProvider>
</ThirdwebAuthConfigProvider>
);
};
/**
* @internal
*/
function useSDKContext(): SDKContext {
const ctx = React.useContext(ThirdwebSDKContext);
invariant(
ctx._inProvider,
"useSDK must be called from within a ThirdwebProvider, did you forget to wrap your app in a <ThirdwebProvider />?",
);
return ctx;
}
/**
*
* @returns {@link ThirdwebSDK}
* Access the instance of the thirdweb SDK created by the ThirdwebProvider
* to call methods using the connected wallet on the desiredChainId.
* @example
* ```javascript
* const sdk = useSDK();
* ```
*/
export function useSDK(): ThirdwebSDK | undefined {
const { sdk } = useSDKContext();
return sdk;
}
/**
* @internal
*/
export function useDesiredChainId(): number {
const { desiredChainId } = useSDKContext();
return desiredChainId;
}
/**
* @internal
*/
export function useActiveChainId(): SUPPORTED_CHAIN_ID | undefined {
const sdk = useSDK();
return (sdk as any)?._chainId;
}
/**
* @internal
*/
export function useActiveSigner(): Signer | undefined {
const sdk = useSDK();
const [signer, setSigner] = useState<Signer | undefined>(sdk?.getSigner());
useEffect(() => {
if (sdk) {
sdk.wallet.events.on("signerChanged", (newSigner: Signer | undefined) => {
setSigner(newSigner);
});
return () => {
sdk.wallet.events.off("signerChanged");
};
}
}, [sdk]);
return signer;
}
/**
* @internal
*/
export function useActiveSignerAddress(): string | undefined {
const signer = useActiveSigner();
const [address, setAddress] = useState<string | undefined>(undefined);
useEffect(() => {
if (signer) {
signer.getAddress().then((a) => {
setAddress(a);
});
}
}, [signer]);
return address;
}
/**
* @internal
*/
export function useActiveSignerChainId(): number | undefined {
const signer = useActiveSigner();
const [chainId, setChainId] = useState<number | undefined>(undefined);
useEffect(() => {
if (signer) {
signer.getChainId().then((id) => {
setChainId(id);
});
}
}, [signer]);
return chainId;
}
@@ -0,0 +1,6 @@
import { ThirdwebSDKContext } from "../providers/ThirdwebSDKProvider";
import { useContext } from "react";
export function useSDK() {
return useContext(ThirdwebSDKContext);
}
+5
View File
@@ -0,0 +1,5 @@
// Providers
export * from "./providers/ThirdwebSDKProvider";
export * from "./providers/ThirdwebProvider";
// Hooks
export * from "./hooks/useSDK";
@@ -0,0 +1,66 @@
import { ThirdwebSDKProvider } from "./ThirdwebSDKProvider";
import type { WalletAdapter } from "@solana/wallet-adapter-base";
import {
ConnectionProvider,
useConnection,
useWallet,
WalletProvider,
} from "@solana/wallet-adapter-react";
import { PhantomWalletAdapter } from "@solana/wallet-adapter-wallets";
import { getUrlForNetwork, Network } from "@thirdweb-dev/solana";
import { PropsWithChildren } from "react";
interface ThirdwebProviderProps {
endpoint: Network;
wallets?: WalletAdapter[];
autoConnect?: boolean;
}
const DEFAULT_WALLETS = [new PhantomWalletAdapter()];
/**
* Gives access to the ThirdwebSDK instance and other useful hooks to the rest of the app.
* Requires to be wrapped with a ConnectionProvider and a WalletProvider from @solana/wallet-adapter-react.
* @example
* ```tsx
* import { ThirdwebProvider } from "@thirdweb-dev/react/solana";
*
* const App = () => {
* return (
* <ThirdwebProvider endpoint="devnet">
* <YourApp />
* </ThirdwebProvider>
* )};
* ```
* @beta
*/
export const ThirdwebProvider: React.FC<
PropsWithChildren<ThirdwebProviderProps>
> = ({ endpoint, wallets, autoConnect, children }) => {
const clusterUrl = getUrlForNetwork(endpoint);
return (
<ConnectionProvider endpoint={clusterUrl}>
<WalletProvider
wallets={wallets || DEFAULT_WALLETS}
autoConnect={autoConnect || true}
>
<ThirdwebWrapperProvider>{children}</ThirdwebWrapperProvider>
</WalletProvider>
</ConnectionProvider>
);
};
/**
* @internal
*/
export const ThirdwebWrapperProvider: React.FC<PropsWithChildren> = ({
children,
}) => {
const { connection } = useConnection();
const wallet = useWallet();
return (
<ThirdwebSDKProvider connection={connection} wallet={wallet}>
{children}
</ThirdwebSDKProvider>
);
};
@@ -0,0 +1,68 @@
import type { WalletContextState } from "@solana/wallet-adapter-react";
import type { Connection } from "@solana/web3.js";
import { ThirdwebSDK } from "@thirdweb-dev/solana";
import {
createContext,
FC,
PropsWithChildren,
useEffect,
useState,
} from "react";
interface ThirdwebSDKProviderProps {
connection: Connection;
wallet?: WalletContextState;
}
/**
* Gives access to the ThirdwebSDK instance and other useful hooks to the rest of the app.
* Requires to be wrapped with a ConnectionProvider and a WalletProvider from @solana/wallet-adapter-react.
* @example
* ```tsx
* import {
* useConnection,
* useWallet,
* } from "@solana/wallet-adapter-react";
* import { ThirdwebProvider } from "@thirdweb-dev/react/solana";
*
* const ThirdwebApp = () => {
* const { connection } = useConnection();
* const wallet = useWallet();
* return (
* <ThirdwebSDKProvider connection={connection} wallet={wallet}>
* <YourApp />
* </ThirdwebSDKProvider>
* )};
* ```
*/
export const ThirdwebSDKProvider: FC<
PropsWithChildren<ThirdwebSDKProviderProps>
> = ({ children, connection, wallet }) => {
const [sdk, setSDK] = useState<ThirdwebSDK | null>(null);
useEffect(() => {
if (connection) {
setSDK(new ThirdwebSDK(connection));
} else {
setSDK(null);
}
}, [connection]);
useEffect(() => {
if (sdk) {
if (wallet?.publicKey) {
sdk.wallet.connect(wallet);
} else {
sdk.wallet.disconnect();
}
}
}, [sdk, wallet]);
return (
<ThirdwebSDKContext.Provider value={sdk}>
{children}
</ThirdwebSDKContext.Provider>
);
};
export const ThirdwebSDKContext = createContext<ThirdwebSDK | null>(null);
+13 -17
View File
@@ -14,12 +14,12 @@ import type {
Erc20,
ClaimOptions,
} from "@thirdweb-dev/sdk";
import type { EditionImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/edition";
import type { EditionDropImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/edition-drop";
import type { NFTCollectionImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/nft-collection";
import type { NFTDropImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/nft-drop";
import type { SignatureDropImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/signature-drop";
import type { TokenDropImpl } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/token-drop";
import type { Edition } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/edition";
import type { EditionDrop } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/edition-drop";
import type { NFTCollection } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/nft-collection";
import type { NFTDrop } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/nft-drop";
import type { SignatureDrop } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/signature-drop";
import type { TokenDrop } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/prebuilt-implementations/token-drop";
import type { SmartContract } from "@thirdweb-dev/sdk/dist/declarations/src/contracts/smart-contract";
import type { BigNumberish } from "ethers";
@@ -72,8 +72,8 @@ export type TokenBurnParams = {
* @beta
*/
export type NFTContract =
| NFTCollectionImpl
| EditionImpl
| NFTCollection
| Edition
| Exclude<DropContract, "TokenDrop">;
/**
@@ -172,10 +172,10 @@ export type BurnNFTParams = { tokenId: BigNumberish; amount?: Amount };
* @beta
*/
export type DropContract =
| NFTDropImpl
| EditionDropImpl
| SignatureDropImpl
| TokenDropImpl
| NFTDrop
| EditionDrop
| SignatureDrop
| TokenDrop
| SmartContract
| null;
@@ -183,11 +183,7 @@ export type DropContract =
* The possible revealable contract types.
* @beta
*/
export type RevealableContract =
| NFTDropImpl
| SignatureDropImpl
| SmartContract
| null;
export type RevealableContract = NFTDrop | SignatureDrop | SmartContract | null;
/**
* The params for the {@link useDelayedRevealLazyMint} hook mutation.
+17 -13
View File
@@ -1,15 +1,19 @@
import { __DEV__ } from "../constants/runtime";
const warnSet = new Set<`${string}:${string}`>();
export const showDeprecationWarning =
// eslint-disable-next-line turbo/no-undeclared-env-vars
process.env.NODE_ENV !== "production"
? (deprecated: string, replacement: string) => {
if (warnSet.has(`${deprecated}:${replacement}`)) {
return;
}
warnSet.add(`${deprecated}:${replacement}`);
console.warn(
`\`${deprecated}\` is deprecated and will be removed in a future version. Please use \`${replacement}\` instead.`,
);
}
: () => undefined;
export const showDeprecationWarning = (
deprecated: string,
replacement: string,
) => {
// deprecation warnings only in dev only in dev
if (__DEV__) {
if (warnSet.has(`${deprecated}:${replacement}`)) {
return;
}
warnSet.add(`${deprecated}:${replacement}`);
console.warn(
`\`${deprecated}\` is deprecated and will be removed in a future major version. Please use \`${replacement}\` instead.`,
);
}
};
+1 -1
View File
@@ -27,7 +27,7 @@ export async function resolveMimeType(url?: string) {
method: "HEAD",
});
if (res.ok && res.headers.has("content-type")) {
return res.headers.get("content-type") ?? undefined;
return res.headers.get("content-type") || undefined;
}
// we failed to resolve the mime type, return null
return undefined;
+13
View File
@@ -0,0 +1,13 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json",
"extends": ["@microsoft/api-extractor/extends/tsdoc-base.json"],
"tagDefinitions": [
{
"tagName": "@twfeature",
"syntaxKind": "block"
}
],
"supportForTags": {
"@twfeature": true
}
}
+3
View File
@@ -1,6 +1,9 @@
module.exports = {
root: true,
extends: ["thirdweb"],
rules: {
"import/no-cycle": "off",
},
// allow all imports from within tests
overrides: [
{
+51
View File
@@ -1,5 +1,56 @@
# @thirdweb-dev/sdk
## 3.0.8
### Patch Changes
- [#205](https://github.com/thirdweb-dev/js/pull/205) [`ce05bfd`](https://github.com/thirdweb-dev/js/commit/ce05bfd8615a9c79664856bce53de8b43bed5c87) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Fix Buffer usage in SDK
## 3.0.7
### Patch Changes
- [#199](https://github.com/thirdweb-dev/js/pull/199) [`5f5ab01`](https://github.com/thirdweb-dev/js/commit/5f5ab015e1dd3c471d6affe995ef36ec88932b3c) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Fix getOwned for signature drop
## 3.0.6
### Patch Changes
- [#195](https://github.com/thirdweb-dev/js/pull/195) [`a80fc97`](https://github.com/thirdweb-dev/js/commit/a80fc97b6a1e72ed46a400b4b602e180947fb870) Thanks [@jnsdls](https://github.com/jnsdls)! - add missing roles for pre-built contracts
- Updated dependencies [[`24f66e3`](https://github.com/thirdweb-dev/js/commit/24f66e38c256f7bd69341b92ba30bd35d14b1caa)]:
- @thirdweb-dev/storage@1.0.3
## 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
- [#174](https://github.com/thirdweb-dev/js/pull/174) [`3b877ba`](https://github.com/thirdweb-dev/js/commit/3b877ba221acfd85f80b99e1bc382055217f0a39) Thanks [@kumaryash90](https://github.com/kumaryash90)! - detect forwarder address for defender
- [#163](https://github.com/thirdweb-dev/js/pull/163) [`b54f95d`](https://github.com/thirdweb-dev/js/commit/b54f95dc906928ff2f9251748f254a16fe1f2cee) Thanks [@adam-maj](https://github.com/adam-maj)! - Use independent JSON types by package
- [#154](https://github.com/thirdweb-dev/js/pull/154) [`f8ab477`](https://github.com/thirdweb-dev/js/commit/f8ab4779bb2d6d66200e1e8fd558e0ac069a2f54) Thanks [@jnsdls](https://github.com/jnsdls)! - Add fiat checkout to nft-drop, edition-drop and signature-drop
- [#162](https://github.com/thirdweb-dev/js/pull/162) [`772f843`](https://github.com/thirdweb-dev/js/commit/772f8431e3a62d0ded62dae90a43e9a7edd5b1a2) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Catch gas estimate errors in gasless tx
- [#188](https://github.com/thirdweb-dev/js/pull/188) [`a9ec190`](https://github.com/thirdweb-dev/js/commit/a9ec190ff99d2714cef2500d20ea0f3f73f07be3) Thanks [@adam-maj](https://github.com/adam-maj)! - Update JSON schema in SDKs
- [#168](https://github.com/thirdweb-dev/js/pull/168) [`208b038`](https://github.com/thirdweb-dev/js/commit/208b0389a50ea48bbb9600fec60fec2f1671d4b9) Thanks [@jnsdls](https://github.com/jnsdls)! - Switch naming of exported prebuilt contract types back from `<name>Impl` to `<name>` for easier use
- [#161](https://github.com/thirdweb-dev/js/pull/161) [`5345479`](https://github.com/thirdweb-dev/js/commit/534547992243bdd3a77e34ec2b2487b5adab366a) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Allow forcing direct deploys to deploy implementations from release flow
- Updated dependencies [[`493ebf0`](https://github.com/thirdweb-dev/js/commit/493ebf032e82a66006b3d5b68f8eeff1973fc97a), [`b54f95d`](https://github.com/thirdweb-dev/js/commit/b54f95dc906928ff2f9251748f254a16fe1f2cee), [`cfe8bba`](https://github.com/thirdweb-dev/js/commit/cfe8bbafa464a9e768e6d31fbd9dd9760fdced16), [`f4074dd`](https://github.com/thirdweb-dev/js/commit/f4074ddadc9fb6e18dcc9251a936376c3f4a9144), [`d608cea`](https://github.com/thirdweb-dev/js/commit/d608cea1977dd418b6892c1c9368b06b17a9748b), [`3580182`](https://github.com/thirdweb-dev/js/commit/3580182fa903ed7a661444f0daa160c330e62ec5), [`0ccbca7`](https://github.com/thirdweb-dev/js/commit/0ccbca78dce38926ccfd5c902c06adff2f440f42), [`45a400f`](https://github.com/thirdweb-dev/js/commit/45a400fd9287582bfb5f21ab2cb2d7a4332434c5)]:
- @thirdweb-dev/storage@1.0.2
## 3.0.4
### Patch Changes
- Updated dependencies [[`964add6`](https://github.com/thirdweb-dev/js/commit/964add6f205577298b8f4b9ce7298e5bf09e88e7)]:
- @thirdweb-dev/storage@1.0.1
## 3.0.3
### Patch Changes
+46
View File
@@ -0,0 +1,46 @@
# Migration Guide
If you are looking to upgrade from an earlier version of the SDK, below are the breaking changes that you should be aware of between each version.
## Upgrading to Version 3
Version 3 of the 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/).
### Getting Contracts is now Async
The `getContract` and similar functions such as `getNFTDrop` or `getMarketplace` are now asynchronous. This means that you will need to `await` the result of these functions before using them.
**Custom**:
```diff
- const contract = getContract("0x...")
+ const contract = await getContract("0x...")
```
**Prebuilt**:
```diff
- const contract = getNFTDrop("0x...")
+ const contract = await getNFTDrop("0x...")
```
### New Contract Namespaces
When working with contracts, 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(...)
```
+4 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/sdk",
"version": "3.0.3",
"version": "3.0.8",
"description": "The main thirdweb SDK.",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/sdk",
"license": "Apache-2.0",
@@ -20,7 +20,8 @@
"build": "tsc && preconstruct build",
"test:all": "SWC_NODE_PROJECT=./tsconfig.test.json mocha --timeout 30000 --parallel './test/**/*.test.ts'",
"test": "make test",
"test:single": "SWC_NODE_PROJECT=./tsconfig.test.json mocha --timeout 30000"
"test:single": "SWC_NODE_PROJECT=./tsconfig.test.json mocha --timeout 30000",
"push": "yalc push"
},
"devDependencies": {
"@esbuild-plugins/node-modules-polyfill": "^0.1.4",
@@ -73,7 +74,7 @@
"merkletreejs": "^0.2.24",
"multihashes": "^4.0.3",
"tiny-invariant": "^1.2.0",
"uuid": "^8.3.2",
"uuid": "^9.0.0",
"zod": "^3.11.6"
},
"resolutions": {
+3 -28
View File
@@ -46,33 +46,8 @@ function languageNameToKey(languageName) {
}
}
const additionalClassesToParse = [
"ThirdwebSDK",
"ContractDeployer",
"MarketplaceDirect",
"MarketplaceAuction",
"ContractMetadata",
"ContractEvents",
"DelayedReveal",
"ContractRoles",
"RemoteStorage",
"GasCostEstimator",
"ContractInterceptor",
"ContractRoles",
"DropClaimConditions",
"ContractPrimarySale",
"ContractRoyalty",
"ContractPlatformFee",
"WalletAuthenticator",
"UserWallet",
"SmartContract",
];
const modules = json.members[0].members.filter(
(m) =>
(m.kind === "Class" && m.name.endsWith("Impl")) ||
additionalClassesToParse.includes(m.name),
);
// just include all classes
const modules = json.members[0].members.filter((m) => m.kind === "Class");
const bases = ["StandardErc20", "StandardErc721", "StandardErc1155"];
const baseClasses = json.members[0].members.filter(
@@ -152,7 +127,7 @@ const moduleMap = modules.reduce((acc, m) => {
const baseClassMembers = baseClassCode
? parseMembers(baseClassCode.members, "Method", baseClassCode.name)
: [];
acc[m.name.replace("Impl", "")] = {
acc[m.name] = {
name: m.name,
summary: Formatter.renderDocNode(docComment.summarySection),
remarks: docComment.remarksBlock
+10 -10
View File
@@ -112,7 +112,7 @@ export function extractConstructorParamsFromAbi(
) {
for (const input of abi) {
if (input.type === "constructor") {
return input.inputs ?? [];
return input.inputs || [];
}
}
return [];
@@ -131,7 +131,7 @@ export function extractFunctionParamsFromAbi(
) {
for (const input of abi) {
if (input.type === "function" && input.name === functionName) {
return input.inputs ?? [];
return input.inputs || [];
}
}
return [];
@@ -159,11 +159,11 @@ export function extractFunctionsFromAbi(
const promise = out ? `: Promise<${out}>` : `: Promise<TransactionResult>`;
const signature = `contract.call("${f.name}"${fargs})${promise}`;
parsed.push({
inputs: f.inputs ?? [],
outputs: f.outputs ?? [],
name: f.name ?? "unknown",
inputs: f.inputs || [],
outputs: f.outputs || [],
name: f.name || "unknown",
signature,
stateMutability: f.stateMutability ?? "",
stateMutability: f.stateMutability || "",
comment: doc,
});
}
@@ -184,9 +184,9 @@ export function extractEventsFromAbi(
for (const e of events) {
const doc = extractCommentFromMetadata(e.name, metadata, "events");
parsed.push({
inputs: e.inputs ?? [],
outputs: e.outputs ?? [],
name: e.name ?? "unknown",
inputs: e.inputs || [],
outputs: e.outputs || [],
name: e.name || "unknown",
comment: doc,
});
}
@@ -271,7 +271,7 @@ async function extractIPFSHashFromBytecode(
const cborLength: number =
numericBytecode[numericBytecode.length - 2] * 0x100 +
numericBytecode[numericBytecode.length - 1];
const bytecodeBuffer = Buffer.from(
const bytecodeBuffer = Uint8Array.from(
numericBytecode.slice(numericBytecode.length - 2 - cborLength, -2),
);
+4 -4
View File
@@ -130,8 +130,8 @@ export async function signDAIPermit(
verifyingContract: currencyAddress,
});
nonce = nonce ?? (await getSignerNonce(signer, currencyAddress)).toString();
deadline = deadline ?? ethers.constants.MaxUint256;
nonce = nonce || (await getSignerNonce(signer, currencyAddress)).toString();
deadline = deadline || ethers.constants.MaxUint256;
const message = {
owner,
@@ -185,8 +185,8 @@ export async function signEIP2612Permit(
verifyingContract: currencyAddress,
});
nonce = nonce ?? (await getSignerNonce(signer, currencyAddress)).toString();
deadline = deadline ?? ethers.constants.MaxUint256;
nonce = nonce || (await getSignerNonce(signer, currencyAddress)).toString();
deadline = deadline || ethers.constants.MaxUint256;
const message = {
owner,
+19 -1
View File
@@ -18,6 +18,7 @@ export const CONTRACT_ADDRESSES: Record<
SUPPORTED_CHAIN_ID,
{
openzeppelinForwarder: string;
openzeppelinForwarderEOA: string;
biconomyForwarder: string;
twFactory: string;
twRegistry: string;
@@ -26,6 +27,7 @@ export const CONTRACT_ADDRESSES: Record<
> = {
[ChainId.Mainnet]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0x76ce2CB1Ae48Fa067f4fb8c5f803111AE0B24BEA",
biconomyForwarder: "0x84a0856b038eaAd1cC7E297cF34A7e72685A8693",
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
@@ -33,6 +35,7 @@ export const CONTRACT_ADDRESSES: Record<
},
[ChainId.Rinkeby]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0x0bBA31EAf82C649C0B9579F5F44374C74F4605Ea",
biconomyForwarder: "0xFD4973FeB2031D4409fB57afEE5dF2051b171104",
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
@@ -40,6 +43,7 @@ export const CONTRACT_ADDRESSES: Record<
},
[ChainId.Goerli]: {
openzeppelinForwarder: "0x5001A14CA6163143316a7C614e30e6041033Ac20",
openzeppelinForwarderEOA: "0xe73c50cB9c5B378627ff625BB6e6725A4A5D65d2",
biconomyForwarder: constants.AddressZero,
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
@@ -47,6 +51,7 @@ export const CONTRACT_ADDRESSES: Record<
},
[ChainId.Polygon]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0x4f247c69184ad61036EC2Bb3213b69F10FbEDe1F",
biconomyForwarder: "0x86C80a8aa58e0A4fa09A69624c31Ab2a6CAD56b8",
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
@@ -54,6 +59,7 @@ export const CONTRACT_ADDRESSES: Record<
},
[ChainId.Mumbai]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0xb1A2883fc4d287d9cB8Dbb96cFF60C76BEf2D250",
biconomyForwarder: "0x9399BB24DBB5C4b782C70c2969F58716Ebbd6a3b",
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
@@ -61,6 +67,7 @@ export const CONTRACT_ADDRESSES: Record<
},
[ChainId.Avalanche]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0xb1A2883fc4d287d9cB8Dbb96cFF60C76BEf2D250",
biconomyForwarder: "0x64CD353384109423a966dCd3Aa30D884C9b2E057",
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
@@ -68,6 +75,7 @@ export const CONTRACT_ADDRESSES: Record<
},
[ChainId.AvalancheFujiTestnet]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0xe73c50cB9c5B378627ff625BB6e6725A4A5D65d2",
biconomyForwarder: "0x6271Ca63D30507f2Dcbf99B52787032506D75BBF",
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
@@ -75,6 +83,7 @@ export const CONTRACT_ADDRESSES: Record<
},
[ChainId.Fantom]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0xb1A2883fc4d287d9cB8Dbb96cFF60C76BEf2D250",
biconomyForwarder: constants.AddressZero,
twFactory: "0x97EA0Fcc552D5A8Fb5e9101316AAd0D62Ea0876B",
twRegistry: TWRegistry_address,
@@ -82,6 +91,7 @@ export const CONTRACT_ADDRESSES: Record<
},
[ChainId.FantomTestnet]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0x42D3048b595B6e1c28a588d70366CcC2AA4dB47b",
biconomyForwarder: constants.AddressZero,
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
@@ -89,6 +99,7 @@ export const CONTRACT_ADDRESSES: Record<
},
[ChainId.Arbitrum]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0x4f247c69184ad61036EC2Bb3213b69F10FbEDe1F",
biconomyForwarder: constants.AddressZero,
twFactory: "0xd24b3de085CFd8c54b94feAD08a7962D343E6DE0",
twRegistry: "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd",
@@ -96,6 +107,7 @@ export const CONTRACT_ADDRESSES: Record<
},
[ChainId.ArbitrumRinkeby]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0xE1eE43D23f247b6A9aF81fcE2766E76709482728",
biconomyForwarder: constants.AddressZero,
twFactory: "0xb0435b47ad26115A39c59735b814f3769F07C2c1",
twRegistry: "0xcF4c511551aE4dab1F997866FC3900cd2aaeC40D",
@@ -103,6 +115,7 @@ export const CONTRACT_ADDRESSES: Record<
},
[ChainId.ArbitrumGoerli]: {
openzeppelinForwarder: "0x8cbc8B5d71702032904750A66AEfE8B603eBC538",
openzeppelinForwarderEOA: "0x119704314Ef304EaAAE4b3c7C9ABd59272A28310",
biconomyForwarder: constants.AddressZero,
twFactory: "0xd24b3de085CFd8c54b94feAD08a7962D343E6DE0",
twRegistry: "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd",
@@ -110,6 +123,7 @@ export const CONTRACT_ADDRESSES: Record<
},
[ChainId.Optimism]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0x7e80648EB2071E26937F9D42A513ccf4815fc702",
biconomyForwarder: constants.AddressZero,
twFactory: "0xd24b3de085CFd8c54b94feAD08a7962D343E6DE0",
twRegistry: "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd",
@@ -117,6 +131,7 @@ export const CONTRACT_ADDRESSES: Record<
},
[ChainId.OptimismKovan]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0xE8dd2Ff0212F86d3197b4AfDC6dAC6ac47eb10aC",
biconomyForwarder: constants.AddressZero,
twFactory: "0xd24b3de085CFd8c54b94feAD08a7962D343E6DE0",
twRegistry: "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd",
@@ -124,6 +139,7 @@ export const CONTRACT_ADDRESSES: Record<
},
[ChainId.OptimismGoerli]: {
openzeppelinForwarder: "0x8cbc8B5d71702032904750A66AEfE8B603eBC538",
openzeppelinForwarderEOA: "0x119704314Ef304EaAAE4b3c7C9ABd59272A28310",
biconomyForwarder: constants.AddressZero,
twFactory: "0xd24b3de085CFd8c54b94feAD08a7962D343E6DE0",
twRegistry: "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd",
@@ -131,6 +147,7 @@ export const CONTRACT_ADDRESSES: Record<
},
[ChainId.BinanceSmartChainMainnet]: {
openzeppelinForwarder: "0x8cbc8B5d71702032904750A66AEfE8B603eBC538",
openzeppelinForwarderEOA: "0xE8dd2Ff0212F86d3197b4AfDC6dAC6ac47eb10aC",
biconomyForwarder: constants.AddressZero,
twBYOCRegistry: constants.AddressZero,
twFactory: "0xd24b3de085CFd8c54b94feAD08a7962D343E6DE0",
@@ -138,6 +155,7 @@ export const CONTRACT_ADDRESSES: Record<
},
[ChainId.BinanceSmartChainTestnet]: {
openzeppelinForwarder: "0x8cbc8B5d71702032904750A66AEfE8B603eBC538",
openzeppelinForwarderEOA: "0x7e80648EB2071E26937F9D42A513ccf4815fc702",
biconomyForwarder: constants.AddressZero,
twBYOCRegistry: constants.AddressZero,
twFactory: "0xd24b3de085CFd8c54b94feAD08a7962D343E6DE0",
@@ -179,4 +197,4 @@ export function getContractPublisherAddress() {
} else {
return ContractPublisher_address;
}
}
}
+50 -74
View File
@@ -24,7 +24,7 @@ type InitalizeParams = [
options?: SDKOptions,
];
export const EditionDrop = {
export const EditionDropInitializer = {
name: "DropERC1155" as const,
contractType: "edition-drop" as const,
schema: DropErc1155ContractSchema,
@@ -33,24 +33,18 @@ export const EditionDrop = {
...[network, address, storage, options]: InitalizeParams
) => {
const [abi, contract] = await Promise.all([
EditionDrop.getAbi(),
EditionDropInitializer.getAbi(),
import("./prebuilt-implementations/edition-drop"),
]);
return new contract.EditionDropImpl(
network,
address,
storage,
options,
abi,
);
return new contract.EditionDrop(network, address, storage, options, abi);
},
getAbi: async () =>
(await import("@thirdweb-dev/contracts-js/dist/abis/DropERC1155.json"))
.default,
};
export const Edition = {
export const EditionInitializer = {
name: "TokenERC1155" as const,
contractType: "edition" as const,
schema: TokenErc1155ContractSchema,
@@ -59,18 +53,18 @@ export const Edition = {
...[network, address, storage, options]: InitalizeParams
) => {
const [abi, contract] = await Promise.all([
Edition.getAbi(),
EditionInitializer.getAbi(),
import("./prebuilt-implementations/edition"),
]);
return new contract.EditionImpl(network, address, storage, options, abi);
return new contract.Edition(network, address, storage, options, abi);
},
getAbi: async () =>
(await import("@thirdweb-dev/contracts-js/dist/abis/TokenERC1155.json"))
.default,
};
export const Marketplace = {
export const MarketplaceInitializer = {
name: "Marketplace" as const,
contractType: "marketplace" as const,
schema: MarketplaceContractSchema,
@@ -79,44 +73,38 @@ export const Marketplace = {
...[network, address, storage, options]: InitalizeParams
) => {
const [abi, contract] = await Promise.all([
Marketplace.getAbi(),
MarketplaceInitializer.getAbi(),
import("./prebuilt-implementations/marketplace"),
]);
return new contract.MarketplaceImpl(
network,
address,
storage,
options,
abi,
);
return new contract.Marketplace(network, address, storage, options, abi);
},
getAbi: async () =>
(await import("@thirdweb-dev/contracts-js/dist/abis/Marketplace.json"))
.default,
};
export const Multiwrap = {
export const MultiwrapInitializer = {
name: "Multiwrap" as const,
contractType: "multiwrap" as const,
schema: MultiwrapContractSchema,
roles: ["transfer", "minter", "unwrap", "asset"] as const,
roles: ["admin", "transfer", "minter", "unwrap", "asset"] as const,
initialize: async (
...[network, address, storage, options]: InitalizeParams
) => {
const [abi, contract] = await Promise.all([
Multiwrap.getAbi(),
MultiwrapInitializer.getAbi(),
import("./prebuilt-implementations/multiwrap"),
]);
return new contract.MultiwrapImpl(network, address, storage, options, abi);
return new contract.Multiwrap(network, address, storage, options, abi);
},
getAbi: async () =>
(await import("@thirdweb-dev/contracts-js/dist/abis/Multiwrap.json"))
.default,
};
export const NFTCollection = {
export const NFTCollectionInitializer = {
name: "TokenERC721" as const,
contractType: "nft-collection" as const,
schema: TokenErc721ContractSchema,
@@ -126,24 +114,18 @@ export const NFTCollection = {
...[network, address, storage, options]: InitalizeParams
) => {
const [abi, contract] = await Promise.all([
NFTCollection.getAbi(),
NFTCollectionInitializer.getAbi(),
import("./prebuilt-implementations/nft-collection"),
]);
return new contract.NFTCollectionImpl(
network,
address,
storage,
options,
abi,
);
return new contract.NFTCollection(network, address, storage, options, abi);
},
getAbi: async () =>
(await import("@thirdweb-dev/contracts-js/dist/abis/TokenERC721.json"))
.default,
};
export const NFTDrop = {
export const NFTDropInitializer = {
name: "DropERC721" as const,
contractType: "nft-drop" as const,
schema: DropErc721ContractSchema,
@@ -152,38 +134,38 @@ export const NFTDrop = {
...[network, address, storage, options]: InitalizeParams
) => {
const [abi, contract] = await Promise.all([
NFTDrop.getAbi(),
NFTDropInitializer.getAbi(),
import("./prebuilt-implementations/nft-drop"),
]);
return new contract.NFTDropImpl(network, address, storage, options, abi);
return new contract.NFTDrop(network, address, storage, options, abi);
},
getAbi: async () =>
(await import("@thirdweb-dev/contracts-js/dist/abis/DropERC721.json"))
.default,
};
export const Pack = {
export const PackInitializer = {
name: "Pack" as const,
contractType: "pack" as const,
schema: PackContractSchema,
roles: ["admin", "minter", "pauser", "transfer"] as const,
roles: ["admin", "minter", "asset", "transfer"] as const,
initialize: async (
...[network, address, storage, options]: InitalizeParams
) => {
const [abi, contract] = await Promise.all([
Pack.getAbi(),
PackInitializer.getAbi(),
import("./prebuilt-implementations/pack"),
]);
return new contract.PackImpl(network, address, storage, options, abi);
return new contract.Pack(network, address, storage, options, abi);
},
getAbi: async () =>
(await import("@thirdweb-dev/contracts-js/dist/abis/Pack.json")).default,
};
export const SignatureDrop = {
export const SignatureDropInitializer = {
name: "SignatureDrop" as const,
contractType: "signature-drop" as const,
schema: DropErc721ContractSchema,
@@ -193,24 +175,18 @@ export const SignatureDrop = {
...[network, address, storage, options]: InitalizeParams
) => {
const [abi, contract] = await Promise.all([
SignatureDrop.getAbi(),
SignatureDropInitializer.getAbi(),
import("./prebuilt-implementations/signature-drop"),
]);
return new contract.SignatureDropImpl(
network,
address,
storage,
options,
abi,
);
return new contract.SignatureDrop(network, address, storage, options, abi);
},
getAbi: async () =>
(await import("@thirdweb-dev/contracts-js/dist/abis/SignatureDrop.json"))
.default,
};
export const Split = {
export const SplitInitializer = {
name: "Split" as const,
contractType: "split" as const,
schema: SplitsContractSchema,
@@ -220,17 +196,17 @@ export const Split = {
...[network, address, storage, options]: InitalizeParams
) => {
const [abi, contract] = await Promise.all([
Split.getAbi(),
SplitInitializer.getAbi(),
import("./prebuilt-implementations/split"),
]);
return new contract.SplitImpl(network, address, storage, options, abi);
return new contract.Split(network, address, storage, options, abi);
},
getAbi: async () =>
(await import("@thirdweb-dev/contracts-js/dist/abis/Split.json")).default,
};
export const TokenDrop = {
export const TokenDropInitializer = {
name: "DropERC20" as const,
contractType: "token-drop" as const,
schema: DropErc20ContractSchema,
@@ -240,18 +216,18 @@ export const TokenDrop = {
...[network, address, storage, options]: InitalizeParams
) => {
const [abi, contract] = await Promise.all([
TokenDrop.getAbi(),
TokenDropInitializer.getAbi(),
import("./prebuilt-implementations/token-drop"),
]);
return new contract.TokenDropImpl(network, address, storage, options, abi);
return new contract.TokenDrop(network, address, storage, options, abi);
},
getAbi: async () =>
(await import("@thirdweb-dev/contracts-js/dist/abis/DropERC20.json"))
.default,
};
export const Token = {
export const TokenInitializer = {
name: "TokenERC20" as const,
contractType: "token" as const,
schema: TokenErc20ContractSchema,
@@ -260,18 +236,18 @@ export const Token = {
...[network, address, storage, options]: InitalizeParams
) => {
const [abi, contract] = await Promise.all([
Token.getAbi(),
TokenInitializer.getAbi(),
import("./prebuilt-implementations/token"),
]);
return new contract.TokenImpl(network, address, storage, options, abi);
return new contract.Token(network, address, storage, options, abi);
},
getAbi: async () =>
(await import("@thirdweb-dev/contracts-js/dist/abis/TokenERC20.json"))
.default,
};
export const Vote = {
export const VoteInitializer = {
name: "VoteERC20" as const,
contractType: "vote" as const,
schema: VoteContractSchema,
@@ -281,11 +257,11 @@ export const Vote = {
...[network, address, storage, options]: InitalizeParams
) => {
const [abi, contract] = await Promise.all([
Vote.getAbi(),
VoteInitializer.getAbi(),
import("./prebuilt-implementations/vote"),
]);
return new contract.VoteImpl(network, address, storage, options, abi);
return new contract.Vote(network, address, storage, options, abi);
},
getAbi: async () =>
(await import("@thirdweb-dev/contracts-js/dist/abis/VoteERC20.json"))
@@ -297,18 +273,18 @@ export const Vote = {
* @internal
*/
export const PREBUILT_CONTRACTS_MAP = {
[EditionDrop.contractType]: EditionDrop,
[Edition.contractType]: Edition,
[Marketplace.contractType]: Marketplace,
[Multiwrap.contractType]: Multiwrap,
[NFTCollection.contractType]: NFTCollection,
[NFTDrop.contractType]: NFTDrop,
[Pack.contractType]: Pack,
[SignatureDrop.contractType]: SignatureDrop,
[Split.contractType]: Split,
[TokenDrop.contractType]: TokenDrop,
[Token.contractType]: Token,
[Vote.contractType]: Vote,
[EditionDropInitializer.contractType]: EditionDropInitializer,
[EditionInitializer.contractType]: EditionInitializer,
[MarketplaceInitializer.contractType]: MarketplaceInitializer,
[MultiwrapInitializer.contractType]: MultiwrapInitializer,
[NFTCollectionInitializer.contractType]: NFTCollectionInitializer,
[NFTDropInitializer.contractType]: NFTDropInitializer,
[PackInitializer.contractType]: PackInitializer,
[SignatureDropInitializer.contractType]: SignatureDropInitializer,
[SplitInitializer.contractType]: SplitInitializer,
[TokenDropInitializer.contractType]: TokenDropInitializer,
[TokenInitializer.contractType]: TokenInitializer,
[VoteInitializer.contractType]: VoteInitializer,
} as const;
const SmartContract = {
@@ -19,6 +19,7 @@ import {
TransactionResult,
TransactionResultWithId,
} from "../../core/types";
import { PaperCheckout } from "../../integrations/paper-xyz";
import { EditionMetadata, EditionMetadataOwner } from "../../schema";
import { DropErc1155ContractSchema } from "../../schema/contracts/drop-erc1155";
import { SDKOptions } from "../../schema/sdk-options";
@@ -43,7 +44,7 @@ import { BigNumber, BigNumberish, CallOverrides, constants } from "ethers";
*
* @public
*/
export class EditionDropImpl extends StandardErc1155<DropERC1155> {
export class EditionDrop extends StandardErc1155<DropERC1155> {
private static contractRoles = ["admin", "minter", "transfer"] as const;
public abi: typeof ABI;
@@ -58,7 +59,7 @@ export class EditionDropImpl extends StandardErc1155<DropERC1155> {
>;
public roles: ContractRoles<
DropERC1155,
typeof EditionDropImpl.contractRoles[number]
typeof EditionDrop.contractRoles[number]
>;
/**
* Configure royalties
@@ -106,6 +107,13 @@ export class EditionDropImpl extends StandardErc1155<DropERC1155> {
* ```
*/
public claimConditions: DropErc1155ClaimConditions<DropERC1155>;
/**
* Checkout
* @remarks Create a FIAT currency checkout for your NFT drop.
*/
public checkout: PaperCheckout<DropERC1155>;
public history: DropErc1155History;
public interceptor: ContractInterceptor<DropERC1155>;
public erc1155: Erc1155<DropERC1155>;
@@ -132,7 +140,7 @@ export class EditionDropImpl extends StandardErc1155<DropERC1155> {
);
this.roles = new ContractRoles(
this.contractWrapper,
EditionDropImpl.contractRoles,
EditionDrop.contractRoles,
);
this.royalties = new ContractRoyalty(this.contractWrapper, this.metadata);
this.sales = new ContractPrimarySale(this.contractWrapper);
@@ -148,6 +156,7 @@ export class EditionDropImpl extends StandardErc1155<DropERC1155> {
this.platformFees = new ContractPlatformFee(this.contractWrapper);
this.interceptor = new ContractInterceptor(this.contractWrapper);
this.erc1155 = new Erc1155(this.contractWrapper, this.storage);
this.checkout = new PaperCheckout(this.contractWrapper);
}
/**
@@ -44,7 +44,7 @@ import { BigNumber, BigNumberish, CallOverrides, constants } from "ethers";
*
* @public
*/
export class EditionImpl extends StandardErc1155<TokenERC1155> {
export class Edition extends StandardErc1155<TokenERC1155> {
static contractRoles = ["admin", "minter", "transfer"] as const;
public abi: typeof ABI;
@@ -54,7 +54,7 @@ export class EditionImpl extends StandardErc1155<TokenERC1155> {
>;
public roles: ContractRoles<
TokenERC1155,
typeof EditionImpl.contractRoles[number]
typeof Edition.contractRoles[number]
>;
public sales: ContractPrimarySale<TokenERC1155>;
public platformFees: ContractPlatformFee<TokenERC1155>;
@@ -120,10 +120,7 @@ export class EditionImpl extends StandardErc1155<TokenERC1155> {
TokenErc1155ContractSchema,
this.storage,
);
this.roles = new ContractRoles(
this.contractWrapper,
EditionImpl.contractRoles,
);
this.roles = new ContractRoles(this.contractWrapper, Edition.contractRoles);
this.royalties = new ContractRoyalty(this.contractWrapper, this.metadata);
this.sales = new ContractPrimarySale(this.contractWrapper);
this.encoder = new ContractEncoder(this.contractWrapper);
@@ -38,7 +38,7 @@ import invariant from "tiny-invariant";
*
* @public
*/
export class MarketplaceImpl implements UpdateableNetwork {
export class Marketplace implements UpdateableNetwork {
static contractRoles = ["admin", "lister", "asset"] as const;
public abi: typeof ABI;
@@ -55,7 +55,7 @@ export class MarketplaceImpl implements UpdateableNetwork {
>;
public roles: ContractRoles<
MarketplaceContract,
typeof MarketplaceImpl.contractRoles[number]
typeof Marketplace.contractRoles[number]
>;
/**
* @internal
@@ -155,7 +155,7 @@ export class MarketplaceImpl implements UpdateableNetwork {
);
this.roles = new ContractRoles(
this.contractWrapper,
MarketplaceImpl.contractRoles,
Marketplace.contractRoles,
);
this.encoder = new ContractEncoder(this.contractWrapper);
this.estimator = new GasCostEstimator(this.contractWrapper);
@@ -50,8 +50,14 @@ import { BigNumberish, CallOverrides, ethers } from "ethers";
*
* @beta
*/
export class MultiwrapImpl extends StandardErc721<MultiwrapContract> {
static contractRoles = ["transfer", "minter", "unwrap", "asset"] as const;
export class Multiwrap extends StandardErc721<MultiwrapContract> {
static contractRoles = [
"admin",
"transfer",
"minter",
"unwrap",
"asset",
] as const;
public abi: typeof ABI;
public encoder: ContractEncoder<MultiwrapContract>;
@@ -63,7 +69,7 @@ export class MultiwrapImpl extends StandardErc721<MultiwrapContract> {
public events: ContractEvents<MultiwrapContract>;
public roles: ContractRoles<
MultiwrapContract,
typeof MultiwrapImpl.contractRoles[number]
typeof Multiwrap.contractRoles[number]
>;
/**
@@ -111,7 +117,7 @@ export class MultiwrapImpl extends StandardErc721<MultiwrapContract> {
this.roles = new ContractRoles(
this.contractWrapper,
MultiwrapImpl.contractRoles,
Multiwrap.contractRoles,
);
this.encoder = new ContractEncoder(this.contractWrapper);
this.estimator = new GasCostEstimator(this.contractWrapper);
@@ -39,7 +39,7 @@ import { BigNumberish, CallOverrides, constants } from "ethers";
*
* @public
*/
export class NFTCollectionImpl extends StandardErc721<TokenERC721> {
export class NFTCollection extends StandardErc721<TokenERC721> {
static contractRoles = ["admin", "minter", "transfer"] as const;
public abi: typeof ABI;
@@ -49,7 +49,7 @@ export class NFTCollectionImpl extends StandardErc721<TokenERC721> {
>;
public roles: ContractRoles<
TokenERC721,
typeof NFTCollectionImpl.contractRoles[number]
typeof NFTCollection.contractRoles[number]
>;
public encoder: ContractEncoder<TokenERC721>;
public estimator: GasCostEstimator<TokenERC721>;
@@ -122,7 +122,7 @@ export class NFTCollectionImpl extends StandardErc721<TokenERC721> {
);
this.roles = new ContractRoles(
this.contractWrapper,
NFTCollectionImpl.contractRoles,
NFTCollection.contractRoles,
);
this.royalties = new ContractRoyalty(this.contractWrapper, this.metadata);
this.sales = new ContractPrimarySale(this.contractWrapper);
@@ -22,6 +22,7 @@ import {
TransactionResult,
TransactionResultWithId,
} from "../../core/types";
import { PaperCheckout } from "../../integrations/paper-xyz";
import { DropErc721ContractSchema } from "../../schema/contracts/drop-erc721";
import { SDKOptions } from "../../schema/sdk-options";
import {
@@ -37,10 +38,7 @@ import {
import { UploadProgressEvent } from "../../types/events";
import type { DropERC721 } from "@thirdweb-dev/contracts-js";
import type ABI from "@thirdweb-dev/contracts-js/dist/abis/DropERC721.json";
import {
TokensClaimedEvent,
TokensLazyMintedEvent,
} from "@thirdweb-dev/contracts-js/dist/declarations/src/DropERC721";
import { TokensLazyMintedEvent } from "@thirdweb-dev/contracts-js/dist/declarations/src/DropERC721";
import { ThirdwebStorage } from "@thirdweb-dev/storage";
import {
BigNumber,
@@ -64,7 +62,7 @@ import {
*
* @public
*/
export class NFTDropImpl extends StandardErc721<DropERC721> {
export class NFTDrop extends StandardErc721<DropERC721> {
static contractRoles = ["admin", "minter", "transfer"] as const;
public abi: typeof ABI;
@@ -77,10 +75,7 @@ export class NFTDropImpl extends StandardErc721<DropERC721> {
public sales: ContractPrimarySale<DropERC721>;
public platformFees: ContractPlatformFee<DropERC721>;
public events: ContractEvents<DropERC721>;
public roles: ContractRoles<
DropERC721,
typeof NFTDropImpl.contractRoles[number]
>;
public roles: ContractRoles<DropERC721, typeof NFTDrop.contractRoles[number]>;
/**
* @internal
*/
@@ -161,6 +156,13 @@ export class NFTDropImpl extends StandardErc721<DropERC721> {
* ```
*/
public revealer: DelayedReveal<DropERC721>;
/**
* Checkout
* @remarks Create a FIAT currency checkout for your NFT drop.
*/
public checkout: PaperCheckout<DropERC721>;
public erc721: Erc721<DropERC721>;
constructor(
@@ -183,10 +185,7 @@ export class NFTDropImpl extends StandardErc721<DropERC721> {
DropErc721ContractSchema,
this.storage,
);
this.roles = new ContractRoles(
this.contractWrapper,
NFTDropImpl.contractRoles,
);
this.roles = new ContractRoles(this.contractWrapper, NFTDrop.contractRoles);
this.royalties = new ContractRoyalty(this.contractWrapper, this.metadata);
this.sales = new ContractPrimarySale(this.contractWrapper);
this.claimConditions = new DropClaimConditions(
@@ -206,6 +205,8 @@ export class NFTDropImpl extends StandardErc721<DropERC721> {
() => this.erc721.nextTokenIdToMint(),
);
this.interceptor = new ContractInterceptor(this.contractWrapper);
this.checkout = new PaperCheckout(this.contractWrapper);
}
/**
@@ -56,15 +56,12 @@ import { BigNumber, BigNumberish, CallOverrides, ethers } from "ethers";
*
* @public
*/
export class PackImpl extends StandardErc1155<PackContract> {
static contractRoles = ["admin", "minter", "pauser", "transfer"] as const;
export class Pack extends StandardErc1155<PackContract> {
static contractRoles = ["admin", "minter", "asset", "transfer"] as const;
public abi: typeof ABI;
public metadata: ContractMetadata<PackContract, typeof PackContractSchema>;
public roles: ContractRoles<
PackContract,
typeof PackImpl.contractRoles[number]
>;
public roles: ContractRoles<PackContract, typeof Pack.contractRoles[number]>;
public encoder: ContractEncoder<PackContract>;
public events: ContractEvents<PackContract>;
public estimator: GasCostEstimator<PackContract>;
@@ -103,7 +100,17 @@ export class PackImpl extends StandardErc1155<PackContract> {
network,
address,
abi,
options,
options.gasless && "openzeppelin" in options.gasless
? {
...options,
gasless: {
openzeppelin: {
...options.gasless.openzeppelin,
useEOAForwarder: true,
},
},
}
: options,
),
) {
super(contractWrapper, storage);
@@ -114,10 +121,7 @@ export class PackImpl extends StandardErc1155<PackContract> {
PackContractSchema,
this.storage,
);
this.roles = new ContractRoles(
this.contractWrapper,
PackImpl.contractRoles,
);
this.roles = new ContractRoles(this.contractWrapper, Pack.contractRoles);
this.royalties = new ContractRoyalty(this.contractWrapper, this.metadata);
this.encoder = new ContractEncoder(this.contractWrapper);
this.estimator = new GasCostEstimator(this.contractWrapper);
@@ -21,6 +21,7 @@ import {
TransactionResult,
TransactionResultWithId,
} from "../../core/types";
import { PaperCheckout } from "../../integrations/paper-xyz";
import { DropErc721ContractSchema } from "../../schema/contracts/drop-erc721";
import { SDKOptions } from "../../schema/sdk-options";
import {
@@ -54,7 +55,7 @@ import { BigNumber, BigNumberish, CallOverrides, constants } from "ethers";
*
* @public
*/
export class SignatureDropImpl extends StandardErc721<SignatureDropContract> {
export class SignatureDrop extends StandardErc721<SignatureDropContract> {
static contractRoles = ["admin", "minter", "transfer"] as const;
public abi: typeof ABI;
@@ -70,7 +71,7 @@ export class SignatureDropImpl extends StandardErc721<SignatureDropContract> {
public events: ContractEvents<SignatureDropContract>;
public roles: ContractRoles<
SignatureDropContract,
typeof SignatureDropImpl.contractRoles[number]
typeof SignatureDrop.contractRoles[number]
>;
/**
* @internal
@@ -161,6 +162,12 @@ export class SignatureDropImpl extends StandardErc721<SignatureDropContract> {
*/
public signature: Erc721WithQuantitySignatureMintable;
/**
* Checkout
* @remarks Create a FIAT currency checkout for your NFT drop.
*/
public checkout: PaperCheckout<SignatureDropContract>;
constructor(
network: NetworkOrSignerOrProvider,
address: string,
@@ -183,7 +190,7 @@ export class SignatureDropImpl extends StandardErc721<SignatureDropContract> {
);
this.roles = new ContractRoles(
this.contractWrapper,
SignatureDropImpl.contractRoles,
SignatureDrop.contractRoles,
);
this.royalties = new ContractRoyalty(this.contractWrapper, this.metadata);
this.sales = new ContractPrimarySale(this.contractWrapper);
@@ -212,6 +219,8 @@ export class SignatureDropImpl extends StandardErc721<SignatureDropContract> {
this.contractWrapper,
this.storage,
);
this.checkout = new PaperCheckout(this.contractWrapper);
}
/**
@@ -35,7 +35,7 @@ import { BigNumber, CallOverrides, Contract } from "ethers";
*
* @public
*/
export class SplitImpl implements UpdateableNetwork {
export class Split implements UpdateableNetwork {
static contractRoles = ["admin"] as const;
private contractWrapper: ContractWrapper<SplitContract>;
@@ -48,7 +48,7 @@ export class SplitImpl implements UpdateableNetwork {
public events: ContractEvents<SplitContract>;
public roles: ContractRoles<
SplitContract,
typeof SplitImpl.contractRoles[number]
typeof Split.contractRoles[number]
>;
/**
* @internal
@@ -76,10 +76,7 @@ export class SplitImpl implements UpdateableNetwork {
SplitsContractSchema,
this.storage,
);
this.roles = new ContractRoles(
this.contractWrapper,
SplitImpl.contractRoles,
);
this.roles = new ContractRoles(this.contractWrapper, Split.contractRoles);
this.encoder = new ContractEncoder(this.contractWrapper);
this.estimator = new GasCostEstimator(this.contractWrapper);
this.events = new ContractEvents(this.contractWrapper);
@@ -32,14 +32,14 @@ import { CallOverrides, constants } from "ethers";
* ```
*
*/
export class TokenDropImpl extends StandardErc20<DropERC20> {
export class TokenDrop extends StandardErc20<DropERC20> {
static contractRoles = ["admin", "transfer"] as const;
public abi: typeof ABI;
public metadata: ContractMetadata<DropERC20, typeof DropErc20ContractSchema>;
public roles: ContractRoles<
DropERC20,
typeof TokenDropImpl.contractRoles[number]
typeof TokenDrop.contractRoles[number]
>;
public encoder: ContractEncoder<DropERC20>;
public estimator: GasCostEstimator<DropERC20>;
@@ -96,7 +96,7 @@ export class TokenDropImpl extends StandardErc20<DropERC20> {
);
this.roles = new ContractRoles(
this.contractWrapper,
TokenDropImpl.contractRoles,
TokenDrop.contractRoles,
);
this.encoder = new ContractEncoder(this.contractWrapper);
this.estimator = new GasCostEstimator(this.contractWrapper);
@@ -35,7 +35,7 @@ import { CallOverrides, constants } from "ethers";
*
* @public
*/
export class TokenImpl extends StandardErc20<TokenERC20> {
export class Token extends StandardErc20<TokenERC20> {
static contractRoles = ["admin", "minter", "transfer"] as const;
public abi: typeof ABI;
@@ -43,10 +43,7 @@ export class TokenImpl extends StandardErc20<TokenERC20> {
TokenERC20,
typeof TokenErc20ContractSchema
>;
public roles: ContractRoles<
TokenERC20,
typeof TokenImpl.contractRoles[number]
>;
public roles: ContractRoles<TokenERC20, typeof Token.contractRoles[number]>;
public encoder: ContractEncoder<TokenERC20>;
public estimator: GasCostEstimator<TokenERC20>;
public history: TokenERC20History;
@@ -92,10 +89,7 @@ export class TokenImpl extends StandardErc20<TokenERC20> {
TokenErc20ContractSchema,
this.storage,
);
this.roles = new ContractRoles(
this.contractWrapper,
TokenImpl.contractRoles,
);
this.roles = new ContractRoles(this.contractWrapper, Token.contractRoles);
this.sales = new ContractPrimarySale(this.contractWrapper);
this.events = new ContractEvents(this.contractWrapper);
this.history = new TokenERC20History(this.contractWrapper, this.events);

Some files were not shown because too many files have changed in this diff Show More