Compare commits
32
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f46f270cd | ||
|
|
e8c25ed0f2 | ||
|
|
78d6d3c159 | ||
|
|
c72d92956a | ||
|
|
cf88795376 | ||
|
|
47287fb189 | ||
|
|
3763326c25 | ||
|
|
894eb27dfa | ||
|
|
8b3b97c8f7 | ||
|
|
89d87a5eb3 | ||
|
|
492a818079 | ||
|
|
86f608390a | ||
|
|
8096c78b46 | ||
|
|
521a49c6ec | ||
|
|
25a4773bba | ||
|
|
18381fac73 | ||
|
|
89b5c6fe07 | ||
|
|
4dccccc6fa | ||
|
|
de15e4212f | ||
|
|
1f41adbd2c | ||
|
|
1918495f2e | ||
|
|
24514a6e9f | ||
|
|
ad06c5b289 | ||
|
|
9de3f8c8e9 | ||
|
|
b1fa17158d | ||
|
|
2bdf1984cb | ||
|
|
df048af605 | ||
|
|
41507d32a7 | ||
|
|
b2cadf164c | ||
|
|
57b9c671aa | ||
|
|
3b7d10ed93 | ||
|
|
d6bb61b7fa |
@@ -1,5 +1,11 @@
|
||||
# @thirdweb-dev/auth
|
||||
|
||||
## 2.0.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#274](https://github.com/thirdweb-dev/js/pull/274) [`ad06c5b`](https://github.com/thirdweb-dev/js/commit/ad06c5b28902422f9b416d65255c64c937a5e046) Thanks [@adam-maj](https://github.com/adam-maj)! - Add solana auth support and plugins for react and auth package
|
||||
|
||||
## 2.0.13
|
||||
|
||||
## 2.0.12
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"main": "dist/thirdweb-dev-auth-next-evm.cjs.js",
|
||||
"module": "dist/thirdweb-dev-auth-next-evm.esm.js"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"main": "dist/thirdweb-dev-auth-next-solana.cjs.js",
|
||||
"module": "dist/thirdweb-dev-auth-next-solana.esm.js"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/auth",
|
||||
"version": "2.0.13",
|
||||
"version": "2.0.14",
|
||||
"exports": {
|
||||
"./next": {
|
||||
"module": "./next/dist/thirdweb-dev-auth-next.esm.js",
|
||||
@@ -10,10 +10,18 @@
|
||||
"module": "./express/dist/thirdweb-dev-auth-express.esm.js",
|
||||
"default": "./express/dist/thirdweb-dev-auth-express.cjs.js"
|
||||
},
|
||||
"./next/evm": {
|
||||
"module": "./next/evm/dist/thirdweb-dev-auth-next-evm.esm.js",
|
||||
"default": "./next/evm/dist/thirdweb-dev-auth-next-evm.cjs.js"
|
||||
},
|
||||
"./next-auth": {
|
||||
"module": "./next-auth/dist/thirdweb-dev-auth-next-auth.esm.js",
|
||||
"default": "./next-auth/dist/thirdweb-dev-auth-next-auth.cjs.js"
|
||||
},
|
||||
"./next/solana": {
|
||||
"module": "./next/solana/dist/thirdweb-dev-auth-next-solana.esm.js",
|
||||
"default": "./next/solana/dist/thirdweb-dev-auth-next-solana.cjs.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/auth",
|
||||
@@ -35,6 +43,8 @@
|
||||
"preconstruct": {
|
||||
"entrypoints": [
|
||||
"next/index.ts",
|
||||
"next/evm/index.ts",
|
||||
"next/solana/index.ts",
|
||||
"express/index.ts",
|
||||
"next-auth/index.ts"
|
||||
],
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
import loginHandler from "./routes/login";
|
||||
import logoutHandler from "./routes/logout";
|
||||
import userHandler from "./routes/user";
|
||||
import {
|
||||
ThirdwebAuthConfig,
|
||||
ThirdwebAuthRoute,
|
||||
ThirdwebAuthUser,
|
||||
} from "./types";
|
||||
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
import cookieParser from "cookie-parser";
|
||||
import { Express, NextFunction, Request, Response } from "express";
|
||||
|
||||
export * from "./types";
|
||||
|
||||
export function getUser(req: Request): ThirdwebAuthUser | null {
|
||||
return req.user;
|
||||
}
|
||||
|
||||
export function ThirdwebAuth(app: Express, cfg: ThirdwebAuthConfig) {
|
||||
const ctx = {
|
||||
...cfg,
|
||||
sdk: ThirdwebSDK.fromPrivateKey(cfg.privateKey, "mainnet"),
|
||||
};
|
||||
|
||||
const authUrl = cfg.authUrl?.replace(/\/$/, "") || "/auth";
|
||||
|
||||
app.use(cookieParser());
|
||||
|
||||
app.use(async (req: Request, _: Response, next: NextFunction) => {
|
||||
const { sdk, domain } = ctx;
|
||||
let user = null;
|
||||
const token = req.cookies.thirdweb_auth_token;
|
||||
|
||||
if (token) {
|
||||
try {
|
||||
const address = await sdk.auth.authenticate(domain, token);
|
||||
|
||||
if (ctx.callbacks?.user) {
|
||||
user = await ctx.callbacks.user(address);
|
||||
}
|
||||
|
||||
user = { ...user, address };
|
||||
} catch {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
|
||||
req.user = user as ThirdwebAuthUser | null;
|
||||
next();
|
||||
});
|
||||
|
||||
app.get(`${authUrl}/:route`, (req: Request, res: Response) => {
|
||||
const action = req.params.route as ThirdwebAuthRoute;
|
||||
|
||||
switch (action) {
|
||||
case "login":
|
||||
return loginHandler(req, res, ctx);
|
||||
case "user":
|
||||
return userHandler(req, res);
|
||||
case "logout":
|
||||
return logoutHandler(req, res);
|
||||
default:
|
||||
return res.status(400).json({
|
||||
message: "Invalid route for authentication.",
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1,68 +1 @@
|
||||
import loginHandler from "./routes/login";
|
||||
import logoutHandler from "./routes/logout";
|
||||
import userHandler from "./routes/user";
|
||||
import {
|
||||
ThirdwebAuthConfig,
|
||||
ThirdwebAuthRoute,
|
||||
ThirdwebAuthUser,
|
||||
} from "./types";
|
||||
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
import cookieParser from "cookie-parser";
|
||||
import { Express, NextFunction, Request, Response } from "express";
|
||||
|
||||
export * from "./types";
|
||||
|
||||
export function getUser(req: Request): ThirdwebAuthUser | null {
|
||||
return req.user;
|
||||
}
|
||||
|
||||
export function ThirdwebAuth(app: Express, cfg: ThirdwebAuthConfig) {
|
||||
const ctx = {
|
||||
...cfg,
|
||||
sdk: ThirdwebSDK.fromPrivateKey(cfg.privateKey, "mainnet"),
|
||||
};
|
||||
|
||||
const authUrl = cfg.authUrl?.replace(/\/$/, "") || "/auth";
|
||||
|
||||
app.use(cookieParser());
|
||||
|
||||
app.use(async (req: Request, _: Response, next: NextFunction) => {
|
||||
const { sdk, domain } = ctx;
|
||||
let user = null;
|
||||
const token = req.cookies.thirdweb_auth_token;
|
||||
|
||||
if (token) {
|
||||
try {
|
||||
const address = await sdk.auth.authenticate(domain, token);
|
||||
|
||||
if (ctx.callbacks?.user) {
|
||||
user = await ctx.callbacks.user(address);
|
||||
}
|
||||
|
||||
user = { ...user, address };
|
||||
} catch {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
|
||||
req.user = user as ThirdwebAuthUser | null;
|
||||
next();
|
||||
});
|
||||
|
||||
app.get(`${authUrl}/:route`, (req: Request, res: Response) => {
|
||||
const action = req.params.route as ThirdwebAuthRoute;
|
||||
|
||||
switch (action) {
|
||||
case "login":
|
||||
return loginHandler(req, res, ctx);
|
||||
case "user":
|
||||
return userHandler(req, res);
|
||||
case "logout":
|
||||
return logoutHandler(req, res);
|
||||
default:
|
||||
return res.status(400).json({
|
||||
message: "Invalid route for authentication.",
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
export * from "./evm";
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
import { ThirdwebNextAuthConfig } from "./types";
|
||||
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
import { serialize } from "cookie";
|
||||
import {
|
||||
GetServerSidePropsContext,
|
||||
NextApiRequest,
|
||||
NextApiResponse,
|
||||
} from "next";
|
||||
import NextAuth, {
|
||||
NextAuthOptions,
|
||||
Session,
|
||||
unstable_getServerSession,
|
||||
} from "next-auth";
|
||||
import CredentialsProvider from "next-auth/providers/credentials";
|
||||
|
||||
export function ThirdwebNextAuth(cfg: ThirdwebNextAuthConfig) {
|
||||
const sdk = ThirdwebSDK.fromPrivateKey(cfg.privateKey, "mainnet");
|
||||
|
||||
function ThirdwebProvider(res: GetServerSidePropsContext["res"]) {
|
||||
return CredentialsProvider({
|
||||
name: "ThirdwebAuth",
|
||||
credentials: {
|
||||
payload: {
|
||||
label: "Payload",
|
||||
type: "text",
|
||||
placeholder: "",
|
||||
},
|
||||
},
|
||||
async authorize({ payload }: any) {
|
||||
try {
|
||||
const parsed = JSON.parse(payload);
|
||||
const token = await sdk.auth.generateAuthToken(cfg.domain, parsed);
|
||||
const address = await sdk.auth.authenticate(cfg.domain, token);
|
||||
|
||||
// Securely set httpOnly cookie on request to prevent XSS on frontend
|
||||
// And set path to / to enable thirdweb_auth_token usage on all endpoints
|
||||
res.setHeader(
|
||||
"Set-Cookie",
|
||||
serialize("thirdweb_auth_token", token, {
|
||||
path: "/",
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "strict",
|
||||
}),
|
||||
);
|
||||
|
||||
return { address };
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function nextOptions(
|
||||
req: GetServerSidePropsContext["req"],
|
||||
res: GetServerSidePropsContext["res"],
|
||||
): NextAuthOptions {
|
||||
async function session({
|
||||
session: _session,
|
||||
}: {
|
||||
session: Session;
|
||||
}): Promise<Session> {
|
||||
const token = req.cookies.thirdweb_auth_token || "";
|
||||
try {
|
||||
const address = await sdk.auth.authenticate(cfg.domain, token);
|
||||
_session.user = { ..._session.user, address } as Session["user"];
|
||||
return _session;
|
||||
} catch {
|
||||
return _session;
|
||||
}
|
||||
}
|
||||
|
||||
function signOut() {
|
||||
res.setHeader(
|
||||
"Set-Cookie",
|
||||
serialize("thirdweb_auth_token", "", {
|
||||
path: "/",
|
||||
expires: new Date(Date.now() + 5 * 1000),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
const providers: NextAuthOptions["providers"] = [
|
||||
...cfg.nextOptions.providers,
|
||||
ThirdwebProvider(res),
|
||||
];
|
||||
|
||||
const configSession = cfg.nextOptions.callbacks?.session;
|
||||
const callbacks: NextAuthOptions["callbacks"] = {
|
||||
...cfg.nextOptions.callbacks,
|
||||
session: configSession
|
||||
? async (params) => {
|
||||
params.session = await session(params);
|
||||
return configSession(params);
|
||||
}
|
||||
: session,
|
||||
};
|
||||
|
||||
const configSignOut = cfg.nextOptions.events?.signOut;
|
||||
const events: NextAuthOptions["events"] = {
|
||||
...cfg.nextOptions.events,
|
||||
signOut: configSignOut
|
||||
? async (params) => {
|
||||
signOut();
|
||||
return configSignOut(params);
|
||||
}
|
||||
: signOut,
|
||||
};
|
||||
|
||||
return {
|
||||
...cfg.nextOptions,
|
||||
providers,
|
||||
callbacks,
|
||||
events,
|
||||
};
|
||||
}
|
||||
|
||||
async function getUser(
|
||||
...args:
|
||||
| [NextApiRequest, NextApiResponse]
|
||||
| [GetServerSidePropsContext["req"], GetServerSidePropsContext["res"]]
|
||||
) {
|
||||
return unstable_getServerSession(
|
||||
args[0],
|
||||
args[1],
|
||||
nextOptions(args[0], args[1]),
|
||||
);
|
||||
}
|
||||
|
||||
function NextAuthHandler(...args: [] | [NextApiRequest, NextApiResponse]) {
|
||||
if (args.length === 0) {
|
||||
return (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return NextAuth(req, res, nextOptions(req, res));
|
||||
};
|
||||
}
|
||||
|
||||
return NextAuth(args[0], args[1], nextOptions(args[0], args[1]));
|
||||
}
|
||||
|
||||
return {
|
||||
NextAuthHandler,
|
||||
getUser,
|
||||
};
|
||||
}
|
||||
@@ -1,145 +1 @@
|
||||
import { ThirdwebNextAuthConfig } from "./types";
|
||||
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
import { serialize } from "cookie";
|
||||
import {
|
||||
GetServerSidePropsContext,
|
||||
NextApiRequest,
|
||||
NextApiResponse,
|
||||
} from "next";
|
||||
import NextAuth, {
|
||||
NextAuthOptions,
|
||||
Session,
|
||||
unstable_getServerSession,
|
||||
} from "next-auth";
|
||||
import CredentialsProvider from "next-auth/providers/credentials";
|
||||
|
||||
export function ThirdwebNextAuth(cfg: ThirdwebNextAuthConfig) {
|
||||
const sdk = ThirdwebSDK.fromPrivateKey(cfg.privateKey, "mainnet");
|
||||
|
||||
function ThirdwebProvider(res: GetServerSidePropsContext["res"]) {
|
||||
return CredentialsProvider({
|
||||
name: "ThirdwebAuth",
|
||||
credentials: {
|
||||
payload: {
|
||||
label: "Payload",
|
||||
type: "text",
|
||||
placeholder: "",
|
||||
},
|
||||
},
|
||||
async authorize({ payload }: any) {
|
||||
try {
|
||||
const parsed = JSON.parse(payload);
|
||||
const token = await sdk.auth.generateAuthToken(cfg.domain, parsed);
|
||||
const address = await sdk.auth.authenticate(cfg.domain, token);
|
||||
|
||||
// Securely set httpOnly cookie on request to prevent XSS on frontend
|
||||
// And set path to / to enable thirdweb_auth_token usage on all endpoints
|
||||
res.setHeader(
|
||||
"Set-Cookie",
|
||||
serialize("thirdweb_auth_token", token, {
|
||||
path: "/",
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "strict",
|
||||
}),
|
||||
);
|
||||
|
||||
return { address };
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function nextOptions(
|
||||
req: GetServerSidePropsContext["req"],
|
||||
res: GetServerSidePropsContext["res"],
|
||||
): NextAuthOptions {
|
||||
async function session({
|
||||
session: _session,
|
||||
}: {
|
||||
session: Session;
|
||||
}): Promise<Session> {
|
||||
const token = req.cookies.thirdweb_auth_token || "";
|
||||
try {
|
||||
const address = await sdk.auth.authenticate(cfg.domain, token);
|
||||
_session.user = { ..._session.user, address } as Session["user"];
|
||||
return _session;
|
||||
} catch {
|
||||
return _session;
|
||||
}
|
||||
}
|
||||
|
||||
function signOut() {
|
||||
res.setHeader(
|
||||
"Set-Cookie",
|
||||
serialize("thirdweb_auth_token", "", {
|
||||
path: "/",
|
||||
expires: new Date(Date.now() + 5 * 1000),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
const providers: NextAuthOptions["providers"] = [
|
||||
...cfg.nextOptions.providers,
|
||||
ThirdwebProvider(res),
|
||||
];
|
||||
|
||||
const configSession = cfg.nextOptions.callbacks?.session;
|
||||
const callbacks: NextAuthOptions["callbacks"] = {
|
||||
...cfg.nextOptions.callbacks,
|
||||
session: configSession
|
||||
? async (params) => {
|
||||
params.session = await session(params);
|
||||
return configSession(params);
|
||||
}
|
||||
: session,
|
||||
};
|
||||
|
||||
const configSignOut = cfg.nextOptions.events?.signOut;
|
||||
const events: NextAuthOptions["events"] = {
|
||||
...cfg.nextOptions.events,
|
||||
signOut: configSignOut
|
||||
? async (params) => {
|
||||
signOut();
|
||||
return configSignOut(params);
|
||||
}
|
||||
: signOut,
|
||||
};
|
||||
|
||||
return {
|
||||
...cfg.nextOptions,
|
||||
providers,
|
||||
callbacks,
|
||||
events,
|
||||
};
|
||||
}
|
||||
|
||||
async function getUser(
|
||||
...args:
|
||||
| [NextApiRequest, NextApiResponse]
|
||||
| [GetServerSidePropsContext["req"], GetServerSidePropsContext["res"]]
|
||||
) {
|
||||
return unstable_getServerSession(
|
||||
args[0],
|
||||
args[1],
|
||||
nextOptions(args[0], args[1]),
|
||||
);
|
||||
}
|
||||
|
||||
function NextAuthHandler(...args: [] | [NextApiRequest, NextApiResponse]) {
|
||||
if (args.length === 0) {
|
||||
return (req: NextApiRequest, res: NextApiResponse) => {
|
||||
return NextAuth(req, res, nextOptions(req, res));
|
||||
};
|
||||
}
|
||||
|
||||
return NextAuth(args[0], args[1], nextOptions(args[0], args[1]));
|
||||
}
|
||||
|
||||
return {
|
||||
NextAuthHandler,
|
||||
getUser,
|
||||
};
|
||||
}
|
||||
export * from "./evm";
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import loginHandler from "./routes/login";
|
||||
import logoutHandler from "./routes/logout";
|
||||
import userHandler from "./routes/user";
|
||||
import {
|
||||
ThirdwebAuthConfig,
|
||||
ThirdwebAuthContext,
|
||||
ThirdwebAuthRoute,
|
||||
ThirdwebAuthUser,
|
||||
} from "./types";
|
||||
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
import { NextRequest } from "next/server";
|
||||
import {
|
||||
GetServerSidePropsContext,
|
||||
NextApiRequest,
|
||||
NextApiResponse,
|
||||
} from "next/types";
|
||||
|
||||
export * from "./types";
|
||||
|
||||
async function ThirdwebAuthRouter(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
ctx: ThirdwebAuthContext,
|
||||
) {
|
||||
// Catch-all route must be named with [...thirdweb]
|
||||
const { thirdweb } = req.query;
|
||||
const action = thirdweb?.[0] as ThirdwebAuthRoute;
|
||||
|
||||
switch (action) {
|
||||
case "login":
|
||||
return await loginHandler(req, res, ctx);
|
||||
case "user":
|
||||
return await userHandler(req, res, ctx);
|
||||
case "logout":
|
||||
return await logoutHandler(req, res);
|
||||
default:
|
||||
return res.status(400).json({
|
||||
message: "Invalid route for authentication.",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function ThirdwebAuth(cfg: ThirdwebAuthConfig) {
|
||||
const ctx = {
|
||||
...cfg,
|
||||
sdk: ThirdwebSDK.fromPrivateKey(cfg.privateKey, "mainnet"),
|
||||
};
|
||||
|
||||
function ThirdwebAuthHandler(
|
||||
...args: [] | [NextApiRequest, NextApiResponse]
|
||||
) {
|
||||
if (args.length === 0) {
|
||||
return async (req: NextApiRequest, res: NextApiResponse) =>
|
||||
await ThirdwebAuthRouter(req, res, ctx);
|
||||
}
|
||||
|
||||
return ThirdwebAuthRouter(args[0], args[1], ctx);
|
||||
}
|
||||
|
||||
async function getUser(
|
||||
req: GetServerSidePropsContext["req"] | NextRequest | NextApiRequest,
|
||||
) {
|
||||
const { sdk, domain } = ctx;
|
||||
let user: ThirdwebAuthUser | null = null;
|
||||
const token =
|
||||
typeof req.cookies.get === "function"
|
||||
? (req.cookies as any).get("thirdweb_auth_token")
|
||||
: (req.cookies as any).thirdweb_auth_token;
|
||||
|
||||
if (token) {
|
||||
try {
|
||||
const address = await sdk.auth.authenticate(domain, token);
|
||||
user = { address };
|
||||
} catch {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
return { ThirdwebAuthHandler, getUser };
|
||||
}
|
||||
@@ -1,83 +1 @@
|
||||
import loginHandler from "./routes/login";
|
||||
import logoutHandler from "./routes/logout";
|
||||
import userHandler from "./routes/user";
|
||||
import {
|
||||
ThirdwebAuthConfig,
|
||||
ThirdwebAuthContext,
|
||||
ThirdwebAuthRoute,
|
||||
ThirdwebAuthUser,
|
||||
} from "./types";
|
||||
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
import { NextRequest } from "next/server";
|
||||
import {
|
||||
GetServerSidePropsContext,
|
||||
NextApiRequest,
|
||||
NextApiResponse,
|
||||
} from "next/types";
|
||||
|
||||
export * from "./types";
|
||||
|
||||
async function ThirdwebAuthRouter(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
ctx: ThirdwebAuthContext,
|
||||
) {
|
||||
// Catch-all route must be named with [...thirdweb]
|
||||
const { thirdweb } = req.query;
|
||||
const action = thirdweb?.[0] as ThirdwebAuthRoute;
|
||||
|
||||
switch (action) {
|
||||
case "login":
|
||||
return await loginHandler(req, res, ctx);
|
||||
case "user":
|
||||
return await userHandler(req, res, ctx);
|
||||
case "logout":
|
||||
return await logoutHandler(req, res);
|
||||
default:
|
||||
return res.status(400).json({
|
||||
message: "Invalid route for authentication.",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function ThirdwebAuth(cfg: ThirdwebAuthConfig) {
|
||||
const ctx = {
|
||||
...cfg,
|
||||
sdk: ThirdwebSDK.fromPrivateKey(cfg.privateKey, "mainnet"),
|
||||
};
|
||||
|
||||
function ThirdwebAuthHandler(
|
||||
...args: [] | [NextApiRequest, NextApiResponse]
|
||||
) {
|
||||
if (args.length === 0) {
|
||||
return async (req: NextApiRequest, res: NextApiResponse) =>
|
||||
await ThirdwebAuthRouter(req, res, ctx);
|
||||
}
|
||||
|
||||
return ThirdwebAuthRouter(args[0], args[1], ctx);
|
||||
}
|
||||
|
||||
async function getUser(
|
||||
req: GetServerSidePropsContext["req"] | NextRequest | NextApiRequest,
|
||||
) {
|
||||
const { sdk, domain } = ctx;
|
||||
let user: ThirdwebAuthUser | null = null;
|
||||
const token =
|
||||
typeof req.cookies.get === "function"
|
||||
? (req.cookies as any).get("thirdweb_auth_token")
|
||||
: (req.cookies as any).thirdweb_auth_token;
|
||||
|
||||
if (token) {
|
||||
try {
|
||||
const address = await sdk.auth.authenticate(domain, token);
|
||||
user = { address };
|
||||
} catch {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
return { ThirdwebAuthHandler, getUser };
|
||||
}
|
||||
export * from "./evm";
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import loginHandler from "./routes/login";
|
||||
import logoutHandler from "./routes/logout";
|
||||
import userHandler from "./routes/user";
|
||||
import {
|
||||
ThirdwebAuthConfig,
|
||||
ThirdwebAuthContext,
|
||||
ThirdwebAuthRoute,
|
||||
ThirdwebAuthUser,
|
||||
} from "./types";
|
||||
import { ThirdwebSDK } from "@thirdweb-dev/sdk/solana";
|
||||
import { NextRequest } from "next/server";
|
||||
import {
|
||||
GetServerSidePropsContext,
|
||||
NextApiRequest,
|
||||
NextApiResponse,
|
||||
} from "next/types";
|
||||
|
||||
export * from "./types";
|
||||
|
||||
async function ThirdwebAuthRouter(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
ctx: ThirdwebAuthContext,
|
||||
) {
|
||||
// Catch-all route must be named with [...thirdweb]
|
||||
const { thirdweb } = req.query;
|
||||
const action = thirdweb?.[0] as ThirdwebAuthRoute;
|
||||
|
||||
switch (action) {
|
||||
case "login":
|
||||
return await loginHandler(req, res, ctx);
|
||||
case "user":
|
||||
return await userHandler(req, res, ctx);
|
||||
case "logout":
|
||||
return await logoutHandler(req, res);
|
||||
default:
|
||||
return res.status(400).json({
|
||||
message: "Invalid route for authentication.",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function ThirdwebAuth(cfg: ThirdwebAuthConfig) {
|
||||
const ctx = {
|
||||
...cfg,
|
||||
sdk: ThirdwebSDK.fromPrivateKey("mainnet-beta", cfg.privateKey),
|
||||
};
|
||||
|
||||
function ThirdwebAuthHandler(
|
||||
...args: [] | [NextApiRequest, NextApiResponse]
|
||||
) {
|
||||
if (args.length === 0) {
|
||||
return async (req: NextApiRequest, res: NextApiResponse) =>
|
||||
await ThirdwebAuthRouter(req, res, ctx);
|
||||
}
|
||||
|
||||
return ThirdwebAuthRouter(args[0], args[1], ctx);
|
||||
}
|
||||
|
||||
async function getUser(
|
||||
req: GetServerSidePropsContext["req"] | NextRequest | NextApiRequest,
|
||||
) {
|
||||
const { sdk, domain } = ctx;
|
||||
let user: ThirdwebAuthUser | null = null;
|
||||
const token =
|
||||
typeof req.cookies.get === "function"
|
||||
? (req.cookies as any).get("thirdweb_auth_token")
|
||||
: (req.cookies as any).thirdweb_auth_token;
|
||||
|
||||
if (token) {
|
||||
try {
|
||||
const address = await sdk.auth.authenticate(domain, token);
|
||||
user = { address };
|
||||
} catch {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
return { ThirdwebAuthHandler, getUser };
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import { ThirdwebAuthContext } from "../types";
|
||||
import { LoginPayload } from "@thirdweb-dev/sdk";
|
||||
import { serialize } from "cookie";
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
function redirectWithError(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
error: string,
|
||||
) {
|
||||
const encodedError = encodeURIComponent(error);
|
||||
const url = new URL(req.headers.referer as string);
|
||||
url.searchParams.set("error", encodedError);
|
||||
return res.redirect(url.toString());
|
||||
}
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
ctx: ThirdwebAuthContext,
|
||||
) {
|
||||
if (req.method !== "GET") {
|
||||
return redirectWithError(req, res, "INVALID_METHOD");
|
||||
}
|
||||
|
||||
const { sdk, domain } = ctx;
|
||||
|
||||
// Get signed login payload from the frontend
|
||||
const payload = JSON.parse(atob(req.query.payload as string)) as LoginPayload;
|
||||
if (!payload) {
|
||||
redirectWithError(req, res, "MISSING_LOGIN_PAYLOAD");
|
||||
}
|
||||
|
||||
let token;
|
||||
try {
|
||||
// Generate an access token with the SDK using the signed payload
|
||||
token = await sdk.auth.generateAuthToken(domain, payload);
|
||||
} catch {
|
||||
return redirectWithError(req, res, "INVALID_LOGIN_PAYLOAD");
|
||||
}
|
||||
|
||||
// Securely set httpOnly cookie on request to prevent XSS on frontend
|
||||
// And set path to / to enable thirdweb_auth_token usage on all endpoints
|
||||
res.setHeader(
|
||||
"Set-Cookie",
|
||||
serialize("thirdweb_auth_token", token, {
|
||||
path: "/",
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "strict",
|
||||
}),
|
||||
);
|
||||
|
||||
if (ctx.callbacks?.login) {
|
||||
const address = sdk.auth.verify(domain, payload);
|
||||
await ctx.callbacks.login(address);
|
||||
}
|
||||
|
||||
return res.status(301).redirect(req.query.redirect as string);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { serialize } from "cookie";
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
) {
|
||||
if (req.method !== "GET") {
|
||||
return res.status(400).json({
|
||||
error: "Invalid method. Only GET supported.",
|
||||
});
|
||||
}
|
||||
|
||||
// Set the access token to 'none' and expire in 5 seconds
|
||||
res.setHeader(
|
||||
"Set-Cookie",
|
||||
serialize("thirdweb_auth_token", "", {
|
||||
path: "/",
|
||||
expires: new Date(Date.now() + 5 * 1000),
|
||||
}),
|
||||
);
|
||||
|
||||
return res.status(301).redirect(req.headers.referer as string);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { ThirdwebAuthContext, ThirdwebAuthUser } from "../types";
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
ctx: ThirdwebAuthContext,
|
||||
) {
|
||||
if (req.method !== "GET") {
|
||||
return res.status(400).json({
|
||||
error: "Invalid method. Only GET supported.",
|
||||
});
|
||||
}
|
||||
|
||||
const { sdk, domain } = ctx;
|
||||
let user = null;
|
||||
const token = req.cookies.thirdweb_auth_token;
|
||||
|
||||
if (token) {
|
||||
try {
|
||||
const address = await sdk.auth.authenticate(domain, token);
|
||||
|
||||
if (ctx.callbacks?.user) {
|
||||
user = await ctx.callbacks.user(address);
|
||||
}
|
||||
|
||||
user = { ...user, address };
|
||||
} catch {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
|
||||
return res.status(200).json(user as ThirdwebAuthUser | null);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { ThirdwebSDK } from "@thirdweb-dev/sdk/solana";
|
||||
|
||||
export type ThirdwebAuthRoute = "login" | "logout" | "user";
|
||||
|
||||
export type ThirdwebAuthConfig = {
|
||||
privateKey: string;
|
||||
domain: string;
|
||||
callbacks?: {
|
||||
login?: (address: string) => Promise<void> | void;
|
||||
user?: (
|
||||
address: string,
|
||||
) =>
|
||||
| Promise<Omit<ThirdwebAuthUser, "address">>
|
||||
| Omit<ThirdwebAuthUser, "address">;
|
||||
};
|
||||
};
|
||||
|
||||
export type ThirdwebAuthContext = {
|
||||
sdk: ThirdwebSDK;
|
||||
domain: string;
|
||||
callbacks?: {
|
||||
login?: (address: string) => Promise<void> | void;
|
||||
user?: (
|
||||
address: string,
|
||||
) =>
|
||||
| Promise<Omit<ThirdwebAuthUser, "address">>
|
||||
| Omit<ThirdwebAuthUser, "address">;
|
||||
};
|
||||
};
|
||||
|
||||
export type ThirdwebAuthUser = {
|
||||
address: string;
|
||||
[key: string]: any;
|
||||
};
|
||||
@@ -1,5 +1,22 @@
|
||||
# thirdweb
|
||||
|
||||
## 0.8.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#276](https://github.com/thirdweb-dev/js/pull/276) [`24514a6`](https://github.com/thirdweb-dev/js/commit/24514a6e9fc1316622c1494e5be225e53f88d26e) Thanks [@furqanrydhan](https://github.com/furqanrydhan)! - build is now default compile command, reorganized the help list
|
||||
|
||||
- [#279](https://github.com/thirdweb-dev/js/pull/279) [`1918495`](https://github.com/thirdweb-dev/js/commit/1918495f2ee7f50d94083d9577dab0bf1c828c94) Thanks [@furqanrydhan](https://github.com/furqanrydhan)! - Updating command list order, helper text and changed detect -> build
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#277](https://github.com/thirdweb-dev/js/pull/277) [`9de3f8c`](https://github.com/thirdweb-dev/js/commit/9de3f8c8e954733bfc3eb6e8e0e786ff5b296f0c) Thanks [@adam-maj](https://github.com/adam-maj)! - Add recursive folder upload support
|
||||
|
||||
- [#268](https://github.com/thirdweb-dev/js/pull/268) [`57b9c67`](https://github.com/thirdweb-dev/js/commit/57b9c671aaf7fce0076dd332c171ba6944752e7a) Thanks [@adam-maj](https://github.com/adam-maj)! - Update storage upload cLI
|
||||
|
||||
- Updated dependencies [[`521a49c`](https://github.com/thirdweb-dev/js/commit/521a49c6ec6a73068adcfbc1d94d2f3f17afae86), [`8b3b97c`](https://github.com/thirdweb-dev/js/commit/8b3b97c8f7b3710ce62ed86cfeb4f6de3c23d559), [`25a4773`](https://github.com/thirdweb-dev/js/commit/25a4773bba406f4e270ac86e68c5266d24c08330), [`b2cadf1`](https://github.com/thirdweb-dev/js/commit/b2cadf164cfe9fb27081df7530356baf70ec2b3a), [`d6bb61b`](https://github.com/thirdweb-dev/js/commit/d6bb61b7fac759fff7d6293edd46f693f5a7889c), [`78d6d3c`](https://github.com/thirdweb-dev/js/commit/78d6d3c15968a449924b3f24354e151a90e4b20d), [`89d87a5`](https://github.com/thirdweb-dev/js/commit/89d87a5eb31e78e68e097718e9ae6e4c4d101868), [`41507d3`](https://github.com/thirdweb-dev/js/commit/41507d32a78c556f50c88de81c4d6109b1783c78), [`8096c78`](https://github.com/thirdweb-dev/js/commit/8096c78b466a7f5f9c2aac6e2c56a06f9d3a25d6), [`b1fa171`](https://github.com/thirdweb-dev/js/commit/b1fa17158dcac00265bc8f4d64f1f9708482cdb5), [`18381fa`](https://github.com/thirdweb-dev/js/commit/18381fac73741826934212ac6441842ed42a64a0), [`df048af`](https://github.com/thirdweb-dev/js/commit/df048af605f449279b01d7352b604e7856ac223c), [`d6bb61b`](https://github.com/thirdweb-dev/js/commit/d6bb61b7fac759fff7d6293edd46f693f5a7889c), [`cf88795`](https://github.com/thirdweb-dev/js/commit/cf88795376d3110f9d3aa839928d22276904b15a), [`89b5c6f`](https://github.com/thirdweb-dev/js/commit/89b5c6fe079e4df2cf12cb557aa9784f88c5d159)]:
|
||||
- @thirdweb-dev/sdk@3.2.2
|
||||
|
||||
## 0.7.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "thirdweb",
|
||||
"main": "dist/cli/index.js",
|
||||
"version": "0.7.24",
|
||||
"version": "0.8.0",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env node
|
||||
import { installGithubAction } from "../common/ci-installer";
|
||||
import { detectExtensions } from "../common/feature-detector";
|
||||
import { processProject } from "../common/processor";
|
||||
import { cliVersion, pkg } from "../constants/urls";
|
||||
@@ -43,10 +42,10 @@ $$$$$$\\ $$$$$$$\\ $$\\ $$$$$$\\ $$$$$$$ |$$\\ $$\\ $$\\ $$$$$$\\ $$$$
|
||||
program
|
||||
.command("create")
|
||||
.description(
|
||||
"Create a thirdweb app from any of our official templates. Checkout some examples you can use here: https://github.com/thirdweb-example/",
|
||||
"Create a web3 app from any of our official templates: https://github.com/thirdweb-example/",
|
||||
)
|
||||
.option("--app", `Create a thirdweb app.`)
|
||||
.option("--contract", `Create a thirdweb contracts project.`)
|
||||
.option("--app", `Create a web3 app.`)
|
||||
.option("--contract", `Create a web3 contract project`)
|
||||
.option("--ts, --typescript", `Initialize as a TypeScript project.`)
|
||||
.option("--js, --javascript", `Initialize as a JavaScript project.`)
|
||||
.option("--forge", `Initialize as a Forge project.`)
|
||||
@@ -71,11 +70,19 @@ $$$$$$\\ $$$$$$$\\ $$\\ $$$$$$\\ $$$$$$$ |$$\\ $$\\ $$\\ $$$$$$\\ $$$$
|
||||
await twCreate(options);
|
||||
});
|
||||
|
||||
program
|
||||
.command("build")
|
||||
.description("Compile contract and detect thirdweb contract extensions")
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option("-d, --debug", "show debug logs")
|
||||
.option("-a, --all", "run detection on all contracts")
|
||||
.action(async (options) => {
|
||||
await detectExtensions(options);
|
||||
});
|
||||
|
||||
program
|
||||
.command("deploy")
|
||||
.description(
|
||||
"Deploy contracts through your thirdweb dashboard, without dealing with private keys.",
|
||||
)
|
||||
.description("Deploy your (or team) contracts securely to blockchains")
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option("--dry-run", "dry run (skip actually publishing)")
|
||||
.option("-d, --debug", "show debug logs")
|
||||
@@ -118,7 +125,7 @@ $$$$$$\\ $$$$$$$\\ $$\\ $$$$$$\\ $$$$$$$ |$$\\ $$\\ $$\\ $$$$$$\\ $$$$
|
||||
program
|
||||
.command("release")
|
||||
.description(
|
||||
"Release contracts, making them available for others to deploy and unlocking SDKs, Dashboards and Analytics.",
|
||||
"Release your protocol so other devs can deploy them and unlock SDKs, Dashboards and Analytics",
|
||||
)
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option("--dry-run", "dry run (skip actually publishing)")
|
||||
@@ -131,22 +138,10 @@ $$$$$$\\ $$$$$$$\\ $$\\ $$$$$$\\ $$$$$$$ |$$\\ $$\\ $$\\ $$$$$$\\ $$$$
|
||||
open(url.toString());
|
||||
});
|
||||
|
||||
program
|
||||
.command("detect")
|
||||
.description(
|
||||
"Compile contracts and detect implemented thirdweb contract extensions",
|
||||
)
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option("-d, --debug", "show debug logs")
|
||||
.option("-a, --all", "run detection on all contracts")
|
||||
.action(async (options) => {
|
||||
await detectExtensions(options);
|
||||
});
|
||||
|
||||
program
|
||||
.command("upload")
|
||||
.description("Upload any file or directory using decentralized storage")
|
||||
.argument("<upload-path>", "path to file or directory to upload")
|
||||
.description("Upload any file or directory to decentralized storage (IPFS)")
|
||||
.argument("[upload]", "path to file or directory to upload")
|
||||
.action(async (path) => {
|
||||
const storage = new ThirdwebStorage();
|
||||
const uri = await upload(storage, path);
|
||||
@@ -159,12 +154,15 @@ $$$$$$\\ $$$$$$$\\ $$\\ $$$$$$\\ $$$$$$$ |$$\\ $$\\ $$\\ $$$$$$\\ $$$$
|
||||
});
|
||||
|
||||
program
|
||||
.command("install-ci")
|
||||
.command("detect")
|
||||
.description(
|
||||
"(alpha) Set up continuous integration for your contracts. This adds a github action to deploy the project on pull requests and pushes to branches. Publishes on push the the main branch.",
|
||||
"(deprecated) Compile contracts and detect implemented thirdweb contract extensions",
|
||||
)
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option("-d, --debug", "show debug logs")
|
||||
.option("-a, --all", "run detection on all contracts")
|
||||
.action(async (options) => {
|
||||
await installGithubAction(options);
|
||||
await detectExtensions(options);
|
||||
});
|
||||
|
||||
await program.parseAsync();
|
||||
|
||||
@@ -1,14 +1,46 @@
|
||||
import { logger } from "../core/helpers/logger";
|
||||
import { spinner } from "../core/helpers/logger";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import { BufferOrStringWithName, ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import chalk from "chalk";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
function recurseFiles(
|
||||
uploadPath: string,
|
||||
basePath: string,
|
||||
): BufferOrStringWithName[] {
|
||||
const files = [];
|
||||
|
||||
const fileType = fs.lstatSync(uploadPath);
|
||||
if (fileType.isFile()) {
|
||||
const fileName = path.relative(basePath, uploadPath);
|
||||
const fileData = fs.readFileSync(uploadPath);
|
||||
files.push({ name: fileName, data: fileData });
|
||||
} else if (fileType.isDirectory()) {
|
||||
const paths = fs.readdirSync(uploadPath);
|
||||
paths.forEach((subPath) => {
|
||||
const fullSubPath = path.join(uploadPath, subPath);
|
||||
const subFiles = recurseFiles(fullSubPath, basePath);
|
||||
subFiles.forEach((file) => files.push(file));
|
||||
});
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
export async function upload(
|
||||
storage: ThirdwebStorage,
|
||||
uploadPath: string,
|
||||
): Promise<string> {
|
||||
if (!uploadPath) {
|
||||
logger.error(
|
||||
`Please pass a path to a file or directory to upload with the following format:\n ${chalk.blueBright(
|
||||
`npx thirdweb@latest upload path/to/file.jpg`,
|
||||
)}\n`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const pathExists = fs.existsSync(uploadPath);
|
||||
if (!pathExists) {
|
||||
logger.error(
|
||||
@@ -22,11 +54,7 @@ export async function upload(
|
||||
let uri = "";
|
||||
const fileType = fs.lstatSync(uploadPath);
|
||||
if (fileType.isDirectory()) {
|
||||
const subPaths = fs.readdirSync(uploadPath);
|
||||
const filePaths = subPaths
|
||||
.map((subPath) => path.join(uploadPath, subPath))
|
||||
.filter((subPath) => fs.lstatSync(subPath).isFile());
|
||||
const files = filePaths.map((filePath) => fs.readFileSync(filePath));
|
||||
const files = recurseFiles(uploadPath, uploadPath);
|
||||
|
||||
if (files.length === 0) {
|
||||
logger.error(
|
||||
@@ -44,11 +72,14 @@ export async function upload(
|
||||
spin.succeed("Successfully uploaded directory to IPFS");
|
||||
uri = uris[0].substring(0, uris[0].lastIndexOf("/"));
|
||||
} else if (fileType.isFile()) {
|
||||
const file = fs.readFileSync(uploadPath);
|
||||
const fileName = path.parse(uploadPath).base;
|
||||
const fileData = fs.readFileSync(uploadPath);
|
||||
const file = { name: fileName, data: fileData };
|
||||
|
||||
const spin = spinner(
|
||||
"Uploading file to IPFS. This may take a while depending on file sizes.",
|
||||
);
|
||||
uri = await storage.upload(file);
|
||||
uri = await storage.upload(file, { uploadWithoutDirectory: true });
|
||||
spin.succeed("Succesfully uploaded file to IPFS.");
|
||||
} else {
|
||||
logger.error(
|
||||
|
||||
@@ -1,5 +1,34 @@
|
||||
# @thirdweb-dev/react
|
||||
|
||||
## 3.2.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#289](https://github.com/thirdweb-dev/js/pull/289) [`521a49c`](https://github.com/thirdweb-dev/js/commit/521a49c6ec6a73068adcfbc1d94d2f3f17afae86) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - Standarize useClaimNFT to evm
|
||||
|
||||
- [#274](https://github.com/thirdweb-dev/js/pull/274) [`ad06c5b`](https://github.com/thirdweb-dev/js/commit/ad06c5b28902422f9b416d65255c64c937a5e046) Thanks [@adam-maj](https://github.com/adam-maj)! - Add solana auth support and plugins for react and auth package
|
||||
|
||||
- [#269](https://github.com/thirdweb-dev/js/pull/269) [`b2cadf1`](https://github.com/thirdweb-dev/js/commit/b2cadf164cfe9fb27081df7530356baf70ec2b3a) Thanks [@jnsdls](https://github.com/jnsdls)! - [EVM] - remove deprecated chains from support
|
||||
|
||||
- [#272](https://github.com/thirdweb-dev/js/pull/272) [`2bdf198`](https://github.com/thirdweb-dev/js/commit/2bdf1984cb97121c447cffd27aa6a5f4f92679b3) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - Add claim conditions hook for Solana
|
||||
|
||||
- [#291](https://github.com/thirdweb-dev/js/pull/291) [`86f6083`](https://github.com/thirdweb-dev/js/commit/86f608390a7848cda82c0f7e8913ca60f7d3901f) Thanks [@jnsdls](https://github.com/jnsdls)! - [SOL] - expose `.program` on `useProgram()` return type to mirror `.contract` on EVM
|
||||
|
||||
- [#292](https://github.com/thirdweb-dev/js/pull/292) [`492a818`](https://github.com/thirdweb-dev/js/commit/492a818079aff67c7f88bc43666c87c3714cc957) Thanks [@jnsdls](https://github.com/jnsdls)! - [SOL] expose `useAddress()` hook that returns the connected wallet address in base58
|
||||
|
||||
- [#290](https://github.com/thirdweb-dev/js/pull/290) [`8096c78`](https://github.com/thirdweb-dev/js/commit/8096c78b466a7f5f9c2aac6e2c56a06f9d3a25d6) Thanks [@jnsdls](https://github.com/jnsdls)! - [SOL] - `useClaimNFT()` allow claiming to connected wallet without passing address explicitly
|
||||
[EVM] - `useClaimNFT()` allow claiming to connected wallet without passing address explicitly
|
||||
|
||||
- [#298](https://github.com/thirdweb-dev/js/pull/298) [`e8c25ed`](https://github.com/thirdweb-dev/js/commit/e8c25ed0f28d566203d70bf59a8908e59216334a) Thanks [@jnsdls](https://github.com/jnsdls)! - [SOL] - fix useBalance
|
||||
|
||||
- [#263](https://github.com/thirdweb-dev/js/pull/263) [`d6bb61b`](https://github.com/thirdweb-dev/js/commit/d6bb61b7fac759fff7d6293edd46f693f5a7889c) Thanks [@jnsdls](https://github.com/jnsdls)! - [EVM] - add chainId getter on contracts
|
||||
|
||||
- [#266](https://github.com/thirdweb-dev/js/pull/266) [`3b7d10e`](https://github.com/thirdweb-dev/js/commit/3b7d10ed93d8e3b698e9f905c93ba79863b35325) Thanks [@adam-maj](https://github.com/adam-maj)! - Add storage hooks to react
|
||||
|
||||
- [#282](https://github.com/thirdweb-dev/js/pull/282) [`1f41adb`](https://github.com/thirdweb-dev/js/commit/1f41adbd2ccfbc367757620e0842ef32bc783a08) Thanks [@jarrodwatts](https://github.com/jarrodwatts)! - Fix useActiveClaimCondition invariant failing for token ID 0
|
||||
|
||||
- [#296](https://github.com/thirdweb-dev/js/pull/296) [`cf88795`](https://github.com/thirdweb-dev/js/commit/cf88795376d3110f9d3aa839928d22276904b15a) Thanks [@jnsdls](https://github.com/jnsdls)! - [SOL] - add `useBalance` hook
|
||||
|
||||
## 3.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -71,7 +71,7 @@ Below are examples of where to set this up in your application:
|
||||
|
||||
### Connect to a User's Wallet
|
||||
|
||||
Now the provider is set up, we can use all of the hooks and UI components available in the SDK, such as the [ConnectWallet](https://portal.thirdweb.com/sdk/ui-components/connectwalletbutton) component.
|
||||
Now the provider is set up, we can use all of the hooks and UI components available in the SDK, such as the [ConnectWallet](https://portal.thirdweb.com/ui-components/connectwalletbutton) component.
|
||||
|
||||
Once the user has connected their wallet, all the calls we make to interact with contracts using the SDK will be on behalf of the user.
|
||||
|
||||
@@ -143,7 +143,7 @@ Each [extension](https://portal.thirdweb.com/extensions) you implement in your s
|
||||
|
||||
These hooks make it easy to interact with your smart contracts by implementing the complex logic for you under the hood.
|
||||
|
||||
For example, if your smart contract implements [ERC721Supply](https://portal.thirdweb.com/extensions/erc721supply#unlocked-features), you unlock the ability to [view all NFTs](https://portal.thirdweb.com/sdk/interacting-with-contracts/erc721supply#get-all-minted-nfts) on that contract using the SDK; which fetches all of your NFT metadata and the current owner of each NFT in parallel. In the React SDK, that is available using `useNFTs`:
|
||||
For example, if your smart contract implements [ERC721Supply](https://portal.thirdweb.com/contractkit/interfaces/erc721supply#unlocked-features), you unlock the ability to [view all NFTs](https://portal.thirdweb.com/sdk/interacting-with-contracts/erc721supply#get-all-minted-nfts) on that contract using the SDK; which fetches all of your NFT metadata and the current owner of each NFT in parallel. In the React SDK, that is available using `useNFTs`:
|
||||
|
||||
```jsx
|
||||
import { useContract, useNFTs } from "@thirdweb-dev/react";
|
||||
@@ -154,7 +154,7 @@ export default function Home() {
|
||||
}
|
||||
```
|
||||
|
||||
If we want to mint an NFT and our contract implements [ERC721Mintable](https://portal.thirdweb.com/extensions/erc721mintable#unlocked-features), we can use the [`useMintNFT`](https://portal.thirdweb.com/sdk/interacting-with-contracts/erc721mintable) hook to mint an NFT from the connected wallet; handling all of the logic of uploading and pinning the metadata to IPFS for us behind the scenes.
|
||||
If we want to mint an NFT and our contract implements [ERC721Mintable](https://portal.thirdweb.com/contractkit/interfaces/erc721mintable#unlocked-features), we can use the [`useMintNFT`](https://portal.thirdweb.com/sdk/interacting-with-contracts/erc721mintable) hook to mint an NFT from the connected wallet; handling all of the logic of uploading and pinning the metadata to IPFS for us behind the scenes.
|
||||
|
||||
```jsx
|
||||
import { useContract, useNFTs, useMintNFT } from "@thirdweb-dev/react";
|
||||
@@ -172,7 +172,7 @@ export default function Home() {
|
||||
|
||||
The SDK provides many UI components to help you build your application.
|
||||
|
||||
For example, we can render each of the NFTs using the [`NFT Media Renderer`](https://portal.thirdweb.com/sdk/ui-components/nft-renderer)
|
||||
For example, we can render each of the NFTs using the [`NFT Media Renderer`](https://portal.thirdweb.com/ui-components/nft-renderer)
|
||||
component, making use of the loading state from `useNFTs`:
|
||||
|
||||
```jsx title="pages/index.jsx"
|
||||
@@ -203,7 +203,7 @@ export default function Home() {
|
||||
}
|
||||
```
|
||||
|
||||
The [`Web3Button`](https://portal.thirdweb.com/sdk/ui-components/web3button) component ensures the user has connected their wallet and is currently configured to the same network as your smart contract before calling the function. It also has access to the `contract` directly, allowing you to perform any action on your smart contract when the button is clicked.
|
||||
The [`Web3Button`](https://portal.thirdweb.com/ui-components/web3button) component ensures the user has connected their wallet and is currently configured to the same network as your smart contract before calling the function. It also has access to the `contract` directly, allowing you to perform any action on your smart contract when the button is clicked.
|
||||
|
||||
For example, we can mint an NFT like so:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react",
|
||||
"version": "3.2.1",
|
||||
"version": "3.2.2",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -70,7 +70,7 @@ function parseExampleTag(docComment) {
|
||||
return examples;
|
||||
}
|
||||
|
||||
const baseDocUrl = "https://portal.thirdweb.com/react/react.";
|
||||
const baseDocUrl = "https://portal.thirdweb.com/react/solana/react.";
|
||||
|
||||
const extractReferenceLink = (m, kind, contractName) => {
|
||||
if (kind === "Property") {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { RequiredParam } from "../types/shared";
|
||||
import { QueryKey } from "@tanstack/react-query";
|
||||
import type { ChainId } from "@thirdweb-dev/sdk";
|
||||
import type { QueryKey } from "@tanstack/react-query";
|
||||
import type { ValidContractInstance } from "@thirdweb-dev/sdk";
|
||||
import type {
|
||||
Network,
|
||||
NFTCollection,
|
||||
@@ -13,7 +13,7 @@ const TW_QUERY_KEY_PREFIX = "__tw__";
|
||||
// marker to make sure the query will not get stored in local storage by a query persister
|
||||
const NEVER_PERSIST_QUERY_POSTFIX = { persist: false } as const;
|
||||
|
||||
function ensureTWPrefix<TKey extends QueryKey>(key: TKey) {
|
||||
export function ensureTWPrefix<TKey extends QueryKey>(key: TKey) {
|
||||
if (key[0] === TW_QUERY_KEY_PREFIX) {
|
||||
return key as unknown as Readonly<[typeof TW_QUERY_KEY_PREFIX, ...TKey]>;
|
||||
}
|
||||
@@ -37,11 +37,23 @@ export function createEVMQueryKey<TKey extends QueryKey>(key: TKey) {
|
||||
}
|
||||
export function createEVMQueryKeyWithChain<TKey extends QueryKey>(
|
||||
key: TKey,
|
||||
chainId: RequiredParam<ChainId>,
|
||||
chainId: RequiredParam<number>,
|
||||
) {
|
||||
return ensureTWPrefix([chainId, ...key] as const);
|
||||
}
|
||||
|
||||
export function createEVMContractQueryKey<TKey extends QueryKey>(
|
||||
contract: RequiredParam<ValidContractInstance>,
|
||||
key: TKey = [] as unknown as TKey,
|
||||
) {
|
||||
const chainId = contract?.chainId;
|
||||
const address = contract?.getAddress();
|
||||
return createEVMQueryKeyWithChain(
|
||||
["contract", address, ...key] as const,
|
||||
chainId,
|
||||
);
|
||||
}
|
||||
|
||||
// SOL
|
||||
|
||||
export function createSOLQueryKey<TKey extends QueryKey>(key: TKey) {
|
||||
|
||||
@@ -76,10 +76,8 @@ const chainIdToCurrencyMap: Record<
|
||||
> = {
|
||||
[ChainId.Mainnet]: "ethereum",
|
||||
[ChainId.Goerli]: "ethereum",
|
||||
[ChainId.Rinkeby]: "ethereum",
|
||||
|
||||
[ChainId.Arbitrum]: "arbitrum",
|
||||
[ChainId.ArbitrumRinkeby]: "arbitrum",
|
||||
[ChainId.ArbitrumGoerli]: "arbitrum",
|
||||
|
||||
[ChainId.Avalanche]: "avalanche",
|
||||
@@ -89,7 +87,6 @@ const chainIdToCurrencyMap: Record<
|
||||
[ChainId.FantomTestnet]: "fantom",
|
||||
|
||||
[ChainId.Optimism]: "optimism",
|
||||
[ChainId.OptimismKovan]: "optimism",
|
||||
[ChainId.OptimismGoerli]: "optimism",
|
||||
|
||||
[ChainId.Polygon]: "polygon",
|
||||
|
||||
@@ -8,7 +8,6 @@ const CHAIN_ID_TO_GNOSIS_SERVER_URL = {
|
||||
[ChainId.Avalanche]: "https://safe-transaction.avalanche.gnosis.io",
|
||||
[ChainId.Polygon]: "https://safe-transaction.polygon.gnosis.io",
|
||||
[ChainId.Goerli]: "https://safe-transaction.goerli.gnosis.io",
|
||||
[ChainId.Rinkeby]: "https://safe-transaction.rinkeby.gnosis.io",
|
||||
};
|
||||
|
||||
export interface GnosisConnectorArguments {
|
||||
|
||||
@@ -16,20 +16,7 @@ const chain: Record<string, Chain> = {
|
||||
},
|
||||
],
|
||||
},
|
||||
rinkeby: {
|
||||
id: ChainId.Rinkeby,
|
||||
name: "Rinkeby",
|
||||
nativeCurrency: NATIVE_TOKENS[ChainId.Rinkeby],
|
||||
rpcUrls: ["https://rinkeby.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161"],
|
||||
blockExplorers: [
|
||||
{
|
||||
name: "Etherscan",
|
||||
url: "https://rinkeby.etherscan.io",
|
||||
},
|
||||
],
|
||||
testnet: true,
|
||||
deprecated: true,
|
||||
},
|
||||
|
||||
goerli: {
|
||||
id: ChainId.Goerli,
|
||||
name: "Goerli",
|
||||
@@ -147,20 +134,7 @@ const chain: Record<string, Chain> = {
|
||||
],
|
||||
testnet: false,
|
||||
},
|
||||
optimismKovan: {
|
||||
id: ChainId.OptimismKovan,
|
||||
name: "Optimism Kovan",
|
||||
nativeCurrency: NATIVE_TOKENS[ChainId.OptimismKovan],
|
||||
rpcUrls: ["https://kovan.optimism.io"],
|
||||
blockExplorers: [
|
||||
{
|
||||
name: "Etherscan",
|
||||
url: "https://kovan-optimistic.etherscan.io/",
|
||||
},
|
||||
],
|
||||
testnet: true,
|
||||
deprecated: true,
|
||||
},
|
||||
|
||||
optimismGoerli: {
|
||||
id: ChainId.OptimismGoerli,
|
||||
name: "Optimism Goerli Testnet",
|
||||
@@ -187,20 +161,7 @@ const chain: Record<string, Chain> = {
|
||||
],
|
||||
testnet: false,
|
||||
},
|
||||
arbitrumRinkeby: {
|
||||
id: ChainId.ArbitrumRinkeby,
|
||||
name: "Arbitrum Rinkeby",
|
||||
nativeCurrency: NATIVE_TOKENS[ChainId.ArbitrumRinkeby],
|
||||
rpcUrls: ["https://rinkeby.arbitrum.io/rpc"],
|
||||
blockExplorers: [
|
||||
{
|
||||
name: "Arbiscan",
|
||||
url: "https://testnet.arbiscan.io/",
|
||||
},
|
||||
],
|
||||
testnet: true,
|
||||
deprecated: true,
|
||||
},
|
||||
|
||||
arbitrumGoerli: {
|
||||
id: ChainId.ArbitrumGoerli,
|
||||
name: "Arbitrum Goerli",
|
||||
|
||||
@@ -13,7 +13,6 @@ interface ThirdwebConfigContext {
|
||||
|
||||
export const defaultChainRpc: Record<SupportedChainId | number, string> = {
|
||||
[ChainId.Mainnet]: "mainnet",
|
||||
[ChainId.Rinkeby]: "rinkeby",
|
||||
[ChainId.Goerli]: "goerli",
|
||||
[ChainId.Polygon]: "polygon",
|
||||
[ChainId.Mumbai]: "mumbai",
|
||||
|
||||
@@ -70,7 +70,10 @@ export function useActiveClaimCondition(
|
||||
cacheKeys.extensions.claimConditions.getActive(contractAddress, tokenId),
|
||||
() => {
|
||||
if (erc1155) {
|
||||
invariant(tokenId, "tokenId is required for ERC1155 claim conditions");
|
||||
invariant(
|
||||
tokenId !== undefined,
|
||||
"tokenId is required for ERC1155 claim conditions",
|
||||
);
|
||||
return erc1155.claimConditions.getActive(tokenId);
|
||||
}
|
||||
if (erc721) {
|
||||
|
||||
@@ -206,11 +206,17 @@ export function useClaimNFT<TContract extends DropContract>(
|
||||
|
||||
return useMutation(
|
||||
async (data: ClaimNFTParams) => {
|
||||
invariant(data.to, 'No "to" address provided');
|
||||
invariant(contract, "contract is undefined");
|
||||
|
||||
if (erc1155) {
|
||||
invariant(!!data.tokenId, "tokenId not provided");
|
||||
if (!data.to) {
|
||||
return (await erc1155.claim(
|
||||
data.tokenId,
|
||||
data.quantity,
|
||||
data.options,
|
||||
)) as ClaimNFTReturnType;
|
||||
}
|
||||
return (await erc1155.claimTo(
|
||||
data.to,
|
||||
data.tokenId,
|
||||
@@ -219,6 +225,12 @@ export function useClaimNFT<TContract extends DropContract>(
|
||||
)) as ClaimNFTReturnType;
|
||||
}
|
||||
if (erc721) {
|
||||
if (!data.to) {
|
||||
return (await erc721.claim(
|
||||
data.quantity,
|
||||
data.options,
|
||||
)) as ClaimNFTReturnType;
|
||||
}
|
||||
return (await erc721.claimTo(
|
||||
data.to,
|
||||
data.quantity,
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
} from "../../utils/cache-keys";
|
||||
import { useQueryWithNetwork } from "../query-utils/useQueryWithNetwork";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import type { Erc20 } from "@thirdweb-dev/sdk";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
/** **********************/
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { useSDK } from "../../providers/base";
|
||||
|
||||
export * from "./useStorageUpload";
|
||||
|
||||
/**
|
||||
* Get the configured `ThirdwebStorage` instance
|
||||
* @returns The `storageInterface` configured on the `ThirdwebProvider`
|
||||
*/
|
||||
export function useStorage() {
|
||||
const sdk = useSDK();
|
||||
return sdk?.storage;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import { useSDK } from "../../providers/base";
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import { IpfsUploadBatchOptions, UploadOptions } from "@thirdweb-dev/storage";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
interface StorageUploadOptions<T extends UploadOptions> {
|
||||
data: unknown[];
|
||||
options?: T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook used to upload any files or JSON data to decentralized storage systems like IPFS,
|
||||
* using the `storageInterface` configured on the `ThirdwebProvider`
|
||||
*
|
||||
* @param options - Configure the options for your upload
|
||||
* @returns Function used to upload files or JSON to decentralized storage systems
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* import { useStorageUpload } from "@thirdweb-dev/react";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const { mutateAsync: upload, isLoading } = useStorageUpload();
|
||||
*
|
||||
* async function uploadData() {
|
||||
* const filesToUpload = [...];
|
||||
* const uris = await upload({ data: files });
|
||||
* console.log(uris);
|
||||
* }
|
||||
*
|
||||
* return (
|
||||
* <button onClick={uploadData}>
|
||||
* Upload
|
||||
* </button>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export function useStorageUpload<
|
||||
T extends UploadOptions = IpfsUploadBatchOptions,
|
||||
>(uploadOptions?: T) {
|
||||
const sdk = useSDK();
|
||||
|
||||
return useMutation(async ({ data, options }: StorageUploadOptions<T>) => {
|
||||
invariant(sdk, "sdk must be defined");
|
||||
|
||||
return await sdk.storage.uploadBatch(data, options || uploadOptions);
|
||||
});
|
||||
}
|
||||
@@ -15,8 +15,9 @@ export * from "./hooks/async/claim-conditions";
|
||||
export * from "./hooks/async/contract-settings";
|
||||
export * from "./hooks/async/roles";
|
||||
|
||||
// thirdweb hooks (work as long as at least `<ThirdwebSDkProvider>` is used)
|
||||
// thirdweb hooks (work as long as at least `<ThirdwebSdkProvider>` is used)
|
||||
export * from "./hooks/auth";
|
||||
export * from "./hooks/storage";
|
||||
export * from "./hooks/useSigner";
|
||||
export * from "./hooks/useReadonlySDK";
|
||||
export * from "./hooks/useNetworkMismatch";
|
||||
|
||||
@@ -191,7 +191,7 @@ export type RevealLazyMintInput = {
|
||||
* @beta
|
||||
*/
|
||||
export type ClaimNFTParams = {
|
||||
to: WalletAddress;
|
||||
to?: WalletAddress;
|
||||
quantity: BigNumberish;
|
||||
options?: ClaimOptions;
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import React, {
|
||||
PropsWithChildren,
|
||||
createContext,
|
||||
useContext,
|
||||
useMemo,
|
||||
} from "react";
|
||||
|
||||
/**
|
||||
* The configuration to use the react SDK with an [auth](https://portal.thirdweb.com/auth) server.
|
||||
*
|
||||
* @beta
|
||||
*/
|
||||
export interface ThirdwebAuthConfig {
|
||||
/**
|
||||
* The backend URL of the authentication endoints. For example, if your endpoints are
|
||||
* at `/api/auth/login`, `/api/auth/logout`, etc. then this should be set to `/api/auth`.
|
||||
*/
|
||||
authUrl: string;
|
||||
|
||||
/**
|
||||
* The frontend domain used to generate the login payload.
|
||||
* This domain should match the domain used on your auth backend.
|
||||
*/
|
||||
domain: string;
|
||||
|
||||
/**
|
||||
* The URL to redirect to after a succesful login.
|
||||
*/
|
||||
loginRedirect?: string;
|
||||
}
|
||||
|
||||
const ThirdwebAuthConfigContext = createContext<ThirdwebAuthConfig | undefined>(
|
||||
undefined,
|
||||
);
|
||||
|
||||
export const ThirdwebAuthConfigProvider: React.FC<
|
||||
PropsWithChildren<{ value?: ThirdwebAuthConfig }>
|
||||
> = ({ value, children }) => {
|
||||
// Remove trailing slash from URL if present
|
||||
const authConfig = useMemo(
|
||||
() =>
|
||||
value
|
||||
? {
|
||||
...value,
|
||||
authUrl: value.authUrl.replace(/\/$/, ""),
|
||||
}
|
||||
: undefined,
|
||||
[value],
|
||||
);
|
||||
return (
|
||||
<ThirdwebAuthConfigContext.Provider value={authConfig}>
|
||||
{children}
|
||||
</ThirdwebAuthConfigContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export function useThirdwebAuthConfig() {
|
||||
return useContext(ThirdwebAuthConfigContext);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { LoginConfig, useLogin } from "./useLogin";
|
||||
import { useLogout } from "./useLogout";
|
||||
import { useUser } from "./useUser";
|
||||
|
||||
export * from "./useLogin";
|
||||
export * from "./useLogout";
|
||||
export * from "./useUser";
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns
|
||||
* @internal
|
||||
*/
|
||||
export function useAuth(loginConfig?: LoginConfig) {
|
||||
const user = useUser();
|
||||
const login = useLogin(loginConfig);
|
||||
const logout = useLogout();
|
||||
return { ...user, login, logout };
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
import { ensureTWPrefix } from "../../../core/query-utils/query-key";
|
||||
import { useThirdwebAuthConfig } from "../../contexts/thirdweb-auth";
|
||||
import { useSDK } from "../../providers/base";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { LoginOptions } from "@thirdweb-dev/sdk";
|
||||
import React from "react";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
export interface LoginConfig {
|
||||
/**
|
||||
* The URL to redirect to on login.
|
||||
*/
|
||||
redirectTo?: string;
|
||||
/**
|
||||
* Function to run on error.
|
||||
*/
|
||||
onError?: (error: string) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to securely login to a backend with the connected wallet. The backend
|
||||
* authentication URL must be configured on the ThirdwebProvider.
|
||||
*
|
||||
* @param config - Configuration for the login.
|
||||
* @returns - A function to invoke to login with the connected wallet.
|
||||
*
|
||||
* @beta
|
||||
*/
|
||||
export function useLogin(config?: LoginConfig) {
|
||||
const sdk = useSDK();
|
||||
const queryClient = useQueryClient();
|
||||
const authConfig = useThirdwebAuthConfig();
|
||||
|
||||
React.useEffect(() => {
|
||||
const queryParams = new URLSearchParams(window.location.search);
|
||||
const error = queryParams.get("error");
|
||||
|
||||
if (error && config?.onError) {
|
||||
// If there is an error, parse it and trigger the onError callback
|
||||
config.onError(decodeURI(error));
|
||||
}
|
||||
}, [config]);
|
||||
|
||||
async function login(cfg?: LoginOptions) {
|
||||
invariant(
|
||||
authConfig,
|
||||
"Please specify an authConfig in the ThirdwebProvider",
|
||||
);
|
||||
const payload = await sdk?.auth.login(authConfig.domain, cfg);
|
||||
|
||||
const encodedPayload = encodeURIComponent(btoa(JSON.stringify(payload)));
|
||||
const encodedRedirectTo = encodeURIComponent(
|
||||
config?.redirectTo ||
|
||||
authConfig.loginRedirect ||
|
||||
window.location.toString(),
|
||||
);
|
||||
|
||||
queryClient.invalidateQueries(ensureTWPrefix(["user"]));
|
||||
|
||||
// Redirect to the login URL with the encoded payload
|
||||
window.location.href = `${authConfig.authUrl}/login?payload=${encodedPayload}&redirect=${encodedRedirectTo}`;
|
||||
}
|
||||
|
||||
return login;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { ensureTWPrefix } from "../../../core/query-utils/query-key";
|
||||
import { useThirdwebAuthConfig } from "../../contexts/thirdweb-auth";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
/**
|
||||
* Hook to logout the connected wallet from the backend.
|
||||
* The backend logout URL must be configured on the ThirdwebProvider.
|
||||
*
|
||||
* @returns - A function to invoke to logout.
|
||||
*
|
||||
* @beta
|
||||
*/
|
||||
export function useLogout() {
|
||||
const queryClient = useQueryClient();
|
||||
const authConfig = useThirdwebAuthConfig();
|
||||
|
||||
function logout() {
|
||||
invariant(
|
||||
authConfig,
|
||||
"Please specify an authConfig in the ThirdwebProvider",
|
||||
);
|
||||
queryClient.invalidateQueries(ensureTWPrefix(["user"]));
|
||||
window.location.href = `${authConfig.authUrl}/logout`;
|
||||
}
|
||||
|
||||
return logout;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { ensureTWPrefix } from "../../../core/query-utils/query-key";
|
||||
import { useThirdwebAuthConfig } from "../../contexts/thirdweb-auth";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
export interface ThirdwebAuthUser {
|
||||
address: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to get the currently logged in user.
|
||||
*
|
||||
* @returns - The currently logged in user or null if not logged in, as well as a loading state.
|
||||
*
|
||||
* @beta
|
||||
*/
|
||||
export function useUser() {
|
||||
const authConfig = useThirdwebAuthConfig();
|
||||
|
||||
const { data: user, isLoading } = useQuery(
|
||||
ensureTWPrefix(["user"]),
|
||||
async () => {
|
||||
invariant(
|
||||
authConfig,
|
||||
"Please specify an authConfig in the ThirdwebProvider",
|
||||
);
|
||||
const res = await fetch(`${authConfig.authUrl}/user`);
|
||||
return (await res.json()) as ThirdwebAuthUser;
|
||||
},
|
||||
{
|
||||
enabled: !!authConfig,
|
||||
},
|
||||
);
|
||||
|
||||
return { user, isLoading };
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import { createSOLProgramQueryKey } from "../../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../../core/types/shared";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import type { NFTDrop } from "@thirdweb-dev/sdk/solana";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
export function claimConditionsQuery(program: RequiredParam<NFTDrop>) {
|
||||
return {
|
||||
queryKey: createSOLProgramQueryKey(program, ["claimConditions"] as const),
|
||||
|
||||
queryFn: async () => {
|
||||
invariant(program, "program is required");
|
||||
|
||||
return await program.claimConditions.get();
|
||||
},
|
||||
enabled: !!program,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current claim conditions on an NFT Drop
|
||||
* @param program - The NFT Drop program to get the claim conditions for
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* import { useProgram, useClaimConditions } from "@thirdweb-dev/react/solana";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const { program } = useProgram("{{program_address}}");
|
||||
* const { data: claimConditions, isLoading } = useClaimConditions(program);
|
||||
*
|
||||
* return (
|
||||
* <p>{claimConditions?.price.displayValue}</p>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function useClaimConditions(program: RequiredParam<NFTDrop>) {
|
||||
return useQuery(claimConditionsQuery(program));
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { createSOLProgramQueryKey } from "../../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../../core/types/shared";
|
||||
import { ClaimNFTParams } from "../../../types";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import type { NFTDrop } from "@thirdweb-dev/sdk/solana";
|
||||
import invariant from "tiny-invariant";
|
||||
@@ -13,11 +14,11 @@ import invariant from "tiny-invariant";
|
||||
* import { useProgram, useClaimNFT } from "@thirdweb-dev/react/solana";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const program = useProgram("{{program_address}}");
|
||||
* const { program } = useProgram("{{program_address}}");
|
||||
* const { mutateAsync: claim, isLoading, error } = useClaimNFT(program);
|
||||
*
|
||||
* return (
|
||||
* <button onClick={() => claim(1)}>
|
||||
* <button onClick={() => claim({amount: 1})}>
|
||||
* Claim
|
||||
* </button>
|
||||
* )
|
||||
@@ -29,9 +30,12 @@ import invariant from "tiny-invariant";
|
||||
export function useClaimNFT(program: RequiredParam<NFTDrop>) {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation(
|
||||
async (quantity: number) => {
|
||||
async (data: ClaimNFTParams) => {
|
||||
invariant(program, "program is required");
|
||||
return await program.claim(quantity);
|
||||
if (!data.to) {
|
||||
return await program.claim(data.amount);
|
||||
}
|
||||
return await program.claimTo(data.to, data.amount);
|
||||
},
|
||||
{
|
||||
onSettled: () =>
|
||||
|
||||
@@ -28,7 +28,7 @@ export function dropTotalClaimedSupplyQuery(program: RequiredParam<NFTDrop>) {
|
||||
* import { useProgram, useDropTotalClaimedSupply } from "@thirdweb-dev/react/solana";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const program = useProgram("{{program_address}}");
|
||||
* const { program } = useProgram("{{program_address}}");
|
||||
* const { data: claimedSupply, isLoading } = useDropTotalClaimedSupply(program);
|
||||
*
|
||||
* return (
|
||||
|
||||
@@ -14,7 +14,7 @@ import invariant from "tiny-invariant";
|
||||
* import { useProgram, useLazyMintNFT } from "@thirdweb-dev/react/solana";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const program = useProgram("{{program_address}}");
|
||||
* const { program } = useProgram("{{program_address}}");
|
||||
* const { mutateAsync: lazyMint, isLoading, error } = useLazyMintNFT(program);
|
||||
*
|
||||
* return (
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { createSOLProgramQueryKey } from "../../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../../core/types/shared";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import type { NFTDrop, NFTDropConditionsInput } from "@thirdweb-dev/sdk/solana";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
/**
|
||||
* Set Claim Conditions to an NFT Drop program
|
||||
* @param program - The NFT Drop program to set claim conditions for
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* import { useProgram, useSetClaimConditions } from "@thirdweb-dev/react/solana";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const { program } = useProgram("{{program_address}}");
|
||||
* const { mutateAsync: setClaimConditions, isLoading, error } = useSetClaimConditions(program);
|
||||
*
|
||||
* return (
|
||||
* <button onClick={() => setClaimConditions(metadata)}>
|
||||
* Set Claim Conditions
|
||||
* </button>
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function useSetClaimConditions(program: RequiredParam<NFTDrop>) {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation(
|
||||
async (metadata: NFTDropConditionsInput) => {
|
||||
invariant(program, "program is required");
|
||||
return await program.claimConditions.set(metadata);
|
||||
},
|
||||
{
|
||||
onSettled: () =>
|
||||
queryClient.invalidateQueries(createSOLProgramQueryKey(program)),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -28,7 +28,7 @@ export function dropUnclaimedSupplyQuery(program: RequiredParam<NFTDrop>) {
|
||||
* import { useProgram, useDropTotalUnclaimedSupply } from "@thirdweb-dev/react/solana";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const program = useProgram("{{program_address}}");
|
||||
* const { program } = useProgram("{{program_address}}");
|
||||
* const { data: unclaimedSupply, isLoading } = useDropTotalUnclaimedSupply(program);
|
||||
*
|
||||
* return (
|
||||
|
||||
@@ -13,7 +13,7 @@ import invariant from "tiny-invariant";
|
||||
* import { useProgram, useBurnNFT } from "@thirdweb-dev/react/solana";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const program = useProgram("{{program_address}}");
|
||||
* const { program } = useProgram("{{program_address}}");
|
||||
* const { mutateAsync: burn, isLoading, error } = useBurnNFT(program);
|
||||
*
|
||||
* return (
|
||||
|
||||
@@ -14,7 +14,7 @@ import invariant from "tiny-invariant";
|
||||
* import { useProgram, useMintNFT } from "@thirdweb-dev/react/solana";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const program = useProgram("{{program_address}}");
|
||||
* const { program } = useProgram("{{program_address}}");
|
||||
* const { mutateAsync: mint, isLoading, error } = useMintNFT(program);
|
||||
*
|
||||
* function mintNFT() {
|
||||
|
||||
@@ -33,7 +33,7 @@ export function nftGetOneQuery(
|
||||
* import { useProgram, useNFT } from "@thirdweb-dev/react/solana";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const program = useProgram("{{program_address}}");
|
||||
* const { program } = useProgram("{{program_address}}");
|
||||
* const { data: metadata, isLoading } = useNFT(program, mintAddress);
|
||||
*
|
||||
* return (
|
||||
|
||||
@@ -27,7 +27,7 @@ export function nftGetAllQuery(
|
||||
* import { useProgram, useNFTs } from "@thirdweb-dev/react/solana";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const program = useProgram("{{program_address}}");
|
||||
* const { program } = useProgram("{{program_address}}");
|
||||
* const { data: metadata, isLoading } = useNFTs(program);
|
||||
*
|
||||
* return (
|
||||
|
||||
@@ -18,7 +18,7 @@ export type TransferNFTMutationParams = {
|
||||
* import { useProgram, useTransferNFT } from "@thirdweb-dev/react/solana";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const program = useProgram("{{program_address}}");
|
||||
* const { program } = useProgram("{{program_address}}");
|
||||
* const { mutateAsync: transfer, isLoading, error } = useTransferNFT(program);
|
||||
*
|
||||
* return (
|
||||
|
||||
@@ -5,7 +5,12 @@ import {
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { useSDK } from "../../providers/base";
|
||||
import { programAccountTypeQuery } from "./useProgramAccountType";
|
||||
import { QueryClient, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import {
|
||||
QueryClient,
|
||||
useQuery,
|
||||
useQueryClient,
|
||||
UseQueryResult,
|
||||
} from "@tanstack/react-query";
|
||||
import type {
|
||||
NFTCollection,
|
||||
NFTDrop,
|
||||
@@ -77,7 +82,7 @@ export function programQuery<TProgramType extends ProgramType>(
|
||||
* import { useProgram } from "@thirdweb-dev/react/solana";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const program = useProgram("{{program_address}}");
|
||||
* const { program } = useProgram("{{program_address}}").program;
|
||||
*
|
||||
* // Now you can use the program in the rest of the component
|
||||
*
|
||||
@@ -98,7 +103,22 @@ export function useProgram<TProgramType extends ProgramType>(
|
||||
) {
|
||||
const queryClient = useQueryClient();
|
||||
const sdk = useSDK();
|
||||
return useQuery(programQuery(queryClient, sdk, address, type));
|
||||
const queryResult = useQuery(programQuery(queryClient, sdk, address, type));
|
||||
|
||||
return { ...queryResult, program: queryResult.data } as UseQueryResult<
|
||||
Readonly<{
|
||||
"nft-collection": NFTCollection;
|
||||
"nft-drop": NFTDrop;
|
||||
token: Token;
|
||||
}>[TProgramType],
|
||||
unknown
|
||||
> & {
|
||||
program: Readonly<{
|
||||
"nft-collection": NFTCollection;
|
||||
"nft-drop": NFTDrop;
|
||||
token: Token;
|
||||
}>[TProgramType];
|
||||
};
|
||||
}
|
||||
|
||||
export type UseProgramResult = ReturnType<typeof useProgram>;
|
||||
|
||||
@@ -19,7 +19,7 @@ export function programAccountTypeQuery(
|
||||
invariant(sdk, "sdk is required");
|
||||
invariant(address, "Address is required");
|
||||
|
||||
return await sdk.registry.getAccountType(address);
|
||||
return await sdk.registry.getProgramType(address);
|
||||
},
|
||||
enabled: !!sdk && !!network && !!address,
|
||||
// this cannot change as it is unique by address & network
|
||||
|
||||
@@ -14,7 +14,7 @@ import invariant from "tiny-invariant";
|
||||
* import { useProgram, useMintToken } from "@thirdweb-dev/react/solana";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const program = useProgram("{{program_address}}");
|
||||
* const { program } = useProgram("{{program_address}}");
|
||||
* const { mutateAsync: mint, isLoading, error } = useMintToken(program);
|
||||
*
|
||||
* return (
|
||||
|
||||
@@ -33,7 +33,7 @@ export function tokenBalanceQuery(
|
||||
* import { useProgram, useTokenBalance } from "@thirdweb-dev/react/solana";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const program = useProgram("{{program_address}}");
|
||||
* const { program } = useProgram("{{program_address}}");
|
||||
* const { data: balance, isLoading } = useTokenBalance(program, "{{wallet_address}}");
|
||||
*
|
||||
* return (
|
||||
|
||||
@@ -25,7 +25,7 @@ export function tokenSupplyQuery(program: RequiredParam<Token>) {
|
||||
* import { useProgram, useMintToken } from "@thirdweb-dev/react/solana";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const program = useProgram("{{program_address}}");
|
||||
* const { program } = useProgram("{{program_address}}");
|
||||
* const { data: totalSupply, isLoading } = useTokenSupply(program);
|
||||
*
|
||||
* return (
|
||||
|
||||
@@ -18,7 +18,7 @@ export type TransferTokenMutationParams = {
|
||||
* import { useProgram, useTransferToken } from "@thirdweb-dev/react/solana";
|
||||
*
|
||||
* export default function Component() {
|
||||
* const program = useProgram("{{program_address}}");
|
||||
* const { program } = useProgram("{{program_address}}");
|
||||
* const { mutateAsync: transfer, isLoading, error } = useTransferToken(program);
|
||||
*
|
||||
* return (
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { useSDK } from "../../providers/base";
|
||||
|
||||
/**
|
||||
* Get the currently connected wallet address
|
||||
*
|
||||
* @returns the address of the connected wallet (in base58 string format)
|
||||
*/
|
||||
export function useAddress() {
|
||||
const sdk = useSDK();
|
||||
return sdk?.wallet?.getAddress();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { createSOLQueryKeyWithNetwork } from "../../../core/query-utils/query-key";
|
||||
import { RequiredParam } from "../../../core/types/shared";
|
||||
import { useSDK } from "../../providers/base";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { ThirdwebSDK } from "@thirdweb-dev/sdk/solana";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
export function balanceQuery(sdk: RequiredParam<ThirdwebSDK>) {
|
||||
const address = sdk?.wallet?.getAddress();
|
||||
const network = sdk?.network;
|
||||
|
||||
return {
|
||||
queryKey: createSOLQueryKeyWithNetwork(
|
||||
["wallet-balance", { address }] as const,
|
||||
network,
|
||||
),
|
||||
|
||||
queryFn: () => {
|
||||
invariant(sdk, "sdk is required");
|
||||
|
||||
return sdk.wallet.getBalance();
|
||||
},
|
||||
enabled: !!sdk && !!address && !!network,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the currently connected wallet balance
|
||||
*
|
||||
* @returns the balace of the connected wallet
|
||||
*/
|
||||
export function useBalance() {
|
||||
const sdk = useSDK();
|
||||
return useQuery(balanceQuery(sdk));
|
||||
}
|
||||
@@ -22,9 +22,18 @@ export * from "./hooks/nft/drop/useLazyMint";
|
||||
export * from "./hooks/nft/drop/useClaimedSupply";
|
||||
export * from "./hooks/nft/drop/useUnclaimedSupply";
|
||||
export * from "./hooks/nft/drop/useClaimNFT";
|
||||
export * from "./hooks/nft/drop/useClaimConditions";
|
||||
export * from "./hooks/nft/drop/useSetClaimConditions";
|
||||
|
||||
// Token
|
||||
export * from "./hooks/token/useTokenSupply";
|
||||
export * from "./hooks/token/useTokenBalance";
|
||||
export * from "./hooks/token/useMintToken";
|
||||
export * from "./hooks/token/useTransferToken";
|
||||
|
||||
// Auth
|
||||
export * from "./hooks/auth";
|
||||
|
||||
//Wallet
|
||||
export * from "./hooks/wallet/useAddress";
|
||||
export * from "./hooks/wallet/useBalance";
|
||||
|
||||
@@ -4,14 +4,19 @@ import {
|
||||
} from "../../core/providers/query-client";
|
||||
import { ComponentWithChildren } from "../../core/types/component";
|
||||
import { RequiredParam } from "../../core/types/shared";
|
||||
import {
|
||||
ThirdwebAuthConfig,
|
||||
ThirdwebAuthConfigProvider,
|
||||
} from "../contexts/thirdweb-auth";
|
||||
import type { WalletContextState } from "@solana/wallet-adapter-react";
|
||||
import { Network, ThirdwebSDK } from "@thirdweb-dev/sdk/solana";
|
||||
import { createContext, useContext, useEffect, useState } from "react";
|
||||
import { createContext, useContext, useEffect, useMemo, useState } from "react";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
interface ThirdwebSDKProviderProps extends QueryClientProviderProps {
|
||||
network: RequiredParam<Network>;
|
||||
wallet?: WalletContextState;
|
||||
authConfig?: ThirdwebAuthConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -33,36 +38,53 @@ interface ThirdwebSDKProviderProps extends QueryClientProviderProps {
|
||||
*/
|
||||
export const ThirdwebSDKProvider: ComponentWithChildren<
|
||||
ThirdwebSDKProviderProps
|
||||
> = ({ children, network, queryClient, wallet }) => {
|
||||
> = ({ children, network, queryClient, wallet, authConfig }) => {
|
||||
const [sdk, setSDK] = useState<ThirdwebSDK | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (network) {
|
||||
const _sdk = ThirdwebSDK.fromNetwork(network);
|
||||
if (wallet && wallet.publicKey) {
|
||||
_sdk.wallet.connect(wallet);
|
||||
}
|
||||
(_sdk as any)._network = network;
|
||||
setSDK(_sdk);
|
||||
} else {
|
||||
setSDK(null);
|
||||
}
|
||||
// disabled wallet on purpose because we handle that below
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [network]);
|
||||
|
||||
useEffect(() => {
|
||||
if (sdk) {
|
||||
if (wallet?.publicKey) {
|
||||
sdk.wallet.connect(wallet);
|
||||
} else {
|
||||
sdk.wallet.disconnect();
|
||||
}
|
||||
if (
|
||||
wallet &&
|
||||
wallet.publicKey &&
|
||||
sdk &&
|
||||
(sdk as any)._network === network
|
||||
) {
|
||||
sdk.wallet.connect(wallet);
|
||||
return;
|
||||
}
|
||||
}, [sdk, wallet]);
|
||||
}, [network, sdk, wallet]);
|
||||
|
||||
const ctxValue = useMemo(
|
||||
() =>
|
||||
({
|
||||
sdk,
|
||||
desiredNetwork: network || "unknown",
|
||||
_inProvider: true,
|
||||
} as const),
|
||||
[sdk, network],
|
||||
);
|
||||
|
||||
return (
|
||||
<QueryClientProviderWithDefault queryClient={queryClient}>
|
||||
<ThirdwebSDKContext.Provider
|
||||
value={{ sdk, desiredNetwork: network || "unknown", _inProvider: true }}
|
||||
>
|
||||
{children}
|
||||
</ThirdwebSDKContext.Provider>
|
||||
<ThirdwebAuthConfigProvider value={authConfig}>
|
||||
<ThirdwebSDKContext.Provider value={ctxValue}>
|
||||
{children}
|
||||
</ThirdwebSDKContext.Provider>
|
||||
</ThirdwebAuthConfigProvider>
|
||||
</QueryClientProviderWithDefault>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ThirdwebAuthConfig } from "../contexts/thirdweb-auth";
|
||||
import { ThirdwebSDKProvider } from "./base";
|
||||
import type { WalletAdapter } from "@solana/wallet-adapter-base";
|
||||
import {
|
||||
@@ -13,6 +14,7 @@ interface ThirdwebProviderProps {
|
||||
network: Network;
|
||||
wallets?: WalletAdapter[];
|
||||
autoConnect?: boolean;
|
||||
authConfig?: ThirdwebAuthConfig;
|
||||
}
|
||||
|
||||
const DEFAULT_WALLETS = [new PhantomWalletAdapter()];
|
||||
@@ -35,12 +37,18 @@ const DEFAULT_WALLETS = [new PhantomWalletAdapter()];
|
||||
*/
|
||||
export const ThirdwebProvider: React.FC<
|
||||
PropsWithChildren<ThirdwebProviderProps>
|
||||
> = ({ network, wallets = DEFAULT_WALLETS, autoConnect = true, children }) => {
|
||||
> = ({
|
||||
network,
|
||||
wallets = DEFAULT_WALLETS,
|
||||
autoConnect = true,
|
||||
authConfig,
|
||||
children,
|
||||
}) => {
|
||||
const clusterUrl = getUrlForNetwork(network);
|
||||
return (
|
||||
<ConnectionProvider endpoint={clusterUrl}>
|
||||
<WalletProvider wallets={wallets} autoConnect={autoConnect}>
|
||||
<ThirdwebWrapperProvider network={network}>
|
||||
<ThirdwebWrapperProvider network={network} authConfig={authConfig}>
|
||||
{children}
|
||||
</ThirdwebWrapperProvider>
|
||||
</WalletProvider>
|
||||
@@ -52,11 +60,15 @@ export const ThirdwebProvider: React.FC<
|
||||
* @internal
|
||||
*/
|
||||
export const ThirdwebWrapperProvider: React.FC<
|
||||
PropsWithChildren<{ network?: Network }>
|
||||
> = ({ network, children }) => {
|
||||
PropsWithChildren<{ network?: Network; authConfig?: ThirdwebAuthConfig }>
|
||||
> = ({ network, authConfig, children }) => {
|
||||
const wallet = useWallet();
|
||||
return (
|
||||
<ThirdwebSDKProvider network={network} wallet={wallet}>
|
||||
<ThirdwebSDKProvider
|
||||
network={network}
|
||||
wallet={wallet}
|
||||
authConfig={authConfig}
|
||||
>
|
||||
{children}
|
||||
</ThirdwebSDKProvider>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Amount } from "@thirdweb-dev/sdk";
|
||||
|
||||
/**
|
||||
* The params for the {@link useClaimNFT} hook mutation.
|
||||
*
|
||||
* @beta
|
||||
*/
|
||||
export type ClaimNFTParams = {
|
||||
to?: string;
|
||||
amount: Amount;
|
||||
};
|
||||
@@ -32,6 +32,11 @@ module.exports = {
|
||||
programId: "89RsF5yJgRXhae6LKuCcMRgXkqxCJm3AeaYwcJN4XopA",
|
||||
deployPath: localDeployPath("counter"),
|
||||
},
|
||||
{
|
||||
label: "TWRegistry Program",
|
||||
programId: "twregzGdRmyFeAKjPgbPMkRkzgFNy8BHrB4HzwjyH14",
|
||||
deployPath: localDeployPath("tw_registry"),
|
||||
},
|
||||
],
|
||||
},
|
||||
storage: {
|
||||
|
||||
@@ -1,5 +1,39 @@
|
||||
# @thirdweb-dev/sdk
|
||||
|
||||
## 3.2.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#289](https://github.com/thirdweb-dev/js/pull/289) [`521a49c`](https://github.com/thirdweb-dev/js/commit/521a49c6ec6a73068adcfbc1d94d2f3f17afae86) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - Standarize useClaimNFT to evm
|
||||
|
||||
- [#293](https://github.com/thirdweb-dev/js/pull/293) [`8b3b97c`](https://github.com/thirdweb-dev/js/commit/8b3b97c8f7b3710ce62ed86cfeb4f6de3c23d559) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - [SOL] Fix getAllClaimed for NFT Drops
|
||||
|
||||
- [#286](https://github.com/thirdweb-dev/js/pull/286) [`25a4773`](https://github.com/thirdweb-dev/js/commit/25a4773bba406f4e270ac86e68c5266d24c08330) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - [SOL] Add pagination for nftCollection.getAll()
|
||||
|
||||
- [#269](https://github.com/thirdweb-dev/js/pull/269) [`b2cadf1`](https://github.com/thirdweb-dev/js/commit/b2cadf164cfe9fb27081df7530356baf70ec2b3a) Thanks [@jnsdls](https://github.com/jnsdls)! - [EVM] - remove deprecated chains from support
|
||||
|
||||
- [#263](https://github.com/thirdweb-dev/js/pull/263) [`d6bb61b`](https://github.com/thirdweb-dev/js/commit/d6bb61b7fac759fff7d6293edd46f693f5a7889c) Thanks [@jnsdls](https://github.com/jnsdls)! - [Solana] - align `getProgram` with `getContract` from EVM
|
||||
|
||||
- [#297](https://github.com/thirdweb-dev/js/pull/297) [`78d6d3c`](https://github.com/thirdweb-dev/js/commit/78d6d3c15968a449924b3f24354e151a90e4b20d) Thanks [@jnsdls](https://github.com/jnsdls)! - [SOL] - fix getAddress to return undefined if wallet is not connected
|
||||
|
||||
- [#294](https://github.com/thirdweb-dev/js/pull/294) [`89d87a5`](https://github.com/thirdweb-dev/js/commit/89d87a5eb31e78e68e097718e9ae6e4c4d101868) Thanks [@jnsdls](https://github.com/jnsdls)! - [SOL] - batch uploads for NFT drop to satisfy solana size limits
|
||||
|
||||
- [#270](https://github.com/thirdweb-dev/js/pull/270) [`41507d3`](https://github.com/thirdweb-dev/js/commit/41507d32a78c556f50c88de81c4d6109b1783c78) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - [SOL] Add to registry when deploying new programs
|
||||
|
||||
- [#290](https://github.com/thirdweb-dev/js/pull/290) [`8096c78`](https://github.com/thirdweb-dev/js/commit/8096c78b466a7f5f9c2aac6e2c56a06f9d3a25d6) Thanks [@jnsdls](https://github.com/jnsdls)! - [SOL] - make `claim()` take a typeof `Amount` instead of `number`
|
||||
|
||||
- [#273](https://github.com/thirdweb-dev/js/pull/273) [`b1fa171`](https://github.com/thirdweb-dev/js/commit/b1fa17158dcac00265bc8f4d64f1f9708482cdb5) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - [Solana] Expose maxClaimable for claim conditions and disallow claiming by default
|
||||
|
||||
- [#280](https://github.com/thirdweb-dev/js/pull/280) [`18381fa`](https://github.com/thirdweb-dev/js/commit/18381fac73741826934212ac6441842ed42a64a0) Thanks [@ElasticBottle](https://github.com/ElasticBottle)! - Fix errorneous ERC20 Allowance check
|
||||
|
||||
- [#271](https://github.com/thirdweb-dev/js/pull/271) [`df048af`](https://github.com/thirdweb-dev/js/commit/df048af605f449279b01d7352b604e7856ac223c) Thanks [@adam-maj](https://github.com/adam-maj)! - Add auth support to Solana
|
||||
|
||||
- [#263](https://github.com/thirdweb-dev/js/pull/263) [`d6bb61b`](https://github.com/thirdweb-dev/js/commit/d6bb61b7fac759fff7d6293edd46f693f5a7889c) Thanks [@jnsdls](https://github.com/jnsdls)! - [EVM] - add chainId getter on contracts
|
||||
|
||||
- [#296](https://github.com/thirdweb-dev/js/pull/296) [`cf88795`](https://github.com/thirdweb-dev/js/commit/cf88795376d3110f9d3aa839928d22276904b15a) Thanks [@jnsdls](https://github.com/jnsdls)! - [SOL] - add network to userwallet
|
||||
|
||||
- [#285](https://github.com/thirdweb-dev/js/pull/285) [`89b5c6f`](https://github.com/thirdweb-dev/js/commit/89b5c6fe079e4df2cf12cb557aa9784f88c5d159) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - [SOL] Make creating NFTDrop transactions sequential
|
||||
|
||||
## 3.2.1
|
||||
|
||||
## 3.2.0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/sdk",
|
||||
"version": "3.2.1",
|
||||
"version": "3.2.2",
|
||||
"description": "The main thirdweb SDK.",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/sdk",
|
||||
"license": "Apache-2.0",
|
||||
@@ -120,6 +120,7 @@
|
||||
"merkletreejs": "^0.2.24",
|
||||
"multihashes": "^4.0.3",
|
||||
"tiny-invariant": "^1.2.0",
|
||||
"tweetnacl": "^1.0.3",
|
||||
"uuid": "^9.0.0",
|
||||
"yaml": "^2.1.1",
|
||||
"zod": "^3.11.6"
|
||||
|
||||
@@ -79,7 +79,8 @@ export function generateSnippets(ecosystem) {
|
||||
return examples;
|
||||
}
|
||||
|
||||
const baseDocUrl = "https://portal.thirdweb.com/typescript/sdk.";
|
||||
const path = ecosystem === "solana" ? "solana-sdk" : "typescript";
|
||||
const baseDocUrl = `https://portal.thirdweb.com/${path}/sdk.`;
|
||||
|
||||
const extractReferenceLink = (m, kind, contractName) => {
|
||||
if (kind === "Property") {
|
||||
|
||||
+2
-4
@@ -1,5 +1,3 @@
|
||||
import { BigNumberish } from "ethers";
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
@@ -13,9 +11,9 @@ export interface QueryAllParams {
|
||||
/**
|
||||
* the index to start from (default: 0)
|
||||
*/
|
||||
start?: BigNumberish;
|
||||
start?: number;
|
||||
/**
|
||||
* how many items to return (default: 100)
|
||||
*/
|
||||
count?: BigNumberish;
|
||||
count?: number;
|
||||
}
|
||||
@@ -96,6 +96,13 @@ export const AmountSchema = z
|
||||
])
|
||||
.transform((arg) => (typeof arg === "number" ? arg.toString() : arg));
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const QuantitySchema = z
|
||||
.union([AmountSchema, z.literal("unlimited")])
|
||||
.default("unlimited");
|
||||
|
||||
export const RawDateSchema = z.date().transform((i) => {
|
||||
return BigNumber.from(Math.floor(i.getTime() / 1000));
|
||||
});
|
||||
|
||||
@@ -33,14 +33,7 @@ export const CONTRACT_ADDRESSES: Record<
|
||||
twRegistry: TWRegistry_address,
|
||||
twBYOCRegistry: constants.AddressZero,
|
||||
},
|
||||
[ChainId.Rinkeby]: {
|
||||
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
|
||||
openzeppelinForwarderEOA: "0x0bBA31EAf82C649C0B9579F5F44374C74F4605Ea",
|
||||
biconomyForwarder: "0xFD4973FeB2031D4409fB57afEE5dF2051b171104",
|
||||
twFactory: TWFactory_address,
|
||||
twRegistry: TWRegistry_address,
|
||||
twBYOCRegistry: "0x3E6eE864f850F5e5A98bc950B68E181Cf4010F23",
|
||||
},
|
||||
|
||||
[ChainId.Goerli]: {
|
||||
openzeppelinForwarder: "0x5001A14CA6163143316a7C614e30e6041033Ac20",
|
||||
openzeppelinForwarderEOA: "0xe73c50cB9c5B378627ff625BB6e6725A4A5D65d2",
|
||||
@@ -105,14 +98,7 @@ export const CONTRACT_ADDRESSES: Record<
|
||||
twRegistry: "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd",
|
||||
twBYOCRegistry: constants.AddressZero,
|
||||
},
|
||||
[ChainId.ArbitrumRinkeby]: {
|
||||
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
|
||||
openzeppelinForwarderEOA: "0xE1eE43D23f247b6A9aF81fcE2766E76709482728",
|
||||
biconomyForwarder: "0x67454E169d613a8e9BA6b06af2D267696EAaAf41",
|
||||
twFactory: "0xb0435b47ad26115A39c59735b814f3769F07C2c1",
|
||||
twRegistry: "0xcF4c511551aE4dab1F997866FC3900cd2aaeC40D",
|
||||
twBYOCRegistry: constants.AddressZero,
|
||||
},
|
||||
|
||||
[ChainId.ArbitrumGoerli]: {
|
||||
openzeppelinForwarder: "0x8cbc8B5d71702032904750A66AEfE8B603eBC538",
|
||||
openzeppelinForwarderEOA: "0x119704314Ef304EaAAE4b3c7C9ABd59272A28310",
|
||||
@@ -129,14 +115,7 @@ export const CONTRACT_ADDRESSES: Record<
|
||||
twRegistry: "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd",
|
||||
twBYOCRegistry: constants.AddressZero,
|
||||
},
|
||||
[ChainId.OptimismKovan]: {
|
||||
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
|
||||
openzeppelinForwarderEOA: "0xE8dd2Ff0212F86d3197b4AfDC6dAC6ac47eb10aC",
|
||||
biconomyForwarder: "0x9C73373C70F23920EA54F7883dCB1F85b162Df40",
|
||||
twFactory: "0xd24b3de085CFd8c54b94feAD08a7962D343E6DE0",
|
||||
twRegistry: "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd",
|
||||
twBYOCRegistry: constants.AddressZero,
|
||||
},
|
||||
|
||||
[ChainId.OptimismGoerli]: {
|
||||
openzeppelinForwarder: "0x8cbc8B5d71702032904750A66AEfE8B603eBC538",
|
||||
openzeppelinForwarderEOA: "0x119704314Ef304EaAAE4b3c7C9ABd59272A28310",
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
*/
|
||||
export enum ChainId {
|
||||
Mainnet = 1,
|
||||
Rinkeby = 4,
|
||||
Goerli = 5,
|
||||
Polygon = 137,
|
||||
Mumbai = 80001,
|
||||
@@ -15,10 +14,8 @@ export enum ChainId {
|
||||
Avalanche = 43114,
|
||||
AvalancheFujiTestnet = 43113,
|
||||
Optimism = 10,
|
||||
OptimismKovan = 69,
|
||||
OptimismGoerli = 420,
|
||||
Arbitrum = 42161,
|
||||
ArbitrumRinkeby = 421611,
|
||||
ArbitrumGoerli = 421613,
|
||||
BinanceSmartChainMainnet = 56,
|
||||
BinanceSmartChainTestnet = 97,
|
||||
@@ -29,7 +26,6 @@ export enum ChainId {
|
||||
*/
|
||||
export type SUPPORTED_CHAIN_ID =
|
||||
| ChainId.Mainnet
|
||||
| ChainId.Rinkeby
|
||||
| ChainId.Goerli
|
||||
| ChainId.Mumbai
|
||||
| ChainId.Polygon
|
||||
@@ -38,10 +34,8 @@ export type SUPPORTED_CHAIN_ID =
|
||||
| ChainId.Avalanche
|
||||
| ChainId.AvalancheFujiTestnet
|
||||
| ChainId.Optimism
|
||||
| ChainId.OptimismKovan
|
||||
| ChainId.OptimismGoerli
|
||||
| ChainId.Arbitrum
|
||||
| ChainId.ArbitrumRinkeby
|
||||
| ChainId.ArbitrumGoerli
|
||||
| ChainId.BinanceSmartChainMainnet
|
||||
| ChainId.BinanceSmartChainTestnet;
|
||||
@@ -51,7 +45,6 @@ export type SUPPORTED_CHAIN_ID =
|
||||
*/
|
||||
export const SUPPORTED_CHAIN_IDS: SUPPORTED_CHAIN_ID[] = [
|
||||
ChainId.Mainnet,
|
||||
ChainId.Rinkeby,
|
||||
ChainId.Goerli,
|
||||
ChainId.Polygon,
|
||||
ChainId.Mumbai,
|
||||
@@ -60,10 +53,8 @@ export const SUPPORTED_CHAIN_IDS: SUPPORTED_CHAIN_ID[] = [
|
||||
ChainId.Avalanche,
|
||||
ChainId.AvalancheFujiTestnet,
|
||||
ChainId.Optimism,
|
||||
ChainId.OptimismKovan,
|
||||
ChainId.OptimismGoerli,
|
||||
ChainId.Arbitrum,
|
||||
ChainId.ArbitrumRinkeby,
|
||||
ChainId.ArbitrumGoerli,
|
||||
ChainId.BinanceSmartChainMainnet,
|
||||
ChainId.BinanceSmartChainTestnet,
|
||||
|
||||
@@ -24,16 +24,7 @@ export const NATIVE_TOKENS: Record<
|
||||
symbol: "WETH",
|
||||
},
|
||||
},
|
||||
[ChainId.Rinkeby]: {
|
||||
name: "Rinkeby Ether",
|
||||
symbol: "RIN",
|
||||
decimals: 18,
|
||||
wrapped: {
|
||||
address: "0xc778417E063141139Fce010982780140Aa0cD5Ab",
|
||||
name: "Wrapped Ether",
|
||||
symbol: "WETH",
|
||||
},
|
||||
},
|
||||
|
||||
[ChainId.Goerli]: {
|
||||
name: "Görli Ether",
|
||||
symbol: "GOR",
|
||||
@@ -114,16 +105,7 @@ export const NATIVE_TOKENS: Record<
|
||||
symbol: "WETH",
|
||||
},
|
||||
},
|
||||
[ChainId.ArbitrumRinkeby]: {
|
||||
name: "Arbitrum Rinkeby Ether",
|
||||
symbol: "ARETH",
|
||||
decimals: 18,
|
||||
wrapped: {
|
||||
address: "0xEBbc3452Cc911591e4F18f3b36727Df45d6bd1f9",
|
||||
name: "Wrapped Ether",
|
||||
symbol: "WETH",
|
||||
},
|
||||
},
|
||||
|
||||
[ChainId.ArbitrumGoerli]: {
|
||||
name: "Arbitrum Goerli Ether",
|
||||
symbol: "AGOR",
|
||||
@@ -144,16 +126,7 @@ export const NATIVE_TOKENS: Record<
|
||||
symbol: "WETH",
|
||||
},
|
||||
},
|
||||
[ChainId.OptimismKovan]: {
|
||||
name: "Kovan Ether",
|
||||
symbol: "KOR",
|
||||
decimals: 18,
|
||||
wrapped: {
|
||||
address: "0xbC6F6b680bc61e30dB47721c6D1c5cde19C1300d",
|
||||
name: "Wrapped Ether",
|
||||
symbol: "WETH",
|
||||
},
|
||||
},
|
||||
|
||||
[ChainId.OptimismGoerli]: {
|
||||
name: "Goerli Ether",
|
||||
symbol: "ETH",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ALL_ROLES } from "../common/role";
|
||||
import { getSignerAndProvider } from "../core/classes/rpc-connection-handler";
|
||||
import type { ContractType, NetworkOrSignerOrProvider } from "../core/types";
|
||||
import {
|
||||
DropErc1155ContractSchema,
|
||||
@@ -32,12 +33,21 @@ export const EditionDropInitializer = {
|
||||
initialize: async (
|
||||
...[network, address, storage, options]: InitalizeParams
|
||||
) => {
|
||||
const [abi, contract] = await Promise.all([
|
||||
const [, provider] = getSignerAndProvider(network, options);
|
||||
const [abi, contract, _network] = await Promise.all([
|
||||
EditionDropInitializer.getAbi(),
|
||||
import("./prebuilt-implementations/edition-drop"),
|
||||
provider.getNetwork(),
|
||||
]);
|
||||
|
||||
return new contract.EditionDrop(network, address, storage, options, abi);
|
||||
return new contract.EditionDrop(
|
||||
network,
|
||||
address,
|
||||
storage,
|
||||
options,
|
||||
abi,
|
||||
_network.chainId,
|
||||
);
|
||||
},
|
||||
getAbi: async () =>
|
||||
(await import("@thirdweb-dev/contracts-js/dist/abis/DropERC1155.json"))
|
||||
@@ -52,12 +62,21 @@ export const EditionInitializer = {
|
||||
initialize: async (
|
||||
...[network, address, storage, options]: InitalizeParams
|
||||
) => {
|
||||
const [abi, contract] = await Promise.all([
|
||||
const [, provider] = getSignerAndProvider(network, options);
|
||||
const [abi, contract, _network] = await Promise.all([
|
||||
EditionInitializer.getAbi(),
|
||||
import("./prebuilt-implementations/edition"),
|
||||
provider.getNetwork(),
|
||||
]);
|
||||
|
||||
return new contract.Edition(network, address, storage, options, abi);
|
||||
return new contract.Edition(
|
||||
network,
|
||||
address,
|
||||
storage,
|
||||
options,
|
||||
abi,
|
||||
_network.chainId,
|
||||
);
|
||||
},
|
||||
getAbi: async () =>
|
||||
(await import("@thirdweb-dev/contracts-js/dist/abis/TokenERC1155.json"))
|
||||
@@ -72,12 +91,21 @@ export const MarketplaceInitializer = {
|
||||
initialize: async (
|
||||
...[network, address, storage, options]: InitalizeParams
|
||||
) => {
|
||||
const [abi, contract] = await Promise.all([
|
||||
const [, provider] = getSignerAndProvider(network, options);
|
||||
const [abi, contract, _network] = await Promise.all([
|
||||
MarketplaceInitializer.getAbi(),
|
||||
import("./prebuilt-implementations/marketplace"),
|
||||
provider.getNetwork(),
|
||||
]);
|
||||
|
||||
return new contract.Marketplace(network, address, storage, options, abi);
|
||||
return new contract.Marketplace(
|
||||
network,
|
||||
address,
|
||||
storage,
|
||||
options,
|
||||
abi,
|
||||
_network.chainId,
|
||||
);
|
||||
},
|
||||
getAbi: async () =>
|
||||
(await import("@thirdweb-dev/contracts-js/dist/abis/Marketplace.json"))
|
||||
@@ -92,12 +120,21 @@ export const MultiwrapInitializer = {
|
||||
initialize: async (
|
||||
...[network, address, storage, options]: InitalizeParams
|
||||
) => {
|
||||
const [abi, contract] = await Promise.all([
|
||||
const [, provider] = getSignerAndProvider(network, options);
|
||||
const [abi, contract, _network] = await Promise.all([
|
||||
MultiwrapInitializer.getAbi(),
|
||||
import("./prebuilt-implementations/multiwrap"),
|
||||
provider.getNetwork(),
|
||||
]);
|
||||
|
||||
return new contract.Multiwrap(network, address, storage, options, abi);
|
||||
return new contract.Multiwrap(
|
||||
network,
|
||||
address,
|
||||
storage,
|
||||
options,
|
||||
abi,
|
||||
_network.chainId,
|
||||
);
|
||||
},
|
||||
getAbi: async () =>
|
||||
(await import("@thirdweb-dev/contracts-js/dist/abis/Multiwrap.json"))
|
||||
@@ -113,12 +150,21 @@ export const NFTCollectionInitializer = {
|
||||
initialize: async (
|
||||
...[network, address, storage, options]: InitalizeParams
|
||||
) => {
|
||||
const [abi, contract] = await Promise.all([
|
||||
const [, provider] = getSignerAndProvider(network, options);
|
||||
const [abi, contract, _network] = await Promise.all([
|
||||
NFTCollectionInitializer.getAbi(),
|
||||
import("./prebuilt-implementations/nft-collection"),
|
||||
provider.getNetwork(),
|
||||
]);
|
||||
|
||||
return new contract.NFTCollection(network, address, storage, options, abi);
|
||||
return new contract.NFTCollection(
|
||||
network,
|
||||
address,
|
||||
storage,
|
||||
options,
|
||||
abi,
|
||||
_network.chainId,
|
||||
);
|
||||
},
|
||||
getAbi: async () =>
|
||||
(await import("@thirdweb-dev/contracts-js/dist/abis/TokenERC721.json"))
|
||||
@@ -133,12 +179,21 @@ export const NFTDropInitializer = {
|
||||
initialize: async (
|
||||
...[network, address, storage, options]: InitalizeParams
|
||||
) => {
|
||||
const [abi, contract] = await Promise.all([
|
||||
const [, provider] = getSignerAndProvider(network, options);
|
||||
const [abi, contract, _network] = await Promise.all([
|
||||
NFTDropInitializer.getAbi(),
|
||||
import("./prebuilt-implementations/nft-drop"),
|
||||
provider.getNetwork(),
|
||||
]);
|
||||
|
||||
return new contract.NFTDrop(network, address, storage, options, abi);
|
||||
return new contract.NFTDrop(
|
||||
network,
|
||||
address,
|
||||
storage,
|
||||
options,
|
||||
abi,
|
||||
_network.chainId,
|
||||
);
|
||||
},
|
||||
getAbi: async () =>
|
||||
(await import("@thirdweb-dev/contracts-js/dist/abis/DropERC721.json"))
|
||||
@@ -154,12 +209,21 @@ export const PackInitializer = {
|
||||
initialize: async (
|
||||
...[network, address, storage, options]: InitalizeParams
|
||||
) => {
|
||||
const [abi, contract] = await Promise.all([
|
||||
const [, provider] = getSignerAndProvider(network, options);
|
||||
const [abi, contract, _network] = await Promise.all([
|
||||
PackInitializer.getAbi(),
|
||||
import("./prebuilt-implementations/pack"),
|
||||
provider.getNetwork(),
|
||||
]);
|
||||
|
||||
return new contract.Pack(network, address, storage, options, abi);
|
||||
return new contract.Pack(
|
||||
network,
|
||||
address,
|
||||
storage,
|
||||
options,
|
||||
abi,
|
||||
_network.chainId,
|
||||
);
|
||||
},
|
||||
getAbi: async () =>
|
||||
(await import("@thirdweb-dev/contracts-js/dist/abis/Pack.json")).default,
|
||||
@@ -174,12 +238,21 @@ export const SignatureDropInitializer = {
|
||||
initialize: async (
|
||||
...[network, address, storage, options]: InitalizeParams
|
||||
) => {
|
||||
const [abi, contract] = await Promise.all([
|
||||
const [, provider] = getSignerAndProvider(network, options);
|
||||
const [abi, contract, _network] = await Promise.all([
|
||||
SignatureDropInitializer.getAbi(),
|
||||
import("./prebuilt-implementations/signature-drop"),
|
||||
provider.getNetwork(),
|
||||
]);
|
||||
|
||||
return new contract.SignatureDrop(network, address, storage, options, abi);
|
||||
return new contract.SignatureDrop(
|
||||
network,
|
||||
address,
|
||||
storage,
|
||||
options,
|
||||
abi,
|
||||
_network.chainId,
|
||||
);
|
||||
},
|
||||
getAbi: async () =>
|
||||
(await import("@thirdweb-dev/contracts-js/dist/abis/SignatureDrop.json"))
|
||||
@@ -195,12 +268,21 @@ export const SplitInitializer = {
|
||||
initialize: async (
|
||||
...[network, address, storage, options]: InitalizeParams
|
||||
) => {
|
||||
const [abi, contract] = await Promise.all([
|
||||
const [, provider] = getSignerAndProvider(network, options);
|
||||
const [abi, contract, _network] = await Promise.all([
|
||||
SplitInitializer.getAbi(),
|
||||
import("./prebuilt-implementations/split"),
|
||||
provider.getNetwork(),
|
||||
]);
|
||||
|
||||
return new contract.Split(network, address, storage, options, abi);
|
||||
return new contract.Split(
|
||||
network,
|
||||
address,
|
||||
storage,
|
||||
options,
|
||||
abi,
|
||||
_network.chainId,
|
||||
);
|
||||
},
|
||||
getAbi: async () =>
|
||||
(await import("@thirdweb-dev/contracts-js/dist/abis/Split.json")).default,
|
||||
@@ -215,12 +297,21 @@ export const TokenDropInitializer = {
|
||||
initialize: async (
|
||||
...[network, address, storage, options]: InitalizeParams
|
||||
) => {
|
||||
const [abi, contract] = await Promise.all([
|
||||
const [, provider] = getSignerAndProvider(network, options);
|
||||
const [abi, contract, _network] = await Promise.all([
|
||||
TokenDropInitializer.getAbi(),
|
||||
import("./prebuilt-implementations/token-drop"),
|
||||
provider.getNetwork(),
|
||||
]);
|
||||
|
||||
return new contract.TokenDrop(network, address, storage, options, abi);
|
||||
return new contract.TokenDrop(
|
||||
network,
|
||||
address,
|
||||
storage,
|
||||
options,
|
||||
abi,
|
||||
_network.chainId,
|
||||
);
|
||||
},
|
||||
getAbi: async () =>
|
||||
(await import("@thirdweb-dev/contracts-js/dist/abis/DropERC20.json"))
|
||||
@@ -235,12 +326,21 @@ export const TokenInitializer = {
|
||||
initialize: async (
|
||||
...[network, address, storage, options]: InitalizeParams
|
||||
) => {
|
||||
const [abi, contract] = await Promise.all([
|
||||
const [, provider] = getSignerAndProvider(network, options);
|
||||
const [abi, contract, _network] = await Promise.all([
|
||||
TokenInitializer.getAbi(),
|
||||
import("./prebuilt-implementations/token"),
|
||||
provider.getNetwork(),
|
||||
]);
|
||||
|
||||
return new contract.Token(network, address, storage, options, abi);
|
||||
return new contract.Token(
|
||||
network,
|
||||
address,
|
||||
storage,
|
||||
options,
|
||||
abi,
|
||||
_network.chainId,
|
||||
);
|
||||
},
|
||||
getAbi: async () =>
|
||||
(await import("@thirdweb-dev/contracts-js/dist/abis/TokenERC20.json"))
|
||||
@@ -256,12 +356,21 @@ export const VoteInitializer = {
|
||||
initialize: async (
|
||||
...[network, address, storage, options]: InitalizeParams
|
||||
) => {
|
||||
const [abi, contract] = await Promise.all([
|
||||
const [, provider] = getSignerAndProvider(network, options);
|
||||
const [abi, contract, _network] = await Promise.all([
|
||||
VoteInitializer.getAbi(),
|
||||
import("./prebuilt-implementations/vote"),
|
||||
provider.getNetwork(),
|
||||
]);
|
||||
|
||||
return new contract.Vote(network, address, storage, options, abi);
|
||||
return new contract.Vote(
|
||||
network,
|
||||
address,
|
||||
storage,
|
||||
options,
|
||||
abi,
|
||||
_network.chainId,
|
||||
);
|
||||
},
|
||||
getAbi: async () =>
|
||||
(await import("@thirdweb-dev/contracts-js/dist/abis/VoteERC20.json"))
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { QueryAllParams } from "../../../core/schema/QueryParams";
|
||||
import { NFT, NFTMetadata, NFTMetadataOrUri } from "../../../core/schema/nft";
|
||||
import { getRoleHash } from "../../common";
|
||||
import { TransactionTask } from "../../core/classes/TransactionTask";
|
||||
@@ -24,10 +25,9 @@ import {
|
||||
import { PaperCheckout } from "../../integrations/paper-xyz";
|
||||
import { DropErc1155ContractSchema } from "../../schema/contracts/drop-erc1155";
|
||||
import { SDKOptions } from "../../schema/sdk-options";
|
||||
import { QueryAllParams, UploadProgressEvent } from "../../types";
|
||||
import type { DropERC1155 } from "@thirdweb-dev/contracts-js";
|
||||
import type ABI from "@thirdweb-dev/contracts-js/dist/abis/DropERC1155.json";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import { ThirdwebStorage, UploadProgressEvent } from "@thirdweb-dev/storage";
|
||||
import { BigNumber, BigNumberish, CallOverrides, constants } from "ethers";
|
||||
|
||||
/**
|
||||
@@ -39,7 +39,7 @@ import { BigNumber, BigNumberish, CallOverrides, constants } from "ethers";
|
||||
* import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
*
|
||||
* const sdk = new ThirdwebSDK("{{chainName}}");
|
||||
* const contract = sdk.getEditionDrop("{{contract_address}}");
|
||||
* const contract = sdk.getContract("{{contract_address}}", "edition-drop");
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
@@ -125,6 +125,7 @@ export class EditionDrop extends StandardErc1155<DropERC1155> {
|
||||
storage: ThirdwebStorage,
|
||||
options: SDKOptions = {},
|
||||
abi: typeof ABI,
|
||||
chainId: number,
|
||||
contractWrapper = new ContractWrapper<DropERC1155>(
|
||||
network,
|
||||
address,
|
||||
@@ -132,7 +133,7 @@ export class EditionDrop extends StandardErc1155<DropERC1155> {
|
||||
options,
|
||||
),
|
||||
) {
|
||||
super(contractWrapper, storage);
|
||||
super(contractWrapper, storage, chainId);
|
||||
this.abi = abi;
|
||||
this.metadata = new ContractMetadata(
|
||||
this.contractWrapper,
|
||||
@@ -156,7 +157,7 @@ export class EditionDrop extends StandardErc1155<DropERC1155> {
|
||||
this.estimator = new GasCostEstimator(this.contractWrapper);
|
||||
this.platformFees = new ContractPlatformFee(this.contractWrapper);
|
||||
this.interceptor = new ContractInterceptor(this.contractWrapper);
|
||||
this.erc1155 = new Erc1155(this.contractWrapper, this.storage);
|
||||
this.erc1155 = new Erc1155(this.contractWrapper, this.storage, chainId);
|
||||
this.checkout = new PaperCheckout(this.contractWrapper);
|
||||
this.owner = new ContractOwner(this.contractWrapper);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { QueryAllParams } from "../../../core/schema/QueryParams";
|
||||
import { NFT } from "../../../core/schema/nft";
|
||||
import { getRoleHash } from "../../common";
|
||||
import { ContractEncoder } from "../../core/classes/contract-encoder";
|
||||
@@ -22,7 +23,6 @@ import {
|
||||
import { TokenErc1155ContractSchema } from "../../schema/contracts/token-erc1155";
|
||||
import { SDKOptions } from "../../schema/sdk-options";
|
||||
import { EditionMetadataOrUri } from "../../schema/tokens/edition";
|
||||
import { QueryAllParams } from "../../types";
|
||||
import type { TokenERC1155 } from "@thirdweb-dev/contracts-js";
|
||||
import type ABI from "@thirdweb-dev/contracts-js/dist/abis/TokenERC1155.json";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
@@ -37,7 +37,7 @@ import { BigNumber, BigNumberish, CallOverrides, constants } from "ethers";
|
||||
* import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
*
|
||||
* const sdk = new ThirdwebSDK("{{chainName}}");
|
||||
* const contract = sdk.getEdition("{{contract_address}}");
|
||||
* const contract = sdk.getContract("{{contract_address}}", "edition");
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
@@ -105,6 +105,7 @@ export class Edition extends StandardErc1155<TokenERC1155> {
|
||||
storage: ThirdwebStorage,
|
||||
options: SDKOptions = {},
|
||||
abi: typeof ABI,
|
||||
chainId: number,
|
||||
contractWrapper = new ContractWrapper<TokenERC1155>(
|
||||
network,
|
||||
address,
|
||||
@@ -112,7 +113,7 @@ export class Edition extends StandardErc1155<TokenERC1155> {
|
||||
options,
|
||||
),
|
||||
) {
|
||||
super(contractWrapper, storage);
|
||||
super(contractWrapper, storage, chainId);
|
||||
this.abi = abi;
|
||||
this.metadata = new ContractMetadata(
|
||||
this.contractWrapper,
|
||||
@@ -132,7 +133,7 @@ export class Edition extends StandardErc1155<TokenERC1155> {
|
||||
this.storage,
|
||||
this.roles,
|
||||
);
|
||||
this.erc1155 = new Erc1155(this.contractWrapper, this.storage);
|
||||
this.erc1155 = new Erc1155(this.contractWrapper, this.storage, chainId);
|
||||
this.owner = new ContractOwner(this.contractWrapper);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { DEFAULT_QUERY_ALL_COUNT } from "../../../core/schema/QueryParams";
|
||||
import { ListingNotFoundError } from "../../common";
|
||||
import { mapOffer } from "../../common/marketplace";
|
||||
import { getRoleHash } from "../../common/role";
|
||||
@@ -16,7 +17,6 @@ import { NetworkOrSignerOrProvider, TransactionResult } from "../../core/types";
|
||||
import { ListingType } from "../../enums";
|
||||
import { MarketplaceContractSchema } from "../../schema/contracts/marketplace";
|
||||
import { SDKOptions } from "../../schema/sdk-options";
|
||||
import { DEFAULT_QUERY_ALL_COUNT } from "../../types/QueryParams";
|
||||
import { AuctionListing, DirectListing, Offer } from "../../types/marketplace";
|
||||
import { MarketplaceFilter } from "../../types/marketplace/MarketPlaceFilter";
|
||||
import { UnmappedOffer } from "../../types/marketplace/UnmappedOffer";
|
||||
@@ -36,7 +36,7 @@ import invariant from "tiny-invariant";
|
||||
* import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
*
|
||||
* const sdk = new ThirdwebSDK("{{chainName}}");
|
||||
* const contract = sdk.getMarketplace("{{contract_address}}");
|
||||
* const contract = sdk.getContract("{{contract_address}}", "marketplace");
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
@@ -135,12 +135,18 @@ export class Marketplace implements UpdateableNetwork {
|
||||
*/
|
||||
public auction: MarketplaceAuction;
|
||||
|
||||
private _chainId;
|
||||
get chainId() {
|
||||
return this._chainId;
|
||||
}
|
||||
|
||||
constructor(
|
||||
network: NetworkOrSignerOrProvider,
|
||||
address: string,
|
||||
storage: ThirdwebStorage,
|
||||
options: SDKOptions = {},
|
||||
abi: typeof ABI,
|
||||
chainId: number,
|
||||
contractWrapper = new ContractWrapper<MarketplaceContract>(
|
||||
network,
|
||||
address,
|
||||
@@ -148,6 +154,7 @@ export class Marketplace implements UpdateableNetwork {
|
||||
options,
|
||||
),
|
||||
) {
|
||||
this._chainId = chainId;
|
||||
this.abi = abi;
|
||||
this.contractWrapper = contractWrapper;
|
||||
this.storage = storage;
|
||||
|
||||
@@ -47,7 +47,7 @@ import { BigNumberish, CallOverrides, ethers } from "ethers";
|
||||
* import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
*
|
||||
* const sdk = new ThirdwebSDK("{{chainName}}");
|
||||
* const contract = sdk.getMultiwrap("{{contract_address}}");
|
||||
* const contract = sdk.getContract("{{contract_address}}", "multiwrap");
|
||||
* ```
|
||||
*
|
||||
* @beta
|
||||
@@ -103,6 +103,7 @@ export class Multiwrap extends StandardErc721<MultiwrapContract> {
|
||||
storage: ThirdwebStorage,
|
||||
options: SDKOptions = {},
|
||||
abi: typeof ABI,
|
||||
chainId: number,
|
||||
contractWrapper = new ContractWrapper<MultiwrapContract>(
|
||||
network,
|
||||
address,
|
||||
@@ -110,7 +111,8 @@ export class Multiwrap extends StandardErc721<MultiwrapContract> {
|
||||
options,
|
||||
),
|
||||
) {
|
||||
super(contractWrapper, storage);
|
||||
super(contractWrapper, storage, chainId);
|
||||
|
||||
this.abi = abi;
|
||||
this.metadata = new ContractMetadata(
|
||||
this.contractWrapper,
|
||||
|
||||
@@ -35,7 +35,7 @@ import { BigNumberish, CallOverrides, constants } from "ethers";
|
||||
* import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
*
|
||||
* const sdk = new ThirdwebSDK("{{chainName}}");
|
||||
* const contract = sdk.getNFTCollection("{{contract_address}}");
|
||||
* const contract = sdk.getContract("{{contract_address}}", "nft-collection");
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
@@ -108,6 +108,7 @@ export class NFTCollection extends StandardErc721<TokenERC721> {
|
||||
storage: ThirdwebStorage,
|
||||
options: SDKOptions = {},
|
||||
abi: typeof ABI,
|
||||
chainId: number,
|
||||
contractWrapper = new ContractWrapper<TokenERC721>(
|
||||
network,
|
||||
address,
|
||||
@@ -115,7 +116,8 @@ export class NFTCollection extends StandardErc721<TokenERC721> {
|
||||
options,
|
||||
),
|
||||
) {
|
||||
super(contractWrapper, storage);
|
||||
super(contractWrapper, storage, chainId);
|
||||
|
||||
this.abi = abi;
|
||||
this.metadata = new ContractMetadata(
|
||||
this.contractWrapper,
|
||||
@@ -133,7 +135,7 @@ export class NFTCollection extends StandardErc721<TokenERC721> {
|
||||
this.events = new ContractEvents(this.contractWrapper);
|
||||
this.platformFees = new ContractPlatformFee(this.contractWrapper);
|
||||
this.interceptor = new ContractInterceptor(this.contractWrapper);
|
||||
this.erc721 = new Erc721(this.contractWrapper, this.storage);
|
||||
this.erc721 = new Erc721(this.contractWrapper, this.storage, chainId);
|
||||
this.signature = new Erc721WithQuantitySignatureMintable(
|
||||
this.contractWrapper,
|
||||
this.storage,
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import {
|
||||
DEFAULT_QUERY_ALL_COUNT,
|
||||
QueryAllParams,
|
||||
} from "../../../core/schema/QueryParams";
|
||||
import { NFT, NFTMetadata, NFTMetadataOrUri } from "../../../core/schema/nft";
|
||||
import { getRoleHash } from "../../common";
|
||||
import { prepareClaim } from "../../common/claim-conditions";
|
||||
@@ -28,10 +32,6 @@ import { PaperCheckout } from "../../integrations/paper-xyz";
|
||||
import { DropErc721ContractSchema } from "../../schema/contracts/drop-erc721";
|
||||
import { SDKOptions } from "../../schema/sdk-options";
|
||||
import { ClaimVerification } from "../../types";
|
||||
import {
|
||||
DEFAULT_QUERY_ALL_COUNT,
|
||||
QueryAllParams,
|
||||
} from "../../types/QueryParams";
|
||||
import { UploadProgressEvent } from "../../types/events";
|
||||
import type { DropERC721 } from "@thirdweb-dev/contracts-js";
|
||||
import type ABI from "@thirdweb-dev/contracts-js/dist/abis/DropERC721.json";
|
||||
@@ -54,7 +54,7 @@ import {
|
||||
* import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
*
|
||||
* const sdk = new ThirdwebSDK("{{chainName}}");
|
||||
* const contract = sdk.getNFTDrop("{{contract_address}}");
|
||||
* const contract = sdk.getContract("{{contract_address}}", "nft-drop");
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
@@ -169,6 +169,7 @@ export class NFTDrop extends StandardErc721<DropERC721> {
|
||||
storage: ThirdwebStorage,
|
||||
options: SDKOptions = {},
|
||||
abi: typeof ABI,
|
||||
chainId: number,
|
||||
contractWrapper = new ContractWrapper<DropERC721>(
|
||||
network,
|
||||
address,
|
||||
@@ -176,7 +177,7 @@ export class NFTDrop extends StandardErc721<DropERC721> {
|
||||
options,
|
||||
),
|
||||
) {
|
||||
super(contractWrapper, storage);
|
||||
super(contractWrapper, storage, chainId);
|
||||
this.abi = abi;
|
||||
this.metadata = new ContractMetadata(
|
||||
this.contractWrapper,
|
||||
@@ -195,7 +196,7 @@ export class NFTDrop extends StandardErc721<DropERC721> {
|
||||
this.estimator = new GasCostEstimator(this.contractWrapper);
|
||||
this.events = new ContractEvents(this.contractWrapper);
|
||||
this.platformFees = new ContractPlatformFee(this.contractWrapper);
|
||||
this.erc721 = new Erc721(this.contractWrapper, this.storage);
|
||||
this.erc721 = new Erc721(this.contractWrapper, this.storage, chainId);
|
||||
this.revealer = new DelayedReveal<DropERC721>(
|
||||
this.contractWrapper,
|
||||
this.storage,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { QueryAllParams } from "../../../core/schema/QueryParams";
|
||||
import { NFT } from "../../../core/schema/nft";
|
||||
import {
|
||||
fetchCurrencyMetadata,
|
||||
@@ -31,7 +32,6 @@ import {
|
||||
PackRewardsOutput,
|
||||
PackRewardsOutputSchema,
|
||||
} from "../../schema/tokens/pack";
|
||||
import { QueryAllParams } from "../../types";
|
||||
import type { Pack as PackContract } from "@thirdweb-dev/contracts-js";
|
||||
import type ABI from "@thirdweb-dev/contracts-js/dist/abis/Pack.json";
|
||||
import { PackUpdatedEvent } from "@thirdweb-dev/contracts-js/dist/declarations/src/IPack";
|
||||
@@ -52,7 +52,7 @@ import { BigNumber, BigNumberish, CallOverrides, ethers } from "ethers";
|
||||
* import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
*
|
||||
* const sdk = new ThirdwebSDK("{{chainName}}");
|
||||
* const contract = sdk.getPack("{{contract_address}}");
|
||||
* const contract = sdk.getContract("{{contract_address}}", "pack");
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
@@ -98,6 +98,7 @@ export class Pack extends StandardErc1155<PackContract> {
|
||||
storage: ThirdwebStorage,
|
||||
options: SDKOptions = {},
|
||||
abi: typeof ABI,
|
||||
chainId: number,
|
||||
contractWrapper = new ContractWrapper<PackContract>(
|
||||
network,
|
||||
address,
|
||||
@@ -115,9 +116,9 @@ export class Pack extends StandardErc1155<PackContract> {
|
||||
: options,
|
||||
),
|
||||
) {
|
||||
super(contractWrapper, storage);
|
||||
super(contractWrapper, storage, chainId);
|
||||
this.abi = abi;
|
||||
this.erc1155 = new Erc1155(this.contractWrapper, this.storage);
|
||||
this.erc1155 = new Erc1155(this.contractWrapper, this.storage, chainId);
|
||||
this.metadata = new ContractMetadata(
|
||||
this.contractWrapper,
|
||||
PackContractSchema,
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import {
|
||||
DEFAULT_QUERY_ALL_COUNT,
|
||||
QueryAllParams,
|
||||
} from "../../../core/schema/QueryParams";
|
||||
import { NFT, NFTMetadata, NFTMetadataOrUri } from "../../../core/schema/nft";
|
||||
import { getRoleHash } from "../../common";
|
||||
import { FEATURE_NFT_REVEALABLE } from "../../constants/erc721-features";
|
||||
@@ -27,10 +31,6 @@ import { PaperCheckout } from "../../integrations/paper-xyz";
|
||||
import { DropErc721ContractSchema } from "../../schema/contracts/drop-erc721";
|
||||
import { SDKOptions } from "../../schema/sdk-options";
|
||||
import { ClaimOptions, UploadProgressEvent } from "../../types";
|
||||
import {
|
||||
DEFAULT_QUERY_ALL_COUNT,
|
||||
QueryAllParams,
|
||||
} from "../../types/QueryParams";
|
||||
import type { SignatureDrop as SignatureDropContract } from "@thirdweb-dev/contracts-js";
|
||||
import type ABI from "@thirdweb-dev/contracts-js/dist/abis/SignatureDrop.json";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
@@ -47,7 +47,7 @@ import { BigNumber, BigNumberish, CallOverrides, constants } from "ethers";
|
||||
* import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
*
|
||||
* const sdk = new ThirdwebSDK("{{chainName}}");
|
||||
* const contract = sdk.getSignatureDrop("{{contract_address}}");
|
||||
* const contract = sdk.getContract("{{contract_address}}", "signature-drop");
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
@@ -172,6 +172,7 @@ export class SignatureDrop extends StandardErc721<SignatureDropContract> {
|
||||
storage: ThirdwebStorage,
|
||||
options: SDKOptions = {},
|
||||
abi: typeof ABI,
|
||||
chainId: number,
|
||||
contractWrapper = new ContractWrapper<SignatureDropContract>(
|
||||
network,
|
||||
address,
|
||||
@@ -179,7 +180,7 @@ export class SignatureDrop extends StandardErc721<SignatureDropContract> {
|
||||
options,
|
||||
),
|
||||
) {
|
||||
super(contractWrapper, storage);
|
||||
super(contractWrapper, storage, chainId);
|
||||
this.abi = abi;
|
||||
this.metadata = new ContractMetadata(
|
||||
this.contractWrapper,
|
||||
@@ -197,7 +198,7 @@ export class SignatureDrop extends StandardErc721<SignatureDropContract> {
|
||||
this.events = new ContractEvents(this.contractWrapper);
|
||||
this.platformFees = new ContractPlatformFee(this.contractWrapper);
|
||||
this.interceptor = new ContractInterceptor(this.contractWrapper);
|
||||
this.erc721 = new Erc721(this.contractWrapper, this.storage);
|
||||
this.erc721 = new Erc721(this.contractWrapper, this.storage, chainId);
|
||||
this.claimConditions = new DropClaimConditions(
|
||||
this.contractWrapper,
|
||||
this.metadata,
|
||||
|
||||
@@ -30,7 +30,7 @@ import { BigNumber, CallOverrides, Contract } from "ethers";
|
||||
* import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
*
|
||||
* const sdk = new ThirdwebSDK("{{chainName}}");
|
||||
* const contract = sdk.getSplit("{{contract_address}}");
|
||||
* const contract = sdk.getContract("{{contract_address}}", "split");
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
@@ -55,12 +55,18 @@ export class Split implements UpdateableNetwork {
|
||||
*/
|
||||
public interceptor: ContractInterceptor<SplitContract>;
|
||||
|
||||
private _chainId: number;
|
||||
get chainId() {
|
||||
return this._chainId;
|
||||
}
|
||||
|
||||
constructor(
|
||||
network: NetworkOrSignerOrProvider,
|
||||
address: string,
|
||||
storage: ThirdwebStorage,
|
||||
options: SDKOptions = {},
|
||||
abi: typeof ABI,
|
||||
chainId: number,
|
||||
contractWrapper = new ContractWrapper<SplitContract>(
|
||||
network,
|
||||
address,
|
||||
@@ -68,6 +74,7 @@ export class Split implements UpdateableNetwork {
|
||||
options,
|
||||
),
|
||||
) {
|
||||
this._chainId = chainId;
|
||||
this.abi = abi;
|
||||
this.contractWrapper = contractWrapper;
|
||||
this.storage = storage;
|
||||
|
||||
@@ -28,7 +28,7 @@ import { CallOverrides, constants } from "ethers";
|
||||
* import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
*
|
||||
* const sdk = new ThirdwebSDK("{{chainName}}");
|
||||
* const contract = sdk.getTokenDrop("{{contract_address}}");
|
||||
* const contract = sdk.getContract("{{contract_address}}", "token-drop");
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
@@ -80,6 +80,7 @@ export class TokenDrop extends StandardErc20<DropERC20> {
|
||||
storage: ThirdwebStorage,
|
||||
options: SDKOptions = {},
|
||||
abi: typeof ABI,
|
||||
chainId: number,
|
||||
contractWrapper = new ContractWrapper<DropERC20>(
|
||||
network,
|
||||
address,
|
||||
@@ -87,7 +88,7 @@ export class TokenDrop extends StandardErc20<DropERC20> {
|
||||
options,
|
||||
),
|
||||
) {
|
||||
super(contractWrapper, storage);
|
||||
super(contractWrapper, storage, chainId);
|
||||
this.abi = abi;
|
||||
this.metadata = new ContractMetadata(
|
||||
this.contractWrapper,
|
||||
|
||||
@@ -30,7 +30,7 @@ import { CallOverrides, constants } from "ethers";
|
||||
* import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
*
|
||||
* const sdk = new ThirdwebSDK("{{chainName}}");
|
||||
* const contract = sdk.getToken("{{contract_address}}");
|
||||
* const contract = sdk.getContract("{{contract_address}}", "token");
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
@@ -75,6 +75,7 @@ export class Token extends StandardErc20<TokenERC20> {
|
||||
storage: ThirdwebStorage,
|
||||
options: SDKOptions = {},
|
||||
abi: typeof ABI,
|
||||
chainId: number,
|
||||
contractWrapper = new ContractWrapper<TokenERC20>(
|
||||
network,
|
||||
address,
|
||||
@@ -82,7 +83,7 @@ export class Token extends StandardErc20<TokenERC20> {
|
||||
options,
|
||||
),
|
||||
) {
|
||||
super(contractWrapper, storage);
|
||||
super(contractWrapper, storage, chainId);
|
||||
this.abi = abi;
|
||||
this.metadata = new ContractMetadata(
|
||||
this.contractWrapper,
|
||||
|
||||
@@ -46,7 +46,7 @@ import {
|
||||
* import { ThirdwebSDK } from "@thirdweb-dev/sdk";
|
||||
*
|
||||
* const sdk = new ThirdwebSDK("{{chainName}}");
|
||||
* const contract = sdk.getVote("{{contract_address}}");
|
||||
* const contract = sdk.getContract("{{contract_address}}", "vote");
|
||||
* ```
|
||||
*
|
||||
* @public
|
||||
@@ -65,12 +65,18 @@ export class Vote implements UpdateableNetwork {
|
||||
*/
|
||||
public interceptor: ContractInterceptor<VoteERC20>;
|
||||
|
||||
private _chainId: number;
|
||||
get chainId() {
|
||||
return this._chainId;
|
||||
}
|
||||
|
||||
constructor(
|
||||
network: NetworkOrSignerOrProvider,
|
||||
address: string,
|
||||
storage: ThirdwebStorage,
|
||||
options: SDKOptions = {},
|
||||
abi: typeof ABI,
|
||||
chainId: number,
|
||||
contractWrapper = new ContractWrapper<VoteERC20>(
|
||||
network,
|
||||
address,
|
||||
@@ -78,6 +84,7 @@ export class Vote implements UpdateableNetwork {
|
||||
options,
|
||||
),
|
||||
) {
|
||||
this._chainId = chainId;
|
||||
this.abi = abi;
|
||||
this.contractWrapper = contractWrapper;
|
||||
this.storage = storage;
|
||||
|
||||
@@ -148,12 +148,18 @@ export class SmartContract<TContract extends BaseContract = BaseContract>
|
||||
return assertEnabled(this.detectErc1155(), FEATURE_EDITION);
|
||||
}
|
||||
|
||||
private _chainId: number;
|
||||
get chainId() {
|
||||
return this._chainId;
|
||||
}
|
||||
|
||||
constructor(
|
||||
network: NetworkOrSignerOrProvider,
|
||||
address: string,
|
||||
abi: ContractInterface,
|
||||
storage: ThirdwebStorage,
|
||||
options: SDKOptions = {},
|
||||
chainId: number,
|
||||
contractWrapper = new ContractWrapper<TContract>(
|
||||
network,
|
||||
address,
|
||||
@@ -161,6 +167,7 @@ export class SmartContract<TContract extends BaseContract = BaseContract>
|
||||
options,
|
||||
),
|
||||
) {
|
||||
this._chainId = chainId;
|
||||
this.storage = storage;
|
||||
this.contractWrapper = contractWrapper;
|
||||
this.abi = abi;
|
||||
@@ -264,21 +271,21 @@ export class SmartContract<TContract extends BaseContract = BaseContract>
|
||||
|
||||
private detectErc20() {
|
||||
if (detectContractFeature<BaseERC20>(this.contractWrapper, "ERC20")) {
|
||||
return new Erc20(this.contractWrapper, this.storage);
|
||||
return new Erc20(this.contractWrapper, this.storage, this.chainId);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private detectErc721() {
|
||||
if (detectContractFeature<BaseERC721>(this.contractWrapper, "ERC721")) {
|
||||
return new Erc721(this.contractWrapper, this.storage);
|
||||
return new Erc721(this.contractWrapper, this.storage, this.chainId);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private detectErc1155() {
|
||||
if (detectContractFeature<BaseERC1155>(this.contractWrapper, "ERC1155")) {
|
||||
return new Erc1155(this.contractWrapper, this.storage);
|
||||
return new Erc1155(this.contractWrapper, this.storage, this.chainId);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ import { UserWallet } from "../wallet";
|
||||
* // And the server can use the following function to authenticate a token and verify the associated address
|
||||
* const address = sdk.auth.authenticate(domain, token);
|
||||
* ```
|
||||
* @beta
|
||||
* @public
|
||||
*/
|
||||
export class WalletAuthenticator extends RPCConnectionHandler {
|
||||
private wallet: UserWallet;
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import {
|
||||
DEFAULT_QUERY_ALL_COUNT,
|
||||
QueryAllParams,
|
||||
} from "../../../core/schema/QueryParams";
|
||||
import { NFT } from "../../../core/schema/nft";
|
||||
import { FEATURE_EDITION_ENUMERABLE } from "../../constants/erc1155-features";
|
||||
import { DEFAULT_QUERY_ALL_COUNT, QueryAllParams } from "../../types";
|
||||
import { BaseERC1155 } from "../../types/eips";
|
||||
import { DetectableFeature } from "../interfaces/DetectableFeature";
|
||||
import { ContractWrapper } from "./contract-wrapper";
|
||||
|
||||
@@ -29,10 +29,20 @@ export class StandardErc1155<
|
||||
protected storage: ThirdwebStorage;
|
||||
public erc1155: Erc1155;
|
||||
|
||||
constructor(contractWrapper: ContractWrapper<T>, storage: ThirdwebStorage) {
|
||||
private _chainId: number;
|
||||
get chainId() {
|
||||
return this._chainId;
|
||||
}
|
||||
|
||||
constructor(
|
||||
contractWrapper: ContractWrapper<T>,
|
||||
storage: ThirdwebStorage,
|
||||
chainId: number,
|
||||
) {
|
||||
this.contractWrapper = contractWrapper;
|
||||
this.storage = storage;
|
||||
this.erc1155 = new Erc1155(this.contractWrapper, this.storage);
|
||||
this.erc1155 = new Erc1155(this.contractWrapper, this.storage, chainId);
|
||||
this._chainId = chainId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { QueryAllParams } from "../../../core/schema/QueryParams";
|
||||
import { NFT, NFTMetadata, NFTMetadataOrUri } from "../../../core/schema/nft";
|
||||
import {
|
||||
assertEnabled,
|
||||
@@ -21,7 +22,7 @@ import {
|
||||
} from "../../constants/erc1155-features";
|
||||
import { AirdropInputSchema } from "../../schema/contracts/common/airdrop";
|
||||
import { EditionMetadataOrUri } from "../../schema/tokens/edition";
|
||||
import { ClaimOptions, QueryAllParams, UploadProgressEvent } from "../../types";
|
||||
import { ClaimOptions, UploadProgressEvent } from "../../types";
|
||||
import { AirdropInput } from "../../types/airdrop/airdrop";
|
||||
import {
|
||||
BaseDropERC1155,
|
||||
@@ -78,7 +79,16 @@ export class Erc1155<
|
||||
protected contractWrapper: ContractWrapper<T>;
|
||||
protected storage: ThirdwebStorage;
|
||||
|
||||
constructor(contractWrapper: ContractWrapper<T>, storage: ThirdwebStorage) {
|
||||
private _chainId: number;
|
||||
get chainId() {
|
||||
return this._chainId;
|
||||
}
|
||||
|
||||
constructor(
|
||||
contractWrapper: ContractWrapper<T>,
|
||||
storage: ThirdwebStorage,
|
||||
chainId: number,
|
||||
) {
|
||||
this.contractWrapper = contractWrapper;
|
||||
this.storage = storage;
|
||||
this.query = this.detectErc1155Enumerable();
|
||||
@@ -86,6 +96,7 @@ export class Erc1155<
|
||||
this.burnable = this.detectErc1155Burnable();
|
||||
this.lazyMintable = this.detectErc1155LazyMintable();
|
||||
this.signatureMintable = this.detectErc1155SignatureMintable();
|
||||
this._chainId = chainId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user