Compare commits
115
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b1d62b323 | ||
|
|
e78da6b36c | ||
|
|
ed711c8cb2 | ||
|
|
05a7495a13 | ||
|
|
11bb053246 | ||
|
|
efb3546ec8 | ||
|
|
0a5d2b5bdd | ||
|
|
ac3e019cd1 | ||
|
|
3c5dc4804a | ||
|
|
30ac3aef84 | ||
|
|
ef4cb09219 | ||
|
|
ad7dae3b16 | ||
|
|
0fd8aa04a9 | ||
|
|
620e89dc25 | ||
|
|
86d33c4b3e | ||
|
|
d43f6171d9 | ||
|
|
06ca1c407d | ||
|
|
c578a437cc | ||
|
|
0c5b03b8d6 | ||
|
|
9af346eead | ||
|
|
d9fb134ad4 | ||
|
|
1c7264b403 | ||
|
|
a140ee99b2 | ||
|
|
6e1fe6e582 | ||
|
|
536b0f1240 | ||
|
|
b626782b0e | ||
|
|
1d76334dd3 | ||
|
|
d498c79a91 | ||
|
|
736b45ac8e | ||
|
|
b5e1d3bb2b | ||
|
|
6816219ac1 | ||
|
|
48065bcd91 | ||
|
|
a388d07a3d | ||
|
|
483e2b9109 | ||
|
|
f7f4f20737 | ||
|
|
6aa6f7e0bd | ||
|
|
d4d9550713 | ||
|
|
3cb298ac4b | ||
|
|
c747670b98 | ||
|
|
c08e6ba988 | ||
|
|
60fb188943 | ||
|
|
1ce8558df4 | ||
|
|
3ce5f9a0c3 | ||
|
|
3d615a62d0 | ||
|
|
6ce366f59e | ||
|
|
8a2d92046a | ||
|
|
45ae105ed3 | ||
|
|
23d61cfeff | ||
|
|
990c665de9 | ||
|
|
08eaefcf0b | ||
|
|
3d62278aba | ||
|
|
3ab7d1e975 | ||
|
|
c6f44722f9 | ||
|
|
e0ce4a3759 | ||
|
|
04416e7c93 | ||
|
|
5166b24a48 | ||
|
|
bb7ca20e49 | ||
|
|
f41f1a2958 | ||
|
|
d9b7360d1d | ||
|
|
8941b22682 | ||
|
|
f61beace93 | ||
|
|
08403dd9da | ||
|
|
36f3191f3e | ||
|
|
7d2a446ece | ||
|
|
ab575726fe | ||
|
|
8e28b0f5e7 | ||
|
|
e7f1ce43b0 | ||
|
|
224b7241dc | ||
|
|
a0eee749a2 | ||
|
|
20bbad1abc | ||
|
|
a430160e6b | ||
|
|
5745481584 | ||
|
|
afdedb1feb | ||
|
|
01293857fa | ||
|
|
ecdcf82cf3 | ||
|
|
12b07aad9a | ||
|
|
c0e2c9457f | ||
|
|
654b8ab351 | ||
|
|
a5578abf66 | ||
|
|
541e488d5b | ||
|
|
088f2567f6 | ||
|
|
6803e8ca09 | ||
|
|
d60e544a24 | ||
|
|
cc20f93e17 | ||
|
|
329bccec4b | ||
|
|
02d55a063e | ||
|
|
73bee2bed1 | ||
|
|
2a443365bd | ||
|
|
ed47fd5310 | ||
|
|
2a0294d8e6 | ||
|
|
65ecf072eb | ||
|
|
9ce3eb6aad | ||
|
|
e32faeb57a | ||
|
|
6a19426200 | ||
|
|
2bcad4b716 | ||
|
|
193de1e9d8 | ||
|
|
645b0303cc | ||
|
|
16232de9ea | ||
|
|
52056edfd6 | ||
|
|
dec4c4a8cf | ||
|
|
9a015a23cd | ||
|
|
15ef4779e0 | ||
|
|
b8498c2a10 | ||
|
|
56f85e57df | ||
|
|
197a6838f6 | ||
|
|
3bf7f37593 | ||
|
|
6803c3e97c | ||
|
|
b672860397 | ||
|
|
ab14cd8938 | ||
|
|
8687d6ac3a | ||
|
|
a5f16b6dc5 | ||
|
|
6a91b6a025 | ||
|
|
54cfd6d891 | ||
|
|
522453fd56 | ||
|
|
0cba69ca40 |
@@ -59,9 +59,15 @@ To begin:
|
||||
```
|
||||
pnpm install
|
||||
```
|
||||
If you are on windows, use the `--ignore-scripts` flag
|
||||
```
|
||||
pnpm install --ignore-scripts
|
||||
```
|
||||
|
||||
Now you have got the repo on your local machine, and you're ready to start making your changes!
|
||||
|
||||
<br/>
|
||||
|
||||
### Test Your Changes
|
||||
|
||||
We use [yalc](https://github.com/wclr/yalc) to test changes locally.
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@
|
||||
"@playwright/test": "1.31.2",
|
||||
"@trivago/prettier-plugin-sort-imports": "^4.1.1",
|
||||
"@types/node": "^18.15.11",
|
||||
"eslint": "^8.37.0",
|
||||
"eslint": "^8.42.0",
|
||||
"mocha": "^10.2.0",
|
||||
"prettier": "^2.8.7",
|
||||
"turbo": "^1.9.8",
|
||||
|
||||
@@ -1,5 +1,71 @@
|
||||
# @thirdweb-dev/auth
|
||||
|
||||
## 3.2.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ed711c8c`](https://github.com/thirdweb-dev/js/commit/ed711c8cb2ed6a0deb1b2a5eeec06df1d4edc5e8), [`05a7495a`](https://github.com/thirdweb-dev/js/commit/05a7495a132aabab5f48abbdb80a468ff6f65df8), [`e78da6b3`](https://github.com/thirdweb-dev/js/commit/e78da6b36cfa6d954234820563201bf760186ed1)]:
|
||||
- @thirdweb-dev/wallets@1.0.2
|
||||
|
||||
## 3.2.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`efb3546e`](https://github.com/thirdweb-dev/js/commit/efb3546ec8268156be00301af28b9d83ecd5ab08)]:
|
||||
- @thirdweb-dev/wallets@1.0.1
|
||||
|
||||
## 3.2.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1250](https://github.com/thirdweb-dev/js/pull/1250) [`d43f6171`](https://github.com/thirdweb-dev/js/commit/d43f6171d910e31b748b171b012174390aac3fff) Thanks [@adam-maj](https://github.com/adam-maj)! - Allow setting login payload validity duration
|
||||
|
||||
- Updated dependencies [[`ac3e019c`](https://github.com/thirdweb-dev/js/commit/ac3e019cd1776dbdb0d06b213420ad17586f678e), [`3c5dc480`](https://github.com/thirdweb-dev/js/commit/3c5dc4804abc56b933ec45e9e1da11eb182296cc)]:
|
||||
- @thirdweb-dev/wallets@1.0.0
|
||||
|
||||
## 3.2.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`536b0f12`](https://github.com/thirdweb-dev/js/commit/536b0f1240ab446aac22cf547a4e09e73ee6bf7b), [`b626782b`](https://github.com/thirdweb-dev/js/commit/b626782b0e8c6b76673472d3aee1c802dfb11b5f)]:
|
||||
- @thirdweb-dev/wallets@0.3.3
|
||||
|
||||
## 3.2.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3cb298ac`](https://github.com/thirdweb-dev/js/commit/3cb298ac4b04d295899b5ac77c7fc5869ec2f5f2), [`3ce5f9a0`](https://github.com/thirdweb-dev/js/commit/3ce5f9a0c3fc7e99b5abf691a87048ab8475f6b1), [`a388d07a`](https://github.com/thirdweb-dev/js/commit/a388d07a3d449e56dc53fed9600931022f4a15e1), [`1ce8558d`](https://github.com/thirdweb-dev/js/commit/1ce8558df47186bcba5ee8564fdb04583bf115dd), [`60fb1889`](https://github.com/thirdweb-dev/js/commit/60fb18894372f14d9cd815fa9a239926d31bb273)]:
|
||||
- @thirdweb-dev/wallets@0.3.2
|
||||
|
||||
## 3.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3d62278a`](https://github.com/thirdweb-dev/js/commit/3d62278aba79101ae1158fb726d6ddfed505c939)]:
|
||||
- @thirdweb-dev/wallets@0.3.1
|
||||
|
||||
## 3.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#1150](https://github.com/thirdweb-dev/js/pull/1150) [`d60e544a`](https://github.com/thirdweb-dev/js/commit/d60e544a240b93312743e62096ee2dc77d0c1bd1) Thanks [@adam-maj](https://github.com/adam-maj)! - Add support for multipled logged in accounts and token refreshing to auth
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1165](https://github.com/thirdweb-dev/js/pull/1165) [`088f2567`](https://github.com/thirdweb-dev/js/commit/088f2567f615360edd44776b20ae0bedff250f43) Thanks [@adam-maj](https://github.com/adam-maj)! - Include chain id in login payload
|
||||
|
||||
- Updated dependencies [[`654b8ab3`](https://github.com/thirdweb-dev/js/commit/654b8ab35184e02127a5a47f05d78606dd5b29ca), [`329bccec`](https://github.com/thirdweb-dev/js/commit/329bccec4b88b02db5bac6c1415158928843376a)]:
|
||||
- @thirdweb-dev/wallets@0.3.0
|
||||
|
||||
## 3.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1126](https://github.com/thirdweb-dev/js/pull/1126) [`ab14cd89`](https://github.com/thirdweb-dev/js/commit/ab14cd89385aefad7f32e20a22baa9fce42b98e2) Thanks [@adam-maj](https://github.com/adam-maj)! - Add expiration date to cookie
|
||||
|
||||
- Updated dependencies [[`2a443365`](https://github.com/thirdweb-dev/js/commit/2a443365bdc3d47d0f41fc895f70256dcde423f5), [`197a6838`](https://github.com/thirdweb-dev/js/commit/197a6838f69ae8b9ad46524e7c469fc757d0a2cb)]:
|
||||
- @thirdweb-dev/wallets@0.2.26
|
||||
|
||||
## 3.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/auth",
|
||||
"version": "3.1.0",
|
||||
"version": "3.2.6",
|
||||
"main": "dist/thirdweb-dev-auth.cjs.js",
|
||||
"module": "dist/thirdweb-dev-auth.esm.js",
|
||||
"browser": {
|
||||
@@ -101,7 +101,7 @@
|
||||
"@typescript-eslint/parser": "^5.33.0",
|
||||
"chai": "^4.3.6",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"eslint": "^8.21.0",
|
||||
"eslint": "^8.42.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-config-thirdweb": "workspace:*",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
const THIRDWEB_AUTH_COOKIE_PREFIX = `thirdweb_auth`;
|
||||
export const THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX = `${THIRDWEB_AUTH_COOKIE_PREFIX}_token`;
|
||||
export const THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE = `${THIRDWEB_AUTH_COOKIE_PREFIX}_active_account`;
|
||||
|
||||
export const THIRDWEB_AUTH_DEFAULT_LOGIN_PAYLOAD_DURATION_IN_SECONDS = 60 * 10;
|
||||
export const THIRDWEB_AUTH_DEFAULT_TOKEN_DURATION_IN_SECONDS = 60 * 60 * 24;
|
||||
export const THIRDWEB_AUTH_DEFAULT_REFRESH_INTERVAL_IN_SECONDS = 5;
|
||||
@@ -1,3 +1,7 @@
|
||||
import {
|
||||
THIRDWEB_AUTH_DEFAULT_LOGIN_PAYLOAD_DURATION_IN_SECONDS,
|
||||
THIRDWEB_AUTH_DEFAULT_TOKEN_DURATION_IN_SECONDS,
|
||||
} from "../constants";
|
||||
import {
|
||||
LoginOptions,
|
||||
LoginPayload,
|
||||
@@ -14,6 +18,8 @@ import {
|
||||
User,
|
||||
Json,
|
||||
LoginOptionsSchema,
|
||||
AuthenticationPayload,
|
||||
AuthenticationPayloadDataInput,
|
||||
} from "./schema";
|
||||
import { isBrowser } from "./utils";
|
||||
import type { GenericAuthWallet } from "@thirdweb-dev/wallets";
|
||||
@@ -53,9 +59,17 @@ export class ThirdwebAuth {
|
||||
chain_id: chainId,
|
||||
nonce: parsedOptions?.nonce,
|
||||
expiration_time:
|
||||
parsedOptions?.expirationTime || new Date(Date.now() + 1000 * 60 * 10),
|
||||
parsedOptions?.expirationTime ||
|
||||
new Date(
|
||||
Date.now() +
|
||||
1000 * THIRDWEB_AUTH_DEFAULT_LOGIN_PAYLOAD_DURATION_IN_SECONDS,
|
||||
),
|
||||
invalid_before:
|
||||
parsedOptions?.invalidBefore || new Date(Date.now() - 1000 * 60 * 10),
|
||||
parsedOptions?.invalidBefore ||
|
||||
new Date(
|
||||
Date.now() -
|
||||
1000 * THIRDWEB_AUTH_DEFAULT_LOGIN_PAYLOAD_DURATION_IN_SECONDS,
|
||||
),
|
||||
resources: parsedOptions?.resources,
|
||||
});
|
||||
}
|
||||
@@ -217,41 +231,37 @@ export class ThirdwebAuth {
|
||||
}
|
||||
|
||||
const adminAddress = await this.wallet.getAddress();
|
||||
const payloadData = AuthenticationPayloadDataSchema.parse({
|
||||
return this.createToken({
|
||||
iss: adminAddress,
|
||||
sub: userAddress,
|
||||
aud: domain,
|
||||
nbf: parsedOptions?.invalidBefore || new Date(),
|
||||
exp:
|
||||
parsedOptions?.expirationTime ||
|
||||
new Date(Date.now() + 1000 * 60 * 60 * 5),
|
||||
new Date(
|
||||
Date.now() + 1000 * THIRDWEB_AUTH_DEFAULT_TOKEN_DURATION_IN_SECONDS,
|
||||
),
|
||||
iat: new Date(),
|
||||
jti: parsedOptions?.tokenId,
|
||||
ctx: session,
|
||||
});
|
||||
}
|
||||
|
||||
const message = JSON.stringify(payloadData);
|
||||
const signature = await this.wallet.signMessage(message);
|
||||
|
||||
// Header used for JWT token specifying hash algorithm
|
||||
const header = {
|
||||
// Specify ECDSA with SHA-256 for hashing algorithm
|
||||
alg: "ES256",
|
||||
typ: "JWT",
|
||||
};
|
||||
|
||||
const encodedHeader = Buffer.from(JSON.stringify(header)).toString(
|
||||
"base64",
|
||||
);
|
||||
const encodedData = Buffer.from(JSON.stringify(payloadData))
|
||||
.toString("base64")
|
||||
.replace(/=/g, "");
|
||||
const encodedSignature = Buffer.from(signature).toString("base64");
|
||||
|
||||
// Generate a JWT token with base64 encoded header, payload, and signature
|
||||
const token = `${encodedHeader}.${encodedData}.${encodedSignature}`;
|
||||
|
||||
return token;
|
||||
public async refresh(token: string, expirationTime?: Date): Promise<string> {
|
||||
const { payload } = this.parseToken(token);
|
||||
return this.createToken({
|
||||
iss: payload.iss,
|
||||
sub: payload.sub,
|
||||
aud: payload.aud,
|
||||
nbf: new Date(),
|
||||
exp:
|
||||
expirationTime ||
|
||||
new Date(
|
||||
Date.now() + 1000 * THIRDWEB_AUTH_DEFAULT_TOKEN_DURATION_IN_SECONDS,
|
||||
),
|
||||
iat: new Date(),
|
||||
ctx: payload.ctx,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -286,12 +296,7 @@ export class ThirdwebAuth {
|
||||
const parsedOptions = AuthenticateOptionsSchema.parse(options);
|
||||
const domain = parsedOptions?.domain || this.domain;
|
||||
|
||||
const encodedPayload = token.split(".")[1];
|
||||
const encodedSignature = token.split(".")[2];
|
||||
const payload: AuthenticationPayloadData = JSON.parse(
|
||||
Buffer.from(encodedPayload, "base64").toString(),
|
||||
);
|
||||
const signature = Buffer.from(encodedSignature, "base64").toString();
|
||||
const { payload, signature } = this.parseToken(token);
|
||||
|
||||
// Check that the payload unique ID is valid
|
||||
if (parsedOptions?.validateTokenId !== undefined) {
|
||||
@@ -359,6 +364,49 @@ export class ThirdwebAuth {
|
||||
};
|
||||
}
|
||||
|
||||
public parseToken(token: string): AuthenticationPayload {
|
||||
const encodedPayload = token.split(".")[1];
|
||||
const encodedSignature = token.split(".")[2];
|
||||
const payload: AuthenticationPayloadData = JSON.parse(
|
||||
Buffer.from(encodedPayload, "base64").toString(),
|
||||
);
|
||||
const signature = Buffer.from(encodedSignature, "base64").toString();
|
||||
|
||||
return {
|
||||
payload,
|
||||
signature,
|
||||
};
|
||||
}
|
||||
|
||||
private async createToken(
|
||||
payload: AuthenticationPayloadDataInput,
|
||||
): Promise<string> {
|
||||
const payloadData = AuthenticationPayloadDataSchema.parse(payload);
|
||||
|
||||
const message = JSON.stringify(payloadData);
|
||||
const signature = await this.wallet.signMessage(message);
|
||||
|
||||
// Header used for JWT token specifying hash algorithm
|
||||
const header = {
|
||||
// Specify ECDSA with SHA-256 for hashing algorithm
|
||||
alg: "ES256",
|
||||
typ: "JWT",
|
||||
};
|
||||
|
||||
const encodedHeader = Buffer.from(JSON.stringify(header)).toString(
|
||||
"base64",
|
||||
);
|
||||
const encodedData = Buffer.from(JSON.stringify(payloadData))
|
||||
.toString("base64")
|
||||
.replace(/=/g, "");
|
||||
const encodedSignature = Buffer.from(signature).toString("base64");
|
||||
|
||||
// Generate a JWT token with base64 encoded header, payload, and signature
|
||||
const token = `${encodedHeader}.${encodedData}.${encodedSignature}`;
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
private async verifySignature(
|
||||
message: string,
|
||||
signature: string,
|
||||
|
||||
@@ -180,6 +180,13 @@ export type AuthenticationPayloadData = z.output<
|
||||
typeof AuthenticationPayloadDataSchema
|
||||
>;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export type AuthenticationPayloadDataInput = z.input<
|
||||
typeof AuthenticationPayloadDataSchema
|
||||
>;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
|
||||
@@ -1,24 +1,51 @@
|
||||
import {
|
||||
THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE,
|
||||
THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX,
|
||||
} from "../../constants";
|
||||
import { Json } from "../../core/schema";
|
||||
import { ThirdwebAuthContext, ThirdwebAuthUser } from "../types";
|
||||
import { Request } from "express";
|
||||
|
||||
function getToken(req: Request): string | undefined {
|
||||
export function getCookie(req: Request, cookie: string): string | undefined {
|
||||
if (typeof req.cookies.get === "function") {
|
||||
return req.cookies.get(cookie);
|
||||
}
|
||||
|
||||
return req.cookies[cookie];
|
||||
}
|
||||
|
||||
export function getActiveCookie(req: Request): string | undefined {
|
||||
if (!req.cookies) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const activeAccount = getCookie(req, THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE);
|
||||
if (activeAccount) {
|
||||
return `${THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX}_${activeAccount}`;
|
||||
}
|
||||
|
||||
// If active account is not present, then use the old default
|
||||
return THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX;
|
||||
}
|
||||
|
||||
export function getToken(req: Request): string | undefined {
|
||||
if (req.headers["authorization"]) {
|
||||
const authorizationHeader = req.headers["authorization"].split(" ");
|
||||
if (authorizationHeader?.length === 2) {
|
||||
return authorizationHeader[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (!req.cookies) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const cookie: string | undefined = !req.cookies
|
||||
? undefined
|
||||
: typeof req.cookies.get === "function"
|
||||
? (req.cookies as any).get("thirdweb_auth_token")
|
||||
: (req.cookies as any).thirdweb_auth_token;
|
||||
const activeCookie = getActiveCookie(req);
|
||||
if (!activeCookie) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return cookie;
|
||||
return getCookie(req, activeCookie);
|
||||
}
|
||||
|
||||
export async function getUser<
|
||||
|
||||
@@ -4,6 +4,7 @@ import payloadHandler from "./routes/payload";
|
||||
import loginHandler from "./routes/login";
|
||||
import logoutHandler from "./routes/logout";
|
||||
import userHandler from "./routes/user";
|
||||
import switchAccountHandler from "./routes/switch-account";
|
||||
import {
|
||||
ThirdwebAuthConfig,
|
||||
ThirdwebAuthContext,
|
||||
@@ -76,6 +77,13 @@ export function ThirdwebAuth<
|
||||
),
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/switch-account",
|
||||
asyncHandler((req: Request, res: Response) =>
|
||||
switchAccountHandler(req, res, ctx as ThirdwebAuthContext),
|
||||
),
|
||||
);
|
||||
|
||||
return {
|
||||
authRouter: router,
|
||||
authMiddleware: cookieMiddleware,
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import {
|
||||
THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE,
|
||||
THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX,
|
||||
} from "../../constants";
|
||||
import { GenerateOptions } from "../../core";
|
||||
import { LoginPayloadBodySchema, ThirdwebAuthContext } from "../types";
|
||||
import { serialize } from "cookie";
|
||||
@@ -64,18 +68,34 @@ export default async function handler(
|
||||
}
|
||||
}
|
||||
|
||||
const {
|
||||
payload: { exp },
|
||||
} = ctx.auth.parseToken(token);
|
||||
|
||||
// Securely set httpOnly cookie on request to prevent XSS on frontend
|
||||
// And set path to / to enable thirdweb_auth_token usage on all endpoints
|
||||
res.setHeader(
|
||||
"Set-Cookie",
|
||||
serialize("thirdweb_auth_token", token, {
|
||||
res.setHeader("Set-Cookie", [
|
||||
serialize(
|
||||
`${THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX}_${payload.payload.address}`,
|
||||
token,
|
||||
{
|
||||
domain: ctx.cookieOptions?.domain,
|
||||
path: ctx.cookieOptions?.path || "/",
|
||||
sameSite: ctx.cookieOptions?.sameSite || "none",
|
||||
expires: new Date(exp * 1000),
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
},
|
||||
),
|
||||
serialize(THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE, payload.payload.address, {
|
||||
domain: ctx.cookieOptions?.domain,
|
||||
path: ctx.cookieOptions?.path || "/",
|
||||
sameSite: ctx.cookieOptions?.sameSite || "none",
|
||||
expires: new Date(exp * 1000),
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
}),
|
||||
);
|
||||
]);
|
||||
|
||||
// Send token in body and as cookie for frontend and backend use cases
|
||||
return res.status(200).json({ token });
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getUser } from "../helpers/user";
|
||||
import { getActiveCookie, getUser } from "../helpers/user";
|
||||
import { ThirdwebAuthContext } from "../types";
|
||||
import { serialize } from "cookie";
|
||||
import { Request, Response } from "express";
|
||||
@@ -14,6 +14,13 @@ export default async function handler(
|
||||
});
|
||||
}
|
||||
|
||||
const activeCookie = getActiveCookie(req);
|
||||
if (!activeCookie) {
|
||||
return res.status(400).json({
|
||||
error: "No logged in user to logout.",
|
||||
});
|
||||
}
|
||||
|
||||
if (ctx.callbacks?.onLogout) {
|
||||
const user = await getUser(req, ctx);
|
||||
if (user) {
|
||||
@@ -24,7 +31,7 @@ export default async function handler(
|
||||
// Set the access token to 'none' and expire in 5 seconds
|
||||
res.setHeader(
|
||||
"Set-Cookie",
|
||||
serialize("thirdweb_auth_token", "", {
|
||||
serialize(activeCookie, "", {
|
||||
domain: ctx.cookieOptions?.domain,
|
||||
path: ctx.cookieOptions?.path || "/",
|
||||
sameSite: ctx.cookieOptions?.sameSite || "none",
|
||||
|
||||
@@ -23,8 +23,13 @@ export default async function handler(
|
||||
statement: ctx.authOptions?.statement,
|
||||
uri: ctx.authOptions?.uri,
|
||||
version: ctx.authOptions?.version,
|
||||
chainId: ctx.authOptions?.chainId,
|
||||
chainId: parsedPayload.data.chainId || ctx.authOptions?.chainId,
|
||||
resources: ctx.authOptions?.resources,
|
||||
expirationTime: ctx.authOptions?.loginPayloadDurationInSeconds
|
||||
? new Date(
|
||||
Date.now() + 1000 * ctx.authOptions.loginPayloadDurationInSeconds,
|
||||
)
|
||||
: undefined,
|
||||
});
|
||||
|
||||
return res.status(200).json({ payload });
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
import { Request, Response } from "express";
|
||||
import { ActiveBodySchema, ThirdwebAuthContext } from "../types";
|
||||
import { serialize } from "cookie";
|
||||
import {
|
||||
THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE,
|
||||
THIRDWEB_AUTH_DEFAULT_TOKEN_DURATION_IN_SECONDS,
|
||||
THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX,
|
||||
} from "../../constants";
|
||||
import { getCookie } from "../helpers/user";
|
||||
|
||||
export default async function handler(
|
||||
req: Request,
|
||||
res: Response,
|
||||
ctx: ThirdwebAuthContext,
|
||||
) {
|
||||
if (req.method !== "POST") {
|
||||
return res.status(405).json({
|
||||
error: "Invalid method. Only POST supported.",
|
||||
});
|
||||
}
|
||||
|
||||
const parsedPayload = ActiveBodySchema.safeParse(req.body);
|
||||
if (!parsedPayload.success) {
|
||||
return res.status(400).json({ error: "Please provide an address" });
|
||||
}
|
||||
|
||||
let cookieExpiration: Date;
|
||||
const cookie = getCookie(
|
||||
req,
|
||||
`${THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX}_${parsedPayload.data.address}`,
|
||||
);
|
||||
|
||||
if (cookie) {
|
||||
// If the new account is already logged in, get the expiration time from the cookie
|
||||
const {
|
||||
payload: { exp },
|
||||
} = ctx.auth.parseToken(cookie);
|
||||
cookieExpiration = new Date(exp * 1000);
|
||||
} else if (ctx.authOptions?.tokenDurationInSeconds) {
|
||||
// Otherwise, if we have a token duration in seconds, set it to that
|
||||
cookieExpiration = new Date(
|
||||
Date.now() + 1000 * ctx.authOptions.tokenDurationInSeconds,
|
||||
);
|
||||
} else {
|
||||
// Otherwise, just default to 24 hours
|
||||
cookieExpiration = new Date(
|
||||
Date.now() + 1000 * THIRDWEB_AUTH_DEFAULT_TOKEN_DURATION_IN_SECONDS,
|
||||
);
|
||||
}
|
||||
|
||||
res.setHeader("Set-Cookie", [
|
||||
serialize(THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE, parsedPayload.data.address, {
|
||||
domain: ctx.cookieOptions?.domain,
|
||||
path: ctx.cookieOptions?.path || "/",
|
||||
sameSite: ctx.cookieOptions?.sameSite || "none",
|
||||
expires: cookieExpiration,
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
}),
|
||||
]);
|
||||
|
||||
return res.status(200).end();
|
||||
}
|
||||
@@ -1,6 +1,12 @@
|
||||
import { getUser } from "../helpers/user";
|
||||
import { serialize } from "cookie";
|
||||
import { getToken, getUser } from "../helpers/user";
|
||||
import { ThirdwebAuthContext } from "../types";
|
||||
import { Request, Response } from "express";
|
||||
import {
|
||||
THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE,
|
||||
THIRDWEB_AUTH_DEFAULT_REFRESH_INTERVAL_IN_SECONDS,
|
||||
THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX,
|
||||
} from "../../constants";
|
||||
|
||||
export default async function handler(
|
||||
req: Request,
|
||||
@@ -14,5 +20,54 @@ export default async function handler(
|
||||
}
|
||||
|
||||
const user = await getUser(req, ctx);
|
||||
|
||||
// Importantly, make sure the user was actually logged in before refreshing
|
||||
if (user) {
|
||||
const token = getToken(req);
|
||||
if (token) {
|
||||
const payload = ctx.auth.parseToken(token);
|
||||
|
||||
const refreshDate = ctx.authOptions?.refreshIntervalInSeconds
|
||||
? new Date(
|
||||
payload.payload.iat * 1000 +
|
||||
ctx.authOptions.refreshIntervalInSeconds * 1000,
|
||||
)
|
||||
: new Date(
|
||||
payload.payload.iat * 1000 +
|
||||
THIRDWEB_AUTH_DEFAULT_REFRESH_INTERVAL_IN_SECONDS * 1000,
|
||||
);
|
||||
|
||||
if (new Date() > refreshDate) {
|
||||
const expirationTime = ctx.authOptions?.tokenDurationInSeconds
|
||||
? new Date(Date.now() + 1000 * ctx.authOptions.tokenDurationInSeconds)
|
||||
: undefined;
|
||||
const refreshedToken = await ctx.auth.refresh(token, expirationTime);
|
||||
const refreshedPayload = ctx.auth.parseToken(refreshedToken);
|
||||
res.setHeader("Set-Cookie", [
|
||||
serialize(
|
||||
`${THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX}_${user.address}`,
|
||||
refreshedToken,
|
||||
{
|
||||
domain: ctx.cookieOptions?.domain,
|
||||
path: ctx.cookieOptions?.path || "/",
|
||||
sameSite: ctx.cookieOptions?.sameSite || "none",
|
||||
expires: new Date(refreshedPayload.payload.exp * 1000),
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
},
|
||||
),
|
||||
serialize(THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE, user.address, {
|
||||
domain: ctx.cookieOptions?.domain,
|
||||
path: ctx.cookieOptions?.path || "/",
|
||||
sameSite: ctx.cookieOptions?.sameSite || "none",
|
||||
expires: new Date(refreshedPayload.payload.exp * 1000),
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
}),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res.status(200).json(user);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,11 @@ import { z } from "zod";
|
||||
|
||||
export const PayloadBodySchema = z.object({
|
||||
address: z.string(),
|
||||
chainId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const ActiveBodySchema = z.object({
|
||||
address: z.string(),
|
||||
});
|
||||
|
||||
export const LoginPayloadBodySchema = z.object({
|
||||
@@ -39,7 +44,9 @@ export type ThirdwebAuthConfig<
|
||||
validateTokenId?:
|
||||
| ((tokenId: string) => void)
|
||||
| ((tokenId: string) => Promise<void>);
|
||||
loginPayloadDurationInSeconds?: number;
|
||||
tokenDurationInSeconds?: number;
|
||||
refreshIntervalInSeconds?: number;
|
||||
};
|
||||
cookieOptions?: {
|
||||
domain?: string;
|
||||
|
||||
@@ -1,9 +1,40 @@
|
||||
import {
|
||||
THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE,
|
||||
THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX,
|
||||
} from "../../constants";
|
||||
import { Json } from "../../core/schema";
|
||||
import { ThirdwebAuthContext, ThirdwebAuthUser } from "../types";
|
||||
import { GetServerSidePropsContext, NextApiRequest } from "next";
|
||||
import { NextRequest } from "next/server";
|
||||
|
||||
function getToken(
|
||||
export function getCookie(
|
||||
req: GetServerSidePropsContext["req"] | NextRequest | NextApiRequest,
|
||||
cookie: string,
|
||||
): string | undefined {
|
||||
if (typeof req.cookies.get === "function") {
|
||||
return req.cookies.get(cookie);
|
||||
}
|
||||
|
||||
return (req.cookies as any)[cookie];
|
||||
}
|
||||
|
||||
export function getActiveCookie(
|
||||
req: GetServerSidePropsContext["req"] | NextRequest | NextApiRequest,
|
||||
): string | undefined {
|
||||
if (!req.cookies) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const activeAccount = getCookie(req, THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE);
|
||||
if (activeAccount) {
|
||||
return `${THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX}_${activeAccount}`;
|
||||
}
|
||||
|
||||
// If active account is not present, then use the old default
|
||||
return THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX;
|
||||
}
|
||||
|
||||
export function getToken(
|
||||
req: GetServerSidePropsContext["req"] | NextRequest | NextApiRequest,
|
||||
): string | undefined {
|
||||
if (!!(req as NextApiRequest).headers["authorization"]) {
|
||||
@@ -13,17 +44,18 @@ function getToken(
|
||||
if (authorizationHeader?.length === 2) {
|
||||
return authorizationHeader[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (!req.cookies) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const cookie: string | undefined = !req.cookies
|
||||
? undefined
|
||||
: typeof req.cookies.get === "function"
|
||||
? (req.cookies as any).get("thirdweb_auth_token")
|
||||
: (req.cookies as any).thirdweb_auth_token;
|
||||
const activeCookie = getActiveCookie(req);
|
||||
if (!activeCookie) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return cookie;
|
||||
return getCookie(req, activeCookie);
|
||||
}
|
||||
|
||||
export async function getUser<
|
||||
|
||||
@@ -4,6 +4,7 @@ import payloadHandler from "./routes/payload";
|
||||
import loginHandler from "./routes/login";
|
||||
import logoutHandler from "./routes/logout";
|
||||
import userHandler from "./routes/user";
|
||||
import switchAccountHandler from "./routes/switch-account";
|
||||
import {
|
||||
ThirdwebAuthConfig,
|
||||
ThirdwebAuthContext,
|
||||
@@ -36,6 +37,8 @@ async function ThirdwebAuthRouter(
|
||||
return await userHandler(req, res, ctx);
|
||||
case "logout":
|
||||
return await logoutHandler(req, res, ctx);
|
||||
case "switch-account":
|
||||
return await switchAccountHandler(req, res, ctx);
|
||||
default:
|
||||
return res.status(400).json({
|
||||
message: "Invalid route for authentication.",
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import {
|
||||
THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE,
|
||||
THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX,
|
||||
} from "../../constants";
|
||||
import { GenerateOptions } from "../../core";
|
||||
import { LoginPayloadBodySchema, ThirdwebAuthContext } from "../types";
|
||||
import { serialize } from "cookie";
|
||||
@@ -64,18 +68,34 @@ export default async function handler(
|
||||
}
|
||||
}
|
||||
|
||||
const {
|
||||
payload: { exp },
|
||||
} = ctx.auth.parseToken(token);
|
||||
|
||||
// Securely set httpOnly cookie on request to prevent XSS on frontend
|
||||
// And set path to / to enable thirdweb_auth_token usage on all endpoints
|
||||
res.setHeader(
|
||||
"Set-Cookie",
|
||||
serialize("thirdweb_auth_token", token, {
|
||||
res.setHeader("Set-Cookie", [
|
||||
serialize(
|
||||
`${THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX}_${payload.payload.address}`,
|
||||
token,
|
||||
{
|
||||
domain: ctx.cookieOptions?.domain,
|
||||
path: ctx.cookieOptions?.path || "/",
|
||||
sameSite: ctx.cookieOptions?.sameSite || "none",
|
||||
expires: new Date(exp * 1000),
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
},
|
||||
),
|
||||
serialize(THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE, payload.payload.address, {
|
||||
domain: ctx.cookieOptions?.domain,
|
||||
path: ctx.cookieOptions?.path || "/",
|
||||
sameSite: ctx.cookieOptions?.sameSite || "none",
|
||||
expires: new Date(exp * 1000),
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
}),
|
||||
);
|
||||
]);
|
||||
|
||||
// Send token in body and as cookie for frontend and backend use cases
|
||||
return res.status(200).json({ token });
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getUser } from "../helpers/user";
|
||||
import { getActiveCookie, getUser } from "../helpers/user";
|
||||
import { ThirdwebAuthContext } from "../types";
|
||||
import { serialize } from "cookie";
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
@@ -14,6 +14,13 @@ export default async function handler(
|
||||
});
|
||||
}
|
||||
|
||||
const activeCookie = getActiveCookie(req);
|
||||
if (!activeCookie) {
|
||||
return res.status(400).json({
|
||||
error: "No logged in user to logout.",
|
||||
});
|
||||
}
|
||||
|
||||
if (ctx.callbacks?.onLogout) {
|
||||
const user = await getUser(req, ctx);
|
||||
if (user) {
|
||||
@@ -24,7 +31,7 @@ export default async function handler(
|
||||
// Set the access token to 'none' and expire in 5 seconds
|
||||
res.setHeader(
|
||||
"Set-Cookie",
|
||||
serialize("thirdweb_auth_token", "", {
|
||||
serialize(activeCookie, "", {
|
||||
domain: ctx.cookieOptions?.domain,
|
||||
path: ctx.cookieOptions?.path || "/",
|
||||
sameSite: ctx.cookieOptions?.sameSite || "none",
|
||||
|
||||
@@ -23,8 +23,13 @@ export default async function handler(
|
||||
statement: ctx.authOptions?.statement,
|
||||
uri: ctx.authOptions?.uri,
|
||||
version: ctx.authOptions?.version,
|
||||
chainId: ctx.authOptions?.chainId,
|
||||
chainId: parsedPayload.data.chainId || ctx.authOptions?.chainId,
|
||||
resources: ctx.authOptions?.resources,
|
||||
expirationTime: ctx.authOptions?.loginPayloadDurationInSeconds
|
||||
? new Date(
|
||||
Date.now() + 1000 * ctx.authOptions.loginPayloadDurationInSeconds,
|
||||
)
|
||||
: undefined,
|
||||
});
|
||||
|
||||
return res.status(200).json({ payload });
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
import { serialize } from "cookie";
|
||||
import { getCookie } from "../helpers/user";
|
||||
import { ActiveBodySchema, ThirdwebAuthContext } from "../types";
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
import {
|
||||
THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE,
|
||||
THIRDWEB_AUTH_DEFAULT_TOKEN_DURATION_IN_SECONDS,
|
||||
THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX,
|
||||
} from "../../constants";
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
ctx: ThirdwebAuthContext,
|
||||
) {
|
||||
if (req.method !== "POST") {
|
||||
return res.status(405).json({
|
||||
error: "Invalid method. Only POST supported.",
|
||||
});
|
||||
}
|
||||
|
||||
const parsedPayload = ActiveBodySchema.safeParse(req.body);
|
||||
if (!parsedPayload.success) {
|
||||
return res.status(400).json({ error: "Please provide an address" });
|
||||
}
|
||||
|
||||
let cookieExpiration: Date;
|
||||
const cookie = getCookie(
|
||||
req,
|
||||
`${THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX}_${parsedPayload.data.address}`,
|
||||
);
|
||||
|
||||
if (cookie) {
|
||||
// If the new account is already logged in, get the expiration time from the cookie
|
||||
const {
|
||||
payload: { exp },
|
||||
} = ctx.auth.parseToken(cookie);
|
||||
cookieExpiration = new Date(exp * 1000);
|
||||
} else if (ctx.authOptions?.tokenDurationInSeconds) {
|
||||
// Otherwise, if we have a token duration in seconds, set it to that
|
||||
cookieExpiration = new Date(
|
||||
Date.now() + 1000 * ctx.authOptions.tokenDurationInSeconds,
|
||||
);
|
||||
} else {
|
||||
// Otherwise, just default to 24 hours
|
||||
cookieExpiration = new Date(
|
||||
Date.now() + 1000 * THIRDWEB_AUTH_DEFAULT_TOKEN_DURATION_IN_SECONDS,
|
||||
);
|
||||
}
|
||||
|
||||
res.setHeader("Set-Cookie", [
|
||||
serialize(THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE, parsedPayload.data.address, {
|
||||
domain: ctx.cookieOptions?.domain,
|
||||
path: ctx.cookieOptions?.path || "/",
|
||||
sameSite: ctx.cookieOptions?.sameSite || "none",
|
||||
expires: cookieExpiration,
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
}),
|
||||
]);
|
||||
|
||||
return res.status(200).end();
|
||||
}
|
||||
@@ -1,4 +1,10 @@
|
||||
import { getUser } from "../helpers/user";
|
||||
import { serialize } from "cookie";
|
||||
import {
|
||||
THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE,
|
||||
THIRDWEB_AUTH_DEFAULT_REFRESH_INTERVAL_IN_SECONDS,
|
||||
THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX,
|
||||
} from "../../constants";
|
||||
import { getToken, getUser } from "../helpers/user";
|
||||
import { ThirdwebAuthContext } from "../types";
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
@@ -14,5 +20,54 @@ export default async function handler(
|
||||
}
|
||||
|
||||
const user = await getUser(req, ctx);
|
||||
|
||||
// Importantly, make sure the user was actually logged in before refreshing
|
||||
if (user) {
|
||||
const token = getToken(req);
|
||||
if (token) {
|
||||
const payload = ctx.auth.parseToken(token);
|
||||
|
||||
const refreshDate = ctx.authOptions?.refreshIntervalInSeconds
|
||||
? new Date(
|
||||
payload.payload.iat * 1000 +
|
||||
ctx.authOptions.refreshIntervalInSeconds * 1000,
|
||||
)
|
||||
: new Date(
|
||||
payload.payload.iat * 1000 +
|
||||
THIRDWEB_AUTH_DEFAULT_REFRESH_INTERVAL_IN_SECONDS * 1000,
|
||||
);
|
||||
|
||||
if (new Date() > refreshDate) {
|
||||
const expirationTime = ctx.authOptions?.tokenDurationInSeconds
|
||||
? new Date(Date.now() + 1000 * ctx.authOptions.tokenDurationInSeconds)
|
||||
: undefined;
|
||||
const refreshedToken = await ctx.auth.refresh(token, expirationTime);
|
||||
const refreshedPayload = ctx.auth.parseToken(refreshedToken);
|
||||
res.setHeader("Set-Cookie", [
|
||||
serialize(
|
||||
`${THIRDWEB_AUTH_TOKEN_COOKIE_PREFIX}_${user.address}`,
|
||||
refreshedToken,
|
||||
{
|
||||
domain: ctx.cookieOptions?.domain,
|
||||
path: ctx.cookieOptions?.path || "/",
|
||||
sameSite: ctx.cookieOptions?.sameSite || "none",
|
||||
expires: new Date(refreshedPayload.payload.exp * 1000),
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
},
|
||||
),
|
||||
serialize(THIRDWEB_AUTH_ACTIVE_ACCOUNT_COOKIE, user.address, {
|
||||
domain: ctx.cookieOptions?.domain,
|
||||
path: ctx.cookieOptions?.path || "/",
|
||||
sameSite: ctx.cookieOptions?.sameSite || "none",
|
||||
expires: new Date(refreshedPayload.payload.exp * 1000),
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
}),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res.status(200).json(user);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,11 @@ import { z } from "zod";
|
||||
|
||||
export const PayloadBodySchema = z.object({
|
||||
address: z.string(),
|
||||
chainId: z.string().optional(),
|
||||
});
|
||||
|
||||
export const ActiveBodySchema = z.object({
|
||||
address: z.string(),
|
||||
});
|
||||
|
||||
export const LoginPayloadBodySchema = z.object({
|
||||
@@ -18,7 +23,12 @@ type RequestType =
|
||||
| NextRequest
|
||||
| NextApiRequest;
|
||||
|
||||
export type ThirdwebAuthRoute = "payload" | "login" | "logout" | "user";
|
||||
export type ThirdwebAuthRoute =
|
||||
| "payload"
|
||||
| "login"
|
||||
| "logout"
|
||||
| "user"
|
||||
| "switch-account";
|
||||
|
||||
export type ThirdwebAuthUser<
|
||||
TData extends Json = Json,
|
||||
@@ -45,7 +55,9 @@ export type ThirdwebAuthConfig<
|
||||
validateTokenId?:
|
||||
| ((tokenId: string) => void)
|
||||
| ((tokenId: string) => Promise<void>);
|
||||
loginPayloadDurationInSeconds?: number;
|
||||
tokenDurationInSeconds?: number;
|
||||
refreshIntervalInSeconds?: number;
|
||||
};
|
||||
cookieOptions?: {
|
||||
domain?: string;
|
||||
|
||||
@@ -1,5 +1,47 @@
|
||||
# @thirdweb-dev/chains
|
||||
|
||||
## 0.1.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1248](https://github.com/thirdweb-dev/js/pull/1248) [`620e89dc`](https://github.com/thirdweb-dev/js/commit/620e89dc25c91557e2164a602c7aedd733525087) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - update chains
|
||||
|
||||
- [#1243](https://github.com/thirdweb-dev/js/pull/1243) [`0fd8aa04`](https://github.com/thirdweb-dev/js/commit/0fd8aa04a9424497758d13a51a72363edcc30e19) Thanks [@therealharpaljadeja](https://github.com/therealharpaljadeja)! - update chains
|
||||
|
||||
## 0.1.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1241](https://github.com/thirdweb-dev/js/pull/1241) [`9af346ee`](https://github.com/thirdweb-dev/js/commit/9af346eeada1037be27c8d3c9e1777f7be11a8ea) Thanks [@nkrishang](https://github.com/nkrishang)! - Use fn getAllAccounts instead of event logs AccountCreated
|
||||
|
||||
## 0.1.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1229](https://github.com/thirdweb-dev/js/pull/1229) [`6816219a`](https://github.com/thirdweb-dev/js/commit/6816219ac13ae571a0c90db6ab389c319bc1f052) Thanks [@jnsdls](https://github.com/jnsdls)! - add/update chains
|
||||
|
||||
## 0.1.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1192](https://github.com/thirdweb-dev/js/pull/1192) [`f41f1a29`](https://github.com/thirdweb-dev/js/commit/f41f1a2958a2cedcf0496c9a3ca284d0b98f1b89) Thanks [@jnsdls](https://github.com/jnsdls)! - fix arbitrum goerli infura url
|
||||
|
||||
## 0.1.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1074](https://github.com/thirdweb-dev/js/pull/1074) [`cc20f93e`](https://github.com/thirdweb-dev/js/commit/cc20f93e178d86ee2b3f39102bbb0811de211f05) Thanks [@Marfuen](https://github.com/Marfuen)! - Enhance CLI Install command and update chains
|
||||
|
||||
- [#1185](https://github.com/thirdweb-dev/js/pull/1185) [`8e28b0f5`](https://github.com/thirdweb-dev/js/commit/8e28b0f5e75596d29273ed80269bcee6d209adb4) Thanks [@jnsdls](https://github.com/jnsdls)! - add Zora Mainnet
|
||||
|
||||
## 0.1.20
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1140](https://github.com/thirdweb-dev/js/pull/1140) [`16232de9`](https://github.com/thirdweb-dev/js/commit/16232de9eab9966e24e335929b2a3919346af265) Thanks [@kumaryash90](https://github.com/kumaryash90)! - Update chains
|
||||
|
||||
- [#1138](https://github.com/thirdweb-dev/js/pull/1138) [`645b0303`](https://github.com/thirdweb-dev/js/commit/645b0303cc1a9cbb0a0e9cbd67d11c3b865e4584) Thanks [@jcstein](https://github.com/jcstein)! - feat: create Taro Testnet
|
||||
|
||||
## 0.1.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Optimism",
|
||||
"name": "OP Mainnet",
|
||||
"chain": "ETH",
|
||||
"rpc": [
|
||||
"https://optimism.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Siberium Test Network",
|
||||
"chain": "SBR",
|
||||
"rpc": [
|
||||
"https://siberium-test-network.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.test.siberium.net"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "TestSIBR",
|
||||
"symbol": "SIBR",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://siberium.net",
|
||||
"shortName": "testsbr",
|
||||
"chainId": 111000,
|
||||
"networkId": 111000,
|
||||
"icon": {
|
||||
"url": "ipfs://QmYeMdWDZ1iaBFeSPorRyPi7RuSXTdDKTgW3rfnUf3W5ne",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "svg"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Siberium Testnet Explorer - blockscout",
|
||||
"url": "https://explorer.test.siberium.net",
|
||||
"icon": {
|
||||
"url": "ipfs://QmYeMdWDZ1iaBFeSPorRyPi7RuSXTdDKTgW3rfnUf3W5ne",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "svg"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "siberium-test-network"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "SatoshiChain Mainnet",
|
||||
"chain": "SATS",
|
||||
"icon": {
|
||||
"url": "ipfs://QmRegpZQBW4o1imYNsW3d27MQjygBSU23Gf6JKje26nvs7",
|
||||
"width": 1251,
|
||||
"height": 1251,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://satoshichain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://mainnet-rpc.satoshichain.io"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "SatoshiChain Coin",
|
||||
"symbol": "SATS",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://satoshichain.net",
|
||||
"shortName": "sats",
|
||||
"chainId": 12009,
|
||||
"networkId": 12009,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "SatoshiChain Explorer",
|
||||
"url": "https://satoshiscan.io",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "satoshichain"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,36 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "BRC Chain Mainnet",
|
||||
"chain": "BRC",
|
||||
"rpc": [
|
||||
"https://brc-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.brcchain.io"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.brcchain.io"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "BRC Chain mainnet native token",
|
||||
"symbol": "BRC",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://bridge.brcchain.io",
|
||||
"shortName": "BRC",
|
||||
"chainId": 12123,
|
||||
"networkId": 12123,
|
||||
"icon": {
|
||||
"url": "ipfs://QmX8qGX7xoZqYUpHxA85uZwQX2fgbTHvmddE1NfseDyBED",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "BRC Chain Explorer",
|
||||
"url": "https://scan.brcchain.io",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "brc-chain"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,28 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Living Assets Mainnet",
|
||||
"chain": "LAS",
|
||||
"icon": {
|
||||
"url": "ipfs://QmRidubY7BVwC737BQwGEttenP1npAXN7ZNryktE416uUW",
|
||||
"width": 500,
|
||||
"height": 500,
|
||||
"format": "jpg"
|
||||
},
|
||||
"rpc": [
|
||||
"https://living-assets.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://beta.mainnet.livingassets.io/rpc",
|
||||
"https://gamma.mainnet.livingassets.io/rpc"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "LAS",
|
||||
"symbol": "LAS",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://dev.livingassets.io/",
|
||||
"shortName": "LAS",
|
||||
"chainId": 1440,
|
||||
"networkId": 1440,
|
||||
"testnet": false,
|
||||
"slug": "living-assets"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,36 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Taro Testnet",
|
||||
"chain": "gETH",
|
||||
"shortName": "Taro",
|
||||
"chainId": 1582,
|
||||
"testnet": true,
|
||||
"icon": {
|
||||
"format": "svg",
|
||||
"url": "ipfs://bafybeibfpls2ealp4e5fdeoxessfjjkldgjnrcx2erph7524pg7alskk6a/1f9cb.svg",
|
||||
"width": 512,
|
||||
"height": 512
|
||||
},
|
||||
"rpc": [
|
||||
"https://taro-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://taro-testnet.calderachain.xyz/http"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"decimals": 18,
|
||||
"name": "Ether",
|
||||
"symbol": "gETH"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"url": "https://explorer.tarotestnet.com",
|
||||
"name": "Taro Testnet Explorer",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"faucets": [
|
||||
"https://tarotestnet.com"
|
||||
],
|
||||
"infoURL": "https://tarotestnet.com",
|
||||
"networkId": 1582,
|
||||
"slug": "taro-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -4,7 +4,7 @@ export default {
|
||||
"chain": "ATH",
|
||||
"rpc": [
|
||||
"https://atheios.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://wallet.atheios.com:8797"
|
||||
"https://rpc.atheios.org/"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
@@ -12,7 +12,7 @@ export default {
|
||||
"symbol": "ATH",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://atheios.com",
|
||||
"infoURL": "https://atheios.org",
|
||||
"shortName": "ath",
|
||||
"chainId": 1620,
|
||||
"networkId": 11235813,
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Omni Testnet 1",
|
||||
"chain": "Omni",
|
||||
"rpc": [
|
||||
"https://omni-testnet-1.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://testnet-1.omni.network"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Omni",
|
||||
"symbol": "OMNI",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://docs.omni.network/",
|
||||
"shortName": "omni_testnet",
|
||||
"chainId": 165,
|
||||
"networkId": 165,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Omni Explorer",
|
||||
"url": "https://testnet-1.explorer.omni.network",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "omni-testnet-1"
|
||||
} as const satisfies Chain;
|
||||
@@ -1,51 +0,0 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Horizen Yuma Testnet",
|
||||
"shortName": "Yuma",
|
||||
"chain": "Yuma",
|
||||
"icon": {
|
||||
"url": "ipfs://QmSFMBk3rMyu45Sy9KQHjgArFj4HdywANNYrSosLMUdcti",
|
||||
"width": 1213,
|
||||
"height": 1213,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://horizen-yuma-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://yuma-testnet.horizenlabs.io/ethv1"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
},
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"faucets": [
|
||||
"https://yuma-testnet-faucet.horizen.io"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "Testnet Zen",
|
||||
"symbol": "tZEN",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://horizen.io/",
|
||||
"chainId": 1662,
|
||||
"networkId": 1662,
|
||||
"slip44": 121,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Yuma Testnet Block Explorer",
|
||||
"url": "https://yuma-explorer.horizen.io",
|
||||
"icon": {
|
||||
"url": "ipfs://QmSFMBk3rMyu45Sy9KQHjgArFj4HdywANNYrSosLMUdcti",
|
||||
"width": 1213,
|
||||
"height": 1213,
|
||||
"format": "png"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "horizen-yuma-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -11,7 +11,8 @@ export default {
|
||||
},
|
||||
"rpc": [
|
||||
"https://horizen-gobi-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://gobi-testnet.horizenlabs.io/ethv1"
|
||||
"https://gobi-testnet.horizenlabs.io/ethv1",
|
||||
"https://rpc.ankr.com/horizen_testnet_evm"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Taiko (Alpha-2 Testnet)",
|
||||
"chain": "ETH",
|
||||
"icon": {
|
||||
"url": "ipfs://QmcHdmVr5VRUJq13jnM6tgah5Ge7hn3Dm14eY6vwivJ5ui",
|
||||
"width": 288,
|
||||
"height": 258,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://taiko-alpha-2-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.a2.taiko.xyz"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Ether",
|
||||
"symbol": "ETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://taiko.xyz",
|
||||
"shortName": "taiko-a2",
|
||||
"chainId": 167004,
|
||||
"networkId": 167004,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "blockscout",
|
||||
"url": "https://explorer.a2.taiko.xyz",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "taiko-alpha-2-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,37 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Pego Network",
|
||||
"chain": "PEGO",
|
||||
"rpc": [
|
||||
"https://pego-network.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://pegorpc.com",
|
||||
"https://node1.pegorpc.com",
|
||||
"https://node2.pegorpc.com",
|
||||
"https://node3.pegorpc.com"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Pego Native Token",
|
||||
"symbol": "PG",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://pego.network",
|
||||
"shortName": "pg",
|
||||
"chainId": 20201022,
|
||||
"networkId": 20201022,
|
||||
"icon": {
|
||||
"url": "ipfs://QmVf1afskRHuZjFSLCZH8397KrVNAoYgyAePX9VMBrPVtx",
|
||||
"width": 246,
|
||||
"height": 247,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Pego Network Explorer",
|
||||
"url": "https://scan.pego.network",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "pego-network"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,21 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Shrapnel Subnet",
|
||||
"chain": "shrapnel",
|
||||
"rpc": [
|
||||
"https://shrapnel-subnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://subnets.avax.network/shrapnel/mainnet/rpc"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Shrapnel Gas Token",
|
||||
"symbol": "SHRAPG",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://www.shrapnel.com/",
|
||||
"shortName": "Shrapnel",
|
||||
"chainId": 2044,
|
||||
"networkId": 2044,
|
||||
"testnet": false,
|
||||
"slug": "shrapnel-subnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -19,8 +19,8 @@ export default {
|
||||
"networkId": 1,
|
||||
"icon": {
|
||||
"url": "ipfs://QmT7PSXBiVBma6E15hNkivmstqLu3JSnG1jXN5pTmcCGRC",
|
||||
"width": 200,
|
||||
"height": 200,
|
||||
"width": 180,
|
||||
"height": 180,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
|
||||
@@ -2,12 +2,6 @@ import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Metaplayerone Dubai Testnet",
|
||||
"chain": "MP1 Dubai-Testnet",
|
||||
"icon": {
|
||||
"url": "ipfs://QmfJKxmubJrqYWDcR2PnPvmpukxPz4fYDu3hqTaSnpJDxC",
|
||||
"width": 42,
|
||||
"height": 23,
|
||||
"format": "svg"
|
||||
},
|
||||
"rpc": [
|
||||
"https://metaplayerone-dubai-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc-dubai.mp1network.com/"
|
||||
@@ -26,12 +20,6 @@ export default {
|
||||
{
|
||||
"name": "MP1Scan",
|
||||
"url": "https://dubai.mp1scan.io",
|
||||
"icon": {
|
||||
"url": "ipfs://QmfJKxmubJrqYWDcR2PnPvmpukxPz4fYDu3hqTaSnpJDxC",
|
||||
"width": 42,
|
||||
"height": 23,
|
||||
"format": "svg"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -21,8 +21,8 @@ export default {
|
||||
"networkId": 1,
|
||||
"icon": {
|
||||
"url": "ipfs://QmT7PSXBiVBma6E15hNkivmstqLu3JSnG1jXN5pTmcCGRC",
|
||||
"width": 200,
|
||||
"height": 200,
|
||||
"width": 180,
|
||||
"height": 180,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
|
||||
@@ -11,7 +11,8 @@ export default {
|
||||
"rpc": [
|
||||
"https://lachain-lachain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc1.mainnet.lachain.network",
|
||||
"https://rpc2.mainnet.lachain.network"
|
||||
"https://rpc2.mainnet.lachain.network",
|
||||
"https://lachain.rpc-nodes.cedalio.dev"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -24,22 +24,10 @@ export default {
|
||||
"shortName": "ncnt",
|
||||
"chainId": 303,
|
||||
"networkId": 303,
|
||||
"icon": {
|
||||
"url": "ipfs://Qmc9zDWXar67cMUodp28mbN5pnwbVibxGXhwa8YCDvxmTR",
|
||||
"width": 62,
|
||||
"height": 59,
|
||||
"format": "svg"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "neuroscan",
|
||||
"url": "https://testnet.ncnscan.com",
|
||||
"icon": {
|
||||
"url": "ipfs://Qmc9zDWXar67cMUodp28mbN5pnwbVibxGXhwa8YCDvxmTR",
|
||||
"width": 62,
|
||||
"height": 59,
|
||||
"format": "svg"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -25,22 +25,10 @@ export default {
|
||||
"shortName": "ncn",
|
||||
"chainId": 313,
|
||||
"networkId": 313,
|
||||
"icon": {
|
||||
"url": "ipfs://Qmc9zDWXar67cMUodp28mbN5pnwbVibxGXhwa8YCDvxmTR",
|
||||
"width": 62,
|
||||
"height": 59,
|
||||
"format": "svg"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "neuroscan",
|
||||
"url": "https://ncnscan.com",
|
||||
"icon": {
|
||||
"url": "ipfs://Qmc9zDWXar67cMUodp28mbN5pnwbVibxGXhwa8YCDvxmTR",
|
||||
"width": 62,
|
||||
"height": 59,
|
||||
"format": "svg"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Filecoin - Hyperspace testnet",
|
||||
"chain": "FIL",
|
||||
"icon": {
|
||||
"url": "ipfs://QmS9r9XQkMHVomWcSBNDkKkz9n87h9bH9ssabeiKZtANoU",
|
||||
"width": 1000,
|
||||
"height": 1000,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://filecoin-hyperspace-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://api.hyperspace.node.glif.io/rpc/v1",
|
||||
"https://rpc.ankr.com/filecoin_testnet",
|
||||
"https://filecoin-hyperspace.chainstacklabs.com/rpc/v1"
|
||||
],
|
||||
"faucets": [
|
||||
"https://hyperspace.yoga/#faucet"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "testnet filecoin",
|
||||
"symbol": "tFIL",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://filecoin.io",
|
||||
"shortName": "filecoin-hyperspace",
|
||||
"chainId": 3141,
|
||||
"networkId": 3141,
|
||||
"slip44": 1,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Filfox - Hyperspace",
|
||||
"url": "https://hyperspace.filfox.info/en",
|
||||
"standard": "none"
|
||||
},
|
||||
{
|
||||
"name": "Glif Explorer - Hyperspace",
|
||||
"url": "https://explorer.glif.io/?network=hyperspace",
|
||||
"standard": "none"
|
||||
},
|
||||
{
|
||||
"name": "Beryx",
|
||||
"url": "https://beryx.zondax.ch",
|
||||
"standard": "none"
|
||||
},
|
||||
{
|
||||
"name": "Dev.storage",
|
||||
"url": "https://dev.storage",
|
||||
"standard": "none"
|
||||
},
|
||||
{
|
||||
"name": "Filscan - Hyperspace",
|
||||
"url": "https://hyperspace.filscan.io",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "filecoin-hyperspace-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -1,31 +0,0 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Filecoin - Wallaby testnet",
|
||||
"chain": "FIL",
|
||||
"icon": {
|
||||
"url": "ipfs://QmS9r9XQkMHVomWcSBNDkKkz9n87h9bH9ssabeiKZtANoU",
|
||||
"width": 1000,
|
||||
"height": 1000,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://filecoin-wallaby-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://wallaby.node.glif.io/rpc/v1"
|
||||
],
|
||||
"faucets": [
|
||||
"https://wallaby.yoga/#faucet"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "testnet filecoin",
|
||||
"symbol": "tFIL",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://filecoin.io",
|
||||
"shortName": "filecoin-wallaby",
|
||||
"chainId": 31415,
|
||||
"networkId": 31415,
|
||||
"slip44": 1,
|
||||
"explorers": [],
|
||||
"testnet": true,
|
||||
"slug": "filecoin-wallaby-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -10,7 +10,10 @@ export default {
|
||||
},
|
||||
"rpc": [
|
||||
"https://filecoin-calibration-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://api.calibration.node.glif.io/rpc/v1"
|
||||
"https://api.calibration.node.glif.io/rpc/v1",
|
||||
"https://rpc.ankr.com/filecoin_testnet",
|
||||
"https://filecoin-calibration.chainstacklabs.com/rpc/v1",
|
||||
"https://filecoin-calibration.chainup.net/rpc/v1"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.calibration.fildev.network/"
|
||||
@@ -40,6 +43,16 @@ export default {
|
||||
"name": "Filfox - Calibration",
|
||||
"url": "https://calibration.filfox.info",
|
||||
"standard": "none"
|
||||
},
|
||||
{
|
||||
"name": "Glif Explorer - Calibration",
|
||||
"url": "https://explorer.glif.io/?network=calibration",
|
||||
"standard": "none"
|
||||
},
|
||||
{
|
||||
"name": "Beryx",
|
||||
"url": "https://beryx.zondax.ch",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Aves Testnet",
|
||||
"chain": "AVST",
|
||||
"rpc": [
|
||||
"https://aves-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://test.rpc.avescoin.io"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "AvesT",
|
||||
"symbol": "AVST",
|
||||
"decimals": 18
|
||||
},
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
},
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"infoURL": "https://ethereum.org",
|
||||
"shortName": "avst",
|
||||
"chainId": 333331,
|
||||
"networkId": 333331,
|
||||
"icon": {
|
||||
"url": "ipfs://QmeKQVv2QneHaaggw2NfpZ7DGMdjVhPywTdse5RzCs4oGn",
|
||||
"width": 232,
|
||||
"height": 232,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "avescan",
|
||||
"url": "https://testnet.avescoin.io",
|
||||
"icon": {
|
||||
"url": "ipfs://QmeKQVv2QneHaaggw2NfpZ7DGMdjVhPywTdse5RzCs4oGn",
|
||||
"width": 232,
|
||||
"height": 232,
|
||||
"format": "png"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "aves-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Metacodechain",
|
||||
"chain": "metacode",
|
||||
"name": "Jouleverse Mainnet",
|
||||
"chain": "Jouleverse",
|
||||
"rpc": [
|
||||
"https://metacodechain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://j.blockcoach.com:8503"
|
||||
"https://jouleverse.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.jnsdao.com:8503"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
@@ -12,17 +12,17 @@ export default {
|
||||
"symbol": "J",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://j.blockcoach.com:8089",
|
||||
"shortName": "metacode",
|
||||
"infoURL": "https://jnsdao.com",
|
||||
"shortName": "jouleverse",
|
||||
"chainId": 3666,
|
||||
"networkId": 3666,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "meta",
|
||||
"url": "https://j.blockcoach.com:8089",
|
||||
"name": "jscan",
|
||||
"url": "https://jscan.jnsdao.com",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "metacodechain"
|
||||
"slug": "jouleverse"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Ozone Chain Mainnet",
|
||||
"chain": "OZONE",
|
||||
"rpc": [
|
||||
"https://ozone-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://node1.ozonechain.io"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "OZONE",
|
||||
"symbol": "OZO",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://ozonechain.io",
|
||||
"shortName": "ozo",
|
||||
"chainId": 4000,
|
||||
"networkId": 4000,
|
||||
"icon": {
|
||||
"url": "ipfs://QmbM4weV8Bk6c9yNhosYntkVw39SNZtCHYGgWyXTxkevZ8",
|
||||
"width": 1600,
|
||||
"height": 1600,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "OZONE Scan",
|
||||
"url": "https://ozonescan.io",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "ozone-chain"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,40 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Peperium Chain Testnet",
|
||||
"chain": "PERIUM",
|
||||
"rpc": [
|
||||
"https://peperium-chain-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc-testnet.peperium.io"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Peperium Chain Testnet",
|
||||
"symbol": "PERIUM",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://peperium.io",
|
||||
"shortName": "PERIUM",
|
||||
"chainId": 4001,
|
||||
"networkId": 4001,
|
||||
"icon": {
|
||||
"url": "ipfs://Qmag2hr5DQghRzKPN3oUFBkjWzqd5CndQzZeb5LfoiMCXf",
|
||||
"width": 160,
|
||||
"height": 160,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Peperium Chain Explorer",
|
||||
"url": "https://scan-testnet.peperium.io",
|
||||
"icon": {
|
||||
"url": "ipfs://Qmag2hr5DQghRzKPN3oUFBkjWzqd5CndQzZeb5LfoiMCXf",
|
||||
"width": 160,
|
||||
"height": 160,
|
||||
"format": "png"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "peperium-chain-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Ozone Chain Testnet",
|
||||
"chain": "OZONE",
|
||||
"rpc": [
|
||||
"https://ozone-chain-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://node1.testnet.ozonechain.io"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "OZONE",
|
||||
"symbol": "OZO",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://ozonechain.io",
|
||||
"shortName": "ozo_tst",
|
||||
"chainId": 401,
|
||||
"networkId": 401,
|
||||
"icon": {
|
||||
"url": "ipfs://QmbM4weV8Bk6c9yNhosYntkVw39SNZtCHYGgWyXTxkevZ8",
|
||||
"width": 1600,
|
||||
"height": 1600,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "OZONE Scan",
|
||||
"url": "https://testnet.ozonescan.io",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "ozone-chain-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,24 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Omega Mainnet",
|
||||
"chain": "OmegaNetwork",
|
||||
"shortName": "OmegaNetwork",
|
||||
"chainId": 408,
|
||||
"testnet": false,
|
||||
"icon": {
|
||||
"format": "png",
|
||||
"url": "ipfs://bafkreig676zxfhwhcx5bvvvjxedx6ftr2wq4iiznrwm3c6ozrprbc4oxwm",
|
||||
"height": 512,
|
||||
"width": 512
|
||||
},
|
||||
"rpc": [
|
||||
"https://omega.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://mainnet-rpc.omtch.com"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "Omega Network Coin",
|
||||
"symbol": "OMN",
|
||||
"decimals": 18
|
||||
},
|
||||
"slug": "omega"
|
||||
} as const satisfies Chain;
|
||||
@@ -10,7 +10,8 @@ export default {
|
||||
},
|
||||
"rpc": [
|
||||
"https://latestnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.testnet.lachain.network"
|
||||
"https://rpc.testnet.lachain.network",
|
||||
"https://lachain-testnet.rpc-nodes.cedalio.dev"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.lachain.network"
|
||||
|
||||
@@ -14,7 +14,7 @@ export default {
|
||||
"rpc": [
|
||||
"https://arbitrum-goerli.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://arb-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
|
||||
"https://abritrum-goerli.infura.io/v3/${INFURA_API_KEY}",
|
||||
"https://arbitrum-goerli.infura.io/v3/${INFURA_API_KEY}",
|
||||
"https://goerli-rollup.arbitrum.io/rpc/"
|
||||
],
|
||||
"faucets": [],
|
||||
|
||||
@@ -12,15 +12,20 @@ export default {
|
||||
},
|
||||
"rpc": [
|
||||
"https://celo-alfajores-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://alfajores-forno.celo-testnet.org",
|
||||
"wss://alfajores-forno.celo-testnet.org/ws"
|
||||
"wss://alfajores-forno.celo-testnet.org/ws",
|
||||
"https://alfajores-forno.celo-testnet.org"
|
||||
],
|
||||
"faucets": [
|
||||
"https://celo.org/developers/faucet",
|
||||
"https://cauldron.pretoriaresearchlab.io/alfajores-faucet"
|
||||
"https://cauldron.pretoriaresearchlab.io/alfajores-faucet",
|
||||
"https://celo.org/developers/faucet"
|
||||
],
|
||||
"infoURL": "https://docs.celo.org/",
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Celoscan",
|
||||
"url": "https://alfajores.celoscan.io/",
|
||||
"standard": "EIP3091"
|
||||
},
|
||||
{
|
||||
"name": "Celoscan",
|
||||
"url": "https://celoscan.io",
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Patex Sepolia Testnet",
|
||||
"chain": "ETH",
|
||||
"rpc": [
|
||||
"https://patex-sepolia-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://test-rpc.patex.io/"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Sepolia Ether",
|
||||
"symbol": "ETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://patex.io/",
|
||||
"shortName": "psep",
|
||||
"chainId": 471100,
|
||||
"networkId": 471100,
|
||||
"testnet": true,
|
||||
"slug": "patex-sepolia-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -12,7 +12,7 @@ export default {
|
||||
"rpc": [
|
||||
"https://wireshape-floripa-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc-floripa.wireshape.org",
|
||||
"https://floripa.rpc.thirdweb.com"
|
||||
"https://wireshape-floripa-testnet.rpc.thirdweb.com"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Titan",
|
||||
"chain": "ETH",
|
||||
"rpc": [
|
||||
"https://titan.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.titan.tokamak.network",
|
||||
"wss://rpc.titan.tokamak.network/ws"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Ether",
|
||||
"symbol": "ETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://tokamak.network",
|
||||
"shortName": "teth",
|
||||
"chainId": 55004,
|
||||
"networkId": 55004,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "blockscout",
|
||||
"url": "https://explorer.titan.tokamak.network",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "titan"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,35 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "opBNB",
|
||||
"chain": "opBNB",
|
||||
"shortName": "opBNB",
|
||||
"chainId": 5611,
|
||||
"testnet": true,
|
||||
"nativeCurrency": {
|
||||
"name": "Testnet bnb",
|
||||
"symbol": "Tbnb",
|
||||
"decimals": 18
|
||||
},
|
||||
"rpc": [
|
||||
"https://opbnb.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://opbnb-testnet-rpc.bnbchain.org"
|
||||
],
|
||||
"explorers": [
|
||||
{
|
||||
"name": "opBNB Scan",
|
||||
"url": "https://opbnbscan.com/",
|
||||
"standard": ""
|
||||
}
|
||||
],
|
||||
"faucets": [
|
||||
"https://opbnb-testnet-bridge.bnbchain.org/"
|
||||
],
|
||||
"infoURL": "https://docs.bnbchain.org/",
|
||||
"icon": {
|
||||
"url": "ipfs://QmfFvfFsQKby3M32uqr8T55ENBnTHL8bkdeeu6rYVL2n4z/opbnblogo.svg",
|
||||
"height": 512,
|
||||
"width": 512,
|
||||
"format": "svg"
|
||||
},
|
||||
"slug": "opbnb"
|
||||
} as const satisfies Chain;
|
||||
@@ -5,7 +5,8 @@ export default {
|
||||
"rpc": [
|
||||
"https://rollux.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.rollux.com",
|
||||
"wss://rpc.rollux.com/wss"
|
||||
"wss://rpc.rollux.com/wss",
|
||||
"https://rpc.ankr.com/rollux/${ANKR_API_KEY}"
|
||||
],
|
||||
"faucets": [
|
||||
"https://rollux.id/faucetapp"
|
||||
|
||||
@@ -10,7 +10,7 @@ export default {
|
||||
},
|
||||
"rpc": [
|
||||
"https://satoshichain-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.satoshichain.io"
|
||||
"https://testnet-rpc.satoshichain.io"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.satoshichain.io"
|
||||
@@ -21,13 +21,13 @@ export default {
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://satoshichain.net",
|
||||
"shortName": "sats",
|
||||
"shortName": "satst",
|
||||
"chainId": 5758,
|
||||
"networkId": 5758,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "SatoshiChain Explorer",
|
||||
"url": "https://satoshiscan.io",
|
||||
"name": "SatoshiChain Testnet Explorer",
|
||||
"url": "https://testnet.satoshiscan.io",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -4,6 +4,7 @@ export default {
|
||||
"chain": "ASTR",
|
||||
"rpc": [
|
||||
"https://astar.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://evm.astar.network",
|
||||
"https://rpc.astar.network:8545"
|
||||
],
|
||||
"faucets": [],
|
||||
|
||||
@@ -4,7 +4,7 @@ export default {
|
||||
"chain": "ETC",
|
||||
"rpc": [
|
||||
"https://ethereum-classic.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://www.ethercluster.com/etc"
|
||||
"https://etc.rivet.link"
|
||||
],
|
||||
"faucets": [
|
||||
"https://free-online-app.com/faucet-for-eth-evm-chains/?"
|
||||
|
||||
@@ -4,7 +4,7 @@ export default {
|
||||
"chain": "ETC",
|
||||
"rpc": [
|
||||
"https://ethereum-classic-testnet-mordor.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://www.ethercluster.com/mordor"
|
||||
"https://rpc.mordor.etccooperative.org"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -3,9 +3,9 @@ export default {
|
||||
"name": "ZetaChain Mainnet",
|
||||
"chain": "ZetaChain",
|
||||
"icon": {
|
||||
"url": "ipfs://QmeABfwZ2nAxDzYyqZ1LEypPgQFMjEyrx8FfnoPLkF8R3f",
|
||||
"width": 1280,
|
||||
"height": 1280,
|
||||
"url": "ipfs://QmP4Gnf4Lkp8q5LQVePNjAWxSqrw8vU2JAf7amcFz4vEUy",
|
||||
"width": 712,
|
||||
"height": 712,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
@@ -18,7 +18,7 @@ export default {
|
||||
"symbol": "ZETA",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://docs.zetachain.com/",
|
||||
"infoURL": "https://zetachain.com/docs/",
|
||||
"shortName": "zetachain-mainnet",
|
||||
"chainId": 7000,
|
||||
"networkId": 7000,
|
||||
|
||||
@@ -3,14 +3,15 @@ export default {
|
||||
"name": "ZetaChain Athens Testnet",
|
||||
"chain": "ZetaChain",
|
||||
"icon": {
|
||||
"url": "ipfs://QmeABfwZ2nAxDzYyqZ1LEypPgQFMjEyrx8FfnoPLkF8R3f",
|
||||
"width": 1280,
|
||||
"height": 1280,
|
||||
"url": "ipfs://QmP4Gnf4Lkp8q5LQVePNjAWxSqrw8vU2JAf7amcFz4vEUy",
|
||||
"width": 712,
|
||||
"height": 712,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://zetachain-athens-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://api.athens2.zetachain.com/evm"
|
||||
"https://zetachain-athens-evm.blockpi.network/v1/rpc/public",
|
||||
"wss://zetachain-athens.blockpi.network/rpc/v1/public/websocket"
|
||||
],
|
||||
"faucets": [
|
||||
"https://labs.zetachain.com/get-zeta"
|
||||
@@ -20,7 +21,7 @@ export default {
|
||||
"symbol": "aZETA",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://docs.zetachain.com/",
|
||||
"infoURL": "https://zetachain.com/docs",
|
||||
"shortName": "zetachain-athens",
|
||||
"chainId": 7001,
|
||||
"networkId": 7001,
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Zora",
|
||||
"chain": "ETH",
|
||||
"rpc": [
|
||||
"https://zora.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.zora.energy/"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Ether",
|
||||
"symbol": "ETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"icon": {
|
||||
"url": "ipfs://QmZ6qaRwTPFEZUspwMUjaxC6KhmzcELdRQcQzS3P72Dzts/Vector.svg",
|
||||
"height": 512,
|
||||
"width": 512,
|
||||
"format": "svg"
|
||||
},
|
||||
"infoURL": "https://zora.energy",
|
||||
"shortName": "zora",
|
||||
"chainId": 7777777,
|
||||
"networkId": 7777777,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Zora Network Explorer",
|
||||
"url": "https://explorer.zora.energy",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "zora"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,36 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "MAAL Sharia Chain",
|
||||
"chain": "MAAL",
|
||||
"icon": {
|
||||
"url": "ipfs://bafkreiexfqfe2x4impvwhra3xxa5eb25gv25zi3kkaoatdnld7wbxdzf2a",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://maal-sharia-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://node1-mainnet.maalscan.io/",
|
||||
"https://node2-mainnet.maalscan.io/",
|
||||
"https://node3-mainnet.maalscan.io/"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "MAAL",
|
||||
"symbol": "MAAL",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://www.maalblockchain.com/",
|
||||
"shortName": "maal",
|
||||
"chainId": 786,
|
||||
"networkId": 786,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "maalscan",
|
||||
"url": "https://maalscan.io",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "maal-sharia-chain"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,48 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Patex",
|
||||
"chain": "ETH",
|
||||
"icon": {
|
||||
"url": "ipfs://QmTNTSNn3t5WpSEzQmUYbkxYkBKaH6QahyVdVrRKyPHChr",
|
||||
"width": 800,
|
||||
"height": 800,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://patex.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.patex.io/"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Ether",
|
||||
"symbol": "ETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
},
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"infoURL": "https://patex.io/",
|
||||
"shortName": "peth",
|
||||
"chainId": 789,
|
||||
"networkId": 789,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "patexscan",
|
||||
"url": "https://patexscan.io",
|
||||
"icon": {
|
||||
"url": "ipfs://QmTNTSNn3t5WpSEzQmUYbkxYkBKaH6QahyVdVrRKyPHChr",
|
||||
"width": 800,
|
||||
"height": 800,
|
||||
"format": "png"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "patex"
|
||||
} as const satisfies Chain;
|
||||
@@ -1,39 +1,35 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Shardeum Liberty 2.X",
|
||||
"name": "Shardeum Sphinx DApp 1.X",
|
||||
"shortName": "Sphinx",
|
||||
"chain": "Shardeum",
|
||||
"chainId": 8081,
|
||||
"icon": {
|
||||
"url": "ipfs://Qma1bfuubpepKn7DLDy4NPSKDeT3S4VPCNhu6UmdGrb6YD",
|
||||
"width": 609,
|
||||
"height": 533,
|
||||
"height": 1200,
|
||||
"width": 1200,
|
||||
"url": "ipfs://QmQWzHUy4kmk1eGksDREGQL3GWrssdAPBxHt4aKGAFHSfJ",
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://shardeum-liberty-2-x.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://liberty20.shardeum.org/"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.liberty20.shardeum.org"
|
||||
"https://shardeum-sphinx-dapp-1-x.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://dapps.shardeum.org/sphinx"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "Shardeum SHM",
|
||||
"name": "Shardeum",
|
||||
"symbol": "SHM",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://docs.shardeum.org/",
|
||||
"shortName": "Liberty20",
|
||||
"chainId": 8081,
|
||||
"networkId": 8081,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Shardeum Scan",
|
||||
"url": "https://explorer-liberty20.shardeum.org",
|
||||
"url": "https://explorer-dapps.shardeum.org",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"redFlags": [
|
||||
"reusedChainId"
|
||||
"faucets": [
|
||||
"https://faucet-dapps.shardeum.org/"
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "shardeum-liberty-2-x"
|
||||
"infoURL": "https://docs.shardeum.org/",
|
||||
"testnet": true,
|
||||
"slug": "shardeum-sphinx-dapp-1-x"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,37 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Nautilus Chain",
|
||||
"title": "Nautilus Trition Testnet",
|
||||
"chain": "ETH",
|
||||
"icon": {
|
||||
"url": "ipfs://QmNutSgM7n6aJPPDiofe9Dm1epy1RcYTMvugukLUK2vmPM",
|
||||
"width": 500,
|
||||
"height": 500,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://nautilus-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://triton.api.nautchain.xyz"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.eclipse.builders"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "Nautilus Zebec Testnet Tokens",
|
||||
"symbol": "tZBC",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://docs.nautchain.xyz",
|
||||
"shortName": "NAUT",
|
||||
"chainId": 91002,
|
||||
"networkId": 91002,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Nautscan",
|
||||
"url": "https://triton.nautscan.com",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "nautilus-chain"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,45 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "CamDL Mainnet",
|
||||
"chain": "CADL",
|
||||
"rpc": [
|
||||
"https://camdl.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc1.camdl.gov.kh/"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.camdl.gov.kh/"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "CADL",
|
||||
"symbol": "CADL",
|
||||
"decimals": 18
|
||||
},
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
}
|
||||
],
|
||||
"infoURL": "https://camdl.gov.kh/",
|
||||
"shortName": "camdl",
|
||||
"chainId": 95,
|
||||
"networkId": 95,
|
||||
"redFlags": [
|
||||
"reusedChainId"
|
||||
],
|
||||
"icon": {
|
||||
"url": "ipfs://QmW5Fpb2Ywnfqcj4ibvpbKvPv5Mo5eseWdYZnnUvLkj2Hp",
|
||||
"width": 1453,
|
||||
"height": 1453,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "CamDL Block Explorer",
|
||||
"url": "https://explorer.camdl.gov.kh",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
"testnet": false,
|
||||
"slug": "camdl"
|
||||
} as const satisfies Chain;
|
||||
@@ -1,21 +1,26 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Wanchain Testnet",
|
||||
"chain": "WAN",
|
||||
"name": "Zora Testnet",
|
||||
"chain": "ETH",
|
||||
"rpc": [
|
||||
"https://wanchain-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://gwan-ssl.wandevs.org:46891/"
|
||||
"https://zora-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://testnet.rpc.zora.co/"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Wancoin",
|
||||
"symbol": "WAN",
|
||||
"name": "Ether",
|
||||
"symbol": "GETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://testnet.wanscan.org",
|
||||
"shortName": "twan",
|
||||
"icon": {
|
||||
"url": "ipfs://QmZ6qaRwTPFEZUspwMUjaxC6KhmzcELdRQcQzS3P72Dzts/Vector.svg",
|
||||
"height": 512,
|
||||
"width": 512,
|
||||
"format": "svg"
|
||||
},
|
||||
"shortName": "Zora",
|
||||
"chainId": 999,
|
||||
"networkId": 999,
|
||||
"testnet": true,
|
||||
"slug": "wanchain-testnet"
|
||||
"slug": "zora-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,33 @@
|
||||
// @ts-check
|
||||
/** @typedef { import("../../src/types").Chain } Chain */
|
||||
|
||||
/** @type {Omit<Chain, "slug">} */
|
||||
export default {
|
||||
name: "Taro Testnet",
|
||||
chain: "gETH",
|
||||
shortName: "Taro",
|
||||
chainId: 1582,
|
||||
testnet: true,
|
||||
icon: {
|
||||
format: "svg",
|
||||
url: "ipfs://bafybeibfpls2ealp4e5fdeoxessfjjkldgjnrcx2erph7524pg7alskk6a/1f9cb.svg",
|
||||
width: 512,
|
||||
height: 512,
|
||||
},
|
||||
rpc: ["https://taro-testnet.calderachain.xyz/http"],
|
||||
nativeCurrency: {
|
||||
decimals: 18,
|
||||
name: "Ether",
|
||||
symbol: "gETH",
|
||||
},
|
||||
explorers: [
|
||||
{
|
||||
url: "https://explorer.tarotestnet.com",
|
||||
name: "Taro Testnet Explorer",
|
||||
standard: "EIP3091",
|
||||
},
|
||||
],
|
||||
faucets: ["https://tarotestnet.com"],
|
||||
infoURL: "https://tarotestnet.com",
|
||||
networkId: 1582,
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
// @ts-check
|
||||
/** @typedef { import("../../src/types").Chain } Chain */
|
||||
|
||||
/** @type {Omit<Chain, "slug">} */
|
||||
export default {
|
||||
name: "Omega Mainnet",
|
||||
chain: "OmegaNetwork",
|
||||
shortName: "OmegaNetwork",
|
||||
chainId: 408,
|
||||
testnet: false,
|
||||
icon: {
|
||||
format: "png",
|
||||
url: "ipfs://bafkreig676zxfhwhcx5bvvvjxedx6ftr2wq4iiznrwm3c6ozrprbc4oxwm",
|
||||
height: 512,
|
||||
width: 512,
|
||||
},
|
||||
rpc: ["https://mainnet-rpc.omtch.com"],
|
||||
nativeCurrency: {
|
||||
name: "Omega Network Coin",
|
||||
symbol: "OMN",
|
||||
decimals: 18,
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
// @ts-check
|
||||
/** @typedef { import("../../src/types").Chain } Chain */
|
||||
|
||||
/** @type {Omit<Chain, "slug">} */
|
||||
export default {
|
||||
name: "opBNB",
|
||||
chain: "opBNB",
|
||||
shortName: "opBNB",
|
||||
chainId: 5611,
|
||||
testnet: true,
|
||||
nativeCurrency: {
|
||||
name: "Testnet bnb",
|
||||
symbol: "Tbnb",
|
||||
decimals: 18,
|
||||
},
|
||||
rpc: ["https://opbnb-testnet-rpc.bnbchain.org"],
|
||||
explorers: [
|
||||
{
|
||||
name: "opBNB Scan",
|
||||
url: "https://opbnbscan.com/",
|
||||
standard: "",
|
||||
},
|
||||
],
|
||||
faucets: ["https://opbnb-testnet-bridge.bnbchain.org/"],
|
||||
infoURL: "https://docs.bnbchain.org/",
|
||||
icon: {
|
||||
url: "ipfs://QmfFvfFsQKby3M32uqr8T55ENBnTHL8bkdeeu6rYVL2n4z/opbnblogo.svg",
|
||||
height: 512,
|
||||
width: 512,
|
||||
format: "svg",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
// @ts-check
|
||||
/** @typedef { import("../../src/types").Chain } Chain */
|
||||
|
||||
/** @type {Omit<Chain, "slug">} */
|
||||
export default {
|
||||
name: "Shardeum Sphinx DApp 1.X",
|
||||
shortName: "Sphinx",
|
||||
chain: "Shardeum",
|
||||
chainId: 8081,
|
||||
icon: {
|
||||
height: 1200,
|
||||
width: 1200,
|
||||
url: "ipfs://QmQWzHUy4kmk1eGksDREGQL3GWrssdAPBxHt4aKGAFHSfJ",
|
||||
format: "png",
|
||||
},
|
||||
rpc: ["https://dapps.shardeum.org/sphinx"],
|
||||
nativeCurrency: {
|
||||
name: "Shardeum",
|
||||
symbol: "SHM",
|
||||
decimals: 18,
|
||||
},
|
||||
explorers: [
|
||||
{
|
||||
name: "Shardeum Scan",
|
||||
url: "https://explorer-dapps.shardeum.org",
|
||||
standard: "EIP3091",
|
||||
},
|
||||
],
|
||||
faucets: ["https://faucet-dapps.shardeum.org/"],
|
||||
infoURL: "https://docs.shardeum.org/",
|
||||
testnet: true,
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
// @ts-check
|
||||
/** @typedef { import("../../src/types").Chain } Chain */
|
||||
|
||||
/** @type {Omit<Chain, "slug">} */
|
||||
export default {
|
||||
name: "Zora Testnet",
|
||||
chain: "ETH",
|
||||
rpc: ["https://testnet.rpc.zora.co/"],
|
||||
faucets: [],
|
||||
nativeCurrency: {
|
||||
name: "Ether",
|
||||
symbol: "GETH",
|
||||
decimals: 18,
|
||||
},
|
||||
icon: {
|
||||
url: "ipfs://QmZ6qaRwTPFEZUspwMUjaxC6KhmzcELdRQcQzS3P72Dzts/Vector.svg",
|
||||
height: 512,
|
||||
width: 512,
|
||||
format: "svg",
|
||||
},
|
||||
shortName: "Zora",
|
||||
chainId: 999,
|
||||
networkId: 999,
|
||||
testnet: true,
|
||||
};
|
||||
@@ -10,7 +10,7 @@ export default {
|
||||
format: "png",
|
||||
},
|
||||
rpc: [
|
||||
"https://abritrum-goerli.infura.io/v3/${INFURA_API_KEY}",
|
||||
"https://arbitrum-goerli.infura.io/v3/${INFURA_API_KEY}",
|
||||
"https://arb-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
|
||||
],
|
||||
};
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// @ts-check
|
||||
/** @typedef { import("../../src/types").Chain } Chain */
|
||||
|
||||
/** @type {Partial<Chain>} */
|
||||
export default {
|
||||
explorers: [
|
||||
{
|
||||
name: "Celoscan",
|
||||
url: "https://alfajores.celoscan.io/",
|
||||
standard: "EIP3091",
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
// @ts-check
|
||||
/** @typedef { import("../../src/types").Chain } Chain */
|
||||
|
||||
/** @type {Partial<Chain>} */
|
||||
export default {
|
||||
rpc: ["https://evm.astar.network"],
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
// @ts-check
|
||||
/** @typedef { import("../../src/types").Chain } Chain */
|
||||
|
||||
/** @type {Partial<Chain>} */
|
||||
export default {
|
||||
icon: {
|
||||
url: "ipfs://QmZ6qaRwTPFEZUspwMUjaxC6KhmzcELdRQcQzS3P72Dzts/Vector.svg",
|
||||
height: 512,
|
||||
width: 512,
|
||||
format: "svg",
|
||||
},
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/chains",
|
||||
"version": "0.1.19",
|
||||
"version": "0.1.25",
|
||||
"main": "dist/thirdweb-dev-chains.cjs.js",
|
||||
"module": "dist/thirdweb-dev-chains.esm.js",
|
||||
"browser": {
|
||||
|
||||
@@ -54,6 +54,8 @@ for (const file of additionalChainsFiles) {
|
||||
const additionalChain = await import(
|
||||
path.join("file://", additionalChainsDir, file)
|
||||
);
|
||||
|
||||
chains = chains.filter((c) => c.chainId !== additionalChain.default.chainId);
|
||||
chains.push(additionalChain.default);
|
||||
}
|
||||
|
||||
@@ -144,6 +146,10 @@ function findSlug(chain) {
|
||||
if (slug === "base-goerli-testnet") {
|
||||
slug = "base-goerli";
|
||||
}
|
||||
// optimisim rename handling
|
||||
if (slug === "op") {
|
||||
slug = "optimism";
|
||||
}
|
||||
// end special cases
|
||||
|
||||
takenSlugs[slug] = true;
|
||||
|
||||
+101
-29
File diff suppressed because one or more lines are too long
@@ -1,5 +1,66 @@
|
||||
# thirdweb
|
||||
|
||||
## 0.10.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ef4cb092`](https://github.com/thirdweb-dev/js/commit/ef4cb092192c58c9b292b29590b888f45f9fd23d), [`30ac3aef`](https://github.com/thirdweb-dev/js/commit/30ac3aef840bde51a61acf786c709cffd3c47354), [`620e89dc`](https://github.com/thirdweb-dev/js/commit/620e89dc25c91557e2164a602c7aedd733525087), [`0fd8aa04`](https://github.com/thirdweb-dev/js/commit/0fd8aa04a9424497758d13a51a72363edcc30e19)]:
|
||||
- @thirdweb-dev/sdk@3.10.26
|
||||
- @thirdweb-dev/chains@0.1.25
|
||||
|
||||
## 0.10.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1240](https://github.com/thirdweb-dev/js/pull/1240) [`1c7264b4`](https://github.com/thirdweb-dev/js/commit/1c7264b40330d068ece67df537a0f5db0f6aedca) Thanks [@Marfuen](https://github.com/Marfuen)! - Small bug fix for updating packages using --nightly
|
||||
|
||||
- Updated dependencies [[`d498c79a`](https://github.com/thirdweb-dev/js/commit/d498c79a911d478077dfb8a2490eb1bf91523186), [`0c5b03b8`](https://github.com/thirdweb-dev/js/commit/0c5b03b8d6cc6a4e69bb2a4647d3626e69f1283c), [`9af346ee`](https://github.com/thirdweb-dev/js/commit/9af346eeada1037be27c8d3c9e1777f7be11a8ea)]:
|
||||
- @thirdweb-dev/sdk@3.10.25
|
||||
- @thirdweb-dev/storage@1.1.5
|
||||
- @thirdweb-dev/chains@0.1.24
|
||||
|
||||
## 0.10.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`6816219a`](https://github.com/thirdweb-dev/js/commit/6816219ac13ae571a0c90db6ab389c319bc1f052), [`48065bcd`](https://github.com/thirdweb-dev/js/commit/48065bcd91c13e1f44d54343b5c6c2646b9e86e4), [`6aa6f7e0`](https://github.com/thirdweb-dev/js/commit/6aa6f7e0bd2313e2e1ad96dd41aad91e6694d380), [`f7f4f207`](https://github.com/thirdweb-dev/js/commit/f7f4f20737ac5d78424ca9c91220f00b85adde6b), [`d4d95507`](https://github.com/thirdweb-dev/js/commit/d4d95507130b2b5408bfaa73ef3b708ca00c773e), [`483e2b91`](https://github.com/thirdweb-dev/js/commit/483e2b910934d75276a68bae64d04c47cd7d57e3), [`c08e6ba9`](https://github.com/thirdweb-dev/js/commit/c08e6ba988ad97aa27d5868cec8abe3498d07a0a), [`3d615a62`](https://github.com/thirdweb-dev/js/commit/3d615a62d0a6801f6fb0e63f9b95c2f98446add1)]:
|
||||
- @thirdweb-dev/chains@0.1.23
|
||||
- @thirdweb-dev/sdk@3.10.24
|
||||
|
||||
## 0.10.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`d9b7360d`](https://github.com/thirdweb-dev/js/commit/d9b7360d1d78abcdaca89aa35e66388cbc5eb26c), [`8a2d9204`](https://github.com/thirdweb-dev/js/commit/8a2d92046a416c99c6bfecf63a6fdb6cc02ea175), [`990c665d`](https://github.com/thirdweb-dev/js/commit/990c665de9e5c1070dc80fe0f1b434e251f70a94), [`c6f44722`](https://github.com/thirdweb-dev/js/commit/c6f44722f9d123db4e7c4c799fe8e0374a02107c), [`45ae105e`](https://github.com/thirdweb-dev/js/commit/45ae105ed3e48bfbf6be84aa12ecb0fb55a917b7), [`f41f1a29`](https://github.com/thirdweb-dev/js/commit/f41f1a2958a2cedcf0496c9a3ca284d0b98f1b89), [`bb7ca20e`](https://github.com/thirdweb-dev/js/commit/bb7ca20e49c5c374b12a4ed746a2ac3db488abd9), [`23d61cfe`](https://github.com/thirdweb-dev/js/commit/23d61cfeff2e5a885c511416d7491e7933ed404a), [`8941b226`](https://github.com/thirdweb-dev/js/commit/8941b22682d1b15a6e0d311b1e8548b95d6cfadf), [`e0ce4a37`](https://github.com/thirdweb-dev/js/commit/e0ce4a37596a91a072f8551e323fce6723113dcb)]:
|
||||
- @thirdweb-dev/sdk@3.10.23
|
||||
- @thirdweb-dev/chains@0.1.22
|
||||
|
||||
## 0.10.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1184](https://github.com/thirdweb-dev/js/pull/1184) [`e7f1ce43`](https://github.com/thirdweb-dev/js/commit/e7f1ce43b04c6ea81fd05c02c8392a16c38d6053) Thanks [@Marfuen](https://github.com/Marfuen)! - Fix typo issues with python detectors
|
||||
|
||||
- [#1074](https://github.com/thirdweb-dev/js/pull/1074) [`cc20f93e`](https://github.com/thirdweb-dev/js/commit/cc20f93e178d86ee2b3f39102bbb0811de211f05) Thanks [@Marfuen](https://github.com/Marfuen)! - Enhance CLI Install command and update chains
|
||||
|
||||
- [#1154](https://github.com/thirdweb-dev/js/pull/1154) [`02d55a06`](https://github.com/thirdweb-dev/js/commit/02d55a063e7c53761d57e6cb6bf63ea78e454d70) Thanks [@beauwilliams](https://github.com/beauwilliams)! - fix: always use latest CLI version in CI
|
||||
|
||||
- [#1171](https://github.com/thirdweb-dev/js/pull/1171) [`c0e2c945`](https://github.com/thirdweb-dev/js/commit/c0e2c9457f5ba992163b175f85b0f4b92b070f48) Thanks [@Marfuen](https://github.com/Marfuen)! - Minor bug fixes and improvements
|
||||
|
||||
- [#1183](https://github.com/thirdweb-dev/js/pull/1183) [`224b7241`](https://github.com/thirdweb-dev/js/commit/224b7241dc82155d3207a2d16523ceaae5532f40) Thanks [@Marfuen](https://github.com/Marfuen)! - Python detectors bug fixes
|
||||
|
||||
- Updated dependencies [[`cc20f93e`](https://github.com/thirdweb-dev/js/commit/cc20f93e178d86ee2b3f39102bbb0811de211f05), [`a430160e`](https://github.com/thirdweb-dev/js/commit/a430160e6b4771c03d97f6ede91f1aeaa043e50e), [`12b07aad`](https://github.com/thirdweb-dev/js/commit/12b07aad9ae3176daf9d05864247d4806a16c9d2), [`7d2a446e`](https://github.com/thirdweb-dev/js/commit/7d2a446ecef9c6c14959d31e9a66537783b9adac), [`8e28b0f5`](https://github.com/thirdweb-dev/js/commit/8e28b0f5e75596d29273ed80269bcee6d209adb4), [`01293857`](https://github.com/thirdweb-dev/js/commit/01293857fac8531bd94764203cd24b3daa4db51f), [`20bbad1a`](https://github.com/thirdweb-dev/js/commit/20bbad1abcb1ec573318d326b09278492a488abd)]:
|
||||
- @thirdweb-dev/chains@0.1.21
|
||||
- @thirdweb-dev/sdk@3.10.22
|
||||
|
||||
## 0.10.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3bf7f375`](https://github.com/thirdweb-dev/js/commit/3bf7f375933cbd7dd8c682a66e8c67bbcb268bf7), [`16232de9`](https://github.com/thirdweb-dev/js/commit/16232de9eab9966e24e335929b2a3919346af265), [`8687d6ac`](https://github.com/thirdweb-dev/js/commit/8687d6ac3a363eae63eeb1959a953cbcd282d353), [`645b0303`](https://github.com/thirdweb-dev/js/commit/645b0303cc1a9cbb0a0e9cbd67d11c3b865e4584), [`522453fd`](https://github.com/thirdweb-dev/js/commit/522453fd568b8c350141a96f9f1c6d5a3ef74493), [`6803c3e9`](https://github.com/thirdweb-dev/js/commit/6803c3e97ca74eed19cd90095afde25b02150d51), [`56f85e57`](https://github.com/thirdweb-dev/js/commit/56f85e57df84bfa93e3230639c95d12466f8aec7), [`6a91b6a0`](https://github.com/thirdweb-dev/js/commit/6a91b6a0253bab5914d4ebdad951dd1c5d141fbc), [`a5f16b6d`](https://github.com/thirdweb-dev/js/commit/a5f16b6dc50b37920a6e5210b60aa6a1682ceb63), [`b6728603`](https://github.com/thirdweb-dev/js/commit/b6728603972ccd6c95108b25e8562807f0f95e19), [`ed47fd53`](https://github.com/thirdweb-dev/js/commit/ed47fd5310d11323080d984bca18a96fdef3a977)]:
|
||||
- @thirdweb-dev/sdk@3.10.21
|
||||
- @thirdweb-dev/chains@0.1.20
|
||||
|
||||
## 0.10.21
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -34,9 +34,6 @@ describe("npx thirdweb detect", () => {
|
||||
// wait for program to finish
|
||||
await create.waitForFinish();
|
||||
|
||||
// the process should exit with code 0
|
||||
expect(create.getExitCode()).toEqual(0);
|
||||
|
||||
// check if the contract was created
|
||||
expect(await exists("thirdweb-contracts/contracts/Contract.sol")).toEqual(
|
||||
true,
|
||||
@@ -56,14 +53,15 @@ describe("npx thirdweb detect", () => {
|
||||
"./thirdweb-contracts",
|
||||
);
|
||||
|
||||
// Select pnpm as package manager.
|
||||
await detect.pressKey("arrowDown");
|
||||
await detect.pressKey("enter");
|
||||
|
||||
// wait for program to finish
|
||||
await detect.waitForFinish();
|
||||
|
||||
const lines = detect.getStdout();
|
||||
|
||||
// check that detect excited successfully
|
||||
expect(detect.getExitCode()).toEqual(0);
|
||||
|
||||
// Detected extensions
|
||||
expect(lines.findIndex((line) => line.includes("ERC721"))).toBeGreaterThan(
|
||||
-1,
|
||||
@@ -86,9 +84,6 @@ describe("npx thirdweb detect", () => {
|
||||
lines.findIndex((line) => line.includes("- ERC721SignatureMint")),
|
||||
).toBeGreaterThan(-1);
|
||||
|
||||
// the process should exit with code 0
|
||||
expect(detect.getExitCode()).toEqual(0);
|
||||
|
||||
await cleanup(); // cleanup after test
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "thirdweb",
|
||||
"main": "dist/cli/index.js",
|
||||
"version": "0.10.21",
|
||||
"version": "0.10.27",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
@@ -47,6 +47,7 @@
|
||||
"got": "11.8.5",
|
||||
"inquirer": "^8.2.3",
|
||||
"js-yaml": "^4.1.0",
|
||||
"node-fetch": "^3.3.1",
|
||||
"open": "^8.4.0",
|
||||
"prompts": "^2.4.2",
|
||||
"rimraf": "^3.0.2",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env node
|
||||
import { detectExtensions } from "../common/feature-detector";
|
||||
import { detectProjectV2 } from "../common/project-detector-v2";
|
||||
import { detectProject } from "../common/project-detector";
|
||||
import { processProject } from "../common/processor";
|
||||
import { cliVersion, pkg } from "../constants/urls";
|
||||
import { info, logger, spinner } from "../core/helpers/logger";
|
||||
@@ -9,7 +9,6 @@ import { twCreate } from "../create/command";
|
||||
import { deploy } from "../deploy";
|
||||
import { generate } from "../generate/command";
|
||||
import { findPackageInstallation } from "../helpers/detect-local-packages";
|
||||
import { install } from "../install/command";
|
||||
import { upload } from "../storage/command";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import chalk from "chalk";
|
||||
@@ -18,6 +17,7 @@ import { Command } from "commander";
|
||||
import open from "open";
|
||||
import prompts from "prompts";
|
||||
import Cache from "sync-disk-cache";
|
||||
import { install } from "../install";
|
||||
|
||||
const main = async () => {
|
||||
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
||||
@@ -204,6 +204,7 @@ const main = async () => {
|
||||
)
|
||||
.option("--nightly", "Install the nightly version of packages.")
|
||||
.option("--dev", "Install the dev version of packages")
|
||||
.option("-d, --debug", "show debug logs")
|
||||
.action(async (path, options) => {
|
||||
await install(path, options);
|
||||
});
|
||||
@@ -398,25 +399,13 @@ const main = async () => {
|
||||
|
||||
program
|
||||
.command("detect")
|
||||
.description(
|
||||
"(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 detectExtensions(options);
|
||||
});
|
||||
|
||||
program
|
||||
.command("detect-project")
|
||||
.description(
|
||||
"Detect the type of project your are running and let you know what it is.",
|
||||
)
|
||||
.option("-p, --path <project-path>", "path to project", ".")
|
||||
.option("-d, --debug", "show debug logs")
|
||||
.action(async (options) => {
|
||||
await detectProjectV2(options);
|
||||
await detectProject(options);
|
||||
});
|
||||
|
||||
program
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
import detectPackageManager from "../core/detection/detectPackageManager";
|
||||
import detectFramework from "../core/detection/detectFramework";
|
||||
import detectLibrary from "../core/detection/detectLibrary";
|
||||
import detectLanguage from "../core/detection/detectLanguage";
|
||||
import { logger } from "../core/helpers/logger";
|
||||
import path from "path";
|
||||
import { ContractLibrariesType, contractLibraries } from "../core/types/ProjectType";
|
||||
|
||||
export async function detectProjectV2(options: any) {
|
||||
logger.setSettings({
|
||||
minLevel: options.debug ? "debug" : "info",
|
||||
});
|
||||
|
||||
let projectPath = process.cwd();
|
||||
if (options.path) {
|
||||
logger.debug("Overriding project path to " + options.path);
|
||||
|
||||
const resolvedPath = (options.path as string).startsWith("/")
|
||||
? options.path
|
||||
: path.resolve(`${projectPath}/${options.path}`);
|
||||
projectPath = resolvedPath;
|
||||
}
|
||||
|
||||
logger.debug("Processing project at path " + projectPath);
|
||||
|
||||
const detectedPackageManager = await detectPackageManager(
|
||||
projectPath,
|
||||
options,
|
||||
);
|
||||
const detectedLanguage = await detectLanguage(projectPath, options);
|
||||
const detectedLibrary = await detectLibrary(
|
||||
projectPath,
|
||||
options,
|
||||
detectedPackageManager,
|
||||
);
|
||||
const detectedFramework = await detectFramework(
|
||||
projectPath,
|
||||
options,
|
||||
detectedPackageManager,
|
||||
);
|
||||
const detectedAppType = contractLibraries.includes(detectedFramework as ContractLibrariesType) ? "contract" : "app";
|
||||
|
||||
logger.debug("Detected package manager: " + detectedPackageManager);
|
||||
logger.debug("Detected library: " + detectedLibrary);
|
||||
logger.debug("Detected language: " + detectedLanguage);
|
||||
logger.debug("Detected framework: " + detectedFramework);
|
||||
logger.debug("Detected app type: " + detectedAppType);
|
||||
}
|
||||
@@ -1,17 +1,20 @@
|
||||
import { ALWAYS_SUGGESTED } from "../constants/features";
|
||||
import build from "../core/builder/build";
|
||||
import detect from "../core/detection/detect";
|
||||
import detectPackageManager from "../core/detection/detectPackageManager";
|
||||
import detectFramework from "../core/detection/detectFramework";
|
||||
import detectLibrary from "../core/detection/detectLibrary";
|
||||
import detectLanguage from "../core/detection/detectLanguage";
|
||||
import { logger, spinner } from "../core/helpers/logger";
|
||||
import path from "path";
|
||||
import { ContractLibrariesType, contractLibraries } from "../core/types/ProjectType";
|
||||
import { FeatureWithEnabled, detectFeatures } from "@thirdweb-dev/sdk";
|
||||
import chalk from "chalk";
|
||||
import ora from "ora";
|
||||
import { ContractPayload } from "../core/interfaces/ContractPayload";
|
||||
import { createContractsPrompt } from "../core/helpers/selector";
|
||||
import { ContractFeatures, Feature } from "../core/interfaces/ContractFeatures";
|
||||
import { ContractPayload } from "../core/interfaces/ContractPayload";
|
||||
import { getPkgManager } from "../create/helpers/get-pkg-manager";
|
||||
import { detectFeatures, FeatureWithEnabled } from "@thirdweb-dev/sdk";
|
||||
import chalk from "chalk";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import ora from "ora";
|
||||
import path from "path";
|
||||
import { getPkgManager } from "../create/helpers/get-pkg-manager";
|
||||
import { ALWAYS_SUGGESTED } from "../constants/features";
|
||||
import build from "../core/builder/build";
|
||||
|
||||
export async function detectProject(options: any) {
|
||||
logger.setSettings({
|
||||
@@ -30,115 +33,137 @@ export async function detectProject(options: any) {
|
||||
|
||||
logger.debug("Processing project at path " + projectPath);
|
||||
|
||||
const packageManagerType = await detectPackageManager(projectPath, options);
|
||||
console.log(packageManagerType);
|
||||
const projectType = await detect(projectPath, options);
|
||||
|
||||
let compiledResult;
|
||||
const compileLoader = spinner("Compiling project...");
|
||||
try {
|
||||
compiledResult = await build(projectPath, projectType, options);
|
||||
} catch (e) {
|
||||
compileLoader.fail("Compilation failed");
|
||||
logger.error(e);
|
||||
process.exit(1);
|
||||
}
|
||||
compileLoader.succeed("Compilation successful");
|
||||
|
||||
let selectedContracts: ContractPayload[] = [];
|
||||
if (compiledResult.contracts.length === 1) {
|
||||
selectedContracts = [compiledResult.contracts[0]];
|
||||
} else {
|
||||
if (options.all) {
|
||||
selectedContracts = compiledResult.contracts;
|
||||
} else {
|
||||
const choices = compiledResult.contracts.map((c) => ({
|
||||
name: c.name,
|
||||
value: c,
|
||||
}));
|
||||
const prompt = createContractsPrompt(
|
||||
choices,
|
||||
"Choose which contracts to run detection on",
|
||||
);
|
||||
const selection: Record<string, ContractPayload> = await prompt.run();
|
||||
selectedContracts = Object.keys(selection).map((key) => selection[key]);
|
||||
}
|
||||
}
|
||||
|
||||
let contractsWithFeatures: ContractFeatures[] = selectedContracts.map(
|
||||
(contract) => {
|
||||
const abi: Parameters<typeof detectFeatures>[0] = JSON.parse(
|
||||
contract.metadata,
|
||||
)["output"]["abi"];
|
||||
const features = extractFeatures(detectFeatures(abi));
|
||||
|
||||
const enabledFeatures: Feature[] = features.enabledFeatures.map(
|
||||
(feature) => ({
|
||||
name: feature.name,
|
||||
reference: `https://portal.thirdweb.com/interfaces/${feature.name.toLowerCase()}`,
|
||||
}),
|
||||
);
|
||||
const suggestedFeatures: Feature[] = features.suggestedFeatures.map(
|
||||
(feature) => ({
|
||||
name: feature.name,
|
||||
reference: `https://portal.thirdweb.com/interfaces/${feature.name.toLowerCase()}`,
|
||||
}),
|
||||
);
|
||||
|
||||
return {
|
||||
name: contract.name,
|
||||
enabledFeatures,
|
||||
suggestedFeatures,
|
||||
};
|
||||
},
|
||||
const detectedPackageManager = await detectPackageManager(
|
||||
projectPath,
|
||||
options,
|
||||
);
|
||||
const detectedLanguage = await detectLanguage(projectPath, options);
|
||||
const detectedLibrary = await detectLibrary(
|
||||
projectPath,
|
||||
options,
|
||||
detectedPackageManager,
|
||||
);
|
||||
const detectedFramework = await detectFramework(
|
||||
projectPath,
|
||||
options,
|
||||
detectedPackageManager,
|
||||
);
|
||||
const detectedAppType = detectedFramework !== "none" ? contractLibraries.includes(detectedFramework as ContractLibrariesType) ? "contract" : "app" : "app";
|
||||
const detectedContractLibrary = detectedAppType === "contract" ? detectedFramework as ContractLibrariesType : "none";
|
||||
|
||||
contractsWithFeatures.map((contractWithFeatures) => {
|
||||
logger.info(`\n`);
|
||||
if (contractWithFeatures.enabledFeatures.length === 0) {
|
||||
ora(
|
||||
`No extensions detected on ${chalk.blueBright(
|
||||
contractWithFeatures.name,
|
||||
)}`,
|
||||
).stopAndPersist({ symbol: "🔎" });
|
||||
} else {
|
||||
ora(
|
||||
`Detected extension on ${chalk.blueBright(contractWithFeatures.name)}`,
|
||||
).stopAndPersist({ symbol: "🔎" });
|
||||
contractWithFeatures.enabledFeatures.map((feature) => {
|
||||
logger.info(`✔️ ${chalk.green(feature.name)}`);
|
||||
});
|
||||
logger.info("Detected package manager: " + detectedPackageManager);
|
||||
logger.info("Detected library: " + detectedLibrary);
|
||||
logger.info("Detected language: " + detectedLanguage);
|
||||
logger.info("Detected framework: " + detectedFramework);
|
||||
logger.info("Detected app type: " + detectedAppType);
|
||||
|
||||
if (detectedAppType === "contract") {
|
||||
let compiledResult;
|
||||
const compileLoader = spinner("Compiling project...");
|
||||
try {
|
||||
compiledResult = await build(projectPath, detectedContractLibrary, options);
|
||||
} catch (e) {
|
||||
compileLoader.fail("Compilation failed");
|
||||
logger.error(e);
|
||||
process.exit(1);
|
||||
}
|
||||
logger.info(``);
|
||||
ora(`Suggested extensions`).info();
|
||||
contractWithFeatures.suggestedFeatures.map((feature) => {
|
||||
logger.info(
|
||||
`${chalk.dim(chalk.gray(`-`))} ${chalk.gray(
|
||||
feature.name,
|
||||
)} - ${chalk.dim(chalk.gray(feature.reference))}`,
|
||||
);
|
||||
});
|
||||
compileLoader.succeed("Compilation successful");
|
||||
|
||||
let deployCmd = `npx thirdweb@latest deploy`;
|
||||
if (existsSync(projectPath + "/package.json")) {
|
||||
const packageManager = getPkgManager();
|
||||
const useYarn = packageManager === "yarn";
|
||||
const pkgJson = JSON.parse(
|
||||
readFileSync(projectPath + "/package.json", "utf-8"),
|
||||
);
|
||||
if (pkgJson?.scripts?.deploy === deployCmd) {
|
||||
deployCmd = `${packageManager}${useYarn ? "" : " run"} deploy`;
|
||||
let selectedContracts: ContractPayload[] = [];
|
||||
if (compiledResult.contracts.length === 1) {
|
||||
selectedContracts = [compiledResult.contracts[0]];
|
||||
} else {
|
||||
if (options.all) {
|
||||
selectedContracts = compiledResult.contracts;
|
||||
} else {
|
||||
const choices = compiledResult.contracts.map((c) => ({
|
||||
name: c.name,
|
||||
value: c,
|
||||
}));
|
||||
const prompt = createContractsPrompt(
|
||||
choices,
|
||||
"Choose which contracts to run detection on",
|
||||
);
|
||||
const selection: Record<string, ContractPayload> = await prompt.run();
|
||||
selectedContracts = Object.keys(selection).map((key) => selection[key]);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(``);
|
||||
ora(
|
||||
`Once you're done writing your contracts, you can run the following command to deploy them:`,
|
||||
).info();
|
||||
logger.info(``);
|
||||
logger.info(` ${chalk.cyan(deployCmd)}`);
|
||||
logger.info(``);
|
||||
});
|
||||
let contractsWithFeatures: ContractFeatures[] = selectedContracts.map(
|
||||
(contract) => {
|
||||
const abi: Parameters<typeof detectFeatures>[0] = JSON.parse(
|
||||
contract.metadata,
|
||||
)["output"]["abi"];
|
||||
const features = extractFeatures(detectFeatures(abi));
|
||||
|
||||
const enabledFeatures: Feature[] = features.enabledFeatures.map(
|
||||
(feature) => ({
|
||||
name: feature.name,
|
||||
reference: `https://portal.thirdweb.com/interfaces/${feature.name.toLowerCase()}`,
|
||||
}),
|
||||
);
|
||||
const suggestedFeatures: Feature[] = features.suggestedFeatures.map(
|
||||
(feature) => ({
|
||||
name: feature.name,
|
||||
reference: `https://portal.thirdweb.com/interfaces/${feature.name.toLowerCase()}`,
|
||||
}),
|
||||
);
|
||||
|
||||
return {
|
||||
name: contract.name,
|
||||
enabledFeatures,
|
||||
suggestedFeatures,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
contractsWithFeatures.map((contractWithFeatures) => {
|
||||
logger.info(`\n`);
|
||||
if (contractWithFeatures.enabledFeatures.length === 0) {
|
||||
ora(
|
||||
`No extensions detected on ${chalk.blueBright(
|
||||
contractWithFeatures.name,
|
||||
)}`,
|
||||
).stopAndPersist({ symbol: "🔎" });
|
||||
} else {
|
||||
ora(
|
||||
`Detected extension on ${chalk.blueBright(contractWithFeatures.name)}`,
|
||||
).stopAndPersist({ symbol: "🔎" });
|
||||
contractWithFeatures.enabledFeatures.map((feature) => {
|
||||
logger.info(`✔️ ${chalk.green(feature.name)}`);
|
||||
});
|
||||
}
|
||||
logger.info(``);
|
||||
ora(`Suggested extensions`).info();
|
||||
contractWithFeatures.suggestedFeatures.map((feature) => {
|
||||
logger.info(
|
||||
`${chalk.dim(chalk.gray(`-`))} ${chalk.gray(
|
||||
feature.name,
|
||||
)} - ${chalk.dim(chalk.gray(feature.reference))}`,
|
||||
);
|
||||
});
|
||||
|
||||
let deployCmd = `npx thirdweb@latest deploy`;
|
||||
if (existsSync(projectPath + "/package.json")) {
|
||||
const packageManager = getPkgManager();
|
||||
const useYarn = packageManager === "yarn";
|
||||
const pkgJson = JSON.parse(
|
||||
readFileSync(projectPath + "/package.json", "utf-8"),
|
||||
);
|
||||
if (pkgJson?.scripts?.deploy === deployCmd) {
|
||||
deployCmd = `${packageManager}${useYarn ? "" : " run"} deploy`;
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(``);
|
||||
ora(
|
||||
`Once you're done writing your contracts, you can run the following command to deploy them:`,
|
||||
).info();
|
||||
logger.info(``);
|
||||
logger.info(` ${chalk.cyan(deployCmd)}`);
|
||||
logger.info(``);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function extractFeatures(
|
||||
|
||||
@@ -29,7 +29,6 @@ export default async function detect(
|
||||
options: any,
|
||||
detectedPackageManager: PackageManagerType,
|
||||
): Promise<FrameworkType> {
|
||||
// We could optimize further if we want, by only running the detectors that match the package manager.
|
||||
const frameworkDetectors: FrameworkDetector[] = [
|
||||
new BrownieDetector(),
|
||||
new CRADetector(),
|
||||
@@ -66,6 +65,10 @@ export default async function detect(
|
||||
return possibleFrameworks[0];
|
||||
}
|
||||
|
||||
if (possibleFrameworks.includes("expo") && possibleFrameworks.includes("react-native-cli")) {
|
||||
return "expo";
|
||||
}
|
||||
|
||||
info(
|
||||
`Detected multiple possible frameworks: ${possibleFrameworks
|
||||
.map((s) => `"${s}"`)
|
||||
|
||||
@@ -30,6 +30,10 @@ export default async function detect(
|
||||
return possibleLanguages[0];
|
||||
}
|
||||
|
||||
if (possibleLanguages.includes("typescript") && possibleLanguages.includes("javascript")) {
|
||||
return "typescript";
|
||||
}
|
||||
|
||||
info(
|
||||
`Detected multiple possible languages: ${possibleLanguages
|
||||
.map((s) => `"${s}"`)
|
||||
|
||||
@@ -36,6 +36,10 @@ export default async function detect(
|
||||
return possibleLibraries[0];
|
||||
}
|
||||
|
||||
if (possibleLibraries.includes("react-native") && possibleLibraries.includes("react")) {
|
||||
return "react-native";
|
||||
}
|
||||
|
||||
info(
|
||||
`Detected multiple possible libraries: ${possibleLibraries
|
||||
.map((s) => `"${s}"`)
|
||||
|
||||
@@ -5,10 +5,12 @@ import inquirer from "inquirer";
|
||||
import NPMDetector from "./packageManagers/npm";
|
||||
import YarnDetector from "./packageManagers/yarn";
|
||||
import PnpmDetector from "./packageManagers/pnpm";
|
||||
import CondaDetector from "./packageManagers/conda";
|
||||
import PipDetector from "./packageManagers/pip";
|
||||
import PipEnvDetector from "./packageManagers/pipenv";
|
||||
import PoetryDetector from "./packageManagers/poetry";
|
||||
import BrownieDetector from "./packageManagers/brownie";
|
||||
import FoundryDetector from "./packageManagers/foundry";
|
||||
import GoModulesDetector from "./packageManagers/goModules";
|
||||
|
||||
export default async function detect(
|
||||
path: string,
|
||||
@@ -18,14 +20,18 @@ export default async function detect(
|
||||
new NPMDetector(),
|
||||
new YarnDetector(),
|
||||
new PnpmDetector(),
|
||||
new CondaDetector(),
|
||||
new PipDetector(),
|
||||
new PipEnvDetector(),
|
||||
new PoetryDetector(),
|
||||
new GoModulesDetector(),
|
||||
new BrownieDetector(),
|
||||
new FoundryDetector(),
|
||||
];
|
||||
|
||||
const possiblePackageManagers = packageManagerDetectors
|
||||
.filter((detector) => detector.matches(path))
|
||||
.filter((detector) => {
|
||||
return detector.matches(path);
|
||||
})
|
||||
.map((detector) => detector.packageManagerType);
|
||||
|
||||
if (!possiblePackageManagers.length) {
|
||||
@@ -36,6 +42,10 @@ export default async function detect(
|
||||
return possiblePackageManagers[0];
|
||||
}
|
||||
|
||||
if (possiblePackageManagers.includes("brownie") && possiblePackageManagers.includes("pip")) {
|
||||
return "brownie";
|
||||
}
|
||||
|
||||
info(
|
||||
`Detected multiple possible package managers: ${possiblePackageManagers
|
||||
.map((s) => `"${s}"`)
|
||||
|
||||
@@ -20,10 +20,16 @@ export default class BrownieDetector implements FrameworkDetector {
|
||||
existsSync(path + file),
|
||||
);
|
||||
|
||||
const additionalDirectoriesToCheck = ["/build", "/contracts", "/reports"];
|
||||
const additionalDirectoriesExist = additionalDirectoriesToCheck.every((dir) => {
|
||||
return existsSync(path + dir);
|
||||
});
|
||||
|
||||
return (
|
||||
dependencies.includes("brownie") ||
|
||||
devDependencies.includes("brownie") ||
|
||||
!!dependencies.find(dep => dep.includes("brownie")) ||
|
||||
!!devDependencies.find(dep => dep.includes("brownie")) ||
|
||||
additionalFilesExist ||
|
||||
additionalDirectoriesExist ||
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@ export default class CRADetector implements FrameworkDetector {
|
||||
const packageJson = readFileSync(packageJsonPath);
|
||||
const { dependencies, devDependencies } = parsePackageJson(packageJson);
|
||||
const craDependencyExists =
|
||||
dependencies["react-scripts"] ||
|
||||
devDependencies["react-scripts"] ||
|
||||
!!dependencies["react-scripts"] ||
|
||||
!!devDependencies["react-scripts"] ||
|
||||
false;
|
||||
|
||||
return craDependencyExists;
|
||||
|
||||
@@ -18,8 +18,8 @@ export default class DjangoDetector implements FrameworkDetector {
|
||||
);
|
||||
|
||||
return (
|
||||
dependencies.includes("django") ||
|
||||
devDependencies.includes("django") ||
|
||||
!!dependencies.find(dep => dep.includes("Django")) ||
|
||||
!!devDependencies.find(dep => dep.includes("Django")) ||
|
||||
additionalFilesExist ||
|
||||
false
|
||||
);
|
||||
|
||||
@@ -16,14 +16,14 @@ export default class ExpoDetector implements FrameworkDetector {
|
||||
const packageJson = readFileSync(packageJsonPath);
|
||||
const { dependencies, devDependencies } = parsePackageJson(packageJson);
|
||||
|
||||
const additionalFilesToCheck = ["/app.json", "/app.config.js", "/assets"];
|
||||
const additionalFilesToCheck = ["/app.json", "/app.config.js"];
|
||||
const additionalFilesExist = additionalFilesToCheck.some((file) =>
|
||||
existsSync(path + file),
|
||||
);
|
||||
|
||||
const expoDependencyExists =
|
||||
dependencies["expo"] ||
|
||||
devDependencies["expo"] ||
|
||||
!!dependencies["expo"] ||
|
||||
!!devDependencies["expo"] ||
|
||||
additionalFilesExist ||
|
||||
false;
|
||||
|
||||
|
||||
@@ -12,14 +12,14 @@ export default class FastAPIDetector implements FrameworkDetector {
|
||||
packageManager,
|
||||
);
|
||||
|
||||
const additionalFilesToCheck = ["/app.py", "/main.py"];
|
||||
const additionalFilesToCheck: string[] = [];
|
||||
const additionalFilesExist = additionalFilesToCheck.some((file) =>
|
||||
existsSync(path + file),
|
||||
);
|
||||
|
||||
return (
|
||||
dependencies.includes("fastapi") ||
|
||||
devDependencies.includes("fastapi") ||
|
||||
!!dependencies.find(dep => dep.includes("fastapi")) ||
|
||||
!!devDependencies.find(dep => dep.includes("fastapi")) ||
|
||||
additionalFilesExist ||
|
||||
false
|
||||
);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user