Compare commits
24
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
817ab2249f | ||
|
|
173777ade4 | ||
|
|
838233075a | ||
|
|
cabfc29119 | ||
|
|
f02570db88 | ||
|
|
c6b025e844 | ||
|
|
332a14552b | ||
|
|
c894270401 | ||
|
|
595815dc3e | ||
|
|
b959cafccc | ||
|
|
4cf0aede0e | ||
|
|
6cf298a29a | ||
|
|
62b2508a6c | ||
|
|
c3967b798e | ||
|
|
588897d1b0 | ||
|
|
862905e161 | ||
|
|
5f81e246f2 | ||
|
|
1b052d63e9 | ||
|
|
a3f6878649 | ||
|
|
74a92dcb7d | ||
|
|
38fc0b796a | ||
|
|
ef76a96c2d | ||
|
|
2667706d8d | ||
|
|
047fbe2918 |
@@ -5,7 +5,7 @@
|
||||
<br />
|
||||
</p>
|
||||
|
||||
<h1 align="center"><a href='https://thirdweb.com/'>thirdweb</a> JavaScript/TypeScript monorepo</h1>
|
||||
<h1 align="center"><a href='https://thirdweb.com/'>thirdweb</a> TypeScript SDK</h1>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/thirdweb-dev/js/actions/workflows/build-test-lint.yml">
|
||||
@@ -16,38 +16,72 @@
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center"><strong>Best in class web3 SDKs for Browser, Node and Mobile apps</strong></p>
|
||||
<p align="center"><strong>All-in-one web3 SDK for Browser, Node and Mobile apps</strong></p>
|
||||
|
||||
> [!IMPORTANT]
|
||||
> We rewrote the thirdweb SDK from scratch for performance! Head over to the [Beta version unified SDK](https://github.com/thirdweb-dev/js/tree/beta/packages/thirdweb).
|
||||
|
||||
## Features
|
||||
|
||||
- Support for React & React-Native
|
||||
- First party support for [Embedded Wallets](https://portal.thirdweb.com/connect/embedded-wallet/overview) (social/email login)
|
||||
- First party support for [Account Abstraction](https://portal.thirdweb.com/connect/account-abstraction)
|
||||
- Instant connection to any chain with RPC Edge integration
|
||||
- Integrated IPFS upload/download
|
||||
- UI Components for connection, transactions, nft rendering
|
||||
- High level contract extensions for interacting with common standards
|
||||
- Automatic ABI resolution
|
||||
|
||||
## Library Comparison
|
||||
|
||||
| | thirdweb | Wagmi | Viem | Ethers@6 |
|
||||
| ----------------------------------------- | -------- | ------------------ | ------------------ | -------- |
|
||||
| Type safe contract API | ✅ | ✅ | ✅ | ✅ |
|
||||
| Type safe wallet API | ✅ | ✅ | ✅ | ✅ |
|
||||
| EVM utils | ✅ | ❌ | ✅ | ✅ |
|
||||
| RPC for any EVM | ✅ | ⚠️ public RPC only | ⚠️ public RPC only | ❌ |
|
||||
| Automatic ABI Resolution | ✅ | ❌ | ❌ | ❌ |
|
||||
| IPFS Upload/Download | ✅ | ❌ | ❌ | ❌ |
|
||||
| Embedded wallet (email/ social login) | ✅ | ⚠️ via 3rd party | ❌ | ❌ |
|
||||
| Account abstraction (ERC4337) support | ✅ | ⚠️ via 3rd party | ⚠️ via 3rd party | ❌ |
|
||||
| Web3 wallet connectors | ✅ | ✅ | ❌ | ❌ |
|
||||
| Local wallet creation | ✅ | ❌ | ✅ | ✅ |
|
||||
| Auth (SIWE) | ✅ | ⚠️ via 3rd party | ❌ | ❌ |
|
||||
| Extensions functions for common standards | ✅ | ❌ | ❌ | ❌ |
|
||||
| React Hooks | ✅ | ✅ | ❌ | ❌ |
|
||||
| React UI components | ✅ | ❌ | ❌ | ❌ |
|
||||
| React Native Hooks | ✅ | ❌ | ❌ | ❌ |
|
||||
| React Native UI Components | ✅ | ❌ | ❌ | ❌ |
|
||||
|
||||
## Packages
|
||||
|
||||
| Package | Description | Latest Version |
|
||||
| ---------------------------------------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| [/sdk](./packages/sdk) | Best in class web3 SDK for Browser, Node and Mobile apps | <a href="https://www.npmjs.com/package/@thirdweb-dev/sdk"><img src="https://img.shields.io/npm/v/@thirdweb-dev/sdk?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/wallets](./packages/wallets) | Unified web3 Wallet library to integrate any wallet into your applications. | <a href="https://www.npmjs.com/package/@thirdweb-dev/wallets"><img src="https://img.shields.io/npm/v/@thirdweb-dev/wallets?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/react](./packages/react) | Ultimate collection of React hooks for your web3 apps | <a href="https://www.npmjs.com/package/@thirdweb-dev/react"><img src="https://img.shields.io/npm/v/@thirdweb-dev/react?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/react-native](./packages/react-native) | Ultimate collection of React hooks for your native mobile web3 apps | <a href="https://www.npmjs.com/package/@thirdweb-dev/react-native"><img src="https://img.shields.io/npm/v/@thirdweb-dev/react-native?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/auth](./packages/auth) | Best in class wallet authentication for Node backends | <a href="https://www.npmjs.com/package/@thirdweb-dev/auth"><img src="https://img.shields.io/npm/v/@thirdweb-dev/auth?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/storage](./packages/storage) | Best in class decentralized storage SDK for Browser and Node | <a href="https://www.npmjs.com/package/@thirdweb-dev/storage"><img src="https://img.shields.io/npm/v/@thirdweb-dev/storage?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/cli](./packages/cli) | Publish and deploy smart contracts without dealing with private keys | <a href="https://www.npmjs.com/package/thirdweb"><img src="https://img.shields.io/npm/v/thirdweb?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
| [/chains](./packages/chains) | All EVM chain information as JS objects for easy handling | <a href="https://www.npmjs.com/package/@thirdweb-dev/chains"><img src="https://img.shields.io/npm/v/@thirdweb-dev/chains?color=red&label=npm&logo=npm" alt="npm version"/></a> |
|
||||
|
||||
## Documentation
|
||||
|
||||
Visit [https://portal.thirdweb.com/](https://portal.thirdweb.com/) to view the full documentation.
|
||||
|
||||
<br />
|
||||
| Package | Description
|
||||
| -----------------------------------------|-----------------------------------------------------------------------------|
|
||||
| [/sdk](./packages/sdk) | Best in class web3 SDK for Browser, Node and Mobile apps |
|
||||
| [/wallets](./packages/wallets) | Unified web3 Wallet library to integrate any wallet into your applications. |
|
||||
| [/react](./packages/react) | Ultimate collection of React hooks for your web3 apps |
|
||||
| [/react-native](./packages/react-native) | Ultimate collection of React hooks for your native mobile web3 apps |
|
||||
| [/auth](./packages/auth) | Best in class wallet authentication for Node backends |
|
||||
| [/storage](./packages/storage) | Best in class decentralized storage SDK for Browser and Node |
|
||||
| [/cli](./packages/cli) | Publish and deploy smart contracts without dealing with private keys |
|
||||
| [/chains](./packages/chains) | All EVM chain information as JS objects for easy handling |
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome contributions from all developers, regardless of experience level. If you are interested in contributing, please read our [Contributing Guide](.github/contributing.md) where you'll learn how the repo works, how to test your changes, and how to submit a pull request.
|
||||
We welcome contributions from all developers regardless of experience level. If you are interested in contributing, please read our [Contributing Guide](.github/contributing.md) to learn how the repo works, how to test your changes, and how to submit a pull request.
|
||||
|
||||
<br />
|
||||
See our [open source page](https://thirdweb.com/open-source) for more information on our open-source bounties and program.
|
||||
|
||||
## Community
|
||||
## Additional Resources
|
||||
|
||||
The best place to discuss your ideas, ask questions, and troubleshoot issues is our [Discord server](https://discord.gg/thirdweb).
|
||||
- [SDK Documentation](https://portal.thirdweb.com/typescript/v5)
|
||||
- [Templates](https://thirdweb.com/templates)
|
||||
- [YouTube](https://www.youtube.com/c/thirdweb_)
|
||||
|
||||
<br/>
|
||||
|
||||
## Support
|
||||
|
||||
For help or feedback, please [visit our support site](https://thirdweb.com/support)
|
||||
|
||||
## Security
|
||||
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
# @thirdweb-dev/auth
|
||||
|
||||
## 4.1.40
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`cabfc29`](https://github.com/thirdweb-dev/js/commit/cabfc29119f25a78010f59f766bdcb8c392afa2d)]:
|
||||
- @thirdweb-dev/wallets@2.4.18
|
||||
|
||||
## 4.1.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c894270`](https://github.com/thirdweb-dev/js/commit/c894270401850575d1a4df73e16198177b46477a), [`332a145`](https://github.com/thirdweb-dev/js/commit/332a14552bf95e13e5220b1bd73414f000088568)]:
|
||||
- @thirdweb-dev/wallets@2.4.17
|
||||
|
||||
## 4.1.38
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2417](https://github.com/thirdweb-dev/js/pull/2417) [`862905e`](https://github.com/thirdweb-dev/js/commit/862905e161a091c15eb9b054cfcca0e5d2879fd6) Thanks [@jnsdls](https://github.com/jnsdls)! - make verify login payload be self-sufficient
|
||||
|
||||
- Updated dependencies [[`862905e`](https://github.com/thirdweb-dev/js/commit/862905e161a091c15eb9b054cfcca0e5d2879fd6)]:
|
||||
- @thirdweb-dev/wallets@2.4.16
|
||||
|
||||
## 4.1.37
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`74a92dc`](https://github.com/thirdweb-dev/js/commit/74a92dcb7dc4be7d03bcb8b7211e87016f52a81f)]:
|
||||
- @thirdweb-dev/wallets@2.4.15
|
||||
|
||||
## 4.1.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/auth",
|
||||
"version": "4.1.36",
|
||||
"version": "4.1.40",
|
||||
"main": "dist/thirdweb-dev-auth.cjs.js",
|
||||
"module": "dist/thirdweb-dev-auth.esm.js",
|
||||
"browser": {
|
||||
@@ -61,7 +61,7 @@
|
||||
"lint": "eslint src/ && bunx publint --strict --level warning",
|
||||
"fix": "eslint src/ --fix",
|
||||
"clean": "rm -rf dist/ && rm -rf node_modules/",
|
||||
"test": "mocha --config './test/.mocharc.json' --timeout 30000 --parallel './test/**/*.test.ts'",
|
||||
"test": "mocha --config './test/.mocharc.json' --timeout 240000 --parallel './test/**/*.test.ts'",
|
||||
"push": "yalc push"
|
||||
},
|
||||
"preconstruct": {
|
||||
|
||||
@@ -23,14 +23,21 @@ import {
|
||||
AuthenticateOptionsWithOptionalDomain,
|
||||
AuthenticationPayload,
|
||||
} from "./schema/authenticate";
|
||||
import { ThirdwebAuthOptions } from "./types";
|
||||
|
||||
export class ThirdwebAuth {
|
||||
private domain: string;
|
||||
private wallet: GenericAuthWallet;
|
||||
private options: ThirdwebAuthOptions;
|
||||
|
||||
constructor(wallet: GenericAuthWallet, domain: string) {
|
||||
constructor(
|
||||
wallet: GenericAuthWallet,
|
||||
domain: string,
|
||||
options: ThirdwebAuthOptions = {},
|
||||
) {
|
||||
this.wallet = wallet;
|
||||
this.domain = domain;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public updateWallet(wallet: GenericAuthWallet) {
|
||||
@@ -66,9 +73,9 @@ export class ThirdwebAuth {
|
||||
options?: VerifyOptionsWithOptionalDomain,
|
||||
): Promise<string> {
|
||||
return verifyLoginPayload({
|
||||
wallet: this.wallet,
|
||||
payload,
|
||||
options: this.formatOptions(options),
|
||||
clientOptions: this.options,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -80,6 +87,7 @@ export class ThirdwebAuth {
|
||||
wallet: this.wallet,
|
||||
payload,
|
||||
options: this.formatOptions(options),
|
||||
clientOptions: this.options,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -99,6 +107,7 @@ export class ThirdwebAuth {
|
||||
wallet: this.wallet,
|
||||
jwt,
|
||||
options: this.formatOptions(options),
|
||||
clientOptions: this.options,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
import { GenerateOptionsSchema } from "../schema/generate";
|
||||
import { RefreshOptionsSchema } from "../schema/refresh";
|
||||
import { verifyLoginPayload } from "./login";
|
||||
import { verifySignature } from "./verify-signature";
|
||||
|
||||
function isBrowser() {
|
||||
return typeof window !== "undefined";
|
||||
@@ -71,15 +72,16 @@ export async function generateJWT({
|
||||
wallet,
|
||||
payload,
|
||||
options,
|
||||
clientOptions,
|
||||
}: GenerateJwtParams): Promise<string> {
|
||||
const parsedOptions = GenerateOptionsSchema.parse(options);
|
||||
const userAddress = await verifyLoginPayload({
|
||||
wallet,
|
||||
payload,
|
||||
options: {
|
||||
domain: parsedOptions.domain,
|
||||
...parsedOptions.verifyOptions,
|
||||
},
|
||||
clientOptions,
|
||||
});
|
||||
|
||||
let session: Json | undefined = undefined;
|
||||
@@ -156,6 +158,7 @@ export async function authenticateJWT<TSession extends Json = Json>({
|
||||
wallet,
|
||||
jwt,
|
||||
options,
|
||||
clientOptions,
|
||||
}: AuthenticateJwtParams): Promise<User<TSession>> {
|
||||
const parsedOptions = AuthenticateOptionsSchema.parse(options);
|
||||
const { payload, signature } = parseJWT(jwt);
|
||||
@@ -210,11 +213,13 @@ export async function authenticateJWT<TSession extends Json = Json>({
|
||||
}
|
||||
}
|
||||
|
||||
const verified = await wallet.verifySignature(
|
||||
const verified = await verifySignature(
|
||||
JSON.stringify(payload),
|
||||
signature,
|
||||
issuerAddress,
|
||||
chainId,
|
||||
clientOptions.clientId,
|
||||
clientOptions.secretKey,
|
||||
);
|
||||
if (!verified) {
|
||||
throw new Error(
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
LoginPayloadDataSchema,
|
||||
} from "../schema/login";
|
||||
import { VerifyOptionsSchema } from "../schema/verify";
|
||||
import { verifySignature } from "./verify-signature";
|
||||
|
||||
/**
|
||||
* Create an EIP-4361 & CAIP-122 compliant message to sign based on the login payload
|
||||
@@ -113,18 +114,12 @@ export async function buildAndSignLoginPayload({
|
||||
}
|
||||
|
||||
export async function verifyLoginPayload({
|
||||
wallet,
|
||||
payload,
|
||||
options,
|
||||
clientOptions,
|
||||
}: 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(
|
||||
@@ -204,16 +199,19 @@ export async function verifyLoginPayload({
|
||||
|
||||
// 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(
|
||||
const chainId = payload.payload.chain_id
|
||||
? parseInt(payload.payload.chain_id)
|
||||
: undefined;
|
||||
|
||||
const verified = await verifySignature(
|
||||
message,
|
||||
payload.signature,
|
||||
payload.payload.address,
|
||||
chainId,
|
||||
clientOptions?.clientId,
|
||||
clientOptions?.secretKey,
|
||||
);
|
||||
|
||||
if (!verified) {
|
||||
throw new Error(
|
||||
`Signer address does not match payload address '${payload.payload.address.toLowerCase()}'`,
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import { checkContractWalletSignature } from "@thirdweb-dev/wallets";
|
||||
import { utils } from "ethers";
|
||||
|
||||
export async function verifySignature(
|
||||
message: string,
|
||||
signature: string,
|
||||
address: string,
|
||||
chainId?: number,
|
||||
clientId?: string,
|
||||
secretKey?: string,
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
const messageHash = utils.hashMessage(message);
|
||||
const messageHashBytes = utils.arrayify(messageHash);
|
||||
const recoveredAddress = utils.recoverAddress(messageHashBytes, signature);
|
||||
|
||||
if (recoveredAddress === address) {
|
||||
return true;
|
||||
}
|
||||
} catch {
|
||||
// no-op
|
||||
}
|
||||
|
||||
if (!chainId) {
|
||||
return false;
|
||||
}
|
||||
return checkContractWalletSignature(
|
||||
message,
|
||||
signature,
|
||||
address,
|
||||
chainId,
|
||||
clientId,
|
||||
secretKey,
|
||||
);
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
} from "./authenticate";
|
||||
import { RefreshOptions } from "./refresh";
|
||||
import { GenerateOptions } from "./generate";
|
||||
import { ThirdwebAuthOptions } from "../types";
|
||||
|
||||
export type BuildLoginPayloadParams = {
|
||||
wallet: GenericAuthWallet;
|
||||
@@ -19,9 +20,9 @@ export type SignLoginPayloadParams = {
|
||||
};
|
||||
|
||||
export type VerifyLoginPayloadParams = {
|
||||
wallet: GenericAuthWallet;
|
||||
payload: LoginPayload;
|
||||
options: VerifyOptions;
|
||||
clientOptions: ThirdwebAuthOptions;
|
||||
};
|
||||
|
||||
export type BuildJwtParams = {
|
||||
@@ -33,6 +34,7 @@ export type GenerateJwtParams = {
|
||||
wallet: GenericAuthWallet;
|
||||
payload: LoginPayload;
|
||||
options: GenerateOptions;
|
||||
clientOptions: ThirdwebAuthOptions;
|
||||
};
|
||||
|
||||
export type RefreshJwtParams = {
|
||||
@@ -45,4 +47,5 @@ export type AuthenticateJwtParams = {
|
||||
wallet: GenericAuthWallet;
|
||||
jwt: string;
|
||||
options: AuthenticateOptions;
|
||||
clientOptions: ThirdwebAuthOptions;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
export type ThirdwebAuthOptions = {
|
||||
clientId?: string;
|
||||
secretKey?: string;
|
||||
};
|
||||
@@ -41,7 +41,7 @@ export function ThirdwebAuth<
|
||||
): ThirdwebAuthReturnType<TData, TSession> {
|
||||
const ctx = {
|
||||
...cfg,
|
||||
auth: new ThirdwebAuthSDK(cfg.wallet, cfg.domain),
|
||||
auth: new ThirdwebAuthSDK(cfg.wallet, cfg.domain, cfg.thirdwebAuthOptions),
|
||||
};
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ThirdwebAuth } from "../../core";
|
||||
import { ThirdwebAuthOptions } from "../../core/types";
|
||||
import { Json, LoginPayloadOutputSchema, User } from "../../core";
|
||||
import type { GenericAuthWallet } from "@thirdweb-dev/wallets";
|
||||
import { Request } from "express";
|
||||
@@ -68,6 +69,7 @@ export type ThirdwebAuthConfig<
|
||||
| ((user: User, req: Request) => void)
|
||||
| ((user: User, req: Request) => Promise<void>);
|
||||
};
|
||||
thirdwebAuthOptions?: ThirdwebAuthOptions;
|
||||
};
|
||||
|
||||
export type ThirdwebAuthContext<
|
||||
|
||||
@@ -44,7 +44,7 @@ export function ThirdwebAuth<
|
||||
): ThirdwebAuthReturnType<TData, TSession> {
|
||||
const ctx = {
|
||||
...cfg,
|
||||
auth: new ThirdwebAuthSDK(cfg.wallet, cfg.domain),
|
||||
auth: new ThirdwebAuthSDK(cfg.wallet, cfg.domain, cfg.thirdwebAuthOptions),
|
||||
};
|
||||
|
||||
const authRouter = async (
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
import { z } from "zod";
|
||||
import { IncomingMessage, ServerResponse } from "http";
|
||||
import { ZodTypeProvider } from "fastify-type-provider-zod";
|
||||
import { ThirdwebAuthOptions } from "../../core/types";
|
||||
|
||||
export const PayloadBodySchema = z.object({
|
||||
address: z.string(),
|
||||
@@ -76,6 +77,7 @@ export type ThirdwebAuthConfig<
|
||||
| ((user: User, req: FastifyRequest) => void)
|
||||
| ((user: User, req: FastifyRequest) => Promise<void>);
|
||||
};
|
||||
thirdwebAuthOptions?: ThirdwebAuthOptions;
|
||||
};
|
||||
|
||||
export type ThirdwebAuthContext<
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { GenericAuthWallet } from "@thirdweb-dev/wallets";
|
||||
import { z } from "zod";
|
||||
|
||||
import { Json, LoginPayloadOutputSchema, User } from "../../core";
|
||||
import { ThirdwebAuthOptions } from "../../core/types";
|
||||
|
||||
export const PayloadBodySchema = z.object({
|
||||
address: z.string(),
|
||||
@@ -55,8 +56,9 @@ export type ThirdwebAuthConfigShared = {
|
||||
sameSite?: "lax" | "strict" | "none";
|
||||
secure?: boolean;
|
||||
};
|
||||
thirdwebAuthOptions?: ThirdwebAuthOptions;
|
||||
};
|
||||
|
||||
export type ThirdwebNextContext = {
|
||||
params?: Record<string, string | string[]>
|
||||
params?: Record<string, string | string[]>;
|
||||
};
|
||||
|
||||
@@ -8,19 +8,10 @@ import loginHandler from "./routes/login";
|
||||
import logoutHandler from "./routes/logout";
|
||||
import userHandler from "./routes/user";
|
||||
import switchAccountHandler from "./routes/switch-account";
|
||||
import type {
|
||||
ThirdwebAuthConfig,
|
||||
ThirdwebAuthContext,
|
||||
} from "./types";
|
||||
import type {
|
||||
ThirdwebAuthRoute,
|
||||
ThirdwebNextContext,
|
||||
} from "../common/types";
|
||||
import type { ThirdwebAuthConfig, ThirdwebAuthContext } from "./types";
|
||||
import type { ThirdwebAuthRoute, ThirdwebNextContext } from "../common/types";
|
||||
|
||||
export type {
|
||||
ThirdwebAuthConfig,
|
||||
ThirdwebAuthContext,
|
||||
} from "./types";
|
||||
export type { ThirdwebAuthConfig, ThirdwebAuthContext } from "./types";
|
||||
|
||||
export async function ThirdwebAuthRouter(
|
||||
req: NextRequest,
|
||||
@@ -44,7 +35,7 @@ export async function ThirdwebAuthRouter(
|
||||
default:
|
||||
return Response.json(
|
||||
{ message: "Invalid route for authentication." },
|
||||
{ status: 400},
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -55,10 +46,13 @@ export function ThirdwebAuth<
|
||||
>(cfg: ThirdwebAuthConfig<TData, TSession>) {
|
||||
const authCtx = {
|
||||
...cfg,
|
||||
auth: new ThirdwebAuthSDK(cfg.wallet, cfg.domain),
|
||||
auth: new ThirdwebAuthSDK(cfg.wallet, cfg.domain, cfg.thirdwebAuthOptions),
|
||||
};
|
||||
|
||||
async function ThirdwebAuthHandler(req: NextRequest, ctx: ThirdwebNextContext) {
|
||||
async function ThirdwebAuthHandler(
|
||||
req: NextRequest,
|
||||
ctx: ThirdwebNextContext,
|
||||
) {
|
||||
return await ThirdwebAuthRouter(req, ctx, authCtx as ThirdwebAuthContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ export function ThirdwebAuth<
|
||||
>(cfg: ThirdwebAuthConfig<TData, TSession>) {
|
||||
const ctx = {
|
||||
...cfg,
|
||||
auth: new ThirdwebAuthSDK(cfg.wallet, cfg.domain),
|
||||
auth: new ThirdwebAuthSDK(cfg.wallet, cfg.domain, cfg.thirdwebAuthOptions),
|
||||
};
|
||||
|
||||
function ThirdwebAuthHandler(
|
||||
|
||||
@@ -3,6 +3,8 @@ import { EthersWallet } from "@thirdweb-dev/wallets/evm/wallets/ethers";
|
||||
import { expect } from "chai";
|
||||
import { Wallet } from "ethers";
|
||||
|
||||
require("dotenv-mono").load();
|
||||
|
||||
describe("Wallet Authentication - EVM", async () => {
|
||||
let adminWallet: any, signerWallet: any, attackerWallet: any;
|
||||
let auth: ThirdwebAuth;
|
||||
@@ -18,7 +20,9 @@ describe("Wallet Authentication - EVM", async () => {
|
||||
signerWallet = new EthersWallet(signerSigner);
|
||||
attackerWallet = new EthersWallet(attackerSigner);
|
||||
|
||||
auth = new ThirdwebAuth(signerWallet, "thirdweb.com");
|
||||
auth = new ThirdwebAuth(signerWallet, "thirdweb.com", {
|
||||
secretKey: process.env.TW_SECRET_KEY,
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
|
||||
@@ -0,0 +1,384 @@
|
||||
import { LocalWallet, SmartWallet } from "@thirdweb-dev/wallets";
|
||||
import { ThirdwebAuth } from "../src/core";
|
||||
import { EthersWallet } from "@thirdweb-dev/wallets/evm/wallets/ethers";
|
||||
import { expect } from "chai";
|
||||
import { Wallet } from "ethers";
|
||||
|
||||
require("dotenv-mono").load();
|
||||
|
||||
describe("Wallet Authentication - EVM - Smart Wallet", async () => {
|
||||
let adminWallet: any, signerWallet: any, attackerWallet: any;
|
||||
let auth: ThirdwebAuth;
|
||||
|
||||
before(async () => {
|
||||
const factoryAddress = "0x13947435c2fe6BE51ED82F6f59C38617a323dB9B";
|
||||
const chain = 80001;
|
||||
const localWallet = new LocalWallet();
|
||||
await localWallet.generate();
|
||||
const smartWallet = new SmartWallet({
|
||||
chain: chain,
|
||||
factoryAddress: factoryAddress,
|
||||
gasless: true,
|
||||
secretKey: process.env.TW_SECRET_KEY,
|
||||
});
|
||||
await smartWallet.connect({ personalWallet: localWallet });
|
||||
|
||||
adminWallet = new EthersWallet(Wallet.createRandom());
|
||||
signerWallet = smartWallet;
|
||||
attackerWallet = new EthersWallet(Wallet.createRandom());
|
||||
|
||||
auth = new ThirdwebAuth(signerWallet, "thirdweb.com", {
|
||||
secretKey: process.env.TW_SECRET_KEY,
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
auth.updateWallet(signerWallet);
|
||||
});
|
||||
|
||||
it("Should verify logged in wallet", async () => {
|
||||
const payload = await auth.login();
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
const address = await auth.verify(payload);
|
||||
|
||||
expect(address).to.equal(await signerWallet.getAddress());
|
||||
});
|
||||
|
||||
it("Should verify logged in wallet with chain ID and expiration", async () => {
|
||||
const payload = await auth.login({
|
||||
expirationTime: new Date(Date.now() + 1000 * 60 * 5),
|
||||
chainId: "80001",
|
||||
});
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
const address = await auth.verify(payload, {
|
||||
chainId: "80001",
|
||||
});
|
||||
|
||||
expect(address).to.equal(await signerWallet.getAddress());
|
||||
});
|
||||
|
||||
it("Should verify payload with resources", async () => {
|
||||
const payload = await auth.login({
|
||||
resources: ["https://example.com", "https://test.com"],
|
||||
});
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
const address = await auth.verify(payload, {
|
||||
resources: ["https://example.com", "https://test.com"],
|
||||
});
|
||||
|
||||
expect(address).to.equal(await signerWallet.getAddress());
|
||||
});
|
||||
|
||||
it("Should reject payload without necessary resources", async () => {
|
||||
const payload = await auth.login({
|
||||
resources: ["https://example.com"],
|
||||
});
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
try {
|
||||
await auth.verify(payload, {
|
||||
resources: ["https://example.com", "https://test.com"],
|
||||
});
|
||||
expect.fail();
|
||||
} catch (err: any) {
|
||||
expect(err.message).to.equal(
|
||||
"Login request is missing required resources: https://test.com",
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("Should verify payload with customized statement", async () => {
|
||||
const payload = await auth.login({
|
||||
statement: "Please sign!",
|
||||
});
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
const address = await auth.verify(payload, {
|
||||
statement: "Please sign!",
|
||||
});
|
||||
|
||||
expect(address).to.equal(await signerWallet.getAddress());
|
||||
});
|
||||
|
||||
it("Should reject payload with incorrect statement", async () => {
|
||||
const payload = await auth.login({
|
||||
statement: "Please sign!",
|
||||
});
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
try {
|
||||
await auth.verify(payload, {
|
||||
statement: "Please sign again!",
|
||||
});
|
||||
expect.fail();
|
||||
} catch (err: any) {
|
||||
expect(err.message).to.include(
|
||||
"Expected statement 'Please sign again!' does not match statement on payload",
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("Should reject invalid nonce", async () => {
|
||||
const payload = await auth.login();
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
try {
|
||||
await auth.verify(payload, {
|
||||
validateNonce: (nonce: string) => {
|
||||
if (nonce === payload.payload.nonce) {
|
||||
throw new Error();
|
||||
}
|
||||
},
|
||||
});
|
||||
expect.fail();
|
||||
} catch (err: any) {
|
||||
expect(err.message).to.equal("Login request nonce is invalid");
|
||||
}
|
||||
});
|
||||
|
||||
it("Should accept valid nonce", async () => {
|
||||
const payload = await auth.login();
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
const address = await auth.verify(payload, {
|
||||
validateNonce: (nonce: string) => {
|
||||
if (nonce !== payload.payload.nonce) {
|
||||
throw new Error();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
expect(address).to.equal(await signerWallet.getAddress());
|
||||
});
|
||||
|
||||
it("Should reject payload with incorrect domain", async () => {
|
||||
const payload = await auth.login();
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
try {
|
||||
await auth.verify(payload, { domain: "test.thirdweb.com" });
|
||||
expect.fail();
|
||||
} catch (err: any) {
|
||||
expect(err.message).to.equal(
|
||||
"Expected domain 'test.thirdweb.com' does not match domain on payload 'thirdweb.com'",
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("Should reject expired login payload", async () => {
|
||||
const payload = await auth.login({
|
||||
expirationTime: new Date(Date.now() - 1000 * 60 * 5),
|
||||
});
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
try {
|
||||
await auth.verify(payload);
|
||||
expect.fail();
|
||||
} catch (err: any) {
|
||||
expect(err.message).to.equal("Login request has expired");
|
||||
}
|
||||
});
|
||||
|
||||
it("Should reject payload with incorrect chain ID", async () => {
|
||||
const payload = await auth.login({
|
||||
chainId: "1",
|
||||
});
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
try {
|
||||
await auth.verify(payload, {
|
||||
chainId: "137",
|
||||
});
|
||||
expect.fail();
|
||||
} catch (err: any) {
|
||||
expect(err.message).to.equal(
|
||||
"Expected chain ID '137' does not match chain ID on payload '1'",
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("Should reject payload with incorrect signer", async () => {
|
||||
const payload = await auth.login();
|
||||
payload.payload.address = await attackerWallet.getAddress();
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
try {
|
||||
await auth.verify(payload);
|
||||
expect.fail();
|
||||
} catch (err: any) {
|
||||
expect(err.message).to.contain("does not match payload address");
|
||||
}
|
||||
});
|
||||
|
||||
it("Should generate valid authentication token", async () => {
|
||||
const payload = await auth.login();
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
const token = await auth.generate(payload);
|
||||
const user = await auth.authenticate(token);
|
||||
|
||||
expect(user.address).to.equal(await signerWallet.getAddress());
|
||||
});
|
||||
|
||||
it("Should reject token with incorrect domain", async () => {
|
||||
const payload = await auth.login();
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
const token = await auth.generate(payload);
|
||||
|
||||
try {
|
||||
await auth.authenticate(token, { domain: "test.thirdweb.com" });
|
||||
expect.fail();
|
||||
} catch (err: any) {
|
||||
expect(err.message).to.contain(
|
||||
"Expected token to be for the domain 'test.thirdweb.com', but found token with domain 'thirdweb.com'",
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("Should reject token before invalid before", async () => {
|
||||
const payload = await auth.login();
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
const token = await auth.generate(payload, {
|
||||
invalidBefore: new Date(Date.now() + 1000 * 60 * 5),
|
||||
});
|
||||
|
||||
try {
|
||||
await auth.authenticate(token);
|
||||
expect.fail();
|
||||
} catch (err: any) {
|
||||
expect(err.message).to.contain("This token is invalid before");
|
||||
}
|
||||
});
|
||||
|
||||
it("Should reject expired authentication token", async () => {
|
||||
const payload = await auth.login();
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
const token = await auth.generate(payload, {
|
||||
expirationTime: new Date(Date.now() - 1000 * 60 * 5),
|
||||
});
|
||||
|
||||
try {
|
||||
await auth.authenticate(token);
|
||||
expect.fail();
|
||||
} catch (err: any) {
|
||||
expect(err.message).to.contain("This token expired");
|
||||
}
|
||||
});
|
||||
|
||||
it("Should reject if admin address is not connected wallet address", async () => {
|
||||
const payload = await auth.login();
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
const token = await auth.generate(payload);
|
||||
|
||||
auth.updateWallet(signerWallet);
|
||||
try {
|
||||
await auth.authenticate(token);
|
||||
expect.fail();
|
||||
} catch (err: any) {
|
||||
expect(err.message).to.contain(
|
||||
`The expected issuer address '${await signerWallet.getAddress()}' did not match the token issuer address '${await adminWallet.getAddress()}'`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it("Should accept token with valid token ID", async () => {
|
||||
const payload = await auth.login();
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
const token = await auth.generate(payload, {
|
||||
tokenId: "test",
|
||||
});
|
||||
|
||||
const user = await auth.authenticate(token, {
|
||||
validateTokenId: (tokenId: string) => {
|
||||
if (tokenId !== "test") {
|
||||
throw new Error();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
expect(user.address).to.equal(await signerWallet.getAddress());
|
||||
});
|
||||
|
||||
it("Should reject token with invalid token ID", async () => {
|
||||
const payload = await auth.login();
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
const token = await auth.generate(payload, {
|
||||
tokenId: "test",
|
||||
});
|
||||
|
||||
try {
|
||||
await auth.authenticate(token, {
|
||||
validateTokenId: (tokenId: string) => {
|
||||
if (tokenId !== "invalid") {
|
||||
throw new Error();
|
||||
}
|
||||
},
|
||||
});
|
||||
expect.fail();
|
||||
} catch (err: any) {
|
||||
expect(err.message).to.contain("Token ID is invalid");
|
||||
}
|
||||
});
|
||||
|
||||
it("Should propagate session on token", async () => {
|
||||
const payload = await auth.login();
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
const token = await auth.generate(payload, {
|
||||
session: { role: "admin" },
|
||||
});
|
||||
|
||||
const user = await auth.authenticate(token);
|
||||
|
||||
expect(user.address).to.equal(await signerWallet.getAddress());
|
||||
expect(user.session).to.deep.equal({ role: "admin" });
|
||||
});
|
||||
|
||||
it("Should call session callback function", async () => {
|
||||
const payload = await auth.login();
|
||||
|
||||
auth.updateWallet(adminWallet);
|
||||
const token = await auth.generate(payload, {
|
||||
session: (address: string) => {
|
||||
return { address, role: "admin" };
|
||||
},
|
||||
});
|
||||
|
||||
const user = await auth.authenticate(token);
|
||||
|
||||
expect(user.address).to.equal(await signerWallet.getAddress());
|
||||
expect(user.session).to.deep.equal({
|
||||
address: await signerWallet.getAddress(),
|
||||
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());
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,17 @@
|
||||
# @thirdweb-dev/chains
|
||||
|
||||
## 0.1.78
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2416](https://github.com/thirdweb-dev/js/pull/2416) [`588897d`](https://github.com/thirdweb-dev/js/commit/588897d1b04e6c63da13639aeb47ca701308e1b2) Thanks [@github-actions](https://github.com/apps/github-actions)! - Synced Chains Package
|
||||
|
||||
## 0.1.77
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2406](https://github.com/thirdweb-dev/js/pull/2406) [`047fbe2`](https://github.com/thirdweb-dev/js/commit/047fbe2918808cbc8fded90104458b6e38d1207d) Thanks [@github-actions](https://github.com/apps/github-actions)! - Synced Chains Package
|
||||
|
||||
## 0.1.76
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"chain": "ETH",
|
||||
"chainId": 17186,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "lazy crimson coral explorer",
|
||||
"url": "https://explorerl2new-lazy-crimson-coral-cotlv0ftqf.t.conduit.xyz",
|
||||
"standard": "standard"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"features": [],
|
||||
"name": "lazy-crimson-coral",
|
||||
"nativeCurrency": {
|
||||
"name": "Ether",
|
||||
"symbol": "ETH",
|
||||
"decimals": 18
|
||||
},
|
||||
"networkId": 17186,
|
||||
"parent": {
|
||||
"type": "L3",
|
||||
"chain": "Base",
|
||||
"bridges": [
|
||||
{
|
||||
"url": "https://lazy-crimson-coral-cotlv0ftqf.testnets.superbridge.app"
|
||||
}
|
||||
]
|
||||
},
|
||||
"redFlags": [],
|
||||
"rpc": [],
|
||||
"shortName": "lazy-crimson-coral",
|
||||
"slug": "lazy-crimson-coral",
|
||||
"testnet": true
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"chain": "Avalanche",
|
||||
"chainId": 22662,
|
||||
"explorers": [],
|
||||
"faucets": [],
|
||||
"features": [],
|
||||
"icon": {
|
||||
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
|
||||
"width": 256,
|
||||
"height": 256,
|
||||
"format": "svg"
|
||||
},
|
||||
"infoURL": "https://avacloud.io",
|
||||
"name": "QA5-03-07 Testnet",
|
||||
"nativeCurrency": {
|
||||
"name": "QA5-03-07 Testnet Token",
|
||||
"symbol": "TYP",
|
||||
"decimals": 18
|
||||
},
|
||||
"networkId": 22662,
|
||||
"redFlags": [],
|
||||
"rpc": [
|
||||
"https://22662.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
|
||||
],
|
||||
"shortName": "QA5-03-07 Testnet",
|
||||
"slug": "qa5-03-07-testnet",
|
||||
"testnet": true
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"chain": "Avalanche",
|
||||
"chainId": 24867,
|
||||
"explorers": [],
|
||||
"faucets": [],
|
||||
"features": [],
|
||||
"icon": {
|
||||
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
|
||||
"width": 256,
|
||||
"height": 256,
|
||||
"format": "svg"
|
||||
},
|
||||
"infoURL": "https://avacloud.io",
|
||||
"name": "QaUser45 Testnet",
|
||||
"nativeCurrency": {
|
||||
"name": "QaUser45 Testnet Token",
|
||||
"symbol": "ZAG",
|
||||
"decimals": 18
|
||||
},
|
||||
"networkId": 24867,
|
||||
"redFlags": [],
|
||||
"rpc": [
|
||||
"https://24867.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
|
||||
],
|
||||
"shortName": "QaUser45 Testnet",
|
||||
"slug": "qauser45-testnet",
|
||||
"testnet": true
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,42 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"chain": "3839",
|
||||
"chainId": 3839,
|
||||
"explorers": [
|
||||
{
|
||||
"name": "traderlands explorer",
|
||||
"url": "https://sepolia.arbiscan.io/",
|
||||
"standard": "standard",
|
||||
"icon": {
|
||||
"url": "ipfs://QmRQVgjLcoWAVTocuYegwumz8J8b2F3Le2WnQhwffRmWcg/traderlands%20logo.png",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
}
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"features": [],
|
||||
"icon": {
|
||||
"url": "ipfs://QmRQVgjLcoWAVTocuYegwumz8J8b2F3Le2WnQhwffRmWcg/traderlands%20logo.png",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"infoURL": "https://sepolia.arbiscan.io/",
|
||||
"name": "traderlands-sepolia",
|
||||
"nativeCurrency": {
|
||||
"name": "Traderlands",
|
||||
"symbol": "TRADE",
|
||||
"decimals": 18
|
||||
},
|
||||
"networkId": 3839,
|
||||
"redFlags": [],
|
||||
"rpc": [
|
||||
"https://3839.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://traderlands-sepolia.rpc.caldera.xyz/http"
|
||||
],
|
||||
"shortName": "Tradetest",
|
||||
"slug": "traderlands-sepolia",
|
||||
"testnet": true
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"chain": "Avalanche",
|
||||
"chainId": 51277,
|
||||
"explorers": [],
|
||||
"faucets": [],
|
||||
"features": [],
|
||||
"icon": {
|
||||
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
|
||||
"width": 256,
|
||||
"height": 256,
|
||||
"format": "svg"
|
||||
},
|
||||
"infoURL": "https://avacloud.io",
|
||||
"name": "QI0344s1 Testne",
|
||||
"nativeCurrency": {
|
||||
"name": "QI0344s1 Testne Token",
|
||||
"symbol": "LKG",
|
||||
"decimals": 18
|
||||
},
|
||||
"networkId": 51277,
|
||||
"redFlags": [],
|
||||
"rpc": [
|
||||
"https://51277.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
|
||||
],
|
||||
"shortName": "QI0344s1 Testne",
|
||||
"slug": "qi0344s1-testne",
|
||||
"testnet": true
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"chain": "Avalanche",
|
||||
"chainId": 57021,
|
||||
"explorers": [],
|
||||
"faucets": [],
|
||||
"features": [],
|
||||
"icon": {
|
||||
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
|
||||
"width": 256,
|
||||
"height": 256,
|
||||
"format": "svg"
|
||||
},
|
||||
"infoURL": "https://avacloud.io",
|
||||
"name": "QIM2403061",
|
||||
"nativeCurrency": {
|
||||
"name": "QIM2403061 Token",
|
||||
"symbol": "VVC",
|
||||
"decimals": 18
|
||||
},
|
||||
"networkId": 57021,
|
||||
"redFlags": [],
|
||||
"rpc": [
|
||||
"https://57021.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
|
||||
],
|
||||
"shortName": "QIM2403061",
|
||||
"slug": "qim2403061",
|
||||
"testnet": true
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,47 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"chain": "FTM",
|
||||
"chainId": 64165,
|
||||
"ens": {
|
||||
"registry": "standard"
|
||||
},
|
||||
"explorers": [
|
||||
{
|
||||
"name": "Fantom Sonic Builders Testnet",
|
||||
"url": "https://sonicscan.io/",
|
||||
"standard": "standard",
|
||||
"icon": {
|
||||
"url": "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/fantom/512.png",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
}
|
||||
}
|
||||
],
|
||||
"faucets": [
|
||||
"https://public-sonic.fantom.network/account"
|
||||
],
|
||||
"features": [],
|
||||
"icon": {
|
||||
"url": "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/fantom/512.png",
|
||||
"width": 512,
|
||||
"height": 512,
|
||||
"format": "png"
|
||||
},
|
||||
"infoURL": "https://sonicscan.io/",
|
||||
"name": "Fantom Sonic Builders Testnet",
|
||||
"nativeCurrency": {
|
||||
"name": "Fantom",
|
||||
"symbol": "FTM",
|
||||
"decimals": 18
|
||||
},
|
||||
"networkId": 64165,
|
||||
"redFlags": [],
|
||||
"rpc": [
|
||||
"https://64165.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://rpc.sonic.fantom.network/"
|
||||
],
|
||||
"shortName": "FantomTestnet",
|
||||
"slug": "fantom-sonic-builders-testnet",
|
||||
"testnet": true
|
||||
} as const satisfies Chain;
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"chain": "Avalanche",
|
||||
"chainId": 65300,
|
||||
"explorers": [],
|
||||
"faucets": [],
|
||||
"features": [],
|
||||
"icon": {
|
||||
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
|
||||
"width": 256,
|
||||
"height": 256,
|
||||
"format": "svg"
|
||||
},
|
||||
"infoURL": "https://avacloud.io",
|
||||
"name": "QaUser46 Testnet",
|
||||
"nativeCurrency": {
|
||||
"name": "QaUser46 Testnet Token",
|
||||
"symbol": "ZAG",
|
||||
"decimals": 18
|
||||
},
|
||||
"networkId": 65300,
|
||||
"redFlags": [],
|
||||
"rpc": [
|
||||
"https://65300.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
|
||||
],
|
||||
"shortName": "QaUser46 Testnet",
|
||||
"slug": "qauser46-testnet",
|
||||
"testnet": true
|
||||
} as const satisfies Chain;
|
||||
@@ -6,22 +6,10 @@ export default {
|
||||
{
|
||||
"name": "GuapcoinX Explorer",
|
||||
"url": "http://explorer.guapcoinx.com",
|
||||
"standard": "none",
|
||||
"icon": {
|
||||
"url": "ipfs://QmcDTR7982VQKDDz2Mh4fZbnE9hn67MuFPWQv1MimCqPvB",
|
||||
"width": 800,
|
||||
"height": 800,
|
||||
"format": "png"
|
||||
}
|
||||
"standard": "none"
|
||||
}
|
||||
],
|
||||
"faucets": [],
|
||||
"icon": {
|
||||
"url": "ipfs://QmcDTR7982VQKDDz2Mh4fZbnE9hn67MuFPWQv1MimCqPvB",
|
||||
"width": 800,
|
||||
"height": 800,
|
||||
"format": "png"
|
||||
},
|
||||
"infoURL": "https://guapcoin.org/",
|
||||
"name": "GuapcoinX",
|
||||
"nativeCurrency": {
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { Chain } from "../src/types";
|
||||
export default {
|
||||
"chain": "Avalanche",
|
||||
"chainId": 72877,
|
||||
"explorers": [],
|
||||
"faucets": [],
|
||||
"features": [],
|
||||
"icon": {
|
||||
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
|
||||
"width": 256,
|
||||
"height": 256,
|
||||
"format": "svg"
|
||||
},
|
||||
"infoURL": "https://avacloud.io",
|
||||
"name": "QaUser4 Testnet",
|
||||
"nativeCurrency": {
|
||||
"name": "QaUser4 Testnet Token",
|
||||
"symbol": "ZAG",
|
||||
"decimals": 18
|
||||
},
|
||||
"networkId": 72877,
|
||||
"redFlags": [],
|
||||
"rpc": [
|
||||
"https://72877.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
|
||||
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
|
||||
],
|
||||
"shortName": "QaUser4 Testnet",
|
||||
"slug": "qauser4-testnet-qauser4 testnet",
|
||||
"testnet": true
|
||||
} as const satisfies Chain;
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/chains",
|
||||
"version": "0.1.76",
|
||||
"version": "0.1.78",
|
||||
"main": "dist/thirdweb-dev-chains.cjs.js",
|
||||
"module": "dist/thirdweb-dev-chains.esm.js",
|
||||
"exports": {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,45 @@
|
||||
# thirdweb
|
||||
|
||||
## 0.13.48
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`cabfc29`](https://github.com/thirdweb-dev/js/commit/cabfc29119f25a78010f59f766bdcb8c392afa2d), [`173777a`](https://github.com/thirdweb-dev/js/commit/173777ade4ea59cde1c6f25a4654d48b277be9ad)]:
|
||||
- @thirdweb-dev/wallets@2.4.18
|
||||
- @thirdweb-dev/sdk@4.0.43
|
||||
- @thirdweb-dev/auth@4.1.40
|
||||
|
||||
## 0.13.47
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c894270`](https://github.com/thirdweb-dev/js/commit/c894270401850575d1a4df73e16198177b46477a), [`332a145`](https://github.com/thirdweb-dev/js/commit/332a14552bf95e13e5220b1bd73414f000088568), [`c6b025e`](https://github.com/thirdweb-dev/js/commit/c6b025e84451341f6f48c0a7c4b5f06b8e49d792)]:
|
||||
- @thirdweb-dev/wallets@2.4.17
|
||||
- @thirdweb-dev/sdk@4.0.42
|
||||
- @thirdweb-dev/auth@4.1.39
|
||||
|
||||
## 0.13.46
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`862905e`](https://github.com/thirdweb-dev/js/commit/862905e161a091c15eb9b054cfcca0e5d2879fd6), [`588897d`](https://github.com/thirdweb-dev/js/commit/588897d1b04e6c63da13639aeb47ca701308e1b2), [`862905e`](https://github.com/thirdweb-dev/js/commit/862905e161a091c15eb9b054cfcca0e5d2879fd6)]:
|
||||
- @thirdweb-dev/auth@4.1.38
|
||||
- @thirdweb-dev/chains@0.1.78
|
||||
- @thirdweb-dev/wallets@2.4.16
|
||||
- @thirdweb-dev/sdk@4.0.41
|
||||
|
||||
## 0.13.45
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2400](https://github.com/thirdweb-dev/js/pull/2400) [`ef76a96`](https://github.com/thirdweb-dev/js/commit/ef76a96c2dda21e28195371fd48e57350721b717) Thanks [@kumaryash90](https://github.com/kumaryash90)! - "Option to link external libraries"
|
||||
|
||||
- Updated dependencies [[`74a92dc`](https://github.com/thirdweb-dev/js/commit/74a92dcb7dc4be7d03bcb8b7211e87016f52a81f), [`047fbe2`](https://github.com/thirdweb-dev/js/commit/047fbe2918808cbc8fded90104458b6e38d1207d)]:
|
||||
- @thirdweb-dev/wallets@2.4.15
|
||||
- @thirdweb-dev/chains@0.1.77
|
||||
- @thirdweb-dev/auth@4.1.37
|
||||
- @thirdweb-dev/sdk@4.0.40
|
||||
|
||||
## 0.13.44
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "thirdweb",
|
||||
"main": "dist/cli/index.js",
|
||||
"version": "0.13.44",
|
||||
"version": "0.13.48",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -20,6 +20,7 @@ import { generate } from "../generate/command";
|
||||
import { findPackageInstallation } from "../helpers/detect-local-packages";
|
||||
import { install } from "../install";
|
||||
import { upload } from "../storage/command";
|
||||
import { parseLinkLibOption } from "../common/link-lib-helper";
|
||||
|
||||
const main = async () => {
|
||||
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
||||
@@ -331,6 +332,12 @@ const main = async () => {
|
||||
"Deploy a dynamic smart contract made up of extensions to blockchains",
|
||||
)
|
||||
.option("--zksync", "Deploy on ZKSync")
|
||||
.option(
|
||||
"--link-lib <library:address...>",
|
||||
"Specify library names and addresses",
|
||||
parseLinkLibOption,
|
||||
[],
|
||||
)
|
||||
.option("-k, --key <key>", "API secret key to authorize usage")
|
||||
.action(async (options) => {
|
||||
let secretKey = "";
|
||||
@@ -370,6 +377,12 @@ const main = async () => {
|
||||
.option("--dry-run", "dry run (skip actually publishing)")
|
||||
.option("-d, --debug", "show debug logs")
|
||||
.option("--ci", "Continuous Integration mode")
|
||||
.option(
|
||||
"--link-lib <library:address...>",
|
||||
"Specify library names and addresses",
|
||||
parseLinkLibOption,
|
||||
[],
|
||||
)
|
||||
.option("-k, --key <key>", "API secret key to authorize usage")
|
||||
.action(async (options) => {
|
||||
let secretKey = "";
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { utils } from "ethers";
|
||||
import { isAddress } from "ethers/lib/utils";
|
||||
|
||||
export interface Link {
|
||||
library: string;
|
||||
address: string;
|
||||
}
|
||||
|
||||
// Custom array option parser for --link-lib
|
||||
export function parseLinkLibOption(
|
||||
value: string,
|
||||
previousValue: Link[] | undefined,
|
||||
): Link[] {
|
||||
const links = previousValue || [];
|
||||
const [library, address] = value.split(":");
|
||||
if (!isAddress(address)) {
|
||||
throw new Error(`Invalid address ${address} `);
|
||||
}
|
||||
links.push({ library, address });
|
||||
return links;
|
||||
}
|
||||
|
||||
// replace placeholder in bytecode with library address
|
||||
export function linkLibrary(
|
||||
bytecode: string,
|
||||
libraries: {
|
||||
[key: string]: string;
|
||||
} = {},
|
||||
): string {
|
||||
let linkedBytecode = bytecode;
|
||||
for (const [key, address] of Object.entries(libraries)) {
|
||||
const placeholder = `__\$${utils
|
||||
.solidityKeccak256(["string"], [key])
|
||||
.slice(2, 36)}\$__`;
|
||||
const formattedAddress = utils
|
||||
.getAddress(address)
|
||||
.toLowerCase()
|
||||
.replace("0x", "");
|
||||
|
||||
linkedBytecode = linkedBytecode.replaceAll(placeholder, formattedAddress);
|
||||
}
|
||||
return linkedBytecode;
|
||||
}
|
||||
@@ -41,5 +41,6 @@ export default async function build(
|
||||
projectPath: path,
|
||||
clean: options.clean,
|
||||
zksync: options.zksync,
|
||||
linkLib: options.linkLib,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { findFiles } from "../../common/file-helper";
|
||||
import { Link, linkLibrary } from "../../common/link-lib-helper";
|
||||
import { hasForge } from "../../create/helpers/has-forge";
|
||||
import { execute } from "../helpers/exec";
|
||||
import { logger } from "../helpers/logger";
|
||||
@@ -43,6 +44,24 @@ export class FoundryBuilder extends BaseBuilder {
|
||||
const files: string[] = [];
|
||||
findFiles(outPath, /^.*(?<!metadata)\.json$/, files);
|
||||
|
||||
const libraries: { [key: string]: string } = {};
|
||||
if (Array.isArray(options.linkLib) && options.linkLib.length > 0) {
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const file = files[i];
|
||||
const contractName = basename(file, ".json");
|
||||
const contractJsonFile = readFileSync(file, "utf-8");
|
||||
const contractInfo = JSON.parse(contractJsonFile);
|
||||
|
||||
options.linkLib.forEach((link: Link) => {
|
||||
if (contractName === link.library) {
|
||||
const key = `${contractInfo.ast.absolutePath}:${link.library}`;
|
||||
libraries[key] = link.address;
|
||||
}
|
||||
});
|
||||
}
|
||||
logger.debug(`Found libraries to link: ${JSON.stringify(libraries)}`);
|
||||
}
|
||||
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const file = files[i];
|
||||
const contractName = basename(file, ".json");
|
||||
@@ -76,8 +95,13 @@ export class FoundryBuilder extends BaseBuilder {
|
||||
continue;
|
||||
}
|
||||
|
||||
const bytecode = contractInfo.bytecode.object;
|
||||
const deployedBytecode = contractInfo.deployedBytecode.object;
|
||||
let bytecode = contractInfo.bytecode.object;
|
||||
let deployedBytecode = contractInfo.deployedBytecode.object;
|
||||
|
||||
// link external libraries if any
|
||||
bytecode = linkLibrary(bytecode, libraries);
|
||||
deployedBytecode = linkLibrary(deployedBytecode, libraries);
|
||||
|
||||
const parsedMetadata = contractInfo.metadata;
|
||||
const metadata =
|
||||
contractInfo.rawMetadata ||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { findFiles } from "../../common/file-helper";
|
||||
import { Link, linkLibrary } from "../../common/link-lib-helper";
|
||||
import { execute } from "../helpers/exec";
|
||||
import { logger } from "../helpers/logger";
|
||||
import { ContractPayload } from "../interfaces/ContractPayload";
|
||||
@@ -85,6 +86,22 @@ export class HardhatBuilder extends BaseBuilder {
|
||||
|
||||
const contractBuildOutputs = buildJson.output.contracts;
|
||||
|
||||
const libraries: { [key: string]: string } = {};
|
||||
if (Array.isArray(options.linkLib) && options.linkLib.length > 0) {
|
||||
for (const [contractPath, contractInfos] of Object.entries(
|
||||
contractBuildOutputs,
|
||||
)) {
|
||||
const contractNames = Object.keys(contractInfos as any);
|
||||
options.linkLib.forEach((link: Link) => {
|
||||
if (contractNames.includes(link.library)) {
|
||||
const key = `${contractPath}:${link.library}`;
|
||||
libraries[key] = link.address;
|
||||
}
|
||||
});
|
||||
}
|
||||
logger.debug(`Found libraries to link: ${JSON.stringify(libraries)}`);
|
||||
}
|
||||
|
||||
for (const [contractPath, contractInfos] of Object.entries(
|
||||
contractBuildOutputs,
|
||||
)) {
|
||||
@@ -109,9 +126,13 @@ export class HardhatBuilder extends BaseBuilder {
|
||||
continue;
|
||||
}
|
||||
|
||||
const bytecode = info.evm.bytecode.object;
|
||||
const deployedBytecode =
|
||||
info.evm.deployedBytecode?.object || bytecode;
|
||||
let bytecode = info.evm.bytecode.object;
|
||||
let deployedBytecode = info.evm.deployedBytecode?.object || bytecode;
|
||||
|
||||
// link external libraries if any
|
||||
bytecode = linkLibrary(bytecode, libraries);
|
||||
deployedBytecode = linkLibrary(deployedBytecode, libraries);
|
||||
|
||||
const { metadata, abi } = info;
|
||||
|
||||
const meta = metadata.solc_metadata
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Link } from "../../common/link-lib-helper";
|
||||
import { ContractPayload } from "./ContractPayload";
|
||||
|
||||
export type CompileOptions = {
|
||||
@@ -5,6 +6,7 @@ export type CompileOptions = {
|
||||
projectPath: string;
|
||||
name: string;
|
||||
zksync?: boolean;
|
||||
linkLib?: Link[];
|
||||
};
|
||||
|
||||
export interface IBuilder {
|
||||
|
||||
@@ -1,5 +1,43 @@
|
||||
# @thirdweb-dev/react-core
|
||||
|
||||
## 4.4.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`cabfc29`](https://github.com/thirdweb-dev/js/commit/cabfc29119f25a78010f59f766bdcb8c392afa2d), [`173777a`](https://github.com/thirdweb-dev/js/commit/173777ade4ea59cde1c6f25a4654d48b277be9ad)]:
|
||||
- @thirdweb-dev/wallets@2.4.18
|
||||
- @thirdweb-dev/sdk@4.0.43
|
||||
- @thirdweb-dev/auth@4.1.40
|
||||
|
||||
## 4.4.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c894270`](https://github.com/thirdweb-dev/js/commit/c894270401850575d1a4df73e16198177b46477a), [`332a145`](https://github.com/thirdweb-dev/js/commit/332a14552bf95e13e5220b1bd73414f000088568), [`c6b025e`](https://github.com/thirdweb-dev/js/commit/c6b025e84451341f6f48c0a7c4b5f06b8e49d792)]:
|
||||
- @thirdweb-dev/wallets@2.4.17
|
||||
- @thirdweb-dev/sdk@4.0.42
|
||||
- @thirdweb-dev/auth@4.1.39
|
||||
|
||||
## 4.4.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`862905e`](https://github.com/thirdweb-dev/js/commit/862905e161a091c15eb9b054cfcca0e5d2879fd6), [`588897d`](https://github.com/thirdweb-dev/js/commit/588897d1b04e6c63da13639aeb47ca701308e1b2), [`862905e`](https://github.com/thirdweb-dev/js/commit/862905e161a091c15eb9b054cfcca0e5d2879fd6)]:
|
||||
- @thirdweb-dev/auth@4.1.38
|
||||
- @thirdweb-dev/chains@0.1.78
|
||||
- @thirdweb-dev/wallets@2.4.16
|
||||
- @thirdweb-dev/sdk@4.0.41
|
||||
|
||||
## 4.4.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`74a92dc`](https://github.com/thirdweb-dev/js/commit/74a92dcb7dc4be7d03bcb8b7211e87016f52a81f), [`047fbe2`](https://github.com/thirdweb-dev/js/commit/047fbe2918808cbc8fded90104458b6e38d1207d)]:
|
||||
- @thirdweb-dev/wallets@2.4.15
|
||||
- @thirdweb-dev/chains@0.1.77
|
||||
- @thirdweb-dev/auth@4.1.37
|
||||
- @thirdweb-dev/sdk@4.0.40
|
||||
|
||||
## 4.4.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-core",
|
||||
"version": "4.4.12",
|
||||
"version": "4.4.16",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-core",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,13 @@
|
||||
# @thirdweb-dev/react-native-compat
|
||||
|
||||
## 0.7.13
|
||||
|
||||
## 0.7.12
|
||||
|
||||
## 0.7.11
|
||||
|
||||
## 0.7.10
|
||||
|
||||
## 0.7.9
|
||||
|
||||
## 0.7.8
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-native-compat",
|
||||
"description": "Shims for Thirdweb in React Native Projects",
|
||||
"version": "0.7.9",
|
||||
"version": "0.7.13",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native-compat",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -1,5 +1,43 @@
|
||||
# @thirdweb-dev/react-native
|
||||
|
||||
## 0.7.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`cabfc29`](https://github.com/thirdweb-dev/js/commit/cabfc29119f25a78010f59f766bdcb8c392afa2d), [`173777a`](https://github.com/thirdweb-dev/js/commit/173777ade4ea59cde1c6f25a4654d48b277be9ad)]:
|
||||
- @thirdweb-dev/wallets@2.4.18
|
||||
- @thirdweb-dev/sdk@4.0.43
|
||||
- @thirdweb-dev/react-core@4.4.16
|
||||
|
||||
## 0.7.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c894270`](https://github.com/thirdweb-dev/js/commit/c894270401850575d1a4df73e16198177b46477a), [`332a145`](https://github.com/thirdweb-dev/js/commit/332a14552bf95e13e5220b1bd73414f000088568), [`c6b025e`](https://github.com/thirdweb-dev/js/commit/c6b025e84451341f6f48c0a7c4b5f06b8e49d792)]:
|
||||
- @thirdweb-dev/wallets@2.4.17
|
||||
- @thirdweb-dev/sdk@4.0.42
|
||||
- @thirdweb-dev/react-core@4.4.15
|
||||
|
||||
## 0.7.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`588897d`](https://github.com/thirdweb-dev/js/commit/588897d1b04e6c63da13639aeb47ca701308e1b2), [`862905e`](https://github.com/thirdweb-dev/js/commit/862905e161a091c15eb9b054cfcca0e5d2879fd6)]:
|
||||
- @thirdweb-dev/chains@0.1.78
|
||||
- @thirdweb-dev/wallets@2.4.16
|
||||
- @thirdweb-dev/react-core@4.4.14
|
||||
- @thirdweb-dev/sdk@4.0.41
|
||||
|
||||
## 0.7.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`74a92dc`](https://github.com/thirdweb-dev/js/commit/74a92dcb7dc4be7d03bcb8b7211e87016f52a81f), [`047fbe2`](https://github.com/thirdweb-dev/js/commit/047fbe2918808cbc8fded90104458b6e38d1207d)]:
|
||||
- @thirdweb-dev/wallets@2.4.15
|
||||
- @thirdweb-dev/chains@0.1.77
|
||||
- @thirdweb-dev/react-core@4.4.13
|
||||
- @thirdweb-dev/sdk@4.0.40
|
||||
|
||||
## 0.7.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react-native",
|
||||
"version": "0.7.9",
|
||||
"version": "0.7.13",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,45 @@
|
||||
# @thirdweb-dev/react
|
||||
|
||||
## 4.4.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2447](https://github.com/thirdweb-dev/js/pull/2447) [`8382330`](https://github.com/thirdweb-dev/js/commit/838233075a4d0897f57570f0f5eb041464838973) Thanks [@MananTank](https://github.com/MananTank)! - Fix multiple renders of EmbeddedWallet social Login screen after connection
|
||||
|
||||
- Updated dependencies [[`cabfc29`](https://github.com/thirdweb-dev/js/commit/cabfc29119f25a78010f59f766bdcb8c392afa2d), [`173777a`](https://github.com/thirdweb-dev/js/commit/173777ade4ea59cde1c6f25a4654d48b277be9ad)]:
|
||||
- @thirdweb-dev/wallets@2.4.18
|
||||
- @thirdweb-dev/sdk@4.0.43
|
||||
- @thirdweb-dev/react-core@4.4.16
|
||||
|
||||
## 4.4.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c894270`](https://github.com/thirdweb-dev/js/commit/c894270401850575d1a4df73e16198177b46477a), [`332a145`](https://github.com/thirdweb-dev/js/commit/332a14552bf95e13e5220b1bd73414f000088568), [`c6b025e`](https://github.com/thirdweb-dev/js/commit/c6b025e84451341f6f48c0a7c4b5f06b8e49d792)]:
|
||||
- @thirdweb-dev/wallets@2.4.17
|
||||
- @thirdweb-dev/sdk@4.0.42
|
||||
- @thirdweb-dev/react-core@4.4.15
|
||||
|
||||
## 4.4.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`588897d`](https://github.com/thirdweb-dev/js/commit/588897d1b04e6c63da13639aeb47ca701308e1b2), [`862905e`](https://github.com/thirdweb-dev/js/commit/862905e161a091c15eb9b054cfcca0e5d2879fd6)]:
|
||||
- @thirdweb-dev/chains@0.1.78
|
||||
- @thirdweb-dev/wallets@2.4.16
|
||||
- @thirdweb-dev/react-core@4.4.14
|
||||
- @thirdweb-dev/sdk@4.0.41
|
||||
|
||||
## 4.4.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`74a92dc`](https://github.com/thirdweb-dev/js/commit/74a92dcb7dc4be7d03bcb8b7211e87016f52a81f), [`047fbe2`](https://github.com/thirdweb-dev/js/commit/047fbe2918808cbc8fded90104458b6e38d1207d)]:
|
||||
- @thirdweb-dev/wallets@2.4.15
|
||||
- @thirdweb-dev/chains@0.1.77
|
||||
- @thirdweb-dev/react-core@4.4.13
|
||||
- @thirdweb-dev/sdk@4.0.40
|
||||
|
||||
## 4.4.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react",
|
||||
"version": "4.4.12",
|
||||
"version": "4.4.16",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
EmbeddedWallet,
|
||||
EmbeddedWalletOauthStrategy,
|
||||
} from "@thirdweb-dev/wallets";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { Spacer } from "../../../components/Spacer";
|
||||
import { Spinner } from "../../../components/Spinner";
|
||||
import { Container, ModalHeader } from "../../../components/basic";
|
||||
@@ -33,7 +33,6 @@ export const EmbeddedWalletSocialLogin = (
|
||||
|
||||
const socialLogin = async () => {
|
||||
try {
|
||||
console.log("socialLogin");
|
||||
const embeddedWallet = createWalletInstance();
|
||||
setConnectionStatus("connecting");
|
||||
const socialWindow = openOauthSignInWindow(props.strategy, themeObj);
|
||||
@@ -63,13 +62,19 @@ export const EmbeddedWalletSocialLogin = (
|
||||
}
|
||||
};
|
||||
|
||||
const closeModal = props.connected;
|
||||
const onConnect = props.connected;
|
||||
|
||||
const onConnectCalled = useRef(false);
|
||||
useEffect(() => {
|
||||
if (connectionStatus === "connected") {
|
||||
closeModal();
|
||||
if (onConnectCalled.current) {
|
||||
return;
|
||||
}
|
||||
}, [connectionStatus, closeModal]);
|
||||
|
||||
if (connectionStatus === "connected") {
|
||||
onConnect();
|
||||
onConnectCalled.current = true;
|
||||
}
|
||||
}, [connectionStatus, onConnect]);
|
||||
|
||||
return (
|
||||
<Container animate="fadein" flex="column" fullHeight>
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,33 @@
|
||||
# @thirdweb-dev/sdk
|
||||
|
||||
## 4.0.43
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2443](https://github.com/thirdweb-dev/js/pull/2443) [`cabfc29`](https://github.com/thirdweb-dev/js/commit/cabfc29119f25a78010f59f766bdcb8c392afa2d) Thanks [@0xFirekeeper](https://github.com/0xFirekeeper)! - [Smart Wallet] Use bundler eth_getUserOperationReceipt instead of rpc eth_getLogs, remove polygon gas station error logs
|
||||
|
||||
- [#2455](https://github.com/thirdweb-dev/js/pull/2455) [`173777a`](https://github.com/thirdweb-dev/js/commit/173777ade4ea59cde1c6f25a4654d48b277be9ad) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Update optimism SDK to fix the pnpm preinstall issue
|
||||
|
||||
## 4.0.42
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2441](https://github.com/thirdweb-dev/js/pull/2441) [`c6b025e`](https://github.com/thirdweb-dev/js/commit/c6b025e84451341f6f48c0a7c4b5f06b8e49d792) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Handle L1 fees for OP chains in `estimateGasCost()`
|
||||
|
||||
## 4.0.41
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`588897d`](https://github.com/thirdweb-dev/js/commit/588897d1b04e6c63da13639aeb47ca701308e1b2)]:
|
||||
- @thirdweb-dev/chains@0.1.78
|
||||
|
||||
## 4.0.40
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`047fbe2`](https://github.com/thirdweb-dev/js/commit/047fbe2918808cbc8fded90104458b6e38d1207d)]:
|
||||
- @thirdweb-dev/chains@0.1.77
|
||||
|
||||
## 4.0.39
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/sdk",
|
||||
"version": "4.0.39",
|
||||
"version": "4.0.43",
|
||||
"description": "The main thirdweb SDK.",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/sdk",
|
||||
"license": "Apache-2.0",
|
||||
@@ -134,6 +134,7 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@eth-optimism/sdk": "3.2.2",
|
||||
"@thirdweb-dev/chains": "workspace:*",
|
||||
"@thirdweb-dev/contracts-js": "workspace:*",
|
||||
"@thirdweb-dev/crypto": "workspace:*",
|
||||
|
||||
@@ -1,6 +1,17 @@
|
||||
import { ChainId } from "../constants/chains/ChainId";
|
||||
import { BigNumber, utils, providers } from "ethers";
|
||||
import { Mumbai, Polygon, Flag, FlagTestnet } from "@thirdweb-dev/chains";
|
||||
import {
|
||||
Mumbai,
|
||||
Polygon,
|
||||
Flag,
|
||||
FlagTestnet,
|
||||
Optimism,
|
||||
OpSepoliaTestnet,
|
||||
Base,
|
||||
BaseSepoliaTestnet,
|
||||
Zora,
|
||||
ZoraSepoliaTestnet,
|
||||
} from "@thirdweb-dev/chains";
|
||||
|
||||
type FeeData = {
|
||||
maxFeePerGas: null | BigNumber;
|
||||
@@ -99,6 +110,35 @@ export async function getGasPrice(
|
||||
return txGasPrice;
|
||||
}
|
||||
|
||||
export async function estimateTransactionCost(
|
||||
provider: providers.Provider,
|
||||
tx: providers.TransactionRequest,
|
||||
) {
|
||||
const chainId = (await provider.getNetwork()).chainId;
|
||||
if (isOpStackChain(chainId)) {
|
||||
const { asL2Provider } = await import("@eth-optimism/sdk");
|
||||
const l2RpcProvider = asL2Provider(provider);
|
||||
const l2GasCost = await l2RpcProvider.estimateTotalGasCost(tx);
|
||||
return l2GasCost;
|
||||
} else {
|
||||
const gasLimit = tx.gasLimit || (await provider.estimateGas(tx));
|
||||
const gasPrice = await getGasPrice(provider);
|
||||
const gasCost = BigNumber.from(gasLimit).mul(gasPrice);
|
||||
return gasCost;
|
||||
}
|
||||
}
|
||||
|
||||
function isOpStackChain(chainId: number) {
|
||||
return (
|
||||
chainId === Optimism.chainId ||
|
||||
chainId === OpSepoliaTestnet.chainId ||
|
||||
chainId === Base.chainId ||
|
||||
chainId === BaseSepoliaTestnet.chainId ||
|
||||
chainId === Zora.chainId ||
|
||||
chainId === ZoraSepoliaTestnet.chainId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
@@ -148,8 +188,8 @@ export async function getPolygonGasPriorityFee(
|
||||
const fixedFee = parseFloat(priorityFee).toFixed(9);
|
||||
return utils.parseUnits(fixedFee, "gwei");
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("failed to fetch gas", e);
|
||||
} catch {
|
||||
// if the gas station is down, return the default gas fee
|
||||
}
|
||||
return getDefaultGasFee(chainId);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { toEther } from "../../common/currency/toEther";
|
||||
import { estimateTransactionCost } from "../../common/gas-price";
|
||||
import { ContractWrapper } from "./internal/contract-wrapper";
|
||||
import { BaseContract, BigNumber, utils } from "ethers";
|
||||
|
||||
@@ -35,11 +37,11 @@ export class GasCostEstimator<TContract extends BaseContract> {
|
||||
fn: keyof TContract["functions"] | (string & {}),
|
||||
args: Parameters<TContract["functions"][typeof fn]> | any[],
|
||||
): Promise<string> {
|
||||
const [price, gasUnits] = await Promise.all([
|
||||
this.contractWrapper.getProvider().getGasPrice(),
|
||||
this.contractWrapper.estimateGas(fn, args),
|
||||
]);
|
||||
return utils.formatEther(gasUnits.mul(price));
|
||||
const gasCost = await estimateTransactionCost(
|
||||
this.contractWrapper.getProvider(),
|
||||
await this.contractWrapper.populateTransaction(fn, args),
|
||||
);
|
||||
return toEther(gasCost);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -192,6 +192,13 @@ export class ContractWrapper<
|
||||
return this.writeContract.estimateGas[fn as string](...args);
|
||||
}
|
||||
|
||||
public async populateTransaction(
|
||||
fn: keyof TContract["functions"],
|
||||
args: any[],
|
||||
): Promise<providers.TransactionRequest> {
|
||||
return this.writeContract.populateTransaction[fn as string](...args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { TransactionError, parseRevertReason } from "../../common/error";
|
||||
import { getDefaultGasOverrides, getGasPrice } from "../../common/gas-price";
|
||||
import {
|
||||
estimateTransactionCost,
|
||||
getDefaultGasOverrides,
|
||||
getGasPrice,
|
||||
} from "../../common/gas-price";
|
||||
import {
|
||||
fetchContractMetadataFromAddress,
|
||||
getContractMetadataFromCache,
|
||||
@@ -165,6 +169,10 @@ abstract class TransactionContext {
|
||||
}
|
||||
|
||||
public abstract estimateGasLimit(): Promise<BigNumber>;
|
||||
public abstract estimateGasCost(): Promise<{
|
||||
ether: string;
|
||||
wei: BigNumber;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* Set a multiple to multiply the gas limit by
|
||||
@@ -187,22 +195,6 @@ abstract class TransactionContext {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate the total gas cost of this transaction (in both ether and wei)
|
||||
*/
|
||||
public async estimateGasCost() {
|
||||
const [gasLimit, gasPrice] = await Promise.all([
|
||||
this.estimateGasLimit(),
|
||||
this.getGasPrice(),
|
||||
]);
|
||||
const gasCost = gasLimit.mul(gasPrice);
|
||||
|
||||
return {
|
||||
ether: utils.formatEther(gasCost),
|
||||
wei: gasCost,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the gas price for transactions (adding a 10% tip buffer)
|
||||
*/
|
||||
@@ -427,6 +419,20 @@ export class Transaction<
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate the total gas cost of this transaction (in both ether and wei)
|
||||
*/
|
||||
public async estimateGasCost() {
|
||||
const gasCost = await estimateTransactionCost(
|
||||
this.provider,
|
||||
await this.populateTransaction(),
|
||||
);
|
||||
return {
|
||||
ether: utils.formatEther(gasCost),
|
||||
wei: gasCost,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the transaction without waiting for it to be mined.
|
||||
*/
|
||||
@@ -755,6 +761,20 @@ export class DeployTransaction extends TransactionContext {
|
||||
}
|
||||
}
|
||||
|
||||
async estimateGasCost() {
|
||||
const gasOverrides = await this.getGasOverrides();
|
||||
const overrides: CallOverrides = { ...gasOverrides, ...this.overrides };
|
||||
const populatedTx = this.factory.getDeployTransaction(
|
||||
...this.args,
|
||||
overrides,
|
||||
);
|
||||
const gasCost = await estimateTransactionCost(this.provider, populatedTx);
|
||||
return {
|
||||
ether: utils.formatEther(gasCost),
|
||||
wei: gasCost,
|
||||
};
|
||||
}
|
||||
|
||||
async send(): Promise<ContractTransaction> {
|
||||
try {
|
||||
const populatedTx = await this.populateTransaction();
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,11 @@
|
||||
# @thirdweb-dev/service-utils
|
||||
|
||||
## 0.4.19
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2431](https://github.com/thirdweb-dev/js/pull/2431) [`6cf298a`](https://github.com/thirdweb-dev/js/commit/6cf298a29a29e37cecb88953aab195db8934a740) Thanks [@edwardysun](https://github.com/edwardysun)! - Add pay to Services list
|
||||
|
||||
## 0.4.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/service-utils",
|
||||
"version": "0.4.18",
|
||||
"version": "0.4.19",
|
||||
"main": "dist/thirdweb-dev-service-utils.cjs.js",
|
||||
"module": "dist/thirdweb-dev-service-utils.esm.js",
|
||||
"exports": {
|
||||
|
||||
@@ -47,10 +47,17 @@ export const SERVICE_DEFINITIONS = {
|
||||
checkout: {
|
||||
name: "checkout",
|
||||
title: "Checkouts",
|
||||
description: "Payments for easy web3 onboarding",
|
||||
description: "NFT Checkouts for easy web3 onboarding",
|
||||
// all actions allowed
|
||||
actions: [],
|
||||
},
|
||||
pay: {
|
||||
name: "pay",
|
||||
title: "Pay",
|
||||
description: "Pay for a blockchain transaction with any currency",
|
||||
// all actions allowed
|
||||
actions: [],
|
||||
}
|
||||
} as const;
|
||||
|
||||
export const SERVICE_NAMES = Object.keys(
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,47 @@
|
||||
# @thirdweb-dev/unity-js-bridge
|
||||
|
||||
## 0.4.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2443](https://github.com/thirdweb-dev/js/pull/2443) [`cabfc29`](https://github.com/thirdweb-dev/js/commit/cabfc29119f25a78010f59f766bdcb8c392afa2d) Thanks [@0xFirekeeper](https://github.com/0xFirekeeper)! - [Smart Wallet] Use bundler eth_getUserOperationReceipt instead of rpc eth_getLogs, remove polygon gas station error logs
|
||||
|
||||
- Updated dependencies [[`cabfc29`](https://github.com/thirdweb-dev/js/commit/cabfc29119f25a78010f59f766bdcb8c392afa2d), [`173777a`](https://github.com/thirdweb-dev/js/commit/173777ade4ea59cde1c6f25a4654d48b277be9ad)]:
|
||||
- @thirdweb-dev/wallets@2.4.18
|
||||
- @thirdweb-dev/sdk@4.0.43
|
||||
- @thirdweb-dev/auth@4.1.40
|
||||
|
||||
## 0.4.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`c894270`](https://github.com/thirdweb-dev/js/commit/c894270401850575d1a4df73e16198177b46477a), [`332a145`](https://github.com/thirdweb-dev/js/commit/332a14552bf95e13e5220b1bd73414f000088568), [`c6b025e`](https://github.com/thirdweb-dev/js/commit/c6b025e84451341f6f48c0a7c4b5f06b8e49d792)]:
|
||||
- @thirdweb-dev/wallets@2.4.17
|
||||
- @thirdweb-dev/sdk@4.0.42
|
||||
- @thirdweb-dev/auth@4.1.39
|
||||
|
||||
## 0.4.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`862905e`](https://github.com/thirdweb-dev/js/commit/862905e161a091c15eb9b054cfcca0e5d2879fd6), [`588897d`](https://github.com/thirdweb-dev/js/commit/588897d1b04e6c63da13639aeb47ca701308e1b2), [`862905e`](https://github.com/thirdweb-dev/js/commit/862905e161a091c15eb9b054cfcca0e5d2879fd6)]:
|
||||
- @thirdweb-dev/auth@4.1.38
|
||||
- @thirdweb-dev/chains@0.1.78
|
||||
- @thirdweb-dev/wallets@2.4.16
|
||||
- @thirdweb-dev/sdk@4.0.41
|
||||
|
||||
## 0.4.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2415](https://github.com/thirdweb-dev/js/pull/2415) [`a3f6878`](https://github.com/thirdweb-dev/js/commit/a3f6878649345ea7b647d085d5d7d536af82948f) Thanks [@0xFirekeeper](https://github.com/0xFirekeeper)! - [Unity] Remove unnecessary logs, add getEmail check
|
||||
|
||||
- Updated dependencies [[`74a92dc`](https://github.com/thirdweb-dev/js/commit/74a92dcb7dc4be7d03bcb8b7211e87016f52a81f), [`047fbe2`](https://github.com/thirdweb-dev/js/commit/047fbe2918808cbc8fded90104458b6e38d1207d)]:
|
||||
- @thirdweb-dev/wallets@2.4.15
|
||||
- @thirdweb-dev/chains@0.1.77
|
||||
- @thirdweb-dev/auth@4.1.37
|
||||
- @thirdweb-dev/sdk@4.0.40
|
||||
|
||||
## 0.4.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/unity-js-bridge",
|
||||
"version": "0.4.2",
|
||||
"version": "0.4.6",
|
||||
"main": "dist/thirdweb-unity-bridge.js",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/unity-js-bridge",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -144,11 +144,10 @@ class ThirdwebBridge implements TWBridge {
|
||||
}
|
||||
(globalThis as any).X_SDK_NAME = "UnitySDK_WebGL";
|
||||
(globalThis as any).X_SDK_PLATFORM = "unity";
|
||||
(globalThis as any).X_SDK_VERSION = "4.7.5";
|
||||
(globalThis as any).X_SDK_VERSION = "4.7.7";
|
||||
(globalThis as any).X_SDK_OS = browser?.os ?? "unknown";
|
||||
}
|
||||
this.initializedChain = chain;
|
||||
console.debug("thirdwebSDK initialization:", chain, options);
|
||||
const sdkOptions = JSON.parse(options);
|
||||
let supportedChains;
|
||||
if (sdkOptions?.supportedChains) {
|
||||
@@ -167,7 +166,7 @@ class ThirdwebBridge implements TWBridge {
|
||||
supportedChains = defaultChains;
|
||||
}
|
||||
} else {
|
||||
console.debug("no supportedChains passed, using default chains");
|
||||
console.warn("no supportedChains passed, using default chains");
|
||||
supportedChains = defaultChains;
|
||||
}
|
||||
sdkOptions.supportedChains = supportedChains;
|
||||
@@ -446,7 +445,7 @@ class ThirdwebBridge implements TWBridge {
|
||||
return arg;
|
||||
}
|
||||
});
|
||||
console.debug("thirdwebSDK call:", route, parsedArgs);
|
||||
// console.debug("thirdwebSDK call:", route, parsedArgs);
|
||||
|
||||
// wallet call
|
||||
if (addrOrSDK.startsWith("sdk")) {
|
||||
@@ -601,14 +600,6 @@ class ThirdwebBridge implements TWBridge {
|
||||
}
|
||||
});
|
||||
|
||||
console.debug(
|
||||
"thirdwebSDK invoke listener:",
|
||||
taskId,
|
||||
route,
|
||||
parsedFnArgs,
|
||||
action,
|
||||
);
|
||||
|
||||
// contract call
|
||||
if (addrOrSDK.startsWith("0x")) {
|
||||
let typeOrAbi: string | ContractInterface | undefined;
|
||||
@@ -673,14 +664,6 @@ class ThirdwebBridge implements TWBridge {
|
||||
personalWallet: AbstractClientWallet,
|
||||
accountAddress?: string,
|
||||
) {
|
||||
if (accountAddress) {
|
||||
console.debug(
|
||||
"Initializing smart wallet with account address override:",
|
||||
accountAddress,
|
||||
);
|
||||
}
|
||||
const personalWalletAddress = await personalWallet.getAddress();
|
||||
console.debug("Personal wallet address:", personalWalletAddress);
|
||||
await sw.connect({
|
||||
personalWallet,
|
||||
accountAddress: accountAddress,
|
||||
@@ -808,6 +791,9 @@ class ThirdwebBridge implements TWBridge {
|
||||
}
|
||||
|
||||
public async getEmail() {
|
||||
if (!this.activeWallet) {
|
||||
throw new Error("No wallet connected");
|
||||
}
|
||||
const embeddedWallet = this.walletMap.get(
|
||||
walletIds.embeddedWallet,
|
||||
) as EmbeddedWallet;
|
||||
@@ -825,9 +811,6 @@ class ThirdwebBridge implements TWBridge {
|
||||
const res = await signer?.getAddress();
|
||||
return JSON.stringify({ result: res }, bigNumberReplacer);
|
||||
} catch {
|
||||
console.debug(
|
||||
"Could not find a smart wallet, defaulting to normal signer",
|
||||
);
|
||||
const signer = await this.activeWallet.getSigner();
|
||||
const res = await signer.getAddress();
|
||||
return JSON.stringify({ result: res }, bigNumberReplacer);
|
||||
|
||||
@@ -1,5 +1,45 @@
|
||||
# @thirdweb-dev/wallets
|
||||
|
||||
## 2.4.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2443](https://github.com/thirdweb-dev/js/pull/2443) [`cabfc29`](https://github.com/thirdweb-dev/js/commit/cabfc29119f25a78010f59f766bdcb8c392afa2d) Thanks [@0xFirekeeper](https://github.com/0xFirekeeper)! - [Smart Wallet] Use bundler eth_getUserOperationReceipt instead of rpc eth_getLogs, remove polygon gas station error logs
|
||||
|
||||
- Updated dependencies [[`cabfc29`](https://github.com/thirdweb-dev/js/commit/cabfc29119f25a78010f59f766bdcb8c392afa2d), [`173777a`](https://github.com/thirdweb-dev/js/commit/173777ade4ea59cde1c6f25a4654d48b277be9ad)]:
|
||||
- @thirdweb-dev/sdk@4.0.43
|
||||
|
||||
## 2.4.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2440](https://github.com/thirdweb-dev/js/pull/2440) [`c894270`](https://github.com/thirdweb-dev/js/commit/c894270401850575d1a4df73e16198177b46477a) Thanks [@0xFirekeeper](https://github.com/0xFirekeeper)! - [Smart Wallet] Update Account Core ABI
|
||||
|
||||
- [#2439](https://github.com/thirdweb-dev/js/pull/2439) [`332a145`](https://github.com/thirdweb-dev/js/commit/332a14552bf95e13e5220b1bd73414f000088568) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Make accountInfo/factoryInfo internal props optional in SmartWalletConfig
|
||||
|
||||
- Updated dependencies [[`c6b025e`](https://github.com/thirdweb-dev/js/commit/c6b025e84451341f6f48c0a7c4b5f06b8e49d792)]:
|
||||
- @thirdweb-dev/sdk@4.0.42
|
||||
|
||||
## 2.4.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2417](https://github.com/thirdweb-dev/js/pull/2417) [`862905e`](https://github.com/thirdweb-dev/js/commit/862905e161a091c15eb9b054cfcca0e5d2879fd6) Thanks [@jnsdls](https://github.com/jnsdls)! - fix signature verification via smart-wallet
|
||||
|
||||
- Updated dependencies [[`588897d`](https://github.com/thirdweb-dev/js/commit/588897d1b04e6c63da13639aeb47ca701308e1b2)]:
|
||||
- @thirdweb-dev/chains@0.1.78
|
||||
- @thirdweb-dev/sdk@4.0.41
|
||||
|
||||
## 2.4.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2414](https://github.com/thirdweb-dev/js/pull/2414) [`74a92dc`](https://github.com/thirdweb-dev/js/commit/74a92dcb7dc4be7d03bcb8b7211e87016f52a81f) Thanks [@jnsdls](https://github.com/jnsdls)! - properly pass through clientId and secretKey variables to verifySignature functions
|
||||
|
||||
- Updated dependencies [[`047fbe2`](https://github.com/thirdweb-dev/js/commit/047fbe2918808cbc8fded90104458b6e38d1207d)]:
|
||||
- @thirdweb-dev/chains@0.1.77
|
||||
- @thirdweb-dev/sdk@4.0.40
|
||||
|
||||
## 2.4.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/wallets",
|
||||
"version": "2.4.14",
|
||||
"version": "2.4.18",
|
||||
"main": "dist/thirdweb-dev-wallets.cjs.js",
|
||||
"module": "dist/thirdweb-dev-wallets.esm.js",
|
||||
"browser": {
|
||||
|
||||
@@ -4,8 +4,8 @@ import { ERC4337EthersProvider } from "./lib/erc4337-provider";
|
||||
import { getVerifyingPaymaster } from "./lib/paymaster";
|
||||
import { create4337Provider } from "./lib/provider-utils";
|
||||
import {
|
||||
AccountContractInfo,
|
||||
FactoryContractInfo,
|
||||
AccountContractInfoInternal,
|
||||
FactoryContractInfoInternal,
|
||||
ProviderConfig,
|
||||
SmartWalletConfig,
|
||||
SmartWalletConnectionArgs,
|
||||
@@ -71,8 +71,22 @@ export class SmartWalletConnector extends Connector<SmartWalletConnectionArgs> {
|
||||
gasless: config.gasless,
|
||||
factoryAddress: config.factoryAddress,
|
||||
accountAddress: params.accountAddress,
|
||||
factoryInfo: config.factoryInfo || this.defaultFactoryInfo(),
|
||||
accountInfo: config.accountInfo || this.defaultAccountInfo(),
|
||||
factoryInfo: {
|
||||
createAccount:
|
||||
config.factoryInfo?.createAccount ||
|
||||
this.defaultFactoryInfo().createAccount,
|
||||
getAccountAddress:
|
||||
config.factoryInfo?.getAccountAddress ||
|
||||
this.defaultFactoryInfo().getAccountAddress,
|
||||
abi: config.factoryInfo?.abi,
|
||||
},
|
||||
accountInfo: {
|
||||
execute:
|
||||
config.accountInfo?.execute || this.defaultAccountInfo().execute,
|
||||
getNonce:
|
||||
config.accountInfo?.getNonce || this.defaultAccountInfo().getNonce,
|
||||
abi: config.accountInfo?.abi,
|
||||
},
|
||||
clientId: config.clientId,
|
||||
secretKey: config.secretKey,
|
||||
erc20PaymasterAddress: config.erc20PaymasterAddress,
|
||||
@@ -541,7 +555,7 @@ export class SmartWalletConnector extends Connector<SmartWalletConnectionArgs> {
|
||||
return sdk.getContract(this.config.factoryAddress);
|
||||
}
|
||||
|
||||
protected defaultFactoryInfo(): FactoryContractInfo {
|
||||
protected defaultFactoryInfo(): FactoryContractInfoInternal {
|
||||
return {
|
||||
createAccount: async (factory, owner) => {
|
||||
return factory.prepare("createAccount", [
|
||||
@@ -558,7 +572,7 @@ export class SmartWalletConnector extends Connector<SmartWalletConnectionArgs> {
|
||||
};
|
||||
}
|
||||
|
||||
protected defaultAccountInfo(): AccountContractInfo {
|
||||
protected defaultAccountInfo(): AccountContractInfoInternal {
|
||||
return {
|
||||
execute: async (account, target, value, data) => {
|
||||
return account.prepare("execute", [target, value, data]);
|
||||
|
||||
@@ -342,28 +342,31 @@ export abstract class BaseAccountAPI {
|
||||
}
|
||||
|
||||
/**
|
||||
* get the transaction that has this userOpHash mined, or null if not found
|
||||
* get the transaction that has this userOpHash mined, or throws if not found
|
||||
* @param userOpHash - returned by sendUserOpToBundler (or by getUserOpHash..)
|
||||
* @param timeout - stop waiting after this timeout
|
||||
* @param interval - time to wait between polls.
|
||||
* @returns The transactionHash this userOp was mined, or null if not found.
|
||||
* @returns The transaction receipt, or an error if timed out.
|
||||
*/
|
||||
async getUserOpReceipt(
|
||||
httpRpcClient: HttpRpcClient,
|
||||
userOpHash: string,
|
||||
timeout = 30000,
|
||||
interval = 2000,
|
||||
): Promise<string | null> {
|
||||
timeout = 120000,
|
||||
interval = 1000,
|
||||
): Promise<providers.TransactionReceipt> {
|
||||
const endtime = Date.now() + timeout;
|
||||
while (Date.now() < endtime) {
|
||||
const events = await this.entryPointView.queryFilter(
|
||||
this.entryPointView.filters.UserOperationEvent(userOpHash),
|
||||
);
|
||||
if (events[0]) {
|
||||
return events[0].transactionHash;
|
||||
const userOpReceipt =
|
||||
await httpRpcClient.getUserOperationReceipt(userOpHash);
|
||||
if (userOpReceipt) {
|
||||
// avoid desync with current provider state
|
||||
return await this.provider.waitForTransaction(
|
||||
userOpReceipt.receipt.transactionHash,
|
||||
);
|
||||
}
|
||||
await new Promise((resolve) => setTimeout(resolve, interval));
|
||||
}
|
||||
return null;
|
||||
throw new Error("Timeout waiting for userOp to be mined");
|
||||
}
|
||||
|
||||
private unwrapBundlerError(error: any) {
|
||||
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
import { Contract, providers, utils } from "ethers";
|
||||
import { setAnalyticsHeaders } from "../../../utils/headers";
|
||||
import { isTwUrl } from "../../../utils/url";
|
||||
import { chainIdToThirdwebRpc } from "../../../wallets/abstract";
|
||||
|
||||
const EIP1271_ABI = [
|
||||
"function isValidSignature(bytes32 _hash, bytes _signature) public view returns (bytes4)",
|
||||
];
|
||||
const EIP1271_MAGICVALUE = "0x1626ba7e";
|
||||
|
||||
export async function checkContractWalletSignature(
|
||||
message: string,
|
||||
signature: string,
|
||||
address: string,
|
||||
chainId: number,
|
||||
clientId?: string,
|
||||
secretKey?: string,
|
||||
): Promise<boolean> {
|
||||
// TODO: remove below `skipFetchSetup` logic when ethers.js v6 support arrives
|
||||
let _skipFetchSetup = false;
|
||||
if (
|
||||
typeof globalThis !== "undefined" &&
|
||||
"TW_SKIP_FETCH_SETUP" in globalThis &&
|
||||
typeof (globalThis as any).TW_SKIP_FETCH_SETUP === "boolean"
|
||||
) {
|
||||
_skipFetchSetup = (globalThis as any).TW_SKIP_FETCH_SETUP as boolean;
|
||||
}
|
||||
|
||||
const rpcUrl = chainIdToThirdwebRpc(chainId, clientId);
|
||||
|
||||
const headers: Record<string, string> = {};
|
||||
|
||||
if (isTwUrl(rpcUrl)) {
|
||||
const bundleId =
|
||||
typeof globalThis !== "undefined" && "APP_BUNDLE_ID" in globalThis
|
||||
? ((globalThis as any).APP_BUNDLE_ID as string)
|
||||
: undefined;
|
||||
|
||||
if (secretKey) {
|
||||
headers["x-secret-key"] = secretKey;
|
||||
} else if (clientId) {
|
||||
headers["x-client-id"] = clientId;
|
||||
|
||||
if (bundleId) {
|
||||
headers["x-bundle-id"] = bundleId;
|
||||
}
|
||||
}
|
||||
|
||||
// Dashboard token
|
||||
if (
|
||||
typeof globalThis !== "undefined" &&
|
||||
"TW_AUTH_TOKEN" in globalThis &&
|
||||
typeof (globalThis as any).TW_AUTH_TOKEN === "string"
|
||||
) {
|
||||
headers["authorization"] = `Bearer ${
|
||||
(globalThis as any).TW_AUTH_TOKEN as string
|
||||
}`;
|
||||
}
|
||||
|
||||
// CLI token
|
||||
if (
|
||||
typeof globalThis !== "undefined" &&
|
||||
"TW_CLI_AUTH_TOKEN" in globalThis &&
|
||||
typeof (globalThis as any).TW_CLI_AUTH_TOKEN === "string"
|
||||
) {
|
||||
headers["authorization"] = `Bearer ${
|
||||
(globalThis as any).TW_CLI_AUTH_TOKEN as string
|
||||
}`;
|
||||
headers["x-authorize-wallet"] = "true";
|
||||
}
|
||||
|
||||
setAnalyticsHeaders(headers);
|
||||
}
|
||||
|
||||
const provider = new providers.StaticJsonRpcProvider(
|
||||
{
|
||||
url: chainIdToThirdwebRpc(chainId),
|
||||
skipFetchSetup: _skipFetchSetup,
|
||||
headers,
|
||||
},
|
||||
chainId,
|
||||
);
|
||||
const walletContract = new Contract(address, EIP1271_ABI, provider);
|
||||
try {
|
||||
const res = await walletContract.isValidSignature(
|
||||
utils.hashMessage(message),
|
||||
signature,
|
||||
);
|
||||
return res === EIP1271_MAGICVALUE;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -110,17 +110,6 @@ export class ERC4337EthersProvider extends providers.BaseProvider {
|
||||
): Promise<providers.TransactionResponse> {
|
||||
const userOp = await utils.resolveProperties(userOp1);
|
||||
const userOpHash = await this.smartAccountAPI.getUserOpHash(userOp);
|
||||
const waitForUserOp = async (): Promise<providers.TransactionReceipt> =>
|
||||
await new Promise((resolve, reject) => {
|
||||
new UserOperationEventListener(
|
||||
resolve,
|
||||
reject,
|
||||
this.entryPoint,
|
||||
userOp.sender,
|
||||
userOpHash,
|
||||
userOp.nonce,
|
||||
).start();
|
||||
});
|
||||
return {
|
||||
hash: userOpHash,
|
||||
confirmations: 0,
|
||||
@@ -134,7 +123,7 @@ export class ERC4337EthersProvider extends providers.BaseProvider {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
confirmations?: number,
|
||||
): Promise<providers.TransactionReceipt> => {
|
||||
const transactionReceipt = await waitForUserOp();
|
||||
const transactionReceipt = await this.smartAccountAPI.getUserOpReceipt(this.httpRpcClient, userOpHash)
|
||||
if (userOp.initCode.length !== 0) {
|
||||
// checking if the wallet has been deployed by the transaction; it must be if we are here
|
||||
await this.smartAccountAPI.checkAccountPhantom();
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Contract, ethers, providers, utils } from "ethers";
|
||||
|
||||
import { Bytes, Signer } from "ethers";
|
||||
import { BaseAccountAPI } from "./base-api";
|
||||
import type { ERC4337EthersProvider } from "./erc4337-provider";
|
||||
@@ -7,10 +6,10 @@ import { HttpRpcClient } from "./http-rpc-client";
|
||||
import { hexlifyUserOp, randomNonce } from "./utils";
|
||||
import { ProviderConfig, UserOpOptions } from "../types";
|
||||
import { signTypedDataInternal } from "@thirdweb-dev/sdk";
|
||||
import {
|
||||
checkContractWalletSignature,
|
||||
chainIdToThirdwebRpc,
|
||||
} from "../../../wallets/abstract";
|
||||
import { chainIdToThirdwebRpc } from "../../../wallets/abstract";
|
||||
import { setAnalyticsHeaders } from "../../../utils/headers";
|
||||
import { isTwUrl } from "../../../utils/url";
|
||||
import { checkContractWalletSignature } from "./check-contract-wallet-signature";
|
||||
|
||||
export class ERC4337EthersSigner extends Signer {
|
||||
config: ProviderConfig;
|
||||
@@ -103,7 +102,7 @@ export class ERC4337EthersSigner extends Signer {
|
||||
errorIn.reason;
|
||||
|
||||
if (failedOpMessage?.includes("FailedOp")) {
|
||||
let paymasterInfo: string = "";
|
||||
let paymasterInfo = "";
|
||||
// TODO: better error extraction methods will be needed
|
||||
const matched = failedOpMessage.match(/FailedOp\((.*)\)/);
|
||||
|
||||
@@ -179,9 +178,58 @@ Code: ${errorCode}`;
|
||||
let factorySupports712: boolean;
|
||||
let signature: string;
|
||||
|
||||
const rpcUrl = chainIdToThirdwebRpc(chainId, this.config.clientId);
|
||||
|
||||
const headers: Record<string, string> = {};
|
||||
|
||||
if (isTwUrl(rpcUrl)) {
|
||||
const bundleId =
|
||||
typeof globalThis !== "undefined" && "APP_BUNDLE_ID" in globalThis
|
||||
? ((globalThis as any).APP_BUNDLE_ID as string)
|
||||
: undefined;
|
||||
|
||||
if (this.config.secretKey) {
|
||||
headers["x-secret-key"] = this.config.secretKey;
|
||||
} else if (this.config.clientId) {
|
||||
headers["x-client-id"] = this.config.clientId;
|
||||
|
||||
if (bundleId) {
|
||||
headers["x-bundle-id"] = bundleId;
|
||||
}
|
||||
}
|
||||
|
||||
// Dashboard token
|
||||
if (
|
||||
typeof globalThis !== "undefined" &&
|
||||
"TW_AUTH_TOKEN" in globalThis &&
|
||||
typeof (globalThis as any).TW_AUTH_TOKEN === "string"
|
||||
) {
|
||||
headers["authorization"] = `Bearer ${
|
||||
(globalThis as any).TW_AUTH_TOKEN as string
|
||||
}`;
|
||||
}
|
||||
|
||||
// CLI token
|
||||
if (
|
||||
typeof globalThis !== "undefined" &&
|
||||
"TW_CLI_AUTH_TOKEN" in globalThis &&
|
||||
typeof (globalThis as any).TW_CLI_AUTH_TOKEN === "string"
|
||||
) {
|
||||
headers["authorization"] = `Bearer ${
|
||||
(globalThis as any).TW_CLI_AUTH_TOKEN as string
|
||||
}`;
|
||||
headers["x-authorize-wallet"] = "true";
|
||||
}
|
||||
|
||||
setAnalyticsHeaders(headers);
|
||||
}
|
||||
|
||||
try {
|
||||
const provider = new providers.JsonRpcProvider(
|
||||
chainIdToThirdwebRpc(chainId, this.config.clientId),
|
||||
const provider = new providers.StaticJsonRpcProvider(
|
||||
{
|
||||
url: chainIdToThirdwebRpc(chainId, this.config.clientId),
|
||||
headers,
|
||||
},
|
||||
chainId,
|
||||
);
|
||||
const walletContract = new Contract(
|
||||
@@ -222,6 +270,8 @@ Code: ${errorCode}`;
|
||||
signature,
|
||||
address,
|
||||
chainId,
|
||||
this.config.clientId,
|
||||
this.config.secretKey,
|
||||
);
|
||||
|
||||
if (isValid) {
|
||||
|
||||
@@ -69,7 +69,7 @@ export class HttpRpcClient {
|
||||
setAnalyticsHeaders(headers);
|
||||
}
|
||||
|
||||
this.userOpJsonRpcProvider = new providers.JsonRpcProvider(
|
||||
this.userOpJsonRpcProvider = new providers.StaticJsonRpcProvider(
|
||||
{
|
||||
url: this.bundlerUrl,
|
||||
headers,
|
||||
@@ -134,6 +134,14 @@ export class HttpRpcClient {
|
||||
);
|
||||
}
|
||||
|
||||
async getUserOperationReceipt(userOpHash: string): Promise<any> {
|
||||
await this.initializing;
|
||||
return await this.userOpJsonRpcProvider.send(
|
||||
"eth_getUserOperationReceipt",
|
||||
[userOpHash],
|
||||
);
|
||||
}
|
||||
|
||||
private async printUserOperation(
|
||||
method: string,
|
||||
[userOp1, entryPointAddress]: [UserOperationStruct, string],
|
||||
|
||||
@@ -54,11 +54,14 @@ export type ContractInfoInput = {
|
||||
};
|
||||
|
||||
export type ContractInfo = {
|
||||
factoryInfo: FactoryContractInfo;
|
||||
accountInfo: AccountContractInfo;
|
||||
factoryInfo: FactoryContractInfoInternal;
|
||||
accountInfo: AccountContractInfoInternal;
|
||||
};
|
||||
|
||||
export type AccountContractInfo = {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export type AccountContractInfoInternal = {
|
||||
abi?: ContractInterface;
|
||||
getNonce: (account: SmartContract) => Promise<BigNumber>;
|
||||
execute: (
|
||||
@@ -69,7 +72,10 @@ export type AccountContractInfo = {
|
||||
) => Promise<Transaction>;
|
||||
};
|
||||
|
||||
export type FactoryContractInfo = {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export type FactoryContractInfoInternal = {
|
||||
abi?: ContractInterface;
|
||||
createAccount: (
|
||||
factory: SmartContract,
|
||||
@@ -78,6 +84,29 @@ export type FactoryContractInfo = {
|
||||
getAccountAddress: (factory: SmartContract, owner: string) => Promise<string>;
|
||||
};
|
||||
|
||||
export type AccountContractInfo = {
|
||||
abi?: ContractInterface;
|
||||
getNonce?: (account: SmartContract) => Promise<BigNumber>;
|
||||
execute?: (
|
||||
account: SmartContract,
|
||||
target: string,
|
||||
value: BigNumberish,
|
||||
data: string,
|
||||
) => Promise<Transaction>;
|
||||
};
|
||||
|
||||
export type FactoryContractInfo = {
|
||||
abi?: ContractInterface;
|
||||
createAccount?: (
|
||||
factory: SmartContract,
|
||||
owner: string,
|
||||
) => Promise<Transaction>;
|
||||
getAccountAddress?: (
|
||||
factory: SmartContract,
|
||||
owner: string,
|
||||
) => Promise<string>;
|
||||
};
|
||||
|
||||
export type PaymasterResult = {
|
||||
paymasterAndData: string;
|
||||
preVerificationGas?: BigNumber;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { TokenBoundSmartWalletConfig } from "./types";
|
||||
import { ethers } from "ethers";
|
||||
import { SmartWalletConnector } from "../smart-wallet";
|
||||
import { FactoryContractInfo } from "../smart-wallet/types";
|
||||
import { FactoryContractInfoInternal } from "../smart-wallet/types";
|
||||
import { ERC6551_REGISTRY } from "../smart-wallet/lib/constants";
|
||||
|
||||
export class TokenBoundSmartWalletConnector extends SmartWalletConnector {
|
||||
@@ -16,7 +16,7 @@ export class TokenBoundSmartWalletConnector extends SmartWalletConnector {
|
||||
// TODO default account implementation address
|
||||
}
|
||||
|
||||
protected defaultFactoryInfo(): FactoryContractInfo {
|
||||
protected defaultFactoryInfo(): FactoryContractInfoInternal {
|
||||
return {
|
||||
createAccount: async (factory) => {
|
||||
return factory.prepare("createAccount", [
|
||||
|
||||
@@ -20,8 +20,8 @@ export type {
|
||||
AbstractWallet,
|
||||
WalletData,
|
||||
WalletEvents,
|
||||
checkContractWalletSignature,
|
||||
} from "./wallets/abstract";
|
||||
export { checkContractWalletSignature } from "./connectors/smart-wallet/lib/check-contract-wallet-signature";
|
||||
|
||||
export * from "./wallets/paper-wallet";
|
||||
// just the types
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { EVMWallet } from "../interfaces";
|
||||
import type { Signer } from "ethers";
|
||||
import { providers, Contract, utils, Bytes, BigNumber } from "ethers";
|
||||
import { utils, Bytes, BigNumber } from "ethers";
|
||||
import EventEmitter from "eventemitter3";
|
||||
import { Ecosystem, GenericAuthWallet } from "../../core/interfaces/auth";
|
||||
import {
|
||||
@@ -39,43 +39,6 @@ export interface WalletEvents {
|
||||
request(): void;
|
||||
}
|
||||
|
||||
const EIP1271_ABI = [
|
||||
"function isValidSignature(bytes32 _hash, bytes _signature) public view returns (bytes4)",
|
||||
];
|
||||
const EIP1271_MAGICVALUE = "0x1626ba7e";
|
||||
|
||||
export async function checkContractWalletSignature(
|
||||
message: string,
|
||||
signature: string,
|
||||
address: string,
|
||||
chainId: number,
|
||||
): Promise<boolean> {
|
||||
// TODO: remove below `skipFetchSetup` logic when ethers.js v6 support arrives
|
||||
let _skipFetchSetup = false;
|
||||
if (
|
||||
typeof globalThis !== "undefined" &&
|
||||
"TW_SKIP_FETCH_SETUP" in globalThis &&
|
||||
typeof (globalThis as any).TW_SKIP_FETCH_SETUP === "boolean"
|
||||
) {
|
||||
_skipFetchSetup = (globalThis as any).TW_SKIP_FETCH_SETUP as boolean;
|
||||
}
|
||||
|
||||
//TODO: A provider should be passed in instead of creating a new one here.
|
||||
const provider = new providers.JsonRpcProvider({
|
||||
url: chainIdToThirdwebRpc(chainId),
|
||||
skipFetchSetup: _skipFetchSetup,
|
||||
});
|
||||
const walletContract = new Contract(address, EIP1271_ABI, provider);
|
||||
try {
|
||||
const res = await walletContract.isValidSignature(
|
||||
utils.hashMessage(message),
|
||||
signature,
|
||||
);
|
||||
return res === EIP1271_MAGICVALUE;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* The base class for any wallet in the Wallet SDK, including backend wallets. It contains the functionality common to all wallets.
|
||||
*
|
||||
@@ -200,7 +163,8 @@ export abstract class AbstractWallet
|
||||
message: string,
|
||||
signature: string,
|
||||
address: string,
|
||||
chainId?: number,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
_chainId?: number,
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
const messageHash = utils.hashMessage(message);
|
||||
@@ -217,21 +181,6 @@ export abstract class AbstractWallet
|
||||
// no-op
|
||||
}
|
||||
|
||||
// Check if the address is a smart contract wallet
|
||||
if (chainId !== undefined) {
|
||||
try {
|
||||
const isValid = await checkContractWalletSignature(
|
||||
message,
|
||||
signature,
|
||||
address,
|
||||
chainId || 1,
|
||||
);
|
||||
return isValid;
|
||||
} catch {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
import { walletIds } from "../constants/walletIds";
|
||||
import { getValidChainRPCs } from "@thirdweb-dev/chains";
|
||||
import { providers, utils } from "ethers";
|
||||
import { checkContractWalletSignature } from "../connectors/smart-wallet/lib/check-contract-wallet-signature";
|
||||
|
||||
// export types and utils for convenience
|
||||
export type * from "../connectors/smart-wallet/types";
|
||||
@@ -663,6 +664,44 @@ export class SmartWallet extends AbstractClientWallet<
|
||||
return connector.getFactoryContract();
|
||||
}
|
||||
|
||||
override async verifySignature(
|
||||
message: string,
|
||||
signature: string,
|
||||
address: string,
|
||||
chainId: number,
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
const messageHash = utils.hashMessage(message);
|
||||
const messageHashBytes = utils.arrayify(messageHash);
|
||||
const recoveredAddress = utils.recoverAddress(
|
||||
messageHashBytes,
|
||||
signature,
|
||||
);
|
||||
|
||||
if (recoveredAddress === address) {
|
||||
return true;
|
||||
}
|
||||
} catch {
|
||||
// no-op
|
||||
}
|
||||
// Check if the address is a smart contract wallet
|
||||
if (chainId !== undefined) {
|
||||
try {
|
||||
return await checkContractWalletSignature(
|
||||
message,
|
||||
signature,
|
||||
address,
|
||||
chainId || 1,
|
||||
this.options?.clientId,
|
||||
this.options?.secretKey,
|
||||
);
|
||||
} catch {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
autoConnect(params: ConnectParams<SmartWalletConnectionArgs>) {
|
||||
return this.connect(params);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { ThirdwebSDK, SmartContract } from "@thirdweb-dev/sdk";
|
||||
import { BigNumber, ethers } from "ethers";
|
||||
|
||||
require("dotenv-mono").load();
|
||||
|
||||
jest.setTimeout(240_000);
|
||||
|
||||
let smartWallet: SmartWallet;
|
||||
@@ -33,7 +34,9 @@ beforeAll(async () => {
|
||||
erc20TokenAddress: erc20TokenAddress,
|
||||
});
|
||||
smartWalletAddress = await smartWallet.connect({ personalWallet });
|
||||
sdk = await ThirdwebSDK.fromWallet(smartWallet, chain);
|
||||
sdk = await ThirdwebSDK.fromWallet(smartWallet, chain, {
|
||||
secretKey: process.env.TW_SECRET_KEY,
|
||||
});
|
||||
contract = await sdk.getContract(
|
||||
"0xF7235993A1BB401620e7c384D541e78D18081090", // using same token for payment and claim
|
||||
);
|
||||
|
||||
@@ -3,9 +3,10 @@ import { SmartWallet } from "../src/evm/wallets/smart-wallet";
|
||||
import { LocalWallet } from "../src/evm/wallets/local-wallet";
|
||||
import { Mumbai } from "@thirdweb-dev/chains";
|
||||
import { ThirdwebSDK, SmartContract } from "@thirdweb-dev/sdk";
|
||||
import { checkContractWalletSignature } from "../src/evm/wallets/abstract";
|
||||
import { checkContractWalletSignature } from "../src/evm/connectors/smart-wallet/lib/check-contract-wallet-signature";
|
||||
|
||||
require("dotenv-mono").load();
|
||||
|
||||
jest.setTimeout(240_000);
|
||||
|
||||
let smartWallet: SmartWallet;
|
||||
@@ -15,6 +16,7 @@ let contract: SmartContract;
|
||||
const factoryAddress = "0x13947435c2fe6BE51ED82F6f59C38617a323dB9B"; // pre 712
|
||||
const factoryAddressV2 = "0xC64d04AedecA895b3F20DC6866b4b532e0b22634"; // post 712
|
||||
const chain = Mumbai;
|
||||
const SECRET_KEY = process.env.TW_SECRET_KEY;
|
||||
|
||||
const describeIf = (condition: boolean) =>
|
||||
condition ? describe : describe.skip;
|
||||
@@ -26,16 +28,18 @@ beforeAll(async () => {
|
||||
chain,
|
||||
factoryAddress,
|
||||
gasless: true,
|
||||
secretKey: process.env.TW_SECRET_KEY,
|
||||
secretKey: SECRET_KEY,
|
||||
});
|
||||
smartWalletAddress = await smartWallet.connect({ personalWallet });
|
||||
const sdk = await ThirdwebSDK.fromWallet(smartWallet, chain);
|
||||
const sdk = await ThirdwebSDK.fromWallet(smartWallet, chain, {
|
||||
secretKey: SECRET_KEY,
|
||||
});
|
||||
contract = await sdk.getContract(
|
||||
"0xD170A53dADb19f62C78AB9982236857B71dbc83A", // mumbai edition drop
|
||||
);
|
||||
});
|
||||
|
||||
describeIf(!!process.env.TW_SECRET_KEY)("SmartWallet core tests", () => {
|
||||
describeIf(!!SECRET_KEY)("SmartWallet core tests", () => {
|
||||
it("can connect", async () => {
|
||||
expect(smartWalletAddress).toHaveLength(42);
|
||||
});
|
||||
@@ -52,7 +56,7 @@ describeIf(!!process.env.TW_SECRET_KEY)("SmartWallet core tests", () => {
|
||||
it("can estimate a tx", async () => {
|
||||
const preparedTx = await contract.erc1155.claim.prepare(0, 1);
|
||||
const estimates = await smartWallet.estimate(preparedTx);
|
||||
expect(estimates.wei.toNumber()).toBeGreaterThan(0);
|
||||
expect(estimates.wei.toString()).not.toBe("0");
|
||||
});
|
||||
|
||||
it("can execute a tx", async () => {
|
||||
@@ -114,6 +118,8 @@ describeIf(!!process.env.TW_SECRET_KEY)("SmartWallet core tests", () => {
|
||||
sig,
|
||||
smartWalletAddress,
|
||||
chain.chainId,
|
||||
undefined,
|
||||
SECRET_KEY,
|
||||
);
|
||||
expect(isValidV2).toEqual(true);
|
||||
});
|
||||
@@ -140,6 +146,8 @@ describeIf(!!process.env.TW_SECRET_KEY)("SmartWallet core tests", () => {
|
||||
sig,
|
||||
smartWalletAddress,
|
||||
chain.chainId,
|
||||
undefined,
|
||||
SECRET_KEY,
|
||||
);
|
||||
expect(isValidV2).toEqual(true);
|
||||
});
|
||||
|
||||
Binary file not shown.
Generated
+160
-53
@@ -1090,6 +1090,9 @@ importers:
|
||||
|
||||
packages/sdk:
|
||||
dependencies:
|
||||
'@eth-optimism/sdk':
|
||||
specifier: 3.2.2
|
||||
version: 3.2.2([email protected])
|
||||
'@thirdweb-dev/chains':
|
||||
specifier: workspace:*
|
||||
version: link:../chains
|
||||
@@ -5089,7 +5092,7 @@ packages:
|
||||
'@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1
|
||||
eslint: 8.56.0
|
||||
eslint-visitor-keys: 2.1.0
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
|
||||
/@babel/[email protected]:
|
||||
resolution: {integrity: sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==}
|
||||
@@ -5139,7 +5142,7 @@ packages:
|
||||
'@babel/helper-validator-option': 7.23.5
|
||||
browserslist: 4.22.2
|
||||
lru-cache: 5.1.1
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
|
||||
/@babel/[email protected](@babel/[email protected]):
|
||||
resolution: {integrity: sha512-xCoqR/8+BoNnXOY7RVSgv6X+o7pmT5q1d+gGcRlXYkI+9B31glE4jeejhKVpA04O1AtzOt7OSQ6VYKP5FcRl9g==}
|
||||
@@ -5156,7 +5159,7 @@ packages:
|
||||
'@babel/helper-replace-supers': 7.22.20(@babel/[email protected])
|
||||
'@babel/helper-skip-transparent-expression-wrappers': 7.22.5
|
||||
'@babel/helper-split-export-declaration': 7.22.6
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
|
||||
/@babel/[email protected](@babel/[email protected]):
|
||||
resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==}
|
||||
@@ -5167,7 +5170,7 @@ packages:
|
||||
'@babel/core': 7.23.7
|
||||
'@babel/helper-annotate-as-pure': 7.22.5
|
||||
regexpu-core: 5.3.2
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
|
||||
/@babel/[email protected](@babel/[email protected]):
|
||||
resolution: {integrity: sha512-1VpEFOIbMRaXyDeUwUfmTIxExLwQ+zkW+Bh5zXpApA3oQedBx9v/updixWxnx/bZpKw7u8VxWjb/qWpIcmPq8A==}
|
||||
@@ -5178,7 +5181,7 @@ packages:
|
||||
'@babel/core': 7.23.7
|
||||
'@babel/helper-annotate-as-pure': 7.22.5
|
||||
regexpu-core: 5.3.2
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
|
||||
/@babel/[email protected](@babel/[email protected]):
|
||||
resolution: {integrity: sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==}
|
||||
@@ -5191,7 +5194,7 @@ packages:
|
||||
debug: 4.3.4([email protected])
|
||||
lodash.debounce: 4.0.8
|
||||
resolve: 1.22.8
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -6298,7 +6301,7 @@ packages:
|
||||
babel-plugin-polyfill-corejs2: 0.3.3(@babel/[email protected])
|
||||
babel-plugin-polyfill-corejs3: 0.6.0(@babel/[email protected])
|
||||
babel-plugin-polyfill-regenerator: 0.4.1(@babel/[email protected])
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -7536,6 +7539,11 @@ packages:
|
||||
resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
|
||||
/@eth-optimism/[email protected]:
|
||||
resolution: {integrity: sha512-Hc5peN5PM8kzl9dzqSD5jv6ED3QliO1DF0dXLRJxfrXR7/rmEeyuAYESUwUM0gdJZjkwRYiS5m230BI6bQmnlw==}
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
|
||||
/@eth-optimism/[email protected]([email protected]):
|
||||
resolution: {integrity: sha512-MrzV0nvsymfO/fursTB7m/KunkPsCndltVgfdHaT1Aj5Vi6R/doKIGGkOofHX+8B6VMZpuZosKCMQ5lQuqjt8w==}
|
||||
peerDependencies:
|
||||
@@ -7550,6 +7558,20 @@ packages:
|
||||
- utf-8-validate
|
||||
dev: false
|
||||
|
||||
/@eth-optimism/[email protected]([email protected]):
|
||||
resolution: {integrity: sha512-vQ04wfG9kMf1Fwy3FEMqH2QZbgS0gldKhcBeBUPfO8zu68L61VI97UDXmsMQXzTsEAxK8HnokW3/gosl4/NW3w==}
|
||||
peerDependencies:
|
||||
ethers: ^5
|
||||
dependencies:
|
||||
'@eth-optimism/core-utils': 0.12.0
|
||||
'@ethersproject/abstract-provider': 5.7.0
|
||||
'@ethersproject/abstract-signer': 5.7.0
|
||||
ethers: 5.7.2
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
dev: false
|
||||
|
||||
/@eth-optimism/[email protected]:
|
||||
resolution: {integrity: sha512-qW+7LZYCz7i8dRa7SRlUKIo1VBU8lvN0HeXCxJR+z+xtMzMQpPds20XJNCMclszxYQHkXY00fOT6GvFw9ZL6nw==}
|
||||
dependencies:
|
||||
@@ -7568,12 +7590,55 @@ packages:
|
||||
'@ethersproject/transactions': 5.7.0
|
||||
'@ethersproject/web': 5.7.1
|
||||
bufio: 1.2.0
|
||||
chai: 4.3.7
|
||||
chai: 4.4.1
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
dev: false
|
||||
|
||||
/@eth-optimism/[email protected]:
|
||||
resolution: {integrity: sha512-1FvzbUmCEy9zSKPG1QWg2VfA2Cy90xBA9Wkp11lXXrz91zUPCNCNSRTujXWYIC86ketNsZp7p4njSf6lTycHCw==}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
'@ethersproject/abi': 5.7.0
|
||||
'@ethersproject/abstract-provider': 5.7.0
|
||||
'@ethersproject/address': 5.7.0
|
||||
'@ethersproject/bignumber': 5.7.0
|
||||
'@ethersproject/bytes': 5.7.0
|
||||
'@ethersproject/constants': 5.7.0
|
||||
'@ethersproject/contracts': 5.7.0
|
||||
'@ethersproject/keccak256': 5.7.0
|
||||
'@ethersproject/properties': 5.7.0
|
||||
'@ethersproject/rlp': 5.7.0
|
||||
'@ethersproject/web': 5.7.1
|
||||
chai: 4.4.1
|
||||
ethers: 5.7.2
|
||||
node-fetch: 2.6.12
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- encoding
|
||||
- utf-8-validate
|
||||
dev: false
|
||||
|
||||
/@eth-optimism/[email protected]([email protected]):
|
||||
resolution: {integrity: sha512-P8YXAlh2lun0KZlwrw4FqmK4kNIoOOzI816XXhfkW3nMVADGRAru3TKSM74MgmEuyGiHrA9EoPRq1WLqUX4B0w==}
|
||||
peerDependencies:
|
||||
ethers: ^5
|
||||
dependencies:
|
||||
'@eth-optimism/contracts': 0.6.0([email protected])
|
||||
'@eth-optimism/contracts-bedrock': 0.17.1
|
||||
'@eth-optimism/core-utils': 0.13.1
|
||||
ethers: 5.7.2
|
||||
lodash: 4.17.21
|
||||
merkletreejs: 0.3.11
|
||||
rlp: 2.2.7
|
||||
semver: 7.6.0
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- encoding
|
||||
- utf-8-validate
|
||||
dev: false
|
||||
|
||||
/@ethereumjs/[email protected]:
|
||||
resolution: {integrity: sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==}
|
||||
dependencies:
|
||||
@@ -7934,7 +7999,7 @@ packages:
|
||||
qrcode-terminal: 0.11.0
|
||||
requireg: 0.2.2
|
||||
resolve-from: 5.0.0
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
send: 0.18.0
|
||||
slugify: 1.6.5
|
||||
structured-headers: 0.4.1
|
||||
@@ -7973,7 +8038,7 @@ packages:
|
||||
getenv: 1.0.0
|
||||
glob: 7.1.6
|
||||
resolve-from: 5.0.0
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
slash: 3.0.0
|
||||
xcode: 3.0.1
|
||||
xml2js: 0.6.0
|
||||
@@ -7996,7 +8061,7 @@ packages:
|
||||
glob: 7.1.6
|
||||
require-from-string: 2.0.2
|
||||
resolve-from: 5.0.0
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
slugify: 1.6.5
|
||||
sucrase: 3.29.0
|
||||
transitivePeerDependencies:
|
||||
@@ -8019,7 +8084,7 @@ packages:
|
||||
node-fetch: 2.6.12
|
||||
open: 8.4.2
|
||||
resolve-from: 5.0.0
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
serialize-error: 6.0.0
|
||||
temp-dir: 2.0.0
|
||||
transitivePeerDependencies:
|
||||
@@ -8059,7 +8124,7 @@ packages:
|
||||
node-fetch: 2.6.12
|
||||
parse-png: 2.1.0
|
||||
resolve-from: 5.0.0
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
tempy: 0.3.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
@@ -8141,7 +8206,7 @@ packages:
|
||||
expo-modules-autolinking: 1.0.2
|
||||
fs-extra: 9.1.0
|
||||
resolve-from: 5.0.0
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
xml2js: 0.6.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
@@ -9071,7 +9136,7 @@ packages:
|
||||
dependencies:
|
||||
'@types/debug': 4.1.7
|
||||
debug: 4.3.4([email protected])
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
superstruct: 1.0.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -9632,7 +9697,7 @@ packages:
|
||||
resolution: {integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==}
|
||||
dependencies:
|
||||
'@gar/promisify': 1.1.3
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
dev: false
|
||||
|
||||
/@npmcli/[email protected]:
|
||||
@@ -10684,7 +10749,7 @@ packages:
|
||||
node-stream-zip: 1.15.0
|
||||
ora: 5.4.1
|
||||
prompts: 2.4.2
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
strip-ansi: 5.2.0
|
||||
sudo-prompt: 9.2.1
|
||||
wcwidth: 1.0.1
|
||||
@@ -10786,7 +10851,7 @@ packages:
|
||||
node-fetch: 2.6.12
|
||||
open: 6.4.0
|
||||
ora: 5.4.1
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
shell-quote: 1.8.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
@@ -10817,7 +10882,7 @@ packages:
|
||||
fs-extra: 8.1.0
|
||||
graceful-fs: 4.2.11
|
||||
prompts: 2.4.2
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
transitivePeerDependencies:
|
||||
- '@babel/core'
|
||||
- bufferutil
|
||||
@@ -11033,7 +11098,7 @@ packages:
|
||||
resolution: {integrity: sha512-ITocwSWlFUA1K9VMP/eJiMfgbP/I9qDxAaFz7ukj5N5NZD3ihVQZkmqML6hjse5UhrfjCnfIEcLkNZhtB2XC2Q==}
|
||||
dependencies:
|
||||
'@safe-global/safe-core-sdk-types': 1.9.2
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
web3-utils: 1.8.2
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
@@ -11058,7 +11123,7 @@ packages:
|
||||
/@safe-global/[email protected]:
|
||||
resolution: {integrity: sha512-j7Ml1MVZw73XMTLbyIjo+Gvohwg5HYi8WM6b3vo+AkYEO/X4TNY8eJ0T0Awip5PO9MNyZymF3QY065uccQP53A==}
|
||||
dependencies:
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
dev: false
|
||||
|
||||
/@safe-global/[email protected](@ethersproject/[email protected])(@ethersproject/[email protected])(@ethersproject/[email protected])(@ethersproject/[email protected]):
|
||||
@@ -12896,7 +12961,7 @@ packages:
|
||||
grapheme-splitter: 1.0.4
|
||||
ignore: 5.3.0
|
||||
natural-compare-lite: 1.4.0
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
tsutils: 3.21.0([email protected])
|
||||
typescript: 5.3.3
|
||||
transitivePeerDependencies:
|
||||
@@ -13081,7 +13146,7 @@ packages:
|
||||
debug: 4.3.4([email protected])
|
||||
globby: 11.1.0
|
||||
is-glob: 4.0.3
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
tsutils: 3.21.0([email protected])
|
||||
typescript: 5.3.3
|
||||
transitivePeerDependencies:
|
||||
@@ -13102,7 +13167,7 @@ packages:
|
||||
debug: 4.3.4([email protected])
|
||||
globby: 11.1.0
|
||||
is-glob: 4.0.3
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
tsutils: 3.21.0([email protected])
|
||||
typescript: 5.3.3
|
||||
transitivePeerDependencies:
|
||||
@@ -13123,7 +13188,7 @@ packages:
|
||||
globby: 11.1.0
|
||||
is-glob: 4.0.3
|
||||
minimatch: 9.0.3
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
ts-api-utils: 1.0.1([email protected])
|
||||
typescript: 5.3.3
|
||||
transitivePeerDependencies:
|
||||
@@ -13143,7 +13208,7 @@ packages:
|
||||
debug: 4.3.4([email protected])
|
||||
globby: 11.1.0
|
||||
is-glob: 4.0.3
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
ts-api-utils: 1.0.1([email protected])
|
||||
typescript: 5.3.3
|
||||
transitivePeerDependencies:
|
||||
@@ -13163,7 +13228,7 @@ packages:
|
||||
'@typescript-eslint/typescript-estree': 5.55.0([email protected])
|
||||
eslint: 8.56.0
|
||||
eslint-scope: 5.1.1
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
@@ -13183,7 +13248,7 @@ packages:
|
||||
'@typescript-eslint/typescript-estree': 5.60.1([email protected])
|
||||
eslint: 8.56.0
|
||||
eslint-scope: 5.1.1
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
@@ -13201,7 +13266,7 @@ packages:
|
||||
'@typescript-eslint/types': 6.2.0
|
||||
'@typescript-eslint/typescript-estree': 6.2.0([email protected])
|
||||
eslint: 8.56.0
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
@@ -14780,7 +14845,7 @@ packages:
|
||||
'@babel/compat-data': 7.23.5
|
||||
'@babel/core': 7.23.7
|
||||
'@babel/helper-define-polyfill-provider': 0.3.3(@babel/[email protected])
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -14792,7 +14857,7 @@ packages:
|
||||
'@babel/compat-data': 7.23.5
|
||||
'@babel/core': 7.23.7
|
||||
'@babel/helper-define-polyfill-provider': 0.4.4(@babel/[email protected])
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -15080,7 +15145,7 @@ packages:
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
bin-version: 6.0.0
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
semver-truncate: 3.0.0
|
||||
dev: true
|
||||
|
||||
@@ -15538,7 +15603,7 @@ packages:
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==}
|
||||
dependencies:
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
dev: false
|
||||
|
||||
/[email protected]([email protected]):
|
||||
@@ -15774,6 +15839,20 @@ packages:
|
||||
loupe: 2.3.6
|
||||
pathval: 1.1.1
|
||||
type-detect: 4.0.8
|
||||
dev: true
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==}
|
||||
engines: {node: '>=4'}
|
||||
dependencies:
|
||||
assertion-error: 1.1.0
|
||||
check-error: 1.0.3
|
||||
deep-eql: 4.1.3
|
||||
get-func-name: 2.0.2
|
||||
loupe: 2.3.6
|
||||
pathval: 1.1.1
|
||||
type-detect: 4.0.8
|
||||
dev: false
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==}
|
||||
@@ -15845,6 +15924,13 @@ packages:
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==}
|
||||
dev: true
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==}
|
||||
dependencies:
|
||||
get-func-name: 2.0.2
|
||||
dev: false
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-HBiYvXvn9Z70Z88XKjz3AEKd4HJhBXsa3j7xFnITAzoS8+q6eIGi8qDB8FKPBAjtuxjI/zFpwuiCb8oDtKOYrA==}
|
||||
@@ -16443,7 +16529,7 @@ packages:
|
||||
dependencies:
|
||||
nice-try: 1.0.5
|
||||
path-key: 2.0.1
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
shebang-command: 1.2.0
|
||||
which: 1.3.1
|
||||
|
||||
@@ -16480,7 +16566,6 @@ packages:
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==}
|
||||
dev: true
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-GsVpkFPlycH7/fRR7Dhcmnoii54gV1nz7y4CWyeFS14N+JVBBhY+r8amRHE4BwSYal7BPTDp8isvAlCxyFt3Hg==}
|
||||
@@ -16543,7 +16628,7 @@ packages:
|
||||
postcss-modules-scope: 3.0.0([email protected])
|
||||
postcss-modules-values: 4.0.0([email protected])
|
||||
postcss-value-parser: 4.2.0
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
webpack: 5.76.2
|
||||
dev: false
|
||||
|
||||
@@ -18205,7 +18290,7 @@ packages:
|
||||
minimatch: 3.1.2
|
||||
object.values: 1.1.6
|
||||
resolve: 1.22.1
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
tsconfig-paths: 3.14.2
|
||||
transitivePeerDependencies:
|
||||
- eslint-import-resolver-typescript
|
||||
@@ -18317,7 +18402,7 @@ packages:
|
||||
minimatch: 3.1.2
|
||||
object.entries: 1.1.6
|
||||
object.fromentries: 2.0.6
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
|
||||
/[email protected]([email protected])([email protected])([email protected]):
|
||||
resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==}
|
||||
@@ -19724,7 +19809,7 @@ packages:
|
||||
memfs: 3.4.13
|
||||
minimatch: 3.1.2
|
||||
schema-utils: 2.7.0
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
tapable: 1.1.3
|
||||
typescript: 5.3.3
|
||||
webpack: 5.76.2
|
||||
@@ -19939,6 +20024,10 @@ packages:
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==}
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
|
||||
dev: false
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==}
|
||||
dependencies:
|
||||
@@ -21517,7 +21606,7 @@ packages:
|
||||
'@babel/core': 7.23.7
|
||||
'@istanbuljs/schema': 0.1.3
|
||||
istanbul-lib-coverage: 3.2.0
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@@ -21530,7 +21619,7 @@ packages:
|
||||
'@babel/parser': 7.23.6
|
||||
'@istanbuljs/schema': 0.1.3
|
||||
istanbul-lib-coverage: 3.2.0
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -22335,7 +22424,7 @@ packages:
|
||||
jest-util: 27.5.1
|
||||
natural-compare: 1.4.0
|
||||
pretty-format: 27.5.1
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
@@ -22363,7 +22452,7 @@ packages:
|
||||
jest-util: 29.6.2
|
||||
natural-compare: 1.4.0
|
||||
pretty-format: 29.6.2
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@@ -23402,13 +23491,13 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
pify: 4.0.1
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
|
||||
@@ -23604,6 +23693,17 @@ packages:
|
||||
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-LJKTl4iVNTndhL+3Uz/tfkjD0klIWsHlUzgtuNnNrsf7bAlXR30m+xYB7lHr5Z/l6e/yAIsr26Dabx6Buo4VGQ==}
|
||||
engines: {node: '>= 7.6.0'}
|
||||
dependencies:
|
||||
bignumber.js: 9.1.1
|
||||
buffer-reverse: 1.0.1
|
||||
crypto-js: 4.2.0
|
||||
treeify: 1.1.0
|
||||
web3-utils: 1.8.2
|
||||
dev: false
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==}
|
||||
engines: {node: '>= 0.6'}
|
||||
@@ -24554,7 +24654,7 @@ packages:
|
||||
dependencies:
|
||||
hosted-git-info: 2.8.9
|
||||
resolve: 1.22.8
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
validate-npm-package-license: 3.0.4
|
||||
|
||||
/[email protected]:
|
||||
@@ -24588,7 +24688,7 @@ packages:
|
||||
dependencies:
|
||||
hosted-git-info: 3.0.8
|
||||
osenv: 0.1.5
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
validate-npm-package-name: 3.0.0
|
||||
dev: false
|
||||
|
||||
@@ -25130,7 +25230,7 @@ packages:
|
||||
got: 12.6.1
|
||||
registry-auth-token: 5.0.2
|
||||
registry-url: 6.0.1
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
dev: false
|
||||
|
||||
/[email protected]:
|
||||
@@ -25823,7 +25923,7 @@ packages:
|
||||
cosmiconfig: 7.1.0
|
||||
klona: 2.0.6
|
||||
postcss: 8.4.21
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
webpack: 5.76.2
|
||||
dev: false
|
||||
|
||||
@@ -26481,7 +26581,7 @@ packages:
|
||||
jsdoc: 4.0.2
|
||||
minimist: 1.2.8
|
||||
protobufjs: 7.2.4
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
tmp: 0.2.1
|
||||
uglify-js: 3.17.4
|
||||
dev: false
|
||||
@@ -27946,7 +28046,7 @@ packages:
|
||||
resolution: {integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
dev: false
|
||||
|
||||
/[email protected]:
|
||||
@@ -27958,7 +28058,7 @@ packages:
|
||||
resolution: {integrity: sha512-LJWA9kSvMolR51oDE6PN3kALBNaUdkxzAGcexw8gjMA8xr5zUqK0JiR3CgARSqanYF3Z1YHvsErb1KDgh+v7Rg==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
dev: true
|
||||
|
||||
/[email protected]:
|
||||
@@ -27975,6 +28075,13 @@ packages:
|
||||
dependencies:
|
||||
lru-cache: 6.0.0
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
lru-cache: 6.0.0
|
||||
|
||||
/[email protected]:
|
||||
resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
@@ -28312,7 +28419,7 @@ packages:
|
||||
js-sha3: 0.8.0
|
||||
memorystream: 0.3.1
|
||||
require-from-string: 2.0.2
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
tmp: 0.0.33
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
@@ -1882,7 +1882,7 @@
|
||||
],
|
||||
"ERC721UpdatableMetadata": [
|
||||
{
|
||||
"name": "update",
|
||||
"name": "updateMetadata",
|
||||
"summary": "Update the metadata of an NFT\n\n",
|
||||
"remarks": "\n\nUpdate the metadata of an NFT\n\n",
|
||||
"examples": {
|
||||
|
||||
Reference in New Issue
Block a user