Home Reference Source

packages/oo7-substrate/src/srml/indices.js

  1. const { Bond, TransformBond } = require('oo7')
  2. const { ss58Encode, ss58Decode } = require('../ss58')
  3. const { AccountId, AccountIndex } = require('../types')
  4.  
  5. function fixedBond(b) {
  6. r = new Bond
  7. r.trigger(b)
  8. return r
  9. }
  10.  
  11. function isId(id) {
  12. return id instanceof AccountId || (id instanceof Uint8Array && id.length == 32)
  13. }
  14.  
  15. function isIndex(index) {
  16. return index instanceof AccountIndex || typeof index === 'number'
  17. }
  18.  
  19. function augment(runtime, chain) {
  20. let indices = runtime.indices
  21. if (indices._extras) {
  22. return
  23. } else {
  24. indices._extras = true
  25. }
  26.  
  27. indices.lookup = indexBond => new TransformBond(index =>
  28. isIndex(index) || typeof(index) === 'number'
  29. ? indices.enumSet(new AccountIndex(Math.floor(index / 64))).map(items => items[index % 64])
  30. : null,
  31. [indexBond]
  32. )
  33.  
  34. indices.accounts = indices.nextEnumSet.map(last =>
  35. [...new Array(last + 1)].map((_, i) => indices.enumSet(i))
  36. ).map(sets => {
  37. let res = {}
  38. sets.forEach((items, i) =>
  39. items.forEach((item, j) =>
  40. res[ss58Encode(item)] = i * 64 + j
  41. )
  42. )
  43. return res
  44. }).subscriptable()
  45.  
  46. indices.tryIndex = (id, whenNone = id) => new TransformBond((accounts, id, whenNone) => {
  47. if (typeof id === 'string') {
  48. id = ss58Decode(id)
  49. }
  50. if (isId(id)) {
  51. let i = accounts[ss58Encode(id)]
  52. return isIndex(i)
  53. ? new AccountIndex(i)
  54. : whenNone
  55. } else {
  56. return whenNone
  57. }
  58. }, [indices.accounts, id, whenNone], [], 3, 3, undefined, false)
  59.  
  60. indices.ss58Encode = (address, type, csLength, length) => new TransformBond((address, id, index, type, csLength, length) => {
  61. if (isIndex(address)) {
  62. index = address
  63. }
  64. if (isId(address)) {
  65. id = address
  66. }
  67. if (!isId(id) || !(isIndex(index) || isId(index))) {
  68. return null
  69. }
  70. return ss58Encode(index, type || undefined, csLength || undefined, length || undefined, id)
  71. }, [address, indices.lookup(address), indices.tryIndex(address), type || null, csLength || null, length || null], [], 3, 3, undefined, false)
  72.  
  73. indices.ss58Decode = address => {
  74. try {
  75. let indexOrId = ss58Decode(address, index => { throw {index} })
  76. if (isId(indexOrId)) {
  77. return fixedBond(indexOrId)
  78. } else {
  79. return indices.lookup(indexOrId)
  80. }
  81. }
  82. catch (indexToLookup) {
  83. return indices.lookup(indexToLookup.index).map(id => {
  84. return ss58Decode(address, id) === null ? null : id
  85. })
  86. }
  87. }
  88. }
  89.  
  90. module.exports = { augment }