evernode-js-client 0.5.9 → 0.5.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "evernode-js-sample-app",
3
+ "scripts": {
4
+ "build": "ncc build test.js --minify -o dist"
5
+ },
6
+ "dependencies": {
7
+ "evernode-js-client": "0.4.32"
8
+ }
9
+ }
package/test/test.js ADDED
@@ -0,0 +1,409 @@
1
+ // const evernode = require("evernode-js-client");
2
+ const evernode = require("../dist"); // Local dist dir. (use 'npm run build' to update)
3
+ const codec = require('ripple-address-codec');
4
+
5
+ const evrIssuerAddress = "rEm71QHHXJzGULG4mkR3yhLz6EZYgvuwwP";
6
+ const registryAddress = "raaFre81618XegCrzTzVotAmarBcqNSAvK";
7
+ const registrySecret = "snrUSoLVodmhVCDNL92K1UafzQDjH";
8
+ const hostAddress = "rNJDQu9pUretQetmxeHRPkasM4o7chdML2";
9
+ const hostSecret = "ss11mwRSG4UxXQ9LakyYTmAzisnN2";
10
+ const foundationAddress = "rMRRzwe2mPhtVJYkBsPYbxkrHdExAduqWi";
11
+ const foundationSecret = "sncQEvGmeMrVGAvkMiLkmE3hrtVH9";
12
+ const tenantAddress = "rw7GPreCDX2nuJVHSwNdH38ZGsiEH8qiY";
13
+ const tenantSecret = "shdQBGbF9d3Tgp3D28pXoBdhWoZ9N";
14
+ const initializerAddress = 'rMv668j9M6x2ww4HNEF4AhB8ju77oSxFJD';
15
+ const initializerSecret = 'sn6TNZivVQY9KxXrLy8XdH9oXk3aG';
16
+ const transfereeAddress = 'rNAW13zAUA4DjkM45peek3WhUs23GZ2fYD';
17
+
18
+ const tosHash = "757A0237B44D8B2BBB04AE2BAD5813858E0AECD2F0B217075E27E0630BA74314";
19
+
20
+ const clients = [];
21
+
22
+ async function app() {
23
+
24
+ // Use a singleton xrplApi for all tests.
25
+ const xrplApi = new evernode.XrplApi('wss://hooks-testnet-v2.xrpl-labs.com');
26
+ evernode.Defaults.set({
27
+ registryAddress: registryAddress,
28
+ xrplApi: xrplApi
29
+ })
30
+
31
+ try {
32
+ await xrplApi.connect();
33
+
34
+ // Process of minting and selling a NFT.
35
+
36
+ // Account1: selling party.
37
+ // const acc1 = new evernode.XrplAccount(ownerAddress, ownerSecret);
38
+ // // Mint an nft with some data included in uri (256 bytes). xrpl doesn't check for uniqueness of data.
39
+ // // We need to make it unique in order to later find the token by uri.
40
+ // const uri = "mynft custom data";
41
+ // await acc1.mintNft(uri, 0, 0, true);
42
+ // // Get the minted nft information and sell it on the dex.
43
+ // const nft = await acc1.getNftByUri(uri);
44
+ // console.log(nft);
45
+ // // Make a sell offer (for free) while restricting it to be only purchased by the specified party.
46
+ // await acc1.offerSellNft(nft.NFTokenID, '0', 'XRP', null, hostAddress);
47
+
48
+ // // Account2: Buying party.
49
+ // const acc2 = new evernode.XrplAccount(hostAddress, hostSecret);
50
+ // // await acc2.offerBuyNft(nft.NFTokenID, registryAddress, '10', 'EVR', evrIssuerAddress);
51
+
52
+ // // const offers = await acc1.getNftOffers();
53
+ // // console.log(offers);
54
+ // // Find the sellOffer information from seller's account.
55
+ // const sellOffer = (await acc1.getNftOffers()).find(o => o.NFTokenID == nft.NFTokenID);
56
+ // console.log(sellOffer);
57
+ // // Buy the NFT by accepting the sell offer.
58
+ // await acc2.buyNft(sellOffer.index);
59
+ // // Get information about the purchased nft.
60
+ // const nft2 = await acc2.getNftByUri(uri);
61
+ // console.log(nft2);
62
+
63
+ const tests = [
64
+ // () => initializeConfigs(),
65
+ // () => getHookStates(),
66
+ // () => registerHost(),
67
+ // () => getHostInfo(),
68
+ // () => updateInfo(),
69
+ // () => getAllHosts(),
70
+ // () => getActiveHosts(),
71
+ // () => heartbeatHost(),
72
+ // () => acquire("success"),
73
+ // () => acquire("error"),
74
+ // () => acquire("timeout"),
75
+ // () => extendLease("success"),
76
+ // () => extendLease("error"),
77
+ // () => extendLease("timeout"),
78
+ // () => deregisterHost(),
79
+ // () => getAllConfigs(),
80
+ // () => pruneDeadHost(),
81
+ // () => transferHost(),
82
+ // () => requestRebate()
83
+
84
+ ];
85
+
86
+ for (const test of tests) {
87
+ await test();
88
+ await Promise.all(clients.map(c => c.disconnect())); // Cleanup clients after every test.
89
+ }
90
+
91
+ // await registerHost();
92
+ // Accepting the sell offer created by registry.
93
+
94
+ // const tokenID = '0008000083CD166E1806EF2076C55077AEFD418E771A516CB30E8CAE00000013';
95
+ // const reg = new evernode.XrplAccount(registryAddress, registrySecret);
96
+ // const sellOffer = (await reg.getNftOffers()).find(o => o.NFTokenID == tokenID);
97
+ // console.log(sellOffer);
98
+ // const host = new evernode.XrplAccount(hostAddress, hostSecret);
99
+ // await host.buyNft(sellOffer.index);
100
+ // const nfts = await host.getNfts();
101
+ // console.log(nfts);
102
+ // await host.register();
103
+ // await initializeConfigs();
104
+ // await registerHost();
105
+ // await deregisterHost();
106
+ // await getHookStates()
107
+
108
+ }
109
+ catch (e) {
110
+ console.error("Error occured:", e);
111
+ }
112
+ finally {
113
+ // Added this timeout since some tests failed with not connected error.
114
+ await new Promise(resolve => setTimeout(resolve, 4000)); // Wait for four seconds before disconnecting.
115
+ await xrplApi.disconnect();
116
+ }
117
+ }
118
+
119
+ async function updateInfo() {
120
+ console.log(`-----------Update host`);
121
+
122
+ const client = await getHostClient();
123
+ await client.updateRegInfo(10);
124
+ }
125
+
126
+ async function getActiveHosts() {
127
+ console.log(`-----------Getting active hosts`);
128
+
129
+ const regClient = await getRegistryClient();
130
+ const hosts = await regClient.getActiveHosts();
131
+
132
+ console.log("Hosts", hosts || "No active hosts");
133
+ }
134
+
135
+ async function initializeConfigs() {
136
+ console.log(`-----------Initialize configs`);
137
+ let memoData = Buffer.allocUnsafe(40);
138
+ codec.decodeAccountID(evrIssuerAddress).copy(memoData);
139
+ codec.decodeAccountID(foundationAddress).copy(memoData, 20);
140
+
141
+ const initAccount = new evernode.XrplAccount(initializerAddress, initializerSecret);
142
+ await initAccount.makePayment(registryAddress, '1', 'XRP', null,
143
+ [{ type: 'evnInitialize', format: 'hex', data: memoData.toString('hex') }]);
144
+ }
145
+
146
+ async function registerHost(address = hostAddress, secret = hostSecret) {
147
+ const host = await getHostClient(address, secret);
148
+
149
+ if (await host.isRegistered())
150
+ return true;
151
+
152
+ console.log(`-----------Register host`);
153
+
154
+ // Prepare host account for Evernode.
155
+ console.log("Prepare...");
156
+ await host.prepareAccount("mydomain.com");
157
+
158
+ // Get EVRs from the foundation if needed.
159
+ const lines = await host.xrplAcc.getTrustLines(evernode.EvernodeConstants.EVR, evrIssuerAddress);
160
+ if (lines.length === 0 || parseInt(lines[0].balance) < 5120) {
161
+ console.log("Transfer EVRs...");
162
+ const foundationAcc = new evernode.XrplAccount(foundationAddress, foundationSecret);
163
+ await foundationAcc.makePayment(address, "5120", evernode.EvernodeConstants.EVR, evrIssuerAddress);
164
+ }
165
+
166
+ console.log("Register...");
167
+ const instanceCount = 3;
168
+ await host.register("AU", 10000, 512, 1024, instanceCount, 'Intel', 10, 10, "Test desctiption", "testemail@gmail.com", 2);
169
+
170
+ console.log("Lease Offer...");
171
+ for (let i = 0; i < instanceCount; i++)
172
+ await host.offerLease(i, 2, tosHash);
173
+
174
+ // Verify the registration.
175
+ return await host.isRegistered();
176
+ }
177
+
178
+ async function deregisterHost(address = hostAddress, secret = hostSecret) {
179
+ const host = await getHostClient(address, secret);
180
+
181
+ if (!await host.isRegistered())
182
+ return true;
183
+
184
+ console.log(`-----------Deregister host`);
185
+
186
+ await host.deregister();
187
+
188
+ // Burn NFTs.
189
+ const nfts = (await host.xrplAcc.getNfts()).filter(n => n.URI.startsWith(evernode.EvernodeConstants.LEASE_NFT_PREFIX_HEX))
190
+ .map(o => { return { nfTokenId: o.NFTokenID, ownerAddress: host.xrplAcc.address }; });
191
+ for (const nft of nfts) {
192
+ const sold = nft.ownerAddress !== host.xrplAcc.address;
193
+ await host.xrplAcc.burnNft(nft.nfTokenId, sold ? nft.ownerAddress : null);
194
+ console.log(`Burnt ${sold ? 'sold' : 'unsold'} hosting NFT (${nft.nfTokenId}) of ${nft.ownerAddress + (sold ? ' tenant' : '')} account`);
195
+ }
196
+
197
+ // Verify the deregistration.
198
+ return !await host.isRegistered();
199
+ }
200
+
201
+ async function heartbeatHost(address = hostAddress, secret = hostSecret) {
202
+ const host = await getHostClient(address, secret);
203
+
204
+ if (!await host.isRegistered())
205
+ return true;
206
+
207
+ console.log(`-----------Heartbeat host`);
208
+
209
+ await host.heartbeat();
210
+ }
211
+
212
+ async function acquire(scenario) {
213
+ console.log(`-----------Acquire (${scenario})`);
214
+
215
+ const tenant = await getTenantClient();
216
+ await tenant.prepareAccount();
217
+
218
+ // Setup host to watch for incoming acquires.
219
+ const host = await getHostClient();
220
+
221
+ host.on(evernode.HostEvents.AcquireLease, async (r) => {
222
+ console.log("Host received acquire request: ", r.payload);
223
+
224
+ if (scenario !== "timeout") {
225
+ console.log(`Host submitting ${scenario} response...`);
226
+ await new Promise(resolve => setTimeout(resolve, 4000));
227
+
228
+ if (scenario === "success")
229
+ await host.acquireSuccess(r.acquireRefId, r.tenant, { content: "dummy success" });
230
+ else if (scenario === "error") {
231
+ const nft = (await (new evernode.XrplAccount(r.tenant)).getNfts())?.find(n => n.NFTokenID == r.nfTokenId);
232
+ const leaseIndex = Buffer.from(nft.URI, 'hex').readUint16BE(evernode.EvernodeConstants.LEASE_NFT_PREFIX_HEX.length);
233
+
234
+ await host.expireLease(r.nfTokenId, r.tenant);
235
+ await host.offerLease(leaseIndex, r.leaseAmount, tosHash);
236
+ await host.acquireError(r.acquireRefId, r.tenant, r.leaseAmount, "dummy_error");
237
+ }
238
+ }
239
+ })
240
+
241
+ await fundTenant(tenant);
242
+
243
+ try {
244
+ const timeout = (scenario === "timeout" ? 10000 : 30000);
245
+ const result = await tenant.acquireLease(hostAddress, {
246
+ owner_pubkey: "ed5cb83404120ac759609819591ef839b7d222c84f1f08b3012f490586159d2b50",
247
+ contract_id: "dc411912-bcdd-4f73-af43-32ec45844b9a",
248
+ image: "evernodedev/sashimono:hp.latest-ubt.20.04-njs.16",
249
+ config: {}
250
+ }, { timeout: timeout });
251
+ console.log('Tenant received instance ', result.instance);
252
+ }
253
+ catch (err) {
254
+ console.log("Tenant recieved acquire error: ", err.reason)
255
+ }
256
+ }
257
+
258
+ async function extendLease(scenario) {
259
+ console.log(`-----------Extend lease (${scenario})`);
260
+
261
+ const tenant = await getTenantClient();
262
+ await tenant.prepareAccount();
263
+
264
+ // Setup host to watch for incoming acquires.
265
+ const host = await getHostClient();
266
+
267
+ host.on(evernode.HostEvents.ExtendLease, async (r) => {
268
+
269
+ console.log(`Host received extend request for: '${r.nfTokenId}'`);
270
+
271
+ console.log(`Host submitting ${scenario} response...`);
272
+ await new Promise(resolve => setTimeout(resolve, 4000));
273
+
274
+ if (scenario === "success")
275
+ await host.extendSuccess(r.extendRefId, r.tenant, { content: "dummy success" }).catch(console.error);
276
+ else if (scenario === "error") {
277
+ await host.extendError(r.extendRefId, r.tenant, "dummy_error", r.payment.toString()).catch(console.error);
278
+ }
279
+ })
280
+
281
+ await fundTenant(tenant);
282
+
283
+ try {
284
+ const timeout = (scenario === "timeout" ? 10000 : 30000);
285
+ const tokenIDs = (await tenant.xrplAcc.getNfts()).map(n => n.NFTokenID);
286
+ const result = await tenant.extendLease(hostAddress, 2, tokenIDs[0], { timeout: timeout });
287
+ console.log(`Extend ref id: ${result.extendeRefId}, Expiry moments: ${result.expiryMoment}`);
288
+ }
289
+ catch (err) {
290
+ console.log("Tenant recieved extend error: ", err.reason)
291
+ }
292
+ }
293
+ //////////////////////////////////////////////////////////////////////////////////////
294
+
295
+ async function getTenantClient() {
296
+ const client = new evernode.TenantClient(tenantAddress, tenantSecret);
297
+ await client.connect();
298
+ clients.push(client);
299
+ return client;
300
+ }
301
+
302
+ async function getHostClient(address = hostAddress, secret = hostSecret) {
303
+ const client = new evernode.HostClient(address, secret);
304
+ await client.connect();
305
+ clients.push(client);
306
+ return client;
307
+ }
308
+
309
+ async function getRegistryClient() {
310
+ const client = new evernode.RegistryClient(registryAddress, registrySecret);
311
+ await client.connect();
312
+ clients.push(client);
313
+ return client;
314
+ }
315
+
316
+ async function fundTenant(tenant) {
317
+ // Send hosting tokens to tenant if needed.
318
+ const lines = await tenant.xrplAcc.getTrustLines('EVR', evrIssuerAddress);
319
+ if (lines.length === 0 || parseInt(lines[0].balance) < 1) {
320
+ await tenant.xrplAcc.setTrustLine('EVR', evrIssuerAddress, "99999999");
321
+ await new evernode.XrplAccount(foundationAddress, foundationSecret).makePayment(tenantAddress, "1000", 'EVR', evrIssuerAddress);
322
+ }
323
+ }
324
+
325
+ async function getHookStates() {
326
+ const registryClient = new evernode.RegistryClient(registryAddress, registrySecret);
327
+ await registryClient.connect();
328
+ const states = await registryClient.getHookStates();
329
+ console.log(states.length, states);
330
+ }
331
+
332
+ async function getAllHosts() {
333
+ console.log(`-----------Getting all hosts (including inactive)`);
334
+ const registryClient = new evernode.RegistryClient(registryAddress, registrySecret);
335
+ await registryClient.connect();
336
+ const hosts = await registryClient.getAllHosts();
337
+ console.log(hosts.length, hosts);
338
+ }
339
+
340
+
341
+ async function getAllConfigs() {
342
+ console.log(`-----------Getting all configs`);
343
+ const registryClient = new evernode.RegistryClient(registryAddress, registrySecret);
344
+ await registryClient.connect();
345
+ const configs = await registryClient.getAllConfigs();
346
+ console.log(configs.length, configs);
347
+ }
348
+
349
+ async function getHostInfo() {
350
+ const host = await getHostClient();
351
+ const hostInfo = await host.getHostInfo();
352
+ console.log(hostInfo);
353
+ return hostInfo;
354
+ }
355
+
356
+ async function pruneDeadHost(address = hostAddress) {
357
+ console.log(`-----------Prune host`);
358
+
359
+ // Create a cleint to send the prune request (the client can be a tenant or another host).
360
+ const tenantClient = await getTenantClient();
361
+ await tenantClient.pruneDeadHost(address);
362
+ }
363
+
364
+ async function transferHost(address = transfereeAddress) {
365
+
366
+ const host = await getHostClient(hostAddress, hostSecret);
367
+
368
+ if (!await host.isRegistered()) {
369
+ console.log("Host is not registered.");
370
+ return true;
371
+ }
372
+
373
+ console.log(`-----------Transfer host`);
374
+
375
+ // Get EVRs from the foundation if needed.
376
+ const lines = await host.xrplAcc.getTrustLines(evernode.EvernodeConstants.EVR, evrIssuerAddress);
377
+ if (lines.length === 0 || parseInt(lines[0].balance) < 1) {
378
+ console.log("Transfer EVRs...");
379
+ const foundationAcc = new evernode.XrplAccount(foundationAddress, foundationSecret);
380
+ await foundationAcc.makePayment(hostAddress, "1", evernode.EvernodeConstants.EVR, evrIssuerAddress);
381
+ }
382
+
383
+ console.log("Initiating a transfer...");
384
+ await host.transfer(address);
385
+
386
+ // Burn NFTs.
387
+ const nfts = (await host.xrplAcc.getNfts()).filter(n => n.URI.startsWith(evernode.EvernodeConstants.LEASE_NFT_PREFIX_HEX))
388
+ .map(o => { return { nfTokenId: o.NFTokenID, ownerAddress: host.xrplAcc.address }; });
389
+ for (const nft of nfts) {
390
+ const sold = nft.ownerAddress !== host.xrplAcc.address;
391
+ await host.xrplAcc.burnNft(nft.nfTokenId, sold ? nft.ownerAddress : null);
392
+ console.log(`Burnt ${sold ? 'sold' : 'unsold'} hosting NFT (${nft.nfTokenId}) of ${nft.ownerAddress + (sold ? ' tenant' : '')} account`);
393
+ }
394
+
395
+ }
396
+
397
+ async function requestRebate() {
398
+ const host = await getHostClient(hostAddress, hostSecret);
399
+
400
+ if (!await host.isRegistered()) {
401
+ console.log("Host is not registered.");
402
+ return true;
403
+ }
404
+
405
+ console.log(`-----------Request rebate`);
406
+ await host.requestRebate();
407
+ }
408
+
409
+ app();