diff --git a/LICENSE b/LICENSE index 9dffd65e4..53014963e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ ISC License -Copyright (c) 2019, SuperHero +Copyright (c) 2019, Superhero Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/README.md b/README.md index 22b1f3f19..3ef9236f5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Superhero Wallet -**SuperHero is a browser extension that allows you to send and recieve value to URLs and content accross Internet.** +**Superhero is a browser extension that allows you to send and recieve value to URLs and content accross Internet.** [![Build Status](https://travis-ci.com/aeternity/superhero-wallet.svg?branch=develop)](https://travis-ci.com/aeternity/superhero-wallet) diff --git a/config.xml b/config.xml index b72d27e7c..5e9cb0947 100644 --- a/config.xml +++ b/config.xml @@ -1,9 +1,9 @@ - - SuperHero - SuperHero wallet + + Superhero + Superhero wallet - SuperHero + Superhero diff --git a/package-lock.json b/package-lock.json index 431d942a7..51bec9b4d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "superhero-wallet", - "version": "0.0.21", + "version": "0.0.22", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -19857,6 +19857,11 @@ "builtins": "^1.0.3" } }, + "validator": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.0.0.tgz", + "integrity": "sha512-anYx5fURbgF04lQV18nEQWZ/3wHGnxiKdG4aL8J+jEDsm98n/sU/bey+tYk6tnGJzm7ioh5FoqrAiQ6m03IgaA==" + }, "varuint-bitcoin": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-1.1.2.tgz", diff --git a/package.json b/package.json index a4afda497..393c0fc66 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "superhero-wallet", - "version": "0.0.21", + "version": "0.0.22", "description": "Superhero wallet", - "author": "SuperHero", + "author": "Superhero", "license": "MIT", "private": true, "scripts": { @@ -59,7 +59,7 @@ "cordova-plugin-statusbar": "^2.4.3", "cordova-plugin-wkwebview-engine": "github:mwchambers/cordova-plugin-wkwebview-engine#da67d6bb6ce8597c38fc69e66b84566e34efea8d", "crypto-browserify": "^3.12.0", - "detect-browser": "^4.7.0", + "detect-browser": "^4.8.0", "emailjs-com": "^2.4.0", "extensionizer": "^1.0.1", "file-saver": "^2.0.2", @@ -74,6 +74,7 @@ "rxjs-etc": "^9.7.4", "tweetnacl": "^1.0.3", "uuid": "^3.3.3", + "validator": "^13.0.0", "vue": "^2.6.10", "vue-awesome": "^3.5.4", "vue-clipboard2": "^0.3.1", diff --git a/src/background.js b/src/background.js index 4e7d857f8..ba460ef01 100644 --- a/src/background.js +++ b/src/background.js @@ -1,83 +1,74 @@ -import { setInterval } from 'timers'; +import uid from 'uuid'; +import { setController, switchNode } from './lib/background-utils'; import './lib/initPolyfills'; -import { phishingCheckUrl, getPhishingUrls, setPhishingUrl } from './popup/utils/phishing-detect'; -import { detectConnectionType } from './popup/utils/helper'; -import { buildTx } from './popup/utils'; -import WalletController from './wallet-controller'; -import Notification from './notifications'; +import { PopupConnections } from './lib/popup-connection'; +import RedirectChainNames from './lib/redirect-chain-names'; import rpcWallet from './lib/rpcWallet'; +import TipClaimRelay from './lib/tip-claim-relay'; +import Notification from './notifications'; +import { buildTx } from './popup/utils'; +import { popupProps } from './popup/utils/config'; import { - HDWALLET_METHODS, AEX2_METHODS, - NOTIFICATION_METHODS, CONNECTION_TYPES, DEFAULT_NETWORK, + HDWALLET_METHODS, + NOTIFICATION_METHODS, } from './popup/utils/constants'; -import { popupProps } from './popup/utils/config'; -import TipClaimRelay from './lib/tip-claim-relay'; -import RedirectChainNames from './lib/redirect-chain-names'; -import { setController, switchNode } from './lib/background-utils'; -import { PopupConnections } from './lib/popup-connection'; +import { detectConnectionType } from './popup/utils/helper'; +import { getPhishingUrls, phishingCheckUrl, setPhishingUrl } from './popup/utils/phishing-detect'; +import WalletController from './wallet-controller'; +import Logger from './lib/logger'; const controller = new WalletController(); if (process.env.IS_EXTENSION && require.main.i === module.id) { + Logger.init({ background: true }); RedirectChainNames.init(); - setInterval(() => { - browser.windows.getAll({}).then(wins => { - if (wins.length === 0) { - sessionStorage.removeItem('phishing_urls'); - } - }); - }, 5000); const notification = new Notification(); setController(controller); const postPhishingData = async data => { const tabs = await browser.tabs.query({ active: true, currentWindow: true }); - const message = { method: 'phishingCheck', data }; + const message = { method: 'phishingCheck', ...data }; tabs.forEach(({ id }) => browser.tabs.sendMessage(id, message)); }; browser.runtime.onMessage.addListener(async (msg, sender) => { - switch (msg.method) { - case 'phishingCheck': { - const data = { ...msg, extUrl: browser.extension.getURL('./') }; - const host = new URL(msg.params.href).hostname; - data.host = host; - const { result } = await phishingCheckUrl(host); - if (result === 'blocked') { - const whitelist = getPhishingUrls().filter(url => url === host); - if (whitelist.length) { - data.blocked = false; - return postPhishingData(data); - } - data.blocked = true; - return postPhishingData(data); - } - data.blocked = false; - return postPhishingData(data); - } - case 'setPhishingUrl': { - const urls = getPhishingUrls(); - urls.push(msg.params.hostname); - setPhishingUrl(urls); - break; + const { method, params, from, type, data } = msg; + if (method === 'phishingCheck') { + const host = new URL(params.href).hostname; + let blocked = false; + const { result } = await phishingCheckUrl(host); + if (result === 'blocked') { + const whitelist = getPhishingUrls().filter(url => url === host); + blocked = !whitelist.length; } - default: - break; + return postPhishingData({ + ...msg, + data: { + method, + extUrl: browser.extension.getURL('./'), + host, + href: params.href, + blocked, + }, + }); + } + + if (method === 'setPhishingUrl') { + const urls = getPhishingUrls(); + urls.push(params.hostname); + setPhishingUrl(urls); + return true; } - if ( - msg.from === 'content' && - msg.type === 'readDom' && - (msg.data.address || msg.data.chainName) - ) { + if (from === 'content' && type === 'readDom' && (data.address || data.chainName)) { const tabs = await browser.tabs.query({ active: true, currentWindow: true }); tabs.forEach(({ url }) => { if (sender.url === url && DEFAULT_NETWORK === 'Mainnet') { - TipClaimRelay.checkUrlHasBalance(url, msg.data); + TipClaimRelay.checkUrlHasBalance(url, data); } }); } @@ -109,15 +100,39 @@ if (process.env.IS_EXTENSION && require.main.i === module.id) { popupConnections.addConnection(id, port); } else if (connectionType === CONNECTION_TYPES.OTHER) { - const check = rpcWallet.sdkReady(() => { + // eslint-disable-next-line no-param-reassign + port.uuid = uid(); + if (rpcWallet.sdkReady()) { rpcWallet.addConnection(port); - }); + } else { + rpcWallet.addConnectionToQueue(port); + } port.onDisconnect.addListener(() => { - clearInterval(check); + rpcWallet.removeConnectionFromQueue(port); }); } } }); + + const contextMenuItem = { + id: 'superheroTip', + title: 'Tip', + }; + + browser.contextMenus.removeAll(); + browser.contextMenus.create(contextMenuItem); + browser.contextMenus.onClicked.addListener(({ menuItemId, pageUrl }) => { + if (menuItemId === 'superheroTip') { + const url = `/tip?url=${pageUrl}`; + localStorage.setItem('tipUrl', url); + browser.windows.create({ + url: `popup/popup.html#${url}`, + type: 'popup', + height: 600, + width: 375, + }); + } + }); } // eslint-disable-next-line import/prefer-default-export diff --git a/src/common/extension.scss b/src/common/extension.scss index 32b544fc7..cacb92393 100644 --- a/src/common/extension.scss +++ b/src/common/extension.scss @@ -73,7 +73,7 @@ a { border-color: $nav-border-color !important; } .error-msg { - color: $secondary-color !important; + color: $input-error-color !important; margin-top:22px; font-size: .88rem; } diff --git a/src/common/variables.scss b/src/common/variables.scss index 3715cd47c..6d5d20bc8 100644 --- a/src/common/variables.scss +++ b/src/common/variables.scss @@ -15,10 +15,10 @@ $ledger-color: #203040; /** Colors for new designs */ -$bg-color: #16161d; +$bg-color: #12121B; $white-color: #f1f1f1; -$border-color: #34343b; -$input-bg-color: #121217; +$border-color: #33343E; +$input-bg-color: #0D0D13; $button-color: #2a9cff; $button-text-color: #ffffff; $modal-background: #1b1b23; @@ -26,7 +26,7 @@ $placeholder-color: #67676d; $text-color: #bcbcc4; $accent-color: #67f7b8; $secondary-color: #2a9cff; -$nav-bg-color: #21212a; +$nav-bg-color: #1C1C24; $input-focus-color: #2a9cff; $input-error-color: #ff5857; $transactions-bg: #12121b; diff --git a/src/icons/badges/blacklisted-big.svg b/src/icons/badges/blacklisted-big.svg new file mode 100644 index 000000000..785695ab0 --- /dev/null +++ b/src/icons/badges/blacklisted-big.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/icons/badges/blacklisted.svg b/src/icons/badges/blacklisted.svg new file mode 100644 index 000000000..f4d7502e3 --- /dev/null +++ b/src/icons/badges/blacklisted.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/icons/badges/default.svg b/src/icons/badges/default.svg new file mode 100644 index 000000000..01df221cf --- /dev/null +++ b/src/icons/badges/default.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/icons/badges/not-verified-big.svg b/src/icons/badges/not-verified-big.svg new file mode 100644 index 000000000..829698533 --- /dev/null +++ b/src/icons/badges/not-verified-big.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/icons/badges/not-verified.svg b/src/icons/badges/not-verified.svg new file mode 100644 index 000000000..fa9442494 --- /dev/null +++ b/src/icons/badges/not-verified.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/icons/badges/verified-big.svg b/src/icons/badges/verified-big.svg new file mode 100644 index 000000000..24d2c9148 --- /dev/null +++ b/src/icons/badges/verified-big.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/icons/badges/verified.svg b/src/icons/badges/verified.svg new file mode 100644 index 000000000..e01f3e4ee --- /dev/null +++ b/src/icons/badges/verified.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/inject.js b/src/inject.js index 7caf0e7f3..bdb90f130 100644 --- a/src/inject.js +++ b/src/inject.js @@ -94,10 +94,9 @@ window.addEventListener('load', () => { // Handle message from background and redirect to page browser.runtime.onMessage.addListener(({ data }) => { - const { method, blocked, params, extUrl, host, uuid } = data; - + const { method, blocked, extUrl, host, uuid, href } = data; if (method === 'phishingCheck' && blocked) { - redirectToWarning(host, params.href, extUrl); + redirectToWarning(host, href, extUrl); } else if (method === 'getAddresses') { browser.runtime.sendMessage({ uuid, data: { ...getAddresses() } }); } diff --git a/src/lib/background-utils.js b/src/lib/background-utils.js index 43eb83d3e..c52645dd3 100644 --- a/src/lib/background-utils.js +++ b/src/lib/background-utils.js @@ -8,6 +8,7 @@ import { getActiveNetwork, } from '../popup/utils/helper'; import { getState } from '../store/plugins/persistState'; +import Logger from './logger'; let sdk; let controller; @@ -60,7 +61,7 @@ export const getSDK = async () => { compilerUrl: network.compilerUrl, }); } catch (e) { - console.error(`getSDK: ${e}`); + Logger.write(e); } } @@ -95,30 +96,22 @@ export const getTippingContractAddress = async address => { return tippingContractAddress; }; -export const contractCallStatic = async ({ tx, callType }) => - new Promise(async (resolve, reject) => { - try { - const { account } = await getActiveAccount(); - if (typeof callType !== 'undefined' && callType === 'static' && account) { - const contractInstance = await getTippingContractInstance(tx); - const call = await contractCall({ - instance: contractInstance, - method: tx.method, - params: [...tx.params, tx.options], - }); - if (call) { - resolve(call); - } else { - reject(new Error('Contract call failed')); - } - } else if ( - !controller.isLoggedIn() && - typeof callType !== 'undefined' && - callType === 'static' - ) { - reject(new Error('You need to unlock the wallet first')); - } - } catch (e) { - reject(e); - } - }); +export const contractCallStatic = async ({ tx, callType }) => { + const { account } = await getActiveAccount(); + if (typeof callType !== 'undefined' && callType === 'static' && account) { + const contractInstance = await getTippingContractInstance(tx); + const call = await contractCall({ + instance: contractInstance, + method: tx.method, + params: [...tx.params, tx.options], + }); + if (call) return call; + const error = new Error('Contract call failed'); + error.payload = { tx }; + throw error; + } + if (!controller.isLoggedIn() && typeof callType !== 'undefined' && callType === 'static') { + throw new Error('You need to unlock the wallet first'); + } + throw new Error('No data to return'); +}; diff --git a/src/lib/logger.js b/src/lib/logger.js new file mode 100644 index 000000000..7b0fdcab2 --- /dev/null +++ b/src/lib/logger.js @@ -0,0 +1,72 @@ +import { pick } from 'lodash-es'; +import Vue from 'vue'; +import { detect } from 'detect-browser'; +import { getState } from '../store/plugins/persistState'; + +export default class Logger { + static init(options = {}) { + const { background } = options; + if (!background) { + Vue.config.errorHandler = (error, vm, info) => { + console.error(info); + console.error(error); + Object.assign(error, { info, type: 'vue-error' }); + Logger.write(error); + }; + + Vue.config.warnHandler = (message, vm, info) => { + console.error(message); + console.error(info); + Logger.write({ + message, + stack: info, + type: 'vue-warn', + }); + }; + } + + window.addEventListener('unhandledrejection', promise => { + const { stack, message } = promise.reason; + Logger.write({ + message, + stack, + type: 'unhandledrejection', + }); + }); + + window.onerror = (message, source, line, col, error) => { + Logger.write({ + message, + stack: `${source} ${line}:${col}`, + type: 'window-error', + info: error, + }); + }; + } + + static async write(error) { + const { saveErrorLog } = await getState(); + if (!saveErrorLog) return; + const errorLog = await Logger.get(); + const logEntry = { + ...pick(error, ['name', ...Object.getOwnPropertyNames(error)]), + appVersion: process.env.npm_package_version, + browser: detect(), + platform: process.env.PLATFORM, + time: Date.now(), + }; + browser.storage.local.set({ errorLog: [...errorLog, logEntry] }); + } + + static async get() { + const { errorLog = [] } = await browser.storage.local.get('errorLog'); + return errorLog; + } + + static async sendLog() { + const errorLog = await Logger.get(); + if (errorLog) { + // TODO: make call to backend here + } + } +} diff --git a/src/lib/redirect-chain-names.js b/src/lib/redirect-chain-names.js index a7f308dc4..5cacb8f35 100644 --- a/src/lib/redirect-chain-names.js +++ b/src/lib/redirect-chain-names.js @@ -10,7 +10,7 @@ export default { }, setListener() { browser.webRequest.onBeforeRequest.addListener( - async requestDetails => { + requestDetails => { const url = new URL(requestDetails.url); const params = url.searchParams .get('q') @@ -20,10 +20,7 @@ export default { if (!q.hostname || !this.supportedDomain(q.hostname) || url.pathname !== '/search') { return {}; } - - chrome.tabs.update({ url: q.toString() }); - - return { cancel: true }; + return { redirectUrl: q.toString() }; }, { urls: ['*://*.google.com/*'], diff --git a/src/lib/rpcWallet.js b/src/lib/rpcWallet.js index 06f169764..471047a09 100644 --- a/src/lib/rpcWallet.js +++ b/src/lib/rpcWallet.js @@ -1,30 +1,29 @@ import MemoryAccount from '@aeternity/aepp-sdk/es/account/memory'; import { RpcWallet } from '@aeternity/aepp-sdk/es/ae/wallet'; -import BrowserRuntimeConnection from '@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/connection/browser-runtime'; import Node from '@aeternity/aepp-sdk/es/node'; -import { setInterval, clearInterval } from 'timers'; -import uuid from 'uuid'; +import BrowserRuntimeConnection from '@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/connection/browser-runtime'; import { isEmpty } from 'lodash-es'; +import uuid from 'uuid'; +import { mockLogin } from '../popup/utils'; import { - parseFromStorage, + AEX2_METHODS, + BLACKLIST_AEPPS, + DEFAULT_NETWORK, + MAX_AMOUNT_WITHOUT_CONFIRM, + NO_POPUP_AEPPS, +} from '../popup/utils/constants'; +import { + addTipAmount, extractHostName, - getAeppAccountPermission, getActiveNetwork, - stringifyForStorage, - addTipAmount, + getAddressByNameEntry, + getAeppAccountPermission, + getContractCallInfo, getTippedAmount, + parseFromStorage, resetTippedAmount, - getContractCallInfo, - getAddressByNameEntry, + stringifyForStorage, } from '../popup/utils/helper'; -import { - DEFAULT_NETWORK, - AEX2_METHODS, - NO_POPUP_AEPPS, - BLACKLIST_AEPPS, - MAX_AMOUNT_WITHOUT_CONFIRM, -} from '../popup/utils/constants'; -import { mockLogin } from '../popup/utils'; import { getState } from '../store/plugins/persistState'; global.browser = require('webextension-polyfill'); @@ -60,6 +59,7 @@ const rpcWallet = { this.subaccounts = null; this.accounts = []; this.accountKeyPairs = []; + this.connectionsQueue = []; }, initNetwork(network = DEFAULT_NETWORK) { this.network = network; @@ -90,7 +90,7 @@ const rpcWallet = { this.sdk = await RpcWallet({ nodes: [{ name: this.network, instance: node }], compilerUrl: this.compiler, - name: 'SuperHero', + name: 'Superhero', accounts: this.accounts, async onConnection(aepp, action) { context.shouldOpenPopup(aepp, action, () => { @@ -142,6 +142,7 @@ const rpcWallet = { 'contract_pubkey', ) : this.tipContractAddress; + this.connectionsQueue.forEach(c => this.addConnection(c)); } catch (e) { this.sdk = null; } @@ -181,14 +182,14 @@ const rpcWallet = { cb(); } }, - sdkReady(cb) { - const check = setInterval(() => { - if (this.sdk) { - cb(); - clearInterval(check); - } - }, 1000); - return check; + sdkReady() { + return this.sdk; + }, + addConnectionToQueue(port) { + this.connectionsQueue.push(port); + }, + removeConnectionFromQueue(port) { + this.connectionsQueue = this.connectionsQueue.filter(p => p.uuid !== port.uuid); }, async checkAeppPermissions(aepp, action, caller, cb) { const { @@ -201,15 +202,16 @@ const rpcWallet = { const isConnected = await getAeppAccountPermission(extractHostName(url), this.activeAccount); if (!isConnected) { try { - const a = caller === 'connection' ? action : {}; - await this.showPopup({ action: a, aepp, type: 'connectConfirm' }); - if (typeof cb !== 'undefined') { - cb(); - } + await this.showPopup({ + action: caller === 'connection' ? action : {}, + aepp, + type: 'connectConfirm', + }); + if (cb) cb(); } catch (e) { console.error(`checkAeppPermissions: ${e}`); } - } else if (typeof cb === 'undefined') { + } else if (!cb) { action.accept(); } else { cb(); @@ -256,13 +258,18 @@ const rpcWallet = { }, async addConnection(port) { - const connection = await BrowserRuntimeConnection({ - connectionInfo: { id: port.sender.frameId }, - port, - }); - this.sdk.addRpcClient(connection); - this.sdk.shareWalletInfo(port.postMessage.bind(port)); + try { + const connection = await BrowserRuntimeConnection({ + connectionInfo: { id: port.sender.frameId }, + port, + }); + this.sdk.addRpcClient(connection); + this.sdk.shareWalletInfo(port.postMessage.bind(port)); + } catch (e) { + console.warn(e); + } setTimeout(() => this.sdk.shareWalletInfo(port.postMessage.bind(port)), 3000); + this.removeConnectionFromQueue(port); }, getClientsByCond(condition) { const clients = Array.from(this.sdk.getClients().clients.values()).filter(condition); diff --git a/src/lib/tip-claim-relay.js b/src/lib/tip-claim-relay.js index d87f2d45a..43c1a2251 100644 --- a/src/lib/tip-claim-relay.js +++ b/src/lib/tip-claim-relay.js @@ -1,12 +1,13 @@ import axios from 'axios'; import { uniq } from 'lodash-es'; +import { DEFAULT_NETWORK, networks, TIPPING_CONTRACT, TIP_SERVICE } from '../popup/utils/constants'; import { contractCallStatic, getActiveAccount, getAddressFromChainName, getTippingContractAddress, } from './background-utils'; -import { networks, DEFAULT_NETWORK, TIPPING_CONTRACT, TIP_SERVICE } from '../popup/utils/constants'; +import Logger from './logger'; export default { checkAddressMatch(account, addresses) { @@ -25,8 +26,11 @@ export default { const claimAmount = await contractCallStatic({ tx, callType: 'static' }) .then(r => r.decodedResult) - .catch(() => 1); - if (claimAmount === 0) throw new Error('No zero amount claims'); + .catch(error => { + Logger.write(error); + return 1; + }); + if (claimAmount === 0) throw new Error('No new tips to claim'); }, async checkUrlHasBalance(url, { address, chainName }) { @@ -48,7 +52,8 @@ export default { } } } catch (e) { - console.error(`checkUrlHasBalance: ${e}`); + e.payload = { url }; + Logger.write(e); } }, }; diff --git a/src/lib/wallet.js b/src/lib/wallet.js index a63ed1c49..3b59638dd 100644 --- a/src/lib/wallet.js +++ b/src/lib/wallet.js @@ -6,6 +6,7 @@ import store from '../store'; import { postMessage } from '../popup/utils/connection'; import { parseFromStorage, middleware, getAllNetworks } from '../popup/utils/helper'; import { TIPPING_CONTRACT } from '../popup/utils/constants'; +import Logger from './logger'; export default { countError: 0, @@ -31,6 +32,7 @@ export default { async initMiddleware() { const { network, current } = store.getters; store.commit('SET_MIDDLEWARE', (await middleware(network, current)).api); + store.dispatch('getRegisteredNames'); }, async initSdk() { const keypair = await this.getKeyPair(); @@ -58,10 +60,13 @@ export default { await this.initMiddleware(); store.commit('SET_NODE_STATUS', 'connected'); setTimeout(() => store.commit('SET_NODE_STATUS', ''), 2000); - } catch (error) { + } catch (e) { this.countError += 1; if (this.countError < 3) await this.initSdk(); - else store.commit('SET_NODE_STATUS', 'error'); + else { + store.commit('SET_NODE_STATUS', 'error'); + Logger.write(e); + } } }, async logout() { @@ -77,17 +82,13 @@ export default { return res.error ? { error: true } : parseFromStorage(res); }, async initContractInstances() { - try { - const contractAddress = await store.dispatch('getTipContractAddress'); - store.commit( - 'SET_TIPPING', - await store.getters.sdk.getContractInstance(TIPPING_CONTRACT, { - contractAddress, - forceCodeCheck: true, - }), - ); - } catch (e) { - console.error(`Error creating tipping instance: ${e}`); - } + const contractAddress = await store.dispatch('getTipContractAddress'); + store.commit( + 'SET_TIPPING', + await store.getters.sdk.getContractInstance(TIPPING_CONTRACT, { + contractAddress, + forceCodeCheck: true, + }), + ); }, }; diff --git a/src/manifest.js b/src/manifest.js index 88c1b4138..ab5702a9e 100644 --- a/src/manifest.js +++ b/src/manifest.js @@ -1,9 +1,9 @@ -module.exports = (isProd, browser) => ({ - name: 'SuperHero', - description: 'SuperHero Wallet', +module.exports = (isProd, platform) => ({ + name: 'Superhero', + description: 'Superhero Wallet', version: process.env.npm_package_version, manifest_version: 2, - ...(browser === 'firefox' && { + ...(platform === 'extension-firefox' && { applications: { gecko: { strict_min_version: '53.0', @@ -16,6 +16,7 @@ module.exports = (isProd, browser) => ({ 'videoCapture', 'activeTab', 'clipboardWrite', + 'contextMenus', 'notifications', 'tabs', 'webRequest', @@ -29,7 +30,7 @@ module.exports = (isProd, browser) => ({ }, content_security_policy: `script-src 'self'${isProd ? '' : " 'unsafe-eval'"}; object-src 'self'`, browser_action: { - default_title: 'SuperHero', + default_title: 'Superhero', default_popup: 'popup/popup.html', }, background: { @@ -43,7 +44,7 @@ module.exports = (isProd, browser) => ({ content_scripts: [ { run_at: 'document_start', - all_frames: !isProd && browser === 'chrome', + all_frames: !isProd && platform === 'extension-chrome', matches: ['https://*/*', 'http://*/*'], js: ['other/inject.js'], }, diff --git a/src/notifications.js b/src/notifications.js index b00441bdb..3724c65ec 100644 --- a/src/notifications.js +++ b/src/notifications.js @@ -1,4 +1,3 @@ -import { setInterval } from 'timers'; import iconUrl from './icons/icon_48.png'; import { getSDK, getNodes } from './lib/background-utils'; import { NOTIFICATION_METHODS } from './popup/utils/constants'; @@ -42,9 +41,6 @@ export default class Notification { async init() { this.client = await getSDK(); this.network = (await getNodes()).network; - setInterval(() => { - this.checkTxReady(); - }, 2000); browser.notifications.onButtonClicked.addListener(id => { browser.tabs.create({ url: id.split('?')[1], active: true }); }); diff --git a/src/options/App.vue b/src/options/App.vue index 1bae3068b..5936a9cf9 100644 --- a/src/options/App.vue +++ b/src/options/App.vue @@ -1,6 +1,6 @@ diff --git a/src/options/options.html b/src/options/options.html index b0a93a969..7f287e9fe 100644 --- a/src/options/options.html +++ b/src/options/options.html @@ -2,7 +2,7 @@ - SuperHero - Options + Superhero - Options diff --git a/src/phishing/App.vue b/src/phishing/App.vue index 7c63a3de8..9ffc7b576 100644 --- a/src/phishing/App.vue +++ b/src/phishing/App.vue @@ -2,19 +2,19 @@
- SuperHero logo -

SuperHero Phishing Detection

+ Superhero logo +

Superhero Phishing Detection

- This domain is currently on the SuperHero domain warning list. This means that based on - information available to us, SuperHero believes this domain could currently compromise - your security and, as an added safety feature, SuperHero has restricted access to the + This domain is currently on the Superhero domain warning list. This means that based on + information available to us, Superhero believes this domain could currently compromise + your security and, as an added safety feature, Superhero has restricted access to the site. To override this, please read the rest of this warning for instructions on how to continue at your own risk.

There are many reasons sites can appear on our warning list, and our warning list compiles from other widely used industry lists. Such reasons can include known fraud or security - risks, such as domains that test positive on the SuperHero Phishing Detector. + risks, such as domains that test positive on the Superhero Phishing Detector. Domains on these warning lists may include outright malicious websites and legitimate websites that have been compromised by a malicious actor.

diff --git a/src/phishing/phishing.html b/src/phishing/phishing.html index 7fa014338..271e5eed0 100644 --- a/src/phishing/phishing.html +++ b/src/phishing/phishing.html @@ -2,7 +2,7 @@ - SuperHero Phishing Detection + Superhero Phishing Detection diff --git a/src/popup/App.vue b/src/popup/App.vue index 43a1977d1..741c4ceee 100644 --- a/src/popup/App.vue +++ b/src/popup/App.vue @@ -28,7 +28,7 @@ diff --git a/src/popup/router/components/Header.vue b/src/popup/router/components/Header.vue index d1c29ec03..7df990e4d 100644 --- a/src/popup/router/components/Header.vue +++ b/src/popup/router/components/Header.vue @@ -5,8 +5,8 @@
- {{ $t(`pages.titles.${title}`) }} - {{ $t('pages.titles.home') }} + {{ $t(`pages.titles.${title}`) }} + {{ $t('pages.titles.home') }}
@@ -37,9 +37,6 @@ import Logo from '../../../icons/logo-small.svg?vue-component'; export default { components: { Arrow, Bell, Hamburger, Logo }, - data() { - return {}; - }, computed: { ...mapGetters(['isLoggedIn', 'aeppPopup', 'notifications', 'notificationsCounter']), ...mapState(['tourRunning']), @@ -63,7 +60,6 @@ export default { .header { padding-top: env(safe-area-inset-top); background-color: $nav-bg-color; - border-bottom: 3px solid $nav-border-color; position: fixed; top: 0; left: 0; diff --git a/src/popup/router/components/Input.vue b/src/popup/router/components/Input.vue index 3e1840338..34565382f 100644 --- a/src/popup/router/components/Input.vue +++ b/src/popup/router/components/Input.vue @@ -1,13 +1,13 @@ @@ -52,23 +48,20 @@ export default { this.$once('hook:beforeDestroy', () => clearInterval(this.polling)); }, computed: { - ...mapGetters(['transactions', 'account', 'sdk', 'current', 'currentCurrency']), + ...mapGetters(['transactions']), ...mapState(['tourStartBar']), }, - allTransactions() { - this.$router.push('/transactions'); - }, methods: { async updateTransactions() { - const transactions = await this.$store.dispatch('fetchTransactions', { limit: 3, page: 1 }); + this.$store.dispatch( + 'updateLatestTransactions', + await this.$store.dispatch('fetchTransactions', { + limit: 3, + page: 1, + recent: true, + }), + ); this.loading = false; - this.$store.dispatch('updateLatestTransactions', transactions); - }, - getKeyByValue(object, value) { - return Object.keys(object).find(key => object[key] === value); - }, - allTransactions() { - this.$router.push('/transactions'); }, }, }; @@ -76,27 +69,34 @@ export default { diff --git a/src/popup/router/components/Tour.vue b/src/popup/router/components/Tour.vue index 7368ca757..61fb4499c 100644 --- a/src/popup/router/components/Tour.vue +++ b/src/popup/router/components/Tour.vue @@ -284,7 +284,7 @@ export default { } &.tip-step[x-placement^='bottom'] { - margin-top: 2.5rem !important; + margin-top: 1rem !important; } } @@ -314,7 +314,7 @@ export default { background: $tour-bg-color; padding: 19px; padding-top: 0; - padding-bottom: 25px; + padding-bottom: 15px; pointer-events: all; &.not-started { @@ -323,7 +323,7 @@ export default { &:before { position: absolute; - top: -90px; + top: -80px; height: 100%; left: 0; right: 0; @@ -412,5 +412,15 @@ export default { .tour-actions:after { top: -30px; } + + .v-step { + &[x-placement^='top'] .v-step__arrow { + bottom: -0.7rem !important; + } + + &[x-placement^='bottom'] .v-step__arrow { + top: -0.7rem !important; + } + } } diff --git a/src/popup/router/components/TransactionFilters.vue b/src/popup/router/components/TransactionFilters.vue index 5e5958473..b198fb59c 100644 --- a/src/popup/router/components/TransactionFilters.vue +++ b/src/popup/router/components/TransactionFilters.vue @@ -36,7 +36,7 @@ export default { }; }, computed: { - ...mapGetters(['account', 'popup', 'sdk', 'current', 'transactions']), + ...mapGetters(['account', 'sdk', 'current', 'transactions']), }, methods: { filtrateTx(type, deteType) { diff --git a/src/popup/router/components/TransactionItem.vue b/src/popup/router/components/TransactionItem.vue index 160d80869..9e9ca9126 100644 --- a/src/popup/router/components/TransactionItem.vue +++ b/src/popup/router/components/TransactionItem.vue @@ -1,25 +1,32 @@ - - diff --git a/src/popup/router/components/UrlStatus.vue b/src/popup/router/components/UrlStatus.vue new file mode 100644 index 000000000..11bae807c --- /dev/null +++ b/src/popup/router/components/UrlStatus.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/src/popup/router/index.js b/src/popup/router/index.js index a82b6915c..19d2f860e 100644 --- a/src/popup/router/index.js +++ b/src/popup/router/index.js @@ -52,6 +52,11 @@ router.beforeEach(async (to, from, next) => { await helper.pollGetter(() => store.state.isRestored); if (store.getters.isLoggedIn) { if (!store.getters.sdk) wallet.initSdk(); + if (localStorage.tipUrl) { + next(localStorage.tipUrl); + delete localStorage.tipUrl; + return; + } next(to.meta.ifNotAuthOnly ? '/account' : undefined); return; } @@ -62,6 +67,9 @@ router.beforeEach(async (to, from, next) => { return; } wallet.initSdk(); + + if (localStorage.tipUrl) delete localStorage.tipUrl; + if (window.RUNNING_IN_POPUP) { store.commit('SET_AEPP_POPUP', true); next( diff --git a/src/popup/router/modals.js b/src/popup/router/modals.js index 8581d97b2..025df83eb 100644 --- a/src/popup/router/modals.js +++ b/src/popup/router/modals.js @@ -1,14 +1,14 @@ import { registerModal } from '../../store/plugins/modals'; -import DefaultModal from './components/Modals/DefaultModal'; -import ClaimSuccessModal from './components/Modals/ClaimSuccessModal'; -import TipBadgeModal from './components/Modals/TipBadgeModal'; +import Default from './components/Modals/Default'; +import ClaimSuccess from './components/Modals/ClaimSuccess'; +import TipUrlStatus from './components/Modals/TipUrlStatus'; import ConfirmTip from './components/Modals/ConfirmTip'; -import ConfirmModal from './components/Modals/ConfirmModal'; +import Confirm from './components/Modals/Confirm'; export default async () => { - registerModal({ name: 'default', component: DefaultModal }); - registerModal({ name: 'claim-success', component: ClaimSuccessModal }); - registerModal({ name: 'tip-badge', component: TipBadgeModal }); + registerModal({ name: 'default', component: Default }); + registerModal({ name: 'claim-success', component: ClaimSuccess }); + registerModal({ name: 'tip-url-status', component: TipUrlStatus }); registerModal({ name: 'confirm-tip', component: ConfirmTip }); - registerModal({ name: 'confirm', component: ConfirmModal }); + registerModal({ name: 'confirm', component: Confirm }); }; diff --git a/src/popup/router/pages/AboutSettings.vue b/src/popup/router/pages/AboutSettings.vue index 2916fa3c8..55e4157a7 100644 --- a/src/popup/router/pages/AboutSettings.vue +++ b/src/popup/router/pages/AboutSettings.vue @@ -16,6 +16,10 @@ + +
@@ -23,6 +27,7 @@ diff --git a/src/popup/router/pages/Account.vue b/src/popup/router/pages/Account.vue index 9cd3ba4d8..93788f35c 100644 --- a/src/popup/router/pages/Account.vue +++ b/src/popup/router/pages/Account.vue @@ -19,28 +19,34 @@ data-cy="tip-button" :text="$t('pages.account.send')" accent - to="tip" + to="/tip" class="tour__step2" > - - + + + + - + - + - + - + - @@ -48,6 +54,7 @@ import { mapGetters, mapState } from 'vuex'; import { setTimeout } from 'timers'; import Tip from '../../../icons/tip-icon.svg?vue-component'; +import Claim from '../../../icons/claim-icon.svg?vue-component'; import Activity from '../../../icons/activity-icon.svg?vue-component'; import Topup from '../../../icons/topup-icon.svg?vue-component'; import Withdraw from '../../../icons/withdraw-icon.svg?vue-component'; @@ -56,12 +63,12 @@ import RecentTransactions from '../components/RecentTransactions'; import BalanceInfo from '../components/BalanceInfo'; import AccountInfo from '../components/AccountInfo'; import BoxButton from '../components/BoxButton'; -import ClaimTips from '../components/ClaimTips'; export default { name: 'Account', components: { Tip, + Claim, Activity, Topup, Withdraw, @@ -70,12 +77,10 @@ export default { BalanceInfo, AccountInfo, BoxButton, - ClaimTips, }, data() { return { backup_seed_notif: false, - loading: false, }; }, computed: { diff --git a/src/popup/router/pages/AuctionBid.vue b/src/popup/router/pages/AuctionBid.vue index 2dbccd22b..b096d5642 100644 --- a/src/popup/router/pages/AuctionBid.vue +++ b/src/popup/router/pages/AuctionBid.vue @@ -78,7 +78,7 @@ export default { }, props: ['auctionInfo'], computed: { - ...mapGetters(['account', 'current', 'network', 'popup', 'sdk']), + ...mapGetters(['account', 'current', 'network', 'sdk']), }, mounted() { this.loading = true; diff --git a/src/popup/router/pages/ClaimTips.vue b/src/popup/router/pages/ClaimTips.vue new file mode 100644 index 000000000..d45cd3d5d --- /dev/null +++ b/src/popup/router/pages/ClaimTips.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/src/popup/router/pages/CommentNew.vue b/src/popup/router/pages/CommentNew.vue index ad588af58..804318301 100644 --- a/src/popup/router/pages/CommentNew.vue +++ b/src/popup/router/pages/CommentNew.vue @@ -23,7 +23,7 @@ import openUrl from '../../utils/openUrl'; export default { data: () => ({ id: 0, text: '', loading: false }), computed: { - ...mapGetters(['sdk', 'popup']), + ...mapGetters(['sdk']), urlParams() { return new URL(this.$route.fullPath, window.location).searchParams; }, @@ -54,6 +54,8 @@ export default { this.openCallbackOrGoHome('x-success'); } catch (e) { this.$store.dispatch('modals/open', { name: 'default', type: 'transaction-failed' }); + e.payload = { id: this.id, text: this.text }; + throw e; } finally { this.loading = false; } diff --git a/src/popup/router/pages/GeneralSettings.vue b/src/popup/router/pages/GeneralSettings.vue index 49d51ca8c..ac6bb51be 100644 --- a/src/popup/router/pages/GeneralSettings.vue +++ b/src/popup/router/pages/GeneralSettings.vue @@ -1,79 +1,54 @@ - diff --git a/src/popup/router/pages/Names.vue b/src/popup/router/pages/Names.vue index c8bb3a158..fe7be00bc 100644 --- a/src/popup/router/pages/Names.vue +++ b/src/popup/router/pages/Names.vue @@ -20,8 +20,11 @@ -
-
{{ name.name }}
+
+
+ {{ name.name }} + Active +
- - + +
+ + + +
import { mapGetters } from 'vuex'; -import { - fetchData, - convertToAE, - getAddressByNameEntry, - checkAddress, - chekAensName, -} from '../../utils/helper'; +import axios from 'axios'; +import { convertToAE, getAddressByNameEntry, checkAddress, chekAensName } from '../../utils/helper'; import Input from '../components/Input'; import Button from '../components/Button'; import UserAvatar from '../components/UserAvatar'; +import Badge from '../components/Badge'; export default { + props: ['activateName'], components: { Input, Button, UserAvatar, + Badge, }, data() { return { @@ -227,7 +237,17 @@ export default { }; }, computed: { - ...mapGetters(['current', 'popup', 'names', 'sdk', 'network', 'account', 'middleware']), + ...mapGetters([ + 'current', + 'popup', + 'names', + 'sdk', + 'network', + 'account', + 'middleware', + 'subaccounts', + 'activeAccountName', + ]), auctions() { if (this.filterType === 'soonest') return this.activeAuctions; if (this.filterType === 'length') @@ -262,6 +282,7 @@ export default { }, }, created() { + if (this.activateName) this.tab = 'registered'; this.loading = true; this.polling = setInterval(async () => { if (!this.middleware) { @@ -272,17 +293,17 @@ export default { this.updateAuctionEntry(); } const middleWareBaseUrl = this.network[this.current.network].middlewareUrl; - const fetched = await fetchData( - `${middleWareBaseUrl}/middleware/names/auctions/active`, - 'get', - '', - ); + const fetched = (await axios(`${middleWareBaseUrl}/middleware/names/auctions/active`)).data; this.activeAuctions = fetched; this.$store.dispatch('getRegisteredNames'); this.loading = false; }, 3000); }, methods: { + async setActiveName(name) { + const aename = name.name; + await this.$store.dispatch('setAccountName', { name: aename }); + }, address(name) { return getAddressByNameEntry(name); }, @@ -306,6 +327,8 @@ export default { this.$store.dispatch('modals/open', { name: 'default', type: 'name-exist' }); } else if (!onlyLettersAndNums.test(this.name)) { this.$store.dispatch('modals/open', { name: 'default', type: 'only-chars' }); + } else if (this.name.length <= 13) { + this.$store.dispatch('modals/open', { name: 'default', type: 'name-length' }); } else { this.loading = true; const name = `${this.name}.chain`; @@ -395,6 +418,9 @@ export default { diff --git a/src/popup/router/pages/Popups/PopupAskAccounts.vue b/src/popup/router/pages/Popups/AskAccounts.vue similarity index 100% rename from src/popup/router/pages/Popups/PopupAskAccounts.vue rename to src/popup/router/pages/Popups/AskAccounts.vue diff --git a/src/popup/router/pages/Popups/PopupConnect.vue b/src/popup/router/pages/Popups/Connect.vue similarity index 100% rename from src/popup/router/pages/Popups/PopupConnect.vue rename to src/popup/router/pages/Popups/Connect.vue diff --git a/src/popup/router/pages/Popups/PopupMessageSign.vue b/src/popup/router/pages/Popups/MessageSign.vue similarity index 100% rename from src/popup/router/pages/Popups/PopupMessageSign.vue rename to src/popup/router/pages/Popups/MessageSign.vue diff --git a/src/popup/router/pages/Popups/PopupSignTx.vue b/src/popup/router/pages/Popups/SignTx.vue similarity index 99% rename from src/popup/router/pages/Popups/PopupSignTx.vue rename to src/popup/router/pages/Popups/SignTx.vue index 0927bb6a1..9281cfa9f 100644 --- a/src/popup/router/pages/Popups/PopupSignTx.vue +++ b/src/popup/router/pages/Popups/SignTx.vue @@ -183,7 +183,7 @@ export default { this.tx.amount = convertToAE(this.txObject.amount); }, computed: { - ...mapGetters(['account', 'activeAccountName', 'balance', 'current', 'popup', 'network']), + ...mapGetters(['account', 'activeAccountName', 'balance', 'current', 'network']), txType() { return this.unpackedTx ? this.unpackedTx.txType : null; }, diff --git a/src/popup/router/pages/PrivacyPolicy.vue b/src/popup/router/pages/PrivacyPolicy.vue index ffbf9d00e..f0e74ec76 100644 --- a/src/popup/router/pages/PrivacyPolicy.vue +++ b/src/popup/router/pages/PrivacyPolicy.vue @@ -12,9 +12,9 @@ “us”, “our” or “the company”) is a company with seat and registered address at: Dr. Grass Str. 12, 9490 Vaduz, Liechtenstein, with email address for - communication related to the SuperHero Wallet: + communication related to the Superhero Wallet: superherowallet@protonmail.com. Superhero is the company, which created - and developed SuperHero Wallet. + and developed Superhero Wallet.

Superhero takes your privacy and the security of your information as a @@ -23,7 +23,7 @@

This Privacy Policy (“Policy”) is applicable for the Superhero developed software program - SuperHero Wallet (the + Superhero Wallet (the “Wallet” or the “application”), designed for end users, which allows supporters to send value to content creators, causes, charities, groups or regular diff --git a/src/popup/router/pages/Receive.vue b/src/popup/router/pages/Receive.vue index ded46926c..997539b11 100644 --- a/src/popup/router/pages/Receive.vue +++ b/src/popup/router/pages/Receive.vue @@ -6,13 +6,7 @@

-
- - -
+ @@ -35,11 +29,11 @@ export default { data() { return { jellySwapUrl: 'https://app.jelly.market', - changellyUrl: 'https://changelly.com/buy', + shopUniverse: 'https://shop.aeternityuniverser.com', }; }, computed: { - ...mapGetters(['account', 'popup']), + ...mapGetters(['account']), }, methods: { copy() { @@ -52,7 +46,7 @@ export default { openUrl(this.jellySwapUrl); }, purchase() { - openUrl(this.changellyUrl); + openUrl(this.shopUniverse); }, }, }; diff --git a/src/popup/router/pages/Retip.vue b/src/popup/router/pages/Retip.vue index db94765df..ec5b62bf2 100644 --- a/src/popup/router/pages/Retip.vue +++ b/src/popup/router/pages/Retip.vue @@ -1,14 +1,12 @@ @@ -42,7 +58,8 @@ export default { margin-top: 30px; a, - button { + button, + .settings-row { text-decoration: none; transition: 0.4s; position: relative; @@ -52,6 +69,7 @@ export default { font-size: 14px; border-bottom: 1px solid #ccc; text-align: left; + border-left: 2px solid transparent; &:last-child { border-bottom: 0; @@ -59,12 +77,22 @@ export default { &:hover { border-left: 2px solid #2a9cff; - background: rgba(226, 226, 226, 0.5); + background: rgba(99, 99, 99, 0.5); .arrow-right { right: 20px; } } } + + .settings-row { + display: flex; + align-items: center; + justify-content: space-between; + + .checkmark { + margin-right: 0; + } + } } .settings-li { diff --git a/src/popup/router/pages/SignTransaction.vue b/src/popup/router/pages/SignTransaction.vue index 167113d33..ca620d39c 100644 --- a/src/popup/router/pages/SignTransaction.vue +++ b/src/popup/router/pages/SignTransaction.vue @@ -188,7 +188,6 @@ export default { 'tokens', 'tokenBalance', 'isLedger', - 'popup', 'tokenRegistry', 'tokenRegistryLima', ]), @@ -560,33 +559,6 @@ export default { }); } }, - async contractCallStatic(tx) { - try { - let options = {}; - if (tx.options) { - options = { ...tx.options }; - } - if (tx.options && tx.options.amount) { - options = { ...options, ...tx.options, amount: aeToAettos(this.data.tx.options.amount) }; - } - const call = await this.$helpers.contractCall({ - instance: this.contractInstance, - method: tx.method, - params: [...tx.params, options], - }); - const decoded = await call.decode(); - call.decoded = decoded; - this.sending = true; - this.port.postMessage(call); - } catch (err) { - this.errorTx.error.message = typeof err.message !== 'undefined' ? err.message : err; - this.sending = true; - this.port.postMessage(this.errorTx); - } - setTimeout(() => { - window.close(); - }, 1000); - }, async contractCall() { let call; try { @@ -805,14 +777,6 @@ export default { const byteCode = await this.sdk.contractCompile(source); return byteCode; }, - async getDeployedByteCode(address) { - const res = await fetch( - `https://testnet.mdw.aepps.com/middleware/contracts/transactions/address/${address}`, - ); - const txs = await res.json(); - const byteCode = txs.transactions.find(tx => tx.tx.type === 'ContractCreateTx'); - return byteCode; - }, }, async beforeDestroy() { if (this.data.popup) { diff --git a/src/popup/router/pages/SuccessTip.vue b/src/popup/router/pages/SuccessTip.vue index af1741400..27df77902 100644 --- a/src/popup/router/pages/SuccessTip.vue +++ b/src/popup/router/pages/SuccessTip.vue @@ -51,6 +51,7 @@ import Textarea from '../components/Textarea'; import openUrl from '../../utils/openUrl'; import { TIP_SERVICE, BACKEND_URL, UI_URL } from '../../utils/constants'; import { aettosToAe } from '../../utils/helper'; +import Logger from '../../../lib/logger'; export default { components: { @@ -77,14 +78,17 @@ export default { }, }, async created() { - try { - this.verifiedUrls = (await axios.get(`${BACKEND_URL}/verified`)).data; - } catch (e) { - console.error(`Can't fetch /verified: ${e}`); - } + this.verifiedUrls = ( + await axios.get(`${BACKEND_URL}/verified`).catch(error => { + Logger.write(error); + return { data: [] }; + }) + ).data; const { addresses, tab } = await this.$store.dispatch('getWebPageAddresses'); if (addresses.length) { - await axios.post(`${TIP_SERVICE}`, { url: tab.url, address: addresses[0] }); + await axios + .post(TIP_SERVICE, { url: tab.url, address: addresses[0] }) + .catch(error => Logger.write(error)); } }, methods: { diff --git a/src/popup/router/pages/TermsOfService.vue b/src/popup/router/pages/TermsOfService.vue index dbf313882..ca514250e 100644 --- a/src/popup/router/pages/TermsOfService.vue +++ b/src/popup/router/pages/TermsOfService.vue @@ -20,14 +20,14 @@

These TERMS OF USE („TERMS“) apply exclusively for the - SuperHero Wallet (hereinafter referred to as the “Wallet” or the + Superhero Wallet (hereinafter referred to as the “Wallet” or the “application”) and all the content available on the website extension. Please make sure that you have carefully read the TERMS before using the application. Otherwise, by using it, we consider these actions implicit agreement to the TERMS OF USE. These TERMS OF USE represent a binding agreement between you, the legal entity you represent and the legal entity that registered you (collectively „YOU“) and Superhero.com LVC (“Superhero”, “we”, “us” or “our”) in connection to your use - of the SuperHero Wallet application.. + of the Superhero Wallet application..

Please, do not use the application provided by Superhero, if you do not agree to the @@ -76,14 +76,14 @@ “us”, “our” or “the company”) is a company with seat and registered address at: Dr. Grass Str. 12, 9490 Vaduz, Liechtenstein, with email address for - communication related to the SuperHero Wallet: + communication related to the Superhero Wallet: superherowallet@protonmail.com. Superhero is the company, which created - and developed SuperHero Wallet. + and developed Superhero Wallet.

1.2. “USER“ or “YOU“ means a natural or legal person, who has downloaded and uses the - SuperHero Wallet application. + Superhero Wallet application.

1.3. “Blockchain“ means the list of records, also known as @@ -96,7 +96,7 @@ cannot be altered retroactively.

- 1.4. “SuperHero Wallet” + 1.4. “Superhero Wallet” (“Wallet” or “application”) is a software program designed for end users, which allows supporters to send value to content creators, causes, charities, groups or regular individuals online as a reward for @@ -134,7 +134,7 @@

The results of the donations and comments are published on the website - beta.superhero.com . + superhero.com .

1.5. “Æid“, “Æternity token” or @@ -256,7 +256,7 @@

After that, the website - - beta.superhero.com, reflects the + superhero.com, reflects the USERS’ donations and comments and gives the possibility for other USERS to actively donate and comment on the newsfeed of the Website.

@@ -267,7 +267,7 @@ could be a blog, a social media account or any other online profile. Save the change and refresh the page. YOU can also add your Wallet address in the source code of the web page. Then, YOU should open your - SuperHero Wallet to access the tips received. Please bear in mind that + Superhero Wallet to access the tips received. Please bear in mind that there may be slight delays in collecting tips, we advise that you wait for a few minutes and open the Wallet again. Do not hesitate to contact us if YOU experience any difficulties. @@ -312,10 +312,10 @@ available on the Wallet, the following will be applicable:

- The tips are sent to the SuperHero Wallet of the URL address entered when + The tips are sent to the Superhero Wallet of the URL address entered when there is such Wallet created. Donations can also be made to websites/platforms/organizations/people who have not downloaded and used the - SuperHero Wallet before or during the moment of tipping. + Superhero Wallet before or during the moment of tipping.

The Æternity blockchain manages smart contracts – they @@ -324,7 +324,7 @@ without any control or interference conducted by Superhero under any form. The smart contracts are a specific feature of the decentralized public ledger. If the websites/platforms/organizations/people who are tipped, do not have a - SuperHero Wallet, the sent tip is stored in the so called “Superhero Wallet, the sent tip is stored in the so called “Tipping Smart Contract”. The Oracles – also a function of the decentralized blockchain – follows when the receiver of the tip will generate a Wallet. If @@ -451,7 +451,7 @@

The name can also be used as your profile name on the Superhero website - beta.superhero.com. + superhero.com.

As a USER, YOU agree to the following rules applicable - for the SuperHero Wallet : + for the Superhero Wallet :

  • @@ -808,7 +808,7 @@

    The notice is as it follows:

    “ISC License

    -

    Copyright (c) 2019, SuperHero

    +

    Copyright (c) 2019, Superhero

    Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this diff --git a/src/popup/router/pages/TipPage.vue b/src/popup/router/pages/Tip.vue similarity index 65% rename from src/popup/router/pages/TipPage.vue rename to src/popup/router/pages/Tip.vue index 863f92212..aab7ebda9 100644 --- a/src/popup/router/pages/TipPage.vue +++ b/src/popup/router/pages/Tip.vue @@ -1,12 +1,9 @@