Compare commits

...
Author SHA1 Message Date
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
f3fb440fb5 Version Packages (#1793)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-10-22 14:33:11 -07:00
Manan TankandGitHub 2307f11ab3 [wallets, react] Add OKX wallet (#1826) 2023-10-22 18:47:23 +00:00
Kien NgoandGitHub d8d48a9516 [SDK] Perf improvement for erc-1155-signature-mintable (#1824) 2023-10-21 22:29:55 +00:00
Winston YeoandGitHub 5ffbcfc302 [wallets, react] expose onAuthSuccess callback in paperWallet (#1815) 2023-10-21 01:03:06 +00:00
Joaquim VergesandGitHub d27a3dee83 [SmartWallet] implement multidimensional nonces for smart wallets (#1821) 2023-10-20 23:28:08 +00:00
iketwandGitHub 7080ff29fc [RN] Allow custom fontFamily (#1820) 2023-10-20 20:39:39 +00:00
iketwandGitHub 638afd8e08 [RN] i18n strings (#1819) 2023-10-20 19:04:13 +00:00
iketwandGitHub 947e3345ef [RN] i18n more strings and fix fontFamily (#1818) 2023-10-20 18:04:29 +00:00
iketwandGitHub ea51a50bfc [RN] Update weights (#1817) 2023-10-20 16:10:07 +00:00
iketwandGitHub c6f59e1b01 [RN] Makes locale optional (#1816) 2023-10-20 15:46:57 +00:00
Kien NgoandGitHub 6d1eabe9f9 [SDK] Some more small improvements (#1813) 2023-10-20 04:46:50 +00:00
Adam MajmudarandGitHub c238fde877 [Auth] Update to call uuidv4 to generate jti (#1812) 2023-10-20 02:14:42 +00:00
Adam MajmudarandGitHub 548601981f [Auth] Expose buildJWT (#1811) 2023-10-20 01:00:05 +00:00
iketwandGitHub 05481aa8c0 [RN]i18n Extract more strings (#1810) 2023-10-20 00:19:25 +00:00
iketwandGitHub 1cc26e43e5 [RN] Enable localization for the RN SDK (#1799) 2023-10-19 23:54:19 +00:00
Adam MajmudarandGitHub 99d7ec06ec [Auth] Add fastify extension, onToken callback, & secure option (#1801) 2023-10-19 23:34:32 +00:00
ff996646b2 [React, RN, Wallets, SDK, Storage] typedoc generation (#1787)
Co-authored-by: ikethirdweb <[email protected]>
2023-10-19 20:11:21 +00:00
iketwandGitHub 01260009be [RN] Pass custom fontfamily to textinput placeholders (#1807) 2023-10-19 19:16:08 +00:00
iketwandGitHub 7dea0975ec [RN] Update README (#1804) 2023-10-19 15:11:22 +00:00
iketwandGitHub a63f5dc7cb [RN] Improve UI and theming (#1803) 2023-10-19 15:07:15 +00:00
Joaquim VergesandGitHub fd7a9f0998 [SmartWallet] expose new send/execute smart wallet functions (#1800) 2023-10-19 05:37:01 +00:00
Manan TankandGitHub 246b0d4aac [react] Fix wrong Icon size of few icons in Firefox in ConnectWallet (#1797) 2023-10-18 23:31:50 +00:00
Kien NgoandGitHub 42ba15f2c0 Improve performance for /prebuilt-implementations (#1795) 2023-10-18 22:30:30 +00:00
Adam MajmudarandGitHub aa9f48d136 [Wallets] Add AsyncWallet (#1790) 2023-10-18 18:48:31 +00:00
Adam MajmudarandGitHub 64138642e8 Manually write GCP KMS signer with full configuration (#1789) 2023-10-18 18:38:48 +00:00
Joaquim VergesandGitHub 223008b1f7 [SDK] fix marketplace tests (#1791) 2023-10-18 06:01:10 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
cbfd445ae7 Version Packages (#1784)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-10-16 20:38:41 -07:00
Jonas DanielsandGitHub 137f46a547 chore(chains): fix up chain sync script (#1783) 2023-10-17 02:28:33 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
1b8accde30 Version Packages (#1782)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-10-16 15:51:35 -07:00
Joaquim VergesandGitHub 07544252b4 [SDK] expose utility functions for abi / sources (#1781) 2023-10-16 22:43:13 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
8708519cad Version Packages (#1772)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-10-16 12:57:26 -07:00
Joaquim VergesandGitHub 6c30b7efc7 [ContractsJS] update contracts-js package (#1771) 2023-10-16 19:50:17 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
8b5e344f72 Version Packages (#1768)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-10-16 09:26:13 -07:00
Manan TankandGitHub 010955ff5c [react] - Fix OTP input not working well with Japanese keyboard (#1769) 2023-10-16 15:41:54 +00:00
Joaquim VergesandGitHub 956b5645e4 [SDK] Enable adding smart wallet admins with signature (#1756) 2023-10-15 23:46:45 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
068db44603 Version Packages (#1761)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-10-14 17:18:54 -07:00
Manan TankandGitHub dd7d0fca2d [react] Fix missing "Continue as Guest" button in ConnectWallet in Social+Guest setup (#1766) 2023-10-14 23:29:07 +00:00
Kien NgoandGitHub 526176c471 [SDK] Perf improv to marketplace methods (#1764) 2023-10-14 21:18:11 +00:00
Kien NgoandGitHub 09120c923c [SDK] Perf improv for getDeploymentInfo (#1765) 2023-10-14 18:12:19 +00:00
Kien NgoandGitHub d1f8e95162 [SDK] Perf improve to fetchPublishedContractFromPolygon() (#1763) 2023-10-14 14:29:09 +00:00
Kien NgoandGitHub 6573556d0e [SDK] Perf improv for drop-claim-conditions (#1762) 2023-10-13 22:53:35 +00:00
iketwandGitHub fc62b91ee5 [RN] Adds Signing with Google to EmbeddedWallet (#1724) 2023-10-13 18:51:47 +00:00
Kien NgoandGitHub 08e9cd206b [React/React Native] Add pagination to useOwnedNFTs (#1758) 2023-10-13 17:23:43 +00:00
fb0f12ae28 refactor(react): OTP Input Readability Enhancements (#1692)
Co-authored-by: Manan Tank <[email protected]>
2023-10-13 06:43:20 -07:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
c710fc1c62 Version Packages (#1745)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-10-12 21:12:59 -07:00
iketwandGitHub f41ee6fb1c [RN] Correctly use custom themes (#1760) 2023-10-13 03:53:48 +00:00
iketwandGitHub 513c332ed0 [RN] Show selectUI component when passing one supportedWallet (#1759) 2023-10-13 03:02:47 +00:00
Kien NgoandGitHub 693f349db2 [SDK] Add pagination to getOwned for ERC721 & 1155 (#1695) 2023-10-12 23:34:39 +00:00
YashandGitHub 63ad0050f0 Update deployment setup (#1757) 2023-10-12 17:34:31 +00:00
iketwandGitHub dcdb0dcb83 [Wallets] Typo fixes for SW api (#1754) 2023-10-11 22:40:05 +00:00
iketwandGitHub b3b9edca29 [RN] Minor bug fix and UI improvements to connecting an app to a smar… (#1753) 2023-10-11 21:51:19 +00:00
Winston YeoandGitHub 1fbbc2d27d [SDK] update ApiKeyMetadata (#1752) 2023-10-11 20:38:44 +00:00
Joaquim VergesandGitHub 4b98e487d4 [Wallets] Add wallet analytics (#1730) 2023-10-11 20:19:22 +00:00
Phillip HoandGitHub 95380eaed4 chore: Add walletType to usage tracker payload (#1751) 2023-10-11 17:55:51 +00:00
Joaquim VergesandGitHub 1f3c64d361 [SDK] handle upgradeable proxies and optimize proxy resolution (#1747) 2023-10-11 16:39:06 +00:00
Manan TankandGitHub bb1666b92b [react] ConnectWallet UI fixes + improvements (#1750) 2023-10-11 13:20:40 +00:00
farhanW3andGitHub 0f12d1f903 RPC Override Fix (#1746) 2023-10-11 01:01:03 +00:00
Joaquim VergesandGitHub 74941603a9 [Wallets] Fix executeBatch type mismatch (#1744) 2023-10-10 21:24:08 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
4fda12aa2d Version Packages (#1743)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-10-10 10:26:32 -07:00
Manan TankandGitHub e684d05e22 [wallets, react] Wallet chain RPC fixes + Update Google Sign in popup UI (#1742) 2023-10-10 15:10:26 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Manan Tank
335744ff6d Bump eslint-plugin-better-tree-shaking from 0.0.3 to 0.0.4 (#1738)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Manan Tank <[email protected]>
2023-10-10 09:14:30 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
7bc40f6223 Version Packages (#1734)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-10-09 20:11:07 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
8291742ad9 Bump @walletconnect/utils from 2.9.1 to 2.10.2 (#1737)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-10 03:00:35 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
fb964ecb85 Bump uuid and @types/uuid (#1736)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-10 01:56:30 +00:00
Jonas DanielsandGitHub 7dba9f782e test: skip deploy marketplacev3 if secret key not set (#1740) 2023-10-10 01:38:45 +00:00
Manan TankandGitHub 79f91ee2d9 [react, react-core] ConnectWallet v3 Improvements (#1645) 2023-10-09 20:22:42 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2df8de0e2a Bump zod from 3.21.4 to 3.22.3 (#1710)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-09 12:53:57 -07:00
Jonas DanielsandGitHub ce4608bff4 Preparing Major Version Bump (#1630) 2023-10-09 19:09:51 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
125c836d88 Version Packages (#1726)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-10-09 11:41:50 -07:00
Kien NgoandGitHub ec36b13a30 [SDK] Improve add/removeContract method for registry.ts (#1731) 2023-10-08 17:38:11 +00:00
Phillip HoandGitHub 52b1a0fcac chore: Make accountId optional in usage event type (#1729) 2023-10-08 05:26:26 +00:00
Kien NgoandGitHub a6c36724eb [SDK] Update transfer function for user wallet (#1728) 2023-10-07 13:10:16 +00:00
Kien NgoandGitHub 6abb845971 [SDK] Concurrent requests for NFT-related code (#1727) 2023-10-07 12:21:54 +00:00
FirekeeperandGitHub dc38a243c2 [Unity] Fix Google popup blocker (#1725) 2023-10-06 22:06:47 +00:00
515 changed files with 13554 additions and 15581 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ runs:
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 16
node-version: 20
registry-url: "https://registry.npmjs.org"
cache: "pnpm"
-1
View File
@@ -29,7 +29,6 @@ You can see a quick outline of each of the projects within this repo below, each
| [/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> |
| [/solana](./packages/solana) | Solana SDK for Browser, Node and React Native | <a href="https://www.npmjs.com/package/@thirdweb-dev/solana"><img src="https://img.shields.io/npm/v/@thirdweb-dev/solana?color=red&label=npm&logo=npm" alt="npm version"/></a> |
## How to contribute
+4 -4
View File
@@ -56,7 +56,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: 16
node-version: 20
check-latest: true
- uses: pnpm/action-setup@v2
@@ -81,7 +81,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: 16
node-version: 20
check-latest: true
- uses: pnpm/action-setup@v2
@@ -100,7 +100,7 @@ jobs:
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
with:
files: ./packages/sdk/coverage/evm/lcov.info,./packages/sdk/coverage/solana/lcov.info,
files: ./packages/sdk/coverage/evm/lcov.info
e2e:
timeout-minutes: 15
@@ -111,7 +111,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: 16
node-version: 20
check-latest: true
- uses: pnpm/action-setup@v2
+42
View File
@@ -0,0 +1,42 @@
name: Release Next
on:
push:
paths:
- ".changeset/**"
- "packages/**"
branches:
- next
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
jobs:
release:
name: Release
timeout-minutes: 30
runs-on: ubuntu-latest-16
steps:
- name: Checkout branch
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install
uses: ./.github/composite-actions/install
- name: Build
run: pnpm build
- name: Create @next release
run: |
git checkout next
pnpm version-packages:next
pnpm release:next
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+3 -1
View File
@@ -20,4 +20,6 @@ playwright-report/
.env/
# Artifacts
packages/cli/artifacts/
packages/cli/artifacts/
typedoc
+1 -1
View File
@@ -1 +1 @@
16
20
+5 -5
View File
@@ -7,11 +7,11 @@
"license": "MIT",
"private": true,
"engines": {
"node": ">=16.7.0"
"node": ">=18.0.0"
},
"scripts": {
"preinstall": "npx only-allow pnpm",
"test": "turbo run test test:evm test:solana --filter=./packages/*",
"test": "turbo run test --filter=./packages/*",
"e2e": "turbo run e2e",
"build": "turbo run build --filter=./packages/*",
"build:release": "turbo run build --force --filter=./packages/*",
@@ -26,12 +26,14 @@
"release": "node ./scripts/pre-release.mjs && changeset publish",
"version-packages:nightly": "node scripts/pre-nightly.mjs && changeset version --snapshot nightly",
"release:nightly": "node ./scripts/pre-release.mjs && changeset publish --tag nightly",
"version-packages:next": "node scripts/pre-nightly.mjs && changeset version --snapshot next",
"release:next": "node ./scripts/pre-release.mjs && changeset publish --tag next",
"push": "turbo run push --filter=./packages/*",
"hotlink-init": "node ./scripts/hotlink/hotlink-init.mjs",
"hotlink-revert": "node ./scripts/hotlink/hotlink-revert.mjs",
"explain:major": "node ./scripts/changeset-explain-major.mjs"
},
"packageManager": "pnpm@8.6.12",
"packageManager": "pnpm@8.9.0",
"dependencies": {
"@changesets/changelog-github": "^0.4.8",
"@changesets/cli": "^2.26.2",
@@ -54,10 +56,8 @@
},
"pnpm": {
"overrides": {
"cross-fetch@>=3.0.0 <3.1.5": ">=3.1.5",
"got@<11.8.5": ">=11.8.5",
"glob-parent@<5.1.2": ">=5.1.2",
"node-fetch@<2.6.7": ">=2.6.7",
"nth-check@<2.0.1": ">=2.0.1",
"socket.io-parser@>=4.0.4 <4.2.3": ">=4.2.3",
"fast-xml-parser@<4.2.4": ">=4.2.4",
+90 -1
View File
@@ -1,5 +1,94 @@
# @thirdweb-dev/auth
## 4.1.0
### Minor Changes
- [#1801](https://github.com/thirdweb-dev/js/pull/1801) [`99d7ec06`](https://github.com/thirdweb-dev/js/commit/99d7ec06ec4f31308627edc87d3122c21a884b5a) Thanks [@adam-maj](https://github.com/adam-maj)! - Add support for fastify
### Patch Changes
- [#1812](https://github.com/thirdweb-dev/js/pull/1812) [`c238fde8`](https://github.com/thirdweb-dev/js/commit/c238fde8777fd14b39837117e2d3fda1dd301029) Thanks [@adam-maj](https://github.com/adam-maj)! - Update to call uuidv4 to generate jti
- [#1811](https://github.com/thirdweb-dev/js/pull/1811) [`54860198`](https://github.com/thirdweb-dev/js/commit/548601981f6dd8706d7a9bd4ca48e4abc7723a1d) Thanks [@adam-maj](https://github.com/adam-maj)! - Expose buildJWT function
- [#1812](https://github.com/thirdweb-dev/js/pull/1812) [`c238fde8`](https://github.com/thirdweb-dev/js/commit/c238fde8777fd14b39837117e2d3fda1dd301029) Thanks [@adam-maj](https://github.com/adam-maj)! - Update to use uuidv4 for default jti
- Updated dependencies [[`5ffbcfc3`](https://github.com/thirdweb-dev/js/commit/5ffbcfc302f74167768b196d93a328f979344036), [`d27a3dee`](https://github.com/thirdweb-dev/js/commit/d27a3dee8398d5707d2d1343c428abf8e03f67e3), [`ff996646`](https://github.com/thirdweb-dev/js/commit/ff996646b228d4d095eea04b05004dd26fc7e522), [`aa9f48d1`](https://github.com/thirdweb-dev/js/commit/aa9f48d1361194fc81146da530c95a3409bd0799), [`fd7a9f09`](https://github.com/thirdweb-dev/js/commit/fd7a9f09989e39b02a93d9dfd01cc7378e6ead53), [`2307f11a`](https://github.com/thirdweb-dev/js/commit/2307f11ab311aa4a775edd23e777d10f8015ce86), [`64138642`](https://github.com/thirdweb-dev/js/commit/64138642e84d8b56b254762eca613d443cca292b)]:
- @thirdweb-dev/wallets@2.0.8
## 4.0.7
### Patch Changes
- Updated dependencies []:
- @thirdweb-dev/wallets@2.0.7
## 4.0.6
### Patch Changes
- Updated dependencies []:
- @thirdweb-dev/wallets@2.0.6
## 4.0.5
### Patch Changes
- Updated dependencies []:
- @thirdweb-dev/wallets@2.0.5
## 4.0.4
### Patch Changes
- Updated dependencies []:
- @thirdweb-dev/wallets@2.0.4
## 4.0.3
### Patch Changes
- Updated dependencies []:
- @thirdweb-dev/wallets@2.0.3
## 4.0.2
### Patch Changes
- Updated dependencies [[`74941603`](https://github.com/thirdweb-dev/js/commit/74941603a96456da46a47147f67c98235ac55022), [`4b98e487`](https://github.com/thirdweb-dev/js/commit/4b98e487d4b47225d7095e5444dc5e7608db48a3), [`dcdb0dcb`](https://github.com/thirdweb-dev/js/commit/dcdb0dcb838168a22c8335738852316dfb6e6fc9), [`b3b9edca`](https://github.com/thirdweb-dev/js/commit/b3b9edca29e7d4053b14270a61caa89c34fecf9e)]:
- @thirdweb-dev/wallets@2.0.2
## 4.0.1
### Patch Changes
- Updated dependencies [[`e684d05e`](https://github.com/thirdweb-dev/js/commit/e684d05e222458f02c8158eb9385d68c879dd946)]:
- @thirdweb-dev/wallets@2.0.1
## 4.0.0
### Major Changes
- [#1630](https://github.com/thirdweb-dev/js/pull/1630) [`ce4608bf`](https://github.com/thirdweb-dev/js/commit/ce4608bff4783caf164ad6e21b42a827b89badf8) Thanks [@jnsdls](https://github.com/jnsdls)! - **Dropped Support for Solana**:
- We've decided to drop support for Solana across our SDKs.
- Starting with this version of our SDKs all previous solana related functionality will be removed.
- Previous versions of our SDKs will continue to work with Solana. However, we will not be providing any further updates or bug fixes for Solana.
- You can read a detailed explanation of our decision [on our blog](https://blog.thirdweb.com/discontinuing-solana-support/).
### Patch Changes
- Updated dependencies [[`ce4608bf`](https://github.com/thirdweb-dev/js/commit/ce4608bff4783caf164ad6e21b42a827b89badf8), [`ce4608bf`](https://github.com/thirdweb-dev/js/commit/ce4608bff4783caf164ad6e21b42a827b89badf8)]:
- @thirdweb-dev/wallets@2.0.0
## 3.2.48
### Patch Changes
- Updated dependencies []:
- @thirdweb-dev/wallets@1.3.5
## 3.2.47
### Patch Changes
@@ -596,7 +685,7 @@
## How to upgrade
The `ThirdwebAuth` constructor now takes the `domain` in the constructor, and takes a more generic `wallet` interface as input. The `wallet` can be imported from the `@thirdweb-dev/wallets` package, or for more simpler use cases, from the `@thirdweb-dev/auth/evm` and `@thirdweb-dev/auth/solana` entrypoints.
The `ThirdwebAuth` constructor now takes the `domain` in the constructor, and takes a more generic `wallet` interface as input. The `wallet` can be imported from the `@thirdweb-dev/wallets` package, or for more simpler use cases, from the `@thirdweb-dev/auth/evm` entrypoint.
```js
import { PrivateKeyWallet } from "@thirdweb-dev/auth/evm";
+7
View File
@@ -0,0 +1,7 @@
{
"main": "dist/thirdweb-dev-auth-fastify.cjs.js",
"module": "dist/thirdweb-dev-auth-fastify.esm.js",
"browser": {
"./dist/thirdweb-dev-auth-fastify.esm.js": "./dist/thirdweb-dev-auth-fastify.browser.esm.js"
}
}
+20 -18
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/auth",
"version": "3.2.47",
"version": "4.1.0",
"main": "dist/thirdweb-dev-auth.cjs.js",
"module": "dist/thirdweb-dev-auth.esm.js",
"browser": {
@@ -28,13 +28,6 @@
},
"default": "./next/dist/thirdweb-dev-auth-next.cjs.js"
},
"./solana": {
"module": {
"browser": "./solana/dist/thirdweb-dev-auth-solana.browser.esm.js",
"default": "./solana/dist/thirdweb-dev-auth-solana.esm.js"
},
"default": "./solana/dist/thirdweb-dev-auth-solana.cjs.js"
},
"./express": {
"module": {
"browser": "./express/dist/thirdweb-dev-auth-express.browser.esm.js",
@@ -42,6 +35,13 @@
},
"default": "./express/dist/thirdweb-dev-auth-express.cjs.js"
},
"./fastify": {
"module": {
"browser": "./fastify/dist/thirdweb-dev-auth-fastify.browser.esm.js",
"default": "./fastify/dist/thirdweb-dev-auth-fastify.esm.js"
},
"default": "./fastify/dist/thirdweb-dev-auth-fastify.cjs.js"
},
"./next-auth": {
"module": {
"browser": "./next-auth/dist/thirdweb-dev-auth-next-auth.browser.esm.js",
@@ -70,8 +70,8 @@
"express/index.ts",
"next/index.ts",
"next-auth/index.ts",
"evm/index.ts",
"solana/index.ts"
"fastify/index.ts",
"evm/index.ts"
],
"exports": {
"envConditions": [
@@ -87,7 +87,6 @@
"@microsoft/api-extractor": "^7.36.3",
"@microsoft/tsdoc": "^0.14.1",
"@preconstruct/cli": "2.7.0",
"@solana/web3.js": "^1.62.0",
"@swc-node/register": "^1.6.6",
"@swc/core": "^1.3.71",
"@thirdweb-dev/tsconfig": "workspace:*",
@@ -96,7 +95,7 @@
"@types/cookie-parser": "^1.4.3",
"@types/express": "^4.17.13",
"@types/mocha": "^10.0.0",
"@types/uuid": "^9.0.2",
"@types/uuid": "^9.0.5",
"@typescript-eslint/eslint-plugin": "^6.2.0",
"@typescript-eslint/parser": "^6.2.0",
"chai": "^4.3.6",
@@ -110,6 +109,7 @@
"eslint-plugin-tsdoc": "^0.2.16",
"ethers": "^5.7.2",
"express": "^4.18.1",
"fastify": "^4.24.2",
"mocha": "^10.2.0",
"next": "^12.3.4",
"next-auth": "^4.22.3",
@@ -117,17 +117,14 @@
"typescript": "^5.1.6"
},
"peerDependencies": {
"@solana/web3.js": "^1.73.0",
"cookie-parser": "^1.4.6",
"ethers": "^5",
"express": "^4",
"fastify": "^4.24.2",
"next": "^12 || ^13",
"next-auth": "^4"
},
"peerDependenciesMeta": {
"@solana/web3.js": {
"optional": true
},
"cookie-parser": {
"optional": true
},
@@ -137,6 +134,9 @@
"express": {
"optional": true
},
"fastify": {
"optional": true
},
"next": {
"optional": true
},
@@ -145,9 +145,11 @@
}
},
"dependencies": {
"@fastify/cookie": "^9.1.0",
"@thirdweb-dev/wallets": "workspace:*",
"cookie": "^0.5.0",
"uuid": "^9.0.0",
"zod": "^3.20.2"
"fastify-type-provider-zod": "^1.1.9",
"uuid": "^9.0.1",
"zod": "^3.22.3"
}
}
-7
View File
@@ -1,7 +0,0 @@
{
"main": "dist/thirdweb-dev-auth-solana.cjs.js",
"module": "dist/thirdweb-dev-auth-solana.esm.js",
"browser": {
"./dist/thirdweb-dev-auth-solana.esm.js": "./dist/thirdweb-dev-auth-solana.browser.esm.js"
}
}
+4 -1
View File
@@ -38,7 +38,10 @@ function base64decode(data: string): string {
/**
* Build JWT token based on the authentication payload
*/
async function buildJWT({ wallet, payload }: BuildJwtParams): Promise<string> {
export async function buildJWT({
wallet,
payload,
}: BuildJwtParams): Promise<string> {
const payloadData = AuthenticationPayloadDataSchema.parse(payload);
const message = JSON.stringify(payloadData);
+1 -1
View File
@@ -15,7 +15,7 @@ import { VerifyOptionsSchema } from "../schema/verify";
* Create an EIP-4361 & CAIP-122 compliant message to sign based on the login payload
*/
function createLoginMessage(payload: LoginPayloadData): string {
const typeField = payload.type === "evm" ? "Ethereum" : "Solana";
const typeField = "Ethereum";
const header = `${payload.domain} wants you to sign in with your ${typeField} account:`;
let prefix = [header, payload.address].join("\n");
prefix = [prefix, payload.statement].join("\n\n");
+1
View File
@@ -3,6 +3,7 @@ export { ThirdwebAuth } from "./auth";
// Export individual auth functions
export {
buildJWT,
generateJWT,
parseJWT,
refreshJWT,
@@ -9,7 +9,7 @@ export const AuthenticationPayloadDataSchema = z.object({
exp: RawDateSchema,
nbf: RawDateSchema,
iat: RawDateSchema,
jti: z.string().default(uuidv4()),
jti: z.string().default(() => uuidv4()),
ctx: JsonSchema.optional(),
});
+1 -4
View File
@@ -23,10 +23,7 @@ export const RawDateSchema = z.date().transform((i) => {
return Math.floor(i.getTime() / 1000);
});
export const AccountTypeSchema = z.union([
z.literal("evm"),
z.literal("solana"),
]);
export const AccountTypeSchema = z.literal("evm");
export type User<TContext extends Json = Json> = {
address: string;
+1 -1
View File
@@ -44,7 +44,7 @@ export const LoginPayloadDataSchema = z.object({
uri: z.string().optional(),
version: z.string().default("1"),
chain_id: z.string().optional(),
nonce: z.string().default(uuidv4()),
nonce: z.string().default(() => uuidv4()),
issued_at: z
.date()
.default(new Date())
+1 -1
View File
@@ -2,7 +2,7 @@ import {
THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE,
THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX,
} from "../../constants";
import { Json } from "../../core/schema";
import { Json } from "../../core";
import { ThirdwebAuthContext, ThirdwebAuthUser } from "../types";
import { Request } from "express";
+8 -4
View File
@@ -2,7 +2,7 @@ import {
THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE,
THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX,
} from "../../constants";
import { GenerateOptions } from "../../core";
import { GenerateOptionsWithOptionalDomain } from "../../core";
import { LoginPayloadBodySchema, ThirdwebAuthContext } from "../types";
import { serialize } from "cookie";
import { Request, Response } from "express";
@@ -41,7 +41,7 @@ export default async function handler(
? new Date(Date.now() + 1000 * ctx.authOptions.tokenDurationInSeconds)
: undefined;
const generateOptions: GenerateOptions = {
const generateOptions: GenerateOptionsWithOptionalDomain = {
verifyOptions: {
statement: ctx.authOptions?.statement,
uri: ctx.authOptions?.uri,
@@ -68,6 +68,10 @@ export default async function handler(
}
}
if (ctx.callbacks?.onToken) {
await ctx.callbacks.onToken(token, req);
}
const {
payload: { exp },
} = ctx.auth.parseToken(token);
@@ -84,7 +88,7 @@ export default async function handler(
sameSite: ctx.cookieOptions?.sameSite || "none",
expires: new Date(exp * 1000),
httpOnly: true,
secure: true,
secure: ctx.cookieOptions?.secure || true,
},
),
serialize(THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE, payload.payload.address, {
@@ -93,7 +97,7 @@ export default async function handler(
sameSite: ctx.cookieOptions?.sameSite || "none",
expires: new Date(exp * 1000),
httpOnly: true,
secure: true,
secure: ctx.cookieOptions?.secure || true,
}),
]);
+1 -1
View File
@@ -37,7 +37,7 @@ export default async function handler(
sameSite: ctx.cookieOptions?.sameSite || "none",
expires: new Date(Date.now() + 5 * 1000),
httpOnly: true,
secure: true,
secure: ctx.cookieOptions?.secure || true,
}),
);
@@ -55,7 +55,7 @@ export default async function handler(
sameSite: ctx.cookieOptions?.sameSite || "none",
expires: cookieExpiration,
httpOnly: true,
secure: true,
secure: ctx.cookieOptions?.secure || true,
}),
]);
+2 -2
View File
@@ -53,7 +53,7 @@ export default async function handler(
sameSite: ctx.cookieOptions?.sameSite || "none",
expires: new Date(refreshedPayload.payload.exp * 1000),
httpOnly: true,
secure: true,
secure: ctx.cookieOptions?.secure || true,
},
),
serialize(THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE, user.address, {
@@ -62,7 +62,7 @@ export default async function handler(
sameSite: ctx.cookieOptions?.sameSite || "none",
expires: new Date(refreshedPayload.payload.exp * 1000),
httpOnly: true,
secure: true,
secure: ctx.cookieOptions?.secure || true,
}),
]);
}
+10 -6
View File
@@ -52,17 +52,21 @@ export type ThirdwebAuthConfig<
domain?: string;
path?: string;
sameSite?: "lax" | "strict" | "none";
secure?: boolean;
};
callbacks?: {
onLogin?:
| ((address: string, req?: Request) => void | TSession)
| ((address: string, req?: Request) => Promise<void | TSession>);
| ((address: string, req: Request) => void | TSession)
| ((address: string, req: Request) => Promise<void | TSession>);
onToken?:
| ((token: string, req: Request) => void)
| ((token: string, req: Request) => Promise<void>);
onUser?:
| ((user: User<TSession>, req?: Request) => void | TData)
| ((user: User<TSession>, req?: Request) => Promise<void | TData>);
| ((user: User<TSession>, req: Request) => void | TData)
| ((user: User<TSession>, req: Request) => Promise<void | TData>);
onLogout?:
| ((user: User, req?: Request) => void)
| ((user: User, req?: Request) => Promise<void>);
| ((user: User, req: Request) => void)
| ((user: User, req: Request) => Promise<void>);
};
};
+91
View File
@@ -0,0 +1,91 @@
import {
THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE,
THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX,
} from "../../constants";
import { Json } from "../../core";
import { ThirdwebAuthContext, ThirdwebAuthUser } from "../types";
import { FastifyRequest } from "fastify";
export function getCookie(
req: FastifyRequest,
cookie: string,
): string | undefined {
return req.cookies[cookie];
}
export function getActiveCookie(req: FastifyRequest): string | undefined {
if (!req.cookies) {
return undefined;
}
const activeAccount = getCookie(req, THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE);
if (activeAccount) {
return `${THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX}_${activeAccount}`;
}
// If active account is not present, then use the old default
return THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX;
}
/**
* @internal
* @param req
* @returns
*/
export function getToken(req: FastifyRequest): string | undefined {
if (req.headers.authorization) {
const authorizationHeader = req.headers.authorization.split(" ");
if (authorizationHeader?.length === 2) {
return authorizationHeader[1];
}
}
if (!req.cookies) {
return undefined;
}
const activeCookie = getActiveCookie(req);
if (!activeCookie) {
return undefined;
}
return getCookie(req, activeCookie);
}
export async function getUser<
TData extends Json = Json,
TSession extends Json = Json,
>(
req: FastifyRequest,
ctx: ThirdwebAuthContext<TData, TSession>,
): Promise<ThirdwebAuthUser<TData, TSession> | null> {
const token = getToken(req);
if (!token) {
return null;
}
let authenticatedUser: ThirdwebAuthUser<TData, TSession>;
try {
authenticatedUser = await ctx.auth.authenticate<TSession>(token, {
validateTokenId: async (tokenId: string) => {
if (ctx.authOptions?.validateTokenId) {
await ctx.authOptions?.validateTokenId(tokenId);
}
},
});
} catch (err) {
return null;
}
if (!ctx.callbacks?.onUser) {
return authenticatedUser;
}
const data = await ctx.callbacks.onUser(authenticatedUser, req);
if (!data) {
return authenticatedUser;
}
return { ...authenticatedUser, data: data };
}
+81
View File
@@ -0,0 +1,81 @@
import { FastifyInstance, FastifyPluginOptions, FastifyRequest } from "fastify";
import { Json, ThirdwebAuth as ThirdwebAuthSDK } from "../core";
import fastifyCookie, { FastifyCookie } from "@fastify/cookie";
import { payloadHandler } from "./routes/payload";
import { loginHandler } from "./routes/login";
import { userHandler } from "./routes/user";
import { logoutHandler } from "./routes/logout";
import { switchAccountHandler } from "./routes/switch-account";
import {
ZodTypeProvider,
serializerCompiler,
validatorCompiler,
} from "fastify-type-provider-zod";
import { getUser } from "./helpers/user";
import {
ThirdwebAuthConfig,
ThirdwebAuthContext,
ThirdwebAuthUser,
} from "./types";
export * from "./types";
export { getToken } from "./helpers/user";
type ThirdwebAuthReturnType<
TData extends Json = Json,
TSession extends Json = Json,
> = {
authRouter: (
fastify: FastifyInstance,
opts: FastifyPluginOptions,
done: (err?: Error | undefined) => void,
) => void;
authMiddleware: FastifyCookie;
getUser: (
req: FastifyRequest,
) => Promise<ThirdwebAuthUser<TData, TSession> | null>;
};
export function ThirdwebAuth<
TData extends Json = Json,
TSession extends Json = Json,
>(
cfg: ThirdwebAuthConfig<TData, TSession>,
): ThirdwebAuthReturnType<TData, TSession> {
const ctx = {
...cfg,
auth: new ThirdwebAuthSDK(cfg.wallet, cfg.domain),
};
const authRouter = async (
fastify: FastifyInstance,
_opts: FastifyPluginOptions,
done: (err?: Error | undefined) => void,
) => {
// Setup plugin to use zod as a type provider
fastify.setValidatorCompiler(validatorCompiler);
fastify.setSerializerCompiler(serializerCompiler);
const plugin = fastify.withTypeProvider<ZodTypeProvider>();
// Register the fastify cookie middleware with this plugin
await plugin.register(fastifyCookie);
// Register individual auth endpoints
payloadHandler(plugin, ctx as ThirdwebAuthContext);
loginHandler(plugin, ctx as ThirdwebAuthContext);
logoutHandler(plugin, ctx as ThirdwebAuthContext);
userHandler(plugin, ctx as ThirdwebAuthContext);
switchAccountHandler(plugin, ctx as ThirdwebAuthContext);
// Mark plugin creation as complete
done();
};
return {
authRouter,
authMiddleware: fastifyCookie,
getUser: (req: FastifyRequest) => {
return getUser<TData, TSession>(req, ctx);
},
};
}
+110
View File
@@ -0,0 +1,110 @@
import {
FastifyInstanceWithZod,
LoginPayloadBodySchema,
ThirdwebAuthContext,
} from "../types";
import { GenerateOptionsWithOptionalDomain } from "../../core";
import {
THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE,
THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX,
} from "../../constants";
import { z } from "zod";
export const loginHandler = (
fastify: FastifyInstanceWithZod,
ctx: ThirdwebAuthContext,
) => {
fastify.route<{
Body: z.infer<typeof LoginPayloadBodySchema>;
}>({
method: "POST",
url: "/login",
schema: {
body: LoginPayloadBodySchema,
response: {
200: z.any(),
},
},
handler: async (req, res) => {
const validateNonce = async (nonce: string) => {
if (ctx.authOptions?.validateNonce) {
await ctx.authOptions?.validateNonce(nonce);
}
};
const getSession = async (address: string) => {
if (ctx.callbacks?.onLogin) {
return ctx.callbacks.onLogin(address, req);
}
};
const expirationTime = ctx.authOptions?.tokenDurationInSeconds
? new Date(Date.now() + 1000 * ctx.authOptions.tokenDurationInSeconds)
: undefined;
const generateOptions: GenerateOptionsWithOptionalDomain = {
verifyOptions: {
statement: ctx.authOptions?.statement,
uri: ctx.authOptions?.uri,
version: ctx.authOptions?.version,
chainId: ctx.authOptions?.chainId,
validateNonce,
resources: ctx.authOptions?.resources,
},
expirationTime,
session: getSession,
};
let token: string;
try {
// Generate an access token with the SDK using the signed payload
token = await ctx.auth.generate(req.body.payload, generateOptions);
} catch (err: any) {
if (err.message) {
return res.status(400).send({ error: err.message });
} else if (typeof err === "string") {
return res.status(400).send({ error: err });
} else {
return res.status(400).send({ error: "Invalid login payload" });
}
}
if (ctx.callbacks?.onToken) {
await ctx.callbacks.onToken(token, req);
}
const {
payload: { exp },
} = ctx.auth.parseToken(token);
// Securely set httpOnly cookie on request to prevent XSS on frontend
// And set path to / to enable thirdweb_auth_token usage on all endpoints
res.setCookie(
`${THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX}_${req.body.payload.payload.address}`,
token,
{
domain: ctx.cookieOptions?.domain,
path: ctx.cookieOptions?.path || "/",
sameSite: ctx.cookieOptions?.sameSite || "none",
expires: new Date(exp * 1000),
httpOnly: true,
secure: ctx.cookieOptions?.secure || true,
},
);
res.setCookie(
THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE,
req.body.payload.payload.address,
{
domain: ctx.cookieOptions?.domain,
path: ctx.cookieOptions?.path || "/",
sameSite: ctx.cookieOptions?.sameSite || "none",
expires: new Date(exp * 1000),
httpOnly: true,
secure: ctx.cookieOptions?.secure || true,
},
);
return res.status(200).send({ success: true });
},
});
};
@@ -0,0 +1,52 @@
import { z } from "zod";
import { getActiveCookie, getUser } from "../helpers/user";
import {
ErrorResponseSchema,
FastifyInstanceWithZod,
ThirdwebAuthContext,
} from "../types";
export const logoutHandler = (
fastify: FastifyInstanceWithZod,
ctx: ThirdwebAuthContext,
) => {
fastify.route({
method: "POST",
url: "/logout",
schema: {
response: {
200: z.object({
message: z.string(),
}),
400: ErrorResponseSchema,
},
},
handler: async (req, res) => {
const activeCookie = getActiveCookie(req);
if (!activeCookie) {
return res.status(400).send({
error: "No logged in user to logout.",
});
}
if (ctx.callbacks?.onLogout) {
const user = await getUser(req, ctx);
if (user) {
await ctx.callbacks.onLogout(user, req);
}
}
// Set the access token to 'none' and expire in 5 seconds
res.setCookie(activeCookie, "", {
domain: ctx.cookieOptions?.domain,
path: ctx.cookieOptions?.path || "/",
sameSite: ctx.cookieOptions?.sameSite || "none",
expires: new Date(Date.now() + 5 * 1000),
httpOnly: true,
secure: ctx.cookieOptions?.secure || true,
});
return res.status(200).send({ message: "Successfully logged out" });
},
});
};
@@ -0,0 +1,41 @@
import {
FastifyInstanceWithZod,
PayloadBodySchema,
ThirdwebAuthContext,
} from "../types";
import { z } from "zod";
export const payloadHandler = (
fastify: FastifyInstanceWithZod,
ctx: ThirdwebAuthContext,
) => {
fastify.route<{
Body: z.infer<typeof PayloadBodySchema>;
}>({
method: "POST",
url: "/payload",
schema: {
body: PayloadBodySchema,
response: {
200: z.any(),
},
},
handler: async (req, res) => {
const payload = await ctx.auth.payload({
address: req.body.address,
statement: ctx.authOptions?.statement,
uri: ctx.authOptions?.uri,
version: ctx.authOptions?.version,
chainId: req.body.chainId || ctx.authOptions?.chainId,
resources: ctx.authOptions?.resources,
expirationTime: ctx.authOptions?.loginPayloadDurationInSeconds
? new Date(
Date.now() + 1000 * ctx.authOptions.loginPayloadDurationInSeconds,
)
: undefined,
});
return res.status(200).send({ payload });
},
});
};
@@ -0,0 +1,68 @@
import {
ActiveBodySchema,
ErrorResponseSchema,
FastifyInstanceWithZod,
ThirdwebAuthContext,
} from "../types";
import {
THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE,
THIRDWEB_AUTH_DEFAULT_TOKEN_DURATION_IN_SECONDS,
THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX,
} from "../../constants";
import { getCookie } from "../helpers/user";
import { z } from "zod";
export const switchAccountHandler = (
fastify: FastifyInstanceWithZod,
ctx: ThirdwebAuthContext,
) => {
fastify.route<{
Body: z.infer<typeof ActiveBodySchema>;
}>({
method: "POST",
url: "/switch-account",
schema: {
body: ActiveBodySchema,
response: {
200: z.any(),
400: ErrorResponseSchema,
},
},
handler: async (req, res) => {
let cookieExpiration: Date;
const cookie = getCookie(
req,
`${THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX}_${req.body.address}`,
);
if (cookie) {
// If the new account is already logged in, get the expiration time from the cookie
const {
payload: { exp },
} = ctx.auth.parseToken(cookie);
cookieExpiration = new Date(exp * 1000);
} else if (ctx.authOptions?.tokenDurationInSeconds) {
// Otherwise, if we have a token duration in seconds, set it to that
cookieExpiration = new Date(
Date.now() + 1000 * ctx.authOptions.tokenDurationInSeconds,
);
} else {
// Otherwise, just default to 24 hours
cookieExpiration = new Date(
Date.now() + 1000 * THIRDWEB_AUTH_DEFAULT_TOKEN_DURATION_IN_SECONDS,
);
}
res.setCookie(THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE, req.body.address, {
domain: ctx.cookieOptions?.domain,
path: ctx.cookieOptions?.path || "/",
sameSite: ctx.cookieOptions?.sameSite || "none",
expires: cookieExpiration,
httpOnly: true,
secure: ctx.cookieOptions?.secure || true,
});
return res.status(200).send();
},
});
};
+80
View File
@@ -0,0 +1,80 @@
import { getToken, getUser } from "../helpers/user";
import { FastifyInstanceWithZod, ThirdwebAuthContext } from "../types";
import {
THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE,
THIRDWEB_AUTH_DEFAULT_REFRESH_INTERVAL_IN_SECONDS,
THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX,
} from "../../constants";
import { z } from "zod";
export const userHandler = (
fastify: FastifyInstanceWithZod,
ctx: ThirdwebAuthContext,
) => {
fastify.route({
method: "GET",
url: "/user",
schema: {
response: {
200: z.any(),
},
},
handler: async (req, res) => {
const user = await getUser(req, ctx);
// Importantly, make sure the user was actually logged in before refreshing
if (user) {
const token = getToken(req);
if (token) {
const payload = ctx.auth.parseToken(token);
const refreshDate = ctx.authOptions?.refreshIntervalInSeconds
? new Date(
payload.payload.iat * 1000 +
ctx.authOptions.refreshIntervalInSeconds * 1000,
)
: new Date(
payload.payload.iat * 1000 +
THIRDWEB_AUTH_DEFAULT_REFRESH_INTERVAL_IN_SECONDS * 1000,
);
if (new Date() > refreshDate) {
const expirationTime = ctx.authOptions?.tokenDurationInSeconds
? new Date(
Date.now() + 1000 * ctx.authOptions.tokenDurationInSeconds,
)
: undefined;
const refreshedToken = await ctx.auth.refresh(
token,
expirationTime,
);
const refreshedPayload = ctx.auth.parseToken(refreshedToken);
res.setCookie(
`${THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX}_${user.address}`,
refreshedToken,
{
domain: ctx.cookieOptions?.domain,
path: ctx.cookieOptions?.path || "/",
sameSite: ctx.cookieOptions?.sameSite || "none",
expires: new Date(refreshedPayload.payload.exp * 1000),
httpOnly: true,
secure: ctx.cookieOptions?.secure || true,
},
);
res.setCookie(THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE, user.address, {
domain: ctx.cookieOptions?.domain,
path: ctx.cookieOptions?.path || "/",
sameSite: ctx.cookieOptions?.sameSite || "none",
expires: new Date(refreshedPayload.payload.exp * 1000),
httpOnly: true,
secure: ctx.cookieOptions?.secure || true,
});
}
}
}
return res.status(200).send(user);
},
});
};
+94
View File
@@ -0,0 +1,94 @@
import { GenericAuthWallet } from "@thirdweb-dev/wallets";
import { Json, LoginPayloadOutputSchema, ThirdwebAuth, User } from "../../core";
import {
FastifyBaseLogger,
FastifyInstance,
FastifyRequest,
RawServerDefault,
} from "fastify";
import { z } from "zod";
import { IncomingMessage, ServerResponse } from "http";
import { ZodTypeProvider } from "fastify-type-provider-zod";
export const PayloadBodySchema = z.object({
address: z.string(),
chainId: z.string().optional(),
});
export const ActiveBodySchema = z.object({
address: z.string(),
});
export const LoginPayloadBodySchema = z.object({
payload: LoginPayloadOutputSchema,
});
export const ErrorResponseSchema = z.object({
error: z.string(),
});
export type ThirdwebAuthUser<
TData extends Json = Json,
TSession extends Json = Json,
> = User<TSession> & {
data?: TData;
};
export type ThirdwebAuthConfig<
TData extends Json = Json,
TSession extends Json = Json,
> = {
domain: string;
wallet: GenericAuthWallet;
authOptions?: {
statement?: string;
uri?: string;
version?: string;
chainId?: string;
resources?: string[];
validateNonce?:
| ((nonce: string) => void)
| ((nonce: string) => Promise<void>);
validateTokenId?:
| ((tokenId: string) => void)
| ((tokenId: string) => Promise<void>);
loginPayloadDurationInSeconds?: number;
tokenDurationInSeconds?: number;
refreshIntervalInSeconds?: number;
};
cookieOptions?: {
domain?: string;
path?: string;
sameSite?: "lax" | "strict" | "none";
secure?: boolean;
};
callbacks?: {
onLogin?:
| ((address: string, req: FastifyRequest) => void | TSession)
| ((address: string, req: FastifyRequest) => Promise<void | TSession>);
onToken?:
| ((token: string, req: FastifyRequest) => void)
| ((token: string, req: FastifyRequest) => Promise<void>);
onUser?:
| ((user: User<TSession>, req: FastifyRequest) => void | TData)
| ((user: User<TSession>, req: FastifyRequest) => Promise<void | TData>);
onLogout?:
| ((user: User, req: FastifyRequest) => void)
| ((user: User, req: FastifyRequest) => Promise<void>);
};
};
export type ThirdwebAuthContext<
TData extends Json = Json,
TSession extends Json = Json,
> = Omit<Omit<ThirdwebAuthConfig<TData, TSession>, "wallet">, "domain"> & {
auth: ThirdwebAuth;
};
export type FastifyInstanceWithZod = FastifyInstance<
RawServerDefault,
IncomingMessage,
ServerResponse<IncomingMessage>,
FastifyBaseLogger,
ZodTypeProvider
>;
+1 -1
View File
@@ -2,7 +2,7 @@ import {
THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE,
THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX,
} from "../../constants";
import { Json } from "../../core/schema";
import { Json } from "../../core";
import { ThirdwebAuthContext, ThirdwebAuthUser } from "../types";
import { GetServerSidePropsContext, NextApiRequest } from "next";
import { NextRequest } from "next/server";
+8 -4
View File
@@ -2,7 +2,7 @@ import {
THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE,
THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX,
} from "../../constants";
import { GenerateOptions } from "../../core";
import { GenerateOptionsWithOptionalDomain } from "../../core";
import { LoginPayloadBodySchema, ThirdwebAuthContext } from "../types";
import { serialize } from "cookie";
import { NextApiRequest, NextApiResponse } from "next";
@@ -41,7 +41,7 @@ export default async function handler(
? new Date(Date.now() + 1000 * ctx.authOptions.tokenDurationInSeconds)
: undefined;
const generateOptions: GenerateOptions = {
const generateOptions: GenerateOptionsWithOptionalDomain = {
verifyOptions: {
statement: ctx.authOptions?.statement,
uri: ctx.authOptions?.uri,
@@ -68,6 +68,10 @@ export default async function handler(
}
}
if (ctx.callbacks?.onToken) {
await ctx.callbacks.onToken(token, req);
}
const {
payload: { exp },
} = ctx.auth.parseToken(token);
@@ -84,7 +88,7 @@ export default async function handler(
sameSite: ctx.cookieOptions?.sameSite || "none",
expires: new Date(exp * 1000),
httpOnly: true,
secure: true,
secure: ctx.cookieOptions?.secure || true,
},
),
serialize(THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE, payload.payload.address, {
@@ -93,7 +97,7 @@ export default async function handler(
sameSite: ctx.cookieOptions?.sameSite || "none",
expires: new Date(exp * 1000),
httpOnly: true,
secure: true,
secure: ctx.cookieOptions?.secure || true,
}),
]);
+1 -1
View File
@@ -37,7 +37,7 @@ export default async function handler(
sameSite: ctx.cookieOptions?.sameSite || "none",
expires: new Date(Date.now() + 5 * 1000),
httpOnly: true,
secure: true,
secure: ctx.cookieOptions?.secure || true,
}),
);
@@ -55,7 +55,7 @@ export default async function handler(
sameSite: ctx.cookieOptions?.sameSite || "none",
expires: cookieExpiration,
httpOnly: true,
secure: true,
secure: ctx.cookieOptions?.secure || true,
}),
]);
+2 -2
View File
@@ -53,7 +53,7 @@ export default async function handler(
sameSite: ctx.cookieOptions?.sameSite || "none",
expires: new Date(refreshedPayload.payload.exp * 1000),
httpOnly: true,
secure: true,
secure: ctx.cookieOptions?.secure || true,
},
),
serialize(THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE, user.address, {
@@ -62,7 +62,7 @@ export default async function handler(
sameSite: ctx.cookieOptions?.sameSite || "none",
expires: new Date(refreshedPayload.payload.exp * 1000),
httpOnly: true,
secure: true,
secure: ctx.cookieOptions?.secure || true,
}),
]);
}
+10 -6
View File
@@ -62,23 +62,27 @@ export type ThirdwebAuthConfig<
domain?: string;
path?: string;
sameSite?: "lax" | "strict" | "none";
secure?: boolean;
};
callbacks?: {
onLogin?:
| ((address: string, req?: NextApiRequest) => void | TSession)
| ((address: string, req?: NextApiRequest) => Promise<void | TSession>);
| ((address: string, req: NextApiRequest) => void | TSession)
| ((address: string, req: NextApiRequest) => Promise<void | TSession>);
onToken?:
| ((token: string, req: NextApiRequest) => void)
| ((token: string, req: NextApiRequest) => Promise<void>);
onUser?:
| (<TRequestType extends RequestType = RequestType>(
user: User<TSession>,
req?: TRequestType,
req: TRequestType,
) => void | TData)
| (<TRequestType extends RequestType = RequestType>(
user: User<TSession>,
req?: TRequestType,
req: TRequestType,
) => Promise<void | TData>);
onLogout?:
| ((user: User, req?: NextApiRequest) => void)
| ((user: User, req?: NextApiRequest) => Promise<void>);
| ((user: User, req: NextApiRequest) => void)
| ((user: User, req: NextApiRequest) => Promise<void>);
};
};
-29
View File
@@ -1,29 +0,0 @@
import { ThirdwebAuth } from "../core";
import { LoginPayload, VerifyOptions } from "../core/schema";
import { Keypair } from "@solana/web3.js";
import { KeypairWallet } from "@thirdweb-dev/wallets/solana/wallets/keypair";
const authMap = new Map<string, ThirdwebAuth>();
let wallet: KeypairWallet;
export async function verifyLogin(
domain: string,
payload: LoginPayload,
options?: Omit<VerifyOptions, "domain">,
) {
wallet = wallet || new KeypairWallet(Keypair.generate());
let auth: ThirdwebAuth;
if (!authMap.has(domain)) {
auth = new ThirdwebAuth(wallet, domain);
authMap.set(domain, auth);
} else {
auth = authMap.get(domain) as ThirdwebAuth;
}
try {
const address = await auth.verify(payload, options);
return { address, error: undefined };
} catch (err: any) {
return { address: undefined, error: err.message };
}
}
-353
View File
@@ -1,353 +0,0 @@
import { ThirdwebAuth } from "../src/core";
import { Keypair } from "@solana/web3.js";
import { KeypairWallet } from "@thirdweb-dev/wallets/solana/wallets/keypair";
import { expect } from "chai";
describe("Wallet Authentication - Solana", async () => {
let adminWallet: any, signerWallet: any, attackerWallet: any;
let auth: ThirdwebAuth;
before(async () => {
const [adminSigner, signerSigner, attackerSigner] = [
Keypair.generate(),
Keypair.generate(),
Keypair.generate(),
];
adminWallet = new KeypairWallet(adminSigner);
signerWallet = new KeypairWallet(signerSigner);
attackerWallet = new KeypairWallet(attackerSigner);
auth = new ThirdwebAuth(signerWallet, "thirdweb.com");
});
beforeEach(async () => {
auth.updateWallet(signerWallet);
});
it("Should verify logged in wallet", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const address = await auth.verify(payload);
expect(address).to.equal(await signerWallet.getAddress());
});
it("Should verify logged in wallet with chain ID and expiration", async () => {
const payload = await auth.login({
expirationTime: new Date(Date.now() + 1000 * 60 * 5),
chainId: "137",
});
auth.updateWallet(adminWallet);
const address = await auth.verify(payload, {
chainId: "137",
});
expect(address).to.equal(await signerWallet.getAddress());
});
it("Should verify payload with resources", async () => {
const payload = await auth.login({
resources: ["https://example.com", "https://test.com"],
});
auth.updateWallet(adminWallet);
const address = await auth.verify(payload, {
resources: ["https://example.com", "https://test.com"],
});
expect(address).to.equal(await signerWallet.getAddress());
});
it("Should reject payload without necessary resources", async () => {
const payload = await auth.login({
resources: ["https://example.com"],
});
auth.updateWallet(adminWallet);
try {
await auth.verify(payload, {
resources: ["https://example.com", "https://test.com"],
});
expect.fail();
} catch (err: any) {
expect(err.message).to.equal(
"Login request is missing required resources: https://test.com",
);
}
});
it("Should verify payload with customized statement", async () => {
const payload = await auth.login({
statement: "Please sign!",
});
auth.updateWallet(adminWallet);
const address = await auth.verify(payload, {
statement: "Please sign!",
});
expect(address).to.equal(await signerWallet.getAddress());
});
it("Should reject payload with incorrect statement", async () => {
const payload = await auth.login({
statement: "Please sign!",
});
auth.updateWallet(adminWallet);
try {
await auth.verify(payload, {
statement: "Please sign again!",
});
expect.fail();
} catch (err: any) {
expect(err.message).to.include(
"Expected statement 'Please sign again!' does not match statement on payload",
);
}
});
it("Should reject invalid nonce", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
try {
await auth.verify(payload, {
validateNonce: (nonce: string) => {
if (nonce === payload.payload.nonce) {
throw new Error();
}
},
});
expect.fail();
} catch (err: any) {
expect(err.message).to.equal("Login request nonce is invalid");
}
});
it("Should accept valid nonce", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const address = await auth.verify(payload, {
validateNonce: (nonce: string) => {
if (nonce !== payload.payload.nonce) {
throw new Error();
}
},
});
expect(address).to.equal(await signerWallet.getAddress());
});
it("Should reject payload with incorrect domain", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
try {
await auth.verify(payload, { domain: "test.thirdweb.com" });
expect.fail();
} catch (err: any) {
expect(err.message).to.equal(
"Expected domain 'test.thirdweb.com' does not match domain on payload 'thirdweb.com'",
);
}
});
it("Should reject expired login payload", async () => {
const payload = await auth.login({
expirationTime: new Date(Date.now() - 1000 * 60 * 5),
});
auth.updateWallet(adminWallet);
try {
await auth.verify(payload);
expect.fail();
} catch (err: any) {
expect(err.message).to.equal("Login request has expired");
}
});
it("Should reject payload with incorrect chain ID", async () => {
const payload = await auth.login({
chainId: "1",
});
auth.updateWallet(adminWallet);
try {
await auth.verify(payload, {
chainId: "137",
});
expect.fail();
} catch (err: any) {
expect(err.message).to.equal(
"Expected chain ID '137' does not match chain ID on payload '1'",
);
}
});
it("Should reject payload with incorrect signer", async () => {
const payload = await auth.login();
payload.payload.address = await attackerWallet.getAddress();
auth.updateWallet(adminWallet);
try {
await auth.verify(payload);
expect.fail();
} catch (err: any) {
expect(err.message).to.contain("does not match payload address");
}
});
it("Should generate valid authentication token", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload);
const user = await auth.authenticate(token);
expect(user.address).to.equal(await signerWallet.getAddress());
});
it("Should reject token with incorrect domain", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload);
try {
await auth.authenticate(token, { domain: "test.thirdweb.com" });
expect.fail();
} catch (err: any) {
expect(err.message).to.contain(
"Expected token to be for the domain 'test.thirdweb.com', but found token with domain 'thirdweb.com'",
);
}
});
it("Should reject token before invalid before", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload, {
invalidBefore: new Date(Date.now() + 1000 * 60 * 5),
});
try {
await auth.authenticate(token);
expect.fail();
} catch (err: any) {
expect(err.message).to.contain("This token is invalid before");
}
});
it("Should reject expired authentication token", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload, {
expirationTime: new Date(Date.now() - 1000 * 60 * 5),
});
try {
await auth.authenticate(token);
expect.fail();
} catch (err: any) {
expect(err.message).to.contain("This token expired");
}
});
it("Should reject if admin address is not connected wallet address", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload);
auth.updateWallet(signerWallet);
try {
await auth.authenticate(token);
expect.fail();
} catch (err: any) {
expect(err.message).to.contain(
`The expected issuer address '${await signerWallet.getAddress()}' did not match the token issuer address '${await adminWallet.getAddress()}'`,
);
}
});
it("Should accept token with valid token ID", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload, {
tokenId: "test",
});
const user = await auth.authenticate(token, {
validateTokenId: (tokenId: string) => {
if (tokenId !== "test") {
throw new Error();
}
},
});
expect(user.address).to.equal(await signerWallet.getAddress());
});
it("Should reject token with invalid token ID", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload, {
tokenId: "test",
});
try {
await auth.authenticate(token, {
validateTokenId: (tokenId: string) => {
if (tokenId !== "invalid") {
throw new Error();
}
},
});
expect.fail();
} catch (err: any) {
expect(err.message).to.contain("Token ID is invalid");
}
});
it("Should propagate session on token", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload, {
session: { role: "admin" },
});
const user = await auth.authenticate(token);
expect(user.address).to.equal(await signerWallet.getAddress());
expect(user.session).to.deep.equal({ role: "admin" });
});
it("Should call session callback function", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload, {
session: (address: string) => {
return { address, role: "admin" };
},
});
const user = await auth.authenticate(token);
expect(user.address).to.equal(await signerWallet.getAddress());
expect(user.session).to.deep.equal({
address: await signerWallet.getAddress(),
role: "admin",
});
});
});
+6
View File
@@ -1,5 +1,11 @@
# @thirdweb-dev/chains
## 0.1.55
### Patch Changes
- [#1783](https://github.com/thirdweb-dev/js/pull/1783) [`137f46a5`](https://github.com/thirdweb-dev/js/commit/137f46a5470d2b5f9d7f9eda9b2d839a53ddeb64) Thanks [@jnsdls](https://github.com/jnsdls)! - sync chains
## 0.1.54
### Patch Changes
+4 -4
View File
@@ -4,13 +4,13 @@ export default {
"chainId": 100,
"explorers": [
{
"name": "gnosisscan",
"url": "https://gnosisscan.io",
"name": "blockscout",
"url": "https://gnosis.blockscout.com",
"standard": "EIP3091"
},
{
"name": "blockscout",
"url": "https://gnosis.blockscout.com",
"name": "gnosisscan",
"url": "https://gnosisscan.io",
"standard": "EIP3091"
}
],
+4 -4
View File
@@ -4,13 +4,13 @@ export default {
"chainId": 11110,
"explorers": [
{
"name": "Astra PingPub Explorer",
"url": "https://ping.astranaut.io/astra",
"name": "Astra EVM Explorer (Blockscout)",
"url": "https://explorer.astranaut.io",
"standard": "none"
},
{
"name": "Astra EVM Explorer (Blockscout)",
"url": "https://explorer.astranaut.io",
"name": "Astra PingPub Explorer",
"url": "https://ping.astranaut.io/astra",
"standard": "none"
}
],
+5 -5
View File
@@ -3,15 +3,15 @@ export default {
"chain": "Astra",
"chainId": 11115,
"explorers": [
{
"name": "Astra PingPub Explorer",
"url": "https://ping.astranaut.dev/astra",
"standard": "none"
},
{
"name": "Astra EVM Explorer",
"url": "https://explorer.astranaut.dev",
"standard": "EIP3091"
},
{
"name": "Astra PingPub Explorer",
"url": "https://ping.astranaut.dev/astra",
"standard": "none"
}
],
"faucets": [
-1
View File
@@ -19,7 +19,6 @@ export default {
},
"redFlags": [],
"rpc": [
"https://localhost.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"http://localhost:8545"
],
"shortName": "local",
+4 -4
View File
@@ -4,13 +4,13 @@ export default {
"chainId": 2023,
"explorers": [
{
"name": "Taycan Cosmos Explorer",
"url": "https://cosmoscan-test.hupayx.io",
"name": "Taycan Explorer(Blockscout)",
"url": "https://evmscan-test.hupayx.io",
"standard": "none"
},
{
"name": "Taycan Explorer(Blockscout)",
"url": "https://evmscan-test.hupayx.io",
"name": "Taycan Cosmos Explorer",
"url": "https://cosmoscan-test.hupayx.io",
"standard": "none"
}
],
-1
View File
@@ -30,7 +30,6 @@ export default {
"rpc": [
"https://kava-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://evm.testnet.kava.io",
"https://kava-evm-testnet.rpc.thirdweb.com",
"wss://wevm.testnet.kava.io"
],
"shortName": "tkava",
-1
View File
@@ -30,7 +30,6 @@ export default {
"https://evm.kava.io",
"https://evm2.kava.io",
"https://kava-rpc.gateway.pokt.network",
"https://kava-evm.rpc.thirdweb.com",
"wss://wevm.kava.io",
"wss://wevm2.kava.io",
"https://kava-evm.publicnode.com",
+4 -4
View File
@@ -4,13 +4,13 @@ export default {
"chainId": 30,
"explorers": [
{
"name": "Rootstock Explorer",
"url": "https://explorer.rsk.co",
"name": "blockscout",
"url": "https://rootstock.blockscout.com",
"standard": "EIP3091"
},
{
"name": "blockscout",
"url": "https://rootstock.blockscout.com",
"name": "Rootstock Explorer",
"url": "https://explorer.rsk.co",
"standard": "EIP3091"
}
],
+5 -5
View File
@@ -3,15 +3,15 @@ export default {
"chain": "SDN",
"chainId": 336,
"explorers": [
{
"name": "subscan",
"url": "https://shiden.subscan.io",
"standard": "none"
},
{
"name": "blockscout",
"url": "https://blockscout.com/shiden",
"standard": "EIP3091"
},
{
"name": "subscan",
"url": "https://shiden.subscan.io",
"standard": "none"
}
],
"faucets": [],
+4 -4
View File
@@ -4,13 +4,13 @@ export default {
"chainId": 369,
"explorers": [
{
"name": "otterscan",
"url": "https://otter.pulsechain.com",
"name": "blockscout",
"url": "https://scan.pulsechain.com",
"standard": "EIP3091"
},
{
"name": "blockscout",
"url": "https://scan.pulsechain.com",
"name": "otterscan",
"url": "https://otter.pulsechain.com",
"standard": "EIP3091"
}
],
+3 -3
View File
@@ -18,7 +18,7 @@ export default {
"format": "png"
},
"infoURL": "http://doschain.io/",
"name": "DOS Tesnet",
"name": "DOS Testnet",
"nativeCurrency": {
"name": "DOS",
"symbol": "DOS",
@@ -26,10 +26,10 @@ export default {
},
"redFlags": [],
"rpc": [
"https://dos-tesnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://dos-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://test.doschain.com"
],
"shortName": "dost",
"slug": "dos-tesnet",
"slug": "dos-testnet",
"testnet": true
} as const satisfies Chain;
+1 -2
View File
@@ -27,8 +27,7 @@ export default {
"redFlags": [],
"rpc": [
"https://wireshape-floripa-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc-floripa.wireshape.org",
"https://wireshape-floripa-testnet.rpc.thirdweb.com"
"https://rpc-floripa.wireshape.org"
],
"shortName": "floripa",
"slug": "wireshape-floripa-testnet",
+4 -4
View File
@@ -4,13 +4,13 @@ export default {
"chainId": 50,
"explorers": [
{
"name": "blocksscan",
"url": "https://xdc.blocksscan.io",
"name": "xdcscan",
"url": "https://xdcscan.io",
"standard": "EIP3091"
},
{
"name": "xdcscan",
"url": "https://xdcscan.io",
"name": "blocksscan",
"url": "https://xdc.blocksscan.io",
"standard": "EIP3091"
}
],
+4 -4
View File
@@ -4,13 +4,13 @@ export default {
"chainId": 51,
"explorers": [
{
"name": "blocksscan",
"url": "https://apothem.blocksscan.io",
"name": "xdcscan",
"url": "https://apothem.xinfinscan.com",
"standard": "EIP3091"
},
{
"name": "xdcscan",
"url": "https://apothem.xinfinscan.com",
"name": "blocksscan",
"url": "https://apothem.blocksscan.io",
"standard": "EIP3091"
}
],
+5 -5
View File
@@ -3,15 +3,15 @@ export default {
"chain": "Imversed",
"chainId": 5555555,
"explorers": [
{
"name": "Imversed Cosmos Explorer (Big Dipper)",
"url": "https://tex-c.imversed.com",
"standard": "none"
},
{
"name": "Imversed EVM explorer (Blockscout)",
"url": "https://txe.imversed.network",
"standard": "EIP3091"
},
{
"name": "Imversed Cosmos Explorer (Big Dipper)",
"url": "https://tex-c.imversed.com",
"standard": "none"
}
],
"faucets": [],
+5 -5
View File
@@ -3,15 +3,15 @@ export default {
"chain": "Imversed",
"chainId": 5555558,
"explorers": [
{
"name": "Imversed Cosmos Explorer (Big Dipper)",
"url": "https://tex-t.imversed.com",
"standard": "none"
},
{
"name": "Imversed EVM Explorer (Blockscout)",
"url": "https://txe-test.imversed.network",
"standard": "EIP3091"
},
{
"name": "Imversed Cosmos Explorer (Big Dipper)",
"url": "https://tex-t.imversed.com",
"standard": "none"
}
],
"faucets": [],
+4 -4
View File
@@ -4,13 +4,13 @@ export default {
"chainId": 59140,
"explorers": [
{
"name": "Blockscout",
"url": "https://explorer.goerli.linea.build",
"name": "Etherscan",
"url": "https://goerli.lineascan.build",
"standard": "EIP3091"
},
{
"name": "Etherscan",
"url": "https://goerli.lineascan.build",
"name": "Blockscout",
"url": "https://explorer.goerli.linea.build",
"standard": "EIP3091"
}
],
-5
View File
@@ -7,11 +7,6 @@ export default {
"name": "lineascan",
"url": "https://lineascan.build",
"standard": "EIP3091"
},
{
"name": "Linea Scan",
"url": "https://lineascan.build",
"standard": ""
}
],
"faucets": [
+5 -5
View File
@@ -3,15 +3,15 @@ export default {
"chain": "ASTR",
"chainId": 592,
"explorers": [
{
"name": "subscan",
"url": "https://astar.subscan.io",
"standard": "none"
},
{
"name": "blockscout",
"url": "https://blockscout.com/astar",
"standard": "EIP3091"
},
{
"name": "subscan",
"url": "https://astar.subscan.io",
"standard": "none"
}
],
"faucets": [],
+4 -4
View File
@@ -4,13 +4,13 @@ export default {
"chainId": 8000,
"explorers": [
{
"name": "Teleport Cosmos Explorer (Big Dipper)",
"url": "https://explorer.teleport.network",
"name": "Teleport EVM Explorer (Blockscout)",
"url": "https://evm-explorer.teleport.network",
"standard": "none"
},
{
"name": "Teleport EVM Explorer (Blockscout)",
"url": "https://evm-explorer.teleport.network",
"name": "Teleport Cosmos Explorer (Big Dipper)",
"url": "https://explorer.teleport.network",
"standard": "none"
}
],
+4 -4
View File
@@ -4,13 +4,13 @@ export default {
"chainId": 8001,
"explorers": [
{
"name": "Teleport Cosmos Explorer (Big Dipper)",
"url": "https://explorer.testnet.teleport.network",
"name": "Teleport EVM Explorer (Blockscout)",
"url": "https://evm-explorer.testnet.teleport.network",
"standard": "none"
},
{
"name": "Teleport EVM Explorer (Blockscout)",
"url": "https://evm-explorer.testnet.teleport.network",
"name": "Teleport Cosmos Explorer (Big Dipper)",
"url": "https://explorer.testnet.teleport.network",
"standard": "none"
}
],
+5 -5
View File
@@ -3,15 +3,15 @@ export default {
"chain": "ETH",
"chainId": 8453,
"explorers": [
{
"name": "basescan",
"url": "https://basescan.org",
"standard": "none"
},
{
"name": "basescout",
"url": "https://base.blockscout.com",
"standard": "EIP3091"
},
{
"name": "basescan",
"url": "https://basescan.org",
"standard": "none"
}
],
"faucets": [],
+5 -5
View File
@@ -3,15 +3,15 @@ export default {
"chain": "ETH",
"chainId": 84531,
"explorers": [
{
"name": "basescan",
"url": "https://goerli.basescan.org",
"standard": "none"
},
{
"name": "basescout",
"url": "https://base-goerli.blockscout.com",
"standard": "EIP3091"
},
{
"name": "basescan",
"url": "https://goerli.basescan.org",
"standard": "none"
}
],
"faucets": [
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/chains",
"version": "0.1.54",
"version": "0.1.55",
"main": "dist/thirdweb-dev-chains.cjs.js",
"module": "dist/thirdweb-dev-chains.esm.js",
"browser": {
+22 -24
View File
@@ -6,7 +6,7 @@ const BASE_URI = (process.env.BASE_URI as string) || "https://api.thirdweb.com";
async function getAllPaginatedChains(
chains: any[] = [],
pathname = "/v1/chains",
pathname = "/v1/chains?limit=100",
) {
const url = new URL(BASE_URI);
url.pathname = pathname;
@@ -33,31 +33,37 @@ async function sync() {
const results = await Promise.all(
allChainsInDB.map(async (chain) => {
let chainId = chain.chainId;
// try to convert to number for legacy reasons
try {
chainId = Number(chainId);
} catch {
// if we fail here then we cannot use this chain in the chains package for now, so we skip it
return null;
}
const pkgChain: Chain = {
...chain,
chainId: Number(chain.chainId),
// assing back the chainId
chainId,
// map the features to the legacy format
features: chain.features?.map((feature) => ({ name: feature })),
};
// remove all null values
Object.keys(pkgChain).forEach((key) => {
// @ts-ignore
if (pkgChain[key] === null || pkgChain[key] === undefined) {
// @ts-ignore
delete pkgChain[key];
}
});
// sort top level keys alphabetically
// @ts-ignore
const sortedChain: Chain = {};
const sortedChain = {} as Chain;
Object.keys(pkgChain)
.sort()
.forEach((key) => {
// @ts-ignore
sortedChain[key] = pkgChain[key];
});
// @ts-ignore
await fs.writeFile(
`${chainsDir}/${sortedChain.chainId}.ts`,
`import type { Chain } from "../src/types";
@@ -78,17 +84,8 @@ export default ${JSON.stringify(
exportName = `_${exportName}`;
}
// imports.push(`import c${chain.chainId} from "../chains/${chain.chainId}";`);
// exports.push(
// `export { default as ${exportName} } from "../chains/${chain.chainId}"`,
// );
const key = `c${sortedChain.chainId}`;
// exportNames.push(key);
// exportNameToChain[key] = chain;
return {
imp: `import c${sortedChain.chainId} from "../chains/${sortedChain.chainId}";`,
exp: `export { default as ${exportName} } from "../chains/${sortedChain.chainId}"`,
@@ -101,20 +98,21 @@ export default ${JSON.stringify(
const { imports, exports, exportNames, exportNameToChain } = results.reduce(
(acc, result) => {
// @ts-ignore
// if it's a null result skip it (can happen when we skip chains above because their chainID is out of bounds)
if (result === null) {
return acc;
}
acc.imports.push(result.imp);
// @ts-ignore
acc.exports.push(result.exp);
// @ts-ignore
acc.exportNames.push(result.key);
acc.exportNameToChain[result.key] = result.chain;
return acc;
},
{
imports: [],
exports: [],
exportNames: [],
exportNameToChain: {},
imports: [] as string[],
exports: [] as string[],
exportNames: [] as string[],
exportNameToChain: {} as Record<string, Chain>,
},
);
+2 -2
View File
@@ -1587,7 +1587,7 @@ export { default as Alveychain } from "../chains/3797"
export { default as Kalychain } from "../chains/3888"
export { default as KalychainTestnet } from "../chains/3889"
export { default as DracNetwork } from "../chains/3912"
export { default as DosTesnet } from "../chains/3939"
export { default as DosTestnet } from "../chains/3939"
export { default as Dyno } from "../chains/3966"
export { default as DynoTestnet } from "../chains/3967"
export { default as Yuanchain } from "../chains/3999"
@@ -3727,7 +3727,7 @@ type ChainIdsBySlug = {
"kalychain": 3888,
"kalychain-testnet": 3889,
"drac-network": 3912,
"dos-tesnet": 3939,
"dos-testnet": 3939,
"dyno": 3966,
"dyno-testnet": 3967,
"yuanchain": 3999,
+108
View File
@@ -1,5 +1,113 @@
# thirdweb
## 0.13.8
### Patch Changes
- Updated dependencies [[`5ffbcfc3`](https://github.com/thirdweb-dev/js/commit/5ffbcfc302f74167768b196d93a328f979344036), [`42ba15f2`](https://github.com/thirdweb-dev/js/commit/42ba15f2c0e77e23e62650119dfaaa5c0dbe4481), [`d27a3dee`](https://github.com/thirdweb-dev/js/commit/d27a3dee8398d5707d2d1343c428abf8e03f67e3), [`c238fde8`](https://github.com/thirdweb-dev/js/commit/c238fde8777fd14b39837117e2d3fda1dd301029), [`99d7ec06`](https://github.com/thirdweb-dev/js/commit/99d7ec06ec4f31308627edc87d3122c21a884b5a), [`ff996646`](https://github.com/thirdweb-dev/js/commit/ff996646b228d4d095eea04b05004dd26fc7e522), [`d8d48a95`](https://github.com/thirdweb-dev/js/commit/d8d48a9516fc8fdd173fbb91a858fe7ec0725ddd), [`aa9f48d1`](https://github.com/thirdweb-dev/js/commit/aa9f48d1361194fc81146da530c95a3409bd0799), [`fd7a9f09`](https://github.com/thirdweb-dev/js/commit/fd7a9f09989e39b02a93d9dfd01cc7378e6ead53), [`fd7a9f09`](https://github.com/thirdweb-dev/js/commit/fd7a9f09989e39b02a93d9dfd01cc7378e6ead53), [`2307f11a`](https://github.com/thirdweb-dev/js/commit/2307f11ab311aa4a775edd23e777d10f8015ce86), [`54860198`](https://github.com/thirdweb-dev/js/commit/548601981f6dd8706d7a9bd4ca48e4abc7723a1d), [`64138642`](https://github.com/thirdweb-dev/js/commit/64138642e84d8b56b254762eca613d443cca292b), [`6d1eabe9`](https://github.com/thirdweb-dev/js/commit/6d1eabe9f9818ee2a79ce5bf6aa74417dbfd0558), [`c238fde8`](https://github.com/thirdweb-dev/js/commit/c238fde8777fd14b39837117e2d3fda1dd301029)]:
- @thirdweb-dev/wallets@2.0.8
- @thirdweb-dev/sdk@4.0.7
- @thirdweb-dev/auth@4.1.0
- @thirdweb-dev/storage@2.0.1
## 0.13.7
### Patch Changes
- Updated dependencies [[`137f46a5`](https://github.com/thirdweb-dev/js/commit/137f46a5470d2b5f9d7f9eda9b2d839a53ddeb64)]:
- @thirdweb-dev/chains@0.1.55
- @thirdweb-dev/sdk@4.0.6
- @thirdweb-dev/wallets@2.0.7
- @thirdweb-dev/auth@4.0.7
## 0.13.6
### Patch Changes
- Updated dependencies [[`07544252`](https://github.com/thirdweb-dev/js/commit/07544252b49163e1ae84ba2cc76b99597a1c4553)]:
- @thirdweb-dev/sdk@4.0.5
- @thirdweb-dev/wallets@2.0.6
- @thirdweb-dev/auth@4.0.6
## 0.13.5
### Patch Changes
- Updated dependencies []:
- @thirdweb-dev/sdk@4.0.4
- @thirdweb-dev/wallets@2.0.5
- @thirdweb-dev/auth@4.0.5
## 0.13.4
### Patch Changes
- Updated dependencies [[`956b5645`](https://github.com/thirdweb-dev/js/commit/956b5645e4266cba536abd27ee250dab5aa9a177)]:
- @thirdweb-dev/sdk@4.0.3
- @thirdweb-dev/wallets@2.0.4
- @thirdweb-dev/auth@4.0.4
## 0.13.3
### Patch Changes
- Updated dependencies [[`526176c4`](https://github.com/thirdweb-dev/js/commit/526176c47108c91d83bcfc5f0ca556274e6462d6), [`d1f8e951`](https://github.com/thirdweb-dev/js/commit/d1f8e951623f1691fdfe3d1e8645970d0a52eb06), [`09120c92`](https://github.com/thirdweb-dev/js/commit/09120c923cca804b9d4f5f779e5a53c97ecc8223), [`6573556d`](https://github.com/thirdweb-dev/js/commit/6573556d0e03efa0d6a157fccb0a1c08dd22d7cd)]:
- @thirdweb-dev/sdk@4.0.2
- @thirdweb-dev/wallets@2.0.3
- @thirdweb-dev/auth@4.0.3
## 0.13.2
### Patch Changes
- Updated dependencies [[`1f3c64d3`](https://github.com/thirdweb-dev/js/commit/1f3c64d3618903b9008cc7b633ea890b508e7800), [`74941603`](https://github.com/thirdweb-dev/js/commit/74941603a96456da46a47147f67c98235ac55022), [`4b98e487`](https://github.com/thirdweb-dev/js/commit/4b98e487d4b47225d7095e5444dc5e7608db48a3), [`693f349d`](https://github.com/thirdweb-dev/js/commit/693f349db2478e1cd0fc82a9ef9882f46832b125), [`dcdb0dcb`](https://github.com/thirdweb-dev/js/commit/dcdb0dcb838168a22c8335738852316dfb6e6fc9), [`0f12d1f9`](https://github.com/thirdweb-dev/js/commit/0f12d1f90320923309f085c372d3a5ed01dd4606), [`b3b9edca`](https://github.com/thirdweb-dev/js/commit/b3b9edca29e7d4053b14270a61caa89c34fecf9e), [`63ad0050`](https://github.com/thirdweb-dev/js/commit/63ad0050f0a24ec15b90933b5664d697618cf2d0)]:
- @thirdweb-dev/sdk@4.0.1
- @thirdweb-dev/wallets@2.0.2
- @thirdweb-dev/auth@4.0.2
## 0.13.1
### Patch Changes
- Updated dependencies [[`e684d05e`](https://github.com/thirdweb-dev/js/commit/e684d05e222458f02c8158eb9385d68c879dd946)]:
- @thirdweb-dev/wallets@2.0.1
- @thirdweb-dev/auth@4.0.1
## 0.13.0
### Minor Changes
- [#1630](https://github.com/thirdweb-dev/js/pull/1630) [`ce4608bf`](https://github.com/thirdweb-dev/js/commit/ce4608bff4783caf164ad6e21b42a827b89badf8) Thanks [@jnsdls](https://github.com/jnsdls)! - **Dropped Support for Solana**:
- We've decided to drop support for Solana across our SDKs.
- Starting with this version of our SDKs all previous solana related functionality will be removed.
- Previous versions of our SDKs will continue to work with Solana. However, we will not be providing any further updates or bug fixes for Solana.
- You can read a detailed explanation of our decision [on our blog](https://blog.thirdweb.com/discontinuing-solana-support/).
- [#1630](https://github.com/thirdweb-dev/js/pull/1630) [`ce4608bf`](https://github.com/thirdweb-dev/js/commit/ce4608bff4783caf164ad6e21b42a827b89badf8) Thanks [@jnsdls](https://github.com/jnsdls)! - **Dropped Support for Node 16**:
- As part of our commitment to maintain up-to-date with the evolving ecosystem and provide the best support for our users, we have made the decision to cease support for Node 16. Starting with this version, our SDKs will no longer be tested against or guaranteed to work with Node.js version 16.
- We encourage users to upgrade to a more recent version of Node.js to continue to benefit from the latest features, improvements, and security updates.
- If you are unable to upgrade to a more recent version of Node.js, you can continue to use the previous version of our SDKs. However, we will not be providing any further updates or bug fixes for Node 16.
- For more information on EOL status of Node 16, see [Node.js Release Cycle](https://nodejs.dev/en/about/releases/).
### Patch Changes
- Updated dependencies [[`ce4608bf`](https://github.com/thirdweb-dev/js/commit/ce4608bff4783caf164ad6e21b42a827b89badf8), [`ce4608bf`](https://github.com/thirdweb-dev/js/commit/ce4608bff4783caf164ad6e21b42a827b89badf8)]:
- @thirdweb-dev/storage@2.0.0
- @thirdweb-dev/wallets@2.0.0
- @thirdweb-dev/auth@4.0.0
- @thirdweb-dev/sdk@4.0.0
## 0.12.10
### Patch Changes
- Updated dependencies [[`ec36b13a`](https://github.com/thirdweb-dev/js/commit/ec36b13a30e0071548df0b7a6eb5299e2e65e4f9), [`6abb8459`](https://github.com/thirdweb-dev/js/commit/6abb8459712e387b6d8b2edf7eb16fb906c05dae), [`a6c36724`](https://github.com/thirdweb-dev/js/commit/a6c36724eb930ee0abbce876bb7847c859c6fb48)]:
- @thirdweb-dev/sdk@3.10.67
- @thirdweb-dev/wallets@1.3.5
- @thirdweb-dev/auth@3.2.48
## 0.12.9
### Patch Changes
-1
View File
@@ -3,7 +3,6 @@ export const CREATE_MESSAGES = {
projectName: "What is your project named?",
contractName: "What will be the name of your new smart contract?",
extensionName: "What will be the name of your new extension?",
chain: "Which blockchain do you want to use?",
framework: "What framework do you want to use?",
language: "What language do you want to use?",
contract: "What type of contract do you want to start from?",
-2
View File
@@ -19,8 +19,6 @@ describe("npx thirdweb create", () => {
await pressKey("enter");
await waitForText(CREATE_MESSAGES.projectName);
await pressKey("enter");
await waitForText(CREATE_MESSAGES.chain);
await pressKey("enter");
await waitForText(CREATE_MESSAGES.framework);
// select CRA
await pressKey("arrowDown");
+2 -3
View File
@@ -1,12 +1,12 @@
{
"name": "thirdweb",
"main": "dist/cli/index.js",
"version": "0.12.9",
"version": "0.13.8",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
"engines": {
"node": ">=16.0.0"
"node": ">=18.0.0"
},
"devDependencies": {
"@gmrchk/cli-testing-library": "^0.1.2",
@@ -50,7 +50,6 @@
"got": "11.8.5",
"inquirer": "^8.2.3",
"js-yaml": "^4.1.0",
"node-fetch": "^3.3.2",
"open": "^8.4.0",
"prompts": "^2.4.2",
"rimraf": "^3.0.2",
-1
View File
@@ -270,7 +270,6 @@ const main = async () => {
"Explicitly tell the CLI to bootstrap the app using pnpm",
)
.option("--framework [name]", "The preferred framework.")
.option("--solana", "Initialize as a Solana project.")
.option("--evm", "Initialize as an Ethereum project.")
.option(
"-t, --template [name]",
+10 -38
View File
@@ -118,9 +118,6 @@ export async function twCreate(
framework = "pwa-vite";
}
if (options.solana) {
chain = "solana";
}
if (options.evm) {
chain = "evm";
}
@@ -251,21 +248,7 @@ export async function twCreate(
if (!options.template) {
if (projectType === "app" && !chain) {
const res = await prompts({
type: "select",
name: "chain",
message: CREATE_MESSAGES.chain,
choices: [
{ title: "EVM", value: "evm" },
{ title: "Solana", value: "solana" },
],
});
if (res.chain === "solana") {
chain = "solana";
} else {
chain = "evm";
}
chain = "evm";
}
if (projectType === "app" && !framework) {
@@ -273,25 +256,15 @@ export async function twCreate(
type: "select",
name: "framework",
message: CREATE_MESSAGES.framework,
choices:
chain === "solana"
? [
{ title: "Next.js", value: "next" },
{ title: "Create React App", value: "cra" },
{ title: "Node.js", value: "node" },
{ title: "Express", value: "express" },
// Solana doesn't support Vite just yet:
// { title: "Vite", value: "vite" },
]
: [
{ title: "Next.js", value: "next" },
{ title: "Create React App", value: "cra" },
{ title: "Vite", value: "vite" },
{ title: "PWA Vite", value: "pwa-vite" },
{ title: "React Native", value: "react-native" },
{ title: "Node.js", value: "node" },
{ title: "Express", value: "express" },
],
choices: [
{ title: "Next.js", value: "next" },
{ title: "Create React App", value: "cra" },
{ title: "Vite", value: "vite" },
{ title: "PWA Vite", value: "pwa-vite" },
{ title: "React Native", value: "react-native" },
{ title: "Node.js", value: "node" },
{ title: "Express", value: "express" },
],
});
if (typeof res.framework === "string") {
@@ -512,7 +485,6 @@ export async function twCreate(
framework,
language,
template,
chain,
});
} else {
await createContractProject({
@@ -24,14 +24,12 @@ export async function createApp({
framework,
language,
template,
chain,
}: {
appPath: string;
packageManager: PackageManager;
framework?: string;
language?: string;
template?: string;
chain?: string;
}): Promise<void> {
let frameworkPath = "";
@@ -47,9 +45,7 @@ export async function createApp({
process.exit(1);
}
} else if (framework) {
frameworkPath = `${framework}-${language || "javascript"}-${
chain === "solana" ? "solana-" : ""
}starter`;
frameworkPath = `${framework}-${language || "javascript"}-starter`;
const found = await hasTemplate(frameworkPath);
if (!found) {
-1
View File
@@ -156,7 +156,6 @@ export const getDependenciesForPython = (
export const getLatestVersion = async (packageName: string): Promise<any> => {
try {
const fetch = (await import("node-fetch")).default;
const url = `https://registry.npmjs.org/${packageName}`;
const response = await fetch(url);
if (!response.ok) {
+18
View File
@@ -1,5 +1,23 @@
# @thirdweb-dev/contracts-js
## 1.3.16
### Patch Changes
- [#1771](https://github.com/thirdweb-dev/js/pull/1771) [`6c30b7ef`](https://github.com/thirdweb-dev/js/commit/6c30b7efc708e1244f3be3e10eac8f3b8b14a8c3) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Updated to latest contracts package
## 1.3.15
### Patch Changes
- [#1756](https://github.com/thirdweb-dev/js/pull/1756) [`956b5645`](https://github.com/thirdweb-dev/js/commit/956b5645e4266cba536abd27ee250dab5aa9a177) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Enable adding smart wallet admins via bundler for new account contracts
## 1.3.14
### Patch Changes
- [#1757](https://github.com/thirdweb-dev/js/pull/1757) [`63ad0050`](https://github.com/thirdweb-dev/js/commit/63ad0050f0a24ec15b90933b5664d697618cf2d0) Thanks [@kumaryash90](https://github.com/kumaryash90)! - Update deployment and tests for MarketplaceV3 latest
## 1.3.13
### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/contracts-js",
"version": "1.3.13",
"version": "1.3.16",
"main": "dist/thirdweb-dev-contracts-js.cjs.js",
"module": "dist/thirdweb-dev-contracts-js.esm.js",
"browser": {
@@ -10,7 +10,7 @@
"license": "Apache-2.0",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/contracts-js",
"dependencies": {
"@thirdweb-dev/contracts": "3.10.1-0"
"@thirdweb-dev/contracts": "3.10.3"
},
"devDependencies": {
"@babel/preset-env": "^7.22.9",
+111
View File
@@ -1,5 +1,116 @@
# @thirdweb-dev/react-core
## 4.0.8
### Patch Changes
- [#1787](https://github.com/thirdweb-dev/js/pull/1787) [`ff996646`](https://github.com/thirdweb-dev/js/commit/ff996646b228d4d095eea04b05004dd26fc7e522) Thanks [@MananTank](https://github.com/MananTank)! - Enable typedoc for packages
- Updated dependencies [[`5ffbcfc3`](https://github.com/thirdweb-dev/js/commit/5ffbcfc302f74167768b196d93a328f979344036), [`42ba15f2`](https://github.com/thirdweb-dev/js/commit/42ba15f2c0e77e23e62650119dfaaa5c0dbe4481), [`d27a3dee`](https://github.com/thirdweb-dev/js/commit/d27a3dee8398d5707d2d1343c428abf8e03f67e3), [`c238fde8`](https://github.com/thirdweb-dev/js/commit/c238fde8777fd14b39837117e2d3fda1dd301029), [`99d7ec06`](https://github.com/thirdweb-dev/js/commit/99d7ec06ec4f31308627edc87d3122c21a884b5a), [`ff996646`](https://github.com/thirdweb-dev/js/commit/ff996646b228d4d095eea04b05004dd26fc7e522), [`d8d48a95`](https://github.com/thirdweb-dev/js/commit/d8d48a9516fc8fdd173fbb91a858fe7ec0725ddd), [`aa9f48d1`](https://github.com/thirdweb-dev/js/commit/aa9f48d1361194fc81146da530c95a3409bd0799), [`fd7a9f09`](https://github.com/thirdweb-dev/js/commit/fd7a9f09989e39b02a93d9dfd01cc7378e6ead53), [`fd7a9f09`](https://github.com/thirdweb-dev/js/commit/fd7a9f09989e39b02a93d9dfd01cc7378e6ead53), [`2307f11a`](https://github.com/thirdweb-dev/js/commit/2307f11ab311aa4a775edd23e777d10f8015ce86), [`54860198`](https://github.com/thirdweb-dev/js/commit/548601981f6dd8706d7a9bd4ca48e4abc7723a1d), [`64138642`](https://github.com/thirdweb-dev/js/commit/64138642e84d8b56b254762eca613d443cca292b), [`6d1eabe9`](https://github.com/thirdweb-dev/js/commit/6d1eabe9f9818ee2a79ce5bf6aa74417dbfd0558), [`c238fde8`](https://github.com/thirdweb-dev/js/commit/c238fde8777fd14b39837117e2d3fda1dd301029)]:
- @thirdweb-dev/wallets@2.0.8
- @thirdweb-dev/sdk@4.0.7
- @thirdweb-dev/auth@4.1.0
- @thirdweb-dev/storage@2.0.1
## 4.0.7
### Patch Changes
- Updated dependencies [[`137f46a5`](https://github.com/thirdweb-dev/js/commit/137f46a5470d2b5f9d7f9eda9b2d839a53ddeb64)]:
- @thirdweb-dev/chains@0.1.55
- @thirdweb-dev/sdk@4.0.6
- @thirdweb-dev/wallets@2.0.7
- @thirdweb-dev/auth@4.0.7
## 4.0.6
### Patch Changes
- Updated dependencies [[`07544252`](https://github.com/thirdweb-dev/js/commit/07544252b49163e1ae84ba2cc76b99597a1c4553)]:
- @thirdweb-dev/sdk@4.0.5
- @thirdweb-dev/wallets@2.0.6
- @thirdweb-dev/auth@4.0.6
## 4.0.5
### Patch Changes
- Updated dependencies []:
- @thirdweb-dev/sdk@4.0.4
- @thirdweb-dev/wallets@2.0.5
- @thirdweb-dev/auth@4.0.5
## 4.0.4
### Patch Changes
- Updated dependencies [[`956b5645`](https://github.com/thirdweb-dev/js/commit/956b5645e4266cba536abd27ee250dab5aa9a177)]:
- @thirdweb-dev/sdk@4.0.3
- @thirdweb-dev/wallets@2.0.4
- @thirdweb-dev/auth@4.0.4
## 4.0.3
### Patch Changes
- [#1758](https://github.com/thirdweb-dev/js/pull/1758) [`08e9cd20`](https://github.com/thirdweb-dev/js/commit/08e9cd206bcc37cf1e84a878dc78bc4f38e5092c) Thanks [@kien-ngo](https://github.com/kien-ngo)! - Add pagination to useOwnedNFTs
- Updated dependencies [[`526176c4`](https://github.com/thirdweb-dev/js/commit/526176c47108c91d83bcfc5f0ca556274e6462d6), [`d1f8e951`](https://github.com/thirdweb-dev/js/commit/d1f8e951623f1691fdfe3d1e8645970d0a52eb06), [`09120c92`](https://github.com/thirdweb-dev/js/commit/09120c923cca804b9d4f5f779e5a53c97ecc8223), [`6573556d`](https://github.com/thirdweb-dev/js/commit/6573556d0e03efa0d6a157fccb0a1c08dd22d7cd)]:
- @thirdweb-dev/sdk@4.0.2
- @thirdweb-dev/wallets@2.0.3
- @thirdweb-dev/auth@4.0.3
## 4.0.2
### Patch Changes
- Updated dependencies [[`1f3c64d3`](https://github.com/thirdweb-dev/js/commit/1f3c64d3618903b9008cc7b633ea890b508e7800), [`74941603`](https://github.com/thirdweb-dev/js/commit/74941603a96456da46a47147f67c98235ac55022), [`4b98e487`](https://github.com/thirdweb-dev/js/commit/4b98e487d4b47225d7095e5444dc5e7608db48a3), [`693f349d`](https://github.com/thirdweb-dev/js/commit/693f349db2478e1cd0fc82a9ef9882f46832b125), [`dcdb0dcb`](https://github.com/thirdweb-dev/js/commit/dcdb0dcb838168a22c8335738852316dfb6e6fc9), [`0f12d1f9`](https://github.com/thirdweb-dev/js/commit/0f12d1f90320923309f085c372d3a5ed01dd4606), [`b3b9edca`](https://github.com/thirdweb-dev/js/commit/b3b9edca29e7d4053b14270a61caa89c34fecf9e), [`63ad0050`](https://github.com/thirdweb-dev/js/commit/63ad0050f0a24ec15b90933b5664d697618cf2d0)]:
- @thirdweb-dev/sdk@4.0.1
- @thirdweb-dev/wallets@2.0.2
- @thirdweb-dev/auth@4.0.2
## 4.0.1
### Patch Changes
- Updated dependencies [[`e684d05e`](https://github.com/thirdweb-dev/js/commit/e684d05e222458f02c8158eb9385d68c879dd946)]:
- @thirdweb-dev/wallets@2.0.1
- @thirdweb-dev/auth@4.0.1
## 4.0.0
### Major Changes
- [#1630](https://github.com/thirdweb-dev/js/pull/1630) [`ce4608bf`](https://github.com/thirdweb-dev/js/commit/ce4608bff4783caf164ad6e21b42a827b89badf8) Thanks [@jnsdls](https://github.com/jnsdls)! - **Dropped Support for Solana**:
- We've decided to drop support for Solana across our SDKs.
- Starting with this version of our SDKs all previous solana related functionality will be removed.
- Previous versions of our SDKs will continue to work with Solana. However, we will not be providing any further updates or bug fixes for Solana.
- You can read a detailed explanation of our decision [on our blog](https://blog.thirdweb.com/discontinuing-solana-support/).
### Patch Changes
- [#1645](https://github.com/thirdweb-dev/js/pull/1645) [`79f91ee2`](https://github.com/thirdweb-dev/js/commit/79f91ee2d96e3a9591d6104c542496bce11f3c71) Thanks [@MananTank](https://github.com/MananTank)! - `WalletConfig.connectUI`` props updated:
- `close` and `open` removed - wallet can no longer "close" the Modal
- `hide` and `show` added to only allow hiding and showing the Modal
- `connected` added - use this instead of `close` when wallet is connected and Modal is safe to close.
- Updated dependencies [[`ce4608bf`](https://github.com/thirdweb-dev/js/commit/ce4608bff4783caf164ad6e21b42a827b89badf8), [`ce4608bf`](https://github.com/thirdweb-dev/js/commit/ce4608bff4783caf164ad6e21b42a827b89badf8)]:
- @thirdweb-dev/storage@2.0.0
- @thirdweb-dev/wallets@2.0.0
- @thirdweb-dev/auth@4.0.0
- @thirdweb-dev/sdk@4.0.0
## 3.16.5
### Patch Changes
- Updated dependencies [[`ec36b13a`](https://github.com/thirdweb-dev/js/commit/ec36b13a30e0071548df0b7a6eb5299e2e65e4f9), [`6abb8459`](https://github.com/thirdweb-dev/js/commit/6abb8459712e387b6d8b2edf7eb16fb906c05dae), [`a6c36724`](https://github.com/thirdweb-dev/js/commit/a6c36724eb930ee0abbce876bb7847c859c6fb48)]:
- @thirdweb-dev/sdk@3.10.67
- @thirdweb-dev/wallets@1.3.5
- @thirdweb-dev/auth@3.2.48
## 3.16.4
### Patch Changes
@@ -1,339 +0,0 @@
/**
* Config file for API Extractor. For more info, please visit: https://api-extractor.com
*/
{
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
/**
* Optionally specifies another JSON config file that this file extends from. This provides a way for
* standard settings to be shared across multiple projects.
*
* If the path starts with "./" or "../", the path is resolved relative to the folder of the file that contains
* the "extends" field. Otherwise, the first path segment is interpreted as an NPM package name, and will be
* resolved using NodeJS require().
*
* SUPPORTED TOKENS: none
* DEFAULT VALUE: ""
*/
// "extends": "./shared/api-extractor-base.json"
// "extends": "my-package/include/api-extractor-base.json"
/**
* Determines the "<projectFolder>" token that can be used with other config file settings. The project folder
* typically contains the tsconfig.json and package.json config files, but the path is user-defined.
*
* The path is resolved relative to the folder of the config file that contains the setting.
*
* The default value for "projectFolder" is the token "<lookup>", which means the folder is determined by traversing
* parent folders, starting from the folder containing api-extractor.json, and stopping at the first folder
* that contains a tsconfig.json file. If a tsconfig.json file cannot be found in this way, then an error
* will be reported.
*
* SUPPORTED TOKENS: <lookup>
* DEFAULT VALUE: "<lookup>"
*/
// "projectFolder": "..",
/**
* (REQUIRED) Specifies the .d.ts file to be used as the starting point for analysis. API Extractor
* analyzes the symbols exported by this module.
*
* The file extension must be ".d.ts" and not ".ts".
*
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
* prepend a folder token such as "<projectFolder>".
*
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
*/
"mainEntryPointFilePath": "<projectFolder>/solana/dist/thirdweb-dev-react-core-solana.cjs.d.ts",
/**
* A list of NPM package names whose exports should be treated as part of this package.
*
* For example, suppose that Webpack is used to generate a distributed bundle for the project "library1",
* and another NPM package "library2" is embedded in this bundle. Some types from library2 may become part
* of the exported API for library1, but by default API Extractor would generate a .d.ts rollup that explicitly
* imports library2. To avoid this, we can specify:
*
* "bundledPackages": [ "library2" ],
*
* This would direct API Extractor to embed those types directly in the .d.ts rollup, as if they had been
* local files for library1.
*/
"bundledPackages": [],
/**
* Determines how the TypeScript compiler engine will be invoked by API Extractor.
*/
"compiler": {
/**
* Specifies the path to the tsconfig.json file to be used by API Extractor when analyzing the project.
*
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
* prepend a folder token such as "<projectFolder>".
*
* Note: This setting will be ignored if "overrideTsconfig" is used.
*
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
* DEFAULT VALUE: "<projectFolder>/tsconfig.json"
*/
// "tsconfigFilePath": "<projectFolder>/tsconfig.json",
/**
* Provides a compiler configuration that will be used instead of reading the tsconfig.json file from disk.
* The object must conform to the TypeScript tsconfig schema:
*
* http://json.schemastore.org/tsconfig
*
* If omitted, then the tsconfig.json file will be read from the "projectFolder".
*
* DEFAULT VALUE: no overrideTsconfig section
*/
"overrideTsconfig": {
"skipLibCheck": true
}
/**
* This option causes the compiler to be invoked with the --skipLibCheck option. This option is not recommended
* and may cause API Extractor to produce incomplete or incorrect declarations, but it may be required when
* dependencies contain declarations that are incompatible with the TypeScript engine that API Extractor uses
* for its analysis. Where possible, the underlying issue should be fixed rather than relying on skipLibCheck.
*
* DEFAULT VALUE: false
*/
// "skipLibCheck": true,
},
/**
* Configures how the API report file (*.api.md) will be generated.
*/
"apiReport": {
/**
* (REQUIRED) Whether to generate an API report.
*/
"enabled": true
/**
* The filename for the API report files. It will be combined with "reportFolder" or "reportTempFolder" to produce
* a full file path.
*
* The file extension should be ".api.md", and the string should not contain a path separator such as "\" or "/".
*
* SUPPORTED TOKENS: <packageName>, <unscopedPackageName>
* DEFAULT VALUE: "<unscopedPackageName>.api.md"
*/
// "reportFileName": "<unscopedPackageName>.api.md",
/**
* Specifies the folder where the API report file is written. The file name portion is determined by
* the "reportFileName" setting.
*
* The API report file is normally tracked by Git. Changes to it can be used to trigger a branch policy,
* e.g. for an API review.
*
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
* prepend a folder token such as "<projectFolder>".
*
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
* DEFAULT VALUE: "<projectFolder>/etc/"
*/
// "reportFolder": "<projectFolder>/etc/",
/**
* Specifies the folder where the temporary report file is written. The file name portion is determined by
* the "reportFileName" setting.
*
* After the temporary file is written to disk, it is compared with the file in the "reportFolder".
* If they are different, a production build will fail.
*
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
* prepend a folder token such as "<projectFolder>".
*
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
* DEFAULT VALUE: "<projectFolder>/temp/"
*/
// "reportTempFolder": "<projectFolder>/temp/"
},
/**
* Configures how the doc model file (*.api.json) will be generated.
*/
"docModel": {
/**
* (REQUIRED) Whether to generate a doc model file.
*/
"enabled": true
/**
* The output path for the doc model file. The file extension should be ".api.json".
*
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
* prepend a folder token such as "<projectFolder>".
*
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
* DEFAULT VALUE: "<projectFolder>/temp/<unscopedPackageName>.api.json"
*/
// "apiJsonFilePath": "<projectFolder>/temp/<unscopedPackageName>.api.json"
},
/**
* Configures how the .d.ts rollup file will be generated.
*/
"dtsRollup": {
/**
* (REQUIRED) Whether to generate the .d.ts rollup file.
*/
"enabled": false,
/**
* Specifies the output path for a .d.ts rollup file to be generated without any trimming.
* This file will include all declarations that are exported by the main entry point.
*
* If the path is an empty string, then this file will not be written.
*
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
* prepend a folder token such as "<projectFolder>".
*
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
* DEFAULT VALUE: "<projectFolder>/dist/<unscopedPackageName>.d.ts"
*/
"untrimmedFilePath": "<projectFolder>/lib/<unscopedPackageName>.d.ts"
/**
* Specifies the output path for a .d.ts rollup file to be generated with trimming for a "beta" release.
* This file will include only declarations that are marked as "@public" or "@beta".
*
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
* prepend a folder token such as "<projectFolder>".
*
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
* DEFAULT VALUE: ""
*/
// "betaTrimmedFilePath": "<projectFolder>/dist/<unscopedPackageName>-beta.d.ts",
/**
* Specifies the output path for a .d.ts rollup file to be generated with trimming for a "public" release.
* This file will include only declarations that are marked as "@public".
*
* If the path is an empty string, then this file will not be written.
*
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
* prepend a folder token such as "<projectFolder>".
*
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
* DEFAULT VALUE: ""
*/
// "publicTrimmedFilePath": "<projectFolder>/dist/<unscopedPackageName>-public.d.ts",
/**
* When a declaration is trimmed, by default it will be replaced by a code comment such as
* "Excluded from this release type: exampleMember". Set "omitTrimmingComments" to true to remove the
* declaration completely.
*
* DEFAULT VALUE: false
*/
// "omitTrimmingComments": true
},
/**
* Configures how the tsdoc-metadata.json file will be generated.
*/
"tsdocMetadata": {
/**
* Whether to generate the tsdoc-metadata.json file.
*
* DEFAULT VALUE: true
*/
// "enabled": true,
/**
* Specifies where the TSDoc metadata file should be written.
*
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
* prepend a folder token such as "<projectFolder>".
*
* The default value is "<lookup>", which causes the path to be automatically inferred from the "tsdocMetadata",
* "typings" or "main" fields of the project's package.json. If none of these fields are set, the lookup
* falls back to "tsdoc-metadata.json" in the package folder.
*
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
* DEFAULT VALUE: "<lookup>"
*/
// "tsdocMetadataFilePath": "<projectFolder>/dist/tsdoc-metadata.json"
},
/**
* Specifies what type of newlines API Extractor should use when writing output files. By default, the output files
* will be written with Windows-style newlines. To use POSIX-style newlines, specify "lf" instead.
* To use the OS's default newline kind, specify "os".
*
* DEFAULT VALUE: "crlf"
*/
// "newlineKind": "crlf",
/**
* Configures how API Extractor reports error and warning messages produced during analysis.
*
* There are three sources of messages: compiler messages, API Extractor messages, and TSDoc messages.
*/
"messages": {
/**
* Configures handling of diagnostic messages reported by the TypeScript compiler engine while analyzing
* the input .d.ts files.
*
* TypeScript message identifiers start with "TS" followed by an integer. For example: "TS2551"
*
* DEFAULT VALUE: A single "default" entry with logLevel=warning.
*/
"compilerMessageReporting": {
/**
* Configures the default routing for messages that don't match an explicit rule in this table.
*/
"default": {
/**
* Specifies whether the message should be written to the the tool's output log. Note that
* the "addToApiReportFile" property may supersede this option.
*
* Possible values: "error", "warning", "none"
*
* Errors cause the build to fail and return a nonzero exit code. Warnings cause a production build fail
* and return a nonzero exit code. For a non-production build (e.g. when "api-extractor run" includes
* the "--local" option), the warning is displayed but the build will not fail.
*
* DEFAULT VALUE: "warning"
*/
"logLevel": "warning"
/**
* When addToApiReportFile is true: If API Extractor is configured to write an API report file (.api.md),
* then the message will be written inside that file; otherwise, the message is instead logged according to
* the "logLevel" option.
*
* DEFAULT VALUE: false
*/
// "addToApiReportFile": false
}
// "TS2551": {
// "logLevel": "warning",
// "addToApiReportFile": true
// },
//
// . . .
},
/**
* Configures handling of messages reported by API Extractor during its analysis.
*
* API Extractor message identifiers start with "ae-". For example: "ae-extra-release-tag"
*
* DEFAULT VALUE: See api-extractor-defaults.json for the complete table of extractorMessageReporting mappings
*/
"extractorMessageReporting": {
"default": {
"logLevel": "warning"
// "addToApiReportFile": false
}
// "ae-extra-release-tag": {
// "logLevel": "warning",
// "addToApiReportFile": true
// },
//
// . . .
},
/**
* Configures handling of messages reported by the TSDoc parser when analyzing code comments.
*
* TSDoc message identifiers start with "tsdoc-". For example: "tsdoc-link-tag-unescaped-text"
*
* DEFAULT VALUE: A single "default" entry with logLevel=warning.
*/
"tsdocMessageReporting": {
"default": {
"logLevel": "warning"
// "addToApiReportFile": false
}
// "tsdoc-link-tag-unescaped-text": {
// "logLevel": "warning",
// "addToApiReportFile": true
// },
//
// . . .
}
}
}
+5 -27
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react-core",
"version": "3.16.4",
"version": "4.0.8",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-core",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -25,24 +25,15 @@
},
"default": "./evm/dist/thirdweb-dev-react-core-evm.cjs.js"
},
"./solana": {
"module": {
"browser": "./solana/dist/thirdweb-dev-react-core-solana.browser.esm.js",
"default": "./solana/dist/thirdweb-dev-react-core-solana.esm.js"
},
"default": "./solana/dist/thirdweb-dev-react-core-solana.cjs.js"
},
"./package.json": "./package.json"
},
"files": [
"dist/",
"evm/",
"solana/"
"evm/"
],
"preconstruct": {
"entrypoints": [
"index.ts",
"solana/index.ts",
"evm/index.ts"
],
"exports": {
@@ -57,10 +48,9 @@
"lint": "eslint src/",
"fix": "eslint src/ --fix",
"clean": "rm -rf dist/",
"generate-docs": "pnpm generate-docs:evm && pnpm generate-docs:solana && pnpm generate-snippets",
"generate-docs": "pnpm generate-docs:evm && pnpm generate-snippets",
"generate-docs:evm": "api-extractor run --local --config ./config/api-extractor-evm.json && api-documenter markdown -i ./temp -o ./docs/evm && rm -rf ./temp-evm && mv ./temp ./temp-evm",
"generate-docs:solana": "api-extractor run --local --config ./config/api-extractor-solana.json && api-documenter markdown -i ./temp -o ./docs/solana && rm -rf ./temp-solana && mv ./temp ./temp-solana",
"generate-snippets": "node ./scripts/generate-snippets-evm.mjs && node ./scripts/generate-snippets-solana.mjs && node ./scripts/generate-feature-snippets-evm.mjs",
"generate-snippets": "node ./scripts/generate-snippets-evm.mjs && node ./scripts/generate-feature-snippets-evm.mjs",
"build": "tsc && preconstruct build",
"push": "yalc push"
},
@@ -75,8 +65,6 @@
"@microsoft/api-extractor": "^7.36.3",
"@microsoft/tsdoc": "^0.14.1",
"@preconstruct/cli": "2.7.0",
"@solana/wallet-adapter-react": "^0.15.19",
"@solana/web3.js": "^1.62.0",
"@thirdweb-dev/auth": "workspace:*",
"@thirdweb-dev/tsconfig": "workspace:*",
"@types/js-cookie": "^3.0.3",
@@ -87,7 +75,7 @@
"eslint": "^8.45.0",
"eslint-config-prettier": "^8.9.0",
"eslint-config-thirdweb": "workspace:*",
"eslint-plugin-better-tree-shaking": "0.0.3",
"eslint-plugin-better-tree-shaking": "0.0.4",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-inclusive-language": "^2.2.0",
"eslint-plugin-prettier": "^5.0.0",
@@ -109,17 +97,7 @@
"tiny-invariant": "^1.2.0"
},
"peerDependencies": {
"@solana/wallet-adapter-react": "^0.15.19",
"@solana/web3.js": "^1.62.0",
"ethers": ">=5.5.1",
"react": ">=18.0.0"
},
"peerDependenciesMeta": {
"@solana/web3.js": {
"optional": true
},
"@solana/wallet-adapter-react": {
"optional": true
}
}
}
@@ -1,135 +0,0 @@
import { Formatter } from "./generate-snippets-evm.mjs";
import { TSDocParser } from "@microsoft/tsdoc";
import fs from "fs";
const NFT_HOOKS = ["useMintNFT", "useNFT", "useNFTs", "useTransferNFT"];
const DROP_HOOKS = [
"useClaimedSupply",
"useClaimNFT",
"useLazyMintNFT",
"useUnclaimedSupply",
];
const TOKEN_HOOKS = [
"useMintToken",
"useTokenBalance",
"useTokenSupply",
"useTransferToken",
];
const HOOKS_CONFIG = {
useNFTCollection: [...NFT_HOOKS],
useNFTDrop: [...NFT_HOOKS, ...DROP_HOOKS],
useToken: [...TOKEN_HOOKS],
useProgram: [],
};
const tsdocParser = new TSDocParser();
const json = JSON.parse(
fs.readFileSync(`${process.cwd()}/temp-solana/react-core.api.json`, "utf8"),
);
function languageNameToKey(languageName) {
switch (languageName) {
case "js":
case "jsx":
return "javascript";
case "ts":
case "tsx":
return "typescript";
default:
return languageName;
}
}
function parseExampleTag(docComment) {
const exampleBlocks = docComment._customBlocks.filter(
(b) => b._blockTag._tagName === "@example",
);
const examplesString = Formatter.renderDocNodes(exampleBlocks);
const regex = /```([a-zA-Z]*)\n([\S\s]*?)\n```/g;
let matches;
const examples = {};
while ((matches = regex.exec(examplesString)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (matches.index === regex.lastIndex) {
regex.lastIndex++;
}
const re = /\n( *)\/\/ For example((.|\n)*)\.\.\.\n/g;
const example = matches[2].replace(re, "");
examples[languageNameToKey(matches[1])] = example;
}
return examples;
}
const baseDocUrl = "https://portal.thirdweb.com/react/solana/react.";
const extractReferenceLink = (m, kind, contractName) => {
if (kind === "Property") {
return m.excerptTokens
.filter((e) => e.kind === "Reference")
.map((e) => `${baseDocUrl}${e.text.toLowerCase()}`)[0];
}
if (kind === "Method") {
return `${baseDocUrl}${contractName}.${m.name}`;
}
return `${baseDocUrl}${m.name}`;
};
const moduleMap = Object.keys(HOOKS_CONFIG).reduce((acc, hookName) => {
let summary = "";
let examples = {};
let reference = "";
const doc = json.members[0].members.find(
(m) =>
m.kind === "Function" && Object.keys(HOOKS_CONFIG).includes(hookName),
);
if (doc) {
const parserContext = tsdocParser.parseString(doc);
const docComment = parserContext.docComment;
summary = Formatter.renderDocNode(docComment.summarySection);
examples = parseExampleTag(docComment);
reference = extractReferenceLink(doc);
}
const contractSubhooks = json.members[0].members.filter(
(f) => f.kind === "Function" && HOOKS_CONFIG[hookName].includes(f.name),
);
const subhooks = contractSubhooks.map((subhookContent) => {
const subhookContext = tsdocParser.parseString(subhookContent.docComment);
const subhookComment = subhookContext.docComment;
const subhookExamples = parseExampleTag(subhookComment);
return {
name: subhookContent.name,
example: subhookExamples?.javascript || "",
reference: `${baseDocUrl}${subhookContent.name.toLowerCase()}`,
};
});
acc[hookName] = {
name: hookName,
summary,
examples,
subhooks,
reference,
};
return acc;
}, {});
fs.writeFileSync(
`${process.cwd()}/docs/solana/snippets.json`,
JSON.stringify(moduleMap, null, 2),
);
-7
View File
@@ -1,7 +0,0 @@
{
"main": "dist/thirdweb-dev-react-core-solana.cjs.js",
"module": "dist/thirdweb-dev-react-core-solana.esm.js",
"browser": {
"./dist/thirdweb-dev-react-core-solana.esm.js": "./dist/thirdweb-dev-react-core-solana.browser.esm.js"
}
}
@@ -1,2 +1,3 @@
/** @internal */
// eslint-disable-next-line turbo/no-undeclared-env-vars, better-tree-shaking/no-top-level-side-effects
export const __DEV__ = process.env.NODE_ENV !== "production";
@@ -8,6 +8,7 @@ import type {
LocalWallet,
MagicLink,
MetaMaskWallet,
OKXWallet,
PaperWallet,
PhantomWallet,
RainbowWallet,
@@ -37,6 +38,7 @@ type WalletIdToWalletTypeMap = {
walletConnect: WalletConnect;
phantom: PhantomWallet;
walletConnectV1: WalletConnect;
okx: OKXWallet;
};
/**
@@ -1,12 +1,6 @@
import { RequiredParam } from "./required-param";
import type { QueryKey } from "@tanstack/react-query";
import type { ValidContractInstance } from "@thirdweb-dev/sdk";
import type {
Network,
NFTCollection,
NFTDrop,
Token,
} from "@thirdweb-dev/sdk/solana";
// we prefix all our query keys with this to avoid possible collisions with user-defined queries that share the same query client
const TW_QUERY_KEY_PREFIX = "__tw__";
@@ -53,28 +47,3 @@ export function createEVMContractQueryKey<TKey extends QueryKey>(
chainId,
);
}
// SOL
export function createSOLQueryKey<TKey extends QueryKey>(key: TKey) {
return ensureTWPrefix(["sol", ...key] as const);
}
export function createSOLQueryKeyWithNetwork<TKey extends QueryKey>(
key: TKey,
network: RequiredParam<Network>,
) {
return createSOLQueryKey([network, ...key] as const);
}
export function createSOLProgramQueryKey<TKey extends QueryKey>(
program: RequiredParam<NFTCollection | NFTDrop | Token>,
key: TKey = [] as unknown as TKey,
) {
const network = program?.network;
const address = program?.publicKey.toBase58();
return createSOLQueryKeyWithNetwork(
["program", address, ...key] as const,
network || null,
);
}
+17 -7
View File
@@ -43,18 +43,28 @@ export type WalletConfig<I extends WalletInstance = WalletInstance> = {
/**
* If true, this wallet will be tagged as "recommended" in ConnectWallet Modal and will be shown at the top of the list
* @default false
*/
recommended?: boolean;
/**
* If the wallet can sign transactions without user interaction, set this to true.
* @default false
*/
isHeadless?: boolean;
};
export type ConnectUIProps<I extends WalletInstance = WalletInstance> = {
/**
* close the connect wallet modal
* @param reset reset Connect Wallet Modal to initial state, so that if it's opened again, it will start from the wallet-selection screen
*
* default: `true`
* temporarily hide the ConnectModal
* This is useful when you want to open another modal and do not want to show the ConnectModal in the background
*/
close: (reset?: boolean) => void;
hide: () => void;
/**
* when the wallet is connected, call this function to indicate that the wallet is connected and it is safe to close the Modal
*/
connected: () => void;
/**
* indicates whether the connect wallet modal is open or not
@@ -62,9 +72,9 @@ export type ConnectUIProps<I extends WalletInstance = WalletInstance> = {
isOpen: boolean;
/**
* open the connect wallet modal
* show the hidden connect wallet modal again
*/
open: () => void;
show: () => void;
/**
* go back to the wallet selector screen in connect wallet modal
@@ -225,11 +225,12 @@ export function useTotalCirculatingSupply(
*
* @example
* ```javascript
* const { data: ownedNFTs, isLoading, error } = useOwnedNFTs(contract, "{{wallet_address}}");
* const { data: ownedNFTs, isLoading, error } = useOwnedNFTs(contract, "{{wallet_address}}", { start: 0, count: 100 });
* ```
*
* @param contract - an instance of a {@link NFTContract}
* @param ownerWalletAddress - the wallet address to get owned tokens for
* @param queryParams - query params to pass to the query for pagination
* @returns a response object that includes the list of owned tokens
* @beta
* @twfeature ERC721Enumerable | ERC1155Enumerable | ERC721Supply
@@ -238,6 +239,7 @@ export function useTotalCirculatingSupply(
export function useOwnedNFTs<TContract extends NFTContract>(
contract: RequiredParam<TContract>,
ownerWalletAddress: RequiredParam<WalletAddress>,
queryParams?: QueryAllParams,
) {
const contractAddress = contract?.getAddress();
const { erc721, erc1155 } = getErcs(contract);
@@ -248,10 +250,10 @@ export function useOwnedNFTs<TContract extends NFTContract>(
requiredParamInvariant(contract, "No Contract instance provided");
invariant(ownerWalletAddress, "No wallet address provided");
if (erc721) {
return await erc721.getOwned(ownerWalletAddress);
return await erc721.getOwned(ownerWalletAddress, queryParams);
}
if (erc1155) {
return await erc1155.getOwned(ownerWalletAddress);
return await erc1155.getOwned(ownerWalletAddress, queryParams);
}
invariant(false, "Unknown NFT type");
},
@@ -1,53 +0,0 @@
import { PropsWithChildren, createContext, useContext, useMemo } from "react";
/**
* The configuration to use the react SDK with an [auth](https://portal.thirdweb.com/auth) server.
*
* @beta
*/
export interface ThirdwebAuthConfig {
/**
* The backend URL of the authentication endoints. For example, if your endpoints are
* at `/api/auth/login`, `/api/auth/logout`, etc. then this should be set to `/api/auth`.
*/
authUrl?: string;
/**
* The frontend domain used to generate the login payload.
* This domain should match the domain used on your auth backend.
*/
domain: string;
}
interface ThirdwebAuthContext extends ThirdwebAuthConfig {}
const ThirdwebAuthContext = /* @__PURE__ */ createContext<
ThirdwebAuthContext | undefined
>(undefined);
export const ThirdwebAuthProvider: React.FC<
PropsWithChildren<{ value?: ThirdwebAuthConfig }>
> = ({ value, children }) => {
// Remove trailing slash from URL if present
const authContext = useMemo(() => {
if (!value) {
return undefined;
}
const context: ThirdwebAuthContext = {
...value,
authUrl: value.authUrl?.replace(/\/$/, ""),
};
return context;
}, [value]);
return (
<ThirdwebAuthContext.Provider value={authContext}>
{children}
</ThirdwebAuthContext.Provider>
);
};
export function useThirdwebAuthContext() {
return useContext(ThirdwebAuthContext);
}
@@ -1,7 +0,0 @@
export { useLogin } from "./useLogin";
export type { LoginConfig } from "./useLogin";
export { useLogout } from "./useLogout";
export type { UserWithData } from "./useUser";
export { useUser } from "./useUser";
@@ -1,204 +0,0 @@
import { ensureTWPrefix } from "../../../core/query-utils/query-key";
import { useThirdwebAuthContext } from "../../contexts/thirdweb-auth";
import { useSDK } from "../../providers/base";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import type {
LoginOptions,
LoginPayload,
LoginPayloadData,
} from "@thirdweb-dev/auth";
import { GenericAuthWallet } from "@thirdweb-dev/wallets";
import { SignerWallet } from "@thirdweb-dev/wallets/solana/wallets/signer";
import invariant from "tiny-invariant";
export interface LoginConfig {
/**
* The URL to redirect to on login.
*/
redirectTo?: string;
/**
* Function to run on error.
*/
onError?: (error: string) => void;
}
/**
* Hook to securely login to a backend with the connected wallet. The backend
* authentication URL must be configured on the ThirdwebProvider.
*
* @param config - Configuration for the login.
* @returns - A function to invoke to login with the connected wallet.
*
* @beta
*/
export function useLogin() {
const queryClient = useQueryClient();
const authConfig = useThirdwebAuthContext();
const signer = useSDK()?.wallet.getSigner();
const login = useMutation({
mutationFn: async () => {
invariant(
authConfig,
"Please specify an authConfig in the ThirdwebProvider",
);
invariant(signer, "You need a connected wallet to login.");
invariant(
authConfig.authUrl,
"Please specify an authUrl in the authConfig.",
);
const wallet = new SignerWallet(signer);
const address = await wallet.getAddress();
let res = await fetch(`${authConfig.authUrl}/payload`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ address }),
});
if (!res.ok) {
throw new Error(`Failed to get payload with status code ${res.status}`);
}
let payloadData: LoginPayloadData;
try {
({ payload: payloadData } = await res.json());
} catch {
throw new Error(`Failed to get payload`);
}
const payload = await doLoginWithPayload(wallet, payloadData);
res = await fetch(`${authConfig.authUrl}/login`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ payload }),
credentials: "include",
});
if (!res.ok) {
const data = await res.json();
if (data.error) {
throw new Error(data.error);
}
throw new Error(`Login request failed with status code ${res.status}`);
}
queryClient.invalidateQueries(ensureTWPrefix(["user"]));
},
});
return {
login: () => login.mutateAsync(),
isLoading: login.isLoading,
};
}
// login function extracted directly from auth
const isBrowser = () => typeof window !== "undefined";
export async function doLoginWithPayload(
wallet: GenericAuthWallet,
payload: LoginPayloadData,
): Promise<LoginPayload> {
const message = generateMessage(payload);
const signature = await wallet.signMessage(message);
return {
payload,
signature,
};
}
export async function doLogin(
wallet: GenericAuthWallet,
options?: LoginOptions,
): Promise<LoginPayload> {
let chainId: string | undefined = options?.chainId;
if (!chainId && wallet.getChainId) {
try {
chainId = (await wallet.getChainId()).toString();
} catch {
// ignore error
}
}
invariant(options?.domain, "Please specify a domain to login with.");
// generate a pseudo-random nonce if none is provided
const nonce =
options?.nonce || Math.floor(Math.random() * 1000000000).toString();
const payloadData: LoginPayloadData = {
type: wallet.type,
domain: options.domain,
address: await wallet.getAddress(),
statement:
options?.statement ||
"Please ensure that the domain above matches the URL of the current website.",
version: options?.version || "1",
uri: options?.uri || (isBrowser() ? window.location.origin : undefined),
chain_id: chainId,
nonce: options?.nonce || nonce,
issued_at: new Date().toISOString(),
expiration_time: new Date(
options?.expirationTime || Date.now() + 1000 * 60 * 5,
).toISOString(),
invalid_before: new Date(
options?.invalidBefore || Date.now(),
).toISOString(),
resources: options?.resources,
};
return doLoginWithPayload(wallet, payloadData);
}
// generate straight from auth
function generateMessage(payload: LoginPayloadData): string {
const typeField = payload.type === "evm" ? "Ethereum" : "Solana";
const header = `${payload.domain} wants you to sign in with your ${typeField} account:`;
let prefix = [header, payload.address].join("\n");
prefix = [prefix, payload.statement].join("\n\n");
if (payload.statement) {
prefix += "\n";
}
const suffixArray = [];
if (payload.uri) {
const uriField = `URI: ${payload.uri}`;
suffixArray.push(uriField);
}
const versionField = `Version: ${payload.version}`;
suffixArray.push(versionField);
if (payload.chain_id) {
const chainField = `Chain ID: ` + payload.chain_id || "1";
suffixArray.push(chainField);
}
const nonceField = `Nonce: ${payload.nonce}`;
suffixArray.push(nonceField);
const issuedAtField = `Issued At: ${payload.issued_at}`;
suffixArray.push(issuedAtField);
const expiryField = `Expiration Time: ${payload.expiration_time}`;
suffixArray.push(expiryField);
if (payload.invalid_before) {
const invalidBeforeField = `Not Before: ${payload.invalid_before}`;
suffixArray.push(invalidBeforeField);
}
if (payload.resources) {
suffixArray.push(
[`Resources:`, ...payload.resources.map((x) => `- ${x}`)].join("\n"),
);
}
const suffix = suffixArray.join("\n");
return [prefix, suffix].join("\n");
}
@@ -1,38 +0,0 @@
import { ensureTWPrefix } from "../../../core/query-utils/query-key";
import { useThirdwebAuthContext } from "../../contexts/thirdweb-auth";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import invariant from "tiny-invariant";
/**
* Hook to logout the connected wallet from the backend.
* The backend logout URL must be configured on the ThirdwebProvider.
*
* @returns - A function to invoke to logout.
*
* @beta
*/
export function useLogout() {
const queryClient = useQueryClient();
const authConfig = useThirdwebAuthContext();
const logout = useMutation({
mutationFn: async () => {
invariant(
authConfig,
"Please specify an authConfig in the ThirdwebProvider",
);
invariant(
authConfig.authUrl,
"Please specify an authUrl in the authConfig.",
);
await fetch(`${authConfig.authUrl}/logout`, {
method: "POST",
});
queryClient.invalidateQueries(ensureTWPrefix(["user"]));
},
});
return { logout: logout.mutateAsync, isLoading: logout.isLoading };
}
@@ -1,52 +0,0 @@
import { ensureTWPrefix } from "../../../core/query-utils/query-key";
import { useThirdwebAuthContext } from "../../contexts/thirdweb-auth";
import { useQuery } from "@tanstack/react-query";
import type { Json, User } from "@thirdweb-dev/auth";
import invariant from "tiny-invariant";
export interface UserWithData<
TData extends Json = Json,
TContext extends Json = Json,
> extends User<TContext> {
data?: TData;
}
/**
* Hook to get the currently logged in user.
*
* @returns - The currently logged in user or null if not logged in, as well as a loading state.
*
* @beta
*/
export function useUser<
TData extends Json = Json,
TContext extends Json = Json,
>() {
const authConfig = useThirdwebAuthContext();
const { data: user, isLoading } = useQuery(
ensureTWPrefix(["user"]),
async () => {
invariant(
authConfig,
"Please specify an authConfig in the ThirdwebProvider",
);
invariant(
authConfig.authUrl,
"Please specify an authUrl in the authConfig.",
);
// We include credentials, so we can getUser even if API is on different URL
const res = await fetch(`${authConfig.authUrl}/user`, {
credentials: "include",
});
return (await res.json()) as UserWithData<TData, TContext>;
},
{
enabled: !!authConfig,
},
);
return { user, isLoggedIn: !!user, isLoading };
}
@@ -1,45 +0,0 @@
import { createSOLProgramQueryKey } from "../../../../core/query-utils/query-key";
import { RequiredParam } from "../../../../core/query-utils/required-param";
import { MintNFTParams } from "../../../types";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import type { NFTCollection } from "@thirdweb-dev/sdk/solana";
import invariant from "tiny-invariant";
/**
* Mint NFTs on your NFT program
* @param program - The NFT program to mint NFTs to
*
* @example
* ```jsx
* import { useProgram, useMintNFT } from "@thirdweb-dev/react/solana";
*
* export default function Component() {
* const { program } = useProgram("{{program_address}}");
* const { mutateAsync: mintNFT, isLoading, error } = useMintNFT(program);
*
* return (
* <button onClick={() => mintNFT({ metadata: { name: "First NFT" } })}>
* Mint
* </button>
* )
* }
* ```
*
* @public
*/
export function useMintNFT(program: RequiredParam<NFTCollection>) {
const queryClient = useQueryClient();
return useMutation(
async (data: MintNFTParams) => {
invariant(program, "program is required");
if (!data.to) {
return await program.mint(data.metadata);
}
return await program.mintTo(data.to, data.metadata);
},
{
onSettled: () =>
queryClient.invalidateQueries(createSOLProgramQueryKey(program)),
},
);
}
@@ -1,51 +0,0 @@
import { createSOLProgramQueryKey } from "../../../../core/query-utils/query-key";
import {
requiredParamInvariant,
RequiredParam,
} from "../../../../core/query-utils/required-param";
import { MintNFTSupplyParams } from "../../../types";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import type { NFTCollection } from "@thirdweb-dev/sdk/solana";
/**
* Mint additional supply for an NFT on your NFT program
* @param program - The NFT program to mint additional NFTs to
*
* @example
* ```jsx
* import { useProgram, useMintNFTSupply } from "@thirdweb-dev/react/solana";
*
* export default function Component() {
* const { program } = useProgram("{{program_address}}");
* const { mutateAsync: mintSupply, isLoading, error } = useMintNFTSupply(program);
*
* return (
* <button onClick={() => mintSupply({ nftAddress: "111...", amount: 10 })}>
* Mint Additional Supply
* </button>
* )
* }
* ```
*
* @public
*/
export function useMintNFTSupply(program: RequiredParam<NFTCollection>) {
const queryClient = useQueryClient();
return useMutation(
async (data: MintNFTSupplyParams) => {
requiredParamInvariant(program, "program is required");
if (!data.to) {
return await program.mintAdditionalSupply(data.nftAddress, data.amount);
}
return await program.mintAdditionalSupplyTo(
data.to,
data.nftAddress,
data.amount,
);
},
{
onSettled: () =>
queryClient.invalidateQueries(createSOLProgramQueryKey(program)),
},
);
}
@@ -1,42 +0,0 @@
import { createSOLProgramQueryKey } from "../../../../core/query-utils/query-key";
import { RequiredParam } from "../../../../core/query-utils/required-param";
import { useQuery } from "@tanstack/react-query";
import type { NFTDrop } from "@thirdweb-dev/sdk/solana";
import invariant from "tiny-invariant";
export function claimConditionsQuery(program: RequiredParam<NFTDrop>) {
return {
queryKey: createSOLProgramQueryKey(program, ["claimConditions"] as const),
queryFn: async () => {
invariant(program, "program is required");
return await program.claimConditions.get();
},
enabled: !!program,
};
}
/**
* Get the current claim conditions on an NFT Drop
* @param program - The NFT Drop program to get the claim conditions for
*
* @example
* ```jsx
* import { useProgram, useClaimConditions } from "@thirdweb-dev/react/solana";
*
* export default function Component() {
* const { program } = useProgram("{{program_address}}");
* const { data: claimConditions, isLoading } = useClaimConditions(program);
*
* return (
* <p>{claimConditions?.price.displayValue}</p>
* )
* }
* ```
*
* @public
*/
export function useClaimConditions(program: RequiredParam<NFTDrop>) {
return useQuery(claimConditionsQuery(program));
}
@@ -1,45 +0,0 @@
import { createSOLProgramQueryKey } from "../../../../core/query-utils/query-key";
import { RequiredParam } from "../../../../core/query-utils/required-param";
import { ClaimNFTParams } from "../../../types";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import type { NFTDrop } from "@thirdweb-dev/sdk/solana";
import invariant from "tiny-invariant";
/**
* Claim NFTs from an NFT Drop program
* @param program - The NFT Drop program instance to claim from
*
* @example
* ```jsx
* import { useProgram, useClaimNFT } from "@thirdweb-dev/react/solana";
*
* export default function Component() {
* const { program } = useProgram("{{program_address}}");
* const { mutateAsync: claim, isLoading, error } = useClaimNFT(program);
*
* return (
* <button onClick={() => claim({amount: 1})}>
* Claim
* </button>
* )
* }
* ```
*
* @public
*/
export function useClaimNFT(program: RequiredParam<NFTDrop>) {
const queryClient = useQueryClient();
return useMutation(
async (data: ClaimNFTParams) => {
invariant(program, "program is required");
if (!data.to) {
return await program.claim(data.amount);
}
return await program.claimTo(data.to, data.amount);
},
{
onSettled: () =>
queryClient.invalidateQueries(createSOLProgramQueryKey(program)),
},
);
}
@@ -1,46 +0,0 @@
import { createSOLProgramQueryKey } from "../../../../core/query-utils/query-key";
import {
requiredParamInvariant,
RequiredParam,
} from "../../../../core/query-utils/required-param";
import { useQuery } from "@tanstack/react-query";
import type { NFTDrop } from "@thirdweb-dev/sdk/solana";
export function dropTotalClaimedSupplyQuery(program: RequiredParam<NFTDrop>) {
return {
queryKey: createSOLProgramQueryKey(program, [
"totalClaimedSupply",
] as const),
queryFn: async () => {
requiredParamInvariant(program, "program is required");
return await program.totalClaimedSupply();
},
enabled: !!program,
};
}
/**
* Get the total claimed supply of NFTs on an NFT Drop
* @param program - The NFT Drop program to get the claimed supply on
*
* @example
* ```jsx
* import { useProgram, useDropTotalClaimedSupply } from "@thirdweb-dev/react/solana";
*
* export default function Component() {
* const { program } = useProgram("{{program_address}}");
* const { data: claimedSupply, isLoading } = useDropTotalClaimedSupply(program);
*
* return (
* <p>{claimedSupply}</p>
* )
* }
* ```
*
* @public
*/
export function useDropTotalClaimedSupply(program: RequiredParam<NFTDrop>) {
return useQuery(dropTotalClaimedSupplyQuery(program));
}
@@ -1,53 +0,0 @@
import { createSOLProgramQueryKey } from "../../../../core/query-utils/query-key";
import {
requiredParamInvariant,
RequiredParam,
} from "../../../../core/query-utils/required-param";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { NFTMetadataInput, UploadProgressEvent } from "@thirdweb-dev/sdk";
import type { NFTDrop } from "@thirdweb-dev/sdk/solana";
/**
* Lazy mint NFTs on an NFT Drop program
* @param program - The NFT Drop program instance to lazy mint on
*
* @example
* ```jsx
* import { useProgram, useLazyMintNFT } from "@thirdweb-dev/react/solana";
*
* export default function Component() {
* const { program } = useProgram("{{program_address}}");
* const { mutateAsync: lazyMint, isLoading, error } = useLazyMintNFT(program);
*
* return (
* <button onClick={() => lazyMint({ name: "My NFT", description: "..." })}>
* Claim
* </button>
* )
* }
* ```
*
* @public
*/
export function useLazyMint(
program: RequiredParam<NFTDrop>,
onProgress?: (progress: UploadProgressEvent) => void,
) {
const queryClient = useQueryClient();
return useMutation(
async (data: { metadatas: NFTMetadataInput[] }) => {
requiredParamInvariant(program, "program is required");
let options;
if (onProgress) {
options = {
onProgress,
};
}
return await program.lazyMint(data.metadatas, options);
},
{
onSettled: () =>
queryClient.invalidateQueries(createSOLProgramQueryKey(program)),
},
);
}
@@ -1,41 +0,0 @@
import { createSOLProgramQueryKey } from "../../../../core/query-utils/query-key";
import { RequiredParam } from "../../../../core/query-utils/required-param";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import type { NFTDrop, NFTDropConditionsInput } from "@thirdweb-dev/sdk/solana";
import invariant from "tiny-invariant";
/**
* Set Claim Conditions to an NFT Drop program
* @param program - The NFT Drop program to set claim conditions for
*
* @example
* ```jsx
* import { useProgram, useSetClaimConditions } from "@thirdweb-dev/react/solana";
*
* export default function Component() {
* const { program } = useProgram("{{program_address}}");
* const { mutateAsync: setClaimConditions, isLoading, error } = useSetClaimConditions(program);
*
* return (
* <button onClick={() => setClaimConditions(metadata)}>
* Set Claim Conditions
* </button>
* )
* }
* ```
*
* @public
*/
export function useSetClaimConditions(program: RequiredParam<NFTDrop>) {
const queryClient = useQueryClient();
return useMutation(
async (metadata: NFTDropConditionsInput) => {
invariant(program, "program is required");
return await program.claimConditions.set(metadata);
},
{
onSettled: () =>
queryClient.invalidateQueries(createSOLProgramQueryKey(program)),
},
);
}
@@ -1,46 +0,0 @@
import { createSOLProgramQueryKey } from "../../../../core/query-utils/query-key";
import {
requiredParamInvariant,
RequiredParam,
} from "../../../../core/query-utils/required-param";
import { useQuery } from "@tanstack/react-query";
import type { NFTDrop } from "@thirdweb-dev/sdk/solana";
export function dropUnclaimedSupplyQuery(program: RequiredParam<NFTDrop>) {
return {
queryKey: createSOLProgramQueryKey(program, [
"totalUnclaimedSupply",
] as const),
queryFn: async () => {
requiredParamInvariant(program, "program is required");
return await program.totalUnclaimedSupply();
},
enabled: !!program,
};
}
/**
* Get the total unclaimed supply of NFTs on an NFT Drop
* @param program - The NFT Drop program to get the unclaimed supply on
*
* @example
* ```jsx
* import { useProgram, useDropTotalUnclaimedSupply } from "@thirdweb-dev/react/solana";
*
* export default function Component() {
* const { program } = useProgram("{{program_address}}");
* const { data: unclaimedSupply, isLoading } = useDropTotalUnclaimedSupply(program);
*
* return (
* <p>{unclaimedSupply}</p>
* )
* }
* ```
*
* @public
*/
export function useDropUnclaimedSupply(program: RequiredParam<NFTDrop>) {
return useQuery(dropUnclaimedSupplyQuery(program));
}
@@ -1,45 +0,0 @@
import { createSOLProgramQueryKey } from "../../../core/query-utils/query-key";
import {
requiredParamInvariant,
RequiredParam,
} from "../../../core/query-utils/required-param";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import type { NFTCollection, NFTDrop } from "@thirdweb-dev/sdk/solana";
/**
* Burn an NFT owned by the connected wallet
* @param program - The NFT program instance to burn NFTs on
*
* @example
* ```jsx
* import { useProgram, useBurnNFT } from "@thirdweb-dev/react/solana";
*
* export default function Component() {
* const { program } = useProgram("{{program_address}}");
* const { mutateAsync: burn, isLoading, error } = useBurnNFT(program);
*
* return (
* <button
* onClick={() => burn("...")}
* >
* Burn
* </button>
* )
* }
* ```
*
* @public
*/
export function useBurnNFT(program: RequiredParam<NFTCollection | NFTDrop>) {
const queryClient = useQueryClient();
return useMutation(
async (nftAddress: string) => {
requiredParamInvariant(program, "program is required");
return await program.burn(nftAddress);
},
{
onSettled: () =>
queryClient.invalidateQueries(createSOLProgramQueryKey(program)),
},
);
}

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