Commit 610dca323ebed504839ca715b11cf37b356ccacf
adds
Tree committed on 1/16/2017, 6:44:33 AMParent: 55f21298275dc4e89f0fcfba863e3849603cc0c8
Files changed
index.js | changed |
package.json | changed |
bot.js | added |
core/index.js | added |
test.js | added |
index.js | ||
---|---|---|
@@ -1,142 +1,64 @@ | ||
1 | -var secretStack = require('secret-stack') | |
2 | -var keys = require('./keys.json') | |
3 | - | |
4 | -var mdns = require('bonjour')() | |
5 | - | |
1 … | +var secretStack =require('secret-stack') | |
6 | 2 … | var sublevel = require('level-sublevel') |
7 | -var memdb = sublevel(require('memdb')()) | |
3 … | +var hyperlog = require('hyperlog') | |
4 … | +var swarmlog = require('swarmlog') | |
8 | 5 … | |
9 | -var hyperlog = require('hyperlog') | |
10 | 6 … | var pull = require('pull-stream') |
11 | - | |
12 | 7 … | var str2ps = require('stream-to-pull-stream') |
13 | 8 … | |
14 | -var selfAdress | |
9 … | +var keer = require('ssb-keys') | |
10 … | +var ws = require('ssb-ws') | |
15 | 11 … | |
16 | -//var ft = require('../ssb-fulltext') | |
12 … | +module.exports = function(bot){ | |
17 | 13 … | |
18 | -var node | |
14 … | + var self = bot // u kno, u wrong! | |
15 … | + var memdb = bot.db // db.sublevel(...) | |
16 … | + var keys = bot.keys | |
17 … | + bot.log = hyperlog(memdb.sublevel(bot.keys.id)) | |
18 … | + var node | |
19 | 19 … | |
20 | -manifest= { | |
21 | - greet: 'async', | |
22 | - createLog: 'duplex', | |
23 | - requestPublicKey: 'async', | |
24 | - netcast: 'duplex' | |
25 | -} | |
26 | - | |
27 | -var createApp = secretStack({ | |
28 | - appKey: new Buffer('00000000000000000000000000000000'), | |
29 | - timers: { | |
30 | - inactivity: 0, | |
31 | - handshake: 0 | |
20 … | + var errLogDB = hyperlog(memdb.sublevel(bot.id + ':errLog')) | |
21 … | + | |
22 … | + var errLog = function(cb){ | |
23 … | + return function(err, data){ | |
24 … | + if(err){ // drop it in the log | |
25 … | + errLogDB.append(JSON.stringify(err)) | |
26 … | + } | |
27 … | + else if(cb) cb(data) | |
28 … | + } | |
32 | 29 … | } |
33 | -}).use({ | |
34 | - name: 'spot', | |
35 | - manifest: manifest , | |
36 | - permissions: { | |
37 | - anonymous: ['greet', 'createLog', 'netcast'] | |
38 | - }, | |
39 | - init: function(api, opts){ | |
40 | - var rpc = { | |
41 | - 'netcast': function(mesg){ | |
42 | - | |
43 | - var distance = mesg.distance || 0 | |
44 | - | |
45 | - var log = hyperlog(memdb.sublevel('netcast')) | |
46 | - var local = str2ps.duplex(log.replicate({live:true}), function(err){ | |
47 | - //console.log('remote error or completion?', err) | |
48 | - }) | |
49 | - | |
50 | - console.log(mesg) | |
51 | 30 … | |
52 | - log.add(mesg.head || undefined, JSON.stringify(Object.keys(node.peers)), function(err, doc){ | |
53 | 31 … | |
54 | - console.log(doc) | |
55 | - | |
56 | - mesg.distance-- | |
57 | - mesg.auth = node.address() | |
58 | - mesg.head = doc.key | |
32 … | + var createApp = secretStack({ | |
33 … | + appKey: bot.appKey || new Buffer('00000000000000000000000000000000'), | |
34 … | + timers: { | |
35 … | + inactivity: 0, | |
36 … | + handshake: 0 | |
37 … | + } | |
38 … | + }).use(require('./core/')) | |
39 … | + //.use(ws) | |
59 | 40 … | |
60 | - if(distance < 0) //??? | |
41 … | + node = createApp({ | |
42 … | + keys: keys, | |
43 … | + errLogDB: errLogDB, | |
44 … | + errLogger: errLog, | |
45 … | + log: bot.log, | |
46 … | + db: memdb, | |
47 … | + self: bot, | |
48 … | + name: bot.name | |
49 … | + }) | |
50 … | + //console.log(node, node.address()) | |
51 … | + bot.do = {} | |
52 … | + node.auth.hook(function(auth, args){ | |
53 … | + var bot = args[0] | |
54 … | + var cb = args[1] | |
55 … | + auth(bot, function(err, perms){ | |
56 … | + //console.log(perms) | |
57 … | + cb(null, {'sign':true, 'log': true}) | |
58 … | + }) | |
59 … | + }) | |
60 … | + Object.assign(bot.do, node.dexbot) | |
61 | 61 … | |
62 | - Object.keys(node.peers).forEach(function(peer){ | |
63 | - if(distance > 0 && !(mesg.publicKey === peer)){ | |
64 | - remote = peer.spot.netcast(mesg) | |
65 | - pull(local, remote, local) | |
66 | - log.on('add', function(data){ | |
67 | - console.log(data.toString()) | |
68 | - }) | |
69 | - } | |
70 | - }) | |
71 | - | |
72 | - }) | |
62 … | + return bot | |
73 | 63 … | |
74 | - return local | |
75 | - }, | |
76 | - 'createLog': function(name){ | |
77 | - var log = hyperlog(memdb.sublevel(name)) | |
78 | - console.log(node.peers, opts.self) | |
79 | - | |
80 | - var stream = str2ps.duplex(log.replicate({live:true}), function(err){ | |
81 | - //console.log('remote error or completion?', err) | |
82 | - }) | |
83 | - setInterval(function(){ | |
84 | - log.add(null, Math.random().toString(2) + process.argv[2], function(err, msg){ | |
85 | - if(err) console.log(err) | |
86 | - }) | |
87 | - },1511) | |
88 | - return stream | |
89 | - }, | |
90 | - 'greet': function(cb){ | |
91 | - cb(null, 'GREETINGS') | |
92 | - } | |
93 | - } | |
94 | - return rpc | |
95 | - } | |
96 | -}) | |
97 | -//.use(ft) | |
98 | - | |
99 | - | |
100 | -node = createApp({ | |
101 | - keys: keys, | |
102 | - db: memdb, | |
103 | - self: node | |
104 | -}) | |
105 | -var record = { | |
106 | - type: 'spot', | |
107 | - port: 12111, | |
108 | - name: process.argv[2], | |
109 | - host: node.getAddress() | |
110 | 64 … | } |
111 | -mdns.publish(record) | |
112 | -mdns.find({type: 'spot'}, function(service){ | |
113 | - if(service.host === node.getAddress()) return | |
114 | - else{ | |
115 | - node.connect(service.host, function(err, rpc){ | |
116 | - if(err) console.log(err) | |
117 | - rpc.manifest(function(err, data){ | |
118 | -// console.log(err, data) | |
119 | - }) | |
120 | - rpc.spot.greet(function(err, greets){ | |
121 | - console.log(greets) | |
122 | - }) | |
123 | - var log = hyperlog(memdb.sublevel()) | |
124 | - var local = str2ps.duplex(log.replicate({live : true}), function(err){ | |
125 | - //console.log('local err or ending?', err) | |
126 | - }) | |
127 | - var remote = rpc.spot.netcast({ | |
128 | - distance: 3, | |
129 | - head: null, | |
130 | - author: '1234567890' | |
131 | - }) | |
132 | - var x | |
133 | - pull(local, remote, local) | |
134 | - | |
135 | - log.on('add', function(data){ | |
136 | - console.log(data.value.toString()) | |
137 | - }) | |
138 | - }) | |
139 | - } | |
140 | -}) | |
141 | - | |
142 | - |
package.json | ||
---|---|---|
@@ -1,6 +1,6 @@ | ||
1 | 1 … | { |
2 | - "name": "spot", | |
2 … | + "name": "dexbot", | |
3 | 3 … | "version": "1.0.0", |
4 | 4 … | "description": "this lib needed for avahi for node module mdns: `libavahi-compat-libdnssd-dev`", |
5 | 5 … | "main": "index.js", |
6 | 6 … | "scripts": { |
@@ -11,15 +11,20 @@ | ||
11 | 11 … | "author": "", |
12 | 12 … | "license": "ISC", |
13 | 13 … | "dependencies": { |
14 | 14 … | "bonjour": "^3.5.0", |
15 … | + "cat-names": "^1.0.2", | |
16 … | + "dns-discovery": "^5.6.0", | |
15 | 17 … | "hyperlog": "^4.11.0", |
16 | 18 … | "level-sublevel": "^6.6.1", |
17 | 19 … | "memdb": "^1.3.1", |
18 | 20 … | "pull-stream": "^3.5.0", |
19 | 21 … | "secret-stack": "^3.2.0", |
22 … | + "secure-scuttlebutt": "^15.5.1", | |
20 | 23 … | "ssb-keys": "^7.0.3", |
21 | - "stream-to-pull-stream": "^1.7.2" | |
24 … | + "ssb-ws": "^1.0.1", | |
25 … | + "stream-to-pull-stream": "^1.7.2", | |
26 … | + "swarmlog": "^1.4.0" | |
22 | 27 … | }, |
23 | 28 … | "devDependencies": {}, |
24 | 29 … | "repository": { |
25 | 30 … | "type": "git", |
bot.js | ||
---|---|---|
@@ -1,0 +1,17 @@ | ||
1 … | +var sublevel = require('level-sublevel') | |
2 … | +var memdb = sublevel(require('memdb')()) | |
3 … | +var namegen = require('cat-names') | |
4 … | +var keygen = require('ssb-keys').generate | |
5 … | + | |
6 … | +module.exports = function(){ | |
7 … | + var keys = keygen() | |
8 … | + var name = namegen.random() | |
9 … | + var bot = require('./')({ | |
10 … | + keys: keys, | |
11 … | + name: name, | |
12 … | + db: memdb.sublevel(keys.public) | |
13 … | + }) | |
14 … | + return bot | |
15 … | +} | |
16 … | + | |
17 … | +//module.exports() |
core/index.js | ||
---|---|---|
@@ -1,0 +1,208 @@ | ||
1 … | +var mdns = require('bonjour')() | |
2 … | +var dnsdisco = require('dns-discovery') | |
3 … | + | |
4 … | +var keer = require('ssb-keys') | |
5 … | +var hyperlog = require('hyperlog') | |
6 … | +var swarmlog = require('swarmlog') | |
7 … | +var pull = require('pull-stream') | |
8 … | +var str2ps = require('stream-to-pull-stream') | |
9 … | + | |
10 … | + | |
11 … | +var $ = module.exports = {} | |
12 … | + | |
13 … | +$.name = 'dexbot' | |
14 … | + | |
15 … | +$.manifest = { | |
16 … | + onConnect: 'async', | |
17 … | + greet: 'async', | |
18 … | + createLog: 'duplex', | |
19 … | + requestPublicKey: 'async', | |
20 … | + netcast: 'duplex', | |
21 … | + bonjour: 'source', | |
22 … | + connect: 'async', | |
23 … | + swarmLog: 'duplex', | |
24 … | + stderr: 'source', | |
25 … | + greeting: 'async', | |
26 … | + sign: 'async', | |
27 … | + replicate: { | |
28 … | + 'push': 'sink', | |
29 … | + 'pull': 'source', | |
30 … | + 'sync': 'duplex' | |
31 … | + }, | |
32 … | + log: { | |
33 … | + 'updates' : 'source', | |
34 … | + 'heads' : 'async', | |
35 … | + 'headStream' : 'source', | |
36 … | + 'add' : 'async', | |
37 … | + 'get' : 'async', | |
38 … | + 'append': 'async', | |
39 … | + 'batch': 'async' | |
40 … | + } | |
41 … | +} | |
42 … | + | |
43 … | +$.permissions = { | |
44 … | + anonymous: ['greet', 'bonjour', 'connect', 'createLog', 'netcast', 'greeting', 'onConnect'], | |
45 … | + replicate: ['push', 'pull', 'sync'], | |
46 … | + log : ['add', 'append', 'batch', 'get', 'heads', 'headStream', 'updates'], | |
47 … | + sign: ['sign'] | |
48 … | +} | |
49 … | + | |
50 … | +$.init = function(dex, bot){ | |
51 … | + var self = dex | |
52 … | + var node = dex | |
53 … | + var rpc = {} | |
54 … | + $.permissions.replicate.forEach(function(e){ | |
55 … | + rpc[e] = function(opts){ | |
56 … | + var type = $.manifest.replicate[e] | |
57 … | + var log = bot.log[e]({mode: e, live: opts.live || false}) | |
58 … | + var stream = str2ps[type](log) | |
59 … | + return stream | |
60 … | + } | |
61 … | + }) | |
62 … | + $.permissions.log.forEach(function(e){ | |
63 … | + var type = $.manifest[e] | |
64 … | + if(type === 'async') rpc[e] = bot.log[e] | |
65 … | + else{ // source stream | |
66 … | + switch(e){ | |
67 … | + case 'headStream': | |
68 … | + rpc[e] = function(opts){ | |
69 … | + return str2ps(bot.log.heads(opts)) | |
70 … | + } | |
71 … | + break; | |
72 … | + case 'updates': | |
73 … | + rpc[e] = function(opts){ | |
74 … | + return str2ps(bot.log.createReadStream(opts)) | |
75 … | + } | |
76 … | + break; | |
77 … | + } | |
78 … | + } | |
79 … | + }) | |
80 … | + var core = { | |
81 … | + 'sign': function(msg, cb){ | |
82 … | + var signed = keer.signObj(bot.keys, {msg: msg}) | |
83 … | + cb(null, signed) | |
84 … | + }, | |
85 … | + 'onConnect' : function(cb){ | |
86 … | + var self = dex | |
87 … | + dex.on('rpc:connect', function(remote){ | |
88 … | + //remote.pause() | |
89 … | + cb(remote) | |
90 … | + }) | |
91 … | + }, | |
92 … | + 'bonjour': function(){ | |
93 … | + //console.log(bot) | |
94 … | + var record = { | |
95 … | + type: 'dexbot', | |
96 … | + port: 12111, // fake cuz why port? idk... also, don't want to parse node.adress() for port #buh | |
97 … | + name: bot.name, | |
98 … | + host: node.getAddress() | |
99 … | + } | |
100 … | + mdns.publish(record) | |
101 … | + | |
102 … | + }, | |
103 … | + 'greet': function(cb){ | |
104 … | + ;(function(_cb){mdns.find({type: 'dexbot'}, function(service){ | |
105 … | + if(service.host === node.getAddress()) return | |
106 … | + else{ | |
107 … | + //console.log(service, _cb) | |
108 … | + if(_cb) _cb(service)// add to list of known bots, loookup, etc | |
109 … | + } | |
110 … | + })})(cb) | |
111 … | + }, | |
112 … | + 'connect': function(peer, cb){ | |
113 … | + node.connect(peer.host, function(err, rpc){ | |
114 … | + if(err) console.log(err) // publish errloggify this callback if the method sticks | |
115 … | + if(cb) cb(rpc) | |
116 … | + rpc.manifest(function(err, data){ | |
117 … | + // console.log(err, data) | |
118 … | + }) | |
119 … | + //rpc.dexbot.greet(self.name, function(err, greets){ | |
120 … | + // console.log(greets) | |
121 … | + //}) | |
122 … | + var log = hyperlog(bot.db.sublevel()) | |
123 … | + var local = str2ps.duplex(log.replicate({live : true}), function(err){ | |
124 … | + //console.log('local err or ending?', err) | |
125 … | + }) | |
126 … | + var random = rpc.dexbot.createLog() | |
127 … | + var remote = rpc.dexbot.netcast({ | |
128 … | + distance: 3, | |
129 … | + head: null, | |
130 … | + author: '1234567890' | |
131 … | + }) | |
132 … | + var x | |
133 … | + //pull(local, remote, local) | |
134 … | + pull(local, random, local) | |
135 … | + log.on('add', function(data){ | |
136 … | + //console.log(data.value.toString() + service.name) | |
137 … | + }) | |
138 … | + }) | |
139 … | + | |
140 … | + }, | |
141 … | + 'netcast': function(mesg){ | |
142 … | + | |
143 … | + var distance = mesg.distance || 0 | |
144 … | + | |
145 … | + var log = hyperlog(bot.db.sublevel('netcast')) | |
146 … | + | |
147 … | + var local = str2ps.duplex(log.replicate({live:true}), function(err){ | |
148 … | + //console.log('remote error or completion?', err) | |
149 … | + }) | |
150 … | + | |
151 … | + log.add(mesg.head || undefined, JSON.stringify(Object.keys(node.peers)), function(err, doc){ | |
152 … | + | |
153 … | + mesg.distance-- | |
154 … | + mesg.auth = node.address() | |
155 … | + mesg.head = doc.key | |
156 … | + | |
157 … | + if(distance < 0) //??? | |
158 … | + | |
159 … | + Object.keys(node.peers).forEach(function(peer){ | |
160 … | + if(distance > 0 && !(mesg.publicKey === peer)){ | |
161 … | + remote = peer.dexbot.netcast(mesg) | |
162 … | + pull(local, remote, local) | |
163 … | + log.on('add', function(data){ | |
164 … | + console.log(data.toString()) | |
165 … | + }) | |
166 … | + } | |
167 … | + }) | |
168 … | + | |
169 … | + }) | |
170 … | + | |
171 … | + return local | |
172 … | + }, | |
173 … | + 'stderr' : function( replicate){ | |
174 … | + var type = replicate ? 'replicate' : 'changes' | |
175 … | + var stream = str2ps.duplex(errLogDB[type]({live:true}), errLog()) | |
176 … | + return stream | |
177 … | + }, | |
178 … | + 'swarmLog' : function(publicKey){ | |
179 … | + var log = swarmlog({ | |
180 … | + keys: publicKey, | |
181 … | + sodium: require('chloride/browser'), | |
182 … | + db: bot.db.sublevel('swarm:' + publicKey), | |
183 … | + valueEncoding: 'json', | |
184 … | + hubs: [ 'https://signalhub.mafintosh.com' ] | |
185 … | + }) | |
186 … | + var stream = str2ps(log) | |
187 … | + return stream | |
188 … | + }, | |
189 … | + 'createLog': function(name){ | |
190 … | + var log = hyperlog(bot.db.sublevel(name)) | |
191 … | + | |
192 … | + var stream = str2ps.duplex(log.replicate({live:true}), function(err){ | |
193 … | + //console.log('remote error or completion?', err) | |
194 … | + }) | |
195 … | + setInterval(function(){ | |
196 … | + log.add(null, '"' + Math.random().toString(2) + '" - ' + bot.name, function(err, msg){ | |
197 … | + if(err) console.log(err) | |
198 … | + }) | |
199 … | + },511) | |
200 … | + return stream | |
201 … | + }, | |
202 … | + 'greeting': function(name, cb){ | |
203 … | + cb(null, bot.name + ': GREETINGS TO ' + name) | |
204 … | + } | |
205 … | + } | |
206 … | + Object.assign(rpc, core) | |
207 … | + return rpc | |
208 … | +} |
test.js | ||
---|---|---|
@@ -1,0 +1,25 @@ | ||
1 … | +'use strict' | |
2 … | +var spawnBot = require('./bot') | |
3 … | + | |
4 … | +var mom = spawnBot() | |
5 … | +var friend = spawnBot() | |
6 … | + | |
7 … | + | |
8 … | + | |
9 … | +friend.do.bonjour() | |
10 … | +friend.do.onConnect(function(peer){ | |
11 … | + peer.dexbot.greeting(friend.name, function(err, address){ | |
12 … | + console.log(err, address) | |
13 … | + peer.dexbot.sign(`${friend.name} says ${peer.id} is all right with ${friend.keys.id}`, function(err, msg){ | |
14 … | + console.log(err, msg) | |
15 … | + }) | |
16 … | + //friend.do.greeting(friend.name, console.log) | |
17 … | + }) | |
18 … | +}) | |
19 … | +mom.do.bonjour() | |
20 … | +mom.do.greet(function(bot){ | |
21 … | + //console.log(bot) | |
22 … | + mom.do.connect(bot, function(rpc){ | |
23 … | + | |
24 … | + }) | |
25 … | +}) |
Built with git-ssb-web