Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd0cf2cc54 | ||
|
|
27a981c84b | ||
|
|
29be1e37bc | ||
|
|
e727efc33e | ||
|
|
4af2c19f45 | ||
|
|
4f67ecdf62 | ||
|
|
3396846a30 | ||
|
|
5c27b45ac9 | ||
|
|
20f6e16394 | ||
|
|
2df9dd1120 | ||
|
|
74470defda | ||
|
|
8175c83026 | ||
|
|
e0ccafb140 | ||
|
|
20335e96c2 | ||
|
|
a56a0a3336 | ||
|
|
4ad47b1b43 | ||
|
|
0e6cc9a9a8 | ||
|
|
21c6c7ddb6 | ||
|
|
8efbfc6afa | ||
|
|
8e3cfd8517 | ||
|
|
0a6c15e691 | ||
|
|
d3b1ac046a | ||
|
|
86b413750d | ||
|
|
70c2b1b300 | ||
|
|
5cb418cf7d | ||
|
|
8e4ee887b9 | ||
|
|
ef09361539 | ||
|
|
6e36447aa0 | ||
|
|
1c4259881a | ||
|
|
ba00df1ab7 | ||
|
|
45a2902874 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -25,3 +25,5 @@ packages/testcases/input/nameprep/**
|
||||
.nyc_output/**
|
||||
|
||||
output/**
|
||||
|
||||
misc/testing/**
|
||||
|
||||
40
CHANGELOG.md
40
CHANGELOG.md
@@ -3,6 +3,42 @@ Changelog
|
||||
|
||||
This change log is managed by `admin/cmds/update-versions` but may be manually updated.
|
||||
|
||||
ethers/v5.0.28 (2021-02-02 17:12)
|
||||
---------------------------------
|
||||
|
||||
- Added load balancer support to PocketProvider. ([#1052](https://github.com/ethers-io/ethers.js/issues/1052); [27a981c](https://github.com/ethers-io/ethers.js/commit/27a981c84b578feb762fdb37dd5325d9c335bd59))
|
||||
|
||||
ethers/v5.0.27 (2021-02-01 15:55)
|
||||
---------------------------------
|
||||
|
||||
- Added support for networks with slightly incorrect EIP-658 implementations. ([#952](https://github.com/ethers-io/ethers.js/issues/952), [#1251](https://github.com/ethers-io/ethers.js/issues/1251); [e727efc](https://github.com/ethers-io/ethers.js/commit/e727efc33eaa31c3af6adbb64a893caf354d0ba7))
|
||||
- Added Pocket network to the default provider. ([#1030](https://github.com/ethers-io/ethers.js/issues/1030), [#1052](https://github.com/ethers-io/ethers.js/issues/1052); [4af2c19](https://github.com/ethers-io/ethers.js/commit/4af2c19f455bb43406d3cc5421c3b3fdda75f78f))
|
||||
- Added TypeScript declaration maps. ([#401](https://github.com/ethers-io/ethers.js/issues/401); [3396846](https://github.com/ethers-io/ethers.js/commit/3396846a30a4be0ed58fe449589e7e4e54f3d32e))
|
||||
|
||||
ethers/v5.0.26 (2021-01-13 14:47)
|
||||
---------------------------------
|
||||
|
||||
- Fixed abundant UnhandledRejectErrors in provider polling. ([#1084](https://github.com/ethers-io/ethers.js/issues/1084), [#1208](https://github.com/ethers-io/ethers.js/issues/1208), [#1221](https://github.com/ethers-io/ethers.js/issues/1221), [#1235](https://github.com/ethers-io/ethers.js/issues/1235); [74470de](https://github.com/ethers-io/ethers.js/commit/74470defda5170338735bbbe676c207cdd5cc1cf), [20f6e16](https://github.com/ethers-io/ethers.js/commit/20f6e16394909a43498c1ac6c73152957bd121bd))
|
||||
- Fixed non-checksum address comparisons in abstract Signer. ([#1236](https://github.com/ethers-io/ethers.js/issues/1236); [8175c83](https://github.com/ethers-io/ethers.js/commit/8175c83026436b6335800780ca12b7257e1b490f))
|
||||
|
||||
ethers/v5.0.25 (2021-01-08 03:31)
|
||||
---------------------------------
|
||||
|
||||
- Safety check on digest length for signing. ([20335e9](https://github.com/ethers-io/ethers.js/commit/20335e96c2429e851081b72031ea3fd4cd677904))
|
||||
- Fixed listenerCount for contract when requesting for all events. ([#1205](https://github.com/ethers-io/ethers.js/issues/1205); [a56a0a3](https://github.com/ethers-io/ethers.js/commit/a56a0a33366ea9276fba5bc45f1e4678dd723fa6))
|
||||
- Lock package versions for the ESM builds. ([#1009](https://github.com/ethers-io/ethers.js/issues/1009); [0e6cc9a](https://github.com/ethers-io/ethers.js/commit/0e6cc9a9a8ebceae4529ccbb7c107618eb54490a))
|
||||
|
||||
ethers/v5.0.24 (2020-12-08 01:43)
|
||||
---------------------------------
|
||||
|
||||
- Fixed EIP-712 getPayload dropping EIP712Domain from types for JSON-RPC calls. ([#687](https://github.com/ethers-io/ethers.js/issues/687); [d3b1ac0](https://github.com/ethers-io/ethers.js/commit/d3b1ac046aaf2a46f6c3efbd93c55adb0cb8f16d))
|
||||
- Remvoed dead files. ([70c2b1b](https://github.com/ethers-io/ethers.js/commit/70c2b1b3002f44c39f4fd87fc2cfc3f5dc6555ed))
|
||||
|
||||
ethers/v5.0.23 (2020-11-25 15:25)
|
||||
---------------------------------
|
||||
|
||||
- Fix BigNumber when passed something with a length property. ([#1172](https://github.com/ethers-io/ethers.js/issues/1172); [45a2902](https://github.com/ethers-io/ethers.js/commit/45a2902874e828a16396a253548bcb00bceccf95))
|
||||
|
||||
ethers/v5.0.22 (2020-11-23 19:16)
|
||||
---------------------------------
|
||||
|
||||
@@ -10,7 +46,7 @@ ethers/v5.0.22 (2020-11-23 19:16)
|
||||
- Add ABI coder function to compute default values. ([#1101](https://github.com/ethers-io/ethers.js/issues/1101); [a8e3380](https://github.com/ethers-io/ethers.js/commit/a8e3380ed547b6368be5fe40b48be6e31b5cdd93))
|
||||
- Fix for new versions of Geth which return formatted data on revert rather than standard data. ([#949](https://github.com/ethers-io/ethers.js/issues/949); [4a8d579](https://github.com/ethers-io/ethers.js/commit/4a8d579dcaf026d0c232e20176605d34cba4767d))
|
||||
- Addd missing sideEffects flag to some packages. ([20defec](https://github.com/ethers-io/ethers.js/commit/20defec9f1683487b6ea9c8730d2ab7b3745bfa5))
|
||||
- Allow base-10 to be passed into BigNumbner.toString and improve errors for other radices. ([#1164](https://github.com/ethers-io/ethers.js/issues/1164); [c8bb77d](https://github.com/ethers-io/ethers.js/commit/c8bb77d8af85d2f9f9df82f1afbe7516ab296e98), [#1164](https://github.com/ethers-io/ethers.js/issues/1164); [fbbe4ad](https://github.com/ethers-io/ethers.js/commit/fbbe4ad638e06089cdd976a7f4ffd51b85a31558))
|
||||
- Allow base-10 to be passed into BigNumbner.toString and improve errors for other radices. ([#1164](https://github.com/ethers-io/ethers.js/issues/1164); [c8bb77d](https://github.com/ethers-io/ethers.js/commit/c8bb77d8af85d2f9f9df82f1afbe7516ab296e98), [fbbe4ad](https://github.com/ethers-io/ethers.js/commit/fbbe4ad638e06089cdd976a7f4ffd51b85a31558))
|
||||
- Allow private keys to Wallet to omit the 0x prefix. ([#1166](https://github.com/ethers-io/ethers.js/issues/1166); [29f6c34](https://github.com/ethers-io/ethers.js/commit/29f6c34343d75fa42023bdcd07632f49a450570c))
|
||||
|
||||
ethers/v5.0.21 (2020-11-19 18:52)
|
||||
@@ -188,4 +224,4 @@ ethers/v5.0.0 (2020-06-12 19:58)
|
||||
--------------------------------
|
||||
|
||||
- Preserve config canary string. ([7157816](https://github.com/ethers-io/ethers.js/commit/7157816fa53f660d750811b293e3b1d5a2f70bd4))
|
||||
- Updated docs. ([9e4c7e6](https://github.com/ethers-io/ethers.js/commit/9e4c7e609d9eeb5f2a11d6a90bfa9d32ee696431))
|
||||
- Updated docs. ([9e4c7e6](https://github.com/ethers-io/ethers.js/commit/9e4c7e609d9eeb5f2a11d6a90bfa9d32ee696431))
|
||||
@@ -1,59 +0,0 @@
|
||||
Admin Tool
|
||||
==========
|
||||
|
||||
This tool is meant for admin tasks related to ethers.js.
|
||||
|
||||
|
||||
Workflow
|
||||
--------
|
||||
|
||||
After a new series of changes have been made and tested:
|
||||
|
||||
1. Run `npm run update-versions` to update and build all packages
|
||||
2. Make any human-necessary changes to the automatically updated `CHANGELOG.md`
|
||||
3. Run `git add .`
|
||||
4. Run `git commit -S -m "Updated dist files."`
|
||||
5. Run `git push`
|
||||
6. Wait for TravisCI to complete running test cases
|
||||
7. Run `npm run publish-all` to publish changed packages to NPM and tag GitHub
|
||||
|
||||
|
||||
Update Dependency Graph: admin/cmds/update-depgraph
|
||||
---------------------------------------------------
|
||||
|
||||
This is run as part of `npm run bootstrap` before running lerna bootstrap.
|
||||
It recomputes the dependency graph and writes out the ordered
|
||||
**tsconfig.project.json**
|
||||
|
||||
|
||||
Update Versions: admin/cmds/update-versions
|
||||
-------------------------------------------
|
||||
|
||||
Run using the `npm run update-versions`, which also cleans, bootstraps and
|
||||
rebuilds the project before running the script.
|
||||
|
||||
For each package that has changed from the version in NPM (the published
|
||||
tarballs are compared):
|
||||
|
||||
- Update the `version` in the **package.json**
|
||||
- Update the `src.ts/_version.ts` (matches the **package.json**)
|
||||
- Updates the `tarballHash` in the **package.json**
|
||||
- Compiles the TypeScript (which updates the `_version.js` and `_version.d.js`)
|
||||
- Lists all changed files (highlighting src.ts files)
|
||||
|
||||
Then:
|
||||
|
||||
- Generate the distribution files
|
||||
- Update the `CHANGELOG.md`
|
||||
|
||||
|
||||
Publish: admin/cmds/publish
|
||||
---------------------------
|
||||
|
||||
Run using `npm run publish-all`. This requires a password for the secure
|
||||
local config and the OTP for NPM.
|
||||
|
||||
- Publish (in dependency order) changed files to NPM
|
||||
- The `gitHead` is updated in **only** the NPM **package.json**
|
||||
- @TODO: Cut a release on GitHub including the relevant CHANGELOG entry
|
||||
|
||||
111
admin/build.js
111
admin/build.js
@@ -1,111 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const resolve = require("path").resolve;
|
||||
const spawn = require("child_process").spawn;
|
||||
|
||||
const { dirnames } = require("./local");
|
||||
const { loadPackage, savePackage } = require("./local");
|
||||
const { loadJson, saveJson } = require("./utils");
|
||||
|
||||
function run(progname, args, ignoreErrorStream) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const proc = spawn(progname, args);
|
||||
|
||||
let stdout = Buffer.from([]);
|
||||
let stderr = Buffer.from([]);
|
||||
|
||||
proc.stdout.on("data", (data) => {
|
||||
stdout = Buffer.concat([ stdout, data ]);
|
||||
});
|
||||
|
||||
proc.stderr.on("data", (data) => {
|
||||
stderr = Buffer.concat([ stdout, data ]);
|
||||
});
|
||||
|
||||
proc.on("error", (error) => {
|
||||
console.log("ERROR");
|
||||
console.log(stderr.toString());
|
||||
error.stderr = stderr.toString();
|
||||
error.stdout = stdout.toString();
|
||||
reject(error);
|
||||
});
|
||||
|
||||
proc.on("close", (code) => {
|
||||
if ((stderr.length && !ignoreErrorStream) || code !== 0) {
|
||||
console.log("ERROR");
|
||||
console.log(stderr.toString());
|
||||
|
||||
let error = new Error(`stderr not empty: ${ progname } ${ JSON.stringify(args) }`);
|
||||
error.stderr = stderr.toString();
|
||||
error.stdout = stdout.toString();
|
||||
error.statusCode = code;
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(stdout.toString());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function setupConfig(outDir, moduleType, targetType) {
|
||||
|
||||
// Configure the tsconfit.package.json...
|
||||
const path = resolve(__dirname, "../tsconfig.package.json");
|
||||
const content = loadJson(path);
|
||||
content.compilerOptions.module = moduleType;
|
||||
content.compilerOptions.target = targetType;
|
||||
saveJson(path, content);
|
||||
|
||||
// Configure the browser field for every pacakge, copying the
|
||||
// browser.umd filed for UMD and browser.esm for ESM
|
||||
dirnames.forEach((dirname) => {
|
||||
let info = loadPackage(dirname);
|
||||
|
||||
if (info._ethers_nobuild) { return; }
|
||||
|
||||
if (targetType === "es2015") {
|
||||
if (info["browser.esm"]) {
|
||||
info.browser = info["browser.esm"];
|
||||
}
|
||||
} else if (targetType === "es5") {
|
||||
if (info["browser.umd"]) {
|
||||
info.browser = info["browser.umd"];
|
||||
}
|
||||
} else {
|
||||
throw new Error("unsupported target");
|
||||
}
|
||||
savePackage(dirname, info);
|
||||
|
||||
let path = resolve(__dirname, "../packages", dirname, "tsconfig.json");
|
||||
let content = loadJson(path);
|
||||
content.compilerOptions.outDir = outDir;
|
||||
saveJson(path, content);
|
||||
});
|
||||
}
|
||||
|
||||
function setupBuild(buildModule) {
|
||||
if (buildModule) {
|
||||
setupConfig("./lib.esm/", "es2015", "es2015");
|
||||
} else {
|
||||
setupConfig("./lib/", "commonjs", "es5");
|
||||
}
|
||||
}
|
||||
|
||||
function runBuild(buildModule) {
|
||||
setupBuild(buildModule);
|
||||
|
||||
// Compile
|
||||
return run("npx", [ "tsc", "--build", resolve(__dirname, "../tsconfig.project.json"), "--force" ]);
|
||||
}
|
||||
|
||||
function runDist() {
|
||||
return run("npm", [ "run", "_dist" ], true);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
run: run,
|
||||
runDist: runDist,
|
||||
runBuild: runBuild,
|
||||
setupBuild: setupBuild
|
||||
};
|
||||
@@ -1,145 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const resolve = require("path").resolve;
|
||||
|
||||
const git = require("./git");
|
||||
const local = require("./local");
|
||||
const npm = require("./npm");
|
||||
const utils = require("./utils");
|
||||
|
||||
const ChangelogPath = resolve(__dirname, "../CHANGELOG.md");
|
||||
|
||||
async function generate() {
|
||||
|
||||
// Get each section of the Changelog
|
||||
let existing = fs.readFileSync(ChangelogPath).toString().split("\n");
|
||||
let sections = [ ];
|
||||
let lastLine = existing[0];
|
||||
existing.slice(1).forEach((line) => {
|
||||
if (line.substring(0, 5) === "=====" || line.substring(0, 5) === "-----") {
|
||||
sections.push({
|
||||
title: lastLine,
|
||||
underline: line.substring(0, 1),
|
||||
body: [ ]
|
||||
});
|
||||
lastLine = null;
|
||||
return;
|
||||
} else if (lastLine) {
|
||||
sections[sections.length - 1].body.push(lastLine);
|
||||
}
|
||||
lastLine = line;
|
||||
});
|
||||
sections[sections.length - 1].body.push(lastLine);
|
||||
|
||||
let lastVersion = await npm.getPackageVersion("ethers");
|
||||
|
||||
let logs = await git.run([ "log", (lastVersion.gitHead + "..") ]);
|
||||
|
||||
let changes = [ ];
|
||||
logs.split("\n").forEach((line) => {
|
||||
if (line.toLowerCase().substring(0, 6) === "commit") {
|
||||
changes.push({
|
||||
commit: line.substring(6).trim(),
|
||||
body: [ ]
|
||||
});
|
||||
} else if (line.toLowerCase().substring(0, 5) === "date:") {
|
||||
changes[changes.length - 1].date = utils.getDateTime(new Date(line.substring(5).trim()));
|
||||
} else if (line.substring(0, 1) === " ") {
|
||||
line = line.trim();
|
||||
if (line === "") { return; }
|
||||
changes[changes.length - 1].body += line + " ";
|
||||
}
|
||||
});
|
||||
|
||||
// @TODO:
|
||||
// ethers/version ([date](tag))
|
||||
let newSection = {
|
||||
title: `ethers/v${ local.loadPackage("ethers").version } (${utils.getDateTime(new Date())})`,
|
||||
underline: "-",
|
||||
body: [ ]
|
||||
}
|
||||
|
||||
// Delete duplicate sections for the same version (ran update multiple times)
|
||||
while (sections[1].title === newSection.title) {
|
||||
sections.splice(1, 1);
|
||||
}
|
||||
|
||||
changes.forEach((change) => {
|
||||
let body = change.body.trim();
|
||||
let link = body.match(/(\((.*#.*)\))/)
|
||||
let commit = `[${ change.commit.substring(0, 7) }](https://github.com/ethers-io/ethers.js/commit/${ change.commit })`;
|
||||
if (link) {
|
||||
body = body.replace(/ *(\(.*#.*)\) */, "");
|
||||
link = link[2].replace(/#([0-9]+)/g, (all, issue) => {
|
||||
return `[#${ issue }](https://github.com/ethers-io/ethers.js/issues/${ issue })`;
|
||||
}) + "; " + commit;
|
||||
} else {
|
||||
link = commit;
|
||||
}
|
||||
newSection.body.push(` - ${ body } (${ link })`);
|
||||
});
|
||||
|
||||
sections.splice(1, 0, newSection);
|
||||
|
||||
|
||||
let formatted = [ ];
|
||||
sections.forEach((section) => {
|
||||
formatted.push(section.title);
|
||||
formatted.push(utils.repeat(section.underline, section.title.length));
|
||||
formatted.push("");
|
||||
section.body.forEach((line) => {
|
||||
line = line.trim();
|
||||
if (line === "") { return; }
|
||||
if (line.substring(0, 1) === "-") {
|
||||
line = "- " + line.substring(1).trim();
|
||||
}
|
||||
if (section.underline === "-") {
|
||||
line = " " + line;
|
||||
}
|
||||
formatted.push(line);
|
||||
});
|
||||
formatted.push("");
|
||||
});
|
||||
|
||||
return formatted.join("\n") + "\n";
|
||||
}
|
||||
|
||||
function getChanges() {
|
||||
const changes = [ ];
|
||||
|
||||
let lastLine = null;
|
||||
fs.readFileSync(ChangelogPath).toString().split("\n").forEach((line) => {
|
||||
line = line.trim();
|
||||
if (line === "") { return; }
|
||||
|
||||
if (line.substring(0, 5) === "-----") {
|
||||
changes.push({ title: lastLine, lines: [ ] });
|
||||
} else if (line.substring(0, 1) === "-" && changes.length) {
|
||||
changes[changes.length - 1].lines.push(line);
|
||||
}
|
||||
lastLine = line;
|
||||
});
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
function latestChange() {
|
||||
const recent = getChanges()[0];
|
||||
|
||||
const match = recent.title.match(/ethers\/([^\(]*)\(([^\)]*)\)/);
|
||||
|
||||
return {
|
||||
title: recent.title,
|
||||
version: match[1].trim(),
|
||||
data: match[2].trim(),
|
||||
content: recent.lines.join("\n")
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
generate: generate,
|
||||
latestChange: latestChange,
|
||||
ChangelogPath: ChangelogPath,
|
||||
}
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const { colorify } = require("../log");
|
||||
const { getIssues } = require("../github");
|
||||
const { repeat } = require("../utils");
|
||||
|
||||
const Options = {
|
||||
"body": 1,
|
||||
"end": 1,
|
||||
"issue": 1,
|
||||
"start": 1,
|
||||
"title": 1,
|
||||
"user": 1,
|
||||
};
|
||||
|
||||
const Flags = {
|
||||
"open": 1,
|
||||
"match-case": 1,
|
||||
};
|
||||
|
||||
(async function() {
|
||||
const options = { };
|
||||
for (let i = 2; i < process.argv.length; i++) {
|
||||
const option = process.argv[i];
|
||||
if (option.substring(0, 2) === "--") {
|
||||
const comps = option.substring(2).split(/=/);
|
||||
if (Flags[comps[0]]) {
|
||||
if (comps[1] != null) { throw new Error("Invalid flag: " + option); }
|
||||
options[comps[0]] = true;
|
||||
} else if (Options[comps[0]]) {
|
||||
if (comps[1] == null) {
|
||||
options[comps[0]] = process.argv[++i];
|
||||
if (options[comps[0]] == null) {
|
||||
throw new Error("Missing option value: " + option);
|
||||
}
|
||||
} else {
|
||||
options[comps[0]] = comps[1];
|
||||
}
|
||||
} else {
|
||||
throw new Error("Unexpected option: " + option);
|
||||
}
|
||||
} else {
|
||||
throw new Error("Unexpected argument: " + option);
|
||||
}
|
||||
}
|
||||
|
||||
if (options["title"]) { options.title = new RegExp(options.title, (options["match-case"] ? "": "i")); }
|
||||
if (options["body"]) { options.body = new RegExp(options.title, (options["match-case"] ? "": "i")); }
|
||||
if (options["start"]) {
|
||||
if (options["start"].match(/^[0-9]{4}-[0-9]{2}-[0-9{2}]$/)) {
|
||||
throw new Error("Expected YYYY-MM-DD");
|
||||
}
|
||||
}
|
||||
if (options["end"]) {
|
||||
if (options["end"].match(/^[0-9]{4}-[0-9]{2}-[0-9{2}]$/)) {
|
||||
throw new Error("Expected YYYY-MM-DD");
|
||||
}
|
||||
}
|
||||
|
||||
const count = { issues: 0, comments: 0, code: 0, responses: 0 };
|
||||
|
||||
const issues = await getIssues();
|
||||
issues.forEach((issue) => {
|
||||
const info = issue.issue;
|
||||
const comments = issue.comments;
|
||||
|
||||
if (options.issue && parseInt(options.issue) != info.number) { return; }
|
||||
if (options.open && info.state !== "open") { return; }
|
||||
if (options.title && !info.title.match(options.title)) { return; }
|
||||
if (options.body) {
|
||||
const body = info.body + "\n" + comments.map((c) => (c.body)).join("\n");
|
||||
if (!body.match(options.body)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (options.user) {
|
||||
const users = comments.map((c) => (c.user.login));
|
||||
users.push(info.user.login);
|
||||
if (users.indexOf(options.user) === -1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const dates = comments.map((c) => (c.created_at.split("T")[0]));
|
||||
dates.push(info.created_at.split("T")[0]);
|
||||
|
||||
if (options.start) {
|
||||
if (dates.filter((d) => (d >= options.start)).length === 0) { return; }
|
||||
}
|
||||
if (options.end) {
|
||||
if (dates.filter((d) => (d <= options.start)).length === 0) { return; }
|
||||
}
|
||||
|
||||
count.issues++;
|
||||
|
||||
console.log(colorify(repeat("=", 70), "bold"))
|
||||
console.log(colorify("Issue:", "bold"), info.title, ` (#${ info.number })`);
|
||||
console.log(colorify("User:","bold"), colorify(info.user.login, "blue"));
|
||||
console.log(colorify("State:", "bold"), info.state);
|
||||
if (info.created_at === info.updated_at) {
|
||||
console.log(colorify("Created:", "bold"), info.created_at);
|
||||
} else {
|
||||
console.log(colorify("Created:", "bold"), info.created_at, ` (updated: ${ info.updated_at })`);
|
||||
}
|
||||
info.body.trim().split("\n").forEach((line) => {
|
||||
console.log(" " + line);
|
||||
});
|
||||
|
||||
if (comments.length) {
|
||||
comments.forEach((info) => {
|
||||
if (options.start && info.created_at < options.start) { return ; }
|
||||
if (options.end && info.created_at > options.end) { return; }
|
||||
count.comments++;
|
||||
if (options.user && info.user.login !== options.user) { return; }
|
||||
count.responses++;
|
||||
if (info.body.indexOf("`") >= 0) { count.code++; }
|
||||
console.log(colorify(repeat("-", 70), "bold"));
|
||||
console.log(colorify("User:", "bold"), colorify(info.user.login, "green"));
|
||||
if (info.created_at === info.updated_at) {
|
||||
console.log(colorify("Created:", "bold"), info.created_at);
|
||||
} else {
|
||||
console.log(colorify("Created:", "bold"), info.created_at, ` (updated: ${ info.updated_at })`);
|
||||
}
|
||||
info.body.trim().split("\n").forEach((line) => {
|
||||
console.log(" " + line);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
console.log(colorify(repeat("=", 70), "bold"))
|
||||
|
||||
// @TODO: Add stats on new/closed issues
|
||||
//if (options.user) {
|
||||
// console.log(`${ count.responses } responses (${ count.code } w/ code) on ${ count.comments } comments across ${ count.issues } issues.`);
|
||||
//} else {
|
||||
console.log(`${ count.comments } comment${ (count.comments !== 1) ? "s": "" } across ${ count.issues } issue${ (count.issues !== 1) ? "s": ""}.`);
|
||||
//}
|
||||
|
||||
})().catch((error) => {
|
||||
console.log("Error: " + error.message);
|
||||
});
|
||||
@@ -1,49 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const { getOrdered, loadPackage } = require("../depgraph");
|
||||
const { savePackage } = require("../local");
|
||||
const { log } = require("../log");
|
||||
|
||||
(async function() {
|
||||
let versions = { };
|
||||
|
||||
const dirnames = getOrdered();
|
||||
|
||||
dirnames.forEach((dirname) => {
|
||||
let info = loadPackage(dirname);
|
||||
if (info.name.split("/")[0] === "@ethersproject" || info.name === "ethers") {
|
||||
versions[info.name] = info.version;
|
||||
}
|
||||
});
|
||||
|
||||
dirnames.forEach((dirname) => {
|
||||
const info = loadPackage(dirname);
|
||||
let shown = false;
|
||||
["dependencies", "devDependencies"].forEach((key) => {
|
||||
const deps = info[key];
|
||||
if (!deps) { return; }
|
||||
Object.keys(deps).forEach((name) => {
|
||||
// Not a package in this monorepoa
|
||||
const version = versions[name];
|
||||
if (version == null) { return; }
|
||||
|
||||
const value = ((version.indexOf("beta") !== -1) ? ">=": "^") + version;
|
||||
|
||||
// No change
|
||||
if (value === deps[name]) { return; }
|
||||
|
||||
// Show a header for the first change
|
||||
if (!shown) {
|
||||
log(`<bold:Locking ${ info.name }:>`);
|
||||
shown = true;
|
||||
}
|
||||
|
||||
// Show the locked version
|
||||
log(` <green:${ name }>: ${ deps[name] } => <bold:${ value.replace(">", ">") }>`);
|
||||
deps[name] = value;
|
||||
});
|
||||
});
|
||||
savePackage(dirname, info);
|
||||
});
|
||||
|
||||
})();
|
||||
@@ -1,210 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const { basename, resolve } = require("path");
|
||||
const fs = require("fs");
|
||||
|
||||
const AWS = require('aws-sdk');
|
||||
|
||||
const config = require("../config");
|
||||
|
||||
const { ChangelogPath, latestChange } = require("../changelog");
|
||||
const { getOrdered, loadPackage } = require("../depgraph");
|
||||
const { getGitTag } = require("../git");
|
||||
const { createRelease } = require("../github");
|
||||
const { getPackageVersion, publish } = require("../npm");
|
||||
const { log } = require("../log");
|
||||
|
||||
const USER_AGENT = "ethers-dist@0.0.0";
|
||||
const TAG = "latest";
|
||||
|
||||
|
||||
let dirnames = getOrdered();
|
||||
|
||||
// Only publish specific packages
|
||||
if (process.argv.length > 2) {
|
||||
let filter = process.argv.slice(2);
|
||||
|
||||
// Verify all named packages exist
|
||||
filter.forEach((dirname) => {
|
||||
try {
|
||||
loadPackage(dirname);
|
||||
} catch (error) {
|
||||
console.log("Package not found: " + dirname);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
// Filter out pacakges we don't care about
|
||||
dirnames = dirnames.filter((dirname) => (filter.indexOf(dirname) >= 0));
|
||||
}
|
||||
|
||||
|
||||
function putObject(s3, info) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
s3.putObject(info, function(error, data) {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve({
|
||||
name: info.Key,
|
||||
hash: data.ETag.replace(/"/g, '')
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function invalidate(cloudfront, distributionId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
cloudfront.createInvalidation({
|
||||
DistributionId: distributionId,
|
||||
InvalidationBatch: {
|
||||
CallerReference: `${ USER_AGENT }-${ parseInt(((new Date()).getTime()) / 1000) }`,
|
||||
Paths: {
|
||||
Quantity: "1",
|
||||
Items: [
|
||||
"/\*"
|
||||
]
|
||||
}
|
||||
}
|
||||
}, function(error, data) {
|
||||
if (error) {
|
||||
console.log(error);
|
||||
return;
|
||||
}
|
||||
resolve(data.Invalidation.Id);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
(async function() {
|
||||
let token = null;
|
||||
|
||||
const gitCommit = await getGitTag(ChangelogPath);
|
||||
|
||||
let includeEthers = false;
|
||||
|
||||
// @TODO: Fail if there are any untracked files or unchecked in files
|
||||
|
||||
// Load the token from the encrypted store
|
||||
try {
|
||||
token = await config.get("npm-token");
|
||||
} catch (error) {
|
||||
switch (error.message) {
|
||||
case "wrong password":
|
||||
log("<bold:Wrong password>");
|
||||
break;
|
||||
case "cancelled":
|
||||
break;
|
||||
default:
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
log("<red:Aborting.>");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
token = token.trim().split("=");
|
||||
|
||||
let options = {
|
||||
npmVersion: USER_AGENT,
|
||||
tag: TAG
|
||||
};
|
||||
|
||||
// Set the authentication token
|
||||
options[token[0]] = token[1];
|
||||
|
||||
for (let i = 0; i < dirnames.length; i++) {
|
||||
let dirname = dirnames[i];
|
||||
|
||||
if (dirname === "ethers") {
|
||||
includeEthers = true;
|
||||
}
|
||||
|
||||
let info = loadPackage(dirname);
|
||||
let npmInfo = await getPackageVersion(info.name);
|
||||
if (!npmInfo) { npmInfo = { version: "NEW" }; }
|
||||
|
||||
if (info.tarballHash === npmInfo.tarballHash) { continue; }
|
||||
|
||||
log(`<bold:Publishing:> ${info.name}...`);
|
||||
log(` <blue:Version:> ${npmInfo.version} <bold:=\\>> ${info.version}`);
|
||||
|
||||
let success = await publish(dirname, options);
|
||||
if (!success) {
|
||||
log(" <red:FAILED! Aborting.>");
|
||||
return;
|
||||
}
|
||||
log(" <green:Done.>");
|
||||
}
|
||||
|
||||
// Publish the GitHub release
|
||||
const beta = false;
|
||||
if (includeEthers) {
|
||||
|
||||
// Get the latest change from the changelog
|
||||
const change = latestChange();
|
||||
|
||||
// Publish the release to GitHub
|
||||
{
|
||||
// The password above already succeeded
|
||||
const username = await config.get("github-user");
|
||||
const password = await config.get("github-release");
|
||||
|
||||
|
||||
// Publish the release
|
||||
const link = await createRelease(username, password, change.version, change.title, change.content, beta, gitCommit);
|
||||
log(`<bold:Published Release:> ${ link }`);
|
||||
}
|
||||
|
||||
// Upload the scripts to the CDN and refresh the edge caches
|
||||
{
|
||||
const awsAccessId = await config.get("aws-upload-scripts-accesskey");
|
||||
const awsSecretKey = await config.get("aws-upload-scripts-secretkey");
|
||||
const bucketName = await config.get("aws-upload-scripts-bucket");
|
||||
const originRoot = await config.get("aws-upload-scripts-root");
|
||||
const distributionId = await config.get("aws-upload-scripts-distribution-id");
|
||||
|
||||
const s3 = new AWS.S3({
|
||||
apiVersion: '2006-03-01',
|
||||
accessKeyId: awsAccessId,
|
||||
secretAccessKey: awsSecretKey
|
||||
});
|
||||
|
||||
// Upload the libs to ethers-v5.0 and ethers-5.0.x
|
||||
const fileInfos = [
|
||||
{ filename: "packages/ethers/dist/ethers.esm.min.js", key: `ethers-${ change.version.substring(1) }.esm.min.js` },
|
||||
{ filename: "packages/ethers/dist/ethers.umd.min.js", key: `ethers-${ change.version.substring(1) }.umd.min.js` },
|
||||
{ filename: "packages/ethers/dist/ethers.esm.min.js", key: `ethers-5.0.esm.min.js` },
|
||||
{ filename: "packages/ethers/dist/ethers.umd.min.js", key: `ethers-5.0.umd.min.js` },
|
||||
];
|
||||
|
||||
for (let i = 0; i < fileInfos.length; i++) {
|
||||
const fileInfo = fileInfos[i];
|
||||
const status = await putObject(s3, {
|
||||
ACL: 'public-read',
|
||||
Body: fs.readFileSync(resolve(__dirname, "../../", fileInfo.filename)),
|
||||
Bucket: bucketName,
|
||||
ContentType: "application/javascript; charset=utf-8",
|
||||
Key: (originRoot + fileInfo.key)
|
||||
});
|
||||
|
||||
log(`<bold:Uploaded :> https://cdn.ethers.io/lib/${ fileInfo.key }`);
|
||||
}
|
||||
|
||||
// Flush the edge caches
|
||||
{
|
||||
const cloudfront = new AWS.CloudFront({
|
||||
//apiVersion: '2006-03-01',
|
||||
accessKeyId: awsAccessId,
|
||||
secretAccessKey: awsSecretKey
|
||||
});
|
||||
|
||||
const invalidationId = await invalidate(cloudfront, distributionId);
|
||||
log(`<bold:Invalidated Cache :> ${ invalidationId }`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
||||
@@ -1,100 +0,0 @@
|
||||
const fs = require("fs");
|
||||
const http = require("http");
|
||||
const path = require("path");
|
||||
|
||||
function getMime(filename) {
|
||||
const comps = filename.split('.');
|
||||
const ext = comps[comps.length - 1];
|
||||
switch (ext.toLowerCase()) {
|
||||
case 'css': return 'text/css';
|
||||
case 'doctree': return 'application/x-doctree';
|
||||
case 'eot': return 'application/vnd.ms-fontobject';
|
||||
case 'gif': return 'image/gif';
|
||||
case 'html': return 'text/html';
|
||||
case 'js': return 'application/javascript';
|
||||
case 'jpg': return 'image/jpeg';
|
||||
case 'jpeg': return 'image/jpeg';
|
||||
case 'md': return 'text/markdown';
|
||||
case 'pickle': return 'application/x-pickle';
|
||||
case 'png': return 'image/png';
|
||||
case 'svg': return 'image/svg+xml';
|
||||
case 'ttf': return 'application/x-font-ttf';
|
||||
case 'txt': return 'text/plain';
|
||||
case 'woff': return 'application/font-woff';
|
||||
}
|
||||
console.log('NO MIME', filename);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function start(root, options) {
|
||||
if (root == null) { throw new Error("root required"); }
|
||||
if (options == null) { options = { }; }
|
||||
if (options.port == null) { options.port = 8000; }
|
||||
root = path.resolve(root);
|
||||
|
||||
const server = http.createServer((req, resp) => {
|
||||
|
||||
// Follow redirects in options
|
||||
if (options.redirects && options.redirects[req.url]) {
|
||||
resp.writeHead(301, { Location: options.redirects[req.url] });
|
||||
resp.end();
|
||||
return;
|
||||
}
|
||||
|
||||
let filename = path.resolve(root, "." + req.url);
|
||||
|
||||
// Make sure we aren't crawling out of our sandbox
|
||||
if (req.url[0] !== "/" || filename.substring(0, filename.length) !== filename) {
|
||||
resp.writeHead(403);
|
||||
resp.end();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const stat = fs.statSync(filename);
|
||||
if (stat.isDirectory()) {
|
||||
|
||||
// Redirect bare directory to its path (i.e. "/foo" => "/foo/")
|
||||
if (req.url[req.url.length - 1] !== "/") {
|
||||
resp.writeHead(301, { Location: req.url + "/" });
|
||||
resp.end();
|
||||
return;
|
||||
}
|
||||
|
||||
filename += "/index.html";
|
||||
}
|
||||
|
||||
const content = fs.readFileSync(filename);
|
||||
|
||||
resp.writeHead(200, {
|
||||
"Content-Length": content.length,
|
||||
"Content-Type": getMime(filename)
|
||||
});
|
||||
resp.end(content);
|
||||
return;
|
||||
|
||||
} catch (error) {
|
||||
if (error.code === "ENOENT") {
|
||||
resp.writeHead(404, { });
|
||||
resp.end();
|
||||
return;
|
||||
}
|
||||
|
||||
resp.writeHead(500, { });
|
||||
resp.end();
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
server.listen(options.port, () => {
|
||||
console.log(`Server running on: http://localhost:${ options.port }`);
|
||||
});
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
start(path.resolve(__dirname, "../../docs"), {
|
||||
redirects: {
|
||||
"/": "/v5/"
|
||||
}
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const { prompt } = require("../../packages/cli");
|
||||
const config = require("../config");
|
||||
|
||||
if (process.argv.length !== 3) {
|
||||
console.log("Usage: set-config KEY");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const key = process.argv[2];
|
||||
|
||||
(async function() {
|
||||
const value = await prompt.getPassword("Value: ");
|
||||
await config.set(key, value);
|
||||
})();
|
||||
@@ -1,146 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
// Expected this to be run after
|
||||
// - npm run clean
|
||||
// - npm run bootstrap
|
||||
// - npm run build
|
||||
|
||||
const fs = require("fs");
|
||||
|
||||
const semver = require("semver");
|
||||
|
||||
const { runBuild, runDist } = require("../build");
|
||||
const { ChangelogPath, generate } = require("../changelog");
|
||||
const { getOrdered, loadPackage } = require("../depgraph");
|
||||
const { getDiff, getStatus, getGitTag } = require("../git");
|
||||
const { updatePackage } = require("../local");
|
||||
const { getPackageVersion } = require("../npm");
|
||||
const { resolve } = require("../utils");
|
||||
const { colorify, log } = require("../log");
|
||||
|
||||
const { prompt } = require("../../packages/cli");
|
||||
|
||||
let dirnames = getOrdered();
|
||||
|
||||
// Only publish specific packages
|
||||
if (process.argv.length > 2) {
|
||||
let filter = process.argv.slice(2);
|
||||
|
||||
// Verify all named packages exist
|
||||
filter.forEach((dirname) => {
|
||||
try {
|
||||
loadPackage(dirname);
|
||||
} catch (error) {
|
||||
console.log("Package not found: " + dirname);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
// Filter out pacakges we don't care about
|
||||
dirnames = dirnames.filter((dirname) => (filter.indexOf(dirname) >= 0));
|
||||
}
|
||||
|
||||
(async function() {
|
||||
let progress = prompt.getProgressBar(colorify("Updating versions", "bold"));
|
||||
|
||||
for (let i = 0; i < dirnames.length; i++) {
|
||||
progress(i / dirnames.length);
|
||||
|
||||
let dirname = dirnames[i];
|
||||
let path = resolve("packages", dirname);
|
||||
|
||||
// Get local package.json (update the tarballHash)
|
||||
let info = await updatePackage(dirname);
|
||||
|
||||
// Get the remote package.json (or sub in a placeholder for new pacakges)
|
||||
let npmInfo = await getPackageVersion(info.name);
|
||||
if (!npmInfo) { npmInfo = { version: "NEW" }; }
|
||||
|
||||
if (info.tarballHash === npmInfo.tarballHash) { continue; }
|
||||
|
||||
// Bump the version if necessary
|
||||
if (info.version === npmInfo.version) {
|
||||
let newVersion = semver.inc(info.version, "patch");
|
||||
|
||||
// Write out the _version.ts
|
||||
if (!info._ethers_nobuild) {
|
||||
let code = "export const version = " + JSON.stringify(dirname + "/" + newVersion) + ";\n";
|
||||
fs.writeFileSync(resolve(path, "src.ts/_version.ts"), code);
|
||||
}
|
||||
|
||||
// Update the package.json (we do this after _version, so if we fail,
|
||||
// this remains old; which is what triggers the version bump)
|
||||
info = await updatePackage(dirname, { version: newVersion });
|
||||
}
|
||||
}
|
||||
progress(1);
|
||||
|
||||
try {
|
||||
log("<bold:Building TypeScript source (es6)...>");
|
||||
await runBuild(true);
|
||||
log("<bold:Building TypeScript source (commonjs)...>");
|
||||
await runBuild(false);
|
||||
log("<bold:Building distribution files...>");
|
||||
let content = await runDist();
|
||||
console.log(content);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
log("<red:Aborting.>");
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the tarball hash now that _version and package.json may have changed.
|
||||
progress = prompt.getProgressBar(colorify("Updating tarballHash", "bold"));
|
||||
for (let i = 0; i < dirnames.length; i++) {
|
||||
progress(i / dirnames.length);
|
||||
await updatePackage(dirnames[i]);
|
||||
}
|
||||
progress(1);
|
||||
|
||||
// Show the changed files (compared to npm)
|
||||
for (let i = 0; i < dirnames.length; i++) {
|
||||
let dirname = dirnames[i];
|
||||
|
||||
// Get local package.json
|
||||
let info = await loadPackage(dirname);
|
||||
let path = resolve("packages/", dirname);
|
||||
|
||||
// Get the remote package.json (or sub in a placeholder for new pacakges)
|
||||
let npmInfo = await getPackageVersion(info.name);
|
||||
if (!npmInfo) { npmInfo = { version: "NEW" }; }
|
||||
|
||||
// No change
|
||||
if (info.tarballHash === npmInfo.tarballHash) { continue; }
|
||||
|
||||
let gitHead = await getGitTag(path);
|
||||
|
||||
log(`<bold:Package>: ${info.name}`);
|
||||
log(` <green:Tarball Changed:> (bumping version)`);
|
||||
log(` ${npmInfo.version} => ${info.version}`)
|
||||
log(` <blue:Changed:>`);
|
||||
let filenames = await getDiff(path, npmInfo.gitHead, true);
|
||||
filenames.forEach((filename) => {
|
||||
let short = filename.split("/").slice(1).join("/");
|
||||
if (short.indexOf("/src.ts/") >= 0 || short.indexOf("/dist/") >= 0) {
|
||||
log(` <bold:${short}>`);
|
||||
} else {
|
||||
log(` ${short}`);
|
||||
}
|
||||
});
|
||||
log("");
|
||||
}
|
||||
|
||||
let existing = fs.readFileSync(ChangelogPath).toString();
|
||||
let changelog = await generate();
|
||||
if (existing !== changelog) {
|
||||
let changelogStatus = await getStatus(ChangelogPath);
|
||||
if (changelogStatus !== "unmodified") {
|
||||
log("<bold:WARNING:> There are local changes to the CHANGELOG (they will be discarded)");
|
||||
console.log(existing);
|
||||
}
|
||||
log("<bold:Updating CHANGELOG>...");
|
||||
fs.writeFileSync(ChangelogPath, changelog);
|
||||
}
|
||||
|
||||
|
||||
})();
|
||||
120
admin/config.js
120
admin/config.js
@@ -1,120 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const os = require("os");
|
||||
const resolve = require("path").resolve;
|
||||
|
||||
const AES = require("aes-js");
|
||||
const scrypt = require("scrypt-js");
|
||||
|
||||
const { prompt } = require("../packages/cli");
|
||||
const randomBytes = require("../packages/random").randomBytes;
|
||||
const computeHmac = require("../packages/sha2").computeHmac;
|
||||
|
||||
const colorify = require("./log").colorify;
|
||||
|
||||
function getScrypt(message, password, salt) {
|
||||
let progressBar = prompt.getProgressBar(message);
|
||||
return scrypt.scrypt(Buffer.from(password), Buffer.from(salt), (1 << 17), 8, 1, 64, progressBar);
|
||||
}
|
||||
|
||||
function Config(filename) {
|
||||
this.salt = null;
|
||||
this.dkey = null;
|
||||
this.values = { };
|
||||
this.canary = "";
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
Config.prototype.load = async function() {
|
||||
if (this.dkey) { return; }
|
||||
|
||||
let data = null;
|
||||
if (fs.existsSync(this.filename)) {
|
||||
data = JSON.parse(fs.readFileSync(this.filename));
|
||||
} else {
|
||||
data = {
|
||||
salt: Buffer.from(randomBytes(32)).toString("hex")
|
||||
};
|
||||
}
|
||||
|
||||
this.canary = data.canary || "";
|
||||
|
||||
this.salt = data.salt;
|
||||
|
||||
const password = await prompt.getPassword(colorify("Password (config-store): ", "bold"));
|
||||
|
||||
this.dkey = await getScrypt(colorify("Unlocking config", "bold"), password, this.salt);
|
||||
|
||||
if (data.ciphertext) {
|
||||
const ciphertext = Buffer.from(data.ciphertext, "base64");
|
||||
const iv = Buffer.from(data.iv, "base64");
|
||||
const aes = new AES.ModeOfOperation.ctr(this.dkey.slice(0, 32), new AES.Counter(iv));
|
||||
const plaintext = aes.decrypt(ciphertext);
|
||||
const hmac = computeHmac("sha512", this.dkey.slice(32, 64), plaintext);
|
||||
if (hmac !== data.hmac) {
|
||||
throw new Error("wrong password");
|
||||
}
|
||||
|
||||
this.values = JSON.parse(Buffer.from(plaintext).toString());
|
||||
}
|
||||
};
|
||||
|
||||
Config.prototype.keys = async function() {
|
||||
await this.load();
|
||||
return Object.keys(this.values);
|
||||
}
|
||||
|
||||
Config.prototype.save = function() {
|
||||
this.values._junk = Buffer.from(randomBytes(16 + parseInt(Math.random() * 48))).toString("base64")
|
||||
|
||||
const plaintext = Buffer.from(JSON.stringify(this.values));
|
||||
|
||||
const iv = Buffer.from(randomBytes(16));
|
||||
const hmac = computeHmac("sha512", this.dkey.slice(32, 64), plaintext);
|
||||
|
||||
const aes = new AES.ModeOfOperation.ctr(this.dkey.slice(0, 32), new AES.Counter(iv));
|
||||
const ciphertext = Buffer.from(aes.encrypt(plaintext));
|
||||
|
||||
const data = {
|
||||
ciphertext: ciphertext.toString("base64"),
|
||||
iv: iv.toString("base64"),
|
||||
salt: this.salt,
|
||||
hmac: hmac,
|
||||
canary: this.canary
|
||||
};
|
||||
|
||||
fs.writeFileSync(this.filename, JSON.stringify(data, null, 2));
|
||||
}
|
||||
|
||||
Config.prototype.get = async function(key) {
|
||||
await this.load();
|
||||
return this.values[key];
|
||||
};
|
||||
|
||||
Config.prototype.set = async function(key, value) {
|
||||
await this.load();
|
||||
this.values[key] = value;
|
||||
this.save();
|
||||
};
|
||||
|
||||
Config.prototype.lock = function() {
|
||||
this.salt = this.dkey = null;
|
||||
}
|
||||
|
||||
const config = new Config(resolve(os.homedir(), ".ethers-dist"));
|
||||
|
||||
module.exports = {
|
||||
get: function(key) {
|
||||
return config.get(key);
|
||||
},
|
||||
set: function(key, value) {
|
||||
config.set(key, value);
|
||||
},
|
||||
keys: function() {
|
||||
return config.keys();
|
||||
},
|
||||
lock: function() {
|
||||
config.lock();
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
|
||||
const { loadJson, resolve } = require("./utils");
|
||||
|
||||
const ROOT = resolve("packages");
|
||||
|
||||
const dirnames = fs.readdirSync(ROOT);
|
||||
|
||||
function loadPackage(dirname) {
|
||||
return loadJson(resolve("packages", dirname, "package.json"));
|
||||
}
|
||||
|
||||
function getOrdered(skipNobuild) {
|
||||
let packages = { };
|
||||
let filenames = { };
|
||||
|
||||
let addDeps = (name, depends) => {
|
||||
Object.keys(depends).forEach((dep) => {
|
||||
// Not a package we manage
|
||||
if (packages[dep] == null) { return; }
|
||||
deps[name][dep] = true;
|
||||
});
|
||||
}
|
||||
|
||||
for (let i = 0; i < dirnames.length; i++) {
|
||||
let dirname = dirnames[i];
|
||||
let info = loadPackage(dirname);
|
||||
if (skipNobuild && info._ethers_nobuild) { continue; }
|
||||
packages[info.name] = info;
|
||||
filenames[info.name] = dirname;
|
||||
}
|
||||
|
||||
// Maps names to list of dependencies; { [ name:string]: Array<name: string> }
|
||||
let deps = { };
|
||||
let depGraph = { };
|
||||
|
||||
Object.keys(packages).forEach((name) => {
|
||||
let info = packages[name];
|
||||
deps[info.name] = { };
|
||||
addDeps(info.name, info.dependencies || { });
|
||||
addDeps(info.name, info.devDependencies || { });
|
||||
deps[info.name] = Object.keys(deps[info.name]);
|
||||
deps[info.name].sort();
|
||||
});
|
||||
|
||||
let ordered = [ ];
|
||||
let remaining = Object.keys(deps);
|
||||
|
||||
let isSatisfied = (name) => {
|
||||
for (let i = 0; i < deps[name].length; i++) {
|
||||
if (ordered.indexOf(deps[name][i]) === -1) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
while (remaining.length) {
|
||||
let bail = true;
|
||||
for (let i = 0; i < remaining.length; i++) {
|
||||
if (!isSatisfied(remaining[i])) { continue; }
|
||||
bail = false;
|
||||
ordered.push(remaining[i]);
|
||||
remaining.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (bail) {
|
||||
throw new Error("Nothing processed; circular dependencies...");
|
||||
}
|
||||
}
|
||||
|
||||
return ordered.map((name) => filenames[name]);
|
||||
}
|
||||
|
||||
function sort(dirnames) {
|
||||
let ordered = getOrdered();
|
||||
dirnames.sort((a, b) => {
|
||||
let ai = ordered.indexOf(local.loadPackage(a).name);
|
||||
let bi = ordered.indexOf(local.loadPackage(b).name);
|
||||
if (ai === -1 || bi === -1) {
|
||||
throw new Error("unknown dirname - " + [a, b].join(", "));
|
||||
}
|
||||
return ai - bi;
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
dirnames: dirnames,
|
||||
getOrdered: getOrdered,
|
||||
loadPackage: loadPackage,
|
||||
ROOT: ROOT,
|
||||
sort: sort
|
||||
}
|
||||
186
admin/git.js
186
admin/git.js
@@ -1,186 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const resolve = require("path").resolve;
|
||||
const spawn = require("child_process").spawn;
|
||||
|
||||
const semver = require("semver");
|
||||
|
||||
const { run } = require("./build");
|
||||
const { loadPackage } = require("./local");
|
||||
|
||||
function git(args) {
|
||||
return run("git", args);
|
||||
}
|
||||
|
||||
function getStatus(filename) {
|
||||
return git([ "status", "-s", resolve(__dirname, "..", filename) ]).then((result) => {
|
||||
result = result.trim();
|
||||
if (result === "") { return "unmodified"; }
|
||||
switch (result.substring(0, 2)) {
|
||||
case 'M ': return "modified";
|
||||
case 'A ': return "added";
|
||||
case 'D ': return "deleted";
|
||||
case 'R ': return "renamed";
|
||||
case 'C ': return "copied";
|
||||
case 'U ': return "updated";
|
||||
case '??': return "untracked";
|
||||
}
|
||||
console.log(result);
|
||||
return "unknown";
|
||||
});
|
||||
}
|
||||
|
||||
async function getChanges(latest) {
|
||||
let diff = await git(["diff", "--name-only", latest ]);
|
||||
|
||||
// Map dirname => { dist: [ ], src: [ ] }
|
||||
let changes = { "_": { filename: "_", dist: [], src: [] } };
|
||||
|
||||
diff.split("\n").forEach((line) => {
|
||||
// e.g. packages/constants/index.d.ts
|
||||
let comps = line.trim().split("/");
|
||||
|
||||
// Track non-packages as dist
|
||||
if (comps.length < 2 || comps[0] !== "packages") {
|
||||
let filename = comps.join("/").trim();
|
||||
if (filename === "") { return; }
|
||||
changes._.dist.push(filename);
|
||||
return;
|
||||
}
|
||||
|
||||
let name = loadPackage(comps[1]).name;
|
||||
|
||||
let change = changes[name];
|
||||
if (!change) {
|
||||
change = { filename: comps[1], dist: [ ], src: [ ] }
|
||||
changes[name] = change;
|
||||
}
|
||||
|
||||
// Split changes into source changes (src.ts/) or dist changes (output of TypeScript)
|
||||
if (comps[2] === "src.ts") {
|
||||
change.src.push(comps.join("/"));
|
||||
} else {
|
||||
change.dist.push(comps.join("/"));
|
||||
}
|
||||
});
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
function getLatestTag() {
|
||||
let seq = Promise.resolve();
|
||||
|
||||
// @TODO: Pull
|
||||
if (false) {
|
||||
seq = seq.then(() => {
|
||||
console.log("Pulling remote changes...");
|
||||
return git([ "pull" ]);
|
||||
});
|
||||
}
|
||||
|
||||
seq = seq.then(() => {
|
||||
return git([ "tag" ]).then((tags) => {
|
||||
tags = tags.split("\n").filter(tag => (tag.match(/^v[0-9]+\.[0-9]+\.[0-9]+\-/)));
|
||||
tags.sort(semver.compare)
|
||||
return tags.pop();
|
||||
});
|
||||
});
|
||||
|
||||
return seq;
|
||||
}
|
||||
|
||||
function findChanges(latest) {
|
||||
let seq = Promise.resolve();
|
||||
|
||||
seq = seq.then(() => {
|
||||
return git(["diff", "--name-only", latest, "HEAD" ]).then((result) => {
|
||||
let filenames = { };
|
||||
result.split("\n").forEach((line) => {
|
||||
// e.g. packages/constants/index.d.ts
|
||||
let comps = line.trim().split("/");
|
||||
if (comps.length < 2) { return; }
|
||||
filenames[comps[1]] = true;
|
||||
});
|
||||
return Object.keys(filenames);
|
||||
});
|
||||
});
|
||||
|
||||
seq = seq.then((filenames) => {
|
||||
return filenames.map((filename) => {
|
||||
let name = packages[filename].name;
|
||||
return {
|
||||
filename: filename,
|
||||
name: name,
|
||||
localVersion: getLocalVersion(name),
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
seq = seq.then((packages) => {
|
||||
let seq = Promise.resolve();
|
||||
packages.forEach((p) => {
|
||||
seq = seq.then(() => {
|
||||
return getNpmVersion(p.name).then((version) => {
|
||||
p.npmVersion = version;
|
||||
});
|
||||
});
|
||||
});
|
||||
return seq.then(() => packages);
|
||||
});
|
||||
return seq;
|
||||
}
|
||||
|
||||
async function getGitTag(filename) {
|
||||
let result = await git([ "log", "-n", "1", "--", filename ]);
|
||||
result = result.trim();
|
||||
if (!result) { return null; }
|
||||
result = result.match(/^commit\s+([0-9a-f]{40})\n/i);
|
||||
if (!result) { return null; }
|
||||
return result[1];
|
||||
}
|
||||
|
||||
async function getDiff(filename, tag, nameOnly) {
|
||||
if (tag == null) { tag = "HEAD"; }
|
||||
let cmd = [ "diff", "--name-only", tag, "--", filename ]
|
||||
if (!nameOnly) { cmd.splice(1, 1); }
|
||||
try {
|
||||
let result = await git(cmd);
|
||||
result = result.trim();
|
||||
if (result === "") { return [ ]; }
|
||||
return result.split("\n");
|
||||
} catch (error) {
|
||||
// This tag does not exist, so compare against beginning of time
|
||||
// This happens when there is a new history (like an orphan branch)
|
||||
if (error.stderr.trim().match(/^fatal: bad object/)) {
|
||||
console.log("Could not find history; showing all");
|
||||
let cmd = [ "rev-list", "--max-parents=0", "HEAD" ];
|
||||
let tag = await git(cmd);
|
||||
return getDiff(filename, tag.trim(), nameOnly);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function getUntracked(filename) {
|
||||
let cmd = [ "ls-files", "-o", "--exclude-standard"];
|
||||
if (filename) {
|
||||
cmd.push("--");
|
||||
cmd.push(filename);
|
||||
}
|
||||
let result = await git(cmd);
|
||||
result = result.trim();
|
||||
if (result === "") { return [ ]; }
|
||||
return result.split("\n");
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
findChanges: findChanges,
|
||||
getChanges: getChanges,
|
||||
getDiff: getDiff,
|
||||
getGitTag: getGitTag,
|
||||
getLatestTag: getLatestTag,
|
||||
getStatus: getStatus,
|
||||
getUntracked: getUntracked,
|
||||
run: git,
|
||||
}
|
||||
162
admin/github.js
162
admin/github.js
@@ -1,162 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const { resolve } = require("path");
|
||||
const zlib = require("zlib");
|
||||
|
||||
const { id } = require("../packages/hash");
|
||||
const { fetchJson } = require("../packages/web");
|
||||
|
||||
const CacheDir = resolve(__dirname, "../github-cache/");
|
||||
|
||||
function addResponse(result, response) {
|
||||
return { result, response };
|
||||
}
|
||||
|
||||
function loadFile(filename) {
|
||||
return JSON.parse(zlib.gunzipSync(fs.readFileSync(filename)).toString());
|
||||
//return JSON.parse(fs.readFileSync(filename).toString());
|
||||
}
|
||||
|
||||
// @TODO: atomic
|
||||
function saveFile(filename, content) {
|
||||
fs.writeFileSync(filename, zlib.gzipSync(JSON.stringify(content)));
|
||||
//fs.writeFileSync(filename, JSON.stringify(content));
|
||||
}
|
||||
|
||||
function mockFetchJson(url, body, headers) {
|
||||
return {
|
||||
result: null,
|
||||
response: {
|
||||
statusCode: 304
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function _fetchGitHub(user, password, fetchJson, url) {
|
||||
const result = [ ];
|
||||
while (true) {
|
||||
|
||||
const filename = resolve(CacheDir, id(url).substring(2, 14));
|
||||
|
||||
const headers = {
|
||||
"User-Agent": "ethers-io",
|
||||
};
|
||||
|
||||
let items = null;
|
||||
let link = null;
|
||||
try {
|
||||
const data = loadFile(filename);
|
||||
headers["if-none-match"] = data.etag;
|
||||
items = data.items;
|
||||
link = data.link;
|
||||
} catch (error) {
|
||||
if (error.code !== "ENOENT") { throw error; }
|
||||
}
|
||||
|
||||
const fetch = await fetchJson({
|
||||
url: url,
|
||||
user: user,
|
||||
password: password,
|
||||
headers: headers
|
||||
}, null, addResponse);
|
||||
|
||||
// Cached response is good; use it!
|
||||
if (fetch.response.statusCode !== 304) {
|
||||
items = fetch.result;
|
||||
if (fetch.response.headers) {
|
||||
link = (fetch.response.headers.link || null);
|
||||
}
|
||||
if (fetch.response.headers.etag){
|
||||
saveFile(filename, {
|
||||
timestamp: (new Date()).getTime(),
|
||||
url: url,
|
||||
link: link,
|
||||
etag: fetch.response.headers.etag,
|
||||
items: items,
|
||||
version: 1
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
items.forEach((item) => { result.push(item)});
|
||||
|
||||
url = null;
|
||||
(link || "").split(",").forEach((item) => {
|
||||
if (item.indexOf('rel="next"') >= 0) {
|
||||
const match = item.match(/<([^>]*)>/);
|
||||
if (match) { url = match[1]; }
|
||||
}
|
||||
});
|
||||
|
||||
if (!url) { break; }
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
async function fetchGitHub(user, password, url, cacheOnly) {
|
||||
if (cacheOnly) {
|
||||
return await _fetchGitHub("none", "none", mockFetchJson, url);
|
||||
}
|
||||
|
||||
const results = await _fetchGitHub(user, password, fetchJson, url);
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
async function _getIssues(user, password) {
|
||||
const cacheOnly = (user == null);
|
||||
|
||||
let issues = await fetchGitHub(user, password, "https:/\/api.github.com/repos/ethers-io/ethers.js/issues?state=all&per_page=100", cacheOnly)
|
||||
if (!cacheOnly) { console.log(`Found ${ issues.length } issues`); }
|
||||
const result = [ ];
|
||||
for (let i = 0; i < issues.length; i++) {
|
||||
const issue = issues[i];
|
||||
let comments = await fetchGitHub(user, password, issue.comments_url, cacheOnly);
|
||||
result.push({ issue, comments});
|
||||
if (!cacheOnly) { console.log(` Issue ${ issue.number }: ${ comments.length } comments`); }
|
||||
}
|
||||
result.sort((a, b) => (a.issue.number - b.issue.number));
|
||||
return result;
|
||||
}
|
||||
|
||||
function getIssues() {
|
||||
return _getIssues();
|
||||
}
|
||||
|
||||
function syncIssues(user, password) {
|
||||
return _getIssues(user, password);
|
||||
}
|
||||
|
||||
async function createRelease(user, password, tagName, title, body, prerelease, commit) {
|
||||
const payload = {
|
||||
tag_name: tagName,
|
||||
target_commitish: (commit || "master"),
|
||||
name: title,
|
||||
body: body,
|
||||
//draft: true,
|
||||
draft: false,
|
||||
prerelease: !!prerelease
|
||||
};
|
||||
|
||||
const headers = {
|
||||
"User-Agent": "ethers-io",
|
||||
};
|
||||
|
||||
const result = await fetchJson({
|
||||
url: "https://api.github.com/repos/ethers-io/ethers.js/releases",
|
||||
user: user,
|
||||
password: password,
|
||||
headers: headers
|
||||
}, JSON.stringify(payload));
|
||||
|
||||
|
||||
return result.html_url;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getIssues,
|
||||
syncIssues,
|
||||
createRelease,
|
||||
}
|
||||
|
||||
401
admin/index.js
401
admin/index.js
@@ -1,401 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const resolve = require("path").resolve;
|
||||
|
||||
const diff = require("diff");
|
||||
const semver = require("semver");
|
||||
|
||||
const { prompt } = require("../packages/cli");
|
||||
|
||||
const build = require("./build");
|
||||
const changelog = require("./changelog");
|
||||
const depgraph = require("./depgraph");
|
||||
const { colorify, colorifyStatus, log } = require("./log");
|
||||
const config = require("./config")
|
||||
const git = require("./git");
|
||||
const local = require("./local");
|
||||
const npm = require("./npm");
|
||||
const utils = require("./utils");
|
||||
|
||||
/*
|
||||
async function runChanged(dirnames, callback) {
|
||||
try {
|
||||
await callback(dirname, info, npmInfo);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
console.log(colorify("Aborting! " + error.message));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if (diff) {
|
||||
} else {
|
||||
*/
|
||||
|
||||
async function runDiff(dirnames) {
|
||||
// Default to all packages
|
||||
if (dirnames == null || dirnames.length === 0) { dirnames = local.dirnames; }
|
||||
|
||||
for (let i = 0; i < dirnames.length; i++) {
|
||||
let dirname = dirnames[i];
|
||||
|
||||
// Get local (update the tarballHash) and remote package.json
|
||||
let info = await local.loadPackage(dirname);
|
||||
let npmInfo = await npm.getPackageVersion(info.name);
|
||||
if (!npmInfo) { npmInfo = { gitHead: "HEAD", version: "NEW" }; }
|
||||
|
||||
let delta = await git.getDiff(resolve(__dirname, "../packages", dirname), npmInfo.gitHead);
|
||||
|
||||
if (delta.length === 0) { continue; }
|
||||
|
||||
// Bump the version if necessary
|
||||
if (info.version === npmInfo.version) {
|
||||
info.version = semver.inc(info.version, "patch");
|
||||
}
|
||||
|
||||
console.log(colorify("<bold:Package>: ") + info.name);
|
||||
console.log(colorify(" <green:Git Head Changed:> (run update to bump version)"));
|
||||
console.log(" " + npmInfo.gitHead)
|
||||
console.log(" " + npmInfo.version + colorify(" => ", "bold") + info.version)
|
||||
|
||||
console.log(colorify(" Diff", "bold"));
|
||||
delta.forEach((line) => {
|
||||
let color = "blue";
|
||||
switch (line.substring(0, 1)) {
|
||||
case '+':
|
||||
color = "green";
|
||||
break;
|
||||
case '-':
|
||||
color = "red";
|
||||
break;
|
||||
case ' ':
|
||||
color = "normal";
|
||||
break;
|
||||
}
|
||||
console.log(" " + colorify(line, color));
|
||||
});
|
||||
|
||||
console.log("");
|
||||
}
|
||||
|
||||
console.log("");
|
||||
}
|
||||
|
||||
async function updateChangelog() {
|
||||
let filename = resolve(local.ROOT, "../CHANGELOG.md");
|
||||
|
||||
let lastVersion = await git.getLatestTag();
|
||||
let newVersion = "v" + local.getVersion("ethers");
|
||||
|
||||
let current = fs.readFileSync(filename).toString();
|
||||
let log = await changelog.generate();
|
||||
if (log === current) { return; }
|
||||
|
||||
let changes = diff.createTwoFilesPatch("CHANGELOG-old.md", "CHANGELOG.md", current, log, lastVersion, newVersion);
|
||||
console.log(changes);
|
||||
|
||||
try {
|
||||
let response = await prompt.getChoice(colorify("Accept changes?", "bold"), "yn", "n");
|
||||
if (response === "n") { throw new Error("Not changing."); }
|
||||
} catch (error) {
|
||||
console.log("Abort: " + error.message);
|
||||
return;
|
||||
}
|
||||
|
||||
fs.writeFileSync(filename, log);
|
||||
}
|
||||
|
||||
// Updates the dependency-graph (tsconfig.project.json) so the build order is correct
|
||||
async function runUpdateDepgraph() {
|
||||
log(`<bold:Updating dependency-graph build order (tsconfig.project.json)...>`);
|
||||
let ordered = depgraph.getOrdered();
|
||||
|
||||
let path = resolve(local.ROOT, "../tsconfig.project.json")
|
||||
|
||||
let projectConfig = local.loadJson(path);
|
||||
projectConfig.references = ordered.map((name) => ({ path: ("./packages/" + name) }));
|
||||
local.saveJson(path, projectConfig);
|
||||
}
|
||||
|
||||
async function runUpdate(dirnames) {
|
||||
|
||||
// Check for untracked files...
|
||||
let untracked = [ ];
|
||||
if (dirnames == null || dirnames.length === 0) {
|
||||
dirnames = local.dirnames;
|
||||
let filenames = await git.getUntracked(resolve(__dirname, ".."));
|
||||
for (let i = 0; i < filenames.length; i++) {
|
||||
untracked.push(filenames[i]);
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < dirnames.length; i++) {
|
||||
let filenames = await git.getUntracked(resolve(local.ROOT, dirnames[i]));
|
||||
for (let j = 0; j < filenames.length; j++) {
|
||||
untracked.push(filenames[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Untracked files! Abort.
|
||||
if (untracked.length) {
|
||||
log("<bold:Untracked Files:>");
|
||||
untracked.forEach((filename) => {
|
||||
console.log(" " + filename);
|
||||
});
|
||||
log("<red:Aborting.>");
|
||||
return;
|
||||
}
|
||||
|
||||
log(`<bold:Run TypeScript build...>`);
|
||||
await build.runBuild()
|
||||
|
||||
log("");
|
||||
|
||||
// @TODO: Root
|
||||
|
||||
// Update all the package.json and _version.ts
|
||||
let progress = prompt.getProgressBar(colorify("Updating versions", "bold"));
|
||||
for (let i = 0; i < dirnames.length; i++) {
|
||||
progress(i / dirnames.length);
|
||||
|
||||
let dirname = dirnames[i];
|
||||
let path = resolve(__dirname, "../packages/", dirname);
|
||||
|
||||
// Get local package.json (update the tarballHash)
|
||||
let info = await local.updatePackage(dirname);
|
||||
|
||||
// Get the remote package.json (or sub in a placeholder for new pacakges)
|
||||
let npmInfo = await npm.getPackageVersion(info.name);
|
||||
if (!npmInfo) { npmInfo = { version: "NEW" }; }
|
||||
|
||||
if (info.tarballHash === npmInfo.tarballHash) { continue; }
|
||||
|
||||
// Bump the version if necessary
|
||||
if (info.version === npmInfo.version) {
|
||||
let newVersion = semver.inc(info.version, "patch");
|
||||
|
||||
// Write out the _version.ts
|
||||
if (!info._ethers_skipPrepare) {
|
||||
let code = "export const version = " + JSON.stringify(newVersion) + ";\n";
|
||||
fs.writeFileSync(resolve(path, "src.ts/_version.ts"), code);
|
||||
}
|
||||
|
||||
// Update the package.json (we do this after _version, so if we fail,
|
||||
// this remains old; which is what triggers the version bump)
|
||||
info = await local.updatePackage(dirname, { version: newVersion });
|
||||
}
|
||||
}
|
||||
progress(1);
|
||||
|
||||
// Build the TypeScript sources
|
||||
log("<bold:Runing TypeScript build...>");
|
||||
try {
|
||||
await build.runTsc();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
log("<red:Aborting.>");
|
||||
return;
|
||||
}
|
||||
|
||||
// Run the dist
|
||||
// @TODO:
|
||||
|
||||
// Update the tarball hash now that _version and package.json may have changed.
|
||||
progress = prompt.getProgressBar(colorify("Updating tarballHash", "bold"));
|
||||
for (let i = 0; i < dirnames.length; i++) {
|
||||
progress(i / dirnames.length);
|
||||
await local.updatePackage(dirnames[i]);
|
||||
}
|
||||
progress(1);
|
||||
|
||||
// Show the changed files (compared to npm)
|
||||
for (let i = 0; i < dirnames.length; i++) {
|
||||
let dirname = dirnames[i];
|
||||
|
||||
// Get local package.json
|
||||
let info = await local.loadPackage(dirname);
|
||||
let path = resolve(__dirname, "../packages/", dirname);
|
||||
|
||||
// Get the remote package.json (or sub in a placeholder for new pacakges)
|
||||
let npmInfo = await npm.getPackageVersion(info.name);
|
||||
if (!npmInfo) { npmInfo = { version: "NEW" }; }
|
||||
|
||||
// No change
|
||||
if (info.tarballHash === npmInfo.tarballHash) { continue; }
|
||||
|
||||
let gitHead = await git.getGitTag(path);
|
||||
|
||||
log(`<bold:Package>: ${info.name}`);
|
||||
log(` <green:Tarball Changed:> (bumping version)`);
|
||||
log(` ${npmInfo.version} => ${info.version}`)
|
||||
log(` <blue:Changed:>`);
|
||||
let filenames = await git.getDiff(resolve(__dirname, "../packages", dirname), npmInfo.gitHead, true);
|
||||
filenames.forEach((filename) => {
|
||||
let short = filename.split("/").slice(1).join("/");
|
||||
if (short.indexOf("/src.ts/") >= 0) {
|
||||
log(` <bold:${short}>`);
|
||||
} else {
|
||||
log(` ${short}`);
|
||||
}
|
||||
});
|
||||
log("");
|
||||
}
|
||||
|
||||
// @TODO: Changelog
|
||||
await updateChangelog();
|
||||
}
|
||||
|
||||
async function runAdd(type, names) {
|
||||
let latest = await git.getLatestTag();
|
||||
console.log("");
|
||||
console.log(colorify("<bold:Latest Published>: ") + latest);
|
||||
console.log("");
|
||||
|
||||
let changes = await git.getChanges("HEAD");
|
||||
|
||||
if (!names || names.length === 0) {
|
||||
names = Object.keys(changes);
|
||||
}
|
||||
|
||||
let filenames = [ ];
|
||||
for (let i = 0; i < names.length; i++) {
|
||||
let name = names[i];
|
||||
let change = changes[name] || changes[(packages[name] || {}).name];
|
||||
if (!change) { return; }
|
||||
change[type].forEach((filename) => {
|
||||
filenames.push(filename);
|
||||
});
|
||||
}
|
||||
|
||||
if (filenames.length === 0) {
|
||||
console.log(colorify("<bold:Nothing to add.>"));
|
||||
console.log("");
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < filenames.length; i++) {
|
||||
let filename = filenames[i];
|
||||
let status = await git.getStatus(filename);
|
||||
console.log(" " + colorifyStatus(status) + ": " + utils.repeat(" ", 10 - status.length) + filename);
|
||||
}
|
||||
|
||||
console.log("");
|
||||
|
||||
try {
|
||||
let response = await prompt.getChoice(colorify("Add these files?", "bold"), "yn", "n");
|
||||
if (response === "n") { throw new Error("Not adding."); }
|
||||
} catch (error) {
|
||||
console.log("Abort: " + error.message);
|
||||
return;
|
||||
}
|
||||
|
||||
let params = filenames.map((f) => f); //resolve(ROOT, f));
|
||||
params.unshift("--");
|
||||
params.unshift("add");
|
||||
|
||||
console.log("git " + params.join(" "));
|
||||
|
||||
try {
|
||||
await git.run(params);
|
||||
} catch (error) {
|
||||
console.log("Error: (status: " + error.code + ")");
|
||||
console.log(" " + error.stderr);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Added.");
|
||||
}
|
||||
|
||||
function runDist() {
|
||||
// Run npm dist
|
||||
// Generate changelog
|
||||
// run status to update all the package
|
||||
// add dist files?
|
||||
}
|
||||
|
||||
async function runPublish(dirnames) {
|
||||
|
||||
// @TODO: Make sure there are no staged files
|
||||
|
||||
// @TODO: Make sure the repo has been pushed
|
||||
|
||||
// @TODO: Run the publish in the correct order
|
||||
|
||||
// Get the authentication token from our encrypted store
|
||||
let token = await config.get("token");
|
||||
token = token.trim().split("=");
|
||||
|
||||
let options = {
|
||||
npmVersion: "ethers-dist@0.0.0",
|
||||
tag: "next"
|
||||
};
|
||||
|
||||
// Set the authentication token
|
||||
options[token[0]] = token[1];
|
||||
|
||||
if (dirnames == null || dirnames.length === 0) { dirnames = local.dirnames; }
|
||||
depgraph.sort(dirnames);
|
||||
|
||||
await runChanged(dirnames, async (dirname, info, npmInfo) => {
|
||||
console.log(colorify("<bold:Publishing:> ") + info.name + "...")
|
||||
console.log(colorify(" Version: ", "blue") + npmInfo.version + colorify(" => ", "bold") + info.version);
|
||||
|
||||
let success = await npm.publish(dirname, options);
|
||||
if (!success) {
|
||||
console.log(colorify(" <red:FAILED! Aborting.>"));
|
||||
throw new Error("");
|
||||
}
|
||||
console.log(colorify(" <green:Done.>"));
|
||||
});
|
||||
}
|
||||
|
||||
async function runTest() {
|
||||
let r = await git([ "tag", "--porcelain", "-a", "-m", "Title of Release\n\nHello\n-----\n\nTesting 4 **bold** #1\nHello World", "test6", "HEAD" ]);
|
||||
console.log(r);
|
||||
try {
|
||||
r = await git([ "push", "--tags" ])
|
||||
} catch(e) { console.log(e); }
|
||||
console.log(r);
|
||||
}
|
||||
|
||||
(function() {
|
||||
let args = process.argv.slice(2);
|
||||
switch (args[0]) {
|
||||
|
||||
// Compare published to current stage
|
||||
case "diff":
|
||||
return runDiff(args.slice(1));
|
||||
|
||||
// Add unchecked-in source files
|
||||
case "add-source":
|
||||
return runAdd("src", args.slice(1));
|
||||
|
||||
// Update all package.json. the changelog and dist files
|
||||
case "update":
|
||||
return runUpdate(args.slice(1));
|
||||
|
||||
// Update dependency graph (./tsconfig-project.json)
|
||||
case "update-depgraph":
|
||||
return runUpdateDepgraph();
|
||||
|
||||
// Add unchecked-in dist files
|
||||
case "add-dist":
|
||||
return runAdd("dist", args.slice(1));
|
||||
|
||||
|
||||
// Add unchecked-in source files
|
||||
case "changelog":
|
||||
return updateChangelog();
|
||||
|
||||
// Add unchecked-in source files
|
||||
case "publish":
|
||||
return runPublish(args.slice(1));
|
||||
|
||||
case "test":
|
||||
return runTest();
|
||||
}
|
||||
})();
|
||||
101
admin/local.js
101
admin/local.js
@@ -1,101 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const packlist = require("npm-packlist");
|
||||
const tar = require("tar");
|
||||
|
||||
const keccak256 = (function() {
|
||||
try {
|
||||
return require("../packages/keccak256").keccak256;
|
||||
} catch (error) {
|
||||
console.log("Cannot load Keccak256 (maybe not built yet? Not really a problem for most things)");
|
||||
return null;
|
||||
}
|
||||
})();
|
||||
|
||||
const { dirnames, loadPackage, ROOT } = require("./depgraph");
|
||||
const { resolve, saveJson } = require("./utils");
|
||||
|
||||
function sorted(obj) {
|
||||
if (Array.isArray(obj)) { return obj.map(sorted); }
|
||||
if (obj == null || typeof(obj) !== "object") { return obj; }
|
||||
|
||||
const keys = Object.keys(obj);
|
||||
keys.sort();
|
||||
|
||||
const result = { };
|
||||
keys.forEach((key) => { result[key] = sorted(obj[key]); });
|
||||
return result;
|
||||
}
|
||||
|
||||
function savePackage(dirname, info) {
|
||||
return saveJson(resolve(ROOT, dirname, "package.json"), sorted(info));
|
||||
}
|
||||
|
||||
async function createTarball(dirname) {
|
||||
let base = resolve(ROOT, dirname);
|
||||
|
||||
// From NPM publish, create the packed version
|
||||
let files = await packlist({ path: base });
|
||||
files = files.map((f) => ("./" + f));
|
||||
|
||||
let options = {
|
||||
cwd: base,
|
||||
prefix: 'package/',
|
||||
portable: true,
|
||||
sync: true,
|
||||
// Provide a specific date in the 1980s for the benefit of zip,
|
||||
// which is confounded by files dated at the Unix epoch 0.
|
||||
mtime: new Date('1985-10-26T08:15:00.000Z'),
|
||||
gzip: true
|
||||
};
|
||||
|
||||
// Take the hash of the package sans
|
||||
return tar.create(options, files).read();
|
||||
}
|
||||
|
||||
async function updatePackage(dirname, values) {
|
||||
let info = loadPackage(dirname);
|
||||
|
||||
if (values) {
|
||||
for (let key in values) {
|
||||
info[key] = values[key];
|
||||
}
|
||||
}
|
||||
/*
|
||||
["dependencies", "devDependencies"].forEach((key) => {
|
||||
let deps = info[key] || [];
|
||||
for (let name in deps) {
|
||||
if (name.substring(0, "@ethersproject".length) === "@ethersproject" || name === "ethers") {
|
||||
deps[name] = ">5.0.0-beta.0";
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
//if (dirname !== "ethers") {
|
||||
// delete info.publishConfig.tag;
|
||||
//}
|
||||
|
||||
// Create a normalized version sans tarballHash to compute the tarballHash
|
||||
delete info.tarballHash;
|
||||
savePackage(dirname, info);
|
||||
|
||||
// Compute the tarballHash
|
||||
let tarball = await createTarball(dirname);
|
||||
info.tarballHash = keccak256(tarball);
|
||||
|
||||
// Save the updated package.json to disk
|
||||
savePackage(dirname, info);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
ROOT: ROOT,
|
||||
createTarball: createTarball,
|
||||
dirnames: dirnames,
|
||||
getVersion: function(dirname) { return ((loadPackage(dirname) || {}).version || null); },
|
||||
loadPackage: loadPackage,
|
||||
savePackage: savePackage,
|
||||
updatePackage: updatePackage,
|
||||
}
|
||||
53
admin/log.js
53
admin/log.js
@@ -1,53 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
function getColor(color) {
|
||||
if (!color || color === "normal") { return "\x1b[0m"; }
|
||||
return "\x1b[1m" + ({
|
||||
blue: "\x1b[34m",
|
||||
cyan: "\x1b[36m",
|
||||
green: "\x1b[32m",
|
||||
magenta: "\x1b[35m",
|
||||
red: "\x1b[31m",
|
||||
yellow: "\x1b[33m",
|
||||
bold: ""
|
||||
})[color];
|
||||
}
|
||||
|
||||
// See: https://stackoverflow.com/questions/9781218/how-to-change-node-jss-console-font-color
|
||||
let disableColor = !(process.stdout.isTTY);
|
||||
function colorify(message, color) {
|
||||
if (color) {
|
||||
if (disableColor) { return message; }
|
||||
return getColor(color) + message + getColor();
|
||||
}
|
||||
|
||||
return message.replace(/<([^:]*):((?:[^<>\\]|\\.)*)>/g, (all, color, message) => {
|
||||
message = message.replace("\\>", ">");
|
||||
if (disableColor) { return message; }
|
||||
return getColor(color) + message + getColor();
|
||||
});
|
||||
}
|
||||
|
||||
function colorifyStatus(status) {
|
||||
switch (status) {
|
||||
case "modified": return colorify("<blue:" + status + ">");
|
||||
case "added": return colorify("<green:" + status + ">");
|
||||
case "deleted": return colorify("<red:" + status + ">");
|
||||
case "unmodified": return colorify("<magenta:" + status + ">");
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
function log(message, color) {
|
||||
if (color) {
|
||||
console.log(colorify(message, color));
|
||||
} else {
|
||||
console.log(colorify(message));
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
colorify: colorify,
|
||||
colorifyStatus: colorifyStatus,
|
||||
log: log
|
||||
}
|
||||
104
admin/npm.js
104
admin/npm.js
@@ -1,104 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const resolve = require("path").resolve;
|
||||
|
||||
const npmpub = require("libnpmpublish");
|
||||
const semver = require("semver");
|
||||
|
||||
const local = require("./local");
|
||||
|
||||
const keccak256 = require("../packages/keccak256").keccak256;
|
||||
const fetchJson = require("../packages/web").fetchJson;
|
||||
const { prompt } = require("../packages/cli");
|
||||
|
||||
const colorify = require("./log").colorify;
|
||||
const git = require("./git");
|
||||
|
||||
|
||||
let cache = { };
|
||||
|
||||
async function getPackage(name) {
|
||||
if (cache[name]) { return cache[name]; }
|
||||
|
||||
return fetchJson("http:/" + "/registry.npmjs.org/" + name).then((result) => {
|
||||
cache[name] = result;
|
||||
return result;
|
||||
}, (error) => {
|
||||
if (error.status === 404) {
|
||||
return null;
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
async function getVersion(name) {
|
||||
return getPackage(name).then((result) => {
|
||||
if (!result) { return null; }
|
||||
let versions = Object.keys(result.versions);
|
||||
versions.sort(semver.compare)
|
||||
return versions.pop();
|
||||
});
|
||||
}
|
||||
|
||||
async function getPackageVersion(name, version) {
|
||||
let info = await getPackage(name)
|
||||
if (!info) { return null; }
|
||||
|
||||
if (version == null) {
|
||||
let versions = Object.keys(info.versions);
|
||||
versions.sort(semver.compare);
|
||||
version = versions.pop();
|
||||
}
|
||||
|
||||
return info.versions[version] || null;
|
||||
}
|
||||
|
||||
async function getTarballHash(name, version) {
|
||||
let info = await getPackageVersion(name, version);
|
||||
return (info || {}).tarballHash;
|
||||
}
|
||||
|
||||
async function _publish(info, tarball, options) {
|
||||
try {
|
||||
let result = await npmpub.publish(info, tarball, options);
|
||||
return result;
|
||||
} catch (error) {
|
||||
|
||||
// We need an OTP
|
||||
if (error.code === "EOTP") {
|
||||
try {
|
||||
let otp = await prompt.getMessage(colorify("Enter OTP: ", "bold"));
|
||||
options.otp = otp.replace(" ", "");
|
||||
} catch (error) {
|
||||
|
||||
// CTRL-C
|
||||
if (error.message === "cancelled") {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Something unexpected...
|
||||
throw error;
|
||||
}
|
||||
|
||||
// Retry with the new OTP
|
||||
return _publish(info, tarball, options);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function publish(dirname, options) {
|
||||
let info = local.loadPackage(dirname);
|
||||
info.gitHead = await git.getGitTag(resolve(__dirname, "../packages/", dirname));
|
||||
if (info.gitHead == null) { throw new Error("no git tag found - " + dirname); }
|
||||
let tarball = await local.createTarball(dirname);
|
||||
return _publish(info, tarball, options);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getPackage: getPackage,
|
||||
getPackageVersion: getPackageVersion,
|
||||
getTarballHash: getTarballHash,
|
||||
getVersion: getVersion,
|
||||
publish: publish,
|
||||
};
|
||||
@@ -1,50 +0,0 @@
|
||||
{
|
||||
"name": "DevelopmentChain",
|
||||
"engine": {
|
||||
"instantSeal": null
|
||||
},
|
||||
"params": {
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"accountStartNonce": "0x0",
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"minGasLimit": "0x1388",
|
||||
"networkID" : "0x11",
|
||||
"registrar" : "0x0000000000000000000000000000000000001337",
|
||||
"maxCodeSize": 24576,
|
||||
"maxCodeSizeTransition": "0x0",
|
||||
"eip98Transition": "0x7fffffffffffff",
|
||||
"eip140Transition": "0x0",
|
||||
"eip145Transition": "0x0",
|
||||
"eip150Transition": "0x0",
|
||||
"eip155Transition": "0x0",
|
||||
"eip160Transition": "0x0",
|
||||
"eip161abcTransition": "0x0",
|
||||
"eip161dTransition": "0x0",
|
||||
"eip211Transition": "0x0",
|
||||
"eip214Transition": "0x0",
|
||||
"eip658Transition": "0x0",
|
||||
"wasmActivationTransition": "0x0"
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
"generic": "0x0"
|
||||
},
|
||||
"difficulty": "0x20000",
|
||||
"author": "0x0000000000000000000000000000000000000000",
|
||||
"timestamp": "0x00",
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"extraData": "0x",
|
||||
"gasLimit": "0x7A1200"
|
||||
},
|
||||
"accounts": {
|
||||
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
||||
"0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } },
|
||||
"0000000000000000000000000000000000000006": { "balance": "1", "builtin": { "name": "alt_bn128_add", "activate_at": 0, "pricing": { "linear": { "base": 500, "word": 0 } } } },
|
||||
"0000000000000000000000000000000000000007": { "balance": "1", "builtin": { "name": "alt_bn128_mul", "activate_at": 0, "pricing": { "linear": { "base": 40000, "word": 0 } } } },
|
||||
"0000000000000000000000000000000000000008": { "balance": "1", "builtin": { "name": "alt_bn128_pairing", "activate_at": 0, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } },
|
||||
"0x7454a8f5a7c7555d79b172c89d20e1f4e4cc226c": { "balance": "1606938044258990275541962092341162602522202993782792835301376" }
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
{"id":"24d70b97-fff9-d322-e760-4b8cc2e21751","version":3,"crypto":{"cipher":"aes-128-ctr","cipherparams":{"iv":"45d392cd16dbbd5c0f5b2d145c112da9"},"ciphertext":"b001ccd09fc5431dc055975b58ee61f86e85529245506c04182c902716e750e5","kdf":"pbkdf2","kdfparams":{"c":10240,"dklen":32,"prf":"hmac-sha256","salt":"028594da27a0e864105f33b912e5dc6ce7c75ecd13c81bfc158fe963d30c93bb"},"mac":"374bf2e9144b74b889708abc19e9ebc164f90bc27e83fd9f01da4571a9f81a70"},"address":"7454a8f5a7c7555d79b172c89d20e1f4e4cc226c","name":"","meta":"{}"}
|
||||
@@ -1,64 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const _resolve = require("path").resolve;
|
||||
|
||||
function repeat(chr, length) {
|
||||
let result = chr;
|
||||
while (result.length < length) { result += chr; }
|
||||
return result;
|
||||
}
|
||||
|
||||
function zpad(value) {
|
||||
value = String(value);
|
||||
while (value.length < 2) { value = "0" + value; }
|
||||
return value;
|
||||
}
|
||||
|
||||
function getDate(date) {
|
||||
return [
|
||||
date.getFullYear(),
|
||||
zpad(date.getMonth() + 1),
|
||||
zpad(date.getDate())
|
||||
].join("-");
|
||||
}
|
||||
|
||||
function getDateTime(date) {
|
||||
return getDate(date) + " " + [
|
||||
zpad(date.getHours()) ,
|
||||
zpad(date.getMinutes() + 1)
|
||||
].join(":");
|
||||
}
|
||||
|
||||
function today() {
|
||||
return getDate(new Date());
|
||||
}
|
||||
|
||||
function loadJson(filename) {
|
||||
return JSON.parse(fs.readFileSync(filename).toString());
|
||||
}
|
||||
|
||||
// @TODO: atomic write
|
||||
function saveJson(filename, json) {
|
||||
fs.writeFileSync(filename, JSON.stringify(json, null, 2) + "\n");
|
||||
}
|
||||
|
||||
function resolve(...args) {
|
||||
args = args.slice();
|
||||
args.unshift("..");
|
||||
args.unshift(__dirname);
|
||||
return _resolve.apply(null, args);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
resolve: resolve,
|
||||
|
||||
loadJson: loadJson,
|
||||
saveJson: saveJson,
|
||||
|
||||
repeat: repeat,
|
||||
|
||||
today: today,
|
||||
getDate: getDate,
|
||||
getDateTime: getDateTime
|
||||
}
|
||||
@@ -1,24 +1,49 @@
|
||||
_section: ContractFactory @<ContractFactory> @SRC<contracts:class.ContractFactory>
|
||||
|
||||
@TODO: Fill this in, including @SRC links
|
||||
To deploy a [[Contract]], additional information is needed
|
||||
that is not available on a Contract object itself.
|
||||
|
||||
Mainly, the bytecode (more specifically the initcode) of a contract is required.
|
||||
|
||||
The **Contract Factory** sends a special type of transaction, an initcode
|
||||
transaction (i.e. the ``to`` field is null, and the ``data`` field is the
|
||||
initcode) where the initcode will be evaluated and the result becomes the
|
||||
new code to be deployed as a new contract.
|
||||
|
||||
_subsection: Creating Instances @<ContractFactory--creating>
|
||||
|
||||
_property: new ethers.ContractFactory(interface, bytecode [ , signer ]) @SRC<contracts:constructor.ContractFactory>
|
||||
|
||||
Creates a new instance of a **ContractFactory** for the contract described
|
||||
by the //interface// and //bytecode// initcode.
|
||||
|
||||
_property: ContractFactory.fromSolidity(compilerOutput [ , signer ]) => [[ContractFactory]]
|
||||
|
||||
Consumes the output of the Solidity compiler, extracting the ABI
|
||||
and bytecode from it, allowing for the various formats the solc
|
||||
compiler has emitted over its life.
|
||||
|
||||
_property: contractFactory.connect(signer) => [[Contract]] @<ContractFactory-connect>
|
||||
|
||||
Returns a **new instance** of the ContractFactory with the same //interface//
|
||||
and //bytecode//, but with a different //signer//.
|
||||
|
||||
_subsection: Properties @<ContractFactory--properties>
|
||||
|
||||
_property: contractFactory.interface => [[Interface]]
|
||||
|
||||
The [[Contract]] interface.
|
||||
|
||||
_property: contractFactory.bytecode => string<[[DataHexString]]>
|
||||
|
||||
The bytecode (i.e. initcode) that this **ContractFactory** will
|
||||
use to deploy the Contract.
|
||||
|
||||
_property: contractFactory.signer => [[Signer]]
|
||||
|
||||
The [[Signer]] (if any) this ContractFactory will use to deploy instances
|
||||
of the Contract to the Blockchain.
|
||||
|
||||
|
||||
_subsection: Methods @<ContractFactory--methods>
|
||||
|
||||
@@ -29,36 +54,52 @@ same as using the [Contract constructor](Contract--creating) with
|
||||
//address// and this the //interface// and //signerOrProvider// passed
|
||||
in when creating the ContractFactory.
|
||||
|
||||
_property: contractFactory.getDeployTransaction(...args) => [[UnsignedTransaction]]
|
||||
_property: contractFactory.getDeployTransaction(...args [ , overrides ]) => [[UnsignedTransaction]]
|
||||
|
||||
Returns the unsigned transaction which would deploy this Contract with //args// passed
|
||||
to the Contract's constructor.
|
||||
|
||||
_property: contractFactory.deploy(...args) => Promise<[[Contract]]> @<ContractFactory-deploy>
|
||||
If the optional //overrides// is specified, they can be used to
|
||||
override the endowment ``value``, transaction ``nonce``, ``gasLimit`` or
|
||||
``gasPrice``.
|
||||
|
||||
_property: contractFactory.deploy(...args [ , overrides ]) => Promise<[[Contract]]> @<ContractFactory-deploy>
|
||||
|
||||
Uses the signer to deploy the Contract with //args// passed into the constructor and
|
||||
returns a Contract which is attached to the address where this contract **will** be
|
||||
returns a Contract which is attached to the address where this contract **will** be
|
||||
deployed once the transaction is mined.
|
||||
|
||||
The transaction can be found at ``contract.deployTransaction``, and no interactions
|
||||
should be made until the transaction is mined.
|
||||
|
||||
_code: Deploying a Contract
|
||||
If the optional //overrides// is specified, they can be used to
|
||||
override the endowment ``value``, transaction ``nonce``, ``gasLimit`` or
|
||||
``gasPrice``.
|
||||
|
||||
_code: Deploying a Contract @lang<javascript>
|
||||
|
||||
// <hide>
|
||||
const signer = ethers.LocalSigner();
|
||||
const signer = localSigner;
|
||||
const ContractFactory = ethers.ContractFactory;
|
||||
const bytecode = "608060405234801561001057600080fd5b5060405161012e38038061012e8339818101604052604081101561003357600080fd5b81019080805190602001909291908051906020019092919050505081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060008190555050506088806100a66000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80633fa4f24514602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000805490509056fea2646970667358221220926465385af0e8706644e1ff3db7161af699dc063beaadd55405f2ccd6478d7564736f6c63430007040033";
|
||||
// </hide>
|
||||
|
||||
|
||||
// If your contract constructor requires parameters, the ABI
|
||||
// must include the constructor
|
||||
const abi = [
|
||||
"constructor(address owner, uint256 initialValue)"
|
||||
"constructor(address owner, uint256 initialValue)",
|
||||
"function value() view returns (uint)"
|
||||
];
|
||||
|
||||
const factory = new ContractFactory(abi, bytecode, signer)
|
||||
// The factory we use for deploying contracts
|
||||
factory = new ContractFactory(abi, bytecode, signer)
|
||||
|
||||
const contract = await factory.deploy("ricmoo.eth", 42);
|
||||
// Deploy an instance of the contract
|
||||
contract = await factory.deploy("ricmoo.eth", 42);
|
||||
//<hide>
|
||||
//! async contract
|
||||
//</hide>
|
||||
|
||||
// The address is available immediately, but the contract
|
||||
// is NOT deployed yet
|
||||
@@ -69,7 +110,9 @@ contract.address
|
||||
contract.deployTransaction
|
||||
//!
|
||||
|
||||
// Wait until the transaction is mined
|
||||
// Wait until the transaction is mined (i.e. contract is deployed)
|
||||
// - returns the receipt
|
||||
// - throws on failure (the reciept is on the error)
|
||||
contract.deployTransaction.wait()
|
||||
//!
|
||||
|
||||
|
||||
@@ -129,6 +129,13 @@ function codeContextify(context) {
|
||||
context.Wallet = ethers.Wallet;
|
||||
context.provider = new ethers.providers.InfuraProvider("mainnet", "49a0efa3aaee4fd99797bfa94d8ce2f1");
|
||||
|
||||
// We use a local dev node for some signing examples, but want to
|
||||
// resolve ENS names against mainnet; super hacky but makes the
|
||||
// docs nicer
|
||||
context.localProvider = new ethers.providers.JsonRpcProvider();
|
||||
context.localSigner = context.localProvider.getSigner();
|
||||
context.localProvider.resolveName = context.provider.resolveName.bind(context.provider);
|
||||
|
||||
context.BigNumber.prototype[inspect.custom] = function(depth, options) {
|
||||
return `{ BigNumber: ${JSON.stringify(this.toString()) } }`;
|
||||
}
|
||||
|
||||
Binary file not shown.
BIN
github-cache/0092e01ba847
Normal file
BIN
github-cache/0092e01ba847
Normal file
Binary file not shown.
Binary file not shown.
BIN
github-cache/00b696045723
Normal file
BIN
github-cache/00b696045723
Normal file
Binary file not shown.
BIN
github-cache/00df3056e64a
Normal file
BIN
github-cache/00df3056e64a
Normal file
Binary file not shown.
BIN
github-cache/0156bd008b7b
Normal file
BIN
github-cache/0156bd008b7b
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
github-cache/01c33179693b
Normal file
BIN
github-cache/01c33179693b
Normal file
Binary file not shown.
Binary file not shown.
BIN
github-cache/0204fabc1638
Normal file
BIN
github-cache/0204fabc1638
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
github-cache/023aa4e9a6ef
Normal file
BIN
github-cache/023aa4e9a6ef
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
github-cache/03c19256301e
Normal file
BIN
github-cache/03c19256301e
Normal file
Binary file not shown.
Binary file not shown.
BIN
github-cache/04931159c0cd
Normal file
BIN
github-cache/04931159c0cd
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
github-cache/0647f84b79d2
Normal file
BIN
github-cache/0647f84b79d2
Normal file
Binary file not shown.
Binary file not shown.
BIN
github-cache/0695656a11c0
Normal file
BIN
github-cache/0695656a11c0
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
github-cache/071ac2ca314d
Normal file
BIN
github-cache/071ac2ca314d
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
github-cache/08efa117f803
Normal file
BIN
github-cache/08efa117f803
Normal file
Binary file not shown.
BIN
github-cache/0957e37ef926
Normal file
BIN
github-cache/0957e37ef926
Normal file
Binary file not shown.
Binary file not shown.
BIN
github-cache/09c471182e2d
Normal file
BIN
github-cache/09c471182e2d
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
github-cache/0a8b9d7b79cd
Normal file
BIN
github-cache/0a8b9d7b79cd
Normal file
Binary file not shown.
BIN
github-cache/0aa40d71beb8
Normal file
BIN
github-cache/0aa40d71beb8
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
github-cache/0d5cf9bbda93
Normal file
BIN
github-cache/0d5cf9bbda93
Normal file
Binary file not shown.
BIN
github-cache/0d78130fb2f5
Normal file
BIN
github-cache/0d78130fb2f5
Normal file
Binary file not shown.
BIN
github-cache/0dccc130eb08
Normal file
BIN
github-cache/0dccc130eb08
Normal file
Binary file not shown.
BIN
github-cache/0e25dc377f38
Normal file
BIN
github-cache/0e25dc377f38
Normal file
Binary file not shown.
Binary file not shown.
BIN
github-cache/0e4ca4f9da4d
Normal file
BIN
github-cache/0e4ca4f9da4d
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
github-cache/10131d9974bd
Normal file
BIN
github-cache/10131d9974bd
Normal file
Binary file not shown.
BIN
github-cache/105add2c5a33
Normal file
BIN
github-cache/105add2c5a33
Normal file
Binary file not shown.
BIN
github-cache/110e276342bd
Normal file
BIN
github-cache/110e276342bd
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user