Compare commits

...
Author SHA1 Message Date
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
96b43b8488 Version Packages (#1106)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-06-02 10:33:56 -07:00
b4c9515937 Add Smart Wallet Factory hooks (#1115)
Co-authored-by: Krishang <[email protected]>
2023-06-02 16:19:24 +00:00
Manan TankandGitHub 9b20fc9ad2 [wallets, react] Remove chain restriction in paper wallet, Fix email validation in paper & magic (#1118) 2023-06-02 15:54:48 +00:00
Manan TankandGitHub 51bbd3d1bc [sdk] Reduce circular dependencies (#1117) 2023-06-02 13:58:26 +00:00
Manan TankandGitHub 356f7aa643 [react] Fix missing connectionStatus on localWallet connection, Metamask QR connection (#1116) 2023-06-02 12:35:14 +00:00
Adam MajmudarandGitHub 2283e71aca [Auth] Switch to server-side payload generation (#1114) 2023-06-02 00:38:35 +00:00
iketwandGitHub 90ab9ab031 [RN] fix lint warning (#1113) 2023-06-01 22:13:39 +00:00
Manan TankandGitHub 6aee041343 [sdk] Reduce circular dependencies (#1112) 2023-06-01 22:07:36 +00:00
Adam MajmudarandGitHub 21627c03d1 Update auth expiration (#1111) 2023-06-01 18:48:26 +00:00
ce36322b38 [SDK] Added getNonce() & updated airdrop (#1104)
Co-authored-by: Joaquim Verges <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
2023-06-01 17:43:55 +00:00
nkrishangandGitHub 564eaccf48 Smart Wallet Factory class for creating accounts and fetching data about them. (#1095) 2023-06-01 14:31:32 +00:00
Manan TankandGitHub aa9e952cb5 [sdk] Reduce circular dependencies (#1110) 2023-06-01 14:28:30 +00:00
Manan TankandGitHub 85a6162137 [sdk] Reduce circular deps (#1109) 2023-06-01 13:30:29 +00:00
Manan TankandGitHub e93aa70ef0 [sdk] Reduce circular deps (#1108) 2023-06-01 12:43:31 +00:00
Manan TankandGitHub 6e86123403 [sdk] Reduce circular dependencies (#1107) 2023-06-01 12:13:22 +00:00
Manan TankandGitHub c60658ed8c [sdk] Reduce circular deps (#1105) 2023-06-01 11:29:45 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
df5f016d31 Version Packages (#1099)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-31 16:52:33 -07:00
iketwandGitHub 89102b0c89 [RN] fix bug after scanning wc uri (#1103) 2023-05-31 23:44:10 +00:00
Adam MajmudarandGitHub e1846c4469 [Auth] Default invalid before state to 5 minutes ago (#1101) 2023-05-31 22:05:16 +00:00
Manan TankandGitHub cc56037e64 [sdk] Reduce circular dependencies (#1102) 2023-05-31 21:23:03 +00:00
Manan TankandGitHub 23d90b3e77 [sdk] Reduce circular dependencies (#1100) 2023-05-31 19:58:48 +00:00
Manan TankandGitHub 6745078947 add sideEffects: false on auth, storage, unity-js-bridge (#1098) 2023-05-31 18:52:05 +00:00
220 changed files with 6605 additions and 7774 deletions
+24
View File
@@ -1,5 +1,29 @@
# @thirdweb-dev/auth
## 3.1.0
### Minor Changes
- [#1114](https://github.com/thirdweb-dev/js/pull/1114) [`2283e71a`](https://github.com/thirdweb-dev/js/commit/2283e71acaaf3d15eb2d6121682f1d2a81eec4f3) Thanks [@adam-maj](https://github.com/adam-maj)! - Switch to server-side payload generation
### Patch Changes
- [#1111](https://github.com/thirdweb-dev/js/pull/1111) [`21627c03`](https://github.com/thirdweb-dev/js/commit/21627c03d1bb1658fee19b12d580faa6c7f048d9) Thanks [@adam-maj](https://github.com/adam-maj)! - Update expiration dates for auth
- Updated dependencies [[`9b20fc9a`](https://github.com/thirdweb-dev/js/commit/9b20fc9ad2d303edc31f44fbd2ea3b4dcf35d11e)]:
- @thirdweb-dev/wallets@0.2.25
## 3.0.23
### Patch Changes
- [#1101](https://github.com/thirdweb-dev/js/pull/1101) [`e1846c44`](https://github.com/thirdweb-dev/js/commit/e1846c44696bcb25a6a137d63e117e7d2ce9d979) Thanks [@adam-maj](https://github.com/adam-maj)! - Bump invalid before with 5 minute window
- [#1098](https://github.com/thirdweb-dev/js/pull/1098) [`67450789`](https://github.com/thirdweb-dev/js/commit/67450789473b6008b86453ee4f4c7b99461223a6) Thanks [@MananTank](https://github.com/MananTank)! - add sideEffects: false in package.json
- Updated dependencies []:
- @thirdweb-dev/wallets@0.2.24
## 3.0.22
### Patch Changes
+2 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/auth",
"version": "3.0.22",
"version": "3.1.0",
"main": "dist/thirdweb-dev-auth.cjs.js",
"module": "dist/thirdweb-dev-auth.esm.js",
"browser": {
@@ -54,6 +54,7 @@
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/auth",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
"sideEffects": false,
"scripts": {
"build": "preconstruct build",
"format": "prettier --write 'src/**/*'",
+18 -8
View File
@@ -6,7 +6,6 @@ import {
LoginPayloadDataSchema,
AuthenticationPayloadDataSchema,
AuthenticationPayloadData,
LoginOptionsSchema,
VerifyOptionsSchema,
VerifyOptions,
GenerateOptionsSchema,
@@ -14,6 +13,7 @@ import {
AuthenticateOptions,
User,
Json,
LoginOptionsSchema,
} from "./schema";
import { isBrowser } from "./utils";
import type { GenericAuthWallet } from "@thirdweb-dev/wallets";
@@ -31,7 +31,7 @@ export class ThirdwebAuth {
this.wallet = wallet;
}
public async login(options?: LoginOptions): Promise<LoginPayload> {
public async payload(options?: LoginOptions): Promise<LoginPayloadData> {
const parsedOptions = LoginOptionsSchema.parse(options);
let chainId: string | undefined = parsedOptions?.chainId;
@@ -43,30 +43,40 @@ export class ThirdwebAuth {
}
}
const payloadData = LoginPayloadDataSchema.parse({
return LoginPayloadDataSchema.parse({
type: this.wallet.type,
domain: parsedOptions?.domain || this.domain,
address: await this.wallet.getAddress(),
address: parsedOptions?.address || (await this.wallet.getAddress()),
statement: parsedOptions?.statement,
version: parsedOptions?.version,
uri: parsedOptions?.uri,
chain_id: chainId,
nonce: parsedOptions?.nonce,
expiration_time:
parsedOptions?.expirationTime || new Date(Date.now() + 1000 * 60 * 5),
invalid_before: parsedOptions?.invalidBefore,
parsedOptions?.expirationTime || new Date(Date.now() + 1000 * 60 * 10),
invalid_before:
parsedOptions?.invalidBefore || new Date(Date.now() - 1000 * 60 * 10),
resources: parsedOptions?.resources,
});
}
const message = this.generateMessage(payloadData);
public async loginWithPayload(
payload: LoginPayloadData,
): Promise<LoginPayload> {
const message = this.generateMessage(payload);
const signature = await this.wallet.signMessage(message);
return {
payload: payloadData,
payload,
signature,
};
}
public async login(options?: LoginOptions): Promise<LoginPayload> {
const payloadData = await this.payload(options);
return await this.loginWithPayload(payloadData);
}
public async verify(
payload: LoginPayload,
options?: VerifyOptions,
+1
View File
@@ -34,6 +34,7 @@ const JsonSchema: z.ZodType<Json> = z.lazy(
export const LoginOptionsSchema = z
.object({
domain: z.string().optional(),
address: z.string().optional(),
statement: z.string().optional(),
uri: z.string().optional(),
version: z.string().optional(),
+8
View File
@@ -1,5 +1,6 @@
import { Json, ThirdwebAuth as ThirdwebAuthSDK } from "../core";
import { getUser } from "./helpers/user";
import payloadHandler from "./routes/payload";
import loginHandler from "./routes/login";
import logoutHandler from "./routes/logout";
import userHandler from "./routes/user";
@@ -47,6 +48,13 @@ export function ThirdwebAuth<
router.use(express.json());
router.use(cookieMiddleware);
router.post(
"/payload",
asyncHandler((req: Request, res: Response) =>
payloadHandler(req, res, ctx as ThirdwebAuthContext),
),
);
router.post(
"/login",
asyncHandler((req: Request, res: Response) =>
@@ -0,0 +1,31 @@
import { Request, Response } from "express";
import { PayloadBodySchema, ThirdwebAuthContext } from "../types";
export default async function handler(
req: Request,
res: Response,
ctx: ThirdwebAuthContext,
) {
if (req.method !== "POST") {
return res.status(405).json({
error: "Invalid method. Only POST supported.",
});
}
const parsedPayload = PayloadBodySchema.safeParse(req.body);
if (!parsedPayload.success) {
return res.status(400).json({ error: "Please provide an address" });
}
// TODO: Add nonce generation + custom expiration + invalid before
const payload = await ctx.auth.payload({
address: parsedPayload.data.address,
statement: ctx.authOptions?.statement,
uri: ctx.authOptions?.uri,
version: ctx.authOptions?.version,
chainId: ctx.authOptions?.chainId,
resources: ctx.authOptions?.resources,
});
return res.status(200).json({ payload });
}
+4
View File
@@ -4,6 +4,10 @@ import type { GenericAuthWallet } from "@thirdweb-dev/wallets";
import { Request } from "express";
import { z } from "zod";
export const PayloadBodySchema = z.object({
address: z.string(),
});
export const LoginPayloadBodySchema = z.object({
payload: LoginPayloadOutputSchema,
});
+3
View File
@@ -1,5 +1,6 @@
import { Json, ThirdwebAuth as ThirdwebAuthSDK } from "../core";
import { getUser } from "./helpers/user";
import payloadHandler from "./routes/payload";
import loginHandler from "./routes/login";
import logoutHandler from "./routes/logout";
import userHandler from "./routes/user";
@@ -27,6 +28,8 @@ async function ThirdwebAuthRouter(
const action = thirdweb?.[0] as ThirdwebAuthRoute;
switch (action) {
case "payload":
return await payloadHandler(req, res, ctx);
case "login":
return await loginHandler(req, res, ctx);
case "user":
+31
View File
@@ -0,0 +1,31 @@
import { PayloadBodySchema, ThirdwebAuthContext } from "../types";
import { NextApiRequest, NextApiResponse } from "next";
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
ctx: ThirdwebAuthContext,
) {
if (req.method !== "POST") {
return res.status(405).json({
error: "Invalid method. Only POST supported.",
});
}
const parsedPayload = PayloadBodySchema.safeParse(req.body);
if (!parsedPayload.success) {
return res.status(400).json({ error: "Please provide an address" });
}
// TODO: Add nonce generation + custom expiration + invalid before
const payload = await ctx.auth.payload({
address: parsedPayload.data.address,
statement: ctx.authOptions?.statement,
uri: ctx.authOptions?.uri,
version: ctx.authOptions?.version,
chainId: ctx.authOptions?.chainId,
resources: ctx.authOptions?.resources,
});
return res.status(200).json({ payload });
}
+5 -1
View File
@@ -5,6 +5,10 @@ import { GetServerSidePropsContext, NextApiRequest } from "next";
import { NextRequest } from "next/server";
import { z } from "zod";
export const PayloadBodySchema = z.object({
address: z.string(),
});
export const LoginPayloadBodySchema = z.object({
payload: LoginPayloadOutputSchema,
});
@@ -14,7 +18,7 @@ type RequestType =
| NextRequest
| NextApiRequest;
export type ThirdwebAuthRoute = "login" | "logout" | "user";
export type ThirdwebAuthRoute = "payload" | "login" | "logout" | "user";
export type ThirdwebAuthUser<
TData extends Json = Json,
+5 -2
View File
@@ -11,20 +11,23 @@ export default {
"rpc": [
"https://gnosis.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.gnosischain.com",
"https://rpc.gnosis.gateway.fm",
"https://rpc.ankr.com/gnosis",
"https://gnosischain-rpc.gateway.pokt.network",
"https://gnosis-mainnet.public.blastapi.io",
"https://gnosis.api.onfinality.io/public",
"https://gnosis.blockpi.network/v1/rpc/public",
"https://web3endpoints.com/gnosischain-mainnet",
"wss://rpc.gnosischain.com/wss"
],
"faucets": [
"https://gnosisfaucet.com",
"https://faucet.gimlu.com/gnosis",
"https://stakely.io/faucet/gnosis-chain-xdai",
"https://faucet.prussia.dev/xdai"
],
"nativeCurrency": {
"name": "xDAI",
"symbol": "xDAI",
"symbol": "XDAI",
"decimals": 18
},
"infoURL": "https://docs.gnosischain.com",
+7 -6
View File
@@ -1,7 +1,7 @@
import type { Chain } from "../src/types";
export default {
"name": "Chiado Testnet",
"chain": "CHI",
"name": "Gnosis Chiado Testnet",
"chain": "GNO",
"icon": {
"url": "ipfs://bafybeidk4swpgdyqmpz6shd5onvpaujvwiwthrhypufnwr6xh3dausz2dm",
"width": 1800,
@@ -9,16 +9,17 @@ export default {
"format": "png"
},
"rpc": [
"https://chiado-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://gnosis-chiado-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.chiadochain.net",
"https://rpc.eu-central-2.gateway.fm/v3/gnosis/archival/chiado"
"https://rpc.chiado.gnosis.gateway.fm",
"wss://rpc.chiadochain.net/wss"
],
"faucets": [
"https://gnosisfaucet.com"
],
"nativeCurrency": {
"name": "Chiado xDAI",
"symbol": "xDAI",
"symbol": "XDAI",
"decimals": 18
},
"infoURL": "https://docs.gnosischain.com",
@@ -39,5 +40,5 @@ export default {
}
],
"testnet": true,
"slug": "chiado-testnet"
"slug": "gnosis-chiado-testnet"
} as const satisfies Chain;
+29
View File
@@ -0,0 +1,29 @@
import type { Chain } from "../src/types";
export default {
"name": "ChainX-EVM",
"chain": "ChainX",
"rpc": [
"https://chainx-evm.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://mainnet.chainx.org/rpc",
"https://mainnet2.chainx.org/rpc"
],
"faucets": [],
"nativeCurrency": {
"name": "BTC",
"symbol": "BTC",
"decimals": 18
},
"infoURL": "https://chainx.org",
"shortName": "chainx",
"chainId": 1501,
"networkId": 1501,
"explorers": [
{
"name": "chainx-evm scan",
"url": "https://evm.chainx.org",
"standard": "none"
}
],
"testnet": false,
"slug": "chainx-evm"
} as const satisfies Chain;
+3 -3
View File
@@ -3,9 +3,9 @@ export default {
"name": "Taiko (Alpha-2 Testnet)",
"chain": "ETH",
"icon": {
"url": "ipfs://QmWMUDmNHzCtism9dYK1JooerZJ4da6kGt67HAQmLiEykc",
"width": 1001,
"height": 1001,
"url": "ipfs://QmcHdmVr5VRUJq13jnM6tgah5Ge7hn3Dm14eY6vwivJ5ui",
"width": 288,
"height": 258,
"format": "png"
},
"rpc": [
+35
View File
@@ -0,0 +1,35 @@
import type { Chain } from "../src/types";
export default {
"name": "Taiko (Alpha-3 Testnet)",
"chain": "ETH",
"status": "active",
"icon": {
"url": "ipfs://QmcHdmVr5VRUJq13jnM6tgah5Ge7hn3Dm14eY6vwivJ5ui",
"width": 288,
"height": 258,
"format": "png"
},
"rpc": [
"https://taiko-alpha-3-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.test.taiko.xyz"
],
"faucets": [],
"nativeCurrency": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"infoURL": "https://taiko.xyz",
"shortName": "taiko-a3",
"chainId": 167005,
"networkId": 167005,
"explorers": [
{
"name": "blockscout",
"url": "https://explorer.test.taiko.xyz",
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "taiko-alpha-3-testnet"
} as const satisfies Chain;
+36
View File
@@ -0,0 +1,36 @@
import type { Chain } from "../src/types";
export default {
"name": "WhiteBIT Network Testnet",
"chain": "WBT",
"rpc": [
"https://whitebit-network-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc-testnet.whitebit.network"
],
"faucets": [
"https://explorer.whitebit.network/testnet/faucet"
],
"nativeCurrency": {
"name": "WhiteBIT Coin",
"symbol": "WBT",
"decimals": 18
},
"infoURL": "https://whitebit.com/wbt",
"shortName": "twbt",
"chainId": 2625,
"networkId": 2625,
"icon": {
"url": "ipfs://QmQqAAn2F98TH5ouRyvReKxQdaGKjE7WJQPEPW6mFFVXUT",
"width": 32,
"height": 32,
"format": "svg"
},
"explorers": [
{
"name": "wb-explorer-testnet",
"url": "https://explorer.whitebit.network/testnet",
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "whitebit-network-testnet"
} as const satisfies Chain;
-37
View File
@@ -1,37 +0,0 @@
import type { Chain } from "../src/types";
export default {
"name": "Optimism on Gnosis",
"chain": "OGC",
"rpc": [
"https://optimism-on-gnosis.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://optimism.gnosischain.com",
"wss://optimism.gnosischain.com/wss"
],
"faucets": [
"https://faucet.gimlu.com/gnosis"
],
"nativeCurrency": {
"name": "xDAI",
"symbol": "xDAI",
"decimals": 18
},
"infoURL": "https://www.xdaichain.com/for-developers/optimism-optimistic-rollups-on-gc",
"shortName": "ogc",
"chainId": 300,
"networkId": 300,
"explorers": [
{
"name": "blockscout",
"url": "https://blockscout.com/xdai/optimism",
"icon": {
"url": "ipfs://bafybeifu5tpui7dk5cjoo54kde7pmuthvnl7sdykobuarsxgu7t2izurnq",
"width": 512,
"height": 512,
"format": "png"
},
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "optimism-on-gnosis"
} as const satisfies Chain;
+31 -22
View File
@@ -1,37 +1,46 @@
import type { Chain } from "../src/types";
export default {
"name": "Kovan",
"title": "Ethereum Testnet Kovan",
"chain": "ETH",
"name": "LUKSO Mainnet",
"chain": "LUKSO",
"icon": {
"url": "ipfs://Qmeg9sFF5tAGi6MCx7YjtVHW6a23zqvHRK1xwzSdp9iE7z",
"width": 512,
"height": 512,
"format": "png"
},
"rpc": [
"https://kovan.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://kovan.poa.network",
"http://kovan.poa.network:8545",
"https://kovan.infura.io/v3/${INFURA_API_KEY}",
"wss://kovan.infura.io/ws/v3/${INFURA_API_KEY}",
"ws://kovan.poa.network:8546"
],
"faucets": [
"http://fauceth.komputing.org?chain=42&address=${ADDRESS}",
"https://faucet.kovan.network",
"https://gitter.im/kovan-testnet/faucet"
"https://lukso.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.mainnet.lukso.network",
"wss://ws-rpc.mainnet.lukso.network"
],
"faucets": [],
"nativeCurrency": {
"name": "Kovan Ether",
"symbol": "ETH",
"name": "LUKSO",
"symbol": "LYX",
"decimals": 18
},
"explorers": [
{
"name": "etherscan",
"url": "https://kovan.etherscan.io",
"name": "Blockscout",
"url": "https://explorer.execution.mainnet.lukso.network",
"standard": "EIP3091"
}
],
"infoURL": "https://kovan-testnet.github.io/website",
"shortName": "kov",
"infoURL": "https://lukso.network",
"shortName": "lukso",
"chainId": 42,
"networkId": 42,
"testnet": true,
"slug": "kovan"
"features": [
{
"name": "EIP155"
},
{
"name": "EIP1559"
}
],
"redFlags": [
"reusedChainId"
],
"testnet": false,
"slug": "lukso"
} as const satisfies Chain;
+45
View File
@@ -0,0 +1,45 @@
import type { Chain } from "../src/types";
export default {
"name": "LUKSO Testnet",
"chain": "LUKSO Testnet",
"icon": {
"url": "ipfs://Qmeg9sFF5tAGi6MCx7YjtVHW6a23zqvHRK1xwzSdp9iE7z",
"width": 512,
"height": 512,
"format": "png"
},
"rpc": [
"https://lukso-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.testnet.lukso.network",
"wss://ws-rpc.testnet.lukso.network"
],
"faucets": [
"https://faucet.testnet.lukso.network"
],
"nativeCurrency": {
"name": "TestLYX",
"symbol": "LYXt",
"decimals": 18
},
"explorers": [
{
"name": "Blockscout",
"url": "https://explorer.execution.testnet.lukso.network",
"standard": "none"
}
],
"infoURL": "https://lukso.network",
"shortName": "lukso-testnet",
"chainId": 4201,
"networkId": 4201,
"features": [
{
"name": "EIP155"
},
{
"name": "EIP1559"
}
],
"testnet": true,
"slug": "lukso-testnet"
} as const satisfies Chain;
+2 -2
View File
@@ -8,8 +8,8 @@ export default {
],
"faucets": [],
"nativeCurrency": {
"name": "BitDAO",
"symbol": "BIT",
"name": "Mantle",
"symbol": "MNT",
"decimals": 18
},
"infoURL": "https://mantle.xyz",
+2 -2
View File
@@ -10,8 +10,8 @@ export default {
"https://faucet.testnet.mantle.xyz"
],
"nativeCurrency": {
"name": "Testnet BitDAO",
"symbol": "BIT",
"name": "Testnet Mantle",
"symbol": "MNT",
"decimals": 18
},
"infoURL": "https://mantle.xyz",
+2
View File
@@ -5,6 +5,8 @@ export default {
"rpc": [
"https://syscoin.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.syscoin.org",
"https://rpc.ankr.com/syscoin/${ANKR_API_KEY}",
"https://syscoin.public-rpc.com",
"wss://rpc.syscoin.org/wss"
],
"faucets": [
+31
View File
@@ -0,0 +1,31 @@
import type { Chain } from "../src/types";
export default {
"name": "Rollux Mainnet",
"chain": "SYS",
"rpc": [
"https://rollux.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.rollux.com",
"wss://rpc.rollux.com/wss"
],
"faucets": [
"https://rollux.id/faucetapp"
],
"nativeCurrency": {
"name": "Syscoin",
"symbol": "SYS",
"decimals": 18
},
"infoURL": "https://rollux.com",
"shortName": "sys-rollux",
"chainId": 570,
"networkId": 570,
"explorers": [
{
"name": "Rollux Explorer",
"url": "https://explorer.rollux.com",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "rollux"
} as const satisfies Chain;
+11 -8
View File
@@ -1,29 +1,32 @@
import type { Chain } from "../src/types";
export default {
"name": "Syscoin Rollux Testnet",
"name": "Rollux Testnet",
"chain": "SYS",
"rpc": [
"https://syscoin-rollux-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rollux-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc-tanenbaum.rollux.com",
"https://rpc.ankr.com/rollux_testnet/${ANKR_API_KEY}",
"wss://rpc-tanenbaum.rollux.com/wss"
],
"faucets": [],
"faucets": [
"https://rollux.id/faucetapp"
],
"nativeCurrency": {
"name": "Rollux Testnet Syscoin",
"symbol": "tSYS",
"name": "Testnet Syscoin",
"symbol": "TSYS",
"decimals": 18
},
"infoURL": "https://syscoin.org",
"infoURL": "https://rollux.com",
"shortName": "tsys-rollux",
"chainId": 57000,
"networkId": 57000,
"explorers": [
{
"name": "Syscoin Rollux Testnet Explorer",
"name": "Rollux Testnet Explorer",
"url": "https://rollux.tanenbaum.io",
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "syscoin-rollux-testnet"
"slug": "rollux-testnet"
} as const satisfies Chain;
+39
View File
@@ -0,0 +1,39 @@
import type { Chain } from "../src/types";
export default {
"name": "UPTN Testnet",
"chain": "UPTN",
"icon": {
"url": "ipfs://Qma6cGPCDcJPFxy5KQaMBrLtuVQiqeLncXVybcBoQuhai5",
"width": 128,
"height": 128,
"format": "png"
},
"rpc": [
"https://uptn-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://node-api.alp.uptn.io/v1/ext/rpc"
],
"features": [
{
"name": "EIP1559"
}
],
"faucets": [],
"nativeCurrency": {
"name": "UPTN",
"symbol": "UPTN",
"decimals": 18
},
"infoURL": "https://uptn.io",
"shortName": "UPTN-TEST",
"chainId": 6118,
"networkId": 6118,
"explorers": [
{
"name": "UPTN Testnet Explorer",
"url": "https://testnet.explorer.uptn.io",
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "uptn-testnet"
} as const satisfies Chain;
+39
View File
@@ -0,0 +1,39 @@
import type { Chain } from "../src/types";
export default {
"name": "UPTN",
"chain": "UPTN",
"icon": {
"url": "ipfs://Qma6cGPCDcJPFxy5KQaMBrLtuVQiqeLncXVybcBoQuhai5",
"width": 128,
"height": 128,
"format": "png"
},
"rpc": [
"https://uptn.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://node-api.uptn.io/v1/ext/rpc"
],
"features": [
{
"name": "EIP1559"
}
],
"faucets": [],
"nativeCurrency": {
"name": "UPTN",
"symbol": "UPTN",
"decimals": 18
},
"infoURL": "https://uptn.io",
"shortName": "UPTN",
"chainId": 6119,
"networkId": 6119,
"explorers": [
{
"name": "UPTN Explorer",
"url": "https://explorer.uptn.io",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "uptn"
} as const satisfies Chain;
File diff suppressed because one or more lines are too long
+15
View File
@@ -1,5 +1,20 @@
# thirdweb
## 0.10.21
### Patch Changes
- Updated dependencies [[`ce36322b`](https://github.com/thirdweb-dev/js/commit/ce36322b383af73905894b73f9409a146359ffb0), [`c60658ed`](https://github.com/thirdweb-dev/js/commit/c60658ed8c94867cca831b0d5535006da5b40aa6), [`aa9e952c`](https://github.com/thirdweb-dev/js/commit/aa9e952cb519a47ed112d2905b1f3787863035b6), [`564eaccf`](https://github.com/thirdweb-dev/js/commit/564eaccf480a81f36db43c782392595a5021e5ac), [`6aee0413`](https://github.com/thirdweb-dev/js/commit/6aee0413439b9ca408879bbb3c38c538c89d01af), [`e93aa70e`](https://github.com/thirdweb-dev/js/commit/e93aa70ef0093a2526404e11b7ddae8fb98c213b), [`51bbd3d1`](https://github.com/thirdweb-dev/js/commit/51bbd3d1bccbb92a1405ea50f6c178c091a90f20)]:
- @thirdweb-dev/sdk@3.10.20
## 0.10.20
### Patch Changes
- Updated dependencies [[`23d90b3e`](https://github.com/thirdweb-dev/js/commit/23d90b3e779a5bfdb7058b8c51349d9c278fcbce), [`cc56037e`](https://github.com/thirdweb-dev/js/commit/cc56037e64560b9e0fc16eb0ac7cc2e47e2c9fdf), [`67450789`](https://github.com/thirdweb-dev/js/commit/67450789473b6008b86453ee4f4c7b99461223a6)]:
- @thirdweb-dev/sdk@3.10.19
- @thirdweb-dev/storage@1.1.4
## 0.10.19
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "thirdweb",
"main": "dist/cli/index.js",
"version": "0.10.19",
"version": "0.10.21",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
+6
View File
@@ -1,5 +1,11 @@
# @thirdweb-dev/contracts-js
## 1.3.5
### Patch Changes
- [#1095](https://github.com/thirdweb-dev/js/pull/1095) [`564eaccf`](https://github.com/thirdweb-dev/js/commit/564eaccf480a81f36db43c782392595a5021e5ac) Thanks [@nkrishang](https://github.com/nkrishang)! - Add SmartWalletFactory extension detection and logic
## 1.3.4
### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/contracts-js",
"version": "1.3.4",
"version": "1.3.5",
"main": "dist/thirdweb-dev-contracts-js.cjs.js",
"module": "dist/thirdweb-dev-contracts-js.esm.js",
"browser": {
@@ -10,7 +10,7 @@
"license": "Apache-2.0",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/contracts-js",
"dependencies": {
"@thirdweb-dev/contracts": "3.4.7-0"
"@thirdweb-dev/contracts": "3.5.5"
},
"devDependencies": {
"@babel/preset-env": "^7.18.10",
+23
View File
@@ -1,5 +1,28 @@
# @thirdweb-dev/react-core
## 3.13.0
### Minor Changes
- [#1114](https://github.com/thirdweb-dev/js/pull/1114) [`2283e71a`](https://github.com/thirdweb-dev/js/commit/2283e71acaaf3d15eb2d6121682f1d2a81eec4f3) Thanks [@adam-maj](https://github.com/adam-maj)! - Switch to server-side payload generation
### Patch Changes
- [#1111](https://github.com/thirdweb-dev/js/pull/1111) [`21627c03`](https://github.com/thirdweb-dev/js/commit/21627c03d1bb1658fee19b12d580faa6c7f048d9) Thanks [@adam-maj](https://github.com/adam-maj)! - Update expiration dates for auth
- Updated dependencies [[`ce36322b`](https://github.com/thirdweb-dev/js/commit/ce36322b383af73905894b73f9409a146359ffb0), [`c60658ed`](https://github.com/thirdweb-dev/js/commit/c60658ed8c94867cca831b0d5535006da5b40aa6), [`aa9e952c`](https://github.com/thirdweb-dev/js/commit/aa9e952cb519a47ed112d2905b1f3787863035b6), [`564eaccf`](https://github.com/thirdweb-dev/js/commit/564eaccf480a81f36db43c782392595a5021e5ac), [`6aee0413`](https://github.com/thirdweb-dev/js/commit/6aee0413439b9ca408879bbb3c38c538c89d01af), [`e93aa70e`](https://github.com/thirdweb-dev/js/commit/e93aa70ef0093a2526404e11b7ddae8fb98c213b), [`51bbd3d1`](https://github.com/thirdweb-dev/js/commit/51bbd3d1bccbb92a1405ea50f6c178c091a90f20), [`9b20fc9a`](https://github.com/thirdweb-dev/js/commit/9b20fc9ad2d303edc31f44fbd2ea3b4dcf35d11e)]:
- @thirdweb-dev/sdk@3.10.20
- @thirdweb-dev/wallets@0.2.25
## 3.12.4
### Patch Changes
- Updated dependencies [[`23d90b3e`](https://github.com/thirdweb-dev/js/commit/23d90b3e779a5bfdb7058b8c51349d9c278fcbce), [`cc56037e`](https://github.com/thirdweb-dev/js/commit/cc56037e64560b9e0fc16eb0ac7cc2e47e2c9fdf), [`67450789`](https://github.com/thirdweb-dev/js/commit/67450789473b6008b86453ee4f4c7b99461223a6)]:
- @thirdweb-dev/sdk@3.10.19
- @thirdweb-dev/storage@1.1.4
- @thirdweb-dev/wallets@0.2.24
## 3.12.3
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react-core",
"version": "3.12.3",
"version": "3.13.0",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-core",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -0,0 +1,122 @@
import {
RequiredParam,
requiredParamInvariant,
} from "../../../core/query-utils/required-param";
import { useSDKChainId } from "../../providers/thirdweb-sdk-provider";
import {
cacheKeys,
invalidateContractAndBalances,
} from "../../utils/cache-keys";
import { useQueryWithNetwork } from "../query-utils/useQueryWithNetwork";
import {
useMutation,
useQueryClient,
UseQueryResult,
} from "@tanstack/react-query";
import type {
AccountEvent, SmartContract,
} from "@thirdweb-dev/sdk";
import type { BytesLike } from "ethers";
import invariant from "tiny-invariant";
/** **********************/
/** READ HOOKS **/
/** **********************/
/**
* Get all wallets
*
* @example
* ```javascript
* const { data: smartWallets, isLoading, error } = useSmartWallets(contract);
* ```
*
* @param contract - an instance of a smart wallet factory contract
* @returns a response object that includes an array of all smart wallets with their associated admin
* @twfeature SmartWalletFactory
* @see {@link https://portal.thirdweb.com/react/react.usesmartwallets?utm_source=sdk | Documentation}
* @beta
*/
export function useSmartWallets(
contract: RequiredParam<SmartContract>
): UseQueryResult<AccountEvent[]> {
const contractAddress = contract?.getAddress();
return useQueryWithNetwork(
cacheKeys.contract.smartWalletFactory.getAll(contractAddress),
() => {
requiredParamInvariant(contract, "No Contract instance provided");
invariant(
contract.smartWalletFactory.getAllWallets,
"Contract instance does not support contract.smartWalletFactory.getAllWallets",
);
return contract.smartWalletFactory.getAllWallets();
},
{ enabled: !!contract },
);
}
/** **********************/
/** WRITE HOOKS **/
/** **********************/
/**
* Create a smart wallet
*
* @example
* ```jsx
* const Component = () => {
* const { contract } = useContract("{{contract_address}}");
* const {
* mutate: createSmartWallet,
* isLoading,
* error,
* } = useCreateSmartWallet(contract);
*
* if (error) {
* console.error("failed to create smart wallet", error);
* }
*
* return (
* <button
* disabled={isLoading}
* onClick={() => createSmartWallet("0x...")}
* >
* Create Smart Wallet
* </button>
* );
* };
* ```
*
* @param contract - an instance of a smart wallet factory contract
* @returns a mutation object that can be used to create a smart wallet
* @twfeature SmartWalletFactory
* @see {@link https://portal.thirdweb.com/react/react.usecreatesmartwallet?utm_source=sdk | Documentation}
* @beta
*/
export function useCreateSmartWallet(
contract: RequiredParam<SmartContract>,
) {
const activeChainId = useSDKChainId();
const contractAddress = contract?.getAddress();
const queryClient = useQueryClient();
return useMutation(
async (data: { admin: string; extraData: BytesLike; }) => {
requiredParamInvariant(contract, "contract is undefined");
return contract.smartWalletFactory.createWallet(
data.admin,
data.extraData,
);
},
{
onSettled: () =>
invalidateContractAndBalances(
queryClient,
contractAddress,
activeChainId,
),
},
);
}
@@ -27,7 +27,7 @@ export function useLogin() {
const wallet = useWallet();
const login = useMutation({
mutationFn: async (options?: LoginOptions) => {
mutationFn: async () => {
invariant(
authConfig,
"Please specify an authConfig in the ThirdwebProvider",
@@ -38,14 +38,29 @@ export function useLogin() {
"Please specify an authUrl in the authConfig.",
);
// we need to generate this auth payload
const payload = await doLogin(wallet, {
...authConfig,
...(options || {}),
const address = await wallet.getAddress();
let res = await fetch(`${authConfig.authUrl}/payload`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ address }),
});
const res = await fetch(`${authConfig.authUrl}/login`, {
if (!res.ok) {
throw new Error(`Failed to get payload with status code ${res.status}`);
}
let payloadData: LoginPayloadData;
try {
({ payload: payloadData } = await res.json());
} catch {
throw new Error(`Failed to get payload`);
}
const payload = await doLoginWithPayload(wallet, payloadData);
res = await fetch(`${authConfig.authUrl}/login`, {
method: "POST",
headers: {
"Content-Type": "application/json",
@@ -73,11 +88,24 @@ export function useLogin() {
});
return {
login: (options?: LoginOptions) => login.mutateAsync(options),
login: () => login.mutateAsync(),
isLoading: login.isLoading,
};
}
export async function doLoginWithPayload(
wallet: GenericAuthWallet,
payload: LoginPayloadData,
): Promise<LoginPayload> {
const message = generateMessage(payload);
const signature = await wallet.signMessage(message);
return {
payload,
signature,
};
}
export async function doLogin(
wallet: GenericAuthWallet,
options?: LoginOptions,
@@ -109,20 +137,15 @@ export async function doLogin(
nonce: options?.nonce || nonce,
issued_at: new Date().toISOString(),
expiration_time: new Date(
options?.expirationTime || Date.now() + 1000 * 60 * 5,
options?.expirationTime || Date.now() + 1000 * 60 * 10,
).toISOString(),
invalid_before: new Date(
options?.invalidBefore || Date.now(),
options?.invalidBefore || Date.now() - 1000 * 60 * 10,
).toISOString(),
resources: options?.resources,
};
const signature = await wallet.signMessage(generateMessage(payloadData));
return {
payload: payloadData,
signature,
};
return doLoginWithPayload(wallet, payloadData);
}
// generate straight from auth
@@ -118,6 +118,11 @@ export const cacheKeys = {
overrides,
]),
smartWalletFactory: {
getAll: (contractAddress: RequiredParam<ContractAddress>) =>
createContractCacheKey(contractAddress, ["smartWalletFactory"]),
},
app: {
get: (contractAddress: RequiredParam<ContractAddress>) =>
createContractCacheKey(contractAddress, ["appURI"]),
@@ -37,7 +37,7 @@ export function useLogin() {
const signer = useSDK()?.wallet.getSigner();
const login = useMutation({
mutationFn: async (options?: LoginOptions) => {
mutationFn: async () => {
invariant(
authConfig,
"Please specify an authConfig in the ThirdwebProvider",
@@ -47,9 +47,29 @@ export function useLogin() {
authConfig.authUrl,
"Please specify an authUrl in the authConfig.",
);
const wallet = new SignerWallet(signer);
const address = await wallet.getAddress();
let res = await fetch(`${authConfig.authUrl}/payload`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ address }),
});
const payload = doLogin(new SignerWallet(signer), options);
const res = await fetch(`${authConfig.authUrl}/login`, {
if (!res.ok) {
throw new Error(`Failed to get payload with status code ${res.status}`);
}
let payloadData: LoginPayloadData;
try {
({ payload: payloadData } = await res.json());
} catch {
throw new Error(`Failed to get payload`);
}
const payload = await doLoginWithPayload(wallet, payloadData);
res = await fetch(`${authConfig.authUrl}/login`, {
method: "POST",
headers: {
"Content-Type": "application/json",
@@ -72,7 +92,7 @@ export function useLogin() {
});
return {
login: (options?: LoginOptions) => login.mutateAsync(options),
login: () => login.mutateAsync(),
isLoading: login.isLoading,
};
}
@@ -80,7 +100,20 @@ export function useLogin() {
// login function extracted directly from auth
const isBrowser = () => typeof window !== "undefined";
async function doLogin(
export async function doLoginWithPayload(
wallet: GenericAuthWallet,
payload: LoginPayloadData,
): Promise<LoginPayload> {
const message = generateMessage(payload);
const signature = await wallet.signMessage(message);
return {
payload,
signature,
};
}
export async function doLogin(
wallet: GenericAuthWallet,
options?: LoginOptions,
): Promise<LoginPayload> {
@@ -119,12 +152,7 @@ async function doLogin(
resources: options?.resources,
};
const signature = await wallet.signMessage(generateMessage(payloadData));
return {
payload: payloadData,
signature,
};
return doLoginWithPayload(wallet, payloadData);
}
// generate straight from auth
@@ -1,5 +1,9 @@
# @thirdweb-dev/react-native-compat
## 0.2.17
## 0.2.16
## 0.2.15
## 0.2.14
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@thirdweb-dev/react-native-compat",
"description": "Shims for Thirdweb in React Native Projects",
"version": "0.2.15",
"version": "0.2.17",
"author": "thirdweb eng <[email protected]>",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native-compat",
"license": "Apache-2.0",
+21
View File
@@ -1,5 +1,26 @@
# @thirdweb-dev/react-native
## 0.2.17
### Patch Changes
- Updated dependencies [[`ce36322b`](https://github.com/thirdweb-dev/js/commit/ce36322b383af73905894b73f9409a146359ffb0), [`c60658ed`](https://github.com/thirdweb-dev/js/commit/c60658ed8c94867cca831b0d5535006da5b40aa6), [`aa9e952c`](https://github.com/thirdweb-dev/js/commit/aa9e952cb519a47ed112d2905b1f3787863035b6), [`564eaccf`](https://github.com/thirdweb-dev/js/commit/564eaccf480a81f36db43c782392595a5021e5ac), [`6aee0413`](https://github.com/thirdweb-dev/js/commit/6aee0413439b9ca408879bbb3c38c538c89d01af), [`21627c03`](https://github.com/thirdweb-dev/js/commit/21627c03d1bb1658fee19b12d580faa6c7f048d9), [`2283e71a`](https://github.com/thirdweb-dev/js/commit/2283e71acaaf3d15eb2d6121682f1d2a81eec4f3), [`e93aa70e`](https://github.com/thirdweb-dev/js/commit/e93aa70ef0093a2526404e11b7ddae8fb98c213b), [`51bbd3d1`](https://github.com/thirdweb-dev/js/commit/51bbd3d1bccbb92a1405ea50f6c178c091a90f20), [`9b20fc9a`](https://github.com/thirdweb-dev/js/commit/9b20fc9ad2d303edc31f44fbd2ea3b4dcf35d11e)]:
- @thirdweb-dev/sdk@3.10.20
- @thirdweb-dev/react-core@3.13.0
- @thirdweb-dev/wallets@0.2.25
## 0.2.16
### Patch Changes
- [#1103](https://github.com/thirdweb-dev/js/pull/1103) [`89102b0c`](https://github.com/thirdweb-dev/js/commit/89102b0c895011bb6528d2b9bc4289173b351c8d) Thanks [@iketw](https://github.com/iketw)! - [ReactNative] Fix bug where the wc uri is not being copied in the textinput after scanning it
- Updated dependencies [[`23d90b3e`](https://github.com/thirdweb-dev/js/commit/23d90b3e779a5bfdb7058b8c51349d9c278fcbce), [`cc56037e`](https://github.com/thirdweb-dev/js/commit/cc56037e64560b9e0fc16eb0ac7cc2e47e2c9fdf), [`67450789`](https://github.com/thirdweb-dev/js/commit/67450789473b6008b86453ee4f4c7b99461223a6)]:
- @thirdweb-dev/sdk@3.10.19
- @thirdweb-dev/storage@1.1.4
- @thirdweb-dev/react-core@3.12.4
- @thirdweb-dev/wallets@0.2.24
## 0.2.15
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react-native",
"version": "0.2.15",
"version": "0.2.17",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react-native",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -80,11 +80,11 @@ const ConnectAppField = () => {
};
const onQRCodeScan = (data: string) => {
if (wcUri !== data) {
if (wcUri !== data && data.startsWith("wc:")) {
setWCUri(data);
setShowQRCodeScan(false);
onWCPress();
onWCPress(data);
}
};
@@ -92,13 +92,15 @@ const ConnectAppField = () => {
setShowQRCodeScan(false);
};
const onWCPress = () => {
if (!wcUri || !wallet) {
const onWCPress = (uri?: string) => {
if (!(wcUri || uri) || !wallet) {
return;
}
if (wcUri.startsWith("wc:")) {
(wallet as unknown as IWalletConnectReceiver).connectApp(wcUri);
const uriToUse = uri || wcUri;
if (uriToUse?.startsWith("wc:")) {
(wallet as unknown as IWalletConnectReceiver).connectApp(uriToUse);
}
};
@@ -119,11 +121,12 @@ const ConnectAppField = () => {
<TextInput
onChangeText={onAddressChangeText}
flex={1}
value={wcUri}
placeholder={"wc://..."}
placeholderTextColor={theme.colors.textSecondary}
/>
<BaseButton
onPress={onWCPress}
onPress={() => onWCPress()}
justifyContent="center"
alignItems="center"
>
@@ -12,7 +12,7 @@ export const QRCodeScan = ({
onClose: () => void;
}) => {
return (
<TWModal isVisible={isVisible} backdropOpacity={0.7}>
<TWModal isVisible={isVisible} backdropOpacity={1}>
<ModalHeaderTextClose headerText={"Scan to Connect"} onClose={onClose} />
<RNCamera
style={{ flex: 1 }}
@@ -95,7 +95,7 @@ export const SessionRequestModal = () => {
default:
throw new Error(`Method not implemented: ${requestData.method}`);
}
}, [requestData]);
}, [chain?.chainId, chain?.slug, requestData]);
return (
<Box
+30
View File
@@ -1,5 +1,35 @@
# @thirdweb-dev/react
## 3.13.0
### Patch Changes
- [#1115](https://github.com/thirdweb-dev/js/pull/1115) [`b4c95159`](https://github.com/thirdweb-dev/js/commit/b4c95159377dfaa27b4b9625bc9a828b799d0005) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - Add hooks for smart wallet factory
- [#1116](https://github.com/thirdweb-dev/js/pull/1116) [`356f7aa6`](https://github.com/thirdweb-dev/js/commit/356f7aa6430003bbe8edf9a526bcee77ad5c21ee) Thanks [@MananTank](https://github.com/MananTank)! - - Fix Local wallet connection issue with Safe & Smart Wallet
- Fix Metamask QR connection issue with Safe & Smart Wallet
- [#1118](https://github.com/thirdweb-dev/js/pull/1118) [`9b20fc9a`](https://github.com/thirdweb-dev/js/commit/9b20fc9ad2d303edc31f44fbd2ea3b4dcf35d11e) Thanks [@MananTank](https://github.com/MananTank)! - - Remove chain restriction in paper wallet
- Fix Email validation in Paper and Magic wallet
- [#1114](https://github.com/thirdweb-dev/js/pull/1114) [`2283e71a`](https://github.com/thirdweb-dev/js/commit/2283e71acaaf3d15eb2d6121682f1d2a81eec4f3) Thanks [@adam-maj](https://github.com/adam-maj)! - Update ConnectWallet button with new auth
- Updated dependencies [[`ce36322b`](https://github.com/thirdweb-dev/js/commit/ce36322b383af73905894b73f9409a146359ffb0), [`c60658ed`](https://github.com/thirdweb-dev/js/commit/c60658ed8c94867cca831b0d5535006da5b40aa6), [`aa9e952c`](https://github.com/thirdweb-dev/js/commit/aa9e952cb519a47ed112d2905b1f3787863035b6), [`564eaccf`](https://github.com/thirdweb-dev/js/commit/564eaccf480a81f36db43c782392595a5021e5ac), [`6aee0413`](https://github.com/thirdweb-dev/js/commit/6aee0413439b9ca408879bbb3c38c538c89d01af), [`21627c03`](https://github.com/thirdweb-dev/js/commit/21627c03d1bb1658fee19b12d580faa6c7f048d9), [`2283e71a`](https://github.com/thirdweb-dev/js/commit/2283e71acaaf3d15eb2d6121682f1d2a81eec4f3), [`e93aa70e`](https://github.com/thirdweb-dev/js/commit/e93aa70ef0093a2526404e11b7ddae8fb98c213b), [`51bbd3d1`](https://github.com/thirdweb-dev/js/commit/51bbd3d1bccbb92a1405ea50f6c178c091a90f20), [`9b20fc9a`](https://github.com/thirdweb-dev/js/commit/9b20fc9ad2d303edc31f44fbd2ea3b4dcf35d11e)]:
- @thirdweb-dev/sdk@3.10.20
- @thirdweb-dev/react-core@3.13.0
- @thirdweb-dev/wallets@0.2.25
## 3.12.4
### Patch Changes
- Updated dependencies [[`23d90b3e`](https://github.com/thirdweb-dev/js/commit/23d90b3e779a5bfdb7058b8c51349d9c278fcbce), [`cc56037e`](https://github.com/thirdweb-dev/js/commit/cc56037e64560b9e0fc16eb0ac7cc2e47e2c9fdf)]:
- @thirdweb-dev/sdk@3.10.19
- @thirdweb-dev/react-core@3.12.4
- @thirdweb-dev/wallets@0.2.24
## 3.12.3
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react",
"version": "3.12.3",
"version": "3.13.0",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -6,16 +6,11 @@ import {
UseQueryResult,
useQueryClient,
} from "@tanstack/react-query";
import type { PaperSupportedChainId } from "@thirdweb-dev/wallets/evm/connectors/paper";
export function usePaperWallet() {
const connect = useConnect();
return useCallback(
async (options: {
chainId?: PaperSupportedChainId;
clientId: string;
email?: string;
}) => {
async (options: { chainId?: number; clientId: string; email?: string }) => {
const { paperWallet } = await import(
"../../../wallet/wallets/paperWallet"
);
@@ -20,7 +20,6 @@ import { Button } from "../../components/buttons";
import { Spinner } from "../../components/Spinner";
import styled from "@emotion/styled";
import { fadeInAnimation } from "../../components/FadeIn";
import type { LoginOptions } from "@thirdweb-dev/auth";
import { LockIcon } from "./icons/LockIcon";
import { Flex } from "../../components/basic";
import { shortenAddress } from "../../evm/utils/addresses";
@@ -42,7 +41,6 @@ type ConnectWalletProps = {
detailsBtn?: () => JSX.Element;
dropdownPosition?: DropDownPosition;
auth?: {
loginOptions?: LoginOptions;
loginOptional?: boolean;
onLogin?: (token: string) => void;
onLogout?: () => void;
@@ -86,7 +84,7 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = (props) => {
const signIn = async () => {
try {
setShowSignatureModal(true);
const token = await login(props.auth?.loginOptions);
const token = await login();
props?.auth?.onLogin?.(token);
} catch (err) {
console.error("failed to log in", err);
@@ -31,7 +31,7 @@ export const CreateLocalWallet_Password: React.FC<{
const { localWallet, meta } = useLocalWalletInfo(props.localWalletConf);
const { setConnectedWallet } = useWalletContext();
const { setConnectedWallet, setConnectionStatus } = useWalletContext();
const [showImportScreen, setShowImportScreen] = useState(false);
const [generatedAddress, setGeneratedAddress] = useState<string | null>(null);
@@ -65,7 +65,8 @@ export const CreateLocalWallet_Password: React.FC<{
}
setIsConnecting(true);
localWallet.connect();
setConnectionStatus("connecting");
await localWallet.connect();
await localWallet.save({
strategy: "encryptedJson",
@@ -193,7 +194,7 @@ export const CreateLocalWallet_Guest: React.FC<{
localWallet: LocalWalletConfig;
}> = (props) => {
const { localWallet } = useLocalWalletInfo(props.localWallet);
const { setConnectedWallet } = useWalletContext();
const { setConnectedWallet, setConnectionStatus } = useWalletContext();
const { onConnect } = props;
const handleConnect = useCallback(async () => {
@@ -201,10 +202,11 @@ export const CreateLocalWallet_Guest: React.FC<{
throw new Error("Invalid state");
}
await localWallet.generate();
setConnectionStatus("connecting");
await localWallet.connect();
setConnectedWallet(localWallet);
onConnect();
}, [localWallet, setConnectedWallet, onConnect]);
}, [localWallet, setConnectedWallet, onConnect, setConnectionStatus]);
const connecting = useRef(false);
useEffect(() => {
@@ -31,7 +31,7 @@ export const ImportLocalWallet: React.FC<{
const [showPassword, setShowPassword] = useState(false);
const [importedAddress, setImportedAddress] = useState<string | undefined>();
const { setConnectedWallet } = useWalletContext();
const { setConnectedWallet, setConnectionStatus } = useWalletContext();
const handleImport = async () => {
const localWallet = createWalletInstance(
@@ -52,6 +52,9 @@ export const ImportLocalWallet: React.FC<{
return;
}
setConnectionStatus("connecting");
await localWallet.connect();
await localWallet.save({
strategy: "encryptedJson",
password,
@@ -37,7 +37,7 @@ export const ReconnectLocalWallet: React.FC<ReconnectLocalWalletProps> = (
const [password, setPassword] = useState("");
const [showPassword, setShowPassword] = useState(false);
const [isWrongPassword, setIsWrongPassword] = useState(false);
const { setConnectedWallet } = useWalletContext();
const { setConnectedWallet, setConnectionStatus } = useWalletContext();
const [isConnecting, setIsConnecting] = useState(false);
const [showCreate, setShowCreate] = useState(false);
const [showBackupConfirmation, setShowBackupConfirmation] = useState(false);
@@ -110,6 +110,7 @@ export const ReconnectLocalWallet: React.FC<ReconnectLocalWalletProps> = (
password,
});
setConnectionStatus("connecting");
await localWallet.connect();
setConnectedWallet(localWallet);
@@ -14,7 +14,6 @@ export const localWallet = (
},
connectUI: LocalWalletConnectUI,
isInstalled() {
// TODO
return false;
},
};
@@ -65,7 +65,8 @@ const MagicSelectionUI: React.FC<
const isPhone = Number.isInteger(Number(input[input.length - 1]));
if (isEmail && isEmailEnabled) {
const isValidEmail = input.match(/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/);
const emailRegex = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,})$/g;
const isValidEmail = emailRegex.test(input);
if (!isValidEmail) {
return "Invalid email address";
}
@@ -15,7 +15,8 @@ export const MetamaskScan: React.FC<{
}> = ({ onBack, onConnected, onGetStarted, walletConfig }) => {
const createInstance = useCreateWalletInstance();
const [qrCodeUri, setQrCodeUri] = useState<string | undefined>();
const { setConnectedWallet, chainToConnect } = useWalletContext();
const { setConnectedWallet, chainToConnect, setConnectionStatus } =
useWalletContext();
const scanStarted = useRef(false);
useEffect(() => {
@@ -26,6 +27,7 @@ export const MetamaskScan: React.FC<{
const metamask = createInstance(walletConfig);
setConnectionStatus("connecting");
metamask.connectWithQrCode({
chainId: chainToConnect?.chainId,
onQrCodeUri(uri) {
@@ -42,6 +44,7 @@ export const MetamaskScan: React.FC<{
chainToConnect,
onConnected,
walletConfig,
setConnectionStatus,
]);
return (
@@ -38,7 +38,8 @@ const PaperSelectionUI: React.FC<SelectUIProps<PaperWallet, PaperConfig>> = (
name="email"
type="email"
errorMessage={(input) => {
const isValidEmail = input.match(/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/);
const emailRegex = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,})$/g;
const isValidEmail = emailRegex.test(input);
if (!isValidEmail) {
return "Invalid email address";
}
@@ -238,7 +238,7 @@ export const SelectAccount: React.FC<{
)}
</NetworkSelect>
{!disableNetworkSelection && (
<ChevronDownIcon
<StyledChevronDownIcon
width={iconSize.sm}
height={iconSize.sm}
style={{
@@ -394,3 +394,7 @@ const NetworkSelect = styled.select<{ theme?: Theme }>`
cursor: not-allowed;
}
`;
const StyledChevronDownIcon = styled(ChevronDownIcon)<{ theme?: Theme }>`
color: ${(p) => p.theme.icon.secondary};
`;
+32
View File
@@ -1,5 +1,37 @@
# @thirdweb-dev/sdk
## 3.10.20
### Patch Changes
- [#1104](https://github.com/thirdweb-dev/js/pull/1104) [`ce36322b`](https://github.com/thirdweb-dev/js/commit/ce36322b383af73905894b73f9409a146359ffb0) Thanks [@farhanW3](https://github.com/farhanW3)! - Added getNonce() to User-Wallets, to help with getting the nonce of the wallet. Updated ERC1155 airdrop to use BigNumber to avoid overflow issue
- [#1105](https://github.com/thirdweb-dev/js/pull/1105) [`c60658ed`](https://github.com/thirdweb-dev/js/commit/c60658ed8c94867cca831b0d5535006da5b40aa6) Thanks [@MananTank](https://github.com/MananTank)! - Reduce Circular dependencies
- [#1110](https://github.com/thirdweb-dev/js/pull/1110) [`aa9e952c`](https://github.com/thirdweb-dev/js/commit/aa9e952cb519a47ed112d2905b1f3787863035b6) Thanks [@MananTank](https://github.com/MananTank)! - Reduce circular dependencies
- [#1095](https://github.com/thirdweb-dev/js/pull/1095) [`564eaccf`](https://github.com/thirdweb-dev/js/commit/564eaccf480a81f36db43c782392595a5021e5ac) Thanks [@nkrishang](https://github.com/nkrishang)! - Add SmartWalletFactory extension detection and logic
- [#1112](https://github.com/thirdweb-dev/js/pull/1112) [`6aee0413`](https://github.com/thirdweb-dev/js/commit/6aee0413439b9ca408879bbb3c38c538c89d01af) Thanks [@MananTank](https://github.com/MananTank)! - Reduce circular dependencies
- [#1108](https://github.com/thirdweb-dev/js/pull/1108) [`e93aa70e`](https://github.com/thirdweb-dev/js/commit/e93aa70ef0093a2526404e11b7ddae8fb98c213b) Thanks [@MananTank](https://github.com/MananTank)! - Reduce circular deps
- [#1117](https://github.com/thirdweb-dev/js/pull/1117) [`51bbd3d1`](https://github.com/thirdweb-dev/js/commit/51bbd3d1bccbb92a1405ea50f6c178c091a90f20) Thanks [@MananTank](https://github.com/MananTank)! - Reduce circular dependencies
- Updated dependencies [[`564eaccf`](https://github.com/thirdweb-dev/js/commit/564eaccf480a81f36db43c782392595a5021e5ac)]:
- @thirdweb-dev/contracts-js@1.3.5
## 3.10.19
### Patch Changes
- [#1100](https://github.com/thirdweb-dev/js/pull/1100) [`23d90b3e`](https://github.com/thirdweb-dev/js/commit/23d90b3e779a5bfdb7058b8c51349d9c278fcbce) Thanks [@MananTank](https://github.com/MananTank)! - Reduce circular dependencies
- [#1102](https://github.com/thirdweb-dev/js/pull/1102) [`cc56037e`](https://github.com/thirdweb-dev/js/commit/cc56037e64560b9e0fc16eb0ac7cc2e47e2c9fdf) Thanks [@MananTank](https://github.com/MananTank)! - Reduce circular dependencies
- Updated dependencies [[`67450789`](https://github.com/thirdweb-dev/js/commit/67450789473b6008b86453ee4f4c7b99461223a6)]:
- @thirdweb-dev/storage@1.1.4
## 3.10.18
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/sdk",
"version": "3.10.18",
"version": "3.10.20",
"description": "The main thirdweb SDK.",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/sdk",
"license": "Apache-2.0",
@@ -12,8 +12,12 @@ import { fetchAndCacheDeployMetadata } from "./fetchAndCacheDeployMetadata";
import { isContractDeployed } from "./isContractDeployed";
import { getInitBytecodeWithSalt } from "./getInitBytecodeWithSalt";
import { computeDeploymentAddress } from "./computeDeploymentAddress";
import { BytesLike, ethers } from "ethers";
import { getNativeTokenByChainId } from "../../constants/currency";
import { PreDeployMetadataFetched } from "../../schema/contracts/custom";
import { ConstructorParamMap } from "../../types/any-evm/deploy-data";
import { extractConstructorParamsFromAbi } from "../feature-detection/extractConstructorParamsFromAbi";
import { caches } from "./caches";
import { encodeConstructorParamsForImplementation } from "./encodeConstructorParamsForImplementation";
export async function computeDeploymentInfo(
contractType: DeployedContractType,
@@ -90,3 +94,109 @@ export async function computeDeploymentInfo(
encodedArgs,
};
}
/**
* @internal
*
* Determine constructor params required by an implementation contract.
* Return abi-encoded params.
*/
export async function encodeConstructorParamsForImplementation(
compilerMetadata: PreDeployMetadataFetched,
provider: providers.Provider,
storage: ThirdwebStorage,
create2Factory: string,
constructorParamMap?: ConstructorParamMap,
): Promise<BytesLike> {
const constructorParams = extractConstructorParamsFromAbi(
compilerMetadata.abi,
);
let constructorParamTypes = constructorParams.map((p) => {
if (p.type === "tuple[]") {
return ethers.utils.ParamType.from(p);
} else {
return p.type;
}
});
const constructorParamValues = await Promise.all(
constructorParams.map(async (p) => {
if (constructorParamMap && constructorParamMap[p.name]) {
if (constructorParamMap[p.name].type) {
invariant(
constructorParamMap[p.name].type === p.type,
`Provided type ${
constructorParamMap[p.name].type
} doesn't match the actual type ${p.type} from Abi`,
);
}
return constructorParamMap[p.name].value;
}
if (p.name && p.name.includes("nativeTokenWrapper")) {
const chainId = (await provider.getNetwork()).chainId;
let nativeTokenWrapperAddress =
getNativeTokenByChainId(chainId).wrapped.address;
if (nativeTokenWrapperAddress === ethers.constants.AddressZero) {
const deploymentInfo = await computeDeploymentInfo(
"infra",
provider,
storage,
create2Factory,
{
contractName: "WETH9",
},
);
if (!caches.deploymentPresets["WETH9"]) {
caches.deploymentPresets["WETH9"] = deploymentInfo;
}
nativeTokenWrapperAddress =
deploymentInfo.transaction.predictedAddress;
}
return nativeTokenWrapperAddress;
} else if (p.name && p.name.includes("trustedForwarder")) {
if (compilerMetadata.name === "Pack") {
// EOAForwarder for Pack
const deploymentInfo = await computeDeploymentInfo(
"infra",
provider,
storage,
create2Factory,
{
contractName: "ForwarderEOAOnly",
},
);
if (!caches.deploymentPresets["ForwarderEOAOnly"]) {
caches.deploymentPresets["ForwarderEOAOnly"] = deploymentInfo;
}
return deploymentInfo.transaction.predictedAddress;
}
const deploymentInfo = await computeDeploymentInfo(
"infra",
provider,
storage,
create2Factory,
{
contractName: "Forwarder",
},
);
if (!caches.deploymentPresets["Forwarder"]) {
caches.deploymentPresets["Forwarder"] = deploymentInfo;
}
return deploymentInfo.transaction.predictedAddress;
} else {
throw new Error("Can't resolve constructor arguments");
}
}),
);
const encodedArgs = ethers.utils.defaultAbiCoder.encode(
constructorParamTypes,
constructorParamValues,
);
return encodedArgs;
}
@@ -1,115 +0,0 @@
import { ThirdwebStorage } from "@thirdweb-dev/storage";
import { BytesLike, ethers, providers } from "ethers";
import invariant from "tiny-invariant";
import { getNativeTokenByChainId } from "../../constants/currency";
import { PreDeployMetadataFetched } from "../../schema/contracts/custom";
import { ConstructorParamMap } from "../../types/any-evm/deploy-data";
import { extractConstructorParamsFromAbi } from "../feature-detection/extractConstructorParamsFromAbi";
import { caches } from "./caches";
import { computeDeploymentInfo } from "./computeDeploymentInfo";
/**
* @internal
*
* Determine constructor params required by an implementation contract.
* Return abi-encoded params.
*/
export async function encodeConstructorParamsForImplementation(
compilerMetadata: PreDeployMetadataFetched,
provider: providers.Provider,
storage: ThirdwebStorage,
create2Factory: string,
constructorParamMap?: ConstructorParamMap,
): Promise<BytesLike> {
const constructorParams = extractConstructorParamsFromAbi(
compilerMetadata.abi,
);
let constructorParamTypes = constructorParams.map((p) => {
if (p.type === "tuple[]") {
return ethers.utils.ParamType.from(p);
} else {
return p.type;
}
});
const constructorParamValues = await Promise.all(
constructorParams.map(async (p) => {
if (constructorParamMap && constructorParamMap[p.name]) {
if (constructorParamMap[p.name].type) {
invariant(
constructorParamMap[p.name].type === p.type,
`Provided type ${
constructorParamMap[p.name].type
} doesn't match the actual type ${p.type} from Abi`,
);
}
return constructorParamMap[p.name].value;
}
if (p.name && p.name.includes("nativeTokenWrapper")) {
const chainId = (await provider.getNetwork()).chainId;
let nativeTokenWrapperAddress =
getNativeTokenByChainId(chainId).wrapped.address;
if (nativeTokenWrapperAddress === ethers.constants.AddressZero) {
const deploymentInfo = await computeDeploymentInfo(
"infra",
provider,
storage,
create2Factory,
{
contractName: "WETH9",
},
);
if (!caches.deploymentPresets["WETH9"]) {
caches.deploymentPresets["WETH9"] = deploymentInfo;
}
nativeTokenWrapperAddress =
deploymentInfo.transaction.predictedAddress;
}
return nativeTokenWrapperAddress;
} else if (p.name && p.name.includes("trustedForwarder")) {
if (compilerMetadata.name === "Pack") {
// EOAForwarder for Pack
const deploymentInfo = await computeDeploymentInfo(
"infra",
provider,
storage,
create2Factory,
{
contractName: "ForwarderEOAOnly",
},
);
if (!caches.deploymentPresets["ForwarderEOAOnly"]) {
caches.deploymentPresets["ForwarderEOAOnly"] = deploymentInfo;
}
return deploymentInfo.transaction.predictedAddress;
}
const deploymentInfo = await computeDeploymentInfo(
"infra",
provider,
storage,
create2Factory,
{
contractName: "Forwarder",
},
);
if (!caches.deploymentPresets["Forwarder"]) {
caches.deploymentPresets["Forwarder"] = deploymentInfo;
}
return deploymentInfo.transaction.predictedAddress;
} else {
throw new Error("Can't resolve constructor arguments");
}
}),
);
const encodedArgs = ethers.utils.defaultAbiCoder.encode(
constructorParamTypes,
constructorParamValues,
);
return encodedArgs;
}
@@ -8,7 +8,7 @@ import { DEFAULT_API_KEY } from "../../../core/constants/urls";
import { fetchAndCachePublishedContractURI } from "./fetchAndCachePublishedContractURI";
import { fetchAndCacheDeployMetadata } from "./fetchAndCacheDeployMetadata";
import { getCreate2FactoryAddress } from "./getCreate2FactoryAddress";
import { encodeConstructorParamsForImplementation } from "./encodeConstructorParamsForImplementation";
import { encodeConstructorParamsForImplementation } from "./computeDeploymentInfo";
import { getDeploymentInfo } from "./getDeploymentInfo";
/**
@@ -1,6 +1,6 @@
import { NATIVE_TOKEN_ADDRESS } from "../../constants/currency";
import { ContractWrapper } from "../../core/classes/contract-wrapper";
import { Address } from "../../schema/shared";
import { Address } from "../../schema/shared/Address";
import { Price } from "../../types";
import { BigNumberish, CallOverrides } from "ethers";
import { approveErc20Allowance } from "../currency/approveErc20Allowance";
+2 -2
View File
@@ -1,4 +1,4 @@
import { getDefaultTrustedForwarders } from "../constants/addresses";
import { getDefaultTrustedForwarders } from "../constants/addresses/getDefaultTrustedForwarders";
import {
PackInitializer,
NFTDropInitializer,
@@ -17,7 +17,7 @@ import {
import { BigNumber, Signer, providers } from "ethers";
import { z } from "zod";
import { ThirdwebStorage } from "@thirdweb-dev/storage";
import { SUPPORTED_CHAIN_IDS } from "../constants/chains";
import { SUPPORTED_CHAIN_IDS } from "../constants/chains/SUPPORTED_CHAIN_IDS";
import { computeForwarderAddress } from "./any-evm-utils/computeForwarderAddress";
import type {
PrebuiltContractType,
@@ -0,0 +1,11 @@
import {
AddressOrEns,
AddressOrEnsSchema,
} from "../../schema/shared/AddressOrEnsSchema";
import { Address } from "../../schema/shared/Address";
export async function resolveAddress(
addressOrEns: AddressOrEns,
): Promise<Address> {
return AddressOrEnsSchema.parseAsync(addressOrEns);
}
@@ -1,5 +1,4 @@
import { getSignerAndProvider } from "../functions/getSignerAndProvider";
import { Address, AddressOrEns, AddressOrEnsSchema } from "../schema/shared";
import { getSignerAndProvider } from "../../constants/urls";
import type { providers } from "ethers";
type CachedEns = {
@@ -53,9 +52,3 @@ export async function resolveEns(
}
return resolvedPromise.address;
}
export async function resolveAddress(
addressOrEns: AddressOrEns,
): Promise<Address> {
return AddressOrEnsSchema.parseAsync(addressOrEns);
}
+1 -1
View File
@@ -1,4 +1,4 @@
import { SUPPORTED_CHAIN_ID } from "../constants/chains";
import { SUPPORTED_CHAIN_ID } from "../constants/chains/SUPPORTED_CHAIN_ID";
import { NATIVE_TOKENS } from "../constants/currency";
import { Feature } from "../constants/contract-features";
import { ContractSource } from "../schema/contracts/custom";
+1 -1
View File
@@ -1,4 +1,4 @@
import { ChainId } from "../constants/chains";
import { ChainId } from "../constants/chains/ChainId";
import fetch from "cross-fetch";
import { BigNumber, ethers } from "ethers";
+4 -3
View File
@@ -68,7 +68,6 @@ export * from "./any-evm-utils/deployContractDeterministic";
export * from "./any-evm-utils/getDeploymentInfo";
export * from "./any-evm-utils/deployWithThrowawayDeployer";
export * from "./any-evm-utils/computeDeploymentInfo";
export * from "./any-evm-utils/encodeConstructorParamsForImplementation";
export * from "./any-evm-utils/convertParamValues";
export * from "./any-evm-utils/getCreate2FactoryDeploymentInfo";
export * from "./any-evm-utils/fetchAndCachePublishedContractURI";
@@ -83,5 +82,7 @@ export { convertToReadableQuantity } from "./claim-conditions/convertToReadableQ
export { fetchSnapshotEntryForAddress } from "./claim-conditions/fetchSnapshotEntryForAddress";
export { getCachedAbiForContract } from "./abi";
export * from "./ens";
export { prepareGaslessRequest } from "./transactions";
// ens
export * from "./ens/resolveEns";
export * from "./ens/resolveAddress";
@@ -6,7 +6,7 @@ import {
ContractInfoSchema,
ContractSource,
} from "../schema/contracts/custom";
import { Address } from "../schema/shared";
import { Address } from "../schema/shared/Address";
import { resolveContractUriFromAddress } from "./feature-detection/resolveContractUriFromAddress";
import { ThirdwebStorage } from "@thirdweb-dev/storage";
import { providers } from "ethers";
@@ -0,0 +1,17 @@
import { SnapshotInputSchema } from "../schema/contracts/common/snapshots";
import { SnapshotInput } from "../types/claim-conditions/claim-conditions";
export async function parseSnapshotInputs(inputs: SnapshotInput) {
const chunkSize = 25000;
const chunks = Array.from(
{ length: Math.ceil(inputs.length / chunkSize) },
(_, i) => inputs.slice(i * chunkSize, i * chunkSize + chunkSize),
);
const results = [];
for (const chunk of chunks) {
results.push(...(await SnapshotInputSchema.parseAsync(chunk)));
}
return results;
}
@@ -1,4 +1,4 @@
import { Address } from "../../schema/shared";
import { Address } from "../../schema/shared/Address";
import { Abi } from "../../schema/contracts/custom";
import { fetchContractMetadataFromAddress } from "../metadata-resolver";
import { ThirdwebStorage } from "@thirdweb-dev/storage";
@@ -12,7 +12,7 @@ import { fetchCurrencyMetadata } from "./currency/fetchCurrencyMetadata";
import { ThirdwebStorage } from "@thirdweb-dev/storage";
import { ethers, utils } from "ethers";
import { MerkleTree } from "merkletreejs";
import { parseSnapshotInputs } from "./snapshots";
import { parseSnapshotInputs } from "./parseSnapshotInputs";
// shard using the first 2 hex character of the address
// this splits the merkle tree into 256 shards
+1 -16
View File
@@ -1,4 +1,3 @@
import { SnapshotInputSchema } from "../schema/contracts/common/snapshots";
import {
SnapshotInfo,
SnapshotInput,
@@ -10,21 +9,7 @@ import {
} from "./sharded-merkle-tree";
import { ThirdwebStorage } from "@thirdweb-dev/storage";
import { ethers } from "ethers";
export async function parseSnapshotInputs(inputs: SnapshotInput) {
const chunkSize = 25000;
const chunks = Array.from(
{ length: Math.ceil(inputs.length / chunkSize) },
(_, i) => inputs.slice(i * chunkSize, i * chunkSize + chunkSize),
);
const results = [];
for (const chunk of chunks) {
results.push(...(await SnapshotInputSchema.parseAsync(chunk)));
}
return results;
}
import { parseSnapshotInputs } from "./parseSnapshotInputs";
/**
* Create a snapshot (merkle tree) from a list of addresses and uploads it to IPFS
+5 -376
View File
@@ -1,30 +1,8 @@
import { ThirdwebStorage } from "@thirdweb-dev/storage";
import {
CONTRACT_ADDRESSES,
getContractAddressByChainId,
} from "../constants/addresses";
import { DeployTransaction, Transaction } from "../core/classes/transactions";
import {
ForwardRequestMessage,
GaslessTransaction,
PermitRequestMessage,
TransactionResult,
} from "../core/types";
import { SDKOptionsOutput } from "../schema/sdk-options";
import { computeEOAForwarderAddress } from "./any-evm-utils/computeEOAForwarderAddress";
import { computeForwarderAddress } from "./any-evm-utils/computeForwarderAddress";
import {
BiconomyForwarderAbi,
ChainAwareForwardRequest,
ForwardRequest,
getAndIncrementNonce,
} from "./forwarder";
import { signEIP2612Permit } from "./permit";
import { signTypedDataInternal } from "./sign";
import ForwarderABI from "@thirdweb-dev/contracts-js/dist/abis/Forwarder.json";
import fetch from "cross-fetch";
import { BigNumber, BytesLike, ethers } from "ethers";
import invariant from "tiny-invariant";
import type {
DeployTransaction,
Transaction,
} from "../core/classes/transactions";
import type { TransactionResult } from "../core/types";
export function buildDeployTransactionFunction<TArgs extends any[]>(
fn: (...args: TArgs) => Promise<DeployTransaction>,
@@ -50,352 +28,3 @@ export function buildTransactionFunction<
executeFn.prepare = fn;
return executeFn;
}
export async function defaultGaslessSendFunction(
transaction: GaslessTransaction,
signer: ethers.Signer,
provider: ethers.providers.Provider,
storage: ThirdwebStorage,
gaslessOptions?: SDKOptionsOutput["gasless"],
): Promise<string> {
if (gaslessOptions && "biconomy" in gaslessOptions) {
return biconomySendFunction(transaction, signer, provider, gaslessOptions);
}
return defenderSendFunction(
transaction,
signer,
provider,
storage,
gaslessOptions,
);
}
export async function prepareGaslessRequest(tx: Transaction) {
// @ts-expect-error
const gaslessTx = await tx.prepareGasless();
const gaslessOptions = tx.getGaslessOptions();
if (gaslessOptions && "biconomy" in gaslessOptions) {
const request = await biconomyPrepareRequest(
gaslessTx,
// @ts-expect-error
tx.signer,
// @ts-expect-error
tx.provider,
gaslessOptions,
);
return {
url: "https://api.biconomy.io/api/v2/meta-tx/native",
...request,
};
} else {
invariant(
gaslessOptions && "openzeppelin" in gaslessOptions,
"calling openzeppelin gasless transaction without openzeppelin config in the SDK options",
);
const request = await defenderPrepareRequest(
gaslessTx,
// @ts-expect-error
tx.signer,
// @ts-expect-error
tx.provider,
// @ts-expect-error
tx.storage,
gaslessOptions,
);
return {
url: gaslessOptions.openzeppelin.relayerUrl,
...request,
};
}
}
async function biconomyPrepareRequest(
transaction: GaslessTransaction,
signer: ethers.Signer,
provider: ethers.providers.Provider,
gaslessOptions?: SDKOptionsOutput["gasless"],
) {
invariant(
gaslessOptions && "biconomy" in gaslessOptions,
"calling biconomySendFunction without biconomy",
);
invariant(signer && provider, "signer and provider must be set");
const forwarder = new ethers.Contract(
getContractAddressByChainId(
transaction.chainId,
"biconomyForwarder",
) as string,
BiconomyForwarderAbi,
provider,
);
const batchId = 0;
const batchNonce = await getAndIncrementNonce(forwarder, "getNonce", [
transaction.from,
batchId,
]);
const request = {
from: transaction.from,
to: transaction.to,
token: ethers.constants.AddressZero,
txGas: transaction.gasLimit.toNumber(),
tokenGasPrice: "0",
batchId,
batchNonce: batchNonce.toNumber(),
deadline: Math.floor(
Date.now() / 1000 +
((gaslessOptions &&
"biconomy" in gaslessOptions &&
gaslessOptions.biconomy?.deadlineSeconds) ||
3600),
),
data: transaction.data,
};
const hashToSign = ethers.utils.arrayify(
ethers.utils.solidityKeccak256(
[
"address",
"address",
"address",
"uint256",
"uint256",
"uint256",
"uint256",
"uint256",
"bytes32",
],
[
request.from,
request.to,
request.token,
request.txGas,
request.tokenGasPrice,
request.batchId,
request.batchNonce,
request.deadline,
ethers.utils.keccak256(request.data),
],
),
);
const signature = await signer.signMessage(hashToSign);
return {
method: "POST",
body: JSON.stringify({
from: transaction.from,
apiId: gaslessOptions.biconomy.apiId,
params: [request, signature],
to: transaction.to,
gasLimit: transaction.gasLimit.toHexString(),
}),
headers: {
"x-api-key": gaslessOptions.biconomy.apiKey,
"Content-Type": "application/json;charset=utf-8",
},
};
}
export async function biconomySendFunction(
transaction: GaslessTransaction,
signer: ethers.Signer,
provider: ethers.providers.Provider,
gaslessOptions?: SDKOptionsOutput["gasless"],
): Promise<string> {
const request = await biconomyPrepareRequest(
transaction,
signer,
provider,
gaslessOptions,
);
const response = await fetch(
"https://api.biconomy.io/api/v2/meta-tx/native",
request,
);
if (response.ok) {
const resp = await response.json();
if (!resp.txHash) {
throw new Error(`relay transaction failed: ${resp.log}`);
}
return resp.txHash;
}
throw new Error(
`relay transaction failed with status: ${response.status} (${response.statusText})`,
);
}
async function defenderPrepareRequest(
transaction: GaslessTransaction,
signer: ethers.Signer,
provider: ethers.providers.Provider,
storage: ThirdwebStorage,
gaslessOptions?: SDKOptionsOutput["gasless"],
) {
invariant(
gaslessOptions && "openzeppelin" in gaslessOptions,
"calling openzeppelin gasless transaction without openzeppelin config in the SDK options",
);
invariant(signer, "provider is not set");
invariant(provider, "provider is not set");
const forwarderAddress =
gaslessOptions.openzeppelin.relayerForwarderAddress ||
(gaslessOptions.openzeppelin.useEOAForwarder
? CONTRACT_ADDRESSES[
transaction.chainId as keyof typeof CONTRACT_ADDRESSES
].openzeppelinForwarderEOA ||
(await computeEOAForwarderAddress(provider, storage))
: CONTRACT_ADDRESSES[
transaction.chainId as keyof typeof CONTRACT_ADDRESSES
].openzeppelinForwarder ||
(await computeForwarderAddress(provider, storage)));
const forwarder = new ethers.Contract(
forwarderAddress,
ForwarderABI,
provider,
);
const nonce = await getAndIncrementNonce(forwarder, "getNonce", [
transaction.from,
]);
let domain;
let types;
let message: ForwardRequestMessage | PermitRequestMessage;
if (gaslessOptions.experimentalChainlessSupport) {
domain = {
name: "GSNv2 Forwarder",
version: "0.0.1",
verifyingContract: forwarderAddress,
};
types = {
ForwardRequest: ChainAwareForwardRequest,
};
message = {
from: transaction.from,
to: transaction.to,
value: BigNumber.from(0).toString(),
gas: BigNumber.from(transaction.gasLimit).toString(),
nonce: BigNumber.from(nonce).toString(),
data: transaction.data,
chainid: BigNumber.from(transaction.chainId).toString(),
};
} else {
domain = {
name: gaslessOptions.openzeppelin.domainName,
version: gaslessOptions.openzeppelin.domainVersion,
chainId: transaction.chainId,
verifyingContract: forwarderAddress,
};
types = {
ForwardRequest,
};
message = {
from: transaction.from,
to: transaction.to,
value: BigNumber.from(0).toString(),
gas: BigNumber.from(transaction.gasLimit).toString(),
nonce: BigNumber.from(nonce).toString(),
data: transaction.data,
};
}
let signature: BytesLike;
// if the executing function is "approve" and matches with erc20 approve signature
// and if the token supports permit, then we use permit for gasless instead of approve.
if (
transaction.functionName === "approve" &&
transaction.functionArgs.length === 2
) {
const spender = transaction.functionArgs[0];
const amount = transaction.functionArgs[1];
// TODO: support DAI permit by signDAIPermit
const { message: permit, signature: sig } = await signEIP2612Permit(
signer,
transaction.to,
transaction.from,
spender,
amount,
);
const { r, s, v } = ethers.utils.splitSignature(sig);
message = {
to: transaction.to,
owner: permit.owner,
spender: permit.spender,
value: BigNumber.from(permit.value).toString(),
nonce: BigNumber.from(permit.nonce).toString(),
deadline: BigNumber.from(permit.deadline).toString(),
r,
s,
v,
};
signature = sig;
} else {
const { signature: sig } = await signTypedDataInternal(
signer,
domain,
types,
message,
);
signature = sig;
}
let messageType = "forward";
// if has owner property then it's permit :)
if ((message as PermitRequestMessage)?.owner) {
messageType = "permit";
}
return {
method: "POST",
body: JSON.stringify({
request: message,
signature,
forwarderAddress,
type: messageType,
}),
};
}
export async function defenderSendFunction(
transaction: GaslessTransaction,
signer: ethers.Signer,
provider: ethers.providers.Provider,
storage: ThirdwebStorage,
gaslessOptions?: SDKOptionsOutput["gasless"],
): Promise<string> {
invariant(
gaslessOptions && "openzeppelin" in gaslessOptions,
"calling openzeppelin gasless transaction without openzeppelin config in the SDK options",
);
const request = await defenderPrepareRequest(
transaction,
signer,
provider,
storage,
gaslessOptions,
);
const response = await fetch(gaslessOptions.openzeppelin.relayerUrl, request);
if (response.ok) {
const resp = await response.json();
if (!resp.result) {
throw new Error(`Relay transaction failed: ${resp.message}`);
}
const result = JSON.parse(resp.result);
return result.txHash;
}
throw new Error(
`relay transaction failed with status: ${response.status} (${response.statusText})`,
);
}
-363
View File
@@ -1,363 +0,0 @@
import type { PrebuiltContractType } from "../contracts";
import { ChainId, SUPPORTED_CHAIN_ID, SUPPORTED_CHAIN_IDS } from "./chains";
import { constants } from "ethers";
/**
* publicly available wallet for local nodes
*/
export const LOCAL_NODE_PKEY =
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
/**
* @internal
*/
export const OZ_DEFENDER_FORWARDER_ADDRESS =
"0xc82BbE41f2cF04e3a8efA18F7032BDD7f6d98a81";
const TWRegistry_address = "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd";
const TWFactory_address = "0x5DBC7B840baa9daBcBe9D2492E45D7244B54A2A0";
const ContractPublisher_address = "0x664244560eBa21Bf82d7150C791bE1AbcD5B4cd7"; // Polygon only
const MultichainRegistry_address = "0xcdAD8FA86e18538aC207872E8ff3536501431B73"; // Polygon only
/**
* @internal
*/
export const CONTRACT_ADDRESSES: Record<
SUPPORTED_CHAIN_ID,
{
openzeppelinForwarder: string;
openzeppelinForwarderEOA: string;
biconomyForwarder: string;
twFactory: string;
twRegistry: string;
twBYOCRegistry: string;
}
> = {
[ChainId.Mainnet]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0x76ce2CB1Ae48Fa067f4fb8c5f803111AE0B24BEA",
biconomyForwarder: "0x84a0856b038eaAd1cC7E297cF34A7e72685A8693",
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
twBYOCRegistry: constants.AddressZero,
},
[ChainId.Goerli]: {
openzeppelinForwarder: "0x5001A14CA6163143316a7C614e30e6041033Ac20",
openzeppelinForwarderEOA: "0xe73c50cB9c5B378627ff625BB6e6725A4A5D65d2",
biconomyForwarder: "0xE041608922d06a4F26C0d4c27d8bCD01daf1f792",
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
twBYOCRegistry: "0xB1Bd9d7942A250BA2Dce27DD601F2ED4211A60C4",
},
[ChainId.Polygon]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0x4f247c69184ad61036EC2Bb3213b69F10FbEDe1F",
biconomyForwarder: "0x86C80a8aa58e0A4fa09A69624c31Ab2a6CAD56b8",
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
twBYOCRegistry: "0x308473Be900F4185A56587dE54bDFF5E8f7a6AE7",
},
[ChainId.Mumbai]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0xb1A2883fc4d287d9cB8Dbb96cFF60C76BEf2D250",
biconomyForwarder: "0x9399BB24DBB5C4b782C70c2969F58716Ebbd6a3b",
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
twBYOCRegistry: "0x3F17972CB27506eb4a6a3D59659e0B57a43fd16C",
},
[ChainId.Avalanche]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0xb1A2883fc4d287d9cB8Dbb96cFF60C76BEf2D250",
biconomyForwarder: "0x64CD353384109423a966dCd3Aa30D884C9b2E057",
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
twBYOCRegistry: constants.AddressZero,
},
[ChainId.AvalancheFujiTestnet]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0xe73c50cB9c5B378627ff625BB6e6725A4A5D65d2",
biconomyForwarder: "0x6271Ca63D30507f2Dcbf99B52787032506D75BBF",
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
twBYOCRegistry: "0x3E6eE864f850F5e5A98bc950B68E181Cf4010F23",
},
[ChainId.Fantom]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0xb1A2883fc4d287d9cB8Dbb96cFF60C76BEf2D250",
biconomyForwarder: "0x64CD353384109423a966dCd3Aa30D884C9b2E057",
twFactory: "0x97EA0Fcc552D5A8Fb5e9101316AAd0D62Ea0876B",
twRegistry: TWRegistry_address,
twBYOCRegistry: constants.AddressZero,
},
[ChainId.FantomTestnet]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0x42D3048b595B6e1c28a588d70366CcC2AA4dB47b",
biconomyForwarder: "0x69FB8Dca8067A5D38703b9e8b39cf2D51473E4b4",
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
twBYOCRegistry: "0x3E6eE864f850F5e5A98bc950B68E181Cf4010F23",
},
[ChainId.Arbitrum]: {
openzeppelinForwarder: "0x4a8AC7f22DeD2CF923A51e4A1c67490bd8868add",
openzeppelinForwarderEOA: "0x4f247c69184ad61036EC2Bb3213b69F10FbEDe1F",
biconomyForwarder: "0xfe0fa3C06d03bDC7fb49c892BbB39113B534fB57",
twFactory: "0xd24b3de085CFd8c54b94feAD08a7962D343E6DE0",
twRegistry: "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd",
twBYOCRegistry: constants.AddressZero,
},
[ChainId.ArbitrumGoerli]: {
openzeppelinForwarder: "0x8cbc8B5d71702032904750A66AEfE8B603eBC538",
openzeppelinForwarderEOA: "0x119704314Ef304EaAAE4b3c7C9ABd59272A28310",
biconomyForwarder: constants.AddressZero,
twFactory: "0xd24b3de085CFd8c54b94feAD08a7962D343E6DE0",
twRegistry: "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd",
twBYOCRegistry: constants.AddressZero,
},
[ChainId.Optimism]: {
openzeppelinForwarder: "0xd85da690EF288A6976DE0E85Fb2Aad512eBAfbf7",
openzeppelinForwarderEOA: "0x7e80648EB2071E26937F9D42A513ccf4815fc702",
biconomyForwarder: "0xefba8a2a82ec1fb1273806174f5e28fbb917cf95",
twFactory: "0xd24b3de085CFd8c54b94feAD08a7962D343E6DE0",
twRegistry: "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd",
twBYOCRegistry: constants.AddressZero,
},
[ChainId.OptimismGoerli]: {
openzeppelinForwarder: "0x8cbc8B5d71702032904750A66AEfE8B603eBC538",
openzeppelinForwarderEOA: "0x119704314Ef304EaAAE4b3c7C9ABd59272A28310",
biconomyForwarder: constants.AddressZero,
twFactory: "0xd24b3de085CFd8c54b94feAD08a7962D343E6DE0",
twRegistry: "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd",
twBYOCRegistry: constants.AddressZero,
},
[ChainId.BinanceSmartChainMainnet]: {
openzeppelinForwarder: "0x7C4717039B89d5859c4Fbb85EDB19A6E2ce61171",
openzeppelinForwarderEOA: "0xE8dd2Ff0212F86d3197b4AfDC6dAC6ac47eb10aC",
biconomyForwarder: "0x86C80a8aa58e0A4fa09A69624c31Ab2a6CAD56b8",
twBYOCRegistry: constants.AddressZero,
twFactory: "0xd24b3de085CFd8c54b94feAD08a7962D343E6DE0",
twRegistry: "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd",
},
[ChainId.BinanceSmartChainTestnet]: {
openzeppelinForwarder: "0x44bE9D54B9C8b5e57a3325E8Ec9154640e7c6955",
openzeppelinForwarderEOA: "0x7e80648EB2071E26937F9D42A513ccf4815fc702",
biconomyForwarder: "0x61456BF1715C1415730076BB79ae118E806E74d2",
twBYOCRegistry: constants.AddressZero,
twFactory: "0xd24b3de085CFd8c54b94feAD08a7962D343E6DE0",
twRegistry: "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd",
},
[ChainId.Hardhat]: {
openzeppelinForwarder: constants.AddressZero,
openzeppelinForwarderEOA: constants.AddressZero,
biconomyForwarder: constants.AddressZero,
twFactory: constants.AddressZero,
twRegistry: constants.AddressZero,
twBYOCRegistry: constants.AddressZero,
},
[ChainId.Localhost]: {
openzeppelinForwarder: constants.AddressZero,
openzeppelinForwarderEOA: constants.AddressZero,
biconomyForwarder: constants.AddressZero,
twFactory: constants.AddressZero,
twRegistry: constants.AddressZero,
twBYOCRegistry: constants.AddressZero,
},
};
type DropContract = Extract<
PrebuiltContractType,
"nft-drop" | "token-drop" | "edition-drop" | "signature-drop"
>;
// @deprecated - should not be needed anymore, rely on the publish data instead
export const APPROVED_IMPLEMENTATIONS: Record<
SUPPORTED_CHAIN_ID,
Record<DropContract, string>
> = {
[ChainId.Mainnet]: {
"nft-drop": "0x60fF9952e0084A6DEac44203838cDC91ABeC8736",
"edition-drop": "0x74af262d0671F378F97a1EDC3d0970Dbe8A1C550",
"token-drop": "0xE1eE43D23f247b6A9aF81fcE2766E76709482728",
"signature-drop": "0x6fD690EB509BdE4C50028C5D9C0dE3750C2Fad6A",
},
[ChainId.Polygon]: {
"nft-drop": "0xB96508050Ba0925256184103560EBADA912Fcc69",
"edition-drop": "0x74af262d0671F378F97a1EDC3d0970Dbe8A1C550",
"token-drop": "0x5A8eA4Adad8289746D073947BA06D69A62499aaf",
"signature-drop": "0xBE2fDc35410E268e41Bec62DBb01AEb43245c7d5",
},
[ChainId.Fantom]: {
"nft-drop": "0x2A396b2D90BAcEF19cDa973586B2633d22710fC2",
"edition-drop": "0x06395FCF9AC6ED827f9dD6e776809cEF1Be0d21B",
"token-drop": "0x0148b28a38efaaC31b6aa0a6D9FEb70FE7C91FFa",
"signature-drop": "0xe135Ef65C2B2213C3fD56d0Bd6500A2cA147aC10",
},
[ChainId.Avalanche]: {
"nft-drop": "0x9cF91118C8ee2913F0588e0F10e36B3d63F68bF6",
"edition-drop": "0x135fC9D26E5eC51260ece1DF4ED424E2f55c7766",
"token-drop": "0xca0B071899E575BA86495D46c5066971b6f3A901",
"signature-drop": "0x1d47526C3292B0130ef0afD5F02c1DA052A017B3",
},
[ChainId.Optimism]: {
"nft-drop": "0xFBd7D24d80ee005671E731a7287DEB6073264dD1",
"edition-drop": "0xe135Ef65C2B2213C3fD56d0Bd6500A2cA147aC10",
"token-drop": "0x902Dd246e66d8C3CE652375a723F2a52b43b9AAE",
"signature-drop": "0x8a4cd3549e548bbEEb38C16E041FFf040a5acabD",
},
[ChainId.Arbitrum]: {
"nft-drop": "0xC4903c1Ff5367b9ac2c349B63DC2409421AaEE2a",
"edition-drop": "0xCcddcec1831646Beff2753249f1B9C580327E89F",
"token-drop": "0x1b5947e1a2d5a29D0df20931DeAB0B87818209B9",
"signature-drop": "0x2dF9851af45dd41C8584ac55D983C604da985Bc7",
},
[ChainId.BinanceSmartChainMainnet]: {
"nft-drop": "0x902Dd246e66d8C3CE652375a723F2a52b43b9AAE",
"edition-drop": "0x2A396b2D90BAcEF19cDa973586B2633d22710fC2",
"token-drop": "0xe135Ef65C2B2213C3fD56d0Bd6500A2cA147aC10",
"signature-drop": "0xFBd7D24d80ee005671E731a7287DEB6073264dD1",
},
[ChainId.Goerli]: {
"nft-drop": "0xD11c97DD5F5546B5bBd630D7D1d7327481B0b92C",
"edition-drop": "0x5A8eA4Adad8289746D073947BA06D69A62499aaf",
"token-drop": "0x5680933221B752EB443654a014f88B101F868d50",
"signature-drop": "0x1b5947e1a2d5a29D0df20931DeAB0B87818209B9",
},
[ChainId.Mumbai]: {
"nft-drop": "0xC4903c1Ff5367b9ac2c349B63DC2409421AaEE2a",
"edition-drop": "0xCcddcec1831646Beff2753249f1B9C580327E89F",
"token-drop": "0x1b5947e1a2d5a29D0df20931DeAB0B87818209B9",
"signature-drop": "0x2dF9851af45dd41C8584ac55D983C604da985Bc7",
},
[ChainId.FantomTestnet]: {
"nft-drop": "0x8a4cd3549e548bbEEb38C16E041FFf040a5acabD",
"edition-drop": "0x902Dd246e66d8C3CE652375a723F2a52b43b9AAE",
"token-drop": "0xFBd7D24d80ee005671E731a7287DEB6073264dD1",
"signature-drop": "0x5A8eA4Adad8289746D073947BA06D69A62499aaf",
},
[ChainId.AvalancheFujiTestnet]: {
"nft-drop": "0xD11c97DD5F5546B5bBd630D7D1d7327481B0b92C",
"edition-drop": "0xE1eE43D23f247b6A9aF81fcE2766E76709482728",
"token-drop": "0x6fD690EB509BdE4C50028C5D9C0dE3750C2Fad6A",
"signature-drop": "0xCcddcec1831646Beff2753249f1B9C580327E89F",
},
[ChainId.OptimismGoerli]: {
"nft-drop": "0xCcddcec1831646Beff2753249f1B9C580327E89F",
"edition-drop": "0x6fD690EB509BdE4C50028C5D9C0dE3750C2Fad6A",
"token-drop": "0xD11c97DD5F5546B5bBd630D7D1d7327481B0b92C",
"signature-drop": "0x1b5947e1a2d5a29D0df20931DeAB0B87818209B9",
},
[ChainId.ArbitrumGoerli]: {
"nft-drop": "0x9CfE807a5b124b962064Fa8F7FD823Cc701255b6",
"edition-drop": "0x9cF91118C8ee2913F0588e0F10e36B3d63F68bF6",
"token-drop": "0x1d47526C3292B0130ef0afD5F02c1DA052A017B3",
"signature-drop": "0xE1eE43D23f247b6A9aF81fcE2766E76709482728",
},
[ChainId.BinanceSmartChainTestnet]: {
"nft-drop": "",
"edition-drop": "",
"token-drop": "",
"signature-drop": "", // TODO
},
[ChainId.Hardhat]: {
"nft-drop": "",
"edition-drop": "",
"token-drop": "",
"signature-drop": "", // TODO
},
[ChainId.Localhost]: {
"nft-drop": "",
"edition-drop": "",
"token-drop": "",
"signature-drop": "", // TODO
},
};
/**
* @internal
* @param chainId
* @param contractType
*/
export function getApprovedImplementation(
chainId: SUPPORTED_CHAIN_ID, // TODO use SupportedChainId once we deploy to all chains
contractType: PrebuiltContractType,
): string | null {
if (chainId in APPROVED_IMPLEMENTATIONS) {
const approvedImpls = APPROVED_IMPLEMENTATIONS[chainId];
if (contractType in approvedImpls) {
return approvedImpls[contractType as keyof typeof approvedImpls];
}
}
return null;
}
/**
* @internal
*/
export function getContractAddressByChainId(
chainId: SUPPORTED_CHAIN_ID | ChainId.Hardhat,
contractName: keyof (typeof CONTRACT_ADDRESSES)[SUPPORTED_CHAIN_ID],
): string | undefined {
// for testing only
if (chainId === ChainId.Hardhat || chainId === ChainId.Localhost) {
if (contractName === "twFactory") {
// eslint-disable-next-line turbo/no-undeclared-env-vars
return process.env.factoryAddress as string;
} else if (contractName === "twRegistry") {
// eslint-disable-next-line turbo/no-undeclared-env-vars
return process.env.registryAddress as string;
} else {
return constants.AddressZero;
}
}
// real output here
return CONTRACT_ADDRESSES[chainId]?.[contractName];
}
/**
* @internal
*/
export function getContractPublisherAddress() {
// eslint-disable-next-line turbo/no-undeclared-env-vars
if (process.env.contractPublisherAddress) {
// eslint-disable-next-line turbo/no-undeclared-env-vars
return process.env.contractPublisherAddress as string;
} else {
return ContractPublisher_address;
}
}
/**
* @internal
*/
export function getMultichainRegistryAddress() {
// eslint-disable-next-line turbo/no-undeclared-env-vars
if (process.env.multiChainRegistryAddress) {
// eslint-disable-next-line turbo/no-undeclared-env-vars
return process.env.multiChainRegistryAddress as string;
} else {
return MultichainRegistry_address;
}
}
/**
*
* @param chainId - chain id
* @returns the array of trusted forwarders for the given chain id
* @internal
*/
export function getDefaultTrustedForwarders(
chainId: SUPPORTED_CHAIN_ID,
): string[] {
const chainEnum = SUPPORTED_CHAIN_IDS.find((c) => c === chainId);
const biconomyForwarder = chainEnum
? CONTRACT_ADDRESSES[chainEnum].biconomyForwarder
: constants.AddressZero;
const openzeppelinForwarder = chainEnum
? CONTRACT_ADDRESSES[chainEnum].openzeppelinForwarder
: constants.AddressZero;
return [openzeppelinForwarder, biconomyForwarder].filter(
(a) => a !== constants.AddressZero,
);
}
@@ -0,0 +1,111 @@
import type { PrebuiltContractType } from "../../contracts";
import { SUPPORTED_CHAIN_ID } from "../chains/SUPPORTED_CHAIN_ID";
import { ChainId } from "../chains/ChainId";
type DropContract = Extract<
PrebuiltContractType,
"nft-drop" | "token-drop" | "edition-drop" | "signature-drop"
>;
// @deprecated - should not be needed anymore, rely on the publish data instead
export const APPROVED_IMPLEMENTATIONS: Record<
SUPPORTED_CHAIN_ID,
Record<DropContract, string>
> = {
[ChainId.Mainnet]: {
"nft-drop": "0x60fF9952e0084A6DEac44203838cDC91ABeC8736",
"edition-drop": "0x74af262d0671F378F97a1EDC3d0970Dbe8A1C550",
"token-drop": "0xE1eE43D23f247b6A9aF81fcE2766E76709482728",
"signature-drop": "0x6fD690EB509BdE4C50028C5D9C0dE3750C2Fad6A",
},
[ChainId.Polygon]: {
"nft-drop": "0xB96508050Ba0925256184103560EBADA912Fcc69",
"edition-drop": "0x74af262d0671F378F97a1EDC3d0970Dbe8A1C550",
"token-drop": "0x5A8eA4Adad8289746D073947BA06D69A62499aaf",
"signature-drop": "0xBE2fDc35410E268e41Bec62DBb01AEb43245c7d5",
},
[ChainId.Fantom]: {
"nft-drop": "0x2A396b2D90BAcEF19cDa973586B2633d22710fC2",
"edition-drop": "0x06395FCF9AC6ED827f9dD6e776809cEF1Be0d21B",
"token-drop": "0x0148b28a38efaaC31b6aa0a6D9FEb70FE7C91FFa",
"signature-drop": "0xe135Ef65C2B2213C3fD56d0Bd6500A2cA147aC10",
},
[ChainId.Avalanche]: {
"nft-drop": "0x9cF91118C8ee2913F0588e0F10e36B3d63F68bF6",
"edition-drop": "0x135fC9D26E5eC51260ece1DF4ED424E2f55c7766",
"token-drop": "0xca0B071899E575BA86495D46c5066971b6f3A901",
"signature-drop": "0x1d47526C3292B0130ef0afD5F02c1DA052A017B3",
},
[ChainId.Optimism]: {
"nft-drop": "0xFBd7D24d80ee005671E731a7287DEB6073264dD1",
"edition-drop": "0xe135Ef65C2B2213C3fD56d0Bd6500A2cA147aC10",
"token-drop": "0x902Dd246e66d8C3CE652375a723F2a52b43b9AAE",
"signature-drop": "0x8a4cd3549e548bbEEb38C16E041FFf040a5acabD",
},
[ChainId.Arbitrum]: {
"nft-drop": "0xC4903c1Ff5367b9ac2c349B63DC2409421AaEE2a",
"edition-drop": "0xCcddcec1831646Beff2753249f1B9C580327E89F",
"token-drop": "0x1b5947e1a2d5a29D0df20931DeAB0B87818209B9",
"signature-drop": "0x2dF9851af45dd41C8584ac55D983C604da985Bc7",
},
[ChainId.BinanceSmartChainMainnet]: {
"nft-drop": "0x902Dd246e66d8C3CE652375a723F2a52b43b9AAE",
"edition-drop": "0x2A396b2D90BAcEF19cDa973586B2633d22710fC2",
"token-drop": "0xe135Ef65C2B2213C3fD56d0Bd6500A2cA147aC10",
"signature-drop": "0xFBd7D24d80ee005671E731a7287DEB6073264dD1",
},
[ChainId.Goerli]: {
"nft-drop": "0xD11c97DD5F5546B5bBd630D7D1d7327481B0b92C",
"edition-drop": "0x5A8eA4Adad8289746D073947BA06D69A62499aaf",
"token-drop": "0x5680933221B752EB443654a014f88B101F868d50",
"signature-drop": "0x1b5947e1a2d5a29D0df20931DeAB0B87818209B9",
},
[ChainId.Mumbai]: {
"nft-drop": "0xC4903c1Ff5367b9ac2c349B63DC2409421AaEE2a",
"edition-drop": "0xCcddcec1831646Beff2753249f1B9C580327E89F",
"token-drop": "0x1b5947e1a2d5a29D0df20931DeAB0B87818209B9",
"signature-drop": "0x2dF9851af45dd41C8584ac55D983C604da985Bc7",
},
[ChainId.FantomTestnet]: {
"nft-drop": "0x8a4cd3549e548bbEEb38C16E041FFf040a5acabD",
"edition-drop": "0x902Dd246e66d8C3CE652375a723F2a52b43b9AAE",
"token-drop": "0xFBd7D24d80ee005671E731a7287DEB6073264dD1",
"signature-drop": "0x5A8eA4Adad8289746D073947BA06D69A62499aaf",
},
[ChainId.AvalancheFujiTestnet]: {
"nft-drop": "0xD11c97DD5F5546B5bBd630D7D1d7327481B0b92C",
"edition-drop": "0xE1eE43D23f247b6A9aF81fcE2766E76709482728",
"token-drop": "0x6fD690EB509BdE4C50028C5D9C0dE3750C2Fad6A",
"signature-drop": "0xCcddcec1831646Beff2753249f1B9C580327E89F",
},
[ChainId.OptimismGoerli]: {
"nft-drop": "0xCcddcec1831646Beff2753249f1B9C580327E89F",
"edition-drop": "0x6fD690EB509BdE4C50028C5D9C0dE3750C2Fad6A",
"token-drop": "0xD11c97DD5F5546B5bBd630D7D1d7327481B0b92C",
"signature-drop": "0x1b5947e1a2d5a29D0df20931DeAB0B87818209B9",
},
[ChainId.ArbitrumGoerli]: {
"nft-drop": "0x9CfE807a5b124b962064Fa8F7FD823Cc701255b6",
"edition-drop": "0x9cF91118C8ee2913F0588e0F10e36B3d63F68bF6",
"token-drop": "0x1d47526C3292B0130ef0afD5F02c1DA052A017B3",
"signature-drop": "0xE1eE43D23f247b6A9aF81fcE2766E76709482728",
},
[ChainId.BinanceSmartChainTestnet]: {
"nft-drop": "",
"edition-drop": "",
"token-drop": "",
"signature-drop": "", // TODO
},
[ChainId.Hardhat]: {
"nft-drop": "",
"edition-drop": "",
"token-drop": "",
"signature-drop": "", // TODO
},
[ChainId.Localhost]: {
"nft-drop": "",
"edition-drop": "",
"token-drop": "",
"signature-drop": "", // TODO
},
};
@@ -0,0 +1 @@
export const AddressZero = "0x0000000000000000000000000000000000000000";
@@ -0,0 +1,159 @@
import { ChainId } from "../chains/ChainId";
import { SUPPORTED_CHAIN_ID } from "../chains/SUPPORTED_CHAIN_ID";
import { AddressZero } from "./AddressZero";
const TWRegistry_address = "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd";
const TWFactory_address = "0x5DBC7B840baa9daBcBe9D2492E45D7244B54A2A0";
/**
* @internal
*/
export const OZ_DEFENDER_FORWARDER_ADDRESS =
"0xc82BbE41f2cF04e3a8efA18F7032BDD7f6d98a81";
/**
* @internal
*/
export const CONTRACT_ADDRESSES: Record<
SUPPORTED_CHAIN_ID,
{
openzeppelinForwarder: string;
openzeppelinForwarderEOA: string;
biconomyForwarder: string;
twFactory: string;
twRegistry: string;
twBYOCRegistry: string;
}
> = {
[ChainId.Mainnet]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0x76ce2CB1Ae48Fa067f4fb8c5f803111AE0B24BEA",
biconomyForwarder: "0x84a0856b038eaAd1cC7E297cF34A7e72685A8693",
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
twBYOCRegistry: AddressZero,
},
[ChainId.Goerli]: {
openzeppelinForwarder: "0x5001A14CA6163143316a7C614e30e6041033Ac20",
openzeppelinForwarderEOA: "0xe73c50cB9c5B378627ff625BB6e6725A4A5D65d2",
biconomyForwarder: "0xE041608922d06a4F26C0d4c27d8bCD01daf1f792",
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
twBYOCRegistry: "0xB1Bd9d7942A250BA2Dce27DD601F2ED4211A60C4",
},
[ChainId.Polygon]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0x4f247c69184ad61036EC2Bb3213b69F10FbEDe1F",
biconomyForwarder: "0x86C80a8aa58e0A4fa09A69624c31Ab2a6CAD56b8",
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
twBYOCRegistry: "0x308473Be900F4185A56587dE54bDFF5E8f7a6AE7",
},
[ChainId.Mumbai]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0xb1A2883fc4d287d9cB8Dbb96cFF60C76BEf2D250",
biconomyForwarder: "0x9399BB24DBB5C4b782C70c2969F58716Ebbd6a3b",
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
twBYOCRegistry: "0x3F17972CB27506eb4a6a3D59659e0B57a43fd16C",
},
[ChainId.Avalanche]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0xb1A2883fc4d287d9cB8Dbb96cFF60C76BEf2D250",
biconomyForwarder: "0x64CD353384109423a966dCd3Aa30D884C9b2E057",
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
twBYOCRegistry: AddressZero,
},
[ChainId.AvalancheFujiTestnet]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0xe73c50cB9c5B378627ff625BB6e6725A4A5D65d2",
biconomyForwarder: "0x6271Ca63D30507f2Dcbf99B52787032506D75BBF",
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
twBYOCRegistry: "0x3E6eE864f850F5e5A98bc950B68E181Cf4010F23",
},
[ChainId.Fantom]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0xb1A2883fc4d287d9cB8Dbb96cFF60C76BEf2D250",
biconomyForwarder: "0x64CD353384109423a966dCd3Aa30D884C9b2E057",
twFactory: "0x97EA0Fcc552D5A8Fb5e9101316AAd0D62Ea0876B",
twRegistry: TWRegistry_address,
twBYOCRegistry: AddressZero,
},
[ChainId.FantomTestnet]: {
openzeppelinForwarder: OZ_DEFENDER_FORWARDER_ADDRESS,
openzeppelinForwarderEOA: "0x42D3048b595B6e1c28a588d70366CcC2AA4dB47b",
biconomyForwarder: "0x69FB8Dca8067A5D38703b9e8b39cf2D51473E4b4",
twFactory: TWFactory_address,
twRegistry: TWRegistry_address,
twBYOCRegistry: "0x3E6eE864f850F5e5A98bc950B68E181Cf4010F23",
},
[ChainId.Arbitrum]: {
openzeppelinForwarder: "0x4a8AC7f22DeD2CF923A51e4A1c67490bd8868add",
openzeppelinForwarderEOA: "0x4f247c69184ad61036EC2Bb3213b69F10FbEDe1F",
biconomyForwarder: "0xfe0fa3C06d03bDC7fb49c892BbB39113B534fB57",
twFactory: "0xd24b3de085CFd8c54b94feAD08a7962D343E6DE0",
twRegistry: "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd",
twBYOCRegistry: AddressZero,
},
[ChainId.ArbitrumGoerli]: {
openzeppelinForwarder: "0x8cbc8B5d71702032904750A66AEfE8B603eBC538",
openzeppelinForwarderEOA: "0x119704314Ef304EaAAE4b3c7C9ABd59272A28310",
biconomyForwarder: AddressZero,
twFactory: "0xd24b3de085CFd8c54b94feAD08a7962D343E6DE0",
twRegistry: "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd",
twBYOCRegistry: AddressZero,
},
[ChainId.Optimism]: {
openzeppelinForwarder: "0xd85da690EF288A6976DE0E85Fb2Aad512eBAfbf7",
openzeppelinForwarderEOA: "0x7e80648EB2071E26937F9D42A513ccf4815fc702",
biconomyForwarder: "0xefba8a2a82ec1fb1273806174f5e28fbb917cf95",
twFactory: "0xd24b3de085CFd8c54b94feAD08a7962D343E6DE0",
twRegistry: "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd",
twBYOCRegistry: AddressZero,
},
[ChainId.OptimismGoerli]: {
openzeppelinForwarder: "0x8cbc8B5d71702032904750A66AEfE8B603eBC538",
openzeppelinForwarderEOA: "0x119704314Ef304EaAAE4b3c7C9ABd59272A28310",
biconomyForwarder: AddressZero,
twFactory: "0xd24b3de085CFd8c54b94feAD08a7962D343E6DE0",
twRegistry: "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd",
twBYOCRegistry: AddressZero,
},
[ChainId.BinanceSmartChainMainnet]: {
openzeppelinForwarder: "0x7C4717039B89d5859c4Fbb85EDB19A6E2ce61171",
openzeppelinForwarderEOA: "0xE8dd2Ff0212F86d3197b4AfDC6dAC6ac47eb10aC",
biconomyForwarder: "0x86C80a8aa58e0A4fa09A69624c31Ab2a6CAD56b8",
twBYOCRegistry: AddressZero,
twFactory: "0xd24b3de085CFd8c54b94feAD08a7962D343E6DE0",
twRegistry: "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd",
},
[ChainId.BinanceSmartChainTestnet]: {
openzeppelinForwarder: "0x44bE9D54B9C8b5e57a3325E8Ec9154640e7c6955",
openzeppelinForwarderEOA: "0x7e80648EB2071E26937F9D42A513ccf4815fc702",
biconomyForwarder: "0x61456BF1715C1415730076BB79ae118E806E74d2",
twBYOCRegistry: AddressZero,
twFactory: "0xd24b3de085CFd8c54b94feAD08a7962D343E6DE0",
twRegistry: "0x7c487845f98938Bb955B1D5AD069d9a30e4131fd",
},
[ChainId.Hardhat]: {
openzeppelinForwarder: AddressZero,
openzeppelinForwarderEOA: AddressZero,
biconomyForwarder: AddressZero,
twFactory: AddressZero,
twRegistry: AddressZero,
twBYOCRegistry: AddressZero,
},
[ChainId.Localhost]: {
openzeppelinForwarder: AddressZero,
openzeppelinForwarderEOA: AddressZero,
biconomyForwarder: AddressZero,
twFactory: AddressZero,
twRegistry: AddressZero,
twBYOCRegistry: AddressZero,
},
};
@@ -0,0 +1,5 @@
/**
* publicly available wallet for local nodes
*/
export const LOCAL_NODE_PKEY =
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
@@ -0,0 +1,21 @@
import type { PrebuiltContractType } from "../../contracts";
import { APPROVED_IMPLEMENTATIONS } from "./APPROVED_IMPLEMENTATIONS";
import { SUPPORTED_CHAIN_ID } from "../chains/SUPPORTED_CHAIN_ID";
/**
* @internal
* @param chainId
* @param contractType
*/
export function getApprovedImplementation(
chainId: SUPPORTED_CHAIN_ID, // TODO use SupportedChainId once we deploy to all chains
contractType: PrebuiltContractType,
): string | null {
if (chainId in APPROVED_IMPLEMENTATIONS) {
const approvedImpls = APPROVED_IMPLEMENTATIONS[chainId];
if (contractType in approvedImpls) {
return approvedImpls[contractType as keyof typeof approvedImpls];
}
}
return null;
}
@@ -0,0 +1,27 @@
import { CONTRACT_ADDRESSES } from "./CONTRACT_ADDRESSES";
import { ChainId } from "../chains/ChainId";
import { SUPPORTED_CHAIN_ID } from "../chains/SUPPORTED_CHAIN_ID";
import { AddressZero } from "./AddressZero";
/**
* @internal
*/
export function getContractAddressByChainId(
chainId: SUPPORTED_CHAIN_ID | ChainId.Hardhat,
contractName: keyof (typeof CONTRACT_ADDRESSES)[SUPPORTED_CHAIN_ID],
): string | undefined {
// for testing only
if (chainId === ChainId.Hardhat || chainId === ChainId.Localhost) {
if (contractName === "twFactory") {
// eslint-disable-next-line turbo/no-undeclared-env-vars
return process.env.factoryAddress as string;
} else if (contractName === "twRegistry") {
// eslint-disable-next-line turbo/no-undeclared-env-vars
return process.env.registryAddress as string;
} else {
return AddressZero;
}
}
// real output here
return CONTRACT_ADDRESSES[chainId]?.[contractName];
}
@@ -0,0 +1,14 @@
const ContractPublisher_address = "0x664244560eBa21Bf82d7150C791bE1AbcD5B4cd7"; // Polygon only
/**
* @internal
*/
export function getContractPublisherAddress() {
// eslint-disable-next-line turbo/no-undeclared-env-vars
if (process.env.contractPublisherAddress) {
// eslint-disable-next-line turbo/no-undeclared-env-vars
return process.env.contractPublisherAddress as string;
} else {
return ContractPublisher_address;
}
}
@@ -0,0 +1,25 @@
import { CONTRACT_ADDRESSES } from "./CONTRACT_ADDRESSES";
import { SUPPORTED_CHAIN_ID } from "../chains/SUPPORTED_CHAIN_ID";
import { SUPPORTED_CHAIN_IDS } from "../chains/SUPPORTED_CHAIN_IDS";
import { AddressZero } from "./AddressZero";
/**
*
* @param chainId - chain id
* @returns the array of trusted forwarders for the given chain id
* @internal
*/
export function getDefaultTrustedForwarders(
chainId: SUPPORTED_CHAIN_ID,
): string[] {
const chainEnum = SUPPORTED_CHAIN_IDS.find((c) => c === chainId);
const biconomyForwarder = chainEnum
? CONTRACT_ADDRESSES[chainEnum].biconomyForwarder
: AddressZero;
const openzeppelinForwarder = chainEnum
? CONTRACT_ADDRESSES[chainEnum].openzeppelinForwarder
: AddressZero;
return [openzeppelinForwarder, biconomyForwarder].filter(
(a) => a !== AddressZero,
);
}
@@ -0,0 +1,14 @@
const MultichainRegistry_address = "0xcdAD8FA86e18538aC207872E8ff3536501431B73"; // Polygon only
/**
* @internal
*/
export function getMultichainRegistryAddress() {
// eslint-disable-next-line turbo/no-undeclared-env-vars
if (process.env.multiChainRegistryAddress) {
// eslint-disable-next-line turbo/no-undeclared-env-vars
return process.env.multiChainRegistryAddress as string;
} else {
return MultichainRegistry_address;
}
}
-89
View File
@@ -1,89 +0,0 @@
import type { ChainInfo } from "../schema/shared";
import { defaultChains } from "@thirdweb-dev/chains";
/**
* @public
*/
export enum ChainId {
Mainnet = 1,
Goerli = 5,
Polygon = 137,
Mumbai = 80001,
Localhost = 1337,
Hardhat = 31337,
Fantom = 250,
FantomTestnet = 4002,
Avalanche = 43114,
AvalancheFujiTestnet = 43113,
Optimism = 10,
OptimismGoerli = 420,
Arbitrum = 42161,
ArbitrumGoerli = 421613,
BinanceSmartChainMainnet = 56,
BinanceSmartChainTestnet = 97,
}
/**
* @public
*/
export type SUPPORTED_CHAIN_ID =
| ChainId.Mainnet
| ChainId.Goerli
| ChainId.Mumbai
| ChainId.Polygon
| ChainId.Fantom
| ChainId.FantomTestnet
| ChainId.Avalanche
| ChainId.AvalancheFujiTestnet
| ChainId.Optimism
| ChainId.OptimismGoerli
| ChainId.Arbitrum
| ChainId.ArbitrumGoerli
| ChainId.BinanceSmartChainMainnet
| ChainId.BinanceSmartChainTestnet
| ChainId.Hardhat
| ChainId.Localhost;
/**
* @public
*/
export const SUPPORTED_CHAIN_IDS: SUPPORTED_CHAIN_ID[] = [
ChainId.Mainnet,
ChainId.Goerli,
ChainId.Polygon,
ChainId.Mumbai,
ChainId.Fantom,
ChainId.FantomTestnet,
ChainId.Avalanche,
ChainId.AvalancheFujiTestnet,
ChainId.Optimism,
ChainId.OptimismGoerli,
ChainId.Arbitrum,
ChainId.ArbitrumGoerli,
ChainId.BinanceSmartChainMainnet,
ChainId.BinanceSmartChainTestnet,
ChainId.Hardhat,
ChainId.Localhost,
];
// @ts-expect-error
let supportedChains: ChainInfo[] = defaultChains;
/**
* @internal
*/
export function setSupportedChains(chains: ChainInfo[] | undefined) {
if (chains && chains.length > 0) {
supportedChains = chains;
} else {
// @ts-expect-error
supportedChains = defaultChains;
}
}
/**
* @internal
*/
export function getSupportedChains() {
return supportedChains;
}
@@ -0,0 +1,21 @@
/**
* @public
*/
export enum ChainId {
Mainnet = 1,
Goerli = 5,
Polygon = 137,
Mumbai = 80001,
Localhost = 1337,
Hardhat = 31337,
Fantom = 250,
FantomTestnet = 4002,
Avalanche = 43114,
AvalancheFujiTestnet = 43113,
Optimism = 10,
OptimismGoerli = 420,
Arbitrum = 42161,
ArbitrumGoerli = 421613,
BinanceSmartChainMainnet = 56,
BinanceSmartChainTestnet = 97,
}
@@ -0,0 +1,22 @@
import { ChainId } from "./ChainId";
/**
* @public
*/
export type SUPPORTED_CHAIN_ID =
| ChainId.Mainnet
| ChainId.Goerli
| ChainId.Mumbai
| ChainId.Polygon
| ChainId.Fantom
| ChainId.FantomTestnet
| ChainId.Avalanche
| ChainId.AvalancheFujiTestnet
| ChainId.Optimism
| ChainId.OptimismGoerli
| ChainId.Arbitrum
| ChainId.ArbitrumGoerli
| ChainId.BinanceSmartChainMainnet
| ChainId.BinanceSmartChainTestnet
| ChainId.Hardhat
| ChainId.Localhost;
@@ -0,0 +1,24 @@
import { ChainId } from "./ChainId";
import { SUPPORTED_CHAIN_ID } from "./SUPPORTED_CHAIN_ID";
/**
* @public
*/
export const SUPPORTED_CHAIN_IDS: SUPPORTED_CHAIN_ID[] = [
ChainId.Mainnet,
ChainId.Goerli,
ChainId.Polygon,
ChainId.Mumbai,
ChainId.Fantom,
ChainId.FantomTestnet,
ChainId.Avalanche,
ChainId.AvalancheFujiTestnet,
ChainId.Optimism,
ChainId.OptimismGoerli,
ChainId.Arbitrum,
ChainId.ArbitrumGoerli,
ChainId.BinanceSmartChainMainnet,
ChainId.BinanceSmartChainTestnet,
ChainId.Hardhat,
ChainId.Localhost,
];
@@ -0,0 +1,24 @@
import type { ChainInfo } from "../../schema/shared/ChainInfo";
import { defaultChains } from "@thirdweb-dev/chains";
// @ts-expect-error
let supportedChains: ChainInfo[] = defaultChains;
/**
* @internal
*/
export function setSupportedChains(chains: ChainInfo[] | undefined) {
if (chains && chains.length > 0) {
supportedChains = chains;
} else {
// @ts-expect-error
supportedChains = defaultChains;
}
}
/**
* @internal
*/
export function getSupportedChains() {
return supportedChains;
}
+2 -1
View File
@@ -1,5 +1,6 @@
import { NativeToken } from "../types/currency";
import { ChainId, getSupportedChains } from "./chains";
import { ChainId } from "./chains/ChainId";
import { getSupportedChains } from "./chains/supportedChains";
import { ethers } from "ethers";
/**
+19 -2
View File
@@ -1,5 +1,22 @@
export * from "./addresses";
export * from "./chains";
// addresses
export * from "./addresses/LOCAL_NODE_PKEY";
export * from "./addresses/CONTRACT_ADDRESSES";
export * from "./addresses/APPROVED_IMPLEMENTATIONS";
export * from "./addresses/getApprovedImplementation";
export * from "./addresses/getContractAddressByChainId";
export * from "./addresses/getContractPublisherAddress";
export * from "./addresses/getMultichainRegistryAddress";
export * from "./addresses/getDefaultTrustedForwarders";
// chains
export * from "./chains/ChainId";
export * from "./chains/SUPPORTED_CHAIN_ID";
export * from "./chains/SUPPORTED_CHAIN_IDS";
export {
setSupportedChains,
getSupportedChains,
} from "./chains/supportedChains";
export * from "./contract";
export * from "./currency";
export * from "./events";
@@ -284,8 +284,8 @@ export const FEATURE_SMART_WALLET_FACTORY = {
namespace: "smartwallet.factory",
docLinks: {
// TODO
sdk: "",
contracts: "",
sdk: "sdk.smartWalletFactory",
contracts: "smartWalletFactory",
},
abis: [IAccountFactory],
features: {},
+52 -1
View File
@@ -4,10 +4,11 @@ import { isProvider, isSigner } from "../functions/getSignerAndProvider";
import { StaticJsonRpcBatchProvider } from "../lib/static-batch-rpc";
import type { SDKOptions, SDKOptionsOutput } from "../schema/sdk-options";
import { SDKOptionsSchema } from "../schema/sdk-options";
import type { ChainInfo } from "../schema/shared";
import type { ChainInfo } from "../schema/shared/ChainInfo";
import { getChainRPC } from "@thirdweb-dev/chains";
import type { Chain } from "@thirdweb-dev/chains";
import { providers } from "ethers";
import type { Signer } from "ethers";
/**
* @internal
@@ -190,3 +191,53 @@ export function getProviderFromRpcUrl(rpcUrl: string, chainId?: number) {
// Always fallback to the default provider if no other option worked
return providers.getDefaultProvider(rpcUrl);
}
/**
* @internal
*/
export function getSignerAndProvider(
network: NetworkInput,
options?: SDKOptions,
): [Signer | undefined, providers.Provider] {
let signer: Signer | undefined;
let provider: providers.Provider | undefined;
if (isSigner(network)) {
// Here, we have an ethers.Signer
signer = network;
if (network.provider) {
provider = network.provider;
}
} else if (isProvider(network)) {
// Here, we have an ethers.providers.Provider
provider = network;
} else {
// Here, we must have a ChainOrRpcUrl, which is a chain name, chain id, rpc url, or chain config
// All of which, getChainProvider can handle for us
provider = getChainProvider(network, options);
}
if (options?.readonlySettings) {
// If readonly settings are specified, then overwrite the provider
provider = getProviderFromRpcUrl(
options.readonlySettings.rpcUrl,
options.readonlySettings.chainId,
);
}
// At this point, if we don't have a provider, don't default to a random chain
// Instead, just throw an error
if (!provider) {
if (signer) {
throw new Error(
"No provider passed to the SDK! Please make sure that your signer is connected to a provider!",
);
}
throw new Error(
"No provider found! Make sure to specify which network to connect to, or pass a signer or provider to the SDK!",
);
}
return [signer, provider];
}
+2 -2
View File
@@ -3,7 +3,7 @@ import { getPrebuiltInfo } from "../common/legacy";
import { fetchAbiFromAddress } from "../common/metadata-resolver";
import { ALL_ROLES } from "../common/role";
import type { NetworkInput } from "../core/types";
import { getSignerAndProvider } from "../functions/getSignerAndProvider";
import { getSignerAndProvider } from "../constants/urls";
import { DropErc1155ContractSchema } from "../schema/contracts/drop-erc1155";
import { DropErc721ContractSchema } from "../schema/contracts/drop-erc721";
import { MarketplaceContractSchema } from "../schema/contracts/marketplace";
@@ -11,7 +11,7 @@ import { SplitsContractSchema } from "../schema/contracts/splits";
import { TokenErc1155ContractSchema } from "../schema/contracts/token-erc1155";
import { TokenErc20ContractSchema } from "../schema/contracts/token-erc20";
import { TokenErc721ContractSchema } from "../schema/contracts/token-erc721";
import { Address } from "../schema/shared";
import { Address } from "../schema/shared/Address";
import { PackContractSchema } from "../schema/contracts/packs";
import { SDKOptions } from "../schema/sdk-options";
import { VoteContractSchema } from "../schema/contracts/vote";
@@ -20,7 +20,8 @@ import { GasCostEstimator } from "../../core/classes/gas-cost-estimator";
import { Transaction } from "../../core/classes/transactions";
import { NetworkInput, TransactionResultWithId } from "../../core/types";
import { PaperCheckout } from "../../integrations/thirdweb-checkout";
import { Address, AddressOrEns } from "../../schema/shared";
import { Address } from "../../schema/shared/Address";
import { AddressOrEns } from "../../schema/shared/AddressOrEnsSchema";
import { Abi, AbiInput, AbiSchema } from "../../schema/contracts/custom";
import { DropErc1155ContractSchema } from "../../schema/contracts/drop-erc1155";
import { SDKOptions } from "../../schema/sdk-options";
@@ -18,7 +18,8 @@ import { StandardErc1155 } from "../../core/classes/erc-1155-standard";
import { GasCostEstimator } from "../../core/classes/gas-cost-estimator";
import { Transaction } from "../../core/classes/transactions";
import { NetworkInput, TransactionResultWithId } from "../../core/types";
import { Address, AddressOrEns } from "../../schema/shared";
import { AddressOrEns } from "../../schema/shared/AddressOrEnsSchema";
import { Address } from "../../schema/shared/Address";
import { Abi, AbiInput, AbiSchema } from "../../schema/contracts/custom";
import { TokenErc1155ContractSchema } from "../../schema/contracts/token-erc1155";
import { SDKOptions } from "../../schema/sdk-options";
@@ -4,7 +4,7 @@ import { isNativeToken } from "../../common/currency/isNativeToken";
import { mapOffer } from "../../common/marketplace";
import { getRoleHash } from "../../common/role";
import { buildTransactionFunction } from "../../common/transactions";
import { SUPPORTED_CHAIN_ID } from "../../constants/chains";
import { SUPPORTED_CHAIN_ID } from "../../constants/chains/SUPPORTED_CHAIN_ID";
import { NATIVE_TOKENS } from "../../constants/currency";
import { ContractAppURI } from "../../core/classes/contract-appuri";
import { ContractEncoder } from "../../core/classes/contract-encoder";
@@ -24,7 +24,7 @@ import { ListingType } from "../../enums";
import { Abi, AbiInput, AbiSchema } from "../../schema/contracts/custom";
import { MarketplaceContractSchema } from "../../schema/contracts/marketplace";
import { SDKOptions } from "../../schema/sdk-options";
import { AddressOrEns } from "../../schema/shared";
import { AddressOrEns } from "../../schema/shared/AddressOrEnsSchema";
import { Price } from "../../types/currency";
import { AuctionListing, DirectListing, Offer } from "../../types/marketplace";
import { MarketplaceFilter } from "../../types/marketplace/MarketPlaceFilter";
@@ -23,7 +23,7 @@ import { NetworkInput } from "../../core/types";
import { Abi, AbiInput, AbiSchema } from "../../schema/contracts/custom";
import { MarketplaceContractSchema } from "../../schema/contracts/marketplace";
import { SDKOptions } from "../../schema/sdk-options";
import { Address } from "../../schema/shared";
import { Address } from "../../schema/shared/Address";
import type {
MarketplaceV3 as MarketplaceV3Contract,
DirectListingsLogic,
@@ -1,5 +1,5 @@
import { NFT, NFTMetadataOrUri } from "../../../core/schema/nft";
import { resolveAddress } from "../../common/ens";
import { resolveAddress } from "../../common/ens/resolveAddress";
import { isTokenApprovedForTransfer } from "../../common/marketplace";
import { uploadOrExtractURI } from "../../common/nft";
import { buildTransactionFunction } from "../../common/transactions";
@@ -15,7 +15,7 @@ import { StandardErc721 } from "../../core/classes/erc-721-standard";
import { GasCostEstimator } from "../../core/classes/gas-cost-estimator";
import { Transaction } from "../../core/classes/transactions";
import { NetworkInput, TransactionResultWithId } from "../../core/types";
import { AddressOrEns } from "../../schema/shared";
import { AddressOrEns } from "../../schema/shared/AddressOrEnsSchema";
import { Abi, AbiInput, AbiSchema } from "../../schema/contracts/custom";
import { SDKOptions } from "../../schema/sdk-options";
import { MultiwrapContractSchema } from "../../schema/contracts/multiwrap";
@@ -17,7 +17,8 @@ import { Erc721WithQuantitySignatureMintable } from "../../core/classes/erc-721-
import { GasCostEstimator } from "../../core/classes/gas-cost-estimator";
import { Transaction } from "../../core/classes/transactions";
import type { NetworkInput, TransactionResultWithId } from "../../core/types";
import { Address, AddressOrEns } from "../../schema/shared";
import { AddressOrEns } from "../../schema/shared/AddressOrEnsSchema";
import { Address } from "../../schema/shared/Address";
import { Abi, AbiInput, AbiSchema } from "../../schema/contracts/custom";
import { TokenErc721ContractSchema } from "../../schema/contracts/token-erc721";
import { SDKOptions } from "../../schema/sdk-options";

Some files were not shown because too many files have changed in this diff Show More