publish.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // const ipfsClient = require('ipfs-http-client')
  2. // const ipfs = ipfsClient('localhost', '5001', { protocol: 'http' })
  3. const debug = require('debug')('joystream:discovery:publish')
  4. /**
  5. * The name of the key used for publishing. We use same key used by the ipfs node
  6. * for the network identitiy, to make it possible to identify the ipfs node of the storage
  7. * provider and use `ipfs ping` to check on the uptime of a particular node.
  8. */
  9. const PUBLISH_KEY = 'self'
  10. /**
  11. * Applies JSON serialization on the data object and converts the utf-8
  12. * string to a Buffer.
  13. * @param {object} data - json object
  14. * @returns {Buffer} returns buffer from UTF-8 json
  15. */
  16. function bufferFrom(data) {
  17. return Buffer.from(JSON.stringify(data), 'utf-8')
  18. }
  19. /**
  20. * Encodes the service info into a standard format see. /storage-node/docs/json-signing.md
  21. * To be able to add a signature over the json data. Signing is not currently implemented.
  22. * @param {object} info - json object
  23. * @returns {Buffer} return buffer.
  24. */
  25. function encodeServiceInfo(info) {
  26. return bufferFrom({
  27. serialized: JSON.stringify(info),
  28. })
  29. }
  30. class PublisherClient {
  31. constructor(ipfs) {
  32. this.ipfs = ipfs || require('ipfs-http-client')('localhost', '5001', { protocol: 'http' })
  33. }
  34. /**
  35. * Publishes the service information, encoded using the standard defined in encodeServiceInfo()
  36. * to ipfs, using the local ipfs node's PUBLISH_KEY, and returns the key id used to publish.
  37. * What we refer to as the ipns id.
  38. * @param {object} serviceInfo - the service information to publish
  39. * @returns {string} - the ipns id
  40. */
  41. async publish(serviceInfo) {
  42. const keys = await this.ipfs.key.list()
  43. let servicesKey = keys.find((key) => key.name === PUBLISH_KEY)
  44. // An ipfs node will always have the self key.
  45. // If the publish key is specified as anything else and it doesn't exist
  46. // we create it.
  47. if (PUBLISH_KEY !== 'self' && !servicesKey) {
  48. debug('generating ipns services key')
  49. servicesKey = await this.ipfs.key.gen(PUBLISH_KEY, {
  50. type: 'rsa',
  51. size: 2048,
  52. })
  53. }
  54. if (!servicesKey) {
  55. throw new Error('No IPFS publishing key available!')
  56. }
  57. debug('adding service info file to node')
  58. const files = await this.ipfs.add(encodeServiceInfo(serviceInfo))
  59. debug('publishing...')
  60. const published = await this.ipfs.name.publish(files[0].hash, {
  61. key: PUBLISH_KEY,
  62. resolve: false,
  63. // lifetime: // string - Time duration of the record. Default: 24h
  64. // ttl: // string - Time duration this record should be cached
  65. })
  66. // The name and ipfs hash of the published service information file, eg.
  67. // {
  68. // name: 'QmUNQCkaU1TRnc1WGixqEP3Q3fazM8guSdFRsdnSJTN36A',
  69. // value: '/ipfs/QmcSjtVMfDSSNYCxNAb9PxNpEigCw7h1UZ77gip3ghfbnA'
  70. // }
  71. // .. The name is equivalent to the key id that was used.
  72. debug(published)
  73. // Return the key id under which the content was published. Which is used
  74. // to lookup the actual ipfs content id of the published service information
  75. return servicesKey.id
  76. }
  77. }
  78. module.exports = {
  79. PublisherClient,
  80. }