{"id":15483397,"url":"https://github.com/hackergrrl/ssb-exchange","last_synced_at":"2025-09-13T17:32:26.376Z","repository":{"id":57368780,"uuid":"137104142","full_name":"hackergrrl/ssb-exchange","owner":"hackergrrl","description":"Fully sync two secure-scuttlebutt databases over a duplex stream.","archived":false,"fork":false,"pushed_at":"2018-06-13T03:44:12.000Z","size":7,"stargazers_count":15,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-12-28T21:44:12.883Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hackergrrl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-06-12T17:11:27.000Z","updated_at":"2020-10-10T12:42:26.000Z","dependencies_parsed_at":"2022-09-12T03:11:00.579Z","dependency_job_id":null,"html_url":"https://github.com/hackergrrl/ssb-exchange","commit_stats":null,"previous_names":["noffle/ssb-exchange"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackergrrl%2Fssb-exchange","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackergrrl%2Fssb-exchange/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackergrrl%2Fssb-exchange/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackergrrl%2Fssb-exchange/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hackergrrl","download_url":"https://codeload.github.com/hackergrrl/ssb-exchange/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":232893475,"owners_count":18592968,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-02T05:14:55.646Z","updated_at":"2025-01-07T14:37:13.698Z","avatar_url":"https://github.com/hackergrrl.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ssb-exchange\n\n\u003e fully exchange two secure-scuttlebutt databases over a duplex stream\n\n## Usage\n\n```js\nvar replicate = require('ssb-exchange')\nvar path = require('path')\nvar pull = require('pull-stream')\n\nvar alice = createDbAndFeed('alice')\nvar bob = createDbAndFeed('bob')\n\nalice.feed.add({ type: 'post', text: 'alice\\'s First Post!' }, function (err, msg, hash) {\n  alice.feed.add({ type: 'post', text: 'alice\\'s Second Post!' }, function (err, msg, hash) {\n    bob.feed.add({ type: 'post', text: 'bob\\'s First Post!' }, function (err, msg, hash) {\n      sync()\n    })\n  })\n})\n\nfunction sync () {\n  var r1 = replicate(alice.ssb, 'alice')\n  var r2 = replicate(bob.ssb, 'bob')\n\n  r1.pipe(r2).pipe(r1)\n\n  r1.on('end', function () {\n    pull(\n      alice.ssb.createLogStream({keys: false, values: true}),\n      pull.drain(console.log)\n    )\n  })\n}\n\nfunction createDbAndFeed (dir) {\n  var keys = require('ssb-keys').loadOrCreateSync(path.join(dir, 'secret'))\n  var ssb = require('secure-scuttlebutt/create')(path.join(dir, 'db'))\n  var feed = ssb.createFeed(keys)\n  return {ssb: ssb, feed: feed}\n}\n```\n\noutputs\n\n```\n{ previous: null,\n  sequence: 1,\n  author: '@6VKBcLTLgL8vDuLHtgFlYEg/yTgYqI1WoPENQrzJNs4=.ed25519',\n  timestamp: 1528823339650,\n  hash: 'sha256',\n  content: { type: 'post', text: 'alice\\'s First Post!' },\n  signature: 'aBLQHwohD2FlTtLU1tsrFovoRQk+cTjgEi2SWZw+A1/Z+RlkDuRvFDplwI9oATzAprWhm1KuA69D9dUAnzMICA==.sig.ed25519' }\n{ previous: '%spHHU8AUpoLU7+tTvdPrfFoGmST/twD/xRH0Jd2Jhgw=.sha256',\n  sequence: 2,\n  author: '@6VKBcLTLgL8vDuLHtgFlYEg/yTgYqI1WoPENQrzJNs4=.ed25519',\n  timestamp: 1528823339700,\n  hash: 'sha256',\n  content: { type: 'post', text: 'alice\\'s Second Post!' },\n  signature: 'mZJqo73/jHAyoOajkInsAMicSx/iTvZg0f5FONuXspuXfzkxKtVUH8atYFmL5JNPxEXc6IR0dhpeMhAN/CHZDg==.sig.ed25519' }\n{ previous: null,\n  sequence: 1,\n  author: '@SWgLOnMBG7wEnmyP+vjueVluNj46IYRiktfyErVbjhA=.ed25519',\n  timestamp: 1528823339717,\n  hash: 'sha256',\n  content: { type: 'post', text: 'bob\\'s First Post!' },\n  signature: 'xrhWyHx129zjk7Bg2CPUQtASqehoeK7Yp6m9n3Yd2DgtMLzDlj1LPBCQIEglnUK2h7uLzKZQnAFrDrYjLYopAQ==.sig.ed25519' }\n```\n\n## API\n\n```js\nvar replicate = require('ssb-exchange')\n```\n\n### var stream = replicate(ssb)\n\nReturns a duplex stream, `stream`, that can be piped into another ssb-exchange\nduplex stream. The two will exchange information about what feeds they have, and\nsend only new information to the other end. The stream terminates once all data\nhas been sent and written to the local ssb database.\n\n## Install\n\nWith [npm](https://npmjs.org/) installed, run\n\n```\n$ npm install ssb-exchange\n```\n\n## License\n\nISC\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhackergrrl%2Fssb-exchange","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhackergrrl%2Fssb-exchange","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhackergrrl%2Fssb-exchange/lists"}