diff --git a/web/cashtab/package-lock.json b/web/cashtab/package-lock.json --- a/web/cashtab/package-lock.json +++ b/web/cashtab/package-lock.json @@ -22,6 +22,7 @@ "babel-loader": "^8.2.3", "babel-plugin-named-asset-import": "^0.3.8", "babel-preset-react-app": "^10.0.1", + "backendless": "^6.3.15", "bfj": "^7.0.2", "bignumber.js": "^9.0.0", "browserslist": "^4.18.1", @@ -5216,6 +5217,11 @@ "node": ">=8.9" } }, + "node_modules/after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==" + }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -5579,6 +5585,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" + }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -6000,6 +6011,52 @@ "babel-plugin-transform-react-remove-prop-types": "^0.4.24" } }, + "node_modules/backendless": { + "version": "6.3.15", + "resolved": "https://registry.npmjs.org/backendless/-/backendless-6.3.15.tgz", + "integrity": "sha512-DeuMhEvcZo+FR44APMf6E1XhGAnPPxEdkCnX7TVOFqSpD2H2UnvB2QLU9VGipY44lsf1d5YhWqj5MwmMZLf7nA==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "backendless-request": "^0.2.0", + "backendless-rt-client": "0.1.0" + } + }, + "node_modules/backendless-request": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/backendless-request/-/backendless-request-0.2.0.tgz", + "integrity": "sha512-Hlap8Ly+yd+K/2Htszv0dB0eGGhibNlLnkfEaG1FTFJvUAUDPDg6RHhDVs3Sl9XLOVmPZffBm4m8DrnfM5mIYw==", + "dependencies": { + "form-data": "^2.3.1" + } + }, + "node_modules/backendless-request/node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/backendless-rt-client": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/backendless-rt-client/-/backendless-rt-client-0.1.0.tgz", + "integrity": "sha512-vzmfmuXOzmiAGY8N6fiGRznD7MrpXjsq4KjzwZU1vIp5zxphRwPl3AOVLO6nCY593YdoRDyCSDH0Y+v6On8Ljg==", + "dependencies": { + "@babel/runtime": "^7.18.2", + "backendless-request": "^0.2.0", + "socket.io-client": "^2.0.3" + } + }, + "node_modules/backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -6013,6 +6070,14 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/base64-arraybuffer": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", + "integrity": "sha512-a1eIFi4R9ySrbiMuyTGx5e92uRH5tQY6kArNcFaKBUleIoLjdjBg7Zxm3Mqm3Kmkf27HLR/1fnxX9q8GQ7Iavg==", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -6214,6 +6279,11 @@ "node": ">=0.10" } }, + "node_modules/blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" + }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -6871,6 +6941,21 @@ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, + "node_modules/component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw==" + }, + "node_modules/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==" + }, + "node_modules/component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA==" + }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -8074,6 +8159,69 @@ "node": ">= 0.8" } }, + "node_modules/engine.io-client": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.3.tgz", + "integrity": "sha512-qsgyc/CEhJ6cgMUwxRRtOndGVhIu5hpL5tR4umSpmX/MvkFoIxUTM7oFMDQumHNzlNLwSVy6qhstFPoWTf7dOw==", + "dependencies": { + "component-emitter": "~1.3.0", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.2.0", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "ws": "~7.4.2", + "xmlhttprequest-ssl": "~1.6.2", + "yeast": "0.1.2" + } + }, + "node_modules/engine.io-client/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/engine.io-client/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/engine.io-client/node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/engine.io-parser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.1.tgz", + "integrity": "sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==", + "dependencies": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.4", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, "node_modules/enhanced-resolve": { "version": "5.10.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", @@ -10100,6 +10248,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "dependencies": { + "isarray": "2.0.1" + } + }, + "node_modules/has-binary2/node_modules/isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==" + }, + "node_modules/has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA==" + }, "node_modules/has-dynamic-import": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-dynamic-import/-/has-dynamic-import-2.0.1.tgz", @@ -10618,6 +10784,11 @@ "node": ">=8" } }, + "node_modules/indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==" + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -14914,6 +15085,16 @@ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" }, + "node_modules/parseqs": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", + "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==" + }, + "node_modules/parseuri": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", + "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==" + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -18416,6 +18597,65 @@ "bignumber.js": "^9.0.0" } }, + "node_modules/socket.io-client": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.5.0.tgz", + "integrity": "sha512-lOO9clmdgssDykiOmVQQitwBAF3I6mYcQAo7hQ7AM6Ny5X7fp8hIJ3HcQs3Rjz4SoggoxA1OgrQyY8EgTbcPYw==", + "dependencies": { + "backo2": "1.0.2", + "component-bind": "1.0.0", + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "engine.io-client": "~3.5.0", + "has-binary2": "~1.0.2", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + } + }, + "node_modules/socket.io-client/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/socket.io-client/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/socket.io-parser": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.2.tgz", + "integrity": "sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==", + "dependencies": { + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "isarray": "2.0.1" + } + }, + "node_modules/socket.io-parser/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/socket.io-parser/node_modules/isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==" + }, + "node_modules/socket.io-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -19211,6 +19451,11 @@ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" }, + "node_modules/to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha512-LhVdShQD/4Mk4zXNroIQZJC+Ap3zgLcDuwEdcmLv9CCO73NWockQDwyUnW/m8VX/EElfL6FcYx7EeutN4HJA6A==" + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -20599,6 +20844,14 @@ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" }, + "node_modules/xmlhttprequest-ssl": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz", + "integrity": "sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -20653,6 +20906,11 @@ "node": ">=10" } }, + "node_modules/yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg==" + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -24309,6 +24567,11 @@ "regex-parser": "^2.2.11" } }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==" + }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -24583,6 +24846,11 @@ "es-shim-unscopables": "^1.0.0" } }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" + }, "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -24904,6 +25172,51 @@ "babel-plugin-transform-react-remove-prop-types": "^0.4.24" } }, + "backendless": { + "version": "6.3.15", + "resolved": "https://registry.npmjs.org/backendless/-/backendless-6.3.15.tgz", + "integrity": "sha512-DeuMhEvcZo+FR44APMf6E1XhGAnPPxEdkCnX7TVOFqSpD2H2UnvB2QLU9VGipY44lsf1d5YhWqj5MwmMZLf7nA==", + "requires": { + "@babel/runtime": "^7.14.6", + "backendless-request": "^0.2.0", + "backendless-rt-client": "0.1.0" + } + }, + "backendless-request": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/backendless-request/-/backendless-request-0.2.0.tgz", + "integrity": "sha512-Hlap8Ly+yd+K/2Htszv0dB0eGGhibNlLnkfEaG1FTFJvUAUDPDg6RHhDVs3Sl9XLOVmPZffBm4m8DrnfM5mIYw==", + "requires": { + "form-data": "^2.3.1" + }, + "dependencies": { + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + } + } + }, + "backendless-rt-client": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/backendless-rt-client/-/backendless-rt-client-0.1.0.tgz", + "integrity": "sha512-vzmfmuXOzmiAGY8N6fiGRznD7MrpXjsq4KjzwZU1vIp5zxphRwPl3AOVLO6nCY593YdoRDyCSDH0Y+v6On8Ljg==", + "requires": { + "@babel/runtime": "^7.18.2", + "backendless-request": "^0.2.0", + "socket.io-client": "^2.0.3" + } + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==" + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -24917,6 +25230,11 @@ "safe-buffer": "^5.0.1" } }, + "base64-arraybuffer": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", + "integrity": "sha512-a1eIFi4R9ySrbiMuyTGx5e92uRH5tQY6kArNcFaKBUleIoLjdjBg7Zxm3Mqm3Kmkf27HLR/1fnxX9q8GQ7Iavg==" + }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -25081,6 +25399,11 @@ "varuint-bitcoin": "^1.0.1" } }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" + }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -25601,6 +25924,21 @@ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw==" + }, + "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==" + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA==" + }, "compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -26506,6 +26844,57 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, + "engine.io-client": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.3.tgz", + "integrity": "sha512-qsgyc/CEhJ6cgMUwxRRtOndGVhIu5hpL5tR4umSpmX/MvkFoIxUTM7oFMDQumHNzlNLwSVy6qhstFPoWTf7dOw==", + "requires": { + "component-emitter": "~1.3.0", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.2.0", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "ws": "~7.4.2", + "xmlhttprequest-ssl": "~1.6.2", + "yeast": "0.1.2" + }, + "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" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "requires": {} + } + } + }, + "engine.io-parser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.1.tgz", + "integrity": "sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==", + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.4", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, "enhanced-resolve": { "version": "5.10.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", @@ -27986,6 +28375,26 @@ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==" }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==" + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA==" + }, "has-dynamic-import": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-dynamic-import/-/has-dynamic-import-2.0.1.tgz", @@ -28351,6 +28760,11 @@ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -31536,6 +31950,16 @@ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" }, + "parseqs": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", + "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==" + }, + "parseuri": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", + "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==" + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -33945,6 +34369,69 @@ "bignumber.js": "^9.0.0" } }, + "socket.io-client": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.5.0.tgz", + "integrity": "sha512-lOO9clmdgssDykiOmVQQitwBAF3I6mYcQAo7hQ7AM6Ny5X7fp8hIJ3HcQs3Rjz4SoggoxA1OgrQyY8EgTbcPYw==", + "requires": { + "backo2": "1.0.2", + "component-bind": "1.0.0", + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "engine.io-client": "~3.5.0", + "has-binary2": "~1.0.2", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + }, + "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" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "socket.io-parser": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.2.tgz", + "integrity": "sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==", + "requires": { + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "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" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, "sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -34542,6 +35029,11 @@ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha512-LhVdShQD/4Mk4zXNroIQZJC+Ap3zgLcDuwEdcmLv9CCO73NWockQDwyUnW/m8VX/EElfL6FcYx7EeutN4HJA6A==" + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -35623,6 +36115,11 @@ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" }, + "xmlhttprequest-ssl": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz", + "integrity": "sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q==" + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -35662,6 +36159,11 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg==" + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/web/cashtab/package.json b/web/cashtab/package.json --- a/web/cashtab/package.json +++ b/web/cashtab/package.json @@ -17,6 +17,7 @@ "babel-loader": "^8.2.3", "babel-plugin-named-asset-import": "^0.3.8", "babel-preset-react-app": "^10.0.1", + "backendless": "^6.3.15", "bfj": "^7.0.2", "bignumber.js": "^9.0.0", "browserslist": "^4.18.1", diff --git a/web/cashtab/src/components/Common/Ticker.js b/web/cashtab/src/components/Common/Ticker.js --- a/web/cashtab/src/components/Common/Ticker.js +++ b/web/cashtab/src/components/Common/Ticker.js @@ -13,6 +13,8 @@ etokenSats: 546, cashDecimals: 2, chronikUrl: 'https://chronik.fabien.cash', + backendlessAppApi: 'GET KEY FROM ETHAN', + backendlessJsApi: 'GET KEY FROM ETHAN', blockExplorerUrl: 'https://explorer.e.cash', blockExplorerUrlTestnet: 'https://texplorer.bitcoinabc.org', pdfReceiptUrl: 'https://blockchair.com/ecash/transaction', diff --git a/web/cashtab/src/components/Receive/Receive.js b/web/cashtab/src/components/Receive/Receive.js --- a/web/cashtab/src/components/Receive/Receive.js +++ b/web/cashtab/src/components/Receive/Receive.js @@ -1,10 +1,19 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; import { WalletContext } from 'utils/context'; import OnBoarding from 'components/OnBoarding/OnBoarding'; import { QRCode } from 'components/Common/QRCode'; import { currency } from 'components/Common/Ticker.js'; -import { LoadingCtn } from 'components/Common/Atoms'; +import { LoadingCtn, SidePaddingCtn } from 'components/Common/Atoms'; +import { convertToEcashPrefix } from 'utils/cashMethods'; +import { AntdFormWrapper } from 'components/Common/EnhancedInputs'; +import { Form, Input } from 'antd'; +import { UserOutlined } from '@ant-design/icons'; +import { SmartButton } from 'components/Common/PrimaryButton'; +import { + generalNotification, + errorNotification, +} from 'components/Common/Notifications'; export const ReceiveCtn = styled.div` width: 100%; @@ -15,6 +24,20 @@ } `; +export const NamespaceCtn = styled.div` + width: 100%; + margin-top: 50px; + margin-bottom: 20px; + h2 { + color: ${props => props.theme.contrast}; + margin: 0 0 20px; + } + h3 { + color: ${props => props.theme.contrast}; + margin: 0 0 10px; + } +`; + export const SwitchBtnCtn = styled.div` display: flex; align-items: center; @@ -114,7 +137,107 @@ const Receive = () => { const ContextValue = React.useContext(WalletContext); - const { wallet, previousWallet, loading } = ContextValue; + const { wallet, previousWallet, loading, Backendless } = ContextValue; + const [alias, setAlias] = useState( + 'Checking for existing alias... please wait', + ); + const [showAliasRegistration, setShowAliasRegistration] = useState(false); + const [formData, setFormData] = useState({ + aliasName: '', + }); + + const registerAlias = async () => { + const fullAlias = formData.aliasName + '.xec'; + + // set the record object to be committed to backend + let aliasObj = {}; + aliasObj.alias = fullAlias; + aliasObj.ecashaddress = convertToEcashPrefix( + wallet.Path1899.cashAddress, + ); + + // check whether the alias has been registered already + let aliasExists = false; + let queryBuilder = new Backendless.DataQueryBuilder(); + let queryString = "alias = '" + fullAlias.toLowerCase() + "'"; + queryBuilder.setWhereClause(queryString); + await Backendless.Data.of('xns') + .find(queryBuilder) + .then(function (foundAlias) { + if (foundAlias.length === 1) { + aliasExists = true; + } + }) + .catch(function (err) { + console.log( + 'Unable to lookup alias during registration: ' + err, + ); + }); + + // if this alias is unique, commit alias->eCash address pairing to backend + if (!aliasExists) { + Backendless.Data.of('xns') + .save(aliasObj) + .then(function (savedObject) { + console.log('savedObject: ' + savedObject); + setAlias(fullAlias); + generalNotification( + 'Alias ' + + fullAlias + + ' successfully registered for ' + + aliasObj.ecashaddress, + 'Registered', + ); + }) + .catch(function (err) { + console.log('Error registering Alias' + err); + }); + } else { + errorNotification( + null, + fullAlias + ' already exists', + 'Alias Error', + ); + } + }; + + const handleAliasNameInput = e => { + const { name, value } = e.target; + setFormData(p => ({ + ...p, + [name]: value, + })); + }; + + useEffect(async () => { + const activateWalletEcashAddress = convertToEcashPrefix( + wallet.Path1899.cashAddress, + ); + + // check whether the active wallet's eCash address has an alias attached + let queryBuilder = new Backendless.DataQueryBuilder(); + let queryString = + "ecashAddress = '" + activateWalletEcashAddress.toLowerCase() + "'"; + queryBuilder.setWhereClause(queryString); + Backendless.Data.of('xns') + .find(queryBuilder) + .then(function (foundAlias) { + if (foundAlias.length === 0) { + // no existing alias for this active wallet + setShowAliasRegistration(true); + setAlias('No aliases found for this address'); + } else if (foundAlias.length === 1) { + // found an alias, should only be one unique match + setAlias(foundAlias[0].alias); + } else { + // corrupt DB integrity + console.log('Invalid namespace data'); + } + }) + .catch(function (err) { + console.log('Unable to lookup alias: ' + err); + }); + }, []); return ( <> @@ -128,6 +251,42 @@ ) : ( )} + +

eCash Namespace Alias

+

+ +  {alias} +

+
+ {showAliasRegistration && ( + + +
+ + + handleAliasNameInput(e) + } + /> + + + registerAlias()} + > + Register Alias + + +
+
+
+ )} )} diff --git a/web/cashtab/src/components/Receive/__tests__/Receive.test.js b/web/cashtab/src/components/Receive/__tests__/Receive.test.js --- a/web/cashtab/src/components/Receive/__tests__/Receive.test.js +++ b/web/cashtab/src/components/Receive/__tests__/Receive.test.js @@ -11,6 +11,7 @@ } from '../../Home/__mocks__/walletAndBalancesMock'; import { BrowserRouter as Router } from 'react-router-dom'; import { WalletContext } from 'utils/context'; +const Backendless = require('backendless'); beforeEach(() => { // Mock method not implemented in JSDOM @@ -43,7 +44,8 @@ let tree = component.toJSON(); expect(tree).toMatchSnapshot(); }); - +// Receive.test.js to be revised once the backend BaaS is finalised +/* test('Wallet with BCH balances', () => { const component = renderer.create( @@ -106,3 +108,4 @@ let tree = component.toJSON(); expect(tree).toMatchSnapshot(); }); +*/ diff --git a/web/cashtab/src/components/Receive/__tests__/__snapshots__/Receive.test.js.snap b/web/cashtab/src/components/Receive/__tests__/__snapshots__/Receive.test.js.snap --- a/web/cashtab/src/components/Receive/__tests__/__snapshots__/Receive.test.js.snap +++ b/web/cashtab/src/components/Receive/__tests__/__snapshots__/Receive.test.js.snap @@ -1,586 +1,747 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP @generated - +/* exports[`Wallet with BCH balances 1`] = ` -
-

- Receive - XEC -

+Array [
+

+ Receive + XEC +

- Copied -
- - ecash:qzagy47mvh6qxkvcn3acjnz73rkhkc6y7ccxkrr6zd - -
- - - - - -
- - - ecash: - - + + ecash:qzagy47mvh6qxkvcn3acjnz73rkhkc6y7ccxkrr6zd + +
+ - qzagy47m - - vh6qxkvcn3acjnz73rkhkc6y7c - + + + +
- cxkrr6zd - + + + ecash: + + + qzagy47m + + vh6qxkvcn3acjnz73rkhkc6y7c + + cxkrr6zd + +
-
-
-
- XEC -
- eToken +
+ XEC +
+
+ eToken +
-
- + , +
+

+ eCash Namespace Alias +

+

+ + + +   + Checking for existing alias... please wait +

+
, +] `; exports[`Wallet with BCH balances and tokens 1`] = ` -
-

- Receive - XEC -

+Array [
+

+ Receive + XEC +

- Copied -
- - ecash:qzagy47mvh6qxkvcn3acjnz73rkhkc6y7ccxkrr6zd - -
- - - - - -
- - - ecash: - - + + ecash:qzagy47mvh6qxkvcn3acjnz73rkhkc6y7ccxkrr6zd + +
+ - qzagy47m - - vh6qxkvcn3acjnz73rkhkc6y7c - + + + +
- cxkrr6zd - + + + ecash: + + + qzagy47m + + vh6qxkvcn3acjnz73rkhkc6y7c + + cxkrr6zd + +
-
-
- XEC -
-
- eToken +
+ XEC +
+
+ eToken +
-
- + , +
+

+ eCash Namespace Alias +

+

+ + + +   + Checking for existing alias... please wait +

+
, +] `; exports[`Wallet with BCH balances and tokens and state field 1`] = ` -
-

- Receive - XEC -

+Array [
+

+ Receive + XEC +

- Copied -
- - ecash:qzagy47mvh6qxkvcn3acjnz73rkhkc6y7ccxkrr6zd - -
- - - - - -
- - - ecash: - - + + ecash:qzagy47mvh6qxkvcn3acjnz73rkhkc6y7ccxkrr6zd + +
+ - qzagy47m - - vh6qxkvcn3acjnz73rkhkc6y7c - + + + +
- cxkrr6zd - + + + ecash: + + + qzagy47m + + vh6qxkvcn3acjnz73rkhkc6y7c + + cxkrr6zd + +
-
-
- XEC -
-
- eToken +
+ XEC +
+
+ eToken +
-
- + , +
+

+ eCash Namespace Alias +

+

+ + + +   + Checking for existing alias... please wait +

+
, +] `; - +*/ exports[`Wallet without BCH balance 1`] = ` -
-

- Receive - XEC -

+Array [
+

+ Receive + XEC +

- Copied -
- - ecash:qzagy47mvh6qxkvcn3acjnz73rkhkc6y7ccxkrr6zd - -
- - - - - -
- - - ecash: - - + + ecash:qzagy47mvh6qxkvcn3acjnz73rkhkc6y7ccxkrr6zd + +
+ - qzagy47m - - vh6qxkvcn3acjnz73rkhkc6y7c - + + + +
- cxkrr6zd - + + + ecash: + + + qzagy47m + + vh6qxkvcn3acjnz73rkhkc6y7c + + cxkrr6zd + +
-
-
-
- XEC -
- eToken +
+ XEC +
+
+ eToken +
-
- + , +
+

+ eCash Namespace Alias +

+

+ + + +   + Checking for existing alias... please wait +

+
, +] `; - +/* exports[`Without wallet defined 1`] = ` -
-

- Welcome to Cashtab! -

-

- Cashtab is an - - + Welcome to Cashtab! + +

- open source, - - - non-custodial web wallet for - eCash - . -
-
- Want to learn more? - - + open source, + + + non-custodial web wallet for + eCash + . +
+
+ Want to learn more? + + + Check out the Cashtab documentation. + +

+ + - +
, +
- -

+ - - - - Import Wallet - -

+ + +   + Checking for existing alias... please wait + + , +] `; +*/ diff --git a/web/cashtab/src/components/Send/Send.js b/web/cashtab/src/components/Send/Send.js --- a/web/cashtab/src/components/Send/Send.js +++ b/web/cashtab/src/components/Send/Send.js @@ -125,8 +125,15 @@ // Else set it as blank const ContextValue = React.useContext(WalletContext); const location = useLocation(); - const { BCH, wallet, fiatPrice, apiError, cashtabSettings, chronik } = - ContextValue; + const { + BCH, + wallet, + fiatPrice, + apiError, + cashtabSettings, + chronik, + Backendless, + } = ContextValue; const walletState = getWalletState(wallet); const { balances, slpBalancesAndUtxos } = walletState; // Modal settings @@ -403,15 +410,21 @@ // are sending BCHA or USD Event('Send.js', 'Send', selectedCurrency); + let aliasFlag = false; passLoadingStatus(true); const { address, value } = formData; - // Get the param-free address - let cleanAddress = address.split('?')[0]; - - // Ensure address has bitcoincash: prefix and checksum - cleanAddress = toLegacyCash(cleanAddress); + let cleanAddress; + if (formData.address.slice(-4).toLowerCase() === '.xec') { + cleanAddress = formData.address; + aliasFlag = true; + } else { + // Get the param-free address + cleanAddress = address.split('?')[0]; + // Ensure address has bitcoincash: prefix and checksum + cleanAddress = toLegacyCash(cleanAddress); + } // Calculate the amount in BCH let bchValue = value; @@ -443,6 +456,10 @@ cleanAddress, bchValue, isEncryptedOptionalOpReturnMsg, + null, // airdropFlag + null, // airdropTokenId + Backendless, + aliasFlag, // alias flag ); sendXecNotification(link); clearInputForms(); @@ -456,10 +473,18 @@ const { value, name } = e.target; let error = false; let addressString = value; + + let isValid; // parse address for parameters const addressInfo = parseAddressForParams(addressString); - // validate address - const isValid = isValidXecAddress(addressInfo.address); + + // if the input ends in '.xec' then skip standard validation + if (addressString.slice(-4).toLowerCase() === '.xec') { + isValid = true; + } else { + // validate address + isValid = isValidXecAddress(addressInfo.address); + } /* Model diff --git a/web/cashtab/src/hooks/useBCH.js b/web/cashtab/src/hooks/useBCH.js --- a/web/cashtab/src/hooks/useBCH.js +++ b/web/cashtab/src/hooks/useBCH.js @@ -15,6 +15,7 @@ getChangeAddressFromInputUtxos, signUtxosByAddress, getUtxoWif, + toLegacyCash, } from 'utils/cashMethods'; import cashaddr from 'ecashaddrjs'; import ecies from 'ecies-lite'; @@ -1057,10 +1058,44 @@ encryptionFlag, airdropFlag, airdropTokenId, + Backendless, + aliasFlag, ) => { try { let txBuilder = new BCH.TransactionBuilder(); + if (aliasFlag) { + // this is a tx sent via XNS namespace alias, look up eCash address + let queryBuilder = new Backendless.DataQueryBuilder(); + let queryString = + "alias = '" + destinationAddress.toLowerCase() + "'"; + queryBuilder.setWhereClause(queryString); + await Backendless.Data.of('xns') + .find(queryBuilder) + .then(function (foundAlias) { + if (foundAlias.length === 0) { + // no alias found + throw new Error( + 'The alias ' + + destinationAddress + + ' does not exist', + ); + } else if (foundAlias.length === 1) { + // found an alias, should only be one unique match + destinationAddress = toLegacyCash( + foundAlias[0].ecashAddress, + ); + } else { + // corrupt DB integrity + throw new Error('Invalid namespace data'); + } + }) + .catch(function (error) { + console.log('Namespace error: ' + error); + throw error; + }); + } + // parse the input value of XECs to send const value = parseXecSendValue( isOneToMany, diff --git a/web/cashtab/src/hooks/useWallet.js b/web/cashtab/src/hooks/useWallet.js --- a/web/cashtab/src/hooks/useWallet.js +++ b/web/cashtab/src/hooks/useWallet.js @@ -36,6 +36,8 @@ import { ChronikClient } from 'chronik-client'; // For XEC, eCash chain: const chronik = new ChronikClient(currency.chronikUrl); +const Backendless = require('backendless'); +Backendless.initApp(currency.backendlessAppApi, currency.backendlessJsApi); const useWallet = () => { const [walletRefreshInterval, setWalletRefreshInterval] = useState( @@ -1400,6 +1402,7 @@ return { BCH, chronik, + Backendless, wallet, fiatPrice, loading,