GithubHelp home page GithubHelp logo

storj-archived / storj.js Goto Github PK

View Code? Open in Web Editor NEW
27.0 12.0 12.0 6.97 MB

Deprecated. Browser library for interacting with Storj.

Home Page: https://storj.io

License: GNU Lesser General Public License v3.0

JavaScript 100.00%
storj p2p cloud

storj.js's Introduction

Notice: Development on this repository is currently on pause during our v3 rearchitecture. Please see storj/storj for ongoing v3 development.

storj.js

The official Storj library, for node.js and the browser.

Development Status

This library is currently in early beta. It is released for testing purposes only. Files uploaded via storj.js are not currently compatible with the reference implementation. If you are developing an application, we strongly recommend that you use libstorj via bindings.

Table of Contents

Install

Node.js

If you are building an application that will run outside of a browser, such as a web server, you should use Node.js. From the root of your project directory, alongside your package.json, run:

npm install --save storj

Note: during the beta, this package will not be available via npm. Instead, install with the following syntax: npm install --save https://github.com/storj/storj.js

Browser

Download the Storj.js library from our releases page and place it alongside the index.html file for your website, saving it as storj.js. Then, in index.html include:

<html>
  <head>...</head>
  <body>
    ...
    <script src="./storj.js"></script>
    ...
  </body>
</html>

The files on our releases page are named after the version of the ECMAScript they target. If you are wanting to target older browsers, use storj.es5.js which targets ES5, othwise use storj.es6.js.

Usage

Use in Node.js

var Storj = require('storj');
var storj = new Storj()

Use in the browser

<script src="storj.js"></script>
<script>
  var storj = new Storj(options);
  ...
</script>

API

Storj.js exposes an isomorphic API that works both in the browser and in node.js!

Storj Object

var storj = new Storj([opts])

Create a new Storj instance, which will be used to talk across the storj protocol. This object will emit the ready event when it has finished being configured.

The optional opts allows you to override the default behaviour of this object. The opts object is how you will pass in your user credentials if you need to work with private buckets.

opts:

{
  bridge: STRING, // The url of the bridge to talk to, defaults to https://api.storj.io
  basicAuth: OBJECT, // Used for any requests that require authentication, this is your username and password
  key: STRING, // Private key, used for any requests that require authentication
  encryptionKey: STRING // Used to encrypt and decrypt data stored in private buckets
}

basicAuth should be of the form:

{
  email: STRING,
  password: STRING
}

If you need to use authentication in your application, we strongly suggest you use the key method as it provides a higher level of security.

Both basicAuth and key are optional, but you may only provide one or the other. If you use basicAuth, the library will assume that you already have registered a public key with the bridge you are authenticating with. To create a public/private key pair for you and register it to your account you can use the generateKeyPair and registerKey API.

If you provide a key, this key will be used to authenticate every request moving forward.

storj.on('error', function (e) {})

Emitted when the library encounters a catastrophic error that will probably prevent normal operation moving forward. When an error is emitted, you should cleanup your Storj object and create a new one.

storj.on('ready', function () {})

Emitted when the Storj object is ready to communicate with the storj network.

var keypair = storj.generateKeyPair([privateKey])

Create a new public/private KeyPair for authenticating against the Storj network. Note, this function will not register this key with your account, you must provide storj.registerKey with the returned public key to do that.

storj.registerKey(publicKey, function cb(e) {})

Register a public key with the Storj network. cb will be called with an Error if something goes wrong or null otherwise.

var keypair = storj.generateKeyPair();
storj.registerKey(keypair.getPublicKey(), function(e) {
  if(e) { /* failed to register key */ }
});

storj.getKeyList(function cb(e, keys) {})

Get a list of all public keys stored for the current user. cb will be called with an Error if something goes wrong, or will be passed an array keys, where each element of the array is an object in the form:

{
  user: String, // The user the key belongs to
  key: Striong, // The public key itself
  id: String    // The unique id of the key
}

storj.removeKey(publicKey, function cb(e) {})

Remove a public key from the Storj network. cb will be called with an Error if something goes wrong or null otherwise.

var encryptionKey = storj.generateEncryptionKey()

Create a new encryption key, which can be used to encrypt/decrypt files on the storj network. Certain operations, such as createFile, require that Storj was provided an encryption key when constructed. Keep track of this, as it will be necessary to retrieve your files in the future.

var key = storj.generateKeyPair().getPrivateKey();
var encryptionKey = storj.generateEncryptionKey();
var storj = new Storj({ key, encryptionKey });
// storj can now perform bucket operations and upload/download files

storj.createBucket(bucketName, function cb(e, meta) {})

Create's a bucket on the storj network with the requested name. cb will be invoked with an error if creating the bucket fails, otherwise meta will contain metadata for the bucket created.

meta has the following properties:

{
  id: String, // The bucket id of the newly created bucket
  name: String // the name of the newly created bucket
}

storj.getBucket(bucketId, function cb(e, meta) {})

Get the metadata for a bucket. cb will be invoked with an error if getting the meta-data fails, otherwise meta will have the following properties:

{
  id: String, // The id of the bucket
  name: String // The name of the bucket
}

storj.getBucketList(function cb(e, buckets) {})

Get a list of all buckets associated with the currently authenticated account on the storj network. cb will be invoked with an error if getting the list of buckets fails, or with an array of meta-data about the buckets. Each element of the buckets array will have the following properties:

{
  id: String, // the bucketID of the bucket
  name: String // the name of the bucket
}

storj.makePublic(bucketId, [perms], function cb(e) {})

Give public access to an existing bucket. cb will be passed an Error if something goes wrong, or undefined otherwise. perms should be an array of permission strings, currently supported permissions are:

  • PULL - Allow others to download from this bucket
  • PUSH - Allow users to upload to this bucket
storj.makePublic(bucketId, ["PULL", "PUSH"], function(e) {
  if(e) {
    /* Handle Error */
  }
  /* Bucket is now public with both pull and push permissions */
})

storj.deleteBucket(bucketId, function cb(e) {})

Remove a bucket from the Storj network. cb will be invoked with an error if the operation fails, or null otherwise.

var file = storj.createFile(bucketId, fileName, file, [opts], [function cb() {}])

Upload a file to a bucket.

bucketId - the id of the bucket that we will be uploading the file to (String) fileName - the name of the file we are uploading, with it's extension (String) file - the contents of the file and can be any of the following:

opts is optional, and allows you to specify some of the file's metadata:

{
  fileSize: Number, // Size of the file in bytes, required if `file` is a stream
}

cb is an optional function that will be registered as a listener on the returned File's done event.

var file = storj.getFile(bucketId, fileId, [function cb() {}])

bucketId - the id of the bucket the file lives in (String) fileId - the id of the file itself (String) cb - an optional function that will be registered as a listener for the done event on the returned file object

storj.getFileList(bucketId, function cb(e, files) {})

Get a list of files stored in a bucket on the Storj network. cb will be invoked with an Error first if the operation fails, or null otherwise. files will be an array of meta-data about the files, each element will have the following properties:

{
  id: String, // the id of the file
  name: String, // the name of the file
  mimetype: String // the mime-type of the file
}

storj.deleteFile(bucketId, fileId, function cb(e) {})

Remove a file from the Storj network. cb will be invoked with an Error first if the operation fails, or null otherwise.

File API

file.name

The name of the file.

file.mimetype

The mimetype of the file.

file.length

The length of the file in bytes.

file.progress

A number between 0 and 1 (inclusive) reflecting what percentage of the file has been downloaded from the network. To determine how many bytes have been downloaded, you can multiply file.length by file.progress.

file.on('done', function cb() {})

Emitted when a File has finished either uploading or downloading it's contents.

file.on('ready', function cb() {})

Emitted when the File has finished being setup and is ready to begin transfering data. You can listen for this event if you are planning on tracking the progress of an upload/download.

file.on('error', function cb(e) {})

Emitted when the File encounters an unrecoverable error either during setup or during upload/download. If this is emitted, it is safe to assume the File is in a corrupted state and the upload/download should be restarted from the beginning.

file.on('data', function cb(data) {})

Emitted when data has been downloaded from the network, this can be used for tracking the value of file.progress. The callback will be provided the chunk of data that was pulled over the network.

Note: This event is not yet implemented. Registering the data event will not throw an error, but the event will never be triggered. To track implementation progress, follow issue #72

file.createReadStream()

Create a readable stream to the file. Pieces of the file will become available from the stream as soon as they are downloaded from the network.

file.getBuffer(function cb(e, buffer) {})

Returns a Buffer representation of the file. If the file is downloading when getBuffer is called, the cb will be called with a Buffer as soon as the file finishes downloading.

file.appendTo(rootElem, [opts], [function cb(e, elem) {}]) (BROWSER ONLY)

Show the file in a the browser by appending it to the DOM. This is a powerful function that handles many file types like video (.mp4, .webm, .m4v, etc.), audio (.m4a, .mp3, .wav, etc.), images (.jpg, .gif, .png, etc.), and other file formats (.pdf, .md, .txt, etc.).

The file will be fetched from the network and streamed into the page (if it's video or audio). In some cases, video or audio files will not be streamable because they're not in a format that the browser can stream so the file will be fully downloaded before being played. For other non-streamable file types like images and PDFs, the file will be downloaded then displayed.

rootElem is a container element (CSS selector or reference to DOM node) that the content will be shown in. A new DOM node will be created for the content and appended to rootElem.

If provided, opts can contain the following options:

  • autoplay: Autoplay video/audio files (default: true)
  • controls: Show video/audio player controls (default: true)
  • maxBlobLength: Files above this size will skip the "blob" strategy and fail (default: 200 * 1000 * 1000 bytes)

If provided, callback will be called once the file is visible to the user. callback is called with an Error (or null) and the new DOM node that is displaying the content.

file.appendTo('#containerElement', function (err, elem) {
  if (err) throw err // file failed to download or display in the DOM
  console.log('New DOM node with the content', elem)
})

Streaming support depends on support for MediaSource API in the browser. All modern browsers have MediaSource support.

For video and audio, storj.js tries multiple methods of playing the file:

  • videostream -- best option, supports streaming with seeking, but only works with MP4-based files for now (uses MediaSource API)
  • mediasource -- supports more formats, supports streaming without seeking (uses MediaSource API)
  • Blob URL -- supports the most formats of all (anything the <video> tag supports from an http url), with seeking, but does not support streaming (entire file must be downloaded first)

The Blob URL strategy will not be attempted if the file is over opts.maxBlobLength (200 MB by default) since it requires the entire file to be downloaded before playback can start which gives the appearance of the <video> tag being stalled. If you increase the size, be sure to indicate loading progress to the user in the UI somehow.

For other media formats, like images, the file is just added to the DOM.

For text-based formats, like html files, pdfs, etc., the file is added to the DOM via a sandboxed <iframe> tag.

file.renderTo(rootElem, [opts], [function cb(e, elem) {}]) (BROWSER ONLY)

Like file.appendTo but renders directly into given element (or CSS selector).

file.getBlob(function cb(e, blob) {}) (BROWSER ONLY)

Get a W3C Blob object which contains the file data.

The file will be fetched from the network, and callback will be called once the file is ready. callback must be specified, and will be called with a an Error (or null) and the Blob object.

file.getBlobUrl(function cb(e, url) {}) (BROWSER ONLY)

Get a url which can be used in the browser to refer to the file.

The file will be fetched from the network and callback will be called once the file is ready. callback must be specified, and will be called with a an Error (or null) and the Blob URL (String).

This method is useful for creating a file download link, like this:

file.getBlobURL(function (err, url) {
  if (err) throw err
  var a = document.createElement('a')
  a.download = file.name
  a.href = url
  a.textContent = 'Download ' + file.name
  document.body.appendChild(a)
})

KeyPair API

var key = keypair.getPrivateKey()

Get the private key component of the KeyPair.

var key = keypair.getPublicKey()

Get the public key component of the KeyPair.

var signature = keypair.sign(message)

Sign a message with this key. message should be either a String or a Buffer, and the returned signature will be a String.

var id = keypair.getNodeID()

Get your client's NodeID on the Storj network, which is derived from this KeyPair.

var address = keypair.getAddress()

Return a bitcoin-format address derived from this KeyPair.

Low Level API

The Low Level API isn't actually that low level. The purpose of these methods is to provide tools that are useful when building production Storj.js applications, but that aren't necessary for casual development. These methods may expose primitives, and often sacrifice usability for perfomance.

Note: The Low Level API is not considered stable yet. Please do not develop against this API unless you are willing to deal with breaking changes in future releases. Until otherwise stated, minor and patch releases may ship breaking cheanges to this API.

var stream = storj.download(fileId, bucketId)

Return a readable stream of decrypted data being pulled directly from farmers. This method bypasses the File API entirely, and doesn't use a backend abstract-blob-store. If you only need to download a file once, and don't want to hold onto it in memory, this is the method for you.

storj.download(fileId, bucketId).pipe(fs.createWriteStream('cat.jpg'));

var stream = storj.upload(bucketId, fileName)

Return a writable stream. When written to, the data will be encrypted and uploaded to the storj network.

When it becomes available, stream will emit a done event. This event will contain the metadata for the uploaded file including:

{
  bucket: STRING, // bucketId
  filename: STRING,
  mimetype: STRING,
  id: STRING, // fileId
  size: NUMBER // Size of file on the network
}
fs.createReadStream('cat.jpg').pipe(
  storj.upload(fileId, bucketId)
).on('done', function(metadata) {
  console.log(`Uploading to id: ${metadata.id}`);
})

storj.getFilePointers(fileId, bucketId, function cb(e, pointers) {})

Get all of the information necessary to download a file from the Storj network. The callback will be inovked with an Error if something goes wrong, otherwise it will return an object of the form:

{
  token: [Object], // Information necessary to decrypt files from public buckets
  pointers: [Array] // Information necessary to find farmers with shards
}

While this method is currently exposed, there is no direct way of instructing the Storj.js API to use this when downloading a file from the network.

storj.js's People

Contributors

barbaraliau avatar cpollard1001 avatar dylanlott avatar nginnever avatar richardlitt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

storj.js's Issues

Need tests for browser functions

renderTo, appendTo, and blob operations do not have tests.

These tests should follow the same pattern as test/index.js, ideally named test/browser.js. Would prefer if the package.json handled figuring out which tests to run in which environment (i.e. node-test picks it's own tests and testling includes browser.js) as opposed to doing feature detection in the tests themselves.

Fix errors in README.MD

Note this particular portion in readme.md

var stream = storj.download(fileId, bucketId)

Return a readable stream of decrypted data being pulled directly from farmers. This method bypasses the File API entirely, and doesn't use a backend abstract-blob-store. If you only need to download a file once, and don't want to hold onto it in memory, this is the method for you.

storj.download(fileId, bucketId).pipe(fs.createWriteStream('cat.jpg'));

The correct function should be storj.download(bucketId,fileId)

Will someone with access fix it, too small for me to file a pull request

Document and support `getFilePointers`

Currently implemented in https://github.com/Storj/storj.js/blob/NewAPI/lib/api/get-file-pointers.js

This needs to be updated to match the new API, exposed as storj.getFilePointers, and documented in https://github.com/Storj/storj.js/blob/NewAPI/README.md

We should consider having getFile invoke getFilePointers as opposed to duplicating logic.

Long term, getFile should accept a pointers object which can be used to bypass the need for a client to talk to the bridge. This would allow a server to handle all bridge auth and allow clients to upload/download data directly from farmers, that way clients wouldn't need to handle private keys or mnemonics.

Implement getKeyList

Need a way of fetching a list of public keys currently stored on the bridge for a user. Needs tests and documentation.

Note, this is for keys uploaded via registerKey, not makePublic. To get keys registered via makePublic, use getBucket.

Firefox de-optimizes Buffer.concat

When streaming data from farmers, we use a lot of Buffer.concat operations to buffer up the file into memory. Firefox appears to be de-optimizing this function. Since all of the crypto logic is shared with the rest of the browser's thread, the user experience for downloading a large file is that their browser locks up until the browser pauses the script with a prompt.

Firefox User Experience:
snapshot1

Flamegraph:
snapshot1

You can see concat invocations (and descendant functions) are plateaus.

Function breakout:
snapshot1

Concat is the in call chain of >75% of the on-thread time for our script

UMD bundle exported as storj

We are exporting the browserified bundle as storj as opposed to Storj

Per the browserify documentation, it looks like the -s flag will automagically be camel cased, so switching to -s Storj may not be enough to properly export the constructor.

Unable to install storj via npm

'pkg-config' is not recognized as an internal or external command,
operable program or batch file.
Unable to download libstorj for platform: win32 and arch: x64
npm WARN [email protected] requires a peer of ajv@^6.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of @types/googlemaps@^3.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of @types/markerclustererplus@^2.1.29 but none is installed. You must install peer dependencies yourself.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] preinstall: node ./download.js
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] preinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\Caprice\AppData\Roaming\npm-cache_logs\2018-08-24T06_31_30_970Z-debug.log

Tracking upload progress

Currently, core does not expose a way to track the upload progress of a file, which prevents storj.js from emitting on('data' events and updating file.progress.

Things to think about:

  • If a file is being uploaded across multiple shards concurrently, the order in which chunks of data are emitted via the data event may not match the order of those chunks in the file. What implications does this carry for userland?
  • When do we emit a data event? When we finish encrypting the chunk, when we send the data over the wire, when we get confirmation that the farmer received that data, etc? What implications will the timing of the data event carry for userland?

Storj.js blocks webpage

Storj.js is CPU heavy compared to most JS on the web. This creates a less-than-ideal user experience in many browsers.

The solution is Web Workers, but we need a little more exploration before we jump to an implementation.

Constraints:

  • Multiple shards should be able to be decrypted simultaneously for the same file. (Web Worker pool)
  • User shouldn't have to pass in a URL to their local storj.js script when initializing. (Should construct a blob via a string containing the JS, pull it's URL, and use that to initialize the Web Worker)
  • Should implement a streaming interface.

Update docs for `keypair.sign(message)`

Default when signing is { compact: true }. I've found that this needs to be { compact: false } in order to generate the correct signature.

Suggested change to lines 395-397 in README.md:

var signature = keypair.sign(message, [opts])
Sign a message with this key. message should be either a String or a Buffer, and the returned signature will be a String. Default options is { compact: true }.

or

var signature = keypair.sign(message, { compact: false })
Sign a message with this key. message should be either a String or a Buffer, and the returned signature will be a String. Default options is { compact: true }.

Keypair Docs

KeyPair.prototype.sign = function(message, options) {
  var sign = null;
  var opts = merge({ compact: true }, options);

  if (opts.compact) {
    sign = Message(message).sign(this._privkey);
  } else {
    if (!Buffer.isBuffer(message)) {
      message = new Buffer(message, 'utf8');
    }

    sign = ecdsa.sign(
      crypto.createHash('sha256').update(message).digest('hex'),
      this.getPrivateKey()
    ).toDER('hex');
  }

`generateMnemonic` should be aliased to `Storj.generateMnemonic`

Requiring that a user instantiate an entire storj object just to generate a mnemonic is silly.

Same for generateKeyPair although registering the keypair still requires auth.

The use case for generateKeyPair isn't there. If you aren't authenticated against the bridge, having generateKeyPair doesn't offer anything. Just focusing on mnemonic for now.

Storj `ready` event not being emitted

The documentation calls for a ready event to be emitted off of the Storj object during setup.

Currently there isn't any async setup necessary. In the original design of this API, there was a round trip for auth validation during setup. We decided to keep the async constructor for forward support of async operations during setup.

We can either:

A) drop the ready event and risk having to make a breaking change in the future
B) implement the ready event

I'm ๐Ÿ‘ on (B)

Browserified Library Not Defined

I've made a browserified version of Storj.js using:

browserify lib/ -o storj.js

and when including it into the HTML like this:

<script src="storj.js"></script>

I get this error:

Uncaught ReferenceError: Storj is not defined
    at index.html:68

Here is the layout of my files:

storj-client
    |-- index.html
    `-- storj.js

Am I doing anything wrong or does it just not work?

mnemonic -> encryptionKey

libstorj has migrated to referring to the mnemonic as an encryptionKey (since we use it to derive the key used to encrypt/decrypt files).

Storj.js should follow suite.

File API methods should be safe to call before `ready`

Since the methods that operate on the file are either stream or callback based, they should be safe to call before the file enters into a ready state.

Callback based functions should either callback with an error if the file object errors before ready is emitted, or should invoke their callback as soon as they have the data necessary to complete the request.

Stream based functions should return a stream immediately. The stream should error when file errors, and should provide data as soon as it becomes readable. NOTE: The stream emitting an error should not save a file object from throwing an unhandled error if the user does not register an error listener directly on the file object. In a similar manner, a readable stream coming from a file should not block the file from downloading it's data from a farmer into a blob store. I.E. calling createReadStream and not consuming data from it should not fill the TCP socket's stream's internal buffer, data should still be able to flow into the underlying blob store.

  • getBuffer
  • getBlob
  • getBlobUrl
  • appendTo
  • renderTo
  • getReadStream

Error: Cannot find module 'storj'

Just tried to install and use:

npm install --save storj

test.js:

const Storj = require('storj');

Run:

truffle test

Output:

Error: Cannot find module 'storj'
    at Function.Module._resolveFilename (module.js:513:15)
    at Function.Module._load (module.js:463:25)
    at Module.require (module.js:556:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/Users/k06a/Projects/pre-alpha-base-contract/test/BaseContract.js:16:15)
    at Module._compile (module.js:612:30)
    at loader (/Users/k06a/Projects/pre-alpha-base-contract/node_modules/babel-register/lib/node.js:144:5)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/k06a/Projects/pre-alpha-base-contract/node_modules/babel-register/lib/node.js:154:7)
    at Module.load (module.js:531:32)
    at tryModuleLoad (module.js:494:12)

More than one instance of bitcore-lib

When browserifying the latest commits I get this error initially destroying the storj module.

Uncaught Error: More than one instance of bitcore-lib found. Please make sure to require bitcore-lib and check that submodules do not also include their own bitcore-lib dependency.

Bitcore lib has a version gaurd coded into that won't allow submodules to require it.

Storj core already requires bitcore-lib so when it is required for the Mnemonic in storj.js it is interfering. The simple fix is to generate a utility in core and require that through storj.js.

Or have storj-crypto module which started as a shim to allow webcrypto (which it cant do) contain all of the crypto modules so we don't run into this again.

Reduce size of final bundle

The file sizes for storj.es5.js and storj.es6.js are both quite large (several MBs). We should pipe them through uglify or something similar to reduce their final size.

Note: we need to maintain our sourcemaps when doing the transform.

BridgeClient library

From @dylanlott at cpollard1001/storj.js#2

After trying to merge in billing changes to Bridge-GUI today and realizing that it's not going to (easily or consistently) work with the most recent storj-lib versions, it is most likely going to be come necessary to pull bridge client out of core, or create a better browser-only library for talking to Bridge instead of using the BridgeClient in storj-lib.

I've started work on this, but wanted to open up a thread for discussion between all parties already involved, since I saw that Storj.js requires a BridgeClient to work as well.

Any thoughts or ideas on this before we get too far in on it? I'm scaffolding out the library right now, and will be working on it tomorrow with @bryanchriswhite

Improve debugging story for Browser

Currently stack traces look like this:

12:44:29.966 Error: Not enough entropy. Minimum is: 192 bits
assert() storj.js:6377
HmacDRBG() storj.js:6373
sign() storj.js:6359
[528]</</KeyPair.prototype.sign() storj.js:20111
[521]</</BridgeClient.prototype._authenticate() storj.js:19978
_request() storj.js:19970
retryAttempt() storj.js:3004
retry() storj.js:3004
[521]</</BridgeClient.prototype._request() storj.js:19970
[521]</</BridgeClient.prototype.createToken() storj.js:19823
createFile() storj.js:8
upload() 03:19
onchange() 03:1
1 storj.js:6377:26596

Looking at storj.js:6377 gives us:
snapshot1

This is hardly useful. Having dev bundles with source maps and un-minified source would help a lot.

Error on upload: Not Enough Entropy

Stack trace:

12:44:29.966 Error: Not enough entropy. Minimum is: 192 bits
assert() storj.js:6377
HmacDRBG() storj.js:6373
sign() storj.js:6359
[528]</</KeyPair.prototype.sign() storj.js:20111
[521]</</BridgeClient.prototype._authenticate() storj.js:19978
_request() storj.js:19970
retryAttempt() storj.js:3004
retry() storj.js:3004
[521]</</BridgeClient.prototype._request() storj.js:19970
[521]</</BridgeClient.prototype.createToken() storj.js:19823
createFile() storj.js:8
upload() 03:19
onchange() 03:1
1 storj.js:6377:26596

In browser when uploading.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.