Compare commits
280
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
408c5a81fa | ||
|
|
352291791e | ||
|
|
aabbb149e8 | ||
|
|
d59450f814 | ||
|
|
7d9a4c6abc | ||
|
|
99806e595d | ||
|
|
21c21c1adf | ||
|
|
4b10719047 | ||
|
|
989cf7347c | ||
|
|
72227b2e16 | ||
|
|
ed6c54f20d | ||
|
|
26116a6f63 | ||
|
|
f11a2719ff | ||
|
|
ef27aad0aa | ||
|
|
b03a902145 | ||
|
|
340605b507 | ||
|
|
15f8006e1f | ||
|
|
811c5a1166 | ||
|
|
c41a80d86d | ||
|
|
ad851f7b4d | ||
|
|
6218c88584 | ||
|
|
c9b564feaf | ||
|
|
87fd6ab14e | ||
|
|
df74340fa5 | ||
|
|
a57b4f01f3 | ||
|
|
126752d7d0 | ||
|
|
89ff921a7d | ||
|
|
9124b3180c | ||
|
|
f41a443c57 | ||
|
|
b7cd744cd0 | ||
|
|
bb1b4e6ac3 | ||
|
|
2f8ec89c4c | ||
|
|
6ae52664e5 | ||
|
|
4f867e15ed | ||
|
|
cc8f983615 | ||
|
|
f45ef62128 | ||
|
|
9727502eb3 | ||
|
|
b6eec6146c | ||
|
|
88daa3c5cb | ||
|
|
53c6507669 | ||
|
|
782b58d3f6 | ||
|
|
e17e41f4d1 | ||
|
|
712b11a43e | ||
|
|
306debb029 | ||
|
|
86f0ceff46 | ||
|
|
7f0d1ec947 | ||
|
|
b1218cbd7d | ||
|
|
97ef35ce0f | ||
|
|
1f46f270cd | ||
|
|
e8c25ed0f2 | ||
|
|
78d6d3c159 | ||
|
|
c72d92956a | ||
|
|
cf88795376 | ||
|
|
47287fb189 | ||
|
|
3763326c25 | ||
|
|
894eb27dfa | ||
|
|
8b3b97c8f7 | ||
|
|
89d87a5eb3 | ||
|
|
492a818079 | ||
|
|
86f608390a | ||
|
|
8096c78b46 | ||
|
|
521a49c6ec | ||
|
|
25a4773bba | ||
|
|
18381fac73 | ||
|
|
89b5c6fe07 | ||
|
|
4dccccc6fa | ||
|
|
de15e4212f | ||
|
|
1f41adbd2c | ||
|
|
1918495f2e | ||
|
|
24514a6e9f | ||
|
|
ad06c5b289 | ||
|
|
9de3f8c8e9 | ||
|
|
b1fa17158d | ||
|
|
2bdf1984cb | ||
|
|
df048af605 | ||
|
|
41507d32a7 | ||
|
|
b2cadf164c | ||
|
|
57b9c671aa | ||
|
|
3b7d10ed93 | ||
|
|
d6bb61b7fa | ||
|
|
8e591383fc | ||
|
|
6f95a520e6 | ||
|
|
f669d3ef4a | ||
|
|
83575058db | ||
|
|
028cb78125 | ||
|
|
c8261b74b5 | ||
|
|
a36c788415 | ||
|
|
ac232b5aff | ||
|
|
ba6f45027a | ||
|
|
d677e9d634 | ||
|
|
9b92697fb7 | ||
|
|
c19e471f65 | ||
|
|
b6fc298d0c | ||
|
|
ea41231b3e | ||
|
|
2ea3f00c41 | ||
|
|
20745f8cd6 | ||
|
|
caf979537b | ||
|
|
e4b10bc5bd | ||
|
|
ef0bac7f44 | ||
|
|
23de9eac4f | ||
|
|
1972f3ec0d | ||
|
|
ffd0fc42ae | ||
|
|
93531a5d47 | ||
|
|
b16aaebc4c | ||
|
|
1136d959ba | ||
|
|
db23f0588d | ||
|
|
e662408e19 | ||
|
|
afe4ba6471 | ||
|
|
6647f707bd | ||
|
|
cac373b010 | ||
|
|
9412d41683 | ||
|
|
2506eeb25d | ||
|
|
ba7dcbbad8 | ||
|
|
cd1abe6ba7 | ||
|
|
e1bcc67ceb | ||
|
|
d26b76872a | ||
|
|
9711b51067 | ||
|
|
e2037310a6 | ||
|
|
683d542334 | ||
|
|
9c8a3fb6d4 | ||
|
|
41accc2e21 | ||
|
|
f2a62110c4 | ||
|
|
db9f811bf8 | ||
|
|
fc5efe9521 | ||
|
|
82397636f4 | ||
|
|
27a30e3ffb | ||
|
|
2f1155239d | ||
|
|
c295a47144 | ||
|
|
0dade96d0d | ||
|
|
666ff5f694 | ||
|
|
8bc41cdc60 | ||
|
|
37a707f98c | ||
|
|
3c8f6205e9 | ||
|
|
1eaedc262f | ||
|
|
e187d21e12 | ||
|
|
b030a86608 | ||
|
|
acbabc8999 | ||
|
|
196195e2f9 | ||
|
|
7c86babb86 | ||
|
|
36f2b70d57 | ||
|
|
849146bf5c | ||
|
|
4cac79c45d | ||
|
|
1bda83b114 | ||
|
|
ce05bfd861 | ||
|
|
d982a98b0c | ||
|
|
b983087101 | ||
|
|
b25789fa46 | ||
|
|
e39b66f309 | ||
|
|
5f5ab015e1 | ||
|
|
f4f05bd9a4 | ||
|
|
2f5b66bef9 | ||
|
|
63258bc9c3 | ||
|
|
a80fc97b6a | ||
|
|
24f66e38c2 | ||
|
|
b5bfaefa85 | ||
|
|
493ebf032e | ||
|
|
d608cea197 | ||
|
|
a9ec190ff9 | ||
|
|
3edec391be | ||
|
|
bdec5a59af | ||
|
|
9d03619aab | ||
|
|
0ccbca78dc | ||
|
|
75c752cc14 | ||
|
|
3580182fa9 | ||
|
|
b54f95dc90 | ||
|
|
f4074ddadc | ||
|
|
208b0389a5 | ||
|
|
3b877ba221 | ||
|
|
45a400fd92 | ||
|
|
3332fa5697 | ||
|
|
fdda564b1e | ||
|
|
89db3db7ff | ||
|
|
bd9c705571 | ||
|
|
0ad0f21bcd | ||
|
|
4169b9428f | ||
|
|
2f9e8aaab4 | ||
|
|
421461ece0 | ||
|
|
485ebc8400 | ||
|
|
772f8431e3 | ||
|
|
5345479922 | ||
|
|
cfe8bbafa4 | ||
|
|
18dc8d33ed | ||
|
|
f8ab4779bb | ||
|
|
6fe16c5bf2 | ||
|
|
ba0e169654 | ||
|
|
27b869ed93 | ||
|
|
091ce2eb45 | ||
|
|
e24a371508 | ||
|
|
b86afb4b09 | ||
|
|
964add6f20 | ||
|
|
ec414bbc42 | ||
|
|
51dde28224 | ||
|
|
57432d21c4 | ||
|
|
19d87c2885 | ||
|
|
68812e9d27 | ||
|
|
90c53475f0 | ||
|
|
5a52585a7a | ||
|
|
6b48b9288b | ||
|
|
9d74a43aac | ||
|
|
9c7e5518ff | ||
|
|
b234c58d44 | ||
|
|
b1ae844e8b | ||
|
|
78bae497ba | ||
|
|
3e425bf8e6 | ||
|
|
4dca5b21a6 | ||
|
|
42c79e93dc | ||
|
|
2951b5533c | ||
|
|
fe8751eeae | ||
|
|
a0cd47ec35 | ||
|
|
3902e7aba4 | ||
|
|
8717cb2c05 | ||
|
|
d57ab03f5d | ||
|
|
5aa3c433d7 | ||
|
|
98dd64a375 | ||
|
|
e25dd1ac8e | ||
|
|
e68f9685b3 | ||
|
|
84beda1cbb | ||
|
|
32e7fb0c96 | ||
|
|
8202cc60d8 | ||
|
|
a37bc00991 | ||
|
|
b442c97080 | ||
|
|
1df2dea18f | ||
|
|
0fa6f3fcfb | ||
|
|
b900b8503f | ||
|
|
5a5bc36150 | ||
|
|
8158a55e66 | ||
|
|
f7ccc30f9d | ||
|
|
78b40a94df | ||
|
|
95d850515c | ||
|
|
1244c38162 | ||
|
|
7b923be499 | ||
|
|
0912dc5f9c | ||
|
|
052aa23888 | ||
|
|
6c10ed93cb | ||
|
|
2327a9d611 | ||
|
|
27ffbc252b | ||
|
|
a70b590be1 | ||
|
|
45818944e5 | ||
|
|
fe047d551e | ||
|
|
82627ea031 | ||
|
|
1de14730bc | ||
|
|
2adb8ff667 | ||
|
|
820a5191b5 | ||
|
|
c94ef909d0 | ||
|
|
8aef97d6f1 | ||
|
|
8a5501fb80 | ||
|
|
8696199849 | ||
|
|
05353fd8da | ||
|
|
baa87a1fbd | ||
|
|
407932680f | ||
|
|
6bec17c07a | ||
|
|
c379d19dfb | ||
|
|
3e2bec8a47 | ||
|
|
8b028c29d5 | ||
|
|
cc286841e2 | ||
|
|
576d968a89 | ||
|
|
f2bdf47b4f | ||
|
|
b92d3f7006 | ||
|
|
c9457bc2e7 | ||
|
|
3308bddd70 | ||
|
|
8954b8c5b6 | ||
|
|
3287c2b0f2 | ||
|
|
a5cdd85c77 | ||
|
|
e9e71cfcd8 | ||
|
|
27b3475d64 | ||
|
|
6ba9cad8d8 | ||
|
|
a5ad3d6828 | ||
|
|
9c817de558 | ||
|
|
326f52ae4e | ||
|
|
beafc856cf | ||
|
|
a85b35e75f | ||
|
|
5644ccd3ee | ||
|
|
14a5a31d70 | ||
|
|
83417c23d8 | ||
|
|
b6ebc82d5a | ||
|
|
091f175860 | ||
|
|
8811b99ad5 | ||
|
|
711783dbbf | ||
|
|
cd44d4d0c2 | ||
|
|
924247a8ed |
@@ -2,12 +2,16 @@
|
||||
"$schema": "https://unpkg.com/@changesets/[email protected]/schema.json",
|
||||
"changelog": ["@changesets/changelog-github", { "repo": "thirdweb-dev/js" }],
|
||||
"commit": false,
|
||||
"fixed": [],
|
||||
"fixed": [["@thirdweb-dev/sdk", "@thirdweb-dev/react"]],
|
||||
"linked": [],
|
||||
"access": "public",
|
||||
"baseBranch": "main",
|
||||
"updateInternalDependencies": "patch",
|
||||
"ignore": [],
|
||||
"ignore": ["e2e-cra-5", "e2e-next-12", "e2e-vite-3"],
|
||||
"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
|
||||
"updateInternalDependents": "always",
|
||||
"onlyUpdatePeerDependentsWhenOutOfRange": true
|
||||
},
|
||||
"snapshot": {
|
||||
"useCalculatedVersion": true,
|
||||
"prereleaseTemplate": "{tag}-{commit}"
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
name: "Install"
|
||||
description: "Sets up Node.js and runs install"
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: yarn install
|
||||
env:
|
||||
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "1"
|
||||
@@ -0,0 +1,136 @@
|
||||
# Contributing to thirdweb
|
||||
|
||||
You can find a full video tutorial on how to contribute to thirdweb below:
|
||||
|
||||
https://www.youtube.com/watch?v=TXsQ3qok3B0
|
||||
|
||||
## Getting Started
|
||||
|
||||
To get started, read the [How this repo works](#how-this-repo-works) section below to learn about the structure of this repo.
|
||||
|
||||
From there, you can take a look at our [Good First Issues](https://github.com/thirdweb-dev/js/labels/good%20first%20issue) board and find an issue that interests you!
|
||||
|
||||
If you have any questions about the issue, feel free to ask on our [Discord server](https://discord.gg/thirdweb) in the `#contributors` channel; where you'll be able to get help from our team and other contributors.
|
||||
|
||||
<br/>
|
||||
|
||||
## How this repo works
|
||||
|
||||
[@thirdweb-dev/js](https://github.com/thirdweb-dev/js) is a monorepo, meaning it contains many projects within it.
|
||||
|
||||
We use [Turborepo](https://turborepo.org/docs/getting-started) to manage the monorepo, and help speed up the [CI/CD](https://www.atlassian.com/continuous-delivery/principles/continuous-integration-vs-delivery-vs-deployment) pipeline to ship to production faster 🚢.
|
||||
|
||||
You can see a quick outline of each of the projects within this repo below, each living within the [/packages](/packages) directory:
|
||||
|
||||
| Package | Description | Latest Version |
|
||||
| ------------------------------ | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [/sdk](./packages/sdk) | Best in class web3 SDK for Browser, Node and Mobile apps | <a href="https://www.npmjs.com/package/@thirdweb-dev/sdk"><img src="https://img.shields.io/npm/v/@thirdweb-dev/sdk?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/react](./packages/react) | Ultimate collection of React hooks for your web3 apps | <a href="https://www.npmjs.com/package/@thirdweb-dev/react"><img src="https://img.shields.io/npm/v/@thirdweb-dev/react?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/auth](./packages/auth) | Best in class wallet authentication for Node backends | <a href="https://www.npmjs.com/package/@thirdweb-dev/auth"><img src="https://img.shields.io/npm/v/@thirdweb-dev/auth?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/storage](./packages/storage) | Best in class decentralized storage SDK for Browser and Node | <a href="https://www.npmjs.com/package/@thirdweb-dev/storage"><img src="https://img.shields.io/npm/v/@thirdweb-dev/storage?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/cli](./packages/cli) | Publish and deploy smart contracts without dealing with private keys | <a href="https://www.npmjs.com/package/thirdweb"><img src="https://img.shields.io/npm/v/thirdweb?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/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
|
||||
|
||||
Let's explore how you can set up the repo on your local machine and start contributing!
|
||||
|
||||
This section requires some existing knowledge of [Git](https://git-scm.com/), [Node.js](https://nodejs.org/en/) and [Yarn](https://yarnpkg.com/).
|
||||
|
||||
<br/>
|
||||
|
||||
### Getting the repo
|
||||
|
||||
For OSS contributions, we use a [Forking Workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/forking-workflow), meaning each developer will fork the repo and work on their own fork; and then submit a PR to the main repo when they're ready to merge their changes.
|
||||
|
||||
To begin:
|
||||
|
||||
1. [Create a fork](https://github.com/thirdweb-dev/js/fork) of this repository to your own GitHub account.
|
||||
|
||||
2. [Clone your fork](https://help.github.com/articles/cloning-a-repository/) to your local device.
|
||||
|
||||
3. Create a new branch on your fork to start working on your changes:
|
||||
|
||||
```
|
||||
git checkout -b MY_BRANCH_NAME
|
||||
```
|
||||
|
||||
4. Install the dependencies:
|
||||
```
|
||||
yarn
|
||||
```
|
||||
|
||||
Now you have got the repo on your local machine, and you're ready to start making your changes!
|
||||
|
||||
### Test Your Changes
|
||||
|
||||
We use [yalc](https://github.com/wclr/yalc) to test changes locally.
|
||||
|
||||
Install the yalc CLI globally:
|
||||
|
||||
```bash
|
||||
yarn global add yalc
|
||||
```
|
||||
|
||||
First, create a test project where you can experiment with your changes:
|
||||
|
||||
You can create a basic starter project with the `sdk` and `react` packages installed using the CLI:
|
||||
|
||||
```bash
|
||||
npx thirdweb create --app
|
||||
```
|
||||
|
||||
Use `yalc` to link your local changes in the monorepo to the test project, by running the following command from your test repo:
|
||||
|
||||
```bash
|
||||
yalc add @thirdweb-dev/react # Link the react package
|
||||
yalc add @thirdweb-dev/sdk # Link the sdk package
|
||||
# etc...
|
||||
```
|
||||
|
||||
From the monorepo, run the following command to publish your local changes to the test project:
|
||||
|
||||
```bash
|
||||
yarn push
|
||||
```
|
||||
|
||||
Now, each time you make a change to the monorepo, you can run `yarn push` to publish your changes to the test project.
|
||||
|
||||
In your test project, you need to:
|
||||
|
||||
1. Delete the dependencies cache. If you're using Next.js, that is the `.next` directory, and if you're using CRA, that is the `node_modules/.cache` directory.
|
||||
2. Restart the development server.
|
||||
|
||||
<br/>
|
||||
|
||||
### Publish Your Changes
|
||||
|
||||
Once you're satisfied with your changes, you are ready to submit them for review!
|
||||
|
||||
1. Use [changeset](https://github.com/changesets/changesets) to generate a changeset file:
|
||||
|
||||
```
|
||||
yarn changeset
|
||||
```
|
||||
|
||||
We follow [semantic versioning](https://semver.org/) for generating versioned releases of our packages (i.e. version = `MAJOR.MINOR.PATCH`)
|
||||
|
||||
- Update `major` for breaking changes
|
||||
- Update `minor` for new features,
|
||||
- Update `patch` for non-breaking bug fixes, etc)
|
||||
|
||||
2. Commit the changeset along with your changes:
|
||||
|
||||
```
|
||||
git commit -am "My commit message"
|
||||
```
|
||||
|
||||
3. Push your changes to the SDK:
|
||||
|
||||
```
|
||||
git push origin MY_BRANCH_NAME
|
||||
```
|
||||
|
||||
4. Create a [pull request](https://www.atlassian.com/git/tutorials/making-a-pull-request) to the `main` branch of the official (not your fork) SDK repo.
|
||||
|
||||
It's helpful to tag PRs with `[SDK]`, `[REACT]`, `[AUTH]`, (the name of the package you're modifying) to indicate the package that you are engaging with.
|
||||
@@ -0,0 +1,17 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 60
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- pinned
|
||||
- security
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: wontfix
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
build:
|
||||
name: Build and Test
|
||||
# timeout-minutes: 15
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-latest-32
|
||||
# To use Remote Caching, uncomment the next lines and follow the steps below.
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
@@ -22,21 +22,13 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 2
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16
|
||||
cache: "yarn"
|
||||
- name: Install
|
||||
uses: ./.github/composite-actions/install
|
||||
|
||||
- name: Install Dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- name: Build
|
||||
run: yarn build
|
||||
|
||||
- name: Test
|
||||
# this already builds anything that changed...
|
||||
- name: Build & Test
|
||||
run: yarn test
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
concurrency: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
# To use Remote Caching, uncomment the next lines and follow the steps below.
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install Dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- name: Create Release Pull Request or Publish to npm
|
||||
id: changesets
|
||||
uses: changesets/action@v1
|
||||
with:
|
||||
# This expects you to have a script called release which does a build for your packages and calls changeset publish
|
||||
publish: yarn release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
@@ -0,0 +1,72 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ "main" ]
|
||||
schedule:
|
||||
- cron: '37 9 * * 3'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'javascript' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
# - run: |
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
@@ -13,28 +13,17 @@ concurrency:
|
||||
jobs:
|
||||
integration-tests:
|
||||
timeout-minutes: 60
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-latest-32
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16
|
||||
cache: "yarn"
|
||||
- name: Install
|
||||
uses: ./.github/composite-actions/install
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- name: Install Playwright Browsers
|
||||
- name: Install Playwright
|
||||
run: npx playwright install --with-deps
|
||||
|
||||
- name: Run e2e tests
|
||||
run: yarn e2e
|
||||
env:
|
||||
NODE_OPTIONS: "--max_old_space_size=4096"
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: always()
|
||||
with:
|
||||
name: playwright-report
|
||||
path: packages/react/playwright-report/
|
||||
retention-days: 30
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
# timeout-minutes: 15
|
||||
# try out buildjet to speed up build and test
|
||||
runs-on: ubuntu-latest
|
||||
# To use Remote Caching, uncomment the next lines and follow the steps below.
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install
|
||||
uses: ./.github/composite-actions/install
|
||||
|
||||
- name: Lint
|
||||
run: yarn lint
|
||||
@@ -1,40 +0,0 @@
|
||||
name: Release Nightly
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: Release Nightly
|
||||
runs-on: ubuntu-latest
|
||||
# To use Remote Caching, uncomment the next lines and follow the steps below.
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Node.js environment
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install Dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- name: Create an .npmrc for nightly release
|
||||
env:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: |
|
||||
cat << EOF > "$HOME/.npmrc"
|
||||
//registry.npmjs.org/:_authToken=$NPM_TOKEN
|
||||
EOF
|
||||
|
||||
- name: Publish Nightly version to NPM
|
||||
run: yarn release:nightly
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,82 @@
|
||||
# pulled from: https://github.com/changesets/changesets/pull/909
|
||||
|
||||
name: release-pr
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
deploy-check:
|
||||
# this just checks if ur allowed to do the action so does not need to run on a fast machine
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: acknowledge deployment request to commenter
|
||||
id: check
|
||||
uses: khan/pull-request-comment-trigger@master
|
||||
with:
|
||||
trigger: "/release-pr"
|
||||
reaction: rocket
|
||||
env:
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
- name: validate user
|
||||
id: validate_user
|
||||
if: ${{ steps.check.outputs.triggered == 'true' }}
|
||||
run: |
|
||||
if [[ "${AUTHOR_ASSOCIATION}" != 'MEMBER' && "${AUTHOR_ASSOCIATION}" != 'OWNER' && "${AUTHOR_ASSOCIATION}" != 'CONTRIBUTOR' ]]
|
||||
then
|
||||
echo "User authorization failed"
|
||||
exit 1
|
||||
else
|
||||
echo "User authorization successful"
|
||||
fi
|
||||
env:
|
||||
AUTHOR_ASSOCIATION: ${{ github.event.comment.author_association }}
|
||||
- name: check outputs
|
||||
run: echo ${{ steps.check.outputs.triggered }}
|
||||
|
||||
outputs:
|
||||
triggered: ${{ steps.check.outputs.triggered }}
|
||||
comment_body: ${{ github.event.comment.body }}
|
||||
|
||||
deploy:
|
||||
runs-on: ubuntu-latest-32
|
||||
needs: deploy-check
|
||||
if: needs.deploy-check.outputs.triggered == 'true'
|
||||
steps:
|
||||
- name: get pull request ref
|
||||
id: get_pull_request_ref
|
||||
uses: octokit/[email protected]
|
||||
with:
|
||||
route: GET /repos/{owner}/{repository}/pulls/{issue_id}
|
||||
owner: ${{ github.repository_owner }}
|
||||
repository: ${{ github.event.repository.name }}
|
||||
issue_id: ${{ github.event.issue.number }}
|
||||
env:
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
||||
- name: pull the repo.
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
persist-credentials: true
|
||||
repository: ${{ fromJson(steps.get_pull_request_ref.outputs.data).head.repo.full_name }}
|
||||
ref: ${{ fromJson(steps.get_pull_request_ref.outputs.data).head.ref }}
|
||||
|
||||
- name: Install
|
||||
uses: ./.github/composite-actions/install
|
||||
|
||||
- name: Build
|
||||
run: yarn build:release
|
||||
|
||||
- name: Configure npm
|
||||
run: |
|
||||
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc
|
||||
env:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- name: Deploy pre-release
|
||||
run: |
|
||||
yarn changeset version --snapshot dev
|
||||
yarn changeset publish --tag dev --no-git-tag
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,49 @@
|
||||
name: Release Nightly & Stable
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- ".changeset/**"
|
||||
- "packages/**"
|
||||
branches:
|
||||
- main
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-latest-32
|
||||
steps:
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install
|
||||
uses: ./.github/composite-actions/install
|
||||
|
||||
- name: Build
|
||||
run: yarn build:release
|
||||
|
||||
- name: Create release Pull Request or publish to NPM
|
||||
id: changesets
|
||||
uses: changesets/action@v1
|
||||
with:
|
||||
publish: yarn release
|
||||
version: yarn version-packages
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Create @nightly release
|
||||
if: steps.changesets.outputs.published != 'true'
|
||||
run: |
|
||||
git checkout main
|
||||
yarn version-packages:nightly
|
||||
yarn release:nightly
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,19 @@
|
||||
name: Compressed Size
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest-32
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- uses: preactjs/compressed-size-action@v2
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
strip-hash: "\\-(\\w{8})(?:\\.esm|\\.cjs)"
|
||||
minimum-change-threshold: 100
|
||||
# exclude source maps, node modules and any test related files
|
||||
exclude: "{**/*.map,**/node_modules/**,**/test/**}"
|
||||
+5
-1
@@ -12,4 +12,8 @@ server/dist
|
||||
public/dist
|
||||
.turbo
|
||||
./packages/contracts-js/abis
|
||||
.idea/
|
||||
.idea/
|
||||
.yalc/
|
||||
yalc.lock
|
||||
build/
|
||||
playwright-report/
|
||||
+4
-2
@@ -1,2 +1,4 @@
|
||||
lib
|
||||
node_modules
|
||||
node_modules
|
||||
dist
|
||||
contracts-js
|
||||
*.d.ts
|
||||
+15
-15
@@ -10,19 +10,19 @@ We pledge to act and interact in ways that contribute to an open, welcoming, div
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the overall community
|
||||
- Demonstrating empathy and kindness toward other people
|
||||
- Being respectful of differing opinions, viewpoints, and experiences
|
||||
- Giving and gracefully accepting constructive feedback
|
||||
- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
|
||||
- Focusing on what is best not just for us as individuals, but for the overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
- The use of sexualized language or imagery, and sexual attention or advances of any kind
|
||||
- Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or email address, without their explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
@@ -64,7 +64,7 @@ Community leaders will follow these Community Impact Guidelines in determining t
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
|
||||
**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within the community.
|
||||
|
||||
@@ -72,12 +72,12 @@ Community leaders will follow these Community Impact Guidelines in determining t
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at [https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][mozilla coc].
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at [https://www.contributor-covenant.org/translations][translations].
|
||||
For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq][faq]. Translations are available at [https://www.contributor-covenant.org/translations][translations].
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
|
||||
[Mozilla CoC]: https://github.com/mozilla/diversity
|
||||
[FAQ]: https://www.contributor-covenant.org/faq
|
||||
[mozilla coc]: https://github.com/mozilla/diversity
|
||||
[faq]: https://www.contributor-covenant.org/faq
|
||||
[translations]: https://www.contributor-covenant.org/translations
|
||||
|
||||
@@ -1,44 +1,52 @@
|
||||
<p align="center">
|
||||
<br />
|
||||
<a href="https://thirdweb.com"><img src="https://github.com/thirdweb-dev/js/blob/main/packages/sdk/logo.svg?raw=true" width="200" alt=""/></a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://thirdweb.com">
|
||||
<img src="https://github.com/thirdweb-dev/js/blob/main/packages/sdk/logo.svg?raw=true" width="200" alt=""/></a>
|
||||
<br />
|
||||
</p>
|
||||
<h1 align="center">thirdweb JavaScript/TypeScript monorepo</h1>
|
||||
|
||||
<h1 align="center"><a href='http://thirdweb.com/'>thirdweb</a> JavaScript/TypeScript monorepo</h1>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/thirdweb-dev/js/actions/workflows/CI.yml"><img alt="Build Status" src="https://github.com/thirdweb-dev/js/actions/workflows/CI.yml/badge.svg"/></a>
|
||||
<a href="https://discord.gg/thirdweb"><img alt="Join our Discord!" src="https://img.shields.io/discord/834227967404146718.svg?color=7289da&label=discord&logo=discord&style=flat"/></a>
|
||||
<a href="https://github.com/thirdweb-dev/js/actions/workflows/CI.yml">
|
||||
<img alt="Build Status" src="https://github.com/thirdweb-dev/js/actions/workflows/CI.yml/badge.svg"/>
|
||||
</a>
|
||||
<a href="https://discord.gg/thirdweb">
|
||||
<img alt="Join our Discord!" src="https://img.shields.io/discord/834227967404146718.svg?color=7289da&label=discord&logo=discord&style=flat"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center"><strong>Best in class web3 SDKs for Browser, Node and Mobile apps</strong></p>
|
||||
<br />
|
||||
|
||||
## Packages
|
||||
|
||||
| Package | Description | Latest Version |
|
||||
| ---------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [/sdk](./packages/sdk/README.md) | Best in class web3 SDK for Browser, Node and Mobile apps | <a href="https://www.npmjs.com/package/@thirdweb-dev/sdk"><img src="https://img.shields.io/npm/v/@thirdweb-dev/sdk?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/react](./packages/react/README.md) | Ultimate collection of React hooks for your web3 apps | <a href="https://www.npmjs.com/package/@thirdweb-dev/react"><img src="https://img.shields.io/npm/v/@thirdweb-dev/react?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/auth](./packages/auth/README.md) | 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/README.md) | 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/README.md) | 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/README.md) | 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> |
|
||||
| Package | Description | Latest Version |
|
||||
| ------------------------------ | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [/sdk](./packages/sdk) | Best in class web3 SDK for Browser, Node and Mobile apps | <a href="https://www.npmjs.com/package/@thirdweb-dev/sdk"><img src="https://img.shields.io/npm/v/@thirdweb-dev/sdk?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/react](./packages/react) | Ultimate collection of React hooks for your web3 apps | <a href="https://www.npmjs.com/package/@thirdweb-dev/react"><img src="https://img.shields.io/npm/v/@thirdweb-dev/react?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/auth](./packages/auth) | Best in class wallet authentication for Node backends | <a href="https://www.npmjs.com/package/@thirdweb-dev/auth"><img src="https://img.shields.io/npm/v/@thirdweb-dev/auth?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/storage](./packages/storage) | Best in class decentralized storage SDK for Browser and Node | <a href="https://www.npmjs.com/package/@thirdweb-dev/storage"><img src="https://img.shields.io/npm/v/@thirdweb-dev/storage?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/cli](./packages/cli) | Publish and deploy smart contracts without dealing with private keys | <a href="https://www.npmjs.com/package/thirdweb"><img src="https://img.shields.io/npm/v/thirdweb?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
|
||||
## How this monorepo functions
|
||||
|
||||
### Contributing
|
||||
## Documentation
|
||||
|
||||
1. Create PRs to the monorepo
|
||||
2. Tag PRs with `[SDK]`, `[REACT]`, `[AUTH]`, etc to indicate the package that you are engaging with (TBD a better process for this / if it is necessary)
|
||||
3. Create a `changeset` (with `yarn changeset`) for every **user impacting** change and describe what changed (try to focus on the end-user impact as much as possible -- use `major` for breaking changes, `minor` for new features, `patch` for non-breaking bug fixes, etc)
|
||||
4. when the PR builds and tests pass merge to main
|
||||
Visit [https://portal.thirdweb.com/](https://portal.thirdweb.com/) to view the full documentation.
|
||||
|
||||
### Releases
|
||||
<br />
|
||||
|
||||
#### Nightly
|
||||
## Contributing
|
||||
|
||||
- every push to main automatically gets published to the `@nightly` tag as a snapshot version (based on the commit hash)
|
||||
- nightly versions are published to npm under the `@nightly` tag
|
||||
We welcome contributions from all developers, regardless of experience level. If you are interested in contributing, please read our [Contributing Guide](.github/contributing.md) where you'll learn how the repo works, how to test your changes, and how to submit a pull request.
|
||||
|
||||
#### Stable
|
||||
<br />
|
||||
|
||||
- every push to main that contains a changeset automatically gets added to the [Version Packages](https://github.com/thirdweb-dev/js/tree/changeset-release/main) PR
|
||||
- to release a stable version of the code that is on main (with the change sets as the release notes / changelog) merge the `Version Packages` PR to main, this will automatically create new `@latest` packages for all of the packages in the monorepo that have changesets
|
||||
## Community
|
||||
|
||||
The best place to discuss your ideas, ask questions, and troubleshoot issues is our [Discord server](https://discord.gg/thirdweb).
|
||||
|
||||
<br/>
|
||||
|
||||
## Security
|
||||
|
||||
If you believe you have found a security vulnerability in any of our packages, we kindly ask you not to open a public issue; and to disclose this to us by emailing `[email protected]`.
|
||||
|
||||
+26
-22
@@ -2,44 +2,48 @@
|
||||
"name": "@thirdweb-dev/js",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"repository": "git@github.com:thirdweb-dev/js.git",
|
||||
"repository": "https://github.com/thirdweb-dev/js",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"workspaces": {
|
||||
"packages": [
|
||||
"packages/*"
|
||||
"packages/*",
|
||||
"test/**/*"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@changesets/changelog-github": "^0.4.6",
|
||||
"@changesets/cli": "^2.24.3",
|
||||
"@trivago/prettier-plugin-sort-imports": "^3.3.0",
|
||||
"eslint": "^8.23.0",
|
||||
"eslint-config-thirdweb": "*",
|
||||
"postinstall-postinstall": "^2.1.0",
|
||||
"prettier": "^2.7.1",
|
||||
"turbo": "latest",
|
||||
"yarn-deduplicate": "^5.0.2"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "yarn-deduplicate yarn.lock",
|
||||
"test": "turbo run test",
|
||||
"test": "turbo run test test:evm test:solana",
|
||||
"e2e": "turbo run e2e",
|
||||
"build": "turbo run build",
|
||||
"build:release": "turbo run build --force",
|
||||
"dev": "turbo run dev --no-cache --parallel --continue",
|
||||
"fix:repo": "manypkg fix",
|
||||
"lint": "turbo run lint",
|
||||
"fix": "turbo run fix",
|
||||
"clean": "turbo run clean && rm -rf node_modules",
|
||||
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
|
||||
"changeset": "changeset",
|
||||
"release": "yarn build:release && changeset publish",
|
||||
"release:nightly": "yarn build:release && changeset version --snapshot nightly && changeset publish --tag nightly --no-git-tag"
|
||||
"version-packages": "changeset version",
|
||||
"release": "node ./scripts/pre-release.mjs && changeset publish",
|
||||
"version-packages:nightly": "changeset version --snapshot nightly",
|
||||
"release:nightly": "node ./scripts/pre-release.mjs && changeset publish --tag nightly",
|
||||
"push": "turbo run push"
|
||||
},
|
||||
"preconstruct": {
|
||||
"packages": [
|
||||
"packages/*"
|
||||
]
|
||||
"packageManager": "[email protected]",
|
||||
"dependencies": {
|
||||
"@changesets/changelog-github": "^0.4.6",
|
||||
"@changesets/cli": "^2.24.3",
|
||||
"@manypkg/cli": "^0.19.1",
|
||||
"@manypkg/get-packages": "^1.1.3",
|
||||
"@trivago/prettier-plugin-sort-imports": "^3.3.0",
|
||||
"eslint": "^8.21.0",
|
||||
"postinstall-postinstall": "^2.1.0",
|
||||
"prettier": "^2.7.1",
|
||||
"turbo": "^1.4.6",
|
||||
"yalc": "^1.0.0-pre.53"
|
||||
},
|
||||
"packageManager": "[email protected]"
|
||||
"manypkg": {
|
||||
"defaultBranch": "main"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,154 @@
|
||||
# @thirdweb-dev/auth
|
||||
|
||||
## 2.0.23
|
||||
|
||||
## 2.0.22
|
||||
|
||||
## 2.0.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#327](https://github.com/thirdweb-dev/js/pull/327) [`ef27aad`](https://github.com/thirdweb-dev/js/commit/ef27aad0aafc4577e85f44dc77dfbe880bd239b5) Thanks [@jnsdls](https://github.com/jnsdls)! - enable e2e testing
|
||||
|
||||
## 2.0.20
|
||||
|
||||
## 2.0.19
|
||||
|
||||
## 2.0.18
|
||||
|
||||
## 2.0.17
|
||||
|
||||
## 2.0.16
|
||||
|
||||
## 2.0.15
|
||||
|
||||
## 2.0.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#274](https://github.com/thirdweb-dev/js/pull/274) [`ad06c5b`](https://github.com/thirdweb-dev/js/commit/ad06c5b28902422f9b416d65255c64c937a5e046) Thanks [@adam-maj](https://github.com/adam-maj)! - Add solana auth support and plugins for react and auth package
|
||||
|
||||
## 2.0.13
|
||||
|
||||
## 2.0.12
|
||||
|
||||
## 2.0.11
|
||||
|
||||
## 2.0.10
|
||||
|
||||
## 2.0.9
|
||||
|
||||
## 2.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ce05bfd`](https://github.com/thirdweb-dev/js/commit/ce05bfd8615a9c79664856bce53de8b43bed5c87)]:
|
||||
- @thirdweb-dev/sdk@3.0.8
|
||||
|
||||
## 2.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5f5ab01`](https://github.com/thirdweb-dev/js/commit/5f5ab015e1dd3c471d6affe995ef36ec88932b3c)]:
|
||||
- @thirdweb-dev/sdk@3.0.7
|
||||
|
||||
## 2.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a80fc97`](https://github.com/thirdweb-dev/js/commit/a80fc97b6a1e72ed46a400b4b602e180947fb870)]:
|
||||
- @thirdweb-dev/sdk@3.0.6
|
||||
|
||||
## 2.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`4169b94`](https://github.com/thirdweb-dev/js/commit/4169b9428f9001b7cad259a4e56fe610316cd191), [`3b877ba`](https://github.com/thirdweb-dev/js/commit/3b877ba221acfd85f80b99e1bc382055217f0a39), [`b54f95d`](https://github.com/thirdweb-dev/js/commit/b54f95dc906928ff2f9251748f254a16fe1f2cee), [`f8ab477`](https://github.com/thirdweb-dev/js/commit/f8ab4779bb2d6d66200e1e8fd558e0ac069a2f54), [`772f843`](https://github.com/thirdweb-dev/js/commit/772f8431e3a62d0ded62dae90a43e9a7edd5b1a2), [`a9ec190`](https://github.com/thirdweb-dev/js/commit/a9ec190ff99d2714cef2500d20ea0f3f73f07be3), [`208b038`](https://github.com/thirdweb-dev/js/commit/208b0389a50ea48bbb9600fec60fec2f1671d4b9), [`5345479`](https://github.com/thirdweb-dev/js/commit/534547992243bdd3a77e34ec2b2487b5adab366a)]:
|
||||
- @thirdweb-dev/sdk@3.0.5
|
||||
|
||||
## 2.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/sdk@3.0.4
|
||||
|
||||
## 2.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`51dde28`](https://github.com/thirdweb-dev/js/commit/51dde28224209f1b8b26f436c204a5e702281564), [`9d74a43`](https://github.com/thirdweb-dev/js/commit/9d74a43aac21448beba63ba4e2637945965a3634), [`b234c58`](https://github.com/thirdweb-dev/js/commit/b234c58d44d8322e44b2d2ba87ad4ec7d699e961)]:
|
||||
- @thirdweb-dev/sdk@3.0.3
|
||||
|
||||
## 2.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`42c79e9`](https://github.com/thirdweb-dev/js/commit/42c79e93dc958ca46a55d705aeea44ffdbbcc5f6), [`fe8751e`](https://github.com/thirdweb-dev/js/commit/fe8751eeae7ad013b890a8092ddbd091ecbd6708)]:
|
||||
- @thirdweb-dev/sdk@3.0.2
|
||||
|
||||
## 2.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`98dd64a`](https://github.com/thirdweb-dev/js/commit/98dd64a375c302a879aab3c628ecfb84b4dd19da)]:
|
||||
- @thirdweb-dev/sdk@3.0.1
|
||||
|
||||
## 2.0.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a70b590`](https://github.com/thirdweb-dev/js/commit/a70b590be1efa7c0ad93a724afb24870439558ed), [`a37bc00`](https://github.com/thirdweb-dev/js/commit/a37bc00991bf1a359f5f8aa8e24e2c388dcd99d8), [`b442c97`](https://github.com/thirdweb-dev/js/commit/b442c970808f6cb7457d29542bd826dba711579c), [`0fa6f3f`](https://github.com/thirdweb-dev/js/commit/0fa6f3fcfbd571579baf9d2a0dbeee556ddbd5fe), [`2adb8ff`](https://github.com/thirdweb-dev/js/commit/2adb8ff6673768a91fa411c2d069245190ad9397), [`5a5bc36`](https://github.com/thirdweb-dev/js/commit/5a5bc361507bd8707dc12e9000bb9a218221cf61), [`820a519`](https://github.com/thirdweb-dev/js/commit/820a5191b5e7af5aba5e4d1cc90cd895c0dade11), [`0fa6f3f`](https://github.com/thirdweb-dev/js/commit/0fa6f3fcfbd571579baf9d2a0dbeee556ddbd5fe), [`82627ea`](https://github.com/thirdweb-dev/js/commit/82627ea0311f612119d0596ed0f568267a7af16b)]:
|
||||
- @thirdweb-dev/sdk@3.0.0
|
||||
|
||||
## 1.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`baa87a1`](https://github.com/thirdweb-dev/js/commit/baa87a1fbd7eee24ce9a95e16028de8435f85e69), [`4079326`](https://github.com/thirdweb-dev/js/commit/407932680fb024f17f12f578aa22c7f8c0c13339), [`05353fd`](https://github.com/thirdweb-dev/js/commit/05353fd8da82f77fb642bb38a533fb99801aed30)]:
|
||||
- @thirdweb-dev/sdk@2.4.9
|
||||
|
||||
## 1.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#61](https://github.com/thirdweb-dev/js/pull/61) [`3287c2b`](https://github.com/thirdweb-dev/js/commit/3287c2b0f233332fe4a095f973deed8efab91db6) Thanks [@jnsdls](https://github.com/jnsdls)! - fix versions in dependencies before releasing stable
|
||||
|
||||
- Updated dependencies [[`3287c2b`](https://github.com/thirdweb-dev/js/commit/3287c2b0f233332fe4a095f973deed8efab91db6)]:
|
||||
- @thirdweb-dev/sdk@2.4.8
|
||||
|
||||
## 1.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`6ba9cad`](https://github.com/thirdweb-dev/js/commit/6ba9cad8d8b933256599dc3b147601cd4828c89b)]:
|
||||
- @thirdweb-dev/sdk@2.4.7
|
||||
|
||||
## 1.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`5644ccd`](https://github.com/thirdweb-dev/js/commit/5644ccd3ee2ff330e4e5840d3266033376750117) Thanks [@jnsdls](https://github.com/jnsdls)! - bump versions again
|
||||
|
||||
- Updated dependencies [[`5644ccd`](https://github.com/thirdweb-dev/js/commit/5644ccd3ee2ff330e4e5840d3266033376750117)]:
|
||||
- @thirdweb-dev/sdk@2.4.6
|
||||
|
||||
## 1.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`091f175`](https://github.com/thirdweb-dev/js/commit/091f1758604d40e825ea28a13c2699d67bc75d8c) Thanks [@jnsdls](https://github.com/jnsdls)! - release-all-packages
|
||||
|
||||
- Updated dependencies [[`091f175`](https://github.com/thirdweb-dev/js/commit/091f1758604d40e825ea28a13c2699d67bc75d8c)]:
|
||||
- @thirdweb-dev/sdk@2.4.5
|
||||
|
||||
## 1.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/sdk@2.4.4
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -18,6 +18,7 @@ Install the latest version of the SDK with either `npm` or `yarn`:
|
||||
```shell
|
||||
npm install @thirdweb-dev/auth @thirdweb-dev/sdk ethers
|
||||
```
|
||||
|
||||
```shell
|
||||
yarn add @thirdweb-dev/auth @thirdweb-dev/sdk ethers
|
||||
```
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"main": "dist/thirdweb-dev-auth-next-evm.cjs.js",
|
||||
"module": "dist/thirdweb-dev-auth-next-evm.esm.js"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"main": "dist/thirdweb-dev-auth-next-solana.cjs.js",
|
||||
"module": "dist/thirdweb-dev-auth-next-solana.esm.js"
|
||||
}
|
||||
+33
-17
@@ -1,26 +1,30 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/auth",
|
||||
"version": "1.0.2",
|
||||
"version": "2.0.23",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
"./next": {
|
||||
"module": "./next/dist/thirdweb-dev-auth-next.esm.js",
|
||||
"default": "./next/dist/thirdweb-dev-auth-next.cjs.js"
|
||||
},
|
||||
"./express": {
|
||||
"module": "./express/dist/thirdweb-dev-auth-express.esm.js",
|
||||
"default": "./express/dist/thirdweb-dev-auth-express.cjs.js"
|
||||
},
|
||||
"./next": {
|
||||
"module": "./next/dist/thirdweb-dev-auth-next.esm.js",
|
||||
"default": "./next/dist/thirdweb-dev-auth-express.cjs.js"
|
||||
"./next/evm": {
|
||||
"module": "./next/evm/dist/thirdweb-dev-auth-next-evm.esm.js",
|
||||
"default": "./next/evm/dist/thirdweb-dev-auth-next-evm.cjs.js"
|
||||
},
|
||||
"./next-auth": {
|
||||
"module": "./next-auth/dist/thirdweb-dev-auth-next-auth.esm.js",
|
||||
"default": "./next-auth/dist/thirdweb-dev-auth-next-auth.cjs.js"
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"directory": "packages/auth",
|
||||
"type": "git",
|
||||
"url": "https://github.com/thirdweb-dev/js.git"
|
||||
},
|
||||
"./next/solana": {
|
||||
"module": "./next/solana/dist/thirdweb-dev-auth-next-solana.esm.js",
|
||||
"default": "./next/solana/dist/thirdweb-dev-auth-next-solana.cjs.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/auth",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
"files": [
|
||||
@@ -31,16 +35,26 @@
|
||||
],
|
||||
"scripts": {
|
||||
"build": "preconstruct build",
|
||||
"lint": "eslint"
|
||||
"format": "prettier --write 'src/**/*'",
|
||||
"lint": "eslint src/",
|
||||
"fix": "eslint src/ --fix",
|
||||
"clean": "rm -rf dist/ && rm -rf node_modules/"
|
||||
},
|
||||
"preconstruct": {
|
||||
"entrypoints": [
|
||||
"next/index.ts",
|
||||
"next/evm/index.ts",
|
||||
"next/solana/index.ts",
|
||||
"express/index.ts",
|
||||
"next-auth/index.ts"
|
||||
]
|
||||
],
|
||||
"___experimentalFlags_WILL_CHANGE_IN_PATCH": {
|
||||
"exports": true
|
||||
},
|
||||
"exports": true
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19.3",
|
||||
"@babel/preset-env": "^7.18.10",
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"@microsoft/api-documenter": "^7.19.4",
|
||||
@@ -54,23 +68,25 @@
|
||||
"@typescript-eslint/eslint-plugin": "^5.33.0",
|
||||
"@typescript-eslint/parser": "^5.33.0",
|
||||
"eslint": "^8.21.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-inclusive-language": "^2.2.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-tsdoc": "^0.2.16",
|
||||
"ethers": ">=5.5.1",
|
||||
"ethers": "^5.7.1",
|
||||
"express": "^4.18.1",
|
||||
"next": "12.2.0",
|
||||
"next": "^12.2.0",
|
||||
"next-auth": "^4.10.3",
|
||||
"prettier": "^2.7.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"typescript": "^4.7.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@thirdweb-dev/sdk": "*",
|
||||
"ethers": ">=5.5.1",
|
||||
"express": "^4.18.1",
|
||||
"next": "12.2.0",
|
||||
"next": "^12.2.0",
|
||||
"next-auth": "^4.10.3"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
import loginHandler from "./routes/login";
|
||||
import logoutHandler from "./routes/logout";
|
||||
import userHandler from "./routes/user";
|
||||
import {
|
||||
ThirdwebAuthConfig,
|
||||
ThirdwebAuthRoute,
|
||||
ThirdwebAuthUser,
|
||||
} from "./types";
|
||||
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
import cookieParser from "cookie-parser";
|
||||
import { Express, NextFunction, Request, Response } from "express";
|
||||
|
||||
export * from "./types";
|
||||
|
||||
export function getUser(req: Request): ThirdwebAuthUser | null {
|
||||
return req.user;
|
||||
}
|
||||
|
||||
export function ThirdwebAuth(app: Express, cfg: ThirdwebAuthConfig) {
|
||||
const ctx = {
|
||||
...cfg,
|
||||
sdk: ThirdwebSDK.fromPrivateKey(cfg.privateKey, "mainnet"),
|
||||
};
|
||||
|
||||
const authUrl = cfg.authUrl?.replace(/\/$/, "") || "/auth";
|
||||
|
||||
app.use(cookieParser());
|
||||
|
||||
app.use(async (req: Request, _: Response, next: NextFunction) => {
|
||||
const { sdk, domain } = ctx;
|
||||
let user = null;
|
||||
const token = req.cookies.thirdweb_auth_token;
|
||||
|
||||
if (token) {
|
||||
try {
|
||||
const address = await sdk.auth.authenticate(domain, token);
|
||||
|
||||
if (ctx.callbacks?.user) {
|
||||
user = await ctx.callbacks.user(address);
|
||||
}
|
||||
|
||||
user = { ...user, address };
|
||||
} catch {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
|
||||
req.user = user as ThirdwebAuthUser | null;
|
||||
next();
|
||||
});
|
||||
|
||||
app.get(`${authUrl}/:route`, (req: Request, res: Response) => {
|
||||
const action = req.params.route as ThirdwebAuthRoute;
|
||||
|
||||
switch (action) {
|
||||
case "login":
|
||||
return loginHandler(req, res, ctx);
|
||||
case "user":
|
||||
return userHandler(req, res);
|
||||
case "logout":
|
||||
return logoutHandler(req, res);
|
||||
default:
|
||||
return res.status(400).json({
|
||||
message: "Invalid route for authentication.",
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
+2
-2
@@ -13,7 +13,7 @@ function redirectWithError(req: Request, res: Response, error: string) {
|
||||
export default async function handler(
|
||||
req: Request,
|
||||
res: Response,
|
||||
ctx: ThirdwebAuthContext
|
||||
ctx: ThirdwebAuthContext,
|
||||
) {
|
||||
if (req.method !== "GET") {
|
||||
return redirectWithError(req, res, "INVALID_METHOD");
|
||||
@@ -44,7 +44,7 @@ export default async function handler(
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "strict",
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
if (ctx.callbacks?.login) {
|
||||
+1
-1
@@ -14,7 +14,7 @@ export default async function handler(req: Request, res: Response) {
|
||||
serialize("thirdweb_auth_token", "", {
|
||||
path: "/",
|
||||
expires: new Date(Date.now() + 5 * 1000),
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
return res.status(301).redirect(req.headers.referer as string);
|
||||
+1
-1
@@ -6,6 +6,6 @@ export default async function handler(req: Request, res: Response) {
|
||||
error: "Invalid method. Only GET supported.",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return res.status(200).json(req.user);
|
||||
}
|
||||
+12
-4
@@ -8,8 +8,12 @@ export type ThirdwebAuthConfig = {
|
||||
domain: string;
|
||||
authUrl?: string;
|
||||
callbacks?: {
|
||||
login?: (address: string) => (Promise<void> | void);
|
||||
user?: (address: string) => (Promise<Omit<ThirdwebAuthUser, "address">> | Omit<ThirdwebAuthUser, "address">);
|
||||
login?: (address: string) => Promise<void> | void;
|
||||
user?: (
|
||||
address: string,
|
||||
) =>
|
||||
| Promise<Omit<ThirdwebAuthUser, "address">>
|
||||
| Omit<ThirdwebAuthUser, "address">;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -17,8 +21,12 @@ export type ThirdwebAuthContext = {
|
||||
sdk: ThirdwebSDK;
|
||||
domain: string;
|
||||
callbacks?: {
|
||||
login?: (address: string) => (Promise<void> | void);
|
||||
user?: (address: string) => (Promise<Omit<ThirdwebAuthUser, "address">> | Omit<ThirdwebAuthUser, "address">);
|
||||
login?: (address: string) => Promise<void> | void;
|
||||
user?: (
|
||||
address: string,
|
||||
) =>
|
||||
| Promise<Omit<ThirdwebAuthUser, "address">>
|
||||
| Omit<ThirdwebAuthUser, "address">;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,68 +1 @@
|
||||
import loginHandler from "./routes/login";
|
||||
import logoutHandler from "./routes/logout";
|
||||
import userHandler from "./routes/user";
|
||||
import {
|
||||
ThirdwebAuthConfig,
|
||||
ThirdwebAuthRoute,
|
||||
ThirdwebAuthUser,
|
||||
} from "./types";
|
||||
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
import cookieParser from "cookie-parser";
|
||||
import { Express, NextFunction, Request, Response } from "express";
|
||||
|
||||
export * from "./types";
|
||||
|
||||
export function getUser(req: Request): ThirdwebAuthUser | null {
|
||||
return req.user;
|
||||
}
|
||||
|
||||
export function ThirdwebAuth(app: Express, cfg: ThirdwebAuthConfig) {
|
||||
const ctx = {
|
||||
...cfg,
|
||||
sdk: ThirdwebSDK.fromPrivateKey(cfg.privateKey, "mainnet"),
|
||||
};
|
||||
|
||||
const authUrl = cfg.authUrl?.replace(/\/$/, "") || "/auth";
|
||||
|
||||
app.use(cookieParser());
|
||||
|
||||
app.use(async (req: Request, _: Response, next: NextFunction) => {
|
||||
const { sdk, domain } = ctx;
|
||||
let user = null;
|
||||
const token = req.cookies.thirdweb_auth_token;
|
||||
|
||||
if (token) {
|
||||
try {
|
||||
const address = await sdk.auth.authenticate(domain, token);
|
||||
|
||||
if (ctx.callbacks?.user) {
|
||||
user = await ctx.callbacks.user(address);
|
||||
}
|
||||
|
||||
user = { ...user, address };
|
||||
} catch {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
|
||||
req.user = user as ThirdwebAuthUser | null;
|
||||
next();
|
||||
});
|
||||
|
||||
app.get(`${authUrl}/:route`, (req: Request, res: Response) => {
|
||||
const action = req.params.route as ThirdwebAuthRoute;
|
||||
|
||||
switch (action) {
|
||||
case "login":
|
||||
return loginHandler(req, res, ctx);
|
||||
case "user":
|
||||
return userHandler(req, res);
|
||||
case "logout":
|
||||
return logoutHandler(req, res);
|
||||
default:
|
||||
return res.status(400).json({
|
||||
message: "Invalid route for authentication.",
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
export * from "./evm";
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
import { ThirdwebNextAuthConfig } from "./types";
|
||||
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
import { serialize } from "cookie";
|
||||
import {
|
||||
GetServerSidePropsContext,
|
||||
NextApiRequest,
|
||||
NextApiResponse,
|
||||
} from "next";
|
||||
import NextAuth, {
|
||||
NextAuthOptions,
|
||||
Session,
|
||||
unstable_getServerSession,
|
||||
} from "next-auth";
|
||||
import CredentialsProvider from "next-auth/providers/credentials";
|
||||
|
||||
export function ThirdwebNextAuth(cfg: ThirdwebNextAuthConfig) {
|
||||
const sdk = ThirdwebSDK.fromPrivateKey(cfg.privateKey, "mainnet");
|
||||
|
||||
function ThirdwebProvider(res: GetServerSidePropsContext["res"]) {
|
||||
return CredentialsProvider({
|
||||
name: "ThirdwebAuth",
|
||||
credentials: {
|
||||
payload: {
|
||||
label: "Payload",
|
||||
type: "text",
|
||||
placeholder: "",
|
||||
},
|
||||
},
|
||||
async authorize({ payload }: any) {
|
||||
try {
|
||||
const parsed = JSON.parse(payload);
|
||||
const token = await sdk.auth.generateAuthToken(cfg.domain, parsed);
|
||||
const address = await sdk.auth.authenticate(cfg.domain, 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.setHeader(
|
||||
"Set-Cookie",
|
||||
serialize("thirdweb_auth_token", token, {
|
||||
path: "/",
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "strict",
|
||||
}),
|
||||
);
|
||||
|
||||
return { address };
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function nextOptions(
|
||||
req: GetServerSidePropsContext["req"],
|
||||
res: GetServerSidePropsContext["res"],
|
||||
): NextAuthOptions {
|
||||
async function session({
|
||||
session: _session,
|
||||
}: {
|
||||
session: Session;
|
||||
}): Promise<Session> {
|
||||
const token = req.cookies.thirdweb_auth_token || "";
|
||||
try {
|
||||
const address = await sdk.auth.authenticate(cfg.domain, token);
|
||||
_session.user = { ..._session.user, address } as Session["user"];
|
||||
return _session;
|
||||
} catch {
|
||||
return _session;
|
||||
}
|
||||
}
|
||||
|
||||
function signOut() {
|
||||
res.setHeader(
|
||||
"Set-Cookie",
|
||||
serialize("thirdweb_auth_token", "", {
|
||||
path: "/",
|
||||
expires: new Date(Date.now() + 5 * 1000),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
const providers: NextAuthOptions["providers"] = [
|
||||
...cfg.nextOptions.providers,
|
||||
ThirdwebProvider(res),
|
||||
];
|
||||
|
||||
const configSession = cfg.nextOptions.callbacks?.session;
|
||||
const callbacks: NextAuthOptions["callbacks"] = {
|
||||
...cfg.nextOptions.callbacks,
|
||||
session: configSession
|
||||
? async (params) => {
|
||||
params.session = await session(params);
|
||||
return configSession(params);
|
||||
}
|
||||
: session,
|
||||
};
|
||||
|
||||
const configSignOut = cfg.nextOptions.events?.signOut;
|
||||
const events: NextAuthOptions["events"] = {
|
||||
...cfg.nextOptions.events,
|
||||
signOut: configSignOut
|
||||
? async (params) => {
|
||||
signOut();
|
||||
return configSignOut(params);
|
||||
}
|
||||
: signOut,
|
||||
};
|
||||
|
||||
return {
|
||||
...cfg.nextOptions,
|
||||
providers,
|
||||
callbacks,
|
||||
events,
|
||||
};
|
||||
}
|
||||
|
||||
async function getUser(
|
||||
...args:
|
||||
| [NextApiRequest, NextApiResponse]
|
||||
| [GetServerSidePropsContext["req"], GetServerSidePropsContext["res"]]
|
||||
) {
|
||||
return unstable_getServerSession(
|
||||
args[0],
|
||||
args[1],
|
||||
nextOptions(args[0], args[1]),
|
||||
);
|
||||
}
|
||||
|
||||
function NextAuthHandler(...args: [] | [NextApiRequest, NextApiResponse]) {
|
||||
if (args.length === 0) {
|
||||
return (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return NextAuth(req, res, nextOptions(req, res));
|
||||
};
|
||||
}
|
||||
|
||||
return NextAuth(args[0], args[1], nextOptions(args[0], args[1]));
|
||||
}
|
||||
|
||||
return {
|
||||
NextAuthHandler,
|
||||
getUser,
|
||||
};
|
||||
}
|
||||
+1
-1
@@ -4,4 +4,4 @@ export type ThirdwebNextAuthConfig = {
|
||||
privateKey: string;
|
||||
domain: string;
|
||||
nextOptions: NextAuthOptions;
|
||||
}
|
||||
};
|
||||
@@ -1,135 +1 @@
|
||||
import { ThirdwebNextAuthConfig } from "./types";
|
||||
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
import { serialize } from "cookie";
|
||||
import { GetServerSidePropsContext, NextApiRequest, NextApiResponse } from "next";
|
||||
import NextAuth, { NextAuthOptions, Session, unstable_getServerSession } from "next-auth";
|
||||
import CredentialsProvider from "next-auth/providers/credentials";
|
||||
|
||||
export function ThirdwebNextAuth(cfg: ThirdwebNextAuthConfig) {
|
||||
const sdk = ThirdwebSDK.fromPrivateKey(cfg.privateKey, "mainnet");
|
||||
|
||||
function ThirdwebProvider(res: GetServerSidePropsContext["res"]) {
|
||||
return CredentialsProvider({
|
||||
name: "ThirdwebAuth",
|
||||
credentials: {
|
||||
payload: {
|
||||
label: "Payload",
|
||||
type: "text",
|
||||
placeholder: "",
|
||||
},
|
||||
},
|
||||
async authorize({ payload }: any) {
|
||||
try {
|
||||
const parsed = JSON.parse(payload);
|
||||
const token = await sdk.auth.generateAuthToken(
|
||||
cfg.domain,
|
||||
parsed
|
||||
);
|
||||
const address = await sdk.auth.authenticate(cfg.domain, 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.setHeader(
|
||||
"Set-Cookie",
|
||||
serialize("thirdweb_auth_token", token, {
|
||||
path: "/",
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "strict",
|
||||
})
|
||||
);
|
||||
|
||||
return { address };
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function nextOptions (
|
||||
req: GetServerSidePropsContext["req"],
|
||||
res: GetServerSidePropsContext["res"]
|
||||
): NextAuthOptions {
|
||||
|
||||
async function session({ session }: { session: Session }) {
|
||||
const token = req.cookies.thirdweb_auth_token || "";
|
||||
try {
|
||||
const address = await sdk.auth.authenticate(cfg.domain, token);
|
||||
session.user = { ...session.user, address } as Session["user"];
|
||||
return session;
|
||||
} catch {
|
||||
return session;
|
||||
}
|
||||
}
|
||||
|
||||
function signOut() {
|
||||
res.setHeader(
|
||||
"Set-Cookie",
|
||||
serialize("thirdweb_auth_token", "", {
|
||||
path: "/",
|
||||
expires: new Date(Date.now() + 5 * 1000),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
const providers: NextAuthOptions["providers"] = [
|
||||
...cfg.nextOptions.providers,
|
||||
ThirdwebProvider(res),
|
||||
]
|
||||
|
||||
const configSession = cfg.nextOptions.callbacks?.session
|
||||
const callbacks: NextAuthOptions["callbacks"] = {
|
||||
...cfg.nextOptions.callbacks,
|
||||
session: configSession
|
||||
? async (params) => {
|
||||
params.session = await session(params);
|
||||
return configSession(params);
|
||||
}
|
||||
: session
|
||||
};
|
||||
|
||||
const configSignOut = cfg.nextOptions.events?.signOut
|
||||
const events: NextAuthOptions["events"] = {
|
||||
...cfg.nextOptions.events,
|
||||
signOut: configSignOut
|
||||
? async (params) => {
|
||||
signOut();
|
||||
return configSignOut(params);
|
||||
}
|
||||
: signOut
|
||||
};
|
||||
|
||||
return {
|
||||
...cfg.nextOptions,
|
||||
providers,
|
||||
callbacks,
|
||||
events,
|
||||
};
|
||||
};
|
||||
|
||||
async function getUser(
|
||||
...args:
|
||||
| [NextApiRequest, NextApiResponse]
|
||||
| [GetServerSidePropsContext["req"], GetServerSidePropsContext["res"]]
|
||||
) {
|
||||
return unstable_getServerSession(args[0], args[1], nextOptions(args[0], args[1]));
|
||||
}
|
||||
|
||||
function NextAuthHandler(
|
||||
...args: [] | [NextApiRequest, NextApiResponse]
|
||||
) {
|
||||
if (args.length === 0) {
|
||||
return (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return NextAuth(req, res, nextOptions(req, res));
|
||||
}
|
||||
}
|
||||
|
||||
return NextAuth(args[0], args[1], nextOptions(args[0], args[1]));
|
||||
}
|
||||
|
||||
return {
|
||||
NextAuthHandler,
|
||||
getUser
|
||||
}
|
||||
}
|
||||
export * from "./evm";
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import loginHandler from "./routes/login";
|
||||
import logoutHandler from "./routes/logout";
|
||||
import userHandler from "./routes/user";
|
||||
import {
|
||||
ThirdwebAuthConfig,
|
||||
ThirdwebAuthContext,
|
||||
ThirdwebAuthRoute,
|
||||
ThirdwebAuthUser,
|
||||
} from "./types";
|
||||
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
import { NextRequest } from "next/server";
|
||||
import {
|
||||
GetServerSidePropsContext,
|
||||
NextApiRequest,
|
||||
NextApiResponse,
|
||||
} from "next/types";
|
||||
|
||||
export * from "./types";
|
||||
|
||||
async function ThirdwebAuthRouter(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
ctx: ThirdwebAuthContext,
|
||||
) {
|
||||
// Catch-all route must be named with [...thirdweb]
|
||||
const { thirdweb } = req.query;
|
||||
const action = thirdweb?.[0] as ThirdwebAuthRoute;
|
||||
|
||||
switch (action) {
|
||||
case "login":
|
||||
return await loginHandler(req, res, ctx);
|
||||
case "user":
|
||||
return await userHandler(req, res, ctx);
|
||||
case "logout":
|
||||
return await logoutHandler(req, res);
|
||||
default:
|
||||
return res.status(400).json({
|
||||
message: "Invalid route for authentication.",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function ThirdwebAuth(cfg: ThirdwebAuthConfig) {
|
||||
const ctx = {
|
||||
...cfg,
|
||||
sdk: ThirdwebSDK.fromPrivateKey(cfg.privateKey, "mainnet"),
|
||||
};
|
||||
|
||||
function ThirdwebAuthHandler(
|
||||
...args: [] | [NextApiRequest, NextApiResponse]
|
||||
) {
|
||||
if (args.length === 0) {
|
||||
return async (req: NextApiRequest, res: NextApiResponse) =>
|
||||
await ThirdwebAuthRouter(req, res, ctx);
|
||||
}
|
||||
|
||||
return ThirdwebAuthRouter(args[0], args[1], ctx);
|
||||
}
|
||||
|
||||
async function getUser(
|
||||
req: GetServerSidePropsContext["req"] | NextRequest | NextApiRequest,
|
||||
) {
|
||||
const { sdk, domain } = ctx;
|
||||
let user: ThirdwebAuthUser | null = null;
|
||||
const token =
|
||||
typeof req.cookies.get === "function"
|
||||
? (req.cookies as any).get("thirdweb_auth_token")
|
||||
: (req.cookies as any).thirdweb_auth_token;
|
||||
|
||||
if (token) {
|
||||
try {
|
||||
const address = await sdk.auth.authenticate(domain, token);
|
||||
user = { address };
|
||||
} catch {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
return { ThirdwebAuthHandler, getUser };
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import { NextApiRequest, NextApiResponse } from "next";
|
||||
function redirectWithError(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
error: string
|
||||
error: string,
|
||||
) {
|
||||
const encodedError = encodeURIComponent(error);
|
||||
const url = new URL(req.headers.referer as string);
|
||||
@@ -17,7 +17,7 @@ function redirectWithError(
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
ctx: ThirdwebAuthContext
|
||||
ctx: ThirdwebAuthContext,
|
||||
) {
|
||||
if (req.method !== "GET") {
|
||||
return redirectWithError(req, res, "INVALID_METHOD");
|
||||
@@ -48,7 +48,7 @@ export default async function handler(
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "strict",
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
if (ctx.callbacks?.login) {
|
||||
+2
-2
@@ -3,7 +3,7 @@ import { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
res: NextApiResponse,
|
||||
) {
|
||||
if (req.method !== "GET") {
|
||||
return res.status(400).json({
|
||||
@@ -17,7 +17,7 @@ export default async function handler(
|
||||
serialize("thirdweb_auth_token", "", {
|
||||
path: "/",
|
||||
expires: new Date(Date.now() + 5 * 1000),
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
return res.status(301).redirect(req.headers.referer as string);
|
||||
@@ -4,14 +4,14 @@ import { NextApiRequest, NextApiResponse } from "next";
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
ctx: ThirdwebAuthContext
|
||||
ctx: ThirdwebAuthContext,
|
||||
) {
|
||||
if (req.method !== "GET") {
|
||||
return res.status(400).json({
|
||||
error: "Invalid method. Only GET supported.",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const { sdk, domain } = ctx;
|
||||
let user = null;
|
||||
const token = req.cookies.thirdweb_auth_token;
|
||||
@@ -6,8 +6,12 @@ export type ThirdwebAuthConfig = {
|
||||
privateKey: string;
|
||||
domain: string;
|
||||
callbacks?: {
|
||||
login?: (address: string) => (Promise<void> | void);
|
||||
user?: (address: string) => (Promise<Omit<ThirdwebAuthUser, "address">> | Omit<ThirdwebAuthUser, "address">);
|
||||
login?: (address: string) => Promise<void> | void;
|
||||
user?: (
|
||||
address: string,
|
||||
) =>
|
||||
| Promise<Omit<ThirdwebAuthUser, "address">>
|
||||
| Omit<ThirdwebAuthUser, "address">;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -15,8 +19,12 @@ export type ThirdwebAuthContext = {
|
||||
sdk: ThirdwebSDK;
|
||||
domain: string;
|
||||
callbacks?: {
|
||||
login?: (address: string) => (Promise<void> | void);
|
||||
user?: (address: string) => (Promise<Omit<ThirdwebAuthUser, "address">> | Omit<ThirdwebAuthUser, "address">);
|
||||
login?: (address: string) => Promise<void> | void;
|
||||
user?: (
|
||||
address: string,
|
||||
) =>
|
||||
| Promise<Omit<ThirdwebAuthUser, "address">>
|
||||
| Omit<ThirdwebAuthUser, "address">;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,83 +1 @@
|
||||
import loginHandler from "./routes/login";
|
||||
import logoutHandler from "./routes/logout";
|
||||
import userHandler from "./routes/user";
|
||||
import {
|
||||
ThirdwebAuthConfig,
|
||||
ThirdwebAuthContext,
|
||||
ThirdwebAuthRoute,
|
||||
ThirdwebAuthUser,
|
||||
} from "./types";
|
||||
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
import { NextRequest } from "next/server";
|
||||
import {
|
||||
GetServerSidePropsContext,
|
||||
NextApiRequest,
|
||||
NextApiResponse,
|
||||
} from "next/types";
|
||||
|
||||
export * from "./types";
|
||||
|
||||
async function ThirdwebAuthRouter(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
ctx: ThirdwebAuthContext
|
||||
) {
|
||||
// Catch-all route must be named with [...thirdweb]
|
||||
const { thirdweb } = req.query;
|
||||
const action = thirdweb?.[0] as ThirdwebAuthRoute;
|
||||
|
||||
switch (action) {
|
||||
case "login":
|
||||
return await loginHandler(req, res, ctx);
|
||||
case "user":
|
||||
return await userHandler(req, res, ctx);
|
||||
case "logout":
|
||||
return await logoutHandler(req, res);
|
||||
default:
|
||||
return res.status(400).json({
|
||||
message: "Invalid route for authentication.",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function ThirdwebAuth(cfg: ThirdwebAuthConfig) {
|
||||
const ctx = {
|
||||
...cfg,
|
||||
sdk: ThirdwebSDK.fromPrivateKey(cfg.privateKey, "mainnet"),
|
||||
};
|
||||
|
||||
function ThirdwebAuthHandler(
|
||||
...args: [] | [NextApiRequest, NextApiResponse]
|
||||
) {
|
||||
if (args.length === 0) {
|
||||
return async (req: NextApiRequest, res: NextApiResponse) =>
|
||||
await ThirdwebAuthRouter(req, res, ctx);
|
||||
}
|
||||
|
||||
return ThirdwebAuthRouter(args[0], args[1], ctx);
|
||||
}
|
||||
|
||||
async function getUser(
|
||||
req: GetServerSidePropsContext["req"] | NextRequest | NextApiRequest
|
||||
) {
|
||||
const { sdk, domain } = ctx;
|
||||
let user: ThirdwebAuthUser | null = null;
|
||||
const token =
|
||||
typeof req.cookies.get === "function"
|
||||
? (req.cookies as any).get("thirdweb_auth_token")
|
||||
: (req.cookies as any).thirdweb_auth_token;
|
||||
|
||||
if (token) {
|
||||
try {
|
||||
const address = await sdk.auth.authenticate(domain, token);
|
||||
user = { address };
|
||||
} catch {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
return { ThirdwebAuthHandler, getUser };
|
||||
}
|
||||
export * from "./evm";
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import loginHandler from "./routes/login";
|
||||
import logoutHandler from "./routes/logout";
|
||||
import userHandler from "./routes/user";
|
||||
import {
|
||||
ThirdwebAuthConfig,
|
||||
ThirdwebAuthContext,
|
||||
ThirdwebAuthRoute,
|
||||
ThirdwebAuthUser,
|
||||
} from "./types";
|
||||
import { ThirdwebSDK } from "@thirdweb-dev/sdk/solana";
|
||||
import { NextRequest } from "next/server";
|
||||
import {
|
||||
GetServerSidePropsContext,
|
||||
NextApiRequest,
|
||||
NextApiResponse,
|
||||
} from "next/types";
|
||||
|
||||
export * from "./types";
|
||||
|
||||
async function ThirdwebAuthRouter(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
ctx: ThirdwebAuthContext,
|
||||
) {
|
||||
// Catch-all route must be named with [...thirdweb]
|
||||
const { thirdweb } = req.query;
|
||||
const action = thirdweb?.[0] as ThirdwebAuthRoute;
|
||||
|
||||
switch (action) {
|
||||
case "login":
|
||||
return await loginHandler(req, res, ctx);
|
||||
case "user":
|
||||
return await userHandler(req, res, ctx);
|
||||
case "logout":
|
||||
return await logoutHandler(req, res);
|
||||
default:
|
||||
return res.status(400).json({
|
||||
message: "Invalid route for authentication.",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function ThirdwebAuth(cfg: ThirdwebAuthConfig) {
|
||||
const ctx = {
|
||||
...cfg,
|
||||
sdk: ThirdwebSDK.fromPrivateKey("mainnet-beta", cfg.privateKey),
|
||||
};
|
||||
|
||||
function ThirdwebAuthHandler(
|
||||
...args: [] | [NextApiRequest, NextApiResponse]
|
||||
) {
|
||||
if (args.length === 0) {
|
||||
return async (req: NextApiRequest, res: NextApiResponse) =>
|
||||
await ThirdwebAuthRouter(req, res, ctx);
|
||||
}
|
||||
|
||||
return ThirdwebAuthRouter(args[0], args[1], ctx);
|
||||
}
|
||||
|
||||
async function getUser(
|
||||
req: GetServerSidePropsContext["req"] | NextRequest | NextApiRequest,
|
||||
) {
|
||||
const { sdk, domain } = ctx;
|
||||
let user: ThirdwebAuthUser | null = null;
|
||||
const token =
|
||||
typeof req.cookies.get === "function"
|
||||
? (req.cookies as any).get("thirdweb_auth_token")
|
||||
: (req.cookies as any).thirdweb_auth_token;
|
||||
|
||||
if (token) {
|
||||
try {
|
||||
const address = await sdk.auth.authenticate(domain, token);
|
||||
user = { address };
|
||||
} catch {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
return { ThirdwebAuthHandler, getUser };
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import { ThirdwebAuthContext } from "../types";
|
||||
import { LoginPayload } from "@thirdweb-dev/sdk";
|
||||
import { serialize } from "cookie";
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
function redirectWithError(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
error: string,
|
||||
) {
|
||||
const encodedError = encodeURIComponent(error);
|
||||
const url = new URL(req.headers.referer as string);
|
||||
url.searchParams.set("error", encodedError);
|
||||
return res.redirect(url.toString());
|
||||
}
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
ctx: ThirdwebAuthContext,
|
||||
) {
|
||||
if (req.method !== "GET") {
|
||||
return redirectWithError(req, res, "INVALID_METHOD");
|
||||
}
|
||||
|
||||
const { sdk, domain } = ctx;
|
||||
|
||||
// Get signed login payload from the frontend
|
||||
const payload = JSON.parse(atob(req.query.payload as string)) as LoginPayload;
|
||||
if (!payload) {
|
||||
redirectWithError(req, res, "MISSING_LOGIN_PAYLOAD");
|
||||
}
|
||||
|
||||
let token;
|
||||
try {
|
||||
// Generate an access token with the SDK using the signed payload
|
||||
token = await sdk.auth.generateAuthToken(domain, payload);
|
||||
} catch {
|
||||
return redirectWithError(req, res, "INVALID_LOGIN_PAYLOAD");
|
||||
}
|
||||
|
||||
// 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.setHeader(
|
||||
"Set-Cookie",
|
||||
serialize("thirdweb_auth_token", token, {
|
||||
path: "/",
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "strict",
|
||||
}),
|
||||
);
|
||||
|
||||
if (ctx.callbacks?.login) {
|
||||
const address = sdk.auth.verify(domain, payload);
|
||||
await ctx.callbacks.login(address);
|
||||
}
|
||||
|
||||
return res.status(301).redirect(req.query.redirect as string);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { serialize } from "cookie";
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
) {
|
||||
if (req.method !== "GET") {
|
||||
return res.status(400).json({
|
||||
error: "Invalid method. Only GET supported.",
|
||||
});
|
||||
}
|
||||
|
||||
// Set the access token to 'none' and expire in 5 seconds
|
||||
res.setHeader(
|
||||
"Set-Cookie",
|
||||
serialize("thirdweb_auth_token", "", {
|
||||
path: "/",
|
||||
expires: new Date(Date.now() + 5 * 1000),
|
||||
}),
|
||||
);
|
||||
|
||||
return res.status(301).redirect(req.headers.referer as string);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { ThirdwebAuthContext, ThirdwebAuthUser } from "../types";
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
ctx: ThirdwebAuthContext,
|
||||
) {
|
||||
if (req.method !== "GET") {
|
||||
return res.status(400).json({
|
||||
error: "Invalid method. Only GET supported.",
|
||||
});
|
||||
}
|
||||
|
||||
const { sdk, domain } = ctx;
|
||||
let user = null;
|
||||
const token = req.cookies.thirdweb_auth_token;
|
||||
|
||||
if (token) {
|
||||
try {
|
||||
const address = await sdk.auth.authenticate(domain, token);
|
||||
|
||||
if (ctx.callbacks?.user) {
|
||||
user = await ctx.callbacks.user(address);
|
||||
}
|
||||
|
||||
user = { ...user, address };
|
||||
} catch {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
|
||||
return res.status(200).json(user as ThirdwebAuthUser | null);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { ThirdwebSDK } from "@thirdweb-dev/sdk/solana";
|
||||
|
||||
export type ThirdwebAuthRoute = "login" | "logout" | "user";
|
||||
|
||||
export type ThirdwebAuthConfig = {
|
||||
privateKey: string;
|
||||
domain: string;
|
||||
callbacks?: {
|
||||
login?: (address: string) => Promise<void> | void;
|
||||
user?: (
|
||||
address: string,
|
||||
) =>
|
||||
| Promise<Omit<ThirdwebAuthUser, "address">>
|
||||
| Omit<ThirdwebAuthUser, "address">;
|
||||
};
|
||||
};
|
||||
|
||||
export type ThirdwebAuthContext = {
|
||||
sdk: ThirdwebSDK;
|
||||
domain: string;
|
||||
callbacks?: {
|
||||
login?: (address: string) => Promise<void> | void;
|
||||
user?: (
|
||||
address: string,
|
||||
) =>
|
||||
| Promise<Omit<ThirdwebAuthUser, "address">>
|
||||
| Omit<ThirdwebAuthUser, "address">;
|
||||
};
|
||||
};
|
||||
|
||||
export type ThirdwebAuthUser = {
|
||||
address: string;
|
||||
[key: string]: any;
|
||||
};
|
||||
@@ -1,5 +1,259 @@
|
||||
# thirdweb
|
||||
|
||||
## 0.8.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`21c21c1`](https://github.com/thirdweb-dev/js/commit/21c21c1adfd09b60ad563bfd4c308597140de33c), [`3522917`](https://github.com/thirdweb-dev/js/commit/352291791ee900e1500f84f095290497934d2f60)]:
|
||||
- @thirdweb-dev/sdk@3.4.2
|
||||
|
||||
## 0.8.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`72227b2`](https://github.com/thirdweb-dev/js/commit/72227b2e166a3a68bbb41cf2b389322f5b7547a2)]:
|
||||
- @thirdweb-dev/sdk@3.4.1
|
||||
|
||||
## 0.8.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#327](https://github.com/thirdweb-dev/js/pull/327) [`ef27aad`](https://github.com/thirdweb-dev/js/commit/ef27aad0aafc4577e85f44dc77dfbe880bd239b5) Thanks [@jnsdls](https://github.com/jnsdls)! - enable e2e testing
|
||||
|
||||
- Updated dependencies [[`340605b`](https://github.com/thirdweb-dev/js/commit/340605b507f384fbd2999b9c16542af3c53e84a9), [`26116a6`](https://github.com/thirdweb-dev/js/commit/26116a6f637ee845f7bd17f20ffe17caf184658e), [`15f8006`](https://github.com/thirdweb-dev/js/commit/15f8006e1fb22333b7ee239b45e7b1b12d6dccc8), [`ef27aad`](https://github.com/thirdweb-dev/js/commit/ef27aad0aafc4577e85f44dc77dfbe880bd239b5)]:
|
||||
- @thirdweb-dev/sdk@3.4.0
|
||||
|
||||
## 0.8.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ad851f7`](https://github.com/thirdweb-dev/js/commit/ad851f7b4d6abb5ab9364ef3dec229f913e18ce5), [`6218c88`](https://github.com/thirdweb-dev/js/commit/6218c885842e6b4e44ec38ec92a9211e56c49bf4)]:
|
||||
- @thirdweb-dev/sdk@3.3.1
|
||||
|
||||
## 0.8.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#326](https://github.com/thirdweb-dev/js/pull/326) [`126752d`](https://github.com/thirdweb-dev/js/commit/126752d7d02c9a808a63fb9e67a9df6658b5682b) Thanks [@jnsdls](https://github.com/jnsdls)! - remove tons of unused dependencies, use SDK function for extracting ipfs has from bytecode
|
||||
|
||||
- Updated dependencies [[`126752d`](https://github.com/thirdweb-dev/js/commit/126752d7d02c9a808a63fb9e67a9df6658b5682b), [`df74340`](https://github.com/thirdweb-dev/js/commit/df74340fa51323304c32419761d6f18628b060fa), [`89ff921`](https://github.com/thirdweb-dev/js/commit/89ff921a7d9f0e42b4e6707c8b56d0aab95c1aa0), [`a57b4f0`](https://github.com/thirdweb-dev/js/commit/a57b4f01f3a49590b897101f2730582e4124a554)]:
|
||||
- @thirdweb-dev/sdk@3.3.0
|
||||
|
||||
## 0.8.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`4f867e1`](https://github.com/thirdweb-dev/js/commit/4f867e15edbe5757afbf54cab207458711a8986c), [`b6eec61`](https://github.com/thirdweb-dev/js/commit/b6eec6146c23b66a3681bbb48b173b9019254214), [`9727502`](https://github.com/thirdweb-dev/js/commit/9727502eb30ac139382b7c7c8e8fc0967cbfbcf1), [`782b58d`](https://github.com/thirdweb-dev/js/commit/782b58d3f6a3b49ff9b3d837551db5161f96171a), [`f41a443`](https://github.com/thirdweb-dev/js/commit/f41a443c5785240197607b5bf93ff18a1c8e8307), [`f45ef62`](https://github.com/thirdweb-dev/js/commit/f45ef62128cfefe06275a38440c90d45e9f3cef7), [`2f8ec89`](https://github.com/thirdweb-dev/js/commit/2f8ec89c4c83ae577092c840c198e6fcfb114e69), [`b7cd744`](https://github.com/thirdweb-dev/js/commit/b7cd744cd0482a6c3fe5ae0c858f20cd380d4114), [`53c6507`](https://github.com/thirdweb-dev/js/commit/53c65076696a43bd9a7e58a7493d4e65c172900f)]:
|
||||
- @thirdweb-dev/sdk@3.2.6
|
||||
|
||||
## 0.8.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`712b11a`](https://github.com/thirdweb-dev/js/commit/712b11a43e389ae10b7f09648779a69c05b2c913)]:
|
||||
- @thirdweb-dev/sdk@3.2.5
|
||||
|
||||
## 0.8.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/sdk@3.2.4
|
||||
|
||||
## 0.8.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/sdk@3.2.3
|
||||
|
||||
## 0.8.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#276](https://github.com/thirdweb-dev/js/pull/276) [`24514a6`](https://github.com/thirdweb-dev/js/commit/24514a6e9fc1316622c1494e5be225e53f88d26e) Thanks [@furqanrydhan](https://github.com/furqanrydhan)! - build is now default compile command, reorganized the help list
|
||||
|
||||
- [#279](https://github.com/thirdweb-dev/js/pull/279) [`1918495`](https://github.com/thirdweb-dev/js/commit/1918495f2ee7f50d94083d9577dab0bf1c828c94) Thanks [@furqanrydhan](https://github.com/furqanrydhan)! - Updating command list order, helper text and changed detect -> build
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#277](https://github.com/thirdweb-dev/js/pull/277) [`9de3f8c`](https://github.com/thirdweb-dev/js/commit/9de3f8c8e954733bfc3eb6e8e0e786ff5b296f0c) Thanks [@adam-maj](https://github.com/adam-maj)! - Add recursive folder upload support
|
||||
|
||||
- [#268](https://github.com/thirdweb-dev/js/pull/268) [`57b9c67`](https://github.com/thirdweb-dev/js/commit/57b9c671aaf7fce0076dd332c171ba6944752e7a) Thanks [@adam-maj](https://github.com/adam-maj)! - Update storage upload cLI
|
||||
|
||||
- Updated dependencies [[`521a49c`](https://github.com/thirdweb-dev/js/commit/521a49c6ec6a73068adcfbc1d94d2f3f17afae86), [`8b3b97c`](https://github.com/thirdweb-dev/js/commit/8b3b97c8f7b3710ce62ed86cfeb4f6de3c23d559), [`25a4773`](https://github.com/thirdweb-dev/js/commit/25a4773bba406f4e270ac86e68c5266d24c08330), [`b2cadf1`](https://github.com/thirdweb-dev/js/commit/b2cadf164cfe9fb27081df7530356baf70ec2b3a), [`d6bb61b`](https://github.com/thirdweb-dev/js/commit/d6bb61b7fac759fff7d6293edd46f693f5a7889c), [`78d6d3c`](https://github.com/thirdweb-dev/js/commit/78d6d3c15968a449924b3f24354e151a90e4b20d), [`89d87a5`](https://github.com/thirdweb-dev/js/commit/89d87a5eb31e78e68e097718e9ae6e4c4d101868), [`41507d3`](https://github.com/thirdweb-dev/js/commit/41507d32a78c556f50c88de81c4d6109b1783c78), [`8096c78`](https://github.com/thirdweb-dev/js/commit/8096c78b466a7f5f9c2aac6e2c56a06f9d3a25d6), [`b1fa171`](https://github.com/thirdweb-dev/js/commit/b1fa17158dcac00265bc8f4d64f1f9708482cdb5), [`18381fa`](https://github.com/thirdweb-dev/js/commit/18381fac73741826934212ac6441842ed42a64a0), [`df048af`](https://github.com/thirdweb-dev/js/commit/df048af605f449279b01d7352b604e7856ac223c), [`d6bb61b`](https://github.com/thirdweb-dev/js/commit/d6bb61b7fac759fff7d6293edd46f693f5a7889c), [`cf88795`](https://github.com/thirdweb-dev/js/commit/cf88795376d3110f9d3aa839928d22276904b15a), [`89b5c6f`](https://github.com/thirdweb-dev/js/commit/89b5c6fe079e4df2cf12cb557aa9784f88c5d159)]:
|
||||
- @thirdweb-dev/sdk@3.2.2
|
||||
|
||||
## 0.7.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#259](https://github.com/thirdweb-dev/js/pull/259) [`6f95a52`](https://github.com/thirdweb-dev/js/commit/6f95a520e6cc69e08f734705e8adc71431b091cc) Thanks [@adam-maj](https://github.com/adam-maj)! - Add npx thirdweb upload command
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/sdk@3.2.1
|
||||
|
||||
## 0.7.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#246](https://github.com/thirdweb-dev/js/pull/246) [`ef0bac7`](https://github.com/thirdweb-dev/js/commit/ef0bac7f44b93939bfc9e2706b39edaa22992eec) Thanks [@simonlim94](https://github.com/simonlim94)! - Renamed initial commit message during thirdweb cli createApp
|
||||
|
||||
- Updated dependencies [[`ba6f450`](https://github.com/thirdweb-dev/js/commit/ba6f45027a6ec11aebb4a1918ab2ba4f88894ede), [`c8261b7`](https://github.com/thirdweb-dev/js/commit/c8261b74b5828ac66ea3a6d7636aa57e40ea1a14), [`20745f8`](https://github.com/thirdweb-dev/js/commit/20745f8cd603235eb5039e61a39c0959c5860bca), [`2ea3f00`](https://github.com/thirdweb-dev/js/commit/2ea3f00c41b5e70d9bb634cd86790890520fc4d6), [`9412d41`](https://github.com/thirdweb-dev/js/commit/9412d416832c87ab2c858cb120c6c5de03459c50), [`d677e9d`](https://github.com/thirdweb-dev/js/commit/d677e9d6341252013762882d25408ea8f93791e5), [`e662408`](https://github.com/thirdweb-dev/js/commit/e662408e1936983485936609552f80a56cbed082), [`e4b10bc`](https://github.com/thirdweb-dev/js/commit/e4b10bc5bd12178cba8856b60255732123cb7ae5), [`caf9795`](https://github.com/thirdweb-dev/js/commit/caf979537b5acb1610f182c94afa5d95c208ec3f), [`028cb78`](https://github.com/thirdweb-dev/js/commit/028cb781252b0050943b14cfdf38132c18753a4b), [`1972f3e`](https://github.com/thirdweb-dev/js/commit/1972f3ec0d511fbc17642b2a30852a177092a09e), [`6647f70`](https://github.com/thirdweb-dev/js/commit/6647f707bdd050725264a8a74220c11912f68e57), [`cac373b`](https://github.com/thirdweb-dev/js/commit/cac373b010ce3be3615a36671b66815a27785061)]:
|
||||
- @thirdweb-dev/sdk@3.2.0
|
||||
|
||||
## 0.7.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#103](https://github.com/thirdweb-dev/js/pull/103) [`e1bcc67`](https://github.com/thirdweb-dev/js/commit/e1bcc67cebfc95fce615439ff03871b4fef0eed9) Thanks [@b4s36t4](https://github.com/b4s36t4)! - automatically re-name the created example repo to the user provided app name
|
||||
|
||||
- Updated dependencies [[`8239763`](https://github.com/thirdweb-dev/js/commit/82397636f41faa2b44cfe70e75212f0f42291092), [`27a30e3`](https://github.com/thirdweb-dev/js/commit/27a30e3ffb56dd7fa8412a066bc3ac0977aca8e2), [`f2a6211`](https://github.com/thirdweb-dev/js/commit/f2a62110c43e7b8f35c86a197730e732f8fcc786), [`d26b768`](https://github.com/thirdweb-dev/js/commit/d26b76872a6c85651ee06aa0732ee2967f70db27), [`ba7dcbb`](https://github.com/thirdweb-dev/js/commit/ba7dcbbad8db2b73baf1435f4175d19933cb7d4f), [`9c8a3fb`](https://github.com/thirdweb-dev/js/commit/9c8a3fb6d4520dd6cdf2d1c17f33b764e871599e)]:
|
||||
- @thirdweb-dev/sdk@3.1.2
|
||||
|
||||
## 0.7.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`666ff5f`](https://github.com/thirdweb-dev/js/commit/666ff5f694f1e146150ddb9fa3233f00533b6d60), [`0dade96`](https://github.com/thirdweb-dev/js/commit/0dade96d0d2553d25b386d822e534eb7ed0aefa9), [`c295a47`](https://github.com/thirdweb-dev/js/commit/c295a47144cd722c6f8861c1ec567b53a05ea0bf)]:
|
||||
- @thirdweb-dev/sdk@3.1.1
|
||||
|
||||
## 0.7.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3c8f620`](https://github.com/thirdweb-dev/js/commit/3c8f6205e9b49ae9fea1f9629678210c6c9c36e6), [`e187d21`](https://github.com/thirdweb-dev/js/commit/e187d21e123a506fac0459da18f2d4fc94abae29), [`acbabc8`](https://github.com/thirdweb-dev/js/commit/acbabc8999b2b7b6e0eb89cae97e2f1ef7143501), [`b030a86`](https://github.com/thirdweb-dev/js/commit/b030a866080953bbf4e504ddc41d7050b250d2d7)]:
|
||||
- @thirdweb-dev/sdk@3.1.0
|
||||
|
||||
## 0.7.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ce05bfd`](https://github.com/thirdweb-dev/js/commit/ce05bfd8615a9c79664856bce53de8b43bed5c87)]:
|
||||
- @thirdweb-dev/sdk@3.0.8
|
||||
|
||||
## 0.7.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`5f5ab01`](https://github.com/thirdweb-dev/js/commit/5f5ab015e1dd3c471d6affe995ef36ec88932b3c)]:
|
||||
- @thirdweb-dev/sdk@3.0.7
|
||||
|
||||
## 0.7.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a80fc97`](https://github.com/thirdweb-dev/js/commit/a80fc97b6a1e72ed46a400b4b602e180947fb870)]:
|
||||
- @thirdweb-dev/sdk@3.0.6
|
||||
|
||||
## 0.7.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#172](https://github.com/thirdweb-dev/js/pull/172) [`89db3db`](https://github.com/thirdweb-dev/js/commit/89db3db7ff3d5af7e7a7b5f25e299b9faad44eb0) Thanks [@adam-maj](https://github.com/adam-maj)! - Add thirdweb deploy to end of thirdweb detect and yarn build to thirdweb create
|
||||
|
||||
- [#175](https://github.com/thirdweb-dev/js/pull/175) [`3332fa5`](https://github.com/thirdweb-dev/js/commit/3332fa5697b9ff2a4ded1f2c508304f59f434be2) Thanks [@adam-maj](https://github.com/adam-maj)! - Split create contract flow into two steps
|
||||
|
||||
- [#177](https://github.com/thirdweb-dev/js/pull/177) [`3edec39`](https://github.com/thirdweb-dev/js/commit/3edec391be169453aaee412846005a820939fab0) Thanks [@adam-maj](https://github.com/adam-maj)! - thirdweb deploy redirects to contract deploy page if no contracts detected
|
||||
|
||||
- [#184](https://github.com/thirdweb-dev/js/pull/184) [`bdec5a5`](https://github.com/thirdweb-dev/js/commit/bdec5a59af680802e206e3025b2c463fc7dcb740) Thanks [@aeither](https://github.com/aeither)! - Fix "Invalid Project name" when a project with a capital letter is entered
|
||||
|
||||
- Updated dependencies [[`4169b94`](https://github.com/thirdweb-dev/js/commit/4169b9428f9001b7cad259a4e56fe610316cd191), [`3b877ba`](https://github.com/thirdweb-dev/js/commit/3b877ba221acfd85f80b99e1bc382055217f0a39), [`b54f95d`](https://github.com/thirdweb-dev/js/commit/b54f95dc906928ff2f9251748f254a16fe1f2cee), [`f8ab477`](https://github.com/thirdweb-dev/js/commit/f8ab4779bb2d6d66200e1e8fd558e0ac069a2f54), [`772f843`](https://github.com/thirdweb-dev/js/commit/772f8431e3a62d0ded62dae90a43e9a7edd5b1a2), [`a9ec190`](https://github.com/thirdweb-dev/js/commit/a9ec190ff99d2714cef2500d20ea0f3f73f07be3), [`208b038`](https://github.com/thirdweb-dev/js/commit/208b0389a50ea48bbb9600fec60fec2f1671d4b9), [`5345479`](https://github.com/thirdweb-dev/js/commit/534547992243bdd3a77e34ec2b2487b5adab366a)]:
|
||||
- @thirdweb-dev/sdk@3.0.5
|
||||
|
||||
## 0.7.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#148](https://github.com/thirdweb-dev/js/pull/148) [`964add6`](https://github.com/thirdweb-dev/js/commit/964add6f205577298b8f4b9ce7298e5bf09e88e7) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Fix deploy/release CLI uploads
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/sdk@3.0.4
|
||||
|
||||
## 0.7.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#134](https://github.com/thirdweb-dev/js/pull/134) [`b1ae844`](https://github.com/thirdweb-dev/js/commit/b1ae844e8bbed59c0225b32f4115ae384fa23ef5) Thanks [@adam-maj](https://github.com/adam-maj)! - Update ordering of commands in npx thirdweb
|
||||
|
||||
- Updated dependencies [[`51dde28`](https://github.com/thirdweb-dev/js/commit/51dde28224209f1b8b26f436c204a5e702281564), [`9d74a43`](https://github.com/thirdweb-dev/js/commit/9d74a43aac21448beba63ba4e2637945965a3634), [`b234c58`](https://github.com/thirdweb-dev/js/commit/b234c58d44d8322e44b2d2ba87ad4ec7d699e961)]:
|
||||
- @thirdweb-dev/sdk@3.0.3
|
||||
|
||||
## 0.7.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#128](https://github.com/thirdweb-dev/js/pull/128) [`4dca5b2`](https://github.com/thirdweb-dev/js/commit/4dca5b21a66fe8ff4c4b24663e1b9ad6c446b7e2) Thanks [@jarrodwatts](https://github.com/jarrodwatts)! - Add new documentation for detectable features
|
||||
|
||||
- Updated dependencies [[`42c79e9`](https://github.com/thirdweb-dev/js/commit/42c79e93dc958ca46a55d705aeea44ffdbbcc5f6), [`fe8751e`](https://github.com/thirdweb-dev/js/commit/fe8751eeae7ad013b890a8092ddbd091ecbd6708)]:
|
||||
- @thirdweb-dev/sdk@3.0.2
|
||||
|
||||
## 0.7.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`98dd64a`](https://github.com/thirdweb-dev/js/commit/98dd64a375c302a879aab3c628ecfb84b4dd19da)]:
|
||||
- @thirdweb-dev/sdk@3.0.1
|
||||
|
||||
## 0.7.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#114](https://github.com/thirdweb-dev/js/pull/114) [`1df2dea`](https://github.com/thirdweb-dev/js/commit/1df2dea18f85f6760040c9000f2eb8aee8a6011b) Thanks [@jnsdls](https://github.com/jnsdls)! - remove deprecacted `publish` cli command (use `release` instead)
|
||||
|
||||
- Updated dependencies [[`a70b590`](https://github.com/thirdweb-dev/js/commit/a70b590be1efa7c0ad93a724afb24870439558ed), [`a37bc00`](https://github.com/thirdweb-dev/js/commit/a37bc00991bf1a359f5f8aa8e24e2c388dcd99d8), [`b442c97`](https://github.com/thirdweb-dev/js/commit/b442c970808f6cb7457d29542bd826dba711579c), [`0fa6f3f`](https://github.com/thirdweb-dev/js/commit/0fa6f3fcfbd571579baf9d2a0dbeee556ddbd5fe), [`2adb8ff`](https://github.com/thirdweb-dev/js/commit/2adb8ff6673768a91fa411c2d069245190ad9397), [`5a5bc36`](https://github.com/thirdweb-dev/js/commit/5a5bc361507bd8707dc12e9000bb9a218221cf61), [`820a519`](https://github.com/thirdweb-dev/js/commit/820a5191b5e7af5aba5e4d1cc90cd895c0dade11), [`0fa6f3f`](https://github.com/thirdweb-dev/js/commit/0fa6f3fcfbd571579baf9d2a0dbeee556ddbd5fe), [`82627ea`](https://github.com/thirdweb-dev/js/commit/82627ea0311f612119d0596ed0f568267a7af16b)]:
|
||||
- @thirdweb-dev/sdk@3.0.0
|
||||
|
||||
## 0.7.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`baa87a1`](https://github.com/thirdweb-dev/js/commit/baa87a1fbd7eee24ce9a95e16028de8435f85e69), [`4079326`](https://github.com/thirdweb-dev/js/commit/407932680fb024f17f12f578aa22c7f8c0c13339), [`05353fd`](https://github.com/thirdweb-dev/js/commit/05353fd8da82f77fb642bb38a533fb99801aed30)]:
|
||||
- @thirdweb-dev/sdk@2.4.9
|
||||
|
||||
## 0.7.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#61](https://github.com/thirdweb-dev/js/pull/61) [`3287c2b`](https://github.com/thirdweb-dev/js/commit/3287c2b0f233332fe4a095f973deed8efab91db6) Thanks [@jnsdls](https://github.com/jnsdls)! - fix versions in dependencies before releasing stable
|
||||
|
||||
- [#56](https://github.com/thirdweb-dev/js/pull/56) [`e9e71cf`](https://github.com/thirdweb-dev/js/commit/e9e71cfcd892611cd653431dc433b27532e9e3cc) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - Add basic tests
|
||||
|
||||
- Updated dependencies [[`3287c2b`](https://github.com/thirdweb-dev/js/commit/3287c2b0f233332fe4a095f973deed8efab91db6)]:
|
||||
- @thirdweb-dev/sdk@2.4.8
|
||||
|
||||
## 0.7.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`6ba9cad`](https://github.com/thirdweb-dev/js/commit/6ba9cad8d8b933256599dc3b147601cd4828c89b)]:
|
||||
- @thirdweb-dev/sdk@2.4.7
|
||||
|
||||
## 0.7.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`5644ccd`](https://github.com/thirdweb-dev/js/commit/5644ccd3ee2ff330e4e5840d3266033376750117) Thanks [@jnsdls](https://github.com/jnsdls)! - bump versions again
|
||||
|
||||
- Updated dependencies [[`5644ccd`](https://github.com/thirdweb-dev/js/commit/5644ccd3ee2ff330e4e5840d3266033376750117)]:
|
||||
- @thirdweb-dev/sdk@2.4.6
|
||||
|
||||
## 0.7.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`091f175`](https://github.com/thirdweb-dev/js/commit/091f1758604d40e825ea28a13c2699d67bc75d8c) Thanks [@jnsdls](https://github.com/jnsdls)! - release-all-packages
|
||||
|
||||
- Updated dependencies [[`091f175`](https://github.com/thirdweb-dev/js/commit/091f1758604d40e825ea28a13c2699d67bc75d8c)]:
|
||||
- @thirdweb-dev/sdk@2.4.5
|
||||
|
||||
## 0.7.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/sdk@2.4.4
|
||||
|
||||
## 0.7.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
export const CREATE_MESSAGES = {
|
||||
typeOfProject: "What type of project do you want to create?",
|
||||
projectName: "What is your project named?",
|
||||
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?",
|
||||
extensions: "What extensions do you want to add to your contract?",
|
||||
} as const;
|
||||
|
||||
export const ERROR_MESSAGES = {
|
||||
noConfiguration:
|
||||
"Failed to find a supported project configuration file in current directory",
|
||||
};
|
||||
@@ -1,36 +1,32 @@
|
||||
import { CREATE_MESSAGES } from "../constants/constants";
|
||||
import { prepareEnvironment } from "@gmrchk/cli-testing-library";
|
||||
|
||||
// this creates an app, can take some time that's fine
|
||||
jest.setTimeout(120_000);
|
||||
|
||||
describe("npx thirdweb create", () => {
|
||||
it("should create app successfully", async () => {
|
||||
it("should create app (CRA) successfully", async () => {
|
||||
const { spawn, cleanup, exists } = await prepareEnvironment();
|
||||
const {
|
||||
// wait,
|
||||
waitForText,
|
||||
waitForFinish,
|
||||
// getStdout,
|
||||
// getStderr,
|
||||
getExitCode,
|
||||
// debug,
|
||||
pressKey,
|
||||
} = await spawn("node", "./dist/cli/index.js create");
|
||||
const { waitForText, waitForFinish, getExitCode, pressKey } = await spawn(
|
||||
"node",
|
||||
"./dist/cli/index.js create",
|
||||
);
|
||||
|
||||
await waitForText("What type of project do you want to create?");
|
||||
await waitForText(CREATE_MESSAGES.typeOfProject);
|
||||
await pressKey("enter");
|
||||
await waitForText("What is your project named?");
|
||||
await waitForText(CREATE_MESSAGES.projectName);
|
||||
await pressKey("enter");
|
||||
await waitForText("What framework do you want to use?");
|
||||
await waitForText(CREATE_MESSAGES.framework);
|
||||
// select CRA
|
||||
await pressKey("arrowDown");
|
||||
await pressKey("enter");
|
||||
await waitForText("What language do you want to use?");
|
||||
await waitForText(CREATE_MESSAGES.language);
|
||||
await pressKey("enter");
|
||||
|
||||
// wait for program to finish
|
||||
await waitForFinish();
|
||||
|
||||
//check if the app was created
|
||||
// check if the app was created
|
||||
expect(await exists("thirdweb-app/package.json")).toEqual(true);
|
||||
|
||||
// the process should exit with code 0
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { ERROR_MESSAGES } from "../constants/constants";
|
||||
import { prepareEnvironment } from "@gmrchk/cli-testing-library";
|
||||
import { copyFile } from "fs/promises";
|
||||
import { resolve } from "path";
|
||||
|
||||
// this creates an app, can take some time that's fine
|
||||
jest.setTimeout(120_000);
|
||||
|
||||
describe("npx thirdweb deploy", () => {
|
||||
it("should return deploy page url", async () => {
|
||||
const { spawn, cleanup, exists, path } = await prepareEnvironment();
|
||||
|
||||
await copyFile(
|
||||
resolve("./e2e/files/BasicContract.sol"),
|
||||
`${path}/BasicContract.sol`,
|
||||
);
|
||||
|
||||
const { waitForText, waitForFinish, getExitCode, writeText, getStdout } =
|
||||
await spawn("node", "./dist/cli/index.js deploy");
|
||||
|
||||
expect(await exists("BasicContract.sol")).toEqual(true);
|
||||
|
||||
await waitForText(ERROR_MESSAGES.noConfiguration);
|
||||
await writeText("y");
|
||||
|
||||
// wait for program to finish
|
||||
await waitForFinish();
|
||||
|
||||
expect(getStdout().at(-1)).toContain(
|
||||
"https://thirdweb.com/contracts/deploy/",
|
||||
);
|
||||
|
||||
// the process should exit with code 0
|
||||
expect(getExitCode()).toEqual(0);
|
||||
|
||||
await cleanup(); // cleanup after test
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,87 @@
|
||||
import { CREATE_MESSAGES } from "../constants/constants";
|
||||
import { prepareEnvironment } from "@gmrchk/cli-testing-library";
|
||||
|
||||
// this creates an app, can take some time that's fine
|
||||
jest.setTimeout(120_000);
|
||||
|
||||
describe("npx thirdweb detect", () => {
|
||||
it("should detect ERC721Base extensions", async () => {
|
||||
const { spawn, cleanup, exists } = await prepareEnvironment();
|
||||
const create = await spawn("node", "./dist/cli/index.js create");
|
||||
|
||||
await create.waitForText(CREATE_MESSAGES.typeOfProject);
|
||||
// select contract
|
||||
await create.pressKey("arrowDown");
|
||||
await create.pressKey("enter");
|
||||
await create.waitForText(CREATE_MESSAGES.projectName);
|
||||
// use default name
|
||||
await create.pressKey("enter");
|
||||
await create.waitForText(CREATE_MESSAGES.framework);
|
||||
// select hardhat
|
||||
await create.pressKey("enter");
|
||||
await create.waitForText(CREATE_MESSAGES.contract);
|
||||
// select ERC721
|
||||
await create.pressKey("arrowDown");
|
||||
await create.pressKey("enter");
|
||||
await create.waitForText(CREATE_MESSAGES.extensions);
|
||||
// select no extra extensions
|
||||
await create.pressKey("enter");
|
||||
|
||||
// wait for program to finish
|
||||
await create.waitForFinish();
|
||||
|
||||
// the process should exit with code 0
|
||||
expect(create.getExitCode()).toEqual(0);
|
||||
|
||||
// check if the contract was created
|
||||
expect(await exists("thirdweb-contracts/contracts/Contract.sol")).toEqual(
|
||||
true,
|
||||
);
|
||||
|
||||
// check that hardhat config exists
|
||||
expect(await exists("thirdweb-contracts/hardhat.config.js")).toEqual(true);
|
||||
|
||||
await create.writeText("cd thirdweb-contracts");
|
||||
await create.pressKey("enter");
|
||||
await create.writeText("npm install");
|
||||
await create.pressKey("enter");
|
||||
|
||||
const detect = await spawn(
|
||||
"node",
|
||||
"./dist/cli/index.js detect",
|
||||
"./thirdweb-contracts",
|
||||
);
|
||||
|
||||
// wait for program to finish
|
||||
await detect.waitForFinish();
|
||||
|
||||
const lines = detect.getStdout();
|
||||
|
||||
// Detected extensions
|
||||
expect(lines.findIndex((line) => line.includes("ERC721"))).toBeGreaterThan(
|
||||
-1,
|
||||
);
|
||||
expect(
|
||||
lines.findIndex((line) => line.includes("ERC721Burnable")),
|
||||
).toBeGreaterThan(-1);
|
||||
expect(
|
||||
lines.findIndex((line) => line.includes("ERC721Mintable")),
|
||||
).toBeGreaterThan(-1);
|
||||
|
||||
// Suggested extensions
|
||||
expect(
|
||||
lines.findIndex((line) => line.includes("- ERC721Enumerable")),
|
||||
).toBeGreaterThan(-1);
|
||||
expect(
|
||||
lines.findIndex((line) => line.includes("- ERC721LazyMintable")),
|
||||
).toBeGreaterThan(-1);
|
||||
expect(
|
||||
lines.findIndex((line) => line.includes("- ERC721SignatureMint")),
|
||||
).toBeGreaterThan(-1);
|
||||
|
||||
// the process should exit with code 0
|
||||
expect(detect.getExitCode()).toEqual(0);
|
||||
|
||||
await cleanup(); // cleanup after test
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
contract BasicContract {
|
||||
constructor() {}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { ERROR_MESSAGES } from "../constants/constants";
|
||||
import { prepareEnvironment } from "@gmrchk/cli-testing-library";
|
||||
import { copyFile } from "fs/promises";
|
||||
import { resolve } from "path";
|
||||
|
||||
// this creates an app, can take some time that's fine
|
||||
jest.setTimeout(120_000);
|
||||
|
||||
describe("npx thirdweb release", () => {
|
||||
it("should return release page url", async () => {
|
||||
const { spawn, cleanup, exists, path } = await prepareEnvironment();
|
||||
|
||||
await copyFile(
|
||||
resolve("./e2e/files/BasicContract.sol"),
|
||||
`${path}/BasicContract.sol`,
|
||||
);
|
||||
|
||||
const { waitForText, waitForFinish, getExitCode, writeText, getStdout } =
|
||||
await spawn("node", "./dist/cli/index.js release");
|
||||
|
||||
expect(await exists("BasicContract.sol")).toEqual(true);
|
||||
|
||||
await waitForText(ERROR_MESSAGES.noConfiguration);
|
||||
await writeText("y");
|
||||
|
||||
// wait for program to finish
|
||||
await waitForFinish();
|
||||
|
||||
expect(getStdout().at(-1)).toContain(
|
||||
"https://thirdweb.com/contracts/release/",
|
||||
);
|
||||
|
||||
// the process should exit with code 0
|
||||
expect(getExitCode()).toEqual(0);
|
||||
|
||||
await cleanup(); // cleanup after test
|
||||
});
|
||||
});
|
||||
+11
-21
@@ -1,12 +1,8 @@
|
||||
{
|
||||
"name": "thirdweb",
|
||||
"main": "dist/cli/index.js",
|
||||
"version": "0.7.4",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com:thirdweb-dev/js.git",
|
||||
"directory": "packages/cli"
|
||||
},
|
||||
"version": "0.8.9",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
@@ -25,47 +21,41 @@
|
||||
"@types/update-notifier": "^5.1.0",
|
||||
"@types/validate-npm-package-name": "^4.0.0",
|
||||
"hardhat": "^2.9.3",
|
||||
"jest": "^29.0.1",
|
||||
"prettier": "^2.6.2",
|
||||
"jest": "^28",
|
||||
"prettier": "^2.7.1",
|
||||
"ts-jest": "^28.0.8",
|
||||
"ts-node": "^10.7.0",
|
||||
"tsc": "^2.0.4",
|
||||
"tsup": "^6.2.3",
|
||||
"typescript": "^4.6.3"
|
||||
"typescript": "^4.7.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@thirdweb-dev/sdk": "*",
|
||||
"async-retry": "^1.3.3",
|
||||
"cbor": "^8.1.0",
|
||||
"commander": "^9.1.0",
|
||||
"cpy": "^9.0.1",
|
||||
"enquirer": "^2.3.6",
|
||||
"ethers": "^5.6.9",
|
||||
"form-data": "^4.0.0",
|
||||
"ethers": "^5.7.0",
|
||||
"got": "11.8.5",
|
||||
"inquirer": "^8.2.3",
|
||||
"ipfs-unixfs": "^6.0.7",
|
||||
"ipld-dag-pb": "^0.22.3",
|
||||
"multihashes": "^4.0.3",
|
||||
"open": "^8.4.0",
|
||||
"prompts": "^2.4.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"solc": "0.8.13",
|
||||
"tar": "^6.1.11",
|
||||
"tslog": "^3.3.3",
|
||||
"update-check": "^1.5.4",
|
||||
"update-notifier": "^6.0.2",
|
||||
"validate-npm-package-name": "^4.0.0",
|
||||
"yaml": "^2.0.1"
|
||||
"yaml": "^2.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"thirdweb": "./dist/cli/index.js"
|
||||
},
|
||||
"scripts": {
|
||||
"prettier": "prettier --write 'src/**/*'",
|
||||
"format": "prettier --write 'src/**/*'",
|
||||
"lint": "eslint src/",
|
||||
"fix": "eslint src/ --fix",
|
||||
"clean": "rm -rf dist/",
|
||||
"cli": "node -r ts-node/register src/cli/index.ts",
|
||||
"build": "yarn clean && tsc --noEmit && tsup --env.NODE_ENV production --minify --format cjs --external hardhat --dts-resolve",
|
||||
"build": "yarn clean && tsup --env.NODE_ENV production --minify --format cjs --external hardhat --dts-resolve",
|
||||
"build:watch": "yarn run build --watch",
|
||||
"generate-thirdweb-package": "node scripts/generate-thirdweb-package.js",
|
||||
"e2e": "jest"
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#!/usr/bin/env node
|
||||
import { installGithubAction } from "../common/ci-installer";
|
||||
import { detectExtensions } from "../common/feature-detector";
|
||||
import { processProject } from "../common/processor";
|
||||
import { cliVersion, pkg } from "../constants/urls";
|
||||
import { info, logger } from "../core/helpers/logger";
|
||||
import { twCreate } from "../create/command";
|
||||
import generateDashboardUrl from "../helpers/generate-dashboard-url";
|
||||
import { upload } from "../storage/command";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import chalk from "chalk";
|
||||
import { Command } from "commander";
|
||||
import open from "open";
|
||||
@@ -28,7 +29,7 @@ $$$$$$\\ $$$$$$$\\ $$\\ $$$$$$\\ $$$$$$$ |$$\\ $$\\ $$\\ $$$$$$\\ $$$$
|
||||
updateNotifier({
|
||||
pkg,
|
||||
shouldNotifyInNpmScript: true,
|
||||
//check every time while we're still building the CLI
|
||||
// check every time while we're still building the CLI
|
||||
updateCheckInterval: 0,
|
||||
}).notify();
|
||||
});
|
||||
@@ -36,13 +37,42 @@ $$$$$$\\ $$$$$$$\\ $$\\ $$$$$$\\ $$$$$$$ |$$\\ $$\\ $$\\ $$$$$$\\ $$$$
|
||||
program
|
||||
.name("thirdweb-cli")
|
||||
.description("Official thirdweb command line interface")
|
||||
.version(cliVersion, "-v, --version", "output the current version");
|
||||
.version(cliVersion, "-v, --version");
|
||||
|
||||
program
|
||||
.command("detect")
|
||||
.command("create [projectPath]")
|
||||
.description(
|
||||
"Compile contracts and detect implemented thirdweb contract extensions",
|
||||
"Create a web3 app from any of our official templates: https://github.com/thirdweb-example/",
|
||||
)
|
||||
.option("--app", `Create a web3 app.`)
|
||||
.option("--contract", `Create a web3 contract project`)
|
||||
.option("--ts, --typescript", `Initialize as a TypeScript project.`)
|
||||
.option("--js, --javascript", `Initialize as a JavaScript project.`)
|
||||
.option("--forge", `Initialize as a Forge project.`)
|
||||
.option("--hardhat", `Initialize as a Hardhat project.`)
|
||||
.option("--cra", `Initialize as a Create React App project.`)
|
||||
.option("--next", `Initialize as a Next.js project.`)
|
||||
.option("--vite", `Initialize as a Vite project.`)
|
||||
.option(
|
||||
"--use-npm",
|
||||
`Explicitly tell the CLI to bootstrap the app using npm`,
|
||||
)
|
||||
.option(
|
||||
"--use-pnpm",
|
||||
`Explicitly tell the CLI to bootstrap the app using pnpm`,
|
||||
)
|
||||
.option("--framework [name]", `The preferred framework.`)
|
||||
.option(
|
||||
"-t, --template [name]",
|
||||
`A template to start your project from. You can use an template repository name from the official thirdweb-example org.`,
|
||||
)
|
||||
.action(async (path, options) => {
|
||||
await twCreate(path, options);
|
||||
});
|
||||
|
||||
program
|
||||
.command("build")
|
||||
.description("Compile contract and detect thirdweb contract extensions")
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option("-d, --debug", "show debug logs")
|
||||
.option("-a, --all", "run detection on all contracts")
|
||||
@@ -50,44 +80,9 @@ $$$$$$\\ $$$$$$$\\ $$\\ $$$$$$\\ $$$$$$$ |$$\\ $$\\ $$\\ $$$$$$\\ $$$$
|
||||
await detectExtensions(options);
|
||||
});
|
||||
|
||||
program
|
||||
.command("publish")
|
||||
.description("[Deprecated] use 'release' instead.")
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option("--dry-run", "dry run (skip actually publishing)")
|
||||
.option("-d, --debug", "show debug logs")
|
||||
.option("--ci", "Continuous Integration mode")
|
||||
.action(async (options) => {
|
||||
logger.warn(
|
||||
"'publish' is deprecated and will be removed in a future update. Please use 'release' instead.",
|
||||
);
|
||||
const url = await processProject(options, "release");
|
||||
info(`Open this link to release your contracts:`);
|
||||
logger.info(chalk.blueBright(url.toString()));
|
||||
open(url.toString());
|
||||
});
|
||||
|
||||
program
|
||||
.command("release")
|
||||
.description(
|
||||
"Release contracts, making them available for others to deploy and unlocking SDKs, Dashboards and Analytics.",
|
||||
)
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option("--dry-run", "dry run (skip actually publishing)")
|
||||
.option("-d, --debug", "show debug logs")
|
||||
.option("--ci", "Continuous Integration mode")
|
||||
.action(async (options) => {
|
||||
const url = await processProject(options, "release");
|
||||
info(`Open this link to release your contracts:`);
|
||||
logger.info(chalk.blueBright(url.toString()));
|
||||
open(url.toString());
|
||||
});
|
||||
|
||||
program
|
||||
.command("deploy")
|
||||
.description(
|
||||
"Deploy contracts through your thirdweb dashboard, without dealing with private keys.",
|
||||
)
|
||||
.description("Deploy your (or team) contracts securely to blockchains")
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option("--dry-run", "dry run (skip actually publishing)")
|
||||
.option("-d, --debug", "show debug logs")
|
||||
@@ -128,43 +123,46 @@ $$$$$$\\ $$$$$$$\\ $$\\ $$$$$$\\ $$$$$$$ |$$\\ $$\\ $$\\ $$$$$$\\ $$$$
|
||||
});
|
||||
|
||||
program
|
||||
.command("create")
|
||||
.command("release")
|
||||
.description(
|
||||
"Create a thirdweb app from any of our official templates. Checkout some examples you can use here: https://github.com/thirdweb-example/",
|
||||
)
|
||||
.option("--app", `Create a thirdweb app.`)
|
||||
.option("--contract", `Create a thirdweb contracts project.`)
|
||||
.option("--ts, --typescript", `Initialize as a TypeScript project.`)
|
||||
.option("--js, --javascript", `Initialize as a JavaScript project.`)
|
||||
.option("--forge", `Initialize as a Forge project.`)
|
||||
.option("--hardhat", `Initialize as a Hardhat project.`)
|
||||
.option("--cra", `Initialize as a Create React App project.`)
|
||||
.option("--next", `Initialize as a Next.js project.`)
|
||||
.option("--vite", `Initialize as a Vite project.`)
|
||||
.option(
|
||||
"--use-npm",
|
||||
`Explicitly tell the CLI to bootstrap the app using npm`,
|
||||
)
|
||||
.option(
|
||||
"--use-pnpm",
|
||||
`Explicitly tell the CLI to bootstrap the app using pnpm`,
|
||||
)
|
||||
.option("--framework [name]", `The preferred framework.`)
|
||||
.option(
|
||||
"-t, --template [name]",
|
||||
`A template to start your project from. You can use an template repository name from the official thirdweb-example org.`,
|
||||
"Release your protocol so other devs can deploy them and unlock SDKs, Dashboards and Analytics",
|
||||
)
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option("--dry-run", "dry run (skip actually publishing)")
|
||||
.option("-d, --debug", "show debug logs")
|
||||
.option("--ci", "Continuous Integration mode")
|
||||
.action(async (options) => {
|
||||
await twCreate(options);
|
||||
const url = await processProject(options, "release");
|
||||
info(`Open this link to release your contracts:`);
|
||||
logger.info(chalk.blueBright(url.toString()));
|
||||
open(url.toString());
|
||||
});
|
||||
|
||||
program
|
||||
.command("install-ci")
|
||||
.command("upload")
|
||||
.description("Upload any file or directory to decentralized storage (IPFS)")
|
||||
.argument("[upload]", "path to file or directory to upload")
|
||||
.action(async (path) => {
|
||||
const storage = new ThirdwebStorage();
|
||||
const uri = await upload(storage, path);
|
||||
info(`Files stored at the following IPFS URI:`);
|
||||
logger.info(chalk.blueBright(uri.toString()));
|
||||
|
||||
const url = storage.resolveScheme(uri);
|
||||
info(`Open this link to view your upload:`);
|
||||
logger.info(chalk.blueBright(url.toString()));
|
||||
});
|
||||
|
||||
program
|
||||
.command("detect")
|
||||
.description(
|
||||
"(alpha) Set up continuous integration for your contracts. This adds a github action to deploy the project on pull requests and pushes to branches. Publishes on push the the main branch.",
|
||||
"(deprecated) Compile contracts and detect implemented thirdweb contract extensions",
|
||||
)
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option("-d, --debug", "show debug logs")
|
||||
.option("-a, --all", "run detection on all contracts")
|
||||
.action(async (options) => {
|
||||
await installGithubAction(options);
|
||||
await detectExtensions(options);
|
||||
});
|
||||
|
||||
await program.parseAsync();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { spinner } from "../core/helpers/logger";
|
||||
import { IpfsStorage } from "@thirdweb-dev/storage";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import { existsSync, mkdirSync, writeFileSync } from "fs";
|
||||
import path, { join } from "path";
|
||||
|
||||
@@ -13,10 +13,10 @@ export async function installGithubAction(options: any) {
|
||||
: path.resolve(`${projectPath}/${options.path}`);
|
||||
projectPath = resolvedPath;
|
||||
}
|
||||
const storage = new IpfsStorage();
|
||||
const storage = new ThirdwebStorage();
|
||||
const log = spinner("Installing thirdweb Github Action...");
|
||||
try {
|
||||
const ghActionData = await storage.getRaw(ghActionHash);
|
||||
const ghActionData = await (await storage.download(ghActionHash)).text();
|
||||
const dir = join(projectPath, ".github/workflows");
|
||||
if (!existsSync(dir)) {
|
||||
mkdirSync(dir, { recursive: true });
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { ALWAYS_SUGGESTED } from "../constants/features";
|
||||
import build from "../core/builder/build";
|
||||
import detect from "../core/detection/detect";
|
||||
import { logger, spinner, warn, info } from "../core/helpers/logger";
|
||||
import { logger, spinner } from "../core/helpers/logger";
|
||||
import { createContractsPrompt } from "../core/helpers/selector";
|
||||
import { ContractFeatures, Feature } from "../core/interfaces/ContractFeatures";
|
||||
import { ContractPayload } from "../core/interfaces/ContractPayload";
|
||||
import { getPkgManager } from "../create/helpers/get-pkg-manager";
|
||||
import { detectFeatures, FeatureWithEnabled } from "@thirdweb-dev/sdk";
|
||||
import chalk from "chalk";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import ora from "ora";
|
||||
import path from "path";
|
||||
|
||||
@@ -41,7 +43,7 @@ export async function detectExtensions(options: any) {
|
||||
compileLoader.succeed("Compilation successful");
|
||||
|
||||
let selectedContracts: ContractPayload[] = [];
|
||||
if (compiledResult.contracts.length == 1) {
|
||||
if (compiledResult.contracts.length === 1) {
|
||||
selectedContracts = [compiledResult.contracts[0]];
|
||||
} else {
|
||||
if (options.all) {
|
||||
@@ -70,13 +72,13 @@ export async function detectExtensions(options: any) {
|
||||
const enabledFeatures: Feature[] = features.enabledFeatures.map(
|
||||
(feature) => ({
|
||||
name: feature.name,
|
||||
reference: `https://portal.thirdweb.com/contracts/${feature.docLinks.contracts}`,
|
||||
reference: `https://portal.thirdweb.com/extensions/${feature.name.toLowerCase()}`,
|
||||
}),
|
||||
);
|
||||
const suggestedFeatures: Feature[] = features.suggestedFeatures.map(
|
||||
(feature) => ({
|
||||
name: feature.name,
|
||||
reference: `https://portal.thirdweb.com/contracts/${feature.docLinks.contracts}`,
|
||||
reference: `https://portal.thirdweb.com/extensions/${feature.name.toLowerCase()}`,
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -101,7 +103,7 @@ export async function detectExtensions(options: any) {
|
||||
`Detected extension on ${chalk.blueBright(contractWithFeatures.name)}`,
|
||||
).stopAndPersist({ symbol: "🔎" });
|
||||
contractWithFeatures.enabledFeatures.map((feature) => {
|
||||
info(`${chalk.green(feature.name)}`);
|
||||
logger.info(`✔️ ${chalk.green(feature.name)}`);
|
||||
});
|
||||
}
|
||||
logger.info(``);
|
||||
@@ -113,6 +115,26 @@ export async function detectExtensions(options: any) {
|
||||
)} - ${chalk.dim(chalk.gray(feature.reference))}`,
|
||||
);
|
||||
});
|
||||
|
||||
let deployCmd = `npx thirdweb@latest deploy`;
|
||||
if (existsSync(projectPath + "/package.json")) {
|
||||
const packageManager = getPkgManager();
|
||||
const useYarn = packageManager === "yarn";
|
||||
const pkgJson = JSON.parse(
|
||||
readFileSync(projectPath + "/package.json", "utf-8"),
|
||||
);
|
||||
if (pkgJson?.scripts?.deploy === deployCmd) {
|
||||
deployCmd = `${packageManager}${useYarn ? "" : " run"} deploy`;
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(``);
|
||||
ora(
|
||||
`Once you're done writing your contracts, you can run the following command to deploy them:`,
|
||||
).info();
|
||||
logger.info(``);
|
||||
logger.info(` ${chalk.cyan(deployCmd)}`);
|
||||
logger.info(``);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { THIRDWEB_URL, cliVersion } from "../constants/urls";
|
||||
import { cliVersion, THIRDWEB_URL } from "../constants/urls";
|
||||
import build from "../core/builder/build";
|
||||
import detect from "../core/detection/detect";
|
||||
import { execute } from "../core/helpers/exec";
|
||||
import { error, info, logger, spinner, warn } from "../core/helpers/logger";
|
||||
import { error, info, logger, spinner } from "../core/helpers/logger";
|
||||
import { createContractsPrompt } from "../core/helpers/selector";
|
||||
import { ContractPayload } from "../core/interfaces/ContractPayload";
|
||||
import { IpfsStorage } from "@thirdweb-dev/storage";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import chalk from "chalk";
|
||||
import { readFileSync } from "fs";
|
||||
import ora from "ora";
|
||||
import path from "path";
|
||||
|
||||
export async function processProject(
|
||||
@@ -15,7 +16,7 @@ export async function processProject(
|
||||
command: "deploy" | "release",
|
||||
) {
|
||||
// TODO: allow overriding the default storage
|
||||
const storage = new IpfsStorage();
|
||||
const storage = new ThirdwebStorage();
|
||||
|
||||
logger.setSettings({
|
||||
minLevel: options.debug ? "debug" : "info",
|
||||
@@ -35,6 +36,27 @@ export async function processProject(
|
||||
|
||||
const projectType = await detect(projectPath, options);
|
||||
|
||||
if (projectType === "none") {
|
||||
if (command === "deploy") {
|
||||
info(
|
||||
"No contracts detected in this directory. Redirecting to the thirdweb contract deployment page.",
|
||||
);
|
||||
return "https://thirdweb.com/contracts";
|
||||
}
|
||||
|
||||
error("No detected contracts in this directory.");
|
||||
logger.info(``);
|
||||
ora(
|
||||
`Detected contract files must end with the '.sol' extension and exist in this directory or the '/contracts' subdirectory`,
|
||||
).info();
|
||||
logger.info(``);
|
||||
ora("To create a new contracts project, run the following command:").info();
|
||||
logger.info(``);
|
||||
logger.info(` ${chalk.cyan(`npx thirdweb@latest create --contract`)}`);
|
||||
logger.info(``);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (options.ci) {
|
||||
logger.info("Installing dependencies...");
|
||||
try {
|
||||
@@ -65,7 +87,7 @@ export async function processProject(
|
||||
}
|
||||
compileLoader.succeed("Compilation successful");
|
||||
|
||||
if (compiledResult.contracts.length == 0) {
|
||||
if (compiledResult.contracts.length === 0) {
|
||||
logger.error(
|
||||
"No deployable contract detected. Run with the '--debug' option to see what contracts were skipped and why.",
|
||||
);
|
||||
@@ -73,7 +95,7 @@ export async function processProject(
|
||||
}
|
||||
|
||||
let selectedContracts: ContractPayload[] = [];
|
||||
if (compiledResult.contracts.length == 1) {
|
||||
if (compiledResult.contracts.length === 1) {
|
||||
selectedContracts = [compiledResult.contracts[0]];
|
||||
info(
|
||||
`Processing contract: ${chalk.blueBright(
|
||||
@@ -129,7 +151,9 @@ export async function processProject(
|
||||
if (file.includes(soliditySDKPackage)) {
|
||||
usesSoliditySDK = true;
|
||||
}
|
||||
return await storage.uploadSingle(file);
|
||||
return await storage.upload(file, {
|
||||
uploadWithoutDirectory: true,
|
||||
});
|
||||
}),
|
||||
);
|
||||
}
|
||||
@@ -140,14 +164,15 @@ export async function processProject(
|
||||
const metadataURIs = await Promise.all(
|
||||
selectedContracts.map(async (c) => {
|
||||
logger.debug(`Uploading ${c.name}...`);
|
||||
const hash = await storage.uploadSingle(c.metadata);
|
||||
return `ipfs://${hash}`;
|
||||
return await storage.upload(JSON.parse(c.metadata), {
|
||||
uploadWithoutDirectory: true,
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
// Upload batch all bytecodes
|
||||
const bytecodes = selectedContracts.map((c) => c.bytecode);
|
||||
const { uris: bytecodeURIs } = await storage.uploadBatch(bytecodes);
|
||||
const bytecodeURIs = await storage.uploadBatch(bytecodes);
|
||||
|
||||
const combinedContents = selectedContracts.map((c, i) => {
|
||||
// attach analytics blob to metadata
|
||||
@@ -167,16 +192,15 @@ export async function processProject(
|
||||
};
|
||||
});
|
||||
let combinedURIs: string[] = [];
|
||||
if (combinedContents.length == 1) {
|
||||
if (combinedContents.length === 1) {
|
||||
// use upload single if only one contract to get a clean IPFS hash
|
||||
const metadataUri = await storage.uploadSingle(
|
||||
JSON.stringify(combinedContents[0]),
|
||||
);
|
||||
const metadataUri = await storage.upload(combinedContents[0], {
|
||||
uploadWithoutDirectory: true,
|
||||
});
|
||||
combinedURIs.push(metadataUri);
|
||||
} else {
|
||||
// otherwise upload batch
|
||||
const { uris } = await storage.uploadMetadataBatch(combinedContents);
|
||||
combinedURIs = uris;
|
||||
combinedURIs = await storage.uploadBatch(combinedContents);
|
||||
}
|
||||
|
||||
loader.succeed("Upload successful");
|
||||
@@ -190,7 +214,7 @@ export async function processProject(
|
||||
|
||||
export function getUrl(hashes: string[], command: string) {
|
||||
let url;
|
||||
if (hashes.length == 1) {
|
||||
if (hashes.length === 1) {
|
||||
url = new URL(
|
||||
THIRDWEB_URL +
|
||||
`/contracts/${command}/` +
|
||||
|
||||
@@ -1,294 +1,294 @@
|
||||
const baseContracts = {
|
||||
ERC721Base: `// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC721Base.sol";
|
||||
|
||||
contract Contract is ERC721Base {
|
||||
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _royaltyRecipient,
|
||||
uint128 _royaltyBps
|
||||
)
|
||||
ERC721Base(
|
||||
_name,
|
||||
_symbol,
|
||||
_royaltyRecipient,
|
||||
_royaltyBps
|
||||
)
|
||||
{}
|
||||
|
||||
}`,
|
||||
ERC721Signature: `// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC721SignatureMint.sol";
|
||||
|
||||
contract Contract is ERC721SignatureMint {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _royaltyRecipient,
|
||||
uint128 _royaltyBps,
|
||||
address _primarySaleRecipient
|
||||
)
|
||||
ERC721SignatureMint(
|
||||
_name,
|
||||
_symbol,
|
||||
_royaltyRecipient,
|
||||
_royaltyBps,
|
||||
_primarySaleRecipient
|
||||
)
|
||||
{}
|
||||
}`,
|
||||
ERC721LazyMint: `// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC721LazyMint.sol";
|
||||
|
||||
contract Contract is ERC721LazyMint {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _royaltyRecipient,
|
||||
uint128 _royaltyBps
|
||||
) ERC721LazyMint(_name, _symbol, _royaltyRecipient, _royaltyBps) {}
|
||||
}`,
|
||||
ERC721DelayedReveal: `// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC721DelayedReveal.sol";
|
||||
|
||||
contract Contract is ERC721DelayedReveal {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _royaltyRecipient,
|
||||
uint128 _royaltyBps
|
||||
) ERC721DelayedReveal(_name, _symbol, _royaltyRecipient, _royaltyBps) {}
|
||||
}`,
|
||||
ERC721Drop: `// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC721Drop.sol";
|
||||
|
||||
contract Contract is ERC721Drop {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _royaltyRecipient,
|
||||
uint128 _royaltyBps,
|
||||
address _primarySaleRecipient
|
||||
)
|
||||
ERC721Drop(
|
||||
_name,
|
||||
_symbol,
|
||||
_royaltyRecipient,
|
||||
_royaltyBps,
|
||||
_primarySaleRecipient
|
||||
)
|
||||
{}
|
||||
}`,
|
||||
ERC1155Base: `// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC1155Base.sol";
|
||||
|
||||
contract Contract is ERC1155Base {
|
||||
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _royaltyRecipient,
|
||||
uint128 _royaltyBps
|
||||
)
|
||||
ERC1155Base(
|
||||
_name,
|
||||
_symbol,
|
||||
_royaltyRecipient,
|
||||
_royaltyBps
|
||||
)
|
||||
{}
|
||||
|
||||
}`,
|
||||
ERC1155Signature: `// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC1155SignatureMint.sol";
|
||||
|
||||
contract Contract is ERC1155SignatureMint {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _royaltyRecipient,
|
||||
uint128 _royaltyBps,
|
||||
address _primarySaleRecipient
|
||||
)
|
||||
ERC1155SignatureMint(
|
||||
_name,
|
||||
_symbol,
|
||||
_royaltyRecipient,
|
||||
_royaltyBps,
|
||||
_primarySaleRecipient
|
||||
)
|
||||
{}
|
||||
}`,
|
||||
ERC1155LazyMint: `// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC1155LazyMint.sol";
|
||||
|
||||
contract Contract is ERC1155LazyMint {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _royaltyRecipient,
|
||||
uint128 _royaltyBps
|
||||
) ERC1155LazyMint(_name, _symbol, _royaltyRecipient, _royaltyBps) {}
|
||||
}`,
|
||||
ERC1155DelayedReveal: `// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC1155DelayedReveal.sol";
|
||||
|
||||
contract Contract is ERC1155DelayedReveal {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _royaltyRecipient,
|
||||
uint128 _royaltyBps
|
||||
) ERC1155DelayedReveal(_name, _symbol, _royaltyRecipient, _royaltyBps) {}
|
||||
}`,
|
||||
ERC1155Drop: `// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC1155Drop.sol";
|
||||
|
||||
contract Contract is ERC1155Drop {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _royaltyRecipient,
|
||||
uint128 _royaltyBps,
|
||||
address _primarySaleRecipient
|
||||
)
|
||||
ERC1155Drop(
|
||||
_name,
|
||||
_symbol,
|
||||
_royaltyRecipient,
|
||||
_royaltyBps,
|
||||
_primarySaleRecipient
|
||||
)
|
||||
{}
|
||||
}`,
|
||||
ERC20Base: `// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC20Base.sol";
|
||||
|
||||
contract Contract is ERC20Base {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol
|
||||
)
|
||||
ERC20Base(
|
||||
_name,
|
||||
_symbol
|
||||
)
|
||||
{}
|
||||
}`,
|
||||
ERC20Vote: `// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC20Vote.sol";
|
||||
|
||||
contract Contract is ERC20Vote {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol
|
||||
)
|
||||
ERC20Vote(
|
||||
_name,
|
||||
_symbol
|
||||
)
|
||||
{}
|
||||
}`,
|
||||
ERC20SignatureMint: `// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC20SignatureMint.sol";
|
||||
|
||||
contract Contract is ERC20SignatureMint {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _primarySaleRecipient
|
||||
)
|
||||
ERC20SignatureMint(
|
||||
_name,
|
||||
_symbol,
|
||||
_primarySaleRecipient
|
||||
)
|
||||
{}
|
||||
}`,
|
||||
|
||||
ERC20SignatureMintVote: `// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC20SignatureMintVote.sol";
|
||||
|
||||
contract Contract is ERC20SignatureMintVote {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _primarySaleRecipient
|
||||
)
|
||||
ERC20SignatureMintVote(
|
||||
_name,
|
||||
_symbol,
|
||||
_primarySaleRecipient
|
||||
)
|
||||
{}
|
||||
}`,
|
||||
|
||||
ERC20Drop: `// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC20Drop.sol";
|
||||
|
||||
contract Contract is ERC20Drop {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _primarySaleRecipient
|
||||
)
|
||||
ERC20Drop(
|
||||
_name,
|
||||
_symbol,
|
||||
_primarySaleRecipient
|
||||
)
|
||||
{}
|
||||
}`,
|
||||
ERC20DropVote: `// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC20DropVote.sol";
|
||||
|
||||
contract Contract is ERC20DropVote {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _primarySaleRecipient
|
||||
)
|
||||
ERC20DropVote(
|
||||
_name,
|
||||
_symbol,
|
||||
_primarySaleRecipient
|
||||
)
|
||||
{}
|
||||
}`,
|
||||
};
|
||||
|
||||
export default baseContracts;
|
||||
const baseContracts = {
|
||||
ERC721Base: `// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC721Base.sol";
|
||||
|
||||
contract Contract is ERC721Base {
|
||||
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _royaltyRecipient,
|
||||
uint128 _royaltyBps
|
||||
)
|
||||
ERC721Base(
|
||||
_name,
|
||||
_symbol,
|
||||
_royaltyRecipient,
|
||||
_royaltyBps
|
||||
)
|
||||
{}
|
||||
|
||||
}`,
|
||||
ERC721SignatureMint: `// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC721SignatureMint.sol";
|
||||
|
||||
contract Contract is ERC721SignatureMint {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _royaltyRecipient,
|
||||
uint128 _royaltyBps,
|
||||
address _primarySaleRecipient
|
||||
)
|
||||
ERC721SignatureMint(
|
||||
_name,
|
||||
_symbol,
|
||||
_royaltyRecipient,
|
||||
_royaltyBps,
|
||||
_primarySaleRecipient
|
||||
)
|
||||
{}
|
||||
}`,
|
||||
ERC721LazyMint: `// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC721LazyMint.sol";
|
||||
|
||||
contract Contract is ERC721LazyMint {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _royaltyRecipient,
|
||||
uint128 _royaltyBps
|
||||
) ERC721LazyMint(_name, _symbol, _royaltyRecipient, _royaltyBps) {}
|
||||
}`,
|
||||
ERC721DelayedReveal: `// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC721DelayedReveal.sol";
|
||||
|
||||
contract Contract is ERC721DelayedReveal {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _royaltyRecipient,
|
||||
uint128 _royaltyBps
|
||||
) ERC721DelayedReveal(_name, _symbol, _royaltyRecipient, _royaltyBps) {}
|
||||
}`,
|
||||
ERC721Drop: `// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC721Drop.sol";
|
||||
|
||||
contract Contract is ERC721Drop {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _royaltyRecipient,
|
||||
uint128 _royaltyBps,
|
||||
address _primarySaleRecipient
|
||||
)
|
||||
ERC721Drop(
|
||||
_name,
|
||||
_symbol,
|
||||
_royaltyRecipient,
|
||||
_royaltyBps,
|
||||
_primarySaleRecipient
|
||||
)
|
||||
{}
|
||||
}`,
|
||||
ERC1155Base: `// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC1155Base.sol";
|
||||
|
||||
contract Contract is ERC1155Base {
|
||||
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _royaltyRecipient,
|
||||
uint128 _royaltyBps
|
||||
)
|
||||
ERC1155Base(
|
||||
_name,
|
||||
_symbol,
|
||||
_royaltyRecipient,
|
||||
_royaltyBps
|
||||
)
|
||||
{}
|
||||
|
||||
}`,
|
||||
ERC1155SignatureMint: `// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC1155SignatureMint.sol";
|
||||
|
||||
contract Contract is ERC1155SignatureMint {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _royaltyRecipient,
|
||||
uint128 _royaltyBps,
|
||||
address _primarySaleRecipient
|
||||
)
|
||||
ERC1155SignatureMint(
|
||||
_name,
|
||||
_symbol,
|
||||
_royaltyRecipient,
|
||||
_royaltyBps,
|
||||
_primarySaleRecipient
|
||||
)
|
||||
{}
|
||||
}`,
|
||||
ERC1155LazyMint: `// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC1155LazyMint.sol";
|
||||
|
||||
contract Contract is ERC1155LazyMint {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _royaltyRecipient,
|
||||
uint128 _royaltyBps
|
||||
) ERC1155LazyMint(_name, _symbol, _royaltyRecipient, _royaltyBps) {}
|
||||
}`,
|
||||
ERC1155DelayedReveal: `// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC1155DelayedReveal.sol";
|
||||
|
||||
contract Contract is ERC1155DelayedReveal {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _royaltyRecipient,
|
||||
uint128 _royaltyBps
|
||||
) ERC1155DelayedReveal(_name, _symbol, _royaltyRecipient, _royaltyBps) {}
|
||||
}`,
|
||||
ERC1155Drop: `// SPDX-License-Identifier: Apache-2.0
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC1155Drop.sol";
|
||||
|
||||
contract Contract is ERC1155Drop {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _royaltyRecipient,
|
||||
uint128 _royaltyBps,
|
||||
address _primarySaleRecipient
|
||||
)
|
||||
ERC1155Drop(
|
||||
_name,
|
||||
_symbol,
|
||||
_royaltyRecipient,
|
||||
_royaltyBps,
|
||||
_primarySaleRecipient
|
||||
)
|
||||
{}
|
||||
}`,
|
||||
ERC20Base: `// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC20Base.sol";
|
||||
|
||||
contract Contract is ERC20Base {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol
|
||||
)
|
||||
ERC20Base(
|
||||
_name,
|
||||
_symbol
|
||||
)
|
||||
{}
|
||||
}`,
|
||||
ERC20Vote: `// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC20Vote.sol";
|
||||
|
||||
contract Contract is ERC20Vote {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol
|
||||
)
|
||||
ERC20Vote(
|
||||
_name,
|
||||
_symbol
|
||||
)
|
||||
{}
|
||||
}`,
|
||||
ERC20SignatureMint: `// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC20SignatureMint.sol";
|
||||
|
||||
contract Contract is ERC20SignatureMint {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _primarySaleRecipient
|
||||
)
|
||||
ERC20SignatureMint(
|
||||
_name,
|
||||
_symbol,
|
||||
_primarySaleRecipient
|
||||
)
|
||||
{}
|
||||
}`,
|
||||
|
||||
ERC20SignatureMintVote: `// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC20SignatureMintVote.sol";
|
||||
|
||||
contract Contract is ERC20SignatureMintVote {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _primarySaleRecipient
|
||||
)
|
||||
ERC20SignatureMintVote(
|
||||
_name,
|
||||
_symbol,
|
||||
_primarySaleRecipient
|
||||
)
|
||||
{}
|
||||
}`,
|
||||
|
||||
ERC20Drop: `// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC20Drop.sol";
|
||||
|
||||
contract Contract is ERC20Drop {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _primarySaleRecipient
|
||||
)
|
||||
ERC20Drop(
|
||||
_name,
|
||||
_symbol,
|
||||
_primarySaleRecipient
|
||||
)
|
||||
{}
|
||||
}`,
|
||||
ERC20DropVote: `// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@thirdweb-dev/contracts/base/ERC20DropVote.sol";
|
||||
|
||||
contract Contract is ERC20DropVote {
|
||||
constructor(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _primarySaleRecipient
|
||||
)
|
||||
ERC20DropVote(
|
||||
_name,
|
||||
_symbol,
|
||||
_primarySaleRecipient
|
||||
)
|
||||
{}
|
||||
}`,
|
||||
};
|
||||
|
||||
export default baseContracts;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
* Features that are always recommended to implement
|
||||
*/
|
||||
export const ALWAYS_SUGGESTED = ["ContractMetadata", "Permissions"];
|
||||
export const ALWAYS_SUGGESTED = ["ContractMetadata", "Permissions"];
|
||||
|
||||
@@ -19,4 +19,5 @@ export const PINATA_IPFS_URL = `https://api.pinata.cloud/pinning/pinFileToIPFS`;
|
||||
export const THIRDWEB_URL = `https://thirdweb.com`;
|
||||
|
||||
export const pkg = require("../../package.json");
|
||||
|
||||
export const cliVersion = pkg.version;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { findFiles } from "../../common/file-helper";
|
||||
import { execute } from "../helpers/exec";
|
||||
import { logger, spinner } from "../helpers/logger";
|
||||
import { logger } from "../helpers/logger";
|
||||
import { CompileOptions } from "../interfaces/Builder";
|
||||
import { ContractPayload } from "../interfaces/ContractPayload";
|
||||
import { BaseBuilder } from "./builder-base";
|
||||
@@ -21,7 +21,10 @@ export class BrownieBuilder extends BaseBuilder {
|
||||
config?.project_structure?.build || "./build",
|
||||
);
|
||||
|
||||
existsSync(buildPath) && rmSync(buildPath, { recursive: true });
|
||||
if (existsSync(buildPath)) {
|
||||
rmSync(buildPath, { recursive: true });
|
||||
}
|
||||
|
||||
await execute("brownie compile", options.projectPath);
|
||||
|
||||
const contractsPath = join(buildPath, "contracts/");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ContractPayload } from "../interfaces/ContractPayload";
|
||||
import { ProjectType } from "./../types/ProjectType";
|
||||
import { ProjectType } from "../types/ProjectType";
|
||||
import { BrownieBuilder } from "./brownie";
|
||||
import { FoundryBuilder } from "./foundry";
|
||||
import { HardhatBuilder } from "./hardhat";
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { extractIPFSHashFromBytecode } from "../helpers/ipfs";
|
||||
import { logger } from "../helpers/logger";
|
||||
import { CompileOptions, IBuilder } from "../interfaces/Builder";
|
||||
import { ContractPayload } from "../interfaces/ContractPayload";
|
||||
import { existsSync, readdirSync, statSync } from "fs";
|
||||
import { basename, join } from "path";
|
||||
import { extractIPFSHashFromBytecode } from "@thirdweb-dev/sdk/evm";
|
||||
|
||||
export abstract class BaseBuilder implements IBuilder {
|
||||
abstract compile(
|
||||
@@ -20,7 +18,7 @@ export abstract class BaseBuilder implements IBuilder {
|
||||
bytecode === "" ||
|
||||
bytecode === "0x" ||
|
||||
!abi ||
|
||||
abi.length == 0
|
||||
abi.length === 0
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -111,9 +111,10 @@ export class FoundryBuilder extends BaseBuilder {
|
||||
}
|
||||
|
||||
private sort(object: any) {
|
||||
if (typeof object != "object" || object instanceof Array)
|
||||
if (typeof object !== "object" || object instanceof Array) {
|
||||
// Not to sort the array
|
||||
return object;
|
||||
}
|
||||
var keys = Object.keys(object);
|
||||
keys.sort();
|
||||
var newObject: any = {};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { findFiles } from "../../common/file-helper";
|
||||
import { execute } from "../helpers/exec";
|
||||
import { logger, spinner } from "../helpers/logger";
|
||||
import { logger } from "../helpers/logger";
|
||||
import { CompileOptions } from "../interfaces/Builder";
|
||||
import { ContractPayload } from "../interfaces/ContractPayload";
|
||||
import { BaseBuilder } from "./builder-base";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { findFiles } from "../../common/file-helper";
|
||||
import { logger, spinner } from "../helpers/logger";
|
||||
import { logger } from "../helpers/logger";
|
||||
import { CompileOptions } from "../interfaces/Builder";
|
||||
import { ContractPayload } from "../interfaces/ContractPayload";
|
||||
import { BaseBuilder } from "./builder-base";
|
||||
@@ -122,7 +122,7 @@ export class SolcBuilder extends BaseBuilder {
|
||||
continue;
|
||||
}
|
||||
|
||||
const sources = Object.keys(parsedMetadata.sources)
|
||||
const _sources = Object.keys(parsedMetadata.sources)
|
||||
.map((path) => {
|
||||
const matchingSourcePath = inputPaths.find((p) => p.includes(path));
|
||||
if (matchingSourcePath && existsSync(matchingSourcePath)) {
|
||||
@@ -145,7 +145,7 @@ export class SolcBuilder extends BaseBuilder {
|
||||
metadata,
|
||||
bytecode,
|
||||
name: contractName,
|
||||
sources,
|
||||
sources: _sources,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { findFiles } from "../../common/file-helper";
|
||||
import { execute } from "../helpers/exec";
|
||||
import { logger, spinner } from "../helpers/logger";
|
||||
import { logger } from "../helpers/logger";
|
||||
import { CompileOptions } from "../interfaces/Builder";
|
||||
import { ContractPayload } from "../interfaces/ContractPayload";
|
||||
import { BaseBuilder } from "./builder-base";
|
||||
@@ -22,7 +22,10 @@ export class TruffleBuilder extends BaseBuilder {
|
||||
truffleConfig.contracts_build_directory || "./build/contracts",
|
||||
);
|
||||
|
||||
existsSync(buildPath) && rmSync(buildPath, { recursive: true });
|
||||
if (existsSync(buildPath)) {
|
||||
rmSync(buildPath, { recursive: true });
|
||||
}
|
||||
|
||||
await execute("npx --yes truffle compile", options.projectPath);
|
||||
|
||||
const contracts: ContractPayload[] = [];
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { logger } from "../helpers/logger";
|
||||
import { ProjectType } from "../types/ProjectType";
|
||||
import { Detector } from "./detector";
|
||||
import { existsSync } from "fs";
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { ERROR_MESSAGES } from "../../../constants/constants";
|
||||
import { info, logger, warn } from "../helpers/logger";
|
||||
import { ProjectType } from "../types/ProjectType";
|
||||
import { Detector } from "./detector";
|
||||
import FoundryDetector from "./foundry";
|
||||
import HardhatDetector from "./hardhat";
|
||||
import TruffleDetector from "./truffle";
|
||||
import fs, { existsSync } from "fs";
|
||||
import inquirer from "inquirer";
|
||||
import { parse } from "path";
|
||||
|
||||
const { Confirm } = require("enquirer");
|
||||
|
||||
@@ -25,17 +28,24 @@ export default async function detect(
|
||||
|
||||
//if there is no project returned at all then just return unknown}
|
||||
if (!possibleProjectTypes.length) {
|
||||
warn("Failed to find a supported project configuration file in current directory " + path);
|
||||
const prompt = new Confirm({
|
||||
name: "continue",
|
||||
message: "Do you want to continue and compile this project with solc instead?",
|
||||
});
|
||||
const shouldCompile = await prompt.run();
|
||||
if (!shouldCompile) {
|
||||
logger.warn("Aborted contract compilation");
|
||||
process.exit(1);
|
||||
const canCompile = hasContracts(path);
|
||||
|
||||
if (canCompile) {
|
||||
warn(`${ERROR_MESSAGES.noConfiguration} ${path}`);
|
||||
const prompt = new Confirm({
|
||||
name: "continue",
|
||||
message:
|
||||
"Do you want to continue and compile this project with solc instead?",
|
||||
});
|
||||
const shouldCompile = await prompt.run();
|
||||
if (!shouldCompile) {
|
||||
logger.warn("Aborted contract compilation");
|
||||
process.exit(1);
|
||||
}
|
||||
return "solc";
|
||||
} else {
|
||||
return "none";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
//if there is only one possible option just return it
|
||||
if (possibleProjectTypes.length === 1) {
|
||||
@@ -62,3 +72,24 @@ export default async function detect(
|
||||
return answer[question];
|
||||
}
|
||||
}
|
||||
|
||||
// Check if a directory has any .sol files or a /contracts folder with .sol files
|
||||
function hasContracts(path: any) {
|
||||
return (
|
||||
["", "/contracts"].filter((p) => {
|
||||
const dirPath = path + p;
|
||||
|
||||
if (!existsSync(dirPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const files = fs.readdirSync(dirPath);
|
||||
const contracts = files.filter((filePath) => {
|
||||
const { ext } = parse(filePath);
|
||||
return ext === ".sol";
|
||||
});
|
||||
|
||||
return contracts.length > 0;
|
||||
}).length > 0
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { logger } from "../helpers/logger";
|
||||
import { ProjectType } from "../types/ProjectType";
|
||||
import { Detector } from "./detector";
|
||||
import { existsSync } from "fs";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { logger } from "../helpers/logger";
|
||||
import { ProjectType } from "../types/ProjectType";
|
||||
import { Detector } from "./detector";
|
||||
import { existsSync } from "fs";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { logger } from "../helpers/logger";
|
||||
import { ProjectType } from "../types/ProjectType";
|
||||
import { Detector } from "./detector";
|
||||
import { existsSync } from "fs";
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
import { logger } from "./logger";
|
||||
import { decodeFirstSync } from "cbor";
|
||||
import { UnixFS } from "ipfs-unixfs";
|
||||
import { DAGNode } from "ipld-dag-pb";
|
||||
import { toB58String } from "multihashes";
|
||||
|
||||
/**
|
||||
* Derives IPFS hash of string
|
||||
* @param {String} str
|
||||
* @return {String} IPFS hash (ex: "Qm")
|
||||
*/
|
||||
export async function getIPFSHash(str: string) {
|
||||
const file = new UnixFS({
|
||||
type: "file",
|
||||
data: Buffer.from(str),
|
||||
});
|
||||
const node = new DAGNode(file.marshal());
|
||||
const metadataLink = await node.toDAGLink();
|
||||
return toB58String(metadataLink.Hash.multihash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the IPFS hash from the given bytecode
|
||||
* @param bytecode
|
||||
* @returns
|
||||
*/
|
||||
export function extractIPFSHashFromBytecode(
|
||||
bytecode: string,
|
||||
): string | undefined {
|
||||
const numericBytecode = hexToBytes(bytecode);
|
||||
const cborLength: number =
|
||||
numericBytecode[numericBytecode.length - 2] * 0x100 +
|
||||
numericBytecode[numericBytecode.length - 1];
|
||||
const bytecodeBuffer = Buffer.from(
|
||||
numericBytecode.slice(numericBytecode.length - 2 - cborLength, -2),
|
||||
);
|
||||
const cborData = decodeFirstSync(bytecodeBuffer);
|
||||
if (cborData["ipfs"]) {
|
||||
const uri = toB58String(cborData["ipfs"]);
|
||||
return uri;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function hexToBytes(hex: string | number) {
|
||||
hex = hex.toString(16);
|
||||
if (!hex.startsWith("0x")) {
|
||||
hex = `0x${hex}`;
|
||||
}
|
||||
if (!isHexStrict(hex)) {
|
||||
throw new Error('Given value "' + hex + '" is not a valid hex string.');
|
||||
}
|
||||
|
||||
hex = hex.replace(/^0x/i, "");
|
||||
|
||||
for (var bytes = [], c = 0; c < hex.length; c += 2)
|
||||
bytes.push(parseInt(hex.slice(c, c + 2), 16));
|
||||
return bytes;
|
||||
}
|
||||
|
||||
function isHexStrict(hex: string | number) {
|
||||
return (
|
||||
(typeof hex === "string" || typeof hex === "number") &&
|
||||
/^(-)?0x[0-9a-f]*$/i.test(hex.toString())
|
||||
);
|
||||
}
|
||||
@@ -5,7 +5,7 @@ const { MultiSelect } = require("enquirer");
|
||||
|
||||
export function createContractsPrompt(
|
||||
choices: { name: string; value: ContractPayload }[],
|
||||
message: string
|
||||
message: string,
|
||||
) {
|
||||
return new MultiSelect({
|
||||
name: "value",
|
||||
@@ -33,4 +33,4 @@ export function createContractsPrompt(
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
export interface Feature {
|
||||
/**
|
||||
* The name of the contract (with the .sol extension)
|
||||
@@ -20,7 +19,6 @@ export interface ContractFeatures {
|
||||
*/
|
||||
name: string;
|
||||
|
||||
|
||||
/**
|
||||
* The features detected on the contract
|
||||
*/
|
||||
@@ -30,4 +28,4 @@ export interface ContractFeatures {
|
||||
* The features suggested to implement on the contract
|
||||
*/
|
||||
suggestedFeatures: Feature[];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,4 +3,5 @@ export type ProjectType =
|
||||
| "foundry"
|
||||
| "hardhat"
|
||||
| "truffle"
|
||||
| "unknown";
|
||||
| "solc"
|
||||
| "none";
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import { CREATE_MESSAGES } from "../../constants/constants";
|
||||
import { DownloadError, createApp } from "./helpers/create-app";
|
||||
import { createContract } from "./helpers/create-contract";
|
||||
import { getPkgManager } from "./helpers/get-pkg-manager";
|
||||
@@ -16,9 +17,9 @@ let language: string = "";
|
||||
let baseContract: string = "";
|
||||
/* let createType: string = "app"; */
|
||||
|
||||
export async function twCreate(options: any) {
|
||||
if (typeof projectPath === "string") {
|
||||
projectPath = projectPath.trim();
|
||||
export async function twCreate(pPath: string = "", options: any) {
|
||||
if (typeof pPath === "string") {
|
||||
projectPath = pPath;
|
||||
}
|
||||
|
||||
if (options.app) {
|
||||
@@ -65,7 +66,7 @@ export async function twCreate(options: any) {
|
||||
const res = await prompts({
|
||||
type: "select",
|
||||
name: "projectType",
|
||||
message: "What type of project do you want to create?",
|
||||
message: CREATE_MESSAGES.typeOfProject,
|
||||
choices: [
|
||||
{ title: "App", value: "app" },
|
||||
{ title: "Contract", value: "contract" },
|
||||
@@ -87,14 +88,17 @@ export async function twCreate(options: any) {
|
||||
const res = await prompts({
|
||||
type: "text",
|
||||
name: "path",
|
||||
message: "What is your project named?",
|
||||
message: CREATE_MESSAGES.projectName,
|
||||
initial: options.template || defaultName,
|
||||
validate: (name) => {
|
||||
const validation = validateNpmName(path.basename(path.resolve(name)));
|
||||
format: (name: string) => name.toLowerCase(),
|
||||
validate: (name: string) => {
|
||||
const validation = validateNpmName(
|
||||
path.basename(path.resolve(name.toLowerCase())),
|
||||
);
|
||||
if (validation.valid) {
|
||||
return true;
|
||||
}
|
||||
return "Invalid project name: " + validation.problems![0];
|
||||
return "Invalid project name: " + validation.problems?.[0];
|
||||
},
|
||||
});
|
||||
|
||||
@@ -123,7 +127,7 @@ export async function twCreate(options: any) {
|
||||
const res = await prompts({
|
||||
type: "select",
|
||||
name: "framework",
|
||||
message: "What framework do you want to use?",
|
||||
message: CREATE_MESSAGES.framework,
|
||||
choices: [
|
||||
{ title: "Next.js", value: "next" },
|
||||
{ title: "Create React App", value: "cra" },
|
||||
@@ -140,7 +144,7 @@ export async function twCreate(options: any) {
|
||||
const res = await prompts({
|
||||
type: "select",
|
||||
name: "language",
|
||||
message: "What language do you want to use?",
|
||||
message: CREATE_MESSAGES.language,
|
||||
choices: [
|
||||
{ title: "JavaScript", value: "javascript" },
|
||||
{ title: "TypeScript", value: "typescript" },
|
||||
@@ -160,7 +164,7 @@ export async function twCreate(options: any) {
|
||||
const res = await prompts({
|
||||
type: "select",
|
||||
name: "framework",
|
||||
message: "What framework do you want to use?",
|
||||
message: CREATE_MESSAGES.framework,
|
||||
choices: [
|
||||
{ title: "Hardhat", value: "hardhat" },
|
||||
{ title: "Forge", value: "forge" },
|
||||
@@ -174,36 +178,64 @@ export async function twCreate(options: any) {
|
||||
|
||||
// Select base contract
|
||||
if (projectType === "contract" && !baseContract) {
|
||||
const res = await prompts({
|
||||
let standard = "none";
|
||||
const standardPrompt = await prompts({
|
||||
type: "select",
|
||||
name: "baseContract",
|
||||
message: "What contract do you want to start from?",
|
||||
name: "standard",
|
||||
message: CREATE_MESSAGES.contract,
|
||||
choices: [
|
||||
{ title: "Empty Contract", value: "" },
|
||||
{ title: "ERC721 Base", value: "ERC721Base" },
|
||||
{ title: "ERC721 + Signature Mint", value: "ERC721Signature" },
|
||||
{ title: "ERC721 + Lazy Mint", value: "ERC721LazyMint" },
|
||||
{ title: "ERC721 + Delayed Reveal", value: "ERC721DelayedReveal" },
|
||||
{ title: "ERC721 + Drop", value: "ERC721Drop" },
|
||||
{ title: "ERC1155 Base", value: "ERC1155Base" },
|
||||
{ title: "ERC1155 + Signature Mint", value: "ERC1155Signature" },
|
||||
{ title: "ERC1155 + Lazy Mint", value: "ERC1155LazyMint" },
|
||||
{ title: "ERC1155 + Delayed Reveal", value: "ERC1155DelayedReveal" },
|
||||
{ title: "ERC1155 + Drop", value: "ERC1155Drop" },
|
||||
{ title: "ERC20 Base", value: "ERC20Base" },
|
||||
{ title: "ERC20 + Vote", value: "ERC20Vote" },
|
||||
{ title: "ERC20 + Signature Mint", value: "ERC20SignatureMint" },
|
||||
{
|
||||
title: "ERC20 + Vote + Signature Mint",
|
||||
value: "ERC20SignatureMintVote",
|
||||
},
|
||||
{ title: "ERC20 + Drop", value: "ERC20Drop" },
|
||||
{ title: "ERC20 + Vote + Drop", value: "ERC20DropVote" },
|
||||
{ title: "Empty Contract", value: "none" },
|
||||
{ title: "ERC721", value: "erc721" },
|
||||
{ title: "ERC20", value: "erc20" },
|
||||
{ title: "ERC1155", value: "erc1155" },
|
||||
],
|
||||
});
|
||||
|
||||
if (typeof res.baseContract === "string") {
|
||||
baseContract = res.baseContract.trim();
|
||||
if (typeof standardPrompt.standard === "string") {
|
||||
standard = standardPrompt.standard.trim();
|
||||
}
|
||||
|
||||
if (standard === "none") {
|
||||
baseContract = "";
|
||||
} else {
|
||||
let choices: prompts.Choice[] = [];
|
||||
if (standard === "erc721") {
|
||||
choices = [
|
||||
{ title: "None", value: "ERC721Base" },
|
||||
{ title: "Signature Mint", value: "ERC721SignatureMint" },
|
||||
{ title: "Lazy Mint", value: "ERC721LazyMint" },
|
||||
{ title: "Delayed Reveal", value: "ERC721DelayedReveal" },
|
||||
{ title: "Drop", value: "ERC721Drop" },
|
||||
];
|
||||
} else if (standard === "erc20") {
|
||||
choices = [
|
||||
{ title: "None", value: "ERC20Base" },
|
||||
{ title: "Vote", value: "ERC20Vote" },
|
||||
{ title: "Signature Mint", value: "ERC20SignatureMint" },
|
||||
{ title: "Vote + Signature Mint", value: "ERC20SignatureMintVote" },
|
||||
{ title: "Drop", value: "ERC20Drop" },
|
||||
{ title: "Vote + Drop", value: "ERC20DropVote" },
|
||||
];
|
||||
} else if (standard === "erc1155") {
|
||||
choices = [
|
||||
{ title: "None", value: "ERC1155Base" },
|
||||
{ title: "Signature Mint", value: "ERC1155SignatureMint" },
|
||||
{ title: "Lazy Mint", value: "ERC1155LazyMint" },
|
||||
{ title: "Delayed Reveal", value: "ERC1155DelayedReveal" },
|
||||
{ title: "Drop", value: "ERC1155Drop" },
|
||||
];
|
||||
}
|
||||
|
||||
const res = await prompts({
|
||||
type: "select",
|
||||
name: "baseContract",
|
||||
message: CREATE_MESSAGES.extensions,
|
||||
choices: choices,
|
||||
});
|
||||
|
||||
if (typeof res.baseContract === "string") {
|
||||
baseContract = res.baseContract.trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,7 +261,7 @@ export async function twCreate(options: any) {
|
||||
)} because of npm naming restrictions:`,
|
||||
);
|
||||
|
||||
problems!.forEach((p) => console.error(` ${chalk.red.bold("*")} ${p}`));
|
||||
problems?.forEach((p) => console.error(` ${chalk.red.bold("*")} ${p}`));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// Import the base contracts'
|
||||
import baseContracts from "../../constants/base-contracts";
|
||||
|
||||
export function hasBaseContract(name: string): boolean {
|
||||
return baseContracts[name as keyof typeof baseContracts] !== undefined;
|
||||
}
|
||||
|
||||
export function readBaseContract(name: string): string {
|
||||
return baseContracts[name as keyof typeof baseContracts];
|
||||
}
|
||||
// Import the base contracts'
|
||||
import baseContracts from "../../constants/base-contracts";
|
||||
|
||||
export function hasBaseContract(name: string): boolean {
|
||||
return baseContracts[name as keyof typeof baseContracts] !== undefined;
|
||||
}
|
||||
|
||||
export function readBaseContract(name: string): string {
|
||||
return baseContracts[name as keyof typeof baseContracts];
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import { makeDir } from "./make-dir";
|
||||
import { downloadAndExtractRepo, hasTemplate } from "./templates";
|
||||
import retry from "async-retry";
|
||||
import chalk from "chalk";
|
||||
import fs from "fs";
|
||||
import os from "os";
|
||||
import path from "path";
|
||||
|
||||
export class DownloadError extends Error {}
|
||||
@@ -109,10 +111,24 @@ export async function createApp({
|
||||
);
|
||||
} catch (reason) {
|
||||
throw new DownloadError(
|
||||
isErrorLike(reason) ? reason.message : reason + "",
|
||||
isErrorLike(reason) ? reason.message : String(reason),
|
||||
);
|
||||
}
|
||||
|
||||
const jsonFile = path.join(root, "package.json");
|
||||
const packageString = fs.readFileSync(jsonFile);
|
||||
try {
|
||||
const packageJson = JSON.parse(packageString.toString());
|
||||
if (packageJson) {
|
||||
packageJson.name = appName;
|
||||
}
|
||||
|
||||
fs.writeFileSync(jsonFile, JSON.stringify(packageJson, null, 2) + os.EOL);
|
||||
} catch (e) {
|
||||
console.log("Failed to re-name package.json, continuing...");
|
||||
console.log();
|
||||
}
|
||||
|
||||
console.log("Installing packages. This might take a couple of minutes.");
|
||||
console.log();
|
||||
|
||||
@@ -137,10 +153,25 @@ export async function createApp({
|
||||
);
|
||||
} catch (reason) {
|
||||
throw new DownloadError(
|
||||
isErrorLike(reason) ? reason.message : reason + "",
|
||||
isErrorLike(reason) ? reason.message : String(reason),
|
||||
);
|
||||
}
|
||||
|
||||
const jsonFile = path.join(root, "package.json");
|
||||
const packageString = fs.readFileSync(jsonFile);
|
||||
try {
|
||||
const packageJson = JSON.parse(packageString.toString());
|
||||
if (packageJson) {
|
||||
packageJson.name = appName;
|
||||
}
|
||||
|
||||
fs.writeFileSync(jsonFile, JSON.stringify(packageJson, null, 2) + os.EOL);
|
||||
} catch (e) {
|
||||
console.log("Failed to re-name package.json, continuing...");
|
||||
|
||||
console.log();
|
||||
}
|
||||
|
||||
console.log("Installing packages. This might take a couple of minutes.");
|
||||
console.log();
|
||||
|
||||
|
||||
@@ -7,12 +7,12 @@ import { isFolderEmpty } from "./is-folder-empty";
|
||||
import { getOnline } from "./is-online";
|
||||
import { isWriteable } from "./is-writeable";
|
||||
import { makeDir } from "./make-dir";
|
||||
import { downloadAndExtractRepo, hasTemplate } from "./templates";
|
||||
import { submodules } from "./submodules";
|
||||
import { downloadAndExtractRepo } from "./templates";
|
||||
import retry from "async-retry";
|
||||
import chalk from "chalk";
|
||||
import { writeFile } from "fs/promises";
|
||||
import path from "path";
|
||||
import { submodules } from "./submodules";
|
||||
|
||||
interface ICreateContract {
|
||||
contractPath: string;
|
||||
@@ -88,7 +88,7 @@ export async function createContract({
|
||||
starter = "forge-starter";
|
||||
} else {
|
||||
console.error("Please provide a valid contracts framework.");
|
||||
process.exit(1)
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
await retry(
|
||||
@@ -115,7 +115,9 @@ export async function createContract({
|
||||
await writeFile(contractFile, baseContractText);
|
||||
}
|
||||
} catch (reason) {
|
||||
throw new DownloadError(isErrorLike(reason) ? reason.message : reason + "");
|
||||
throw new DownloadError(
|
||||
isErrorLike(reason) ? reason.message : String(reason),
|
||||
);
|
||||
}
|
||||
|
||||
console.log("Installing packages. This might take a couple of minutes.");
|
||||
@@ -143,15 +145,21 @@ export async function createContract({
|
||||
console.log(
|
||||
`${chalk.green("Success!")} Created ${projectName} at ${contractPath}`,
|
||||
);
|
||||
console.log();
|
||||
console.log("Inside that directory, you can run several commands:");
|
||||
console.log();
|
||||
console.log(chalk.cyan(` ${packageManager} ${useYarn ? "" : "run"} deploy`));
|
||||
console.log(chalk.cyan(` ${packageManager}${useYarn ? "" : " run"} build`));
|
||||
console.log(
|
||||
" Compiles your contracts and detects thirdweb extensions implemented on them.",
|
||||
);
|
||||
console.log();
|
||||
console.log(chalk.cyan(` ${packageManager}${useYarn ? "" : " run"} deploy`));
|
||||
console.log(" Deploys your contracts with the thirdweb deploy flow.");
|
||||
console.log();
|
||||
console.log(
|
||||
chalk.cyan(` ${packageManager} ${useYarn ? "" : "run"} release`),
|
||||
chalk.cyan(` ${packageManager}${useYarn ? "" : " run"} release`),
|
||||
);
|
||||
console.log(" Releases your contracts with the thirdweb release flow..");
|
||||
console.log(" Releases your contracts with the thirdweb release flow.");
|
||||
console.log();
|
||||
console.log("We suggest that you begin by typing:");
|
||||
console.log();
|
||||
|
||||
@@ -4,6 +4,7 @@ export type PackageManager = "npm" | "pnpm" | "yarn";
|
||||
|
||||
export function getPkgManager(): PackageManager {
|
||||
try {
|
||||
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
||||
const userAgent = process.env.npm_config_user_agent;
|
||||
if (userAgent) {
|
||||
if (userAgent.startsWith("yarn")) {
|
||||
|
||||
@@ -33,7 +33,7 @@ export function tryGitInit(root: string): boolean {
|
||||
execSync("git checkout -b main", { stdio: "ignore" });
|
||||
|
||||
execSync("git add -A", { stdio: "ignore" });
|
||||
execSync('git commit -m "Initial commit from Create thirdweb app"', {
|
||||
execSync('git commit -m "Initial commit from npx thirdweb create"', {
|
||||
stdio: "ignore",
|
||||
});
|
||||
return true;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import type { PackageManager } from "./get-pkg-manager";
|
||||
import chalk from "chalk";
|
||||
import spawn from "cross-spawn";
|
||||
import type { PackageManager } from "./get-pkg-manager";
|
||||
|
||||
interface InstallArgs {
|
||||
/**
|
||||
@@ -53,9 +53,13 @@ export function install(
|
||||
* Call `yarn add --exact (--offline)? (-D)? ...`.
|
||||
*/
|
||||
args = ["add", "--exact"];
|
||||
if (!isOnline) args.push("--offline");
|
||||
if (!isOnline) {
|
||||
args.push("--offline");
|
||||
}
|
||||
args.push("--cwd", root);
|
||||
if (devDependencies) args.push("--dev");
|
||||
if (devDependencies) {
|
||||
args.push("--dev");
|
||||
}
|
||||
args.push(...dependencies);
|
||||
} else {
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,9 @@ import dns from "dns";
|
||||
import url from "url";
|
||||
|
||||
function getProxy(): string | undefined {
|
||||
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
||||
if (process.env.https_proxy) {
|
||||
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
||||
return process.env.https_proxy;
|
||||
}
|
||||
|
||||
@@ -33,7 +35,7 @@ export function getOnline(): Promise<boolean> {
|
||||
}
|
||||
|
||||
dns.lookup(hostname, (proxyErr) => {
|
||||
resolve(proxyErr == null);
|
||||
resolve(proxyErr === null);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,4 +14,4 @@ export async function runCommand(command: string, args: string[]) {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,11 @@ export async function submodules(): Promise<void> {
|
||||
await runCommand("rm", ["-rf", ".gitmodules"]);
|
||||
await runCommand("rm", ["-rf", "lib"]);
|
||||
await runCommand("touch", [".gitmodules"]);
|
||||
await runCommand("git", ["submodule", "add", "https://github.com/foundry-rs/forge-std.git", "lib/forge-std"])
|
||||
await runCommand("git", [
|
||||
"submodule",
|
||||
"add",
|
||||
"https://github.com/foundry-rs/forge-std.git",
|
||||
"lib/forge-std",
|
||||
]);
|
||||
await runCommand("git", ["submodule", "update", "--init", "--recursive"]);
|
||||
}
|
||||
|
||||
@@ -1,38 +1,38 @@
|
||||
export default function generateDashboardUrl(
|
||||
name: string,
|
||||
version: string | undefined,
|
||||
): string | undefined {
|
||||
const splitName = name.split("/");
|
||||
// Released contract
|
||||
if (splitName.length > 1) {
|
||||
return `https://thirdweb.com/dashboard/${splitName[0]}/${splitName[1]}${
|
||||
version ? `/${version}` : ""
|
||||
}`;
|
||||
}
|
||||
|
||||
// Pre-built contract
|
||||
else {
|
||||
const mapping = {
|
||||
"signature-drop": "drop/signature-drop",
|
||||
"nft-drop": "drop/nft-drop",
|
||||
"edition-drop": "drop/edition-drop",
|
||||
"nft-collection": "token/nft-collection",
|
||||
edition: "token/edition",
|
||||
"token-drop": "drop/token-drop",
|
||||
token: "token/token",
|
||||
marketplace: "marketplace/marketplace",
|
||||
split: "governance/split",
|
||||
vote: "governance/vote",
|
||||
pack: "token/pack",
|
||||
multiwrap: "token/multiwrap",
|
||||
};
|
||||
|
||||
const foundMapping = mapping[name as keyof typeof mapping];
|
||||
|
||||
if (!foundMapping) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return `https://thirdweb.com/contracts/new/pre-built/${foundMapping}`;
|
||||
}
|
||||
}
|
||||
export default function generateDashboardUrl(
|
||||
name: string,
|
||||
version: string | undefined,
|
||||
): string | undefined {
|
||||
const splitName = name.split("/");
|
||||
// Released contract
|
||||
if (splitName.length > 1) {
|
||||
return `https://thirdweb.com/dashboard/${splitName[0]}/${splitName[1]}${
|
||||
version ? `/${version}` : ""
|
||||
}`;
|
||||
}
|
||||
|
||||
// Pre-built contract
|
||||
else {
|
||||
const mapping = {
|
||||
"signature-drop": "drop/signature-drop",
|
||||
"nft-drop": "drop/nft-drop",
|
||||
"edition-drop": "drop/edition-drop",
|
||||
"nft-collection": "token/nft-collection",
|
||||
edition: "token/edition",
|
||||
"token-drop": "drop/token-drop",
|
||||
token: "token/token",
|
||||
marketplace: "marketplace/marketplace",
|
||||
split: "governance/split",
|
||||
vote: "governance/vote",
|
||||
pack: "token/pack",
|
||||
multiwrap: "token/multiwrap",
|
||||
};
|
||||
|
||||
const foundMapping = mapping[name as keyof typeof mapping];
|
||||
|
||||
if (!foundMapping) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return `https://thirdweb.com/contracts/new/pre-built/${foundMapping}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
(BigInt.prototype as any).toJSON = function () {
|
||||
return this.toString();
|
||||
};
|
||||
|
||||
console.log(`__tw__${JSON.stringify((globalThis as any).config)}__tw__`);
|
||||
|
||||
export {};
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
import { logger } from "../core/helpers/logger";
|
||||
import { spinner } from "../core/helpers/logger";
|
||||
import { BufferOrStringWithName, ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import chalk from "chalk";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
function recurseFiles(
|
||||
uploadPath: string,
|
||||
basePath: string,
|
||||
): BufferOrStringWithName[] {
|
||||
const files = [];
|
||||
|
||||
const fileType = fs.lstatSync(uploadPath);
|
||||
if (fileType.isFile()) {
|
||||
const fileName = path.relative(basePath, uploadPath);
|
||||
const fileData = fs.readFileSync(uploadPath);
|
||||
files.push({ name: fileName, data: fileData });
|
||||
} else if (fileType.isDirectory()) {
|
||||
const paths = fs.readdirSync(uploadPath);
|
||||
paths.forEach((subPath) => {
|
||||
const fullSubPath = path.join(uploadPath, subPath);
|
||||
const subFiles = recurseFiles(fullSubPath, basePath);
|
||||
subFiles.forEach((file) => files.push(file));
|
||||
});
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
export async function upload(
|
||||
storage: ThirdwebStorage,
|
||||
uploadPath: string,
|
||||
): Promise<string> {
|
||||
if (!uploadPath) {
|
||||
logger.error(
|
||||
`Please pass a path to a file or directory to upload with the following format:\n ${chalk.blueBright(
|
||||
`npx thirdweb@latest upload path/to/file.jpg`,
|
||||
)}\n`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const pathExists = fs.existsSync(uploadPath);
|
||||
if (!pathExists) {
|
||||
logger.error(
|
||||
`Invalid path ${chalk.blueBright(
|
||||
uploadPath,
|
||||
)} provided. Please provide a valid path to a file or directory to upload."`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
let uri = "";
|
||||
const fileType = fs.lstatSync(uploadPath);
|
||||
if (fileType.isDirectory()) {
|
||||
const files = recurseFiles(uploadPath, uploadPath);
|
||||
|
||||
if (files.length === 0) {
|
||||
logger.error(
|
||||
`No files detected in specified directory ${chalk.blueBright(
|
||||
uploadPath,
|
||||
)} to upload.`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const spin = spinner(
|
||||
"Uploading directory to IPFS. This may take a while depending on file sizes.",
|
||||
);
|
||||
const uris = await storage.uploadBatch(files);
|
||||
spin.succeed("Successfully uploaded directory to IPFS");
|
||||
uri = uris[0].substring(0, uris[0].lastIndexOf("/"));
|
||||
} else if (fileType.isFile()) {
|
||||
const fileName = path.parse(uploadPath).base;
|
||||
const fileData = fs.readFileSync(uploadPath);
|
||||
const file = { name: fileName, data: fileData };
|
||||
|
||||
const spin = spinner(
|
||||
"Uploading file to IPFS. This may take a while depending on file sizes.",
|
||||
);
|
||||
uri = await storage.upload(file, { uploadWithoutDirectory: true });
|
||||
spin.succeed("Succesfully uploaded file to IPFS.");
|
||||
} else {
|
||||
logger.error(
|
||||
`Path ${chalk.blueBright(
|
||||
uploadPath,
|
||||
)} does not point to a valid file or directory. Please provide a valid path to a file or directory to upload`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
return uri;
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
{
|
||||
"extends": "@thirdweb-dev/tsconfig/sdk.json",
|
||||
"include": ["src"],
|
||||
"exclude": ["dist", "build", "node_modules"]
|
||||
"exclude": ["dist", "build", "node_modules"],
|
||||
"compilerOptions": {
|
||||
"allowJs": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
src/
|
||||
@@ -1,5 +1,47 @@
|
||||
# @thirdweb-dev/contracts-js
|
||||
|
||||
## 1.1.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#226](https://github.com/thirdweb-dev/js/pull/226) [`f2a6211`](https://github.com/thirdweb-dev/js/commit/f2a62110c43e7b8f35c86a197730e732f8fcc786) Thanks [@jnsdls](https://github.com/jnsdls)! - expose some factories as separate exports
|
||||
|
||||
## 1.1.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#90](https://github.com/thirdweb-dev/js/pull/90) [`820a519`](https://github.com/thirdweb-dev/js/commit/820a5191b5e7af5aba5e4d1cc90cd895c0dade11) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Update to contracts v3.1.7
|
||||
|
||||
## 1.1.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#61](https://github.com/thirdweb-dev/js/pull/61) [`3287c2b`](https://github.com/thirdweb-dev/js/commit/3287c2b0f233332fe4a095f973deed8efab91db6) Thanks [@jnsdls](https://github.com/jnsdls)! - fix versions in dependencies before releasing stable
|
||||
|
||||
## 1.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#59](https://github.com/thirdweb-dev/js/pull/59) [`6ba9cad`](https://github.com/thirdweb-dev/js/commit/6ba9cad8d8b933256599dc3b147601cd4828c89b) Thanks [@jnsdls](https://github.com/jnsdls)! - move `abis` from top level into `dist` in contracts-js
|
||||
|
||||
## 1.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`5644ccd`](https://github.com/thirdweb-dev/js/commit/5644ccd3ee2ff330e4e5840d3266033376750117) Thanks [@jnsdls](https://github.com/jnsdls)! - bump versions again
|
||||
|
||||
## 1.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`091f175`](https://github.com/thirdweb-dev/js/commit/091f1758604d40e825ea28a13c2699d67bc75d8c) Thanks [@jnsdls](https://github.com/jnsdls)! - release-all-packages
|
||||
|
||||
## 1.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#53](https://github.com/thirdweb-dev/js/pull/53) [`924247a`](https://github.com/thirdweb-dev/js/commit/924247a8ed5ef1867dccfad9479b00f71795ebf6) Thanks [@jnsdls](https://github.com/jnsdls)! - do not check-in abis output
|
||||
|
||||
## 1.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
[
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "string",
|
||||
"name": "prevURI",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "string",
|
||||
"name": "newURI",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "AppURIUpdated",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "appURI",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "_uri",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "setAppURI",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
@@ -1,34 +0,0 @@
|
||||
[
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "getBaseURICount",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_index",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "getBatchIdAtIndex",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
@@ -1 +0,0 @@
|
||||
[]
|
||||
@@ -1,47 +0,0 @@
|
||||
[
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "string",
|
||||
"name": "prevURI",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "string",
|
||||
"name": "newURI",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "ContractURIUpdated",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "contractURI",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "_uri",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "setContractURI",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
@@ -1,717 +0,0 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_trustedForwarder",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "contract IContractPublisher",
|
||||
"name": "_prevPublisher",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "operator",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "publisher",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "contractId",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "publishTimestamp",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "publishMetadataUri",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "bytecodeHash",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"indexed": false,
|
||||
"internalType": "struct IContractPublisher.CustomContractInstance",
|
||||
"name": "publishedContract",
|
||||
"type": "tuple"
|
||||
}
|
||||
],
|
||||
"name": "ContractPublished",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "operator",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "publisher",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "string",
|
||||
"name": "contractId",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "ContractUnpublished",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "bool",
|
||||
"name": "isPaused",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "Paused",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "publisher",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "string",
|
||||
"name": "prevURI",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "string",
|
||||
"name": "newURI",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "PublisherProfileUpdated",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "role",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "previousAdminRole",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "newAdminRole",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "RoleAdminChanged",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "role",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "sender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "RoleGranted",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "bytes32",
|
||||
"name": "role",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "sender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "RoleRevoked",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "DEFAULT_ADMIN_ROLE",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_publisher",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getAllPublishedContracts",
|
||||
"outputs": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "contractId",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "publishTimestamp",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "publishMetadataUri",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "bytecodeHash",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"internalType": "struct IContractPublisher.CustomContractInstance[]",
|
||||
"name": "published",
|
||||
"type": "tuple[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_publisher",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "_contractId",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "getPublishedContract",
|
||||
"outputs": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "contractId",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "publishTimestamp",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "publishMetadataUri",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "bytecodeHash",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"internalType": "struct IContractPublisher.CustomContractInstance",
|
||||
"name": "published",
|
||||
"type": "tuple"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_publisher",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "_contractId",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "getPublishedContractVersions",
|
||||
"outputs": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "contractId",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "publishTimestamp",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "publishMetadataUri",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "bytecodeHash",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"internalType": "struct IContractPublisher.CustomContractInstance[]",
|
||||
"name": "published",
|
||||
"type": "tuple[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "compilerMetadataUri",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "getPublishedUriFromCompilerUri",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string[]",
|
||||
"name": "publishedMetadataUris",
|
||||
"type": "string[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "publisher",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getPublisherProfileUri",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "uri",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "role",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "getRoleAdmin",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "role",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "index",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "getRoleMember",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "role",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "getRoleMemberCount",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "role",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "grantRole",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "role",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "hasRole",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "isPaused",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "forwarder",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "isTrustedForwarder",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes[]",
|
||||
"name": "data",
|
||||
"type": "bytes[]"
|
||||
}
|
||||
],
|
||||
"name": "multicall",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes[]",
|
||||
"name": "results",
|
||||
"type": "bytes[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "prevPublisher",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "contract IContractPublisher",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_publisher",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "_contractId",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "_publishMetadataUri",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "_compilerMetadataUri",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "_bytecodeHash",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "publishContract",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "role",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "renounceRole",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "role",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "revokeRole",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "_pause",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "setPause",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "publisher",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "uri",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "setPublisherProfileUri",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes4",
|
||||
"name": "interfaceId",
|
||||
"type": "bytes4"
|
||||
}
|
||||
],
|
||||
"name": "supportsInterface",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_publisher",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "_contractId",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "unpublishContract",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
@@ -1 +0,0 @@
|
||||
[]
|
||||
@@ -1,15 +0,0 @@
|
||||
[
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "NATIVE_TOKEN",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
@@ -1,131 +0,0 @@
|
||||
[
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "uint256",
|
||||
"name": "index",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "string",
|
||||
"name": "revealedURI",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"name": "TokenURIRevealed",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "data",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "key",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "encryptDecrypt",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "result",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "encryptedData",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_batchId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "_key",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "getRevealURI",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "revealedURI",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_batchId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "isEncryptedBatch",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "identifier",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "key",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "reveal",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "revealedURI",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
@@ -1,530 +0,0 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "blockTimestamp",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "startTimestamp",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "lastClaimedAt",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "nextValidClaimTimestamp",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Drop__CannotClaimYet",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "supplyClaimed",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "maxClaimableSupply",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Drop__ExceedMaxClaimableSupply",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "givenCurrency",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "requiredCurrency",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "givenPricePerToken",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "requiredPricePerToken",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Drop__InvalidCurrencyOrPrice",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "Drop__InvalidQuantity",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "maxQuantityInAllowlist",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Drop__InvalidQuantityProof",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "supplyClaimedAlready",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Drop__MaxSupplyClaimedAlready",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "Drop__NotAuthorized",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "Drop__NotInWhitelist",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "Drop__ProofClaimed",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "startTimestamp",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "maxClaimableSupply",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "supplyClaimed",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "quantityLimitPerTransaction",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "waitTimeInSecondsBetweenClaims",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "merkleRoot",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "pricePerToken",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "currency",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"indexed": false,
|
||||
"internalType": "struct IClaimCondition.ClaimCondition[]",
|
||||
"name": "claimConditions",
|
||||
"type": "tuple[]"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "bool",
|
||||
"name": "resetEligibility",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "ClaimConditionsUpdated",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "uint256",
|
||||
"name": "claimConditionIndex",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "claimer",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "receiver",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "startTokenId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "quantityClaimed",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "TokensClaimed",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_receiver",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_quantity",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_currency",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_pricePerToken",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"internalType": "bytes32[]",
|
||||
"name": "proof",
|
||||
"type": "bytes32[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "maxQuantityInAllowlist",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"internalType": "struct IDrop.AllowlistProof",
|
||||
"name": "_allowlistProof",
|
||||
"type": "tuple"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "_data",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "claim",
|
||||
"outputs": [],
|
||||
"stateMutability": "payable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "claimCondition",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "currentStartId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "count",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "getActiveClaimConditionId",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_conditionId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "getClaimConditionById",
|
||||
"outputs": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "startTimestamp",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "maxClaimableSupply",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "supplyClaimed",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "quantityLimitPerTransaction",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "waitTimeInSecondsBetweenClaims",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "merkleRoot",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "pricePerToken",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "currency",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"internalType": "struct IClaimCondition.ClaimCondition",
|
||||
"name": "condition",
|
||||
"type": "tuple"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_conditionId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_claimer",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getClaimTimestamp",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "lastClaimTimestamp",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "nextValidClaimTimestamp",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "startTimestamp",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "maxClaimableSupply",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "supplyClaimed",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "quantityLimitPerTransaction",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "waitTimeInSecondsBetweenClaims",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "merkleRoot",
|
||||
"type": "bytes32"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "pricePerToken",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "currency",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"internalType": "struct IClaimCondition.ClaimCondition[]",
|
||||
"name": "_conditions",
|
||||
"type": "tuple[]"
|
||||
},
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "_resetClaimEligibility",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "setClaimConditions",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_conditionId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_claimer",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_quantity",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_currency",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_pricePerToken",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "verifyMaxQuantityPerTransaction",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "verifyClaim",
|
||||
"outputs": [],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_conditionId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_claimer",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_quantity",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"internalType": "bytes32[]",
|
||||
"name": "proof",
|
||||
"type": "bytes32[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "maxQuantityInAllowlist",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"internalType": "struct IDrop.AllowlistProof",
|
||||
"name": "_allowlistProof",
|
||||
"type": "tuple"
|
||||
}
|
||||
],
|
||||
"name": "verifyClaimMerkleProof",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "validMerkleProof",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "merkleProofIndex",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user