hypercore-signing-request 3.1.2 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +6 -2
  2. package/index.js +118 -30
  3. package/package.json +4 -2
package/README.md CHANGED
@@ -16,10 +16,14 @@ const { generate, decode, signable } = require('hypercore-signing-request')
16
16
 
17
17
  ## API
18
18
 
19
- #### `requestBuffer = await generate(core, { length = core.length })`
19
+ #### `requestBuffer = await generate(coreOrDrive, { length = core.length })`
20
20
 
21
21
  Generate a signing request, returned as a buffer so it can be shared.
22
- Only works for non-compat cores (ie manifest backed)
22
+ Only works for non-compat cores (ie manifest backed).
23
+
24
+ Alternatvely a Hyperdrive can be passed and a joint request for signing both metadata and blob cores will be generated.
25
+ Only works for v1 manifest backed Hyperdrives.
26
+
23
27
 
24
28
  #### `req = decode(requestBuffer)`
25
29
 
package/index.js CHANGED
@@ -1,10 +1,12 @@
1
1
  const HypercoreID = require('hypercore-id-encoding')
2
+ const Hyperdrive = require('hyperdrive')
2
3
  const Verifier = require('hypercore/lib/verifier')
3
4
  const caps = require('hypercore/lib/caps')
4
5
  const m = require('hypercore/lib/messages')
5
6
  const c = require('compact-encoding')
6
7
 
7
- const VERSION = 1
8
+ const VERSION = 2
9
+ const FLAG_DRIVE = 1
8
10
 
9
11
  const Request = {
10
12
  preencode (state, req) {
@@ -13,6 +15,13 @@ const Request = {
13
15
  c.uint.preencode(state, req.fork)
14
16
  c.fixed32.preencode(state, req.treeHash)
15
17
  m.manifest.preencode(state, req.manifest)
18
+
19
+ c.uint.preencode(state, 0) // flags
20
+
21
+ if (req.content) {
22
+ c.uint.preencode(state, req.content.length)
23
+ c.fixed32.preencode(state, req.content.treeHash)
24
+ }
16
25
  },
17
26
  encode (state, req) {
18
27
  c.uint.encode(state, req.version)
@@ -20,10 +29,19 @@ const Request = {
20
29
  c.uint.encode(state, req.fork)
21
30
  c.fixed32.encode(state, req.treeHash)
22
31
  m.manifest.encode(state, req.manifest)
32
+
33
+ let flags = 0
34
+ if (req.content) flags |= FLAG_DRIVE
35
+ c.uint.encode(state, flags)
36
+
37
+ if (req.content) {
38
+ c.uint.encode(state, req.content.length)
39
+ c.fixed32.encode(state, req.content.treeHash)
40
+ }
23
41
  },
24
42
  decode (state) {
25
43
  const version = c.uint.decode(state)
26
- if (version !== VERSION) throw new Error('Unknown signing request version: ' + version)
44
+ if (version > VERSION) throw new Error('Unknown signing request version: ' + version)
27
45
 
28
46
  const length = c.uint.decode(state)
29
47
  const fork = c.uint.decode(state)
@@ -33,6 +51,18 @@ const Request = {
33
51
  const key = Verifier.manifestHash(manifest)
34
52
  const id = HypercoreID.normalize(key)
35
53
 
54
+ const flags = state.start !== state.end ? c.uint.decode(state) : 0
55
+
56
+ let content = null
57
+
58
+ const isHyperdrive = flags & FLAG_DRIVE
59
+ if (isHyperdrive) {
60
+ content = {
61
+ length: c.uint.decode(state),
62
+ treeHash: c.fixed32.decode(state)
63
+ }
64
+ }
65
+
36
66
  return {
37
67
  version,
38
68
  id,
@@ -40,43 +70,101 @@ const Request = {
40
70
  length,
41
71
  fork,
42
72
  treeHash,
43
- manifest
73
+ manifest,
74
+ isHyperdrive,
75
+ content
44
76
  }
45
77
  }
46
78
  }
47
79
 
48
80
  module.exports = {
49
- async generate (core, { length = core.length, fork = core.fork, manifest = null } = {}) {
50
- if (!core.opened) await core.ready()
81
+ generate,
82
+ generateDrive,
83
+ decode,
84
+ signable
85
+ }
51
86
 
52
- if (core.core.compat && !manifest) throw new Error('Cannot generate signing requests for compat cores')
53
- if (!manifest) manifest = core.manifest
87
+ async function generate (core, { length = core.length, fork = core.fork, manifest = null } = {}) {
88
+ if (!core.opened) await core.ready()
54
89
 
55
- return c.encode(Request, {
56
- version: VERSION,
57
- length,
58
- fork,
59
- treeHash: await core.treeHash(length),
60
- manifest
61
- })
62
- },
63
- decode (buffer) {
64
- const state = { start: 0, end: buffer.byteLength, buffer }
65
- const req = Request.decode(state)
90
+ if (core.blobs) return generateDrive(core, { length, fork, manifest })
66
91
 
67
- if (req.length === 0) throw new Error('Refusing to sign length = 0')
68
- if (state.start < state.end) throw new Error('Unparsed padding left in request, bailing')
92
+ if (core.core.compat && !manifest) throw new Error('Cannot generate signing requests for compat cores')
93
+ if (!manifest) manifest = core.manifest
69
94
 
70
- return req
71
- },
72
- signable (pub, req) {
73
- const v = req.manifest.version
74
- for (const s of req.manifest.signers) {
75
- if (s.publicKey.equals(pub)) {
76
- return caps.treeSignable(v === 0 ? s.namespace : req.key, req.treeHash, req.length, req.fork)
77
- }
78
- }
95
+ return c.encode(Request, {
96
+ version: VERSION,
97
+ length,
98
+ fork,
99
+ treeHash: await core.treeHash(length),
100
+ manifest,
101
+ content: null
102
+ })
103
+ }
104
+
105
+ async function generateDrive (drive, { length = drive.core.length, fork = drive.core.fork, manifest = null }) {
106
+ if (drive.core.core.compat && !manifest) throw new Error('Cannot generate signing requests for compat cores')
79
107
 
80
- throw new Error('Public key is not a declared signer for this request')
108
+ if (!manifest) manifest = drive.core.manifest
109
+ if (manifest < 1) throw new Error('Only v1 manifests are supported')
110
+
111
+ const last = await drive.db.getBySeq(length - 1)
112
+ const { blockOffset, blockLength } = last.value.blob
113
+
114
+ const contentLength = blockOffset + blockLength
115
+ const content = {
116
+ length: contentLength,
117
+ treeHash: await drive.blobs.core.treeHash(contentLength)
118
+ }
119
+
120
+ return c.encode(Request, {
121
+ version: VERSION,
122
+ length,
123
+ fork,
124
+ treeHash: await drive.core.treeHash(length),
125
+ manifest,
126
+ content
127
+ })
128
+ }
129
+
130
+ function decode (buffer) {
131
+ const state = { start: 0, end: buffer.byteLength, buffer }
132
+ const req = Request.decode(state)
133
+
134
+ if (req.length === 0) throw new Error('Refusing to sign length = 0')
135
+ if (state.start < state.end) throw new Error('Unparsed padding left in request, bailing')
136
+
137
+ return req
138
+ }
139
+
140
+ function signable (pub, req) {
141
+ const v = req.manifest.version
142
+
143
+ for (let signer = 0; signer < req.manifest.signers.length; signer++) {
144
+ const s = req.manifest.signers[signer]
145
+ if (!s.publicKey.equals(pub)) continue
146
+
147
+ if (req.isHyperdrive) return driveSignable(pub, req, signer)
148
+
149
+ const signable = caps.treeSignable(v === 0 ? s.namespace : req.key, req.treeHash, req.length, req.fork)
150
+
151
+ return [{ signer, signable }]
152
+ }
153
+
154
+ throw new Error('Public key is not a declared signer for this request')
155
+ }
156
+
157
+ function driveSignable (pub, req, signer) {
158
+ const contentKey = Hyperdrive.getContentKey(req.manifest)
159
+ if (!contentKey) {
160
+ throw new Error('Drive is not compatible, needs v1 manifest')
81
161
  }
162
+
163
+ const signable = caps.treeSignable(req.key, req.treeHash, req.length, req.fork)
164
+ const content = caps.treeSignable(contentKey, req.content.treeHash, req.content.length, req.fork)
165
+
166
+ return [
167
+ { signer, signable },
168
+ { signer, signable: content }
169
+ ]
82
170
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hypercore-signing-request",
3
- "version": "3.1.2",
3
+ "version": "4.0.1",
4
4
  "description": "Generate shareable signing requests for Hypercore",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -12,7 +12,8 @@
12
12
  "dependencies": {
13
13
  "compact-encoding": "^2.13.0",
14
14
  "hypercore": "^10.32.8",
15
- "hypercore-id-encoding": "^1.2.0"
15
+ "hypercore-id-encoding": "^1.2.0",
16
+ "hyperdrive": "^11.8.1"
16
17
  },
17
18
  "repository": {
18
19
  "type": "git",
@@ -26,6 +27,7 @@
26
27
  "homepage": "https://github.com/holepunchto/hypercore-signing-request",
27
28
  "devDependencies": {
28
29
  "brittle": "^3.4.0",
30
+ "corestore": "^6.17.0",
29
31
  "random-access-memory": "^6.2.0",
30
32
  "standard": "^17.1.0"
31
33
  }