Compare commits
73
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c88fa57591 | ||
|
|
c12f0874b4 | ||
|
|
184c325ab2 | ||
|
|
046c9ad604 | ||
|
|
2a7bbf8665 | ||
|
|
f97ddf4c7f | ||
|
|
66c53360cd | ||
|
|
bd1fcbae32 | ||
|
|
e196264172 | ||
|
|
c9deda6f4b | ||
|
|
b91d3e9901 | ||
|
|
d248aa2c5a | ||
|
|
8f3b685ad2 | ||
|
|
26349f311d | ||
|
|
2897576513 | ||
|
|
07fb1b5ffa | ||
|
|
300a3c6f04 | ||
|
|
26367c04f3 | ||
|
|
39e2af6f2f | ||
|
|
a5ba9e4fbf | ||
|
|
c9b0131acd | ||
|
|
34b315993c | ||
|
|
14d9a71c92 | ||
|
|
7f5311222b | ||
|
|
b4847dd134 | ||
|
|
cf82c3b58c | ||
|
|
a17326634e | ||
|
|
70c4a119d6 | ||
|
|
f0443bd989 | ||
|
|
73462ef108 | ||
|
|
27c225a512 | ||
|
|
cb1c9937fa | ||
|
|
588b210601 | ||
|
|
7e483ec97f | ||
|
|
c902901cff | ||
|
|
205018f6e1 | ||
|
|
269e68c0a1 | ||
|
|
2888efc065 | ||
|
|
c753641570 | ||
|
|
4b0e63dcc0 | ||
|
|
6979810de5 | ||
|
|
4c37af49aa | ||
|
|
7858632429 | ||
|
|
0647f12498 | ||
|
|
3e1c4045e7 | ||
|
|
3ba8ba4288 | ||
|
|
dfd120a3a9 | ||
|
|
262edc6a46 | ||
|
|
4f79053ec3 | ||
|
|
2a91113a76 | ||
|
|
b103872daf | ||
|
|
7f54012ec6 | ||
|
|
df36e27f32 | ||
|
|
8c0dc9c880 | ||
|
|
074a3eb01c | ||
|
|
a5d0be939a | ||
|
|
5ec0f064d2 | ||
|
|
becbb63736 | ||
|
|
5ee700e804 | ||
|
|
67b145b94d | ||
|
|
c0a6d2f182 | ||
|
|
fd9816556f | ||
|
|
2a3cd62dc9 | ||
|
|
c9bf4f05c1 | ||
|
|
9f5adc5c5c | ||
|
|
d01e6396d1 | ||
|
|
2283d21027 | ||
|
|
ab36d84f1c | ||
|
|
a9f2ff73c9 | ||
|
|
9a7b2098ee | ||
|
|
2b96f71e19 | ||
|
|
3b6b0746b3 | ||
|
|
b0ec1d8083 |
@@ -0,0 +1,13 @@
|
||||
## Problem solved
|
||||
|
||||
Short description of the bug fixed or feature added
|
||||
|
||||
## Changes made
|
||||
|
||||
- [ ] Public API changes: list the public API changes made if any
|
||||
- [ ] Internal API changes: explain the internal logic changes
|
||||
|
||||
## How to test
|
||||
|
||||
- [ ] Automated tests: link to unit test file
|
||||
- [ ] Manual tests: step by step instructions on how to test
|
||||
@@ -17,6 +17,7 @@ concurrency:
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
TW_SECRET_KEY: ${{ secrets.TW_SECRET_KEY }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@
|
||||
"hotlink-revert": "node ./scripts/hotlink/hotlink-revert.mjs",
|
||||
"explain:major": "node ./scripts/changeset-explain-major.mjs"
|
||||
},
|
||||
"packageManager": "pnpm@8.1.0",
|
||||
"packageManager": "pnpm@8.6.12",
|
||||
"dependencies": {
|
||||
"@changesets/changelog-github": "^0.4.8",
|
||||
"@changesets/cli": "^2.26.2",
|
||||
|
||||
@@ -1,5 +1,91 @@
|
||||
# @thirdweb-dev/auth
|
||||
|
||||
## 3.2.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/wallets@1.1.18
|
||||
|
||||
## 3.2.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/wallets@1.1.17
|
||||
|
||||
## 3.2.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/wallets@1.1.16
|
||||
|
||||
## 3.2.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`07fb1b5f`](https://github.com/thirdweb-dev/js/commit/07fb1b5ffa4c170e252df31070852ddb9a81dec9)]:
|
||||
- @thirdweb-dev/wallets@1.1.15
|
||||
|
||||
## 3.2.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`39e2af6f`](https://github.com/thirdweb-dev/js/commit/39e2af6f2f4d933dca1b3de4a37de76375bafd74)]:
|
||||
- @thirdweb-dev/wallets@1.1.14
|
||||
|
||||
## 3.2.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`34b31599`](https://github.com/thirdweb-dev/js/commit/34b315993c0abaccb9640a5d5804c2c93af569c2)]:
|
||||
- @thirdweb-dev/wallets@1.1.13
|
||||
|
||||
## 3.2.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`73462ef1`](https://github.com/thirdweb-dev/js/commit/73462ef10800aeeb5976634e2bc6fb5d3e8501e4), [`70c4a119`](https://github.com/thirdweb-dev/js/commit/70c4a119d691a37ec999d9f6087902d532cc82ed)]:
|
||||
- @thirdweb-dev/wallets@1.1.12
|
||||
|
||||
## 3.2.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`4b0e63dc`](https://github.com/thirdweb-dev/js/commit/4b0e63dcc0ca871ce9cef76f8a41ff290316741c)]:
|
||||
- @thirdweb-dev/wallets@1.1.11
|
||||
|
||||
## 3.2.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1392](https://github.com/thirdweb-dev/js/pull/1392) [`dfd120a3`](https://github.com/thirdweb-dev/js/commit/dfd120a3a9d1582c8b174265c92bf43dbbaf5c86) Thanks [@adam-maj](https://github.com/adam-maj)! - Expose functions from auth and update useAuth
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/wallets@1.1.10
|
||||
|
||||
## 3.2.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @thirdweb-dev/wallets@1.1.9
|
||||
|
||||
## 3.2.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a9f2ff73`](https://github.com/thirdweb-dev/js/commit/a9f2ff73c9f83f05c3e2d3c53b23b2843e8a2576), [`fd981655`](https://github.com/thirdweb-dev/js/commit/fd9816556fe595b0c764e34dbcf15b0ad1677edb)]:
|
||||
- @thirdweb-dev/wallets@1.1.8
|
||||
|
||||
## 3.2.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3b6b0746`](https://github.com/thirdweb-dev/js/commit/3b6b0746b3fc792f4c5092814a7abfabcbc9801e), [`b0ec1d80`](https://github.com/thirdweb-dev/js/commit/b0ec1d80839efccad11b50afbf2216c2c132cf7e)]:
|
||||
- @thirdweb-dev/wallets@1.1.7
|
||||
|
||||
## 3.2.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/auth",
|
||||
"version": "3.2.23",
|
||||
"version": "3.2.35",
|
||||
"main": "dist/thirdweb-dev-auth.cjs.js",
|
||||
"module": "dist/thirdweb-dev-auth.esm.js",
|
||||
"browser": {
|
||||
|
||||
+73
-423
@@ -1,28 +1,28 @@
|
||||
import {
|
||||
THIRDWEB_AUTH_DEFAULT_LOGIN_PAYLOAD_DURATION_IN_SECONDS,
|
||||
THIRDWEB_AUTH_DEFAULT_TOKEN_DURATION_IN_SECONDS,
|
||||
} from "../constants";
|
||||
authenticateJWT,
|
||||
generateJWT,
|
||||
parseJWT,
|
||||
refreshJWT,
|
||||
} from "./functions/jwt";
|
||||
import {
|
||||
LoginOptions,
|
||||
LoginPayload,
|
||||
GenerateOptions,
|
||||
LoginPayloadData,
|
||||
LoginPayloadDataSchema,
|
||||
AuthenticationPayloadDataSchema,
|
||||
AuthenticationPayloadData,
|
||||
VerifyOptionsSchema,
|
||||
VerifyOptions,
|
||||
GenerateOptionsSchema,
|
||||
AuthenticateOptionsSchema,
|
||||
AuthenticateOptions,
|
||||
User,
|
||||
Json,
|
||||
LoginOptionsSchema,
|
||||
AuthenticationPayload,
|
||||
AuthenticationPayloadDataInput,
|
||||
} from "./schema";
|
||||
import { isBrowser } from "./utils";
|
||||
buildAndSignLoginPayload,
|
||||
buildLoginPayload,
|
||||
signLoginPayload,
|
||||
verifyLoginPayload,
|
||||
} from "./functions/login";
|
||||
import type { GenericAuthWallet } from "@thirdweb-dev/wallets";
|
||||
import { Json, User } from "./schema/common";
|
||||
import {
|
||||
LoginOptionsWithOptionalDomain,
|
||||
LoginPayload,
|
||||
LoginPayloadData,
|
||||
} from "./schema/login";
|
||||
import { VerifyOptionsWithOptionalDomain } from "./schema/verify";
|
||||
import { GenerateOptionsWithOptionalDomain } from "./schema/generate";
|
||||
import {
|
||||
AuthenticateOptionsWithOptionalDomain,
|
||||
AuthenticationPayload,
|
||||
} from "./schema/authenticate";
|
||||
|
||||
export class ThirdwebAuth {
|
||||
private domain: string;
|
||||
@@ -37,432 +37,82 @@ export class ThirdwebAuth {
|
||||
this.wallet = wallet;
|
||||
}
|
||||
|
||||
public async payload(options?: LoginOptions): Promise<LoginPayloadData> {
|
||||
const parsedOptions = LoginOptionsSchema.parse(options);
|
||||
|
||||
let chainId: string | undefined = parsedOptions?.chainId;
|
||||
if (!chainId && this.wallet.getChainId) {
|
||||
try {
|
||||
chainId = (await this.wallet.getChainId()).toString();
|
||||
} catch {
|
||||
// ignore error
|
||||
}
|
||||
}
|
||||
|
||||
return LoginPayloadDataSchema.parse({
|
||||
type: this.wallet.type,
|
||||
domain: parsedOptions?.domain || this.domain,
|
||||
address: parsedOptions?.address || (await this.wallet.getAddress()),
|
||||
statement: parsedOptions?.statement,
|
||||
version: parsedOptions?.version,
|
||||
uri: parsedOptions?.uri,
|
||||
chain_id: chainId,
|
||||
nonce: parsedOptions?.nonce,
|
||||
expiration_time:
|
||||
parsedOptions?.expirationTime ||
|
||||
new Date(
|
||||
Date.now() +
|
||||
1000 * THIRDWEB_AUTH_DEFAULT_LOGIN_PAYLOAD_DURATION_IN_SECONDS,
|
||||
),
|
||||
invalid_before:
|
||||
parsedOptions?.invalidBefore ||
|
||||
new Date(
|
||||
Date.now() -
|
||||
1000 * THIRDWEB_AUTH_DEFAULT_LOGIN_PAYLOAD_DURATION_IN_SECONDS,
|
||||
),
|
||||
resources: parsedOptions?.resources,
|
||||
public async payload(
|
||||
options?: LoginOptionsWithOptionalDomain,
|
||||
): Promise<LoginPayloadData> {
|
||||
return buildLoginPayload({
|
||||
wallet: this.wallet,
|
||||
options: this.formatOptions(options),
|
||||
});
|
||||
}
|
||||
|
||||
public async loginWithPayload(
|
||||
payload: LoginPayloadData,
|
||||
): Promise<LoginPayload> {
|
||||
const message = this.generateMessage(payload);
|
||||
const signature = await this.wallet.signMessage(message);
|
||||
|
||||
return {
|
||||
payload,
|
||||
signature,
|
||||
};
|
||||
return signLoginPayload({ wallet: this.wallet, payload });
|
||||
}
|
||||
|
||||
public async login(options?: LoginOptions): Promise<LoginPayload> {
|
||||
const payloadData = await this.payload(options);
|
||||
return await this.loginWithPayload(payloadData);
|
||||
public async login(
|
||||
options?: LoginOptionsWithOptionalDomain,
|
||||
): Promise<LoginPayload> {
|
||||
return buildAndSignLoginPayload({
|
||||
wallet: this.wallet,
|
||||
options: this.formatOptions(options),
|
||||
});
|
||||
}
|
||||
|
||||
public async verify(
|
||||
payload: LoginPayload,
|
||||
options?: VerifyOptions,
|
||||
options?: VerifyOptionsWithOptionalDomain,
|
||||
): Promise<string> {
|
||||
const parsedOptions = VerifyOptionsSchema.parse(options);
|
||||
|
||||
if (payload.payload.type !== this.wallet.type) {
|
||||
throw new Error(
|
||||
`Expected chain type '${this.wallet.type}' does not match chain type on payload '${payload.payload.type}'`,
|
||||
);
|
||||
}
|
||||
|
||||
// Check that the intended domain matches the domain of the payload
|
||||
const domain = parsedOptions?.domain || this.domain;
|
||||
if (payload.payload.domain !== domain) {
|
||||
throw new Error(
|
||||
`Expected domain '${domain}' does not match domain on payload '${payload.payload.domain}'`,
|
||||
);
|
||||
}
|
||||
|
||||
// Check that the payload statement matches the expected statement
|
||||
if (parsedOptions?.statement) {
|
||||
if (payload.payload.statement !== parsedOptions.statement) {
|
||||
throw new Error(
|
||||
`Expected statement '${parsedOptions.statement}' does not match statement on payload '${payload.payload.statement}'`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the intended URI matches the URI of the payload
|
||||
if (parsedOptions?.uri) {
|
||||
if (payload.payload.uri !== parsedOptions.uri) {
|
||||
throw new Error(
|
||||
`Expected URI '${parsedOptions.uri}' does not match URI on payload '${payload.payload.uri}'`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the intended version matches the version of the payload
|
||||
if (parsedOptions?.version) {
|
||||
if (payload.payload.version !== parsedOptions.version) {
|
||||
throw new Error(
|
||||
`Expected version '${parsedOptions.version}' does not match version on payload '${payload.payload.version}'`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the intended chain ID matches the chain ID of the payload
|
||||
if (parsedOptions?.chainId) {
|
||||
if (payload.payload.chain_id !== parsedOptions.chainId) {
|
||||
throw new Error(
|
||||
`Expected chain ID '${parsedOptions.chainId}' does not match chain ID on payload '${payload.payload.chain_id}'`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the payload nonce is valid
|
||||
if (parsedOptions?.validateNonce !== undefined) {
|
||||
try {
|
||||
await parsedOptions.validateNonce(payload.payload.nonce);
|
||||
} catch (err) {
|
||||
throw new Error(`Login request nonce is invalid`);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that it isn't before the invalid before time
|
||||
const currentTime = new Date();
|
||||
if (currentTime < new Date(payload.payload.invalid_before)) {
|
||||
throw new Error(`Login request is not yet valid`);
|
||||
}
|
||||
|
||||
// Check that the payload hasn't expired
|
||||
if (currentTime > new Date(payload.payload.expiration_time)) {
|
||||
throw new Error(`Login request has expired`);
|
||||
}
|
||||
|
||||
// Check that the specified resources are present on the payload
|
||||
if (parsedOptions?.resources) {
|
||||
const missingResources = parsedOptions.resources.filter(
|
||||
(resource) => !payload.payload.resources?.includes(resource),
|
||||
);
|
||||
if (missingResources.length > 0) {
|
||||
throw new Error(
|
||||
`Login request is missing required resources: ${missingResources.join(
|
||||
", ",
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the signing address is the claimed wallet address
|
||||
const message = this.generateMessage(payload.payload);
|
||||
const chainId =
|
||||
this.wallet.type === "evm" && payload.payload.chain_id
|
||||
? parseInt(payload.payload.chain_id)
|
||||
: undefined;
|
||||
const verified = await this.verifySignature(
|
||||
message,
|
||||
payload.signature,
|
||||
payload.payload.address,
|
||||
chainId,
|
||||
);
|
||||
if (!verified) {
|
||||
throw new Error(
|
||||
`Signer address does not match payload address '${payload.payload.address.toLowerCase()}'`,
|
||||
);
|
||||
}
|
||||
|
||||
return payload.payload.address;
|
||||
return verifyLoginPayload({
|
||||
wallet: this.wallet,
|
||||
payload,
|
||||
options: this.formatOptions(options),
|
||||
});
|
||||
}
|
||||
|
||||
public async generate(
|
||||
payload: LoginPayload,
|
||||
options?: GenerateOptions,
|
||||
options?: GenerateOptionsWithOptionalDomain,
|
||||
): Promise<string> {
|
||||
if (isBrowser()) {
|
||||
throw new Error(
|
||||
"Authentication tokens should not be generated in the browser, as they must be signed by a server-side admin wallet.",
|
||||
);
|
||||
}
|
||||
|
||||
const parsedOptions = GenerateOptionsSchema.parse(options);
|
||||
|
||||
const domain = parsedOptions?.domain || this.domain;
|
||||
const userAddress = await this.verify(payload, {
|
||||
domain,
|
||||
...parsedOptions?.verifyOptions,
|
||||
});
|
||||
|
||||
let session: Json | undefined = undefined;
|
||||
if (typeof parsedOptions?.session === "function") {
|
||||
const sessionTrigger = (await parsedOptions.session(userAddress)) as Json;
|
||||
if (sessionTrigger) {
|
||||
session = sessionTrigger;
|
||||
}
|
||||
} else {
|
||||
session = parsedOptions?.session;
|
||||
}
|
||||
|
||||
const adminAddress = await this.wallet.getAddress();
|
||||
return this.createToken({
|
||||
iss: adminAddress,
|
||||
sub: userAddress,
|
||||
aud: domain,
|
||||
nbf: parsedOptions?.invalidBefore || new Date(),
|
||||
exp:
|
||||
parsedOptions?.expirationTime ||
|
||||
new Date(
|
||||
Date.now() + 1000 * THIRDWEB_AUTH_DEFAULT_TOKEN_DURATION_IN_SECONDS,
|
||||
),
|
||||
iat: new Date(),
|
||||
jti: parsedOptions?.tokenId,
|
||||
ctx: session,
|
||||
});
|
||||
}
|
||||
|
||||
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,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate With Token
|
||||
* @remarks Server-side function that authenticates the provided JWT token. This function verifies that
|
||||
* the provided authentication token is valid and returns the address of the authenticated wallet.
|
||||
*
|
||||
* @param domain - The domain of the server-side application doing authentication
|
||||
* @param token - The authentication token being used
|
||||
* @returns The address of the authenticated wallet
|
||||
*
|
||||
* @example
|
||||
* ```javascript
|
||||
* const domain = "example.com";
|
||||
* const loginPayload = await sdk.auth.login(domain);
|
||||
* const token = await sdk.auth.generateAuthToken(domain, loginPayload);
|
||||
*
|
||||
* // Authenticate the token and get the address of authenticating users wallet
|
||||
* const address = sdk.auth.authenticate(domain, token);
|
||||
* ```
|
||||
*/
|
||||
public async authenticate<TSession extends Json = Json>(
|
||||
token: string,
|
||||
options?: AuthenticateOptions,
|
||||
): Promise<User<TSession>> {
|
||||
if (isBrowser()) {
|
||||
throw new Error(
|
||||
"Should not authenticate tokens in the browser, as they must be verified by the server-side admin wallet.",
|
||||
);
|
||||
}
|
||||
|
||||
const parsedOptions = AuthenticateOptionsSchema.parse(options);
|
||||
const domain = parsedOptions?.domain || this.domain;
|
||||
|
||||
const { payload, signature } = this.parseToken(token);
|
||||
|
||||
// Check that the payload unique ID is valid
|
||||
if (parsedOptions?.validateTokenId !== undefined) {
|
||||
try {
|
||||
await parsedOptions.validateTokenId(payload.jti);
|
||||
} catch (err) {
|
||||
throw new Error(`Token ID is invalid`);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the token audience matches the domain
|
||||
if (payload.aud !== domain) {
|
||||
throw new Error(
|
||||
`Expected token to be for the domain '${domain}', but found token with domain '${payload.aud}'`,
|
||||
);
|
||||
}
|
||||
|
||||
// Check that the token is past the invalid before time
|
||||
const currentTime = Math.floor(new Date().getTime() / 1000);
|
||||
if (currentTime < payload.nbf) {
|
||||
throw new Error(
|
||||
`This token is invalid before epoch time '${payload.nbf}', current epoch time is '${currentTime}'`,
|
||||
);
|
||||
}
|
||||
|
||||
// Check that the token hasn't expired
|
||||
if (currentTime > payload.exp) {
|
||||
throw new Error(
|
||||
`This token expired at epoch time '${payload.exp}', current epoch time is '${currentTime}'`,
|
||||
);
|
||||
}
|
||||
|
||||
// Check that the connected wallet matches the token issuer
|
||||
const connectedAddress = await this.wallet.getAddress();
|
||||
if (connectedAddress.toLowerCase() !== payload.iss.toLowerCase()) {
|
||||
throw new Error(
|
||||
`Expected the connected wallet address '${connectedAddress}' to match the token issuer address '${payload.iss}'`,
|
||||
);
|
||||
}
|
||||
|
||||
let chainId: number | undefined = undefined;
|
||||
if (this.wallet.getChainId) {
|
||||
try {
|
||||
chainId = await this.wallet.getChainId();
|
||||
} catch {
|
||||
// ignore error
|
||||
}
|
||||
}
|
||||
|
||||
const verified = await this.verifySignature(
|
||||
JSON.stringify(payload),
|
||||
signature,
|
||||
connectedAddress,
|
||||
chainId,
|
||||
);
|
||||
if (!verified) {
|
||||
throw new Error(
|
||||
`The connected wallet address '${connectedAddress}' did not sign the token`,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
address: payload.sub,
|
||||
session: payload.ctx as TSession | undefined,
|
||||
};
|
||||
}
|
||||
|
||||
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 {
|
||||
return generateJWT({
|
||||
wallet: this.wallet,
|
||||
payload,
|
||||
signature,
|
||||
};
|
||||
options: this.formatOptions(options),
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
public async refresh(jwt: string, expirationTime?: Date): Promise<string> {
|
||||
return refreshJWT({
|
||||
wallet: this.wallet,
|
||||
jwt,
|
||||
options: { expirationTime },
|
||||
});
|
||||
}
|
||||
|
||||
private async verifySignature(
|
||||
message: string,
|
||||
signature: string,
|
||||
address: string,
|
||||
chainId?: number,
|
||||
) {
|
||||
return this.wallet.verifySignature(message, signature, address, chainId);
|
||||
public async authenticate<TSession extends Json = Json>(
|
||||
jwt: string,
|
||||
options?: AuthenticateOptionsWithOptionalDomain,
|
||||
): Promise<User<TSession>> {
|
||||
return authenticateJWT({
|
||||
wallet: this.wallet,
|
||||
jwt,
|
||||
options: this.formatOptions(options),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a EIP-4361 & CAIP-122 compliant message to sign based on the login payload
|
||||
*/
|
||||
private generateMessage(payload: LoginPayloadData): string {
|
||||
const typeField = payload.type === "evm" ? "Ethereum" : "Solana";
|
||||
const header = `${payload.domain} wants you to sign in with your ${typeField} account:`;
|
||||
let prefix = [header, payload.address].join("\n");
|
||||
prefix = [prefix, payload.statement].join("\n\n");
|
||||
if (payload.statement) {
|
||||
prefix += "\n";
|
||||
}
|
||||
public parseToken(jwt: string): AuthenticationPayload {
|
||||
return parseJWT(jwt);
|
||||
}
|
||||
|
||||
const suffixArray = [];
|
||||
if (payload.uri) {
|
||||
const uriField = `URI: ${payload.uri}`;
|
||||
suffixArray.push(uriField);
|
||||
}
|
||||
|
||||
const versionField = `Version: ${payload.version}`;
|
||||
suffixArray.push(versionField);
|
||||
|
||||
if (payload.chain_id) {
|
||||
const chainField = `Chain ID: ` + payload.chain_id || "1";
|
||||
suffixArray.push(chainField);
|
||||
}
|
||||
|
||||
const nonceField = `Nonce: ${payload.nonce}`;
|
||||
suffixArray.push(nonceField);
|
||||
|
||||
const issuedAtField = `Issued At: ${payload.issued_at}`;
|
||||
suffixArray.push(issuedAtField);
|
||||
|
||||
const expiryField = `Expiration Time: ${payload.expiration_time}`;
|
||||
suffixArray.push(expiryField);
|
||||
|
||||
if (payload.invalid_before) {
|
||||
const invalidBeforeField = `Not Before: ${payload.invalid_before}`;
|
||||
suffixArray.push(invalidBeforeField);
|
||||
}
|
||||
|
||||
if (payload.resources) {
|
||||
suffixArray.push(
|
||||
[`Resources:`, ...payload.resources.map((x) => `- ${x}`)].join("\n"),
|
||||
);
|
||||
}
|
||||
|
||||
const suffix = suffixArray.join("\n");
|
||||
return [prefix, suffix].join("\n");
|
||||
private formatOptions<TOptions extends { domain?: string }>(
|
||||
options?: TOptions,
|
||||
): Omit<TOptions, "domain"> & { domain: string } {
|
||||
return options
|
||||
? { ...options, domain: options?.domain || this.domain }
|
||||
: ({ domain: this.domain } as Omit<TOptions, "domain"> & {
|
||||
domain: string;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
import {
|
||||
AuthenticateOptionsSchema,
|
||||
AuthenticationPayload,
|
||||
AuthenticationPayloadData,
|
||||
AuthenticationPayloadDataSchema,
|
||||
} from "../schema/authenticate";
|
||||
import { Json, User } from "../schema/common";
|
||||
import {
|
||||
BuildJwtParams,
|
||||
RefreshJwtParams,
|
||||
GenerateJwtParams,
|
||||
AuthenticateJwtParams,
|
||||
} from "../schema/functions";
|
||||
import { GenerateOptionsSchema } from "../schema/generate";
|
||||
import { RefreshOptionsSchema } from "../schema/refresh";
|
||||
import { verifyLoginPayload } from "./login";
|
||||
|
||||
function isBrowser() {
|
||||
return typeof window !== "undefined";
|
||||
}
|
||||
|
||||
function base64encode(data: string): string {
|
||||
if (isBrowser()) {
|
||||
return window.btoa(data);
|
||||
}
|
||||
|
||||
return Buffer.from(data).toString("base64").replace(/=/g, "");
|
||||
}
|
||||
|
||||
function base64decode(data: string): string {
|
||||
if (isBrowser()) {
|
||||
return window.atob(data);
|
||||
}
|
||||
|
||||
return Buffer.from(data, "base64").toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build JWT token based on the authentication payload
|
||||
*/
|
||||
async function buildJWT({ wallet, payload }: BuildJwtParams): Promise<string> {
|
||||
const payloadData = AuthenticationPayloadDataSchema.parse(payload);
|
||||
|
||||
const message = JSON.stringify(payloadData);
|
||||
const signature = await 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 = base64encode(JSON.stringify(header));
|
||||
const encodedData = base64encode(JSON.stringify(payloadData));
|
||||
const encodedSignature = base64encode(signature);
|
||||
|
||||
// Generate a JWT with base64 encoded header, payload, and signature
|
||||
const jwt = `${encodedHeader}.${encodedData}.${encodedSignature}`;
|
||||
|
||||
return jwt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new JWT using a login payload
|
||||
*/
|
||||
export async function generateJWT({
|
||||
wallet,
|
||||
payload,
|
||||
options,
|
||||
}: GenerateJwtParams): Promise<string> {
|
||||
const parsedOptions = GenerateOptionsSchema.parse(options);
|
||||
const userAddress = await verifyLoginPayload({
|
||||
wallet,
|
||||
payload,
|
||||
options: {
|
||||
domain: parsedOptions.domain,
|
||||
...parsedOptions.verifyOptions,
|
||||
},
|
||||
});
|
||||
|
||||
let session: Json | undefined = undefined;
|
||||
if (typeof parsedOptions?.session === "function") {
|
||||
const sessionTrigger = (await parsedOptions.session(userAddress)) as Json;
|
||||
if (sessionTrigger) {
|
||||
session = sessionTrigger;
|
||||
}
|
||||
} else {
|
||||
session = parsedOptions?.session;
|
||||
}
|
||||
|
||||
const adminAddress = await wallet.getAddress();
|
||||
return buildJWT({
|
||||
wallet,
|
||||
payload: {
|
||||
iss: adminAddress,
|
||||
sub: userAddress,
|
||||
aud: parsedOptions.domain,
|
||||
nbf: parsedOptions?.invalidBefore || new Date(),
|
||||
exp: parsedOptions.expirationTime,
|
||||
iat: new Date(),
|
||||
jti: parsedOptions?.tokenId,
|
||||
ctx: session,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse data from an encoded auth JWT
|
||||
*/
|
||||
export function parseJWT(jwt: string): AuthenticationPayload {
|
||||
const encodedPayload = jwt.split(".")[1];
|
||||
const encodedSignature = jwt.split(".")[2];
|
||||
const payload: AuthenticationPayloadData = JSON.parse(
|
||||
base64decode(encodedPayload),
|
||||
);
|
||||
const signature = base64decode(encodedSignature);
|
||||
|
||||
return {
|
||||
payload,
|
||||
signature,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh an existing JWT
|
||||
*/
|
||||
export async function refreshJWT({
|
||||
wallet,
|
||||
jwt,
|
||||
options,
|
||||
}: RefreshJwtParams): Promise<string> {
|
||||
const { payload } = parseJWT(jwt);
|
||||
const parsedOptions = RefreshOptionsSchema.parse(options);
|
||||
return buildJWT({
|
||||
wallet,
|
||||
payload: {
|
||||
iss: payload.iss,
|
||||
sub: payload.sub,
|
||||
aud: payload.aud,
|
||||
nbf: new Date(),
|
||||
exp: parsedOptions.expirationTime,
|
||||
iat: new Date(),
|
||||
ctx: payload.ctx,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a JWT and extract the user's info
|
||||
*/
|
||||
export async function authenticateJWT<TSession extends Json = Json>({
|
||||
wallet,
|
||||
jwt,
|
||||
options,
|
||||
}: AuthenticateJwtParams): Promise<User<TSession>> {
|
||||
const parsedOptions = AuthenticateOptionsSchema.parse(options);
|
||||
const { payload, signature } = parseJWT(jwt);
|
||||
|
||||
// Check that the payload unique ID is valid
|
||||
if (parsedOptions?.validateTokenId !== undefined) {
|
||||
try {
|
||||
await parsedOptions.validateTokenId(payload.jti);
|
||||
} catch (err) {
|
||||
throw new Error(`Token ID is invalid`);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the token audience matches the domain
|
||||
if (payload.aud !== parsedOptions.domain) {
|
||||
throw new Error(
|
||||
`Expected token to be for the domain '${parsedOptions.domain}', but found token with domain '${payload.aud}'`,
|
||||
);
|
||||
}
|
||||
|
||||
// Check that the token is past the invalid before time
|
||||
const currentTime = Math.floor(new Date().getTime() / 1000);
|
||||
if (currentTime < payload.nbf) {
|
||||
throw new Error(
|
||||
`This token is invalid before epoch time '${payload.nbf}', current epoch time is '${currentTime}'`,
|
||||
);
|
||||
}
|
||||
|
||||
// Check that the token hasn't expired
|
||||
if (currentTime > payload.exp) {
|
||||
throw new Error(
|
||||
`This token expired at epoch time '${payload.exp}', current epoch time is '${currentTime}'`,
|
||||
);
|
||||
}
|
||||
|
||||
// Check that the connected wallet matches the token issuer
|
||||
const issuerAddress = parsedOptions.issuerAddress
|
||||
? parsedOptions.issuerAddress
|
||||
: await wallet.getAddress();
|
||||
if (issuerAddress.toLowerCase() !== payload.iss.toLowerCase()) {
|
||||
throw new Error(
|
||||
`The expected issuer address '${issuerAddress}' did not match the token issuer address '${payload.iss}'`,
|
||||
);
|
||||
}
|
||||
|
||||
let chainId: number | undefined = undefined;
|
||||
if (wallet.getChainId) {
|
||||
try {
|
||||
chainId = await wallet.getChainId();
|
||||
} catch {
|
||||
// ignore error
|
||||
}
|
||||
}
|
||||
|
||||
const verified = await wallet.verifySignature(
|
||||
JSON.stringify(payload),
|
||||
signature,
|
||||
issuerAddress,
|
||||
chainId,
|
||||
);
|
||||
if (!verified) {
|
||||
throw new Error(
|
||||
`The expected signer address '${issuerAddress}' did not sign the token`,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
address: payload.sub,
|
||||
session: payload.ctx as TSession | undefined,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
import {
|
||||
BuildLoginPayloadParams,
|
||||
SignLoginPayloadParams,
|
||||
VerifyLoginPayloadParams,
|
||||
} from "../schema/functions";
|
||||
import {
|
||||
LoginOptionsSchema,
|
||||
LoginPayload,
|
||||
LoginPayloadData,
|
||||
LoginPayloadDataSchema,
|
||||
} from "../schema/login";
|
||||
import { VerifyOptionsSchema } from "../schema/verify";
|
||||
|
||||
/**
|
||||
* Create an EIP-4361 & CAIP-122 compliant message to sign based on the login payload
|
||||
*/
|
||||
function createLoginMessage(payload: LoginPayloadData): string {
|
||||
const typeField = payload.type === "evm" ? "Ethereum" : "Solana";
|
||||
const header = `${payload.domain} wants you to sign in with your ${typeField} account:`;
|
||||
let prefix = [header, payload.address].join("\n");
|
||||
prefix = [prefix, payload.statement].join("\n\n");
|
||||
if (payload.statement) {
|
||||
prefix += "\n";
|
||||
}
|
||||
|
||||
const suffixArray = [];
|
||||
if (payload.uri) {
|
||||
const uriField = `URI: ${payload.uri}`;
|
||||
suffixArray.push(uriField);
|
||||
}
|
||||
|
||||
const versionField = `Version: ${payload.version}`;
|
||||
suffixArray.push(versionField);
|
||||
|
||||
if (payload.chain_id) {
|
||||
const chainField = `Chain ID: ` + payload.chain_id || "1";
|
||||
suffixArray.push(chainField);
|
||||
}
|
||||
|
||||
const nonceField = `Nonce: ${payload.nonce}`;
|
||||
suffixArray.push(nonceField);
|
||||
|
||||
const issuedAtField = `Issued At: ${payload.issued_at}`;
|
||||
suffixArray.push(issuedAtField);
|
||||
|
||||
const expiryField = `Expiration Time: ${payload.expiration_time}`;
|
||||
suffixArray.push(expiryField);
|
||||
|
||||
if (payload.invalid_before) {
|
||||
const invalidBeforeField = `Not Before: ${payload.invalid_before}`;
|
||||
suffixArray.push(invalidBeforeField);
|
||||
}
|
||||
|
||||
if (payload.resources) {
|
||||
suffixArray.push(
|
||||
[`Resources:`, ...payload.resources.map((x) => `- ${x}`)].join("\n"),
|
||||
);
|
||||
}
|
||||
|
||||
const suffix = suffixArray.join("\n");
|
||||
return [prefix, suffix].join("\n");
|
||||
}
|
||||
|
||||
export async function buildLoginPayload({
|
||||
wallet,
|
||||
options,
|
||||
}: BuildLoginPayloadParams): Promise<LoginPayloadData> {
|
||||
const parsedOptions = LoginOptionsSchema.parse(options);
|
||||
|
||||
let chainId: string | undefined = parsedOptions?.chainId;
|
||||
if (!chainId && wallet.getChainId) {
|
||||
try {
|
||||
chainId = (await wallet.getChainId()).toString();
|
||||
} catch {
|
||||
// ignore error
|
||||
}
|
||||
}
|
||||
|
||||
return LoginPayloadDataSchema.parse({
|
||||
type: wallet.type,
|
||||
domain: parsedOptions.domain,
|
||||
address: parsedOptions?.address || (await wallet.getAddress()),
|
||||
statement: parsedOptions?.statement,
|
||||
version: parsedOptions?.version,
|
||||
uri: parsedOptions?.uri,
|
||||
chain_id: chainId,
|
||||
nonce: parsedOptions?.nonce,
|
||||
expiration_time: parsedOptions.expirationTime,
|
||||
invalid_before: parsedOptions.invalidBefore,
|
||||
resources: parsedOptions?.resources,
|
||||
});
|
||||
}
|
||||
|
||||
export async function signLoginPayload({
|
||||
wallet,
|
||||
payload,
|
||||
}: SignLoginPayloadParams): Promise<LoginPayload> {
|
||||
const message = createLoginMessage(payload);
|
||||
const signature = await wallet.signMessage(message);
|
||||
|
||||
return {
|
||||
payload,
|
||||
signature,
|
||||
};
|
||||
}
|
||||
|
||||
export async function buildAndSignLoginPayload({
|
||||
wallet,
|
||||
options,
|
||||
}: BuildLoginPayloadParams): Promise<LoginPayload> {
|
||||
const payload = await buildLoginPayload({ wallet, options });
|
||||
return signLoginPayload({ wallet, payload });
|
||||
}
|
||||
|
||||
export async function verifyLoginPayload({
|
||||
wallet,
|
||||
payload,
|
||||
options,
|
||||
}: VerifyLoginPayloadParams): Promise<string> {
|
||||
const parsedOptions = VerifyOptionsSchema.parse(options);
|
||||
|
||||
if (payload.payload.type !== wallet.type) {
|
||||
throw new Error(
|
||||
`Expected chain type '${wallet.type}' does not match chain type on payload '${payload.payload.type}'`,
|
||||
);
|
||||
}
|
||||
|
||||
// Check that the intended domain matches the domain of the payload
|
||||
if (payload.payload.domain !== parsedOptions.domain) {
|
||||
throw new Error(
|
||||
`Expected domain '${parsedOptions.domain}' does not match domain on payload '${payload.payload.domain}'`,
|
||||
);
|
||||
}
|
||||
|
||||
// Check that the payload statement matches the expected statement
|
||||
if (parsedOptions?.statement) {
|
||||
if (payload.payload.statement !== parsedOptions.statement) {
|
||||
throw new Error(
|
||||
`Expected statement '${parsedOptions.statement}' does not match statement on payload '${payload.payload.statement}'`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the intended URI matches the URI of the payload
|
||||
if (parsedOptions?.uri) {
|
||||
if (payload.payload.uri !== parsedOptions.uri) {
|
||||
throw new Error(
|
||||
`Expected URI '${parsedOptions.uri}' does not match URI on payload '${payload.payload.uri}'`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the intended version matches the version of the payload
|
||||
if (parsedOptions?.version) {
|
||||
if (payload.payload.version !== parsedOptions.version) {
|
||||
throw new Error(
|
||||
`Expected version '${parsedOptions.version}' does not match version on payload '${payload.payload.version}'`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the intended chain ID matches the chain ID of the payload
|
||||
if (parsedOptions?.chainId) {
|
||||
if (payload.payload.chain_id !== parsedOptions.chainId) {
|
||||
throw new Error(
|
||||
`Expected chain ID '${parsedOptions.chainId}' does not match chain ID on payload '${payload.payload.chain_id}'`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the payload nonce is valid
|
||||
if (parsedOptions?.validateNonce !== undefined) {
|
||||
try {
|
||||
await parsedOptions.validateNonce(payload.payload.nonce);
|
||||
} catch (err) {
|
||||
throw new Error(`Login request nonce is invalid`);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that it isn't before the invalid before time
|
||||
const currentTime = new Date();
|
||||
if (currentTime < new Date(payload.payload.invalid_before)) {
|
||||
throw new Error(`Login request is not yet valid`);
|
||||
}
|
||||
|
||||
// Check that the payload hasn't expired
|
||||
if (currentTime > new Date(payload.payload.expiration_time)) {
|
||||
throw new Error(`Login request has expired`);
|
||||
}
|
||||
|
||||
// Check that the specified resources are present on the payload
|
||||
if (parsedOptions?.resources) {
|
||||
const missingResources = parsedOptions.resources.filter(
|
||||
(resource) => !payload.payload.resources?.includes(resource),
|
||||
);
|
||||
if (missingResources.length > 0) {
|
||||
throw new Error(
|
||||
`Login request is missing required resources: ${missingResources.join(
|
||||
", ",
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the signing address is the claimed wallet address
|
||||
const message = createLoginMessage(payload.payload);
|
||||
const chainId =
|
||||
wallet.type === "evm" && payload.payload.chain_id
|
||||
? parseInt(payload.payload.chain_id)
|
||||
: undefined;
|
||||
const verified = await wallet.verifySignature(
|
||||
message,
|
||||
payload.signature,
|
||||
payload.payload.address,
|
||||
chainId,
|
||||
);
|
||||
if (!verified) {
|
||||
throw new Error(
|
||||
`Signer address does not match payload address '${payload.payload.address.toLowerCase()}'`,
|
||||
);
|
||||
}
|
||||
|
||||
return payload.payload.address;
|
||||
}
|
||||
@@ -1,2 +1,25 @@
|
||||
// Export thirdweb auth class
|
||||
export { ThirdwebAuth } from "./auth";
|
||||
export * from "./schema";
|
||||
|
||||
// Export individual auth functions
|
||||
export {
|
||||
generateJWT,
|
||||
parseJWT,
|
||||
refreshJWT,
|
||||
authenticateJWT,
|
||||
} from "./functions/jwt";
|
||||
export {
|
||||
buildLoginPayload,
|
||||
signLoginPayload,
|
||||
buildAndSignLoginPayload,
|
||||
verifyLoginPayload,
|
||||
} from "./functions/login";
|
||||
|
||||
// Export schema files individually
|
||||
export * from "./schema/authenticate";
|
||||
export * from "./schema/common";
|
||||
export * from "./schema/functions";
|
||||
export * from "./schema/generate";
|
||||
export * from "./schema/login";
|
||||
export * from "./schema/refresh";
|
||||
export * from "./schema/verify";
|
||||
|
||||
@@ -1,216 +0,0 @@
|
||||
import { utils, BigNumber } from "ethers";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { z } from "zod";
|
||||
|
||||
export const AddressSchema = z.string().refine(
|
||||
(arg) => utils.isAddress(arg),
|
||||
(out) => {
|
||||
return {
|
||||
message: `${out} is not a valid address`,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
export const RawDateSchema = z.date().transform((i) => {
|
||||
return BigNumber.from(Math.floor(i.getTime() / 1000));
|
||||
});
|
||||
|
||||
export const AccountTypeSchema = z.union([
|
||||
z.literal("evm"),
|
||||
z.literal("solana"),
|
||||
]);
|
||||
|
||||
const literalSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]);
|
||||
type Literal = z.infer<typeof literalSchema>;
|
||||
export type Json = Literal | { [key: string]: Json } | Json[];
|
||||
const JsonSchema: z.ZodType<Json> = z.lazy(
|
||||
() => z.union([literalSchema, z.array(JsonSchema), z.record(JsonSchema)]),
|
||||
{ invalid_type_error: "Provided value was not valid JSON" },
|
||||
);
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const LoginOptionsSchema = z
|
||||
.object({
|
||||
domain: z.string().optional(),
|
||||
address: z.string().optional(),
|
||||
statement: z.string().optional(),
|
||||
uri: z.string().optional(),
|
||||
version: z.string().optional(),
|
||||
chainId: z.string().optional(),
|
||||
nonce: z.string().optional(),
|
||||
expirationTime: z.date().optional(),
|
||||
invalidBefore: z.date().optional(),
|
||||
resources: z.array(z.string()).optional(),
|
||||
})
|
||||
.optional();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const LoginPayloadDataSchema = z.object({
|
||||
type: AccountTypeSchema,
|
||||
domain: z.string(),
|
||||
address: z.string(),
|
||||
statement: z
|
||||
.string()
|
||||
.default(
|
||||
"Please ensure that the domain above matches the URL of the current website.",
|
||||
),
|
||||
uri: z.string().optional(),
|
||||
version: z.string().default("1"),
|
||||
chain_id: z.string().optional(),
|
||||
nonce: z.string().default(uuidv4()),
|
||||
issued_at: z
|
||||
.date()
|
||||
.default(new Date())
|
||||
.transform((d) => d.toISOString()),
|
||||
expiration_time: z.date().transform((d) => d.toISOString()),
|
||||
invalid_before: z
|
||||
.date()
|
||||
.default(new Date())
|
||||
.transform((d) => d.toISOString()),
|
||||
resources: z.array(z.string()).optional(),
|
||||
});
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const LoginPayloadSchema = z.object({
|
||||
payload: LoginPayloadDataSchema,
|
||||
signature: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
const VerifyOptionsSchemaRequired = z.object({
|
||||
domain: z.string().optional(),
|
||||
statement: z.string().optional(),
|
||||
uri: z.string().optional(),
|
||||
version: z.string().optional(),
|
||||
chainId: z.string().optional(),
|
||||
validateNonce: z.function().args(z.string()).optional(),
|
||||
resources: z.array(z.string()).optional(),
|
||||
});
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const VerifyOptionsSchema = VerifyOptionsSchemaRequired.optional();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const GenerateOptionsSchema = z
|
||||
.object({
|
||||
domain: z.string().optional(),
|
||||
tokenId: z.string().optional(),
|
||||
expirationTime: z.date().optional(),
|
||||
invalidBefore: z.date().optional(),
|
||||
session: z.union([JsonSchema, z.function().args(z.string())]).optional(),
|
||||
verifyOptions: VerifyOptionsSchemaRequired.omit({
|
||||
domain: true,
|
||||
}).optional(),
|
||||
})
|
||||
.optional();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const AuthenticationPayloadDataSchema = z.object({
|
||||
iss: z.string(),
|
||||
sub: z.string(),
|
||||
aud: z.string(),
|
||||
exp: RawDateSchema.transform((b) => b.toNumber()),
|
||||
nbf: RawDateSchema.transform((b) => b.toNumber()),
|
||||
iat: RawDateSchema.transform((b) => b.toNumber()),
|
||||
jti: z.string().default(uuidv4()),
|
||||
ctx: JsonSchema.optional(),
|
||||
});
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const AuthenticationPayloadSchema = z.object({
|
||||
payload: AuthenticationPayloadDataSchema,
|
||||
signature: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const AuthenticateOptionsSchema = z
|
||||
.object({
|
||||
domain: z.string().optional(),
|
||||
validateTokenId: z.function().args(z.string()).optional(),
|
||||
})
|
||||
.optional();
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type LoginOptions = z.input<typeof LoginOptionsSchema>;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type LoginPayloadData = z.output<typeof LoginPayloadDataSchema>;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type LoginPayload = z.output<typeof LoginPayloadSchema>;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type VerifyOptions = z.input<typeof VerifyOptionsSchema>;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type GenerateOptions = z.input<typeof GenerateOptionsSchema>;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type AuthenticationPayloadData = z.output<
|
||||
typeof AuthenticationPayloadDataSchema
|
||||
>;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export type AuthenticationPayloadDataInput = z.input<
|
||||
typeof AuthenticationPayloadDataSchema
|
||||
>;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type AuthenticationPayload = z.output<
|
||||
typeof AuthenticationPayloadSchema
|
||||
>;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type AuthenticateOptions = z.output<typeof AuthenticateOptionsSchema>;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type User<TContext extends Json = Json> = {
|
||||
address: string;
|
||||
session?: TContext;
|
||||
};
|
||||
|
||||
export const LoginPayloadOutputSchema = LoginPayloadSchema.extend({
|
||||
payload: LoginPayloadDataSchema.extend({
|
||||
issued_at: z.string(),
|
||||
expiration_time: z.string(),
|
||||
invalid_before: z.string(),
|
||||
}),
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
import { z } from "zod";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { AddressSchema, JsonSchema, RawDateSchema } from "./common";
|
||||
|
||||
export const AuthenticationPayloadDataSchema = z.object({
|
||||
iss: z.string(),
|
||||
sub: z.string(),
|
||||
aud: z.string(),
|
||||
exp: RawDateSchema,
|
||||
nbf: RawDateSchema,
|
||||
iat: RawDateSchema,
|
||||
jti: z.string().default(uuidv4()),
|
||||
ctx: JsonSchema.optional(),
|
||||
});
|
||||
|
||||
export const AuthenticationPayloadSchema = z.object({
|
||||
payload: AuthenticationPayloadDataSchema,
|
||||
signature: z.string(),
|
||||
});
|
||||
|
||||
export const AuthenticateOptionsSchema = z.object({
|
||||
domain: z.string(),
|
||||
issuerAddress: AddressSchema.optional(),
|
||||
validateTokenId: z.function().args(z.string()).optional(),
|
||||
});
|
||||
|
||||
export type AuthenticationPayloadDataInput = z.input<
|
||||
typeof AuthenticationPayloadDataSchema
|
||||
>;
|
||||
|
||||
export type AuthenticationPayloadData = z.output<
|
||||
typeof AuthenticationPayloadDataSchema
|
||||
>;
|
||||
|
||||
export type AuthenticationPayload = z.output<
|
||||
typeof AuthenticationPayloadSchema
|
||||
>;
|
||||
|
||||
export type AuthenticateOptions = z.output<typeof AuthenticateOptionsSchema>;
|
||||
|
||||
export type AuthenticateOptionsWithOptionalDomain = Omit<
|
||||
AuthenticateOptions,
|
||||
"domain"
|
||||
> & {
|
||||
domain?: string;
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
import { utils } from "ethers";
|
||||
import { z } from "zod";
|
||||
|
||||
const literalSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]);
|
||||
type Literal = z.infer<typeof literalSchema>;
|
||||
export type Json = Literal | { [key: string]: Json } | Json[];
|
||||
|
||||
export const JsonSchema: z.ZodType<Json> = z.lazy(
|
||||
() => z.union([literalSchema, z.array(JsonSchema), z.record(JsonSchema)]),
|
||||
{ invalid_type_error: "Provided value was not valid JSON" },
|
||||
);
|
||||
|
||||
export const AddressSchema = z.string().refine(
|
||||
(arg) => utils.isAddress(arg),
|
||||
(out) => {
|
||||
return {
|
||||
message: `${out} is not a valid address`,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
export const RawDateSchema = z.date().transform((i) => {
|
||||
return Math.floor(i.getTime() / 1000);
|
||||
});
|
||||
|
||||
export const AccountTypeSchema = z.union([
|
||||
z.literal("evm"),
|
||||
z.literal("solana"),
|
||||
]);
|
||||
|
||||
export type User<TContext extends Json = Json> = {
|
||||
address: string;
|
||||
session?: TContext;
|
||||
};
|
||||
@@ -0,0 +1,48 @@
|
||||
import { GenericAuthWallet } from "@thirdweb-dev/wallets";
|
||||
import { LoginOptions, LoginPayload, LoginPayloadData } from "./login";
|
||||
import { VerifyOptions } from "./verify";
|
||||
import {
|
||||
AuthenticateOptions,
|
||||
AuthenticationPayloadDataInput,
|
||||
} from "./authenticate";
|
||||
import { RefreshOptions } from "./refresh";
|
||||
import { GenerateOptions } from "./generate";
|
||||
|
||||
export type BuildLoginPayloadParams = {
|
||||
wallet: GenericAuthWallet;
|
||||
options: LoginOptions;
|
||||
};
|
||||
|
||||
export type SignLoginPayloadParams = {
|
||||
wallet: GenericAuthWallet;
|
||||
payload: LoginPayloadData;
|
||||
};
|
||||
|
||||
export type VerifyLoginPayloadParams = {
|
||||
wallet: GenericAuthWallet;
|
||||
payload: LoginPayload;
|
||||
options: VerifyOptions;
|
||||
};
|
||||
|
||||
export type BuildJwtParams = {
|
||||
wallet: GenericAuthWallet;
|
||||
payload: AuthenticationPayloadDataInput;
|
||||
};
|
||||
|
||||
export type GenerateJwtParams = {
|
||||
wallet: GenericAuthWallet;
|
||||
payload: LoginPayload;
|
||||
options: GenerateOptions;
|
||||
};
|
||||
|
||||
export type RefreshJwtParams = {
|
||||
wallet: GenericAuthWallet;
|
||||
jwt: string;
|
||||
options?: RefreshOptions;
|
||||
};
|
||||
|
||||
export type AuthenticateJwtParams = {
|
||||
wallet: GenericAuthWallet;
|
||||
jwt: string;
|
||||
options: AuthenticateOptions;
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
import { z } from "zod";
|
||||
import { VerifyOptionsSchema } from "./verify";
|
||||
import { JsonSchema } from "./common";
|
||||
import { THIRDWEB_AUTH_DEFAULT_TOKEN_DURATION_IN_SECONDS } from "../../constants";
|
||||
|
||||
export const GenerateOptionsSchema = z.object({
|
||||
domain: z.string(),
|
||||
tokenId: z.string().optional(),
|
||||
expirationTime: z
|
||||
.date()
|
||||
.default(
|
||||
() =>
|
||||
new Date(
|
||||
Date.now() + 1000 * THIRDWEB_AUTH_DEFAULT_TOKEN_DURATION_IN_SECONDS,
|
||||
),
|
||||
),
|
||||
invalidBefore: z.date().optional(),
|
||||
session: z.union([JsonSchema, z.function().args(z.string())]).optional(),
|
||||
verifyOptions: VerifyOptionsSchema.omit({
|
||||
domain: true,
|
||||
}).optional(),
|
||||
});
|
||||
|
||||
export type GenerateOptions = z.input<typeof GenerateOptionsSchema>;
|
||||
|
||||
export type GenerateOptionsWithOptionalDomain = Omit<
|
||||
GenerateOptions,
|
||||
"domain"
|
||||
> & {
|
||||
domain?: string;
|
||||
};
|
||||
@@ -0,0 +1,81 @@
|
||||
import { z } from "zod";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { AccountTypeSchema } from "./common";
|
||||
import { THIRDWEB_AUTH_DEFAULT_LOGIN_PAYLOAD_DURATION_IN_SECONDS } from "../../constants";
|
||||
|
||||
export const LoginOptionsSchema = z.object({
|
||||
domain: z.string(),
|
||||
address: z.string().optional(),
|
||||
statement: z.string().optional(),
|
||||
uri: z.string().optional(),
|
||||
version: z.string().optional(),
|
||||
chainId: z.string().optional(),
|
||||
nonce: z.string().optional(),
|
||||
expirationTime: z
|
||||
.date()
|
||||
.default(
|
||||
() =>
|
||||
new Date(
|
||||
Date.now() +
|
||||
1000 * THIRDWEB_AUTH_DEFAULT_LOGIN_PAYLOAD_DURATION_IN_SECONDS,
|
||||
),
|
||||
),
|
||||
invalidBefore: z
|
||||
.date()
|
||||
.default(
|
||||
() =>
|
||||
new Date(
|
||||
Date.now() -
|
||||
1000 * THIRDWEB_AUTH_DEFAULT_LOGIN_PAYLOAD_DURATION_IN_SECONDS,
|
||||
),
|
||||
),
|
||||
resources: z.array(z.string()).optional(),
|
||||
});
|
||||
|
||||
export const LoginPayloadDataSchema = z.object({
|
||||
type: AccountTypeSchema,
|
||||
domain: z.string(),
|
||||
address: z.string(),
|
||||
statement: z
|
||||
.string()
|
||||
.default(
|
||||
"Please ensure that the domain above matches the URL of the current website.",
|
||||
),
|
||||
uri: z.string().optional(),
|
||||
version: z.string().default("1"),
|
||||
chain_id: z.string().optional(),
|
||||
nonce: z.string().default(uuidv4()),
|
||||
issued_at: z
|
||||
.date()
|
||||
.default(new Date())
|
||||
.transform((d) => d.toISOString()),
|
||||
expiration_time: z.date().transform((d) => d.toISOString()),
|
||||
invalid_before: z
|
||||
.date()
|
||||
.default(new Date())
|
||||
.transform((d) => d.toISOString()),
|
||||
resources: z.array(z.string()).optional(),
|
||||
});
|
||||
|
||||
export const LoginPayloadSchema = z.object({
|
||||
payload: LoginPayloadDataSchema,
|
||||
signature: z.string(),
|
||||
});
|
||||
|
||||
export const LoginPayloadOutputSchema = LoginPayloadSchema.extend({
|
||||
payload: LoginPayloadDataSchema.extend({
|
||||
issued_at: z.string(),
|
||||
expiration_time: z.string(),
|
||||
invalid_before: z.string(),
|
||||
}),
|
||||
});
|
||||
|
||||
export type LoginOptions = z.input<typeof LoginOptionsSchema>;
|
||||
|
||||
export type LoginPayloadData = z.output<typeof LoginPayloadDataSchema>;
|
||||
|
||||
export type LoginPayload = z.output<typeof LoginPayloadSchema>;
|
||||
|
||||
export type LoginOptionsWithOptionalDomain = Omit<LoginOptions, "domain"> & {
|
||||
domain?: string;
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
import { z } from "zod";
|
||||
import { THIRDWEB_AUTH_DEFAULT_TOKEN_DURATION_IN_SECONDS } from "../../constants";
|
||||
|
||||
export const RefreshOptionsSchema = z.object({
|
||||
expirationTime: z
|
||||
.date()
|
||||
.default(
|
||||
() =>
|
||||
new Date(
|
||||
Date.now() + 1000 * THIRDWEB_AUTH_DEFAULT_TOKEN_DURATION_IN_SECONDS,
|
||||
),
|
||||
),
|
||||
});
|
||||
|
||||
export type RefreshOptions = z.input<typeof RefreshOptionsSchema>;
|
||||
@@ -0,0 +1,17 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const VerifyOptionsSchema = z.object({
|
||||
domain: z.string(),
|
||||
statement: z.string().optional(),
|
||||
uri: z.string().optional(),
|
||||
version: z.string().optional(),
|
||||
chainId: z.string().optional(),
|
||||
validateNonce: z.function().args(z.string()).optional(),
|
||||
resources: z.array(z.string()).optional(),
|
||||
});
|
||||
|
||||
export type VerifyOptions = z.input<typeof VerifyOptionsSchema>;
|
||||
|
||||
export type VerifyOptionsWithOptionalDomain = Omit<VerifyOptions, "domain"> & {
|
||||
domain?: string;
|
||||
};
|
||||
@@ -1,9 +0,0 @@
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const isBrowser = () => typeof window !== "undefined";
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const isNode = () => !isBrowser();
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ThirdwebAuth } from "../../core";
|
||||
import { Json, LoginPayloadOutputSchema, User } from "../../core/schema";
|
||||
import { Json, LoginPayloadOutputSchema, User } from "../../core";
|
||||
import type { GenericAuthWallet } from "@thirdweb-dev/wallets";
|
||||
import { Request } from "express";
|
||||
import { z } from "zod";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { ThirdwebAuth } from "../../core";
|
||||
import { Json, LoginPayloadOutputSchema, User } from "../../core/schema";
|
||||
import { Json, LoginPayloadOutputSchema, ThirdwebAuth, User } from "../../core";
|
||||
import type { GenericAuthWallet } from "@thirdweb-dev/wallets";
|
||||
import { GetServerSidePropsContext, NextApiRequest } from "next";
|
||||
import { NextRequest } from "next/server";
|
||||
|
||||
@@ -3,7 +3,7 @@ import { EthersWallet } from "@thirdweb-dev/wallets/evm/wallets/ethers";
|
||||
import { expect } from "chai";
|
||||
import { Wallet } from "ethers";
|
||||
|
||||
describe("Wallet Authentication", async () => {
|
||||
describe("Wallet Authentication - EVM", async () => {
|
||||
let adminWallet: any, signerWallet: any, attackerWallet: any;
|
||||
let auth: ThirdwebAuth;
|
||||
|
||||
@@ -272,7 +272,7 @@ describe("Wallet Authentication", async () => {
|
||||
expect.fail();
|
||||
} catch (err: any) {
|
||||
expect(err.message).to.contain(
|
||||
`Expected the connected wallet address '${await signerWallet.getAddress()}' to match the token issuer address '${await adminWallet.getAddress()}'`,
|
||||
`The expected issuer address '${await signerWallet.getAddress()}' did not match the token issuer address '${await adminWallet.getAddress()}'`,
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -350,4 +350,24 @@ describe("Wallet Authentication", async () => {
|
||||
role: "admin",
|
||||
});
|
||||
});
|
||||
|
||||
it("Should authenticate with issuer address", async () => {
|
||||
const payload = await auth.login();
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
const token = await auth.generate(payload);
|
||||
|
||||
auth.updateWallet(attackerWallet);
|
||||
try {
|
||||
await auth.authenticate(token);
|
||||
expect.fail();
|
||||
} catch (err: any) {
|
||||
expect(err.message).to.contain("The expected issuer address");
|
||||
}
|
||||
|
||||
const user = await auth.authenticate(token, {
|
||||
issuerAddress: await adminWallet.getAddress(),
|
||||
});
|
||||
expect(user.address).to.equal(await signerWallet.getAddress());
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Keypair } from "@solana/web3.js";
|
||||
import { KeypairWallet } from "@thirdweb-dev/wallets/solana/wallets/keypair";
|
||||
import { expect } from "chai";
|
||||
|
||||
describe("Wallet Authentication", async () => {
|
||||
describe("Wallet Authentication - Solana", async () => {
|
||||
let adminWallet: any, signerWallet: any, attackerWallet: any;
|
||||
let auth: ThirdwebAuth;
|
||||
|
||||
@@ -272,7 +272,7 @@ describe("Wallet Authentication", async () => {
|
||||
expect.fail();
|
||||
} catch (err: any) {
|
||||
expect(err.message).to.contain(
|
||||
`Expected the connected wallet address '${await signerWallet.getAddress()}' to match the token issuer address '${await adminWallet.getAddress()}'`,
|
||||
`The expected issuer address '${await signerWallet.getAddress()}' did not match the token issuer address '${await adminWallet.getAddress()}'`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,5 +1,51 @@
|
||||
# @thirdweb-dev/chains
|
||||
|
||||
## 0.1.46
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1508](https://github.com/thirdweb-dev/js/pull/1508) [`184c325a`](https://github.com/thirdweb-dev/js/commit/184c325ab2ef028022a050c4274f2ab12b1a3a7f) Thanks [@jnsdls](https://github.com/jnsdls)! - update xpla chain icons
|
||||
|
||||
- [#1513](https://github.com/thirdweb-dev/js/pull/1513) [`c12f0874`](https://github.com/thirdweb-dev/js/commit/c12f0874b4dac43c263c7edb20d0343c16381c34) Thanks [@jnsdls](https://github.com/jnsdls)! - add additonal chains
|
||||
|
||||
## 0.1.45
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1506](https://github.com/thirdweb-dev/js/pull/1506) [`f97ddf4c`](https://github.com/thirdweb-dev/js/commit/f97ddf4c7f14854f3b204ad9741b52ddb8dac736) Thanks [@jnsdls](https://github.com/jnsdls)! - add xpla chains & update chains
|
||||
|
||||
## 0.1.44
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1499](https://github.com/thirdweb-dev/js/pull/1499) [`8f3b685a`](https://github.com/thirdweb-dev/js/commit/8f3b685ad2bd73cb4d5d8c8aa25c04ffc10fb7cf) Thanks [@Marfuen](https://github.com/Marfuen)! - Update deploy command from CLI to use show a public gateway url temporarily. Updated chains too.
|
||||
|
||||
## 0.1.43
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1469](https://github.com/thirdweb-dev/js/pull/1469) [`cb1c9937`](https://github.com/thirdweb-dev/js/commit/cb1c9937fadb2d06eb148cf9819f2b3601376308) Thanks [@jnsdls](https://github.com/jnsdls)! - update chains
|
||||
|
||||
- [#1474](https://github.com/thirdweb-dev/js/pull/1474) [`a1732663`](https://github.com/thirdweb-dev/js/commit/a17326634e758c3bf42f0cc3869b8792f1e18cc9) Thanks [@adam-maj](https://github.com/adam-maj)! - Add back scroll-alpha-testnet
|
||||
|
||||
- [#1458](https://github.com/thirdweb-dev/js/pull/1458) [`588b2106`](https://github.com/thirdweb-dev/js/commit/588b21060139a7c0bf5805e2c629a16792ed2c76) Thanks [@kien-ngo](https://github.com/kien-ngo)! - Update chains
|
||||
|
||||
- [#1461](https://github.com/thirdweb-dev/js/pull/1461) [`269e68c0`](https://github.com/thirdweb-dev/js/commit/269e68c0a15e8f78cb5b68c9456ca8094b9e1f30) Thanks [@0xFirekeeper](https://github.com/0xFirekeeper)! - add xai-goerli chain and support BigInteger from Unity
|
||||
|
||||
## 0.1.42
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1450](https://github.com/thirdweb-dev/js/pull/1450) [`262edc6a`](https://github.com/thirdweb-dev/js/commit/262edc6a46792da88f49ff6ef0a756a932a6a0cf) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - update chains
|
||||
|
||||
## 0.1.41
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1436](https://github.com/thirdweb-dev/js/pull/1436) [`fd981655`](https://github.com/thirdweb-dev/js/commit/fd9816556fe595b0c764e34dbcf15b0ad1677edb) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Updated chains
|
||||
|
||||
- [#1432](https://github.com/thirdweb-dev/js/pull/1432) [`9f5adc5c`](https://github.com/thirdweb-dev/js/commit/9f5adc5c5c2782ffb878759df481e5fb1e1740e5) Thanks [@jnsdls](https://github.com/jnsdls)! - update chains
|
||||
|
||||
## 0.1.40
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -18,6 +18,7 @@ export default {
|
||||
"https://gnosis.api.onfinality.io/public",
|
||||
"https://gnosis.blockpi.network/v1/rpc/public",
|
||||
"https://web3endpoints.com/gnosischain-mainnet",
|
||||
"https://gnosis.oat.farm",
|
||||
"wss://rpc.gnosischain.com/wss"
|
||||
],
|
||||
"faucets": [
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Japan Open Chain Testnet",
|
||||
"chain": "JOCT",
|
||||
"rpc": [
|
||||
"https://japan-open-chain-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc-1.testnet.japanopenchain.org:8545",
|
||||
"https://rpc-2.testnet.japanopenchain.org:8545"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Japan Open Chain Testnet Token",
|
||||
"symbol": "JOCT",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://www.japanopenchain.org/",
|
||||
"shortName": "joct",
|
||||
"chainId": 10081,
|
||||
"networkId": 10081,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Testnet Block Explorer",
|
||||
"url": "https://explorer.testnet.japanopenchain.org",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "japan-open-chain-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,38 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "MaxxChain Mainnet",
|
||||
"chain": "MaxxChain",
|
||||
"rpc": [
|
||||
"https://maxxchain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.maxxchain.org",
|
||||
"https://rpc1.maxxchain.org",
|
||||
"https://rpc2.maxxchain.org"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.maxxchain.org"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "Power",
|
||||
"symbol": "PWR",
|
||||
"decimals": 18
|
||||
},
|
||||
"icon": {
|
||||
"url": "ipfs://QmRhQG9TZrXDdbQeTzBmjg3pqgwaD5TKVZj8k4kaz8AoZx",
|
||||
"width": 1021,
|
||||
"height": 1021,
|
||||
"format": "png"
|
||||
},
|
||||
"infoURL": "https://www.maxxchain.org/",
|
||||
"shortName": "PWR",
|
||||
"chainId": 10201,
|
||||
"networkId": 10201,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "MaxxChain Block Explorer",
|
||||
"url": "https://explorer.maxxchain.org",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "maxxchain"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,42 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Arthera Testnet",
|
||||
"chain": "AA",
|
||||
"icon": {
|
||||
"url": "ipfs://QmYQp3e52KjkT4bYdAvB6ACEEpXs2D8DozsDitaADRY2Ak",
|
||||
"width": 1024,
|
||||
"height": 998,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://arthera-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc-test.arthera.net"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.arthera.net"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "Arthera",
|
||||
"symbol": "AA",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://docs.arthera.net",
|
||||
"shortName": "aa",
|
||||
"chainId": 10243,
|
||||
"networkId": 10243,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "blockscout",
|
||||
"url": "https://explorer-test.arthera.net",
|
||||
"icon": {
|
||||
"url": "ipfs://QmYtUimyqHkkFxYdbXXRbUqNg2VLPUg6Uu2C2nmFWowiZM",
|
||||
"width": 551,
|
||||
"height": 540,
|
||||
"format": "png"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "arthera-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -3,7 +3,7 @@ export default {
|
||||
"name": "Ultron Testnet",
|
||||
"chain": "Ultron",
|
||||
"icon": {
|
||||
"url": "ipfs://QmS4W4kY7XYBA4f52vuuytXh3YaTcNBXF14V9tEY6SNqhz",
|
||||
"url": "ipfs://QmPC6odFVyAQrXJQaZJVFpEQfRNbzZ5BjDZ7KBKmXPaYDw",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
@@ -27,7 +27,7 @@ export default {
|
||||
"name": "Ultron Testnet Explorer",
|
||||
"url": "https://explorer.ultron-dev.io",
|
||||
"icon": {
|
||||
"url": "ipfs://QmS4W4kY7XYBA4f52vuuytXh3YaTcNBXF14V9tEY6SNqhz",
|
||||
"url": "ipfs://QmPC6odFVyAQrXJQaZJVFpEQfRNbzZ5BjDZ7KBKmXPaYDw",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
|
||||
@@ -3,7 +3,7 @@ export default {
|
||||
"name": "Ultron Mainnet",
|
||||
"chain": "Ultron",
|
||||
"icon": {
|
||||
"url": "ipfs://QmS4W4kY7XYBA4f52vuuytXh3YaTcNBXF14V9tEY6SNqhz",
|
||||
"url": "ipfs://QmPC6odFVyAQrXJQaZJVFpEQfRNbzZ5BjDZ7KBKmXPaYDw",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
@@ -27,7 +27,7 @@ export default {
|
||||
"name": "Ultron Explorer",
|
||||
"url": "https://ulxscan.com",
|
||||
"icon": {
|
||||
"url": "ipfs://QmS4W4kY7XYBA4f52vuuytXh3YaTcNBXF14V9tEY6SNqhz",
|
||||
"url": "ipfs://QmPC6odFVyAQrXJQaZJVFpEQfRNbzZ5BjDZ7KBKmXPaYDw",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Swisstronik Testnet",
|
||||
"chain": "SWTR",
|
||||
"rpc": [
|
||||
"https://swisstronik-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://json-rpc.testnet.swisstronik.com"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.testnet.swisstronik.com"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "Swisstronik",
|
||||
"symbol": "SWTR",
|
||||
"decimals": 18
|
||||
},
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
},
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"infoURL": "https://www.swisstronik.com",
|
||||
"shortName": "swtr",
|
||||
"chainId": 1291,
|
||||
"networkId": 1291,
|
||||
"icon": {
|
||||
"url": "ipfs://bafybeihuintkoipxalwans23vhxajbwjnozpy34ww7ia7ds7nay3rpylzi",
|
||||
"width": 256,
|
||||
"height": 256,
|
||||
"format": "svg"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Swisstronik Scout",
|
||||
"url": "https://explorer-evm.testnet.swisstronik.com",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "swisstronik-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Credit Smartchain Mainnet",
|
||||
"name": "Credit Smart Chain",
|
||||
"chain": "CREDIT",
|
||||
"rpc": [
|
||||
"https://credit-smartchain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://mainnet-rpc.cscscan.io"
|
||||
"https://credit-smart-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.creditsmartchain.com"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
@@ -23,7 +23,7 @@ export default {
|
||||
"infoURL": "https://creditsmartchain.com",
|
||||
"shortName": "Credit",
|
||||
"chainId": 13308,
|
||||
"networkId": 1,
|
||||
"networkId": 13308,
|
||||
"icon": {
|
||||
"url": "ipfs://bafkreifbso3gd4wu5wxl27xyurxctmuae2jyuy37guqtzx23nga6ba4ag4",
|
||||
"width": 1000,
|
||||
@@ -32,8 +32,8 @@ export default {
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "CSC Scan",
|
||||
"url": "https://explorer.cscscan.io",
|
||||
"name": "Creditscan",
|
||||
"url": "https://scan.creditsmartchain.com",
|
||||
"icon": {
|
||||
"url": "ipfs://bafkreifbso3gd4wu5wxl27xyurxctmuae2jyuy37guqtzx23nga6ba4ag4",
|
||||
"width": 1000,
|
||||
@@ -44,5 +44,5 @@ export default {
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "credit-smartchain"
|
||||
"slug": "credit-smart-chain"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,33 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Beam Testnet",
|
||||
"chain": "BEAM",
|
||||
"rpc": [
|
||||
"https://beam-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://subnets.avax.network/beam/testnet/rpc"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Merit Circle",
|
||||
"symbol": "MC",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://gaming.meritcircle.io",
|
||||
"shortName": "BEAM",
|
||||
"chainId": 13337,
|
||||
"networkId": 13337,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Beam Explorer",
|
||||
"url": "https://subnets-test.avax.network/beam",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "beam-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Kalar Chain Mainnet",
|
||||
"name": "Kalar Chain",
|
||||
"chain": "KLC",
|
||||
"icon": {
|
||||
"url": "ipfs://bafkreihfoy2kgf2rebaoicso7z5h7ju46z6gtr64mskkths3qbfkrtnkjm",
|
||||
@@ -10,7 +10,7 @@ export default {
|
||||
},
|
||||
"rpc": [
|
||||
"https://kalar-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"http://rpc-api.kalarchain.tech"
|
||||
"https://rpc-api.kalarchain.tech"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Humanode Testnet 5 Israfel",
|
||||
"chain": "Humanode Testnet 5",
|
||||
"rpc": [
|
||||
"https://humanode-testnet-5-israfel.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://explorer-rpc-http.testnet5.stages.humanode.io"
|
||||
],
|
||||
"faucets": [
|
||||
"https://t.me/HumanodeTestnet5FaucetBot"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "eHMND",
|
||||
"symbol": "eHMND",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://humanode.io",
|
||||
"shortName": "hmnd-t5",
|
||||
"chainId": 14853,
|
||||
"networkId": 14853,
|
||||
"explorers": [],
|
||||
"testnet": true,
|
||||
"slug": "humanode-testnet-5-israfel"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,44 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Holesky",
|
||||
"chain": "ETH",
|
||||
"rpc": [
|
||||
"https://holesky.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.holesky.ethpandaops.io"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.holesky.ethpandaops.io",
|
||||
"https://holesky-faucet.pk910.de"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "Testnet ETH",
|
||||
"symbol": "ETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://holesky.ethpandaops.io",
|
||||
"shortName": "holesky",
|
||||
"chainId": 17000,
|
||||
"networkId": 17000,
|
||||
"icon": {
|
||||
"url": "ipfs://QmdwQDr6vmBtXmK2TmknkEuZNoaDqTasFdZdu3DRw8b2wt",
|
||||
"width": 1000,
|
||||
"height": 1628,
|
||||
"format": "png"
|
||||
},
|
||||
"status": "incubating",
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Holesky Explorer",
|
||||
"url": "https://holesky.beaconcha.in",
|
||||
"icon": {
|
||||
"url": "ipfs://QmdwQDr6vmBtXmK2TmknkEuZNoaDqTasFdZdu3DRw8b2wt",
|
||||
"width": 1000,
|
||||
"height": 1628,
|
||||
"format": "png"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "holesky"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "WhiteBIT Network",
|
||||
"chain": "WBT",
|
||||
"rpc": [
|
||||
"https://whitebit-network.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.whitebit.network"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "WhiteBIT Coin",
|
||||
"symbol": "WBT",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://whitebit.network",
|
||||
"shortName": "wbt",
|
||||
"chainId": 1875,
|
||||
"networkId": 1875,
|
||||
"icon": {
|
||||
"url": "ipfs://Qmbi6cqsQyDjkQSoxbNTTUy8WGyVEFqCtATX2aF4KLmCcZ",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "wb-explorer",
|
||||
"url": "https://explorer.whitebit.network",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "whitebit-network"
|
||||
} as const satisfies Chain;
|
||||
@@ -3,9 +3,9 @@ export default {
|
||||
"name": "Lightlink Phoenix Mainnet",
|
||||
"chain": "Lightlink Phoenix Mainnet",
|
||||
"icon": {
|
||||
"url": "ipfs://QmNRUoMgx16hurD3au3ou5A9rmTLYmre8WiGmQEPFmP2Vo",
|
||||
"width": 600,
|
||||
"height": 600,
|
||||
"url": "ipfs://QmXMDj6iAFn2ducQcUU1M87PMMdT2jfyL3Tp3Lz5uUD5Lv",
|
||||
"width": 200,
|
||||
"height": 200,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
@@ -33,9 +33,9 @@ export default {
|
||||
"name": "phoenix",
|
||||
"url": "https://phoenix.lightlink.io",
|
||||
"icon": {
|
||||
"url": "ipfs://QmNRUoMgx16hurD3au3ou5A9rmTLYmre8WiGmQEPFmP2Vo",
|
||||
"width": 600,
|
||||
"height": 600,
|
||||
"url": "ipfs://QmXMDj6iAFn2ducQcUU1M87PMMdT2jfyL3Tp3Lz5uUD5Lv",
|
||||
"width": 200,
|
||||
"height": 200,
|
||||
"format": "png"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
|
||||
@@ -3,9 +3,9 @@ export default {
|
||||
"name": "Lightlink Pegasus Testnet",
|
||||
"chain": "Lightlink Pegasus Testnet",
|
||||
"icon": {
|
||||
"url": "ipfs://QmNRUoMgx16hurD3au3ou5A9rmTLYmre8WiGmQEPFmP2Vo",
|
||||
"width": 600,
|
||||
"height": 600,
|
||||
"url": "ipfs://QmXMDj6iAFn2ducQcUU1M87PMMdT2jfyL3Tp3Lz5uUD5Lv",
|
||||
"width": 200,
|
||||
"height": 200,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
@@ -35,9 +35,9 @@ export default {
|
||||
"name": "pegasus",
|
||||
"url": "https://pegasus.lightlink.io",
|
||||
"icon": {
|
||||
"url": "ipfs://QmNRUoMgx16hurD3au3ou5A9rmTLYmre8WiGmQEPFmP2Vo",
|
||||
"width": 600,
|
||||
"height": 600,
|
||||
"url": "ipfs://QmXMDj6iAFn2ducQcUU1M87PMMdT2jfyL3Tp3Lz5uUD5Lv",
|
||||
"width": 200,
|
||||
"height": 200,
|
||||
"format": "png"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Centrifuge",
|
||||
"chain": "CFG",
|
||||
"rpc": [
|
||||
"wss://fullnode.parachain.centrifuge.io"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
},
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Centrifuge",
|
||||
"symbol": "CFG",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://centrifuge.io",
|
||||
"shortName": "cfg",
|
||||
"chainId": 2031,
|
||||
"networkId": 2031,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "subscan",
|
||||
"url": "https://centrifuge.subscan.io",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "centrifuge"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,28 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Catalyst",
|
||||
"chain": "CFG",
|
||||
"rpc": [
|
||||
"wss://fullnode.catalyst.cntrfg.com"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
},
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Catalyst CFG",
|
||||
"symbol": "NCFG",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://centrifuge.io",
|
||||
"shortName": "ncfg",
|
||||
"chainId": 2032,
|
||||
"networkId": 2032,
|
||||
"testnet": false,
|
||||
"slug": "catalyst"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,33 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Kiwi Subnet",
|
||||
"chain": "KIWI",
|
||||
"rpc": [
|
||||
"https://kiwi-subnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://subnets.avax.network/kiwi/testnet/rpc"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Shrapgas",
|
||||
"symbol": "SHRAP",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "",
|
||||
"shortName": "kiwi",
|
||||
"chainId": 2037,
|
||||
"networkId": 2037,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "KIWI Explorer",
|
||||
"url": "https://subnets-test.avax.network/kiwi",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "kiwi-subnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,28 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Altair",
|
||||
"chain": "AIR",
|
||||
"rpc": [
|
||||
"wss://fullnode.altair.centrifuge.io"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
},
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Altair",
|
||||
"symbol": "AIR",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://centrifuge.io",
|
||||
"shortName": "air",
|
||||
"chainId": 2088,
|
||||
"networkId": 2088,
|
||||
"testnet": false,
|
||||
"slug": "altair"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,28 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Algol",
|
||||
"chain": "algol",
|
||||
"rpc": [
|
||||
"wss://fullnode.algol.cntrfg.com"
|
||||
],
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
},
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Algol",
|
||||
"symbol": "ALGL",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://centrifuge.io",
|
||||
"shortName": "algl",
|
||||
"chainId": 2089,
|
||||
"networkId": 2089,
|
||||
"testnet": false,
|
||||
"slug": "algol"
|
||||
} as const satisfies Chain;
|
||||
@@ -4,7 +4,7 @@ export default {
|
||||
"chain": "REAP",
|
||||
"rpc": [
|
||||
"https://reapchain-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://test-rpc.reapchain.org"
|
||||
"https://test-eth.reapchain.org"
|
||||
],
|
||||
"faucets": [
|
||||
"http://faucet.reapchain.com"
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Kava EVM Testnet",
|
||||
"name": "Kava Testnet",
|
||||
"chain": "KAVA",
|
||||
"rpc": [
|
||||
"https://kava-evm-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://kava-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://evm.testnet.kava.io",
|
||||
"https://kava-evm-testnet.rpc.thirdweb.com",
|
||||
"wss://wevm.testnet.kava.io"
|
||||
],
|
||||
"faucets": [
|
||||
@@ -28,7 +29,7 @@ export default {
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Kava Testnet Explorer",
|
||||
"url": "https://explorer.testnet.kava.io",
|
||||
"url": "http://testnet.kavascan.com",
|
||||
"standard": "EIP3091",
|
||||
"icon": {
|
||||
"url": "ipfs://QmdpRTk6oL1HRW9xC6cAc4Rnf9gs6zgdAcr4Z3HcLztusm",
|
||||
@@ -39,5 +40,5 @@ export default {
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "kava-evm-testnet"
|
||||
"slug": "kava-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -1,11 +1,13 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Kava EVM",
|
||||
"name": "Kava",
|
||||
"chain": "KAVA",
|
||||
"rpc": [
|
||||
"https://kava-evm.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://kava.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://evm.kava.io",
|
||||
"https://evm2.kava.io",
|
||||
"https://kava-rpc.gateway.pokt.network",
|
||||
"https://kava-evm.rpc.thirdweb.com",
|
||||
"wss://wevm.kava.io",
|
||||
"wss://wevm2.kava.io",
|
||||
"https://kava-evm.publicnode.com"
|
||||
@@ -29,7 +31,7 @@ export default {
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Kava EVM Explorer",
|
||||
"url": "https://explorer.kava.io",
|
||||
"url": "https://kavascan.com",
|
||||
"standard": "EIP3091",
|
||||
"icon": {
|
||||
"url": "ipfs://QmdpRTk6oL1HRW9xC6cAc4Rnf9gs6zgdAcr4Z3HcLztusm",
|
||||
@@ -40,5 +42,5 @@ export default {
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "kava-evm"
|
||||
"slug": "kava"
|
||||
} as const satisfies Chain;
|
||||
@@ -4,7 +4,11 @@ export default {
|
||||
"chain": "SOMA",
|
||||
"rpc": [
|
||||
"https://soma-network-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://data-testnet-v1.somanetwork.io/"
|
||||
"https://data-testnet-v1.somanetwork.io/",
|
||||
"https://testnet-au-server-2.somanetwork.io",
|
||||
"https://testnet-au-server-1.somanetwork.io",
|
||||
"https://testnet-sg-server-1.somanetwork.io",
|
||||
"https://testnet-sg-server-2.somanetwork.io"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.somanetwork.io"
|
||||
|
||||
@@ -4,7 +4,10 @@ export default {
|
||||
"chain": "SOMA",
|
||||
"rpc": [
|
||||
"https://soma-network.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://data-mainnet-v1.somanetwork.io/"
|
||||
"https://data-mainnet-v1.somanetwork.io/",
|
||||
"https://id-mainnet.somanetwork.io",
|
||||
"https://hk-mainnet.somanetwork.io",
|
||||
"https://sg-mainnet.somanetwork.io"
|
||||
],
|
||||
"faucets": [
|
||||
"https://airdrop.somanetwork.io"
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Unicorn Ultra Nebulas Testnet",
|
||||
"chain": "u2u",
|
||||
"rpc": [
|
||||
"https://unicorn-ultra-nebulas-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc-nebulas-testnet.uniultra.xyz"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.uniultra.xyz"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "Unicorn Ultra Nebulas Testnet",
|
||||
"symbol": "U2U",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://uniultra.xyz",
|
||||
"shortName": "u2u_nebulas",
|
||||
"chainId": 2484,
|
||||
"networkId": 2484,
|
||||
"icon": {
|
||||
"url": "ipfs://QmcW64RgqQVHnNbVFyfaMNKt7dJvFqEbfEHZmeyeK8dpEa",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"icon": {
|
||||
"url": "ipfs://QmcW64RgqQVHnNbVFyfaMNKt7dJvFqEbfEHZmeyeK8dpEa",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"name": "U2U Explorer",
|
||||
"url": "https://testnet.u2uscan.xyz",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "unicorn-ultra-nebulas-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Ancient8 Testnet",
|
||||
"chain": "Ancient8",
|
||||
"icon": {
|
||||
"url": "ipfs://QmSX8sHToRzyFupT8BvPQjVsegRWFYz2mdnLkVnqBFKohY",
|
||||
"width": 901,
|
||||
"height": 901,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://ancient8-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc-testnet.ancient8.gg"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Ether",
|
||||
"symbol": "ETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://ancient8.gg/",
|
||||
"shortName": "a8",
|
||||
"chainId": 2863311531,
|
||||
"networkId": 2863311531,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "a8scan-testnet",
|
||||
"url": "https://testnet.a8scan.io",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "ancient8-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -5,6 +5,12 @@ export default {
|
||||
"shortName": "POPTestnet",
|
||||
"chainId": 331769,
|
||||
"testnet": true,
|
||||
"icon": {
|
||||
"format": "png",
|
||||
"url": "ipfs://QmP8rYvcc7aJB3c2YZxjxaySvHapHnoK8MnxuSuDT4PtF2",
|
||||
"height": 400,
|
||||
"width": 400
|
||||
},
|
||||
"rpc": [
|
||||
"https://proofofpepe-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://testnet01.proofofpepe.tech"
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "POP Mainnet",
|
||||
"chain": "POP",
|
||||
"shortName": "POP",
|
||||
"chainId": 331771,
|
||||
"testnet": false,
|
||||
"icon": {
|
||||
"format": "png",
|
||||
"url": "ipfs://QmP8rYvcc7aJB3c2YZxjxaySvHapHnoK8MnxuSuDT4PtF2",
|
||||
"height": 400,
|
||||
"width": 400
|
||||
},
|
||||
"rpc": [
|
||||
"https://pop.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc00.proofofpepe.tech",
|
||||
"https://rpc01.proofofpepe.tech",
|
||||
"https://rpc02.proofofpepe.tech"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "Pepe",
|
||||
"symbol": "PEPE",
|
||||
"decimals": 18
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Pepescan",
|
||||
"url": "https://pepescan.app",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"slug": "pop"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,42 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Manta Pacific Testnet",
|
||||
"chain": "Manta Pacific",
|
||||
"rpc": [
|
||||
"https://manta-pacific-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://manta-testnet.calderachain.xyz/http"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Manta",
|
||||
"symbol": "MANTA",
|
||||
"decimals": 18
|
||||
},
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
},
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
],
|
||||
"infoURL": "https://manta-testnet.caldera.dev/",
|
||||
"shortName": "manta",
|
||||
"chainId": 3441005,
|
||||
"networkId": 3441005,
|
||||
"icon": {
|
||||
"url": "ipfs://QmTckcVTViRZ3NqT36MTt8AvgBSmudrbgU3pi8AaNtthoV",
|
||||
"width": 834,
|
||||
"height": 834,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "manta-testnet Explorer",
|
||||
"url": "https://manta-testnet.calderaexplorer.xyz",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "manta-pacific-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,38 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Yooldo Verse Mainnet",
|
||||
"chain": "Yooldo Verse",
|
||||
"icon": {
|
||||
"url": "ipfs://QmWvfA2usnYp1ktzLcqFS8eTLgdp4ifrxjiify46KyG9NZ",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://yooldo-verse.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.yooldo-verse.xyz/"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "OAS",
|
||||
"symbol": "OAS",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://yooldo.gg/",
|
||||
"shortName": "YVM",
|
||||
"chainId": 345,
|
||||
"networkId": 345,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Yooldo Verse Explorer",
|
||||
"url": "https://explorer.yooldo-verse.xyz",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"parent": {
|
||||
"type": "L2",
|
||||
"chain": "eip155-248"
|
||||
},
|
||||
"testnet": false,
|
||||
"slug": "yooldo-verse"
|
||||
} as const satisfies Chain;
|
||||
@@ -1,27 +1,35 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "SeedCoin-Network",
|
||||
"chain": "SeedCoin-Network",
|
||||
"name": "Xpla Mainnet",
|
||||
"chain": "XPLA",
|
||||
"rpc": [
|
||||
"https://seedcoin-network.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://node.seedcoin.network"
|
||||
"https://xpla.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://dimension-evm-rpc.xpla.dev"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "SeedCoin",
|
||||
"symbol": "SEED",
|
||||
"name": "XPLA",
|
||||
"symbol": "XPLA",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://www.seedcoin.network/",
|
||||
"shortName": "SEED",
|
||||
"infoURL": "https://xpla.io/",
|
||||
"shortName": "xpla",
|
||||
"chainId": 37,
|
||||
"icon": {
|
||||
"url": "ipfs://QmSchLvCCZjBzcv5n22v1oFDAc2yHJ42NERyjZeL9hBgrh",
|
||||
"width": 64,
|
||||
"height": 64,
|
||||
"url": "ipfs://QmbvEAKZfgJckEziU3mpCwz6jqMeWRcLgd8TNsWA7g8sD9/xpla.png",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"chainId": 37,
|
||||
"networkId": 37,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "XPLA Explorer",
|
||||
"url": "https://explorer.xpla.io",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "seedcoin-network"
|
||||
"redFlags": [
|
||||
"reusedChainId"
|
||||
],
|
||||
"slug": "xpla"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,43 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Alterium L2 Testnet",
|
||||
"chain": "ALT",
|
||||
"icon": {
|
||||
"url": "ipfs://bafkreid3v7ow4c4t3ljya6aouiwvqbtssb2lzmkwt2eghryk234g7yynrq",
|
||||
"width": 756,
|
||||
"height": 756,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://alterium-l2-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://l2-testnet-rpc.altscan.org"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Alterium ETH",
|
||||
"symbol": "AltETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://alteriumprotocol.org",
|
||||
"shortName": "alterium",
|
||||
"chainId": 420692,
|
||||
"networkId": 420692,
|
||||
"parent": {
|
||||
"type": "L2",
|
||||
"chain": "eip155-5",
|
||||
"bridges": [
|
||||
{
|
||||
"url": "https://testnet-bridge.alteriumprotocol.org"
|
||||
}
|
||||
]
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Alterium L2 Testnet Explorer",
|
||||
"url": "https://l2-testnet.altscan.org",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "alterium-l2-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,39 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Orderly Sepolia Testnet",
|
||||
"chain": "ETH",
|
||||
"rpc": [
|
||||
"https://orderly-sepolia-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://l2-orderly-l2-4460-sepolia-8tc3sd7dvy.t.conduit.xyz"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Sepolia Ether",
|
||||
"symbol": "ETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"shortName": "orderlyl2",
|
||||
"chainId": 4460,
|
||||
"networkId": 4460,
|
||||
"icon": {
|
||||
"url": "ipfs://QmSpwp3RAVhZsErAQrCQxEmjnGqJQMigarzZbfqr9Ktakb",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "basescout",
|
||||
"url": "https://explorerl2new-orderly-l2-4460-sepolia-8tc3sd7dvy.t.conduit.xyz",
|
||||
"icon": {
|
||||
"url": "ipfs://QmYtUimyqHkkFxYdbXXRbUqNg2VLPUg6Uu2C2nmFWowiZM",
|
||||
"width": 551,
|
||||
"height": 540,
|
||||
"format": "png"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "orderly-sepolia-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -1,36 +1,38 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Acria IntelliChain",
|
||||
"chain": "AIC",
|
||||
"name": "Xpla Testnet",
|
||||
"chain": "XPLA",
|
||||
"rpc": [
|
||||
"https://acria-intellichain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://aic.acria.ai"
|
||||
"https://xpla-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://cube-evm-rpc.xpla.dev"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "ACRIA",
|
||||
"symbol": "ACRIA",
|
||||
"name": "XPLA",
|
||||
"symbol": "XPLA",
|
||||
"decimals": 18
|
||||
},
|
||||
"features": [
|
||||
{
|
||||
"name": "EIP155"
|
||||
},
|
||||
{
|
||||
"name": "EIP1559"
|
||||
}
|
||||
"faucets": [
|
||||
"https://faucet.xpla.io/"
|
||||
],
|
||||
"infoURL": "https://acria.ai",
|
||||
"shortName": "aic",
|
||||
"infoURL": "https://xpla.io/",
|
||||
"shortName": "xpla-test",
|
||||
"chainId": 47,
|
||||
"networkId": 47,
|
||||
"icon": {
|
||||
"url": "ipfs://QmbvEAKZfgJckEziU3mpCwz6jqMeWRcLgd8TNsWA7g8sD9/xpla.png",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Acria IntelliChain-Explorer",
|
||||
"url": "https://explorer.acria.ai",
|
||||
"standard": "EIP3091"
|
||||
"name": "XPLA Explorer",
|
||||
"url": "https://explorer.xpla.io/testnet",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "acria-intellichain"
|
||||
"testnet": true,
|
||||
"redFlags": [
|
||||
"reusedChainId"
|
||||
],
|
||||
"slug": "xpla-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,27 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Xai Goerli Orbit",
|
||||
"chain": "Xai Goerli Orbit Testnet",
|
||||
"shortName": "xai-goerli",
|
||||
"chainId": 47279324479,
|
||||
"testnet": true,
|
||||
"nativeCurrency": {
|
||||
"name": "Xai Goerli Ether",
|
||||
"symbol": "ETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"rpc": [
|
||||
"https://xai-goerli-orbit.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://testnet.xai-chain.net/rpc"
|
||||
],
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Xai Goerli Testnet Explorer",
|
||||
"url": "https://testnet-explorer.xai-chain.net",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"infoURL": "https://xai.games/",
|
||||
"slug": "xai-goerli-orbit"
|
||||
} as const satisfies Chain;
|
||||
@@ -8,8 +8,8 @@ export default {
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "HMND",
|
||||
"symbol": "HMND",
|
||||
"name": "eHMND",
|
||||
"symbol": "eHMND",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://humanode.io",
|
||||
|
||||
@@ -2,8 +2,11 @@ import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Scroll Sepolia Testnet",
|
||||
"chain": "ETH",
|
||||
"status": "incubating",
|
||||
"rpc": [],
|
||||
"status": "active",
|
||||
"rpc": [
|
||||
"https://scroll-sepolia-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://sepolia-rpc.scroll.io/"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Ether",
|
||||
@@ -14,11 +17,21 @@ export default {
|
||||
"shortName": "scr-sepolia",
|
||||
"chainId": 534351,
|
||||
"networkId": 534351,
|
||||
"explorers": [],
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Scroll Sepolia Testnet Block Explorer",
|
||||
"url": "https://sepolia-blockscout.scroll.io",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"parent": {
|
||||
"type": "L2",
|
||||
"chain": "eip155-11155111",
|
||||
"bridges": []
|
||||
"bridges": [
|
||||
{
|
||||
"url": "https://scroll.io/bridge"
|
||||
}
|
||||
]
|
||||
},
|
||||
"testnet": true,
|
||||
"slug": "scroll-sepolia-testnet"
|
||||
|
||||
@@ -3,7 +3,10 @@ export default {
|
||||
"name": "Scroll",
|
||||
"chain": "ETH",
|
||||
"status": "incubating",
|
||||
"rpc": [],
|
||||
"rpc": [
|
||||
"https://scroll.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.scroll.io"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Ether",
|
||||
@@ -14,11 +17,21 @@ export default {
|
||||
"shortName": "scr",
|
||||
"chainId": 534352,
|
||||
"networkId": 534352,
|
||||
"explorers": [],
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Scroll Mainnet Block Explorer",
|
||||
"url": "https://blockscout.scroll.io",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"parent": {
|
||||
"type": "L2",
|
||||
"chain": "eip155-1",
|
||||
"bridges": []
|
||||
"bridges": [
|
||||
{
|
||||
"url": "https://scroll.io/bridge"
|
||||
}
|
||||
]
|
||||
},
|
||||
"testnet": false,
|
||||
"slug": "scroll"
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Scroll Alpha Testnet",
|
||||
"chain": "ETH",
|
||||
"status": "active",
|
||||
"status": "deprecated",
|
||||
"rpc": [
|
||||
"https://scroll-alpha-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://alpha-rpc.scroll.io/l2"
|
||||
@@ -20,12 +20,7 @@ export default {
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Scroll Alpha Testnet Block Explorer",
|
||||
"url": "https://blockscout.scroll.io",
|
||||
"standard": "EIP3091"
|
||||
},
|
||||
{
|
||||
"name": "Scroll Alpha Testnet Block Explorer",
|
||||
"url": "https://scrollscan.co",
|
||||
"url": "https://alpha-blockscout.scroll.io",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "PAWCHAIN Testnet",
|
||||
"chain": "PAW",
|
||||
"rpc": [
|
||||
"https://pawchain-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://pawchainx.com/"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "PAW",
|
||||
"symbol": "PAW",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://pawchainx.com/",
|
||||
"shortName": "PAW",
|
||||
"chainId": 542,
|
||||
"networkId": 542,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "PAWCHAIN Testnet",
|
||||
"url": "https://pawscan.io",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "pawchain-testnet"
|
||||
} as const satisfies Chain;
|
||||
@@ -7,7 +7,8 @@ export default {
|
||||
"https://rpc.syscoin.org",
|
||||
"https://rpc.ankr.com/syscoin/${ANKR_API_KEY}",
|
||||
"https://syscoin.public-rpc.com",
|
||||
"wss://rpc.syscoin.org/wss"
|
||||
"wss://rpc.syscoin.org/wss",
|
||||
"https://syscoin-evm.publicnode.com"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.syscoin.org"
|
||||
|
||||
@@ -5,7 +5,8 @@ export default {
|
||||
"rpc": [
|
||||
"https://syscoin-tanenbaum-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.tanenbaum.io",
|
||||
"wss://rpc.tanenbaum.io/wss"
|
||||
"wss://rpc.tanenbaum.io/wss",
|
||||
"https://syscoin-tanenbaum-evm.publicnode.com"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.tanenbaum.io"
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "LAOS Arrakis",
|
||||
"title": "LAOS Testnet Arrakis",
|
||||
"chain": "LAOS",
|
||||
"icon": {
|
||||
"url": "ipfs://QmZ4YYcvhcaeotMPaGXC5Vab7JFaVkka37V8TiTJpT7Mak",
|
||||
"width": 586,
|
||||
"height": 558,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://laos-arrakis.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://arrakis.gorengine.com/own",
|
||||
"wss://arrakis.gorengine.com/own"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "LAOS",
|
||||
"symbol": "LAOS",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://www.laosfoundation.io/",
|
||||
"shortName": "laos",
|
||||
"chainId": 667,
|
||||
"networkId": 667,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "blockscout",
|
||||
"url": "https://arrakis.gorengine.com",
|
||||
"icon": {
|
||||
"url": "ipfs://QmZ4YYcvhcaeotMPaGXC5Vab7JFaVkka37V8TiTJpT7Mak",
|
||||
"width": 586,
|
||||
"height": 558,
|
||||
"format": "png"
|
||||
},
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": true,
|
||||
"slug": "laos-arrakis"
|
||||
} as const satisfies Chain;
|
||||
@@ -4,7 +4,11 @@ export default {
|
||||
"chain": "DSC",
|
||||
"rpc": [
|
||||
"https://decimal-smart-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://node.decimalchain.com/web3/"
|
||||
"https://node.decimalchain.com/web3/",
|
||||
"https://node1-mainnet.decimalchain.com/web3/",
|
||||
"https://node2-mainnet.decimalchain.com/web3/",
|
||||
"https://node3-mainnet.decimalchain.com/web3/",
|
||||
"https://node4-mainnet.decimalchain.com/web3/"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Miexs Smartchain",
|
||||
"chain": "MiexsSmartchain",
|
||||
"icon": {
|
||||
"url": "ipfs://bafkreic6tcc6swh5kzljwqnswj6rlemcm7n6ra7xkgttwv5v3fv7ozj5zu",
|
||||
"width": 1500,
|
||||
"height": 1500,
|
||||
"format": "png"
|
||||
},
|
||||
"rpc": [
|
||||
"https://miexs-smartchain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://mainnet-rpc.miexs.com"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
"name": "Miexs Coin",
|
||||
"symbol": "MIX",
|
||||
"decimals": 18
|
||||
},
|
||||
"infoURL": "https://miexs.com",
|
||||
"shortName": "Miexs",
|
||||
"chainId": 761412,
|
||||
"networkId": 761412,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Miexs Smartchain Explorer",
|
||||
"url": "https://miexs.com",
|
||||
"standard": "EIP3091"
|
||||
}
|
||||
],
|
||||
"testnet": false,
|
||||
"slug": "miexs-smartchain"
|
||||
} as const satisfies Chain;
|
||||
@@ -9,7 +9,11 @@ export default {
|
||||
"https://evm-dataseed3.meerscan.io",
|
||||
"https://evm-dataseed.meerscan.com",
|
||||
"https://evm-dataseed1.meerscan.com",
|
||||
"https://evm-dataseed2.meerscan.com"
|
||||
"https://evm-dataseed2.meerscan.com",
|
||||
"https://qng.rpc.qitmeer.io",
|
||||
"https://mainnet.meerlabs.com",
|
||||
"https://rpc.dimai.ai",
|
||||
"https://rpc.woowow.io"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
@@ -37,7 +41,7 @@ export default {
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"url": "https://evm.meerscan.com",
|
||||
"url": "https://qng.meerscan.io",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -2,8 +2,15 @@ import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Qitmeer Network Testnet",
|
||||
"chain": "MEER",
|
||||
"rpc": [],
|
||||
"faucets": [],
|
||||
"rpc": [
|
||||
"https://qitmeer-network-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://testnet-qng.rpc.qitmeer.io",
|
||||
"https://testnet.meerlabs.com",
|
||||
"https://meer.testnet.meerfans.club"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.qitmeer.io"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "Qitmeer Testnet",
|
||||
"symbol": "MEER-T",
|
||||
@@ -28,7 +35,7 @@ export default {
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"url": "https://testnet.qng.meerscan.io",
|
||||
"url": "https://qng-testnet.meerscan.io",
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -4,7 +4,8 @@ export default {
|
||||
"chain": "ETH",
|
||||
"rpc": [
|
||||
"https://base.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://mainnet.base.org/"
|
||||
"https://mainnet.base.org/",
|
||||
"https://developer-access-mainnet.base.org/"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "Worlds Appchain",
|
||||
"chain": "WRLDS",
|
||||
"shortName": "WRLDS",
|
||||
"chainId": 91003,
|
||||
"testnet": true,
|
||||
"rpc": [
|
||||
"https://worlds-appchain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://api.evm.worlds.dev.eclipsenetwork.xyz/"
|
||||
],
|
||||
"nativeCurrency": {
|
||||
"name": "WRLDS",
|
||||
"symbol": "WRLDS",
|
||||
"decimals": 18
|
||||
},
|
||||
"faucets": [
|
||||
"https://faucet.evm.worlds.dev.eclipsenetwork.xyz/request_neon"
|
||||
],
|
||||
"slug": "worlds-appchain"
|
||||
} as const satisfies Chain;
|
||||
@@ -2,7 +2,11 @@ import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "IMPERIUM TESTNET",
|
||||
"chain": "tIMP",
|
||||
"rpc": [],
|
||||
"rpc": [
|
||||
"https://imperium-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://data-aws-testnet.imperiumchain.com",
|
||||
"https://data-aws2-testnet.imperiumchain.com"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.imperiumchain.com/"
|
||||
],
|
||||
|
||||
@@ -2,7 +2,11 @@ import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"name": "IMPERIUM MAINNET",
|
||||
"chain": "IMP",
|
||||
"rpc": [],
|
||||
"rpc": [
|
||||
"https://imperium.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://data-aws-mainnet.imperiumchain.com",
|
||||
"https://data-aws2-mainnet.imperiumchain.com"
|
||||
],
|
||||
"faucets": [
|
||||
"https://faucet.imperiumchain.com/"
|
||||
],
|
||||
|
||||
@@ -11,7 +11,8 @@ export default {
|
||||
"rpc": [
|
||||
"https://mind-smart-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc-msc.mindchain.info/",
|
||||
"https://seednode.mindchain.info"
|
||||
"https://seednode.mindchain.info",
|
||||
"wss://seednode.mindchain.info/ws"
|
||||
],
|
||||
"faucets": [],
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -8,6 +8,12 @@ export default {
|
||||
shortName: "POPTestnet",
|
||||
chainId: 331769,
|
||||
testnet: true,
|
||||
icon: {
|
||||
format: "png",
|
||||
url: "ipfs://QmP8rYvcc7aJB3c2YZxjxaySvHapHnoK8MnxuSuDT4PtF2",
|
||||
height: 400,
|
||||
width: 400,
|
||||
},
|
||||
rpc: ["https://testnet01.proofofpepe.tech"],
|
||||
nativeCurrency: {
|
||||
name: "POP",
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// @ts-check
|
||||
/** @typedef { import("../../src/types").Chain } Chain */
|
||||
|
||||
/** @type {Omit<Chain, "slug">} */
|
||||
export default {
|
||||
name: "POP Mainnet",
|
||||
chain: "POP",
|
||||
shortName: "POP",
|
||||
chainId: 331771,
|
||||
testnet: false,
|
||||
icon: {
|
||||
format: "png",
|
||||
url: "ipfs://QmP8rYvcc7aJB3c2YZxjxaySvHapHnoK8MnxuSuDT4PtF2",
|
||||
height: 400,
|
||||
width: 400,
|
||||
},
|
||||
rpc: [
|
||||
"https://rpc00.proofofpepe.tech",
|
||||
"https://rpc01.proofofpepe.tech",
|
||||
"https://rpc02.proofofpepe.tech",
|
||||
],
|
||||
nativeCurrency: {
|
||||
name: "Pepe",
|
||||
symbol: "PEPE",
|
||||
decimals: 18,
|
||||
},
|
||||
explorers: [
|
||||
{ name: "Pepescan", url: "https://pepescan.app", standard: "none" },
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
// @ts-check
|
||||
/** @typedef { import("../../src/types").Chain } Chain */
|
||||
|
||||
/** @type {Omit<Chain, "slug">} */
|
||||
export default {
|
||||
name: "Xpla Mainnet",
|
||||
chain: "XPLA",
|
||||
rpc: ["https://dimension-evm-rpc.xpla.dev"],
|
||||
nativeCurrency: {
|
||||
name: "XPLA",
|
||||
symbol: "XPLA",
|
||||
decimals: 18,
|
||||
},
|
||||
infoURL: "https://xpla.io/",
|
||||
shortName: "xpla",
|
||||
chainId: 37,
|
||||
icon: {
|
||||
url: "ipfs://QmbvEAKZfgJckEziU3mpCwz6jqMeWRcLgd8TNsWA7g8sD9/xpla.png",
|
||||
width: 512,
|
||||
height: 512,
|
||||
format: "png",
|
||||
},
|
||||
explorers: [
|
||||
{
|
||||
name: "XPLA Explorer",
|
||||
url: "https://explorer.xpla.io",
|
||||
standard: "none",
|
||||
},
|
||||
],
|
||||
testnet: false,
|
||||
redFlags: ["reusedChainId"],
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
// @ts-check
|
||||
/** @typedef { import("../../src/types").Chain } Chain */
|
||||
|
||||
/** @type {Omit<Chain, "slug">} */
|
||||
export default {
|
||||
name: "Xpla Testnet",
|
||||
chain: "XPLA",
|
||||
rpc: ["https://cube-evm-rpc.xpla.dev"],
|
||||
nativeCurrency: {
|
||||
name: "XPLA",
|
||||
symbol: "XPLA",
|
||||
decimals: 18,
|
||||
},
|
||||
faucets: ["https://faucet.xpla.io/"],
|
||||
infoURL: "https://xpla.io/",
|
||||
shortName: "xpla-test",
|
||||
chainId: 47,
|
||||
icon: {
|
||||
url: "ipfs://QmbvEAKZfgJckEziU3mpCwz6jqMeWRcLgd8TNsWA7g8sD9/xpla.png",
|
||||
width: 512,
|
||||
height: 512,
|
||||
format: "png",
|
||||
},
|
||||
explorers: [
|
||||
{
|
||||
name: "XPLA Explorer",
|
||||
url: "https://explorer.xpla.io/testnet",
|
||||
standard: "none",
|
||||
},
|
||||
],
|
||||
testnet: true,
|
||||
redFlags: ["reusedChainId"],
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
// @ts-check
|
||||
/** @typedef { import("../../src/types").Chain } Chain */
|
||||
|
||||
/** @type {Omit<Chain, "slug">} */
|
||||
export default {
|
||||
name: "Xai Goerli Orbit",
|
||||
chain: "Xai Goerli Orbit Testnet",
|
||||
shortName: "xai-goerli",
|
||||
chainId: 47279324479,
|
||||
testnet: true,
|
||||
nativeCurrency: {
|
||||
name: "Xai Goerli Ether",
|
||||
symbol: "ETH",
|
||||
decimals: 18,
|
||||
},
|
||||
rpc: ["https://testnet.xai-chain.net/rpc"],
|
||||
explorers: [
|
||||
{
|
||||
name: "Xai Goerli Testnet Explorer",
|
||||
url: "https://testnet-explorer.xai-chain.net",
|
||||
standard: "EIP3091",
|
||||
},
|
||||
],
|
||||
faucets: [],
|
||||
infoURL: "https://xai.games/",
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
// @ts-check
|
||||
/** @typedef { import("../../src/types").Chain } Chain */
|
||||
|
||||
/** @type {Omit<Chain, "slug">} */
|
||||
export default {
|
||||
name: "Worlds Appchain",
|
||||
chain: "WRLDS",
|
||||
shortName: "WRLDS",
|
||||
chainId: 91003,
|
||||
testnet: true,
|
||||
rpc: ["https://api.evm.worlds.dev.eclipsenetwork.xyz/"],
|
||||
nativeCurrency: {
|
||||
name: "WRLDS",
|
||||
symbol: "WRLDS",
|
||||
decimals: 18,
|
||||
},
|
||||
faucets: ["https://faucet.evm.worlds.dev.eclipsenetwork.xyz/request_neon"],
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/chains",
|
||||
"version": "0.1.40",
|
||||
"version": "0.1.46",
|
||||
"main": "dist/thirdweb-dev-chains.cjs.js",
|
||||
"module": "dist/thirdweb-dev-chains.esm.js",
|
||||
"browser": {
|
||||
|
||||
@@ -105,7 +105,8 @@ for (const file of additionalChainsFiles) {
|
||||
}
|
||||
|
||||
chains = chains
|
||||
.filter((c) => c.status !== "deprecated")
|
||||
// Keep scroll-alpha-testnet for now even though its deprecated
|
||||
.filter((c) => c.status !== "deprecated" || c.chainId === 534353)
|
||||
.map((chain) => {
|
||||
if (overrides[chain.chainId]) {
|
||||
chain = merge(chain, overrides[chain.chainId], {
|
||||
@@ -343,6 +344,7 @@ ${exports.join("\n")}
|
||||
export * from "./types";
|
||||
export * from "./utils";
|
||||
export const defaultChains = [c1, c5, c8453, c84531, c137, c80001, c42161, c421613, c10, c420, c56, c97, c250, c4002, c43114, c43113, c1337];
|
||||
// @ts-expect-error - TODO: fix this later
|
||||
export const allChains: Chain[] = [${exportNames.join(", ")}];
|
||||
|
||||
type ChainsById = {
|
||||
|
||||
+116
-15
File diff suppressed because one or more lines are too long
@@ -1,5 +1,108 @@
|
||||
# thirdweb
|
||||
|
||||
## 0.11.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`184c325a`](https://github.com/thirdweb-dev/js/commit/184c325ab2ef028022a050c4274f2ab12b1a3a7f), [`046c9ad6`](https://github.com/thirdweb-dev/js/commit/046c9ad604587ff79bf028c4fe7b1f9c94f4ea54), [`c12f0874`](https://github.com/thirdweb-dev/js/commit/c12f0874b4dac43c263c7edb20d0343c16381c34)]:
|
||||
- @thirdweb-dev/chains@0.1.46
|
||||
- @thirdweb-dev/storage@1.2.7
|
||||
- @thirdweb-dev/sdk@3.10.54
|
||||
|
||||
## 0.11.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f97ddf4c`](https://github.com/thirdweb-dev/js/commit/f97ddf4c7f14854f3b204ad9741b52ddb8dac736)]:
|
||||
- @thirdweb-dev/chains@0.1.45
|
||||
- @thirdweb-dev/sdk@3.10.53
|
||||
|
||||
## 0.11.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`e1962641`](https://github.com/thirdweb-dev/js/commit/e19626417218767a0e44c00f440761d7b86d02eb), [`bd1fcbae`](https://github.com/thirdweb-dev/js/commit/bd1fcbae327e788124f5635673511f0b72e9d7ab)]:
|
||||
- @thirdweb-dev/sdk@3.10.52
|
||||
|
||||
## 0.11.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1499](https://github.com/thirdweb-dev/js/pull/1499) [`8f3b685a`](https://github.com/thirdweb-dev/js/commit/8f3b685ad2bd73cb4d5d8c8aa25c04ffc10fb7cf) Thanks [@Marfuen](https://github.com/Marfuen)! - Update deploy command from CLI to use show a public gateway url temporarily. Updated chains too.
|
||||
|
||||
- Updated dependencies [[`d248aa2c`](https://github.com/thirdweb-dev/js/commit/d248aa2c5a89a297dd2623c961793026de1de346), [`d248aa2c`](https://github.com/thirdweb-dev/js/commit/d248aa2c5a89a297dd2623c961793026de1de346), [`8f3b685a`](https://github.com/thirdweb-dev/js/commit/8f3b685ad2bd73cb4d5d8c8aa25c04ffc10fb7cf), [`28975765`](https://github.com/thirdweb-dev/js/commit/2897576513eb6f497a9f92e3e473182b4fc9681b), [`b91d3e99`](https://github.com/thirdweb-dev/js/commit/b91d3e990198b77dc1358e738c11dc4acaa67491)]:
|
||||
- @thirdweb-dev/sdk@3.10.51
|
||||
- @thirdweb-dev/storage@1.2.6
|
||||
- @thirdweb-dev/chains@0.1.44
|
||||
|
||||
## 0.11.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a5ba9e4f`](https://github.com/thirdweb-dev/js/commit/a5ba9e4fbfee228e5b9ac27cd0157187e3a50117), [`39e2af6f`](https://github.com/thirdweb-dev/js/commit/39e2af6f2f4d933dca1b3de4a37de76375bafd74)]:
|
||||
- @thirdweb-dev/sdk@3.10.50
|
||||
|
||||
## 0.11.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7f531122`](https://github.com/thirdweb-dev/js/commit/7f5311222b14da04877df056baae36409dff4696)]:
|
||||
- @thirdweb-dev/sdk@3.10.49
|
||||
|
||||
## 0.11.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`73462ef1`](https://github.com/thirdweb-dev/js/commit/73462ef10800aeeb5976634e2bc6fb5d3e8501e4), [`27c225a5`](https://github.com/thirdweb-dev/js/commit/27c225a51221417592b5940887abd1ccb8b67e47), [`cb1c9937`](https://github.com/thirdweb-dev/js/commit/cb1c9937fadb2d06eb148cf9819f2b3601376308), [`70c4a119`](https://github.com/thirdweb-dev/js/commit/70c4a119d691a37ec999d9f6087902d532cc82ed), [`a1732663`](https://github.com/thirdweb-dev/js/commit/a17326634e758c3bf42f0cc3869b8792f1e18cc9), [`f0443bd9`](https://github.com/thirdweb-dev/js/commit/f0443bd989dbba50d0836d1cf274bfb2f44a53fd), [`cb1c9937`](https://github.com/thirdweb-dev/js/commit/cb1c9937fadb2d06eb148cf9819f2b3601376308), [`588b2106`](https://github.com/thirdweb-dev/js/commit/588b21060139a7c0bf5805e2c629a16792ed2c76), [`269e68c0`](https://github.com/thirdweb-dev/js/commit/269e68c0a15e8f78cb5b68c9456ca8094b9e1f30)]:
|
||||
- @thirdweb-dev/storage@1.2.5
|
||||
- @thirdweb-dev/sdk@3.10.48
|
||||
- @thirdweb-dev/chains@0.1.43
|
||||
|
||||
## 0.11.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`4c37af49`](https://github.com/thirdweb-dev/js/commit/4c37af49aa4fa66beb8ffe8ef556068a29f3c5d4)]:
|
||||
- @thirdweb-dev/storage@1.2.4
|
||||
- @thirdweb-dev/sdk@3.10.47
|
||||
|
||||
## 0.11.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`262edc6a`](https://github.com/thirdweb-dev/js/commit/262edc6a46792da88f49ff6ef0a756a932a6a0cf), [`262edc6a`](https://github.com/thirdweb-dev/js/commit/262edc6a46792da88f49ff6ef0a756a932a6a0cf)]:
|
||||
- @thirdweb-dev/chains@0.1.42
|
||||
- @thirdweb-dev/sdk@3.10.46
|
||||
|
||||
## 0.11.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1442](https://github.com/thirdweb-dev/js/pull/1442) [`7f54012e`](https://github.com/thirdweb-dev/js/commit/7f54012ec648b727b60784990e71b0efb4690934) Thanks [@Marfuen](https://github.com/Marfuen)! - - Warn users on windows to not use the powershell as there are some compatibility issues with it at the moment.
|
||||
- Warn users if they are pasting a client id instead of a secret key.
|
||||
- Updated dependencies [[`2a91113a`](https://github.com/thirdweb-dev/js/commit/2a91113a760733fcff2aec90041f69e15de33905)]:
|
||||
- @thirdweb-dev/sdk@3.10.45
|
||||
|
||||
## 0.11.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1443](https://github.com/thirdweb-dev/js/pull/1443) [`8c0dc9c8`](https://github.com/thirdweb-dev/js/commit/8c0dc9c88084efcd184a416ed372c50c2fb8a209) Thanks [@nessup](https://github.com/nessup)! - Switch IPFS download domain used in CLI
|
||||
|
||||
- Updated dependencies [[`a5d0be93`](https://github.com/thirdweb-dev/js/commit/a5d0be939a143095e769b68cf86360bfe4720744), [`c0a6d2f1`](https://github.com/thirdweb-dev/js/commit/c0a6d2f18231310d143c9b0cb1b2ff59315087a4), [`becbb637`](https://github.com/thirdweb-dev/js/commit/becbb637367285ed3d8d7d131e1020bf23e38298), [`fd981655`](https://github.com/thirdweb-dev/js/commit/fd9816556fe595b0c764e34dbcf15b0ad1677edb), [`c9bf4f05`](https://github.com/thirdweb-dev/js/commit/c9bf4f05c161707c6eb799ecef82f462e4a82405), [`67b145b9`](https://github.com/thirdweb-dev/js/commit/67b145b94dafb2fb1d90553ed4829f0ed22e2907), [`5ee700e8`](https://github.com/thirdweb-dev/js/commit/5ee700e80438650fa253c25c0bee6658ce68d2cf), [`9f5adc5c`](https://github.com/thirdweb-dev/js/commit/9f5adc5c5c2782ffb878759df481e5fb1e1740e5)]:
|
||||
- @thirdweb-dev/sdk@3.10.44
|
||||
- @thirdweb-dev/chains@0.1.41
|
||||
|
||||
## 0.11.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1419](https://github.com/thirdweb-dev/js/pull/1419) [`2b96f71e`](https://github.com/thirdweb-dev/js/commit/2b96f71e191d7f69c2c75f9c6a9ee4537bac65aa) Thanks [@Marfuen](https://github.com/Marfuen)! - Fix path of cache to work with windows.
|
||||
|
||||
- Updated dependencies [[`3b6b0746`](https://github.com/thirdweb-dev/js/commit/3b6b0746b3fc792f4c5092814a7abfabcbc9801e)]:
|
||||
- @thirdweb-dev/storage@1.2.3
|
||||
- @thirdweb-dev/sdk@3.10.43
|
||||
|
||||
## 0.11.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "thirdweb",
|
||||
"main": "dist/cli/index.js",
|
||||
"version": "0.11.6",
|
||||
"version": "0.11.18",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -2,6 +2,7 @@ import chalk from "chalk";
|
||||
import prompts from "prompts";
|
||||
import Cache, { CacheEntry } from "sync-disk-cache";
|
||||
import { ApiResponse } from "../lib/types";
|
||||
import os from "os";
|
||||
|
||||
export async function loginUser(
|
||||
cache: Cache,
|
||||
@@ -40,6 +41,10 @@ export function getSession(cache: Cache) {
|
||||
|
||||
export async function createSession(cache: Cache) {
|
||||
try {
|
||||
const isWindows = os.type() === "Windows_NT";
|
||||
if (isWindows) {
|
||||
console.log(chalk.yellow("Windows detected: if you are using powershell, there are some known issues with it that we are actively working on, please use git bash or the command prompt. Thank you for your understanding."));
|
||||
}
|
||||
const response = await prompts({
|
||||
type: "invisible",
|
||||
name: "apiSecretKey",
|
||||
@@ -48,6 +53,20 @@ export async function createSession(cache: Cache) {
|
||||
)}`,
|
||||
});
|
||||
|
||||
const keyPassed = response.apiSecretKey;
|
||||
if (!keyPassed) {
|
||||
console.log(chalk.red("You need to pass an API secret key"));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (keyPassed.length === 32) {
|
||||
console.log(chalk.red(`This is not a valid secret key. To get your secret key
|
||||
1. Create an API key at https://thirdweb.com/create-api-key
|
||||
2. Store and copy your Secret Key. This will be shown only once.
|
||||
3. Paste it in the CLI when prompted`));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
await validateKey(response.apiSecretKey);
|
||||
} catch (error) {
|
||||
|
||||
@@ -26,7 +26,7 @@ const main = async () => {
|
||||
const skipIntro = process.env.THIRDWEB_CLI_SKIP_INTRO === "true";
|
||||
|
||||
const program = new Command();
|
||||
const cache = new Cache("thirdweb:cli", {
|
||||
const cache = new Cache("thirdweb-cli", {
|
||||
location: path.join(os.homedir(), ".thirdweb", "creds"),
|
||||
});
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ export async function deployApp(
|
||||
const uri = await upload(storage, distPath);
|
||||
return `${uri.replace(
|
||||
"ipfs://",
|
||||
"https://ipfs-public.thirdwebcdn.com/ipfs/",
|
||||
"https://cf-ipfs.com/ipfs/",
|
||||
)}`;
|
||||
} catch (err) {
|
||||
console.error("Can't upload project", err);
|
||||
|
||||
@@ -199,13 +199,15 @@ export async function generate(options: GenerateOptions, apiSecretKey: string) {
|
||||
}
|
||||
|
||||
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
||||
if (packageJson.scripts?.postinstall?.includes("thirdweb generate") || packageJson.scripts?.postinstall?.includes("thirdweb@latest generate")) {
|
||||
if (
|
||||
packageJson.scripts?.postinstall?.includes("thirdweb generate") ||
|
||||
packageJson.scripts?.postinstall?.includes("thirdweb@latest generate")
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const postinstall = packageJson.scripts?.postinstall
|
||||
? packageJson.scripts.postinstall +
|
||||
`npx --yes thirdweb@latest generate`
|
||||
? packageJson.scripts.postinstall + `npx --yes thirdweb@latest generate`
|
||||
: `npx --yes thirdweb@latest generate`;
|
||||
|
||||
fs.writeFileSync(
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @thirdweb-dev/contracts-js
|
||||
|
||||
## 1.3.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1432](https://github.com/thirdweb-dev/js/pull/1432) [`9f5adc5c`](https://github.com/thirdweb-dev/js/commit/9f5adc5c5c2782ffb878759df481e5fb1e1740e5) Thanks [@jnsdls](https://github.com/jnsdls)! - upgrade contracts package
|
||||
|
||||
## 1.3.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"main": "dist/thirdweb-dev-contracts-js-factories-TWRegistryLegacy__factory.cjs.js",
|
||||
"module": "dist/thirdweb-dev-contracts-js-factories-TWRegistryLegacy__factory.esm.js"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/contracts-js",
|
||||
"version": "1.3.10",
|
||||
"version": "1.3.11",
|
||||
"main": "dist/thirdweb-dev-contracts-js.cjs.js",
|
||||
"module": "dist/thirdweb-dev-contracts-js.esm.js",
|
||||
"browser": {
|
||||
@@ -10,7 +10,7 @@
|
||||
"license": "Apache-2.0",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/contracts-js",
|
||||
"dependencies": {
|
||||
"@thirdweb-dev/contracts": "3.8.1-0"
|
||||
"@thirdweb-dev/contracts": "3.8.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/preset-env": "^7.22.9",
|
||||
|
||||
@@ -1,5 +1,135 @@
|
||||
# @thirdweb-dev/react-core
|
||||
|
||||
## 3.14.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`184c325a`](https://github.com/thirdweb-dev/js/commit/184c325ab2ef028022a050c4274f2ab12b1a3a7f), [`046c9ad6`](https://github.com/thirdweb-dev/js/commit/046c9ad604587ff79bf028c4fe7b1f9c94f4ea54), [`c12f0874`](https://github.com/thirdweb-dev/js/commit/c12f0874b4dac43c263c7edb20d0343c16381c34)]:
|
||||
- @thirdweb-dev/chains@0.1.46
|
||||
- @thirdweb-dev/storage@1.2.7
|
||||
- @thirdweb-dev/sdk@3.10.54
|
||||
- @thirdweb-dev/wallets@1.1.18
|
||||
- @thirdweb-dev/auth@3.2.35
|
||||
|
||||
## 3.14.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`f97ddf4c`](https://github.com/thirdweb-dev/js/commit/f97ddf4c7f14854f3b204ad9741b52ddb8dac736)]:
|
||||
- @thirdweb-dev/chains@0.1.45
|
||||
- @thirdweb-dev/sdk@3.10.53
|
||||
- @thirdweb-dev/wallets@1.1.17
|
||||
- @thirdweb-dev/auth@3.2.34
|
||||
|
||||
## 3.14.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`e1962641`](https://github.com/thirdweb-dev/js/commit/e19626417218767a0e44c00f440761d7b86d02eb), [`bd1fcbae`](https://github.com/thirdweb-dev/js/commit/bd1fcbae327e788124f5635673511f0b72e9d7ab)]:
|
||||
- @thirdweb-dev/sdk@3.10.52
|
||||
- @thirdweb-dev/wallets@1.1.16
|
||||
- @thirdweb-dev/auth@3.2.33
|
||||
|
||||
## 3.14.32
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1489](https://github.com/thirdweb-dev/js/pull/1489) [`07fb1b5f`](https://github.com/thirdweb-dev/js/commit/07fb1b5ffa4c170e252df31070852ddb9a81dec9) Thanks [@iketw](https://github.com/iketw)! - Cleanup and minor bug fix in ReactCore
|
||||
|
||||
- [#1486](https://github.com/thirdweb-dev/js/pull/1486) [`300a3c6f`](https://github.com/thirdweb-dev/js/commit/300a3c6f04d0ea7e25dfdb0a4c28b3a5796fcadf) Thanks [@iketw](https://github.com/iketw)! - Add better error messages when using hooks outside the <ThirdwebProvider />
|
||||
|
||||
- Updated dependencies [[`07fb1b5f`](https://github.com/thirdweb-dev/js/commit/07fb1b5ffa4c170e252df31070852ddb9a81dec9), [`d248aa2c`](https://github.com/thirdweb-dev/js/commit/d248aa2c5a89a297dd2623c961793026de1de346), [`d248aa2c`](https://github.com/thirdweb-dev/js/commit/d248aa2c5a89a297dd2623c961793026de1de346), [`8f3b685a`](https://github.com/thirdweb-dev/js/commit/8f3b685ad2bd73cb4d5d8c8aa25c04ffc10fb7cf), [`28975765`](https://github.com/thirdweb-dev/js/commit/2897576513eb6f497a9f92e3e473182b4fc9681b), [`b91d3e99`](https://github.com/thirdweb-dev/js/commit/b91d3e990198b77dc1358e738c11dc4acaa67491)]:
|
||||
- @thirdweb-dev/wallets@1.1.15
|
||||
- @thirdweb-dev/sdk@3.10.51
|
||||
- @thirdweb-dev/storage@1.2.6
|
||||
- @thirdweb-dev/chains@0.1.44
|
||||
- @thirdweb-dev/auth@3.2.32
|
||||
|
||||
## 3.14.31
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`39e2af6f`](https://github.com/thirdweb-dev/js/commit/39e2af6f2f4d933dca1b3de4a37de76375bafd74), [`a5ba9e4f`](https://github.com/thirdweb-dev/js/commit/a5ba9e4fbfee228e5b9ac27cd0157187e3a50117), [`39e2af6f`](https://github.com/thirdweb-dev/js/commit/39e2af6f2f4d933dca1b3de4a37de76375bafd74)]:
|
||||
- @thirdweb-dev/wallets@1.1.14
|
||||
- @thirdweb-dev/sdk@3.10.50
|
||||
- @thirdweb-dev/auth@3.2.31
|
||||
|
||||
## 3.14.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`34b31599`](https://github.com/thirdweb-dev/js/commit/34b315993c0abaccb9640a5d5804c2c93af569c2), [`7f531122`](https://github.com/thirdweb-dev/js/commit/7f5311222b14da04877df056baae36409dff4696)]:
|
||||
- @thirdweb-dev/wallets@1.1.13
|
||||
- @thirdweb-dev/sdk@3.10.49
|
||||
- @thirdweb-dev/auth@3.2.30
|
||||
|
||||
## 3.14.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`73462ef1`](https://github.com/thirdweb-dev/js/commit/73462ef10800aeeb5976634e2bc6fb5d3e8501e4), [`27c225a5`](https://github.com/thirdweb-dev/js/commit/27c225a51221417592b5940887abd1ccb8b67e47), [`cb1c9937`](https://github.com/thirdweb-dev/js/commit/cb1c9937fadb2d06eb148cf9819f2b3601376308), [`70c4a119`](https://github.com/thirdweb-dev/js/commit/70c4a119d691a37ec999d9f6087902d532cc82ed), [`a1732663`](https://github.com/thirdweb-dev/js/commit/a17326634e758c3bf42f0cc3869b8792f1e18cc9), [`f0443bd9`](https://github.com/thirdweb-dev/js/commit/f0443bd989dbba50d0836d1cf274bfb2f44a53fd), [`cb1c9937`](https://github.com/thirdweb-dev/js/commit/cb1c9937fadb2d06eb148cf9819f2b3601376308), [`588b2106`](https://github.com/thirdweb-dev/js/commit/588b21060139a7c0bf5805e2c629a16792ed2c76), [`269e68c0`](https://github.com/thirdweb-dev/js/commit/269e68c0a15e8f78cb5b68c9456ca8094b9e1f30)]:
|
||||
- @thirdweb-dev/storage@1.2.5
|
||||
- @thirdweb-dev/wallets@1.1.12
|
||||
- @thirdweb-dev/sdk@3.10.48
|
||||
- @thirdweb-dev/chains@0.1.43
|
||||
- @thirdweb-dev/auth@3.2.29
|
||||
|
||||
## 3.14.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1460](https://github.com/thirdweb-dev/js/pull/1460) [`4b0e63dc`](https://github.com/thirdweb-dev/js/commit/4b0e63dcc0ca871ce9cef76f8a41ff290316741c) Thanks [@MananTank](https://github.com/MananTank)! - Save `oAuthRedirectResult` when autoconnecting Magic Link via social login
|
||||
|
||||
- Updated dependencies [[`4c37af49`](https://github.com/thirdweb-dev/js/commit/4c37af49aa4fa66beb8ffe8ef556068a29f3c5d4), [`4b0e63dc`](https://github.com/thirdweb-dev/js/commit/4b0e63dcc0ca871ce9cef76f8a41ff290316741c)]:
|
||||
- @thirdweb-dev/storage@1.2.4
|
||||
- @thirdweb-dev/wallets@1.1.11
|
||||
- @thirdweb-dev/sdk@3.10.47
|
||||
- @thirdweb-dev/auth@3.2.28
|
||||
|
||||
## 3.14.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1392](https://github.com/thirdweb-dev/js/pull/1392) [`dfd120a3`](https://github.com/thirdweb-dev/js/commit/dfd120a3a9d1582c8b174265c92bf43dbbaf5c86) Thanks [@adam-maj](https://github.com/adam-maj)! - Expose functions from auth and update useAuth
|
||||
|
||||
- Updated dependencies [[`262edc6a`](https://github.com/thirdweb-dev/js/commit/262edc6a46792da88f49ff6ef0a756a932a6a0cf), [`262edc6a`](https://github.com/thirdweb-dev/js/commit/262edc6a46792da88f49ff6ef0a756a932a6a0cf), [`dfd120a3`](https://github.com/thirdweb-dev/js/commit/dfd120a3a9d1582c8b174265c92bf43dbbaf5c86)]:
|
||||
- @thirdweb-dev/chains@0.1.42
|
||||
- @thirdweb-dev/sdk@3.10.46
|
||||
- @thirdweb-dev/auth@3.2.27
|
||||
- @thirdweb-dev/wallets@1.1.10
|
||||
|
||||
## 3.14.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`2a91113a`](https://github.com/thirdweb-dev/js/commit/2a91113a760733fcff2aec90041f69e15de33905)]:
|
||||
- @thirdweb-dev/sdk@3.10.45
|
||||
- @thirdweb-dev/wallets@1.1.9
|
||||
|
||||
## 3.14.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1423](https://github.com/thirdweb-dev/js/pull/1423) [`2283d210`](https://github.com/thirdweb-dev/js/commit/2283d21027503e047c25df5ebb21bdde0734be9e) Thanks [@nkrishang](https://github.com/nkrishang)! - Create useAccountAdmins hook
|
||||
|
||||
- [#1429](https://github.com/thirdweb-dev/js/pull/1429) [`ab36d84f`](https://github.com/thirdweb-dev/js/commit/ab36d84f1ce5647fa52475b4a35ea29d5007ad9b) Thanks [@iketw](https://github.com/iketw)! - Pass secretKey in the React SDK for server-side rendering
|
||||
|
||||
- [#1437](https://github.com/thirdweb-dev/js/pull/1437) [`5ee700e8`](https://github.com/thirdweb-dev/js/commit/5ee700e80438650fa253c25c0bee6658ce68d2cf) Thanks [@farhanW3](https://github.com/farhanW3)! - Updated the error messages
|
||||
|
||||
- Updated dependencies [[`a5d0be93`](https://github.com/thirdweb-dev/js/commit/a5d0be939a143095e769b68cf86360bfe4720744), [`c0a6d2f1`](https://github.com/thirdweb-dev/js/commit/c0a6d2f18231310d143c9b0cb1b2ff59315087a4), [`a9f2ff73`](https://github.com/thirdweb-dev/js/commit/a9f2ff73c9f83f05c3e2d3c53b23b2843e8a2576), [`fd981655`](https://github.com/thirdweb-dev/js/commit/fd9816556fe595b0c764e34dbcf15b0ad1677edb), [`becbb637`](https://github.com/thirdweb-dev/js/commit/becbb637367285ed3d8d7d131e1020bf23e38298), [`fd981655`](https://github.com/thirdweb-dev/js/commit/fd9816556fe595b0c764e34dbcf15b0ad1677edb), [`c9bf4f05`](https://github.com/thirdweb-dev/js/commit/c9bf4f05c161707c6eb799ecef82f462e4a82405), [`67b145b9`](https://github.com/thirdweb-dev/js/commit/67b145b94dafb2fb1d90553ed4829f0ed22e2907), [`5ee700e8`](https://github.com/thirdweb-dev/js/commit/5ee700e80438650fa253c25c0bee6658ce68d2cf), [`9f5adc5c`](https://github.com/thirdweb-dev/js/commit/9f5adc5c5c2782ffb878759df481e5fb1e1740e5)]:
|
||||
- @thirdweb-dev/sdk@3.10.44
|
||||
- @thirdweb-dev/wallets@1.1.8
|
||||
- @thirdweb-dev/chains@0.1.41
|
||||
|
||||
## 3.14.24
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3b6b0746`](https://github.com/thirdweb-dev/js/commit/3b6b0746b3fc792f4c5092814a7abfabcbc9801e), [`b0ec1d80`](https://github.com/thirdweb-dev/js/commit/b0ec1d80839efccad11b50afbf2216c2c132cf7e)]:
|
||||
- @thirdweb-dev/storage@1.2.3
|
||||
- @thirdweb-dev/wallets@1.1.7
|
||||
- @thirdweb-dev/sdk@3.10.43
|
||||
|
||||
## 3.14.23
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-core",
|
||||
"version": "3.14.23",
|
||||
"version": "3.14.35",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-core",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
@@ -104,6 +104,7 @@
|
||||
"@thirdweb-dev/sdk": "workspace:*",
|
||||
"@thirdweb-dev/storage": "workspace:*",
|
||||
"@thirdweb-dev/wallets": "workspace:*",
|
||||
"@thirdweb-dev/auth": "workspace:*",
|
||||
"mime": "3.0.0",
|
||||
"tiny-invariant": "^1.2.0"
|
||||
},
|
||||
|
||||
@@ -161,6 +161,7 @@ export const ThirdwebProviderCore = <TChains extends Chain[]>({
|
||||
storageInterface={props.storageInterface}
|
||||
authConfig={props.authConfig}
|
||||
clientId={props.clientId}
|
||||
secretKey={props.secretKey}
|
||||
>
|
||||
<ThirdwebAuthProvider value={props.authConfig}>
|
||||
{props.children}
|
||||
|
||||
@@ -229,7 +229,11 @@ export function ThirdwebWalletProvider(
|
||||
|
||||
try {
|
||||
const parsedWallet = JSON.parse(lastConnectedWallet as string);
|
||||
parsedWallet.connectParams.chainId = chainId;
|
||||
if (parsedWallet.connectParams) {
|
||||
parsedWallet.connectParams.chainId = chainId;
|
||||
} else {
|
||||
parsedWallet.connectParams = { chainId };
|
||||
}
|
||||
await lastConnectedWalletStorage.setItem(
|
||||
LAST_CONNECTED_WALLET_STORAGE_KEY,
|
||||
JSON.stringify(parsedWallet),
|
||||
@@ -317,10 +321,11 @@ export function ThirdwebWalletProvider(
|
||||
),
|
||||
{
|
||||
ms: autoConnectTimeout,
|
||||
message: "Failed to Auto connect. Auto connect timed out.",
|
||||
message: autoConnectTimeoutErrorMessage,
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
console.error("Failed to auto connect wallet");
|
||||
console.error(e);
|
||||
setConnectionStatus("disconnected");
|
||||
return;
|
||||
@@ -345,10 +350,11 @@ export function ThirdwebWalletProvider(
|
||||
setConnectionStatus("connecting");
|
||||
await timeoutPromise(wallet.autoConnect(walletInfo.connectParams), {
|
||||
ms: autoConnectTimeout,
|
||||
message: "Failed to Auto connect. Auto connect timed out.",
|
||||
message: autoConnectTimeoutErrorMessage,
|
||||
});
|
||||
setConnectedWallet(wallet, walletInfo.connectParams, true);
|
||||
} catch (e) {
|
||||
console.error("Failed to auto connect wallet");
|
||||
console.error(e);
|
||||
lastConnectedWalletStorage.removeItem(
|
||||
LAST_CONNECTED_WALLET_STORAGE_KEY,
|
||||
@@ -550,3 +556,5 @@ function timeoutPromise<T>(
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
const autoConnectTimeoutErrorMessage = `Failed to Auto connect. Auto connect timed out. You can increase the timeout duration using the autoConnectTimeout prop on <ThirdwebProvider />`;
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { Chain, defaultChains } from "@thirdweb-dev/chains";
|
||||
import { Chain } from "@thirdweb-dev/chains";
|
||||
import React, { createContext, PropsWithChildren, useContext } from "react";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
interface ThirdwebConfigContext {
|
||||
chains: Chain[];
|
||||
clientId?: string;
|
||||
}
|
||||
|
||||
const ThirdwebConfigContext =
|
||||
/* @__PURE__ */ createContext<ThirdwebConfigContext>({
|
||||
chains: defaultChains,
|
||||
});
|
||||
export const ThirdwebConfigContext = /* @__PURE__ */ createContext<
|
||||
ThirdwebConfigContext | undefined
|
||||
>(undefined);
|
||||
|
||||
export const ThirdwebConfigProvider: React.FC<
|
||||
PropsWithChildren<{
|
||||
@@ -22,5 +22,10 @@ export const ThirdwebConfigProvider: React.FC<
|
||||
);
|
||||
|
||||
export function useThirdwebConfigContext() {
|
||||
return useContext(ThirdwebConfigContext);
|
||||
const context = useContext(ThirdwebConfigContext);
|
||||
invariant(
|
||||
context,
|
||||
"useThirdwebConfigContext() hook must be used within a <ThirdwebProvider/>",
|
||||
);
|
||||
return context;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import React, {
|
||||
useState,
|
||||
} from "react";
|
||||
import { useSDK } from "../hooks/useSDK";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
interface ThirdwebConnectedWalletContext {
|
||||
wallet: UserWallet | undefined;
|
||||
@@ -26,10 +27,9 @@ const INITIAL_CONTEXT_VALUE: ThirdwebConnectedWalletContext = {
|
||||
signer: undefined,
|
||||
};
|
||||
|
||||
const ThirdwebConnectedWalletContext =
|
||||
/* @__PURE__ */ createContext<ThirdwebConnectedWalletContext>(
|
||||
INITIAL_CONTEXT_VALUE,
|
||||
);
|
||||
export const ThirdwebConnectedWalletContext = /* @__PURE__ */ createContext<
|
||||
ThirdwebConnectedWalletContext | undefined
|
||||
>(undefined);
|
||||
|
||||
export const ThirdwebConnectedWalletProvider: React.FC<
|
||||
PropsWithChildren<{ signer?: Signer }>
|
||||
@@ -115,5 +115,10 @@ export const ThirdwebConnectedWalletProvider: React.FC<
|
||||
};
|
||||
|
||||
export function useThirdwebConnectedWalletContext() {
|
||||
return useContext(ThirdwebConnectedWalletContext);
|
||||
const context = useContext(ThirdwebConnectedWalletContext);
|
||||
invariant(
|
||||
context,
|
||||
"useThirdwebConnectedWalletContext() hook must be used within a <ThirdwebProvider/>",
|
||||
);
|
||||
return context;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user