cardano-wallet-js
Version:
javascript/typescript client for the official cardano-wallet api
1,597 lines (1,491 loc) • 47.8 kB
text/typescript
import * as chai from 'chai';
import * as chaiAsPromised from 'chai-as-promised';
chai.use(chaiAsPromised);
const expect = chai.expect;
import 'mocha';
import { ApiTransactionDirectionEnum, ApiTransactionStatusEnum, WalletsDelegationActiveStatusEnum } from '../models';
import { Seed } from '../utils';
import { WalletServer } from '../wallet-server';
import { KeyRoleEnum } from '../wallet/key-wallet';
import * as dotenv from "dotenv";
import { ShelleyWallet } from '../wallet/shelley-wallet';
import { TransactionWallet } from '../wallet/transaction-wallet';
import { LocalCluster } from '../config/network.config';
dotenv.config();
describe('Cardano wallet API', function () {
this.timeout(0);
let walletServer: WalletServer;
let wallets = [
{
"passphrase": "shellley-no-delegation",
"mnemonic_sentence": ["over", "decorate", "flock", "badge", "beauty", "stamp", "chest", "owner", "excess", "omit", "bid", "raccoon", "spin", "reduce", "rival"],
"address_pool_gap": 20,
"state": {
"status": "ready"
},
"balance": {
"reward": {
"quantity": 0,
"unit": "lovelace"
},
"total": {
"quantity": 100000000000,
"unit": "lovelace"
},
"available": {
"quantity": 100000000000,
"unit": "lovelace"
}
},
"name": "shelley-no-delegation",
"delegation": {
"next": [] as any[],
"active": {
"status": "not_delegating"
}
},
"id": "2a793eb367d44a42f658eb02d1004f50c14612fd",
"tip": {
"height": {
"quantity": 15010,
"unit": "block"
},
"time": "2021-03-31T14:17:56.2Z",
"epoch_number": 590,
"absolute_slot_number": 29511,
"slot_number": 11
},
"assets": {
"total": [] as any[],
"available": [] as any[]
},
"txs": [
{
"inserted_at": {
"height": {
"quantity": 9,
"unit": "block"
},
"time": "2021-03-31T22:28:15.2Z",
"epoch_number": 1,
"absolute_slot_number": 66,
"slot_number": 16
},
"status": "in_ledger",
"withdrawals": [] as any[],
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"inputs": [
{
"id": "1669654d59d76084dfd7c14a0960d3de56f81d24e5a19351853ea0be434b3ed1",
"index": 0
}
],
"direction": "incoming",
"fee": {
"quantity": 0,
"unit": "lovelace"
},
"outputs": [
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v9m7qqkehg8y08wkw0p8qrnkrsqdj4tew78r7vqt0e4rfyg6e628h",
"assets": [] as any[]
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vxk7zajwxrj7d63d857leyr5xjns5eqwu90t7av9s3qansgy3n03h",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vxzfrx9fqmr9rksy3d3p5dt4s7kuzvxecptp4g6k6jyjf0c4wqrqv",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v9fgg22y8zg9ew0sr8zecem3awlp8y2nkz06pj9rp0jze2g8yaz8s",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vxqxrkn4m9gkkw9zjxv0ucclakl9yk0mf58szfnexv6gp4cqd8lmc",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vxyh67eruv8lk7j5cd4uxxlwzhh5s37agmq82g8yly8d6ysgvf36v",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v8fh0twhfl8asg2umdrghc0atawtlsvgtn4w2em5cdka5nq9htxna",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v9jxt6pyruyjp09hcgmfz842cewgd76rft7kc2th7xaq74qfcrflh",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vynncsy67q5gzuextklwhgg7fqesm28lk7k3tryy4j9cmfsepfas7",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vxwghnp98zdnqwxhsjccm4w7kcz5u5cazhe6f3dyes4g7pgf6f5lp",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v8kjvptz7htc03uck4a6s78cvuetqgwhqyt5kf7mtleta8ce94xxu",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vxy82rpx84s58vy74y34gy88lw0x0hvttuap6599nujp3cgdqvwsh",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v8twacd3svulf74kxg4us59yrvp3lt4ajvl90w3u8vdjx2cajgkgy",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vxwz08f2nd28eagctmpfxzcv8xn5lg8d4wjpx20ypfn93zcs8uucg",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vx9n2zkkgc6gqy2j3kkyfxjf27mtm98lx0vnwhj5jz5uasq9yl5hk",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v9zsagjclpwam9p6humeg87x7r8r268kf5k8h5kun0sh3rgs7536w",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vyjqralj63q5xyw03sxxeyc8svfk3ymrw2gwj79p0p00lxcapajam",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vx7r3cy4uanwjgqjyttnymqkqsrt448ezylrkkdvqrjzxzssn75lu",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vydvk9kl2tqf5wkxajalkgf8kemjak3glhrm4d5l99jwhysfqx5ts",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vy7qf5ctc8ydaz0d0g8dwy05eq8d4mtenlz377mzpec45sgk3f5q0",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v9c36pmak8t8a8ra8jz347rmv3vxxq4mvc3ccmn9aez9glgq5mwq6",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vy3f4vhj8xt9x8t93np94uak2kptltuw2spr0a7jy0jnftgzskwy5",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v8y20cs4h8n4jcf6fgpkf9yea35r8sawazk7r7rktf9w2hssz5yu7",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v94ywg549gh0zs4g9fmty4tgm0cq5a95lsm29lccpezks3qf9w3hg",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v876apusu8nfs6d6apgmj6vp5lcjjxmlvlc2sj9y98wtv5c7qc2yq",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vxyht88xde2nj25wfm63a0c24tvs2xulzpcvvhm4z4sjxsc0rfvah",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v95k6agq60kjdpf9uh68nz32wayqdf7m9zgqzeqc64mdefstkmfj8",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vyshpxd63rwpg7l9qt3atsfnf2mgw749zuz9sk5ytk5jtxctw66gt",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vy2qapgq2m8f6rawzlh9f9e4haz0h6rxsk4rul6xec29rsc96c9nt",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v946mhp66he3x8vwltpakf9m3k4nrs85k6gpxg8pprhmhyq5n8erd",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vyzngcwg46eemhu9uduvu7nwmjhzc5grnzl9dtftmhjf9fc8vqq7a",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v8qfgyumu7n0tsje3m9aednwgm9vut79h8l02dr99rtjvssps5qr5",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vyhcdseax6mjcrxz2c64p2czmgqtpvzptgtjhdlykm0ppmg8emn7s",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v8qafj5c5yms4wcquvq6mznnhv9qdtpemr5y0dw9m885rqs2cjg7e",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v92gawsmqg5qguugclyearf2qrv6m9sjhsy20qdxp7a76dsg6yn5f",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vxwpcgf27r7nnwf983zzc8zgh0mgh3jgdhugps7cvuy0mcgyzs9sa",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vxe02c3trl78295wmdymgc02ep4l299t80msq4zk70dxtuckl9k29",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v8kt5a9fu6emsqwn9pmkzxwf5cws8nnyk72nsseqldt7r2cc40gw2",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vxzh0n0kleyazj8uvla92vvxhydwrpmfnsnuq5paa45lk9smr9pxc",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v9rw4mn2hlgcvhw96p25r98vgppk2xpyq78f3mrkufwhxncw6a0qs",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vy02rescazffxy9447eh3pcgvy22kywdwatmp4ehu2cy5dgtwd2fr",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v9csrpk0l9rh5y3xx0qwjpq97ag00cp3qunlgdwmzwfd0nqrqtqny",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vxed6d24ug6h5xsvr5prnzsyur5ux38l2cw6rva84a4e9ccm42vm2",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vyqysc73p93ecrnea6jx98u09ueuq39kk52z0f57vzl5vjqqzdw3p",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v89tyleg3qxqg00u9qsvmykyy3dfutcl2qsu5wnsm2fj33q5rdr5m",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vxq95kjh5yf6t4uy9ytlu5mzp6kgxa3wvszv5fzx99k92hc0d248y",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v8mpmyf5fj2hgvfapgwc3g2tvw4revnpn4xy6ezrprsjencrsaudf",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1v8qmyqyacms90zr5npww4zl3gh5sxe4afmzdzr6temtcw4surwdhx",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vy074kt6eytqra6gh58ju70u76n5gujm09q6ej3hqpcw5gc9vhktm",
"assets": []
},
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1vy3qlm7k4chn3p9zh37u0mpny420n5r7854yujc30lsyf7gk2ppyf",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1vxv60se24f26v2xex66nnuqa2s2nrr0v3094uk0vwxhkjkc3mwljs",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1vyuxc75xmzzy7sy955pyz4tqg0ycgttjcv2u39ay929q2yq8h7umy",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1vx7hsxtpw3vae52avvwy24j4xj7kpcvpxqzs4m24h0r8ngc9e6rd6",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1v9qw9xflglesswd8prfagn3e3rauu7hyn7cnd6fw7y2ht3gdah3qf",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1vxu5sa6effs76vgayk9n5wfdaprmwt96g6wrfxaz7nhynncl3a9j2",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1vym7k0fkzfr6q6ykvd7wfdn35aqyx6mnewsh0ws2zdh7l5spt00my",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1v99wq77g6t2jvmy420r22hqd028s7079p8ssgz45ehxnexqjg5qwx",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1vy7ptj37j2j09agtqa822fdqpf82e5ws2xtzd0xn8xeygpqu6pvqu",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1vxztq9lhj9k7v7r3ye930uvpwarc8cps53qjcq0q35t4glcx9a3m7",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1vy97tuy34tz42jg60dyft9qp89msyn9vsdd730nmemk5s4qzu5tjf",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1v9qhhts5p86qj9ursda7y22rv5m0mcjsuqdct7gulnfkhps9ysqeg",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1vy835wr2cgu7ypff304hana5j9c8nuald28ktldn53wzedsxxzwkv",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1vx8uckm9s4ty0ste2mk6tj77h0pcrfystmrmthns5nls8rqallrvy",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1v8jdrahgwxyc26ptdtfgm2qrrpath6p5wdhcrqtcj94vkts72czsg",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1vyx0myhmrd7dj3l6zkyhmag7shmdd48yhylm34u2lud3pdcehesq2",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1vy6sqevluqp7lftl88hup6h4pu3ggeexnwrmqkfvewtvuvsn9ftn5",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1vxtk0aguznvjqqatj9cfdx0xhmtp52hqxky87yusjsn34cc7kh3k6",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1vx48m9dn30hgm840g9s30yyjlv5dsqfh429xn89sskunr4q46q3yd",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1v8ecg4npdm76m8gdmnvnze4hukmgn7yy4au5ta7447kh4vq2pkt30",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1vx9j2tk307qzkkzk68x6h57r26fj802g9gja268r8z5umpgnql9fw",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1v9u6pzee8v733z6cptppjq6wyprztqpp58kzfaz8qypphdsummuyt",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1v9fwez477qgc9wm72c78e46q0nvfujcefqklsea4kdn784stk7ufq",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1v957kxplc6pq8j7xajm2kcydn3cj8zf3a7u55swysah8ldq6narjd",
"assets": []
},
{
"amount": {
"quantity": 100000000000,
"unit": "lovelace"
},
"address": "addr1v98d5fszt89zk9fw4jjnuptk67n8z0707v8gqr03c88y8uc7plull",
"assets": []
}
],
"metadata": null as any,
"depth": {
"quantity": 170,
"unit": "block"
},
"id": "1d9025cddb72f9e15510dff6e67d1d7718704f19d6b66f1f4232dc5847f921d4",
"deposit": {
"quantity": 0,
"unit": "lovelace"
},
"mint": [] as any[]
}
]
},
{
"passphrase": "shelley-small-coins",
"mnemonic_sentence": ["either", "flip", "maple", "shift", "dismiss", "bridge", "sweet", "reveal", "green", "tornado", "need", "patient", "wall", "stamp", "pass"],
"address_pool_gap": 20,
"state": {
"status": "ready"
},
"balance": {
"reward": {
"quantity": 0,
"unit": "lovelace"
},
"total": {
"quantity": 43000000,
"unit": "lovelace"
},
"available": {
"quantity": 43000000,
"unit": "lovelace"
}
},
"name": "shelley-small-coins",
"delegation": {
"next": [] as any[],
"active": {
"status": "not_delegating"
}
},
"id": "60bb5513e4e262e445cf203db9cf73ba925064d2",
"tip": {
"height": {
"quantity": 15010,
"unit": "block"
},
"time": "2021-03-31T14:17:56.2Z",
"epoch_number": 590,
"absolute_slot_number": 29511,
"slot_number": 11
},
"assets": {
"total": [] as any[],
"available": [] as any[]
}
},
{
"passphrase": "shelley-100-utxo",
"mnemonic_sentence": ["radar", "scare", "sense", "winner", "little", "jeans", "blue", "spell", "mystery", "sketch", "omit", "time", "tiger", "leave", "load"],
"address_pool_gap": 20,
"state": {
"status": "ready"
},
"balance": {
"reward": {
"quantity": 0,
"unit": "lovelace"
},
"total": {
"quantity": 10000100000000,
"unit": "lovelace"
},
"available": {
"quantity": 10000100000000,
"unit": "lovelace"
}
},
"name": "shelley-100-utxo",
"delegation": {
"next": [],
"active": {
"status": "not_delegating"
}
},
"id": "868d04759fd222ac776484888d4bcd462d146772",
"tip": {
"height": {
"quantity": 15010,
"unit": "block"
},
"time": "2021-03-31T14:17:56.2Z",
"epoch_number": 590,
"absolute_slot_number": 29511,
"slot_number": 11
},
"assets": {
"total": [],
"available": []
}
},
{
"passphrase": "icarus-500-address-index",
"mnemonic_sentence": ["erosion", "ahead", "vibrant", "air", "day", "timber", "thunder", "general", "dice", "into", "chest", "enrich", "social", "neck", "shine"],
"address_pool_gap": 20,
"state": {
"status": "ready"
},
"balance": {
"reward": {
"quantity": 0,
"unit": "lovelace"
},
"total": {
"quantity": 0,
"unit": "lovelace"
},
"available": {
"quantity": 0,
"unit": "lovelace"
}
},
"name": "icarus-500-address-index",
"delegation": {
"next": [],
"active": {
"status": "not_delegating"
}
},
"id": "9ada973fd29d6b3d096ab361ef5fd082576bdbe3",
"tip": {
"height": {
"quantity": 15010,
"unit": "block"
},
"time": "2021-03-31T14:17:56.2Z",
"epoch_number": 590,
"absolute_slot_number": 29511,
"slot_number": 11
},
"assets": {
"total": [],
"available": []
}
},
{
"passphrase": "ledger-1234567890",
"mnemonic_sentence": ["vague", "wrist", "poet", "crazy", "danger", "dinner", "grace", "home", "naive", "unfold", "april", "exile", "relief", "rifle", "ranch", "tone", "betray", "wrong"],
"address_pool_gap": 20,
"state": {
"status": "ready"
},
"balance": {
"reward": {
"quantity": 0,
"unit": "lovelace"
},
"total": {
"quantity": 0,
"unit": "lovelace"
},
"available": {
"quantity": 0,
"unit": "lovelace"
}
},
"name": "ledger-2",
"delegation": {
"next": [],
"active": {
"status": "not_delegating"
}
},
"id": "4ea40ca5323bad2efb77c68ae42e5bb7205ab5e6",
"tip": {
"height": {
"quantity": 15010,
"unit": "block"
},
"time": "2021-03-31T14:17:56.2Z",
"epoch_number": 590,
"absolute_slot_number": 29511,
"slot_number": 11
},
"assets": {
"total": [],
"available": []
}
}
];
let utxoStats = {
"distribution": {
"10000000000000000": 0,
"100000000000000": 0,
"1000000000000": 0,
"10000000000": 0,
"100000000": 0,
"1000000": 100,
"10000": 0,
"100": 0,
"1000000000": 0,
"100000000000": 100,
"10": 0,
"45000000000000000": 0,
"1000": 0,
"10000000000000": 0,
"1000000000000000": 0,
"100000": 0,
"10000000": 0
},
"scale": "log10",
"total": {
"quantity": 10000100000000,
"unit": "lovelace"
}
}
let fee = {
"estimated_min": {
"quantity": 130500,
"unit": "lovelace"
},
"deposit": {
"quantity": 0,
"unit": "lovelace"
},
"minimum_coins": [
{
"quantity": 1000000,
"unit": "lovelace"
}
],
"estimated_max": {
"quantity": 158700,
"unit": "lovelace"
}
};
let tx = {
"status": "pending",
"withdrawals": [] as any[],
"amount": {
"quantity": 1130500,
"unit": "lovelace"
},
"inputs": [
{
"amount": {
"quantity": 12000000,
"unit": "lovelace",
},
"address": "addr1vxlassd5m5z2757zqkj9vsfyqnjpzqa79tfclypa5ltwtgcfsgk0y",
"id": "d7700008431233698659a03ad6e0fe0baf00dddfc12c03c0a1a6bab42124652e",
"assets": [] as any[],
"index": 3,
},
],
"direction": "outgoing",
"fee": {
"quantity": 130500,
"unit": "lovelace"
},
"outputs": [
{
"amount": {
"quantity": 1000000,
"unit": "lovelace"
},
"address": "addr1q99d7qnpvw53stx5ppave9n2aarwxar552v55p4xnhjy6me59kkfl90wf7f9vlm99fek6e9l5zh65td8jhw63hn9skqq9hd2f7",
"assets": [] as any[]
},
{
"amount": {
"quantity": 10869500,
"unit": "lovelace"
},
"address": "addr1q8s2ev94k83lsctwyzj0kklgzlt02hv75z6cjqtpqxlafpq7vjhxlzaazkhgv47za494arh3lqhz997hat2vveuzlvfse80cay",
"assets": []
}
],
"expires_at": {
"time": "2021-04-01T00:14:55Z",
"epoch_number": 728,
"absolute_slot_number": 36440,
"slot_number": 40
},
"pending_since": {
"height": {
"quantity": 190,
"unit": "block"
},
"time": "2021-03-31T22:14:54.8Z",
"epoch_number": 8,
"absolute_slot_number": 439,
"slot_number": 39
},
"metadata": null as any,
"id": "99ed1d6c8c7f557d1631236e132c0ca73404a9928e47457204816065163cc967",
"deposit": {
"quantity": 0,
"unit": "lovelace"
},
"mint": [] as any[]
};
let poolMaintenanceAction = {
"gc_stake_pools": {
"status": "not_applicable"
}
};
let delegationFee = {
"estimated_min": {
"quantity": 125300,
"unit": "lovelace"
},
"deposit": {
"quantity": 1000000,
"unit": "lovelace"
},
"minimum_coins": [] as any[],
"estimated_max": {
"quantity": 139400,
"unit": "lovelace"
}
};
let afterDelegation = {
"next": [] as any[],
"active": {
"status": "delegating",
"target": "pool1as50x0wtumtyqzs7tceeh5ry0syh8jnvpnuu9wlxswxuv48sw4w"
}
};
let poolStake = [
{
"flags": [] as any[],
"metrics": {
"saturation": 0.8769869515692323,
"non_myopic_member_rewards": {
"quantity": 0,
"unit": "lovelace"
},
"produced_blocks": {
"quantity": 286,
"unit": "block"
},
"relative_stake": {
"quantity": 29.23,
"unit": "percent"
}
},
"retirement": {
"epoch_start_time": "2021-07-31T11:51:50Z",
"epoch_number": 1000000
},
"cost": {
"quantity": 0,
"unit": "lovelace"
},
"margin": {
"quantity": 10,
"unit": "percent"
},
"pledge": {
"quantity": 1000000000000,
"unit": "lovelace"
},
"id": "pool1hvg5evmawhaq2fsr9rprtg76u226x0gt5e62t6c78etgu2j7xtn"
},
{
"flags": [] as any[],
"metrics": {
"saturation": 0.6474533657431686,
"non_myopic_member_rewards": {
"quantity": 0,
"unit": "lovelace"
},
"produced_blocks": {
"quantity": 298,
"unit": "block"
},
"relative_stake": {
"quantity": 21.58,
"unit": "percent"
}
},
"cost": {
"quantity": 0,
"unit": "lovelace"
},
"margin": {
"quantity": 10,
"unit": "percent"
},
"pledge": {
"quantity": 2000000000000,
"unit": "lovelace"
},
"id": "pool1as50x0wtumtyqzs7tceeh5ry0syh8jnvpnuu9wlxswxuv48sw4w"
},
{
"flags": [],
"metrics": {
"saturation": 0.8740602172660131,
"non_myopic_member_rewards": {
"quantity": 0,
"unit": "lovelace"
},
"produced_blocks": {
"quantity": 296,
"unit": "block"
},
"relative_stake": {
"quantity": 29.14,
"unit": "percent"
}
},
"retirement": {
"epoch_start_time": "2021-04-18T07:51:50Z",
"epoch_number": 100000
},
"cost": {
"quantity": 0,
"unit": "lovelace"
},
"margin": {
"quantity": 10,
"unit": "percent"
},
"pledge": {
"quantity": 1000000000000,
"unit": "lovelace"
},
"id": "pool1k3tk3sdzmf9az04u4g0229qgak33mnppwewvh4q8ek5ly09nqjm"
}
];
let txRaw = {
"type": "TxBodyMary",
"description": "",
"cborHex": "82a400818258202d7928a59fcba5bf71c40fe6428a301ffda4d2fa681e5357051970436462b89400018282583900c0e88694ab569f42453eb950fb4ec14cb50f4d5d26ac83fdec2c505d818bcebf1df51c84239805b8a330d68fdbc3c047c12bb4c3172cb9391a002b335f825839003d2d9ceb1a47bc1b62b7498ca496b16a7b4bbcc6d97ede81ba8621ebd6d947875fcf4845ef3a5f08dd5522581cf6de7b9c065379cbb3754d1a001e8480021a00029361031a01672b7ef6"
};
before('Initializing the test cluster ...', async function () {
walletServer = WalletServer.init(`http://${process.env.TEST_WALLET_HOST}:${process.env.TEST_WALLET_PORT}/v2`);
for (let i = 0; i < wallets.length - 1; i++) {
const w = wallets[i];
await walletServer.createOrRestoreShelleyWallet(w.name, w.mnemonic_sentence, w.passphrase);
}
});
after('Cleaning the test cluster ...', async function () {
let list = await walletServer.wallets();
for (let i = 0; i < list.length; i++) {
const wallet = list[i];
await wallet.delete();
}
})
describe('wallet', function () {
it('should create a wallet', async function () {
let mnemonic_sentence = Seed.toMnemonicList(Seed.generateRecoveryPhrase());
let passphrase = 'tangocrypto';
let name = 'tangocrypto-wallet';
let wallet = await walletServer.createOrRestoreShelleyWallet(name, mnemonic_sentence, passphrase);
expect(wallet.balance.total.quantity).equal(0);
expect(wallet.balance.available.quantity).equal(0);
expect(wallet.balance.reward.quantity).equal(0);
expect(wallet.name).equal(name);
expect(wallet.id).lengthOf(40);
expect(wallet.passphrase.last_updated_at).be.a('string');
});
it("should resotre a wallet", async function () {
let w = wallets[wallets.length - 1];
let wallet = await walletServer.createOrRestoreShelleyWallet(w.name, w.mnemonic_sentence, w.passphrase);
expect(wallet.id).equal(w.id);
expect(wallet.name).equal(w.name);
expect(wallet.passphrase.last_updated_at).be.a('string');
});
it("should throw an 'wallet_already_exist' error", async function () {
let w = wallets[0];
await expect(walletServer.createOrRestoreShelleyWallet(w.name, w.mnemonic_sentence, w.passphrase)).to.eventually.rejectedWith(Error)
.and.have.nested.property('response.data.code').equal('wallet_already_exists');
});
it("should get a list of wallets", async function () {
let ls = await walletServer.wallets();
let ids = ls.map(w => w.id);
expect(ls.length).least(wallets.length);
for (let i = 0; i < wallets.length; i++) {
const id = wallets[i].id;
expect(ids).include(id);
}
});
it("should get utxo wallet statistics", async function () {
let w = wallets.find(w => w.id == '868d04759fd222ac776484888d4bcd462d146772');
let wallet = await walletServer.getShelleyWallet(w.id);
let statistics = await wallet.getUtxoStatistics();
expect(statistics).deep.equal(utxoStats)
});
it("should get a wallet", async function () {
let w = wallets.find(w => w.id === '2a793eb367d44a42f658eb02d1004f50c14612fd');
let wallet = await walletServer.getShelleyWallet(w.id);
expect(wallet.id).equal(w.id);
expect(wallet.name).equal(w.name);
expect(wallet.passphrase.last_updated_at).be.a('string');
});
it("shuld remove a wallet", async function () {
let ls = await walletServer.wallets();
let wallet = ls.find(w => w.name == 'tangocrypto-wallet');
await wallet.delete();
await expect(walletServer.getShelleyWallet(wallet.id)).to.eventually.rejectedWith(Error)
.and.have.nested.property('response.status').equal(404);
})
it("should rename a wallet", async function () {
let w = wallets.find(w => w.id === '60bb5513e4e262e445cf203db9cf73ba925064d2');
let name = 'new-name';
let wallet = await walletServer.getShelleyWallet(w.id);
wallet = await wallet.rename(name);
expect(wallet.name).equal(name);
wallet = await wallet.rename(w.name);
expect(wallet.name).equal(w.name);
});
it("should change a wallet passphrase", async function () {
let w = wallets.find(w => w.id === '60bb5513e4e262e445cf203db9cf73ba925064d2');
let newPassphrase = 'new-passphrase';
let wallet = await walletServer.getShelleyWallet(w.id);
let lastUpdatedAt = wallet.passphrase.last_updated_at;
wallet = await wallet.updatePassphrase(w.passphrase, newPassphrase);
expect(wallet.passphrase.last_updated_at).not.equal(lastUpdatedAt);
await wallet.updatePassphrase(newPassphrase, w.passphrase);
});
});
describe('address', function () {
it('should get wallet addresses', async function () {
let w = wallets.find(w => w.id === '60bb5513e4e262e445cf203db9cf73ba925064d2');
let wallet = await walletServer.getShelleyWallet(w.id);
let addresses = await wallet.getAddresses();
expect(addresses.length).least(20);
});
it('should get wallet unused addresses', async function () {
let w = wallets.find(w => w.id === '60bb5513e4e262e445cf203db9cf73ba925064d2');
let wallet = await walletServer.getShelleyWallet(w.id);
let addresses = await wallet.getUnusedAddresses();
expect(addresses).be.an('array');
expect(addresses).lengthOf.at.least(wallet.address_pool_gap);
});
it('should get wallet used addresses', async function () {
let w = wallets.find(w => w.id === '60bb5513e4e262e445cf203db9cf73ba925064d2');
let wallet = await walletServer.getShelleyWallet(w.id);
let addresses = await wallet.getUsedAddresses();
expect(addresses).be.an('array');
});
it('should get first wallet\'s address external verification key', async function () {
let id = '2a793eb367d44a42f658eb02d1004f50c14612fd';
let addr = 'addr_vk1rfx8dy8dh3t04234qu98gcuu9sqenpvzqx506tfwh9c26vd02fwqmx69lx'; // external verification address at 0
let wallet = await walletServer.getShelleyWallet(id);
let address = await wallet.getAddressExternalVerificationKey(0);
expect(address.key).equal(addr);
expect(address.role).equal(KeyRoleEnum.AddressExternal);
});
it('should get first wallet\'s stake verification key', async function () {
let id = '2a793eb367d44a42f658eb02d1004f50c14612fd';
let addr = 'stake_vk1jj0une4hu8sjaye6cdw7tft9eynykzk9kccmfadzz4ytcmt9v9hs2k6s7u'; // stake address at 0
let wallet = await walletServer.getShelleyWallet(id);
let stake = await wallet.getStakeVerificationKey(0);
expect(stake).have.property('key').equal(addr);
expect(stake).have.property('role').equal(KeyRoleEnum.Stake);
});
it('should get wallet next unused address', async function () {
let id = '4ea40ca5323bad2efb77c68ae42e5bb7205ab5e6';
let addr = 'addr1q99q78gt2898zgu2dcswf2yuxj6vujcqece38rycc7wsncl5lx8y8swrhrt93dt5kykkhtd57gpc0hc8820vh6cy8n6su9tsj8'; // next unused address;
let wallet = await walletServer.getShelleyWallet(id);
let addresses = (await wallet.getAddresses()).map(addr => addr.address);
let address = await wallet.getNextAddress();
expect(address.address).equal(addr);
expect(address.used()).equal(false);
expect(addresses).not.include(address.address);
});
});
describe('stake pool', function () {
it("should return stake pool ranking list by member rewards", async function () {
let stake = 1000000000;
let pools = await walletServer.getStakePools(stake);
let rewards = pools.map(p => p.metrics.non_myopic_member_rewards.quantity);
expect(rewards).equal(rewards.sort().reverse());
});
it("should return stake pools maintenance actions", async function(){
let maintenanceActions = await walletServer.stakePoolMaintenanceActions();
expect(maintenanceActions).deep.equal(poolMaintenanceAction);
});
it("should trigger garbage collection", async function(){
await walletServer.triggerStakePoolGarbageCollection();
});
it("should estimate delegation fee", async function(){
let w = wallets.find(w => w.id == '868d04759fd222ac776484888d4bcd462d146772');
let wallet = await walletServer.getShelleyWallet(w.id);
let fee = await wallet.estimateDelegationFee();
expect(fee).deep.equal(delegationFee);
});
it("should delegate to stake pool", async function(){
let pool = (await walletServer.getStakePools()).find(p => p.id == 'pool1as50x0wtumtyqzs7tceeh5ry0syh8jnvpnuu9wlxswxuv48sw4w');
let w = wallets.find(w => w.id == '2a793eb367d44a42f658eb02d1004f50c14612fd');
let wallet = await walletServer.getShelleyWallet(w.id);
let transaction = await wallet.delegate(pool.id, w.passphrase);
let inputAmount = transaction.inputs.map(i => i.amount.quantity).reduce((a, b) => a + b);
let outputAmount = transaction.outputs.map(o => o.amount.quantity).reduce((a, b) => a + b);
let spent = transaction.amount.quantity; // fee + deposit
expect(ApiTransactionStatusEnum.Pending).equal(transaction.status);
expect(ApiTransactionDirectionEnum.Outgoing).equal(transaction.direction);
expect(outputAmount + spent).equal(inputAmount);
await waitUntilTxFinish(transaction.id, wallet);
transaction = await wallet.getTransaction(transaction.id);
if(transaction.status == ApiTransactionStatusEnum.InLedger) {
await wallet.refresh();
if(wallet.delegation.next.length > 0 ) {
let epoch = wallet.delegation.next.sort((a, b) => -(a.changes_at.epoch_number - b.changes_at.epoch_number)).map(d => d.changes_at.epoch_number)[0];
await waitUntilEpoch(epoch, walletServer);
await wallet.refresh();
}
let delegation = wallet.getDelegation();
expect(delegation).deep.equal(afterDelegation);
}
});
it("should withdraw wallet rewards", async function(){
let w = wallets.find(w => w.id == '2a793eb367d44a42f658eb02d1004f50c14612fd');
let wallet = await walletServer.getShelleyWallet(w.id);
let addresses = (await wallet.getUsedAddresses()).slice(0, 1);
let amounts = [wallet.getRewardBalance()];
let availableBalance = wallet.getAvailableBalance();
let transaction = await wallet.withdraw(w.passphrase, addresses, amounts);
let inputAmount = transaction.inputs.map(i => i.amount.quantity).reduce((a, b) => a + b);
let outputAmount = transaction.outputs.map(o => o.amount.quantity).reduce((a, b) => a + b);
let fee = transaction.fee.quantity;
expect(ApiTransactionStatusEnum.Pending).equal(transaction.status);
expect(ApiTransactionDirectionEnum.Outgoing).equal(transaction.direction);
expect(outputAmount + fee).equal(inputAmount);
await waitUntilTxFinish(transaction.id, wallet);
transaction = await wallet.getTransaction(transaction.id);
if(transaction.status == ApiTransactionStatusEnum.InLedger) {
await wallet.refresh();
let newAvailableBalance = wallet.getAvailableBalance() + fee;
expect(availableBalance + amounts[0]).equal(newAvailableBalance);
}
});
it("should stop delegating", async function(){
let w = wallets.find(w => w.id == '2a793eb367d44a42f658eb02d1004f50c14612fd');
let wallet = await walletServer.getShelleyWallet(w.id);
let transaction = await wallet.stopDelegation(w.passphrase);
let inputAmount = transaction.inputs.map(i => i.amount.quantity).reduce((a, b) => a + b);
let outputAmount = transaction.outputs.map(o => o.amount.quantity).reduce((a, b) => a + b);
let amount = transaction.amount.quantity;
expect(ApiTransactionStatusEnum.Pending).equal(transaction.status);
expect(ApiTransactionDirectionEnum.Incoming).equal(transaction.direction);
expect(amount + inputAmount).equal(outputAmount);
await waitUntilTxFinish(transaction.id, wallet);
transaction = await wallet.getTransaction(transaction.id);
if(transaction.status == ApiTransactionStatusEnum.InLedger) {
await wallet.refresh();
if(wallet.delegation.next.length > 0 ) {
let epoch = wallet.delegation.next.sort((a, b) => -(a.changes_at.epoch_number - b.changes_at.epoch_number)).map(d => d.changes_at.epoch_number)[0];
await waitUntilEpoch(epoch, walletServer);
await wallet.refresh();
}
let delegation = wallet.getDelegation();
let rewards = wallet.getRewardBalance();
expect(rewards).equal(0);
expect(delegation.active.status).equal(WalletsDelegationActiveStatusEnum.NotDelegating);
}
});
});
describe('transaction', function () {
let tx: TransactionWallet = null;
it('should get tx list', async function(){
let w = wallets.find(w => w.id == '2a793eb367d44a42f658eb02d1004f50c14612fd');
let wallet = await walletServer.getShelleyWallet(w.id);
let start = new Date(2021, 0, 1); // January 1st 2021;
let end = new Date(Date.now());
let transactions = await wallet.getTransactions(start, end);
tx = transactions[0];
transactions.filter(tx => tx.metadata).forEach(t => {
let metadata = Seed.reverseMetadata(t.metadata, "array");
expect(metadata).not.empty;
})
expect(transactions).be.an('array');
});
it('should get tx details', async function () {
let w = wallets.find(w => w.id == '2a793eb367d44a42f658eb02d1004f50c14612fd');
let wallet = await walletServer.getShelleyWallet(w.id);
let transaction = await wallet.getTransaction(tx.id);
expect(tx.id).equal(transaction.id);
expect(tx.status).equal(transaction.status);
expect(tx.direction).equal(transaction.direction);
expect(tx.depth.unit).equal(transaction.depth.unit);
expect(tx.fee).deep.equal(transaction.fee);
expect(tx.deposit).deep.equal(transaction.deposit);
expect(tx.inputs).deep.equal(transaction.inputs);
expect(tx.outputs).deep.equal(transaction.outputs);
expect(tx.mint).deep.equal(transaction.mint);
expect(tx.amount).deep.equal(transaction.amount);
expect(tx.withdrawals).deep.equal(transaction.withdrawals);
});
it('should get payment fee', async function () {
let receiver = '9ada973fd29d6b3d096ab361ef5fd082576bdbe3';
let payeer = '2a793eb367d44a42f658eb02d1004f50c14612fd';
let rWallet = await walletServer.getShelleyWallet(receiver);
let addresses = (await rWallet.getUnusedAddresses()).slice(0, 1);
let amounts = [1000000];
let wallet = await walletServer.getShelleyWallet(payeer);
let estimatedFees = await wallet.estimateFee(addresses, amounts);
expect(estimatedFees).not.undefined;
});
it('should send a payment transfer', async function () {
let receiver = '2a793eb367d44a42f658eb02d1004f50c14612fd';
let payeer = '60bb5513e4e262e445cf203db9cf73ba925064d2';
let passphrase = 'shelley-small-coins';
let rWallet = await walletServer.getShelleyWallet(receiver);
let addresses = (await rWallet.getUsedAddresses()).slice(0, 1);
let amounts = [1000000];
let wallet = await walletServer.getShelleyWallet(payeer);
let transaction = await wallet.sendPayment(passphrase, addresses, amounts);
let output = transaction.outputs.find(o => o.address == addresses[0].address);
let inputAmount = transaction.inputs.map(i => i.amount.quantity).reduce((a, b) => a + b);
let outputAmount = transaction.outputs.map(o => o.amount.quantity).reduce((a, b) => a + b);
let fee = transaction.fee.quantity;
let spent = output.amount.quantity + fee;
let paid = amounts.reduce((a, b) => a + b);
expect(output).to.not.undefined;
expect(output.amount.quantity).equal(paid);
expect(spent).equal(transaction.amount.quantity);
expect(outputAmount + fee).equal(inputAmount);
});
it('should send a payment transfer with complex metadata', async function () {
let receiver = '2a793eb367d44a42f658eb02d1004f50c14612fd';
let payeer = '60bb5513e4e262e445cf203db9cf73ba925064d2';
let passphrase = 'shelley-small-coins';
let rWallet = await walletServer.getShelleyWallet(receiver);
let addresses = (await rWallet.getUsedAddresses()).slice(0, 1);
let amounts = [1000000];
let wallet = await walletServer.getShelleyWallet(payeer);
let metadata: any = {0: 'hello', 1: Buffer.from('2512a00e9653fe49a44a5886202e24d77eeb998f', 'hex'), 4: [1, 2, {0: true}], 5: {'key': null, 'l': [3, true, {}]}, 6: undefined};
let transaction = await wallet.sendPayment(passphrase, addresses, amounts, metadata);
let output = transaction.outputs.find(o => o.address == addresses[0].address);
let inputAmount = transaction.inputs.map(i => i.amount.quantity).reduce((a, b) => a + b);
let outputAmount = transaction.outputs.map(o => o.amount.quantity).reduce((a, b) => a + b);
let fee = transaction.fee.quantity;
let spent = output.amount.quantity + fee;
let paid = amounts.reduce((a, b) => a + b);
expect(output).to.not.undefined;
expect(output.amount.quantity).equal(paid);
expect(spent).equal(transaction.amount.quantity);
expect(outputAmount + fee).equal(inputAmount);
});
it('should get coin selection', async function(){
let w = wallets.find(w => w.id == '2a793eb367d44a42f658eb02d1004f50c14612fd');
let receiver = wallets.find(w => w.id == '60bb5513e4e262e445cf203db9cf73ba925064d2');
let wallet = await walletServer.getShelleyWallet(w.id);
let addresses = (await (await walletServer.getShelleyWallet(receiver.id)).getUsedAddresses()).slice(0, 1);
let amounts = [5000000];
let coins = await wallet.getCoinSelection(addresses, amounts);
let inputAmount = coins.inputs.map(i => i.amount.quantity).reduce((a, b) => a + b);
let outputAmount = coins.outputs.map(o => o.amount.quantity).reduce((a, b) => a + b);
let changeAmount = coins.change.map(c => c.amount.quantity).reduce((a, b) => a + b);
expect(inputAmount).least(outputAmount + changeAmount);
});
it("should send a offline signed payment transaction", async function(){
let receiver = '2a793eb367d44a42f658eb02d1004f50c14612fd';
let payeer = wallets.find(w => w.id == "60bb5513e4e262e445cf203db9cf73ba925064d2");
let wallet = await walletServer.getShelleyWallet(payeer.id);
let addresses = (await (await walletServer.getShelleyWallet(receiver)).getUnusedAddresses()).slice(0, 1);
let amounts = [1000000];
let info = await walletServer.getNetworkInformation();
let data: any = {0: 'hello', 1: Buffer.from('2512a00e9653fe49a44a5886202e24d77eeb998f', 'hex'), 4: [1, 2, {0: true}], 5: {'key': null, 'l': [3, true, {}]}, 6: undefined};
let coinSelection = await wallet.getCoinSelection(addresses, amounts, data);
//build and sign tx
let rootKey = Seed.deriveRootKey(payeer.mnemonic_sentence);
let signingKeys = coinSelection.inputs.map(i => {
let privateKey = Seed.deriveKey(rootKey, i.derivation_path).to_raw_key();
return privateKey;
});
let metadata = Seed.buildTransactionMetadata(data);
let txBuild = Seed.buildTransaction(coinSelection, info.node_tip.absolute_slot_number * 12000, {metadata: metadata, config: LocalCluster});
let txBody = Seed.sign(txBuild, signingKeys, metadata);
let signed = Buffer.from(txBody.to_bytes()).toString('hex');
let txId = await walletServer.submitTx(signed);
expect(txId).not.undefined;
});
});
});
async function waitUntilTxFinish(txId: string, wallet: ShelleyWallet): Promise<void> {
return new Promise<void>(async (resolve, reject) => {
let tx = {status: ApiTransactionStatusEnum.Pending};
do {
await delay(1);
tx = await wallet.getTransaction(txId);
}while(tx.status == ApiTransactionStatusEnum.Pending)
resolve();
})
};
async function waitUntilEpoch(epoch: number, server: WalletServer) {
return new Promise<void>(async (resolve, reject) => {
let information = {epoch_number: 0};
do {
await delay(1);
let info = await server.getNetworkInformation();
information.epoch_number = info.node_tip.epoch_number;
}while(information.epoch_number < epoch)
resolve();
})
}
async function delay(time: number) {
return new Promise<void>((resolve, reject) => {
setTimeout(function(){ resolve();}, time*1000);
});
}