From 1a377d5f715243836e1ebf3dec7ea4cc3db5ad9e Mon Sep 17 00:00:00 2001 From: Martin Kaintas Date: Mon, 27 May 2024 15:01:37 +0300 Subject: [PATCH 01/55] fix: custom networks are testnet type --- src/protocols/bitcoin/libs/BitcoinAdapter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/protocols/bitcoin/libs/BitcoinAdapter.ts b/src/protocols/bitcoin/libs/BitcoinAdapter.ts index f5f2390a12..fee0d5081d 100644 --- a/src/protocols/bitcoin/libs/BitcoinAdapter.ts +++ b/src/protocols/bitcoin/libs/BitcoinAdapter.ts @@ -180,8 +180,8 @@ export class BitcoinAdapter extends BaseProtocolAdapter { ): IHdWalletAccount { const { activeNetwork } = useNetworks(); - const network = networks[activeNetwork.value.type as keyof typeof networks] || networks.bitcoin; - const pathCoinType = activeNetwork.value.type === NETWORK_TYPE_TESTNET ? 1 : 0; + const network = networks[activeNetwork.value.type === NETWORK_TYPE_MAINNET ? 'bitcoin' : 'testnet']; + const pathCoinType = activeNetwork.value.type === NETWORK_TYPE_MAINNET ? 0 : 1; const node = this.bip32.fromSeed(Buffer.from(seed)); const path = `m/84'/${pathCoinType}'/${accountIndex}'/0/0`; // 84 for Native-SegWit and 44 for Legacy From b69cb4a7848dabb68e74791012efe22d316cc78d Mon Sep 17 00:00:00 2001 From: Martin Kaintas Date: Mon, 27 May 2024 13:54:50 +0300 Subject: [PATCH 02/55] fix: reset input after generating gift card --- package-lock.json | 159 ++++++++++++++++++------------------- package.json | 6 +- src/popup/pages/Invite.vue | 9 ++- 3 files changed, 87 insertions(+), 87 deletions(-) diff --git a/package-lock.json b/package-lock.json index d3e3f057c9..d4c62aba36 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,8 +40,8 @@ "@ionic/vue-router": "^7.1.2", "@rushstack/eslint-patch": "^1.3.2", "@trapezedev/configure": "^7.0.10", - "@vee-validate/i18n": "^4.8.6", - "@vee-validate/rules": "^4.8.6", + "@vee-validate/i18n": "^4.12.8", + "@vee-validate/rules": "^4.12.8", "@vue/vue3-jest": "^27.0.0", "bignumber.js": "^9.0.2", "bip32": "^4.0.0", @@ -63,7 +63,7 @@ "tweetnacl": "^1.0.3", "uuid": "^9.0.1", "validator": "^13.9.0", - "vee-validate": "^4.8.6", + "vee-validate": "^4.12.8", "vue": "^3.3.2", "vue-i18n": "^9.2.2", "vue-loader": "^17.2.2", @@ -6445,16 +6445,18 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" }, "node_modules/@vee-validate/i18n": { - "version": "4.12.6", - "resolved": "https://registry.npmjs.org/@vee-validate/i18n/-/i18n-4.12.6.tgz", - "integrity": "sha512-K3xbjLIQQwDrllS18Ka5nyQDIF/1FuHnedXTr6bfmTm44/7C4MyMGo9KDahnrMWTcFkYIKR7XMshM3R6o54MFg==" + "version": "4.12.8", + "resolved": "https://registry.npmjs.org/@vee-validate/i18n/-/i18n-4.12.8.tgz", + "integrity": "sha512-Jl63ZUICt15GIDi+GIcdPRVIVcLJcVMApTnSprfs53BllXnxbq/A3QNo9wCbQk4bP3L/S3NcPoLBFEH6PQU65g==", + "license": "MIT" }, "node_modules/@vee-validate/rules": { - "version": "4.12.6", - "resolved": "https://registry.npmjs.org/@vee-validate/rules/-/rules-4.12.6.tgz", - "integrity": "sha512-vXhunbllildEbCWaBI2m6mij7U4pDTeoqX9CQ7/0gVMhtkTZh+QhKsDSaGI2evatECINH2cpLOBaMkubdN82VQ==", + "version": "4.12.8", + "resolved": "https://registry.npmjs.org/@vee-validate/rules/-/rules-4.12.8.tgz", + "integrity": "sha512-RisPzo+jGt0B0QTVhyZK5Pxb0Q6TESnS2rbR+CE3HRtJ+z0q5rkqkSIwvKrTKJFZpowJIoAHYS02jm5Pty5C3Q==", + "license": "MIT", "dependencies": { - "vee-validate": "4.12.6" + "vee-validate": "4.12.8" } }, "node_modules/@vue/babel-helper-vue-jsx-merge-props": { @@ -7672,49 +7674,49 @@ "dev": true }, "node_modules/@vue/compiler-core": { - "version": "3.4.21", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.21.tgz", - "integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==", + "version": "3.4.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.27.tgz", + "integrity": "sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==", "dependencies": { - "@babel/parser": "^7.23.9", - "@vue/shared": "3.4.21", + "@babel/parser": "^7.24.4", + "@vue/shared": "3.4.27", "entities": "^4.5.0", "estree-walker": "^2.0.2", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-dom": { - "version": "3.4.21", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz", - "integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==", + "version": "3.4.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz", + "integrity": "sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==", "dependencies": { - "@vue/compiler-core": "3.4.21", - "@vue/shared": "3.4.21" + "@vue/compiler-core": "3.4.27", + "@vue/shared": "3.4.27" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.4.21", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz", - "integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==", + "version": "3.4.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz", + "integrity": "sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==", "dependencies": { - "@babel/parser": "^7.23.9", - "@vue/compiler-core": "3.4.21", - "@vue/compiler-dom": "3.4.21", - "@vue/compiler-ssr": "3.4.21", - "@vue/shared": "3.4.21", + "@babel/parser": "^7.24.4", + "@vue/compiler-core": "3.4.27", + "@vue/compiler-dom": "3.4.27", + "@vue/compiler-ssr": "3.4.27", + "@vue/shared": "3.4.27", "estree-walker": "^2.0.2", - "magic-string": "^0.30.7", - "postcss": "^8.4.35", - "source-map-js": "^1.0.2" + "magic-string": "^0.30.10", + "postcss": "^8.4.38", + "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.4.21", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz", - "integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==", + "version": "3.4.27", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz", + "integrity": "sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==", "dependencies": { - "@vue/compiler-dom": "3.4.21", - "@vue/shared": "3.4.21" + "@vue/compiler-dom": "3.4.27", + "@vue/shared": "3.4.27" } }, "node_modules/@vue/component-compiler-utils": { @@ -7847,48 +7849,48 @@ } }, "node_modules/@vue/reactivity": { - "version": "3.4.21", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.21.tgz", - "integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==", + "version": "3.4.27", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.27.tgz", + "integrity": "sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==", "dependencies": { - "@vue/shared": "3.4.21" + "@vue/shared": "3.4.27" } }, "node_modules/@vue/runtime-core": { - "version": "3.4.21", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.21.tgz", - "integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==", + "version": "3.4.27", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.27.tgz", + "integrity": "sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==", "dependencies": { - "@vue/reactivity": "3.4.21", - "@vue/shared": "3.4.21" + "@vue/reactivity": "3.4.27", + "@vue/shared": "3.4.27" } }, "node_modules/@vue/runtime-dom": { - "version": "3.4.21", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz", - "integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==", + "version": "3.4.27", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.27.tgz", + "integrity": "sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==", "dependencies": { - "@vue/runtime-core": "3.4.21", - "@vue/shared": "3.4.21", + "@vue/runtime-core": "3.4.27", + "@vue/shared": "3.4.27", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.4.21", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.21.tgz", - "integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==", + "version": "3.4.27", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.27.tgz", + "integrity": "sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==", "dependencies": { - "@vue/compiler-ssr": "3.4.21", - "@vue/shared": "3.4.21" + "@vue/compiler-ssr": "3.4.27", + "@vue/shared": "3.4.27" }, "peerDependencies": { - "vue": "3.4.21" + "vue": "3.4.27" } }, "node_modules/@vue/shared": { - "version": "3.4.21", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz", - "integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==" + "version": "3.4.27", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz", + "integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==" }, "node_modules/@vue/test-utils": { "version": "2.4.5", @@ -21556,14 +21558,11 @@ } }, "node_modules/magic-string": { - "version": "0.30.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.9.tgz", - "integrity": "sha512-S1+hd+dIrC8EZqKyT9DstTH/0Z+f76kmmvZnkfQVmOpDEF9iVgdYif3Q/pIWHmCoo59bQVGW0kVL3e2nl+9+Sw==", + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" } }, "node_modules/make-dir": { @@ -29184,15 +29183,15 @@ } }, "node_modules/vee-validate": { - "version": "4.12.6", - "resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-4.12.6.tgz", - "integrity": "sha512-EKM3YHy8t1miPh30d5X6xOrfG/Ctq0nbN4eMpCK7ezvI6T98/S66vswP+ihL4QqAK/k5KqreWOxof09+JG7N/A==", + "version": "4.12.8", + "resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-4.12.8.tgz", + "integrity": "sha512-A07rm3+y7SRk0CMD/O4nBT0nxtwjyfzGZwjEUDk18SxK0ZMzd4AFCzzdHlIiCE1QgHetxd0I3kVkZdN0GG0Oww==", "dependencies": { - "@vue/devtools-api": "^6.5.1", + "@vue/devtools-api": "^6.6.1", "type-fest": "^4.8.3" }, "peerDependencies": { - "vue": "^3.3.11" + "vue": "^3.4.26" } }, "node_modules/vee-validate/node_modules/type-fest": { @@ -29226,15 +29225,15 @@ "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" }, "node_modules/vue": { - "version": "3.4.21", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.21.tgz", - "integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==", - "dependencies": { - "@vue/compiler-dom": "3.4.21", - "@vue/compiler-sfc": "3.4.21", - "@vue/runtime-dom": "3.4.21", - "@vue/server-renderer": "3.4.21", - "@vue/shared": "3.4.21" + "version": "3.4.27", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.27.tgz", + "integrity": "sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==", + "dependencies": { + "@vue/compiler-dom": "3.4.27", + "@vue/compiler-sfc": "3.4.27", + "@vue/runtime-dom": "3.4.27", + "@vue/server-renderer": "3.4.27", + "@vue/shared": "3.4.27" }, "peerDependencies": { "typescript": "*" diff --git a/package.json b/package.json index 6814667ec5..2ac9a70f85 100644 --- a/package.json +++ b/package.json @@ -63,8 +63,8 @@ "@ionic/vue-router": "^7.1.2", "@rushstack/eslint-patch": "^1.3.2", "@trapezedev/configure": "^7.0.10", - "@vee-validate/i18n": "^4.8.6", - "@vee-validate/rules": "^4.8.6", + "@vee-validate/i18n": "^4.12.8", + "@vee-validate/rules": "^4.12.8", "@vue/vue3-jest": "^27.0.0", "bignumber.js": "^9.0.2", "bip32": "^4.0.0", @@ -86,7 +86,7 @@ "tweetnacl": "^1.0.3", "uuid": "^9.0.1", "validator": "^13.9.0", - "vee-validate": "^4.8.6", + "vee-validate": "^4.12.8", "vue": "^3.3.2", "vue-i18n": "^9.2.2", "vue-loader": "^17.2.2", diff --git a/src/popup/pages/Invite.vue b/src/popup/pages/Invite.vue index 417843b647..9ed87874c8 100644 --- a/src/popup/pages/Invite.vue +++ b/src/popup/pages/Invite.vue @@ -16,7 +16,7 @@ {{ $t('pages.invite.generate-link') }}

{{ $t('pages.invite.generate') }} @@ -121,7 +121,7 @@ export default defineComponent({ const { max, fee } = useMaxAmount({ formModel }); - async function generate() { + async function generate(resetField: () => void) { setLoaderVisible(true); const { publicKey, secretKey } = generateKeyPair(); @@ -143,7 +143,8 @@ export default defineComponent({ } addInvite(Buffer.from(secretKey, 'hex').slice(0, 32)); - formModel.value.amount = ''; + // Field is dirty after submit, so we need to reset it and not just clear the value + resetField(); } return { From 80fd11a49b50c788bab5a93f627d14fda8724cf5 Mon Sep 17 00:00:00 2001 From: Bartosz Date: Fri, 24 May 2024 10:24:20 +0200 Subject: [PATCH 03/55] refactor: apps browser types and composables update --- src/composables/index.ts | 1 + src/popup/pages/AppsBrowser.vue | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/composables/index.ts b/src/composables/index.ts index deac2acbc6..93026e749d 100644 --- a/src/composables/index.ts +++ b/src/composables/index.ts @@ -31,3 +31,4 @@ export * from './scrollTransactions'; export * from './languages'; export * from './permissions'; export * from './auth'; +export * from './appsBrowserHistory'; diff --git a/src/popup/pages/AppsBrowser.vue b/src/popup/pages/AppsBrowser.vue index 16299102ac..3e8f66ffe7 100644 --- a/src/popup/pages/AppsBrowser.vue +++ b/src/popup/pages/AppsBrowser.vue @@ -7,7 +7,7 @@ > @@ -28,7 +28,7 @@ show-message-help :placeholder="$t('pages.appsBrowser.inputPlaceholder')" :message="errorMessage" - @keydown.enter.stop="(event) => handleEnter(event, errorMessage)" + @keydown.enter.stop="(event: any) => handleEnter(event, errorMessage)" > + + diff --git a/src/popup/components/NotificationsIcon.vue b/src/popup/components/NotificationsIcon.vue index 55907fa76e..1373e1fa93 100644 --- a/src/popup/components/NotificationsIcon.vue +++ b/src/popup/components/NotificationsIcon.vue @@ -5,6 +5,7 @@ :icon="BellIcon" :to="{ name: ROUTE_NOTIFICATIONS }" :badge-text="notificationsCount" + dimmed /> diff --git a/src/popup/components/SwapRoute.vue b/src/popup/components/SwapRoute.vue index ca32bf0256..c407eeb7b0 100644 --- a/src/popup/components/SwapRoute.vue +++ b/src/popup/components/SwapRoute.vue @@ -79,15 +79,16 @@ export default defineComponent({ } let { tokens } = resolver(props.transaction, aeTokensAvailable.value); - const index = props.transaction.tx.arguments.findIndex(({ type }) => type === 'list'); + const args = props.transaction.tx.arguments || []; + const index = args.findIndex(({ type }) => type === 'list'); const waeContract = DEX_CONTRACTS[nodeNetworkId.value!]?.wae; const tokenLastIndex = tokens.length - 1; - if (index >= 0 && props.transaction.tx.arguments[index].value.length > tokens.length) { + if (index >= 0 && args[index].value.length > tokens.length) { tokens = [ tokens[0], - ...props.transaction.tx.arguments[index].value - .slice(1, props.transaction.tx.arguments[index].value.length - 1) + ...args[index].value + .slice(1, args[index].value.length - 1) .map((element: any) => aeTokensAvailable.value[element.value]), tokens[1], ]; diff --git a/src/popup/components/TransactionDetailsPoolTokenRow.vue b/src/popup/components/TransactionDetailsPoolTokenRow.vue index cd666c5df3..ff39259b61 100644 --- a/src/popup/components/TransactionDetailsPoolTokenRow.vue +++ b/src/popup/components/TransactionDetailsPoolTokenRow.vue @@ -50,7 +50,8 @@ export default defineComponent({ props: { label: { type: String, default: '' }, token: { type: Object as PropType, required: true }, - tokens: { type: Array as PropType, required: true }, + // TODO having `token` and `tokens` prop is confusing, refactor to one `assets` prop + tokens: { type: Array as PropType, default: null }, hideAmount: Boolean, }, setup(props) { @@ -61,7 +62,7 @@ export default defineComponent({ )); const assetsMapped = computed( - () => (props.token.isPool ? props.tokens : [props.token]) + () => ((props.token.isPool && props.tokens) ? props.tokens : [props.token]) .map((asset) => convertWrappedCoinTokenToCoin(asset)), ); diff --git a/src/popup/components/buttons/BtnIcon.vue b/src/popup/components/buttons/BtnIcon.vue index 5e35a32c43..26e22cd80e 100644 --- a/src/popup/components/buttons/BtnIcon.vue +++ b/src/popup/components/buttons/BtnIcon.vue @@ -32,37 +32,39 @@ - diff --git a/src/popup/components/TransactionOverview.vue b/src/popup/components/TransactionOverview.vue index cfe9d73a5a..a057dd7ebf 100644 --- a/src/popup/components/TransactionOverview.vue +++ b/src/popup/components/TransactionOverview.vue @@ -124,6 +124,7 @@ export default defineComponent({ label: t('transaction.overview.accountAddress'), }, }; + case Tag.ContractCallTx: { const contract: IAccountOverview = { address: contractId, @@ -133,6 +134,21 @@ export default defineComponent({ : t('common.smartContract'), }; + if (protocol.value === PROTOCOLS.ethereum) { + return { + sender: { + address: senderId, + url: protocolExplorer.prepareUrlForAccount(senderId), + label: t('transaction.overview.accountAddress'), + }, + recipient: { + address: recipientId, + url: protocolExplorer.prepareUrlForAccount(recipientId), + label: t('common.smartContract'), + }, + }; + } + let transactionOwner; let transactionReceiver = contract; @@ -159,6 +175,7 @@ export default defineComponent({ : contract, }; } + case Tag.ContractCreateTx: return { sender: ownershipAccount.value, @@ -166,6 +183,7 @@ export default defineComponent({ label: t('transaction.overview.contractCreate'), }, }; + case Tag.NamePreclaimTx: case Tag.NameClaimTx: case Tag.NameUpdateTx: @@ -175,6 +193,7 @@ export default defineComponent({ label: t('transaction.overview.aens'), }, }; + default: throw new Error(`Unsupported transaction type ${outerTxTag.value}`); } diff --git a/src/popup/locales/en.json b/src/popup/locales/en.json index 93bffefaef..2ad393ae8c 100644 --- a/src/popup/locales/en.json +++ b/src/popup/locales/en.json @@ -1,5 +1,6 @@ { "common": { + "activeAccount": "Active account", "address": "Address", "addressCopied": "Copied", "ae": "AE", @@ -15,6 +16,7 @@ "connect": "Connect", "connected": "Connected", "connecting": "Connecting...", + "connectingAs": "Connecting as", "connectionFailed": "Connection failed", "contractId": "Contract ID", "notNow": "Not now", @@ -33,6 +35,7 @@ "minutesShort": "{n} mins | {n} min | {n} mins", "next": "Next", "nonce": "Nonce", + "noProtocolAccountFound": "No {protocol} account found", "of": "of", "ok": "OK", "pending": "Pending", diff --git a/src/protocols/aeternity/views/TransactionDetails.vue b/src/protocols/aeternity/views/TransactionDetails.vue index a187bbf572..fb2a23c503 100644 --- a/src/protocols/aeternity/views/TransactionDetails.vue +++ b/src/protocols/aeternity/views/TransactionDetails.vue @@ -172,6 +172,7 @@ import { } from '@/utils'; import { useAccounts, + useFungibleTokens, useMultisigAccounts, useTransactionData, useTransactionList, @@ -228,6 +229,7 @@ export default defineComponent({ const { activeMultisigAccountId } = useMultisigAccounts({ pollOnce: true }); const { activeAccount, isLocalAccountAddress } = useAccounts(); const { setLoaderVisible } = useUi(); + const { getTxAmountTotal } = useFungibleTokens(); const hash = route.params.hash as string; const transactionOwner = route.params.transactionOwner as Encoded.AccountAddress; @@ -249,8 +251,6 @@ export default defineComponent({ const multisigContractId = ref(); const { - amount, - amountTotal, direction, isAex9, isErrorTransaction, @@ -266,6 +266,12 @@ export default defineComponent({ showDetailedAllowanceInfo: true, }); + const amount = computed((): number => transaction.value + ? getTxAmountTotal(transaction.value, TX_DIRECTION.received) + : 0); + const amountTotal = computed((): number => transaction.value + ? getTxAmountTotal(transaction.value, direction.value) + : 0); const tipUrl = computed(() => transaction.value ? getTransactionTipUrl(transaction.value) : ''); const tipLink = computed(() => /^http[s]*:\/\//.test(tipUrl.value) ? tipUrl.value : `http://${tipUrl.value}`); diff --git a/src/protocols/bitcoin/helpers/index.ts b/src/protocols/bitcoin/helpers/index.ts index f3088231c7..0c433702d7 100644 --- a/src/protocols/bitcoin/helpers/index.ts +++ b/src/protocols/bitcoin/helpers/index.ts @@ -1,3 +1,4 @@ +import BigNumber from 'bignumber.js'; import type { ITransaction } from '@/types'; import { PROTOCOLS } from '@/constants'; import { BTC_COIN_PRECISION, BTC_CONTRACT_ID } from '../config'; @@ -6,6 +7,15 @@ export function satoshiToBtc(amount: number) { return amount / 10 ** BTC_COIN_PRECISION; } +// TODO Duplicate in fungibleTokens.ts composable +export function getTxAmountTotal(transaction: ITransaction, isReceived: boolean): number { + return new BigNumber( + transaction.tx?.amount || 0, + ) + .plus(isReceived ? 0 : transaction.tx?.fee || 0) + .toNumber(); +} + export function normalizeTransactionStructure( transaction: any, transactionOwner?: string, diff --git a/src/protocols/bitcoin/views/TransactionDetails.vue b/src/protocols/bitcoin/views/TransactionDetails.vue index ee204d1576..3d2ea531da 100644 --- a/src/protocols/bitcoin/views/TransactionDetails.vue +++ b/src/protocols/bitcoin/views/TransactionDetails.vue @@ -14,8 +14,8 @@ > @@ -46,12 +53,19 @@ + diff --git a/src/popup/components/TransferQRCodeGenerator.vue b/src/popup/components/TransferQRCodeGenerator.vue new file mode 100644 index 0000000000..fd9204dbe9 --- /dev/null +++ b/src/popup/components/TransferQRCodeGenerator.vue @@ -0,0 +1,94 @@ + + + + + diff --git a/src/popup/components/TransferRawTxReview.vue b/src/popup/components/TransferRawTxReview.vue new file mode 100644 index 0000000000..4eaa94577a --- /dev/null +++ b/src/popup/components/TransferRawTxReview.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/src/popup/components/TransferSend/TransferReviewBase.vue b/src/popup/components/TransferSend/TransferReviewBase.vue index f0283bcc56..d0afa45972 100644 --- a/src/popup/components/TransferSend/TransferReviewBase.vue +++ b/src/popup/components/TransferSend/TransferReviewBase.vue @@ -2,7 +2,7 @@
@@ -114,6 +114,7 @@ export default defineComponent({ }, props: { title: { type: String, default: tg('pages.send.reviewtx') }, + subtitle: { type: String, default: tg('pages.send.checkalert') }, senderLabel: { type: String, default: tg('pages.send.sender') }, amountLabel: { type: String, default: tg('common.amount') }, baseTokenSymbol: { type: String, required: true }, diff --git a/src/popup/locales/en.json b/src/popup/locales/en.json index a2b5ab5b02..ca16ee96b2 100644 --- a/src/popup/locales/en.json +++ b/src/popup/locales/en.json @@ -247,8 +247,7 @@ "btnText": "Pair QR Wallet", "btnSubtitle": "Connect QR-based Hardware Wallet", "scanTitle": "Scan QR code", - "scanDescription": "from your AirGap vault", - + "scanDescription": "Scan QR code from your AirGap vault in order to pair wallets and import accounts.", "importConfirmDialog": { "title": "Select accounts to import from AirGap", "selectAll": "Select all", @@ -257,6 +256,15 @@ "noAccountsFound": "There are no accounts found." } }, + "scanAirGapTx": { + "heading": "Scan QR code", + "title": "Scan the QR code of the signed transaction from your AirGap vault in order to send it.", + + "help": { + "title": "Sign AirGap transaction", + "msg": "In order to sign an AirGap transaction and send it from Superhero wallet you need to follow 3 simple steps:

  1. Review carefully transaction details and scan the QR code generated by Superhero wallet with your AirGap vault.
  2. Sign the transaction in your AirGap vault. Another QR code will be generated by AirGap vault.
  3. Scan the QR code from your AirGap vault with Superhero wallet and confirm sending the transaction.
" + } + }, "removeAccount": { "title": "Are you sure you want to remove this account?", "msg": "This action will remove your account from the wallet and will delete the extension storage. Make sure you have backed up your seed phrase before proceeding. This action cannot be undone!" @@ -405,6 +413,11 @@ "proposeAndApprove": "Propose and approve", "tokenWarning": "Multisig transactions currently support AE coin only." }, + "airGapSend": { + "sendTitle": "Send funds with AirGap", + "reviewTitle": "Review and sign transaction", + "reviewSubTitle": "Scan QR-code with your AirGap vault in order to sign the transaction" + }, "wrongNetwork": { "title": "Network discrepancy", "msg": "This action was initiated on a different network. Please switch to {0} in your wallet settings to proceed.", diff --git a/src/popup/pages/Assets/AssetDetails.vue b/src/popup/pages/Assets/AssetDetails.vue index 9016646417..93fb09aae6 100644 --- a/src/popup/pages/Assets/AssetDetails.vue +++ b/src/popup/pages/Assets/AssetDetails.vue @@ -31,6 +31,7 @@ !!route?.meta?.isMultisig); const { isNodeMainnet, isNodeTestnet, getAeSdk } = useAeSdk(); - const { activeAccount, getLastActiveProtocolAccount } = useAccounts(); + const { activeAccount, getLastActiveProtocolAccount, isAirGap } = useAccounts(); const { protocolCoinBalance } = useAccountAssetsList({ isMultisig: isMultisig.value, }); @@ -403,6 +404,7 @@ export default defineComponent({ stickyTabsWrapperEl, fungibleToken, isAeCoin, + isAirGap, isCoin, isNodeMainnet, isNodeTestnet, diff --git a/src/popup/pages/Dashboard.vue b/src/popup/pages/Dashboard.vue index e8559b5125..9396c92ef2 100644 --- a/src/popup/pages/Dashboard.vue +++ b/src/popup/pages/Dashboard.vue @@ -29,7 +29,7 @@