diff --git a/README.md b/README.md index e0f7ec088..9d9d6fd0c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ The Ethers Project ================== -[![npm (tag)](https://img.shields.io/npm/v/ethers/latest)](https://www.npmjs.com/package/ethers) +[![npm (tag)](https://img.shields.io/npm/v/ethers)](https://www.npmjs.com/package/ethers) [![Node.js CI](https://github.com/ethers-io/ethers.js/workflows/Node.js%20CI/badge.svg?branch=ethers-v5-beta)](https://github.com/ethers-io/ethers.js/actions?query=workflow%3A%22Node.js+CI%22) A complete Ethereum wallet implementation and utilities in JavaScript (and TypeScript). @@ -38,7 +38,7 @@ Installing **node.js** ``` -/home/ricmoo/some_project> npm install --save ethers@next +/home/ricmoo/some_project> npm install --save ethers ``` **browser (UMD)** @@ -60,13 +60,13 @@ Installing Documentation ------------- -Browse the documentation online: +Browse the [documentation](https://docs.ethers.io/v5/) online: -- [Getting Started](https://docs.ethers.io/) -- [Full API Documentation](https://docs.ethers.io/) +- [Getting Started](https://docs.ethers.io/v5/getting-started/) +- [Full API Documentation](https://docs.ethers.io/v5/api/) - [Various Ethereum Articles](https://blog.ricmoo.com/) -Or browser the entire documentations as a [single page](https://docs.ethers.io/single-page/). +Or browser the entire documentations as a [single page](https://docs.ethers.io/single-page/) to make searching easier. Ancillary Packages diff --git a/admin/cmds/serve-docs.js b/admin/cmds/serve-docs.js new file mode 100644 index 000000000..90f0d9556 --- /dev/null +++ b/admin/cmds/serve-docs.js @@ -0,0 +1,100 @@ +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(`Listening on port: ${ options.port }`); + }); + + return server; +} + +start(path.resolve(__dirname, "../../docs"), { + redirects: { + "/": "/v5/" + } +}); diff --git a/docs.wrm/api/providers/api-providers.wrm b/docs.wrm/api/providers/api-providers.wrm index c974b4779..1291244ce 100644 --- a/docs.wrm/api/providers/api-providers.wrm +++ b/docs.wrm/api/providers/api-providers.wrm @@ -82,7 +82,7 @@ _subsection: InfuraProvider @ @INHERIT<[[UrlJsonRpcProvider]]> @ The **InfuraProvider** is backed by the popular [INFURA](link-infura) Ethereum service. -_property: new ethers.providers.InfuraProvider([ network = "homestead", [ apiKey ] ]) +_property: new ethers.providers.InfuraProvider([ network = "homestead", [ apiKey ] ]) @SRC Create a new **InfuraProvider** connected to //network// with the optional //apiKey//. @@ -96,6 +96,12 @@ specify a [Project Secret](link-infura-secret) which can be used on non-public sources (like on a server) to further secure your API access and quotas. +_property: InfuraProvider.getWebSocketProvider([ network [ , apiKey ] ]) => [[WebSocketProvider]] @ @SRC +Create a new [[WebSocketProvider]] using the INFURA web-socket endpoint +to connect to //network// with the optional //apiKey//. + +The //network// and //apiKey// are specified the same as [the constructor](InfuraProvider). + _note: Note: Default API keys If no //apiKey// is provided, a shared API key will be used, which may result in reduced performance and throttled requests. @@ -136,6 +142,14 @@ provider = new InfuraProvider("homestead", { projectSecret: projectSecret }); +// Connect to the INFURA WebSocket endpoints with a WebSocketProvider +provider = InfuraProvider.getWebSocketProvider() +// +provider._websocket.onopen = function(){ + provider._websocket.close(); +}; +// + _subsection: AlchemyProvider @ @inherit<[[UrlJsonRpcProvider]]> @src diff --git a/docs.wrm/api/providers/other.wrm b/docs.wrm/api/providers/other.wrm index 80e793106..2105b310e 100644 --- a/docs.wrm/api/providers/other.wrm +++ b/docs.wrm/api/providers/other.wrm @@ -93,7 +93,7 @@ The URL to use for the JsonRpcProvider instance. -_subsection: Web3Provider @ @INHERIT<[[JsonRpcProvider]]> +_subsection: Web3Provider @ @INHERIT<[[JsonRpcProvider]]> @SRC The Web3Provider is meant to ease moving from a [web3.js based](link-web3) application to ethers by wraping an existing Web3-compatible (such as a @@ -144,3 +144,20 @@ This is identical to ``sendAsync``. Historically, this used a synchronous web request, but no current browsers support this, so its use this way was deprecated quite a long time ago + +_subsection: WebSocketProvider @ @INHERIT<[[JsonRpcProvider]]> @SRC + +The **WebSocketProvider** connects to a JSON-RPC WebSocket-compatible backend +which allows for a persistent connection, multiplexing requests and pub-sub +events for a more immediate event dispatching. + +The WebSocket API is newer, and if running your own infrastructure, note that +WebSockets are much more intensive on your server resourses, as they must manage +and maintain the state for each client. For this reason, many services may also +charge additional fees for using their WebSocket endpoints. + +_property: new ethers.provider.WebSockerProvider([ url [ , network ] ]) +Returns a new [[WebSocketProvider]] connected to //url// as the //network//. + +If //url// is unspecified, the default ``"ws:/\/localhost:8546"`` will be used. +If //network// is unspecified, it will be queried from the network. diff --git a/docs.wrm/contributing.wrm b/docs.wrm/contributing.wrm index da43a431c..56e71dc8a 100644 --- a/docs.wrm/contributing.wrm +++ b/docs.wrm/contributing.wrm @@ -1,4 +1,4 @@ -_section: Contributing and Hacking +_section: Contributing and Hacking @ The ethers.js library is something that I've written out of necessity, and has grown somewhat organically over time. @@ -25,14 +25,19 @@ have a public discussion and figure out the best way to address to problem/featu **:)** -_subsection: Building +_subsection: Building @ -If you wish to modify the source code, there are a few steps involved in setting up -your environment. +If you wish to modify the source code, there are a few steps involved in +setting up your environment. -_code: Preparing the Package @lang +Since the library uses a monorepo, you must install an initial required +set of libraries, which can then be used to install the remaining libraries +used within each package, as well as link all the packages within the repo +with each other. -# Clone the REPO +_code: Preparing for builds @lang + +# Clone the repository /home/ricmoo> git clone git@github.com:ethers-io/ethers.js.git /home/ricmoo> cd ethers.js @@ -44,6 +49,10 @@ _code: Preparing the Package @lang /home/ricmoo/ethers.js> npm run bootstrap +_subsection: Making your changes @ + +TODO: Add more information here. + _code: Watching and Building @lang # Begin watching the files and re-building whenever they change @@ -72,3 +81,65 @@ _code: Preparing the Distribution @lang /home/ricmoo/ethers.js> npm run update-version + +_subsection: Documentation @ + +The documents are generated using [Flatworm](flatworm) documentation +generation tool, which was written for the purpose of writing the documentation +for ethers. + +Style Guide (this section will have much more coming): + +- Try to keep lines no longer than //around// 80 characters +- Avoid inline links in the source; use the ``externalLinks`` field in the config.js +- Prefix external links with ``link-`` +- Changing an anchor name must be well justified, as it will break all existing links + to that section; flatworm will support symblinks in the future +- In general, I aim for xonsistency; look to similar situations throughout the documentation + + +_heading: Building + +To build the documentation, you should first follow the +[above steps](contributing--building) to build the ethers library. + +Building the docs will generate several types of output: + +- A full set of HTML pages, linking across each other +- A single one-page HTML page with all pages linking to local anchors +- A full set of README.md pages organized to be browsable and linkable in GitHub +- A metadata dump for tool ingestion (still needs more work) +- (@TODO; only half done) The documentation as a LaTeX and generated PDF + +_code: Building the Documentations @lang + +/home/ricmoo/ethers.js> npm run build-docs + + +_heading: Evaluation + +When building the documentation, all code samples are run through a JavaScript +VM to ensure there are no typos in the example code, as well the exact output +of results are injected into the output, so there is no need to keep the results +and code in-sync. + +However, this can be a bit of a headache when making many small changes, so to +build the documentation faster, you can skip the evaluation step, which will +inject the code directly. + +_code: Build docs skipping evaluation @lang + +/home/ricmoo/ethers.js> npm run build-docs -- --skip-eval + + +_heading: Previewing Changes + +To preview the changes locally, you can use any standard web server and run +from the ``/docs/`` folder, or use the built-in web server. + +The same caveats as normal web development apply, such flushing browser +caches after changing (and re-building) the docs. + +_code: Running a webserver @lang + +/home/ricmoo/ethers.js> npm run serve-docs diff --git a/docs.wrm/documentation.wrm b/docs.wrm/documentation.wrm index 8f001c40e..4c0b271cb 100644 --- a/docs.wrm/documentation.wrm +++ b/docs.wrm/documentation.wrm @@ -1,4 +1,4 @@ -_section: Flatworm Docs +_section: Flatworm Docs @ The //Flatworm Docs// rendering engine is designed to be **very** simple, but provide enough formatting necessary for documenting @@ -102,7 +102,7 @@ _definition: **_table:** //FOOTER// Creates a [Table](flatworm--table) structured according to the body. -Each cell support and variables support markdown. +Each cell contents supports markdown and variables supports markdown. **Extensions:** [@style](flatworm--ext-style) @@ -173,7 +173,8 @@ This is placed in an orange box. \_null: -This breaks out of a directive. For example, to end a +This breaks out of a directive. For example, to end +a ``_note:`` or ``_code:``. _subsection: Markdown @ diff --git a/package-lock.json b/package-lock.json index 9f081f096..40061b2d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1935,9 +1935,9 @@ } }, "acorn-walk": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz", - "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==" + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" }, "aes-js": { "version": "3.0.0", @@ -4655,9 +4655,9 @@ "dev": true }, "flatworm": { - "version": "0.0.2-beta.3", - "resolved": "https://registry.npmjs.org/flatworm/-/flatworm-0.0.2-beta.3.tgz", - "integrity": "sha512-mAwxCjcY3OeA+y3/R0WcHuO1R5yhxh3eAvKmKjQBxGcwtOI7D34ko6HtxE9WR+L/OAiqsdyYKa+LfjDJWgDkLw==", + "version": "0.0.2-beta.4", + "resolved": "https://registry.npmjs.org/flatworm/-/flatworm-0.0.2-beta.4.tgz", + "integrity": "sha512-C9TqeUGFq7fHpwEawUhb53mA9tfnHrD14edu0LF/anNBfaU+kUcTZeXVjKUgfYzS/0aBZyL0vstQvltS76pp4w==", "dev": true }, "flush-write-stream": { diff --git a/package.json b/package.json index 2175b7022..42f82dc74 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,8 @@ "test": "if [ \"$TEST\" == \"\" ]; then npm run test-node; else npm run \"test-$TEST\"; fi", "lock-versions": "node ./admin/cmds/lock-versions", "build-docs": "flatworm docs.wrm docs", + "serve-docs": "node ./admin/cmds/serve-docs.js", + "test-docs": "npm run build-docs && npm run serve-docs", "upload-docs": " node ./admin/cmds/upload-docs.js", "spell-check": "node admin/cmds/spell-check.js", "_admin_prepare": "npm run clean && npm run bootstrap && npm run build && node ./admin/cmds/update-exports.js", @@ -43,7 +45,7 @@ "aes-js": "3.0.0", "aws-sdk": "2.137.0", "diff": "4.0.1", - "flatworm": "0.0.2-beta.3", + "flatworm": "0.0.2-beta.4", "karma": "5.0.2", "karma-chrome-launcher": "3.1.0", "karma-mocha": "2.0.0", diff --git a/packages/ethers/README.md b/packages/ethers/README.md index bfae05c5d..9d9d6fd0c 100644 --- a/packages/ethers/README.md +++ b/packages/ethers/README.md @@ -1,17 +1,92 @@ -Ethers -====== +The Ethers Project +================== -**EXPERIMENTAL** +[![npm (tag)](https://img.shields.io/npm/v/ethers)](https://www.npmjs.com/package/ethers) +[![Node.js CI](https://github.com/ethers-io/ethers.js/workflows/Node.js%20CI/badge.svg?branch=ethers-v5-beta)](https://github.com/ethers-io/ethers.js/actions?query=workflow%3A%22Node.js+CI%22) -Please see the [ethers](https://github.com/ethers-io/ethers.js) repository -for more informations. +A complete Ethereum wallet implementation and utilities in JavaScript (and TypeScript). -API ---- +**Features:** + +- Keep your private keys in your client, **safe** and sound +- Import and export **JSON wallets** (Geth, Parity and crowdsale) +- Import and export BIP 39 **mnemonic phrases** (12 word backup phrases) and **HD Wallets** (English as well as Czech, French, Italian, Japanese, Korean, Simplified Chinese, Spanish, Traditional Chinese) +- Meta-classes create JavaScript objects from any contract ABI, including **ABIv2** and **Human-Readable ABI** +- Connect to Ethereum nodes over [JSON-RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC), [INFURA](https://infura.io), [Etherscan](https://etherscan.io), [Alchemy](https://alchemyapi.io) or [MetaMask](https://metamask.io) +- **ENS names** are first-class citizens; they can be used anywhere an Ethereum addresses can be used +- **Tiny** (~104kb compressed; 322kb uncompressed) +- **Modular** packages; include only what you need +- **Complete** functionality for all your Ethereum desires +- Extensive [documentation](https://docs.ethers.io/ethers.js/html/) +- Large collection of **test cases** which are maintained and added to +- Fully **TypeScript** ready, with definition files and full TypeScript source +- **MIT License** (including ALL dependencies); completely open source to do with as you please + + +Keep Updated +------------ + +For the latest news and advisories, please follow the [@ethersproject](https://twitter.com/ethersproject) +on Twitter (low-traffic, non-marketting, important information only) as well as watch this GitHub project. + +For the latest changes, see the [CHANGELOG](https://github.com/ethers-io/ethers.js/blob/master/CHANGELOG.md). + + +Installing +---------- + +**node.js** + +``` +/home/ricmoo/some_project> npm install --save ethers +``` + +**browser (UMD)** + +``` + +``` + +**browser (ESM)** + +``` + +``` + + +Documentation +------------- + +Browse the [documentation](https://docs.ethers.io/v5/) online: + +- [Getting Started](https://docs.ethers.io/v5/getting-started/) +- [Full API Documentation](https://docs.ethers.io/v5/api/) +- [Various Ethereum Articles](https://blog.ricmoo.com/) + +Or browser the entire documentations as a [single page](https://docs.ethers.io/single-page/) to make searching easier. + + +Ancillary Packages +------------------ + +These are a number of packages not included in the umbrella `ethers` npm package, and +additional packages are always being added. Often these packages are for specific +use-cases, so rather than adding them to the umbrella package, they are added as +ancillary packaged, which can be included by those who need them, while not bloating +everyone else with packages they do not need. + +We will keep a list of useful pacakges here. + +- `@ethersproject/experimental` ([documentation](https://docs.ethers.io)) +- `@ethersproject/cli` ([documentation](https://docs.ethers.io)) +- `@ethersproject/hardware-wallets` ([documentation](https://docs.ethers.io)) -`@TODO` License ------- -MIT License +MIT License (including **all** dependencies). +