Skip to content
This repository has been archived by the owner on Jul 24, 2024. It is now read-only.

Commit

Permalink
Merge branch 'master' into fix/rpc-relay
Browse files Browse the repository at this point in the history
  • Loading branch information
Nuhvi authored Jul 3, 2023
2 parents e624cd5 + 042d555 commit b1a3414
Show file tree
Hide file tree
Showing 18 changed files with 164 additions and 678 deletions.
4 changes: 3 additions & 1 deletion declarations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ declare module 'hypercore' {
sign?: (message: Uint8Array) => Uint8Array;
verify: (message: Uint8Array, signature: Uint8Array) => boolean;
}
export = class Hypercore extends EventEmitter<'close'> {
class Hypercore extends EventEmitter<'close'> {
constructor(storage: any, key?: Opts | Uint8Array, opts?: Opts);

length: number;
Expand Down Expand Up @@ -443,6 +443,8 @@ Populated after ready has been emitted. Will be null before the event.

sessions: Hypercore[];
};

export = Hypercore
}

// file://./node_modules/hyperblobs/index.js
Expand Down
96 changes: 45 additions & 51 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 0 additions & 52 deletions packages/drive/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,3 @@

[DEPRECATED] use `@synonymdev/slashtags-core-data` instead.

Drivestore is a Hyperdrive factory that makes it easier to manage large collections of named Hyperdrives.

## Features

- Public unencrypted drive
- Creates and keep track of all created encrypted private drives

## Installation

```
npm install @synonymdev/slashdrive
```

## Usage

```js
import Corestore from 'corestore'
import Drivestore from '@synonymdev/slashdrive'

const corestore = new Corestore('./corestore_dir')
const store = new Drivestore(corestore, keyPair)

const publicDrive = store.get('public') // or store.get()

const privateDrive = store.get('foo') // returns an encrypted Hyperdrive
```

## API

#### `const drivestore = new Drivestore(corestore, keyPair)`

Create new Drivestore.

- `corestore` must be an instance of [Corestore](https://github.com/hypercore-protocol/corestore).

If the instance is a [namespace](https://github.com/hypercore-protocol/corestore#const-store--storenamespacename), the internal corestore will reset its namespace to the `DEFAULT_NAMESPACE` (32 0-bytes).

- `keyPair` public and secret keys to create the public Hyperdrive, the secret key will be used as the `primaryKey` for the internal corestore.

#### `await drivestore.ready()`

Awaits opening metadata hypercore. Useful before [async iterating](#for-await-let-name-of-drivestore) over all created drives.

#### `const hyperdrive = drivestore.get([name])`

Returns an encrypted [Hyperdrive](https://github.com/hypercore-protocol/hyperdrive-next) for a given name.

If `name` is undefined or equal to `/public` it will return a public unencrypted drive, by the same keypair passed to the contsructor.

#### `const stream = drivestore.replicate(stream)`

Same as [drivestore.corestore.replicate(stream)](https://github.com/hypercore-protocol/corestore#const-stream--storereplicateoptsorstream)
97 changes: 11 additions & 86 deletions packages/drive/index.js
Original file line number Diff line number Diff line change
@@ -1,55 +1,25 @@
const Hyperdrive = require('hyperdrive')
const Hyperbee = require('hyperbee')
const b4a = require('b4a')
const safetyCatch = require('safety-catch')

const METADATA_KEY = 'slashtags-drivestore-metadata'

class Drivestore {
/**
* @param {import('corestore')} corestore
* @param {import('hyperdht').KeyPair} keyPair
* @param {import('@synonymdev/slashtags-core-data')} coreData
*/
constructor (corestore, keyPair) {
this.fava = Math.random()
this.keyPair = keyPair
/** @type {import('corestore')} */
this.corestore = corestore.session({ primaryKey: this.keyPair.secretKey, namespace: null })

const metadataCore = this.corestore.get({
name: METADATA_KEY,
encryptionKey: this.keyPair.secretKey
})
this._metadata = new Hyperbee(metadataCore, { keyEncoding: 'utf8' })
this._drives = this._metadata.sub('drives')

this._opening = this._open().catch(safetyCatch)
constructor (coreData) {
this._coreData = coreData
this.corestore = this._coreData._corestoreSession
}

/** @returns {import('hyperbee').Iterator<{name: string}>} */
/**
* @deprecated
*/
[Symbol.asyncIterator] () {
if (!this.opened) return emptyIterator
const iterator = this._drives.createReadStream()[Symbol.asyncIterator]()
return {
async next () {
const node = await iterator.next()
const value = node.value
return { done: node.done, value: value && { name: value.key } }
}
}
return new Error('not supported')
}

get closed () {
return this.corestore._root._closing
}

async _open () {
await this._drives.feed.ready()
this.opened = true
return this.corestore._root.closing
}

ready () {
return this._opening
return this._coreData.ready()
}

/** @param {Parameters<import('corestore')['replicate']>} args */
Expand All @@ -61,53 +31,8 @@ class Drivestore {
* Get a Hyperdrive by its name.
*/
get (name = 'public') {
validateName(name)
const ns = this.corestore.namespace(name).session({ primaryKey: this.keyPair.secretKey })
const _preload = ns._preload.bind(ns)
ns._preload = (opts) => this._preload.bind(this)(opts, _preload, ns, name)
return new Hyperdrive(ns)
return this._coreData._getLocalDrive(name)
}

/**
* Set the correct and current key and encryption Key (enables future key rotation)
* @param {Parameters<import('corestore')['get']>[0]} opts
* @param {*} preload orginal ns._preload
* @param {import('corestore')} ns
* @param {string} name
* @returns {Promise<any>}
*/
async _preload (opts, preload, ns, name) {
const isPublic = name === 'public'

// Get keyPair programatically from name
const { from } = await preload(opts)

// public drive needs no encryption
// No need currently to save a record about the public drive
if (isPublic) {
if (opts.name !== 'db') return { from }
const session = this.corestore.get({ keyPair: this.keyPair })
await session.ready()
return { from: session }
}

this._drives.ready().then(async () => {
const saved = await this._drives.get(name)
if (!saved) await this._drives.put(name, b4a.from(''))
// TODO enable key rotation, where we overwrite keys, or use saved ones.
// TODO block closing drivestore before this update is flushed
})

// Add encryption keys for non public drives
return { from, encryptionKey: ns._namespace }
}
}

/** @param {string} name */
function validateName (name) {
if (!/^[0-9a-zA-Z-._ ]*$/.test(name)) throw new Error('Invalid drive name')
}

const emptyIterator = { async next () { return { done: true, value: null } } }

module.exports = Drivestore
10 changes: 2 additions & 8 deletions packages/drive/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,12 @@
"types",
"!**/*.tsbuildinfo"
],
"dependencies": {
"b4a": "^1.6.0",
"corestore": "^6.2.1",
"hyperbee": "^2.0.1",
"hyperdrive": "^11.0.0-alpha.5",
"safety-catch": "^1.0.2"
},
"devDependencies": {
"@synonymdev/slashtags-core-data": "^1.0.0-alpha.9",
"b4a": "^1.6.4",
"brittle": "^3.0.2",
"depcheck": "^1.4.3",
"hypercore-crypto": "^3.3.0",
"random-access-memory": "^5.0.1",
"standard": "^17.0.0",
"typescript": "^4.8.2"
}
Expand Down
Loading

0 comments on commit b1a3414

Please sign in to comment.