diff --git a/angular.json b/angular.json index 3cea02daa028fa979a8792ceac158bb388985512..2969763b1fbeb4de901c4e92d9f01c8f23898e92 100644 --- a/angular.json +++ b/angular.json @@ -195,7 +195,13 @@ } }, "cli": { - "defaultCollection": "@ionic/angular-toolkit" + "defaultCollection": "@ionic/angular-toolkit", + "packageManager": "yarn", + "analytics": false, + "cache": { + "enabled": true, + "environment": "all" + } }, "schematics": { "@ionic/angular-toolkit:component": { diff --git a/package-lock.json b/package-lock.json index 0cedd897bdd731d30f0f50fe1cdaad481c8fc816..033b5a5332f0aafca681aec19d69ac13d123790a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,6 @@ "@capacitor/haptics": "1.0.2", "@capacitor/keyboard": "1.0.2", "@capacitor/status-bar": "1.0.2", - "@capacitor/storage": "^1.2.5", "@ionic/angular": "^6.1.11", "@ionic/storage": "^3.0.6", "@ionic/storage-angular": "^3.0.6", @@ -39,6 +38,7 @@ "moment-timezone": "^0.5.34", "ngx-jdenticon": "^1.0.4", "rxjs": "~7.4.0", + "scrypt-async": "^2.0.1", "stream-browserify": "^3.0.0", "tslib": "^2.0.0", "zone.js": "~0.11.6" @@ -53,7 +53,6 @@ "@angular/compiler": "~13.3.11", "@angular/compiler-cli": "~13.3.11", "@angular/language-service": "~13.3.11", - "@biesbjerg/ngx-translate-extract": "^7.0.4", "@capacitor/cli": "3.6.0", "@ionic/angular-toolkit": "^6.1.0", "@polkadot/typegen": "^8.9.1", @@ -2725,34 +2724,6 @@ "node": ">=6.9.0" } }, - "node_modules/@biesbjerg/ngx-translate-extract": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/@biesbjerg/ngx-translate-extract/-/ngx-translate-extract-7.0.4.tgz", - "integrity": "sha512-33hR94Fu26LK7Z+ImW2IdZiHfOcAzyIs1CdkUXg/536z2MqxBYqPoI9Ghsk6RTEfnsGa65wMgOcDXn7Ilhp8ew==", - "dev": true, - "dependencies": { - "@phenomnomnominal/tsquery": "^4.1.1", - "boxen": "^5.0.1", - "colorette": "^1.2.2", - "flat": "^5.0.2", - "gettext-parser": "^4.0.4", - "glob": "^7.1.6", - "mkdirp": "^1.0.4", - "path": "^0.12.7", - "terminal-link": "^2.1.1", - "yargs": "^16.2.0" - }, - "bin": { - "ngx-translate-extract": "bin/cli.js" - }, - "engines": { - "node": ">=11.15.0" - }, - "peerDependencies": { - "@angular/compiler": ">=8.0.0", - "typescript": ">=3.0.0" - } - }, "node_modules/@capacitor/app": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@capacitor/app/-/app-1.0.2.tgz", @@ -2857,15 +2828,6 @@ "@capacitor/core": "^3.0.0" } }, - "node_modules/@capacitor/storage": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@capacitor/storage/-/storage-1.2.5.tgz", - "integrity": "sha512-pWhnw4U7wN/zFV4lA4BLMypSufTktCbk548Yk4whSb0KAq3R0mLfSubRIHkGdcPqQWCsM6g/zUuszurhz6ncWQ==", - "deprecated": "package has been renamed to @capacitor/preferences", - "peerDependencies": { - "@capacitor/core": "^3.0.0" - } - }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -4004,18 +3966,6 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@phenomnomnominal/tsquery": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@phenomnomnominal/tsquery/-/tsquery-4.2.0.tgz", - "integrity": "sha512-hR2U3uVcrrdkuG30ItQ+uFDs4ncZAybxWG0OjTE8ptPzVoU7GVeXpy+vMU8zX9EbmjGeITPw/su5HjYQyAH8bA==", - "dev": true, - "dependencies": { - "esquery": "^1.0.1" - }, - "peerDependencies": { - "typescript": "^3 || ^4" - } - }, "node_modules/@polkadot/api": { "version": "8.14.1", "resolved": "https://registry.npmjs.org/@polkadot/api/-/api-8.14.1.tgz", @@ -6207,15 +6157,6 @@ } } }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dev": true, - "dependencies": { - "string-width": "^4.1.0" - } - }, "node_modules/ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", @@ -6810,110 +6751,6 @@ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", "dev": true }, - "node_modules/boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", - "dev": true, - "dependencies": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/boxen/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/boxen/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/boxen/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/boxen/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/boxen/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/boxen/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/boxen/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/bplist-parser": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.2.tgz", @@ -7240,18 +7077,6 @@ "node": ">=6" } }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/caniuse-lite": { "version": "1.0.30001358", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001358.tgz", @@ -7371,18 +7196,6 @@ "node": ">=6" } }, - "node_modules/cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -7474,12 +7287,6 @@ "color-support": "bin.js" } }, - "node_modules/colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", - "dev": true - }, "node_modules/colors": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", @@ -8766,6 +8573,7 @@ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "dev": true, + "optional": true, "dependencies": { "iconv-lite": "^0.6.2" } @@ -8775,6 +8583,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, + "optional": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -10770,38 +10579,6 @@ "assert-plus": "^1.0.0" } }, - "node_modules/gettext-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/gettext-parser/-/gettext-parser-4.2.0.tgz", - "integrity": "sha512-aMgPyjC9W5Mz9tbFU8DcQ7GYMXoFWq633kaWGt4imlcpBWzDIWk7HY7nCSZTCJxyjRaLq9L/NEjMKkZ9gR630Q==", - "dev": true, - "dependencies": { - "content-type": "^1.0.4", - "encoding": "^0.1.13", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.1" - } - }, - "node_modules/gettext-parser/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -14699,16 +14476,6 @@ "node": ">= 0.8" } }, - "node_modules/path": { - "version": "0.12.7", - "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", - "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==", - "dev": true, - "dependencies": { - "process": "^0.11.1", - "util": "^0.10.3" - } - }, "node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -15527,15 +15294,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -16616,6 +16374,11 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "node_modules/scrypt-async": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/scrypt-async/-/scrypt-async-2.0.1.tgz", + "integrity": "sha512-wHR032jldwZNy7Tzrfu7RccOgGf8r5hyDMSP2uV6DpLiBUsR8JsDcx/in73o2UGVVrH5ivRFdNsFPcjtl3LErQ==" + }, "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -17553,40 +17316,6 @@ "node": ">=4" } }, - "node_modules/supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -17667,22 +17396,6 @@ "node": ">=6" } }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/terser": { "version": "5.11.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.11.0.tgz", @@ -18257,26 +17970,11 @@ "node": ">=6.14.2" } }, - "node_modules/util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", - "dev": true, - "dependencies": { - "inherits": "2.0.3" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "node_modules/util/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true - }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -19027,18 +18725,6 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, - "node_modules/widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "dependencies": { - "string-width": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/wildcard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", @@ -19238,9 +18924,9 @@ } }, "node_modules/zone.js": { - "version": "0.11.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.11.6.tgz", - "integrity": "sha512-umJqFtKyZlPli669gB1gOrRE9hxUUGkZr7mo878z+NEBJZZixJkKeVYfnoLa7g25SseUDc92OZrMKKHySyJrFg==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.11.8.tgz", + "integrity": "sha512-82bctBg2hKcEJ21humWIkXRlLBBmrc3nN7DFh5LGGhcyycO2S7FN8NmdvlcKaGFDNVL4/9kFLmwmInTavdJERA==", "dependencies": { "tslib": "^2.3.0" } @@ -21102,24 +20788,6 @@ "to-fast-properties": "^2.0.0" } }, - "@biesbjerg/ngx-translate-extract": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/@biesbjerg/ngx-translate-extract/-/ngx-translate-extract-7.0.4.tgz", - "integrity": "sha512-33hR94Fu26LK7Z+ImW2IdZiHfOcAzyIs1CdkUXg/536z2MqxBYqPoI9Ghsk6RTEfnsGa65wMgOcDXn7Ilhp8ew==", - "dev": true, - "requires": { - "@phenomnomnominal/tsquery": "^4.1.1", - "boxen": "^5.0.1", - "colorette": "^1.2.2", - "flat": "^5.0.2", - "gettext-parser": "^4.0.4", - "glob": "^7.1.6", - "mkdirp": "^1.0.4", - "path": "^0.12.7", - "terminal-link": "^2.1.1", - "yargs": "^16.2.0" - } - }, "@capacitor/app": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@capacitor/app/-/app-1.0.2.tgz", @@ -21200,12 +20868,6 @@ "integrity": "sha512-NgAZIw8Uq2lm6Ln1lWipAqi/YxqIDd92boO4k81Z1WMOdZJt6oLxZB8LfJRDLXU7xNkpW97zHcNBf5pIXJIFqw==", "requires": {} }, - "@capacitor/storage": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@capacitor/storage/-/storage-1.2.5.tgz", - "integrity": "sha512-pWhnw4U7wN/zFV4lA4BLMypSufTktCbk548Yk4whSb0KAq3R0mLfSubRIHkGdcPqQWCsM6g/zUuszurhz6ncWQ==", - "requires": {} - }, "@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -22072,15 +21734,6 @@ "node-gyp-build": "^4.3.0" } }, - "@phenomnomnominal/tsquery": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@phenomnomnominal/tsquery/-/tsquery-4.2.0.tgz", - "integrity": "sha512-hR2U3uVcrrdkuG30ItQ+uFDs4ncZAybxWG0OjTE8ptPzVoU7GVeXpy+vMU8zX9EbmjGeITPw/su5HjYQyAH8bA==", - "dev": true, - "requires": { - "esquery": "^1.0.1" - } - }, "@polkadot/api": { "version": "8.14.1", "resolved": "https://registry.npmjs.org/@polkadot/api/-/api-8.14.1.tgz", @@ -23819,15 +23472,6 @@ "ajv": "^8.0.0" } }, - "ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dev": true, - "requires": { - "string-width": "^4.1.0" - } - }, "ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", @@ -24274,79 +23918,6 @@ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", "dev": true }, - "boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", - "dev": true, - "requires": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - } - } - }, "bplist-parser": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.2.tgz", @@ -24604,12 +24175,6 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, "caniuse-lite": { "version": "1.0.30001358", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001358.tgz", @@ -24697,12 +24262,6 @@ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true }, - "cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "dev": true - }, "cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -24773,12 +24332,6 @@ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true }, - "colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", - "dev": true - }, "colors": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", @@ -25772,6 +25325,7 @@ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "dev": true, + "optional": true, "requires": { "iconv-lite": "^0.6.2" }, @@ -25781,6 +25335,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, + "optional": true, "requires": { "safer-buffer": ">= 2.1.2 < 3.0.0" } @@ -27221,26 +26776,6 @@ "assert-plus": "^1.0.0" } }, - "gettext-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/gettext-parser/-/gettext-parser-4.2.0.tgz", - "integrity": "sha512-aMgPyjC9W5Mz9tbFU8DcQ7GYMXoFWq633kaWGt4imlcpBWzDIWk7HY7nCSZTCJxyjRaLq9L/NEjMKkZ9gR630Q==", - "dev": true, - "requires": { - "content-type": "^1.0.4", - "encoding": "^0.1.13", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, "glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -30207,16 +29742,6 @@ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true }, - "path": { - "version": "0.12.7", - "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", - "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==", - "dev": true, - "requires": { - "process": "^0.11.1", - "util": "^0.10.3" - } - }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -30751,12 +30276,6 @@ "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", "dev": true }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -31582,6 +31101,11 @@ } } }, + "scrypt-async": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/scrypt-async/-/scrypt-async-2.0.1.tgz", + "integrity": "sha512-wHR032jldwZNy7Tzrfu7RccOgGf8r5hyDMSP2uV6DpLiBUsR8JsDcx/in73o2UGVVrH5ivRFdNsFPcjtl3LErQ==" + }, "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -32317,33 +31841,6 @@ "has-flag": "^3.0.0" } }, - "supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", - "dev": true, - "requires": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -32403,16 +31900,6 @@ "readable-stream": "^3.1.1" } }, - "terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - } - }, "terser": { "version": "5.11.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.11.0.tgz", @@ -32822,23 +32309,6 @@ "node-gyp-build": "^4.3.0" } }, - "util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true - } - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -33391,15 +32861,6 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, - "widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "requires": { - "string-width": "^4.0.0" - } - }, "wildcard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", @@ -33545,9 +33006,9 @@ "dev": true }, "zone.js": { - "version": "0.11.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.11.6.tgz", - "integrity": "sha512-umJqFtKyZlPli669gB1gOrRE9hxUUGkZr7mo878z+NEBJZZixJkKeVYfnoLa7g25SseUDc92OZrMKKHySyJrFg==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.11.8.tgz", + "integrity": "sha512-82bctBg2hKcEJ21humWIkXRlLBBmrc3nN7DFh5LGGhcyycO2S7FN8NmdvlcKaGFDNVL4/9kFLmwmInTavdJERA==", "requires": { "tslib": "^2.3.0" } diff --git a/package.json b/package.json index 783d0b0d2b6a5d7ccbad22965ba21a2d0af06b72..e26caf225494c265603c44b9cf6b88389931de4e 100644 --- a/package.json +++ b/package.json @@ -36,9 +36,7 @@ "@capacitor/haptics": "1.0.2", "@capacitor/keyboard": "1.0.2", "@capacitor/status-bar": "1.0.2", - "@capacitor/storage": "^1.2.5", "@ionic/angular": "^6.1.11", - "@ionic/storage": "^3.0.6", "@ionic/storage-angular": "^3.0.6", "@ngx-translate/core": "^13.0.0", "@ngx-translate/http-loader": "^6.0.0", @@ -93,6 +91,8 @@ "typescript": "~4.6.4" }, "engines": { - "node": ">= 14.17.3" + "node": ">= 14.17.3", + "yarn": ">= 1.22.19", + "npm": ">= 8.17.0" } } diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index d112a9351df0a361025fbd17dbae49fb3bac6b43..88f43782b5cd76e42013bd71c59a3a55b5685890 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -12,7 +12,7 @@ const routes: Routes = [ loadChildren: () => import('./home/home.module').then( m => m.HomeModule) }, { - path: 'wallet/:id', + path: 'wallet', loadChildren: () => import('./wallet/wallet.module').then( m => m.WalletPageModule) }, { diff --git a/src/app/app.component.ts b/src/app/app.component.ts index ec0f29fff0cbcd11f1b6ddfa30176e69da55db32..90f9f03cde8dbfecea3c4d76962f0c56fb0cb9dc 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -13,7 +13,7 @@ export class AppComponent { appPages = [ { title: 'MENU.HOME', url: '/home', icon: 'home' }, - { title: 'MENU.ACCOUNT', url: '/wallet/Alice', icon: 'card' }, + { title: 'MENU.ACCOUNT', url: '/wallet', icon: 'card' }, { title: 'TRANSFER.SUB_TITLE', url: '/transfer', icon: 'paper-plane' }, // { title: 'Messages', url: '/message/inbox', icon: 'mail' }, diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 8e4eae9be6b57ce9d8137afd0a6f90956e00dd85..15e6be2447bb533b7d9e73902b8ba1fb4a041d79 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -2,7 +2,7 @@ import {NgModule} from '@angular/core'; import {BrowserModule} from '@angular/platform-browser'; import {RouteReuseStrategy} from '@angular/router'; -import {IonicModule, IonicRouteStrategy} from '@ionic/angular'; +import {IonicModule, IonicRouteStrategy, Platform} from '@ionic/angular'; import {AppComponent} from './app.component'; import {AppRoutingModule} from './app-routing.module'; @@ -11,13 +11,14 @@ import {BrowserAnimationsModule} from "@angular/platform-browser/animations"; import {HttpClient, HttpClientModule} from "@angular/common/http"; import {TranslateLoader, TranslateModule} from '@ngx-translate/core'; import {TranslateHttpLoader} from '@ngx-translate/http-loader'; -import {IonicStorageModule} from '@ionic/storage-angular'; +import {IonicStorageModule, Storage} from '@ionic/storage-angular'; import {environment} from "@environments/environment"; import {AppSharedModule} from "@app/shared/shared.module"; import {APP_BASE_HREF} from "@angular/common"; import {JDENTICON_CONFIG} from "ngx-jdenticon"; import {APP_LOCALES} from "@app/settings/settings.model"; -import {FormsModule, ReactiveFormsModule} from "@angular/forms"; +import {APP_STORAGE} from "@app/shared/services/storage/storage.interface"; +import {StorageService} from "@app/shared/services/storage/storage.service"; export function createTranslateLoader(http: HttpClient) { return new TranslateHttpLoader(http, './assets/i18n/', '.json'); @@ -33,7 +34,7 @@ export function createTranslateLoader(http: HttpClient) { AppRoutingModule, AppSharedModule, IonicStorageModule.forRoot({ - name: environment.name || 'cesium', // default + name: environment.name || 'cesium', ...environment.storage }), TranslateModule.forRoot({ @@ -49,6 +50,8 @@ export function createTranslateLoader(http: HttpClient) { providers: [ { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, { provide: PlatformService, useClass: PlatformService }, + { provide: StorageService, useClass: StorageService, deps: [Platform, Storage] }, + { provide: APP_STORAGE, useExisting: StorageService }, {provide: APP_BASE_HREF, useValue: (environment.baseUrl || '/')}, diff --git a/src/app/auth/auth.modal.ts b/src/app/auth/auth.modal.ts index 475948de2f6f69c52f8fd46954d0448f73cf7df0..31cf3c46be3dc0d95fabfcfdd4f73f23e6fb68cd 100644 --- a/src/app/auth/auth.modal.ts +++ b/src/app/auth/auth.modal.ts @@ -85,9 +85,11 @@ export class AuthModal implements OnInit { protected markAsLoading(opts?: {emitEvent?: boolean}) { this.form.markAsLoading(opts); + this.markForCheck(); } protected markAsLoaded(opts?: {emitEvent?: boolean}) { this.form.markAsLoaded(opts); + this.markForCheck(); } } diff --git a/src/app/auth/auth.model.ts b/src/app/auth/auth.model.ts index b2fd6beb32aef60c3c321070fca1f2c77fe5bfd2..f035217c3351b711425e6e774503d138bd6abf11 100644 --- a/src/app/auth/auth.model.ts +++ b/src/app/auth/auth.model.ts @@ -1,9 +1,6 @@ -import {AccountMeta} from "@app/wallet/account.model"; - export interface AuthData { - phrase?: string; - meta?: AccountMeta; + password?: string; v1?: { salt: string; diff --git a/src/app/network/currency.model.ts b/src/app/network/currency.model.ts index 2a5aada3f83e25fc650a7e2d747f443ccf6c741b..c735f7a9489a6c998b3117da1afa01345851f170 100644 --- a/src/app/network/currency.model.ts +++ b/src/app/network/currency.model.ts @@ -1,5 +1,6 @@ export interface Currency { name: string; symbol: string; + ss58Format: number; genesys: string; } diff --git a/src/app/network/network.service.ts b/src/app/network/network.service.ts index c4c3187190ee7a0f6636980f2d06d5269c06670e..58b343d6f71111286368bef86b12ed036345704f 100644 --- a/src/app/network/network.service.ts +++ b/src/app/network/network.service.ts @@ -5,13 +5,21 @@ import {Peer, Peers} from "./peer.model"; import {StartableService} from "@app/shared/services/startable-service.class"; import {abbreviate} from "@app/shared/currencies"; import {Currency} from "@app/network/currency.model"; +import {cryptoWaitReady} from "@polkadot/util-crypto"; //import * as definitions from '@duniter/core-types/interfaces' const WELL_KNOWN_CURRENCIES = Object.freeze({ 'Ğdev': <Currency>{ name: 'Ğdev', symbol: 'ĞD', + ss58Format: 42, genesys: '0x096baa94878da1965c8a7929212f4e7a5f6a813cdcbbb401603b39e5e470b6e0' + }, + 'Ğ1': <Currency>{ + name: 'Ğ1', + symbol: 'Ğ1', + ss58Format: 42, + genesys: '0x___TODO___' } }); @@ -29,8 +37,7 @@ export class NetworkService extends StartableService<ApiPromise> { } get currencySign(): string { - // TODO - return 'GD' + return this.currency.symbol || ''; } constructor( @@ -42,7 +49,6 @@ export class NetworkService extends StartableService<ApiPromise> { } protected async ngOnStart(): Promise<any> { - const settings = await this.settings.ready(); const peers = await this.filterAliveNodes(settings.preferredPeers); @@ -69,7 +75,7 @@ export class NetworkService extends StartableService<ApiPromise> { // get the chain information const chainInfo = await api.registry.getChainProperties(); - this.debug('Connecting to chain: ', chainInfo); + this.debug('Connecting to chain: ', chainInfo.toHuman()); // Read the genesys block hash console.info('Connected to Blockchain genesis: ' + api.genesisHash.toHex()); diff --git a/src/app/register/register.form.html b/src/app/register/register.form.html index e7c8756dc1c8ee49251461ff952ed31569c2dfd5..f27fd9e4e06a50ef1afb20ba81eaa31b56852f05 100644 --- a/src/app/register/register.form.html +++ b/src/app/register/register.form.html @@ -155,7 +155,8 @@ <!-- check code --> <ion-slide> - + <app-unlock-form [control]="form|formGetControl: 'codeConfirmation'" + (change)="checkCodeConfirmation($event)"></app-unlock-form> </ion-slide> <!-- congratulation ! --> diff --git a/src/app/register/register.form.ts b/src/app/register/register.form.ts index 09b81df63511d941ff628c44e234e2d71425f283..4d4fa856e0a15dd4592fb47c761f55f4aa94ee2c 100644 --- a/src/app/register/register.form.ts +++ b/src/app/register/register.form.ts @@ -23,7 +23,8 @@ import {AccountMeta} from "@app/wallet/account.model"; export const REGISTER_FORM_SLIDES = { MNEMONIC: 5, ASK_WORD: 6, - CODE: 9 + CODE: 9, + CODE_CONFIRMATION: 10 } @Component({ @@ -66,6 +67,7 @@ export class RegisterForm extends AppForm<RegisterData> implements OnInit { words: new FormControl(null, Validators.required), wordNumber: new FormControl(null, Validators.required), code: new FormControl(null, Validators.required), + codeConfirmation: new FormControl(null, Validators.compose([Validators.required, this.equalsValidator('code')])), name: new FormControl(null) })); } @@ -77,6 +79,7 @@ export class RegisterForm extends AppForm<RegisterData> implements OnInit { words: 'search average amateur muffin inspire lake resist width intact viable stone barrel'.split(' '), wordNumber: 1, code: 'AAAAA', + codeConfirmation: null, name: 'Nouveau portefeuille' }); } @@ -171,6 +174,9 @@ export class RegisterForm extends AppForm<RegisterData> implements OnInit { case REGISTER_FORM_SLIDES.CODE: this.generateCode(); break; + case REGISTER_FORM_SLIDES.CODE_CONFIRMATION: + this.slideState.canNext = false; + break; } } @@ -216,7 +222,6 @@ export class RegisterForm extends AppForm<RegisterData> implements OnInit { this.markForCheck(); } - generateCode() { let code: string; if (!environment.production) { @@ -231,4 +236,10 @@ export class RegisterForm extends AppForm<RegisterData> implements OnInit { this.form.patchValue({code}); this.markForCheck(); } + + checkCodeConfirmation(code: string) { + const expectedCode = this.form.get('code').value; + this.slideState.canNext = expectedCode === code; + this.markForCheck(); + } } diff --git a/src/app/register/register.module.ts b/src/app/register/register.module.ts index c9bd19b93976144aa4a88cfdf5f29bc5bd8792c6..e7ceb82c397ae47fc88da4af48d8f1132313e563 100644 --- a/src/app/register/register.module.ts +++ b/src/app/register/register.module.ts @@ -7,6 +7,7 @@ import {RegisterForm} from "@app/register/register.form"; import {RegisterModal} from "@app/register/register.modal"; import {TranslateModule} from "@ngx-translate/core"; import {AppSharedModule} from "@app/shared/shared.module"; +import {AppUnlockModule} from "@app/unlock/unlock.module"; @NgModule({ imports: [ @@ -14,7 +15,8 @@ import {AppSharedModule} from "@app/shared/shared.module"; FormsModule, IonicModule, TranslateModule, - AppSharedModule + AppSharedModule, + AppUnlockModule ], exports: [ RegisterForm, RegisterModal diff --git a/src/app/shared/pipes/account.pipes.ts b/src/app/shared/pipes/account.pipes.ts new file mode 100644 index 0000000000000000000000000000000000000000..a6b2591c1753d13df726cd73daf40d62d21f6a45 --- /dev/null +++ b/src/app/shared/pipes/account.pipes.ts @@ -0,0 +1,34 @@ +import {Pipe, PipeTransform} from '@angular/core'; +import {NumberFormatPipe} from "@app/shared/pipes/number-format.pipe"; +import {NetworkService} from "@app/network/network.service"; +import {Account, AccountUtils} from "@app/wallet/account.model"; +import {isNotNilOrBlank} from "@app/shared/functions"; +import {AddressFormatPipe} from "@app/shared/pipes/address.pipes"; + +@Pipe({ + name: 'balance' +}) +export class AccountBalancePipe implements PipeTransform { + + delegate = new NumberFormatPipe(); + + constructor(private networkService: NetworkService) { + } + + transform(account: Partial<Account>, opts?: Intl.NumberFormatOptions & {fixedDecimals?: number}): number | undefined { + if (!account?.data) return undefined; + return AccountUtils.getBalance(account); + } +} + +@Pipe({ + name: 'accountName' +}) +export class AccountNamePipe implements PipeTransform { + + private addressFormatter = new AddressFormatPipe(); + + transform(account: Partial<Account>): string { + return account?.meta?.name || this.addressFormatter.transform(account?.address, true); + } +} diff --git a/src/app/shared/pipes/address.pipes.ts b/src/app/shared/pipes/address.pipes.ts index d2116387cd501a7436220343517beea53c5390fc..cce70c175635931a41d2191740e092bf18dcde93 100644 --- a/src/app/shared/pipes/address.pipes.ts +++ b/src/app/shared/pipes/address.pipes.ts @@ -1,7 +1,4 @@ -import {ChangeDetectorRef, OnDestroy, Pipe, PipeTransform} from '@angular/core'; -import {AbstractControl, FormArray, FormControl, FormGroup} from '@angular/forms'; -import {Subscription} from 'rxjs'; -import {equals} from '../functions'; +import {Pipe, PipeTransform} from '@angular/core'; @Pipe({ name: 'addressFormat' diff --git a/src/app/shared/pipes/amount.pipe.ts b/src/app/shared/pipes/amount.pipe.ts index dafb1a9d2a96223262a9d45059b6283d2db2b5a8..fb39d71480f0e6e1df027f21de1cf6c61a34c522 100644 --- a/src/app/shared/pipes/amount.pipe.ts +++ b/src/app/shared/pipes/amount.pipe.ts @@ -13,7 +13,7 @@ export class AmountFormatPipe extends NumberFormatPipe { super(); } - transform(val: number, opts?: Intl.NumberFormatOptions & {fixedDecimals?: number}): string | Promise<string> { + transform(val: number, opts?: Intl.NumberFormatOptions & {fixedDecimals?: number}): string { if (isNil(val)) return ''; return super.transform(val / 100, opts) + (' ' + this.networkService.currencySign); } diff --git a/src/app/shared/pipes/number-format.pipe.ts b/src/app/shared/pipes/number-format.pipe.ts index df03ccdbc12554ccb4d60fa60e4cbf5d1c3197aa..4a27088c0f0b7f768453305e15ccff9c6d4f0868 100644 --- a/src/app/shared/pipes/number-format.pipe.ts +++ b/src/app/shared/pipes/number-format.pipe.ts @@ -5,7 +5,7 @@ import {Pipe, PipeTransform} from '@angular/core'; }) export class NumberFormatPipe implements PipeTransform { - transform(val: number, opts?: Intl.NumberFormatOptions & {fixedDecimals?: number}): string | Promise<string> { + transform(val: number, opts?: Intl.NumberFormatOptions & {fixedDecimals?: number}): string { // Format the output to display any way you want here. // For instance: if (val !== undefined && val !== null) { diff --git a/src/app/shared/pipes/pipes.module.ts b/src/app/shared/pipes/pipes.module.ts index 39595e7cd28f1234227b3b5790bbfd2cd97153e4..81e39fac7105921f2988ab1f3097112cd75c2843 100644 --- a/src/app/shared/pipes/pipes.module.ts +++ b/src/app/shared/pipes/pipes.module.ts @@ -34,6 +34,7 @@ import {FormGetArrayPipe, FormGetControlPipe, FormGetGroupPipe, FormGetPipe, For import {PropertyGetPipe} from './property.pipes'; import {AmountFormatPipe} from "@app/shared/pipes/amount.pipe"; import {AddressFormatPipe} from "@app/shared/pipes/address.pipes"; +import {AccountBalancePipe, AccountNamePipe} from "@app/shared/pipes/account.pipes"; @NgModule({ imports: [ @@ -78,7 +79,10 @@ import {AddressFormatPipe} from "@app/shared/pipes/address.pipes"; // Currency pipes AmountFormatPipe, AddressFormatPipe, - AbbreviatePipe + AbbreviatePipe, + // Account pipes + AccountBalancePipe, + AccountNamePipe ], exports: [ PropertyGetPipe, @@ -117,7 +121,10 @@ import {AddressFormatPipe} from "@app/shared/pipes/address.pipes"; // Currency pipes AmountFormatPipe, AddressFormatPipe, - AbbreviatePipe + AbbreviatePipe, + // Account pipes + AccountBalancePipe, + AccountNamePipe ] }) export class SharedPipesModule { diff --git a/src/app/shared/services/keyring-storage.ts b/src/app/shared/services/keyring-storage.ts index a44f97690aa2cc62363c8ad8f66c272fc5f682ee..4e8f7962f2375403bc267557c742128201712ce3 100644 --- a/src/app/shared/services/keyring-storage.ts +++ b/src/app/shared/services/keyring-storage.ts @@ -1,35 +1,38 @@ import {KeyringJson, KeyringStore} from "@polkadot/ui-keyring/types"; -import {StorageService} from "@app/shared/services/storage.service"; +import {Directive} from '@angular/core'; +import {IStorage} from "@app/shared/services/storage/storage.interface"; +// @dynamic +@Directive() export class KeyringStorage implements KeyringStore { constructor( - protected storage: StorageService, + protected storage: IStorage, protected storagePrefix?: string ) { this.storagePrefix = this.storagePrefix || 'keyring-'; } - get(key: string, cb) { - this.storage.getObject(this.storagePrefix + key) + get(key: string, cb: (value: KeyringJson) => void) { + this.storage.get(this.storagePrefix + key) .then(json => cb(json as unknown as KeyringJson)); } - set(key: string, value: KeyringJson, cb) { - this.storage.setObject(this.storagePrefix + key, value).then(cb); + set(key: string, value: KeyringJson, cb?: () => void) { + this.storage.set(this.storagePrefix + key, value) + .then(() => cb && cb()); } - remove(key, cb) { - this.storage.removeItem(this.storagePrefix + key).then(cb); + remove(key: string, cb?: () => void) { + this.storage.remove(this.storagePrefix + key) + .then(() => cb && cb()); } - async all(cb) { - const keys = await this.storage.keys(); - for (let key of keys) { + all(cb: (key: string, value: KeyringJson) => void) { + this.storage.forEach((value, key, counter) => { if (key.startsWith(this.storagePrefix)) { - const json = await this.storage.getObject(key); const shortKey = key.substring(this.storagePrefix.length); - cb(shortKey, json as unknown as KeyringJson); + cb(shortKey, value as KeyringJson); } - } + }); } } diff --git a/src/app/shared/services/platform.service.ts b/src/app/shared/services/platform.service.ts index 46372fd4b0a1e8f5a869ea9fe81b51ef0da2b52a..f861f7b0bec88e25f7bfaab1682b5ec45e654cb3 100644 --- a/src/app/shared/services/platform.service.ts +++ b/src/app/shared/services/platform.service.ts @@ -3,7 +3,7 @@ import {Platform} from "@ionic/angular"; import {NetworkService} from "../../network/network.service"; import {SettingsService} from "../../settings/settings.service"; import {StartableService} from "@app/shared/services/startable-service.class"; -import {StorageService} from "@app/shared/services/storage.service"; +import {StorageService} from "@app/shared/services/storage/storage.service"; import {environment} from "@environments/environment.prod"; import {TranslateService} from "@ngx-translate/core"; import * as momentImported from 'moment'; @@ -50,13 +50,11 @@ export class PlatformService extends StartableService { // Configure translation await this.configureTranslate(); - await this.configureStorage(); - await Promise.all([ - this.settings.ready(), - this.network.ready() - ] - ); + this.storage.ready(), + this.settings.ready(), + this.network.ready() + ]); } @@ -98,10 +96,4 @@ export class PlatformService extends StartableService { }); } - private async configureStorage(): Promise<void> { - console.info(`[platform] Configure storage...`); - await this.storage.configure({ - group: environment.storage?.name - }); - } } diff --git a/src/app/shared/services/storage.service.ts b/src/app/shared/services/storage.service.ts deleted file mode 100644 index fa30c12dc79a2ed80ee3ce4f34ad792e3b030eb2..0000000000000000000000000000000000000000 --- a/src/app/shared/services/storage.service.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Injectable } from '@angular/core'; -import {ConfigureOptions, Storage} from '@capacitor/storage'; - - -@Injectable({ - providedIn: 'root' -}) -export class StorageService { - - constructor() { } - - configure(options: ConfigureOptions): Promise<void> { - return Storage.configure(options); - } - - async setString(key: string, value: string) { - await Storage.set({ key, value }); - } - - async getString(key: string): Promise<{ value: any }> { - return (await Storage.get({ key })); - } - - async setObject(key: string, value: any) { - await Storage.set({ key, value: JSON.stringify(value) }); - } - - async getObject(key: string): Promise<{ value: any }> { - const ret = await Storage.get({ key }); - return JSON.parse(ret.value); - } - - async removeItem(key: string) { - await Storage.remove({ key }); - } - - async keys(): Promise<string[]> { - const {keys} = await Storage.keys(); - return keys; - } - - async clear() { - await Storage.clear(); - } -} diff --git a/src/app/shared/services/storage/storage.interface.ts b/src/app/shared/services/storage/storage.interface.ts new file mode 100644 index 0000000000000000000000000000000000000000..9d3e4fa44dfab11e05d6fbd00ec94c4e8731c5bc --- /dev/null +++ b/src/app/shared/services/storage/storage.interface.ts @@ -0,0 +1,14 @@ +import {InjectionToken} from "@angular/core"; + +export interface IStorage<T = any> { + readonly driver: string; + ready(): Promise<T> + set(key: string, value: any): Promise<void>; + get(key: string): Promise<any>; + remove(key: string): Promise<void> + keys(): Promise<string[]>; + clear(): Promise<void>; + forEach(iteratorCallback: (value: any, key: string, iterationNumber: Number) => any): Promise<void>; +} + +export const APP_STORAGE = new InjectionToken<IStorage>('Storage'); diff --git a/src/app/shared/services/storage/storage.service.ts b/src/app/shared/services/storage/storage.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..4a8d98f0821e842eadd4212e621454e95dbd8f9a --- /dev/null +++ b/src/app/shared/services/storage/storage.service.ts @@ -0,0 +1,58 @@ +import {Injectable} from '@angular/core'; +import {Storage} from '@ionic/storage-angular'; +import {StartableService} from "@app/shared/services/startable-service.class"; +import {IStorage} from "@app/shared/services/storage/storage.interface"; +import {Platform} from '@ionic/angular'; + +@Injectable({ + providedIn: 'root' +}) +export class StorageService extends StartableService<Storage> + implements IStorage<Storage> { + + get driver(): string | undefined { + return this._data?.driver; + } + + constructor(private platform: Platform, + private storage: Storage) { + super(platform); + this.start(); + } + + + protected async ngOnStart(): Promise<Storage> { + await this.platform.ready(); + return this.storage.create(); + } + + async set(key: string, value: any) { + if (!this.started) await this.ready(); + return this._data.set(key, value); + } + + async get(key: string): Promise<any> { + if (!this.started) await this.ready(); + return this._data.get(key); + } + + async remove(key: string) { + if (!this.started) await this.ready(); + return this._data.remove(key); + } + + async keys(): Promise<string[]> { + if (!this.started) await this.ready(); + return this._data.keys(); + } + + async clear() { + if (!this.started) await this.ready(); + await this._data.clear(); + } + + async forEach(iteratorCallback: (value: any, key: string, iterationNumber: Number) => any): Promise<void> { + if (!this.started) await this.ready(); + return this._data.forEach(iteratorCallback); + } +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 15a36ff32f3ae3b10f895d1d98105d0de27fb90e..bcff8e47b0221bcde5c3e12dea7235165288b3a7 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -5,6 +5,7 @@ import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {IonicModule} from '@ionic/angular'; import {TranslateModule} from "@ngx-translate/core"; import {SharedPipesModule} from "@app/shared/pipes/pipes.module"; +import {BrowserAnimationsModule} from "@angular/platform-browser/animations"; @NgModule({ imports: [ diff --git a/src/app/transfer/transfer.page.html b/src/app/transfer/transfer.page.html index c5b192f10996315d18ccbabe757b80f0a66169e7..3eaeaed88e0b2a438e186b5d0f5714b0fa18a49c 100644 --- a/src/app/transfer/transfer.page.html +++ b/src/app/transfer/transfer.page.html @@ -1,5 +1,5 @@ <ion-header [translucent]="true"> - <ion-toolbar> + <ion-toolbar color="primary"> <ion-buttons slot="start"> <ion-menu-button></ion-menu-button> </ion-buttons> @@ -16,22 +16,37 @@ <div id="container"> <ion-list> + <!-- error --> + <ion-item *ngIf="error" lines="none" color="light"> + <ion-icon slot="start" name="alert-circle" color="danger"></ion-icon> + <ion-label color="danger">{{error|translate}}</ion-label> + </ion-item> + + <!-- TO --> <ion-item> <ion-label color="medium" slot="start" translate>TRANSFER.TO</ion-label> <ion-input [(ngModel)]="recipient.address" (ionFocus)="modal.present()"> </ion-input> - <ion-button slot="end" id="open-modal-trigger"> + <ion-button slot="end" fill="clear" id="open-modal-trigger" [title]="'COMMON.BTN_SEARCH'|translate"> <ion-icon slot="icon-only" name="search"></ion-icon> </ion-button> </ion-item> - <ion-item> + + <!-- FROM --> + <ion-item > <ion-label color="medium" translate>TRANSFER.FROM</ion-label> - <ion-select [(ngModel)]="issuer.address"> - <ng-container *ngFor="let account$ of data"> - <ion-select-option *ngIf="(account$|async); let account" [value]="account.address">{{account.meta?.name}}</ion-select-option> - </ng-container> + <ion-select *ngIf="data|async; let accounts; else inputSkeleton" + [(ngModel)]="issuer.address" [interface]="mobile ? 'action-sheet' : 'popover'" + [okText]="'COMMON.BTN_OK'|translate" + [cancelText]="'COMMON.BTN_CANCEL'|translate"> + <ion-select-option *ngFor="let account of accounts" + [value]="account.address" + [disabled]="!(account|balance)"> + {{account|accountName}} + <ng-container *ngIf="account|balance; let balance">({{balance|amountFormat}})</ng-container> + </ion-select-option> </ion-select> - <ion-badge *ngIf="issuer" slot="end">{{issuer.free|amountFormat}}</ion-badge> + <ion-badge *ngIf="issuer?.address" slot="end">{{issuer|balance|amountFormat}}</ion-badge> </ion-item> <ion-item> @@ -56,10 +71,10 @@ </ion-list> <div class="ion-text-center" *ngIf="!mobile"> - <ion-button (click)="cancel()" color="light"> + <ion-button (click)="cancel($event)" color="light"> <ion-label translate>COMMON.BTN_CANCEL</ion-label> </ion-button> - <ion-button (click)="submit()"> + <ion-button (click)="submit($event)"> <ion-icon slot="start" name="paper-plane"></ion-icon> <ion-label translate>TRANSFER.BTN_SEND</ion-label> </ion-button> @@ -72,7 +87,7 @@ [isOpen]="false" [initialBreakpoint]="0.25" [breakpoints]="[0.25, 0.5, 0.75]" - [backdropDismiss]="false" + backdropDismiss="true" [backdropBreakpoint]="0.5" > <ng-template> @@ -88,11 +103,15 @@ </ion-content> <ion-footer *ngIf="mobile"> - <ion-button (click)="wallet.transfer()" color="light"> + <ion-button (click)="cancel($event)" color="light"> <ion-label translate>COMMON.BTN_CANCEL</ion-label> </ion-button> - <ion-button (click)="wallet.transfer()"> + <ion-button (click)="submit($event)"> <ion-icon slot="start" name="paper-plane"></ion-icon> <ion-label translate>TRANSFER.BTN_SEND</ion-label> </ion-button> </ion-footer> + +<ng-template #inputSkeleton> + <ion-skeleton-text [animated]="true" style="width: 60%"></ion-skeleton-text> +</ng-template> diff --git a/src/app/transfer/transfer.page.scss b/src/app/transfer/transfer.page.scss index 281733f194d1a6cca00e20cad7302c7779ffd76b..c5fe043b8dd1c147ec1cf95a64625372943b0cc5 100644 --- a/src/app/transfer/transfer.page.scss +++ b/src/app/transfer/transfer.page.scss @@ -4,3 +4,7 @@ ion-menu-button { #container { } + +.balance { + color: var(--ion-color-base); +} diff --git a/src/app/transfer/transfer.page.ts b/src/app/transfer/transfer.page.ts index fd8b9a444b0474788492841eb2187117953fdf68..bf11748cce09230469849d69c86efb563f5cff28 100644 --- a/src/app/transfer/transfer.page.ts +++ b/src/app/transfer/transfer.page.ts @@ -1,18 +1,37 @@ -import {Component, Injector, OnDestroy, OnInit, ViewChild} from '@angular/core'; +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + Injector, + OnDestroy, + OnInit, + ViewChild +} from '@angular/core'; import {AccountService} from "../wallet/account.service"; import {BasePage} from "@app/shared/pages/base.page"; -import {Account} from "@app/wallet/account.model"; +import {Account, AccountUtils} from "@app/wallet/account.model"; import {IonModal} from "@ionic/angular"; -import {from, Observable} from "rxjs"; +import { + BehaviorSubject, + combineAll, + combineLatestAll, + concat, + concatAll, + from, + Observable, + Subject, + switchMap, + zip +} from "rxjs"; import {isNotNil} from "@app/shared/functions"; -import {FormBuilder} from "@angular/forms"; @Component({ selector: 'app-transfer', templateUrl: './transfer.page.html', styleUrls: ['./transfer.page.scss'], + changeDetection: ChangeDetectionStrategy.OnPush }) -export class TransferPage extends BasePage<Observable<Account>[]> implements OnInit, OnDestroy { +export class TransferPage extends BasePage<Observable<Account[]>> implements OnInit, OnDestroy { showComment: boolean; issuer: Partial<Account> = {}; @@ -21,10 +40,16 @@ export class TransferPage extends BasePage<Observable<Account>[]> implements OnI @ViewChild('modal') modal: IonModal; + get balance(): number { + if (!this.issuer?.data) return undefined; + return (this.issuer.data.free || 0) + (this.issuer.data.reserved || 0); + } + + constructor( injector: Injector, - formBuilder: FormBuilder, - public wallet: AccountService, + protected accountService: AccountService, + protected cd: ChangeDetectorRef ) { super(injector, {name: 'transfer'}); } @@ -39,14 +64,10 @@ export class TransferPage extends BasePage<Observable<Account>[]> implements OnI } } - protected async ngOnLoad(): Promise<Observable<Account>[]> { - await this.wallet.ready(); + protected async ngOnLoad(): Promise<Observable<Account[]>> { + await this.accountService.ready(); - const accounts = await this.wallet.getAll(); - return accounts - .map(a => a.meta?.name) - .filter(isNotNil) - .map(id => from(this.wallet.getById(id))); + return this.accountService.watchAll({positiveBalanceFirst: true}); } setRecipient(recipient: string|Account) { @@ -58,14 +79,26 @@ export class TransferPage extends BasePage<Observable<Account>[]> implements OnI this.recipient.address = recipient; this.recipient.meta = null; } + this.markForCheck(); } - cancel() { + cancel(event?: UIEvent) { // } - submit() { - // TODO send TX + async submit(event?: UIEvent) { + // Check valid + if (!this.recipient || !this.issuer) return; // Skip + + this.resetError(); + try { + const txHash = await this.accountService.transfer(this.issuer, this.recipient, this.amount); + + await this.showToast({message: 'INFO.TRANSFER_SENT'}); + } + catch (err) { + this.setError(err); + } } } diff --git a/src/app/unlock/unlock.form.html b/src/app/unlock/unlock.form.html new file mode 100644 index 0000000000000000000000000000000000000000..ed5a552674fafe901f338fa5929a9f07b70f751f --- /dev/null +++ b/src/app/unlock/unlock.form.html @@ -0,0 +1,22 @@ +<form [formGroup]="form"> + <ion-list> + <ion-item lines="none"> + <ion-text> + <p>TODO i18n - Pour vous authentifier, veuillez <b>composer votre code secret</b> :</p> + </ion-text> + </ion-item> + + <ion-item> + <ion-label color="medium">{{'AUTH.PASSPHRASE'|translate }}</ion-label> + <ion-input formControlName="code" [maxlength]="maxLength" [minlength]="minLength" required + (ionInput)="onChange($event)"></ion-input> + <ion-icon slot="end" name="checkmark" *ngIf="$valid|async"></ion-icon> + </ion-item> + + <ion-item *ngIf="debug" lines="none"> + <ion-text> + {{form|formGetValue:'code'}} + </ion-text> + </ion-item> + </ion-list> +</form> diff --git a/src/app/unlock/unlock.form.scss b/src/app/unlock/unlock.form.scss new file mode 100644 index 0000000000000000000000000000000000000000..fa568caf25f85d7cabba21313fdf65dab0476e2d --- /dev/null +++ b/src/app/unlock/unlock.form.scss @@ -0,0 +1,6 @@ + +.has-footer { + height: calc(100% - var(--app-toolbar-height) - var(--app-footer-height)); +} + + diff --git a/src/app/unlock/unlock.form.ts b/src/app/unlock/unlock.form.ts new file mode 100644 index 0000000000000000000000000000000000000000..4dcee5fc69cedc58cd39b16a163aa358fcf133a2 --- /dev/null +++ b/src/app/unlock/unlock.form.ts @@ -0,0 +1,143 @@ +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, EventEmitter, forwardRef, + Injector, + Input, + OnInit, + Optional, + Output +} from '@angular/core'; +import { + AbstractControl, + FormBuilder, + FormControl, FormControlName, FormGroup, + FormGroupDirective, NG_VALUE_ACCESSOR, + ValidationErrors, + ValidatorFn, + Validators +} from '@angular/forms'; +import {SettingsService} from "@app/settings/settings.service"; +import {environment} from "@environments/environment"; +import {RegisterData} from "@app/register/register.model"; +import {AppForm} from "@app/shared/form.class"; +import {isNotNilOrBlank} from "@app/shared/functions"; +import {distinctUntilChanged, map, Subject} from "rxjs"; + +export const REGISTER_FORM_SLIDES = { + MNEMONIC: 5, + ASK_WORD: 6, + CODE: 9 +} + +@Component({ + selector: 'app-unlock-form', + templateUrl: 'unlock.form.html', + styleUrls: ['./unlock.form.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class UnlockForm extends AppForm<string> implements OnInit { + + @Input('class') classList: string = null; + + @Input() expectedCode: string = null; + @Input() minLength: number = 5; + @Input() maxLength: number = 5; + @Input() control: FormControl = null; + @Input() controlName: string = null; + + @Output() change = new EventEmitter<string>(); + + $valid = new Subject<boolean>() + + constructor( + injector: Injector, + public formBuilder: FormBuilder, + protected settings?: SettingsService, + @Optional() protected formGroupDir?: FormGroupDirective + ) { + super(injector); + + this.debug = !environment.production; + } + + ngOnInit() { + if (!this.control) { + const formControlName = (this.formGroupDir.directives || []).find(d => this.controlName && d.name === this.controlName); + this.control = formControlName && formControlName.control; + if (this.formGroupDir && this.control) { + this.setForm(this.formGroupDir.form); + } + } + if (!this.form) { + if (this.control) { + this.setForm(this.control.parent as FormGroup); + } + else { + this.setForm(this.formBuilder.group({ + code: new FormControl(this.createValidator()) + })); + this.control = this.form.get('code') as FormControl; + } + } + this.registerSubscription( + this.control.statusChanges.pipe( + map(state => state === 'VALID'), + distinctUntilChanged() + ).subscribe(valid => this.$valid.next(valid)) + ); + + // For DEV only ------------------------ + if (!environment.production) { + this.control.setValue(this.expectedCode); + } + + } + + get value(): RegisterData { + const json = this.form.value; + return json.code; + } + + get valid(): boolean { + return this.form.valid; + } + + cancel() { + this.onCancel.emit(); + } + + onChange(event: UIEvent, value?: string) { + value = this.control?.value; + value = value && value.toUpperCase() || null; + if (value && value.length > this.maxLength) { + event.preventDefault(); + event.stopPropagation(); + return; + } + this.control.setValue(value || null); + this.change.emit(value); + } + + private createValidator(): ValidatorFn { + const validators = [Validators.required, Validators.minLength(this.minLength), Validators.maxLength(this.maxLength)]; + + // Add equals to expected code + if (isNotNilOrBlank(this.expectedCode)) { + return Validators.compose([...validators, this.equalsValidator(this.expectedCode)]); + } + + return Validators.compose(validators); + } + + private equalsValidator(expectedCode: string): ValidatorFn { + return function(c: AbstractControl): ValidationErrors | null { + if (c.value !== expectedCode) { + return { + equals: true + }; + } + return null; + }; + } +} diff --git a/src/app/unlock/unlock.module.ts b/src/app/unlock/unlock.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..b796195f568c1a161a8fe3e37777372522d55703 --- /dev/null +++ b/src/app/unlock/unlock.module.ts @@ -0,0 +1,25 @@ +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import {FormsModule} from '@angular/forms'; + +import {IonicModule} from '@ionic/angular'; +import {RegisterForm} from "@app/register/register.form"; +import {RegisterModal} from "@app/register/register.modal"; +import {TranslateModule} from "@ngx-translate/core"; +import {AppSharedModule} from "@app/shared/shared.module"; +import {UnlockForm} from "@app/unlock/unlock.form"; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + IonicModule, + TranslateModule, + AppSharedModule + ], + exports: [ + UnlockForm + ], + declarations: [UnlockForm] +}) +export class AppUnlockModule {} diff --git a/src/app/wallet/account.model.ts b/src/app/wallet/account.model.ts index 228e881b8a00ab60a6c0723af624e0c3d32b41d6..b2449dad8712a587340ec2fb5b99d999b8100888 100644 --- a/src/app/wallet/account.model.ts +++ b/src/app/wallet/account.model.ts @@ -1,9 +1,9 @@ import {KeypairType} from "@polkadot/util-crypto/types"; -import {Option, u64} from "@polkadot/types-codec"; -import {H256} from "@polkadot/types/interfaces/runtime"; export interface Account { address: string; + publicKey?: string; + default?: boolean; type?: KeypairType; meta: AccountMeta; @@ -25,3 +25,11 @@ export interface AccountData { reserved?: number; feeFrozen?: number; } + + +export class AccountUtils { + static getBalance(account: Partial<Account>): number { + if (!account?.data) return undefined; // Data not loaded. This should be done by the account service + return (account.data.free || 0) + (account.data.reserved || 0); + } +} diff --git a/src/app/wallet/account.service.ts b/src/app/wallet/account.service.ts index bafcbf449d5d21ac3e6b97683afcd361676ff71b..d21108d195f3471e22cc7e6faba10e59b8edbe38 100644 --- a/src/app/wallet/account.service.ts +++ b/src/app/wallet/account.service.ts @@ -1,23 +1,26 @@ import {Injectable} from "@angular/core"; import {NetworkService} from "../network/network.service"; -import {ApiPromise} from "@polkadot/api"; -import {Account, AccountMeta} from "./account.model"; +import {ApiPromise, Keyring} from "@polkadot/api"; +import {Account, AccountMeta, AccountUtils} from "./account.model"; import {StartableService} from "@app/shared/services/startable-service.class"; import {AuthData} from "@app/auth/auth.model"; import {keyring} from "@polkadot/ui-keyring"; import {environment} from "@environments/environment"; -import {StorageService} from "@app/shared/services/storage.service"; +import {StorageService} from "@app/shared/services/storage/storage.service"; import {KeyringStorage} from "@app/shared/services/keyring-storage"; import {RegisterData} from "@app/register/register.model"; -import { mnemonicGenerate } from '@polkadot/util-crypto'; -import {ScryptOptions} from "crypto"; -import {FrameSystemAccountInfo} from "@polkadot/types/lookup"; +import {cryptoWaitReady, mnemonicGenerate} from '@polkadot/util-crypto'; +import {isNilOrNaN, isNotEmptyArray} from "@app/shared/functions"; +import {Inject} from "@angular/core"; +import {IStorage, APP_STORAGE} from "@app/shared/services/storage/storage.interface"; +import {BehaviorSubject, from, map, Observable, switchMap} from "rxjs"; + const scrypt = require('scrypt-async'); @Injectable({providedIn: 'root'}) export class AccountService extends StartableService { - private _accounts: Account[] = null; + private _$accounts = new BehaviorSubject<Account[]>([]); private _store = new KeyringStorage(this.storage); get api(): ApiPromise { @@ -26,7 +29,7 @@ export class AccountService extends StartableService { constructor( protected network: NetworkService, - protected storage: StorageService + @Inject(APP_STORAGE) protected storage: IStorage ) { super(network, { name: 'wallet-service' @@ -35,15 +38,15 @@ export class AccountService extends StartableService { protected async ngOnStart(): Promise<any> { - // Not need, because network already wait crypto - //await cryptoWaitReady(); + // Wait crypto to be loaded by browser + await cryptoWaitReady(); - const ss58Format = environment.keyring.ss58Format || 42; // 42 = dev format + keyring.setDevMode(!environment.production); // Set the default SS58 format + const ss58Format = this.network.currency?.ss58Format || 42; // 42 = dev format keyring.setSS58Format(ss58Format); - // load all available addresses and accounts const now = Date.now(); console.info('Loading accounts...'); @@ -54,28 +57,34 @@ export class AccountService extends StartableService { isDevelopment: !environment.production }); - await this.addDevAccounts(); - - const accounts = keyring.getAccounts(); - if (accounts?.length) { - console.info(`Loading accounts [OK] ${accounts.length} accounts loaded in ${Date.now() - now}ms`); - this._accounts = accounts.map(a => { - return { - address: a.address, + const keyringAddresses = keyring.getAccounts(); + if (isNotEmptyArray(keyringAddresses)) { + const accounts = keyringAddresses.map(ka => { + return <Account>{ + address: ka.address, type: 'sr25519', meta: { - name: a.meta.name, - genesisHash: a.meta.genesisHash + name: ka.meta.name, + genesisHash: ka.meta.genesisHash } } }); - await Promise.all(this._accounts.map(a => this.loadData(a))); + // Load account's data + await Promise.all(accounts.map(a => this.loadData(a))); - // Dump - this._accounts.forEach(a => { - console.debug(` - ${a.address} (${a.meta?.name}) - free=${a.data.free} - reserved=${a.data.reserved}`); + // Log + console.info(`Loading accounts [OK] ${accounts.length} accounts loaded in ${Date.now() - now}ms`); + accounts.forEach(a => { + console.info(` - ${a.address} (${a.meta?.name}) - free=${a.data.free} - reserved=${a.data.reserved}`); }); + + this._$accounts.next(accounts); + } + + // Auto login + if (!environment.production && environment.dev?.auth) { + setTimeout(() => this.login(environment.dev.auth)); } } @@ -85,11 +94,11 @@ export class AccountService extends StartableService { await this.ready(); if (auth.v1) { - return this.migrationV1({...auth.v1, meta: auth.meta}); + return this.loginV1({...auth.v1}); } // TODO - return this._accounts[0]; + //return this._accounts[0]; } async generateNew() { @@ -109,6 +118,8 @@ export class AccountService extends StartableService { genesisHash: this.network.currency?.genesys }, 'sr25519'); + keyring.saveAccount(pair, data.password); + //this.debug('check pair', pair, json); await this.addAccount({ @@ -121,91 +132,180 @@ export class AccountService extends StartableService { return true; } - async addDevAccounts() { - - if (environment.production) return; - - // (Advanced, development-only) add with an implied dev seed and hard derivation - // Add fake account - keyring.addUri('//Alice', null, { name: 'Alice default' }); - keyring.addUri('//Bob', null, { name: 'Bob default' }); - - } - async addAccount(account: Account): Promise<Account> { - const existingAccount = this._accounts.find(a => a.address === account.address); + let accounts = this._$accounts.value || []; + const existingAccount = accounts.find(a => a.address === account.address); if (existingAccount) { console.warn(`Account with address '${account.address}' already added. Skip`); - return existingAccount; + account = existingAccount; } + else { + console.info(`Add account with address '${account.address}'`); + + // Define as default + if (account.default || accounts.length === 1) await this.setDefaultAccount(account, accounts); - console.info(`Add account with address '${account.address}'`); - this._accounts.push(account); + accounts = [...accounts, account]; + } await this.loadData(account); + this._$accounts.next(accounts) + return account; } + setDefaultAccount(account: Account, accounts?: Account[]) : AccountService { + account.default = true; + // Set other as NOT default + accounts = accounts || this._$accounts.value || []; + accounts.filter(a => a.address !== account.address && a.default) + .forEach(a => { + a.default = false; + }); + return this; + } + + watchAll(opts?: {positiveBalanceFirst?: boolean}): Observable<Account[]> { + + let accounts$: Observable<Account[]>; + if (!this.started) { + accounts$ = from(this.ready()) + .pipe( + switchMap(() => this._$accounts) + ); + } + else { + accounts$ = this._$accounts; + } + + return accounts$.pipe( + map(accounts => { + + // Sort with a balance first + if (opts?.positiveBalanceFirst) { + accounts.sort((a1, a2) => { + const b1 = AccountUtils.getBalance(a1); + const b2 = AccountUtils.getBalance(a2); + return b1 === b2 ? 0 : (b1 < b2 ? 0 : -1); + }) + } + return accounts; + })); + } + async getAll(): Promise<Account[]> { if (!this.started) await this.ready(); - return this._accounts; + return this._$accounts.value || []; } - async getDefault(opts?: { withTx?: boolean }): Promise<Account> { + async isAvailable(address: string): Promise<boolean> { if (!this.started) await this.ready(); + return this._$accounts.value.some(a => a.address === address); - const account = this._accounts[0]; - if (!account) throw {message: 'ERROR.UNKNOWN_WALLET_ID'}; + // FIXME: why is is always return false ?? + // && keyring.isAvailable(address); + } - // Load - return await this.loadData(account); + async getDefault(opts?: { withTx?: boolean; reload?: boolean }): Promise<Account> { + if (!this.started) await this.ready(); + + const accounts = this._$accounts.value || []; + let account = accounts.find(a => a.default); + if (!account) { + if (accounts.length) { + account = accounts[0]; + this.setDefaultAccount(account); + } + else { + throw {message: 'ERROR.UNKNOWN_WALLET_ID'}; + } + } + + // Load data + return await this.loadData(account, opts); } - async getById(name: string, opts?: { withTx?: boolean }): Promise<Account> { + async getByName(name: string, opts?: { withTx?: boolean; reload?: boolean }): Promise<Account> { if (!this.started) await this.ready(); - const account = this._accounts.find(a => a.meta?.name === name); + const accounts = this._$accounts.value || []; + const account = accounts.find(a => a.meta?.name === name); if (!account) throw {message: 'ERROR.UNKNOWN_WALLET_ID'}; // Load - return await this.loadData(account); + return await this.loadData(account, opts); } - async transfer(from?: Account, to?: Account) { + async getByAddress(address: string, opts?: { withTx?: boolean; reload?: boolean }): Promise<Account> { + if (!this.started) await this.ready(); + + const accounts = this._$accounts.value || []; + const account = accounts.find(a => a.address === address); + if (!account) throw {message: 'ERROR.UNKNOWN_WALLET_ID'}; + + // Load data + return await this.loadData(account, opts); + } + async transfer(from: Partial<Account>, to: Partial<Account>, amount: number) : Promise<string> { + if (!from || !to) throw new Error('Missing argument \'from\' or \'to\' !'); + if (isNilOrNaN(amount)) { + throw new Error('ERROR.AMOUNT_REQUIRED'); + } + if (amount < 0) { + throw new Error('ERROR.AMOUNT_NEGATIVE'); + } + // Same issuer/recipient + if (from.address === to.address) { + throw new Error('ERROR.SAME_TX_RECIPIENT'); + } // the address we use to use for signing, as injected - const SENDER = this._accounts[0].address; - - // Sign and send a transfer from Alice to Bob - // const txHash = await this.api.tx.balances - // .transfer(BOB, 12345) - // .signAndSend(alice); - - // Show the hash - //console.info(`Submitted with hash ${txHash}`); - - // finds an injector for an address - //const injector = await web3FromSource(this.accounts[0].meta.source); - //const injector = await web3FromAddress(SENDER); - /* - - // sign and send our transaction - notice here that the address of the account - // (as retrieved injected) is passed through as the param to the `signAndSend`, - // the API then calls the extension to present to the user and get it signed. - // Once complete, the api sends the tx + signature via the normal process - this.api.tx.balances - .transfer('5C5555yEXUcmEJ5kkcCMvdZjUo7NGJiQJMS7vZXEeoMhj3VQ', 12) - .signAndSend(SENDER, { signer: injector.signer }, (status) => { - if (status.isInBlock) { - console.log(`Completed at block hash #${status}`); - } else { - console.log(`Current status: ${status}`); - } - }).catch((error: any) => { - console.log(':( transaction failed', error); - });*/ + //const issuer = from.address ? await this.getByAddress(from.address) : await this.getByAddress(from.meta?.name); + + console.info(`[account-service] Sending ${amount} :\nfrom: ${from.address}\nto ${to.address}`) + + const issuerAccount = await this.getByAddress(from.address); + const issuerPair = keyring.getPair(issuerAccount.address); + const toOwner = await this.isAvailable(to.address); + + const convertedAmount = Math.floor(amount * 100); + + // TODO display unlock modal if need + issuerPair.unlock('test'); + + try { + // Sign and send a transfer from Alice to Bob + const txHash = await this.api.tx.balances + .transfer(to.address, convertedAmount) + .signAndSend(issuerPair, async ({status}) => { + if (status.isInBlock) { + console.info('Completed at block hash #' + status.hash.toHuman()); + + if (toOwner) { + const toAccount = await this.getByAddress(to.address); + await this.loadData(toAccount); + } + + await this.loadData(issuerAccount); + this.notifyChanged(); + + } else { + console.info(`Current status`, status.toHuman()); + } + }); + + // Show the hash + console.info(`Submitted with hash ${txHash}`); + + return txHash.toString(); + + } + catch (err) { + console.error(err); + throw new Error('ERROR.SEND_TX_FAILED'); + } } private async loadData(account: Account, opts?: {reload?: boolean}): Promise<Account> { @@ -220,29 +320,42 @@ export class AccountService extends StartableService { return account; } - async migrationV1(data: {salt: string, password: string; meta?: AccountMeta}): Promise<Account> { + private notifyChanged() { + this._$accounts.next(this._$accounts.value); + } + + async loginV1(data: {salt: string, password: string; meta?: AccountMeta}): Promise<Account> { if (!data?.salt || !data?.password) return; this.log('Authenticating using salt+pwd...'); - const rawSeedString = await this.scrypt(data.password, data.salt, 32, { - N: 4096, - r: 16, - p: 1, - encoding: 'hex' + const rawSeedString = await new Promise((resolve) => { + scrypt(data.password, data.salt, { + N: 4096, + r: 16, + p: 1, + dkLen: 32, + encoding: 'hex' + }, (result) => resolve(result)); }); console.info(rawSeedString); const meta = { - name: data.meta?.name || 'NEW', + name: data.meta?.name, genesisHash: this.network.currency?.genesys } const {pair, json} = await keyring.addUri(`0x${rawSeedString}`, data.password, meta, 'ed25519'); + pair.unlock(data.password); + + keyring.saveAccount(pair, data.password); + keyring.addPair(pair, data.password); + const account = this.addAccount({ address: json.address, + publicKey: pair.publicKey.toString(), type: pair.type, meta }); @@ -250,10 +363,4 @@ export class AccountService extends StartableService { return account; } - protected scrypt(password: string, salt: string, keylen: number, opts: ScryptOptions & {dkLen?: number; encoding?: 'hex'|'base64'|'binary'}): Promise<any> { - return new Promise((resolve, reject) => { - - scrypt(password, salt, opts, (result) => resolve(result)); - }) - } } diff --git a/src/app/wallet/wallet-routing.module.ts b/src/app/wallet/wallet-routing.module.ts index d05d7da8fda09150268f3c00b05e8ea03148b966..c3c832895b9f5dd005c649078d3d7919e44faa17 100644 --- a/src/app/wallet/wallet-routing.module.ts +++ b/src/app/wallet/wallet-routing.module.ts @@ -6,6 +6,11 @@ import { WalletPage } from './wallet.page'; const routes: Routes = [ { path: '', + pathMatch: 'full', + redirectTo: 'default' + }, + { + path: ':address', component: WalletPage } ]; diff --git a/src/app/wallet/wallet.module.ts b/src/app/wallet/wallet.module.ts index d765b24ac3944c48771f86d461f3fd6d55aade26..1c174bdf8204096fe0589434197c95040d3420c9 100644 --- a/src/app/wallet/wallet.module.ts +++ b/src/app/wallet/wallet.module.ts @@ -4,12 +4,14 @@ import {WalletPage} from './wallet.page'; import {WalletPageRoutingModule} from "./wallet-routing.module"; import {AppSharedModule} from "@app/shared/shared.module"; import {TranslateModule} from "@ngx-translate/core"; +import {AppAuthModule} from "@app/auth/auth.module"; @NgModule({ imports: [ AppSharedModule, TranslateModule.forChild(), - WalletPageRoutingModule + WalletPageRoutingModule, + AppAuthModule ], declarations: [WalletPage] }) diff --git a/src/app/wallet/wallet.page.html b/src/app/wallet/wallet.page.html index e5581fe494bb71767356c0b25d55ff0adc30e2dc..3b62d16fa0b0bca6123fffa08cc70cf054226ebf 100644 --- a/src/app/wallet/wallet.page.html +++ b/src/app/wallet/wallet.page.html @@ -3,14 +3,28 @@ <ion-buttons slot="start"> <ion-menu-button></ion-menu-button> </ion-buttons> - <ion-title>{{'ACCOUNT.TITLE'|translate: {name: walletId} }}</ion-title> + <ion-title translate>ACCOUNT.TITLE</ion-title> + + <ng-container *ngIf="$account|async; let accounts"> + <ion-select slot="end" + *ngIf="accounts|isNotEmptyArray" + [(ngModel)]="data" + [interface]="mobile ? 'action-sheet' : 'popover'" + [okText]="'COMMON.BTN_OK'|translate" + [cancelText]="'COMMON.BTN_CANCEL'|translate"> + <ion-select-option *ngFor="let account of accounts" + [value]="account"> + {{account|accountName}} + </ion-select-option> + </ion-select> + </ng-container> </ion-toolbar> </ion-header> <ion-content [fullscreen]="true"> <ion-header> <ion-toolbar class="ion-text-end" color="secondary"> - <ion-title size="large">{{ data?.free | amountFormat }}</ion-title> + <ion-title size="large">{{ balance | amountFormat }}</ion-title> </ion-toolbar> </ion-header> @@ -35,6 +49,12 @@ </ion-button> </ion-item> +<!-- <ion-item detail [routerLink]="['/wot/cert/', data?.address]">--> +<!-- <ion-icon slot="start" name="ribbon"></ion-icon>--> +<!-- <ion-label translate>ACCOUNT.BALANCE_ACCOUNT</ion-label>--> +<!-- <ion-badge color="success">{{(data?.data.free || 0) | amountFormat}} {{currency}}</ion-badge>--> +<!-- </ion-item>--> + <ion-item detail [routerLink]="['/wot/cert/', data?.address]"> <ion-icon slot="start" name="ribbon"></ion-icon> <ion-label translate>ACCOUNT.CERTIFICATION_COUNT</ion-label> @@ -53,5 +73,16 @@ </ion-content> <ng-template #inputSkeleton> - <ion-skeleton-text animated style="width: 60%"></ion-skeleton-text> + <ion-skeleton-text [animated]="true" style="width: 60%"></ion-skeleton-text> </ng-template> + +<ion-modal + #authModal + [backdropDismiss]="false" +> + <ng-template> + <ion-content scrollY="false"> + <app-auth-modal></app-auth-modal> + </ion-content> + </ng-template> +</ion-modal> diff --git a/src/app/wallet/wallet.page.ts b/src/app/wallet/wallet.page.ts index 68a132fa02339fb502d9388a2c4efbdb30195fed..97a1e74e2048cb909aec17b79646208060166d82 100644 --- a/src/app/wallet/wallet.page.ts +++ b/src/app/wallet/wallet.page.ts @@ -1,8 +1,15 @@ -import {ChangeDetectionStrategy, Component, Injector, OnInit} from '@angular/core'; +import {AfterViewChecked, ChangeDetectionStrategy, Component, Injector, OnInit, ViewChild} from '@angular/core'; import {AccountService} from "./account.service"; import {Clipboard} from "@capacitor/clipboard"; import {BasePage} from "@app/shared/pages/base.page"; -import {Account} from "@app/wallet/account.model"; +import {Account, AccountData} from "@app/wallet/account.model"; +import {isEmptyArray, isNilOrBlank} from "@app/shared/functions"; +import {keyring} from "@polkadot/ui-keyring"; +import {NetworkService} from "@app/network/network.service"; +import {BehaviorSubject} from "rxjs"; +import {AuthModal} from "@app/auth/auth.modal"; +import {IonModal} from "@ionic/angular"; +import {Router} from "@angular/router"; @Component({ selector: 'app-wallet', @@ -10,29 +17,84 @@ import {Account} from "@app/wallet/account.model"; styleUrls: ['./wallet.page.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) -export class WalletPage extends BasePage<Account> implements OnInit { +export class WalletPage extends BasePage<Account> implements OnInit, AfterViewChecked { - public walletId: string; + address: string; + currency: string; + + $account = new BehaviorSubject<Account[]>(null); get loaded(): boolean { return !this.loading; } + get balance(): number { + if (!this.data?.data) return undefined; + return (this.data.data.free || 0) + (this.data.data.reserved || 0); + } + + get account(): Account { + return this.data; + } + + @ViewChild('authModal') authModal: IonModal; + constructor( injector: Injector, - public accountService: AccountService + protected router: Router, + protected networkService: NetworkService, + protected accountService: AccountService ) { super(injector, {name: 'wallet-page'}) - this.walletId = this.activatedRoute.snapshot.paramMap.get('id'); + this.address = this.activatedRoute.snapshot.paramMap.get('address'); } ngOnInit() { super.ngOnInit(); } - protected ngOnLoad(): Promise<Account> { - return this.accountService.getById(this.walletId); + ngAfterViewChecked() { + + // force page reload, when auth was previously cancelled + if (!this.loading && !this.data) { + setTimeout(() => this.load()); + } + } + + protected async ngOnLoad(): Promise<Account> { + + this.currency = this.networkService.currencySign; + + const accounts = await this.accountService.getAll(); + this.$account.next(accounts); + + if (isEmptyArray(accounts)) { + const account = await this.openAuthModal(); + // Redirect to home + if (!account) { + await this.router.navigateByUrl('/home'); + throw new Error('ERROR.AUTH_REQUIRED'); + } + + this.$account.next([account]); + return account; + } + + if (this.address === 'default') { + const account = await this.accountService.getDefault(); + this.address = account.address; + return account; + } + + // Load by address + const isAddressAvailable = await this.accountService.isAvailable(this.address); + if (isAddressAvailable) { + return this.accountService.getByAddress(this.address); + } + + // Try by name + return this.accountService.getByName(this.address); } async copyAddress() { @@ -42,4 +104,12 @@ export class WalletPage extends BasePage<Account> implements OnInit { await this.showToast({message: 'INFO.COPY_TO_CLIPBOARD_DONE'}); } + async openAuthModal(): Promise<Account|null> { + if (!this.authModal.isOpen) { + await this.authModal.present(); + } + const {data, role} = await this.authModal.onDidDismiss(); + if (!data?.address) return null; + return data; + } } diff --git a/src/assets/i18n/ca.json b/src/assets/i18n/ca.json index d71dff0d3cd86938ca59274cc8ffa9491f9c1f7e..6c2bcbb27776cab7d111146394f84c142a56c0e4 100644 --- a/src/assets/i18n/ca.json +++ b/src/assets/i18n/ca.json @@ -243,7 +243,7 @@ "TAB_WOT": "Red de confianza", "TAB_NETWORK": "Red", "TAB_BLOCKS": "Bloques", - "CURRENCY_SHORT_DESCRIPTION": "{{currency|abbreviate}} es una <b>moneda libre</b>, originada {{firstBlockTime|formatFromNow}}. Cuenta actualmente con <b>{{N}} miembros</b>, que producen y reciben un <a ng-click=\"showHelpModal('ud')\">Dividendo Universal</a> (DU) cada {{dt|formatPeriod}}.", + "CURRENCY_SHORT_DESCRIPTION": "{{currency}} es una <b>moneda libre</b>, originada {{firstBlockTime|formatFromNow}}. Cuenta actualmente con <b>{{N}} miembros</b>, que producen y reciben un <a ng-click=\"showHelpModal('ud')\">Dividendo Universal</a> (DU) cada {{dt|formatPeriod}}.", "NETWORK_RULES_DIVIDER": "Reglas de la red", "CURRENCY_NAME": "Nombre de la moneda", "MEMBERS": "Cantidad de miembros", @@ -953,9 +953,9 @@ "MENU_BTN_CURRENCY": "El menú <b>{{'MENU.CURRENCY'|translate}}</b> permite consultar las <b>reglas de la moneda</b> y su estado.", "CURRENCY_WOT": "El <b>número de miembros</b> muestra el peso de la comunidad y permite <b>seguir su evolución</b>.", "CURRENCY_MASS": "Siga aquí la <b>cantidad total de moneda</b> existente y su <b>distribución media</b> por miembro.<br/><br/>Esto permite juzgar la <b>relevancia de un importe</b>, en relación con lo que <b>poseen los demás</b> en sus cuentas (de media).", - "CURRENCY_UNIT_RELATIVE": "La unidad utilizada (“<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”) significa que los importes en {{currency|capitalize}} han sido divididos entre el valor del <b>Dividendo Universal</b> (DU).<br/><br/><small> Esta unidad relativa es <b>pertinente</b>, porque permanece estable, independiente de la cantidad de moneda que aumenta constantemente.</small>", - "CURRENCY_CHANGE_UNIT": "Este botón permite <b>cambiar la unidad</b>, para visualizar los importes <b>directamente en {{currency|capitalize}}</b> (en lugar de “<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”).", - "CURRENCY_CHANGE_UNIT_TO_RELATIVE": "Este botón permite <b>cambiar la unidad</b>, para visualizar los importes en “<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”, es decir, relativo al Dividendo Universal (el monto co-producido por cada miembro).", + "CURRENCY_UNIT_RELATIVE": "La unidad utilizada (“<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”) significa que los importes en {{currency|capitalize}} han sido divididos entre el valor del <b>Dividendo Universal</b> (DU).<br/><br/><small> Esta unidad relativa es <b>pertinente</b>, porque permanece estable, independiente de la cantidad de moneda que aumenta constantemente.</small>", + "CURRENCY_CHANGE_UNIT": "Este botón permite <b>cambiar la unidad</b>, para visualizar los importes <b>directamente en {{currency|capitalize}}</b> (en lugar de “<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”).", + "CURRENCY_CHANGE_UNIT_TO_RELATIVE": "Este botón permite <b>cambiar la unidad</b>, para visualizar los importes en “<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”, es decir, relativo al Dividendo Universal (el monto co-producido por cada miembro).", "CURRENCY_RULES": "Las <b>reglas</b> de la moneda fijan su funcionamiento <b>exacto y previsible</b>.<br/><br/>Es el propio ADN de la moneda, que hace que su código monetario sea <b>legible y transparente</b>.", "MENU_BTN_NETWORK": "El menú <b>{{'MENU.NETWORK'|translate}}</b> permite consultar el estado de la red.", "NETWORK_BLOCKCHAIN": "Todas las transacciones de la moneda están registradas dentro de un gran libro de contabilidad <b>público e infalsificable</b>, conocido como la <b>cadena de bloques</b> (<em>BlockChain</em> en inglés).", @@ -969,7 +969,7 @@ "WALLET_GIVEN_CERTIFICATIONS": "Haga clic aquí para consultar el detalle de sus <b>certificaciones emitidas</b>.", "WALLET_BALANCE": "El <b>saldo</b> de su cuenta se visualiza aquí.", "WALLET_BALANCE_RELATIVE": - "{{'HELP.TIP.WALLET_BALANCE'|translate}}<br/><br/>La unidad utilizada (“<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”) significa que el importe en {{currency|capitalize}} fue dividido entre el <b>Dividendo Universal</b> (DU) co-producido por cada miembro.<br/><br/>Actualmente un DU vale {{currentUD|formatInteger}} {{currency|capitalize}}s.", + "{{'HELP.TIP.WALLET_BALANCE'|translate}}<br/><br/>La unidad utilizada (“<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”) significa que el importe en {{currency|capitalize}} fue dividido entre el <b>Dividendo Universal</b> (DU) co-producido por cada miembro.<br/><br/>Actualmente un DU vale {{currentUD|formatInteger}} {{currency|capitalize}}s.", "WALLET_BALANCE_CHANGE_UNIT": "Podrá <b>cambiar la unidad</b> de visualización de los importes en los <b><i class=\"icon ion-android-settings\"></i> {{'MENU.SETTINGS'|translate}}</b>.<br/><br/>Por ejemplo, para visualizar los importes <b>directamente en {{currency|capitalize}}</b>, en lugar de unidad relativa.", "WALLET_PUBKEY": "Esta es la llave pública de su cuenta. Puede comunicarla a un tercero para que pueda identificar su cuenta de forma simple.", "WALLET_SEND": "Realizar un pago en algunos clics", @@ -991,7 +991,7 @@ "CERTIFY_RULES": "<b>Atención:</b> Certifique solamente <b>seres humanos físicos vivos</b>, que no posean ya ninguna otra cuenta miembro.<br/><br/>¡La seguridad de la red de la moneda depende del cuidado de cada individuo/a!", "MENU_BTN_SETTINGS": "En <b>{{'MENU.SETTINGS'|translate}}</b> podrá configurar la aplicación.", "HEADER_BAR_BTN_PROFILE": "Haga clic aquí para acceder a su <b>perfil</b>", - "SETTINGS_CHANGE_UNIT": "Podrá <b>cambiar la unidad de visualización</b> de los importes haciendo clic aquí.<br/><br/>- Desactive la opción para mostrar los importes en {{currency|capitalize}}.<br/>- Actívela para importes relativos al {{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub> (las cantidades de los importes se mostrarán <b>divididos</b> entre el Dividendo Universal actual).", + "SETTINGS_CHANGE_UNIT": "Podrá <b>cambiar la unidad de visualización</b> de los importes haciendo clic aquí.<br/><br/>- Desactive la opción para mostrar los importes en {{currency|capitalize}}.<br/>- Actívela para importes relativos al {{'COMMON.UD'|translate}}<sub>{{currency}}</sub> (las cantidades de los importes se mostrarán <b>divididos</b> entre el Dividendo Universal actual).", "END_LOGIN": "¡La visita guiada ha <b>terminado</b>!<br/><br/>¡Buena suerte en este nuevo mundo de la <b>economía libre</b> !", "END_NOT_LOGIN": "¡La visita guiada ha <b>terminado</b>!<br/><br/>Si quiere utilizar la moneda {{currency|capitalize}}, tiene que hacer un clic en <b>{{'LOGIN.CREATE_ACCOUNT'|translate}}</b> más abajo." } diff --git a/src/assets/i18n/en-GB.json b/src/assets/i18n/en-GB.json index 0b8b75bca656770e231035ddc6a15245a3fa198f..2a8de883eb6ec7a5af82b8afeb9eeef5148a641d 100644 --- a/src/assets/i18n/en-GB.json +++ b/src/assets/i18n/en-GB.json @@ -121,7 +121,7 @@ "WELCOME_READONLY": "Welcome to Cesium <span class='badge badge-balanced'>Monit</span> !", "MESSAGE": "Receive and send libre currency {{currency}}", "MESSAGE_READONLY": "Real-time monitoring of libre currency {{currency}}", - "BTN_CURRENCY": "Explore currency {{currency|abbreviate}}", + "BTN_CURRENCY": "Explore currency {{currency}}", "BTN_ABOUT": "about", "BTN_HELP": "Help", "BTN_NETWORK": "Network status", @@ -886,9 +886,9 @@ "MENU_BTN_CURRENCY": "Menu <b>{{'MENU.CURRENCY'|translate}}</b> allows discovery of <b>currency parameters</b> and its state.", "CURRENCY_WOT": "The <b>member count</b> shows the <b>community's weight and evolution</b>.", "CURRENCY_MASS": "Shown here is the <b>total amount</b> currently in circulation and its <b>average distribution</b> per member.<br/><br/>This allows to estimate the <b>worth of any amount</b>, in respect to what <b>others own</b> on their account (on average).", - "CURRENCY_UNIT_RELATIVE": "The unit used here (“<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”) signifies that the amounts in {{currency|capitalize}} have been devided by the <b>Universal Dividend</b> (UD).<br/><br/><small>This relative unit is <b>relevant</b> because it is stable in contrast to the permanently growing monitary mass.</small>", - "CURRENCY_CHANGE_UNIT": "The option <b>{{'COMMON.BTN_RELATIVE_UNIT'|translate}}</b> allows to <b>switch the unit</b> to show amounts in <b>{{currency|capitalize}}</b>, undevided by the Universal Dividend (instead of in “<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”).", - "CURRENCY_CHANGE_UNIT_TO_RELATIVE": "The option <b>{{'COMMON.BTN_RELATIVE_UNIT'|translate}}</b> allows to <b>switch the unit</b> to show amounts in “<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”, which is relative to the Universal Dividend (the amount co-produced by each member).", + "CURRENCY_UNIT_RELATIVE": "The unit used here (“<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”) signifies that the amounts in {{currency|capitalize}} have been devided by the <b>Universal Dividend</b> (UD).<br/><br/><small>This relative unit is <b>relevant</b> because it is stable in contrast to the permanently growing monitary mass.</small>", + "CURRENCY_CHANGE_UNIT": "The option <b>{{'COMMON.BTN_RELATIVE_UNIT'|translate}}</b> allows to <b>switch the unit</b> to show amounts in <b>{{currency|capitalize}}</b>, undevided by the Universal Dividend (instead of in “<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”).", + "CURRENCY_CHANGE_UNIT_TO_RELATIVE": "The option <b>{{'COMMON.BTN_RELATIVE_UNIT'|translate}}</b> allows to <b>switch the unit</b> to show amounts in “<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”, which is relative to the Universal Dividend (the amount co-produced by each member).", "CURRENCY_RULES": "The <b>rules</b> of the currency determine its <b>exact and predictible</b> performance.<br/><br/>As a true DNA of the currency these rules make the monetary code <b>transparent and understandable</b>.", "MENU_BTN_NETWORK": "Menu <b>{{'MENU.NETWORK'|translate}}</b> allows discovery of <b>network's state<b>.", "NETWORK_BLOCKCHAIN": "All monetary transactions are recoded in a <b>public and tamper proof</b> ledger, generally referred to as the <b>blockchain</b>.", @@ -901,7 +901,7 @@ "WALLET_RECEIVED_CERTIFICATIONS": "Click here to review the details of your <b>received certifications</b>.", "WALLET_GIVEN_CERTIFICATIONS": "Click here to review the details of your <b>given certifications</b>.", "WALLET_BALANCE": "Your account <b>balance</b> is shown here.", - "WALLET_BALANCE_RELATIVE": "{{'HELP.TIP.WALLET_BALANCE'|translate}}<br/><br/>The used unit (“<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”) signifies that the amount in {{currency|capitalize}} has been divided by the <b>Universal Dividend</b> (UD) co-created by each member.<br/>At this moment, 1 UD equals {{currentUD}} {{currency|capitalize}}.", + "WALLET_BALANCE_RELATIVE": "{{'HELP.TIP.WALLET_BALANCE'|translate}}<br/><br/>The used unit (“<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”) signifies that the amount in {{currency|capitalize}} has been divided by the <b>Universal Dividend</b> (UD) co-created by each member.<br/>At this moment, 1 UD equals {{currentUD}} {{currency|capitalize}}.", "WALLET_BALANCE_CHANGE_UNIT": "You can <b>change the unit</b> in which amounts are shown in <b><i class=\"icon ion-android-settings\"></i> {{'MENU.SETTINGS'|translate}}</b>.<br/><br/>For example, to display amounts <b>directly in {{currency|capitalize}}</b> instead of relative amounts.", "WALLET_PUBKEY": "This is your account public key. You can communicate it to a third party so that it more easily identifies your account.", "WALLET_SEND": "Issue a payment in just a few clicks.", @@ -923,7 +923,7 @@ "CERTIFY_RULES": "<b>Attention:</b> Only certify <b>real and living persons</b> that do not own any other certified account.<br/><br/>The trust carried by the currency depends on each member's vigilance!", "MENU_BTN_SETTINGS": "The <b>{{'MENU.SETTINGS'|translate}}</b> allow you to configure the Cesium application.<br/><br/>For example, you can <b>change the unit</b> in which the currency will be shown.", "HEADER_BAR_BTN_PROFILE": "Click here to access your <b>user profile</b>", - "SETTINGS_CHANGE_UNIT": "You can <b>change the display unit</b> of amounts by clicking here.<br/><br/>- Deactivate the option to show amounts in {{currency|capitalize}}.<br/>- Activate the option for relative amounts in {{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub> (<b>divided</b> by the current Universal Dividend).", + "SETTINGS_CHANGE_UNIT": "You can <b>change the display unit</b> of amounts by clicking here.<br/><br/>- Deactivate the option to show amounts in {{currency|capitalize}}.<br/>- Activate the option for relative amounts in {{'COMMON.UD'|translate}}<sub>{{currency}}</sub> (<b>divided</b> by the current Universal Dividend).", "END_LOGIN": "This guided visit has <b>ended</b>.<br/><br/>Welcome to the <b>free economy</b>!", "END_NOT_LOGIN": "This guided visit has <b>ended</b>.<br/><br/>If you wish to join the currency {{currency|capitalize}}, simply click <b>{{'LOGIN.CREATE_FREE_ACCOUNT'|translate}}</b> below.", "END_READONLY": "This guided visit has <b>ended</b>.<br/><br/>{{'MODE.READONLY.INSTALL_HELP'|translate}}." @@ -1004,7 +1004,7 @@ "PARAM_PREFERRED_NODE_HELP": "Peer address (URL) to use preferably (\"g1.domain.com:443\" or \"https://g1.domain.com\")", "EXAMPLES_HELP": "Examples of integration:", "EXAMPLE_BUTTON": "HTML Button", - "EXAMPLE_BUTTON_DEFAULT_TEXT": "Pay in {{currency|abbreviate}}", + "EXAMPLE_BUTTON_DEFAULT_TEXT": "Pay in {{currency}}", "EXAMPLE_BUTTON_DEFAULT_STYLE": "Custom style", "EXAMPLE_BUTTON_TEXT_HELP": "Button text", "EXAMPLE_BUTTON_BG_COLOR": "Background color", diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 8e328acf2bd937d49e138a4bf18e1a28ac240c4e..a7bdf553bf0ecb2006a035a40291c2168894b94a 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -119,9 +119,9 @@ "TITLE": "Cesium", "WELCOME": "Welcome to the Cesium application!", "WELCOME_READONLY": "Welcome to Cesium <span class='badge badge-balanced'>Monit</span> !", - "MESSAGE": "Receive and send libre currency {{currency|abbreviate}}", - "MESSAGE_READONLY": "Real-time monitoring of libre currency {{currency|abbreviate}}", - "BTN_CURRENCY": "Explore currency {{currency|abbreviate}}", + "MESSAGE": "Receive and send libre currency {{currency}}", + "MESSAGE_READONLY": "Real-time monitoring of libre currency {{currency}}", + "BTN_CURRENCY": "Explore currency {{currency}}", "BTN_ABOUT": "about", "BTN_HELP": "Help", "BTN_NETWORK": "Network status", @@ -886,9 +886,9 @@ "MENU_BTN_CURRENCY": "Menu <b>{{'MENU.CURRENCY'|translate}}</b> allows discovery of <b>currency parameters</b> and its state.", "CURRENCY_WOT": "The <b>member count</b> shows the <b>community's weight and evolution</b>.", "CURRENCY_MASS": "Shown here is the <b>total amount</b> currently in circulation and its <b>average distribution</b> per member.<br/><br/>This allows to estimate the <b>worth of any amount</b>, in respect to what <b>others own</b> on their account (on average).", - "CURRENCY_UNIT_RELATIVE": "The unit used here (“<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”) signifies that the amounts in {{currency|capitalize}} have been devided by the <b>Universal Dividend</b> (UD).<br/><br/><small>This relative unit is <b>relevant</b> because it is stable in contrast to the permanently growing monitary mass.</small>", - "CURRENCY_CHANGE_UNIT": "The option <b>{{'COMMON.BTN_RELATIVE_UNIT'|translate}}</b> allows to <b>switch the unit</b> to show amounts in <b>{{currency|capitalize}}</b>, undevided by the Universal Dividend (instead of in “<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”).", - "CURRENCY_CHANGE_UNIT_TO_RELATIVE": "The option <b>{{'COMMON.BTN_RELATIVE_UNIT'|translate}}</b> allows to <b>switch the unit</b> to show amounts in “<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”, which is relative to the Universal Dividend (the amount co-produced by each member).", + "CURRENCY_UNIT_RELATIVE": "The unit used here (“<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”) signifies that the amounts in {{currency|capitalize}} have been devided by the <b>Universal Dividend</b> (UD).<br/><br/><small>This relative unit is <b>relevant</b> because it is stable in contrast to the permanently growing monitary mass.</small>", + "CURRENCY_CHANGE_UNIT": "The option <b>{{'COMMON.BTN_RELATIVE_UNIT'|translate}}</b> allows to <b>switch the unit</b> to show amounts in <b>{{currency|capitalize}}</b>, undevided by the Universal Dividend (instead of in “<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”).", + "CURRENCY_CHANGE_UNIT_TO_RELATIVE": "The option <b>{{'COMMON.BTN_RELATIVE_UNIT'|translate}}</b> allows to <b>switch the unit</b> to show amounts in “<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”, which is relative to the Universal Dividend (the amount co-produced by each member).", "CURRENCY_RULES": "The <b>rules</b> of the currency determine its <b>exact and predictible</b> performance.<br/><br/>As a true DNA of the currency these rules make the monetary code <b>transparent and understandable</b>.", "MENU_BTN_NETWORK": "Menu <b>{{'MENU.NETWORK'|translate}}</b> allows discovery of <b>network's state<b>.", "NETWORK_BLOCKCHAIN": "All monetary transactions are recoded in a <b>public and tamper proof</b> ledger, generally referred to as the <b>blockchain</b>.", @@ -901,7 +901,7 @@ "WALLET_RECEIVED_CERTIFICATIONS": "Click here to review the details of your <b>received certifications</b>.", "WALLET_GIVEN_CERTIFICATIONS": "Click here to review the details of your <b>given certifications</b>.", "WALLET_BALANCE": "Your account <b>balance</b> is shown here.", - "WALLET_BALANCE_RELATIVE": "{{'HELP.TIP.WALLET_BALANCE'|translate}}<br/><br/>The used unit (“<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”) signifies that the amount in {{currency|capitalize}} has been divided by the <b>Universal Dividend</b> (UD) co-created by each member.<br/>At this moment, 1 UD equals {{currentUD}} {{currency|capitalize}}.", + "WALLET_BALANCE_RELATIVE": "{{'HELP.TIP.WALLET_BALANCE'|translate}}<br/><br/>The used unit (“<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”) signifies that the amount in {{currency|capitalize}} has been divided by the <b>Universal Dividend</b> (UD) co-created by each member.<br/>At this moment, 1 UD equals {{currentUD}} {{currency|capitalize}}.", "WALLET_BALANCE_CHANGE_UNIT": "You can <b>change the unit</b> in which amounts are shown in <b><i class=\"icon ion-android-settings\"></i> {{'MENU.SETTINGS'|translate}}</b>.<br/><br/>For example, to display amounts <b>directly in {{currency|capitalize}}</b> instead of relative amounts.", "WALLET_PUBKEY": "This is your account public key. You can communicate it to a third party so that it more easily identifies your account.", "WALLET_SEND": "Issue a payment in just a few clicks.", @@ -923,7 +923,7 @@ "CERTIFY_RULES": "<b>Attention:</b> Only certify <b>real and living persons</b> that do not own any other certified account.<br/><br/>The trust carried by the currency depends on each member's vigilance!", "MENU_BTN_SETTINGS": "The <b>{{'MENU.SETTINGS'|translate}}</b> allow you to configure the Cesium application.<br/><br/>For example, you can <b>change the unit</b> in which the currency will be shown.", "HEADER_BAR_BTN_PROFILE": "Click here to access your <b>user profile</b>", - "SETTINGS_CHANGE_UNIT": "You can <b>change the display unit</b> of amounts by clicking here.<br/><br/>- Deactivate the option to show amounts in {{currency|capitalize}}.<br/>- Activate the option for relative amounts in {{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub> (<b>divided</b> by the current Universal Dividend).", + "SETTINGS_CHANGE_UNIT": "You can <b>change the display unit</b> of amounts by clicking here.<br/><br/>- Deactivate the option to show amounts in {{currency|capitalize}}.<br/>- Activate the option for relative amounts in {{'COMMON.UD'|translate}}<sub>{{currency}}</sub> (<b>divided</b> by the current Universal Dividend).", "END_LOGIN": "This guided visit has <b>ended</b>.<br/><br/>Welcome to the <b>free economy</b>!", "END_NOT_LOGIN": "This guided visit has <b>ended</b>.<br/><br/>If you wish to join the currency {{currency|capitalize}}, simply click <b>{{'LOGIN.CREATE_FREE_ACCOUNT'|translate}}</b> below.", "END_READONLY": "This guided visit has <b>ended</b>.<br/><br/>{{'MODE.READONLY.INSTALL_HELP'|translate}}." @@ -1004,7 +1004,7 @@ "PARAM_PREFERRED_NODE_HELP": "Peer address (URL) to use preferably (\"g1.domain.com:443\" or \"https://g1.domain.com\")", "EXAMPLES_HELP": "Examples of integration:", "EXAMPLE_BUTTON": "HTML Button", - "EXAMPLE_BUTTON_DEFAULT_TEXT": "Pay in {{currency|abbreviate}}", + "EXAMPLE_BUTTON_DEFAULT_TEXT": "Pay in {{currency}}", "EXAMPLE_BUTTON_DEFAULT_STYLE": "Custom style", "EXAMPLE_BUTTON_TEXT_HELP": "Button text", "EXAMPLE_BUTTON_BG_COLOR": "Background color", diff --git a/src/assets/i18n/eo-EO.json b/src/assets/i18n/eo-EO.json index f819ccd635cf9409e411ba4058e90d39148bd1c9..f8bfd8cd33f7f5e1c428873785875cd459de53a8 100644 --- a/src/assets/i18n/eo-EO.json +++ b/src/assets/i18n/eo-EO.json @@ -119,9 +119,9 @@ "TITLE": "Cesium", "WELCOME": "Bonvenon ĉe la programo Cesium!", "WELCOME_READONLY": "Bonvenon ĉe Cesium <span class='badge badge-balanced'>Observo</span>!", - "MESSAGE": "Ricevu kaj sendu liberan monon {{currency|abbreviate}}", - "MESSAGE_READONLY": "Sekvu la staton de la libera mono {{currency|abbreviate}} en tuja tempo.", - "BTN_CURRENCY": "Esploru la monon {{currency|abbreviate}}", + "MESSAGE": "Ricevu kaj sendu liberan monon {{currency}}", + "MESSAGE_READONLY": "Sekvu la staton de la libera mono {{currency}} en tuja tempo.", + "BTN_CURRENCY": "Esploru la monon {{currency}}", "BTN_ABOUT": "prie", "BTN_HELP": "Reta helpo", "BTN_NETWORK": "Stato de la reto", @@ -249,7 +249,7 @@ "TAB_WOT": "Reto de fido", "TAB_NETWORK": "Reto", "TAB_BLOCKS": "Blokoj", - "CURRENCY_SHORT_DESCRIPTION": "{{currency|abbreviate}} estas <b>libera mono</b>, kiu ekis {{firstBlockTime|formatFromNow}}. Ĝi nombras nun <b>{{N}} membrojn</b>, kiuj produktas kaj ricevas <a ng-click=\"showHelpModal('ud')\">Universalan Dividendon</a> (UD), ĉiun {{dt|formatPeriod}}n.", + "CURRENCY_SHORT_DESCRIPTION": "{{currency}} estas <b>libera mono</b>, kiu ekis {{firstBlockTime|formatFromNow}}. Ĝi nombras nun <b>{{N}} membrojn</b>, kiuj produktas kaj ricevas <a ng-click=\"showHelpModal('ud')\">Universalan Dividendon</a> (UD), ĉiun {{dt|formatPeriod}}n.", "NETWORK_RULES_DIVIDER": "Reguloj de la reto", "CURRENCY_NAME": "Nomo de la mono", "MEMBERS": "Nombro de membroj", @@ -885,9 +885,9 @@ "MENU_BTN_CURRENCY": "La menuo <b>{{'MENU.CURRENCY'|translate}}</b> ebligas konsulti la <b>regulojn de la mono</b> kaj ties staton.", "CURRENCY_WOT": "La <b>nombro de membroj</b> montras la gravecon de la komunumo kaj ebligas <b>sekvi ties evoluon</b>.", "CURRENCY_MASS": "Sekvu ĉi tie la <b>ĉioman kvanton da mono</b> ekzistanta kaj ties <b>mezan distribuon</b> por membro.<br/><br/>Tio ĉi ebligas taksi la <b>gravecon de iu sumo</b>, kompare kun tio, kion <b>posedas la aliuloj</b> en sia konto (mezume).", - "CURRENCY_UNIT_RELATIVE": "La unuo uzata (“<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”) signifas, ke la sumoj en {{currency|capitalize}} estis dividitaj per la <b> Universala Dividendo</b> (UD).<br/><br/><small>Tiu relativa unuo estas <b>trafa</b>, ĉar stabila malgraŭ la kvanto de mono, kiu kreskas seninterrompe.</small>", - "CURRENCY_CHANGE_UNIT": "La kromaĵo <b>{{'COMMON.BTN_RELATIVE_UNIT'|translate}}</b> ebligas <b>ŝanĝi la unuon</b>, por vidigi la sumojn <b>rekte en {{currency|capitalize}}</b> (prefere ol en “<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”).", - "CURRENCY_CHANGE_UNIT_TO_RELATIVE": "La kromaĵo <b>{{'COMMON.BTN_RELATIVE_UNIT'|translate}}</b> ebligas <b>ŝanĝi la unuon</b>, por vidigi la sumojn en “<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”, tio estas rilate al la Universala Dividendo (la sumo kunproduktita de ĉiu membro).", + "CURRENCY_UNIT_RELATIVE": "La unuo uzata (“<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”) signifas, ke la sumoj en {{currency|capitalize}} estis dividitaj per la <b> Universala Dividendo</b> (UD).<br/><br/><small>Tiu relativa unuo estas <b>trafa</b>, ĉar stabila malgraŭ la kvanto de mono, kiu kreskas seninterrompe.</small>", + "CURRENCY_CHANGE_UNIT": "La kromaĵo <b>{{'COMMON.BTN_RELATIVE_UNIT'|translate}}</b> ebligas <b>ŝanĝi la unuon</b>, por vidigi la sumojn <b>rekte en {{currency|capitalize}}</b> (prefere ol en “<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”).", + "CURRENCY_CHANGE_UNIT_TO_RELATIVE": "La kromaĵo <b>{{'COMMON.BTN_RELATIVE_UNIT'|translate}}</b> ebligas <b>ŝanĝi la unuon</b>, por vidigi la sumojn en “<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”, tio estas rilate al la Universala Dividendo (la sumo kunproduktita de ĉiu membro).", "CURRENCY_RULES": "La <b>reguloj</b> de la mono fiksas ties funkciadon <b>ĝustan kaj antaŭvideblan</b>.<br/><br/>Vera DNA de la mono, ili igas sian monan kodon <b>legebla kaj travidebla</b>.", "MENU_BTN_NETWORK": "La menuo <b>{{'MENU.NETWORK'|translate}}</b> ebligas konsulti la staton de la reto.", "NETWORK_BLOCKCHAIN": "Ĉiuj operacioj pri la mono estas registritaj en granda konto-libro <b>publika kaj nefalsigebla</b>, ankaŭ nomata <b>blokĉeno</b> (<em>BlockChain</em> en la angla).", @@ -900,7 +900,7 @@ "WALLET_RECEIVED_CERTIFICATIONS": "Alklaku ĉi tien por konsulti la detalon pri viaj <b>ricevitaj atestaĵoj</b>.", "WALLET_GIVEN_CERTIFICATIONS": "Alklaku ĉi tien por konsulti la detalon pri viaj <b>senditaj atestaĵoj</b>.", "WALLET_BALANCE": "La <b>saldo</b> de via konto afiŝiĝas tie ĉi.", - "WALLET_BALANCE_RELATIVE": "{{'HELP.TIP.WALLET_BALANCE'|translate}}<br/><br/>La uzata unuo (“<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”) signifas, ke la sumo en {{currency|capitalize}} estis dividita per la <b>Universala Dividendo</b> (UD) kunkreita de ĉiu membro.<br/><br/>Nuntempe 1 UD valoras {{currentUD|formatInteger}} {{currency|capitalize}}j.", + "WALLET_BALANCE_RELATIVE": "{{'HELP.TIP.WALLET_BALANCE'|translate}}<br/><br/>La uzata unuo (“<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”) signifas, ke la sumo en {{currency|capitalize}} estis dividita per la <b>Universala Dividendo</b> (UD) kunkreita de ĉiu membro.<br/><br/>Nuntempe 1 UD valoras {{currentUD|formatInteger}} {{currency|capitalize}}j.", "WALLET_BALANCE_CHANGE_UNIT": "Vi povos <b>ŝanĝi la unuon</b> afiŝitan por la sumoj en la <b><i class=\"icon ion-android-settings\"></i> {{'MENU.SETTINGS'|translate}}</b>.<br/><br/>Ekzemple por vidigi la sumojn <b>rekte en {{currency|capitalize}}</b>, prefere ol en relativa unuo.", "WALLET_PUBKEY": "Jen la publika ŝlosilo de via konto. Vi povas sciigi ĝin al aliulo, por ke li identigu pli simple vian konton.", "WALLET_SEND": "Efektivigi pagon per kelkaj klakoj.", @@ -922,7 +922,7 @@ "CERTIFY_RULES": "<b>Atenton:</b> Atestu nur <b>personojn fizikajn vivantajn</b>, posedantajn neniun alian membro-konton.<br/><br/>La sekureco de la mono dependas de ĉies atentego!", "MENU_BTN_SETTINGS": "La <b>{{'MENU.SETTINGS'|translate}}</b> ebligos al vi agordi la programon.", "HEADER_BAR_BTN_PROFILE": "Alklaku ĉi tien por aliri vian <b>uzanto-profilon.</b>", - "SETTINGS_CHANGE_UNIT": "Vi povos <b>ŝanĝi la afiŝ-unuon</b> de la sumoj alklakante ĉi-supren.<br/><br/>- Malaktivigu la kromaĵon por afiŝi sumojn en {{currency|capitalize}}.<br/>- Aktivigu la kromaĵon por relativa afiŝado en {{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub> (ĉiuj sumoj estos <b>dividitaj</b> per la Universala Dividendo aktuala).", + "SETTINGS_CHANGE_UNIT": "Vi povos <b>ŝanĝi la afiŝ-unuon</b> de la sumoj alklakante ĉi-supren.<br/><br/>- Malaktivigu la kromaĵon por afiŝi sumojn en {{currency|capitalize}}.<br/>- Aktivigu la kromaĵon por relativa afiŝado en {{'COMMON.UD'|translate}}<sub>{{currency}}</sub> (ĉiuj sumoj estos <b>dividitaj</b> per la Universala Dividendo aktuala).", "END_LOGIN": "Tiu ĉi gvidata vizito <b>finiĝis</b>!<br/><br/>Bonan daŭrigon al vi, en la nova mondo de la<b>libera ekonomio</b>!", "END_NOT_LOGIN": "Tiu ĉi gvidata vizito <b>finiĝis</b>!<br/><br/>Se vi deziras partopreni en la mono {{currency|capitalize}}, sufiĉos al vi alklaki <b>{{'LOGIN.CREATE_FREE_ACCOUNT'|translate}}</b> ĉi-sube.", "END_READONLY": "Tiu ĉi gvidata vizito <b>finiĝis</b>.<br/><br/>{{'MODE.READONLY.INSTALL_HELP'|translate}}." diff --git a/src/assets/i18n/es-ES.json b/src/assets/i18n/es-ES.json index 3fbcf2e130b27460da69179934693d054cfdf36c..bc945b1d4019d5ea9f95d0bbd987889f77398ffd 100644 --- a/src/assets/i18n/es-ES.json +++ b/src/assets/i18n/es-ES.json @@ -121,7 +121,7 @@ "SHOW_ALL_FEED": "Ver todo", "TITLE": "Cesium", "WELCOME": "¡Bienvenida/o a la aplicación Cesium!", - "MESSAGE": "Reciba y envíe moneda libre {{currency|abbreviate}} fácilmente", + "MESSAGE": "Reciba y envíe moneda libre {{currency}} fácilmente", "BTN_CURRENCY": "Explorar la moneda", "BTN_ABOUT": "Acerca de", "BTN_HELP": "Ayuda en línea", @@ -243,7 +243,7 @@ "TAB_WOT": "Red de confianza", "TAB_NETWORK": "Red", "TAB_BLOCKS": "Bloques", - "CURRENCY_SHORT_DESCRIPTION": "{{currency|abbreviate}} es una <b>moneda libre</b>, originada {{firstBlockTime|formatFromNow}}. Cuenta actualmente con <b>{{N}} miembros</b>, que producen y reciben un <a ng-click=\"showHelpModal('ud')\">Dividendo Universal</a> (DU) cada {{dt|formatPeriod}}.", + "CURRENCY_SHORT_DESCRIPTION": "{{currency}} es una <b>moneda libre</b>, originada {{firstBlockTime|formatFromNow}}. Cuenta actualmente con <b>{{N}} miembros</b>, que producen y reciben un <a ng-click=\"showHelpModal('ud')\">Dividendo Universal</a> (DU) cada {{dt|formatPeriod}}.", "NETWORK_RULES_DIVIDER": "Reglas de la red", "CURRENCY_NAME": "Nombre de la moneda", "MEMBERS": "Cantidad de miembros", @@ -954,9 +954,9 @@ "MENU_BTN_CURRENCY": "El menú <b>{{'MENU.CURRENCY'|translate}}</b> permite consultar las <b>reglas de la moneda</b> y su estado.", "CURRENCY_WOT": "El <b>número de miembros</b> muestra el peso de la comunidad y permite <b>seguir su evolución</b>.", "CURRENCY_MASS": "Siga aquí la <b>cantidad total de moneda</b> existente y su <b>distribución media</b> por miembro.<br/><br/>Esto permite juzgar la <b>relevancia de un importe</b>, en relación con lo que <b>poseen los demás</b> en sus cuentas (de media).", - "CURRENCY_UNIT_RELATIVE": "La unidad utilizada (“<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”) significa que los importes en {{currency|capitalize}} han sido divididos entre el valor del <b>Dividendo Universal</b> (DU).<br/><br/><small> Esta unidad relativa es <b>pertinente</b>, porque permanece estable, independiente de la cantidad de moneda que aumenta constantemente.</small>", - "CURRENCY_CHANGE_UNIT": "Este botón permite <b>cambiar la unidad</b>, para visualizar los importes <b>directamente en {{currency|capitalize}}</b> (en lugar de “<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”).", - "CURRENCY_CHANGE_UNIT_TO_RELATIVE": "Este botón permite <b>cambiar la unidad</b>, para visualizar los importes en “<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”, es decir, relativo al Dividendo Universal (el monto co-producido por cada miembro).", + "CURRENCY_UNIT_RELATIVE": "La unidad utilizada (“<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”) significa que los importes en {{currency|capitalize}} han sido divididos entre el valor del <b>Dividendo Universal</b> (DU).<br/><br/><small> Esta unidad relativa es <b>pertinente</b>, porque permanece estable, independiente de la cantidad de moneda que aumenta constantemente.</small>", + "CURRENCY_CHANGE_UNIT": "Este botón permite <b>cambiar la unidad</b>, para visualizar los importes <b>directamente en {{currency|capitalize}}</b> (en lugar de “<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”).", + "CURRENCY_CHANGE_UNIT_TO_RELATIVE": "Este botón permite <b>cambiar la unidad</b>, para visualizar los importes en “<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”, es decir, relativo al Dividendo Universal (el monto co-producido por cada miembro).", "CURRENCY_RULES": "Las <b>reglas</b> de la moneda fijan su funcionamiento <b>exacto y previsible</b>.<br/><br/>Es el propio ADN de la moneda, que hace que su código monetario sea <b>legible y transparente</b>.", "MENU_BTN_NETWORK": "El menú <b>{{'MENU.NETWORK'|translate}}</b> permite consultar el estado de la red.", "NETWORK_BLOCKCHAIN": "Todas las transacciones de la moneda están registradas dentro de un gran libro de contabilidad <b>público e infalsificable</b>, conocido como la <b>cadena de bloques</b> (<em>BlockChain</em> en inglés).", @@ -970,7 +970,7 @@ "WALLET_GIVEN_CERTIFICATIONS": "Haga clic aquí para consultar el detalle de sus <b>certificaciones emitidas</b>.", "WALLET_BALANCE": "El <b>saldo</b> de su cuenta se visualiza aquí.", "WALLET_BALANCE_RELATIVE": - "{{'HELP.TIP.WALLET_BALANCE'|translate}}<br/><br/>La unidad utilizada (“<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”) significa que el importe en {{currency|capitalize}} fue dividido entre el <b>Dividendo Universal</b> (DU) co-producido por cada miembro.<br/><br/>Actualmente un DU vale {{currentUD|formatInteger}} {{currency|capitalize}}s.", + "{{'HELP.TIP.WALLET_BALANCE'|translate}}<br/><br/>La unidad utilizada (“<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”) significa que el importe en {{currency|capitalize}} fue dividido entre el <b>Dividendo Universal</b> (DU) co-producido por cada miembro.<br/><br/>Actualmente un DU vale {{currentUD|formatInteger}} {{currency|capitalize}}s.", "WALLET_BALANCE_CHANGE_UNIT": "Podrá <b>cambiar la unidad</b> de visualización de los importes en los <b><i class=\"icon ion-android-settings\"></i> {{'MENU.SETTINGS'|translate}}</b>.<br/><br/>Por ejemplo, para visualizar los importes <b>directamente en {{currency|capitalize}}</b>, en lugar de unidad relativa.", "WALLET_PUBKEY": "Esta es la llave pública de su cuenta. Puede comunicarla a un tercero para que pueda identificar su cuenta de forma simple.", "WALLET_SEND": "Realizar un pago en algunos clics", @@ -992,7 +992,7 @@ "CERTIFY_RULES": "<b>Atención:</b> Certifique solamente <b>seres humanos físicos vivos</b>, que no posean ya ninguna otra cuenta miembro.<br/><br/>¡La seguridad de la red de la moneda depende del cuidado de cada individuo/a!", "MENU_BTN_SETTINGS": "En <b>{{'MENU.SETTINGS'|translate}}</b> podrá configurar la aplicación.", "HEADER_BAR_BTN_PROFILE": "Haga clic aquí para acceder a su <b>perfil</b>", - "SETTINGS_CHANGE_UNIT": "Podrá <b>cambiar la unidad de visualización</b> de los importes haciendo clic aquí.<br/><br/>- Desactive la opción para mostrar los importes en {{currency|capitalize}}.<br/>- Actívela para importes relativos al {{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub> (las cantidades de los importes se mostrarán <b>divididos</b> entre el Dividendo Universal actual).", + "SETTINGS_CHANGE_UNIT": "Podrá <b>cambiar la unidad de visualización</b> de los importes haciendo clic aquí.<br/><br/>- Desactive la opción para mostrar los importes en {{currency|capitalize}}.<br/>- Actívela para importes relativos al {{'COMMON.UD'|translate}}<sub>{{currency}}</sub> (las cantidades de los importes se mostrarán <b>divididos</b> entre el Dividendo Universal actual).", "END_LOGIN": "¡La visita guiada ha <b>terminado</b>!<br/><br/>¡Buena suerte en este nuevo mundo de la <b>economía libre</b> !", "END_NOT_LOGIN": "¡La visita guiada ha <b>terminado</b>!<br/><br/>Si quiere utilizar la moneda {{currency|capitalize}}, tiene que hacer un clic en <b>{{'LOGIN.CREATE_ACCOUNT'|translate}}</b> más abajo." } diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json index 1cc2fb1314330ace7006237b3e857cb272f77faf..5696f0fa007c2e7fc69449bd2f5b2582fe6a8bec 100644 --- a/src/assets/i18n/fr.json +++ b/src/assets/i18n/fr.json @@ -119,9 +119,9 @@ "TITLE": "Cesium", "WELCOME": "Bienvenue dans l'application Cesium !", "WELCOME_READONLY": "Bienvenue dans Cesium <span class='badge badge-balanced'>Monit</span> !", - "MESSAGE": "Recevez et envoyez de la monnaie libre {{currency|abbreviate}}", + "MESSAGE": "Recevez et envoyez de la monnaie libre {{currency}}", "MESSAGE_READONLY": "Suivez l'état de la monnaie libre {{currency}} en temps réel.", - "BTN_CURRENCY": "Explorer la monnaie {{currency|abbreviate}}", + "BTN_CURRENCY": "Explorer la monnaie {{currency}}", "BTN_ABOUT": "à propos", "BTN_HELP": "Aide en ligne", "BTN_NETWORK": "État du réseau", @@ -250,7 +250,7 @@ "TAB_WOT": "Toile de confiance", "TAB_NETWORK": "Réseau", "TAB_BLOCKS": "Blocs", - "CURRENCY_SHORT_DESCRIPTION": "{{currency|abbreviate}} est une <b>monnaie libre</b>, démarrée {{firstBlockTime|formatFromNow}}. Elle compte actuellement <b>{{N}} membres</b>, qui produisent et perçoivent un <a ng-click=\"showHelpModal('ud')\">Dividende Universel</a> (DU), chaque {{dt|formatPeriod}}.", + "CURRENCY_SHORT_DESCRIPTION": "{{currency}} est une <b>monnaie libre</b>, démarrée {{firstBlockTime|formatFromNow}}. Elle compte actuellement <b>{{N}} membres</b>, qui produisent et perçoivent un <a ng-click=\"showHelpModal('ud')\">Dividende Universel</a> (DU), chaque {{dt|formatPeriod}}.", "NETWORK_RULES_DIVIDER": "Règles du réseau", "CURRENCY_NAME": "Nom de la monnaie", "MEMBERS": "Nombre de membres", @@ -472,6 +472,7 @@ "AUTH": { "TITLE": "<i class=\"icon ion-locked\"></i> Authentification", "BTN_AUTH": "S'authentifier", + "PASSPHRASE": "Code secret", "GENERAL_HELP": "Veuillez vous authentifier :", "EXPECTED_UID_HELP": "Veuillez vous authentifier sur le compte <i class=\"ion-person\"></i> {{uid}} :", "EXPECTED_PUBKEY_HELP": "Veuillez vous authentifier sur le portefeuille <br class=\"visible-xs\"/><i class=\"ion-key\"></i> {{pubkey|formatPubkey}} :", @@ -891,9 +892,9 @@ "MENU_BTN_CURRENCY": "Le menu <b>{{'MENU.CURRENCY'|translate}}</b> permet la consultation des <b>règles de la monnaie</b> et de son état.", "CURRENCY_WOT": "Le <b>nombre de membres</b> montre l'importance de la communauté et permet de <b>suivre son évolution</b>.", "CURRENCY_MASS": "Suivez ici la <b>quantité totale de monnaie</b> existante et sa <b>répartition moyenne</b> par membre.<br/><br/>Ceci permet de juger de l'<b>importance d'un montant</b>, vis à vis de ce que <b>possède les autres</b> sur leur compte (en moyenne).", - "CURRENCY_UNIT_RELATIVE": "L'unité utilisée (“<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”) signifie que les montants en {{currency|capitalize}} ont été divisés par le <b>Dividende Universel</b> (DU).<br/><br/><small>Cette unité relative est <b>pertinente</b>, car stable malgré la quantitié de monnaie qui augmente en permanence.</small>", - "CURRENCY_CHANGE_UNIT": "L'option <b>{{'COMMON.BTN_RELATIVE_UNIT'|translate}}</b> permet de <b>changer d'unité</b>, pour visualiser les montants <b>directement en {{currency|capitalize}}</b> (plutôt qu'en “<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”).", - "CURRENCY_CHANGE_UNIT_TO_RELATIVE": "L'option <b>{{'COMMON.BTN_RELATIVE_UNIT'|translate}}</b> permet de <b>changer d'unité</b>, pour visualiser les montants en “<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”, c'est-à-dire relativement au Dividende Universel (le montant co-produit par chaque membre).", + "CURRENCY_UNIT_RELATIVE": "L'unité utilisée (“<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”) signifie que les montants en {{currency|capitalize}} ont été divisés par le <b>Dividende Universel</b> (DU).<br/><br/><small>Cette unité relative est <b>pertinente</b>, car stable malgré la quantitié de monnaie qui augmente en permanence.</small>", + "CURRENCY_CHANGE_UNIT": "L'option <b>{{'COMMON.BTN_RELATIVE_UNIT'|translate}}</b> permet de <b>changer d'unité</b>, pour visualiser les montants <b>directement en {{currency|capitalize}}</b> (plutôt qu'en “<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”).", + "CURRENCY_CHANGE_UNIT_TO_RELATIVE": "L'option <b>{{'COMMON.BTN_RELATIVE_UNIT'|translate}}</b> permet de <b>changer d'unité</b>, pour visualiser les montants en “<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”, c'est-à-dire relativement au Dividende Universel (le montant co-produit par chaque membre).", "CURRENCY_RULES": "Les <b>règles</b> de la monnaie fixent son fonctionnement <b>exact et prévisible</b>.<br/><br/>Véritable ADN de la monnaie, elles rendent son code monétaire <b>lisible et transparent</b>.", "MENU_BTN_NETWORK": "Le menu <b>{{'MENU.NETWORK'|translate}}</b> permet la consultation de l'état du réseau.", "NETWORK_BLOCKCHAIN": "Toutes les opérations de la monnaie sont enregistrées dans un grand livre de compte <b>public et infalsifiable</b>, appelé aussi <b>chaine de blocs</b> (<em>BlockChain</em> en anglais).", @@ -906,7 +907,7 @@ "WALLET_RECEIVED_CERTIFICATIONS": "Cliquez ici pour consulter le détail de vos <b>certifications reçues</b>.", "WALLET_GIVEN_CERTIFICATIONS": "Cliquez ici pour consulter le détail de vos <b>certifications émises</b>.", "WALLET_BALANCE": "Le <b>solde</b> de votre compte s'affiche ici.", - "WALLET_BALANCE_RELATIVE": "{{'HELP.TIP.WALLET_BALANCE'|translate}}<br/><br/>L'unité utilisée (“<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”) signifie que le montant en {{currency|capitalize}} a été divisé par le <b>Dividende Universel</b> (DU) co-créé par chaque membre.<br/><br/>Actuellement 1 DU vaut {{currentUD|formatInteger}} {{currency|capitalize}}s.", + "WALLET_BALANCE_RELATIVE": "{{'HELP.TIP.WALLET_BALANCE'|translate}}<br/><br/>L'unité utilisée (“<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”) signifie que le montant en {{currency|capitalize}} a été divisé par le <b>Dividende Universel</b> (DU) co-créé par chaque membre.<br/><br/>Actuellement 1 DU vaut {{currentUD|formatInteger}} {{currency|capitalize}}s.", "WALLET_BALANCE_CHANGE_UNIT": "Vous pourrez <b>changer l'unité</b> d'affichage des montants dans les <b><i class=\"icon ion-android-settings\"></i> {{'MENU.SETTINGS'|translate}}</b>.<br/><br/>Par exemple pour visualiser les montants <b>directement en {{currency|capitalize}}</b>, plutôt qu'en unité relative.", "WALLET_PUBKEY": "Voici la clé publique de votre compte. Vous pouvez la communiquer à un tiers afin qu'il identifie plus simplement votre compte.", "WALLET_SEND": "Effectuer un paiement en quelques clics.", @@ -928,7 +929,7 @@ "CERTIFY_RULES": "<b>Attention :</b> Ne certifiez que des <b>personnes physiques vivantes</b>, ne possédant aucun autre compte membre.<br/><br/>La sécurité de la monnaie dépend de la vigilance de chacun !", "MENU_BTN_SETTINGS": "Les <b>{{'MENU.SETTINGS'|translate}}</b> vous permettront de configurer l'application.", "HEADER_BAR_BTN_PROFILE": "Cliquez ici pour accéder à votre <b>profil utilisateur.</b>", - "SETTINGS_CHANGE_UNIT": "Vous pourrez <b>changer d'unité d'affichage</b> des montants en cliquant ci-dessus.<br/><br/>- Désactivez l'option pour un affichage des montants en {{currency|capitalize}}.<br/>- Activez l'option pour un affichage relatif en {{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub> (tous les montants seront <b>divisés</b> par le Dividende Universel courant).", + "SETTINGS_CHANGE_UNIT": "Vous pourrez <b>changer d'unité d'affichage</b> des montants en cliquant ci-dessus.<br/><br/>- Désactivez l'option pour un affichage des montants en {{currency|capitalize}}.<br/>- Activez l'option pour un affichage relatif en {{'COMMON.UD'|translate}}<sub>{{currency}}</sub> (tous les montants seront <b>divisés</b> par le Dividende Universel courant).", "END_LOGIN": "Cette visite guidée est <b>terminée</b> !<br/><br/>Bonne continuation à vous, dans le nouveau monde de l'<b>économie libre</b> !", "END_NOT_LOGIN": "Cette visite guidée est <b>terminée</b> !<br/><br/>Si vous souhaitez rejoindre la monnaie {{currency|capitalize}}, il vous suffira de cliquer sur <b>{{'LOGIN.CREATE_FREE_ACCOUNT'|translate}}</b> ci-dessous.", "END_READONLY": "Cette visite guidée est <b>terminée</b>.<br/><br/>{{'MODE.READONLY.INSTALL_HELP'|translate}}." diff --git a/src/assets/i18n/it-IT.json b/src/assets/i18n/it-IT.json index 94d60314ef28cb8e1f8d1c45d8145768fb754725..59d105b51a65b2d651d00571a128a2631f0f5eb5 100644 --- a/src/assets/i18n/it-IT.json +++ b/src/assets/i18n/it-IT.json @@ -116,9 +116,9 @@ "TITLE": "Cesium", "WELCOME": "Benvenuti al Cesium App!", "WELCOME_READONLY": "Benvenuti nel Cesium <span class='badge badge-balanced'>Monit</span>!", - "MESSAGE": "Scambiate in moneta libera {{currency|abbreviate}}", - "MESSAGE_READONLY": "Monitoraggio in tempo reale della moneta libera {{currency|abbreviate}}", - "BTN_CURRENCY": "Esplorare la moneta {{currency|abbreviate}}", + "MESSAGE": "Scambiate in moneta libera {{currency}}", + "MESSAGE_READONLY": "Monitoraggio in tempo reale della moneta libera {{currency}}", + "BTN_CURRENCY": "Esplorare la moneta {{currency}}", "BTN_ABOUT": "A proposito", "BTN_HELP": "Aiuto", "BTN_NETWORK": "Stato della rete", @@ -804,9 +804,9 @@ "MENU_BTN_CURRENCY": "Menu <b>{{'MENU.CURRENCY'|translate}}</b> permette la scoperta dei <b>parametri della moneta</b> e la sua condizione presente.", "CURRENCY_WOT": "Il <b>numero di membri</b> mostra <b>le dimensioni della RdF e la sua evoluzione </b>.", "CURRENCY_MASS": "In evidenza qui è <b>l'importo totale</b> attualmente in circolazione e la sua <b> ripartizione media </b> a testa.<br/><br/>Questa cifra permette di avere un'idea <b>del valore di qualsiasi importo</b>, in base a quello che <b>hanno gli altri</b> sul loro conto (in media).", - "CURRENCY_UNIT_RELATIVE": "L'unità usata qui (“<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”) significa che gli importi in {{currency|capitalize}} sono stati divisi dal <b>Dividendo Universale</b> (DU).<br/><br/><small>Questa unità relativa <b>ha senso</b> perche è stabile in contrasto con la massa monetaria che cresce costantemente.</small>", - "CURRENCY_CHANGE_UNIT": "Questa opzione <b>{{'COMMON.BTN_RELATIVE_UNIT'|translate}}</b> permette di <b>permutare unità</b> per vedere gli importi in <b>{{currency|capitalize}}</b>, non divisi dal Dividendo Universale (piuttosto che in “<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”).", - "CURRENCY_CHANGE_UNIT_TO_RELATIVE": "Questa opzione <b>{{'COMMON.BTN_RELATIVE_UNIT'|translate}}</b> permette <b>di permutare unità</b> per vedere gli importi in “<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”, che è relativo al Dividendo Universale (l'importo co-prodotto da ogni membro).", + "CURRENCY_UNIT_RELATIVE": "L'unità usata qui (“<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”) significa che gli importi in {{currency|capitalize}} sono stati divisi dal <b>Dividendo Universale</b> (DU).<br/><br/><small>Questa unità relativa <b>ha senso</b> perche è stabile in contrasto con la massa monetaria che cresce costantemente.</small>", + "CURRENCY_CHANGE_UNIT": "Questa opzione <b>{{'COMMON.BTN_RELATIVE_UNIT'|translate}}</b> permette di <b>permutare unità</b> per vedere gli importi in <b>{{currency|capitalize}}</b>, non divisi dal Dividendo Universale (piuttosto che in “<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”).", + "CURRENCY_CHANGE_UNIT_TO_RELATIVE": "Questa opzione <b>{{'COMMON.BTN_RELATIVE_UNIT'|translate}}</b> permette <b>di permutare unità</b> per vedere gli importi in “<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”, che è relativo al Dividendo Universale (l'importo co-prodotto da ogni membro).", "CURRENCY_RULES": "Le<b>regole</b> della moneta determinano il suo <b>esatto e previdibile</b> comportamento.<br/><br/> Considerate come il proprio DNA della moneta, queste regole rendono il codice monetario <b>trasparente e comprensibile</b>.", "MENU_BTN_NETWORK": "Menu <b>{{'MENU.NETWORK'|translate}}</b> permette la scopertà dello <b>stato della rete<b>.", "NETWORK_BLOCKCHAIN": "Tutte le transazioni monetarie sono registrate in <b>registro sicuro e a prova di manomissione</b>, spesso chiamato <b>blockchain</b>.", @@ -819,7 +819,7 @@ "WALLET_RECEIVED_CERTIFICATIONS": "Clicca qui per vedere i dettagli delle <b>certificazioni che hai ricevuto</b>.", "WALLET_GIVEN_CERTIFICATIONS": "Clicca qui per vedere i dettagli delle <b>certificazioni che hai dato</b>.", "WALLET_BALANCE": "Il <b>saldo</b> del tuo conto è visibile qui.", - "WALLET_BALANCE_RELATIVE": "{{'HELP.TIP.WALLET_BALANCE'|translate}}<br/><br/>L'unità utilizzata (“<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”) significa che questo importo in {{currency|capitalize}} è stato diviso dal <b>Dividendo Universale</b> (DU) co-creato da ogni membro.<br/>Ad oggi, 1 DU equivale a {{currentUD}} {{currency|capitalize}}.", + "WALLET_BALANCE_RELATIVE": "{{'HELP.TIP.WALLET_BALANCE'|translate}}<br/><br/>L'unità utilizzata (“<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”) significa che questo importo in {{currency|capitalize}} è stato diviso dal <b>Dividendo Universale</b> (DU) co-creato da ogni membro.<br/>Ad oggi, 1 DU equivale a {{currentUD}} {{currency|capitalize}}.", "WALLET_BALANCE_CHANGE_UNIT": "Puoi <b>cambiare l'unità</b> in cui sono mostrati gli importi in <b><i class=\"icon ion-android-settings\"></i> {{'MENU.SETTINGS'|translate}}</b>.<br/><br/>Per esempio, per mostrare gli importi <b>direttamente in {{currency|capitalize}}</b> piuttosto che in unità relativa.", "WALLET_PUBKEY": "Questa è la chiave pubblica del tuo conto. La puoi dare ad un terzo perché possa identificare tuo conto.", "WALLET_SEND": "Paghi in pochi clics.", @@ -840,7 +840,7 @@ "CERTIFY_RULES": "<b>Attenzione:</b> Certifica <b>solo persone reali e vive</b> che non hanno nessun altro conto membro.<br/><br/>L'affidabilità della moneta dipende della vigilanza di ciascuno.", "MENU_BTN_SETTINGS": "Le <b>{{'MENU.SETTINGS'|translate}}</b> ti permettono di configurare il Cesium.<br/><br/>Per esempio, puoi <b>cambiare l'unità</b> in cui visualizzi la moneta.", "HEADER_BAR_BTN_PROFILE": "Clicca qui per entrare nel <b>tuo profilo utente</b>", - "SETTINGS_CHANGE_UNIT": "Puoi cambiare <b>l'unità</b> della moneta cliccando qui.<br/><br/>- Disabilita questa opzione per vedere gli importi in {{currency|capitalize}}.<br/>- Abilita l'opzione per importi relativi in {{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub> (<b>divisi</b> dal attuale Dividendo Universale).", + "SETTINGS_CHANGE_UNIT": "Puoi cambiare <b>l'unità</b> della moneta cliccando qui.<br/><br/>- Disabilita questa opzione per vedere gli importi in {{currency|capitalize}}.<br/>- Abilita l'opzione per importi relativi in {{'COMMON.UD'|translate}}<sub>{{currency}}</sub> (<b>divisi</b> dal attuale Dividendo Universale).", "END_LOGIN": "Il tour guidato <b>è finito</b>.<br/><br/>Benvenuto nel <b>economia libera</b>!", "END_NOT_LOGIN": "Il tour guidato <b>è finito</b>.<br/><br/>Se desideri entrare nella Rete di Fiducia {{currency|capitalize}}, basta cliccare <b>{{'LOGIN.CREATE_ACCOUNT'|translate}}</b> qui sotto.", "END_READONLY": "Il tour guidato <b>è finito</b>.<br/><br/>{{'MODE.READONLY.INSTALL_HELP'|translate}}." diff --git a/src/assets/i18n/nl-NL.json b/src/assets/i18n/nl-NL.json index 977828b1077d78fa1bf80a5cc0cbf4ec242be28e..7a65ac325d1ad5f06c6fa0a3d3b2a926e3c9a49e 100644 --- a/src/assets/i18n/nl-NL.json +++ b/src/assets/i18n/nl-NL.json @@ -105,7 +105,7 @@ "HOME": { "TITLE": "Cesium", "WELCOME": "Welkom bij de Cesium Applicatie!", - "MESSAGE": "Bekijk je {{currency|abbreviate}} portefeilles in real time.", + "MESSAGE": "Bekijk je {{currency}} portefeilles in real time.", "BTN_REGISTRY": "Register", "BTN_CURRENCY": "Verken valuta", "BTN_ABOUT": "over", @@ -539,9 +539,9 @@ "MENU_BTN_CURRENCY": "Menu <b>{{'MENU.CURRENCY'|translate}}</b> allows discovery of <b>currency parameters</b> and its state.", "CURRENCY_WOT": "The <b>member count</b> shows the <b>community's weight and evolution</b>.", "CURRENCY_MASS": "Shown here is the <b>total amount</b> currently in circulation and its <b>average distribution</b> per member.<br/><br/>This allows to estimate the <b>worth of any amount</b>, in respect to what <b>others own</b> on their account (on average).", - "CURRENCY_UNIT_RELATIVE": "The unit used here (“<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”) signifies that the amounts in {{currency|capitalize}} have been devided by the <b>Universal Dividend</b> (UD).<br/><br/><small>This relative unit is <b>relevant</b> because it is stable in contrast to the permanently growing monitary mass.</small>", - "CURRENCY_CHANGE_UNIT": "This button allows to <b>switch the unit</b> to show amounts in <b>{{currency|capitalize}}</b>, undevided by the Universal Dividend (instead of in “<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”).", - "CURRENCY_CHANGE_UNIT_TO_RELATIVE": "This button allows to <b>switch the unit</b> to show amounts in “<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”, which is relative to the Universal Dividend (the amount co-produced by each member).", + "CURRENCY_UNIT_RELATIVE": "The unit used here (“<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”) signifies that the amounts in {{currency|capitalize}} have been devided by the <b>Universal Dividend</b> (UD).<br/><br/><small>This relative unit is <b>relevant</b> because it is stable in contrast to the permanently growing monitary mass.</small>", + "CURRENCY_CHANGE_UNIT": "This button allows to <b>switch the unit</b> to show amounts in <b>{{currency|capitalize}}</b>, undevided by the Universal Dividend (instead of in “<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”).", + "CURRENCY_CHANGE_UNIT_TO_RELATIVE": "This button allows to <b>switch the unit</b> to show amounts in “<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”, which is relative to the Universal Dividend (the amount co-produced by each member).", "CURRENCY_RULES": "The <b>rules</b> of the currency determine its <b>exact and predictible</b> performance.<br/><br/>As a true DNA of the currency these rules make the monetary code <b>transparent and understandable</b>.", "NETWORK_BLOCKCHAIN": "All monetary transactions are recoded in a <b>public and tamper proof</b> ledger, generally referred to as the <b>blockchain</b>.", "NETWORK_PEERS": "The <b>peers</b> shown here correspond to <b>computers that update and check</b> the blockchain.<br/><br/>The more active peers there are, the more <b>decentralised</b> and therefore trustworhty the currency becomes.", @@ -551,7 +551,7 @@ "MENU_BTN_ACCOUNT_MEMBER": "Here you can consult your account status, transaction history and your certifications.", "WALLET_CERTIFICATIONS": "Click here to reveiw the details of your certifications (given and received).", "WALLET_BALANCE": "Your account <b>balance</b> is shown here.", - "WALLET_BALANCE_RELATIVE": "{{'HELP.TIP.WALLET_BALANCE'|translate}}<br/><br/>The used unit (“<b>{{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub></b>”) signifies that the amount in {{currency|capitalize}} has been divided by the <b>Universal Dividend</b> (UD) co-created by each member.<br/>At this moment, 1 UD equals {{currentUD}} {{currency|capitalize}}.", + "WALLET_BALANCE_RELATIVE": "{{'HELP.TIP.WALLET_BALANCE'|translate}}<br/><br/>The used unit (“<b>{{'COMMON.UD'|translate}}<sub>{{currency}}</sub></b>”) signifies that the amount in {{currency|capitalize}} has been divided by the <b>Universal Dividend</b> (UD) co-created by each member.<br/>At this moment, 1 UD equals {{currentUD}} {{currency|capitalize}}.", "WALLET_BALANCE_CHANGE_UNIT": "You can <b>change the unit</b> in which amounts are shown in <b><i class=\"icon ion-android-settings\"></i> {{'MENU.SETTINGS'|translate}}</b>.<br/><br/>For example, to display amounts <b>directly in {{currency|capitalize}}</b> instead of relative amounts.", "WALLET_SEND": "Issue a payment in just a few clicks.", "WALLET_SEND_NO_MONEY": "Issue a payment in just a few clicks.<br/>(Your balance does not allow this yet)", @@ -570,7 +570,7 @@ "CERTIFY_RULES": "<b>Attention:</b> Only certify <b>real and living persons</b> that do not own any other certified account.<br/><br/>The trust carried by the currency depends on each member's vigilance!", "MENU_BTN_SETTINGS": "The <b>{{'MENU.SETTINGS'|translate}}</b> allow you to configure the Cesium application.<br/><br/>For example, you can <b>change the unit</b> in which the currency will be shown.", "HEADER_BAR_BTN_PROFILE": "Click here to access your <b>user profile</b>", - "SETTINGS_CHANGE_UNIT": "You can <b>change the display unit</b> of amounts by clicking here.<br/><br/>- Deactivate the option to show amounts in {{currency|capitalize}}.<br/>- Activate the option for relative amounts in {{'COMMON.UD'|translate}}<sub>{{currency|abbreviate}}</sub> (<b>divided</b> by the current Universal Dividend).", + "SETTINGS_CHANGE_UNIT": "You can <b>change the display unit</b> of amounts by clicking here.<br/><br/>- Deactivate the option to show amounts in {{currency|capitalize}}.<br/>- Activate the option for relative amounts in {{'COMMON.UD'|translate}}<sub>{{currency}}</sub> (<b>divided</b> by the current Universal Dividend).", "END_LOGIN": "This guided visit has <b>ended</b>.<br/><br/>Welcome to the <b>free economy</b>!", "END_NOT_LOGIN": "This guided visit has <b>ended</b>.<br/><br/>If you wish to join the currency {{currency|capitalize}}, simply click <b>{{'LOGIN.CREATE_ACCOUNT'|translate}}</b> below." } diff --git a/src/environments/environment.class.ts b/src/environments/environment.class.ts index fd9ab0d6f87def3c8d68ebe3146cc9ac7f32b5f0..fd7b9599eed7fd2ae9fb0a47e8ba8d1efd22c3ca 100644 --- a/src/environments/environment.class.ts +++ b/src/environments/environment.class.ts @@ -1,5 +1,5 @@ import {AuthData} from "@app/auth/auth.model"; -import {StorageConfig} from '@ionic/storage'; +import {StorageConfig} from '@ionic/storage-angular'; export interface Environment { name: string; diff --git a/src/environments/environment.ts b/src/environments/environment.ts index b1357128598c6bab2d23be3d0f3bfb12eb8f9268..9b1ef9850964b2795be1db67dca74885886a550e 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -3,17 +3,21 @@ // The list of file replacements can be found in `angular.json`. import {Environment} from "./environment.class"; +import {AuthData} from "@app/auth/auth.model"; +import {Drivers} from "@ionic/storage"; export const environment = <Environment>{ + //production: true, production: false, - name: 'Cesium²', + + name: 'Cesium', defaultLocale: 'fr', // Storage storage: { - name: 'decsium-dev', - driverOrder: ['sqlite', 'indexeddb', 'websql', 'localstorage'] + name: 'cesium', + driverOrder: ['localForage-cordovaSQLiteDriver', Drivers.IndexedDB, Drivers.LocalStorage] }, keyring: { @@ -22,17 +26,21 @@ export const environment = <Environment>{ dev: { //peer: 'ws://localhost:9944', - peer: 'wss://gdev.komun.org/ws', + //peer: 'wss://gdev.komun.org/ws', + peer: 'wss://gdev.librelois.fr/ws', - auth: { - salt: 'test', password: 'test' + auth: <AuthData>{ + v1: { + salt: 'test', password: 'test' + } } }, defaultPeers: [ - 'ws://localhost:9944/ws', + //'ws://localhost:9944/ws', /* GDev endpoints */ - 'wss://gdev.komun.org/ws', - 'wss://1000i100.fr/ws' + 'wss://gdev.librelois.fr/ws', + //'wss://gdev.komun.org/ws', + //'wss://1000i100.fr/ws' ] }; diff --git a/tsconfig.app.json b/tsconfig.app.json index 82d91dc4a4de57f380b66c59cdd16ff6cd5798e4..4cfb3a2153c21f1056a0b5fac301c6b4fec038d3 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -11,5 +11,9 @@ ], "include": [ "src/**/*.d.ts" + ], + "exclude": [ + "src/test.ts", + "src/**/*.spec.ts" ] }