Compare commits
33
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
@@ -9,10 +9,10 @@ runs:
|
||||
with:
|
||||
node-version: 16
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
# cache: "yarn"
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: yarn install --frozen-lockfile
|
||||
run: yarn install
|
||||
env:
|
||||
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "1"
|
||||
|
||||
@@ -14,8 +14,7 @@ jobs:
|
||||
build:
|
||||
name: Build and Test
|
||||
# timeout-minutes: 15
|
||||
# try out buildjet to speed up build and test
|
||||
runs-on: buildjet-32vcpu-ubuntu-2204
|
||||
runs-on: ubuntu-latest-32
|
||||
# To use Remote Caching, uncomment the next lines and follow the steps below.
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
|
||||
@@ -13,8 +13,7 @@ concurrency:
|
||||
jobs:
|
||||
integration-tests:
|
||||
timeout-minutes: 60
|
||||
# try out buildjet to speed up build and test
|
||||
runs-on: buildjet-32vcpu-ubuntu-2204
|
||||
runs-on: ubuntu-latest-32
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
@@ -28,9 +27,3 @@ jobs:
|
||||
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
|
||||
|
||||
@@ -40,8 +40,7 @@ jobs:
|
||||
comment_body: ${{ github.event.comment.body }}
|
||||
|
||||
deploy:
|
||||
# try out buildjet to speed up build and test
|
||||
runs-on: buildjet-32vcpu-ubuntu-2204
|
||||
runs-on: ubuntu-latest-32
|
||||
needs: deploy-check
|
||||
if: needs.deploy-check.outputs.triggered == 'true'
|
||||
steps:
|
||||
|
||||
@@ -14,8 +14,7 @@ concurrency:
|
||||
jobs:
|
||||
release:
|
||||
name: Release
|
||||
# try out buildjet to speed up build and test
|
||||
runs-on: buildjet-32vcpu-ubuntu-2204
|
||||
runs-on: ubuntu-latest-32
|
||||
steps:
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v3
|
||||
|
||||
@@ -4,8 +4,7 @@ on: [pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# try out buildjet to speed up build and test
|
||||
runs-on: buildjet-32vcpu-ubuntu-2204
|
||||
runs-on: ubuntu-latest-32
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
+5
-1
@@ -12,4 +12,8 @@ server/dist
|
||||
public/dist
|
||||
.turbo
|
||||
./packages/contracts-js/abis
|
||||
.idea/
|
||||
.idea/
|
||||
.yalc/
|
||||
yalc.lock
|
||||
build/
|
||||
playwright-report/
|
||||
@@ -1,4 +1,3 @@
|
||||
lib
|
||||
node_modules
|
||||
dist
|
||||
contracts-js
|
||||
|
||||
+2
-6
@@ -8,7 +8,8 @@
|
||||
"private": true,
|
||||
"workspaces": {
|
||||
"packages": [
|
||||
"packages/*"
|
||||
"packages/*",
|
||||
"test/**/*"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
@@ -29,11 +30,6 @@
|
||||
"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",
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @thirdweb-dev/auth
|
||||
|
||||
## 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/auth",
|
||||
"version": "2.0.16",
|
||||
"version": "2.0.21",
|
||||
"exports": {
|
||||
"./next": {
|
||||
"module": "./next/dist/thirdweb-dev-auth-next.esm.js",
|
||||
|
||||
@@ -1,5 +1,44 @@
|
||||
# thirdweb
|
||||
|
||||
## 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "thirdweb",
|
||||
"main": "dist/cli/index.js",
|
||||
"version": "0.8.2",
|
||||
"version": "0.8.7",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
@@ -31,24 +31,17 @@
|
||||
"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.7.0",
|
||||
"form-data": "^4.0.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.1.1"
|
||||
|
||||
@@ -40,7 +40,7 @@ $$$$$$\\ $$$$$$$\\ $$\\ $$$$$$\\ $$$$$$$ |$$\\ $$\\ $$\\ $$$$$$\\ $$$$
|
||||
.version(cliVersion, "-v, --version");
|
||||
|
||||
program
|
||||
.command("create")
|
||||
.command("create [projectPath]")
|
||||
.description(
|
||||
"Create a web3 app from any of our official templates: https://github.com/thirdweb-example/",
|
||||
)
|
||||
@@ -66,8 +66,8 @@ $$$$$$\\ $$$$$$$\\ $$\\ $$$$$$\\ $$$$$$$ |$$\\ $$\\ $$\\ $$$$$$\\ $$$$
|
||||
"-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 (options) => {
|
||||
await twCreate(options);
|
||||
.action(async (path, options) => {
|
||||
await twCreate(path, options);
|
||||
});
|
||||
|
||||
program
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { extractIPFSHashFromBytecode } from "../helpers/ipfs";
|
||||
import { logger } from "../helpers/logger";
|
||||
import { CompileOptions, IBuilder } from "../interfaces/Builder";
|
||||
import { ContractPayload } from "../interfaces/ContractPayload";
|
||||
import { extractIPFSHashFromBytecode } from "@thirdweb-dev/sdk/evm";
|
||||
|
||||
export abstract class BaseBuilder implements IBuilder {
|
||||
abstract compile(
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
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())
|
||||
);
|
||||
}
|
||||
@@ -17,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) {
|
||||
|
||||
@@ -11,7 +11,8 @@ module.exports = {
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-non-null-assertion": "error",
|
||||
"@typescript-eslint/no-parameter-properties": "error",
|
||||
"@typescript-eslint/no-unused-vars": "warn",
|
||||
// making this an error going forward
|
||||
"@typescript-eslint/no-unused-vars": "error",
|
||||
|
||||
// import rules
|
||||
"import/first": "error",
|
||||
|
||||
@@ -1,5 +1,65 @@
|
||||
# @thirdweb-dev/react
|
||||
|
||||
## 3.4.0
|
||||
|
||||
### Minor 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)! - Gnosis Safe and Magic Link connectors are no longer included in the default export. They are now available as named exports instead.
|
||||
|
||||
## Gnosis Safe
|
||||
|
||||
### Connector
|
||||
|
||||
```diff
|
||||
- import { GnosisSafeConnector } from "@thirdweb-dev/react";
|
||||
+ import { GnosisSafeConnector } from "@thirdweb-dev/react/evm/connectors/gnosis-safe";
|
||||
```
|
||||
|
||||
### Hook
|
||||
|
||||
```diff
|
||||
- import { useGnosis } from "@thirdweb-dev/react";
|
||||
+ import { useGnosis } from "@thirdweb-dev/react/evm/connectors/gnosis-safe";
|
||||
```
|
||||
|
||||
## Magic Link
|
||||
|
||||
### Connector
|
||||
|
||||
```diff
|
||||
- import { MagicLink } from "@thirdweb-dev/react";
|
||||
+ import { MagicConnector } from "@thirdweb-dev/react/evm/connectors/magic";
|
||||
```
|
||||
|
||||
### Hook
|
||||
|
||||
```diff
|
||||
- import { useMagic } from "@thirdweb-dev/react";
|
||||
+ import { useMagic } from "@thirdweb-dev/react/evm/connectors/magic";
|
||||
```
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#339](https://github.com/thirdweb-dev/js/pull/339) [`b03a902`](https://github.com/thirdweb-dev/js/commit/b03a9021451b79f802f682f66e5ae8e9355d7e6f) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - Fix docs for some functions
|
||||
|
||||
## 3.3.1
|
||||
|
||||
## 3.3.0
|
||||
|
||||
## 3.2.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#316](https://github.com/thirdweb-dev/js/pull/316) [`6ae5266`](https://github.com/thirdweb-dev/js/commit/6ae52664e5865564cd4fc2e00e3120675b9e0ca3) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Fix SIWE when using an external signer
|
||||
|
||||
- [#310](https://github.com/thirdweb-dev/js/pull/310) [`9727502`](https://github.com/thirdweb-dev/js/commit/9727502eb30ac139382b7c7c8e8fc0967cbfbcf1) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - [SOL] - add useMintNFTSupply hook in react and accomodate inputs for it in SDK
|
||||
|
||||
- [#319](https://github.com/thirdweb-dev/js/pull/319) [`2f8ec89`](https://github.com/thirdweb-dev/js/commit/2f8ec89c4c83ae577092c840c198e6fcfb114e69) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Expose total claimed and unclaimed supply for erc721 drop contracts
|
||||
|
||||
- [#318](https://github.com/thirdweb-dev/js/pull/318) [`bb1b4e6`](https://github.com/thirdweb-dev/js/commit/bb1b4e6ac39d98cc68b8e31e659cd68be3a5b967) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - Add useMinimumNextBid hook and change invariant for other marketplace hooks
|
||||
|
||||
## 3.2.5
|
||||
|
||||
## 3.2.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -26,11 +26,11 @@ The `useContractCall` hook to call a smart contract function has been renamed to
|
||||
|
||||
### Prebuilt Contract Hooks
|
||||
|
||||
Hooks to connect to prebuilt contracts such as `useNFTDrop` and `useMarketplace` are now deprecated in favour of using the generic `useContract` hook:
|
||||
Hooks to connect to prebuilt contracts such as `useNFTDrop` and `useMarketplace` are now deprecated in favour of using the generic `useContract` hook followed by the contract type:
|
||||
|
||||
```diff
|
||||
- const contract = useNFTDrop("0x...")
|
||||
+ const { contract } = useContract("0x...")
|
||||
+ const { contract } = useContract("0x...", "nft-drop")
|
||||
```
|
||||
|
||||
You can currently still continue to use the prebuilt hooks, however they provide a warning in the console informing you of their deprecation. We will likely remove these hooks in a future version of the SDK.
|
||||
|
||||
@@ -191,7 +191,7 @@ export default function Home() {
|
||||
<div>
|
||||
{nfts.map((nft) => (
|
||||
<ThirdwebNftMedia
|
||||
key={nft.tokenId}
|
||||
key={nft.metadata.id}
|
||||
metadata={nft.metadata}
|
||||
height={200}
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"main": "dist/thirdweb-dev-react-evm-connectors-gnosis-safe.cjs.js",
|
||||
"module": "dist/thirdweb-dev-react-evm-connectors-gnosis-safe.esm.js"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"main": "dist/thirdweb-dev-react-evm-connectors-magic.cjs.js",
|
||||
"module": "dist/thirdweb-dev-react-evm-connectors-magic.esm.js"
|
||||
}
|
||||
+19
-18
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react",
|
||||
"version": "3.2.4",
|
||||
"version": "3.4.0",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
@@ -20,6 +20,14 @@
|
||||
"module": "./solana/dist/thirdweb-dev-react-solana.esm.js",
|
||||
"default": "./solana/dist/thirdweb-dev-react-solana.cjs.js"
|
||||
},
|
||||
"./evm/connectors/magic": {
|
||||
"module": "./evm/connectors/magic/dist/thirdweb-dev-react-evm-connectors-magic.esm.js",
|
||||
"default": "./evm/connectors/magic/dist/thirdweb-dev-react-evm-connectors-magic.cjs.js"
|
||||
},
|
||||
"./evm/connectors/gnosis-safe": {
|
||||
"module": "./evm/connectors/gnosis-safe/dist/thirdweb-dev-react-evm-connectors-gnosis-safe.esm.js",
|
||||
"default": "./evm/connectors/gnosis-safe/dist/thirdweb-dev-react-evm-connectors-gnosis-safe.cjs.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"files": [
|
||||
@@ -31,7 +39,8 @@
|
||||
"entrypoints": [
|
||||
"index.ts",
|
||||
"solana/index.ts",
|
||||
"evm/index.ts"
|
||||
"evm/index.ts",
|
||||
"evm/connectors/**.ts"
|
||||
],
|
||||
"___experimentalFlags_WILL_CHANGE_IN_PATCH": {
|
||||
"exports": true
|
||||
@@ -49,8 +58,6 @@
|
||||
"generate-docs:solana": "api-extractor run --local --config ./config/api-extractor-solana.json && api-documenter markdown -i ./temp -o ./docs/solana && rm -rf ./temp-solana && mv ./temp ./temp-solana",
|
||||
"generate-snippets": "node ./scripts/generate-snippets-evm.mjs && node ./scripts/generate-snippets-solana.mjs && node ./scripts/generate-feature-snippets-evm.mjs",
|
||||
"build": "tsc && preconstruct build",
|
||||
"e2e": "yarn test-ct",
|
||||
"test-ct": "playwright test -c playwright-ct.config.ts",
|
||||
"push": "yalc push"
|
||||
},
|
||||
"sideEffects:": false,
|
||||
@@ -63,15 +70,11 @@
|
||||
"@microsoft/api-documenter": "^7.19.4",
|
||||
"@microsoft/api-extractor": "^7.29.2",
|
||||
"@microsoft/tsdoc": "^0.14.1",
|
||||
"@playwright/experimental-ct-react": "1.25.1",
|
||||
"@playwright/test": "1.25.1",
|
||||
"@preconstruct/cli": "^2.2.1",
|
||||
"@solana/wallet-adapter-base": "^0.9.17",
|
||||
"@solana/wallet-adapter-react": "^0.15.19",
|
||||
"@solana/wallet-adapter-wallets": "^0.19.0",
|
||||
"@solana/web3.js": "^1.63.0",
|
||||
"@solana/web3.js": "^1.62.0",
|
||||
"@thirdweb-dev/sdk": "*",
|
||||
"@thirdweb-dev/solana": "*",
|
||||
"@types/color": "^3.0.3",
|
||||
"@types/mime": "^3.0.1",
|
||||
"@types/react": "^18.0.5",
|
||||
@@ -93,13 +96,14 @@
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.10.0",
|
||||
"@emotion/styled": "^11.10.0",
|
||||
"@gnosis.pm/safe-core-sdk": "2.1.0",
|
||||
"@gnosis.pm/safe-ethers-adapters": "0.1.0-alpha.9",
|
||||
"@gnosis.pm/safe-ethers-lib": "1.1.0",
|
||||
"@gnosis.pm/safe-core-sdk": "^3.1.1",
|
||||
"@gnosis.pm/safe-ethers-adapters": "0.1.0-alpha.11",
|
||||
"@gnosis.pm/safe-ethers-lib": "^1.6.1",
|
||||
"@react-icons/all-files": "^4.1.0",
|
||||
"@solana/wallet-adapter-phantom": "^0.9.17",
|
||||
"@tanstack/react-query": "^4.0.10",
|
||||
"@zag-js/menu": "0.1.14",
|
||||
"@zag-js/react": "0.1.16",
|
||||
"@zag-js/menu": "^0.1.16",
|
||||
"@zag-js/react": "^0.1.18",
|
||||
"buffer": "^6.0.3",
|
||||
"color": "^4.2.3",
|
||||
"copy-to-clipboard": "^3.3.2",
|
||||
@@ -114,7 +118,7 @@
|
||||
"@solana/wallet-adapter-base": "^0.9.17",
|
||||
"@solana/wallet-adapter-react": "^0.15.19",
|
||||
"@solana/wallet-adapter-wallets": "^0.19.0",
|
||||
"@solana/web3.js": "^1.63.0",
|
||||
"@solana/web3.js": "^1.62.0",
|
||||
"@thirdweb-dev/sdk": "*",
|
||||
"ethers": ">=5.5.1",
|
||||
"react": ">=18.0.0",
|
||||
@@ -136,9 +140,6 @@
|
||||
},
|
||||
"@solana/web3.js": {
|
||||
"optional": true
|
||||
},
|
||||
"@thirdweb-dev/solana": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
import type { PlaywrightTestConfig } from "@playwright/experimental-ct-react";
|
||||
import { devices } from "@playwright/experimental-ct-react";
|
||||
|
||||
/**
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
const config: PlaywrightTestConfig = {
|
||||
testDir: "./",
|
||||
/* The base directory, relative to the config file, for snapshot files created with toMatchSnapshot and toHaveScreenshot. */
|
||||
snapshotDir: "./__snapshots__",
|
||||
/* Maximum time one test can run for. */
|
||||
timeout: 10 * 1000,
|
||||
/* Run tests in files in parallel */
|
||||
fullyParallel: true,
|
||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||
forbidOnly: !!process.env.CI,
|
||||
/* Retry on CI only */
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
/* Opt out of parallel tests on CI. */
|
||||
// workers: process.env.CI ? 1 : undefined,
|
||||
// we can use parallel tests because we have more cores now
|
||||
workers: undefined,
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: "html",
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: "on-first-retry",
|
||||
|
||||
/* Port to use for Playwright component endpoint. */
|
||||
ctPort: 3100,
|
||||
},
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
projects: [
|
||||
{
|
||||
name: "chromium",
|
||||
use: {
|
||||
...devices["Desktop Chrome"],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "firefox",
|
||||
use: {
|
||||
...devices["Desktop Firefox"],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "webkit",
|
||||
use: {
|
||||
...devices["Desktop Safari"],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -1,4 +0,0 @@
|
||||
// Import styles, initialize component theme here.
|
||||
// import '../src/common.css';
|
||||
|
||||
export {};
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RequiredParam } from "../types/shared";
|
||||
import { RequiredParam } from "./required-param";
|
||||
import type { QueryKey } from "@tanstack/react-query";
|
||||
import type { ValidContractInstance } from "@thirdweb-dev/sdk";
|
||||
import type {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
/**
|
||||
* Makes a parameter required to be passed, but still allowes it to be null or undefined.
|
||||
*
|
||||
* @beta
|
||||
*/
|
||||
export type RequiredParam<T> = T | null | undefined;
|
||||
|
||||
export function requiredParamInvariant<TValue>(
|
||||
condition: RequiredParam<TValue>,
|
||||
message?: string,
|
||||
): asserts condition {
|
||||
invariant(condition !== null || condition !== undefined, message);
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
/**
|
||||
* Makes a parameter required to be passed, but still allowes it to be null or undefined.
|
||||
*
|
||||
* @beta
|
||||
*/
|
||||
export type RequiredParam<T> = T | null | undefined;
|
||||
@@ -1,15 +0,0 @@
|
||||
import { ConnectWallet } from ".";
|
||||
import { ThirdwebProvider } from "../../providers/full";
|
||||
import { test, expect } from "@playwright/experimental-ct-react";
|
||||
|
||||
test.use({ viewport: { width: 500, height: 500 } });
|
||||
|
||||
test("should render the connect wallet button", async ({ mount }) => {
|
||||
const component = await mount(
|
||||
<ThirdwebProvider desiredChainId={1}>
|
||||
<ConnectWallet />
|
||||
</ThirdwebProvider>,
|
||||
);
|
||||
|
||||
await expect(component).toContainText("Connect Wallet");
|
||||
});
|
||||
@@ -144,7 +144,7 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = ({
|
||||
},
|
||||
connect,
|
||||
] = useConnect();
|
||||
const disconnect = useDisconnect({ reconnectAfterGnosis: false });
|
||||
const disconnect = useDisconnect({ reconnectPrevious: false });
|
||||
|
||||
const supportedConnectors = connectors.filter((c) =>
|
||||
SUPPORTED_CONNECTORS.includes(c.id as typeof SUPPORTED_CONNECTORS[number]),
|
||||
|
||||
@@ -13,12 +13,14 @@ export interface ThirdwebNftMediaProps extends SharedMediaProps {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* This component can be used to render NFTs from the thirdweb SDK.
|
||||
* Props: {@link ThirdwebNftMediaProps}
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* import { ThirdwebNftMedia, useNFTCollection, useNFT } from "@thirdweb-dev/react";
|
||||
* import { ThirdwebNftMedia, useContract, useNFT } from "@thirdweb-dev/react";
|
||||
* export default function NFTCollectionRender() {
|
||||
* const contract = useNFTCollection(<your-contract-address>);
|
||||
* const { contract } = useContract(<your-contract-address>);
|
||||
* const { data: nft, isLoading } = useNFT(contract, 0);
|
||||
*
|
||||
* return (
|
||||
@@ -32,11 +34,6 @@ export interface ThirdwebNftMediaProps extends SharedMediaProps {
|
||||
* );
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Use this to get the primary sales recipient of your {@link SmartContract}
|
||||
* @param contract - an instance of a {@link SmartContract}
|
||||
* @returns the wallet address of the primary sales recipient
|
||||
* @beta
|
||||
*/
|
||||
export const ThirdwebNftMedia = React.forwardRef<
|
||||
HTMLMediaElement,
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
import { Web3Button } from ".";
|
||||
import { ThirdwebProvider } from "../../providers/full";
|
||||
import { test, expect } from "@playwright/experimental-ct-react";
|
||||
|
||||
test.use({ viewport: { width: 500, height: 500 } });
|
||||
|
||||
test("should render the connect wallet button", async ({ mount }) => {
|
||||
const component = await mount(
|
||||
<ThirdwebProvider desiredChainId={1}>
|
||||
<Web3Button contractAddress="0x123" action={() => undefined}>
|
||||
Do the thing
|
||||
</Web3Button>
|
||||
</ThirdwebProvider>,
|
||||
);
|
||||
await expect(component).toContainText("Connect Wallet");
|
||||
});
|
||||
@@ -1,13 +1,23 @@
|
||||
import { ChainId } from "@thirdweb-dev/sdk";
|
||||
import { useConnect } from "../hooks/wagmi-required/useConnect";
|
||||
import { Signer, ethers, utils } from "ethers";
|
||||
import invariant from "tiny-invariant";
|
||||
import { Chain, Connector, ConnectorData, normalizeChainId } from "wagmi";
|
||||
import {
|
||||
Chain,
|
||||
Connector,
|
||||
ConnectorData,
|
||||
normalizeChainId,
|
||||
useContext as useWagmiContext,
|
||||
} from "wagmi";
|
||||
|
||||
const CHAIN_ID_TO_GNOSIS_SERVER_URL = {
|
||||
[ChainId.Mainnet]: "https://safe-transaction.mainnet.gnosis.io",
|
||||
[ChainId.Avalanche]: "https://safe-transaction.avalanche.gnosis.io",
|
||||
[ChainId.Polygon]: "https://safe-transaction.polygon.gnosis.io",
|
||||
[ChainId.Goerli]: "https://safe-transaction.goerli.gnosis.io",
|
||||
// mainnet
|
||||
1: "https://safe-transaction.mainnet.gnosis.io",
|
||||
// avalanche
|
||||
43114: "https://safe-transaction.avalanche.gnosis.io",
|
||||
// polygon
|
||||
137: "https://safe-transaction.polygon.gnosis.io",
|
||||
// goerli
|
||||
5: "https://safe-transaction.goerli.gnosis.io",
|
||||
};
|
||||
|
||||
export interface GnosisConnectorArguments {
|
||||
@@ -163,3 +173,67 @@ export class GnosisSafeConnector extends Connector {
|
||||
this.config = config;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for connecting to a Gnosis Safe. This enables multisig wallets to connect to your application and sing transactions.
|
||||
*
|
||||
* ```javascript
|
||||
* import { useGnosis } from "@thirdweb-dev/react"
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* import { useGnosis } from "@thirdweb-dev/react"
|
||||
*
|
||||
* const App = () => {
|
||||
* const connectWithGnosis = useGnosis()
|
||||
*
|
||||
* return (
|
||||
* <button onClick={() => connectWithGnosis({ safeAddress: "0x...", safeChainId: 1 })}>
|
||||
* Connect Gnosis Safe
|
||||
* </button>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function useGnosis() {
|
||||
const wagmiContext = useWagmiContext();
|
||||
invariant(
|
||||
wagmiContext,
|
||||
`useGnosis() can only be used inside <ThirdwebProvider />. If you are using <ThirdwebSDKProvider /> you will have to use your own wallet-connection logic.`,
|
||||
);
|
||||
const [connectors, connect] = useConnect();
|
||||
if (connectors.loading) {
|
||||
return () => Promise.reject("Gnosis connector not ready to be used, yet");
|
||||
}
|
||||
const connector = connectors.data.connectors.find((c) => c.id === "gnosis");
|
||||
invariant(
|
||||
connector,
|
||||
"Gnosis connector not found, please make sure it is provided to your <ThirdwebProvider />",
|
||||
);
|
||||
|
||||
return async (config: GnosisConnectorArguments) => {
|
||||
const previousConnector = connectors.data.connector;
|
||||
const previousConnectorChain = await previousConnector?.getChainId();
|
||||
invariant(
|
||||
!!previousConnector,
|
||||
"Cannot connect to Gnosis Safe without first being connected to a personal wallet.",
|
||||
);
|
||||
invariant(
|
||||
previousConnectorChain === config.safeChainId,
|
||||
"Gnosis safe chain id must match personal wallet chain id.",
|
||||
);
|
||||
invariant(
|
||||
utils.isAddress(config.safeAddress),
|
||||
"Gnosis safe address must be a valid address.",
|
||||
);
|
||||
(connector as GnosisSafeConnector).setConfiguration(
|
||||
previousConnector,
|
||||
config,
|
||||
);
|
||||
return connect(connector);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useConnect } from "../hooks/wagmi-required/useConnect";
|
||||
import { providers, utils } from "ethers";
|
||||
import type {
|
||||
LoginWithMagicLinkConfiguration,
|
||||
@@ -5,7 +6,12 @@ import type {
|
||||
MagicSDKAdditionalConfiguration,
|
||||
} from "magic-sdk";
|
||||
import invariant from "tiny-invariant";
|
||||
import { Chain, Connector, normalizeChainId } from "wagmi";
|
||||
import {
|
||||
Chain,
|
||||
Connector,
|
||||
normalizeChainId,
|
||||
useContext as useWagmiContext,
|
||||
} from "wagmi";
|
||||
|
||||
export interface MagicConnectorArguments
|
||||
extends MagicSDKAdditionalConfiguration {
|
||||
@@ -186,3 +192,89 @@ export class MagicConnector extends Connector {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for connecting to an email wallet using magic link.
|
||||
* This enables users without their own wallets to connect to your application and sign transactions securely using their email.
|
||||
*
|
||||
* ```javascript
|
||||
* import { useMagic } from "@thirdweb-dev/react"
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* Before using this hook, you first need to set up the magic configuration in your `ThirdwebProvider`, including your magic API key.
|
||||
*
|
||||
* ```javascript
|
||||
* // Add the magic configuration object to your wallet connectors
|
||||
* const connectors = [
|
||||
* "metamask",
|
||||
* "walletConnect",
|
||||
* "walletLink",
|
||||
* {
|
||||
* name: "magic",
|
||||
* options: {
|
||||
* apiKey: "your-magic-api-key",
|
||||
* }
|
||||
* }
|
||||
* ]
|
||||
*
|
||||
* // Add the above to the walletConnectors prop of your <ThirdwebProvider />
|
||||
* const Provider = ({ children }) => (
|
||||
* return (
|
||||
* <ThirdwebProvider
|
||||
* walletConnectors={connectors}
|
||||
* // Specify remaining parameters
|
||||
* ...
|
||||
* >
|
||||
* {children}
|
||||
* </ThirdwebProvider>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* In order to use the hook to connect users with magic link, you just need to provide the users email to the connect function.
|
||||
*
|
||||
* You can setup the hook with the following configuration:
|
||||
* ```javascript
|
||||
* import { useMagic } from "@thirdweb-dev/react"
|
||||
* import { useState } from "react"
|
||||
*
|
||||
* const LoginWithMagicLink = () => {
|
||||
* const connectWithMagic = useMagic()
|
||||
* const [email, setEmail] = useState()
|
||||
*
|
||||
* return (
|
||||
* <div>
|
||||
* <input value={email} onChange={(e) => setEmail(e.target.value)} />
|
||||
* <button onClick={() => connectWithMagic({ email })}>Login</button>
|
||||
* </div>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function useMagic() {
|
||||
const wagmiContext = useWagmiContext();
|
||||
invariant(
|
||||
wagmiContext,
|
||||
`useMagic() can only be used inside <ThirdwebProvider />. If you are using <ThirdwebSDKProvider /> you will have to use your own wallet-connection logic.`,
|
||||
);
|
||||
const [connectors, connect] = useConnect();
|
||||
if (connectors.loading) {
|
||||
return () => Promise.reject("Magic connector not ready to be used, yet");
|
||||
}
|
||||
|
||||
const connector = connectors.data.connectors.find((c) => c.id === "magic");
|
||||
|
||||
invariant(
|
||||
connector,
|
||||
"Magic connector not found, please make sure it is provided to your <ThirdwebProvider />",
|
||||
);
|
||||
|
||||
return (configuration: LoginWithMagicLinkConfiguration) => {
|
||||
(connector as MagicConnector).setConfiguration(configuration);
|
||||
return connect(connector);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
SupportedChainId,
|
||||
defaultSupportedChains,
|
||||
} from "../constants/chain";
|
||||
import { ChainId } from "@thirdweb-dev/sdk";
|
||||
import { DEFAULT_RPC_URLS } from "@thirdweb-dev/sdk";
|
||||
import React, { PropsWithChildren, createContext, useContext } from "react";
|
||||
|
||||
interface ThirdwebConfigContext {
|
||||
@@ -11,17 +11,8 @@ interface ThirdwebConfigContext {
|
||||
supportedChains: Chain[];
|
||||
}
|
||||
|
||||
export const defaultChainRpc: Record<SupportedChainId | number, string> = {
|
||||
[ChainId.Mainnet]: "mainnet",
|
||||
[ChainId.Goerli]: "goerli",
|
||||
[ChainId.Polygon]: "polygon",
|
||||
[ChainId.Mumbai]: "mumbai",
|
||||
[ChainId.Fantom]: "fantom",
|
||||
[ChainId.Avalanche]: "avalanche",
|
||||
};
|
||||
|
||||
const ThirdwebConfigContext = createContext<ThirdwebConfigContext>({
|
||||
rpcUrlMap: defaultChainRpc,
|
||||
rpcUrlMap: DEFAULT_RPC_URLS,
|
||||
supportedChains: defaultSupportedChains,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import {
|
||||
RequiredParam,
|
||||
requiredParamInvariant,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import { useSDKChainId } from "../../providers/base";
|
||||
import { getErcs, DropContract, WalletAddress } from "../../types";
|
||||
import {
|
||||
@@ -7,7 +10,11 @@ import {
|
||||
} from "../../utils/cache-keys";
|
||||
import { useQueryWithNetwork } from "../query-utils/useQueryWithNetwork";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { ClaimCondition, ClaimConditionInput } from "@thirdweb-dev/sdk";
|
||||
import {
|
||||
ClaimCondition,
|
||||
ClaimConditionFetchOptions,
|
||||
ClaimConditionInput,
|
||||
} from "@thirdweb-dev/sdk";
|
||||
import { BigNumberish } from "ethers";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
@@ -62,25 +69,30 @@ export type SetClaimConditionsParams = {
|
||||
export function useActiveClaimCondition(
|
||||
contract: RequiredParam<DropContract>,
|
||||
tokenId?: BigNumberish,
|
||||
options?: ClaimConditionFetchOptions,
|
||||
) {
|
||||
const contractAddress = contract?.getAddress();
|
||||
const { erc1155, erc721, erc20 } = getErcs(contract);
|
||||
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.extensions.claimConditions.getActive(contractAddress, tokenId),
|
||||
cacheKeys.extensions.claimConditions.getActive(
|
||||
contractAddress,
|
||||
tokenId,
|
||||
options,
|
||||
),
|
||||
() => {
|
||||
if (erc1155) {
|
||||
invariant(
|
||||
tokenId !== undefined,
|
||||
requiredParamInvariant(
|
||||
tokenId,
|
||||
"tokenId is required for ERC1155 claim conditions",
|
||||
);
|
||||
return erc1155.claimConditions.getActive(tokenId);
|
||||
return erc1155.claimConditions.getActive(tokenId, options);
|
||||
}
|
||||
if (erc721) {
|
||||
return erc721.claimConditions.getActive();
|
||||
return erc721.claimConditions.getActive(options);
|
||||
}
|
||||
if (erc20) {
|
||||
return erc20.claimConditions.getActive();
|
||||
return erc20.claimConditions.getActive(options);
|
||||
}
|
||||
throw new Error("Contract must be ERC721, ERC1155 or ERC20");
|
||||
},
|
||||
@@ -118,22 +130,30 @@ export function useActiveClaimCondition(
|
||||
export function useClaimConditions(
|
||||
contract: RequiredParam<DropContract>,
|
||||
tokenId?: BigNumberish,
|
||||
options?: ClaimConditionFetchOptions,
|
||||
) {
|
||||
const contractAddress = contract?.getAddress();
|
||||
const { erc1155, erc721, erc20 } = getErcs(contract);
|
||||
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.extensions.claimConditions.getAll(contractAddress, tokenId),
|
||||
cacheKeys.extensions.claimConditions.getAll(
|
||||
contractAddress,
|
||||
tokenId,
|
||||
options,
|
||||
),
|
||||
() => {
|
||||
if (erc1155) {
|
||||
invariant(tokenId, "tokenId is required for ERC1155 claim conditions");
|
||||
return erc1155.claimConditions.getAll(tokenId);
|
||||
requiredParamInvariant(
|
||||
tokenId,
|
||||
"tokenId is required for ERC1155 claim conditions",
|
||||
);
|
||||
return erc1155.claimConditions.getAll(tokenId, options);
|
||||
}
|
||||
if (erc721) {
|
||||
return erc721.claimConditions.getAll();
|
||||
return erc721.claimConditions.getAll(options);
|
||||
}
|
||||
if (erc20) {
|
||||
return erc20.claimConditions.getAll();
|
||||
return erc20.claimConditions.getAll(options);
|
||||
}
|
||||
throw new Error("Contract must be ERC721, ERC1155 or ERC20");
|
||||
},
|
||||
@@ -184,7 +204,7 @@ export function useClaimIneligibilityReasons(
|
||||
),
|
||||
() => {
|
||||
if (erc1155) {
|
||||
invariant(
|
||||
requiredParamInvariant(
|
||||
tokenId,
|
||||
"tokenId is required for ERC1155 claim ineligibility reasons",
|
||||
);
|
||||
@@ -270,11 +290,14 @@ export function useSetClaimConditions(
|
||||
|
||||
return useMutation(
|
||||
async (data: SetClaimConditionsParams) => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
const { phases, reset = false } = data;
|
||||
invariant(phases, 'No "phases" provided');
|
||||
if (erc1155) {
|
||||
invariant(tokenId, "tokenId is required for ERC1155 claim conditions");
|
||||
requiredParamInvariant(
|
||||
tokenId,
|
||||
"tokenId is required for ERC1155 claim conditions",
|
||||
);
|
||||
return erc1155.claimConditions.set(tokenId, phases, reset);
|
||||
}
|
||||
if (erc721) {
|
||||
@@ -341,7 +364,7 @@ export function useResetClaimConditions(
|
||||
|
||||
return useMutation(
|
||||
async () => {
|
||||
const cleanConditions = (conditions: ClaimCondition[]) => {
|
||||
const cleanConditions = async (conditions: ClaimCondition[]) => {
|
||||
return conditions.map((c) => ({
|
||||
...c,
|
||||
price: c.currencyMetadata.displayValue,
|
||||
@@ -351,25 +374,34 @@ export function useResetClaimConditions(
|
||||
};
|
||||
|
||||
if (erc1155) {
|
||||
invariant(tokenId, "tokenId is required for ERC1155 claim conditions");
|
||||
const claimConditions = await erc1155.claimConditions.getAll(tokenId);
|
||||
requiredParamInvariant(
|
||||
tokenId,
|
||||
"tokenId is required for ERC1155 claim conditions",
|
||||
);
|
||||
const claimConditions = await erc1155.claimConditions.getAll(tokenId, {
|
||||
withAllowList: true,
|
||||
});
|
||||
return erc1155.claimConditions.set(
|
||||
tokenId,
|
||||
cleanConditions(claimConditions || []),
|
||||
await cleanConditions(claimConditions || []),
|
||||
true,
|
||||
);
|
||||
}
|
||||
if (erc721) {
|
||||
const claimConditions = await erc721.claimConditions.getAll();
|
||||
const claimConditions = await erc721.claimConditions.getAll({
|
||||
withAllowList: true,
|
||||
});
|
||||
return await erc721.claimConditions.set(
|
||||
cleanConditions(claimConditions || []),
|
||||
await cleanConditions(claimConditions || []),
|
||||
true,
|
||||
);
|
||||
}
|
||||
if (erc20) {
|
||||
const claimConditions = await erc20.claimConditions.getAll();
|
||||
const claimConditions = await erc20.claimConditions.getAll({
|
||||
withAllowList: true,
|
||||
});
|
||||
return await erc20.claimConditions.set(
|
||||
cleanConditions(claimConditions || []),
|
||||
await cleanConditions(claimConditions || []),
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import {
|
||||
RequiredParam,
|
||||
requiredParamInvariant,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import { useSDKChainId } from "../../providers/base";
|
||||
import { WalletAddress } from "../../types";
|
||||
import {
|
||||
@@ -35,7 +38,7 @@ export function usePrimarySaleRecipient(
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.extensions.sales.getRecipient(contractAddress),
|
||||
() => {
|
||||
invariant(contract, "No contract provided");
|
||||
requiredParamInvariant(contract, "No contract provided");
|
||||
invariant(
|
||||
"sales" in contract && contract.sales,
|
||||
"Contract does not support primarySale",
|
||||
@@ -86,7 +89,7 @@ export function useUpdatePrimarySaleRecipient(
|
||||
const activeChainId = useSDKChainId();
|
||||
return useMutation(
|
||||
(newRecipient: WalletAddress) => {
|
||||
invariant(contract, "No contract provided");
|
||||
requiredParamInvariant(contract, "No contract provided");
|
||||
invariant(
|
||||
"sales" in contract && contract.sales,
|
||||
"Contract does not support primarySale",
|
||||
@@ -128,7 +131,7 @@ export function useRoyaltySettings(
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.extensions.royalties.getDefaultRoyaltyInfo(contractAddress),
|
||||
() => {
|
||||
invariant(contract, "No contract provided");
|
||||
requiredParamInvariant(contract, "No contract provided");
|
||||
invariant(
|
||||
"royalties" in contract && contract.royalties,
|
||||
"Contract does not support royalties",
|
||||
@@ -182,7 +185,7 @@ export function useUpdateRoyaltySettings(
|
||||
seller_fee_basis_points?: number;
|
||||
fee_recipient?: WalletAddress;
|
||||
}) => {
|
||||
invariant(contract, "No contract provided");
|
||||
requiredParamInvariant(contract, "No contract provided");
|
||||
invariant(
|
||||
"royalties" in contract && contract.royalties,
|
||||
"Contract does not support royalties",
|
||||
@@ -224,7 +227,7 @@ export function usePlatformFees(
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.extensions.platformFees.get(contractAddress),
|
||||
() => {
|
||||
invariant(contract, "No contract provided");
|
||||
requiredParamInvariant(contract, "No contract provided");
|
||||
invariant(
|
||||
"platformFees" in contract && contract.platformFees,
|
||||
"Contract does not support platformFees",
|
||||
@@ -277,7 +280,7 @@ export function useUpdatePlatformFees(
|
||||
platform_fee_basis_points?: number;
|
||||
fee_recipient?: WalletAddress;
|
||||
}) => {
|
||||
invariant(contract, "No contract provided");
|
||||
requiredParamInvariant(contract, "No contract provided");
|
||||
invariant(
|
||||
"platformFees" in contract && contract.platformFees,
|
||||
"Contract does not support platformFees",
|
||||
@@ -317,7 +320,7 @@ export function useMetadata(contract: RequiredParam<ValidContractInstance>) {
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.extensions.metadata.get(contractAddress),
|
||||
() => {
|
||||
invariant(contract, "No contract provided");
|
||||
requiredParamInvariant(contract, "No contract provided");
|
||||
invariant(
|
||||
"metadata" in contract && contract.metadata,
|
||||
"Contract does not support metadata",
|
||||
@@ -366,7 +369,7 @@ export function useUpdateMetadata(
|
||||
const activeChainId = useSDKChainId();
|
||||
return useMutation(
|
||||
(updatePayload: CustomContractMetadata) => {
|
||||
invariant(contract, "No contract provided");
|
||||
requiredParamInvariant(contract, "No contract provided");
|
||||
invariant(
|
||||
"metadata" in contract && contract.metadata,
|
||||
"Contract does not support metadata",
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { neverPersist } from "../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import {
|
||||
RequiredParam,
|
||||
requiredParamInvariant,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import { useSDK, useSDKChainId } from "../../providers/base";
|
||||
import { ContractAddress } from "../../types";
|
||||
import {
|
||||
@@ -216,7 +219,7 @@ export function useContract(
|
||||
{ wallet, walletChainId, sdkTimestamp },
|
||||
]),
|
||||
async () => {
|
||||
invariant(contractAddress, "contract address is required");
|
||||
requiredParamInvariant(contractAddress, "contract address is required");
|
||||
invariant(sdk, "SDK not initialized");
|
||||
invariant(activeChainId, "active chain id is required");
|
||||
|
||||
@@ -290,7 +293,7 @@ export function useContractMetadata<TContract extends ValidContractInstance>(
|
||||
>(
|
||||
cacheKeys.contract.metadata(contract?.getAddress()),
|
||||
async () => {
|
||||
invariant(contract, "contract is required");
|
||||
requiredParamInvariant(contract, "contract is required");
|
||||
return await contract.metadata.get();
|
||||
},
|
||||
{
|
||||
@@ -311,7 +314,7 @@ export function useContractMetadataUpdate(
|
||||
|
||||
return useMutation(
|
||||
async (metadata: CommonContractSchemaInput) => {
|
||||
invariant(contract, "contract must be defined");
|
||||
requiredParamInvariant(contract, "contract must be defined");
|
||||
|
||||
return contract.metadata.update(metadata);
|
||||
},
|
||||
@@ -406,7 +409,7 @@ export function useContractEvents(
|
||||
return useQuery(
|
||||
cacheKey,
|
||||
() => {
|
||||
invariant(contract, "contract must be defined");
|
||||
requiredParamInvariant(contract, "contract must be defined");
|
||||
if (eventName) {
|
||||
return contract.events.getEvents(eventName, options.queryFilter);
|
||||
}
|
||||
@@ -447,8 +450,8 @@ export function useContractRead(
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.call(contractAddress, functionName, args),
|
||||
() => {
|
||||
invariant(contract, "contract must be defined");
|
||||
invariant(functionName, "function name must be provided");
|
||||
requiredParamInvariant(contract, "contract must be defined");
|
||||
requiredParamInvariant(functionName, "function name must be provided");
|
||||
return contract.call(functionName, ...args);
|
||||
},
|
||||
{
|
||||
@@ -485,8 +488,8 @@ export function useContractWrite(
|
||||
|
||||
return useMutation(
|
||||
async (callParams?: unknown[] | [...unknown[], CallOverrides]) => {
|
||||
invariant(contract, "contract must be defined");
|
||||
invariant(functionName, "function name must be provided");
|
||||
requiredParamInvariant(contract, "contract must be defined");
|
||||
requiredParamInvariant(functionName, "function name must be provided");
|
||||
if (!callParams?.length) {
|
||||
return contract.call(functionName);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import {
|
||||
RequiredParam,
|
||||
requiredParamInvariant,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import { useSDKChainId } from "../../providers/base";
|
||||
import {
|
||||
ClaimNFTParams,
|
||||
@@ -51,7 +54,7 @@ export function useUnclaimedNFTs(
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.nft.drop.getAllUnclaimed(contractAddress, queryParams),
|
||||
() => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
// TODO make this work for custom contracts (needs ABI change)
|
||||
invariant(
|
||||
contract.getAllUnclaimed,
|
||||
@@ -94,18 +97,18 @@ export function useClaimedNFTs(
|
||||
*/
|
||||
export function useUnclaimedNFTSupply(contract: RequiredParam<DropContract>) {
|
||||
const contractAddress = contract?.getAddress();
|
||||
const { erc721 } = getErcs(contract);
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.nft.drop.totalUnclaimedSupply(contractAddress),
|
||||
() => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
// TODO make this work for custom contracts (needs ABI change)
|
||||
invariant(
|
||||
"totalUnclaimedSupply" in contract && contract.totalUnclaimedSupply,
|
||||
"Contract instance does not support fetching unclaimed supply",
|
||||
);
|
||||
return contract.totalUnclaimedSupply();
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
if (erc721) {
|
||||
invariant(erc721, "No ERC721 Contract instance provided");
|
||||
return erc721.totalUnclaimedSupply();
|
||||
}
|
||||
invariant(false, "Contract is not an instance of ERC721")
|
||||
},
|
||||
{ enabled: !!contract },
|
||||
{ enabled: !!erc721 },
|
||||
);
|
||||
}
|
||||
|
||||
@@ -118,18 +121,17 @@ export function useUnclaimedNFTSupply(contract: RequiredParam<DropContract>) {
|
||||
*/
|
||||
export function useClaimedNFTSupply(contract: RequiredParam<DropContract>) {
|
||||
const contractAddress = contract?.getAddress();
|
||||
const { erc721 } = getErcs(contract);
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.nft.drop.totalClaimedSupply(contractAddress),
|
||||
() => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
// TODO make this work for custom contracts (needs ABI change)
|
||||
invariant(
|
||||
"totalClaimedSupply" in contract && contract.totalClaimedSupply,
|
||||
"Contract instance does not support fetching unclaimed supply",
|
||||
);
|
||||
return contract.totalClaimedSupply();
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
if (erc721) {
|
||||
return erc721.totalClaimedSupply();
|
||||
}
|
||||
invariant(false, "Contract is not an instance of ERC721")
|
||||
},
|
||||
{ enabled: !!contract },
|
||||
{ enabled: !!erc721 },
|
||||
);
|
||||
}
|
||||
|
||||
@@ -206,10 +208,10 @@ export function useClaimNFT<TContract extends DropContract>(
|
||||
|
||||
return useMutation(
|
||||
async (data: ClaimNFTParams) => {
|
||||
invariant(contract, "contract is undefined");
|
||||
requiredParamInvariant(contract, "contract is undefined");
|
||||
|
||||
if (erc1155) {
|
||||
invariant(!!data.tokenId, "tokenId not provided");
|
||||
requiredParamInvariant(data.tokenId, "tokenId not provided");
|
||||
if (!data.to) {
|
||||
return (await erc1155.claim(
|
||||
data.tokenId,
|
||||
@@ -270,7 +272,7 @@ export function useLazyMint<TContract extends DropContract>(
|
||||
|
||||
return useMutation(
|
||||
async (data: { metadatas: NFTMetadataInput[] }) => {
|
||||
invariant(contract, "contract is undefined");
|
||||
requiredParamInvariant(contract, "contract is undefined");
|
||||
let options;
|
||||
if (onProgress) {
|
||||
options = {
|
||||
@@ -316,7 +318,7 @@ export function useDelayedRevealLazyMint<TContract extends RevealableContract>(
|
||||
|
||||
return useMutation(
|
||||
async (data: DelayedRevealLazyMintInput) => {
|
||||
invariant(contract, "contract is undefined");
|
||||
requiredParamInvariant(contract, "contract is undefined");
|
||||
let options;
|
||||
if (onProgress) {
|
||||
options = {
|
||||
@@ -370,7 +372,7 @@ export function useRevealLazyMint<TContract extends RevealableContract>(
|
||||
|
||||
return useMutation(
|
||||
async (data: RevealLazyMintInput) => {
|
||||
invariant(contract, "contract is undefined");
|
||||
requiredParamInvariant(contract, "contract is undefined");
|
||||
const { erc721, erc1155 } = getErcs(contract);
|
||||
if (erc721) {
|
||||
return await erc721.revealer.reveal(data.batchId, data.password);
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import {
|
||||
RequiredParam,
|
||||
requiredParamInvariant,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import { useSDKChainId } from "../../providers/base";
|
||||
import { BuyNowParams, MakeBidParams } from "../../types";
|
||||
import {
|
||||
@@ -17,7 +20,7 @@ import type {
|
||||
} from "@thirdweb-dev/sdk";
|
||||
import { ListingType } from "@thirdweb-dev/sdk";
|
||||
import { Marketplace } from "@thirdweb-dev/sdk/dist/declarations/src/evm/contracts/prebuilt-implementations/marketplace";
|
||||
import { BigNumber, BigNumberish } from "ethers";
|
||||
import { BigNumberish } from "ethers";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
/** **********************/
|
||||
@@ -45,8 +48,9 @@ export function useListing(
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.marketplace.getListing(contractAddress, listingId),
|
||||
() => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
return contract.getListing(BigNumber.from(listingId || 0));
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
requiredParamInvariant(listingId, "No listing id provided");
|
||||
return contract.getListing(listingId);
|
||||
},
|
||||
{
|
||||
enabled: !!contract,
|
||||
@@ -76,7 +80,7 @@ export function useListings(
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.marketplace.getAllListings(contractAddress, filter),
|
||||
() => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
return contract.getAllListings(filter);
|
||||
},
|
||||
{
|
||||
@@ -103,7 +107,7 @@ export function useListingsCount(contract: RequiredParam<Marketplace>) {
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.marketplace.getTotalCount(contractAddress),
|
||||
() => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
return contract.getTotalCount();
|
||||
},
|
||||
{
|
||||
@@ -133,7 +137,7 @@ export function useActiveListings(
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.marketplace.getActiveListings(contractAddress, filter),
|
||||
() => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
|
||||
return contract.getActiveListings(filter);
|
||||
},
|
||||
@@ -168,8 +172,9 @@ export function useWinningBid(
|
||||
listingId,
|
||||
),
|
||||
() => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
return contract.auction.getWinningBid(BigNumber.from(listingId || 0));
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
requiredParamInvariant(listingId, "No listing id provided");
|
||||
return contract.auction.getWinningBid(listingId);
|
||||
},
|
||||
{
|
||||
enabled: !!contract && listingId !== undefined,
|
||||
@@ -201,12 +206,11 @@ export function useAuctionWinner(
|
||||
listingId,
|
||||
),
|
||||
async () => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
requiredParamInvariant(listingId, "No listing id provided");
|
||||
let winner: string | undefined;
|
||||
try {
|
||||
winner = await contract.auction.getWinner(
|
||||
BigNumber.from(listingId || 0),
|
||||
);
|
||||
winner = await contract.auction.getWinner(listingId);
|
||||
} catch (err) {
|
||||
if (!(err as Error)?.message?.includes("Could not find auction")) {
|
||||
throw err;
|
||||
@@ -238,7 +242,7 @@ export function useBidBuffer(contract: RequiredParam<Marketplace>) {
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.marketplace.getBidBufferBps(contractAddress),
|
||||
() => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
return contract.getBidBufferBps();
|
||||
},
|
||||
{
|
||||
@@ -247,6 +251,40 @@ export function useBidBuffer(contract: RequiredParam<Marketplace>) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this to get the minimum next bid for the auction listing from your marketplace contract.
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const { data: minimumNextBid, isLoading, error } = useMinimumNextBid(<YourMarketplaceContractInstance>, <listingId>);
|
||||
* ```
|
||||
*
|
||||
* @param contract - an instance of a marketplace contract
|
||||
* @param listingId - the listing id to check
|
||||
* @returns a response object that includes the minimum next bid for the auction listing
|
||||
* @beta
|
||||
*/
|
||||
export function useMinimumNextBid(
|
||||
contract: RequiredParam<Marketplace>,
|
||||
listingId: RequiredParam<BigNumberish>,
|
||||
) {
|
||||
const contractAddress = contract?.getAddress();
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.marketplace.auction.getWinner(
|
||||
contractAddress,
|
||||
listingId,
|
||||
),
|
||||
async () => {
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
requiredParamInvariant(listingId, "No listing id provided");
|
||||
return await contract.auction.getMinimumNextBid(listingId);
|
||||
},
|
||||
{
|
||||
enabled: !!contract && listingId !== undefined,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** **********************/
|
||||
/** WRITE HOOKS **/
|
||||
/** **********************/
|
||||
@@ -290,8 +328,9 @@ export function useCreateDirectListing(contract: RequiredParam<Marketplace>) {
|
||||
return useMutation(
|
||||
async (data: NewDirectListing) => {
|
||||
invariant(walletAddress, "no wallet connected, cannot create listing");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
invariant(
|
||||
contract?.direct?.createListing,
|
||||
contract.direct.createListing,
|
||||
"contract does not support direct.createListing",
|
||||
);
|
||||
return await contract.direct.createListing(data);
|
||||
@@ -346,8 +385,9 @@ export function useCreateAuctionListing(contract: RequiredParam<Marketplace>) {
|
||||
return useMutation(
|
||||
async (data: NewAuctionListing) => {
|
||||
invariant(walletAddress, "no wallet connected, cannot create listing");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
invariant(
|
||||
contract?.direct?.createListing,
|
||||
contract.direct.createListing,
|
||||
"contract does not support auction.createListing",
|
||||
);
|
||||
return await contract.auction.createListing(data);
|
||||
@@ -456,8 +496,9 @@ export function useMakeBid(contract: RequiredParam<Marketplace>) {
|
||||
return useMutation(
|
||||
async (data: MakeBidParams) => {
|
||||
invariant(walletAddress, "no wallet connected, cannot make bid");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
invariant(
|
||||
contract?.auction?.makeBid,
|
||||
contract.auction.makeBid,
|
||||
"contract does not support auction.makeBid",
|
||||
);
|
||||
return await contract.auction.makeBid(data.listingId, data.bid);
|
||||
@@ -512,9 +553,10 @@ export function useBuyNow(contract: RequiredParam<Marketplace>) {
|
||||
return useMutation(
|
||||
async (data: BuyNowParams) => {
|
||||
invariant(walletAddress, "no wallet connected, cannot make bid");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
if (data.type === ListingType.Direct) {
|
||||
invariant(
|
||||
contract?.direct.buyoutListing,
|
||||
contract.direct.buyoutListing,
|
||||
"contract does not support direct.buyoutListing",
|
||||
);
|
||||
|
||||
@@ -525,7 +567,7 @@ export function useBuyNow(contract: RequiredParam<Marketplace>) {
|
||||
);
|
||||
}
|
||||
invariant(
|
||||
contract?.auction?.buyoutListing,
|
||||
contract.auction.buyoutListing,
|
||||
"contract does not support auction.buyoutListing",
|
||||
);
|
||||
return await contract.auction.buyoutListing(data.id);
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import {
|
||||
requiredParamInvariant,
|
||||
RequiredParam,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import { useSDKChainId } from "../../providers/base";
|
||||
import {
|
||||
AirdropNFTParams,
|
||||
@@ -50,7 +53,7 @@ export function useNFT<TContract extends NFTContract>(
|
||||
return useQueryWithNetwork<NFT>(
|
||||
cacheKeys.contract.nft.get(contractAddress, tokenId),
|
||||
async () => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
|
||||
if (erc1155) {
|
||||
invariant(erc1155.get, "Contract instance does not support get");
|
||||
@@ -93,7 +96,7 @@ export function useNFTs<TContract extends NFTContract>(
|
||||
return useQueryWithNetwork<NFT[]>(
|
||||
cacheKeys.contract.nft.query.all(contractAddress, queryParams),
|
||||
async () => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
|
||||
if (erc721) {
|
||||
invariant(erc721.getAll, "Contract instance does not support getAll");
|
||||
@@ -134,7 +137,7 @@ export function useTotalCount<TContract extends NFTContract>(
|
||||
return useQueryWithNetwork<BigNumber>(
|
||||
cacheKeys.contract.nft.query.totalCount(contractAddress),
|
||||
async () => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
|
||||
if (erc1155) {
|
||||
invariant(
|
||||
@@ -182,14 +185,14 @@ export function useTotalCirculatingSupply(
|
||||
return useQueryWithNetwork<BigNumber>(
|
||||
cacheKeys.contract.nft.query.totalCirculatingSupply(contractAddress),
|
||||
async () => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
|
||||
if (erc1155) {
|
||||
invariant(
|
||||
erc1155.totalCirculatingSupply,
|
||||
"Contract instance does not support totalCirculatingSupply",
|
||||
);
|
||||
invariant(tokenId, "No tokenId provided");
|
||||
requiredParamInvariant(tokenId, "No tokenId provided");
|
||||
return await erc1155.totalCirculatingSupply(tokenId);
|
||||
}
|
||||
if (erc721) {
|
||||
@@ -232,7 +235,7 @@ export function useOwnedNFTs<TContract extends NFTContract>(
|
||||
return useQueryWithNetwork<NFT[]>(
|
||||
cacheKeys.contract.nft.query.owned.all(contractAddress, ownerWalletAddress),
|
||||
async () => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
invariant(ownerWalletAddress, "No wallet address provided");
|
||||
if (erc721) {
|
||||
return await erc721.getOwned(ownerWalletAddress);
|
||||
@@ -277,11 +280,11 @@ export function useNFTBalance(
|
||||
tokenId,
|
||||
),
|
||||
() => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
|
||||
invariant(ownerWalletAddress, "No owner wallet address provided");
|
||||
if (erc1155) {
|
||||
invariant(tokenId, "No tokenId provided");
|
||||
requiredParamInvariant(tokenId, "No tokenId provided");
|
||||
invariant(
|
||||
erc1155.balanceOf,
|
||||
"Contract instance does not support balanceOf",
|
||||
@@ -375,7 +378,7 @@ export function useMintNFT<TContract extends NFTContract>(
|
||||
return useMutation(
|
||||
async (data: MintNFTParams) => {
|
||||
invariant(data.to, 'No "to" address provided');
|
||||
invariant(contract, "contract is undefined");
|
||||
requiredParamInvariant(contract, "contract is undefined");
|
||||
if (erc1155) {
|
||||
invariant("supply" in data, "supply not provided");
|
||||
const { to, metadata, supply } = data;
|
||||
@@ -444,9 +447,9 @@ export function useMintNFTSupply(contract: Erc1155) {
|
||||
return useMutation(
|
||||
async (data: MintNFTSupplyParams) => {
|
||||
invariant(data.to, 'No "to" address provided');
|
||||
invariant(contract, "contract is undefined");
|
||||
requiredParamInvariant(contract, "contract is undefined");
|
||||
|
||||
invariant("tokenId" in data, "tokenId not provided");
|
||||
requiredParamInvariant(data.tokenId, "tokenId not provided");
|
||||
invariant("additionalSupply" in data, "additionalSupply not provided");
|
||||
const { to, tokenId, additionalSupply } = data;
|
||||
return await contract.mintAdditionalSupplyTo(
|
||||
@@ -512,7 +515,7 @@ export function useTransferNFT<TContract extends NFTContract>(
|
||||
invariant("to" in data, "to not provided");
|
||||
if (erc1155) {
|
||||
invariant(erc1155.transfer, "contract does not support transfer");
|
||||
invariant("tokenId" in data, "tokenId not provided");
|
||||
requiredParamInvariant(data.tokenId, "tokenId not provided");
|
||||
invariant("amount" in data, "amount not provided");
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
return erc1155.transfer(data.to, data.tokenId, data.amount!);
|
||||
@@ -539,7 +542,7 @@ export function useTransferNFT<TContract extends NFTContract>(
|
||||
* @example
|
||||
* ```jsx
|
||||
* const Component = () => {
|
||||
* const editionDrop = useEditionDrop(<ContractAddress>);
|
||||
* const editionDrop = useContract(<ContractAddress>, "edition-drop");
|
||||
* const {
|
||||
* mutate: airdropNFT,
|
||||
* isLoading,
|
||||
@@ -602,7 +605,8 @@ export function useAirdropNFT(contract: Erc1155) {
|
||||
|
||||
return useMutation(
|
||||
({ tokenId, addresses }: AirdropNFTParams) => {
|
||||
invariant(contract?.airdrop, "contract does not support airdrop");
|
||||
requiredParamInvariant(contract, "contract is undefined");
|
||||
invariant(contract.airdrop, "contract does not support airdrop");
|
||||
|
||||
return contract.airdrop(tokenId, addresses);
|
||||
},
|
||||
@@ -688,8 +692,8 @@ export function useBurnNFT<TContract extends NFTContract>(
|
||||
|
||||
return useMutation(
|
||||
async (data: BurnNFTParams) => {
|
||||
invariant(data.tokenId, "No tokenId provided");
|
||||
invariant(contract, "contract is undefined");
|
||||
requiredParamInvariant(data.tokenId, "No tokenId provided");
|
||||
requiredParamInvariant(contract, "contract is undefined");
|
||||
if (erc1155) {
|
||||
invariant("amount" in data, "amount not provided");
|
||||
const { tokenId, amount } = data;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import {
|
||||
requiredParamInvariant,
|
||||
RequiredParam,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import { useSDKChainId } from "../../providers/base";
|
||||
import { WalletAddress } from "../../types";
|
||||
import {
|
||||
@@ -61,7 +64,7 @@ export function useAllRoleMembers<TContract extends ContractWithRoles>(
|
||||
return useQueryWithNetwork<Awaited<GetAllReturnType<TContract>>>(
|
||||
cacheKeys.extensions.roles.getAll(contractAddress),
|
||||
() => {
|
||||
invariant(contract, "No contract provided");
|
||||
requiredParamInvariant(contract, "No contract provided");
|
||||
invariant(contract.roles, "Contract does not support roles");
|
||||
// have to cast to any because of role bs, type is defined in the useQueryWithNetwork definition above
|
||||
return contract.roles.getAll() as any;
|
||||
@@ -94,7 +97,7 @@ export function useRoleMembers<TContract extends ContractWithRoles>(
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.extensions.roles.get(contractAddress, role),
|
||||
() => {
|
||||
invariant(contract, "No contract provided");
|
||||
requiredParamInvariant(contract, "No contract provided");
|
||||
invariant(contract.roles, "Contract does not support roles");
|
||||
return contract.roles.get(role);
|
||||
},
|
||||
@@ -192,7 +195,7 @@ export function useSetAllRoleMembers<TContract extends ContractWithRoles>(
|
||||
async (rolesWithAddresses: {
|
||||
[role in RolesForContract<TContract>]: string[];
|
||||
}) => {
|
||||
invariant(contract, "No contract provided");
|
||||
requiredParamInvariant(contract, "No contract provided");
|
||||
invariant(contract.roles, "Contract does not support roles");
|
||||
await contract.roles.setAll(rolesWithAddresses);
|
||||
},
|
||||
@@ -253,7 +256,7 @@ export function useGrantRole<TContract extends ContractWithRoles>(
|
||||
role: RolesForContract<TContract>;
|
||||
address: WalletAddress;
|
||||
}) => {
|
||||
invariant(contract, "No contract provided");
|
||||
requiredParamInvariant(contract, "No contract provided");
|
||||
invariant(contract.roles, "Contract does not support roles");
|
||||
await contract.roles.grant(params.role as any, params.address);
|
||||
},
|
||||
@@ -311,7 +314,7 @@ export function useRevokeRole<TContract extends ContractWithRoles>(
|
||||
role: RolesForContract<TContract>;
|
||||
address: WalletAddress;
|
||||
}) => {
|
||||
invariant(contract, "No contract provided");
|
||||
requiredParamInvariant(contract, "No contract provided");
|
||||
invariant(contract.roles, "Contract does not support roles");
|
||||
await contract.roles.revoke(params.role as any, params.address);
|
||||
},
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import {
|
||||
requiredParamInvariant,
|
||||
RequiredParam,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import { useSDKChainId } from "../../providers/base";
|
||||
import {
|
||||
ClaimTokenParams,
|
||||
@@ -39,7 +42,7 @@ export function useTokenSupply(contract: RequiredParam<TokenContract>) {
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.token.totalSupply(contractAddress),
|
||||
() => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
const erc20 = getErc20(contract);
|
||||
if (erc20) {
|
||||
return erc20.totalSupply();
|
||||
@@ -75,7 +78,7 @@ export function useTokenBalance(
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.token.balanceOf(contractAddress, walletAddress),
|
||||
async () => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
invariant(walletAddress, "No address provided");
|
||||
if (erc20) {
|
||||
return await erc20.balanceOf(walletAddress);
|
||||
@@ -109,7 +112,7 @@ export function useTokenDecimals(contract: RequiredParam<TokenContract>) {
|
||||
return useQueryWithNetwork(
|
||||
cacheKeys.contract.token.decimals(contractAddress),
|
||||
async () => {
|
||||
invariant(contract, "No Contract instance provided");
|
||||
requiredParamInvariant(contract, "No Contract instance provided");
|
||||
|
||||
if (erc20) {
|
||||
return (await erc20.get()).decimals;
|
||||
@@ -168,7 +171,7 @@ export function useMintToken(contract: RequiredParam<TokenContract>) {
|
||||
return useMutation(
|
||||
(data: TokenParams) => {
|
||||
const { to, amount } = data;
|
||||
invariant(contract, "contract is undefined");
|
||||
requiredParamInvariant(contract, "contract is undefined");
|
||||
if (erc20) {
|
||||
return erc20.mintTo(to, amount);
|
||||
}
|
||||
@@ -350,7 +353,7 @@ export function useTransferBatchToken(contract: RequiredParam<TokenContract>) {
|
||||
(data: TokenParams[]) => {
|
||||
if (erc20) {
|
||||
invariant(
|
||||
erc20?.transferBatch,
|
||||
erc20.transferBatch,
|
||||
"contract does not support transferBatch",
|
||||
);
|
||||
const convertedData = data.map((token) => ({
|
||||
@@ -415,9 +418,9 @@ export function useBurnToken(contract: RequiredParam<TokenContract>) {
|
||||
return useMutation(
|
||||
(data: TokenBurnParams) => {
|
||||
const { amount } = data;
|
||||
invariant(contract, "contract is undefined");
|
||||
requiredParamInvariant(contract, "contract is undefined");
|
||||
if (erc20) {
|
||||
invariant(erc20?.burn, "contract does not support burn");
|
||||
invariant(erc20.burn, "contract does not support burn");
|
||||
return erc20.burn(amount);
|
||||
}
|
||||
invariant(false, "Smart contract is not a valid erc20 contract");
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
import {
|
||||
GnosisConnectorArguments,
|
||||
GnosisSafeConnector,
|
||||
} from "../../connectors/gnosis-safe";
|
||||
import { useConnect } from "../wagmi-required/useConnect";
|
||||
import { utils } from "ethers";
|
||||
import invariant from "tiny-invariant";
|
||||
import { useContext as useWagmiContext } from "wagmi";
|
||||
|
||||
/**
|
||||
* Hook for connecting to a Gnosis Safe. This enables multisig wallets to connect to your application and sing transactions.
|
||||
*
|
||||
* ```javascript
|
||||
* import { useGnosis } from "@thirdweb-dev/react"
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* import { useGnosis } from "@thirdweb-dev/react"
|
||||
*
|
||||
* const App = () => {
|
||||
* const connectWithGnosis = useGnosis()
|
||||
*
|
||||
* return (
|
||||
* <button onClick={() => connectWithGnosis({ safeAddress: "0x...", safeChainId: 1 })}>
|
||||
* Connect Gnosis Safe
|
||||
* </button>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function useGnosis() {
|
||||
const wagmiContext = useWagmiContext();
|
||||
invariant(
|
||||
wagmiContext,
|
||||
`useGnosis() can only be used inside <ThirdwebProvider />. If you are using <ThirdwebSDKProvider /> you will have to use your own wallet-connection logic.`,
|
||||
);
|
||||
const [connectors, connect] = useConnect();
|
||||
if (connectors.loading) {
|
||||
return () => Promise.reject("Gnosis connector not ready to be used, yet");
|
||||
}
|
||||
const connector = connectors.data.connectors.find((c) => c.id === "gnosis");
|
||||
invariant(
|
||||
connector,
|
||||
"Gnosis connector not found, please make sure it is provided to your <ThirdwebProvider />",
|
||||
);
|
||||
|
||||
return async (config: GnosisConnectorArguments) => {
|
||||
const previousConnector = connectors.data.connector;
|
||||
const previousConnectorChain = await previousConnector?.getChainId();
|
||||
invariant(
|
||||
!!previousConnector,
|
||||
"Cannot connect to Gnosis Safe without first being connected to a personal wallet.",
|
||||
);
|
||||
invariant(
|
||||
previousConnectorChain === config.safeChainId,
|
||||
"Gnosis safe chain id must match personal wallet chain id.",
|
||||
);
|
||||
invariant(
|
||||
utils.isAddress(config.safeAddress),
|
||||
"Gnosis safe address must be a valid address.",
|
||||
);
|
||||
(connector as GnosisSafeConnector).setConfiguration(
|
||||
previousConnector,
|
||||
config,
|
||||
);
|
||||
return connect(connector);
|
||||
};
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
import { MagicConnector } from "../../connectors/magic";
|
||||
import { useConnect } from "../wagmi-required/useConnect";
|
||||
import { LoginWithMagicLinkConfiguration } from "magic-sdk";
|
||||
import invariant from "tiny-invariant";
|
||||
import { useContext as useWagmiContext } from "wagmi";
|
||||
|
||||
/**
|
||||
* Hook for connecting to an email wallet using magic link.
|
||||
* This enables users without their own wallets to connect to your application and sign transactions securely using their email.
|
||||
*
|
||||
* ```javascript
|
||||
* import { useMagic } from "@thirdweb-dev/react"
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* Before using this hook, you first need to set up the magic configuration in your `ThirdwebProvider`, including your magic API key.
|
||||
*
|
||||
* ```javascript
|
||||
* // Add the magic configuration object to your wallet connectors
|
||||
* const connectors = [
|
||||
* "metamask",
|
||||
* "walletConnect",
|
||||
* "walletLink",
|
||||
* {
|
||||
* name: "magic",
|
||||
* options: {
|
||||
* apiKey: "your-magic-api-key",
|
||||
* }
|
||||
* }
|
||||
* ]
|
||||
*
|
||||
* // Add the above to the walletConnectors prop of your <ThirdwebProvider />
|
||||
* const Provider = ({ children }) => (
|
||||
* return (
|
||||
* <ThirdwebProvider
|
||||
* walletConnectors={connectors}
|
||||
* // Specify remaining parameters
|
||||
* ...
|
||||
* >
|
||||
* {children}
|
||||
* </ThirdwebProvider>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* In order to use the hook to connect users with magic link, you just need to provide the users email to the connect function.
|
||||
*
|
||||
* You can setup the hook with the following configuration:
|
||||
* ```javascript
|
||||
* import { useMagic } from "@thirdweb-dev/react"
|
||||
* import { useState } from "react"
|
||||
*
|
||||
* const LoginWithMagicLink = () => {
|
||||
* const connectWithMagic = useMagic()
|
||||
* const [email, setEmail] = useState()
|
||||
*
|
||||
* return (
|
||||
* <div>
|
||||
* <input value={email} onChange={(e) => setEmail(e.target.value)} />
|
||||
* <button onClick={() => connectWithMagic({ email })}>Login</button>
|
||||
* </div>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function useMagic() {
|
||||
const wagmiContext = useWagmiContext();
|
||||
invariant(
|
||||
wagmiContext,
|
||||
`useMagic() can only be used inside <ThirdwebProvider />. If you are using <ThirdwebSDKProvider /> you will have to use your own wallet-connection logic.`,
|
||||
);
|
||||
const [connectors, connect] = useConnect();
|
||||
if (connectors.loading) {
|
||||
return () => Promise.reject("Magic connector not ready to be used, yet");
|
||||
}
|
||||
|
||||
const connector = connectors.data.connectors.find((c) => c.id === "magic");
|
||||
|
||||
invariant(
|
||||
connector,
|
||||
"Magic connector not found, please make sure it is provided to your <ThirdwebProvider />",
|
||||
);
|
||||
|
||||
return (configuration: LoginWithMagicLinkConfiguration) => {
|
||||
(connector as MagicConnector).setConfiguration(configuration);
|
||||
return connect(connector);
|
||||
};
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useConnect } from "../wagmi-required/useConnect";
|
||||
import { Buffer } from "buffer";
|
||||
import invariant from "tiny-invariant";
|
||||
import { useContext as useWagmiContext } from "wagmi";
|
||||
|
||||
if (!globalThis.Buffer) {
|
||||
globalThis.Buffer = require("buffer/").Buffer;
|
||||
}
|
||||
globalThis.Buffer = Buffer;
|
||||
|
||||
/**
|
||||
* Hook for connecting to a mobile wallet with Wallet Connect
|
||||
*
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useConnect } from "../wagmi-required/useConnect";
|
||||
import { Buffer } from "buffer";
|
||||
import invariant from "tiny-invariant";
|
||||
import { useContext as useWagmiContext } from "wagmi";
|
||||
|
||||
if (!globalThis.Buffer) {
|
||||
globalThis.Buffer = require("buffer/").Buffer;
|
||||
}
|
||||
globalThis.Buffer = Buffer;
|
||||
|
||||
/**
|
||||
* Hook for connecting to a Coinbase wallet.
|
||||
*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { RequiredParam } from "../../../core/query-utils/required-param";
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
|
||||
@@ -28,8 +28,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const edition = await sdk.useEdition("0x1234...");
|
||||
* + const edition = await sdk.useContract("0x1234...", "edition").contract;
|
||||
* - const edition = useEdition("0x1234...");
|
||||
* + const edition = useContract("0x1234...", "edition").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useEdition(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { RequiredParam } from "../../../core/query-utils/required-param";
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
|
||||
@@ -27,8 +27,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const editionDrop = await sdk.useEditionDrop("0x1234...");
|
||||
* + const editionDrop = await sdk.useContract("0x1234...", "edition-drop").contract;
|
||||
* - const editionDrop = useEditionDrop("0x1234...");
|
||||
* + const editionDrop = useContract("0x1234...", "edition-drop").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useEditionDrop(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { RequiredParam } from "../../../core/query-utils/required-param";
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
|
||||
@@ -28,8 +28,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const marketplace = await sdk.useMarketplace("0x1234...");
|
||||
* + const marketplace = await sdk.useContract("0x1234...", "marketplace").contract;
|
||||
* - const marketplace = useMarketplace("0x1234...");
|
||||
* + const marketplace = useContract("0x1234...", "marketplace").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useMarketplace(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { RequiredParam } from "../../../core/query-utils/required-param";
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
|
||||
@@ -27,8 +27,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const multiwrap = await sdk.useMultiwrap("0x1234...");
|
||||
* + const multiwrap = await sdk.useContract("0x1234...", "multiwrap").contract;
|
||||
* - const multiwrap = useMultiwrap("0x1234...");
|
||||
* + const multiwrap = useContract("0x1234...", "multiwrap").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useMultiwrap(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { RequiredParam } from "../../../core/query-utils/required-param";
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
|
||||
@@ -28,8 +28,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const nftCollection = await sdk.useNFTCollection("0x1234...");
|
||||
* + const nftCollection = await sdk.useContract("0x1234...", "nft-collection").contract;
|
||||
* - const nftCollection = useNFTCollection("0x1234...");
|
||||
* + const nftCollection = useContract("0x1234...", "nft-collection").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useNFTCollection(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { RequiredParam } from "../../../core/query-utils/required-param";
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
|
||||
@@ -27,8 +27,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const nftDrop = await sdk.useNFTDrop("0x1234...");
|
||||
* + const nftDrop = await sdk.useContract("0x1234...", "nft-drop").contract;
|
||||
* - const nftDrop = useNFTDrop("0x1234...");
|
||||
* + const nftDrop = useContract("0x1234...", "nft-drop").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useNFTDrop(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { RequiredParam } from "../../../core/query-utils/required-param";
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
|
||||
@@ -28,8 +28,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const pack = await sdk.usePack("0x1234...");
|
||||
* + const pack = await sdk.useContract("0x1234...", "pack").contract;
|
||||
* - const pack = usePack("0x1234...");
|
||||
* + const pack = useContract("0x1234...", "pack").contract;
|
||||
* ```
|
||||
*/
|
||||
export function usePack(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { RequiredParam } from "../../../core/query-utils/required-param";
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
|
||||
@@ -27,8 +27,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const signatureDrop = await sdk.useSignatureDrop("0x1234...");
|
||||
* + const signatureDrop = await sdk.useContract("0x1234...", "signature-drop").contract;
|
||||
* - const signatureDrop = useSignatureDrop("0x1234...");
|
||||
* + const signatureDrop = useContract("0x1234...", "signature-drop").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useSignatureDrop(contractAddress?: RequiredParam<string>) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { RequiredParam } from "../../../core/query-utils/required-param";
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
|
||||
@@ -28,8 +28,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const split = await sdk.useSplit("0x1234...");
|
||||
* + const split = await sdk.useContract("0x1234...", "split").contract;
|
||||
* - const split = useSplit("0x1234...");
|
||||
* + const split = useContract("0x1234...", "split").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useSplit(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { RequiredParam } from "../../../core/query-utils/required-param";
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
|
||||
@@ -28,8 +28,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const token = await sdk.useToken("0x1234...");
|
||||
* + const token = await sdk.useContract("0x1234...", "token").contract;
|
||||
* - const token = useToken("0x1234...");
|
||||
* + const token = useContract("0x1234...", "token").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useToken(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { RequiredParam } from "../../../core/query-utils/required-param";
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
|
||||
@@ -28,8 +28,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const token = await sdk.useTokenDrop("0x1234...");
|
||||
* + const token = await sdk.useContract("0x1234...", "token-drop").contract;
|
||||
* - const token = useTokenDrop("0x1234...");
|
||||
* + const token = useContract("0x1234...", "token-drop").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useTokenDrop(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { RequiredParam } from "../../../core/query-utils/required-param";
|
||||
import { showDeprecationWarning } from "../../utils/deprecation-warning";
|
||||
import { useContract } from "../async/contracts";
|
||||
|
||||
@@ -28,8 +28,8 @@ import { useContract } from "../async/contracts";
|
||||
* @deprecated
|
||||
* This hook is deprecated and will be removed in a future major version. You should use {@link useContract} instead.
|
||||
* ```diff
|
||||
* - const vote = await sdk.useVote("0x1234...");
|
||||
* + const vote = await sdk.useContract("0x1234...", "vote").contract;
|
||||
* - const vote = useVote("0x1234...");
|
||||
* + const vote = useContract("0x1234...", "vote").contract;
|
||||
* ```
|
||||
*/
|
||||
export function useVote(contractAddress: RequiredParam<string>) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { GnosisSafeConnector } from "../../connectors/gnosis-safe";
|
||||
import { useConnect } from "./useConnect";
|
||||
import invariant from "tiny-invariant";
|
||||
import { useAccount, useContext as useWagmiContext } from "wagmi";
|
||||
import { Connector, useAccount, useContext as useWagmiContext } from "wagmi";
|
||||
|
||||
/**
|
||||
* Hook for disconnecting the currently connected wallet
|
||||
@@ -31,23 +30,22 @@ import { useAccount, useContext as useWagmiContext } from "wagmi";
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function useDisconnect(options?: { reconnectAfterGnosis?: boolean }) {
|
||||
export function useDisconnect(options?: { reconnectPrevious?: boolean }) {
|
||||
const wagmiContext = useWagmiContext();
|
||||
invariant(
|
||||
wagmiContext,
|
||||
`useDisconnect() can only be used inside <ThirdwebProvider />. If you are using <ThirdwebSDKProvider /> you will have to use your own connection logic.`,
|
||||
);
|
||||
const optsWithDefaults = { ...{ reconnectAfterGnosis: true }, ...options };
|
||||
const optsWithDefaults = { ...{ reconnectPrevious: true }, ...options };
|
||||
const [, connect] = useConnect();
|
||||
const [data, disconnect] = useAccount();
|
||||
|
||||
return async () => {
|
||||
const previousConnector =
|
||||
(data.data?.connector instanceof GnosisSafeConnector &&
|
||||
data.data.connector.previousConnector) ||
|
||||
undefined;
|
||||
// if there is a previous connector get it
|
||||
const previousConnector: Connector | undefined =
|
||||
(data?.data?.connector as any)?.previousConnector || undefined;
|
||||
// if it's gnosis, just connect the previous connector
|
||||
if (optsWithDefaults.reconnectAfterGnosis && previousConnector) {
|
||||
if (optsWithDefaults.reconnectPrevious && previousConnector) {
|
||||
try {
|
||||
return await connect(previousConnector);
|
||||
} catch (err) {
|
||||
|
||||
@@ -31,8 +31,6 @@ export * from "./hooks/wagmi-required/useConnect";
|
||||
export * from "./hooks/connectors/useMetamask";
|
||||
export * from "./hooks/connectors/useWalletConnect";
|
||||
export * from "./hooks/connectors/useWalletLink";
|
||||
export * from "./hooks/connectors/useGnosis";
|
||||
export * from "./hooks/connectors/useMagic";
|
||||
|
||||
// re-exports
|
||||
export { ChainId } from "@thirdweb-dev/sdk";
|
||||
|
||||
@@ -1,90 +1,93 @@
|
||||
import { useState, useCallback, useLayoutEffect, useEffect, useRef, PropsWithChildren } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import {
|
||||
useState,
|
||||
useCallback,
|
||||
useLayoutEffect,
|
||||
useEffect,
|
||||
useRef,
|
||||
PropsWithChildren,
|
||||
} from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
|
||||
|
||||
function canUseDOM() {
|
||||
function canUseDOM() {
|
||||
return !!(
|
||||
typeof window !== "undefined" &&
|
||||
window.document &&
|
||||
window.document.createElement
|
||||
);
|
||||
typeof window !== "undefined" &&
|
||||
window.document &&
|
||||
window.document.createElement
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces a re-render, similar to `forceUpdate` in class components.
|
||||
*/
|
||||
function useForceUpdate() {
|
||||
const [, dispatch] = useState<{}>(Object.create(null));
|
||||
return useCallback(() => {
|
||||
dispatch(Object.create(null));
|
||||
}, []);
|
||||
const [, dispatch] = useState<{}>(Object.create(null));
|
||||
return useCallback(() => {
|
||||
dispatch(Object.create(null));
|
||||
}, []);
|
||||
}
|
||||
|
||||
|
||||
const useIsomorphicLayoutEffect = canUseDOM() ? useLayoutEffect : useEffect;
|
||||
|
||||
/**
|
||||
* Portal from `@reach/portal`
|
||||
*
|
||||
* @see Docs https://reach.tech/portal#portal
|
||||
*/
|
||||
const PortalImpl: React.FC<PortalProps> = ({
|
||||
children,
|
||||
type = "reach-portal",
|
||||
containerRef,
|
||||
}) => {
|
||||
const mountNode = useRef<HTMLDivElement | null>(null);
|
||||
const portalNode = useRef<HTMLElement | null>(null);
|
||||
const forceUpdate = useForceUpdate();
|
||||
|
||||
/**
|
||||
* Portal from `@reach/portal`
|
||||
*
|
||||
* @see Docs https://reach.tech/portal#portal
|
||||
*/
|
||||
const PortalImpl: React.FC<PortalProps> = ({
|
||||
children,
|
||||
type = "reach-portal",
|
||||
containerRef,
|
||||
}) => {
|
||||
const mountNode = useRef<HTMLDivElement | null>(null);
|
||||
const portalNode = useRef<HTMLElement | null>(null);
|
||||
const forceUpdate = useForceUpdate();
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
// This ref may be null when a hot-loader replaces components on the page
|
||||
if (!mountNode.current) {
|
||||
return;
|
||||
}
|
||||
// It's possible that the content of the portal has, itself, been portaled.
|
||||
// In that case, it's important to append to the correct document element.
|
||||
const ownerDocument = mountNode.current.ownerDocument;
|
||||
const body = containerRef?.current || ownerDocument.body;
|
||||
portalNode.current = ownerDocument?.createElement(type);
|
||||
body.appendChild(portalNode.current);
|
||||
forceUpdate();
|
||||
return () => {
|
||||
if (portalNode.current && body) {
|
||||
body.removeChild(portalNode.current);
|
||||
}
|
||||
};
|
||||
}, [type, forceUpdate, containerRef]);
|
||||
|
||||
return portalNode.current ? (
|
||||
createPortal(children, portalNode.current)
|
||||
) : (
|
||||
<span ref={mountNode} />
|
||||
);
|
||||
};
|
||||
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
// This ref may be null when a hot-loader replaces components on the page
|
||||
if (!mountNode.current) {return;}
|
||||
// It's possible that the content of the portal has, itself, been portaled.
|
||||
// In that case, it's important to append to the correct document element.
|
||||
const ownerDocument = mountNode.current.ownerDocument;
|
||||
const body = containerRef?.current || ownerDocument.body;
|
||||
portalNode.current = ownerDocument?.createElement(type);
|
||||
body.appendChild(portalNode.current);
|
||||
forceUpdate();
|
||||
return () => {
|
||||
if (portalNode.current && body) {
|
||||
body.removeChild(portalNode.current);
|
||||
}
|
||||
};
|
||||
}, [type, forceUpdate, containerRef]);
|
||||
export const Portal: React.FC<PortalProps> = ({
|
||||
unstable_skipInitialRender,
|
||||
...props
|
||||
}) => {
|
||||
const [hydrated, setHydrated] = useState(false);
|
||||
useEffect(() => {
|
||||
if (unstable_skipInitialRender) {
|
||||
setHydrated(true);
|
||||
}
|
||||
}, [unstable_skipInitialRender]);
|
||||
if (unstable_skipInitialRender && !hydrated) {
|
||||
return null;
|
||||
}
|
||||
return <PortalImpl {...props} />;
|
||||
};
|
||||
|
||||
return portalNode.current ? (
|
||||
createPortal(children, portalNode.current)
|
||||
) : (
|
||||
<span ref={mountNode} />
|
||||
);
|
||||
};
|
||||
|
||||
export const Portal: React.FC<PortalProps> = ({
|
||||
unstable_skipInitialRender,
|
||||
...props
|
||||
}) => {
|
||||
const [hydrated, setHydrated] = useState(false);
|
||||
useEffect(() => {
|
||||
if (unstable_skipInitialRender) {
|
||||
setHydrated(true);
|
||||
}
|
||||
}, [unstable_skipInitialRender]);
|
||||
if (unstable_skipInitialRender && !hydrated) {
|
||||
return null;
|
||||
}
|
||||
return <PortalImpl {...props} />;
|
||||
};
|
||||
|
||||
|
||||
export type PortalProps = PropsWithChildren<{
|
||||
type?: string;
|
||||
containerRef?: React.RefObject<Node>;
|
||||
unstable_skipInitialRender?: boolean;
|
||||
}>;
|
||||
|
||||
Portal.displayName = "Portal";
|
||||
export type PortalProps = PropsWithChildren<{
|
||||
type?: string;
|
||||
containerRef?: React.RefObject<Node>;
|
||||
unstable_skipInitialRender?: boolean;
|
||||
}>;
|
||||
|
||||
Portal.displayName = "Portal";
|
||||
|
||||
@@ -2,8 +2,8 @@ import {
|
||||
QueryClientProviderProps,
|
||||
QueryClientProviderWithDefault,
|
||||
} from "../../core/providers/query-client";
|
||||
import { RequiredParam } from "../../core/query-utils/required-param";
|
||||
import { ComponentWithChildren } from "../../core/types/component";
|
||||
import { RequiredParam } from "../../core/types/shared";
|
||||
import {
|
||||
ThirdwebAuthConfig,
|
||||
ThirdwebAuthConfigProvider,
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
import {
|
||||
GnosisConnectorArguments,
|
||||
GnosisSafeConnector,
|
||||
} from "../connectors/gnosis-safe";
|
||||
import { MagicConnector, MagicConnectorArguments } from "../connectors/magic";
|
||||
import type { GnosisSafeConnector } from "../connectors/gnosis-safe";
|
||||
import type { MagicConnector } from "../connectors/magic";
|
||||
import {
|
||||
Chain,
|
||||
SupportedChain,
|
||||
defaultSupportedChains,
|
||||
} from "../constants/chain";
|
||||
import { ThirdwebAuthConfig } from "../contexts/thirdweb-auth";
|
||||
import {
|
||||
ThirdwebConfigProvider,
|
||||
defaultChainRpc,
|
||||
} from "../contexts/thirdweb-config";
|
||||
import { ThirdwebConfigProvider } from "../contexts/thirdweb-config";
|
||||
import { ThirdwebSDKProvider, ThirdwebSDKProviderProps } from "./base";
|
||||
import { QueryClient } from "@tanstack/react-query";
|
||||
import {
|
||||
@@ -20,6 +14,7 @@ import {
|
||||
getProviderForNetwork,
|
||||
SDKOptionsOutput,
|
||||
} from "@thirdweb-dev/sdk";
|
||||
import { DEFAULT_RPC_URLS } from "@thirdweb-dev/sdk";
|
||||
import type { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import React, { useMemo } from "react";
|
||||
import {
|
||||
@@ -27,6 +22,7 @@ import {
|
||||
ProviderProps as WagmiproviderProps,
|
||||
useProvider,
|
||||
useSigner,
|
||||
Connector,
|
||||
} from "wagmi";
|
||||
import { CoinbaseWalletConnector } from "wagmi/connectors/coinbaseWallet";
|
||||
import { InjectedConnector } from "wagmi/connectors/injected";
|
||||
@@ -58,26 +54,6 @@ export type WalletLinkConnectorType =
|
||||
options: CoinbaseWalletConnector["options"];
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export type MagicConnectorType =
|
||||
| "magic"
|
||||
| {
|
||||
name: "magic";
|
||||
options: Omit<MagicConnectorArguments, "network">;
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export type GnosisConnectorType =
|
||||
| "gnosis"
|
||||
| {
|
||||
name: "gnosis";
|
||||
options: GnosisConnectorArguments;
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
@@ -85,8 +61,8 @@ export type WalletConnector =
|
||||
| InjectedConnectorType
|
||||
| WalletConnectConnectorType
|
||||
| WalletLinkConnectorType
|
||||
| MagicConnectorType
|
||||
| GnosisConnectorType;
|
||||
| GnosisSafeConnector
|
||||
| MagicConnector;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@@ -223,7 +199,7 @@ export const ThirdwebProvider = <
|
||||
TSupportedChain extends SupportedChain = SupportedChain,
|
||||
>({
|
||||
sdkOptions,
|
||||
chainRpc = defaultChainRpc,
|
||||
chainRpc = DEFAULT_RPC_URLS,
|
||||
supportedChains = defaultSupportedChains.map(
|
||||
(c) => c.id,
|
||||
) as TSupportedChain[],
|
||||
@@ -282,6 +258,9 @@ export const ThirdwebProvider = <
|
||||
connectors: ({ chainId }: { chainId?: number }) => {
|
||||
return walletConnectors
|
||||
.map((connector) => {
|
||||
if (connector instanceof Connector) {
|
||||
return connector;
|
||||
}
|
||||
// injected connector
|
||||
if (
|
||||
(typeof connector === "string" &&
|
||||
@@ -346,25 +325,7 @@ export const ThirdwebProvider = <
|
||||
},
|
||||
});
|
||||
}
|
||||
if (typeof connector === "object" && connector.name === "magic") {
|
||||
const jsonRpcUrl = _rpcUrlMap[chainId || desiredChainId || 1];
|
||||
return new MagicConnector({
|
||||
chains: _supporrtedChains,
|
||||
options: {
|
||||
...connector.options,
|
||||
network: { rpcUrl: jsonRpcUrl, chainId: desiredChainId || 1 },
|
||||
rpcUrls: _rpcUrlMap,
|
||||
},
|
||||
});
|
||||
}
|
||||
if (
|
||||
(typeof connector === "string" && connector === "gnosis") ||
|
||||
(typeof connector === "object" && connector.name === "gnosis")
|
||||
) {
|
||||
return new GnosisSafeConnector({
|
||||
chains: _supporrtedChains,
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
.filter((c) => c !== null);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RequiredParam } from "../core/types/shared";
|
||||
import { RequiredParam } from "../core/query-utils/required-param";
|
||||
import type {
|
||||
AirdropInput,
|
||||
Amount,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { RequiredParam } from "../../core/types/shared";
|
||||
import { RequiredParam } from "../../core/query-utils/required-param";
|
||||
import { SupportedChainId } from "../constants/chain";
|
||||
import { ContractAddress, WalletAddress } from "../types";
|
||||
import { QueryClient, QueryKey } from "@tanstack/react-query";
|
||||
import type {
|
||||
ClaimConditionFetchOptions,
|
||||
MarketplaceFilter,
|
||||
QueryAllParams,
|
||||
SUPPORTED_CHAIN_ID,
|
||||
@@ -267,22 +268,24 @@ export const cacheKeys = {
|
||||
getActive: (
|
||||
contractAddress: RequiredParam<ContractAddress>,
|
||||
tokenId?: BigNumberish,
|
||||
options?: ClaimConditionFetchOptions,
|
||||
) =>
|
||||
createContractCacheKey(
|
||||
contractAddress,
|
||||
tokenId
|
||||
? ["claimConditions", "getActive", { tokenId }]
|
||||
: ["claimConditions", "getActive"],
|
||||
? ["claimConditions", "getActive", { tokenId }, options]
|
||||
: ["claimConditions", "getActive", options],
|
||||
),
|
||||
getAll: (
|
||||
contractAddress: RequiredParam<ContractAddress>,
|
||||
tokenId?: BigNumberish,
|
||||
options?: ClaimConditionFetchOptions,
|
||||
) =>
|
||||
createContractCacheKey(
|
||||
contractAddress,
|
||||
tokenId
|
||||
? ["claimConditions", "getAll", { tokenId }]
|
||||
: ["claimConditions", "getAll"],
|
||||
? ["claimConditions", "getAll", { tokenId }, options]
|
||||
: ["claimConditions", "getAll", options],
|
||||
),
|
||||
getClaimIneligibilityReasons: (
|
||||
contractAddress: RequiredParam<ContractAddress>,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// at the moment we'll re-export everything from the ethereum package (only!)
|
||||
// at the moment we'll re-export everything from the ethereum package
|
||||
export * from "./evm";
|
||||
|
||||
// core exports
|
||||
export { shouldNeverPersistQuery } from "./core/query-utils/query-key";
|
||||
export type { RequiredParam } from "./core/types/shared";
|
||||
export type { RequiredParam } from "./core/query-utils/required-param";
|
||||
|
||||
+8
-10
@@ -1,6 +1,6 @@
|
||||
import { createSOLProgramQueryKey } from "../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { MintNFTParams } from "../../../evm/types";
|
||||
import { createSOLProgramQueryKey } from "../../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../../core/query-utils/required-param";
|
||||
import { MintNFTParams } from "../../../types";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import type { NFTCollection } from "@thirdweb-dev/sdk/solana";
|
||||
import invariant from "tiny-invariant";
|
||||
@@ -15,15 +15,10 @@ import invariant from "tiny-invariant";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const { program } = useProgram("{{program_address}}");
|
||||
* const { mutateAsync: mint, isLoading, error } = useMintNFT(program);
|
||||
*
|
||||
* function mintNFT() {
|
||||
* const metadata = { name: "First NFT", description: "This is a cool NFT!" };
|
||||
* mint({ to: "{{wallet_address}}", metadata });
|
||||
* }
|
||||
* const { mutateAsync: mintNFT, isLoading, error } = useMintNFT(program);
|
||||
*
|
||||
* return (
|
||||
* <button onClick={() => mintNFT()}>
|
||||
* <button onClick={() => mintNFT({ metadata: { name: "First NFT" } })}>
|
||||
* Mint
|
||||
* </button>
|
||||
* )
|
||||
@@ -37,6 +32,9 @@ export function useMintNFT(program: RequiredParam<NFTCollection>) {
|
||||
return useMutation(
|
||||
async (data: MintNFTParams) => {
|
||||
invariant(program, "program is required");
|
||||
if (!data.to) {
|
||||
return await program.mint(data.metadata);
|
||||
}
|
||||
return await program.mintTo(data.to, data.metadata);
|
||||
},
|
||||
{
|
||||
@@ -0,0 +1,51 @@
|
||||
import { createSOLProgramQueryKey } from "../../../../core/query-utils/query-key";
|
||||
import {
|
||||
requiredParamInvariant,
|
||||
RequiredParam,
|
||||
} from "../../../../core/query-utils/required-param";
|
||||
import { MintNFTSupplyParams } from "../../../types";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import type { NFTCollection } from "@thirdweb-dev/sdk/solana";
|
||||
|
||||
/**
|
||||
* Mint additional supply for an NFT on your NFT program
|
||||
* @param program - The NFT program to mint additional NFTs to
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* import { useProgram, useMintNFTSupply } from "@thirdweb-dev/react/solana";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const { program } = useProgram("{{program_address}}");
|
||||
* const { mutateAsync: mintSupply, isLoading, error } = useMintNFTSupply(program);
|
||||
*
|
||||
* return (
|
||||
* <button onClick={() => mintSupply({ nftAddress: "111...", amount: 10 })}>
|
||||
* Mint Additional Supply
|
||||
* </button>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function useMintNFTSupply(program: RequiredParam<NFTCollection>) {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation(
|
||||
async (data: MintNFTSupplyParams) => {
|
||||
requiredParamInvariant(program, "program is required");
|
||||
if (!data.to) {
|
||||
return await program.mintAdditionalSupply(data.nftAddress, data.amount);
|
||||
}
|
||||
return await program.mintAdditionalSupplyTo(
|
||||
data.to,
|
||||
data.nftAddress,
|
||||
data.amount,
|
||||
);
|
||||
},
|
||||
{
|
||||
onSettled: () =>
|
||||
queryClient.invalidateQueries(createSOLProgramQueryKey(program)),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createSOLProgramQueryKey } from "../../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../../core/types/shared";
|
||||
import { RequiredParam } from "../../../../core/query-utils/required-param";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import type { NFTDrop } from "@thirdweb-dev/sdk/solana";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createSOLProgramQueryKey } from "../../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../../core/types/shared";
|
||||
import { RequiredParam } from "../../../../core/query-utils/required-param";
|
||||
import { ClaimNFTParams } from "../../../types";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import type { NFTDrop } from "@thirdweb-dev/sdk/solana";
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { createSOLProgramQueryKey } from "../../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../../core/types/shared";
|
||||
import {
|
||||
requiredParamInvariant,
|
||||
RequiredParam,
|
||||
} from "../../../../core/query-utils/required-param";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import type { NFTDrop } from "@thirdweb-dev/sdk/solana";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
export function dropTotalClaimedSupplyQuery(program: RequiredParam<NFTDrop>) {
|
||||
return {
|
||||
@@ -11,7 +13,7 @@ export function dropTotalClaimedSupplyQuery(program: RequiredParam<NFTDrop>) {
|
||||
] as const),
|
||||
|
||||
queryFn: async () => {
|
||||
invariant(program, "program is required");
|
||||
requiredParamInvariant(program, "program is required");
|
||||
|
||||
return await program.totalClaimedSupply();
|
||||
},
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { createSOLProgramQueryKey } from "../../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../../core/types/shared";
|
||||
import {
|
||||
requiredParamInvariant,
|
||||
RequiredParam,
|
||||
} from "../../../../core/query-utils/required-param";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { NFTMetadataInput, UploadProgressEvent } from "@thirdweb-dev/sdk";
|
||||
import type { NFTDrop } from "@thirdweb-dev/sdk/solana";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
/**
|
||||
* Lazy mint NFTs on an NFT Drop program
|
||||
@@ -34,7 +36,7 @@ export function useLazyMint(
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation(
|
||||
async (data: { metadatas: NFTMetadataInput[] }) => {
|
||||
invariant(program, "program is required");
|
||||
requiredParamInvariant(program, "program is required");
|
||||
let options;
|
||||
if (onProgress) {
|
||||
options = {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createSOLProgramQueryKey } from "../../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../../core/types/shared";
|
||||
import { RequiredParam } from "../../../../core/query-utils/required-param";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import type { NFTDrop, NFTDropConditionsInput } from "@thirdweb-dev/sdk/solana";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { createSOLProgramQueryKey } from "../../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../../core/types/shared";
|
||||
import {
|
||||
requiredParamInvariant,
|
||||
RequiredParam,
|
||||
} from "../../../../core/query-utils/required-param";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import type { NFTDrop } from "@thirdweb-dev/sdk/solana";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
export function dropUnclaimedSupplyQuery(program: RequiredParam<NFTDrop>) {
|
||||
return {
|
||||
@@ -11,7 +13,7 @@ export function dropUnclaimedSupplyQuery(program: RequiredParam<NFTDrop>) {
|
||||
] as const),
|
||||
|
||||
queryFn: async () => {
|
||||
invariant(program, "program is required");
|
||||
requiredParamInvariant(program, "program is required");
|
||||
|
||||
return await program.totalUnclaimedSupply();
|
||||
},
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { createSOLProgramQueryKey } from "../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import {
|
||||
requiredParamInvariant,
|
||||
RequiredParam,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import type { NFTCollection, NFTDrop } from "@thirdweb-dev/sdk/solana";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
/**
|
||||
* Burn an NFT owned by the connected wallet
|
||||
@@ -32,7 +34,7 @@ export function useBurnNFT(program: RequiredParam<NFTCollection | NFTDrop>) {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation(
|
||||
async (nftAddress: string) => {
|
||||
invariant(program, "program is required");
|
||||
requiredParamInvariant(program, "program is required");
|
||||
return await program.burn(nftAddress);
|
||||
},
|
||||
{
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import { createSOLProgramQueryKey } from "../../../core/query-utils/query-key";
|
||||
import {
|
||||
requiredParamInvariant,
|
||||
RequiredParam,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { NFTCollection, NFTDrop } from "@thirdweb-dev/sdk/solana";
|
||||
|
||||
export function nftCreatorsQuery(
|
||||
program: RequiredParam<NFTCollection | NFTDrop>,
|
||||
) {
|
||||
return {
|
||||
queryKey: createSOLProgramQueryKey(program, ["creators"] as const),
|
||||
|
||||
queryFn: async () => {
|
||||
requiredParamInvariant(program, "program is required");
|
||||
return await program.getCreators();
|
||||
},
|
||||
enabled: !!program,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the creators for an NFT program
|
||||
* @param program - The NFT program to get the creators for
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* import { useProgram, useCreators } from "@thirdweb-dev/react/solana";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const { program } = useProgram("{{program_address}}");
|
||||
* const { data: creators, isLoading } = useCreators(program);
|
||||
*
|
||||
* return (
|
||||
* <pre>{JSON.stringify(creators)}</pre>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function useCreators(program: RequiredParam<NFTCollection | NFTDrop>) {
|
||||
return useQuery(nftCreatorsQuery(program));
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
import { createSOLProgramQueryKey } from "../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import {
|
||||
requiredParamInvariant,
|
||||
RequiredParam,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import type { NFTCollection, NFTDrop } from "@thirdweb-dev/sdk/solana";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
export function nftGetOneQuery(
|
||||
program: RequiredParam<NFTCollection | NFTDrop>,
|
||||
@@ -15,8 +17,8 @@ export function nftGetOneQuery(
|
||||
] as const),
|
||||
|
||||
queryFn: async () => {
|
||||
invariant(program, "program is required");
|
||||
invariant(tokenAddress, "tokenAddress is required");
|
||||
requiredParamInvariant(program, "program is required");
|
||||
requiredParamInvariant(tokenAddress, "tokenAddress is required");
|
||||
return await program.get(tokenAddress);
|
||||
},
|
||||
enabled: !!program && !!tokenAddress,
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { createSOLProgramQueryKey } from "../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import {
|
||||
requiredParamInvariant,
|
||||
RequiredParam,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import type { NFTCollection, NFTDrop } from "@thirdweb-dev/sdk/solana";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
export function nftGetAllQuery(
|
||||
program: RequiredParam<NFTCollection | NFTDrop>,
|
||||
@@ -11,7 +13,7 @@ export function nftGetAllQuery(
|
||||
queryKey: createSOLProgramQueryKey(program, ["getAll"] as const),
|
||||
|
||||
queryFn: async () => {
|
||||
invariant(program, "program is required");
|
||||
requiredParamInvariant(program, "program is required");
|
||||
return await program.getAll();
|
||||
},
|
||||
enabled: !!program,
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import { createSOLProgramQueryKey } from "../../../core/query-utils/query-key";
|
||||
import {
|
||||
requiredParamInvariant,
|
||||
RequiredParam,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { NFTCollection, NFTDrop } from "@thirdweb-dev/sdk/solana";
|
||||
|
||||
export function nftRoyaltyQuery(
|
||||
program: RequiredParam<NFTCollection | NFTDrop>,
|
||||
) {
|
||||
return {
|
||||
queryKey: createSOLProgramQueryKey(program, ["royalty"] as const),
|
||||
|
||||
queryFn: async () => {
|
||||
requiredParamInvariant(program, "program is required");
|
||||
return await program.getRoyalty();
|
||||
},
|
||||
enabled: !!program,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the royalty for an NFT program
|
||||
* @param program - The NFT program to get the royalty for
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* import { useProgram, useRoyalty } from "@thirdweb-dev/react/solana";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const { program } = useProgram("{{program_address}}");
|
||||
* const { data: royalty, isLoading } = useRoyalty(program);
|
||||
*
|
||||
* return (
|
||||
* <p>{royalty}</p>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function useRoyalty(program: RequiredParam<NFTCollection | NFTDrop>) {
|
||||
return useQuery(nftRoyaltyQuery(program));
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
import { createSOLProgramQueryKey } from "../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import {
|
||||
requiredParamInvariant,
|
||||
RequiredParam,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import type { NFTCollection, NFTDrop } from "@thirdweb-dev/sdk/solana";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
export type TransferNFTMutationParams = {
|
||||
receiverAddress: string;
|
||||
@@ -42,7 +44,7 @@ export function useTransferNFT(
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation(
|
||||
async ({ tokenAddress, receiverAddress }: TransferNFTMutationParams) => {
|
||||
invariant(program, "program is required");
|
||||
requiredParamInvariant(program, "program is required");
|
||||
return await program.transfer(receiverAddress, tokenAddress);
|
||||
},
|
||||
{
|
||||
|
||||
@@ -2,7 +2,10 @@ import {
|
||||
createSOLQueryKeyWithNetwork,
|
||||
neverPersist,
|
||||
} from "../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import {
|
||||
requiredParamInvariant,
|
||||
RequiredParam,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import { useSDK } from "../../providers/base";
|
||||
import { programAccountTypeQuery } from "./useProgramAccountType";
|
||||
import {
|
||||
@@ -17,7 +20,6 @@ import type {
|
||||
ThirdwebSDK,
|
||||
Token,
|
||||
} from "@thirdweb-dev/sdk/solana";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
type ProgramMap = Readonly<{
|
||||
"nft-collection": NFTCollection;
|
||||
@@ -42,8 +44,8 @@ export function programQuery<TProgramType extends ProgramType>(
|
||||
),
|
||||
),
|
||||
queryFn: (async () => {
|
||||
invariant(sdk, "sdk is required");
|
||||
invariant(address, "Address is required");
|
||||
requiredParamInvariant(sdk, "sdk is required");
|
||||
requiredParamInvariant(address, "Address is required");
|
||||
// if the type is not passed in explicitly then we'll try to resolve it
|
||||
if (!type) {
|
||||
// why do we call `fetchQuery` here instead of calling the sdk directly?
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { createSOLQueryKeyWithNetwork } from "../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import {
|
||||
requiredParamInvariant,
|
||||
RequiredParam,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import { useSDK } from "../../providers/base";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import type { ThirdwebSDK } from "@thirdweb-dev/sdk/solana";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
export function programAccountTypeQuery(
|
||||
sdk: RequiredParam<ThirdwebSDK>,
|
||||
@@ -16,8 +18,8 @@ export function programAccountTypeQuery(
|
||||
network || null,
|
||||
),
|
||||
queryFn: async () => {
|
||||
invariant(sdk, "sdk is required");
|
||||
invariant(address, "Address is required");
|
||||
requiredParamInvariant(sdk, "sdk is required");
|
||||
requiredParamInvariant(address, "Address is required");
|
||||
|
||||
return await sdk.registry.getProgramType(address);
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createSOLProgramQueryKey } from "../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { RequiredParam } from "../../../core/query-utils/required-param";
|
||||
import { UseProgramResult } from "./useProgram";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { createSOLProgramQueryKey } from "../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import {
|
||||
requiredParamInvariant,
|
||||
RequiredParam,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import type { TokenParams } from "../../../evm";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import type { Token } from "@thirdweb-dev/sdk/solana";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
/**
|
||||
* Mint tokens on your token program
|
||||
@@ -31,7 +33,7 @@ export function useMintToken(program: RequiredParam<Token>) {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation(
|
||||
async (params: TokenParams) => {
|
||||
invariant(program, "program is required");
|
||||
requiredParamInvariant(program, "program is required");
|
||||
// TODO switch this to use mintTo once that is exposed
|
||||
return await program.mint(params.amount);
|
||||
},
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { createSOLProgramQueryKey } from "../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import {
|
||||
requiredParamInvariant,
|
||||
RequiredParam,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { Token } from "@thirdweb-dev/sdk/solana";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
export function tokenBalanceQuery(
|
||||
program: RequiredParam<Token>,
|
||||
@@ -14,9 +16,8 @@ export function tokenBalanceQuery(
|
||||
{ walletAddress },
|
||||
] as const),
|
||||
queryFn: async () => {
|
||||
invariant(program, "program is required");
|
||||
|
||||
invariant(walletAddress, "Wallet address is required");
|
||||
requiredParamInvariant(program, "program is required");
|
||||
requiredParamInvariant(walletAddress, "Wallet address is required");
|
||||
return await program.balanceOf(walletAddress);
|
||||
},
|
||||
enabled: !!program && !!walletAddress,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createSOLProgramQueryKey } from "../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { RequiredParam } from "../../../core/query-utils/required-param";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { Token } from "@thirdweb-dev/sdk/solana";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { createSOLProgramQueryKey } from "../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import {
|
||||
requiredParamInvariant,
|
||||
RequiredParam,
|
||||
} from "../../../core/query-utils/required-param";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import type { Amount, Token } from "@thirdweb-dev/sdk/solana";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
export type TransferTokenMutationParams = {
|
||||
amount: Amount;
|
||||
@@ -35,7 +37,7 @@ export function useTransferToken(program: RequiredParam<Token>) {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation(
|
||||
async ({ amount, receiverAddress }: TransferTokenMutationParams) => {
|
||||
invariant(program, "program is required");
|
||||
requiredParamInvariant(program, "program is required");
|
||||
return await program.transfer(receiverAddress, amount);
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createSOLQueryKeyWithNetwork } from "../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { RequiredParam } from "../../../core/query-utils/required-param";
|
||||
import { useSDK } from "../../providers/base";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { ThirdwebSDK } from "@thirdweb-dev/sdk/solana";
|
||||
|
||||
@@ -12,11 +12,13 @@ export * from "./hooks/program/useProgramAccountType";
|
||||
|
||||
// NFT Shared
|
||||
export * from "./hooks/nft/useNFTs";
|
||||
export * from "./hooks/nft/useMintNFT";
|
||||
export * from "./hooks/nft/useNFT";
|
||||
export * from "./hooks/nft/useTransferNFT";
|
||||
export * from "./hooks/nft/useBurnNFT";
|
||||
|
||||
// NFT Collection
|
||||
export * from "./hooks/nft/collection/useMintNFT";
|
||||
export * from "./hooks/nft/collection/useMintNFTSupply";
|
||||
|
||||
// NFT Drop
|
||||
export * from "./hooks/nft/drop/useLazyMint";
|
||||
export * from "./hooks/nft/drop/useClaimedSupply";
|
||||
|
||||
@@ -2,8 +2,8 @@ import {
|
||||
QueryClientProviderProps,
|
||||
QueryClientProviderWithDefault,
|
||||
} from "../../core/providers/query-client";
|
||||
import { RequiredParam } from "../../core/query-utils/required-param";
|
||||
import { ComponentWithChildren } from "../../core/types/component";
|
||||
import { RequiredParam } from "../../core/types/shared";
|
||||
import {
|
||||
ThirdwebAuthConfig,
|
||||
ThirdwebAuthConfigProvider,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { ThirdwebAuthConfig } from "../contexts/thirdweb-auth";
|
||||
import { ThirdwebSDKProvider } from "./base";
|
||||
import type { WalletAdapter } from "@solana/wallet-adapter-base";
|
||||
import { PhantomWalletAdapter } from "@solana/wallet-adapter-phantom";
|
||||
import {
|
||||
ConnectionProvider,
|
||||
useWallet,
|
||||
WalletProvider,
|
||||
} from "@solana/wallet-adapter-react";
|
||||
import { PhantomWalletAdapter } from "@solana/wallet-adapter-wallets";
|
||||
import { getUrlForNetwork, Network } from "@thirdweb-dev/sdk/solana";
|
||||
import { PropsWithChildren } from "react";
|
||||
|
||||
|
||||
@@ -1,4 +1,15 @@
|
||||
import { Amount } from "@thirdweb-dev/sdk";
|
||||
import { Amount, NFTMetadataOrUri } from "@thirdweb-dev/sdk";
|
||||
|
||||
/**
|
||||
* The params for the {@link useMintNFT} hook mutation.
|
||||
*
|
||||
* @beta
|
||||
*/
|
||||
export type MintNFTParams = {
|
||||
to?: string;
|
||||
metadata: NFTMetadataOrUri;
|
||||
amount?: Amount;
|
||||
};
|
||||
|
||||
/**
|
||||
* The params for the {@link useClaimNFT} hook mutation.
|
||||
@@ -9,3 +20,13 @@ export type ClaimNFTParams = {
|
||||
to?: string;
|
||||
amount: Amount;
|
||||
};
|
||||
|
||||
/**
|
||||
* The params to pass to {@link useMintNFTSupply} hook mutation
|
||||
* @beta
|
||||
*/
|
||||
export type MintNFTSupplyParams = {
|
||||
to?: string;
|
||||
nftAddress: string;
|
||||
amount: Amount;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,94 @@
|
||||
# @thirdweb-dev/sdk
|
||||
|
||||
## 3.4.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#337](https://github.com/thirdweb-dev/js/pull/337) [`340605b`](https://github.com/thirdweb-dev/js/commit/340605b507f384fbd2999b9c16542af3c53e84a9) Thanks [@adam-maj](https://github.com/adam-maj)! - Clean native token address in listing
|
||||
|
||||
- [#342](https://github.com/thirdweb-dev/js/pull/342) [`26116a6`](https://github.com/thirdweb-dev/js/commit/26116a6f637ee845f7bd17f20ffe17caf184658e) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Add new univeral RPC urls
|
||||
|
||||
- [#335](https://github.com/thirdweb-dev/js/pull/335) [`15f8006`](https://github.com/thirdweb-dev/js/commit/15f8006e1fb22333b7ee239b45e7b1b12d6dccc8) Thanks [@adam-maj](https://github.com/adam-maj)! - Export smart contract
|
||||
|
||||
- [#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 [[`ef27aad`](https://github.com/thirdweb-dev/js/commit/ef27aad0aafc4577e85f44dc77dfbe880bd239b5)]:
|
||||
- @thirdweb-dev/storage@1.0.6
|
||||
|
||||
## 3.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#332](https://github.com/thirdweb-dev/js/pull/332) [`ad851f7`](https://github.com/thirdweb-dev/js/commit/ad851f7b4d6abb5ab9364ef3dec229f913e18ce5) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Fix for finding addresses in legacy merkle tree format
|
||||
|
||||
- [#330](https://github.com/thirdweb-dev/js/pull/330) [`6218c88`](https://github.com/thirdweb-dev/js/commit/6218c885842e6b4e44ec38ec92a9211e56c49bf4) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Fix deploying contracts with non-32 bytes parameters like bytes4
|
||||
|
||||
## 3.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#315](https://github.com/thirdweb-dev/js/pull/315) [`89ff921`](https://github.com/thirdweb-dev/js/commit/89ff921a7d9f0e42b4e6707c8b56d0aab95c1aa0) Thanks [@furqanrydhan](https://github.com/furqanrydhan)! - fixing vite, multihash moved to non lazy load + cbor-x instead of cbor-web
|
||||
|
||||
- [#321](https://github.com/thirdweb-dev/js/pull/321) [`a57b4f0`](https://github.com/thirdweb-dev/js/commit/a57b4f01f3a49590b897101f2730582e4124a554) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - [SDK] Implement sharded merkle trees for lightweight allowlist checks
|
||||
|
||||
**Behavior change**
|
||||
|
||||
We've made allowlists much more performant using sharded merkle trees. This allows us to process large allowlists (1M+) efficiently.
|
||||
|
||||
To support those large allowlists, fetching claim conditions does not fetch the allowlist data by default anymore. Instead, you can pass an options object to additionally fetch the allowlist data along with the rest of the claim conditions data.
|
||||
|
||||
This affects `ClaimConditions.getActive()` and `ClaimConditions.getAll()`
|
||||
|
||||
Examples:
|
||||
|
||||
```ts
|
||||
const activeClaimCondition =
|
||||
await contract.erc721.claimConditions.getActive();
|
||||
// `activeClaimCondition.snapshot` is undefined
|
||||
const activeclaimConditionWithtAllowList =
|
||||
await contract.erc721.claimConditions.getActive({
|
||||
withAllowList: true,
|
||||
});
|
||||
// `activeClaimCondition.snapshot` returns the allowlist data
|
||||
```
|
||||
|
||||
### 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)! - [EVM] - expose fn to get ipfs hash from bytecote publicly
|
||||
|
||||
- [#328](https://github.com/thirdweb-dev/js/pull/328) [`df74340`](https://github.com/thirdweb-dev/js/commit/df74340fa51323304c32419761d6f18628b060fa) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Update cbor-x import to work with es2018 builds (embeds)
|
||||
|
||||
- Updated dependencies [[`87fd6ab`](https://github.com/thirdweb-dev/js/commit/87fd6ab14e1a67a1b12e72bd397fb21769537307)]:
|
||||
- @thirdweb-dev/[email protected]
|
||||
|
||||
## 3.2.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#317](https://github.com/thirdweb-dev/js/pull/317) [`4f867e1`](https://github.com/thirdweb-dev/js/commit/4f867e15edbe5757afbf54cab207458711a8986c) Thanks [@adam-maj](https://github.com/adam-maj)! - Add supply to nft.get
|
||||
|
||||
- [#312](https://github.com/thirdweb-dev/js/pull/312) [`b6eec61`](https://github.com/thirdweb-dev/js/commit/b6eec6146c23b66a3681bbb48b173b9019254214) Thanks [@adam-maj](https://github.com/adam-maj)! - Add quantity to mint additional supply
|
||||
|
||||
- [#310](https://github.com/thirdweb-dev/js/pull/310) [`9727502`](https://github.com/thirdweb-dev/js/commit/9727502eb30ac139382b7c7c8e8fc0967cbfbcf1) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - [SOL] - add useMintNFTSupply hook in react and accomodate inputs for it in SDK
|
||||
|
||||
- [#307](https://github.com/thirdweb-dev/js/pull/307) [`782b58d`](https://github.com/thirdweb-dev/js/commit/782b58d3f6a3b49ff9b3d837551db5161f96171a) Thanks [@kumaryash90](https://github.com/kumaryash90)! - fix multicall gasless
|
||||
|
||||
- [#320](https://github.com/thirdweb-dev/js/pull/320) [`f41a443`](https://github.com/thirdweb-dev/js/commit/f41a443c5785240197607b5bf93ff18a1c8e8307) Thanks [@adam-maj](https://github.com/adam-maj)! - Add update creators and update royalty
|
||||
|
||||
- [#313](https://github.com/thirdweb-dev/js/pull/313) [`f45ef62`](https://github.com/thirdweb-dev/js/commit/f45ef62128cfefe06275a38440c90d45e9f3cef7) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Return default metadata when failing to fetch a given tokenId on NFT contracts
|
||||
|
||||
- [#319](https://github.com/thirdweb-dev/js/pull/319) [`2f8ec89`](https://github.com/thirdweb-dev/js/commit/2f8ec89c4c83ae577092c840c198e6fcfb114e69) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Expose total claimed and unclaimed supply for erc721 drop contracts
|
||||
|
||||
- [#322](https://github.com/thirdweb-dev/js/pull/322) [`b7cd744`](https://github.com/thirdweb-dev/js/commit/b7cd744cd0482a6c3fe5ae0c858f20cd380d4114) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - [SOL] Allow signing multiple claims at once
|
||||
|
||||
- [#306](https://github.com/thirdweb-dev/js/pull/306) [`53c6507`](https://github.com/thirdweb-dev/js/commit/53c65076696a43bd9a7e58a7493d4e65c172900f) Thanks [@adam-maj](https://github.com/adam-maj)! - Add contract deploy listener
|
||||
|
||||
## 3.2.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#303](https://github.com/thirdweb-dev/js/pull/303) [`712b11a`](https://github.com/thirdweb-dev/js/commit/712b11a43e389ae10b7f09648779a69c05b2c913) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - [SOL] Fix getting real NFT owners
|
||||
|
||||
## 3.2.4
|
||||
|
||||
## 3.2.3
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/sdk",
|
||||
"version": "3.2.4",
|
||||
"version": "3.4.0",
|
||||
"description": "The main thirdweb SDK.",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/sdk",
|
||||
"license": "Apache-2.0",
|
||||
@@ -65,9 +65,8 @@
|
||||
"push": "yalc push"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@gmrchk/cli-testing-library": "^0.1.2",
|
||||
"@metaplex-foundation/amman": "^0.10.0",
|
||||
"@metaplex-foundation/amman-client": "^0.2.1",
|
||||
"@metaplex-foundation/amman": "0.10.0",
|
||||
"@metaplex-foundation/amman-client": "0.2.1",
|
||||
"@microsoft/api-documenter": "^7.19.4",
|
||||
"@microsoft/api-extractor": "^7.29.2",
|
||||
"@microsoft/tsdoc": "^0.14.1",
|
||||
@@ -82,7 +81,6 @@
|
||||
"@types/uuid": "^8.3.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.33.0",
|
||||
"@typescript-eslint/parser": "^5.33.0",
|
||||
"cbor": "^8.1.0",
|
||||
"chai": "^4.3.6",
|
||||
"deep-equal-in-any-order": "^1.1.18",
|
||||
"eslint": "^8.21.0",
|
||||
@@ -91,11 +89,9 @@
|
||||
"eslint-plugin-inclusive-language": "^2.2.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-tsdoc": "^0.2.16",
|
||||
"esm": "^3.2.25",
|
||||
"ethers": "^5.7.0",
|
||||
"hardhat": "^2.9.3",
|
||||
"mocha": "^10.0.0",
|
||||
"node-stdlib-browser": "^1.2.0",
|
||||
"prettier": "^2.7.1",
|
||||
"typescript": "^4.7.4"
|
||||
},
|
||||
@@ -103,22 +99,20 @@
|
||||
"ethers": "^5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@metaplex-foundation/js": "^0.15.0",
|
||||
"@metaplex-foundation/mpl-token-metadata": "^2.2.2",
|
||||
"@project-serum/anchor": "^0.25.0",
|
||||
"@solana/spl-token": "^0.2.0",
|
||||
"@solana/web3.js": "^1.50.1",
|
||||
"@metaplex-foundation/js": "0.15.0",
|
||||
"@metaplex-foundation/mpl-token-metadata": "2.2.2",
|
||||
"@project-serum/anchor": "0.25.0",
|
||||
"@solana/spl-token": "0.2.0",
|
||||
"@solana/web3.js": "1.62.0",
|
||||
"@thirdweb-dev/contracts-js": "*",
|
||||
"@thirdweb-dev/storage": "*",
|
||||
"bn.js": "^5.2.1",
|
||||
"bs58": "^5.0.0",
|
||||
"cbor-web": "^8.1.0",
|
||||
"cbor-x": "^1.4.1",
|
||||
"cross-fetch": "^3.1.5",
|
||||
"eventemitter3": "^4.0.7",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"form-data": "^4.0.0",
|
||||
"merkletreejs": "^0.2.24",
|
||||
"multihashes": "^4.0.3",
|
||||
"tiny-invariant": "^1.2.0",
|
||||
"tweetnacl": "^1.0.3",
|
||||
"uuid": "^9.0.0",
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
export const DEFAULT_API_KEY =
|
||||
"c6634ad2d97b74baf15ff556016830c251050e6c36b9da508ce3ec80095d3dc1";
|
||||
|
||||
export function getRpcUrl(network: string) {
|
||||
return `https://${network}.rpc.thirdweb.com/${DEFAULT_API_KEY}`;
|
||||
}
|
||||
@@ -6,6 +6,8 @@ import {
|
||||
ClaimConditionOutputSchema,
|
||||
} from "../schema/contracts/common/claim-conditions";
|
||||
import {
|
||||
SnapshotEntry,
|
||||
SnapshotEntryWithProof,
|
||||
SnapshotInputSchema,
|
||||
SnapshotSchema,
|
||||
} from "../schema/contracts/common/snapshots";
|
||||
@@ -23,17 +25,18 @@ import {
|
||||
isNativeToken,
|
||||
normalizePriceValue,
|
||||
} from "./currency";
|
||||
import { ShardedMerkleTree } from "./sharded-merkle-tree";
|
||||
import { createSnapshot } from "./snapshots";
|
||||
import { IDropClaimCondition } from "@thirdweb-dev/contracts-js/dist/declarations/src/DropERC20";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import {
|
||||
BigNumber,
|
||||
BigNumberish,
|
||||
ethers,
|
||||
CallOverrides,
|
||||
constants,
|
||||
ethers,
|
||||
providers,
|
||||
utils,
|
||||
CallOverrides,
|
||||
} from "ethers";
|
||||
|
||||
/**
|
||||
@@ -59,21 +62,17 @@ export async function prepareClaim(
|
||||
.toString()
|
||||
.startsWith(constants.AddressZero)
|
||||
) {
|
||||
const claims = await fetchSnapshot(
|
||||
const claim = await fetchSnapshotEntryForAddress(
|
||||
addressToClaim,
|
||||
activeClaimCondition.merkleRootHash.toString(),
|
||||
await merkleMetadataFetcher(),
|
||||
storage,
|
||||
);
|
||||
const item =
|
||||
claims &&
|
||||
claims.find(
|
||||
(c) => c.address.toLowerCase() === addressToClaim.toLowerCase(),
|
||||
);
|
||||
if (item === undefined) {
|
||||
if (!claim) {
|
||||
throw new Error("No claim found for this address");
|
||||
}
|
||||
proofs = item.proof;
|
||||
maxClaimable = ethers.utils.parseUnits(item.maxClaimable, tokenDecimals);
|
||||
proofs = claim.proof;
|
||||
maxClaimable = ethers.utils.parseUnits(claim.maxClaimable, tokenDecimals);
|
||||
}
|
||||
} catch (e) {
|
||||
// have to handle the valid error case that we *do* want to throw on
|
||||
@@ -114,14 +113,6 @@ export async function prepareClaim(
|
||||
};
|
||||
}
|
||||
|
||||
type Snapshot =
|
||||
| {
|
||||
address: string;
|
||||
proof: string[];
|
||||
maxClaimable: string;
|
||||
}[]
|
||||
| undefined;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param merkleRoot
|
||||
@@ -132,20 +123,59 @@ export async function fetchSnapshot(
|
||||
merkleRoot: string,
|
||||
merkleMetadata: Record<string, string> | undefined,
|
||||
storage: ThirdwebStorage,
|
||||
): Promise<Snapshot> {
|
||||
): Promise<SnapshotEntry[] | null> {
|
||||
if (!merkleMetadata) {
|
||||
return undefined;
|
||||
return null;
|
||||
}
|
||||
const snapshotUri = merkleMetadata[merkleRoot];
|
||||
let snapshot: Snapshot = undefined;
|
||||
if (snapshotUri) {
|
||||
const raw = await storage.downloadJSON(snapshotUri);
|
||||
const snapshotData = SnapshotSchema.parse(raw);
|
||||
if (merkleRoot === snapshotData.merkleRoot) {
|
||||
snapshot = snapshotData.claims;
|
||||
if (raw.isShardedMerkleTree && raw.merkleRoot === merkleRoot) {
|
||||
const smt = await ShardedMerkleTree.fromUri(snapshotUri, storage);
|
||||
return smt?.getAllEntries() || null;
|
||||
} else {
|
||||
const snapshotData = SnapshotSchema.parse(raw);
|
||||
if (merkleRoot === snapshotData.merkleRoot) {
|
||||
return snapshotData.claims.map((claim) => ({
|
||||
address: claim.address,
|
||||
maxClaimable: claim.maxClaimable,
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
return snapshot;
|
||||
return null;
|
||||
}
|
||||
|
||||
export async function fetchSnapshotEntryForAddress(
|
||||
address: string,
|
||||
merkleRoot: string,
|
||||
merkleMetadata: Record<string, string> | undefined,
|
||||
storage: ThirdwebStorage,
|
||||
): Promise<SnapshotEntryWithProof | null> {
|
||||
if (!merkleMetadata) {
|
||||
return null;
|
||||
}
|
||||
const snapshotUri = merkleMetadata[merkleRoot];
|
||||
if (snapshotUri) {
|
||||
const raw = await storage.downloadJSON(snapshotUri);
|
||||
if (raw.isShardedMerkleTree && raw.merkleRoot === merkleRoot) {
|
||||
const merkleTree = await ShardedMerkleTree.fromShardedMerkleTreeInfo(
|
||||
raw,
|
||||
storage,
|
||||
);
|
||||
return await merkleTree.getProof(address);
|
||||
}
|
||||
// legacy non-sharded, just fetch it all and filter out
|
||||
const snapshotData = SnapshotSchema.parse(raw);
|
||||
if (merkleRoot === snapshotData.merkleRoot) {
|
||||
return (
|
||||
snapshotData.claims.find(
|
||||
(c) => c.address.toLowerCase() === address.toLowerCase(),
|
||||
) || null
|
||||
);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -203,7 +233,11 @@ export async function updateExistingClaimConditions(
|
||||
/**
|
||||
* Fetches the proof for the current signer for a particular wallet.
|
||||
*
|
||||
* @param addressToClaim
|
||||
* @param merkleRoot - The merkle root of the condition to check.
|
||||
* @param tokenDecimals
|
||||
* @param merkleMetadata
|
||||
* @param storage
|
||||
* @returns - The proof for the current signer for the specified condition.
|
||||
*/
|
||||
export async function getClaimerProofs(
|
||||
@@ -213,30 +247,21 @@ export async function getClaimerProofs(
|
||||
merkleMetadata: Record<string, string>,
|
||||
storage: ThirdwebStorage,
|
||||
): Promise<{ maxClaimable: BigNumber; proof: string[] }> {
|
||||
const claims: Snapshot = await fetchSnapshot(
|
||||
const claim = await fetchSnapshotEntryForAddress(
|
||||
addressToClaim,
|
||||
merkleRoot,
|
||||
merkleMetadata,
|
||||
storage,
|
||||
);
|
||||
if (claims === undefined) {
|
||||
return {
|
||||
proof: [],
|
||||
maxClaimable: BigNumber.from(0),
|
||||
};
|
||||
}
|
||||
const item = claims.find(
|
||||
(c) => c.address.toLowerCase() === addressToClaim?.toLowerCase(),
|
||||
);
|
||||
|
||||
if (item === undefined) {
|
||||
if (!claim) {
|
||||
return {
|
||||
proof: [],
|
||||
maxClaimable: BigNumber.from(0),
|
||||
};
|
||||
}
|
||||
return {
|
||||
proof: item.proof,
|
||||
maxClaimable: ethers.utils.parseUnits(item.maxClaimable, tokenDecimals),
|
||||
proof: claim.proof,
|
||||
maxClaimable: ethers.utils.parseUnits(claim.maxClaimable, tokenDecimals),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -356,10 +381,10 @@ export async function transformResultToClaimCondition(
|
||||
provider: providers.Provider,
|
||||
merkleMetadata: Record<string, string> | undefined,
|
||||
storage: ThirdwebStorage,
|
||||
shouldDownloadSnapshot: boolean,
|
||||
): Promise<ClaimCondition> {
|
||||
const cv = await fetchCurrencyValue(provider, pm.currency, pm.pricePerToken);
|
||||
|
||||
const claims = await fetchSnapshot(pm.merkleRoot, merkleMetadata, storage);
|
||||
const maxClaimableSupply = convertToReadableQuantity(
|
||||
pm.maxClaimableSupply,
|
||||
tokenDecimals,
|
||||
@@ -388,7 +413,9 @@ export async function transformResultToClaimCondition(
|
||||
currencyAddress: pm.currency,
|
||||
currencyMetadata: cv,
|
||||
merkleRootHash: pm.merkleRoot,
|
||||
snapshot: claims,
|
||||
snapshot: shouldDownloadSnapshot
|
||||
? await fetchSnapshot(pm.merkleRoot, merkleMetadata, storage)
|
||||
: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,13 @@ export function isNativeToken(tokenAddress: string): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
export function cleanCurrencyAddress(currencyAddress: string): string {
|
||||
if (isNativeToken(currencyAddress)) {
|
||||
return NATIVE_TOKEN_ADDRESS;
|
||||
}
|
||||
return currencyAddress;
|
||||
}
|
||||
|
||||
export async function normalizePriceValue(
|
||||
provider: providers.Provider,
|
||||
inputPrice: Price,
|
||||
|
||||
@@ -22,6 +22,8 @@ import {
|
||||
} from "../schema/contracts/custom";
|
||||
import { ExtensionNotImplementedError } from "./error";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import bs58 from "bs58";
|
||||
import { decode } from "cbor-x";
|
||||
import { BaseContract, BigNumber, ethers } from "ethers";
|
||||
import { z } from "zod";
|
||||
|
||||
@@ -179,7 +181,7 @@ export function extractEventsFromAbi(
|
||||
abi: z.input<typeof AbiSchema>,
|
||||
metadata?: Record<string, any>,
|
||||
): AbiEvent[] {
|
||||
const events = abi.filter((el) => el.type === "event");
|
||||
const events = (abi || []).filter((el) => el.type === "event");
|
||||
const parsed: AbiEvent[] = [];
|
||||
for (const e of events) {
|
||||
const doc = extractCommentFromMetadata(e.name, metadata, "events");
|
||||
@@ -282,9 +284,9 @@ export async function resolveContractUriFromAddress(
|
||||
* @internal
|
||||
* @param bytecode
|
||||
*/
|
||||
async function extractIPFSHashFromBytecode(
|
||||
export function extractIPFSHashFromBytecode(
|
||||
bytecode: string,
|
||||
): Promise<string | undefined> {
|
||||
): string | undefined {
|
||||
const numericBytecode = hexToBytes(bytecode);
|
||||
const cborLength: number =
|
||||
numericBytecode[numericBytecode.length - 2] * 0x100 +
|
||||
@@ -293,15 +295,13 @@ async function extractIPFSHashFromBytecode(
|
||||
numericBytecode.slice(numericBytecode.length - 2 - cborLength, -2),
|
||||
);
|
||||
|
||||
// load these lazily to avoid loading them when they are not needed
|
||||
const [cbor, multiHashes] = await Promise.all([
|
||||
import("cbor-web"),
|
||||
import("multihashes"),
|
||||
]);
|
||||
|
||||
const cborData = cbor.decodeFirstSync(bytecodeBuffer);
|
||||
if (cborData["ipfs"]) {
|
||||
return `ipfs://${multiHashes.toB58String(cborData["ipfs"])}`;
|
||||
const cborData = decode(bytecodeBuffer);
|
||||
if ("ipfs" in cborData && cborData["ipfs"]) {
|
||||
try {
|
||||
return `ipfs://${bs58.encode(cborData["ipfs"])}`;
|
||||
} catch (e) {
|
||||
console.warn("feature-detection ipfs cbor failed", e);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user