diff --git a/packages/extension-bridge/package.json b/packages/extension-bridge/package.json index c9407b368..7c3f0d01a 100644 --- a/packages/extension-bridge/package.json +++ b/packages/extension-bridge/package.json @@ -36,14 +36,14 @@ "nanoevents": "^6.0.2", "serialize-error": "9.1.0", "tiny-uid": "^1.1.1", - "webextension-polyfill": "^0.8.0" + "webextension-polyfill": "^0.9.0" }, "devDependencies": { "@antfu/eslint-config": "^0.16.1", "@types/chai": "^4.3.0", "@types/mocha": "^9.1.0", "@types/node": "^17.0.17", - "@types/webextension-polyfill": "^0.8.2", + "@types/webextension-polyfill": "^0.8.3", "@typescript-eslint/eslint-plugin": "^5.11.0", "@typescript-eslint/parser": "^5.11.0", "bumpp": "^7.1.1", diff --git a/packages/extension-bridge/src/internal.ts b/packages/extension-bridge/src/internal.ts index 798da86d8..6985d2ecf 100644 --- a/packages/extension-bridge/src/internal.ts +++ b/packages/extension-bridge/src/internal.ts @@ -142,7 +142,8 @@ const initIntercoms = () => { routeMessage(message); }); port.onDisconnect.addListener(() => { - connectToBackgroundWithDisconnect(); + port = null; + initIntercoms(); }); }; connectToBackgroundWithDisconnect(); @@ -157,7 +158,8 @@ const initIntercoms = () => { routeMessage(message); }); port.onDisconnect.addListener(() => { - connectToBackgroundWithDisconnect(); + port = null; + initIntercoms(); }); }; connectToBackgroundWithDisconnect(); @@ -175,7 +177,8 @@ const initIntercoms = () => { routeMessage(message); }); port.onDisconnect.addListener(() => { - connectToBackgroundWithDisconnect(); + port = null; + initIntercoms(); }); }; connectToBackgroundWithDisconnect(); diff --git a/packages/extension/package.json b/packages/extension/package.json index 5b0272053..1eff825d7 100644 --- a/packages/extension/package.json +++ b/packages/extension/package.json @@ -14,6 +14,7 @@ "watch-vue": "vue-cli-service build --watch --no-clean" }, "dependencies": { + "@acala-network/api": "^4.1.1", "@enkryptcom/extension-bridge": "^0.0.1", "@enkryptcom/keyring": "^0.0.1", "@enkryptcom/request": "^0.0.1", @@ -29,6 +30,7 @@ "@types/lodash": "^4.14.182", "add": "^2.0.6", "bignumber.js": "^9.0.2", + "bip39": "^3.0.4", "chai": "^4.3.6", "concurrently": "^7.0.0", "core-js": "^3.21.0", @@ -45,7 +47,7 @@ "vue3-lottie": "^2.1.0", "web3": "^1.7.3", "web3-utils": "^1.7.3", - "yarn": "^1.22.18" + "zxcvbn": "^4.4.2" }, "devDependencies": { "@polkadot/api": "^8.0.2", @@ -88,7 +90,7 @@ "tsconfig-paths": "^3.12.0", "typescript": "^4.5.5", "url": "^0.11.0", - "webextension-polyfill": "^0.8.0" + "webextension-polyfill": "^0.9.0" }, "installConfig": { "hoistingLimits": "none" diff --git a/packages/extension/src/libs/background/index.ts b/packages/extension/src/libs/background/index.ts index 1dd8db040..7aabd1c66 100644 --- a/packages/extension/src/libs/background/index.ts +++ b/packages/extension/src/libs/background/index.ts @@ -4,7 +4,7 @@ import { InternalOnMessageResponse, Message, } from "@/types/messenger"; -import { KeyRecord, RPCRequestType } from "@enkryptcom/types"; +import { KeyRecord, KeyRecordAdd, RPCRequestType } from "@enkryptcom/types"; import { getCustomError } from "../error"; import KeyRingBase from "../keyring/keyring"; import { sendToWindow } from "@/libs/messenger/extension"; @@ -36,20 +36,6 @@ class BackgroundHandler { [ProviderName.ethereum]: EthereumProvider, [ProviderName.polkadot]: PolkadotProvider, }; - // this.#keyring - // .generate("test pass") - // .then(() => { - // console.log("keyring created"); - // }) - // .catch(console.error); - // this.#keyring.unlock("test pass").then(() => { - // this.#keyring.addEthereumAddress("abc").then((key) => { - // console.log("added", key); - // }); - // this.#keyring.addPolkadotAddress("def1").then((key) => { - // console.log("added", key); - // }); - // }); } async init(): Promise { const allPersistentEvents = await this.#persistentEvents.getAllEvents(); @@ -191,27 +177,57 @@ class BackgroundHandler { return Promise.resolve({ result: JSON.stringify(this.#keyring.isLocked()), }); + } else if (message.method === InternalMethods.sendToTab) { + const actionMsg = msg as any as ActionSendMessage; + if ( + actionMsg.provider && + actionMsg.tabId && + this.#tabProviders[actionMsg.provider][actionMsg.tabId] + ) { + this.#tabProviders[actionMsg.provider][ + actionMsg.tabId + ].sendNotification( + JSON.stringify(message.params?.length ? message.params[0] : {}) + ); + return Promise.resolve({ + result: JSON.stringify(true), + }); + } else { + return Promise.resolve({ + result: JSON.stringify(false), + }); + } + } else if ( + message.method === InternalMethods.getNewAccount || + message.method === InternalMethods.saveNewAccount + ) { + if (!message.params || message.params.length < 1) + return Promise.resolve({ + error: getCustomError("background: invalid params for new account"), + }); + const method = + message.method === InternalMethods.getNewAccount + ? "getNewAccount" + : "saveNewAccount"; + const keyrecord = message.params[0] as KeyRecordAdd; + return this.#keyring + [method](keyrecord) + .then((res) => { + return { + result: JSON.stringify(res), + }; + }) + .catch((e) => { + return { + error: getCustomError(e.message), + }; + }); } else { return Promise.resolve({ error: getCustomError(`background: unknown method: ${message.method}`), }); } } - actionHandler(msg: Message): Promise { - const actionMsg = msg as any as ActionSendMessage; - if (this.#tabProviders[actionMsg.provider][actionMsg.tabId]) { - this.#tabProviders[actionMsg.provider][actionMsg.tabId].sendNotification( - actionMsg.message - ); - return Promise.resolve({ - result: JSON.stringify(true), - }); - } else { - return Promise.resolve({ - result: JSON.stringify(false), - }); - } - } } export default BackgroundHandler; diff --git a/packages/extension/src/libs/keyring/keyring.ts b/packages/extension/src/libs/keyring/keyring.ts index a7a89fc00..a0e5f41f7 100644 --- a/packages/extension/src/libs/keyring/keyring.ts +++ b/packages/extension/src/libs/keyring/keyring.ts @@ -1,7 +1,12 @@ import KeyRing from "@enkryptcom/keyring"; import { InternalStorageNamespace } from "@/types/provider"; import BrowserStorage from "../common/browser-storage"; -import { KeyRecord, SignerType, SignOptions } from "@enkryptcom/types"; +import { + KeyRecord, + KeyRecordAdd, + SignerType, + SignOptions, +} from "@enkryptcom/types"; export class KeyRingBase { #keyring: KeyRing; constructor() { @@ -11,19 +16,18 @@ export class KeyRingBase { generate(password: string): Promise { return this.#keyring.init(password); } - addEthereumAddress(name: string): Promise { - return this.#keyring.createAndSaveKey({ - type: SignerType.secp256k1, - basePath: "m/44'/60'/0'/0", - name: name, + getNewAccount(options: { + basePath: string; + type: SignerType; + }): Promise { + return this.#keyring.createKey({ + name: "", + basePath: options.basePath, + type: options.type, }); } - addPolkadotAddress(name: string): Promise { - return this.#keyring.createAndSaveKey({ - type: SignerType.sr25519, - basePath: "//", - name: name, - }); + saveNewAccount(options: KeyRecordAdd): Promise { + return this.#keyring.createAndSaveKey(options); } sign( hexMessage: `0x${string}`, diff --git a/packages/extension/src/libs/sparkline/index.ts b/packages/extension/src/libs/sparkline/index.ts index 88832efd4..eb7e7c0fe 100644 --- a/packages/extension/src/libs/sparkline/index.ts +++ b/packages/extension/src/libs/sparkline/index.ts @@ -69,10 +69,8 @@ export default class Sparkline { 100 ); }); - console.log(this._values); this._viewBoxHeight = 100; this._viewBoxWidth = 100; - console.log(this._values.length, "----------------"); } public get d(): string { diff --git a/packages/extension/src/libs/assets-handlers/tokenbalance-mew.ts b/packages/extension/src/providers/ethereum/libs/assets-handlers/tokenbalance-mew.ts similarity index 93% rename from packages/extension/src/libs/assets-handlers/tokenbalance-mew.ts rename to packages/extension/src/providers/ethereum/libs/assets-handlers/tokenbalance-mew.ts index b35f484e6..2588d00fa 100644 --- a/packages/extension/src/libs/assets-handlers/tokenbalance-mew.ts +++ b/packages/extension/src/providers/ethereum/libs/assets-handlers/tokenbalance-mew.ts @@ -4,17 +4,17 @@ import { SupportedNetwork, TokenBalance, } from "./types/tokenbalance-mew"; -import MarketData from "../market-data"; -import cacheFetch from "../cache-fetch"; -import { fromBase } from "../utils/units"; +import MarketData from "@/libs/market-data"; +import cacheFetch from "@/libs/cache-fetch"; +import { fromBase } from "@/libs/utils/units"; import { toBN } from "web3-utils"; import BigNumber from "bignumber.js"; import { formatFiatValue, formatFloatingPointValue, -} from "../utils/number-formatter"; +} from "@/libs/utils/number-formatter"; import API from "@/providers/ethereum/libs/api"; -import Sparkline from "../sparkline"; +import Sparkline from "@/libs/sparkline"; import { EthereumNodeType } from "@/providers/ethereum/types"; const API_ENPOINT = "https://tokenbalance.mewapi.io/"; const NATIVE_CONTRACT = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; @@ -114,7 +114,7 @@ export default (network: NodeType, address: string): Promise => { sparkline: new Sparkline(market.sparkline_in_7d.price, 25) .dataUri, priceChangePercentage: - market.price_change_percentage_7d_in_currency, + market.price_change_percentage_7d_in_currency || 0, }; if (address !== NATIVE_CONTRACT) assets.push(asset); else nativeAsset = asset; @@ -123,8 +123,8 @@ export default (network: NodeType, address: string): Promise => { } } assets.sort((a, b) => { - if (a.balanceUSD > b.balanceUSD) return 1; - else if (a.balanceUSD < b.balanceUSD) return -1; + if (a.balanceUSD < b.balanceUSD) return 1; + else if (a.balanceUSD > b.balanceUSD) return -1; else return 0; }); assets.unshift(nativeAsset as AssetsType); diff --git a/packages/extension/src/libs/assets-handlers/types/tokenbalance-mew.ts b/packages/extension/src/providers/ethereum/libs/assets-handlers/types/tokenbalance-mew.ts similarity index 100% rename from packages/extension/src/libs/assets-handlers/types/tokenbalance-mew.ts rename to packages/extension/src/providers/ethereum/libs/assets-handlers/types/tokenbalance-mew.ts diff --git a/packages/extension/src/providers/ethereum/networks/bsc.ts b/packages/extension/src/providers/ethereum/networks/bsc.ts index e03849ed5..976a792d0 100644 --- a/packages/extension/src/providers/ethereum/networks/bsc.ts +++ b/packages/extension/src/providers/ethereum/networks/bsc.ts @@ -4,7 +4,7 @@ import { toChecksumAddress } from "ethereumjs-util"; import API from "../libs/api"; import { EthereumNodeType } from "../types"; import createIcon from "../libs/blockies"; -import tokenbalanceMew from "@/libs/assets-handlers/tokenbalance-mew"; +import tokenbalanceMew from "@/providers/ethereum/libs/assets-handlers/tokenbalance-mew"; const bscNode: EthereumNodeType = { name: "BNB", name_long: "BNB Chain", @@ -23,6 +23,7 @@ const bscNode: EthereumNodeType = { coingeckoID: "binancecoin", identicon: createIcon, assetsHandler: tokenbalanceMew, + basePath: "m/44'/714'", }; bscNode.api = async () => { const api = new API(bscNode.node); diff --git a/packages/extension/src/providers/ethereum/networks/etc.ts b/packages/extension/src/providers/ethereum/networks/etc.ts index 6ee557a05..3a55fbace 100644 --- a/packages/extension/src/providers/ethereum/networks/etc.ts +++ b/packages/extension/src/providers/ethereum/networks/etc.ts @@ -21,6 +21,7 @@ const etcNode: EthereumNodeType = { provider: ProviderName.ethereum, coingeckoID: "ethereum-classic", identicon: createIcon, + basePath: "m/44'/61'/0'/0", }; etcNode.api = async () => { const api = new API(etcNode.node); diff --git a/packages/extension/src/providers/ethereum/networks/eth.ts b/packages/extension/src/providers/ethereum/networks/eth.ts index 0a0a103f1..b1c11d52c 100644 --- a/packages/extension/src/providers/ethereum/networks/eth.ts +++ b/packages/extension/src/providers/ethereum/networks/eth.ts @@ -1,4 +1,4 @@ -import tokenbalanceMew from "@/libs/assets-handlers/tokenbalance-mew"; +import tokenbalanceMew from "@/providers/ethereum/libs/assets-handlers/tokenbalance-mew"; import rarible from "@/libs/nft-handlers/rarible"; import { ProviderName } from "@/types/provider"; import { SignerType } from "@enkryptcom/types"; @@ -25,6 +25,7 @@ const ethNode: EthereumNodeType = { NFTHandler: rarible, identicon: createIcon, assetsHandler: tokenbalanceMew, + basePath: "m/44'/60'/0'/0", }; ethNode.api = async () => { const api = new API(ethNode.node); diff --git a/packages/extension/src/providers/ethereum/networks/goerli.ts b/packages/extension/src/providers/ethereum/networks/goerli.ts index 5efb20b4e..53f78f2db 100644 --- a/packages/extension/src/providers/ethereum/networks/goerli.ts +++ b/packages/extension/src/providers/ethereum/networks/goerli.ts @@ -20,6 +20,7 @@ const goerliNode: EthereumNodeType = { displayAddress: (address: string) => toChecksumAddress(address), provider: ProviderName.ethereum, identicon: createIcon, + basePath: "m/44'/60'/0'/0", }; goerliNode.api = async () => { const api = new API(goerliNode.node); diff --git a/packages/extension/src/providers/ethereum/networks/kov.ts b/packages/extension/src/providers/ethereum/networks/kov.ts index 0ad16743e..0f5325029 100644 --- a/packages/extension/src/providers/ethereum/networks/kov.ts +++ b/packages/extension/src/providers/ethereum/networks/kov.ts @@ -20,6 +20,7 @@ const kovanNode: EthereumNodeType = { displayAddress: (address: string) => toChecksumAddress(address), provider: ProviderName.ethereum, identicon: createIcon, + basePath: "m/44'/60'/0'/0", }; kovanNode.api = async () => { const api = new API(kovanNode.node); diff --git a/packages/extension/src/providers/ethereum/networks/matic.ts b/packages/extension/src/providers/ethereum/networks/matic.ts index c8853d602..98ea2fe94 100644 --- a/packages/extension/src/providers/ethereum/networks/matic.ts +++ b/packages/extension/src/providers/ethereum/networks/matic.ts @@ -5,7 +5,7 @@ import { toChecksumAddress } from "ethereumjs-util"; import API from "../libs/api"; import { EthereumNodeType } from "../types"; import createIcon from "../libs/blockies"; -import tokenbalanceMew from "@/libs/assets-handlers/tokenbalance-mew"; +import tokenbalanceMew from "@/providers/ethereum/libs/assets-handlers/tokenbalance-mew"; const maticNode: EthereumNodeType = { name: "MATIC", name_long: "Polygon (Matic)", @@ -25,6 +25,7 @@ const maticNode: EthereumNodeType = { NFTHandler: rarible, identicon: createIcon, assetsHandler: tokenbalanceMew, + basePath: "m/44'/60'/0'/0", }; maticNode.api = async () => { const api = new API(maticNode.node); diff --git a/packages/extension/src/providers/ethereum/networks/moonbeam.ts b/packages/extension/src/providers/ethereum/networks/moonbeam.ts index 64c4cb119..a88fe647e 100644 --- a/packages/extension/src/providers/ethereum/networks/moonbeam.ts +++ b/packages/extension/src/providers/ethereum/networks/moonbeam.ts @@ -21,6 +21,7 @@ const moonbeamNode: EthereumNodeType = { provider: ProviderName.ethereum, coingeckoID: "moonbeam", identicon: createIcon, + basePath: "m/44'/60'/0'/0", }; moonbeamNode.api = async () => { const api = new API(moonbeamNode.node); diff --git a/packages/extension/src/providers/ethereum/networks/rin.ts b/packages/extension/src/providers/ethereum/networks/rin.ts index 9a4dfde2e..1d76ced70 100644 --- a/packages/extension/src/providers/ethereum/networks/rin.ts +++ b/packages/extension/src/providers/ethereum/networks/rin.ts @@ -20,6 +20,7 @@ const rinkebyNode: EthereumNodeType = { displayAddress: (address: string) => toChecksumAddress(address), provider: ProviderName.ethereum, identicon: createIcon, + basePath: "m/44'/60'/0'/0", }; rinkebyNode.api = async () => { const api = new API(rinkebyNode.node); diff --git a/packages/extension/src/providers/ethereum/networks/rop.ts b/packages/extension/src/providers/ethereum/networks/rop.ts index b43d73980..4d33f4f7d 100644 --- a/packages/extension/src/providers/ethereum/networks/rop.ts +++ b/packages/extension/src/providers/ethereum/networks/rop.ts @@ -20,6 +20,7 @@ const ropstenNode: EthereumNodeType = { displayAddress: (address: string) => toChecksumAddress(address), provider: ProviderName.ethereum, identicon: createIcon, + basePath: "m/44'/60'/0'/0", }; ropstenNode.api = async () => { const api = new API(ropstenNode.node); diff --git a/packages/extension/src/providers/polkadot/inject.ts b/packages/extension/src/providers/polkadot/inject.ts index f3b1c8699..cc8b6f0f4 100644 --- a/packages/extension/src/providers/polkadot/inject.ts +++ b/packages/extension/src/providers/polkadot/inject.ts @@ -60,6 +60,7 @@ const injectDocument = ( const provider = new Provider(options); document.injectedWeb3 = document.injectedWeb3 || {}; document.injectedWeb3["enkrypt"] = provider; + document.injectedWeb3["polkadot-js"] = provider; document["enkrypt"]["providers"][options.name] = provider; }; diff --git a/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/icons/ACA.png b/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/icons/ACA.png new file mode 100644 index 000000000..35747aec0 Binary files /dev/null and b/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/icons/ACA.png differ diff --git a/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/icons/AUSD.png b/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/icons/AUSD.png new file mode 100644 index 000000000..085636783 Binary files /dev/null and b/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/icons/AUSD.png differ diff --git a/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/icons/DOT.png b/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/icons/DOT.png new file mode 100644 index 000000000..a9d64e0be Binary files /dev/null and b/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/icons/DOT.png differ diff --git a/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/icons/LCDOT.png b/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/icons/LCDOT.png new file mode 100644 index 000000000..46d3297bf Binary files /dev/null and b/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/icons/LCDOT.png differ diff --git a/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/icons/LDOT.png b/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/icons/LDOT.png new file mode 100644 index 000000000..dff99e44d Binary files /dev/null and b/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/icons/LDOT.png differ diff --git a/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/index.ts b/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/index.ts new file mode 100644 index 000000000..fa2b5004c --- /dev/null +++ b/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/index.ts @@ -0,0 +1,78 @@ +import { AssetsType, NodeType } from "@/types/provider"; +import supported from "./supportedTokens"; +import { options } from "@acala-network/api"; +import { ApiPromise, WsProvider } from "@polkadot/api"; +import MarketData from "@/libs/market-data"; +import { OrmlTokensAccountData } from "@acala-network/types/interfaces/types-lookup"; +import BigNumber from "bignumber.js"; +import { fromBase } from "@/libs/utils/units"; +import { + formatFiatValue, + formatFloatingPointValue, +} from "@/libs/utils/number-formatter"; +import Sparkline from "@/libs/sparkline"; +import { AccountInfoWithRefCount } from "@polkadot/types/interfaces"; + +export default async ( + network: NodeType, + address: string +): Promise => { + const provider = new WsProvider(network.node); + const api = new ApiPromise(options({ provider })); + await api.isReadyOrError; + const balancePromises = supported.map(async (token) => { + if (token.crowdloanId) { + return api.query.tokens.accounts(address, { + LiquidCrowdloan: token.crowdloanId, + }); + } else if (token.native) { + return api.query.system + .account(address) + .then(({ data }) => data); + } + return api.query.tokens.accounts(address, { + Token: token.symbol, + }); + }); + const marketData = new MarketData(); + const market = await marketData.getMarketData( + supported.map((supported) => supported.coingeckoID) + ); + const balances = (await Promise.all( + balancePromises + )) as unknown as OrmlTokensAccountData[]; + + const tokens: AssetsType[] = supported.map((st, idx) => { + const userBalance = fromBase(balances[idx].free.toString(), st.decimals); + const usdBalance = new BigNumber(userBalance).times( + market[idx]?.current_price || 0 + ); + return { + balance: balances[idx].free.toString(), + balancef: formatFloatingPointValue(userBalance).value, + balanceUSD: usdBalance.toNumber(), + balanceUSDf: formatFiatValue(usdBalance.toString()).value, + decimals: st.decimals, + icon: st.image, + name: st.name, + symbol: st.symbol, + priceChangePercentage: + market[idx]?.price_change_percentage_7d_in_currency || 0, + sparkline: market[idx] + ? new Sparkline(market[idx]?.sparkline_in_7d.price, 25).dataUri + : "", + value: market[idx]?.current_price.toString() || "0", + valuef: formatFloatingPointValue( + market[idx]?.current_price.toString() || "0" + ).value, + }; + }); + const sorted = [...tokens].filter((val, idx) => idx !== 0); + sorted.sort((a, b) => { + if (a.balanceUSD < b.balanceUSD) return 1; + else if (a.balanceUSD > b.balanceUSD) return -1; + else return 0; + }); + sorted.unshift(tokens[0]); + return sorted; +}; diff --git a/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/supportedTokens.ts b/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/supportedTokens.ts new file mode 100644 index 000000000..cb9877b98 --- /dev/null +++ b/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/supportedTokens.ts @@ -0,0 +1,42 @@ +import { AcalaTokenType } from "./types"; + +const supported: AcalaTokenType[] = [ + { + name: "Acala", + symbol: "ACA", + decimals: 12, + image: require("./icons/ACA.png"), + coingeckoID: "acala", + native: true, + }, + { + name: "Acala Dollar", + symbol: "AUSD", + decimals: 12, + image: require("./icons/AUSD.png"), + coingeckoID: "usd-coin", + }, + { + name: "Polkadot", + symbol: "DOT", + decimals: 10, + image: require("./icons/DOT.png"), + coingeckoID: "polkadot", + }, + { + name: "Liquid DOT", + symbol: "LDOT", + decimals: 10, + image: require("./icons/LDOT.png"), + coingeckoID: "polkadot", + }, + { + name: "Crowdloan DOT", + symbol: "lcDOT", + decimals: 10, + image: require("./icons/LDOT.png"), + crowdloanId: 13, + coingeckoID: "polkadot", + }, +]; +export default supported; diff --git a/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/types.ts b/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/types.ts new file mode 100644 index 000000000..ca24d7d15 --- /dev/null +++ b/packages/extension/src/providers/polkadot/libs/assets-handlers/acala/types.ts @@ -0,0 +1,9 @@ +export interface AcalaTokenType { + name: string; + symbol: string; + image: string; + decimals: number; + coingeckoID: string; + crowdloanId?: number; + native?: boolean; +} diff --git a/packages/extension/src/providers/polkadot/libs/assets-handlers/dot/index.ts b/packages/extension/src/providers/polkadot/libs/assets-handlers/dot/index.ts new file mode 100644 index 000000000..fa5485552 --- /dev/null +++ b/packages/extension/src/providers/polkadot/libs/assets-handlers/dot/index.ts @@ -0,0 +1,71 @@ +import { AssetsType, NodeType } from "@/types/provider"; +import supported from "./supportedTokens"; +import { options } from "@acala-network/api"; +import { ApiPromise, WsProvider } from "@polkadot/api"; +import MarketData from "@/libs/market-data"; +import BigNumber from "bignumber.js"; +import { fromBase } from "@/libs/utils/units"; +import { + formatFiatValue, + formatFloatingPointValue, +} from "@/libs/utils/number-formatter"; +import Sparkline from "@/libs/sparkline"; +import { + AccountData, + AccountInfoWithRefCount, +} from "@polkadot/types/interfaces"; + +export default async ( + network: NodeType, + address: string +): Promise => { + const provider = new WsProvider(network.node); + const api = new ApiPromise(options({ provider })); + await api.isReadyOrError; + const balancePromises = supported.map(() => { + return api.query.system + .account(address) + .then(({ data }) => data); + }); + const marketData = new MarketData(); + const market = await marketData.getMarketData( + supported.map((supported) => supported.coingeckoID) + ); + const balances = (await Promise.all( + balancePromises + )) as unknown as AccountData[]; + + const tokens: AssetsType[] = supported.map((st, idx) => { + const userBalance = fromBase(balances[idx].free.toString(), st.decimals); + const usdBalance = new BigNumber(userBalance).times( + market[idx]?.current_price || 0 + ); + return { + balance: balances[idx].free.toString(), + balancef: formatFloatingPointValue(userBalance).value, + balanceUSD: usdBalance.toNumber(), + balanceUSDf: formatFiatValue(usdBalance.toString()).value, + decimals: st.decimals, + icon: st.image, + name: st.name, + symbol: st.symbol, + priceChangePercentage: + market[idx]?.price_change_percentage_7d_in_currency || 0, + sparkline: market[idx] + ? new Sparkline(market[idx]?.sparkline_in_7d.price, 25).dataUri + : "", + value: market[idx]?.current_price.toString() || "0", + valuef: formatFloatingPointValue( + market[idx]?.current_price.toString() || "0" + ).value, + }; + }); + const sorted = [...tokens].filter((val, idx) => idx !== 0); + sorted.sort((a, b) => { + if (a.balanceUSD < b.balanceUSD) return 1; + else if (a.balanceUSD > b.balanceUSD) return -1; + else return 0; + }); + sorted.unshift(tokens[0]); + return sorted; +}; diff --git a/packages/extension/src/providers/polkadot/libs/assets-handlers/dot/supportedTokens.ts b/packages/extension/src/providers/polkadot/libs/assets-handlers/dot/supportedTokens.ts new file mode 100644 index 000000000..d14b505b6 --- /dev/null +++ b/packages/extension/src/providers/polkadot/libs/assets-handlers/dot/supportedTokens.ts @@ -0,0 +1,12 @@ +import { TokenType } from "./types"; + +const supported: TokenType[] = [ + { + name: "Polkadot", + symbol: "DOT", + decimals: 10, + image: require("@/providers/polkadot/networks/icons/polkadot.svg"), + coingeckoID: "polkadot", + }, +]; +export default supported; diff --git a/packages/extension/src/providers/polkadot/libs/assets-handlers/dot/types.ts b/packages/extension/src/providers/polkadot/libs/assets-handlers/dot/types.ts new file mode 100644 index 000000000..c523d98ae --- /dev/null +++ b/packages/extension/src/providers/polkadot/libs/assets-handlers/dot/types.ts @@ -0,0 +1,7 @@ +export interface TokenType { + name: string; + symbol: string; + image: string; + decimals: number; + coingeckoID: string; +} diff --git a/packages/extension/src/providers/polkadot/libs/metadata.ts b/packages/extension/src/providers/polkadot/libs/metadata.ts index c20a3504d..068e6fbe6 100644 --- a/packages/extension/src/providers/polkadot/libs/metadata.ts +++ b/packages/extension/src/providers/polkadot/libs/metadata.ts @@ -14,14 +14,14 @@ export default class Metadata implements InjectedMetadata { } public get(): Promise { - console.log("metadata get called"); + console.info("metadata get called"); return this.sendMessageHandler(this.id, { method: "dot_metadata_get", }); } public provide(definition: MetadataDef): Promise { - console.log(definition); + console.info(definition); return Promise.resolve(true); } } diff --git a/packages/extension/src/providers/polkadot/networks/acala.ts b/packages/extension/src/providers/polkadot/networks/acala.ts index 08f51109f..2877a6a43 100644 --- a/packages/extension/src/providers/polkadot/networks/acala.ts +++ b/packages/extension/src/providers/polkadot/networks/acala.ts @@ -2,6 +2,7 @@ import { ProviderName } from "@/types/provider"; import { SignerType } from "@enkryptcom/types"; import { polkadotEncodeAddress } from "@enkryptcom/utils"; import API from "../libs/api"; +import acalaAssetsHandler from "../libs/assets-handlers/acala"; import createIcon from "../libs/blockies"; import { PolkadotNodeType } from "../types"; const acaNode: PolkadotNodeType = { @@ -12,7 +13,7 @@ const acaNode: PolkadotNodeType = { blockExplorerAddr: "https://acala.subscan.io/account/[[address]]", isTestNetwork: false, currencyName: "ACA", - icon: require("./icons/polkadot.svg"), + icon: require("./icons/acala.svg"), decimals: 12, prefix: 10, signer: [SignerType.sr25519, SignerType.ed25519], @@ -22,6 +23,8 @@ const acaNode: PolkadotNodeType = { provider: ProviderName.polkadot, coingeckoID: "acala", identicon: createIcon, + assetsHandler: acalaAssetsHandler, + basePath: "//", }; acaNode.api = async () => { const api = new API(acaNode.node, { decimals: acaNode.decimals }); diff --git a/packages/extension/src/providers/polkadot/networks/polkadot.ts b/packages/extension/src/providers/polkadot/networks/polkadot.ts index 41b69990d..695fde90e 100644 --- a/packages/extension/src/providers/polkadot/networks/polkadot.ts +++ b/packages/extension/src/providers/polkadot/networks/polkadot.ts @@ -2,6 +2,7 @@ import { ProviderName } from "@/types/provider"; import { SignerType } from "@enkryptcom/types"; import { polkadotEncodeAddress } from "@enkryptcom/utils"; import API from "../libs/api"; +import dot from "../libs/assets-handlers/dot"; import createIcon from "../libs/blockies"; import { PolkadotNodeType } from "../types"; const dotNode: PolkadotNodeType = { @@ -22,6 +23,8 @@ const dotNode: PolkadotNodeType = { provider: ProviderName.polkadot, coingeckoID: "polkadot", identicon: createIcon, + assetsHandler: dot, + basePath: "//", }; dotNode.api = async () => { const api = new API(dotNode.node, { decimals: dotNode.decimals }); diff --git a/packages/extension/src/scripts/chrome/background.ts b/packages/extension/src/scripts/chrome/background.ts index c2f7980bf..2c63c2e01 100644 --- a/packages/extension/src/scripts/chrome/background.ts +++ b/packages/extension/src/scripts/chrome/background.ts @@ -15,10 +15,10 @@ backgroundHandler.init().then(() => { return backgroundHandler.internalHandler(msg); } ); - backgroundOnMessageFromWindow((msg): Promise => { - return backgroundHandler.externalHandler(msg); - }); - backgroundOnMessageFromAction((msg): Promise => { - return backgroundHandler.actionHandler(msg); - }); +}); +backgroundOnMessageFromWindow((msg): Promise => { + return backgroundHandler.externalHandler(msg); +}); +backgroundOnMessageFromAction((msg): Promise => { + return backgroundHandler.internalHandler(msg); }); diff --git a/packages/extension/src/scripts/contentscript.ts b/packages/extension/src/scripts/contentscript.ts index 82cf8d563..d9ce9ff63 100644 --- a/packages/extension/src/scripts/contentscript.ts +++ b/packages/extension/src/scripts/contentscript.ts @@ -11,7 +11,7 @@ function injectScript() { scriptTag.setAttribute("async", "false"); scriptTag.src = injectURL; scriptTag.onload = function () { - console.log("Hello from the content-script"); + console.info("Hello from the content-script"); container.removeChild(scriptTag); }; container.insertBefore(scriptTag, container.children[0]); diff --git a/packages/extension/src/scripts/inject.ts b/packages/extension/src/scripts/inject.ts index d96be6911..219d6d225 100644 --- a/packages/extension/src/scripts/inject.ts +++ b/packages/extension/src/scripts/inject.ts @@ -27,7 +27,7 @@ window.addEventListener("beforeunload", () => { JSON.stringify({ method: InternalMethods.newWindowUnload }) ); }); -console.log("hello from injected code"); +console.info("hello from injected code"); EthereumProvider(window, { name: ProviderName.ethereum, type: ProviderType.evm, diff --git a/packages/extension/src/types/messenger.ts b/packages/extension/src/types/messenger.ts index 12a2ac626..33cd18c27 100644 --- a/packages/extension/src/types/messenger.ts +++ b/packages/extension/src/types/messenger.ts @@ -19,6 +19,9 @@ export enum InternalMethods { isLocked = "enkrypt_is_locked_keyring", newWindowInit = "enkrypt_newWindowInit", newWindowUnload = "enkrypt_newWindowUnload", + sendToTab = "enkrypt_sendToTab", + getNewAccount = "enkrypt_getNewAccount", + saveNewAccount = "enkrypt_saveNewAccount", } export interface SendMessage { [key: string]: any; @@ -27,9 +30,9 @@ export interface SendMessage { } export interface ActionSendMessage { [key: string]: any; - provider: ProviderName; + provider?: ProviderName; message: string; - tabId: number; + tabId?: number; } export interface Message extends SendMessage { sender: Endpoint; diff --git a/packages/extension/src/types/provider.ts b/packages/extension/src/types/provider.ts index 1e5879f3d..ef649ac7a 100644 --- a/packages/extension/src/types/provider.ts +++ b/packages/extension/src/types/provider.ts @@ -131,6 +131,7 @@ export interface NodeType { NFTHandler?: (network: NodeType, address: string) => Promise; identicon: (address: string, options: any) => string; assetsHandler?: (network: NodeType, address: string) => Promise; + basePath: string; } export interface AssetsType { @@ -143,7 +144,7 @@ export interface AssetsType { balanceUSDf: string; value: string; valuef: string; - contract: string; + contract?: string; decimals: number; sparkline: string; priceChangePercentage: number; diff --git a/packages/extension/src/ui/action/App.vue b/packages/extension/src/ui/action/App.vue index 15dc35e8b..0b78876f1 100644 --- a/packages/extension/src/ui/action/App.vue +++ b/packages/extension/src/ui/action/App.vue @@ -10,7 +10,7 @@ />
- to Cretate / Restore + to Create / Restore @@ -87,8 +90,11 @@ const props = defineProps({ type: Function, default: () => ({}), }, + init: { + type: Function as PropType<() => void>, + default: () => ({}), + }, }); - const close = () => { props.toggle(); }; diff --git a/packages/extension/src/ui/action/views/lock-screen/components/lock-screen-forgot.vue b/packages/extension/src/ui/action/views/lock-screen/components/lock-screen-forgot.vue index a67c56f88..aaa78b63a 100644 --- a/packages/extension/src/ui/action/views/lock-screen/components/lock-screen-forgot.vue +++ b/packages/extension/src/ui/action/views/lock-screen/components/lock-screen-forgot.vue @@ -30,7 +30,6 @@ export default { diff --git a/packages/extension/src/ui/action/views/swap-best-offer/components/swap-best-offer-block/components/best-offer-list-item.vue b/packages/extension/src/ui/action/views/swap-best-offer/components/swap-best-offer-block/components/best-offer-list-item.vue new file mode 100644 index 000000000..cd2dad264 --- /dev/null +++ b/packages/extension/src/ui/action/views/swap-best-offer/components/swap-best-offer-block/components/best-offer-list-item.vue @@ -0,0 +1,133 @@ + + + + + + + diff --git a/packages/extension/src/ui/action/views/swap-best-offer/components/swap-best-offer-block/components/best-offer-list.vue b/packages/extension/src/ui/action/views/swap-best-offer/components/swap-best-offer-block/components/best-offer-list.vue new file mode 100644 index 000000000..c335c9f35 --- /dev/null +++ b/packages/extension/src/ui/action/views/swap-best-offer/components/swap-best-offer-block/components/best-offer-list.vue @@ -0,0 +1,62 @@ + + + + + + + diff --git a/packages/extension/src/ui/action/views/swap-best-offer/components/swap-best-offer-block/components/best-offer-warning.vue b/packages/extension/src/ui/action/views/swap-best-offer/components/swap-best-offer-block/components/best-offer-warning.vue new file mode 100644 index 000000000..1d5a0a054 --- /dev/null +++ b/packages/extension/src/ui/action/views/swap-best-offer/components/swap-best-offer-block/components/best-offer-warning.vue @@ -0,0 +1,67 @@ + + + + + + + diff --git a/packages/extension/src/ui/action/views/swap-best-offer/components/swap-best-offer-block/index.vue b/packages/extension/src/ui/action/views/swap-best-offer/components/swap-best-offer-block/index.vue new file mode 100644 index 000000000..83c5063b6 --- /dev/null +++ b/packages/extension/src/ui/action/views/swap-best-offer/components/swap-best-offer-block/index.vue @@ -0,0 +1,222 @@ + + + + + + + diff --git a/packages/extension/src/ui/action/views/swap-best-offer/components/swap-best-offer-list/index.vue b/packages/extension/src/ui/action/views/swap-best-offer/components/swap-best-offer-list/index.vue new file mode 100644 index 000000000..e69de29bb diff --git a/packages/extension/src/ui/action/views/swap-best-offer/index.vue b/packages/extension/src/ui/action/views/swap-best-offer/index.vue new file mode 100644 index 000000000..7b5530b2b --- /dev/null +++ b/packages/extension/src/ui/action/views/swap-best-offer/index.vue @@ -0,0 +1,259 @@ + + + + + + + diff --git a/packages/extension/src/ui/action/views/swap-initiated/components/swap-initiated-amount.vue b/packages/extension/src/ui/action/views/swap-initiated/components/swap-initiated-amount.vue new file mode 100644 index 000000000..974bd8d4c --- /dev/null +++ b/packages/extension/src/ui/action/views/swap-initiated/components/swap-initiated-amount.vue @@ -0,0 +1,74 @@ + + + + + + + diff --git a/packages/extension/src/ui/action/views/swap-initiated/index.vue b/packages/extension/src/ui/action/views/swap-initiated/index.vue new file mode 100644 index 000000000..5b64b01a0 --- /dev/null +++ b/packages/extension/src/ui/action/views/swap-initiated/index.vue @@ -0,0 +1,163 @@ + + + + + + + diff --git a/packages/extension/src/ui/action/views/swap/components/swap-looking/index.vue b/packages/extension/src/ui/action/views/swap/components/swap-looking/index.vue new file mode 100644 index 000000000..5f330dfb7 --- /dev/null +++ b/packages/extension/src/ui/action/views/swap/components/swap-looking/index.vue @@ -0,0 +1,123 @@ + + + + + + + diff --git a/packages/extension/src/ui/action/views/swap/components/swap-token-amount-input/components/swap-token-amount-input.vue b/packages/extension/src/ui/action/views/swap/components/swap-token-amount-input/components/swap-token-amount-input.vue new file mode 100644 index 000000000..624fe6de2 --- /dev/null +++ b/packages/extension/src/ui/action/views/swap/components/swap-token-amount-input/components/swap-token-amount-input.vue @@ -0,0 +1,74 @@ + + + + + + + diff --git a/packages/extension/src/ui/action/views/swap/components/swap-token-amount-input/index.vue b/packages/extension/src/ui/action/views/swap/components/swap-token-amount-input/index.vue new file mode 100644 index 000000000..7faf2d239 --- /dev/null +++ b/packages/extension/src/ui/action/views/swap/components/swap-token-amount-input/index.vue @@ -0,0 +1,134 @@ + + + + + + + diff --git a/packages/extension/src/ui/action/views/swap/components/swap-token-fast-list/components/swap-token-fast-item.vue b/packages/extension/src/ui/action/views/swap/components/swap-token-fast-list/components/swap-token-fast-item.vue new file mode 100644 index 000000000..4af5ba1dd --- /dev/null +++ b/packages/extension/src/ui/action/views/swap/components/swap-token-fast-list/components/swap-token-fast-item.vue @@ -0,0 +1,74 @@ + + + + + + + diff --git a/packages/extension/src/ui/action/views/swap/components/swap-token-fast-list/index.vue b/packages/extension/src/ui/action/views/swap/components/swap-token-fast-list/index.vue new file mode 100644 index 000000000..a20bf8da2 --- /dev/null +++ b/packages/extension/src/ui/action/views/swap/components/swap-token-fast-list/index.vue @@ -0,0 +1,52 @@ + + + + + + + diff --git a/packages/extension/src/ui/action/views/swap/components/swap-token-list/components/swap-token-list-item.vue b/packages/extension/src/ui/action/views/swap/components/swap-token-list/components/swap-token-list-item.vue new file mode 100644 index 000000000..92d656c13 --- /dev/null +++ b/packages/extension/src/ui/action/views/swap/components/swap-token-list/components/swap-token-list-item.vue @@ -0,0 +1,132 @@ + + + + + + + diff --git a/packages/extension/src/ui/action/views/swap/components/swap-token-list/components/swap-token-list-search.vue b/packages/extension/src/ui/action/views/swap/components/swap-token-list/components/swap-token-list-search.vue new file mode 100644 index 000000000..2a94ffdff --- /dev/null +++ b/packages/extension/src/ui/action/views/swap/components/swap-token-list/components/swap-token-list-search.vue @@ -0,0 +1,48 @@ + + + + + + + diff --git a/packages/extension/src/ui/action/views/swap/components/swap-token-list/index.vue b/packages/extension/src/ui/action/views/swap/components/swap-token-list/index.vue new file mode 100644 index 000000000..c823a171d --- /dev/null +++ b/packages/extension/src/ui/action/views/swap/components/swap-token-list/index.vue @@ -0,0 +1,144 @@ + + + + + + + diff --git a/packages/extension/src/ui/action/views/swap/components/swap-token-select/index.vue b/packages/extension/src/ui/action/views/swap/components/swap-token-select/index.vue new file mode 100644 index 000000000..bf76beb9f --- /dev/null +++ b/packages/extension/src/ui/action/views/swap/components/swap-token-select/index.vue @@ -0,0 +1,129 @@ + + + + + + + diff --git a/packages/extension/src/ui/action/views/swap/index.vue b/packages/extension/src/ui/action/views/swap/index.vue new file mode 100644 index 000000000..d71b2ac7e --- /dev/null +++ b/packages/extension/src/ui/action/views/swap/index.vue @@ -0,0 +1,251 @@ + + + + + + + diff --git a/packages/extension/src/ui/action/views/transaction-fee/components/transaction-fee-item.vue b/packages/extension/src/ui/action/views/transaction-fee/components/transaction-fee-item.vue index 7d50791c9..5f2822e73 100644 --- a/packages/extension/src/ui/action/views/transaction-fee/components/transaction-fee-item.vue +++ b/packages/extension/src/ui/action/views/transaction-fee/components/transaction-fee-item.vue @@ -24,14 +24,14 @@ v-show="fee.price.speed == TransactionFeeSpeed.economy" class="transaction-fee-item__block-amount down" > - -{{ $filters.currencyFormat(2.23, "USD") }} + -{{ $filters.formatFiatValue(2.23).value }}
- +{{ $filters.currencyFormat(1.23, "USD") }} + +{{ $filters.formatFiatValue(1.23).value }}
diff --git a/packages/extension/src/ui/action/views/transaction-fee/index.vue b/packages/extension/src/ui/action/views/transaction-fee/index.vue index 2a8a29dd8..cd6b8ad67 100644 --- a/packages/extension/src/ui/action/views/transaction-fee/index.vue +++ b/packages/extension/src/ui/action/views/transaction-fee/index.vue @@ -5,7 +5,7 @@

- {{ $filters.currencyFormat(10.12, "USD") }} + {{ $filters.formatFiatValue(10.12).value }}

0.0000123 eth diff --git a/packages/extension/src/ui/action/views/verify-transaction/components/verify-transaction-amount.vue b/packages/extension/src/ui/action/views/verify-transaction/components/verify-transaction-amount.vue index 33586ddca..204809b58 100644 --- a/packages/extension/src/ui/action/views/verify-transaction/components/verify-transaction-amount.vue +++ b/packages/extension/src/ui/action/views/verify-transaction/components/verify-transaction-amount.vue @@ -7,7 +7,7 @@

{{ amount }} {{ token.symbol }}

-
{{ $filters.currencyFormat(amount * token.price, "USD") }}
+
{{ $filters.formatFiatValue(amount).value }}
diff --git a/packages/extension/src/ui/action/views/verify-transaction/components/verify-transaction-fee.vue b/packages/extension/src/ui/action/views/verify-transaction/components/verify-transaction-fee.vue index d5704d222..af2c9a874 100644 --- a/packages/extension/src/ui/action/views/verify-transaction/components/verify-transaction-fee.vue +++ b/packages/extension/src/ui/action/views/verify-transaction/components/verify-transaction-fee.vue @@ -1,7 +1,7 @@ diff --git a/packages/extension/src/ui/onboard/create-wallet/double-check-phrase.vue b/packages/extension/src/ui/onboard/create-wallet/double-check-phrase.vue index dc6400141..30d29b110 100644 --- a/packages/extension/src/ui/onboard/create-wallet/double-check-phrase.vue +++ b/packages/extension/src/ui/onboard/create-wallet/double-check-phrase.vue @@ -7,80 +7,167 @@ :id="item.id" :key="index" :phrases="item.items" + :increment="increment" + :reset="reset" + :count="correctPhrasesChecked" > - +