-
Notifications
You must be signed in to change notification settings - Fork 0
/
library.js
163 lines (143 loc) · 4.12 KB
/
library.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/* eslint-disable no-await-in-loop */
const { abi: libAbi } = require('./build/contracts/Library.json')
const { abi: proxyAbi } = require('./build/contracts/AFS.json')
const { LIBRARY_ADDRESS } = require('./constants')
const {
proxyExists,
getProxyAddress
} = require('./registry')
const {
hashDID,
getIdentifier,
web3: {
sha3,
call,
isAddress
},
transform: {
toHexString
},
getAddressFromDID
} = require('ara-util')
/**
* Returns requesterDid's library
* @param {string} unhashed did
* @return {Array}
* @throws {TypeError}
*/
async function getLibrary(requesterDid = '') {
if (!requesterDid || 'string' !== typeof requesterDid) {
throw TypeError('Expecting non-empty requester DID')
}
requesterDid = getIdentifier(requesterDid)
const libSize = await getLibrarySize(requesterDid)
const lib = []
for (let i = 0; i < libSize; i++) {
const item = await getLibraryItem({ requesterDid, index: i })
lib.push(item)
}
return lib
}
/**
* Gets the size of requesterDid's library
* @param {String} unhashed requesterDid
* @return {String} // web3 coerces return type uint16 to a string for some reason
* @throws {TypeError}
*/
async function getLibrarySize(requesterDid = '') {
if ('string' !== typeof requesterDid || !requesterDid) {
throw TypeError('Expecting non-empty requester DID')
}
const hIdentity = hashDID(requesterDid)
try {
return call({
abi: libAbi,
address: LIBRARY_ADDRESS,
functionName: 'getLibrarySize',
arguments: [
toHexString(hIdentity, { encoding: 'hex', ethify: true })
]
})
} catch (err) {
throw err
}
}
/**
* Gets the DID of the item at index in requesterDid's library
* @param {Object} opts
* @param {String} opts.requesterDid
* @param {int} opts.index
* @return {string}
* @throws {Error, TypeError}
*/
async function getLibraryItem(opts) {
if (!opts || 'object' !== typeof opts) {
throw new TypeError('Expecting opts object.')
} else if ('string' !== typeof opts.requesterDid || !opts.requesterDid) {
throw TypeError('Expecting non-empty requester DID')
} else if ('number' !== typeof opts.index || opts.index < 0) {
throw TypeError('Expecting a whole number index')
}
const { requesterDid, index } = opts
const hIdentity = hashDID(requesterDid)
if (await getLibrarySize(requesterDid) <= index) {
throw Error('Invalid index')
}
try {
return call({
abi: libAbi,
address: LIBRARY_ADDRESS,
functionName: 'getLibraryItem',
arguments: [
toHexString(hIdentity, { encoding: 'hex', ethify: true }),
index
]
})
} catch (err) {
throw err
}
}
/**
* Checks whether a user has purchased an AFS.
* @param {Object} opts
* @param {String} opts.purchaserDid
* @param {String} opts.contentDid
* @param {Object} [opts.keyringOpts]
* @return {Boolean} [description]
*/
async function hasPurchased(opts) {
if (!opts || 'object' !== typeof opts) {
throw new TypeError('Expecting opts object.')
} else if (!opts.purchaserDid || 'string' !== typeof opts.purchaserDid) {
throw new TypeError('Expecting non-empty string for purchaser DID')
} else if (!opts.contentDid || 'string' !== typeof opts.contentDid) {
throw new TypeError('Expecting non-empty string for content DID')
}
const { purchaserDid, contentDid, keyringOpts } = opts
if (!(await proxyExists(contentDid))) {
throw new Error('This content does not have a valid proxy contract')
}
const proxy = await getProxyAddress(contentDid)
let purchaser = await getAddressFromDID(purchaserDid, keyringOpts)
if (!isAddress(purchaser)) {
// TODO(cckelly) convert all ara-contracts errors to this style
throw new Error(`${purchaserDid} did not resolve to a valid Ethereum address. Got ${purchaser}. Ensure ${purchaserDid} is a valid Ara identity.`)
}
purchaser = sha3(purchaser)
try {
return call({
abi: proxyAbi,
address: proxy,
functionName: 'purchasers_',
arguments: [ purchaser ]
})
} catch (err) {
throw err
}
}
module.exports = {
getLibrarySize,
getLibraryItem,
hasPurchased,
getLibrary
}