-
Notifications
You must be signed in to change notification settings - Fork 240
/
Copy pathUser.js
174 lines (164 loc) · 6.47 KB
/
User.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
164
165
166
167
168
169
170
171
172
173
174
const {getErrorResponse} = require("./utils/error");
module.exports = class User {
/**
* @dev Create new Superfluid user object
* @param {Framework} sf Superfluid framework object.
* @param {string} address The EOA address of the user you want to create.
* @param {string} token The address of the supertoken you want to interact with.
*/
constructor({sf, address, token}) {
this.sf = sf;
this.address = address;
this.token = token;
}
/**
* @dev Returns instantiated details regarding the users' cfa and ida data.
* @returns {object} top-level cfa property contains flows: Flow[] and netFlow: number
* top-level ida property contains subscriptions: Subscription[]
*/
async details() {
try {
const listFlows = this.sf.cfa.listFlows({
superToken: this.token,
account: this.address,
});
const getNewFlow = this.sf.cfa
.getNetFlow({
superToken: this.token,
account: this.address,
})
.then((x) => x.toString());
const listSubscriptions = this.sf.ida.listSubscriptions({
superToken: this.token,
subscriber: this.address,
});
const [flows, netFlow, subscriptions] = await Promise.all([
listFlows,
getNewFlow,
listSubscriptions,
]);
return {cfa: {flows, netFlow}, ida: {subscriptions}};
} catch (e) {
throw getErrorResponse(e, "user", "details");
}
}
/**
* @dev Allows you to create, update or delete a flow from the user you initialized.
* @param {string} recipient the recipient of the flow agreement
* @param {string} flowRate the agreed upon flowRate
* @param {object} options options taken by cfa (userData, onTransaction, by (deleteFlow only))
* @returns {Promise<Transaction | undefined>} web3 transaction object or undefined on error
* NOTE: !0 in JS evaluates to true as 0 is a falsey value. We also stringify the flowRate,
* just in case the user somehow is able to input a number (using JS).
*/
async flow({recipient, flowRate, ...options}) {
try {
if (!recipient || flowRate == null || flowRate == undefined)
throw "You must provide a recipient and flowRate";
if (typeof flowRate !== "string")
throw "You must provide flowRate as a string";
const recipientAddress = recipient.address || recipient;
if (flowRate === "0")
return await this.sf.cfa.deleteFlow({
superToken: this.token,
sender: this.address,
receiver: recipientAddress,
...options,
});
const existingFlow = await this.sf.cfa.getFlow({
superToken: this.token,
sender: this.address,
receiver: recipientAddress,
});
if (existingFlow.flowRate !== "0")
return await this.sf.cfa.updateFlow({
superToken: this.token,
sender: this.address,
receiver: recipientAddress,
flowRate,
...options,
});
return await this.sf.cfa.createFlow({
superToken: this.token,
sender: this.address,
receiver: recipientAddress,
flowRate,
...options,
});
} catch (e) {
throw getErrorResponse(e, "user", "flow");
}
}
/**
* @dev Create an Index using the IDA.
* @param {number} poolId The id of the index.
* @returns {Promise<Transaction | undefined>} web3 transaction object or undefined on error
*/
async createPool({poolId: indexId}) {
try {
if (!indexId) throw "You must provide a poolId";
const {exist} = await this.sf.ida.getIndex({
superToken: this.token,
publisher: this.address,
indexId,
});
if (exist) throw "This pool has already been created";
return await this.sf.ida.createIndex({
superToken: this.token,
publisher: this.address,
indexId,
});
} catch (e) {
throw getErrorResponse(e, "user", "createPool");
}
}
/**
* @dev Gives shares (units) to a recipient.
* @param {string} recipient The recipient of the shares.
* @param {number} shares The number of units the recipient will receive.
* @param {number} poolId The id of the index.
* @returns {Promise<Transaction | undefined>} web3 transaction object or undefined on error
*/
async giveShares({recipient, shares, poolId: indexId}) {
try {
if (!recipient || !shares || !indexId)
throw "You must provide a recipient, share amount, and poolId";
const recipientAddress = recipient.address || recipient;
const {exist} = await this.sf.ida.getIndex({
superToken: this.token,
publisher: this.address,
indexId,
});
if (!exist) throw "This pool has not been created yet";
return await this.sf.ida.updateSubscription({
superToken: this.token,
publisher: this.address,
indexId,
subscriber: recipientAddress,
units: shares,
});
} catch (e) {
throw getErrorResponse(e, "user", "giveShares");
}
}
/**
* @dev Distributes tokens to subscribers who are approved.
* @param {number} poolId The id of the index.
* @param {number} amount The amount of tokens to distribute.
* @returns {Promise<Transaction | undefined>} web3 transaction object or undefined on error
*/
async distributeToPool({poolId: indexId, amount}) {
try {
if (!indexId || !amount)
throw "You must provide a poolId and amount";
return await this.sf.ida.distribute({
superToken: this.token,
publisher: this.address,
indexId,
amount,
});
} catch (e) {
throw getErrorResponse(e, "user", "distributeToPool");
}
}
};