Compare commits
13
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cbf5508bd5 | ||
|
|
3731459d33 | ||
|
|
64f24f1bb1 | ||
|
|
cac6c30bca | ||
|
|
e7740a59db | ||
|
|
7a37e564fd | ||
|
|
e173636f4b | ||
|
|
8c6cdaa288 | ||
|
|
ad9b3febff | ||
|
|
94f49b1294 | ||
|
|
517e2a75e3 | ||
|
|
72692689e9 | ||
|
|
efc56fa580 |
@@ -1,5 +1,11 @@
|
||||
# @thirdweb-dev/auth
|
||||
|
||||
## 2.0.37
|
||||
|
||||
## 2.0.36
|
||||
|
||||
## 2.0.35
|
||||
|
||||
## 2.0.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/auth",
|
||||
"version": "2.0.34",
|
||||
"version": "2.0.37",
|
||||
"exports": {
|
||||
"./next": {
|
||||
"module": "./next/dist/thirdweb-dev-auth-next.esm.js",
|
||||
|
||||
@@ -1,5 +1,36 @@
|
||||
# thirdweb
|
||||
|
||||
## 0.9.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#441](https://github.com/thirdweb-dev/js/pull/441) [`64f24f1`](https://github.com/thirdweb-dev/js/commit/64f24f1bb167c3d0cb3beca51fd300eaec21cc27) Thanks [@adam-maj](https://github.com/adam-maj)! - CLI autoupdates on run
|
||||
|
||||
- [#447](https://github.com/thirdweb-dev/js/pull/447) [`e7740a5`](https://github.com/thirdweb-dev/js/commit/e7740a59db022a3396194ac66cd195d8ae754d57) Thanks [@adam-maj](https://github.com/adam-maj)! - Detect whether forge is installed
|
||||
|
||||
- Updated dependencies [[`3731459`](https://github.com/thirdweb-dev/js/commit/3731459d33f1ded7ebb69124809449b901b3ad3d), [`cac6c30`](https://github.com/thirdweb-dev/js/commit/cac6c30bca5e17df81d746ef81316af47d5e252e), [`7a37e56`](https://github.com/thirdweb-dev/js/commit/7a37e564fd5d5a9df84c8da44ecaf6c42f67a0e2)]:
|
||||
- @thirdweb-dev/sdk@3.6.7
|
||||
|
||||
## 0.9.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8c6cdaa`](https://github.com/thirdweb-dev/js/commit/8c6cdaa2887fb2cc40d3ee6991233d195d103805)]:
|
||||
- @thirdweb-dev/sdk@3.6.6
|
||||
|
||||
## 0.9.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#444](https://github.com/thirdweb-dev/js/pull/444) [`94f49b1`](https://github.com/thirdweb-dev/js/commit/94f49b1294bc0208171b16ed413cbb44644af017) Thanks [@adam-maj](https://github.com/adam-maj)! - Add changeset
|
||||
|
||||
## 0.9.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`efc56fa`](https://github.com/thirdweb-dev/js/commit/efc56fa5802490ac8ef50037658d046afd89e9a1)]:
|
||||
- @thirdweb-dev/sdk@3.6.5
|
||||
|
||||
## 0.9.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "thirdweb",
|
||||
"main": "dist/cli/index.js",
|
||||
"version": "0.9.2",
|
||||
"version": "0.9.6",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
@@ -32,6 +32,7 @@
|
||||
"@thirdweb-dev/sdk": "*",
|
||||
"async-retry": "^1.3.3",
|
||||
"commander": "^9.1.0",
|
||||
"detect-package-manager": "^2.0.1",
|
||||
"enquirer": "^2.3.6",
|
||||
"ethers": "^5.7.2",
|
||||
"got": "11.8.5",
|
||||
@@ -73,4 +74,4 @@
|
||||
"sourcemap": true,
|
||||
"clean": true
|
||||
}
|
||||
}
|
||||
}
|
||||
+148
-20
@@ -2,37 +2,37 @@
|
||||
import { detectExtensions } from "../common/feature-detector";
|
||||
import { processProject } from "../common/processor";
|
||||
import { cliVersion, pkg } from "../constants/urls";
|
||||
import { info, logger } from "../core/helpers/logger";
|
||||
import { info, logger, spinner } from "../core/helpers/logger";
|
||||
import { twCreate } from "../create/command";
|
||||
import { deploy } from "../deploy";
|
||||
import { findPackageInstallation } from "../helpers/detect-local-packages";
|
||||
import { upload } from "../storage/command";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import chalk from "chalk";
|
||||
import { exec, spawn } from "child_process";
|
||||
import { Command } from "commander";
|
||||
import open from "open";
|
||||
import prompts from "prompts";
|
||||
|
||||
const main = async () => {
|
||||
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
||||
const skipIntro = process.env.THIRDWEB_CLI_SKIP_INTRO === "true";
|
||||
|
||||
const program = new Command();
|
||||
|
||||
//yes this has to look like this, eliminates whitespace
|
||||
console.info(`
|
||||
$$\\ $$\\ $$\\ $$\\ $$\\
|
||||
$$ | $$ | \\__| $$ | $$ |
|
||||
$$$$$$\\ $$$$$$$\\ $$\\ $$$$$$\\ $$$$$$$ |$$\\ $$\\ $$\\ $$$$$$\\ $$$$$$$\\
|
||||
\\_$$ _| $$ __$$\\ $$ |$$ __$$\\ $$ __$$ |$$ | $$ | $$ |$$ __$$\\ $$ __$$\\
|
||||
$$ | $$ | $$ |$$ |$$ | \\__|$$ / $$ |$$ | $$ | $$ |$$$$$$$$ |$$ | $$ |
|
||||
$$ |$$\\ $$ | $$ |$$ |$$ | $$ | $$ |$$ | $$ | $$ |$$ ____|$$ | $$ |
|
||||
\\$$$$ |$$ | $$ |$$ |$$ | \\$$$$$$$ |\\$$$$$\\$$$$ |\\$$$$$$$\\ $$$$$$$ |
|
||||
\\____/ \\__| \\__|\\__|\\__| \\_______| \\_____\\____/ \\_______|\\_______/ `);
|
||||
console.info(`\n 💎 thirdweb-cli v${cliVersion} 💎\n`);
|
||||
import("update-notifier").then(({ default: updateNotifier }) => {
|
||||
updateNotifier({
|
||||
pkg,
|
||||
shouldNotifyInNpmScript: true,
|
||||
// check every time while we're still building the CLI
|
||||
updateCheckInterval: 0,
|
||||
}).notify();
|
||||
});
|
||||
// yes this has to look like this, eliminates whitespace
|
||||
if (!skipIntro) {
|
||||
console.info(`
|
||||
$$\\ $$\\ $$\\ $$\\ $$\\
|
||||
$$ | $$ | \\__| $$ | $$ |
|
||||
$$$$$$\\ $$$$$$$\\ $$\\ $$$$$$\\ $$$$$$$ |$$\\ $$\\ $$\\ $$$$$$\\ $$$$$$$\\
|
||||
\\_$$ _| $$ __$$\\ $$ |$$ __$$\\ $$ __$$ |$$ | $$ | $$ |$$ __$$\\ $$ __$$\\
|
||||
$$ | $$ | $$ |$$ |$$ | \\__|$$ / $$ |$$ | $$ | $$ |$$$$$$$$ |$$ | $$ |
|
||||
$$ |$$\\ $$ | $$ |$$ |$$ | $$ | $$ |$$ | $$ | $$ |$$ ____|$$ | $$ |
|
||||
\\$$$$ |$$ | $$ |$$ |$$ | \\$$$$$$$ |\\$$$$$\\$$$$ |\\$$$$$$$\\ $$$$$$$ |
|
||||
\\____/ \\__| \\__|\\__|\\__| \\_______| \\_____\\____/ \\_______|\\_______/ `);
|
||||
console.info(`\n 💎 thirdweb-cli v${cliVersion} 💎\n`);
|
||||
}
|
||||
|
||||
program
|
||||
.name("thirdweb-cli")
|
||||
@@ -198,6 +198,134 @@ $$$$$$\\ $$$$$$$\\ $$\\ $$$$$$\\ $$$$$$$ |$$\\ $$\\ $$\\ $$$$$$\\ $$$$
|
||||
await detectExtensions(options);
|
||||
});
|
||||
|
||||
if (!skipIntro) {
|
||||
const versionSpinner = spinner("Checking for updates...");
|
||||
await import("update-notifier").then(
|
||||
async ({ default: updateNotifier }) => {
|
||||
const notifier = updateNotifier({
|
||||
pkg,
|
||||
shouldNotifyInNpmScript: true,
|
||||
// check every time while we're still building the CLI
|
||||
updateCheckInterval: 0,
|
||||
});
|
||||
|
||||
const versionInfo = await notifier.fetchInfo();
|
||||
versionSpinner.stop();
|
||||
|
||||
if (versionInfo.type !== "latest") {
|
||||
const res = await prompts({
|
||||
type: "toggle",
|
||||
name: "upgrade",
|
||||
message: `A new version of the CLI is available. Would you like to upgrade?`,
|
||||
initial: true,
|
||||
active: "yes",
|
||||
inactive: "no",
|
||||
});
|
||||
|
||||
if (res.upgrade) {
|
||||
const updateSpinner = spinner(
|
||||
`Upgrading CLI to version ${versionInfo.latest}...`,
|
||||
);
|
||||
|
||||
const clonedEnvironment = { ...process.env };
|
||||
clonedEnvironment.THIRDWEB_CLI_SKIP_INTRO = "true";
|
||||
|
||||
const installation = await findPackageInstallation();
|
||||
|
||||
// If the package isn't installed anywhere, just defer to npx thirdweb@latest
|
||||
if (!installation) {
|
||||
updateSpinner.succeed(
|
||||
`Now using CLI version ${versionInfo.latest}. Continuing execution...`,
|
||||
);
|
||||
|
||||
await new Promise((done, failed) => {
|
||||
const shell = spawn(
|
||||
`npx --yes thirdweb@latest ${process.argv
|
||||
.slice(2)
|
||||
.join(" ")}`,
|
||||
[],
|
||||
{ stdio: "inherit", shell: true, env: clonedEnvironment },
|
||||
);
|
||||
shell.on("close", (code) => {
|
||||
if (code === 0) {
|
||||
done("");
|
||||
} else {
|
||||
failed();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return process.exit(0);
|
||||
}
|
||||
|
||||
// Otherwise, get the correct command based on package manager and local vs. global
|
||||
let command = "";
|
||||
switch (installation.packageManager) {
|
||||
case "npm":
|
||||
command = installation.isGlobal
|
||||
? `npm install -g thirdweb`
|
||||
: `npm install thirdweb`;
|
||||
break;
|
||||
case "yarn":
|
||||
command = installation.isGlobal
|
||||
? `yarn global add thirdweb`
|
||||
: `yarn add thirdweb`;
|
||||
break;
|
||||
case "pnpm":
|
||||
command = installation.isGlobal
|
||||
? `pnpm add -g thirdweb@latest`
|
||||
: `pnpm add thirdweb@latest`;
|
||||
break;
|
||||
default:
|
||||
console.error(
|
||||
`Could not detect package manager in use, aborting automatic upgrade.\nIf you want to upgrade the CLI, please do it manually with your package manager.`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
await new Promise((done, failed) => {
|
||||
exec(command, (err, stdout, stderr) => {
|
||||
if (err) {
|
||||
failed(err);
|
||||
return;
|
||||
}
|
||||
|
||||
done({ stdout, stderr });
|
||||
});
|
||||
});
|
||||
|
||||
updateSpinner.succeed(
|
||||
`Successfully upgraded CLI to version ${versionInfo.latest}. Continuing execution...`,
|
||||
);
|
||||
|
||||
// If the package is installed globally with yarn or pnpm, then npx won't recognize it
|
||||
// So we need to make sure to run the command directly
|
||||
const executionCommand =
|
||||
!installation.isGlobal || installation.packageManager === "npm"
|
||||
? `npx thirdweb`
|
||||
: `thirdweb`;
|
||||
await new Promise((done, failed) => {
|
||||
const shell = spawn(
|
||||
`${executionCommand} ${process.argv.slice(2).join(" ")}`,
|
||||
[],
|
||||
{ stdio: "inherit", shell: true, env: clonedEnvironment },
|
||||
);
|
||||
shell.on("close", (code) => {
|
||||
if (code === 0) {
|
||||
done("");
|
||||
} else {
|
||||
failed();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
await program.parseAsync();
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { findFiles } from "../../common/file-helper";
|
||||
import { hasForge } from "../../create/helpers/has-forge";
|
||||
import { execute } from "../helpers/exec";
|
||||
import { logger } from "../helpers/logger";
|
||||
import { CompileOptions } from "../interfaces/Builder";
|
||||
import { ContractPayload } from "../interfaces/ContractPayload";
|
||||
import { BaseBuilder } from "./builder-base";
|
||||
import chalk from "chalk";
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import { basename, join } from "path";
|
||||
|
||||
@@ -11,6 +13,18 @@ export class FoundryBuilder extends BaseBuilder {
|
||||
public async compile(options: CompileOptions): Promise<{
|
||||
contracts: ContractPayload[];
|
||||
}> {
|
||||
const isInstalled = await hasForge();
|
||||
if (!isInstalled) {
|
||||
console.error(
|
||||
`\n${chalk.redBright(
|
||||
`error`,
|
||||
)} You don't have forge installed on this machine!\n\nYou can install forge by following these instructions:\n${chalk.blueBright(
|
||||
`https://book.getfoundry.sh/getting-started/installation`,
|
||||
)}\n`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
await execute("forge clean", options.projectPath);
|
||||
await execute("forge build --extra-output metadata", options.projectPath);
|
||||
|
||||
|
||||
@@ -259,16 +259,16 @@ export async function twCreate(
|
||||
framework = res.framework.trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!framework) {
|
||||
console.log("Please specify a framework");
|
||||
process.exit(1);
|
||||
}
|
||||
if (!framework) {
|
||||
console.log("Please specify a framework");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (!language) {
|
||||
// Default = JavaScript
|
||||
language = "javascript";
|
||||
if (!language) {
|
||||
// Default = JavaScript
|
||||
language = "javascript";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { hasBaseContract, readBaseContract } from "./base-contracts";
|
||||
import { DownloadError } from "./create-app";
|
||||
import { PackageManager } from "./get-pkg-manager";
|
||||
import { tryGitInit } from "./git";
|
||||
import { hasForge } from "./has-forge";
|
||||
import { install } from "./install";
|
||||
import { isFolderEmpty } from "./is-folder-empty";
|
||||
import { getOnline } from "./is-online";
|
||||
@@ -218,5 +219,19 @@ export async function createContractProject({
|
||||
console.log();
|
||||
console.log(chalk.cyan(" cd"), cdpath);
|
||||
console.log();
|
||||
|
||||
if (framework === "forge") {
|
||||
const isInstalled = await hasForge();
|
||||
|
||||
if (!isInstalled) {
|
||||
console.log(
|
||||
`\n${chalk.yellowBright(
|
||||
`warning`,
|
||||
)} You don't have forge installed on this machine, and will need it to run this project! \n\nYou can install forge by following these instructions:\n${chalk.blueBright(
|
||||
`https://book.getfoundry.sh/getting-started/installation`,
|
||||
)}\n`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { exec } from "child_process";
|
||||
|
||||
export async function hasForge() {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
return await new Promise((resolve, reject) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
exec("forge --version", (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
resolve(false);
|
||||
}
|
||||
resolve(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
import { exec } from "child_process";
|
||||
|
||||
type PackageManager = "npm" | "yarn" | "pnpm";
|
||||
|
||||
interface Installation {
|
||||
packageManager: PackageManager;
|
||||
isGlobal: boolean;
|
||||
}
|
||||
|
||||
export async function findPackageInstallation(): Promise<
|
||||
Installation | undefined
|
||||
> {
|
||||
const isLocal = await isInstalledLocally();
|
||||
if (isLocal) {
|
||||
const packageManager = await import("detect-package-manager").then(
|
||||
({ detect }) => {
|
||||
return detect();
|
||||
},
|
||||
);
|
||||
|
||||
return { packageManager, isGlobal: false };
|
||||
}
|
||||
|
||||
const isGlobalNpm = await isInstalledGloballyWithNpm();
|
||||
if (isGlobalNpm) {
|
||||
return { packageManager: "npm", isGlobal: true };
|
||||
}
|
||||
|
||||
const isGlobalYarn = await isInstalledGloballyWithYarn();
|
||||
if (isGlobalYarn) {
|
||||
return { packageManager: "yarn", isGlobal: true };
|
||||
}
|
||||
|
||||
const isGlobalPnpm = await isInstalledGloballyWithPnpm();
|
||||
if (isGlobalPnpm) {
|
||||
return { packageManager: "pnpm", isGlobal: true };
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// For LOCAL packages, npm ls picks up things installed by yarn and pnpm too
|
||||
async function isInstalledLocally(): Promise<boolean> {
|
||||
const packages = await detectPackages("npm ls --depth=0");
|
||||
return containsThirdweb(packages || []);
|
||||
}
|
||||
|
||||
// But for GLOBAL packages, we need to use a separate command for each one
|
||||
async function isInstalledGloballyWithNpm(): Promise<boolean> {
|
||||
const packages = await detectPackages("npm ls -g --depth=0");
|
||||
return containsThirdweb(packages || []);
|
||||
}
|
||||
|
||||
async function isInstalledGloballyWithYarn(): Promise<boolean> {
|
||||
const packages = await detectPackages("yarn --cwd `yarn global dir` list");
|
||||
return containsThirdweb(packages || []);
|
||||
}
|
||||
|
||||
async function isInstalledGloballyWithPnpm(): Promise<boolean> {
|
||||
const packages: string[] = await new Promise((resolve) => {
|
||||
exec(`pnpm list -g --depth=0`, (err, stdout) => {
|
||||
var pkgs: string[] = [];
|
||||
pkgs = stdout.split("dependencies:")[1]?.trim().split("\n") || [];
|
||||
pkgs = pkgs.map((pkg) => pkg.replace(" ", "@"));
|
||||
resolve(pkgs);
|
||||
});
|
||||
});
|
||||
return containsThirdweb(packages || []);
|
||||
}
|
||||
|
||||
function containsThirdweb(packages: string[]) {
|
||||
return packages.some((pkg) => pkg.match(/^thirdweb/));
|
||||
}
|
||||
|
||||
async function detectPackages(cmd: string): Promise<string[]> {
|
||||
return new Promise((resolve) => {
|
||||
exec(cmd, (err, stdout) => {
|
||||
var packages: string[] = [];
|
||||
packages = stdout.split("\n");
|
||||
// We're one short on '-' to support both yarn and npm
|
||||
packages = packages.filter(function (item) {
|
||||
if (item.match(/^├─.+/g) !== null) {
|
||||
return true;
|
||||
}
|
||||
if (item.match(/^└─.+/g) !== null) {
|
||||
return true;
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
packages = packages
|
||||
.map(function (item) {
|
||||
if (item.match(/^├─.+/g) !== null) {
|
||||
return item.replace(/(^├──\s|^├─\s)/g, "");
|
||||
}
|
||||
if (item.match(/^└─.+/g) !== null) {
|
||||
return item.replace(/(^└──\s|^├─\s)/g, "");
|
||||
}
|
||||
})
|
||||
.filter((item) => !!item) as string[];
|
||||
resolve(packages);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"presets": [
|
||||
"@babel/preset-typescript",
|
||||
["@babel/preset-env", { "targets": "defaults, not ie 11" }]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
# folders
|
||||
dist/
|
||||
|
||||
# files
|
||||
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: ["thirdweb"],
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
# @thirdweb-dev/pay
|
||||
|
||||
## 0.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#433](https://github.com/thirdweb-dev/js/pull/433) [`7269268`](https://github.com/thirdweb-dev/js/commit/72692689e9adb41e92038765fd01a36c2b7457e1) Thanks [@jnsdls](https://github.com/jnsdls)! - Initialize Pay Package
|
||||
@@ -0,0 +1,16 @@
|
||||
<p align="center">
|
||||
<br />
|
||||
<a href="https://thirdweb.com"><img src="https://github.com/thirdweb-dev/js/blob/main/packages/sdk/logo.svg?raw=true" width="200" alt=""/></a>
|
||||
<br />
|
||||
</p>
|
||||
<h1 align="center">thirdweb wallets</h1>
|
||||
<p align="center">
|
||||
<!-- <a href="https://www.npmjs.com/package/@thirdweb-dev/sdk"><img src="https://img.shields.io/npm/v/@thirdweb-dev/sdk?color=red&label=npm&logo=npm" alt="npm version"/></a> -->
|
||||
<!-- <a href="https://github.com/thirdweb-dev/js/actions/workflows/CI.yml"><img alt="Build Status" src="https://github.com/thirdweb-dev/js/actions/workflows/CI.yml/badge.svg"/></a> -->
|
||||
<!-- <a href="https://discord.gg/thirdweb"><img alt="Join our Discord!" src="https://img.shields.io/discord/834227967404146718.svg?color=7289da&label=discord&logo=discord&style=flat"/></a> -->
|
||||
|
||||
</p>
|
||||
<!-- <p align="center"><strong>Best in class Web3 SDK for Browser, Node and Mobile apps</strong></p> -->
|
||||
<br />
|
||||
|
||||
### todo
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"main": "dist/thirdweb-dev-pay-integrations-coinbase.cjs.js",
|
||||
"module": "dist/thirdweb-dev-pay-integrations-coinbase.esm.js"
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/pay",
|
||||
"version": "0.1.0",
|
||||
"main": "dist/thirdweb-dev-pay.cjs.js",
|
||||
"module": "dist/thirdweb-dev-pay.esm.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"module": "./dist/thirdweb-dev-pay.esm.js",
|
||||
"default": "./dist/thirdweb-dev-pay.cjs.js"
|
||||
},
|
||||
"./integrations/coinbase": {
|
||||
"module": "./integrations/coinbase/dist/thirdweb-dev-pay-integrations-coinbase.esm.js",
|
||||
"default": "./integrations/coinbase/dist/thirdweb-dev-pay-integrations-coinbase.cjs.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/pay",
|
||||
"license": "Apache-2.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/thirdweb-dev/js/issues"
|
||||
},
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"files": [
|
||||
"dist/",
|
||||
"integrations/"
|
||||
],
|
||||
"preconstruct": {
|
||||
"entrypoints": [
|
||||
"index.ts",
|
||||
"integrations/**"
|
||||
],
|
||||
"___experimentalFlags_WILL_CHANGE_IN_PATCH": {
|
||||
"exports": true
|
||||
},
|
||||
"exports": true
|
||||
},
|
||||
"sideEffects": false,
|
||||
"dependencies": {
|
||||
"@coinbase/cbpay-js": "^1.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@preconstruct/cli": "^2.2.1",
|
||||
"typescript": "^4.7.4"
|
||||
},
|
||||
"scripts": {
|
||||
"format": "prettier --write 'src/**/*'",
|
||||
"lint": "eslint src/",
|
||||
"fix": "eslint src/ --fix",
|
||||
"clean": "rm -rf dist/",
|
||||
"build": "tsc && preconstruct build",
|
||||
"push": "yalc push"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./integrations/coinbase";
|
||||
@@ -0,0 +1,62 @@
|
||||
import { initOnRamp, InitOnRampParams } from "@coinbase/cbpay-js";
|
||||
|
||||
interface CoinbasePayOptions extends Pick<InitOnRampParams, "appId"> {}
|
||||
|
||||
const CHAIN_ID_MAP = {
|
||||
[-1]: "solana",
|
||||
1: "ethereum",
|
||||
69: "optimism",
|
||||
137: "polygon",
|
||||
} as const;
|
||||
|
||||
export type FundWalletOptions = {
|
||||
address: string;
|
||||
chainId: keyof typeof CHAIN_ID_MAP;
|
||||
assets?: string[];
|
||||
};
|
||||
|
||||
export class CoinbasePayIntegration {
|
||||
#appId: string;
|
||||
constructor(options: CoinbasePayOptions) {
|
||||
this.#appId = options.appId;
|
||||
}
|
||||
|
||||
async fundWallet(opts: FundWalletOptions): Promise<void> {
|
||||
const { address, chainId, assets } = opts;
|
||||
|
||||
return new Promise((res, rej) => {
|
||||
initOnRamp(
|
||||
{
|
||||
appId: this.#appId,
|
||||
widgetParameters: {
|
||||
destinationWallets: [
|
||||
{
|
||||
address,
|
||||
assets,
|
||||
supportedNetworks: [CHAIN_ID_MAP[chainId]],
|
||||
},
|
||||
],
|
||||
},
|
||||
experienceLoggedIn: "embedded",
|
||||
experienceLoggedOut: "popup",
|
||||
closeOnExit: true,
|
||||
onSuccess: () => {
|
||||
res();
|
||||
},
|
||||
onExit(error) {
|
||||
if (error) {
|
||||
return rej(error);
|
||||
}
|
||||
return res();
|
||||
},
|
||||
},
|
||||
(err, instance) => {
|
||||
if (err || !instance) {
|
||||
return rej(err);
|
||||
}
|
||||
instance.open();
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"extends": "@thirdweb-dev/tsconfig/sdk.json",
|
||||
"include": ["src", "types"],
|
||||
"exclude": ["dist", "build", "node_modules"]
|
||||
}
|
||||
@@ -1,5 +1,19 @@
|
||||
# @thirdweb-dev/react
|
||||
|
||||
## 3.6.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#448](https://github.com/thirdweb-dev/js/pull/448) [`7a37e56`](https://github.com/thirdweb-dev/js/commit/7a37e564fd5d5a9df84c8da44ecaf6c42f67a0e2) Thanks [@jnsdls](https://github.com/jnsdls)! - [EVM] - allow `useContract` to fail faster to enable the import case
|
||||
|
||||
## 3.6.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#443](https://github.com/thirdweb-dev/js/pull/443) [`8c6cdaa`](https://github.com/thirdweb-dev/js/commit/8c6cdaa2887fb2cc40d3ee6991233d195d103805) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Fix magic link connector not connecting to the right chain
|
||||
|
||||
## 3.6.5
|
||||
|
||||
## 3.6.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/react",
|
||||
"version": "3.6.4",
|
||||
"version": "3.6.7",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/react",
|
||||
"author": "thirdweb eng <[email protected]>",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -62,6 +62,18 @@ export class MagicConnector extends Connector {
|
||||
const { apiKey, ...options } = this.options;
|
||||
const configuration = this.getConfiguration();
|
||||
|
||||
const chains = Object.entries(this.options.rpcUrls);
|
||||
if (chains.length > 1) {
|
||||
console.warn(
|
||||
`Magic only supports connecting to one chain at a time. Using the first chain specified in rpcUrls: ${chains[0]}.`,
|
||||
);
|
||||
}
|
||||
const [chainId, rpcUrl] = chains[0];
|
||||
this.options.network = {
|
||||
chainId: parseInt(chainId),
|
||||
rpcUrl,
|
||||
};
|
||||
|
||||
try {
|
||||
invariant(
|
||||
configuration,
|
||||
|
||||
@@ -238,7 +238,7 @@ export function useContract(
|
||||
await queryClient.fetchQuery(
|
||||
compilerMetadata.cacheKey(contractAddress, activeChainId),
|
||||
() => compilerMetadata.fetchQuery(contractAddress, sdk),
|
||||
{ cacheTime: Infinity, staleTime: Infinity },
|
||||
{ cacheTime: Infinity, staleTime: Infinity, retry: 0 },
|
||||
)
|
||||
)?.abi;
|
||||
}
|
||||
@@ -258,6 +258,8 @@ export function useContract(
|
||||
cacheTime: Infinity,
|
||||
staleTime: Infinity,
|
||||
enabled: !!contractAddress && !!sdk && !!activeChainId,
|
||||
// never retry
|
||||
retry: 0,
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
# @thirdweb-dev/sdk
|
||||
|
||||
## 3.6.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#451](https://github.com/thirdweb-dev/js/pull/451) [`3731459`](https://github.com/thirdweb-dev/js/commit/3731459d33f1ded7ebb69124809449b901b3ad3d) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Less strict prebuilt checks to support OSRF variants
|
||||
|
||||
- [#450](https://github.com/thirdweb-dev/js/pull/450) [`cac6c30`](https://github.com/thirdweb-dev/js/commit/cac6c30bca5e17df81d746ef81316af47d5e252e) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Fix setting allowance or approvals gaslessly
|
||||
|
||||
- [#448](https://github.com/thirdweb-dev/js/pull/448) [`7a37e56`](https://github.com/thirdweb-dev/js/commit/7a37e564fd5d5a9df84c8da44ecaf6c42f67a0e2) Thanks [@jnsdls](https://github.com/jnsdls)! - [EVM] - allow `useContract` to fail faster to enable the import case
|
||||
|
||||
## 3.6.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#443](https://github.com/thirdweb-dev/js/pull/443) [`8c6cdaa`](https://github.com/thirdweb-dev/js/commit/8c6cdaa2887fb2cc40d3ee6991233d195d103805) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Fix signature minting from OpenSea Royalty Filter NFT collection contracts
|
||||
|
||||
## 3.6.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#440](https://github.com/thirdweb-dev/js/pull/440) [`efc56fa`](https://github.com/thirdweb-dev/js/commit/efc56fa5802490ac8ef50037658d046afd89e9a1) Thanks [@jnsdls](https://github.com/jnsdls)! - [EVM] - providers are now re-used if the constructor options are identical leading to better batching, also introduced an additional max batch size param (250 by default)
|
||||
|
||||
## 3.6.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/sdk",
|
||||
"version": "3.6.4",
|
||||
"version": "3.6.7",
|
||||
"description": "The main thirdweb SDK.",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/sdk",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -124,7 +124,7 @@ export async function setErc20Allowance(
|
||||
signer || provider,
|
||||
currencyAddress,
|
||||
ERC20Abi,
|
||||
{},
|
||||
contractToApprove.options,
|
||||
);
|
||||
|
||||
const owner = await contractToApprove.getSignerAddress();
|
||||
@@ -151,7 +151,7 @@ export async function approveErc20Allowance(
|
||||
signer || provider,
|
||||
currencyAddress,
|
||||
ERC20Abi,
|
||||
{},
|
||||
contractToApprove.options,
|
||||
);
|
||||
const owner = await contractToApprove.getSignerAddress();
|
||||
const spender = contractToApprove.readContract.address;
|
||||
|
||||
@@ -442,6 +442,11 @@ export async function fetchContractMetadata(
|
||||
storage: ThirdwebStorage,
|
||||
): Promise<PublishedMetadata> {
|
||||
const metadata = await storage.downloadJSON(compilerMetadataUri);
|
||||
if (!metadata || !metadata.output) {
|
||||
throw new Error(
|
||||
`Could not resolve metadata for contract at ${compilerMetadataUri}`,
|
||||
);
|
||||
}
|
||||
const abi = AbiSchema.parse(metadata.output.abi);
|
||||
const compilationTarget = metadata.settings.compilationTarget;
|
||||
const targets = Object.keys(compilationTarget);
|
||||
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
InterfaceId_IERC1155,
|
||||
InterfaceId_IERC721,
|
||||
} from "../constants/contract";
|
||||
import { SignerOrProvider } from "../core";
|
||||
import { ContractWrapper } from "../core/classes/contract-wrapper";
|
||||
import {
|
||||
NewAuctionListing,
|
||||
@@ -76,33 +75,38 @@ export async function isTokenApprovedForTransfer(
|
||||
/**
|
||||
* Checks if the marketplace is approved to make transfers on the assetContract
|
||||
* If not, it tries to set the approval.
|
||||
* @param signerOrProvider
|
||||
* @param contractWrapper
|
||||
* @param marketplaceAddress
|
||||
* @param assetContract
|
||||
* @param tokenId
|
||||
* @param from
|
||||
*/
|
||||
export async function handleTokenApproval(
|
||||
signerOrProvider: SignerOrProvider,
|
||||
contractWrapper: ContractWrapper<any>,
|
||||
marketplaceAddress: string,
|
||||
assetContract: string,
|
||||
tokenId: BigNumberish,
|
||||
from: string,
|
||||
): Promise<void> {
|
||||
const erc165 = new Contract(
|
||||
const erc165 = new ContractWrapper<IERC165>(
|
||||
contractWrapper.getSignerOrProvider(),
|
||||
assetContract,
|
||||
ERC165Abi,
|
||||
signerOrProvider,
|
||||
) as IERC165;
|
||||
const isERC721 = await erc165.supportsInterface(InterfaceId_IERC721);
|
||||
const isERC1155 = await erc165.supportsInterface(InterfaceId_IERC1155);
|
||||
contractWrapper.options,
|
||||
);
|
||||
const isERC721 = await erc165.readContract.supportsInterface(
|
||||
InterfaceId_IERC721,
|
||||
);
|
||||
const isERC1155 = await erc165.readContract.supportsInterface(
|
||||
InterfaceId_IERC1155,
|
||||
);
|
||||
// check for token approval
|
||||
if (isERC721) {
|
||||
const asset = new ContractWrapper<IERC721>(
|
||||
signerOrProvider,
|
||||
contractWrapper.getSignerOrProvider(),
|
||||
assetContract,
|
||||
ERC721Abi,
|
||||
{},
|
||||
contractWrapper.options,
|
||||
);
|
||||
const approved = await asset.readContract.isApprovedForAll(
|
||||
from,
|
||||
@@ -122,10 +126,10 @@ export async function handleTokenApproval(
|
||||
}
|
||||
} else if (isERC1155) {
|
||||
const asset = new ContractWrapper<IERC1155>(
|
||||
signerOrProvider,
|
||||
contractWrapper.getSignerOrProvider(),
|
||||
assetContract,
|
||||
ERC1155Abi,
|
||||
{},
|
||||
contractWrapper.options,
|
||||
);
|
||||
|
||||
const approved = await asset.readContract.isApprovedForAll(
|
||||
|
||||
@@ -123,6 +123,11 @@ export function getProviderForNetwork(network: ChainOrRpc | SignerOrProvider) {
|
||||
}
|
||||
}
|
||||
|
||||
const READONLY_PROVIDER_MAP: Map<
|
||||
string,
|
||||
StaticJsonRpcBatchProvider | providers.JsonRpcBatchProvider
|
||||
> = new Map();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param network - the chain name or rpc url
|
||||
@@ -136,11 +141,19 @@ export function getReadOnlyProvider(network: string, chainId?: number) {
|
||||
if (match) {
|
||||
switch (match[1]) {
|
||||
case "http":
|
||||
return chainId
|
||||
const seralizedOpts = `${network}-${chainId || -1}`;
|
||||
const existingProvider = READONLY_PROVIDER_MAP.get(seralizedOpts);
|
||||
if (existingProvider) {
|
||||
return existingProvider;
|
||||
}
|
||||
|
||||
const newProvider = chainId
|
||||
? // if we know the chainId we should use the StaticJsonRpcBatchProvider
|
||||
new StaticJsonRpcBatchProvider(network, chainId)
|
||||
: // otherwise fall back to the built in json rpc batch provider
|
||||
new providers.JsonRpcBatchProvider(network, chainId);
|
||||
READONLY_PROVIDER_MAP.set(seralizedOpts, newProvider);
|
||||
return newProvider;
|
||||
|
||||
case "ws":
|
||||
return new providers.WebSocketProvider(network, chainId);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import { getPrebuiltInfo } from "../common/legacy";
|
||||
import { ALL_ROLES } from "../common/role";
|
||||
import { getSignerAndProvider } from "../core/classes/rpc-connection-handler";
|
||||
@@ -56,12 +57,8 @@ export const EditionDropInitializer = {
|
||||
);
|
||||
},
|
||||
getAbi: async (address: string, provider: ethers.providers.Provider) => {
|
||||
const contractInfo = await assertContractType(
|
||||
address,
|
||||
provider,
|
||||
"edition-drop",
|
||||
);
|
||||
return contractInfo.version > 2
|
||||
const contractInfo = await getContractInfo(address, provider);
|
||||
return !contractInfo || contractInfo.version > 2
|
||||
? (await import("@thirdweb-dev/contracts-js/dist/abis/DropERC1155.json"))
|
||||
.default
|
||||
: (
|
||||
@@ -97,7 +94,6 @@ export const EditionInitializer = {
|
||||
);
|
||||
},
|
||||
getAbi: async (address: string, provider: ethers.providers.Provider) => {
|
||||
await assertContractType(address, provider, "edition");
|
||||
return (
|
||||
await import("@thirdweb-dev/contracts-js/dist/abis/TokenERC1155.json")
|
||||
).default;
|
||||
@@ -129,7 +125,6 @@ export const MarketplaceInitializer = {
|
||||
);
|
||||
},
|
||||
getAbi: async (address: string, provider: ethers.providers.Provider) => {
|
||||
await assertContractType(address, provider, "marketplace");
|
||||
return (
|
||||
await import("@thirdweb-dev/contracts-js/dist/abis/Marketplace.json")
|
||||
).default;
|
||||
@@ -161,7 +156,6 @@ export const MultiwrapInitializer = {
|
||||
);
|
||||
},
|
||||
getAbi: async (address: string, provider: ethers.providers.Provider) => {
|
||||
await assertContractType(address, provider, "multiwrap");
|
||||
return (await import("@thirdweb-dev/contracts-js/dist/abis/Multiwrap.json"))
|
||||
.default;
|
||||
},
|
||||
@@ -193,7 +187,6 @@ export const NFTCollectionInitializer = {
|
||||
);
|
||||
},
|
||||
getAbi: async (address: string, provider: ethers.providers.Provider) => {
|
||||
await assertContractType(address, provider, "nft-collection");
|
||||
return (
|
||||
await import("@thirdweb-dev/contracts-js/dist/abis/TokenERC721.json")
|
||||
).default;
|
||||
@@ -225,12 +218,8 @@ export const NFTDropInitializer = {
|
||||
);
|
||||
},
|
||||
getAbi: async (address: string, provider: ethers.providers.Provider) => {
|
||||
const contractInfo = await assertContractType(
|
||||
address,
|
||||
provider,
|
||||
"nft-drop",
|
||||
);
|
||||
return contractInfo.version > 3
|
||||
const contractInfo = await getContractInfo(address, provider);
|
||||
return !contractInfo || contractInfo.version > 3
|
||||
? (await import("@thirdweb-dev/contracts-js/dist/abis/DropERC721.json"))
|
||||
.default
|
||||
: (
|
||||
@@ -267,7 +256,6 @@ export const PackInitializer = {
|
||||
);
|
||||
},
|
||||
getAbi: async (address: string, provider: ethers.providers.Provider) => {
|
||||
await assertContractType(address, provider, "pack");
|
||||
return (await import("@thirdweb-dev/contracts-js/dist/abis/Pack.json"))
|
||||
.default;
|
||||
},
|
||||
@@ -299,12 +287,8 @@ export const SignatureDropInitializer = {
|
||||
);
|
||||
},
|
||||
getAbi: async (address: string, provider: ethers.providers.Provider) => {
|
||||
const contractInfo = await assertContractType(
|
||||
address,
|
||||
provider,
|
||||
"signature-drop",
|
||||
);
|
||||
return contractInfo.version > 4
|
||||
const contractInfo = await getContractInfo(address, provider);
|
||||
return !contractInfo || contractInfo.version > 4
|
||||
? (
|
||||
await import(
|
||||
"@thirdweb-dev/contracts-js/dist/abis/SignatureDrop.json"
|
||||
@@ -344,7 +328,6 @@ export const SplitInitializer = {
|
||||
);
|
||||
},
|
||||
getAbi: async (address: string, provider: ethers.providers.Provider) => {
|
||||
await assertContractType(address, provider, "split");
|
||||
return (await import("@thirdweb-dev/contracts-js/dist/abis/Split.json"))
|
||||
.default;
|
||||
},
|
||||
@@ -376,12 +359,8 @@ export const TokenDropInitializer = {
|
||||
);
|
||||
},
|
||||
getAbi: async (address: string, provider: ethers.providers.Provider) => {
|
||||
const contractInfo = await assertContractType(
|
||||
address,
|
||||
provider,
|
||||
"token-drop",
|
||||
);
|
||||
return contractInfo.version > 2
|
||||
const contractInfo = await getContractInfo(address, provider);
|
||||
return !contractInfo || contractInfo.version > 2
|
||||
? (await import("@thirdweb-dev/contracts-js/dist/abis/DropERC20.json"))
|
||||
.default
|
||||
: (await import("@thirdweb-dev/contracts-js/dist/abis/DropERC20_V2.json"))
|
||||
@@ -414,7 +393,6 @@ export const TokenInitializer = {
|
||||
);
|
||||
},
|
||||
getAbi: async (address: string, provider: ethers.providers.Provider) => {
|
||||
await assertContractType(address, provider, "token");
|
||||
return (
|
||||
await import("@thirdweb-dev/contracts-js/dist/abis/TokenERC20.json")
|
||||
).default;
|
||||
@@ -447,22 +425,20 @@ export const VoteInitializer = {
|
||||
);
|
||||
},
|
||||
getAbi: async (address: string, provider: ethers.providers.Provider) => {
|
||||
await assertContractType(address, provider, "vote");
|
||||
return (await import("@thirdweb-dev/contracts-js/dist/abis/VoteERC20.json"))
|
||||
.default;
|
||||
},
|
||||
};
|
||||
|
||||
async function assertContractType(
|
||||
async function getContractInfo(
|
||||
address: string,
|
||||
provider: ethers.providers.Provider,
|
||||
type: PrebuiltContractType,
|
||||
) {
|
||||
const contractInfo = await getPrebuiltInfo(address, provider);
|
||||
if (!contractInfo || contractInfo.type !== getContractName(type)) {
|
||||
throw new Error(`Contract is not a ${type}`);
|
||||
try {
|
||||
return await getPrebuiltInfo(address, provider);
|
||||
} catch (e) {
|
||||
return undefined;
|
||||
}
|
||||
return contractInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { hasFunction } from "../../common";
|
||||
import { detectContractFeature } from "../../common";
|
||||
import { normalizePriceValue, setErc20Allowance } from "../../common/currency";
|
||||
import { uploadOrExtractURIs } from "../../common/nft";
|
||||
import { FEATURE_NFT_SIGNATURE_MINTABLE_V2 } from "../../constants/erc721-features";
|
||||
@@ -22,7 +22,7 @@ import type {
|
||||
} from "@thirdweb-dev/contracts-js";
|
||||
import { TokensMintedWithSignatureEvent } from "@thirdweb-dev/contracts-js/dist/declarations/src/SignatureDrop";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import { BigNumber, ethers } from "ethers";
|
||||
import { BigNumber } from "ethers";
|
||||
import invariant from "tiny-invariant";
|
||||
|
||||
/**
|
||||
@@ -397,17 +397,9 @@ export class Erc721WithQuantitySignatureMintable implements DetectableFeature {
|
||||
}
|
||||
|
||||
private async isLegacyNFTContract() {
|
||||
if (hasFunction<TokenERC721>("contractType", this.contractWrapper)) {
|
||||
try {
|
||||
const contractType = ethers.utils.toUtf8String(
|
||||
await this.contractWrapper.readContract.contractType(),
|
||||
);
|
||||
return contractType.includes("TokenERC721");
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return detectContractFeature<ISignatureMintERC721>(
|
||||
this.contractWrapper,
|
||||
"ERC721SignatureMintV1",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ export class MarketplaceAuction {
|
||||
validateNewListingParam(listing);
|
||||
|
||||
await handleTokenApproval(
|
||||
this.contractWrapper.getSignerOrProvider(),
|
||||
this.contractWrapper,
|
||||
this.getAddress(),
|
||||
listing.assetContractAddress,
|
||||
listing.tokenId,
|
||||
|
||||
@@ -162,7 +162,7 @@ export class MarketplaceDirect {
|
||||
validateNewListingParam(listing);
|
||||
|
||||
await handleTokenApproval(
|
||||
this.contractWrapper.getSignerOrProvider(),
|
||||
this.contractWrapper,
|
||||
this.getAddress(),
|
||||
listing.assetContractAddress,
|
||||
listing.tokenId,
|
||||
|
||||
@@ -14,7 +14,7 @@ import EventEmitter from "eventemitter3";
|
||||
export class RPCConnectionHandler extends EventEmitter {
|
||||
private provider: providers.Provider;
|
||||
private signer: Signer | undefined;
|
||||
protected readonly options: SDKOptionsOutput;
|
||||
public readonly options: SDKOptionsOutput;
|
||||
|
||||
constructor(network: NetworkOrSignerOrProvider, options: SDKOptions) {
|
||||
super();
|
||||
|
||||
@@ -1,99 +1,130 @@
|
||||
import { providers, utils } from "ethers";
|
||||
|
||||
const DEFAULT_BATCH_TIME_LIMIT_MS = 50;
|
||||
const DEFAULT_BATCH_SIZE_LIMIT = 250;
|
||||
|
||||
const DEFAULT_BATCH_OPTIONS = {
|
||||
timeLimitMs: DEFAULT_BATCH_TIME_LIMIT_MS,
|
||||
sizeLimit: DEFAULT_BATCH_SIZE_LIMIT,
|
||||
};
|
||||
|
||||
export type BatchOptions = Partial<typeof DEFAULT_BATCH_OPTIONS>;
|
||||
|
||||
// mostly copied from ethers.js directly but make it a StaticJsonRpcProvider
|
||||
export class StaticJsonRpcBatchProvider extends providers.StaticJsonRpcProvider {
|
||||
_pendingBatchAggregator: NodeJS.Timer | null;
|
||||
_pendingBatch: Array<{
|
||||
request: { method: string, params: Array<any>, id: number, jsonrpc: "2.0" },
|
||||
resolve: (result: any) => void,
|
||||
reject: (error: Error) => void
|
||||
}> | null;
|
||||
private _timeLimitMs: number;
|
||||
private _sizeLimit: number;
|
||||
_pendingBatchAggregator: NodeJS.Timer | null;
|
||||
_pendingBatch: Array<{
|
||||
request: { method: string; params: Array<any>; id: number; jsonrpc: "2.0" };
|
||||
resolve: (result: any) => void;
|
||||
reject: (error: Error) => void;
|
||||
}> | null;
|
||||
|
||||
constructor(url: string | utils.ConnectionInfo | undefined, network: providers.Networkish | undefined){
|
||||
super(url, network);
|
||||
this._pendingBatchAggregator = null;
|
||||
this._pendingBatch = null;
|
||||
constructor(
|
||||
url: string | utils.ConnectionInfo | undefined,
|
||||
network: providers.Networkish | undefined,
|
||||
batchOptions: BatchOptions = DEFAULT_BATCH_OPTIONS,
|
||||
) {
|
||||
super(url, network);
|
||||
this._timeLimitMs = batchOptions.timeLimitMs || DEFAULT_BATCH_SIZE_LIMIT;
|
||||
this._sizeLimit = batchOptions.sizeLimit || DEFAULT_BATCH_TIME_LIMIT_MS;
|
||||
this._pendingBatchAggregator = null;
|
||||
this._pendingBatch = null;
|
||||
}
|
||||
|
||||
private sendCurrentBatch(request: any) {
|
||||
// if we still have a timeout clear that first
|
||||
if (this._pendingBatchAggregator) {
|
||||
clearTimeout(this._pendingBatchAggregator);
|
||||
}
|
||||
// Get the current batch and clear it, so new requests
|
||||
// go into the next batch
|
||||
const batch = this._pendingBatch || [];
|
||||
this._pendingBatch = null;
|
||||
this._pendingBatchAggregator = null;
|
||||
|
||||
send(method: string, params: Array<any>): Promise<any> {
|
||||
const request = {
|
||||
method: method,
|
||||
params: params,
|
||||
id: (this._nextId++),
|
||||
jsonrpc: "2.0"
|
||||
};
|
||||
// Get the request as an array of requests
|
||||
const request_ = batch.map((inflight) => inflight.request);
|
||||
|
||||
if (this._pendingBatch === null) {
|
||||
this._pendingBatch = [ ];
|
||||
}
|
||||
this.emit("debug", {
|
||||
action: "requestBatch",
|
||||
request: utils.deepCopy(request),
|
||||
provider: this,
|
||||
});
|
||||
|
||||
const inflightRequest: any = { request, resolve: null, reject: null };
|
||||
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
inflightRequest.resolve = resolve;
|
||||
inflightRequest.reject = reject;
|
||||
return utils.fetchJson(this.connection, JSON.stringify(request_)).then(
|
||||
(result) => {
|
||||
this.emit("debug", {
|
||||
action: "response",
|
||||
request: request_,
|
||||
response: result,
|
||||
provider: this,
|
||||
});
|
||||
|
||||
this._pendingBatch.push(inflightRequest);
|
||||
// For each result, feed it to the correct Promise, depending
|
||||
// on whether it was a success or error
|
||||
batch.forEach((inflightRequest_, index) => {
|
||||
const payload = result[index];
|
||||
if (payload.error) {
|
||||
const error = new Error(payload.error.message);
|
||||
(error as any).code = payload.error.code;
|
||||
(error as any).data = payload.error.data;
|
||||
inflightRequest_.reject(error);
|
||||
} else {
|
||||
inflightRequest_.resolve(payload.result);
|
||||
}
|
||||
});
|
||||
},
|
||||
(error) => {
|
||||
this.emit("debug", {
|
||||
action: "response",
|
||||
error: error,
|
||||
request: request_,
|
||||
provider: this,
|
||||
});
|
||||
|
||||
if (!this._pendingBatchAggregator) {
|
||||
// Schedule batch for next event loop + short duration
|
||||
this._pendingBatchAggregator = setTimeout(() => {
|
||||
// If there was an error, reject all the requests
|
||||
batch.forEach((inflightRequest_) => {
|
||||
inflightRequest_.reject(error);
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Get the current batch and clear it, so new requests
|
||||
// go into the next batch
|
||||
const batch = this._pendingBatch || [];
|
||||
this._pendingBatch = null;
|
||||
this._pendingBatchAggregator = null;
|
||||
send(method: string, params: Array<any>): Promise<any> {
|
||||
const request = {
|
||||
method: method,
|
||||
params: params,
|
||||
id: this._nextId++,
|
||||
jsonrpc: "2.0",
|
||||
};
|
||||
|
||||
// Get the request as an array of requests
|
||||
const request_ = batch.map((inflight) => inflight.request);
|
||||
|
||||
this.emit("debug", {
|
||||
action: "requestBatch",
|
||||
request: utils.deepCopy(request),
|
||||
provider: this
|
||||
});
|
||||
|
||||
return utils.fetchJson(this.connection, JSON.stringify(request_)).then((result) => {
|
||||
this.emit("debug", {
|
||||
action: "response",
|
||||
request: request_,
|
||||
response: result,
|
||||
provider: this
|
||||
});
|
||||
|
||||
// For each result, feed it to the correct Promise, depending
|
||||
// on whether it was a success or error
|
||||
batch.forEach((inflightRequest_, index) => {
|
||||
const payload = result[index];
|
||||
if (payload.error) {
|
||||
const error = new Error(payload.error.message);
|
||||
(<any>error).code = payload.error.code;
|
||||
(<any>error).data = payload.error.data;
|
||||
inflightRequest_.reject(error);
|
||||
} else {
|
||||
inflightRequest_.resolve(payload.result);
|
||||
}
|
||||
});
|
||||
|
||||
}, (error) => {
|
||||
this.emit("debug", {
|
||||
action: "response",
|
||||
error: error,
|
||||
request: request,
|
||||
provider: this
|
||||
});
|
||||
|
||||
batch.forEach((inflightRequest_) => {
|
||||
inflightRequest_.reject(error);
|
||||
});
|
||||
});
|
||||
|
||||
}, 10);
|
||||
}
|
||||
|
||||
return promise;
|
||||
if (this._pendingBatch === null) {
|
||||
this._pendingBatch = [];
|
||||
}
|
||||
}
|
||||
|
||||
const inflightRequest: any = { request, resolve: null, reject: null };
|
||||
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
inflightRequest.resolve = resolve;
|
||||
inflightRequest.reject = reject;
|
||||
});
|
||||
|
||||
// if we would go *over* the size limit of the batch with this request, send the batch now
|
||||
if (this._pendingBatch.length === this._sizeLimit) {
|
||||
this.sendCurrentBatch(request);
|
||||
}
|
||||
|
||||
this._pendingBatch.push(inflightRequest);
|
||||
|
||||
if (!this._pendingBatchAggregator) {
|
||||
// Schedule batch for next event loop + short duration
|
||||
this._pendingBatchAggregator = setTimeout(() => {
|
||||
this.sendCurrentBatch(request);
|
||||
}, this._timeLimitMs);
|
||||
}
|
||||
|
||||
return promise;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,29 @@
|
||||
# @thirdweb-dev/unity-js-bridge
|
||||
|
||||
## 0.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`3731459`](https://github.com/thirdweb-dev/js/commit/3731459d33f1ded7ebb69124809449b901b3ad3d), [`cac6c30`](https://github.com/thirdweb-dev/js/commit/cac6c30bca5e17df81d746ef81316af47d5e252e), [`7a37e56`](https://github.com/thirdweb-dev/js/commit/7a37e564fd5d5a9df84c8da44ecaf6c42f67a0e2)]:
|
||||
- @thirdweb-dev/sdk@3.6.7
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8c6cdaa`](https://github.com/thirdweb-dev/js/commit/8c6cdaa2887fb2cc40d3ee6991233d195d103805)]:
|
||||
- @thirdweb-dev/sdk@3.6.6
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#433](https://github.com/thirdweb-dev/js/pull/433) [`7269268`](https://github.com/thirdweb-dev/js/commit/72692689e9adb41e92038765fd01a36c2b7457e1) Thanks [@jnsdls](https://github.com/jnsdls)! - add fundWallet method to bridge
|
||||
|
||||
- Updated dependencies [[`efc56fa`](https://github.com/thirdweb-dev/js/commit/efc56fa5802490ac8ef50037658d046afd89e9a1), [`7269268`](https://github.com/thirdweb-dev/js/commit/72692689e9adb41e92038765fd01a36c2b7457e1)]:
|
||||
- @thirdweb-dev/sdk@3.6.5
|
||||
- @thirdweb-dev/pay@0.1.0
|
||||
|
||||
## 0.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@thirdweb-dev/unity-js-bridge",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.3",
|
||||
"main": "dist/thirdweb-unity-bridge.js",
|
||||
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/unity-js-bridge",
|
||||
"license": "Apache-2.0",
|
||||
@@ -15,6 +15,7 @@
|
||||
"@thirdweb-dev/sdk": "*",
|
||||
"@thirdweb-dev/storage": "*",
|
||||
"@thirdweb-dev/wallets": "*",
|
||||
"@thirdweb-dev/pay": "*",
|
||||
"ethers": "^5.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/// --- Thirdweb Brige ---
|
||||
import { CoinbasePayIntegration, FundWalletOptions } from "@thirdweb-dev/pay";
|
||||
import { ChainOrRpc, ThirdwebSDK } from "@thirdweb-dev/sdk/evm";
|
||||
import { ThirdwebStorage } from "@thirdweb-dev/storage";
|
||||
import {
|
||||
@@ -44,12 +45,17 @@ const WALLETS = [
|
||||
|
||||
type PossibleWallet = typeof WALLETS[number]["id"];
|
||||
|
||||
type FundWalletInput = FundWalletOptions & {
|
||||
appId: string;
|
||||
};
|
||||
|
||||
interface TWBridge {
|
||||
initialize: (chain: ChainOrRpc, options: string) => void;
|
||||
connect: (wallet: PossibleWallet, chainId?: number) => Promise<string>;
|
||||
disconnect: () => Promise<void>;
|
||||
switchNetwork: (chainId: number) => Promise<void>;
|
||||
invoke: (route: string, payload: string) => Promise<string | undefined>;
|
||||
fundWallet: (options: string) => Promise<void>;
|
||||
}
|
||||
|
||||
const w = window;
|
||||
@@ -211,6 +217,15 @@ class ThirdwebBridge implements TWBridge {
|
||||
}
|
||||
}
|
||||
}
|
||||
public async fundWallet(options: string) {
|
||||
if (!this.activeSDK) {
|
||||
throw new Error("SDK not initialized");
|
||||
}
|
||||
const { appId, ...fundOptions } = JSON.parse(options) as FundWalletInput;
|
||||
const cbPay = new CoinbasePayIntegration({ appId });
|
||||
|
||||
return await cbPay.fundWallet(fundOptions);
|
||||
}
|
||||
}
|
||||
|
||||
// add the bridge to the window object type
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
"outputs": ["dist/**", "wallets/**", "connectors/**"],
|
||||
"dependsOn": ["^build"]
|
||||
},
|
||||
"@thirdweb-dev/pay#build": {
|
||||
"outputs": ["dist/**", "integrations/**"],
|
||||
"dependsOn": ["^build"]
|
||||
},
|
||||
"@thirdweb-dev/sdk#build": {
|
||||
"outputs": ["dist/**", "evm/**", "solana/**"],
|
||||
"dependsOn": ["^build"]
|
||||
|
||||
@@ -2103,6 +2103,11 @@
|
||||
human-id "^1.0.2"
|
||||
prettier "^2.7.1"
|
||||
|
||||
"@coinbase/cbpay-js@^1.6.0":
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@coinbase/cbpay-js/-/cbpay-js-1.6.0.tgz#23f4456ba57f3e6ba1583e21376e9a2337fd1aaa"
|
||||
integrity sha512-jt1BUaMLbA2/xfHc2YC/Uq+rYD0LIpU5s70ms8VpxImNGiMLUEgUZnAzjk1aIqWiTpQWRmwqyq+WvKTb0Yv05Q==
|
||||
|
||||
"@coinbase/wallet-sdk@^3.0.8", "@coinbase/wallet-sdk@^3.6.0":
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@coinbase/wallet-sdk/-/wallet-sdk-3.6.0.tgz#52cc01d6721b171b69f8c4a83ef5029e52d997d4"
|
||||
@@ -9759,6 +9764,13 @@ [email protected], detect-node@^2.0.4:
|
||||
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1"
|
||||
integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==
|
||||
|
||||
detect-package-manager@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/detect-package-manager/-/detect-package-manager-2.0.1.tgz#6b182e3ae5e1826752bfef1de9a7b828cffa50d8"
|
||||
integrity sha512-j/lJHyoLlWi6G1LDdLgvUtz60Zo5GEj+sVYtTVXnYLDPuzgC3llMxonXym9zIwhhUII8vjdw0LXxavpLqTbl1A==
|
||||
dependencies:
|
||||
execa "^5.1.1"
|
||||
|
||||
detect-port-alt@^1.1.6:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275"
|
||||
|
||||
Reference in New Issue
Block a user