assets.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. 'use strict'
  2. const debug = require('debug')('joystream:runtime:assets')
  3. const { decodeAddress } = require('@polkadot/keyring')
  4. function parseContentId(contentId) {
  5. try {
  6. return decodeAddress(contentId)
  7. } catch (err) {
  8. return contentId
  9. }
  10. }
  11. /*
  12. * Add asset related functionality to the substrate API.
  13. */
  14. class AssetsApi {
  15. static async create(base) {
  16. const ret = new AssetsApi()
  17. ret.base = base
  18. await AssetsApi.init()
  19. return ret
  20. }
  21. static async init() {
  22. debug('Init')
  23. }
  24. /*
  25. * Create and return a data object.
  26. */
  27. async createDataObject(accountId, memberId, contentId, doTypeId, size, ipfsCid) {
  28. contentId = parseContentId(contentId)
  29. const tx = this.base.api.tx.dataDirectory.addContent(memberId, contentId, doTypeId, size, ipfsCid)
  30. await this.base.signAndSend(accountId, tx)
  31. // If the data object constructed properly, we should now be able to return
  32. // the data object from the state.
  33. return this.getDataObject(contentId)
  34. }
  35. /*
  36. * Return the Data Object for a contendId
  37. */
  38. async getDataObject(contentId) {
  39. contentId = parseContentId(contentId)
  40. return this.base.api.query.dataDirectory.dataObjectByContentId(contentId)
  41. }
  42. /*
  43. * Verify the liaison state for a DataObject:
  44. * - Check the content ID has a DataObject
  45. * - Check the storageProviderId is the liaison
  46. * - Check the liaison state is Pending
  47. *
  48. * Each failure errors out, success returns the data object.
  49. */
  50. async checkLiaisonForDataObject(storageProviderId, contentId) {
  51. contentId = parseContentId(contentId)
  52. let obj = await this.getDataObject(contentId)
  53. if (obj.isNone) {
  54. throw new Error(`No DataObject created for content ID: ${contentId}`)
  55. }
  56. obj = obj.unwrap()
  57. if (!obj.liaison.eq(storageProviderId)) {
  58. throw new Error(`This storage node is not liaison for the content ID: ${contentId}`)
  59. }
  60. if (obj.liaison_judgement.type !== 'Pending') {
  61. throw new Error(`Expected Pending judgement, but found: ${obj.liaison_judgement.type}`)
  62. }
  63. return obj
  64. }
  65. /*
  66. * Sets the data object liaison judgement to Accepted
  67. */
  68. async acceptContent(providerAccoundId, storageProviderId, contentId) {
  69. contentId = parseContentId(contentId)
  70. const tx = this.base.api.tx.dataDirectory.acceptContent(storageProviderId, contentId)
  71. return this.base.signAndSend(providerAccoundId, tx)
  72. }
  73. /*
  74. * Sets the data object liaison judgement to Rejected
  75. */
  76. async rejectContent(providerAccountId, storageProviderId, contentId) {
  77. contentId = parseContentId(contentId)
  78. const tx = this.base.api.tx.dataDirectory.rejectContent(storageProviderId, contentId)
  79. return this.base.signAndSend(providerAccountId, tx)
  80. }
  81. /*
  82. * Gets storage relationship for contentId for the given provider
  83. */
  84. async getStorageRelationshipAndId(storageProviderId, contentId) {
  85. contentId = parseContentId(contentId)
  86. const rids = await this.base.api.query.dataObjectStorageRegistry.relationshipsByContentId(contentId)
  87. while (rids.length) {
  88. const relationshipId = rids.shift()
  89. let relationship = await this.base.api.query.dataObjectStorageRegistry.relationships(relationshipId)
  90. relationship = relationship.unwrap()
  91. if (relationship.storage_provider.eq(storageProviderId)) {
  92. return { relationship, relationshipId }
  93. }
  94. }
  95. return {}
  96. }
  97. /*
  98. * Creates storage relationship for a data object and provider and
  99. * returns the relationship id
  100. */
  101. async createStorageRelationship(providerAccountId, storageProviderId, contentId) {
  102. contentId = parseContentId(contentId)
  103. const tx = this.base.api.tx.dataObjectStorageRegistry.addRelationship(storageProviderId, contentId)
  104. return this.base.signAndSendThenGetEventResult(providerAccountId, tx, {
  105. module: 'dataObjectStorageRegistry',
  106. event: 'DataObjectStorageRelationshipAdded',
  107. type: 'DataObjectStorageRelationshipId',
  108. index: 0,
  109. })
  110. }
  111. /*
  112. * Set the ready state for a data object storage relationship to the new value
  113. */
  114. async toggleStorageRelationshipReady(providerAccountId, storageProviderId, dosrId, ready) {
  115. const tx = ready
  116. ? this.base.api.tx.dataObjectStorageRegistry.setRelationshipReady(storageProviderId, dosrId)
  117. : this.base.api.tx.dataObjectStorageRegistry.unsetRelationshipReady(storageProviderId, dosrId)
  118. return this.base.signAndSend(providerAccountId, tx)
  119. }
  120. /*
  121. * Returns array of know content ids
  122. */
  123. async getKnownContentIds() {
  124. return this.base.api.query.dataDirectory.knownContentIds()
  125. }
  126. }
  127. module.exports = {
  128. AssetsApi,
  129. }