diff --git a/DEVELOPERS.md b/DEVELOPERS.md index f4ca23922..28d77dcbc 100644 --- a/DEVELOPERS.md +++ b/DEVELOPERS.md @@ -5,7 +5,7 @@ applications, so grab a coffee ☕ and settle in. ## Quick Start See also [`QUICKSTART.md`][quickstart-guide] for up-to-date instructions. -0. `nvm use 16.17.1` (you can get `nvm` from [nvm.sh][nvm-official]) +0. `nvm use 18.19.0` (you can get `nvm` from [nvm.sh][nvm-official]) 1. `npm install -g @fabric/core` to add `fabric` to your path 2. (optional) `fabric setup` to set up your environment (generates a new master key) 3. `fabric` should now be enough to get you up and running! @@ -15,6 +15,10 @@ That's it! Let's take a look at overall Fabric system and how you, as a develop ## Architecture Fabric is two things — a protocol for machines to exchange information ("the Fabric Protocol"), and a sotware library (`@fabric/core`) offering up many tools and utilities for building your own networks which speak this protocol. +Typically, you will need the following: + + - a Bitcoin Node (bitcoind and/or bcoin with `bcoin --only=127.0.0.1`) + ### Overview Using Fabric to interface securely with decentralized systems, you'll start by following the instructions above to obtain a globally-available version of the `fabric` command-line client, which provides the majority of tools you'll need along the way. diff --git a/README.md b/README.md index 23d2fc8d8..d538a00c2 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,9 @@ You'll also want `bitcoind` installed, and fully synchronized with your preferred network. You can use `scripts/playnet.sh` to run a local playnet node, for which you can use the faucet: https://faucet.playnet.fabric.pub +## What is Fabric? +`@fabric/core` provides the reference implementation for [the Fabric Protocol][protocol], a "language" for exchanging information through peer-to-peer networks. Written in JavaScript, it is meant to be well-documented and easy to understand — but not the final implementation. + ## Contributing Fork and clone [the Fabric GitHub repository][fabric-github] and launch a local web server with `npm run examples` to view the examples, or `npm run docs` once @@ -102,29 +105,6 @@ main().catch((exception) => { }); ``` -### Using Fabric in the Browser -[`@fabric/http`][fabric-http] generates a `fabric.min.js` bundle, which can be included with any HTML -document to expose the API in a browser. - -```html - - -
-

Example

-
- - - - -``` - ## Plugins Fabric is an extensible framework, supporting a variety of plugins. @@ -148,6 +128,25 @@ To add your project to the list, [read the API docs][api-docs], create a public repository for the source code, then [edit this file][edit-readme] to include a link to your work. +### Edge Nodes +Full Fabric nodes connected to the World Wide Web (WWW). Only SSL (port 443) is supported. + +| Host | Status | +| ---- | ------ | +| `hub.fabric.pub` | `ONLINE` +| `labs.fabric.pub` | `OFFLINE` + +### Fabric Projects +Either Fabric libraries or projects running Fabric, this list encompasses the most interesting work in the ecosystem. + +| Name | Description | Status | v0.1.0-RC1 ready +| ---- | ----------- | ------ | ---------- +| [`@fabric/core`][fabric-github] | Core Library +| [`@fabric/http`][http-plugin] | Edge Nodes +| [`hub.fabric.pub`](https://hub.fabric.pub) | +| [`labs.fabric.pub`](https://labs.fabric.pub) | +| [`grove.chat`][chat] | + ## Learning More The best place to get started is in [the #learning channel][learning], a collection of empassioned educators eager to help you. @@ -169,6 +168,7 @@ Fabric on Twitter: [@FabricProtocol][twitter] [fabric-github]: https://github.com/FabricLabs/fabric [http-plugin]: https://github.com/FabricLabs/fabric-http +[hub-plugin]: https://github.com/FabricLabs/hub.fabric.pub [matrix-plugin]: https://github.com/FabricLabs/fabric-matrix [twilio-plugin]: https://github.com/FabricLabs/fabric-twilio [zapier-plugin]: https://github.com/FabricLabs/fabric-zapier @@ -187,7 +187,9 @@ Fabric on Twitter: [@FabricProtocol][twitter] [badge-doorman-status]: https://img.shields.io/travis/FabricLabs/doorman.svg?branch=master&style=flat-square [badge-doorman-coverage]: https://img.shields.io/codecov/c/github/FabricLabs/doorman.svg?style=flat-square [badge-http-status]: https://img.shields.io/travis/FabricLabs/fabric-http.svg?branch=master&style=flat-square +[badge-hub-status]: https://img.shields.io/travis/FabricLabs/fabric-hub.svg?branch=master&style=flat-square [badge-http-coverage]: https://img.shields.io/codecov/c/github/FabricLabs/fabric-http.svg?style=flat-square +[badge-hub-coverage]: https://img.shields.io/codecov/c/github/FabricLabs/fabric-hub.svg?style=flat-square [badge-matrix-status]: https://img.shields.io/travis/FabricLabs/fabric-matrix.svg?branch=master&style=flat-square [badge-matrix-coverage]: https://img.shields.io/codecov/c/github/FabricLabs/fabric-matrix.svg?style=flat-square [badge-twilio-status]: https://img.shields.io/travis/FabricLabs/fabric-twilio.svg?branch=master&style=flat-square diff --git a/functions/_sortKeys.js b/functions/_sortKeys.js index fdc4df559..ff53a2027 100644 --- a/functions/_sortKeys.js +++ b/functions/_sortKeys.js @@ -4,8 +4,11 @@ * @returns {Object} Re-sorted instance of `state` as provided. */ module.exports = function _sortKeys (state = {}) { + // Sort the keys of the state object, and return a new object with the sorted keys. return Object.keys(state).sort().reduce((obj, key) => { + // Add the key to the new object. obj[key] = state[key]; + // Return the new object. return obj; }, {}); }; diff --git a/tests/fabric.contract.js b/tests/fabric.contract.js index 609d62b67..cf2014225 100644 --- a/tests/fabric.contract.js +++ b/tests/fabric.contract.js @@ -36,6 +36,7 @@ describe('@fabric/core/types/contract', function () { it('can publish a contract', function (done) { async function test () { const contract = new Contract(sample); + contract.on('message', (msg) => { switch (msg['@type']) { default: @@ -46,6 +47,7 @@ describe('@fabric/core/types/contract', function () { break; } }); + contract.deploy(); } diff --git a/types/peer.js b/types/peer.js index 3878860b7..5f8506e89 100644 --- a/types/peer.js +++ b/types/peer.js @@ -159,6 +159,55 @@ class Peer extends Service { return this.settings.interface || this.settings.address; } + get documentation () { + return { + name: 'Fabric', + description: 'Manages connections to the Fabric Network.', + methods: { + ack: { + description: 'Acknowledge a message.', + parameters: { + message: { + // TODO: consider making this a FabricMessageID + type: 'FabricMessage', + description: 'The message to acknowledge.' + } + }, + returns: { + type: 'Promise', + description: 'A Promise which resolves to the completed FabricState.' + } + }, + send: { + description: 'Send a message to a connected peer.', + parameters: { + message: { + type: 'FabricMessage', + description: 'The message to send to the peer.' + } + }, + returns: { + type: 'Promise', + description: 'A Promise which resolves to the response (if any).' + } + }, + broadcast: { + description: 'Broadcast a message to all connected nodes.', + parameters: { + message: { + type: 'FabricMessage', + description: 'The message to send to the node.' + } + }, + returns: { + type: 'Promise', + description: 'A Promise which resolves to the responses (if any).' + } + } + } + } + } + get interface () { return this.settings.interface || this.settings.address; } diff --git a/types/service.js b/types/service.js index a80965418..d7573bb81 100644 --- a/types/service.js +++ b/types/service.js @@ -41,9 +41,11 @@ const Store = require('./store'); class Service extends Actor { /** * Create an instance of a Service. - * @param {Object} settings Configuration for this service. - * @param {Boolean} [settings.networking=true] Whether or not to connect to the network. - * @param {Object} [settings.@data] Internal data to assign. + * @param {Object} [settings] Configuration for this service. + * @param {Boolean} [settings.networking=true] Whether or not to connect to the network. + * @param {Object} [settings.frequency] Interval frequency in hertz. + * @param {Object} [settings.state] Initial state to assign. + * @param {Object} [settings.@data] Internal data to assign. */ constructor (settings = {}) { // Initialize Scribe, our logging tool @@ -55,6 +57,7 @@ class Service extends Actor { this.settings = merge({ name: 'Service', path: './stores/service', + frequency: 0.0133333334, // Hz networking: true, persistent: false, constraints: { @@ -165,6 +168,10 @@ class Service extends Actor { return this._heart; } + get interval () { + return 1000 / this.settings.frequency; + } + get status () { return this._state.status; }