evernode-js-client 0.4.51 → 0.5.0

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