IpfsResolver.js 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. const IpfsClient = require('ipfs-http-client')
  2. const axios = require('axios')
  3. const { Resolver } = require('./Resolver')
  4. class IpfsResolver extends Resolver {
  5. constructor({
  6. host = 'localhost',
  7. port,
  8. mode = 'rpc', // rpc or gateway
  9. protocol = 'http', // http or https
  10. ipfs,
  11. runtime
  12. }) {
  13. super({runtime})
  14. if (ipfs) {
  15. // use an existing ipfs client instance
  16. this.ipfs = ipfs
  17. } else if (mode == 'rpc') {
  18. port = port || '5001'
  19. this.ipfs = IpfsClient(host, port, { protocol })
  20. } else if (mode === 'gateway') {
  21. port = port || '8080'
  22. this.gateway = this.constructUrl(protocol, host, port)
  23. } else {
  24. throw new Error('Invalid IPFS Resolver options')
  25. }
  26. }
  27. async _resolveOverRpc(identity) {
  28. const ipnsPath = `/ipns/${identity}/`
  29. const ipfsName = await this.ipfs.name.resolve(ipnsPath, {
  30. recursive: false, // there should only be one indirection to service info file
  31. nocache: false,
  32. })
  33. const data = await this.ipfs.get(ipfsName)
  34. // there should only be one file published under the resolved path
  35. const content = data[0].content
  36. return JSON.parse(content)
  37. }
  38. async _resolveOverGateway(identity) {
  39. const url = `${this.gateway}/ipns/${identity}`
  40. // expected JSON object response
  41. const response = await axios.get(url)
  42. return response.data
  43. }
  44. resolve(accountId) {
  45. const identity = this.resolveIdentity(accountId)
  46. if (this.ipfs) {
  47. return this._resolveOverRpc(identity)
  48. } else {
  49. return this._resolveOverGateway(identity)
  50. }
  51. }
  52. }
  53. module.exports = {
  54. IpfsResolver
  55. }