Compare commits

..
Author SHA1 Message Date
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
0b4b6a5b4e Version Packages (#871)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-04-05 12:42:31 -07:00
b3d57949bd [SDK] Relax the requirement for LazyMint (#864)
Co-authored-by: Joaquim Verges <[email protected]>
2023-04-05 17:26:02 +00:00
Manan TankandGitHub 1cf1f866d5 Add stable css selectors on web3button and connect wallet button (#866) 2023-04-05 14:24:48 +00:00
602d8cbcfa [SDK] Add .prepare() support to tiered-drop (#869)
Co-authored-by: Jonas Daniels <[email protected]>
2023-04-05 01:01:46 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
33a78e68d1 Version Packages (#865)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-04-04 17:50:09 -07:00
Jonas DanielsandGitHub 235eb0460a [react-core, wallets] - fix window undefined error during SSR (#870) 2023-04-05 00:41:12 +00:00
Adam MajmudarandGitHub 3bb846adf0 [CLI] Generate detects contracts in project (#867) 2023-04-05 00:19:56 +00:00
b5648aee83 [React] Make tokenId optional one useNFTBalance (#862)
Co-authored-by: Adam Majmudar <[email protected]>
2023-04-04 23:51:28 +00:00
ciaranightingaleandGitHub 1b8f812fb8 [SDK] contract portal links (#863) 2023-04-04 21:47:53 +00:00
Adam MajmudarandGitHub 1547d76cce [SDK] Add unix timestamp dates (#861) 2023-04-04 00:54:48 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
7c78d1c6e8 Version Packages (#858)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-04-03 16:41:59 -07:00
iketwandGitHub 058e4357c7 [CLI] Only run react-native ios specific tasks on macOS envs (#860) 2023-04-03 23:14:19 +00:00
Adam MajmudarandGitHub 3a0e904fc2 [CLI] Add skip intro flag to generate and update regex (#857) 2023-04-02 22:08:59 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
5143d535f4 Version Packages (#852)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-03-31 16:51:47 -07:00
Manan TankandGitHub 2dd192a567 [react] add auth in connect wallet button (#855) 2023-03-31 22:20:58 +00:00
Adam MajmudarandGitHub 6e9396f535 Update README.md (#854) 2023-03-31 19:55:44 +00:00
Jonas DanielsandGitHub b3b00e510b [tooling] - update pnpm (#853) 2023-03-31 19:04:21 +00:00
Manan TankandGitHub c5c2d9478a [wallets] Fix autoconnect issues (#851) 2023-03-31 18:10:14 +00:00
75 changed files with 9706 additions and 6177 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ runs:
steps:
- uses: pnpm/action-setup@v2
with:
version: 7
version: 8
- name: Setup Node.js
uses: actions/setup-node@v3
with:
+3 -3
View File
@@ -60,7 +60,7 @@ jobs:
- uses: pnpm/action-setup@v2
with:
version: 7
version: 8
- uses: actions/cache@v3
timeout-minutes: 5
@@ -85,7 +85,7 @@ jobs:
- uses: pnpm/action-setup@v2
with:
version: 7
version: 8
- uses: actions/cache@v3
timeout-minutes: 5
@@ -115,7 +115,7 @@ jobs:
- uses: pnpm/action-setup@v2
with:
version: 7
version: 8
- uses: actions/cache@v3
timeout-minutes: 5
-1
View File
@@ -1 +0,0 @@
auto-install-peers=true
+8 -7
View File
@@ -20,13 +20,14 @@
## Packages
| Package | Description | Latest Version |
| ------------------------------ | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [/sdk](./packages/sdk) | Best in class web3 SDK for Browser, Node and Mobile apps | <a href="https://www.npmjs.com/package/@thirdweb-dev/sdk"><img src="https://img.shields.io/npm/v/@thirdweb-dev/sdk?color=red&label=npm&logo=npm" alt="npm version"/></a> |
| [/react](./packages/react) | Ultimate collection of React hooks for your web3 apps | <a href="https://www.npmjs.com/package/@thirdweb-dev/react"><img src="https://img.shields.io/npm/v/@thirdweb-dev/react?color=red&label=npm&logo=npm" alt="npm version"/></a> |
| [/auth](./packages/auth) | Best in class wallet authentication for Node backends | <a href="https://www.npmjs.com/package/@thirdweb-dev/auth"><img src="https://img.shields.io/npm/v/@thirdweb-dev/auth?color=red&label=npm&logo=npm" alt="npm version"/></a> |
| [/storage](./packages/storage) | Best in class decentralized storage SDK for Browser and Node | <a href="https://www.npmjs.com/package/@thirdweb-dev/storage"><img src="https://img.shields.io/npm/v/@thirdweb-dev/storage?color=red&label=npm&logo=npm" alt="npm version"/></a> |
| [/cli](./packages/cli) | Publish and deploy smart contracts without dealing with private keys | <a href="https://www.npmjs.com/package/thirdweb"><img src="https://img.shields.io/npm/v/thirdweb?color=red&label=npm&logo=npm" alt="npm version"/></a> |
| Package | Description | Latest Version |
| --------------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [/sdk](./packages/sdk) | Best in class web3 SDK for Browser, Node and Mobile apps | <a href="https://www.npmjs.com/package/@thirdweb-dev/sdk"><img src="https://img.shields.io/npm/v/@thirdweb-dev/sdk?color=red&label=npm&logo=npm" alt="npm version"/></a> |
| [/react](./packages/react) | Ultimate collection of React hooks for your web3 apps | <a href="https://www.npmjs.com/package/@thirdweb-dev/react"><img src="https://img.shields.io/npm/v/@thirdweb-dev/react?color=red&label=npm&logo=npm" alt="npm version"/></a> |
| [/react](./packages/react-native) | Ultimate collection of React hooks for your native web3 apps | <a href="https://www.npmjs.com/package/@thirdweb-dev/react-native"><img src="https://img.shields.io/npm/v/@thirdweb-dev/react-native?color=red&label=npm&logo=npm" alt="npm version"/></a> |
| [/auth](./packages/auth) | Best in class wallet authentication for Node backends | <a href="https://www.npmjs.com/package/@thirdweb-dev/auth"><img src="https://img.shields.io/npm/v/@thirdweb-dev/auth?color=red&label=npm&logo=npm" alt="npm version"/></a> |
| [/storage](./packages/storage) | Best in class decentralized storage SDK for Browser and Node | <a href="https://www.npmjs.com/package/@thirdweb-dev/storage"><img src="https://img.shields.io/npm/v/@thirdweb-dev/storage?color=red&label=npm&logo=npm" alt="npm version"/></a> |
| [/cli](./packages/cli) | Publish and deploy smart contracts without dealing with private keys | <a href="https://www.npmjs.com/package/thirdweb"><img src="https://img.shields.io/npm/v/thirdweb?color=red&label=npm&logo=npm" alt="npm version"/></a> |
## Documentation
+4 -4
View File
@@ -31,7 +31,7 @@
"hotlink-revert": "node ./scripts/hotlink/hotlink-revert.mjs",
"explain:major": "node ./scripts/changeset-explain-major.mjs"
},
"packageManager": "pnpm@7.29.3",
"packageManager": "pnpm@8.1.0",
"dependencies": {
"@changesets/changelog-github": "^0.4.8",
"@changesets/cli": "^2.26.1",
@@ -42,11 +42,11 @@
"@manypkg/get-packages": "^1.1.3",
"@playwright/test": "1.31.2",
"@trivago/prettier-plugin-sort-imports": "^4.1.1",
"@types/node": "^18.15.7",
"eslint": "^8.36.0",
"@types/node": "^18.15.11",
"eslint": "^8.37.0",
"mocha": "^10.2.0",
"prettier": "^2.8.7",
"turbo": "^1.8.5",
"turbo": "^1.8.8",
"yalc": "1.0.0-pre.53"
},
"manypkg": {
+14
View File
@@ -1,5 +1,19 @@
# @thirdweb-dev/auth
## 3.0.13
### Patch Changes
- Updated dependencies [[`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d)]:
- @thirdweb-dev/wallets@0.2.14
## 3.0.12
### Patch Changes
- Updated dependencies [[`c5c2d947`](https://github.com/thirdweb-dev/js/commit/c5c2d9478acd4d4a4e6ce814716bdf1b6e51eafc), [`2dd192a5`](https://github.com/thirdweb-dev/js/commit/2dd192a5676f1b6d3c310ec796bf331252098d48)]:
- @thirdweb-dev/wallets@0.2.13
## 3.0.11
### Patch Changes
+10 -2
View File
@@ -13,6 +13,14 @@
<p align="center"><strong>Best in class wallet authentication for Node backends</strong></p>
<br />
## Overview
Auth is a developer SDK that lets you integrate passwordless web3-native authentication and authorization into your applications.
It enables users to sign in with their wallets, allowing apps to access rich blockchain-level data and interact with their users on-chain.
With Auth, developers can build applications that have secure, self-custodied, web3-first authentication.
## Installation
Install the latest version of the SDK with either `npm` or `yarn`:
@@ -25,6 +33,6 @@ npm install @thirdweb-dev/auth
yarn add @thirdweb-dev/auth
```
## Documentation
## Resources
- [Auth Docs](https://portal.thirdweb.com/auth)
- Check out the [Auth Documentation](https://portal.thirdweb.com/auth) for full guides and API references on how to use Auth.
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/auth",
"version": "3.0.11",
"version": "3.0.13",
"main": "dist/thirdweb-dev-auth.cjs.js",
"module": "dist/thirdweb-dev-auth.esm.js",
"browser": {
+6
View File
@@ -1,5 +1,11 @@
# @thirdweb-dev/chains
## 0.1.11
### Patch Changes
- [#870](https://github.com/thirdweb-dev/js/pull/870) [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d) Thanks [@jnsdls](https://github.com/jnsdls)! - update chains
## 0.1.10
### Patch Changes
+38
View File
@@ -0,0 +1,38 @@
import type { Chain } from "../src/types";
export default {
"name": "ShimmerEVM Testnet",
"title": "ShimmerEVM Testnet",
"chain": "ShimmerEVM",
"icon": {
"url": "ipfs://bafkreibky2sy6qhi6arktayvologkrgu5kudpgdxfkx4uosbvmstz7v4di",
"width": 720,
"height": 720,
"format": "png"
},
"rpc": [
"https://shimmerevm-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://json-rpc.evm.testnet.shimmer.network"
],
"faucets": [
"https://evm-toolkit.evm.testnet.shimmer.network",
"https://evm-faucet.testnet.shimmer.network"
],
"nativeCurrency": {
"name": "SMR",
"symbol": "SMR",
"decimals": 18
},
"infoURL": "https://shimmer.network",
"shortName": "shimmerevm-testnet",
"chainId": 1071,
"networkId": 1071,
"explorers": [
{
"name": "explorer",
"url": "https://explorer.evm.testnet.shimmer.network",
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "shimmerevm-testnet"
} as const satisfies Chain;
+47
View File
@@ -0,0 +1,47 @@
import type { Chain } from "../src/types";
export default {
"name": "Defi Oracle Meta Mainnet",
"chain": "dfiometa",
"icon": {
"url": "ipfs://QmYrMRnjQJcNkYq9AvZ2FQ9kzYj9szzP4YDmyNA1ybd8xE",
"width": 1000,
"height": 1043,
"format": "png"
},
"rpc": [
"https://defi-oracle-meta.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.public-0138.defi-oracle.io",
"wss://rpc.public-0138.defi-oracle.io"
],
"features": [
{
"name": "EIP155"
},
{
"name": "EIP1559"
}
],
"faucets": [],
"nativeCurrency": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"infoURL": "https://defi-oracle.io/",
"shortName": "dfio-meta-main",
"chainId": 138,
"networkId": 1,
"slip44": 60,
"ens": {
"registry": "0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85"
},
"explorers": [
{
"name": "Quorum Explorer",
"url": "https://public-0138.defi-oracle.io",
"standard": "none"
}
],
"testnet": false,
"slug": "defi-oracle-meta"
} as const satisfies Chain;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"name": "Neutrinos TestNet",
"chain": "NEUTR",
"rpc": [
"https://neutrinos-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://testnet-rpc.neutrinoschain.com"
],
"faucets": [
"https://neutrinoschain.com/faucet"
],
"nativeCurrency": {
"name": "Neutrinos",
"symbol": "NEUTR",
"decimals": 18
},
"infoURL": "https://docs.neutrinoschain.com",
"shortName": "NEUTR",
"chainId": 197,
"networkId": 197,
"explorers": [
{
"name": "blockscout",
"url": "https://testnet.neutrinoschain.com",
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "neutrinos-testnet"
} as const satisfies Chain;
+5 -5
View File
@@ -1,14 +1,14 @@
import type { Chain } from "../src/types";
export default {
"name": "CamelArk Mainnet",
"name": "Camelark Mainnet",
"chainId": 20001,
"shortName": "CamelArk",
"shortName": "Camelark",
"chain": "ETHW",
"icon": {
"url": "ipfs://QmbXDcCWHh8jExE1tAUkUKzXyTb8srpC75ogZq1QYkMMRW",
"url": "ipfs://QmeJerrsURFNt2LL7DE7TxeunjrQXiuezdfHyqmsbwX3MZ",
"width": 128,
"height": 128,
"format": "svg"
"format": "png"
},
"networkId": 20001,
"nativeCurrency": {
@@ -23,7 +23,7 @@ export default {
"faucets": [],
"explorers": [
{
"name": "CamelArkscan",
"name": "CamelarkScan",
"url": "https://scan.camelark.com",
"standard": "EIP3091"
}
+47
View File
@@ -0,0 +1,47 @@
import type { Chain } from "../src/types";
export default {
"name": "Defi Oracle Meta Testnet",
"chain": "dfiometatest",
"icon": {
"url": "ipfs://QmYrMRnjQJcNkYq9AvZ2FQ9kzYj9szzP4YDmyNA1ybd8xE",
"width": 1000,
"height": 1043,
"format": "png"
},
"rpc": [
"https://defi-oracle-meta-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.public-2138.defi-oracle.io",
"wss://rpc.public-2138.defi-oracle.io"
],
"features": [
{
"name": "EIP155"
},
{
"name": "EIP1559"
}
],
"faucets": [],
"nativeCurrency": {
"name": "testEther",
"symbol": "tETH",
"decimals": 18
},
"infoURL": "https://defi-oracle.io/",
"shortName": "dfio-meta-test",
"chainId": 2138,
"networkId": 21,
"slip44": 60,
"ens": {
"registry": "0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85"
},
"explorers": [
{
"name": "Quorum Explorer",
"url": "https://public-2138.defi-oracle.io",
"standard": "none"
}
],
"testnet": true,
"slug": "defi-oracle-meta-testnet"
} as const satisfies Chain;
+34
View File
@@ -0,0 +1,34 @@
import type { Chain } from "../src/types";
export default {
"name": "Taf ECO Chain Mainnet",
"chain": "Taf ECO Chain",
"icon": {
"url": "ipfs://bafkreigpxhu7glccsislhjqpl5fnsfmj2io4cy33blhky642uiuyojossy",
"width": 400,
"height": 400,
"format": "png"
},
"rpc": [
"https://taf-eco-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://mainnet.tafchain.com/v1"
],
"faucets": [],
"nativeCurrency": {
"name": "Taf ECO Chain Mainnet",
"symbol": "TAFECO",
"decimals": 18
},
"infoURL": "https://www.tafchain.com",
"shortName": "TAFECO",
"chainId": 224168,
"networkId": 224168,
"explorers": [
{
"name": "Taf ECO Chain Mainnet",
"url": "https://ecoscan.tafchain.com",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "taf-eco-chain"
} as const satisfies Chain;
+50
View File
@@ -0,0 +1,50 @@
import type { Chain } from "../src/types";
export default {
"name": "WEMIX Kanvas Sepolia",
"title": "WEMIX Kanvas Testnet Sepolia",
"chainId": 2357,
"shortName": "kanvas-aqua",
"chain": "ETH",
"networkId": 2357,
"nativeCurrency": {
"name": "Sepolia Ether",
"symbol": "ETH",
"decimals": 18
},
"rpc": [
"https://wemix-kanvas-sepolia.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://api.aqua.wemixkanvas.io"
],
"faucets": [],
"infoURL": "https://wemixkanvas.io",
"icon": {
"url": "ipfs://QmVcVxsHsVg5BMii3EJ1MUSnLBZkQicpjmXjSmW66bCEUF",
"width": 320,
"height": 320,
"format": "svg"
},
"explorers": [
{
"name": "blockscout",
"url": "https://blockscout.aqua.wemixkanvas.io",
"icon": {
"url": "ipfs://QmVcVxsHsVg5BMii3EJ1MUSnLBZkQicpjmXjSmW66bCEUF",
"width": 320,
"height": 320,
"format": "svg"
},
"standard": "EIP3091"
}
],
"parent": {
"type": "L2",
"chain": "eip155-11155111",
"bridges": [
{
"url": "https://wemixkanvas.io/bridge"
}
]
},
"testnet": true,
"slug": "wemix-kanvas-sepolia"
} as const satisfies Chain;
+36
View File
@@ -0,0 +1,36 @@
import type { Chain } from "../src/types";
export default {
"name": "Acria IntelliChain",
"chain": "AIC",
"rpc": [
"https://acria-intellichain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://aic.acria.ai"
],
"faucets": [],
"nativeCurrency": {
"name": "ACRIA",
"symbol": "ACRIA",
"decimals": 18
},
"features": [
{
"name": "EIP155"
},
{
"name": "EIP1559"
}
],
"infoURL": "https://acria.ai",
"shortName": "aic",
"chainId": 47,
"networkId": 47,
"explorers": [
{
"name": "Acria IntelliChain-Explorer",
"url": "https://explorer.acria.ai",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "acria-intellichain"
} as const satisfies Chain;
-28
View File
@@ -1,28 +0,0 @@
import type { Chain } from "../src/types";
export default {
"name": "Canto Testnet",
"chain": "Canto Tesnet",
"rpc": [
"https://canto-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://eth.plexnode.wtf/"
],
"faucets": [],
"nativeCurrency": {
"name": "Canto",
"symbol": "CANTO",
"decimals": 18
},
"infoURL": "https://canto.io",
"shortName": "tcanto",
"chainId": 740,
"networkId": 740,
"explorers": [
{
"name": "Canto Tesnet Explorer (Neobase)",
"url": "https://testnet-explorer.canto.neobase.one",
"standard": "none"
}
],
"testnet": true,
"slug": "canto-testnet"
} as const satisfies Chain;
+28
View File
@@ -0,0 +1,28 @@
import type { Chain } from "../src/types";
export default {
"name": "Canto Tesnet",
"chain": "Canto",
"rpc": [
"https://canto-tesnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://testnet-archive.plexnode.wtf"
],
"faucets": [],
"nativeCurrency": {
"name": "Testnet Canto",
"symbol": "CANTO",
"decimals": 18
},
"infoURL": "https://canto.io",
"shortName": "TestnetCanto",
"chainId": 7701,
"networkId": 7701,
"explorers": [
{
"name": "Canto Testnet EVM Explorer (Blockscout)",
"url": "https://testnet.tuber.build",
"standard": "none"
}
],
"testnet": true,
"slug": "canto-tesnet"
} as const satisfies Chain;
+40
View File
@@ -0,0 +1,40 @@
import type { Chain } from "../src/types";
export default {
"name": "BeOne Chain Mainnet",
"chain": "BOC",
"icon": {
"url": "ipfs://QmbVLQnaMDu86bPyKgCvTGhFBeYwjr15hQnrCcsp1EkAGL",
"width": 500,
"height": 500,
"format": "png"
},
"rpc": [
"https://beone-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://dataseed1.beonechain.com",
"https://dataseed2.beonechain.com",
"https://dataseed-us1.beonechain.com",
"https://dataseed-us2.beonechain.com",
"https://dataseed-uk1.beonechain.com",
"https://dataseed-uk2.beonechain.com"
],
"faucets": [],
"nativeCurrency": {
"name": "BeOne Chain Mainnet",
"symbol": "BOC",
"decimals": 18
},
"infoURL": "https://beonechain.com",
"shortName": "BOC",
"chainId": 818,
"networkId": 818,
"slip44": 8181,
"explorers": [
{
"name": "BeOne Chain Mainnet",
"url": "https://beonescan.com",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "beone-chain"
} as const satisfies Chain;
+21
View File
@@ -0,0 +1,21 @@
import type { Chain } from "../src/types";
export default {
"name": "DecentraBone Layer1 Testnet",
"chain": "DBONE",
"rpc": [
"https://decentrabone-layer1-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://layer1test.decentrabone.com"
],
"faucets": [],
"nativeCurrency": {
"name": "DecentraBone",
"symbol": "DBONE",
"decimals": 18
},
"infoURL": "https://decentrabone.com",
"shortName": "DBONE",
"chainId": 910,
"networkId": 910,
"testnet": true,
"slug": "decentrabone-layer1-testnet"
} as const satisfies Chain;
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/chains",
"version": "0.1.10",
"version": "0.1.11",
"main": "dist/thirdweb-dev-chains.cjs.js",
"module": "dist/thirdweb-dev-chains.esm.js",
"browser": {
File diff suppressed because one or more lines are too long
+25
View File
@@ -1,5 +1,30 @@
# thirdweb
## 0.10.10
### Patch Changes
- Updated dependencies [[`b3d57949`](https://github.com/thirdweb-dev/js/commit/b3d57949bd047831fda7e600b4872200340903b5), [`602d8cbc`](https://github.com/thirdweb-dev/js/commit/602d8cbcfaa7c1e117c01f842f89508f7333fcfe)]:
- @thirdweb-dev/sdk@3.10.9
## 0.10.9
### Patch Changes
- [#867](https://github.com/thirdweb-dev/js/pull/867) [`3bb846ad`](https://github.com/thirdweb-dev/js/commit/3bb846adf0484e8b7dc7dfeba9f9c0ee26f4ef35) Thanks [@adam-maj](https://github.com/adam-maj)! - Generate auto detects smart contracts in project
- Updated dependencies [[`1547d76c`](https://github.com/thirdweb-dev/js/commit/1547d76cce52265076c347599014f578c1de6152), [`1b8f812f`](https://github.com/thirdweb-dev/js/commit/1b8f812fb8c910d91fb7535d6446a0b6fc6b2310), [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d)]:
- @thirdweb-dev/sdk@3.10.8
- @thirdweb-dev/chains@0.1.11
## 0.10.8
### Patch Changes
- [#857](https://github.com/thirdweb-dev/js/pull/857) [`3a0e904f`](https://github.com/thirdweb-dev/js/commit/3a0e904fc2bae5134ba3bf65ba666c3360e4fced) Thanks [@adam-maj](https://github.com/adam-maj)! - Add skip intro flag to generate command and fix ABI cache regex
- [#860](https://github.com/thirdweb-dev/js/pull/860) [`058e4357`](https://github.com/thirdweb-dev/js/commit/058e4357c783911a6cab6b38c6eebbb3277dfe93) Thanks [@iketw](https://github.com/iketw)! - [CLI] Only checks ruby version and attempts to run pod install if the platform is macOS
## 0.10.7
### Patch Changes
+2 -2
View File
@@ -77,7 +77,7 @@ npm i -g @thirdweb-dev/cli
---
## Supported projects
## Supported Projects
To publish, you need to be in a directory that contains a project which the CLI is compatible
with. The projects we support so far:
@@ -89,7 +89,7 @@ with. The projects we support so far:
---
## Running the examples
## Running the Examples
Clone the repo and run this command after installing the CLI tool:
+1 -1
View File
@@ -11,7 +11,7 @@ export const CREATE_MESSAGES = {
} as const;
export const GENERATE_MESSAGES = {
deployerAddress: "What is your deployer wallet address?",
chains: "What chains are you using in your project?",
};
export const ERROR_MESSAGES = {
+2 -1
View File
@@ -1,7 +1,7 @@
{
"name": "thirdweb",
"main": "dist/cli/index.js",
"version": "0.10.7",
"version": "0.10.10",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -34,6 +34,7 @@
"typescript": "^4.7.4"
},
"dependencies": {
"@thirdweb-dev/chains": "workspace:*",
"@thirdweb-dev/sdk": "workspace:*",
"@thirdweb-dev/storage": "workspace:*",
"async-retry": "^1.3.3",
+36 -1
View File
@@ -1,5 +1,5 @@
import { logger } from "../core/helpers/logger";
import { existsSync, readdirSync, statSync } from "fs";
import { existsSync, readFileSync, readdirSync, statSync } from "fs";
import { basename, join } from "path";
export function findFiles(
@@ -38,3 +38,38 @@ export function findFiles(
}
}
}
export function findMatches(
startPath: string,
filter: RegExp,
results: string[],
) {
if (!existsSync(startPath)) {
console.log("no dir ", startPath);
return;
}
const files = readdirSync(startPath);
for (let i = 0; i < files.length; i++) {
const filename = join(startPath, files[i]);
const stat = statSync(filename);
if (stat.isDirectory() && basename(filename) === "node_modules") {
continue;
}
if (stat.isDirectory() && filename.startsWith(".")) {
continue;
}
if (stat.isDirectory()) {
findMatches(filename, filter, results);
} else {
const fileContents = readFileSync(filename, "utf-8");
const matches = fileContents.match(filter);
if (matches) {
results.push(...matches);
}
}
}
}
+19 -15
View File
@@ -62,6 +62,24 @@ export async function createApp({
}
}
const isReactNative =
template?.includes("react-native") || framework === "react-native";
function isReactNativeCLI() {
return (
isReactNative &&
(language === "typescript" || (template && !template.includes("expo")))
);
}
function isMacOS() {
return process.platform === "darwin";
}
if (isReactNativeCLI() && isMacOS()) {
// fail early if the user doesn't have the right version of Ruby installed on macOS
await checkRubyVersion();
}
const root = path.resolve(appPath);
if (!(await isWriteable(path.dirname(root)))) {
@@ -98,20 +116,6 @@ export async function createApp({
);
}
const isReactNative =
template?.includes("react-native") || framework === "react-native";
function isReactNativeCLI() {
return (
isReactNative &&
(language === "typescript" || (template && !template.includes("expo")))
);
}
if (isReactNativeCLI()) {
// fail early if the user doesn't have the right version of Ruby installed
await checkRubyVersion();
}
if (template) {
/**
* If a template repository is provided, clone it.
@@ -199,7 +203,7 @@ export async function createApp({
console.log();
}
if (isReactNativeCLI()) {
if (isReactNativeCLI() && isMacOS()) {
await podInstall(root, isOnline);
}
+91 -33
View File
@@ -3,54 +3,101 @@ import {
DeployedContract,
fetchContractMetadataFromAddress,
getChainProvider,
ThirdwebSDK,
} from "@thirdweb-dev/sdk";
import { ThirdwebStorage } from "@thirdweb-dev/storage";
import { spinner, info } from "../core/helpers/logger";
import { allChains } from "@thirdweb-dev/chains";
import fs from "fs";
import prompts from "prompts";
type GenerateOptions = {
path: string;
deployer?: string;
};
import { findMatches } from "../common/file-helper";
import ora from "ora";
import { GenerateOptions, ThirdwebConfig } from "./types";
import { CHAIN_OPTIONS, getContractsForAddresses } from "./utils";
export async function generate(options: GenerateOptions) {
let projectPath: string = options.path?.replace(/\/$/, "") || ".";
let contracts: DeployedContract[] = [];
// Find all addresses in this project
let addresses: string[] = [];
findMatches(projectPath, /(0x[a-fA-F0-9]{40})/g, addresses);
// We check if there's a thirdweb.json config file present
if (fs.existsSync(`${projectPath}/thirdweb.json`)) {
// First we check if there's a thirdweb.json config file present
const thirdwebConfig = JSON.parse(
// Read the current thirdweb config file
const thirdwebConfig: ThirdwebConfig = JSON.parse(
fs.readFileSync(`${projectPath}/thirdweb.json`, "utf-8"),
);
contracts = thirdwebConfig.contracts as DeployedContract[];
} else {
// Otherwise, we get contracts by deployer address (and generate a thirdweb.json)
let deployerAddress: string;
if (options.deployer) {
deployerAddress = options.deployer;
} else {
const res = await prompts({
type: "text",
name: "deployer",
message: GENERATE_MESSAGES.deployerAddress,
});
deployerAddress = res.deployer.trim();
}
const sdk = new ThirdwebSDK("polygon");
contracts = await sdk.multiChainRegistry.getContractAddresses(
deployerAddress,
// Check if there are any addresses in the project that aren't yet in the config
const configAddresses = thirdwebConfig.contracts.map((contract) =>
contract.address.toLowerCase(),
);
const newAddresses = addresses.filter(
(address) => !configAddresses.includes(address.toLowerCase()),
);
// Initialize contracts to the contracts in thirdweb.json file
contracts = [...thirdwebConfig.contracts];
// If we have new contracts that aren't yet stored in config
// get full contract objects
if (newAddresses.length) {
const chainIds = thirdwebConfig.chainIds;
await getContractsForAddresses(newAddresses, chainIds, contracts);
if (contracts.length > thirdwebConfig.contracts.length) {
fs.writeFileSync(
`${projectPath}/thirdweb.json`,
JSON.stringify({ chainIds, contracts }, undefined, 2),
);
const numberOfNewContracts =
contracts.length - thirdwebConfig.contracts.length;
info(
`Updated thirdweb.json with ${numberOfNewContracts} new contract${
numberOfNewContracts === 1 ? "" : "s"
}`,
);
}
}
} else {
// If there is no configuration file present, we need to generate one...
// First we ask the user what chains are used in their project
const res = await prompts({
type: "autocompleteMultiselect",
name: "chains",
message: GENERATE_MESSAGES.chains,
choices: CHAIN_OPTIONS,
});
const chainIds: number[] = res.chains.map(
(index: number) => allChains[index].chainId,
);
// Then we check for the chainId of each address
await getContractsForAddresses(addresses, chainIds, contracts);
// Create a thirdweb.json file with the specific contracts and chain ids
fs.writeFileSync(
`${projectPath}/thirdweb.json`,
JSON.stringify({ contracts }, undefined, 2),
JSON.stringify({ chainIds, contracts }, undefined, 2),
);
info(
`Created a thirdweb.json file with configuration for ${
contracts.length
} contract${
contracts.length === 1 ? "" : "s"
} detected in your project.\n\n - You can also update this configuration manually by editing the file.\n`,
);
}
// Attempt to download the ABI for the contract
// Attempt to download the ABI for each contract
const abiSpinner = spinner(
`Downloading ABIs for contracts configured in 'thirdweb.json'`,
);
const storage = new ThirdwebStorage();
const metadata: {
address: string;
@@ -97,7 +144,7 @@ export async function generate(options: GenerateOptions) {
}
const file = fs.readFileSync(filePath, "utf-8");
const abiRegex = /GENERATED_ABI = \{.*\}/s;
const abiRegex = /GENERATED_ABI = \{.*\};\n\n/s;
const contractAbis = metadata.reduce((acc, contract) => {
acc[contract.address] = contract.metadata.abi;
return acc;
@@ -105,8 +152,9 @@ export async function generate(options: GenerateOptions) {
const updatedAbis = JSON.stringify(contractAbis, null, 2);
const updatedFile = file.replace(
abiRegex,
`GENERATED_ABI = ${updatedAbis}`,
`GENERATED_ABI = ${updatedAbis};\n\n`,
);
fs.writeFileSync(filePath, updatedFile);
});
@@ -128,6 +176,12 @@ export async function generate(options: GenerateOptions) {
fs.writeFileSync(typeFilePath, updatedFile);
}
abiSpinner.succeed(
`Downloaded and cached ABIs for ${contracts.length} smart contract${
contracts.length === 1 ? "" : "s"
}`,
);
// Add generate command to postinstall
const packageJsonPath = `${projectPath}/package.json`;
if (!fs.existsSync(packageJsonPath)) {
@@ -141,8 +195,8 @@ export async function generate(options: GenerateOptions) {
const postinstall = packageJson.scripts?.postinstall
? packageJson.scripts.postinstall +
` && npx thirdweb generate --skip-update-check`
: `npx thirdweb generate --skip-update-check`;
` && export THIRDWEB_CLI_SKIP_INTRO=true && npx thirdweb generate --skip-update-check`
: `export THIRDWEB_CLI_SKIP_INTRO=true && npx thirdweb generate --skip-update-check`;
fs.writeFileSync(
packageJsonPath,
@@ -158,4 +212,8 @@ export async function generate(options: GenerateOptions) {
2,
),
);
ora(
"Added 'npx thirdweb generate' to postinstall in package.json.\n\n - This is necessary to use 'thirdweb generate' in production.\n",
).info();
}
+19
View File
@@ -0,0 +1,19 @@
import { DeployedContract } from "@thirdweb-dev/sdk";
export type ThirdwebConfig = {
chainIds: number[];
contracts: DeployedContract[];
};
export type GenerateOptions = {
path: string;
deployer?: string;
};
export type ContractChainPrompt = {
address: string;
chains: {
slug: string;
chainId: number;
}[];
};
+87
View File
@@ -0,0 +1,87 @@
import { DeployedContract, getChainProvider } from "@thirdweb-dev/sdk";
import prompts from "prompts";
import { ContractChainPrompt } from "./types";
import { allChains } from "@thirdweb-dev/chains";
export const CHAIN_OPTIONS = allChains.map((chain) => ({ title: chain.slug }));
export async function getContractsForAddresses(
addresses: string[],
chainIds: number[],
contracts: DeployedContract[],
) {
let contractChainPrompts: ContractChainPrompt[] = [];
await Promise.all(
addresses.map(async (address) => {
// Check which chainIds of the provided chains have a contract at this address
let chainIdsWithContract: number[] = [];
await Promise.all(
chainIds.map(async (chainId) => {
// Handles cacheing of provider by chain
const provider = getChainProvider(chainId, {});
try {
const code = await provider.getCode(address);
if (!code || code === "0x") {
return;
}
chainIdsWithContract.push(chainId);
} catch {
return;
}
}),
);
// If no chainId has this contract, we assume it's an EOA and move on
if (!chainIdsWithContract.length) {
return;
}
// If only one chain has this contract address, add it to our contracts list
if (chainIdsWithContract.length === 1) {
contracts.push({
address,
chainId: chainIdsWithContract[0],
});
return;
}
// Otherwise, add our contract to the list of contracts
// where we need to prompt the user to select the chain
contractChainPrompts.push({
address,
chains: chainIdsWithContract.map((chainId) => ({
slug: allChains[chainId].slug,
chainId,
})),
});
}),
);
// TODO: Long term, smart contracts in the generated-abis cache should be cached by
// both smart contract and chain id because people may want to use the same contract address
// on different chains
// For all addresses that have smart contracts deployed on multiple selected chains
// allow the user to specify which chain they want to use for their smart contract
for (const prompt of contractChainPrompts) {
const res = await prompts({
type: "select",
name: "chainId",
message: `What chain is smart contract '${prompt.address}' on?`,
choices: prompt.chains.map((chain) => ({
title: chain.slug,
value: chain.chainId,
})),
});
contracts.push({
address: prompt.address,
chainId: res.chainId,
});
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
# generated-abis
This package is used as an ABI cache for the CLI and SDK that can get bundled with the SDK. It will never need to be edited or rebuilt.
This package is used as an ABI cache for the CLI and SDK that can get bundled with the SDK. It's used to store generated ABIs that can be used for performance optimization purposes and static types by the SDK. It will never need to be edited or rebuilt.
Instead of using this directly, go to the [thirdweb SDK package](https://npmjs.com/package/@thirdweb-dev/sdk).
+38
View File
@@ -1,5 +1,43 @@
# @thirdweb-dev/react-core
## 3.11.6
### Patch Changes
- Updated dependencies [[`b3d57949`](https://github.com/thirdweb-dev/js/commit/b3d57949bd047831fda7e600b4872200340903b5), [`602d8cbc`](https://github.com/thirdweb-dev/js/commit/602d8cbcfaa7c1e117c01f842f89508f7333fcfe)]:
- @thirdweb-dev/sdk@3.10.9
## 3.11.5
### Patch Changes
- [#870](https://github.com/thirdweb-dev/js/pull/870) [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d) Thanks [@jnsdls](https://github.com/jnsdls)! - fix crash during SSR when "window" is undefined
- [#862](https://github.com/thirdweb-dev/js/pull/862) [`b5648aee`](https://github.com/thirdweb-dev/js/commit/b5648aee83b299d07a8eed7773bd32bcceef9657) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - Make tokenId optional one useNFTBalance
- Updated dependencies [[`1547d76c`](https://github.com/thirdweb-dev/js/commit/1547d76cce52265076c347599014f578c1de6152), [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d), [`1b8f812f`](https://github.com/thirdweb-dev/js/commit/1b8f812fb8c910d91fb7535d6446a0b6fc6b2310), [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d)]:
- @thirdweb-dev/sdk@3.10.8
- @thirdweb-dev/wallets@0.2.14
- @thirdweb-dev/chains@0.1.11
## 3.11.4
### Patch Changes
- [#851](https://github.com/thirdweb-dev/js/pull/851) [`c5c2d947`](https://github.com/thirdweb-dev/js/commit/c5c2d9478acd4d4a4e6ce814716bdf1b6e51eafc) Thanks [@MananTank](https://github.com/MananTank)! - Fix wallet autoconnect issues
### Fixes
- infinite loading spinner on connect wallet button when wallet is locked or connection to app is closed
- network switch popup on page load when wallet is connected to different network than it was previously connected
- removed autoconnect timeout - don't need it anymore
- [#855](https://github.com/thirdweb-dev/js/pull/855) [`2dd192a5`](https://github.com/thirdweb-dev/js/commit/2dd192a5676f1b6d3c310ec796bf331252098d48) Thanks [@MananTank](https://github.com/MananTank)! - Add auth in Connect Wallet button
- Updated dependencies [[`c5c2d947`](https://github.com/thirdweb-dev/js/commit/c5c2d9478acd4d4a4e6ce814716bdf1b6e51eafc), [`2dd192a5`](https://github.com/thirdweb-dev/js/commit/2dd192a5676f1b6d3c310ec796bf331252098d48)]:
- @thirdweb-dev/wallets@0.2.13
- @thirdweb-dev/sdk@3.10.7
## 3.11.3
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react-core",
"version": "3.11.3",
"version": "3.11.6",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-core",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -61,12 +61,12 @@ export function useNetwork(): [NetworkMetadata, SwitchNetwork | undefined] {
const supportedChains = useSupportedChains();
const wallet = useWallet();
const isMetamaskInstalled = assertWindowEthereum(window)
? window.ethereum.isMetaMask
const isMetamaskInstalled = assertWindowEthereum(globalThis.window)
? globalThis.window.ethereum.isMetaMask
: false;
const isCoinbaseInstalled = assertWindowEthereum(window)
? window.ethereum.isCoinbaseWallet
const isCoinbaseInstalled = assertWindowEthereum(globalThis.window)
? globalThis.window.ethereum.isCoinbaseWallet
: false;
// switch not supported if connected to a mobile wallet
@@ -1,6 +1,5 @@
import { DAppMetaData } from "../types/dAppMeta";
import type { Wallet, WalletInstance } from "../types/wallet";
import { timeoutPromise } from "../utils/timeoutPromise";
import { ThirdwebThemeContext } from "./theme-context";
import { Chain } from "@thirdweb-dev/chains";
import {
@@ -102,12 +101,7 @@ export function ThirdwebWalletProvider(
chain: props.activeChain || props.chains[0],
theme: theme || "dark",
};
}, [
props.chains,
props.dAppMeta,
props.activeChain,
theme,
]);
}, [props.chains, props.dAppMeta, props.activeChain, theme]);
const createWalletInstance = useCallback(
<I extends WalletInstance>(wallet: Wallet<I>): I => {
@@ -250,15 +244,10 @@ export function ThirdwebWalletProvider(
const wallet = createWalletInstance(lastConnectedWallet);
try {
setConnectionStatus("connecting");
// give up auto connect if it takes more than 10 seconds
// this is to handle the edge case when trying to auto-connect to wallet that does not exist anymore (extension is uninstalled)
await timeoutPromise(
10000,
wallet.autoConnect(parsedParams),
`AutoConnect timeout`,
);
await wallet.autoConnect(parsedParams);
handleWalletConnect(wallet, parsedParams);
} catch (e) {
coordinatorStorage.removeItem(LAST_CONNECTED_WALLET_STORAGE_KEY);
setConnectionStatus("disconnected");
throw e;
}
@@ -1,13 +0,0 @@
// it rejects the promise if the given promise does not resolve within the given time
export const timeoutPromise = <T>(
ms: number,
promise: Promise<T>,
errorMessage: string,
): Promise<T> => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error(errorMessage));
}, ms);
promise.then(resolve, reject);
});
};
@@ -275,7 +275,7 @@ export function useOwnedNFTs<TContract extends NFTContract>(
export function useNFTBalance(
contract: RequiredParam<NFTContract>,
ownerWalletAddress: RequiredParam<WalletAddress>,
tokenId: RequiredParam<BigNumberish>,
tokenId?: RequiredParam<BigNumberish>,
) {
const contractAddress = contract?.getAddress();
const { erc721, erc1155 } = getErcs(contract);
@@ -1,5 +1,11 @@
# @thirdweb-dev/react-native-compat
## 0.2.6
## 0.2.5
## 0.2.4
## 0.2.3
## 0.2.2
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@thirdweb-dev/react-native-compat",
"description": "Shims for Thirdweb in React Native Projects",
"version": "0.2.3",
"version": "0.2.6",
"author": "thirdweb eng <[email protected]>",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native-compat",
"license": "Apache-2.0",
+27
View File
@@ -1,5 +1,32 @@
# @thirdweb-dev/react-native
## 0.2.6
### Patch Changes
- Updated dependencies [[`b3d57949`](https://github.com/thirdweb-dev/js/commit/b3d57949bd047831fda7e600b4872200340903b5), [`602d8cbc`](https://github.com/thirdweb-dev/js/commit/602d8cbcfaa7c1e117c01f842f89508f7333fcfe)]:
- @thirdweb-dev/sdk@3.10.9
- @thirdweb-dev/react-core@3.11.6
## 0.2.5
### Patch Changes
- Updated dependencies [[`1547d76c`](https://github.com/thirdweb-dev/js/commit/1547d76cce52265076c347599014f578c1de6152), [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d), [`b5648aee`](https://github.com/thirdweb-dev/js/commit/b5648aee83b299d07a8eed7773bd32bcceef9657), [`1b8f812f`](https://github.com/thirdweb-dev/js/commit/1b8f812fb8c910d91fb7535d6446a0b6fc6b2310), [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d)]:
- @thirdweb-dev/sdk@3.10.8
- @thirdweb-dev/react-core@3.11.5
- @thirdweb-dev/wallets@0.2.14
- @thirdweb-dev/chains@0.1.11
## 0.2.4
### Patch Changes
- Updated dependencies [[`c5c2d947`](https://github.com/thirdweb-dev/js/commit/c5c2d9478acd4d4a4e6ce814716bdf1b6e51eafc), [`2dd192a5`](https://github.com/thirdweb-dev/js/commit/2dd192a5676f1b6d3c310ec796bf331252098d48)]:
- @thirdweb-dev/react-core@3.11.4
- @thirdweb-dev/wallets@0.2.13
- @thirdweb-dev/sdk@3.10.7
## 0.2.3
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react-native",
"version": "0.2.3",
"version": "0.2.6",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
+37
View File
@@ -1,5 +1,42 @@
# @thirdweb-dev/react
## 3.11.6
### Patch Changes
- Updated dependencies [[`b3d57949`](https://github.com/thirdweb-dev/js/commit/b3d57949bd047831fda7e600b4872200340903b5), [`602d8cbc`](https://github.com/thirdweb-dev/js/commit/602d8cbcfaa7c1e117c01f842f89508f7333fcfe)]:
- @thirdweb-dev/sdk@3.10.9
- @thirdweb-dev/react-core@3.11.6
## 3.11.5
### Patch Changes
- Updated dependencies [[`1547d76c`](https://github.com/thirdweb-dev/js/commit/1547d76cce52265076c347599014f578c1de6152), [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d), [`b5648aee`](https://github.com/thirdweb-dev/js/commit/b5648aee83b299d07a8eed7773bd32bcceef9657), [`1b8f812f`](https://github.com/thirdweb-dev/js/commit/1b8f812fb8c910d91fb7535d6446a0b6fc6b2310), [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d)]:
- @thirdweb-dev/sdk@3.10.8
- @thirdweb-dev/react-core@3.11.5
- @thirdweb-dev/wallets@0.2.14
- @thirdweb-dev/chains@0.1.11
## 3.11.4
### Patch Changes
- [#851](https://github.com/thirdweb-dev/js/pull/851) [`c5c2d947`](https://github.com/thirdweb-dev/js/commit/c5c2d9478acd4d4a4e6ce814716bdf1b6e51eafc) Thanks [@MananTank](https://github.com/MananTank)! - Fix wallet autoconnect issues
### Fixes
- infinite loading spinner on connect wallet button when wallet is locked or connection to app is closed
- network switch popup on page load when wallet is connected to different network than it was previously connected
- removed autoconnect timeout - don't need it anymore
- [#855](https://github.com/thirdweb-dev/js/pull/855) [`2dd192a5`](https://github.com/thirdweb-dev/js/commit/2dd192a5676f1b6d3c310ec796bf331252098d48) Thanks [@MananTank](https://github.com/MananTank)! - Add auth in Connect Wallet button
- Updated dependencies [[`c5c2d947`](https://github.com/thirdweb-dev/js/commit/c5c2d9478acd4d4a4e6ce814716bdf1b6e51eafc), [`2dd192a5`](https://github.com/thirdweb-dev/js/commit/2dd192a5676f1b6d3c310ec796bf331252098d48)]:
- @thirdweb-dev/react-core@3.11.4
- @thirdweb-dev/wallets@0.2.13
- @thirdweb-dev/sdk@3.10.7
## 3.11.3
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react",
"version": "3.11.3",
"version": "3.11.6",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -11,6 +11,7 @@ export const ChainIcon: React.FC<{
chain?: Chain;
size: string;
active?: boolean;
className?: string;
}> = (props) => {
const url = props.chain?.icon?.url;
const src = url ? resolveIpfsUri(url) : defaultChainIcon;
@@ -34,6 +35,7 @@ export const ChainIcon: React.FC<{
alt=""
width={props.size}
height={props.size}
className={props.className}
/>
{props.active && <ActiveDot />}
</div>
+2
View File
@@ -6,6 +6,7 @@ export const Img: React.FC<{
src: string;
alt?: string;
loading?: "eager" | "lazy";
className?: string;
}> = (props) => {
return (
<img
@@ -19,6 +20,7 @@ export const Img: React.FC<{
height: props.height + "px",
width: props.width + "px",
}}
className={props.className}
/>
);
};
+2 -2
View File
@@ -10,8 +10,8 @@ export const Button = styled.button<{
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: ${radius.sm};
padding: ${spacing.sm} ${spacing.md};
border-radius: ${radius.md};
padding: ${spacing.sm} ${spacing.sm};
font-size: ${fontSize.md};
font-weight: 500;
box-sizing: border-box;
@@ -7,7 +7,7 @@ import { ChevronLeftIcon } from "@radix-ui/react-icons";
export const ModalTitle = styled(Title)<{ theme?: Theme }>`
margin: 0;
font-weight: 500;
font-weight: 600;
font-size: ${fontSize.lg};
color: ${(p) => p.theme.text.neutral};
${media.mobile} {
@@ -22,6 +22,8 @@ import invariant from "tiny-invariant";
type ActionFn = (contract: SmartContract) => any;
const TW_WEB3BUTTON = "tw-web3button";
interface Web3ButtonProps<TActionFn extends ActionFn> {
className?: string;
contractAddress: `0x${string}` | `${string}.eth` | string;
@@ -121,7 +123,12 @@ export const Web3Button = <TAction extends ActionFn>({
);
if (!address) {
return <ConnectWallet theme={theme} />;
return (
<ConnectWallet
theme={theme}
className={`${className || ""} ${TW_WEB3BUTTON}--connect-wallet`}
/>
);
}
// let onClick = () => actionMutation.mutate();
@@ -152,9 +159,11 @@ export const Web3Button = <TAction extends ActionFn>({
<Button
variant="inverted"
type={type}
className={className}
className={`${className || ""} ${TW_WEB3BUTTON}--switch-network`}
onClick={handleSwitchChain}
style={btnStyle}
data-is-loading={confirmStatus === "waiting"}
data-theme={theme}
>
{confirmStatus === "waiting" ? (
<Spinner size="sm" color={"inverted"} />
@@ -195,10 +204,11 @@ export const Web3Button = <TAction extends ActionFn>({
<Button
variant="inverted"
type={type}
className={className}
className={`${className || ""} ${TW_WEB3BUTTON}`}
disabled
onClick={handleSwitchChain}
style={btnStyle}
data-is-loading
data-theme={theme}
>
<Spinner size="md" color={"inverted"} />
</Button>
@@ -211,10 +221,12 @@ export const Web3Button = <TAction extends ActionFn>({
<Button
variant="inverted"
type={type}
className={className}
className={`${className || ""} ${TW_WEB3BUTTON}`}
onClick={() => actionMutation.mutate()}
disabled={isDisabled}
style={btnStyle}
data-is-loading="false"
data-theme={theme}
>
{children}
</Button>
@@ -1,12 +1,17 @@
import { darkTheme, lightTheme } from "../../design-system";
import { darkTheme, iconSize, lightTheme, spacing } from "../../design-system";
import { ConnectedWalletDetails, DropDownPosition } from "./Details";
import { ThemeProvider } from "@emotion/react";
import {
ThirdwebThemeContext,
useAddress,
useConnectionStatus,
useLogin,
useLogout,
useThirdwebAuthContext,
useUser,
useWallet,
} from "@thirdweb-dev/react-core";
import { useContext } from "react";
import { useContext, useState } from "react";
import {
useIsConnectingToSafe,
useSetIsWalletModalOpen,
@@ -16,14 +21,25 @@ import { Button } from "../../components/buttons";
import { Spinner } from "../../components/Spinner";
import styled from "@emotion/styled";
import { fadeInAnimation } from "../../components/FadeIn";
import type { LoginOptions } from "@thirdweb-dev/auth";
import { LockIcon } from "./icons/LockIcon";
import { Flex } from "../../components/basic";
import { shortenAddress } from "../../evm/utils/addresses";
import { SignatureModal } from "./SignatureModal";
type ConnectWalletProps = {
className?: string;
theme?: "dark" | "light";
btnTitle?: string;
dropdownPosition?: DropDownPosition;
auth?: {
loginOptions?: LoginOptions;
loginOptional?: boolean;
};
};
const TW_CONNECT_WALLET = "tw-connect-wallet";
/**
* A component that allows the user to connect their wallet.
*
@@ -44,6 +60,27 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = (props) => {
const setModalTheme = useSetModalTheme();
const address = useAddress();
const [showSignatureModal, setShowSignatureModal] = useState(false);
const authConfig = useThirdwebAuthContext();
const { user } = useUser();
const { login } = useLogin();
const { logout } = useLogout();
const requiresSignIn = props.auth?.loginOptional
? false
: !!authConfig?.authUrl && !!address && !user?.address;
const signIn = async () => {
try {
setShowSignatureModal(true);
await login(props.auth?.loginOptions);
} catch (err) {
console.error("failed to log in", err);
}
setShowSignatureModal(false);
};
return (
<ThemeProvider
theme={
@@ -54,28 +91,71 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = (props) => {
: lightTheme
}
>
{!activeWallet || isConnectingToSafe ? (
<AnimatedButton
disabled={isLoading}
className={props.className}
variant="inverted"
type="button"
style={{
minWidth: "140px",
}}
aria-label={
connectionStatus === "connecting" ? "Connecting" : btnTitle
}
onClick={() => {
setModalTheme(theme);
setIsWalletModalOpen(true);
}}
>
{isLoading ? <Spinner size="sm" color="inverted" /> : btnTitle}
</AnimatedButton>
) : (
<ConnectedWalletDetails dropdownPosition={props.dropdownPosition} />
{showSignatureModal && (
<SignatureModal
open={showSignatureModal}
setOpen={setShowSignatureModal}
/>
)}
{/* Sign In Button */}
{requiresSignIn && (
<Button
variant="inverted"
onClick={signIn}
data-theme={theme}
className={`${TW_CONNECT_WALLET}--sign-in`}
>
<Flex
alignItems="center"
gap="sm"
style={{
paddingRight: spacing.xs,
borderRight: "1px solid",
marginRight: spacing.xs,
}}
>
<LockIcon size={iconSize.sm} />
<span> Sign in </span>
</Flex>
<span>{shortenAddress(address || "", true)}</span>
</Button>
)}
{!requiresSignIn &&
(!activeWallet || isConnectingToSafe ? (
// connect wallet button
<AnimatedButton
disabled={isLoading}
className={`${props.className || ""} ${TW_CONNECT_WALLET}`}
data-theme={theme}
data-is-loading={isLoading}
variant="inverted"
type="button"
style={{
minWidth: "140px",
}}
aria-label={
connectionStatus === "connecting" ? "Connecting" : btnTitle
}
onClick={() => {
setModalTheme(theme);
setIsWalletModalOpen(true);
}}
>
{isLoading ? <Spinner size="sm" color="inverted" /> : btnTitle}
</AnimatedButton>
) : (
<ConnectedWalletDetails
dropdownPosition={props.dropdownPosition}
theme={theme}
onDisconnect={() => {
if (authConfig?.authUrl) {
logout();
}
}}
/>
))}
</ThemeProvider>
);
};
@@ -44,8 +44,12 @@ export type DropDownPosition = {
align: "start" | "center" | "end";
};
const TW_CONNECTED_WALLET = "tw-connected-wallet";
export const ConnectedWalletDetails: React.FC<{
dropdownPosition?: DropDownPosition;
onDisconnect: () => void;
theme: "dark" | "light";
}> = (props) => {
const disconnect = useDisconnect();
const chains = useSupportedChains();
@@ -100,12 +104,20 @@ export const ConnectedWalletDetails: React.FC<{
}, [personalWallet]);
const trigger = (
<WalletInfoButton type="button">
<ChainIcon chain={chain} size={iconSize.lg} />
<WalletInfoButton
type="button"
className={TW_CONNECTED_WALLET}
data-theme={props.theme}
>
<ChainIcon
chain={chain}
size={iconSize.lg}
className={`${TW_CONNECTED_WALLET}__network-icon`}
/>
<ColFlex>
{!balanceQuery.isLoading ? (
<WalletBalance>
<WalletBalance className={`${TW_CONNECTED_WALLET}__balance`}>
{balanceQuery.data?.displayValue.slice(0, 5)}{" "}
{balanceQuery.data?.symbol}
</WalletBalance>
@@ -113,10 +125,17 @@ export const ConnectedWalletDetails: React.FC<{
<Skeleton height={fontSize.sm} width="82px" />
)}
<Spacer y="xs" />
<WalletAddress>{shortenString(address || "")}</WalletAddress>
<WalletAddress className={`${TW_CONNECTED_WALLET}__address`}>
{shortenString(address || "")}
</WalletAddress>
</ColFlex>
<Img width={iconSize.lg} height={iconSize.lg} src={activeWalletIconURL} />
<Img
width={iconSize.lg}
height={iconSize.lg}
src={activeWalletIconURL}
className={`${TW_CONNECTED_WALLET}__wallet-icon`}
/>
</WalletInfoButton>
);
@@ -249,6 +268,7 @@ export const ConnectedWalletDetails: React.FC<{
variant="secondary"
onClick={() => {
disconnect();
props.onDisconnect();
}}
>
<ExitIcon size={iconSize.md} />
@@ -0,0 +1,81 @@
import { Modal } from "../../components/Modal";
import { iconSize, media, spacing } from "../../design-system";
import {
HelperLink,
ModalDescription,
ModalTitle,
} from "../../components/modalElements";
import { useWallet } from "@thirdweb-dev/react-core";
import { Img } from "../../components/Img";
import { Spacer } from "../../components/Spacer";
import { Spinner } from "../../components/Spinner";
import styled from "@emotion/styled";
export const SignatureModal: React.FC<{
open: boolean;
setOpen: (open: boolean) => void;
}> = (props) => {
const wallet = useWallet();
return (
<Modal
open={props.open}
style={{
maxWidth: "450px",
}}
setOpen={props.setOpen}
>
<Container>
<Img
height={iconSize.xl}
src={wallet?.getMeta().iconURL as string}
width={iconSize.xl}
/>
<Spacer y="xl" />
<TitleContainer>
<ModalTitle>Signature Request</ModalTitle>
<Spinner size="md" color="link" />
</TitleContainer>
<Spacer y="md" />
<Desc>Sign the signature request pop-up in your wallet</Desc>
<Spacer y="xxl" />
<HelperLink target="_blank" href="https://support.thirdweb.com/contact">
Having troubles connecting to wallet
</HelperLink>
</Container>
</Modal>
);
};
const TitleContainer = styled.div`
display: flex;
align-items: center;
gap: ${spacing.sm};
${media.mobile} {
justify-content: center;
flex-direction: column;
gap: ${spacing.md};
}
`;
const Desc = styled(ModalDescription)`
${media.mobile} {
max-width: 240px;
margin: 0 auto;
}
`;
const Container = styled.div`
${media.mobile} {
display: flex;
flex-direction: column;
align-items: center;
}
`;
@@ -0,0 +1,18 @@
import { IconFC } from "./types";
export const LockIcon: IconFC = (props) => {
return (
<svg
width={props.size}
height={props.size}
viewBox="0 0 16 21"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M2 21C1.45 21 0.979333 20.8043 0.588 20.413C0.196 20.021 0 19.55 0 19V9C0 8.45 0.196 7.979 0.588 7.587C0.979333 7.19567 1.45 7 2 7H3V5C3 3.61667 3.48767 2.43733 4.463 1.462C5.43767 0.487333 6.61667 0 8 0C9.38333 0 10.5627 0.487333 11.538 1.462C12.5127 2.43733 13 3.61667 13 5V7H14C14.55 7 15.021 7.19567 15.413 7.587C15.8043 7.979 16 8.45 16 9V19C16 19.55 15.8043 20.021 15.413 20.413C15.021 20.8043 14.55 21 14 21H2ZM8 16C8.55 16 9.021 15.8043 9.413 15.413C9.80433 15.021 10 14.55 10 14C10 13.45 9.80433 12.979 9.413 12.587C9.021 12.1957 8.55 12 8 12C7.45 12 6.97933 12.1957 6.588 12.587C6.196 12.979 6 13.45 6 14C6 14.55 6.196 15.021 6.588 15.413C6.97933 15.8043 7.45 16 8 16ZM5 7H11V5C11 4.16667 10.7083 3.45833 10.125 2.875C9.54167 2.29167 8.83333 2 8 2C7.16667 2 6.45833 2.29167 5.875 2.875C5.29167 3.45833 5 4.16667 5 5V7Z"
fill="currentColor"
/>
</svg>
);
};
+19
View File
@@ -1,5 +1,24 @@
# @thirdweb-dev/sdk
## 3.10.9
### Patch Changes
- [#864](https://github.com/thirdweb-dev/js/pull/864) [`b3d57949`](https://github.com/thirdweb-dev/js/commit/b3d57949bd047831fda7e600b4872200340903b5) Thanks [@ciaranightingale](https://github.com/ciaranightingale)! - Remove necessity for LazyMint to detect any of the claim extensions
- [#869](https://github.com/thirdweb-dev/js/pull/869) [`602d8cbc`](https://github.com/thirdweb-dev/js/commit/602d8cbcfaa7c1e117c01f842f89508f7333fcfe) Thanks [@adam-maj](https://github.com/adam-maj)! - Add .prepare() syntax to tiered-drop
## 3.10.8
### Patch Changes
- [#861](https://github.com/thirdweb-dev/js/pull/861) [`1547d76c`](https://github.com/thirdweb-dev/js/commit/1547d76cce52265076c347599014f578c1de6152) Thanks [@adam-maj](https://github.com/adam-maj)! - Add option to pass timestamps for dates
- [#863](https://github.com/thirdweb-dev/js/pull/863) [`1b8f812f`](https://github.com/thirdweb-dev/js/commit/1b8f812fb8c910d91fb7535d6446a0b6fc6b2310) Thanks [@ciaranightingale](https://github.com/ciaranightingale)! - Update Solidity SDK detected extension portal links
- Updated dependencies [[`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d)]:
- @thirdweb-dev/chains@0.1.11
## 3.10.7
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/sdk",
"version": "3.10.7",
"version": "3.10.9",
"description": "The main thirdweb SDK.",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/sdk",
"license": "Apache-2.0",
@@ -17,7 +17,7 @@ export const FEATURE_EDITION_BURNABLE = {
namespace: "edition.burn",
docLinks: {
sdk: "sdk.erc1155burnable",
contracts: "IBurnableERC1155",
contracts: "erc1155burnable",
},
abis: [Erc1155Abi, IBurnableERC1155Abi],
features: {},
@@ -28,9 +28,9 @@ export const FEATURE_EDITION_CLAIM_CONDITIONS_V1 = {
namespace: "edition.drop.claim",
docLinks: {
sdk: "sdk.erc1155claimable",
contracts: "DropSinglePhase1155",
contracts: "erc1155dropsinglephase",
},
abis: [Erc1155Abi, ILazyMintAbi, IDropSinglePhase1155_V1],
abis: [Erc1155Abi, IDropSinglePhase1155_V1],
features: {},
} as const;
@@ -39,9 +39,9 @@ export const FEATURE_EDITION_CLAIM_CONDITIONS_V2 = {
namespace: "edition.drop.claim",
docLinks: {
sdk: "sdk.erc1155claimable",
contracts: "DropSinglePhase1155",
contracts: "erc1155claimconditions",
},
abis: [Erc1155Abi, ILazyMintAbi, IDropSinglePhase1155],
abis: [Erc1155Abi, IDropSinglePhase1155],
features: {},
} as const;
@@ -50,9 +50,9 @@ export const FEATURE_EDITION_CLAIM_PHASES_V2 = {
namespace: "edition.drop.claim",
docLinks: {
sdk: "sdk.erc1155claimable",
contracts: "Drop1155",
contracts: "erc1155claimphases",
},
abis: [Erc1155Abi, ILazyMintAbi, IDropMultiPhase1155],
abis: [Erc1155Abi, IDropMultiPhase1155],
features: {},
} as const;
@@ -61,7 +61,7 @@ export const FEATURE_EDITION_CLAIM_PHASES_V1 = {
namespace: "edition.drop.claim",
docLinks: {
sdk: "sdk.erc1155claimable",
contracts: "Drop1155",
contracts: "erc1155claimphases",
},
abis: [DropERC1155_V2Abi],
features: {},
@@ -72,9 +72,9 @@ export const FEATURE_EDITION_CLAIM_CUSTOM = {
namespace: "edition.drop.claim",
docLinks: {
sdk: "sdk.erc1155claimable",
contracts: "IClaimableERC1155",
contracts: "erc1155claimcustom",
},
abis: [Erc1155Abi, ILazyMintAbi, IClaimableERC1155],
abis: [Erc1155Abi, IClaimableERC1155],
features: {},
} as const;
@@ -83,7 +83,7 @@ export const FEATURE_EDITION_REVEALABLE = {
namespace: "edition.drop.revealer",
docLinks: {
sdk: "sdk.drop.delayedreveal",
contracts: "DelayedReveal",
contracts: "erc1155revealable",
},
abis: [Erc1155Abi, ILazyMintAbi, DelayedRevealAbi],
features: {},
@@ -94,17 +94,11 @@ export const FEATURE_EDITION_LAZY_MINTABLE_V2 = {
namespace: "edition.drop",
docLinks: {
sdk: "sdk.erc1155droppable",
contracts: "LazyMint",
contracts: "lazymint",
},
abis: [Erc1155Abi, ILazyMintAbi],
features: {
[FEATURE_EDITION_REVEALABLE.name]: FEATURE_EDITION_REVEALABLE,
[FEATURE_EDITION_CLAIM_CUSTOM.name]: FEATURE_EDITION_CLAIM_CUSTOM,
[FEATURE_EDITION_CLAIM_CONDITIONS_V1.name]:
FEATURE_EDITION_CLAIM_CONDITIONS_V1,
[FEATURE_EDITION_CLAIM_CONDITIONS_V2.name]:
FEATURE_EDITION_CLAIM_CONDITIONS_V2,
[FEATURE_EDITION_CLAIM_PHASES_V2.name]: FEATURE_EDITION_CLAIM_PHASES_V2,
},
} as const;
@@ -113,7 +107,7 @@ export const FEATURE_EDITION_LAZY_MINTABLE_V1 = {
namespace: "edition.drop",
docLinks: {
sdk: "sdk.erc1155droppable",
contracts: "LazyMint",
contracts: "lazymint",
},
abis: [DropERC1155_V2Abi],
features: {
@@ -126,7 +120,7 @@ export const FEATURE_EDITION_SIGNATURE_MINTABLE = {
namespace: "edition.signature",
docLinks: {
sdk: "sdk.erc1155signaturemintable",
contracts: "ISignatureMintERC1155",
contracts: "erc1155signaturemint",
},
abis: [Erc1155Abi, ISignatureMintERC1155Abi],
features: {},
@@ -137,7 +131,7 @@ export const FEATURE_EDITION_BATCH_TRASNFERABLE = {
namespace: "",
docLinks: {
sdk: "sdk.erc1155",
contracts: "IMulticall",
contracts: "multicall",
},
abis: [Erc1155Abi, MulticallAbi],
features: {},
@@ -148,7 +142,7 @@ export const FEATURE_EDITION_BATCH_MINTABLE = {
namespace: "edition.mint.batch",
docLinks: {
sdk: "sdk.erc1155batchmintable",
contracts: "IMulticall",
contracts: "erc1155batchmintable",
},
abis: [Erc1155Abi, IMintableERC1155Abi, MulticallAbi],
features: {},
@@ -159,7 +153,7 @@ export const FEATURE_EDITION_MINTABLE = {
namespace: "edition.mint",
docLinks: {
sdk: "sdk.erc1155mintable",
contracts: "IMintableERC1155",
contracts: "erc1155mintable",
},
abis: [Erc1155Abi, IMintableERC1155Abi],
features: {
@@ -172,7 +166,7 @@ export const FEATURE_EDITION_ENUMERABLE = {
namespace: "edition.query",
docLinks: {
sdk: "sdk.erc1155",
contracts: "IERC1155",
contracts: "erc1155enumerable",
},
abis: [Erc1155Abi, Erc1155EnumerableAbi],
features: {},
@@ -183,7 +177,7 @@ export const FEATURE_EDITION = {
namespace: "edition",
docLinks: {
sdk: "sdk.erc1155enumerable",
contracts: "IERC1155Enumerable",
contracts: "erc1155",
},
abis: [Erc1155Abi],
features: {
@@ -195,5 +189,11 @@ export const FEATURE_EDITION = {
[FEATURE_EDITION_REVEALABLE.name]: FEATURE_EDITION_REVEALABLE,
[FEATURE_EDITION_SIGNATURE_MINTABLE.name]:
FEATURE_EDITION_SIGNATURE_MINTABLE,
[FEATURE_EDITION_CLAIM_CUSTOM.name]: FEATURE_EDITION_CLAIM_CUSTOM,
[FEATURE_EDITION_CLAIM_CONDITIONS_V1.name]:
FEATURE_EDITION_CLAIM_CONDITIONS_V1,
[FEATURE_EDITION_CLAIM_CONDITIONS_V2.name]:
FEATURE_EDITION_CLAIM_CONDITIONS_V2,
[FEATURE_EDITION_CLAIM_PHASES_V2.name]: FEATURE_EDITION_CLAIM_PHASES_V2,
},
} as const;
@@ -14,7 +14,7 @@ export const FEATURE_TOKEN_CLAIM_CONDITIONS_V1 = {
namespace: "token.drop.claim",
docLinks: {
sdk: "sdk.erc20dclaimable",
contracts: "DropSinglePhase_V1",
contracts: "erc20claimconditions",
},
abis: [ERC20Abi, IDropSinglePhaseV1],
features: {},
@@ -25,7 +25,7 @@ export const FEATURE_TOKEN_CLAIM_CONDITIONS_V2 = {
namespace: "token.drop.claim",
docLinks: {
sdk: "sdk.erc20dclaimable",
contracts: "DropSinglePhase",
contracts: "erc20claimconditions",
},
abis: [ERC20Abi, IDropSinglePhase],
features: {},
@@ -36,7 +36,7 @@ export const FEATURE_TOKEN_CLAIM_PHASES_V2 = {
namespace: "token.drop.claim",
docLinks: {
sdk: "sdk.erc20dclaimable",
contracts: "Drop",
contracts: "erc20claimphases",
},
abis: [ERC20Abi, IDrop],
features: {},
@@ -47,7 +47,7 @@ export const FEATURE_TOKEN_CLAIM_PHASES_V1 = {
namespace: "token.drop.claim",
docLinks: {
sdk: "sdk.erc20dclaimable",
contracts: "Drop",
contracts: "erc20claimphases",
},
abis: [DropERC20_V2Abi],
features: {},
@@ -58,7 +58,7 @@ export const FEATURE_TOKEN_BURNABLE = {
namespace: "token.burn",
docLinks: {
sdk: "sdk.erc20burnable",
contracts: "IBurnableERC20",
contracts: "erc20burnable",
},
abis: [ERC20Abi, IBurnableERC20Abi],
features: {},
@@ -69,7 +69,7 @@ export const FEATURE_TOKEN_SIGNATURE_MINTABLE = {
namespace: "token.signature",
docLinks: {
sdk: "sdk.erc20signaturemintable",
contracts: "ISignatureMintERC20",
contracts: "erc20signaturemint",
},
abis: [ERC20Abi, ISignatureMintERC20Abi],
features: {},
@@ -80,7 +80,7 @@ export const FEATURE_TOKEN_BATCH_MINTABLE = {
namespace: "token.mint.batch",
docLinks: {
sdk: "sdk.erc20batchmintable",
contracts: "IMulticall",
contracts: "erc20batchmintable",
},
abis: [ERC20Abi, IMintableERC20Abi, MulticallAbi],
features: {},
@@ -91,7 +91,7 @@ export const FEATURE_TOKEN_MINTABLE = {
namespace: "token.mint",
docLinks: {
sdk: "sdk.erc20mintable",
contracts: "IMintableERC20",
contracts: "erc20mintable",
},
abis: [ERC20Abi, IMintableERC20Abi],
features: {
@@ -104,7 +104,7 @@ export const FEATURE_TOKEN_PERMIT = {
namespace: "token.permit",
docLinks: {
sdk: "sdk.erc20permit",
contracts: "IERC20Permit",
contracts: "erc20permit",
},
abis: [ERC20Abi, IERC20PermitAbi],
features: {},
@@ -115,7 +115,7 @@ export const FEATURE_TOKEN = {
namespace: "token",
docLinks: {
sdk: "sdk.erc20",
contracts: "IERC20",
contracts: "erc20",
},
abis: [ERC20Abi],
features: {
@@ -20,7 +20,7 @@ export const FEATURE_NFT_BURNABLE = {
namespace: "nft.burn",
docLinks: {
sdk: "sdk.erc721burnable",
contracts: "IBurnableERC721",
contracts: "erc721burnable",
},
abis: [Erc721Abi, IBurnableERC721Abi],
features: {},
@@ -31,7 +31,7 @@ export const FEATURE_NFT_REVEALABLE = {
namespace: "nft.drop.revealer",
docLinks: {
sdk: "sdk.delayedreveal",
contracts: "DelayedReveal",
contracts: "erc721revealable",
},
abis: [Erc721Abi, ILazyMintAbi, DelayedRevealAbi],
features: {},
@@ -42,7 +42,8 @@ export const FEATURE_NFT_TIERED_DROP = {
namespace: "nft.tieredDrop",
docLinks: {
sdk: "sdk.erc721tiereddrop",
contracts: "TieredDrop",
//TODO
contracts: "",
},
abis: [Erc721Abi, TieredDropAbi],
features: {},
@@ -53,9 +54,9 @@ export const FEATURE_NFT_CLAIM_CONDITIONS_V1 = {
namespace: "nft.drop.claim",
docLinks: {
sdk: "sdk.erc721claimable",
contracts: "DropSinglePhase_V1",
contracts: "erc721claimconditions",
},
abis: [Erc721Abi, ILazyMintAbi, IDropSinglePhaseV1],
abis: [Erc721Abi, IDropSinglePhaseV1],
features: {},
} as const;
@@ -64,9 +65,9 @@ export const FEATURE_NFT_CLAIM_CONDITIONS_V2 = {
namespace: "nft.drop.claim",
docLinks: {
sdk: "sdk.erc721claimable",
contracts: "DropSinglePhase",
contracts: "erc721claimconditions",
},
abis: [Erc721Abi, ILazyMintAbi, IDropSinglePhase],
abis: [Erc721Abi, IDropSinglePhase],
features: {},
} as const;
@@ -75,7 +76,7 @@ export const FEATURE_NFT_CLAIM_PHASES_V1 = {
namespace: "nft.drop.claim",
docLinks: {
sdk: "sdk.erc721claimable",
contracts: "Drop",
contracts: "erc721claimphases",
},
abis: [DropERC721_V3Abi],
features: {},
@@ -86,9 +87,9 @@ export const FEATURE_NFT_CLAIM_PHASES_V2 = {
namespace: "nft.drop.claim",
docLinks: {
sdk: "sdk.erc721claimable",
contracts: "Drop",
contracts: "erc721claimphases",
},
abis: [Erc721Abi, ILazyMintAbi, IDrop],
abis: [Erc721Abi, IDrop],
features: {},
} as const;
@@ -97,9 +98,9 @@ export const FEATURE_NFT_CLAIM_CUSTOM = {
namespace: "nft.drop.claim",
docLinks: {
sdk: "sdk.erc721claimable",
contracts: "IClaimableERC721",
contracts: "erc721claimcustom",
},
abis: [Erc721Abi, ILazyMintAbi, IClaimableERC721],
abis: [Erc721Abi, IClaimableERC721],
features: {},
} as const;
@@ -108,16 +109,11 @@ export const FEATURE_NFT_LAZY_MINTABLE = {
namespace: "nft.drop",
docLinks: {
sdk: "sdk.erc721lazymintable",
contracts: "LazyMint",
contracts: "lazymint",
},
abis: [Erc721Abi, ILazyMintAbi],
features: {
[FEATURE_NFT_REVEALABLE.name]: FEATURE_NFT_REVEALABLE,
[FEATURE_NFT_CLAIM_CUSTOM.name]: FEATURE_NFT_CLAIM_CUSTOM,
[FEATURE_NFT_CLAIM_CONDITIONS_V1.name]: FEATURE_NFT_CLAIM_CONDITIONS_V1,
[FEATURE_NFT_CLAIM_CONDITIONS_V2.name]: FEATURE_NFT_CLAIM_CONDITIONS_V2,
[FEATURE_NFT_CLAIM_PHASES_V1.name]: FEATURE_NFT_CLAIM_PHASES_V1,
[FEATURE_NFT_CLAIM_PHASES_V2.name]: FEATURE_NFT_CLAIM_PHASES_V2,
},
} as const;
@@ -126,7 +122,7 @@ export const FEATURE_NFT_BATCH_MINTABLE = {
namespace: "nft.mint.batch",
docLinks: {
sdk: "sdk.erc721batchmintable",
contracts: "IMulticall",
contracts: "erc721batchmintable",
},
abis: [Erc721Abi, IMintableERC721Abi, MulticallAbi],
features: {},
@@ -137,7 +133,7 @@ export const FEATURE_NFT_MINTABLE = {
namespace: "nft.mint",
docLinks: {
sdk: "sdk.erc721mintable",
contracts: "IMintableERC721",
contracts: "erc721mintable",
},
abis: [Erc721Abi, IMintableERC721Abi],
features: {
@@ -150,7 +146,7 @@ export const FEATURE_NFT_SIGNATURE_MINTABLE_V2 = {
namespace: "nft.signature",
docLinks: {
sdk: "sdk.erc721signaturemint",
contracts: "ISignatureMintERC721",
contracts: "erc721signaturemint",
},
abis: [Erc721Abi, SignatureMintERC721Abi],
features: {},
@@ -161,7 +157,7 @@ export const FEATURE_NFT_SIGNATURE_MINTABLE_V1 = {
namespace: "nft.signature",
docLinks: {
sdk: "sdk.erc721signaturemint",
contracts: "ISignatureMintERC721",
contracts: "erc721signaturemint",
},
abis: [SignatureMintERC721_V1Abi],
features: {},
@@ -172,7 +168,7 @@ export const FEATURE_NFT_ENUMERABLE = {
namespace: "nft.query.owned",
docLinks: {
sdk: "sdk.erc721enumerable",
contracts: "IERC721Enumerable",
contracts: "erc721enumerable",
},
abis: [Erc721Abi, Erc721EnumerableAbi],
features: {},
@@ -183,7 +179,7 @@ export const FEATURE_NFT_SUPPLY = {
namespace: "nft.query",
docLinks: {
sdk: "sdk.erc721supply",
contracts: "IERC721Supply",
contracts: "erc721supply",
},
abis: [Erc721Abi, Erc721SupplyAbi],
features: {
@@ -196,7 +192,7 @@ export const FEATURE_NFT = {
namespace: "nft",
docLinks: {
sdk: "sdk.erc721",
contracts: "IERC721",
contracts: "erc721",
},
abis: [Erc721Abi],
features: {
@@ -207,5 +203,10 @@ export const FEATURE_NFT = {
[FEATURE_NFT_SIGNATURE_MINTABLE_V1.name]: FEATURE_NFT_SIGNATURE_MINTABLE_V1,
[FEATURE_NFT_SIGNATURE_MINTABLE_V2.name]: FEATURE_NFT_SIGNATURE_MINTABLE_V2,
[FEATURE_NFT_TIERED_DROP.name]: FEATURE_NFT_TIERED_DROP,
[FEATURE_NFT_CLAIM_CUSTOM.name]: FEATURE_NFT_CLAIM_CUSTOM,
[FEATURE_NFT_CLAIM_CONDITIONS_V1.name]: FEATURE_NFT_CLAIM_CONDITIONS_V1,
[FEATURE_NFT_CLAIM_CONDITIONS_V2.name]: FEATURE_NFT_CLAIM_CONDITIONS_V2,
[FEATURE_NFT_CLAIM_PHASES_V1.name]: FEATURE_NFT_CLAIM_PHASES_V1,
[FEATURE_NFT_CLAIM_PHASES_V2.name]: FEATURE_NFT_CLAIM_PHASES_V2,
},
} as const;
@@ -107,7 +107,7 @@ export const FEATURE_ROYALTY = {
namespace: "royalty",
docLinks: {
sdk: "sdk.contractroyalty",
contracts: "Royalty",
contracts: "royalty",
},
abis: [IThirdwebRoyaltyAbi],
features: {},
@@ -118,7 +118,7 @@ export const FEATURE_PRIMARY_SALE = {
namespace: "sales",
docLinks: {
sdk: "sdk.contractprimarysale",
contracts: "PrimarySale",
contracts: "primarysale",
},
abis: [IThirdwebPrimarySaleAbi],
features: {},
@@ -129,7 +129,7 @@ export const FEATURE_PLATFORM_FEE = {
namespace: "platformFee",
docLinks: {
sdk: "sdk.platformfee",
contracts: "PlatformFee",
contracts: "platformfee",
},
abis: [IThirdwebPlatformFeeAbi],
features: {},
@@ -140,7 +140,7 @@ export const FEATURE_PERMISSIONS_ENUMERABLE = {
namespace: "roles",
docLinks: {
sdk: "sdk.contractroles",
contracts: "PermissionsEnumerable",
contracts: "permissionsenumerable",
},
abis: [IPermissionsEnumerableAbi],
features: {},
@@ -151,7 +151,7 @@ export const FEATURE_PERMISSIONS = {
namespace: "roles",
docLinks: {
sdk: "sdk.contractroles",
contracts: "Permissions",
contracts: "permissions",
},
abis: [IPermissionsAbi],
features: {
@@ -164,7 +164,7 @@ export const FEATURE_METADATA = {
namespace: "metadata",
docLinks: {
sdk: "sdk.contractmetadata",
contracts: "ContractMetadata",
contracts: "contractmetadata",
},
abis: [IContractMetadataAbi],
features: {},
@@ -175,7 +175,8 @@ export const FEATURE_APPURI = {
namespace: "appURI",
docLinks: {
sdk: "sdk.appURI",
contracts: "AppURI",
//TODO
contracts: "",
},
abis: [IAppURI],
features: {},
@@ -186,7 +187,7 @@ export const FEATURE_OWNER = {
namespace: "owner",
docLinks: {
sdk: "sdk.owner",
contracts: "Ownable",
contracts: "ownable",
},
abis: [IOwnableAbi],
features: {},
@@ -209,7 +210,8 @@ export const FEATURE_PACK_VRF = {
namespace: "pack.vrf",
docLinks: {
sdk: "sdk.packvrf",
contracts: "IPackVRFDirect",
//TODO
contracts: "",
},
abis: [IPackVRFAbi],
features: {},
@@ -220,7 +222,8 @@ export const FEATURE_PLUGIN_ROUTER = {
namespace: "plugin.router",
docLinks: {
sdk: "sdk.pluginrouter",
contracts: "IRouter",
//TODO
contracts: "",
},
abis: [getAllPluginsAbi],
features: {},
@@ -231,6 +234,7 @@ export const FEATURE_EXTENSION_ROUTER = {
namespace: "extension.router",
docLinks: {
sdk: "",
//TODO
contracts: "",
},
abis: [getAllExtensionsAbi],
@@ -7,24 +7,15 @@ import {
FEATURE_EDITION_LAZY_MINTABLE_V2,
FEATURE_EDITION_REVEALABLE,
} from "../../constants/erc1155-features";
import {
BaseClaimConditionERC1155,
BaseDelayedRevealERC1155,
BaseDropERC1155,
} from "../../types/eips";
import { BaseDelayedRevealERC1155, BaseDropERC1155 } from "../../types/eips";
import { UploadProgressEvent } from "../../types/events";
import { DetectableFeature } from "../interfaces/DetectableFeature";
import { TransactionResultWithId } from "../types";
import { ContractWrapper } from "./contract-wrapper";
import { DelayedReveal } from "./delayed-reveal";
import { Erc1155 } from "./erc-1155";
import { ERC1155Claimable } from "./erc-1155-claimable";
import { Erc1155ClaimableWithConditions } from "./erc-1155-claimable-with-conditions";
import { Transaction } from "./transactions";
import type {
DropERC1155_V2,
IClaimableERC1155,
} from "@thirdweb-dev/contracts-js";
import type { DropERC1155_V2 } from "@thirdweb-dev/contracts-js";
import { TokensLazyMintedEvent } from "@thirdweb-dev/contracts-js/dist/declarations/src/LazyMint";
import { ThirdwebStorage } from "@thirdweb-dev/storage";
import { ethers } from "ethers";
@@ -65,19 +56,6 @@ export class Erc1155LazyMintable implements DetectableFeature {
*/
public revealer: DelayedReveal<BaseDelayedRevealERC1155> | undefined;
/**
* Claim tokens and configure claim conditions
* @remarks Let users claim NFTs. Define who can claim NFTs in the collection, when and how many.
* @example
* ```javascript
* const quantity = 10;
* const tokenId = 0;
* await contract.erc1155.claimTo("0x...", 0, quantity);
* ```
*/
public claimWithConditions: Erc1155ClaimableWithConditions | undefined;
public claim: ERC1155Claimable | undefined;
private contractWrapper: ContractWrapper<BaseDropERC1155>;
private erc1155: Erc1155;
private storage: ThirdwebStorage;
@@ -91,8 +69,6 @@ export class Erc1155LazyMintable implements DetectableFeature {
this.contractWrapper = contractWrapper;
this.storage = storage;
this.claim = this.detectErc1155Claimable();
this.claimWithConditions = this.detectErc1155ClaimableWithConditions();
this.revealer = this.detectErc1155Revealable();
}
@@ -201,47 +177,6 @@ export class Erc1155LazyMintable implements DetectableFeature {
* PRIVATE FUNCTIONS
*******************************/
private detectErc1155Claimable(): ERC1155Claimable | undefined {
if (
detectContractFeature<IClaimableERC1155>(
this.contractWrapper,
"ERC1155ClaimCustom",
)
) {
return new ERC1155Claimable(this.contractWrapper);
}
return undefined;
}
private detectErc1155ClaimableWithConditions():
| Erc1155ClaimableWithConditions
| undefined {
if (
detectContractFeature<BaseClaimConditionERC1155>(
this.contractWrapper,
"ERC1155ClaimConditionsV1",
) ||
detectContractFeature<BaseClaimConditionERC1155>(
this.contractWrapper,
"ERC1155ClaimConditionsV2",
) ||
detectContractFeature<BaseClaimConditionERC1155>(
this.contractWrapper,
"ERC1155ClaimPhasesV1",
) ||
detectContractFeature<BaseClaimConditionERC1155>(
this.contractWrapper,
"ERC1155ClaimPhasesV2",
)
) {
return new Erc1155ClaimableWithConditions(
this.contractWrapper,
this.storage,
);
}
return undefined;
}
private detectErc1155Revealable():
| DelayedReveal<BaseDelayedRevealERC1155>
| undefined {
+54 -5
View File
@@ -28,6 +28,7 @@ import { EditionMetadataOrUri } from "../../schema/tokens/edition";
import { ClaimOptions, UploadProgressEvent } from "../../types";
import { AirdropInput } from "../../types/airdrop/airdrop";
import {
BaseClaimConditionERC1155,
BaseDropERC1155,
BaseERC1155,
BaseSignatureMintERC1155,
@@ -45,12 +46,15 @@ import { Transaction } from "./transactions";
import type {
DropERC1155,
IBurnableERC1155,
IClaimableERC1155,
IERC1155Enumerable,
IMintableERC1155,
TokenERC1155,
} from "@thirdweb-dev/contracts-js";
import { ThirdwebStorage } from "@thirdweb-dev/storage";
import { BigNumber, BigNumberish, BytesLike, ethers } from "ethers";
import { ERC1155Claimable } from "./erc-1155-claimable";
import { Erc1155ClaimableWithConditions } from "./erc-1155-claimable-with-conditions";
/**
* Standard ERC1155 NFT functions
@@ -74,6 +78,8 @@ export class Erc1155<
private burnable: Erc1155Burnable | undefined;
private lazyMintable: Erc1155LazyMintable | undefined;
private signatureMintable: Erc1155SignatureMintable | undefined;
private claimWithConditions: Erc1155ClaimableWithConditions | undefined;
private claimCustom: ERC1155Claimable | undefined;
protected contractWrapper: ContractWrapper<T>;
protected storage: ThirdwebStorage;
@@ -95,6 +101,8 @@ export class Erc1155<
this.burnable = this.detectErc1155Burnable();
this.lazyMintable = this.detectErc1155LazyMintable();
this.signatureMintable = this.detectErc1155SignatureMintable();
this.claimCustom = this.detectErc1155Claimable();
this.claimWithConditions = this.detectErc1155ClaimableWithConditions();
this._chainId = chainId;
}
@@ -853,8 +861,8 @@ export class Erc1155<
quantity: BigNumberish,
options?: ClaimOptions,
): Promise<Transaction> {
const claimWithConditions = this.lazyMintable?.claimWithConditions;
const claim = this.lazyMintable?.claim;
const claimWithConditions = this.claimWithConditions;
const claim = this.claimCustom;
if (claimWithConditions) {
return claimWithConditions.conditions.getClaimTransaction(
destinationAddress,
@@ -940,8 +948,8 @@ export class Erc1155<
quantity: BigNumberish,
options?: ClaimOptions,
) => {
const claimWithConditions = this.lazyMintable?.claimWithConditions;
const claim = this.lazyMintable?.claim;
const claimWithConditions = this.claimWithConditions;
const claim = this.claimCustom;
if (claimWithConditions) {
return claimWithConditions.to.prepare(
destinationAddress,
@@ -982,7 +990,7 @@ export class Erc1155<
*/
get claimConditions() {
return assertEnabled(
this.lazyMintable?.claimWithConditions,
this.claimWithConditions,
FEATURE_EDITION_CLAIM_CONDITIONS_V2,
).conditions;
}
@@ -1132,4 +1140,45 @@ export class Erc1155<
}
return undefined;
}
private detectErc1155Claimable(): ERC1155Claimable | undefined {
if (
detectContractFeature<IClaimableERC1155>(
this.contractWrapper,
"ERC1155ClaimCustom",
)
) {
return new ERC1155Claimable(this.contractWrapper);
}
return undefined;
}
private detectErc1155ClaimableWithConditions():
| Erc1155ClaimableWithConditions
| undefined {
if (
detectContractFeature<BaseClaimConditionERC1155>(
this.contractWrapper,
"ERC1155ClaimConditionsV1",
) ||
detectContractFeature<BaseClaimConditionERC1155>(
this.contractWrapper,
"ERC1155ClaimConditionsV2",
) ||
detectContractFeature<BaseClaimConditionERC1155>(
this.contractWrapper,
"ERC1155ClaimPhasesV1",
) ||
detectContractFeature<BaseClaimConditionERC1155>(
this.contractWrapper,
"ERC1155ClaimPhasesV2",
)
) {
return new Erc1155ClaimableWithConditions(
this.contractWrapper,
this.storage,
);
}
return undefined;
}
}
@@ -7,20 +7,13 @@ import {
FEATURE_NFT_REVEALABLE,
} from "../../constants/erc721-features";
import { UploadProgressEvent } from "../../types";
import {
BaseClaimConditionERC721,
BaseDelayedRevealERC721,
BaseDropERC721,
} from "../../types/eips";
import { BaseDelayedRevealERC721, BaseDropERC721 } from "../../types/eips";
import { DetectableFeature } from "../interfaces/DetectableFeature";
import { TransactionResultWithId } from "../types";
import { ContractWrapper } from "./contract-wrapper";
import { DelayedReveal } from "./delayed-reveal";
import { Erc721 } from "./erc-721";
import { Erc721Claimable } from "./erc-721-claimable";
import { Erc721ClaimableWithConditions } from "./erc-721-claimable-with-conditions";
import { Transaction } from "./transactions";
import type { IClaimableERC721 } from "@thirdweb-dev/contracts-js";
import { TokensLazyMintedEvent } from "@thirdweb-dev/contracts-js/dist/declarations/src/LazyMint";
import { ThirdwebStorage } from "@thirdweb-dev/storage";
import { ethers } from "ethers";
@@ -70,18 +63,6 @@ export class Erc721LazyMintable implements DetectableFeature {
*/
public revealer: DelayedReveal<BaseDelayedRevealERC721> | undefined;
/**
* Claim tokens and configure claim conditions
* @remarks Let users claim NFTs. Define who can claim NFTs in the collection, when and how many.
* @example
* ```javascript
* const quantity = 10;
* await contract.erc721.claim(quantity);
* ```
*/
public claimWithConditions: Erc721ClaimableWithConditions | undefined;
public claim: Erc721Claimable | undefined;
private contractWrapper: ContractWrapper<BaseDropERC721>;
private erc721: Erc721;
private storage: ThirdwebStorage;
@@ -96,8 +77,6 @@ export class Erc721LazyMintable implements DetectableFeature {
this.storage = storage;
this.revealer = this.detectErc721Revealable();
this.claimWithConditions = this.detectErc721ClaimableWithConditions();
this.claim = this.detectErc721Claimable();
}
/**
@@ -194,46 +173,4 @@ export class Erc721LazyMintable implements DetectableFeature {
}
return undefined;
}
private detectErc721ClaimableWithConditions():
| Erc721ClaimableWithConditions
| undefined {
if (
detectContractFeature<BaseClaimConditionERC721>(
this.contractWrapper,
"ERC721ClaimConditionsV1",
) ||
detectContractFeature<BaseClaimConditionERC721>(
this.contractWrapper,
"ERC721ClaimConditionsV2",
) ||
detectContractFeature<BaseClaimConditionERC721>(
this.contractWrapper,
"ERC721ClaimPhasesV1",
) ||
detectContractFeature<BaseClaimConditionERC721>(
this.contractWrapper,
"ERC721ClaimPhasesV2",
)
) {
return new Erc721ClaimableWithConditions(
this.erc721,
this.contractWrapper,
this.storage,
);
}
return undefined;
}
private detectErc721Claimable(): Erc721Claimable | undefined {
if (
detectContractFeature<IClaimableERC721>(
this.contractWrapper,
"ERC721ClaimCustom",
)
) {
return new Erc721Claimable(this.erc721, this.contractWrapper);
}
return undefined;
}
}
@@ -17,7 +17,7 @@ import {
} from "../../schema/contracts/tiered-drop";
import { UploadProgressEvent } from "../../types/events";
import { DetectableFeature } from "../interfaces/DetectableFeature";
import { TransactionResult, TransactionResultWithId } from "../types";
import { TransactionResultWithId } from "../types";
import { ContractWrapper } from "./contract-wrapper";
import { Erc721 } from "./erc-721";
import type { TieredDrop, ISignatureAction } from "@thirdweb-dev/contracts-js";
@@ -28,6 +28,8 @@ import {
import { ThirdwebStorage } from "@thirdweb-dev/storage";
import { BigNumberish, ethers } from "ethers";
import invariant from "tiny-invariant";
import { Transaction } from "./transactions";
import { buildTransactionFunction } from "../../common/transactions";
export class Erc721TieredDrop implements DetectableFeature {
featureName = FEATURE_NFT_TIERED_DROP.name;
@@ -112,164 +114,182 @@ export class Erc721TieredDrop implements DetectableFeature {
return nfts;
}
public async createBatchWithTier(
metadatas: NFTMetadataOrUri[],
tier: string,
options?: {
onProgress: (event: UploadProgressEvent) => void;
},
): Promise<TransactionResultWithId<NFTMetadata>[]> {
// TODO: Change this to on extension
const startFileNumber = await this.erc721.nextTokenIdToMint();
const batch = await uploadOrExtractURIs(
metadatas,
this.storage,
startFileNumber.toNumber(),
options,
);
const baseUri = getBaseUriFromBatch(batch);
createBatchWithTier = buildTransactionFunction(
async (
metadatas: NFTMetadataOrUri[],
tier: string,
options?: {
onProgress: (event: UploadProgressEvent) => void;
},
): Promise<Transaction<TransactionResultWithId<NFTMetadata>[]>> => {
// TODO: Change this to on extension
const startFileNumber = await this.erc721.nextTokenIdToMint();
const batch = await uploadOrExtractURIs(
metadatas,
this.storage,
startFileNumber.toNumber(),
options,
);
const baseUri = getBaseUriFromBatch(batch);
const receipt = await this.contractWrapper.sendTransaction("lazyMint", [
batch.length,
baseUri.endsWith("/") ? baseUri : `${baseUri}/`,
tier,
ethers.utils.toUtf8Bytes(""),
]);
return Transaction.fromContractWrapper({
contractWrapper: this.contractWrapper,
method: "lazyMint",
args: [
batch.length,
baseUri.endsWith("/") ? baseUri : `${baseUri}/`,
tier,
ethers.utils.toUtf8Bytes(""),
],
parse: (receipt) => {
const event = this.contractWrapper.parseLogs<TokensLazyMintedEvent>(
"TokensLazyMinted",
receipt?.logs,
);
const event = this.contractWrapper.parseLogs<TokensLazyMintedEvent>(
"TokensLazyMinted",
receipt?.logs,
);
const startingIndex = event[0].args[1];
const endingIndex = event[0].args[2];
const results: TransactionResultWithId<NFTMetadata>[] = [];
for (let id = startingIndex; id.lte(endingIndex); id = id.add(1)) {
results.push({
id,
receipt,
data: () => this.erc721.getTokenMetadata(id),
const startingIndex = event[0].args[1];
const endingIndex = event[0].args[2];
const results: TransactionResultWithId<NFTMetadata>[] = [];
for (let id = startingIndex; id.lte(endingIndex); id = id.add(1)) {
results.push({
id,
receipt,
data: () => this.erc721.getTokenMetadata(id),
});
}
return results;
},
});
}
return results;
}
public async createDelayedRevealBatchWithTier(
placeholder: NFTMetadataInput,
metadatas: NFTMetadataInput[],
password: string,
tier: string,
options?: {
onProgress: (event: UploadProgressEvent) => void;
},
): Promise<TransactionResultWithId<NFTMetadata>[]> {
if (!password) {
throw new Error("Password is required");
}
);
const placeholderUris = await this.storage.uploadBatch(
[CommonNFTInput.parse(placeholder)],
{
rewriteFileNames: {
fileStartNumber: 0,
},
createDelayedRevealBatchWithTier = buildTransactionFunction(
async (
placeholder: NFTMetadataInput,
metadatas: NFTMetadataInput[],
password: string,
tier: string,
options?: {
onProgress: (event: UploadProgressEvent) => void;
},
);
const placeholderUri = getBaseUriFromBatch(placeholderUris);
const startFileNumber = await this.erc721.nextTokenIdToMint();
const uris = await this.storage.uploadBatch(
metadatas.map((m) => CommonNFTInput.parse(m)),
{
onProgress: options?.onProgress,
rewriteFileNames: {
fileStartNumber: startFileNumber.toNumber(),
): Promise<Transaction<TransactionResultWithId<NFTMetadata>[]>> => {
if (!password) {
throw new Error("Password is required");
}
const placeholderUris = await this.storage.uploadBatch(
[CommonNFTInput.parse(placeholder)],
{
rewriteFileNames: {
fileStartNumber: 0,
},
},
);
const placeholderUri = getBaseUriFromBatch(placeholderUris);
const startFileNumber = await this.erc721.nextTokenIdToMint();
const uris = await this.storage.uploadBatch(
metadatas.map((m) => CommonNFTInput.parse(m)),
{
onProgress: options?.onProgress,
rewriteFileNames: {
fileStartNumber: startFileNumber.toNumber(),
},
},
},
);
const baseUri = getBaseUriFromBatch(uris);
const baseUriId = await this.contractWrapper.readContract.getBaseURICount();
const chainId = await this.contractWrapper.getChainID();
const hashedPassword = ethers.utils.solidityKeccak256(
["string", "uint256", "uint256", "address"],
[password, chainId, baseUriId, this.contractWrapper.readContract.address],
);
const encryptedBaseUri =
await this.contractWrapper.readContract.encryptDecrypt(
ethers.utils.toUtf8Bytes(baseUri),
hashedPassword,
);
let data: string;
const provenanceHash = ethers.utils.solidityKeccak256(
["bytes", "bytes", "uint256"],
[ethers.utils.toUtf8Bytes(baseUri), hashedPassword, chainId],
);
data = ethers.utils.defaultAbiCoder.encode(
["bytes", "bytes32"],
[encryptedBaseUri, provenanceHash],
);
const baseUri = getBaseUriFromBatch(uris);
const baseUriId =
await this.contractWrapper.readContract.getBaseURICount();
const chainId = await this.contractWrapper.getChainID();
const hashedPassword = ethers.utils.solidityKeccak256(
["string", "uint256", "uint256", "address"],
[
password,
chainId,
baseUriId,
this.contractWrapper.readContract.address,
],
);
const receipt = await this.contractWrapper.sendTransaction("lazyMint", [
uris.length,
placeholderUri.endsWith("/") ? placeholderUri : `${placeholderUri}/`,
tier,
data,
]);
const encryptedBaseUri =
await this.contractWrapper.readContract.encryptDecrypt(
ethers.utils.toUtf8Bytes(baseUri),
hashedPassword,
);
const event = this.contractWrapper.parseLogs<TokensLazyMintedEvent>(
"TokensLazyMinted",
receipt?.logs,
);
const startingIndex = event[0].args[1];
const endingIndex = event[0].args[2];
const results: TransactionResultWithId<NFTMetadata>[] = [];
for (let id = startingIndex; id.lte(endingIndex); id = id.add(1)) {
results.push({
id,
receipt,
data: () => this.erc721.getTokenMetadata(id),
let data: string;
const provenanceHash = ethers.utils.solidityKeccak256(
["bytes", "bytes", "uint256"],
[ethers.utils.toUtf8Bytes(baseUri), hashedPassword, chainId],
);
data = ethers.utils.defaultAbiCoder.encode(
["bytes", "bytes32"],
[encryptedBaseUri, provenanceHash],
);
return Transaction.fromContractWrapper({
contractWrapper: this.contractWrapper,
method: "lazyMint",
args: [
uris.length,
placeholderUri.endsWith("/") ? placeholderUri : `${placeholderUri}/`,
tier,
data,
],
parse: (receipt) => {
const event = this.contractWrapper.parseLogs<TokensLazyMintedEvent>(
"TokensLazyMinted",
receipt?.logs,
);
const startingIndex = event[0].args[1];
const endingIndex = event[0].args[2];
const results: TransactionResultWithId<NFTMetadata>[] = [];
for (let id = startingIndex; id.lte(endingIndex); id = id.add(1)) {
results.push({
id,
receipt,
data: () => this.erc721.getTokenMetadata(id),
});
}
return results;
},
});
}
},
);
return results;
}
public async reveal(
batchId: BigNumberish,
password: string,
): Promise<TransactionResult> {
if (!password) {
throw new Error("Password is required");
}
const chainId = await this.contractWrapper.getChainID();
const key = ethers.utils.solidityKeccak256(
["string", "uint256", "uint256", "address"],
[password, chainId, batchId, this.contractWrapper.readContract.address],
);
// performing the reveal locally to make sure it'd succeed before sending the transaction
try {
const decryptedUri = await this.contractWrapper
.callStatic()
.reveal(batchId, key);
// basic sanity check for making sure decryptedUri is valid
// this is optional because invalid decryption key would result in non-utf8 bytes and
// ethers would throw when trying to decode it
if (!decryptedUri.includes("://") || !decryptedUri.endsWith("/")) {
reveal = buildTransactionFunction(
async (batchId: BigNumberish, password: string) => {
if (!password) {
throw new Error("Password is required");
}
const chainId = await this.contractWrapper.getChainID();
const key = ethers.utils.solidityKeccak256(
["string", "uint256", "uint256", "address"],
[password, chainId, batchId, this.contractWrapper.readContract.address],
);
// performing the reveal locally to make sure it'd succeed before sending the transaction
try {
const decryptedUri = await this.contractWrapper
.callStatic()
.reveal(batchId, key);
// basic sanity check for making sure decryptedUri is valid
// this is optional because invalid decryption key would result in non-utf8 bytes and
// ethers would throw when trying to decode it
if (!decryptedUri.includes("://") || !decryptedUri.endsWith("/")) {
throw new Error("invalid password");
}
} catch (e) {
throw new Error("invalid password");
}
} catch (e) {
throw new Error("invalid password");
}
return {
receipt: await this.contractWrapper.sendTransaction("reveal", [
batchId,
key,
]),
};
}
return Transaction.fromContractWrapper({
contractWrapper: this.contractWrapper,
method: "reveal",
args: [batchId, key],
});
},
);
public async generate(
payloadToSign: TieredDropPayloadInput,
+59 -6
View File
@@ -25,7 +25,11 @@ import {
} from "../../constants/erc721-features";
import { Address, AddressOrEns } from "../../schema";
import { ClaimOptions, UploadProgressEvent } from "../../types";
import { BaseDropERC721, BaseERC721 } from "../../types/eips";
import {
BaseClaimConditionERC721,
BaseDropERC721,
BaseERC721,
} from "../../types/eips";
import { DetectableFeature } from "../interfaces/DetectableFeature";
import { UpdateableNetwork } from "../interfaces/contract";
import { NetworkInput, TransactionResultWithId } from "../types";
@@ -40,6 +44,7 @@ import { Transaction } from "./transactions";
import type {
DropERC721,
IBurnableERC721,
IClaimableERC721,
IERC721Supply,
IMintableERC721,
ISignatureMintERC721,
@@ -50,6 +55,8 @@ import type {
} from "@thirdweb-dev/contracts-js";
import { ThirdwebStorage } from "@thirdweb-dev/storage";
import { BigNumber, BigNumberish, constants } from "ethers";
import { Erc721Claimable } from "./erc-721-claimable";
import { Erc721ClaimableWithConditions } from "./erc-721-claimable-with-conditions";
/**
* Standard ERC721 NFT functions
@@ -77,6 +84,8 @@ export class Erc721<
private lazyMintable: Erc721LazyMintable | undefined;
private tieredDropable: Erc721TieredDrop | undefined;
private signatureMintable: Erc721WithQuantitySignatureMintable | undefined;
private claimWithConditions: Erc721ClaimableWithConditions | undefined;
private claimCustom: Erc721Claimable | undefined;
protected contractWrapper: ContractWrapper<T>;
protected storage: ThirdwebStorage;
@@ -98,6 +107,8 @@ export class Erc721<
this.lazyMintable = this.detectErc721LazyMintable();
this.tieredDropable = this.detectErc721TieredDrop();
this.signatureMintable = this.detectErc721SignatureMintable();
this.claimWithConditions = this.detectErc721ClaimableWithConditions();
this.claimCustom = this.detectErc721Claimable();
this._chainId = chainId;
}
@@ -654,8 +665,8 @@ export class Erc721<
quantity: BigNumberish,
options?: ClaimOptions,
): Promise<Transaction<TransactionResultWithId<NFT>[]>> => {
const claimWithConditions = this.lazyMintable?.claimWithConditions;
const claim = this.lazyMintable?.claim;
const claimWithConditions = this.claimWithConditions;
const claim = this.claimCustom;
if (claimWithConditions) {
return claimWithConditions.to.prepare(
destinationAddress,
@@ -685,8 +696,8 @@ export class Erc721<
quantity: BigNumberish,
options?: ClaimOptions,
): Promise<Transaction> {
const claimWithConditions = this.lazyMintable?.claimWithConditions;
const claim = this.lazyMintable?.claim;
const claimWithConditions = this.claimWithConditions;
const claim = this.claimCustom;
if (claimWithConditions) {
return claimWithConditions.conditions.getClaimTransaction(
destinationAddress,
@@ -770,7 +781,7 @@ export class Erc721<
*/
get claimConditions() {
return assertEnabled(
this.lazyMintable?.claimWithConditions,
this.claimWithConditions,
FEATURE_NFT_CLAIM_CONDITIONS_V2,
).conditions;
}
@@ -960,4 +971,46 @@ export class Erc721<
}
return undefined;
}
private detectErc721ClaimableWithConditions():
| Erc721ClaimableWithConditions
| undefined {
if (
detectContractFeature<BaseClaimConditionERC721>(
this.contractWrapper,
"ERC721ClaimConditionsV1",
) ||
detectContractFeature<BaseClaimConditionERC721>(
this.contractWrapper,
"ERC721ClaimConditionsV2",
) ||
detectContractFeature<BaseClaimConditionERC721>(
this.contractWrapper,
"ERC721ClaimPhasesV1",
) ||
detectContractFeature<BaseClaimConditionERC721>(
this.contractWrapper,
"ERC721ClaimPhasesV2",
)
) {
return new Erc721ClaimableWithConditions(
this,
this.contractWrapper,
this.storage,
);
}
return undefined;
}
private detectErc721Claimable(): Erc721Claimable | undefined {
if (
detectContractFeature<IClaimableERC721>(
this.contractWrapper,
"ERC721ClaimCustom",
)
) {
return new Erc721Claimable(this, this.contractWrapper);
}
return undefined;
}
}
+8 -3
View File
@@ -42,9 +42,14 @@ export const AddressOrEnsSchema = z.union([AddressSchema, EnsSchema], {
invalid_type_error: "Provided value was not a valid address or ENS name",
});
export const RawDateSchema = z.date().transform((i) => {
return BigNumber.from(Math.floor(i.getTime() / 1000));
});
export const RawDateSchema = z.union([
z.date().transform((i) => {
return BigNumber.from(Math.floor(i.getTime() / 1000));
}),
z.number().transform((i) => {
return BigNumber.from(i);
}),
]);
/**
* Default to now
+1 -1
View File
@@ -247,7 +247,7 @@ describe("Custom Contracts", async () => {
try {
c.roles.get("admin");
} catch (e) {
expectError(e, "contract does not implement the 'Permissions' Extension");
expectError(e, "contract does not implement the 'permissions' Extension");
}
});
+25
View File
@@ -1,5 +1,30 @@
# @thirdweb-dev/unity-js-bridge
## 0.2.24
### Patch Changes
- Updated dependencies [[`b3d57949`](https://github.com/thirdweb-dev/js/commit/b3d57949bd047831fda7e600b4872200340903b5), [`602d8cbc`](https://github.com/thirdweb-dev/js/commit/602d8cbcfaa7c1e117c01f842f89508f7333fcfe)]:
- @thirdweb-dev/sdk@3.10.9
## 0.2.23
### Patch Changes
- Updated dependencies [[`1547d76c`](https://github.com/thirdweb-dev/js/commit/1547d76cce52265076c347599014f578c1de6152), [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d), [`1b8f812f`](https://github.com/thirdweb-dev/js/commit/1b8f812fb8c910d91fb7535d6446a0b6fc6b2310)]:
- @thirdweb-dev/sdk@3.10.8
- @thirdweb-dev/wallets@0.2.14
- @thirdweb-dev/auth@3.0.13
## 0.2.22
### Patch Changes
- Updated dependencies [[`c5c2d947`](https://github.com/thirdweb-dev/js/commit/c5c2d9478acd4d4a4e6ce814716bdf1b6e51eafc), [`2dd192a5`](https://github.com/thirdweb-dev/js/commit/2dd192a5676f1b6d3c310ec796bf331252098d48)]:
- @thirdweb-dev/wallets@0.2.13
- @thirdweb-dev/auth@3.0.12
- @thirdweb-dev/sdk@3.10.7
## 0.2.21
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/unity-js-bridge",
"version": "0.2.21",
"version": "0.2.24",
"main": "dist/thirdweb-unity-bridge.js",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/unity-js-bridge",
"license": "Apache-2.0",
+23
View File
@@ -1,5 +1,28 @@
# @thirdweb-dev/wallets
## 0.2.14
### Patch Changes
- [#870](https://github.com/thirdweb-dev/js/pull/870) [`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d) Thanks [@jnsdls](https://github.com/jnsdls)! - fix crash during SSR when "window" is undefined
- Updated dependencies [[`235eb046`](https://github.com/thirdweb-dev/js/commit/235eb0460ae0638f63acf82957bcfea41b9e955d)]:
- @thirdweb-dev/chains@0.1.11
## 0.2.13
### Patch Changes
- [#851](https://github.com/thirdweb-dev/js/pull/851) [`c5c2d947`](https://github.com/thirdweb-dev/js/commit/c5c2d9478acd4d4a4e6ce814716bdf1b6e51eafc) Thanks [@MananTank](https://github.com/MananTank)! - Fix wallet autoconnect issues
### Fixes
- infinite loading spinner on connect wallet button when wallet is locked or connection to app is closed
- network switch popup on page load when wallet is connected to different network than it was previously connected
- removed autoconnect timeout - don't need it anymore
- [#855](https://github.com/thirdweb-dev/js/pull/855) [`2dd192a5`](https://github.com/thirdweb-dev/js/commit/2dd192a5676f1b6d3c310ec796bf331252098d48) Thanks [@MananTank](https://github.com/MananTank)! - Add auth in Connect Wallet button
## 0.2.12
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/wallets",
"version": "0.2.12",
"version": "0.2.14",
"main": "dist/thirdweb-dev-wallets.cjs.js",
"module": "dist/thirdweb-dev-wallets.esm.js",
"types": "dist/thirdweb-dev-wallets.cjs.d.ts",
@@ -79,8 +79,8 @@ export class InjectedConnector extends Connector<
shimDisconnect: true,
shimChainChangedDisconnect: true,
getProvider: () => {
if (assertWindowEthereum(window)) {
return window.ethereum;
if (assertWindowEthereum(globalThis.window)) {
return globalThis.window.ethereum;
}
},
};
+13 -4
View File
@@ -49,7 +49,11 @@ export abstract class AbstractBrowserWallet<
async autoConnect(
connectOptions?: ConnectParams<TConnectParams>,
): Promise<string | undefined> {
return this.#connect(true, connectOptions);
// remove chainId when autoconnecting to prevent switch-network popup on page load
const options = connectOptions
? { ...connectOptions, chainId: undefined }
: undefined;
return this.#connect(true, options);
}
/**
@@ -75,6 +79,7 @@ export abstract class AbstractBrowserWallet<
const isConnected = await connector.isConnected();
// if already connected, return the address and setup listeners
if (isConnected) {
const address = await connector.getAddress();
connector.setupListeners();
@@ -89,11 +94,15 @@ export abstract class AbstractBrowserWallet<
chainId: await this.getChainId(),
});
return address;
} else if (!isAutoConnect) {
const address = await connector.connect(connectOptions);
return address;
}
if (isAutoConnect) {
throw new Error("Failed to auto connect to the wallet.");
}
const address = await connector.connect(connectOptions);
return address;
}
async #subscribeToEvents(connector: TWConnector) {
+8138 -5624
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -12,7 +12,7 @@ then
if command -v corepack &> /dev/null
then
corepack enable
corepack prepare pnpm@7.29.3 --activate
corepack prepare pnpm@8.1.0 --activate
else
# if not, install it using npm
npm install -g pnpm