Browse Source

Submission

master
Robby Zambito 1 month ago
parent
commit
7853cb8b98
16 changed files with 788 additions and 114 deletions
  1. +3
    -3
      babel.config.js
  2. +183
    -41
      package-lock.json
  3. +7
    -1
      package.json
  4. +1
    -0
      public/algosdk.min.js
  5. BIN
      public/favicon.ico
  6. +4
    -0
      public/index.html
  7. +60
    -19
      src/App.vue
  8. BIN
      src/assets/logo.png
  9. +161
    -0
      src/components/CreateVirtualMachine.vue
  10. +55
    -49
      src/components/HelloWorld.vue
  11. +69
    -0
      src/components/Login.vue
  12. +79
    -0
      src/components/Manager.vue
  13. +93
    -0
      src/components/VirtualMachineList.vue
  14. +32
    -0
      src/components/VirtualMachineViewer.vue
  15. +31
    -0
      src/components/Welcome.vue
  16. +10
    -1
      src/main.js

+ 3
- 3
babel.config.js View File

@@ -1,5 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
presets: [
'@vue/cli-plugin-babel/preset'
]
}

+ 183
- 41
package-lock.json View File

@@ -1033,6 +1033,11 @@
"glob-to-regexp": "^0.3.0"
}
},
"@msgpack/msgpack": {
"version": "1.12.1",
"resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-1.12.1.tgz",
"integrity": "sha512-nGwwmkdm3tuLdEkWMIwLBgFBfMFILILxcZIQY0dfqsdboN2iZdKfOYKUOKoa0wXw1FL1PL3yEYGPCXhwodQDTA=="
},
"@nodelib/fs.stat": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
@@ -1887,6 +1892,28 @@
"integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==",
"dev": true
},
"algosdk": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/algosdk/-/algosdk-1.5.0.tgz",
"integrity": "sha512-N1WMvqDuTDDotP8c4a1Ro1xiGDHW+RQp9ItySuUhxb21mPr3oj+6pN2x8iVpt4DgqqT3pvGM04JMmJ5AapjWTA==",
"requires": {
"@msgpack/msgpack": "^1.9.0",
"hi-base32": "^0.5.0",
"js-sha256": "^0.9.0",
"js-sha512": "^0.8.0",
"js-yaml": ">=3.13.1",
"keccak256": "^1.0.0",
"superagent": "^4.1.0",
"tweetnacl": "^1.0.1"
},
"dependencies": {
"tweetnacl": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
"integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw=="
}
}
},
"alphanum-sort": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz",
@@ -1980,7 +2007,6 @@
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"dev": true,
"requires": {
"sprintf-js": "~1.0.2"
}
@@ -2119,8 +2145,7 @@
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
"dev": true
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"atob": {
"version": "2.1.2",
@@ -2155,6 +2180,37 @@
"integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==",
"dev": true
},
"axios": {
"version": "0.19.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
"integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
"requires": {
"follow-redirects": "1.5.10"
},
"dependencies": {
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
"ms": "2.0.0"
}
},
"follow-redirects": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
"requires": {
"debug": "=3.1.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"babel-eslint": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz",
@@ -2301,8 +2357,6 @@
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"dev": true,
"optional": true,
"requires": {
"file-uri-to-path": "1.0.0"
}
@@ -2316,8 +2370,7 @@
"bn.js": {
"version": "4.11.8",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
"integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
"dev": true
"integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
},
"body-parser": {
"version": "1.19.0",
@@ -3088,7 +3141,6 @@
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dev": true,
"requires": {
"delayed-stream": "~1.0.0"
}
@@ -3108,8 +3160,7 @@
"component-emitter": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
"dev": true
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
},
"compressible": {
"version": "2.0.18",
@@ -3239,6 +3290,11 @@
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
"dev": true
},
"cookiejar": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz",
"integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA=="
},
"copy-concurrently": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
@@ -3689,7 +3745,6 @@
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
@@ -3953,8 +4008,7 @@
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
"dev": true
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"depd": {
"version": "1.1.2",
@@ -4492,8 +4546,7 @@
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
},
"esquery": {
"version": "1.3.1",
@@ -4889,9 +4942,7 @@
"file-uri-to-path": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
"dev": true,
"optional": true
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
},
"filesize": {
"version": "3.6.1",
@@ -5048,13 +5099,17 @@
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
"dev": true,
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.6",
"mime-types": "^2.1.12"
}
},
"formidable": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz",
"integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q=="
},
"forwarded": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
@@ -5932,6 +5987,11 @@
"integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==",
"dev": true
},
"hi-base32": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/hi-base32/-/hi-base32-0.5.0.tgz",
"integrity": "sha512-DDRmxSyoYuvjUb9EnXdoiMChBZ7ZcUVJsK5Frd3kqMhuBxvmZdnBeynAVfj7/ECbn++CekcoprvC/rprHPAtow=="
},
"highlight.js": {
"version": "9.18.1",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.1.tgz",
@@ -6306,8 +6366,7 @@
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"inquirer": {
"version": "7.1.0",
@@ -6831,6 +6890,16 @@
"easy-stack": "^1.0.0"
}
},
"js-sha256": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz",
"integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA=="
},
"js-sha512": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz",
"integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ=="
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -6841,7 +6910,6 @@
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
"dev": true,
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
@@ -6925,6 +6993,26 @@
"verror": "1.10.0"
}
},
"keccak": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz",
"integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==",
"requires": {
"bindings": "^1.2.1",
"inherits": "^2.0.3",
"nan": "^2.2.1",
"safe-buffer": "^5.1.0"
}
},
"keccak256": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/keccak256/-/keccak256-1.0.0.tgz",
"integrity": "sha512-8qv2vJdQk+Aa2tFXo8zYodm+6DgXqUOqvNJhj1p1V2pxQJT1oNKxNF+zWfhtKXNLZdLvyxjB/dvd9GwcvTHSQQ==",
"requires": {
"bn.js": "^4.11.8",
"keccak": "^1.4.0"
}
},
"killable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
@@ -7290,8 +7378,7 @@
"methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
"dev": true
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
},
"micromatch": {
"version": "3.1.10",
@@ -7327,20 +7414,17 @@
"mime": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
"integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==",
"dev": true
"integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA=="
},
"mime-db": {
"version": "1.44.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
"integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
"dev": true
"integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg=="
},
"mime-types": {
"version": "2.1.27",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
"integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
"dev": true,
"requires": {
"mime-db": "1.44.0"
}
@@ -7507,6 +7591,11 @@
"minimist": "^1.2.5"
}
},
"moment": {
"version": "2.25.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.25.1.tgz",
"integrity": "sha512-nRKMf9wDS4Fkyd0C9LXh2FFXinD+iwbJ5p/lh3CHitW9kZbRbJ8hCruiadiIXZVbeAqKZzqcTvHnK3mRhFjb6w=="
},
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
@@ -7524,8 +7613,7 @@
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"multicast-dns": {
"version": "6.2.3",
@@ -7563,9 +7651,7 @@
"nan": {
"version": "2.14.1",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz",
"integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==",
"dev": true,
"optional": true
"integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw=="
},
"nanomatch": {
"version": "1.2.13",
@@ -9553,8 +9639,7 @@
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"safe-regex": {
"version": "1.1.0",
@@ -10162,8 +10247,7 @@
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
"dev": true
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
},
"sshpk": {
"version": "1.16.1",
@@ -10338,7 +10422,6 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"requires": {
"safe-buffer": "~5.1.0"
}
@@ -10408,6 +10491,39 @@
}
}
},
"superagent": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/superagent/-/superagent-4.1.0.tgz",
"integrity": "sha512-FT3QLMasz0YyCd4uIi5HNe+3t/onxMyEho7C3PSqmti3Twgy2rXT4fmkTz6wRL6bTF4uzPcfkUCa8u4JWHw8Ag==",
"requires": {
"component-emitter": "^1.2.0",
"cookiejar": "^2.1.2",
"debug": "^4.1.0",
"form-data": "^2.3.3",
"formidable": "^1.2.0",
"methods": "^1.1.1",
"mime": "^2.4.0",
"qs": "^6.6.0",
"readable-stream": "^3.0.6"
},
"dependencies": {
"qs": {
"version": "6.9.3",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.3.tgz",
"integrity": "sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw=="
},
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
}
}
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -10623,6 +10739,11 @@
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
"dev": true
},
"tiny-cookie": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/tiny-cookie/-/tiny-cookie-1.0.1.tgz",
"integrity": "sha1-dTeGB5xkKjw9CyrMrWAPjeEZrCo="
},
"tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
@@ -11022,8 +11143,7 @@
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
"dev": true
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"util.promisify": {
"version": "1.0.1",
@@ -11105,6 +11225,14 @@
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.11.tgz",
"integrity": "sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ=="
},
"vue-cookie": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/vue-cookie/-/vue-cookie-1.1.4.tgz",
"integrity": "sha1-uLRtESvan5Oi9HAXwu1SgtIGT9o=",
"requires": {
"tiny-cookie": "^1.0"
}
},
"vue-eslint-parser": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.0.0.tgz",
@@ -11158,6 +11286,20 @@
}
}
},
"vue-moment": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/vue-moment/-/vue-moment-4.1.0.tgz",
"integrity": "sha512-Gzisqpg82ItlrUyiD9d0Kfru+JorW2o4mQOH06lEDZNgxci0tv/fua1Hl0bo4DozDV2JK1r52Atn/8QVCu8qQw==",
"requires": {
"moment": "^2.19.2"
}
},
"vue-plugin-load-script": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/vue-plugin-load-script/-/vue-plugin-load-script-1.2.0.tgz",
"integrity": "sha512-QbWjZSFRToSP6S0nZFsH618PsTlZgSg8m8Xv602vezznLTHYd0wAXEw0jlYND7L6BMe0KcA7cvUwLROyfBlQ4w==",
"dev": true
},
"vue-style-loader": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz",


+ 7
- 1
package.json View File

@@ -8,8 +8,13 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"algosdk": "^1.5.0",
"axios": "^0.19.2",
"core-js": "^3.6.4",
"vue": "^2.6.11"
"moment": "^2.25.1",
"vue": "^2.6.11",
"vue-cookie": "^1.1.4",
"vue-moment": "^4.1.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.3.0",
@@ -18,6 +23,7 @@
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"vue-plugin-load-script": "^1.2.0",
"vue-template-compiler": "^2.6.11"
},
"eslintConfig": {


+ 1
- 0
public/algosdk.min.js
File diff suppressed because it is too large
View File


BIN
public/favicon.ico View File

Before After

+ 4
- 0
public/index.html View File

@@ -6,6 +6,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
</head>
<body>
<noscript>
@@ -13,5 +14,8 @@
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>

+ 60
- 19
src/App.vue View File

@@ -1,28 +1,69 @@
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
<div id="app">

<!-- <img alt="Vue logo" src="./assets/logo.png">-->
<span v-if="!algoAccount">
<Welcome v-on:login="login($event)" />
</span>
<span v-else>
<Manager v-bind:account="algoAccount" v-on:logout="login(null)"/>
</span>
</div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'
import * as algosdk from 'algosdk';
import Manager from "@/components/Manager";
import Welcome from './components/Welcome.vue';

export default {
name: 'App',
components: {
Manager,
Welcome
},
data: function () {
const mnemonic = this.$cookie.get('mnemonic');
return {
algoAccount: (
mnemonic && mnemonic.length ?
algosdk.mnemonicToSecretKey(mnemonic) :
null
),
};
},
methods: {
login: function (mnemonic) {
if (mnemonic && mnemonic.length && mnemonic.split(" ").length) {
try {
this.algoAccount = algosdk.mnemonicToSecretKey(mnemonic);
this.$cookie.set('mnemonic', mnemonic, 1);
} catch (e) {
alert(e)
}

export default {
name: 'App',
components: {
HelloWorld
}
}
} else {
this.$cookie.delete('mnemonic');
this.algoAccount = null;
}
},
},
}
</script>

<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: left;
color: #2c3e50;
margin-top: 0;
}

.card {
margin: 3vh auto;
padding: 2vh 2vw;
min-width: 30vw;
}
</style>

BIN
src/assets/logo.png View File

Before After
Width: 200  |  Height: 200  |  Size: 6.7 KiB Width: 300  |  Height: 300  |  Size: 4.1 KiB

+ 161
- 0
src/components/CreateVirtualMachine.vue View File

@@ -0,0 +1,161 @@
<template>
<div class="container">
<h3>Create a Virtual Machine</h3>
<br>
<div class="card">
<!-- <div class="form-group">-->
<!-- <label for="vm-name-input">Name</label>-->
<!-- <input id="vm-name-input" type="text" v-model="vmName">-->
<!-- </div>-->
<div>
<span>Deletion Date: {{ dateString }} </span>

<span id="adjust-time">
<button class="btn btn-success" v-on:click="addDay">Add Day</button>
<button class="btn btn-success" v-on:click="addHour">Add Hour</button>
<button class="btn btn-warning" v-on:click="subtractHour">Subtract Hour</button>
<button class="btn btn-warning" v-on:click="subtractDay">Subtract Day</button>
</span>
</div>
<div>
<span>Cost: {{ cost }}</span>
</div>
<div>
<button class="btn btn-primary" v-on:click="submit">Create</button>
<button class="btn btn-danger" v-on:click="$emit('done')">Back</button>
</div>
</div>

</div>
</template>

<script>
import axios from 'axios';
import * as algosdk from 'algosdk';
import moment from 'moment';

export default {
name: "CreateVirtualMachine",
props: ['account'],
methods: {
submit: async function () {
const params = await this.getParams();

this.transaction = {
from: this.account.addr,
to: "ALGOVP5KCBHBU2ZYILN6RDFFZB6S35KHUNVCOEXIUHCZ5O6BHRLTIJM2W4",
fee: 10,
amount: this.cost,
firstRound: params.lastRound,
lastRound: parseInt(params.lastRound) + 1000,
genesisID: params.genesisID,
genesisHash: params.genesishashb64,
note: new Uint8Array(0),
};

const signedTransaction = algosdk.signTransaction(this.transaction, this.account.sk);

try {
const res = await axios.post(`http://192.168.122.125/api/virtual-machines/${this.account.addr}/create-machine`, signedTransaction.blob, {
headers: {
'Content-Type': 'application/octet-stream',
'Deletion-Date': this.deletionDateTime.toISOString(),
}
});

console.log(`res: ${res}`);

await this.optInAsset(res.data.assetId);
} catch (e) {
console.log(e);
} finally {
this.$emit('done');
}

},
optInAsset: async function (assetId) {
console.log(`Opting into asset: ${assetId}`);

const note = undefined;
const sender = this.account.addr;
const recipient = sender;
const revocationTarget = undefined;
const closeRemainderTo = undefined;
const amount = 0;
const params = await this.getParams();

const optInTxn = algosdk.makeAssetTransferTxn(
sender,
recipient,
closeRemainderTo,
revocationTarget,
10,
amount,
params.lastRound,
params.lastRound + 1000,
note,
params.genesishashb64,
params.genesisID,
assetId
);

const signedTxn = optInTxn.signTxn(this.account.sk);
await axios.post(`http://192.168.122.125/api/algo/${this.account.addr}/opt-in-asset/${assetId}`, signedTxn.blob, {
headers: {
'Content-Type': 'application/octet-stream',
}
});
},
addDay: function () {
this.deletionDateTime = moment(this.deletionDateTime.add(1, 'day'));
console.log(`New time: ${this.deletionDateTime.calendar()}`);
},
addHour: function () {
this.deletionDateTime = moment(this.deletionDateTime.add(1, 'hour'));
console.log(`New time: ${this.deletionDateTime.calendar()}`);
},
subtractHour: function () {
this.deletionDateTime = moment(this.deletionDateTime.subtract(1, 'hour'));
console.log(`New time: ${this.deletionDateTime.calendar()}`);
},
subtractDay: function () {
this.deletionDateTime = moment(this.deletionDateTime.subtract(1, 'day'));
console.log(`New time: ${this.deletionDateTime.calendar()}`);
},
getParams: async function () {
return (await axios.get("http://192.168.122.125/api/algo/recommended-parameters")).data;
},
},
data: function () {
return {
vmName: "",
deletionDateTime: moment(),
transaction: null,
};
},
computed: {
cost: function () {
return Math.max(Math.ceil(-moment().diff(this.deletionDateTime, 'minutes') / 60), 0);
},
dateString: function () {
return this.deletionDateTime.calendar();
}
},
}
</script>

<style scoped>

label {
margin-right: .5vw;
}

.btn {
margin-right: .5vw;
}

#adjust-time {
float: right;
}

</style>

+ 55
- 49
src/components/HelloWorld.vue View File

@@ -1,58 +1,64 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" rel="noopener" target="_blank">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" rel="noopener"
target="_blank">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" rel="noopener"
target="_blank">eslint</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" rel="noopener" target="_blank">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" rel="noopener" target="_blank">Forum</a></li>
<li><a href="https://chat.vuejs.org" rel="noopener" target="_blank">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" rel="noopener" target="_blank">Twitter</a></li>
<li><a href="https://news.vuejs.org" rel="noopener" target="_blank">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" rel="noopener" target="_blank">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" rel="noopener" target="_blank">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" rel="noopener"
target="_blank">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" rel="noopener" target="_blank">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" rel="noopener" target="_blank">awesome-vue</a></li>
</ul>
</div>
</template>

<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
h3 {
margin: 40px 0 0;
}

ul {
list-style-type: none;
padding: 0;
}

li {
display: inline-block;
margin: 0 10px;
}

a {
color: #42b983;
}
</style>

+ 69
- 0
src/components/Login.vue View File

@@ -0,0 +1,69 @@
<template>
<div>
<div class="row">
<div class="card">
<form>
<div class="form-group">
<label for="login-mnemonic-input">Restore account from mnemonic: </label>
<br>
<textarea id="login-mnemonic-input"
v-model="loginMnemonic"
v-on:keydown.enter="login"
rows="3" />
</div>
<button class="btn btn-outline-primary" type="button" v-on:click="login">OK</button>
</form>
</div>
</div>
<div class="row">
<div class="card">
<div class="card-header">
Generate a new account
<button class="btn btn-outline-primary" type="button" v-on:click="generateWallet">OK</button>
</div>
<div class="card-body">

<div id="wallet">
<span id="address">{{ generatedAddress }}</span><br>
<span id="mnemonic">{{ generatedMnemonic }}</span>
</div>
</div>
</div>
</div>
</div>
</template>

<script>
import * as algosdk from 'algosdk';

export default {
name: "Login",
data: function () {
return {
generatedAddress: "",
generatedMnemonic: "",
loginMnemonic: "",
};
},
methods: {
generateWallet: function () {
const newWallet = algosdk.generateAccount();
this.generatedAddress = newWallet.addr;
this.generatedMnemonic = algosdk.secretKeyToMnemonic(newWallet.sk);
},
login: function () {
this.$emit('login', this.loginMnemonic.trim());
}
}
}
</script>

<style scoped>
.card > .card-header > .btn {
right: .2vw;
}

textarea {
width: 100%;
}
</style>

+ 79
- 0
src/components/Manager.vue View File

@@ -0,0 +1,79 @@
<template>
<span>
<nav class="navbar navbar-dark bg-dark">
<a class="navbar-brand" href="#">Virtual Machine Manager</a>
<button class="btn btn-danger" v-on:click="logout">Logout</button>
</nav>

<div v-if="!creatingVirtualMachine && !selectedMachine" class="container">
<p>Logged in with address: {{ account.addr }}</p>
<p>Account balance: {{ balance >= 0 ? balance / 1000000 : "" }}</p>
<button class="btn btn-primary" v-on:click="viewCreateVirtualMachine">Create a new Virtual Machine</button>
<br><br>
<VirtualMachineList v-bind:account="account" v-on:selectMachine="updateSelectedMachine($event)" />
</div>
<div v-else-if="creatingVirtualMachine">
<CreateVirtualMachine v-bind:account="account" v-on:done="creatingVirtualMachine = false"/>
</div>
<div v-else class="container">
<VirtualMachineViewer v-bind:machine="selectedMachine" />
<button class="btn btn-danger" v-on:click="updateSelectedMachine(null)">Close Machine</button>
</div>

</span>
</template>

<script>
// import * as algosdk from 'algosdk';
import axios from 'axios';
import VirtualMachineList from "@/components/VirtualMachineList";
import VirtualMachineViewer from "@/components/VirtualMachineViewer";
import CreateVirtualMachine from "@/components/CreateVirtualMachine";

export default {
name: "Manager",
components: {CreateVirtualMachine, VirtualMachineViewer, VirtualMachineList},
props: ['account'],
methods: {
logout: function () {
this.$emit('logout');
},
updateSelectedMachine: function (machine) {
this.selectedMachine = machine;
},
viewCreateVirtualMachine: function () {
this.creatingVirtualMachine = true;
},
getBalance: async function () {
const res = await axios
.get(`http://192.168.122.125/api/algo/${this.account.addr}/balance`);
if (res && res.data && res.data.balance)
this.balance = res.data.balance;
else console.log("Could not get balance");
},
},
data: function () {
return {
balance: -1,
selectedMachine: null,
creatingVirtualMachine: false,
pricePoll: null,
}
},
created: function() {
this.getBalance();
this.pricePoll = setInterval(() => {
this.getBalance();
}, 5000);
},
beforeDestroy: function () {
clearInterval(this.pricePoll);
},
}
</script>

<style scoped>
nav {
margin-bottom: 15px;
}
</style>

+ 93
- 0
src/components/VirtualMachineList.vue View File

@@ -0,0 +1,93 @@
<template>
<div>
<ul class="list-group" v-if="virtualMachines.length">
<li class="list-group-item" v-for="vm in virtualMachines.slice().sort()"
v-bind:key="vm.assetID">
<h4>{{ vm.name }}</h4>
<div>Virtual Machine ID: {{ vm.assetId }}</div>
<div>Created on: {{ createdDate(vm) }}</div>
<div>Expires at: {{ expirationDate(vm) }}</div>
<button class="btn btn-outline-primary" v-on:click="selectMachine(vm)">View Machine</button>
<button class="btn btn-outline-danger" v-on:click="deleteMachine(vm)">Delete Machine</button>
<button class="btn btn-outline-success" onclick="console.log('Not implemented!!')">Add Time</button>

<button v-if="vm.poweredOn" class="btn btn-outline-warning" v-on:click="turnOffVirtualMachine(vm)">Turn Off</button>
<button v-else class="btn btn-outline-info" v-on:click="turnOnVirtualMachine(vm)">Turn On</button>
</li>
</ul>
<div v-else>
<h5>No machines found! Create a new virtual machine to get started.</h5>
</div>
</div>
</template>

<script>
import axios from 'axios';
import moment from 'moment';

export default {
name: "VirtualMachineList",
props: ['account'],
data: function () {
return {
virtualMachines: [{
name: "First VM",
dateCreated: new Date(new Date() - 1000 * 60 * 60),
poweredOn: true,
assetId: 12345,
}, {
name: "Second VM",
dateCreated: new Date(),
poweredOn: false,
assetId: 54321,
}],
virtualMachineListPoll: null,
};
},
methods: {
selectMachine: function (machine) {
this.$emit('selectMachine', machine);
},
deleteMachine: async function (machine) {
await axios
.get(`http://192.168.122.125/api/virtual-machines/delete/${machine.name}`);
},
createdDate: function (machine) {
return moment(machine.dateCreated).calendar();
},
expirationDate: function (machine) {
return moment(machine.paidUntil).calendar();
},
getVirtualMachineList: async function () {
const res = await axios
.get(`http://192.168.122.125/api/virtual-machines/${this.account.addr}/list-vms`);
if (res && res.data && res.data.virtualMachines) {
this.virtualMachines = res.data.virtualMachines;
} else console.log("Could not fetch virtual machine list.");
},
turnOffVirtualMachine: async function (vm) {
await axios
.get(`http://192.168.122.125/api/virtual-machines/turn-off/${vm.name}`);
},
turnOnVirtualMachine: async function (vm) {
await axios
.get(`http://192.168.122.125/api/virtual-machines/turn-on/${vm.name}`);
},
},
created: function() {
this.getVirtualMachineList();
this.virtualMachineListPoll = setInterval(() => {
this.getVirtualMachineList();
}, 5000);
},
beforeDestroy: function () {
clearInterval(this.virtualMachineListPoll);
},
}
</script>

<style scoped>
li > button {
margin-right: .5vw;
}
</style>

+ 32
- 0
src/components/VirtualMachineViewer.vue View File

@@ -0,0 +1,32 @@
<template>
<div>
<h3>{{ machine.name }}</h3>
<span>
Created on: {{ dateString() }}
</span>
<div>
<iframe id="vm-vnc" src="http://192.168.122.125:6081/vnc.html?host=algo-vps&port=6081" frameborder="0"></iframe>
</div>
</div>
</template>

<script>
import moment from 'moment';

export default {
name: "VirtualMachineViewer",
props: ['machine'],
methods: {
dateString: function () {
return moment(this.machine.dateCreated).calendar();
},
},
}
</script>

<style scoped>
#vm-vnc {
width: 800px;
height: 600px;
}
</style>

+ 31
- 0
src/components/Welcome.vue View File

@@ -0,0 +1,31 @@
<template>
<div>
<div class="jumbotron">
<h1>Welcome to AlgoVPS</h1>
<p>Login to get started</p>
</div>
<div class="container">
<Login v-on:login="login($event)" />
</div>
</div>
</template>

<script>
import Login from "@/components/Login";

export default {
name: "Welcome",
components: {
Login
},
methods: {
login: function (mnemonic) {
this.$emit('login', mnemonic);
}
}
}
</script>

<style scoped>

</style>

+ 10
- 1
src/main.js View File

@@ -1,8 +1,17 @@
import Vue from 'vue'
import App from './App.vue'
import LoadScript from 'vue-plugin-load-script';
import VueCookie from 'vue-cookie';
// import VueMoment from 'vue-moment';

Vue.config.productionTip = false

Vue.use(LoadScript);
Vue.use(VueCookie);
// Vue.use(VueMoment);

Vue.loadScript("/algosdk.min.js");

new Vue({
render: h => h(App),
render: h => h(App),
}).$mount('#app')