-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.ts
304 lines (265 loc) · 7.27 KB
/
index.ts
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
import { Eip1193Provider, SigningKey, ethers } from 'ethers';
import { ICollateral, IContract, IMode, ISigner } from './types';
import { Signer, Provider } from 'ethers';
import { SupportedNetwork } from './contracts/types';
import { waitTime } from './libs/utils';
import {
burnCurrency,
collateralizeVault,
mintCurrency,
setupVault,
withdrawCollateral,
} from './services/vault';
import { Transaction } from './libs/transactions';
import { Internal } from './libs/internal';
import { getContractAddress } from './contracts/getContractAddresses';
import { checkVaultSetupStatus, getCollateralData, getVault } from './services/getters';
import {
approveCollateralToken,
approveCurrencyToken,
getCollateralTokenBalance,
getCurrencyTokenBalance,
getCollateralTokenAllowance,
} from './services/utility';
export class DescentClass {
signer: Signer;
protected provider: Provider;
private collateral: ICollateral;
configMode: IMode | string;
chainId: string;
// Extensions
readonly internal = new Internal(this);
readonly transaction = new Transaction(this);
constructor(
signer: Signer,
provider: Provider,
collateral: ICollateral,
configMode: IMode | string,
chainId: string,
) {
this.provider = provider;
this.signer = signer;
this.collateral = collateral;
this.configMode = configMode;
this.chainId = chainId;
}
/**
* @dev Gets a vault detail by it's ID
* @param ownerAddress Vault owner
* @returns The Vault information
*/
public async getVaultInfo(ownerAddress: string) {
const result = await getVault(
this.collateral,
ownerAddress,
this.chainId,
this.internal,
this.signer,
);
return result;
}
/**
* @dev Gets the information of collateral initialized in `create()`
* @returns The collateral information
*/
public async getCollateralInfo() {
const result = await getCollateralData(this.collateral, this.chainId, this.signer);
return result;
}
/**
* @dev borrow xNGN against deposited USDC
* @param amount amount of xNGN to borrow
* @returns transaction obj
*/
public async borrowCurrency(borrowAmount: string) {
const owner = await this.signer.getAddress();
const result = await mintCurrency(
borrowAmount,
this.collateral,
owner,
this.chainId,
this.transaction,
this.internal,
this.signer,
);
return result;
}
/**
* @dev repay borrowed xNGN for a particular vault
* @param amount amount of xNGN to repay
* @returns transaction obj
*/
public async repayCurrency(amount: string) {
const owner = await this.signer.getAddress();
const result = await burnCurrency(
amount,
this.collateral,
owner,
this.chainId,
this.transaction,
this.internal,
this.signer,
);
return result;
}
/**
* @dev withdraw usdc for a particular vault
* @param collateralAmount amount of unlocked collateral to withdraw
* @returns transaction obj
*/
public async withdrawCollateral(collateralAmount: string) {
const owner = await this.signer.getAddress();
const result = await withdrawCollateral(
collateralAmount,
this.collateral,
owner,
this.chainId,
this.transaction,
this.internal,
this.signer,
);
return result;
}
/**
* @dev deposit usdc for a particular vault
* @param collateralAmount amount of unlocked collateral to withdraw
* @param ownerAddress owner of the vault which should be the caller
* @returns transaction obj
*/
public async depositCollateral(collateralAmount: string) {
const owner = await this.signer.getAddress();
const result = await collateralizeVault(
collateralAmount,
this.collateral,
owner,
this.chainId,
this.transaction,
this.internal,
);
return result;
}
/**
* @dev initializes a vault for a an address
* @returns transaction obj
*/
public async setupVault() {
const owner = await this.signer.getAddress();
const result = await setupVault(owner, this.chainId, this.transaction, this.internal);
return result;
}
/**
* @dev Check if a vault has been initialized
* @returns boolean
*/
public async getVaultSetupStatus() {
const owner = await this.signer.getAddress();
const result = await checkVaultSetupStatus(owner, this.chainId, this.signer);
return result;
}
// UTILITY HELPER FUNCTIONS FUNCTIONS
/**
* @dev gets the collateral token balance of an address
* @param owner address of the owner
* @returns balance
*/
public async getCollateralTokenBalance(owner: string) {
const result = await getCollateralTokenBalance(
this.collateral,
owner,
this.chainId,
this.signer,
);
return result;
}
/**
* @dev approve the vault to take a certain amount of collateral
* @param amount amount of allowance
* @returns tx object
*/
public async approveCollateral(amount: string) {
const owner = await this.signer.getAddress();
const result = await approveCollateralToken(
this.collateral,
owner,
amount,
this.chainId,
this.internal,
this.transaction,
);
return result;
}
/**
* @dev approve the vault to take a certain amount of collateral
* @param amount amount of allowance
* @returns tx object
*/
public async collateralTokenAllowance(approver: string) {
const result = await getCollateralTokenAllowance(
this.collateral,
approver,
this.chainId,
this.signer,
);
return result;
}
/**
* @dev gets the xNGN balalnce of an address
* @param owner address of the owner
* @returns balance
*/
public async getxNGNBalance(owner: string) {
const result = await getCurrencyTokenBalance(owner, this.chainId, this.signer);
return result;
}
/**
* @dev approve the vault to take a certain amount of xNGN
* @param amount amount of allowance
* @returns tx object
*/
public async approvexNGN(amount: string) {
const owner = await this.signer.getAddress();
const result = await approveCurrencyToken(
owner,
amount,
this.chainId,
this.internal,
this.transaction,
);
return result;
}
}
async function create(
mode: string,
options: {
ethereum?: Eip1193Provider | any;
rpcUrl?: string;
privateKey?: any | SigningKey;
collateral: ICollateral;
},
) {
const supportedNetworks = [SupportedNetwork.BASE_GOERLI, SupportedNetwork.BASE_SEPOLIA];
// Validate required options
if (!options.collateral) {
throw new Error('Missing required options');
}
let provider: any;
let signer: any;
if (mode == 'https') {
provider = new ethers.JsonRpcProvider(options?.rpcUrl);
signer = new ethers.Wallet(options.privateKey, provider);
}
if (mode == 'browser') {
provider = new ethers.BrowserProvider(options?.ethereum);
signer = await provider?.getSigner();
}
const chainId = (await provider.getNetwork()).chainId.toString(10);
if (!supportedNetworks.includes(chainId)) {
throw new Error(`chainId '${chainId}' is not supported.`);
}
const descent = new DescentClass(signer, provider, options.collateral, mode, chainId);
return descent;
}
const Descent = {
create,
};
export default Descent;