diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 4a5520e49..08747c5cc 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -14,7 +14,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@master with: - node-version: "11.x" + node-version: "16.x" - name: Get yarn cache directory path id: yarn-cache-dir-path @@ -37,3 +37,7 @@ jobs: ${{ runner.os }}-${{ matrix.node-version }}-nodemodules- - run: yarn install - run: yarn test + env: + INFURA_PROJECT_ID: "12345" + EXT_VALIDATORS_URL: "" + WALLETCONNECT_PROJECT_ID: "12345" diff --git a/README.md b/README.md index 507cc2058..5cb5e9143 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Plasmachain Staking and Validator Dashboard Set the following environment variables before running anything: +- `WALLETCONNECT_PROJECT_ID` - should be set to the project ID generated by WalletConnect Developer Cloud. - `INFURA_PROJECT_ID` - should be set to the project ID generated by Infura. - `NODE_ENV` - should be set to `PRODUCTION` for production deploys. - `EXT_VALIDATORS_URL` - should be set to the API endpoint that provides additional information about diff --git a/babel.config.js b/babel.config.js index 5c595a8d8..5581b77e6 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,15 +1,9 @@ -// module.exports = { -// presets: ['@vue/app'] -// } module.exports = { - presets: ["@vue/app", "@babel/preset-env"], + presets: ["@vue/cli-plugin-babel/preset", "@babel/preset-env"], env: { test: { plugins: [ - "@babel/plugin-transform-runtime", - "@babel/proposal-class-properties", - "@babel/proposal-object-rest-spread", - "istanbul" + "@babel/plugin-transform-runtime" ] } } diff --git a/package.json b/package.json index c9fb0f002..b55060846 100644 --- a/package.json +++ b/package.json @@ -5,12 +5,14 @@ "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build", - "test": "NODE_ENV=test ./node_modules/.bin/nyc vue-cli-service test:unit src/**/*.spec.ts", - "lint": "vue-cli-service lint", "test:unit": "vue-cli-service test:unit src/**/*.spec.ts", - "tokens": "ts-node --compiler-options '{\"noImplicitAny\": false, \"module\": \"commonjs\" }' --project tsconfig.json ./scripts/gen-tokens-info.ts" + "lint": "vue-cli-service lint", + "test": "NODE_ENV=test vue-cli-service test:unit src/**/*.spec.ts", + "tokens": "ts-node --compiler-options '{\"noImplicitAny\": false, \"module\": \"commonjs\" }' --project tsconfig.json ./scripts/gen-tokens-info.ts", + "gen-contract-types": "yarn typechain \"src/contracts/ERC20.json\" --target=web3-v1 --out-dir src/store/plasma/web3-contracts" }, "dependencies": { + "@coinbase/wallet-sdk": "^3.7.1", "@fortawesome/fontawesome": "^1.1.3", "@fortawesome/fontawesome-free-brands": "5.0.6", "@fortawesome/fontawesome-free-regular": "^5.0.6", @@ -18,7 +20,8 @@ "@fortawesome/vue-fontawesome": "^0.0.22", "@sentry/browser": "^5.5.0", "@sentry/integrations": "^5.5.0", - "@walletconnect/web3-provider": "^1.4.1", + "@walletconnect/ethereum-provider": "^2.8.1", + "@walletconnect/modal": "^2.4.7", "animate.css": "^3.7.0", "axios": "^0.19.0", "bech32": "^1.1.3", @@ -28,14 +31,21 @@ "bn.js": "^4.11.8", "bootstrap": "^4.1.3", "bootstrap-vue": "^2.0.0-rc.22", + "buffer": "^6.0.3", "chart.js": "^2.7.2", + "core-js": "^3.8.3", "date-fns": "^1.29.0", + "ethers": "^5.7.0", "google-protobuf": "^3.6.0", + "https-browserify": "^1.0.0", "js-sha256": "^0.9.0", - "loom-js": "1.79.0", + "loom-js": "1.91.0", "marked": "^0.8.0", "rxjs": "^6.5.2", + "stream-browserify": "^3.0.0", + "stream-http": "^3.2.0", "tslib": "^1.10.0", + "underscore": "^1.13.6", "v-autocomplete": "^1.8.2", "vue": "^2.5.16", "vue-chartjs": "^3.3.2", @@ -53,14 +63,13 @@ "vuex-class": "^0.3.1", "vuex-router-sync": "^5.0.0", "vuex-typex": "^3.1.5", - "walletlink": "^2.1.0", - "web3": "1.2.1", - "web3-eth-contract": "1.0.0-beta.36", - "web3-providers": "^1.0.0-beta.38" + "web3": "1.8.2", + "web3-eth-contract": "1.8.2" }, "devDependencies": { "@prerenderer/renderer-jsdom": "^0.2.0", "@sentry/webpack-plugin": "^1.7.0", + "@typechain/web3-v1": "^6.0.3", "@types/bip39": "^2.4.2", "@types/bn.js": "^4.11.5", "@types/chai": "^4.1.7", @@ -69,10 +78,10 @@ "@types/mocha": "^5.2.7", "@types/retry": "^0.10.2", "@types/sinon": "^7.0.13", - "@vue/cli-plugin-babel": "^3.7.0", - "@vue/cli-plugin-typescript": "^3.7.0", - "@vue/cli-plugin-unit-mocha": "^3.8.0", - "@vue/cli-service": "^3.8.3", + "@vue/cli-plugin-babel": "~5.0.8", + "@vue/cli-plugin-typescript": "~5.0.8", + "@vue/cli-plugin-unit-mocha": "~5.0.8", + "@vue/cli-service": "~5.0.8", "@vue/eslint-config-airbnb": "^4.0.0", "@vue/eslint-config-typescript": "^4.0.0", "@vue/test-utils": "1.0.0-beta.29", @@ -86,32 +95,26 @@ "eslint-plugin-html": "^5.0.3", "eslint-plugin-prettier": "^3.1.0", "husky": "^3.0.0", - "inspectpack": "^4.2.1", - "istanbul-instrumenter-loader": "^3.0.1", "jsdom": "^15.1.1", "jsdom-global": "^3.0.2", "lolex": "^4.1.0", "mocha": "^6.1.4", - "nyc": "^14.1.1", "prerender-spa-plugin": "^3.3.0", "prettier": "^1.18.2", - "protoc": "^1.0.3", "sass": "^1.35.2", "sass-loader": "^8.0.0", "sentry-testkit": "^2.2.1", "sinon": "^7.3.2", - "ts-node": "^8.2.0", - "ts-protoc-gen": "^0.7.3", + "ts-node": "^10.9.1", "tslint-config-prettier": "^1.18.0", - "typechain": "^0.3.14", - "typescript": "^3.4.3", - "wait-for-expect": "^1.1.0", - "webpack-bundle-analyzer": "^3.3.2", - "window-mock": "^0.0.13" + "typechain": "^8.2.0", + "typescript": "~4.5.5", + "wait-for-expect": "^1.1.0" + }, + "engines": { + "node": ">= 16.0.0" }, "husky": { - "hooks": { - "pre-push": "yarn test" - } + "hooks": {} } -} \ No newline at end of file +} diff --git a/src/App.vue b/src/App.vue index f010a3670..f0e08a0ab 100644 --- a/src/App.vue +++ b/src/App.vue @@ -80,10 +80,6 @@ main.container { box-shadow: rgba(219, 219, 219, 0.56) 0px 3px 8px 0px; } -#walletconnect-qrcode-modal { - z-index: 9999 !important; -} - .faq img { border: 1px solid; box-shadow: 0 0 5px #ccc; diff --git a/src/components/HistoryEvent.vue b/src/components/HistoryEvent.vue index d69b884c0..4e6108954 100644 --- a/src/components/HistoryEvent.vue +++ b/src/components/HistoryEvent.vue @@ -25,7 +25,9 @@ export default class HistoryEvent extends Vue { @Prop({ required: true }) event: any - etherScanUrl = `${this.state.ethereum.blockExplorer}/tx/${this.event.transactionHash}` + get etherScanUrl(): string { + return `${this.state.ethereum.blockExplorer}/tx/${this.event.transactionHash}` + } get state(): DashboardState { return this.$store.state diff --git a/src/components/InputAddress.vue b/src/components/InputAddress.vue index 3e1b4a66f..9866a6d78 100644 --- a/src/components/InputAddress.vue +++ b/src/components/InputAddress.vue @@ -14,8 +14,6 @@ - \ No newline at end of file diff --git a/src/dpos/store/__test__/_helpers.ts b/src/dpos/store/__test__/_helpers.ts index bb1f21ba5..bb4662bdc 100644 --- a/src/dpos/store/__test__/_helpers.ts +++ b/src/dpos/store/__test__/_helpers.ts @@ -7,7 +7,6 @@ import { plasmaModule } from "@/store/plasma" import { dposModule } from ".." import { ethereumModule } from "@/store/ethereum" import { dposUtils } from "../reactions" -import { IValidator } from "loom-js/dist/contracts/dpos3" export function emptyValidator() { return { diff --git a/src/dpos/store/__test__/reactions.spec.ts b/src/dpos/store/__test__/reactions.spec.ts index b22213406..18089dec4 100644 --- a/src/dpos/store/__test__/reactions.spec.ts +++ b/src/dpos/store/__test__/reactions.spec.ts @@ -11,7 +11,6 @@ import { contracts as plasmaTokenContracts } from "@/store/plasma/tokens" import { CoinAdapter } from "@/store/plasma/tokens" import sinon from "sinon" import { now, nowStub, dposUtilsStub, dposModuleStub, plasmaModuleStub } from "./_helpers" -import { Coin } from "loom-js/dist/contracts" const localVue = createLocalVue() localVue.use(Vuex) diff --git a/src/dpos/store/index.ts b/src/dpos/store/index.ts index f9aeafb0b..9df42593d 100644 --- a/src/dpos/store/index.ts +++ b/src/dpos/store/index.ts @@ -449,7 +449,7 @@ export async function undelegate(context: ActionContext, delegation: Delegation) feedback.endTask() } catch (error) { feedback.endTask() - if (error.message.indexOf("Delegation currently locked") !== -1) { + if ((error as Error).message.indexOf("Delegation currently locked") !== -1) { feedback.showError(i18n.t("feedback_msg.error.err_delegation_locked").toString()) } else { console.error(error) @@ -637,7 +637,7 @@ export async function unjail(context: ActionContext) { feedback.showSuccess(i18n.t("dpos.unjail_success").toString()) } catch (err) { console.error(err) - feedback.showError(i18n.t("dpos.unjail_error", { error: err.message }).toString()) + feedback.showError(i18n.t("dpos.unjail_error", { error: (err as Error).message }).toString()) } finally { feedback.endTask() } diff --git a/src/locales/en.json b/src/locales/en.json index 1f03ed8aa..18d920b39 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -82,7 +82,7 @@ "ledger_via_metamask": "Ledger (via Metamask)", "trezor_via_metamask": "Trezor (via Metamask)", "walletconnect": "WalletConnect", - "walletlink": "WalletLink", + "walletlink": "Coinbase Wallet", "explore": "Explore", "binance": "Binance Chain" }, diff --git a/src/store/ethereum/actions.ts b/src/store/ethereum/actions.ts index 684712da1..2bc6aee4f 100644 --- a/src/store/ethereum/actions.ts +++ b/src/store/ethereum/actions.ts @@ -1,4 +1,4 @@ -import { ERC20Factory } from "loom-js/dist/mainnet-contracts/ERC20Factory" +import { ERC20__factory as ERC20Factory } from "loom-js/dist/mainnet-contracts/factories/ERC20__factory" import { timer } from "rxjs" import BN from "bn.js" import { BareActionContext } from "vuex-typex" diff --git a/src/store/ethereum/erc20.ts b/src/store/ethereum/erc20.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/store/ethereum/index.ts b/src/store/ethereum/index.ts index 424ce14a8..7ff40b8c0 100644 --- a/src/store/ethereum/index.ts +++ b/src/store/ethereum/index.ts @@ -7,7 +7,7 @@ import { ERC20 } from "@/store/plasma/web3-contracts/ERC20" import { Transfer } from "@/types" import BN from "bn.js" import debug from "debug" -import { abi as ERC20ABI } from "loom-js/dist/mainnet-contracts/ERC20Factory" +import { abi as ERC20ABI } from "loom-js/dist/mainnet-contracts/factories/ERC20__factory" import { BareActionContext, getStoreBuilder } from "vuex-typex" import Web3 from "web3" import { @@ -118,7 +118,7 @@ export const ethereumModule = { return stateGetter() }, - get web3(): Web3 { + get web3(): Web3 | null { return web3 }, @@ -173,17 +173,16 @@ async function setWalletType(context: ActionContext, walletType: string) { feedbackModule.setTask(i18n.t("feedback_msg.task.connect_wallet").toString()) feedbackModule.setStep(i18n.t("feedback_msg.task.connect_wallet").toString()) - await wallet - .createProvider(context.state) - .then((provider) => { - disconnectWalletBeforeUnload(provider) - return setProvider(context, provider) - }) - .catch((error) => { + try { + const provider = await wallet.createProvider(context.state) + disconnectWalletBeforeUnload(provider) + await setProvider(context, provider) + } catch(error) { Sentry.captureException(error) console.error(error) + feedbackModule.endTask() feedbackModule.showError(i18n.t("feedback_msg.error.connect_wallet_prob").toString()) - }) + } } } @@ -257,7 +256,7 @@ export async function refreshBalance(context: ActionContext, symbol: string) { // On Ethereum fetch the current user's ETH balance, on BSC fetch the BNB balance, etc. const nativeTokenSymbol = context.state.nativeTokenSymbol if (symbol === nativeTokenSymbol) { - const b = await web3.eth.getBalance(context.state.address) + const b = await web3!.eth.getBalance(context.state.address) context.state.coins[nativeTokenSymbol].balance = new BN(b.toString()) return } @@ -303,7 +302,7 @@ export async function approve(context: ActionContext, payload: Transfer) { return result } catch (error) { if (isBCWallet(context.rootState.ethereum.wallet) && - error.message.includes("Failed to subscribe to new newBlockHeaders to confirm the transaction receipts")) { + (error as any).message.includes("Failed to subscribe to new newBlockHeaders to confirm the transaction receipts")) { await new Promise((resolve) => setTimeout(resolve, BSC_SAFE_BLOCK_WAIT_TIME_MS)) // XXX when it fails it doesnt return the transaction hash return "" diff --git a/src/store/ethereum/types.ts b/src/store/ethereum/types.ts index c449d56c6..c2c3c8b1a 100644 --- a/src/store/ethereum/types.ts +++ b/src/store/ethereum/types.ts @@ -1,7 +1,7 @@ import BN from "bn.js" import { ethers, Signer } from "ethers" import { Observable } from "rxjs" -import { ERC20Factory } from "loom-js/dist/mainnet-contracts/ERC20Factory" +import { ERC20__factory as ERC20Factory } from "loom-js/dist/mainnet-contracts/factories/ERC20__factory" import Web3 from "web3" export interface EthereumConfig { diff --git a/src/store/ethereum/wallets/binance.ts b/src/store/ethereum/wallets/binance.ts index a5cdd403d..47af637ab 100644 --- a/src/store/ethereum/wallets/binance.ts +++ b/src/store/ethereum/wallets/binance.ts @@ -33,7 +33,7 @@ export const BinanceChainWalletAdapter: WalletType = { try { accounts = await bc.request({ method: "eth_requestAccounts" }) } catch (err) { - if (err.code === 4001) { + if ((err as any).code === 4001) { // EIP-1193 userRejectedRequest error // If this happens, the user rejected the connection request. console.log("Use rejected Binance Chain Wallet connection request") @@ -84,13 +84,13 @@ async function changeAccounts(accounts: string[]) { /** * https://github.com/loomnetwork/dashboard/issues/1421 - * NOTE: based on ethers 4.0.47! + * NOTE: based on ethers 5.7.0! */ function patchSigner(signer: ethers.Signer) { - const patch = async (message: ethers.utils.Arrayish) => { + const patch = async (message: string | ethers.utils.Bytes) => { const data = ((typeof (message) === "string") ? ethers.utils.toUtf8Bytes(message) : message) const address = await signer.getAddress() - // @ts-ignore + // @ts-expect-error return signer.provider.provider.bnbSign(address, ethers.utils.hexlify(data)) .then((result) => result.signature) .catch((result) => { throw new Error(`Binance wallet bnbSign failed: ${result.error}`) }) @@ -101,5 +101,5 @@ function patchSigner(signer: ethers.Signer) { } export function isBCWallet(wallet: IWalletProvider | null) { - return wallet != null && wallet.web3.currentProvider.isBCWallet + return wallet != null && (wallet.web3.currentProvider as any).isBCWallet } diff --git a/src/store/ethereum/wallets/metamask.ts b/src/store/ethereum/wallets/metamask.ts index 5a64ca530..96f701e67 100644 --- a/src/store/ethereum/wallets/metamask.ts +++ b/src/store/ethereum/wallets/metamask.ts @@ -4,7 +4,6 @@ * @preferred */ import * as Sentry from "@sentry/browser" -import { provider as W3Provider } from "web3-providers" import { feedbackModule } from "@/feedback/store" import Web3 from "web3" import { getMetamaskSigner } from "loom-js" @@ -21,6 +20,7 @@ export const MetaMaskAdapter: WalletType = { desktop: true, mobile: false, detect: isMetamaskPresent, + async createProvider(): Promise { if (!isMetamaskPresent()) { throw new Error("no Metamask installation detected") @@ -42,7 +42,7 @@ function isMetamaskPresent() { return "ethereum" in window && window.ethereum.isMetaMask } -async function getCurrentApi(): Promise { +async function getCurrentApi(): Promise { // @ts-ignore const ethereum: any = window.ethereum try { diff --git a/src/store/ethereum/wallets/walletconnect.ts b/src/store/ethereum/wallets/walletconnect.ts index 7b6f932b1..48f2f80fe 100644 --- a/src/store/ethereum/wallets/walletconnect.ts +++ b/src/store/ethereum/wallets/walletconnect.ts @@ -1,7 +1,5 @@ -import WalletConnectProvider from "@walletconnect/web3-provider" -import { IWalletConnectProviderOptions } from "@walletconnect/types" +import { EthereumProvider } from "@walletconnect/ethereum-provider" import { getMetamaskSigner } from "loom-js" -import { Signer } from "ethers" import Web3 from "web3" import { WalletType, EthereumConfig, IWalletProvider } from "../types" @@ -15,21 +13,30 @@ export const WalletConnectAdapter: WalletType = { isMultiAccount: false, desktop: true, mobile: true, + detect() { return true }, + async createProvider(config: EthereumConfig): Promise { - const opts: IWalletConnectProviderOptions = {} - if (config.genericNetworkName === "Ethereum") { - opts.infuraId = `${process.env.INFURA_PROJECT_ID}` - } else { - opts.chainId = parseInt(config.networkId, 10) - opts.rpc = { [opts.chainId]: config.endpoint } - } - opts.bridge = "https://walletconnect.dappchains.com" - // clear our previous session so user is prompted to scan QR code - localStorage.removeItem("walletconnect") - const wcProvider = new WalletConnectProvider(opts) + // WalletConnect session restore is unreliable so clear it out every time + // a new provider is created so the user is prompted to scan QR code to connect + Object.keys(localStorage).filter(x =>x.startsWith('wc@2:')).forEach(x => localStorage.removeItem(x)) + + const chainId = parseInt(config.networkId, 10) + const wcProvider = await EthereumProvider.init({ + projectId: `${process.env.WALLETCONNECT_PROJECT_ID}`, + chains: [chainId], + rpcMap: { chainId: config.endpoint }, + showQrModal: true, // requires @walletconnect/modal + qrModalOptions: { + enableExplorer: false, + themeMode: "dark", + themeVariables: { + "--w3m-z-index": "9999", + }, + }, + }) wcProvider.on( "chainChanged", @@ -42,13 +49,14 @@ export const WalletConnectAdapter: WalletType = { wcProvider.on("accountsChanged", (accounts: string[]) => { console.log(`WalletConnect accountsChanged ${accounts}`) }) - wcProvider.on("disconnect", (code, reason) => { - console.log(`WalletConnect session disconnected, ${code}, reason ${reason}`) + wcProvider.on("disconnect", (err) => { + console.log(`WalletConnect session disconnected, ${err.code}: ${err.message}}`) window.location.reload() }) // enable session (triggers QR Code modal) await wcProvider.enable() + return { web3: new Web3(wcProvider), signer: getMetamaskSigner(wcProvider), diff --git a/src/store/ethereum/wallets/walletlink.ts b/src/store/ethereum/wallets/walletlink.ts index daf40c569..2be02b41a 100644 --- a/src/store/ethereum/wallets/walletlink.ts +++ b/src/store/ethereum/wallets/walletlink.ts @@ -1,59 +1,62 @@ import { ethers } from "ethers" import Web3 from "web3" -import WalletLink from "walletlink" +import CoinbaseWalletSDK from "@coinbase/wallet-sdk" import { WalletType, EthereumConfig, IWalletProvider } from "../types" export const WalletLinkAdapter: WalletType = { id: "walletlink", - name: "WalletLink", + name: "Coinbase Wallet", logo: require("@/assets/walletlink-logo.png"), detectable: true, isMultiAccount: false, desktop: true, mobile: true, + detect() { return true }, + async createProvider(config: EthereumConfig): Promise { const chainId = parseInt(config.networkId, 10) - const walletLink = new WalletLink({ + const walletLink = new CoinbaseWalletSDK({ appName: "Loom Network - Basechain Dashboard", }) - // In config we use websockets. Not supported by walletlink yet. + // In config we use websockets urls, but that's not supported by the Coinbase Wallet yet. + // For well known chains Coinbase Wallet should use its own endpoints, but fallback + // endpoints must be specified. // const rpcUrl = config.endpoint const rpcUrl = chainId === 1 ? `https://mainnet.infura.io/v3/${process.env.INFURA_PROJECT_ID}` : - `https://rinkeby.infura.io/v3/${process.env.INFURA_PROJECT_ID}` + undefined - const wlProvider = walletLink.makeWeb3Provider(rpcUrl, chainId) - wlProvider.enable() + if (!rpcUrl) { + throw new Error(`Coinbase Wallet not configured for ${config.networkName}`) + } + const wlProvider = walletLink.makeWeb3Provider(rpcUrl, chainId) + let accounts: string[] = [] try { accounts = await wlProvider.send("eth_requestAccounts") } catch (err) { - if (err.code === 4001) { + if ((err as any).code === 4001) { // EIP-1193 userRejectedRequest error // If this happens, the user rejected the connection request. - console.log("User rejected WalletLink connection request") + console.log("User rejected Coinbase Wallet connection request") } else { console.error(err) } } if (accounts.length === 0) { - throw new Error("Wallet is locked or the user has not connected any accounts") + throw new Error("Coinbase Wallet is locked or the user has not connected any accounts") } - const web3 = new Web3(wlProvider) - // See https://github.com/walletlink/walletlink/issues/19 - // Said to be fixed in version 2 but it seems not to be the case. - // @ts-ignore - wlProvider.on = null - Object.defineProperties(wlProvider, { isMetaMask: { value: true } }) - const signer = new ethers.providers.Web3Provider(wlProvider).getSigner(wlProvider.selectedAddress) + // @ts-expect-error missing properties in CoinbaseWalletProvider + const web3Provider = new ethers.providers.Web3Provider(wlProvider) + const signer = web3Provider.getSigner(wlProvider.selectedAddress) return { - web3, + web3: new Web3(wlProvider), signer, chainId, disconnect() { diff --git a/src/store/gateway/ethereum.ts b/src/store/gateway/ethereum.ts index 33dc1797c..eaf01ae97 100644 --- a/src/store/gateway/ethereum.ts +++ b/src/store/gateway/ethereum.ts @@ -8,16 +8,16 @@ import Axios from "axios" import BN from "bn.js" import debug from "debug" import { ethers } from "ethers" -import { CryptoUtils } from "loom-js" +import { CryptoUtils, parseSigs } from "loom-js" import { IWithdrawalReceipt } from "loom-js/dist/contracts/transfer-gateway" -import { parseSigs } from "loom-js/dist/helpers" -import { abi as GatewayABIv1, EthereumGatewayV1Factory } from "loom-js/dist/mainnet-contracts/EthereumGatewayV1Factory" -import { abi as GatewayABIv2, EthereumGatewayV2Factory } from "loom-js/dist/mainnet-contracts/EthereumGatewayV2Factory" -import { abi as ValidatorManagerV2FactoryABI } from "loom-js/dist/mainnet-contracts/ValidatorManagerV2Factory" +import { abi as GatewayABIv1, EthereumGatewayV1__factory as EthereumGatewayV1Factory } from "loom-js/dist/mainnet-contracts/factories/EthereumGatewayV1__factory" +import { abi as GatewayABIv2, EthereumGatewayV2__factory as EthereumGatewayV2Factory } from "loom-js/dist/mainnet-contracts/factories/EthereumGatewayV2__factory" +import { abi as ValidatorManagerV2FactoryABI } from "loom-js/dist/mainnet-contracts/factories/ValidatorManagerV2__factory" import { TransferGatewayTokenKind } from "loom-js/dist/proto/transfer_gateway_pb" import { from } from "rxjs" import { filter, mergeMap, tap, toArray } from "rxjs/operators" import Web3 from "web3" +import type { Contract } from "web3-eth-contract" import { AbiItem } from "web3-utils" import { ethereumModule } from "../ethereum" import { PlasmaTokenKind } from "../plasma/types" @@ -38,7 +38,7 @@ const log = debug("dash.gateway.ethereum") */ interface EthereumGatewayAdapter { token: string - contract: EthereumGatewayV2Factory | EthereumGatewayV1Factory + contract: Contract deposit(amount: BN, address: string) withdraw(receipt: IWithdrawalReceipt) @@ -48,17 +48,15 @@ interface EthereumGatewayAdapter { class ERC20GatewayAdapter implements EthereumGatewayAdapter { constructor( private vmc: ValidatorManagerContract | null, - readonly contract: EthereumGatewayV2Factory | EthereumGatewayV1Factory, + readonly contract: Contract, readonly tokenAddress: string, readonly token: string, ) { } deposit(amount: BN, address: string) { return ( - // @ts-ignore this.contract.methods .depositERC20(amount.toString(), this.tokenAddress) - // @ts-ignore .send({ from: address, }) @@ -84,13 +82,11 @@ class ERC20GatewayAdapter implements EthereumGatewayAdapter { if (this.vmc) { const { decodedSig } = await decodeSig(receipt, this.contract, this.vmc) const { valIndexes, vs, ss, rs } = decodedSig - // @ts-ignore tx = await this.contract.methods .withdrawERC20(amount, tokenAddress, valIndexes, vs, rs, ss) .send({ from: localAddress }) } else { const signature = CryptoUtils.bytesToHexAddr(receipt.oracleSignature) - // @ts-ignore tx = await this.contract.methods .withdrawERC20(amount, signature, tokenAddress) .send({ from: localAddress }) @@ -110,7 +106,7 @@ class EthGatewayAdapter implements EthereumGatewayAdapter { constructor( private vmc: ValidatorManagerContract | null, - readonly contract: EthereumGatewayV1Factory, + readonly contract: Contract, readonly tokenAddress: string, readonly web3: Web3, ) { } @@ -118,14 +114,12 @@ class EthGatewayAdapter implements EthereumGatewayAdapter { async deposit(amount: BN, sender: string) { console.log({ from: sender, - // @ts-ignore - to: this.contract._address, - value: amount.toString(), + to: this.contract.options.address, + value: amount.toString() }) return await this.web3.eth.sendTransaction({ from: sender, - // @ts-ignore - to: this.contract._address, + to: this.contract.options.address, value: amount.toString(), }) } @@ -139,14 +133,12 @@ class EthGatewayAdapter implements EthereumGatewayAdapter { if (this.vmc) { const { decodedSig } = await decodeSig(receipt, this.contract, this.vmc) const { valIndexes, vs, ss, rs } = decodedSig - // @ts-ignore return this.contract.methods.withdrawETH( amount, valIndexes, vs, rs, ss, ).send({ from: localAddress }) } else { const signature = CryptoUtils.bytesToHexAddr(receipt.oracleSignature) - // @ts-ignore return this.contract.methods.withdrawETH(amount.toString(), signature) .send({ from: localAddress }) @@ -161,18 +153,18 @@ export async function init( addresses: { mainGateway: string; loomGateway: string }, version: { main: 1 | 2, loom: 1 | 2 }, ) { + // @ts-expect-error 2322 ... readonly cannot be assigned to mutable type AbiItem[] const ERC20GatewayABI: AbiItem[] = version.loom === 2 ? GatewayABIv2 : GatewayABIv1 + // @ts-expect-error 2322 ... readonly cannot be assigned to mutable type AbiItem[]1 const GatewayABI: AbiItem[] = version.main === 2 ? GatewayABIv2 : GatewayABIv1 - // @ts-ignore const loomGateway = new web3.eth.Contract( ERC20GatewayABI, addresses.loomGateway, - ) as EthereumGatewayV2Factory + ) log("loom gateway initialized") let mainGateway: Gateway | null = null if (addresses.mainGateway !== ethers.constants.AddressZero) { - // @ts-ignore mainGateway = new web3.eth.Contract( GatewayABI as AbiItem[], addresses.mainGateway, @@ -190,6 +182,7 @@ export async function init( const vmcAddress = await vmcSourceGateway.methods.vmc().call() log("vmc address", vmcAddress) vmcContract = new web3.eth.Contract( + // @ts-expect-error 2322 ... readonly cannot be assigned to mutable type AbiItem[] ValidatorManagerV2FactoryABI, vmcAddress, ) @@ -219,8 +212,8 @@ class EthereumGateways { * @param web3 */ constructor( - readonly mainGateway: EthereumGatewayV1Factory | null, - readonly loomGateway: EthereumGatewayV2Factory, + readonly mainGateway: Contract | null, + readonly loomGateway: Contract, readonly vmc: ValidatorManagerContract | null, readonly web3: Web3, readonly version: { main: 1 | 2, loom: 1 | 2 }, @@ -282,8 +275,7 @@ export async function refreshAllowances(context: ActionContext) { filter((symbol) => symbol !== "ETH"), tap(log), mergeMap(async (symbol) => { - // @ts-ignore - const spender = gateways.get(symbol).contract._address + const spender = gateways.get(symbol).contract.options.address const amount = await ethereumModule.allowance({ symbol, spender }) return { token: tokenService.getTokenbySymbol(symbol), amount } }), @@ -336,14 +328,12 @@ export async function ethereumDeposit(context: ActionContext, funds: Funds) { fb.showLoadingBar(true) const approvalAmount = await ethereumModule.allowance({ symbol, - // @ts-ignore - spender: gateway.contract._address, + spender: gateway.contract.options.address, }) if (weiAmount.gt(approvalAmount)) { try { await ethereumModule.approve({ - // @ts-ignore - to: gateway.contract._address, + to: gateway.contract.options.address, ...funds, }) fb.showLoadingBar(false) @@ -364,8 +354,7 @@ export async function ethereumDeposit(context: ActionContext, funds: Funds) { symbol, amount: weiAmount.toString(), }), - // @ts-ignore - spender: JSON.stringify(gateway.contract._address.toString()), + spender: JSON.stringify(gateway.contract.options.address.toString()), }) Sentry.captureException(err) }) @@ -387,7 +376,7 @@ export async function ethereumDeposit(context: ActionContext, funds: Funds) { let sendToSentry = true // NOTE remove this when BSC supports websocket if (isBCWallet(context.rootState.ethereum.wallet) && - err.message.includes("Failed to subscribe to new newBlockHeaders to confirm the transaction receipts")) { + (err as any).message.includes("Failed to subscribe to new newBlockHeaders to confirm the transaction receipts")) { fb.showSuccess(i18n.t("components.gateway.deposit.confirmed").toString()) sendToSentry = false } else if ("imToken" in window) { @@ -481,12 +470,12 @@ export async function ethereumWithdraw(context: ActionContext, token_: string) { let sendToSentry = true // NOTE remove this when BSC supports websocket if (isBCWallet(context.rootState.ethereum.wallet) && - err.message.includes("Failed to subscribe to new newBlockHeaders to confirm the transaction receipts")) { + (err as any).message.includes("Failed to subscribe to new newBlockHeaders to confirm the transaction receipts")) { fb.showSuccess(i18n.t("feedback_msg.success.transaction_success").toString()) sendToSentry = false } else if ("imToken" in window) { // imToken throws even if transaction succeeds - console.log("imToken error", err, err.hash, "x", err.transactionHash) + console.log("imToken error", err, (err as any).hash, "x", (err as any).transactionHash) } else { console.error(err) fb.showError(i18n.t("feedback_msg.error.withdraw_failed").toString()) @@ -590,7 +579,7 @@ const WithdrawalPrefixes = [ async function decodeSig( receipt: IWithdrawalReceipt, - gatewayContract: EthereumGatewayV1Factory | EthereumGatewayV2Factory, + gatewayContract: Contract, ethereumVMC: ValidatorManagerContract, ) { const hash = await createWithdrawalHash(receipt, gatewayContract) @@ -613,13 +602,12 @@ async function decodeSig( */ async function createWithdrawalHash( receipt: IWithdrawalReceipt, - gatewayContract: EthereumGatewayV1Factory | EthereumGatewayV2Factory, + gatewayContract: Contract, ): Promise { const ethAddress = receipt.tokenOwner.local.toString() const tokenAddress = receipt.tokenContract!.local.toString() // ETH: gatewayAddress ? - // @ts-ignore - const gatewayAddress = gatewayContract._address + const gatewayAddress = gatewayContract.options.address const amount = receipt.value.isZero() ? receipt.tokenAmount!.toString() : receipt.value.toString() const amountHashed = receipt.tokenKind === TransferGatewayTokenKind.ETH ? ethers.utils.solidityKeccak256( @@ -633,7 +621,6 @@ async function createWithdrawalHash( if (prefix === undefined) { throw new Error("Don't know prefix for token kind " + receipt.tokenKind) } - // @ts-ignore const nonce = await gatewayContract.methods.nonces(ethAddress).call() log("hash", [prefix, ethAddress, nonce, gatewayAddress, amountHashed]) return ethers.utils.solidityKeccak256( diff --git a/src/store/gateway/index.ts b/src/store/gateway/index.ts index 2fd84c055..70133bb66 100644 --- a/src/store/gateway/index.ts +++ b/src/store/gateway/index.ts @@ -3,7 +3,6 @@ */ import debug from "debug" -import BN from "bn.js" import { getStoreBuilder } from "vuex-typex" import { GatewayState, HasGatewayState } from "./types" @@ -12,7 +11,6 @@ import * as PlasmaGateways from "./plasma" import * as EthereumGateways from "./ethereum" import * as mutations from "./mutations" import { ethereumModule } from "../ethereum" -import { TransferGatewayTokenKind } from "loom-js/dist/proto/transfer_gateway_pb" import { ActionContext } from "./types" import Axios from "axios" @@ -42,7 +40,6 @@ function initialState(): GatewayState { withdrawStateIdx: 0, maybeRelentlessUser: null, requireMapping: false, - checkMarketplaceURL: "", tokenContractLogsURL: "", ethereumMappings: { confirmed: [], @@ -89,7 +86,6 @@ export const gatewayModule = { loadMapping: builder.dispatch(Mapper.loadMapping), createMapping: builder.dispatch(Mapper.createMapping), setMaybeRelentlessUser: builder.commit(mutations.setMaybeRelentlessUser), - checkRelentlessUser: builder.dispatch(Mapper.checkRelentlessUser), // helper generateNewId: Mapper.generateNewId, diff --git a/src/store/gateway/mapper.ts b/src/store/gateway/mapper.ts index 5e0626c94..376167bc7 100644 --- a/src/store/gateway/mapper.ts +++ b/src/store/gateway/mapper.ts @@ -12,11 +12,10 @@ import { } from "loom-js" import { AddressMapper } from "loom-js/dist/contracts/address-mapper" import { ActionContext } from "./types" -import { createDefaultClient, createDefaultEthSignClientAsync } from "loom-js/dist/helpers" +import { createDefaultClient } from "loom-js" import { feedbackModule } from "@/feedback/store" import * as Sentry from "@sentry/browser" -import axios from "axios" import { i18n } from "@/i18n" const log = debug("dash.mapper") @@ -44,27 +43,27 @@ export async function loadMapping(context: ActionContext, address: string) { Address.fromString([chainId, caller].join(":")), ) try { - log("getMappingAsync", `eth:${address}`) - const mapping = await mapper.getMappingAsync( + const hasMapping = await mapper.hasMappingAsync( Address.fromString(`eth:${address}`), ) - context.state.mapping = mapping - log("got mapping", context.state.mapping) - } catch (e) { - // check if user mapping is from Relentless Marketplace - if (e.message.includes("failed to map address")) { - context.state.mapping = { - from: Address.fromString(`eth:${address}`), - to: new Address("", new LocalAddress(new Uint8Array())), - } + if (hasMapping) { + log("getMappingAsync", `eth:${address}`) + const mapping = await mapper.getMappingAsync( + Address.fromString(`eth:${address}`), + ) + context.state.mapping = mapping + log("got mapping", context.state.mapping) } else { - console.error("Failed to load mapping, response was " + e.message) - // todo feedback.showError("mapper.errors.load") + // set an empty/placeholder mapping until the real one gets created context.state.mapping = { from: Address.fromString(`eth:${address}`), to: new Address("", new LocalAddress(new Uint8Array())), } + // trigger display of AccountMappingModal + context.state.requireMapping = true } + } catch (e) { + console.error("Failed to load mapping", e) } finally { mapper.removeAllListeners() } @@ -104,7 +103,7 @@ export async function createMapping(context: ActionContext, privateKey: string) log("addIdentityMappingAsync ok ") loadMapping(context, rootState.ethereum.address) } catch (e) { - if (e.message.includes("identity mapping already exists")) { + if ((e as Error).message.includes("identity mapping already exists")) { state.requireMapping = true feedbackModule.showError(i18n.t("feedback_msg.error.supplied_key_already_mapped").toString()) } else { @@ -138,23 +137,3 @@ export function idFromPrivateKey(pk: string, chainId = "default") { const address = new Address(chainId, LocalAddress.fromPublicKey(publicKey)) return { address, privateKey, publicKey } } - -/** - * Check if user already have mapping on relentless, return in valid_address - * if valid_address = false, There is a possibility that users have logged in marketplace with wallet before. - * otherwise, it's assume that user is newcomer so new mapping will be create - */ -export async function checkRelentlessUser(context: ActionContext, address: string) { - if (context.state.checkMarketplaceURL === "") { - context.state.requireMapping = true - return - } - const checkURL = context.state.checkMarketplaceURL.replace("{address}", address) - await axios.get(checkURL).then((response) => { - context.state.maybeRelentlessUser = !response.data.valid_address - if (!context.state.maybeRelentlessUser) { - context.state.requireMapping = true - } - log("maybeRelentlessUser", context.state.maybeRelentlessUser) - }) -} diff --git a/src/store/gateway/plasma.ts b/src/store/gateway/plasma.ts index 2b23debce..032f5a5c2 100644 --- a/src/store/gateway/plasma.ts +++ b/src/store/gateway/plasma.ts @@ -329,8 +329,7 @@ export async function plasmaWithdraw(context: ActionContext, funds: Funds) { feedback.endTask() } catch (error) { console.error(error) - console.log(error, error.handled) - if (error.handled) { + if ((error as any).handled) { return } feedback.endTask() diff --git a/src/store/gateway/reactions.ts b/src/store/gateway/reactions.ts index 9fa7b86cd..9fff4e8f6 100644 --- a/src/store/gateway/reactions.ts +++ b/src/store/gateway/reactions.ts @@ -1,17 +1,13 @@ import { ethers } from "ethers" import { tokenService, TokenData } from "@/services/TokenService" -import { ERC20 } from "@/store/plasma/web3-contracts/ERC20" -import { DashboardState, Funds } from "@/types" -import BN from "bn.js" +import { DashboardState } from "@/types" import debug from "debug" import { Address } from "loom-js" import { IAddressMapping } from "loom-js/dist/contracts/address-mapper" import { Store } from "vuex" -import { EventLog } from "web3-core" import { gatewayModule } from "." import { ethereumModule } from "../ethereum" import { plasmaModule } from "../plasma" -import { EthereumGatewayV2Factory } from "loom-js/dist/mainnet-contracts/EthereumGatewayV2Factory" import * as EthereumGateways from "./ethereum" import * as PlasmaGateways from "./plasma" import { EthPlasmSigner } from "./signer" @@ -37,8 +33,6 @@ export function gatewayReactions(store: Store) { log("null mapping") // todo destroy anything that needs to be disposed of return - } else if (mapping.to.isEmpty()) { - await gatewayModule.checkRelentlessUser(mapping.from.local.toString().toLowerCase()) } else if (mapping.to!.isEmpty() === false) { Sentry.setExtra(mapping.from.chainId, mapping.from.local.toString()) @@ -49,39 +43,11 @@ export function gatewayReactions(store: Store) { const ethereumGateways = EthereumGateways.service() - // TODO: Remove this. This event listening stuff is half done, the events are fetched and - // then nothing actually looks at them or does anything useful, - // also BSC doesn't have any official websocket endpoints so this just plain doesn't - // work there. - /* - // Listen to approval & deposit events - listenToDepositApproval( - ethereumModule.state.address, - ethereumGateways.loomGateway, - ethereumModule.getERC20("LOOM")!, - ) - - listenToDeposit( - ethereumModule.state.address, - ethereumGateways.loomGateway, - ethereumModule.getERC20("LOOM")!, - ) - */ checkIncompleteTransfers() } }, ) - // store.watch( - // (s) => s.gateway.maybeRelentlessUser, - // async (maybeRelentlessUser) => { - // if (maybeRelentlessUser === false) { - // // User agree to create a new mapping - // await gatewayModule.createMapping() - // } - // }, - // ) - store.subscribeAction({ after(action) { if (/^plasma.+addToken$/.test(action.type)) { @@ -125,7 +91,7 @@ export function gatewayReactions(store: Store) { // Initialize Ethereum gateways & coin contracts try { const ethereumGateway = await EthereumGateways.init( - ethereumModule.web3, + ethereumModule.web3!, addresses, version, ) @@ -135,7 +101,7 @@ export function gatewayReactions(store: Store) { ethereumGateway.add("ETH", "") // Ether does not have a contract address } } catch (error) { - console.error("Error initializing ethereum gateways " + error.message) + console.error("Error initializing ethereum gateways " + (error as any).message) return } @@ -153,7 +119,7 @@ export function gatewayReactions(store: Store) { plasmaGateways.add("ethereum", "ETH", Address.fromString(`eth:${addresses.mainGateway}`)) } } catch (error) { - console.error("Error initializing plasma gateways " + error.message) + console.error("Error initializing plasma gateways " + (error as any).message) return } @@ -221,76 +187,3 @@ export function gatewayReactions(store: Store) { await plasmaModule.changeIdentity({ signer, address: plasmaAddress }) } } - -function listenToDepositApproval( - account: string, - gw: EthereumGatewayV2Factory, - loom: ERC20, -) { - // const approval = loom.filters.Approval(account, gw.address, null) - loom.events.Approval( - { - filter: { - from: account, - // @ts-ignore - to: gw.address, - }, - fromBlock: "latest", - }, - (error, event) => { - if (error) { - console.log(error) - return - } - log( - `transfer ${event.returnValues.value.toString()} - tokens from ${event.returnValues.from} to ${event.returnValues.to}`, - ) - const payload = formatTxFromEvent(event) - // TODO: Uncomments if using Ethers - gatewayModule.setPendingTransactions(payload) - // TODO: Clear specific hash - // gatewayModule.clearPendingTransactions() - }, - ) -} - -function listenToDeposit(account: string, gw: EthereumGatewayV2Factory, loom: ERC20) { - loom.events.Transfer( - { - filter: { - from: account, - // @ts-ignore - to: gw.address, - }, - fromBlock: "latest", - }, - (error, event) => { - if (error) { - console.log(error) - return - } - log( - `transfer ${event.returnValues.value.toString()} - tokens from ${event.returnValues.from} to ${event.returnValues.to}`, - ) - const payload = formatTxFromEvent(event) - // TODO: Uncomments if using Ethers - gatewayModule.setPendingTransactions(payload) - // TODO: Clear specific hash - // gatewayModule.clearPendingTransactions() - }, - ) -} - -function formatTxFromEvent(event: EventLog) { - const contractAddr = (event.address as string).toLowerCase() - const chain = "ethereum" - const symbol = tokenService.tokenFromAddress(contractAddr, "ethereum")!.symbol - const funds: Funds = { - chain, - symbol, - weiAmount: new BN(event.returnValues.value.toString()), - } - return { ...event, funds } -} diff --git a/src/store/gateway/signer.ts b/src/store/gateway/signer.ts index e87b6c9ce..9a067f01e 100644 --- a/src/store/gateway/signer.ts +++ b/src/store/gateway/signer.ts @@ -46,14 +46,14 @@ function initSignedEthMiddleware(signer: ethers.Signer): SignedEthTxMiddleware { feedbackModule.showInfo("") return res } catch (e) { - if (e.message.includes("User denied message")) { - feedbackModule.showError(i18n.t("messages.user_denied_sign_tx").toString()) - e.handled = true + if ((e as Error).message.includes("User denied message")) { + feedbackModule.showError(i18n.t("messages.user_denied_sign_tx").toString()); + (e as any).handled = true feedbackModule.endTask() } else { feedbackModule.showError( i18n - .t("messages.transaction_apprv_err_tx", { msg: e.message }) + .t("messages.transaction_apprv_err_tx", { msg: (e as any).message }) .toString(), ) feedbackModule.endTask() @@ -73,14 +73,14 @@ export function modifyRPCSigner(signer: ethers.Signer): ethers.Signer { feedbackModule.showInfo("") return res } catch (e) { - if (e.message.includes("User denied message")) { - feedbackModule.showError(i18n.t("messages.user_denied_sign_tx").toString()) - e.handled = true + if ((e as Error).message.includes("User denied message")) { + feedbackModule.showError(i18n.t("messages.user_denied_sign_tx").toString()); + (e as any).handled = true feedbackModule.endTask() } else { feedbackModule.showError( i18n - .t("messages.transaction_apprv_err_tx", { msg: e.message }) + .t("messages.transaction_apprv_err_tx", { msg: (e as Error).message }) .toString(), ) feedbackModule.endTask() diff --git a/src/store/gateway/types.ts b/src/store/gateway/types.ts index c78648c7a..3acafa301 100644 --- a/src/store/gateway/types.ts +++ b/src/store/gateway/types.ts @@ -2,7 +2,7 @@ import { IAddressMapping } from "loom-js/dist/contracts/address-mapper" import { IWithdrawalReceipt } from "loom-js/dist/contracts/transfer-gateway" import { BareActionContext } from "vuex-typex" import { HasEthereumState } from "../ethereum/types" -import { HasPlasmaState, PlasmaSigner } from "../plasma/types" +import { HasPlasmaState } from "../plasma/types" import BN from "bn.js" import { Contract, Address } from "loom-js" import { TokenData } from "@/services/TokenService" @@ -16,7 +16,6 @@ export interface HasGatewayState extends HasEthereumState, HasPlasmaState { export interface GatewayConfig { chains: string[] - checkMarketplaceURL: string tokenContractLogsURL: string binance: BinanceGateway withdrawalLimit: boolean diff --git a/src/store/index.ts b/src/store/index.ts index 8c036b717..e5b95ac44 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -7,17 +7,13 @@ import Vue from "vue" import Vuex, { Store } from "vuex" import { getStoreBuilder } from "vuex-typex" -import { tokenService } from "@/services/TokenService" - import "@/feedback/store" import { zbcardsReactions } from "@/store/plasma/assets/reactions" -import { airdropReactions } from "@/store/plasma/airdrop/reactions" import "./ethereum" import { ethereumModule } from "./ethereum" import { ethereumReactions } from "./ethereum/reactions" -import "./plasma" import { plasmaModule } from "./plasma" import "./gateway" @@ -78,7 +74,6 @@ function plugin(store_: Store) { dposReactions(store_) zbcardsReactions(store_) whiteListReaction(store_) - airdropReactions(store_) } export { dashboardStore, store } diff --git a/src/store/plasma/airdrop/getters.ts b/src/store/plasma/airdrop/getters.ts deleted file mode 100644 index ee3584b1b..000000000 --- a/src/store/plasma/airdrop/getters.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { AirdropState } from "./types" - -export function getAirdropInstance(state: AirdropState) { - return state.airdropContract -} diff --git a/src/store/plasma/airdrop/index.ts b/src/store/plasma/airdrop/index.ts deleted file mode 100644 index bd07f6d5e..000000000 --- a/src/store/plasma/airdrop/index.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { AirdropState, HasAirdropState, AirdropContext } from "./types" -import { getStoreBuilder } from "vuex-typex" -import * as getters from "./getters" -import * as mutations from "./mutations" - -import { AirdropDetail } from "../airdrop/types" -import { plasmaModule } from ".." -import { i18n } from "@/i18n" -import { feedbackModule } from "@/feedback/store" -import { feedbackModule as feedback } from "@/feedback/store" - -function initialState(): AirdropState { - return { - airdropContract: null, - usersAirdrops: [], - } -} - -const builder = getStoreBuilder().module( - "airdrop", - initialState(), -) -const stateGetter = builder.state() - -export const airdropModule = { - get state() { - return stateGetter() - }, - // // Getters - getAirdropInstance: builder.read(getters.getAirdropInstance), - // Mutations - setAirdropContract: builder.commit(mutations.setAirdropContract), - setUsersAirdrops: builder.commit(mutations.setUsersAirdrops), - - // // Actions - fetchAirdrop: builder.dispatch(fetchAirdrop), - withdrawAirdrop: builder.dispatch(withdrawAirdrop), - isAirdropWithdrew: builder.dispatch(isAirdropWithdrew), -} - -export async function fetchAirdrop(context: AirdropContext) { - const account = context.rootState.plasma.address - const caller = await plasmaModule.getCallerAddress() - - const airdropLength = await context.state.airdropContract!.methods.getAirdropLengthByUserAddress(account) - // @ts-ignore - .call({ from: caller.local.toString() }) - const usersAirdrops: AirdropDetail[] = [] - for (let index = 0; index < airdropLength; index++) { - const airdropObject = await context.state.airdropContract!.methods.airdropPerUser(account, index) - .call({ from: caller.local.toString() }) - const isWithdrew = await airdropModule.isAirdropWithdrew({airdropID: airdropObject.airdropID}) - airdropObject.isWithdrew = isWithdrew - usersAirdrops.push(airdropObject) - } - airdropModule.setUsersAirdrops(usersAirdrops) -} - -export async function withdrawAirdrop(context: AirdropContext, payload: {airdropID: number}) { - const caller = await plasmaModule.getCallerAddress() - try { - const tx = await context.state.airdropContract!.methods.withdrawAirdrop(payload.airdropID) - .send({ from: caller.local.toString() }) - feedback.showSuccess(i18n.t("feedback_msg.success.withdraw_airdrop_success").toString()) - } catch (error) { - if (error.message.includes("denied")) { - feedbackModule.showError(i18n.t("messages.user_denied_tx").toString()) - } else { - feedback.showError(i18n.t("feedback_msg.error.err_while_withdraw_airdrop").toString()) - } - console.error(error) - } -} - -export async function isAirdropWithdrew(context: AirdropContext, payload: {airdropID: number}) { - const caller = await plasmaModule.getCallerAddress() - const isWithdrew = await context.state.airdropContract!.methods.airdropWithdrawals(payload.airdropID) - // @ts-ignore - .call({ from: caller.local.toString() }) - return isWithdrew -} diff --git a/src/store/plasma/airdrop/mutations.ts b/src/store/plasma/airdrop/mutations.ts deleted file mode 100644 index ee9451fdd..000000000 --- a/src/store/plasma/airdrop/mutations.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Airdrop } from "./web3-contracts/Airdrop" -import { AirdropState, AirdropDetail } from "./types" - -export function setAirdropContract(state: AirdropState, payload: Airdrop) { - state.airdropContract = payload -} - -export function setUsersAirdrops(state: AirdropState, payload: AirdropDetail[]) { - state.usersAirdrops = payload -} diff --git a/src/store/plasma/airdrop/reactions.ts b/src/store/plasma/airdrop/reactions.ts deleted file mode 100644 index 558661c6f..000000000 --- a/src/store/plasma/airdrop/reactions.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Store } from "vuex" -import AirdropJSON from "@/contracts/Airdrop.json" - -import { plasmaModule } from ".." -import { Airdrop } from "@/store/plasma/airdrop/web3-contracts/Airdrop.d.ts" - -import debug from "debug" -import { DashboardState } from "@/types" -import { airdropModule } from "." - -const log = debug("ui.airdrop") - -export function airdropReactions(store: Store) { - // When a new plasma web3 instance is set, - // create new contracts - store.watch( - (state) => state.plasma.web3, - (web3) => { - if (web3 === null) { - // todo dispose of contracts if that's a thing - return - } - const envName = store.state.plasma.networkId - const airdropInstance = new web3.eth.Contract( - // @ts-ignore - AirdropJSON.abi, - AirdropJSON.networks[envName].address, - ) as Airdrop - airdropModule.setAirdropContract(airdropInstance) - log("airdropInstance", airdropInstance) - }, - ) -} diff --git a/src/store/plasma/airdrop/types.ts b/src/store/plasma/airdrop/types.ts deleted file mode 100644 index 76688a74a..000000000 --- a/src/store/plasma/airdrop/types.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { HasPlasmaState } from "../types" -import { Airdrop } from "@/store/plasma/airdrop/web3-contracts/Airdrop" -import { BareActionContext } from "vuex-typex" - -export interface HasAirdropState extends HasPlasmaState { - airdrop: AirdropState -} - -export interface AirdropState { - airdropContract: Airdrop | null, - usersAirdrops: AirdropDetail[] -} -export interface AirdropDetail { - airdropID: number, - receiver: string, - tokenAddress: string, - airdropAmount: number, - timelock: number, - isWithdrew: boolean, -} - -// helper/shorthand for plasma module action context -export declare type AirdropContext = BareActionContext< - AirdropState, - HasAirdropState -> diff --git a/src/store/plasma/airdrop/web3-contracts/Airdrop.d.ts b/src/store/plasma/airdrop/web3-contracts/Airdrop.d.ts deleted file mode 100644 index a325d01f4..000000000 --- a/src/store/plasma/airdrop/web3-contracts/Airdrop.d.ts +++ /dev/null @@ -1,161 +0,0 @@ -/* Generated by ts-generator ver. 0.0.8 */ -/* tslint:disable */ - -import { Contract, ContractTransaction, EventFilter, Signer } from "ethers"; -import { Listener, Provider } from "ethers/providers"; -import { Arrayish, BigNumber, BigNumberish, Interface } from "ethers/utils"; -import { - TransactionOverrides, - TypedEventDescription, - TypedFunctionDescription -} from "."; - -interface AirdropInterface extends Interface { - functions: { - addAirdrop: TypedFunctionDescription<{ - encode([_receiverAddress, _tokenAddress, _airdropAmount, _timelock]: [ - string, - string, - BigNumberish, - BigNumberish - ]): string; - }>; - - withdrawAirdrop: TypedFunctionDescription<{ - encode([_airdropID]: [BigNumberish]): string; - }>; - - updateAdmin: TypedFunctionDescription<{ - encode([_admin, _enable]: [string, boolean]): string; - }>; - }; - - events: { - AirdropAdded: TypedEventDescription<{ - encodeTopics([ - airdropID, - receiver, - tokenAddress, - airdropAmount, - timelock, - adder - ]: [null, null, null, null, null, null]): string[]; - }>; - - AirdropWithdrew: TypedEventDescription<{ - encodeTopics([ - airdropID, - receiver, - tokenAddress, - airdropAmount, - timelock - ]: [null, null, null, null, null]): string[]; - }>; - }; -} - -export class Airdrop extends Contract { - connect(signerOrProvider: Signer | Provider | string): Airdrop; - attach(addressOrName: string): Airdrop; - deployed(): Promise; - - on(event: EventFilter | string, listener: Listener): Airdrop; - once(event: EventFilter | string, listener: Listener): Airdrop; - addListener(eventName: EventFilter | string, listener: Listener): Airdrop; - removeAllListeners(eventName: EventFilter | string): Airdrop; - removeListener(eventName: any, listener: Listener): Airdrop; - - interface: AirdropInterface; - - functions: { - admins(arg0: string): Promise; - - airdropPerUser( - arg0: string, - arg1: BigNumberish - ): Promise<{ - airdropID: BigNumber; - receiverAddress: string; - tokenAddress: string; - airdropAmount: BigNumber; - timelock: BigNumber; - 0: BigNumber; - 1: string; - 2: string; - 3: BigNumber; - 4: BigNumber; - }>; - - airdropWithdrawals(arg0: BigNumberish): Promise; - - airdrops( - arg0: BigNumberish - ): Promise<{ - airdropID: BigNumber; - receiverAddress: string; - tokenAddress: string; - airdropAmount: BigNumber; - timelock: BigNumber; - 0: BigNumber; - 1: string; - 2: string; - 3: BigNumber; - 4: BigNumber; - }>; - - getAirdropLengthByUserAddress(_receiver: string): Promise; - - addAirdrop( - _receiverAddress: string, - _tokenAddress: string, - _airdropAmount: BigNumberish, - _timelock: BigNumberish, - overrides?: TransactionOverrides - ): Promise; - - withdrawAirdrop( - _airdropID: BigNumberish, - overrides?: TransactionOverrides - ): Promise; - - updateAdmin( - _admin: string, - _enable: boolean, - overrides?: TransactionOverrides - ): Promise; - - airdropID(): Promise; - }; - - filters: { - AirdropAdded( - airdropID: null, - receiver: null, - tokenAddress: null, - airdropAmount: null, - timelock: null, - adder: null - ): EventFilter; - - AirdropWithdrew( - airdropID: null, - receiver: null, - tokenAddress: null, - airdropAmount: null, - timelock: null - ): EventFilter; - }; - - estimate: { - addAirdrop( - _receiverAddress: string, - _tokenAddress: string, - _airdropAmount: BigNumberish, - _timelock: BigNumberish - ): Promise; - - withdrawAirdrop(_airdropID: BigNumberish): Promise; - - updateAdmin(_admin: string, _enable: boolean): Promise; - }; -} diff --git a/src/store/plasma/airdrop/web3-contracts/types.d.ts b/src/store/plasma/airdrop/web3-contracts/types.d.ts deleted file mode 100644 index 535ac0435..000000000 --- a/src/store/plasma/airdrop/web3-contracts/types.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* Generated by ts-generator ver. 0.0.8 */ -/* tslint:disable */ - -import { Transaction } from "web3-core"; -// @ts-ignore -import PromiEvent from "web3-core-promievent"; -export type Callback = (error: Error, result: T) => void; -export interface TransactionObject { - arguments: any[]; - call(tx?: Transaction): Promise; - send(tx?: Transaction): PromiEvent; - estimateGas(tx?: Transaction): Promise; - encodeABI(): string; -} diff --git a/src/store/plasma/assets/__test__/actions.spec.ts b/src/store/plasma/assets/__test__/actions.spec.ts deleted file mode 100644 index 9a3d526d0..000000000 --- a/src/store/plasma/assets/__test__/actions.spec.ts +++ /dev/null @@ -1,233 +0,0 @@ -import "mocha" -import { expect } from "chai" -import sinon from "sinon" -import { feedbackModuleStub, plasmaModuleStub } from "@/dpos/store/__test__/_helpers" -import { Address } from "loom-js" -import { AssetsState } from "../types" -import { MigratedZBGCard } from "@/contracts/types/web3-contracts/MigratedZBGCard" -import { Contract } from "web3-eth-contract" -import { assetsModule, checkCardBalance, checkPackBalance, transferCards, transferPacks } from ".." -import { PACKS_NAME } from "../reactions" - -const state: AssetsState = { - packsContract: {}, - cardContract: { - methods: { - batchTransferFrom: Function(), - tokensOwned: Function(), - }, - } as Contract as MigratedZBGCard, - cardBalance: [], - packBalance: [], - cardToTransferSelected: { - id: "0", - amount: 0, - display_name: "default", - image: "default", - title: "default", - variant: "default", - variation: "default", - mould_type: "default", - element: "default", - originalID: "default", - }, - packToTransferSelected: { - type: "Booster", - amount: 0, - }, - allCardsToTransferSelected: { - edition: "none", - cards: [], - amount: 0, - }, -} - -PACKS_NAME.forEach((type) => { - state.packsContract[type] = { - methods: { - transfer: Function(), - balanceOf: Function(), - }, - } -}) - -const address = Address.fromString("default:0x" + "".padEnd(40, "0")) -const addressString = address.local.toString() -const rootState = { - plasma: { - address: addressString, - }, -} - -describe("Transfers assets", () => { - describe("checking card balance", () => { - const tokensOwnedStub = sinon.stub(state.cardContract!.methods, "tokensOwned") - const callStub = sinon.stub().returns({ - balances: ["1", "2", "3"], - indexes: ["270", "430", "1410"], - }) - const setCardBalanceStub = sinon.stub(assetsModule, "setCardBalance") - - before(async () => { - plasmaModuleStub.getCallerAddress.reset() - plasmaModuleStub.getCallerAddress.resolves(address) - // @ts-ignore - tokensOwnedStub.returns({ - call: callStub, - }) - // @ts-ignore - await checkCardBalance({ ...{state}, ...{rootState} }) - }) - - it("calls plasmaModule.getCallerAddress", () => { - sinon.assert.calledOnce(plasmaModuleStub.getCallerAddress) - }) - it("calls cardContract.tokensOwned", () => { - sinon.assert.calledOnce(tokensOwnedStub) - sinon.assert.calledWith(tokensOwnedStub, rootState.plasma.address) - }) - it("calls TransactionObject.call", () => { - sinon.assert.calledOnce(callStub) - sinon.assert.calledWith(callStub, { from: addressString }) - }) - it("calls assetsModule.setCardBalanceStub", () => { - sinon.assert.calledOnce(setCardBalanceStub) - }) - }) - - describe("transfering cards success", () => { - const cardIds = ["0"] - const amounts = [1] - const receiver = addressString - - const batchTransferFromStub = sinon.stub(state.cardContract!.methods, "batchTransferFrom") - const sendStub = sinon.stub().returns({ transactionHash: "xxx" }) - const checkCardBalanceStub = sinon.stub(assetsModule, "checkCardBalance") - - before(async () => { - plasmaModuleStub.getCallerAddress.reset() - plasmaModuleStub.getCallerAddress.resolves(address) - // @ts-ignore - batchTransferFromStub.returns({ - send: sendStub, - }) - checkCardBalanceStub.resolves() - // @ts-ignore - await transferCards({ ...{state}, ...{rootState} }, { cardIds, amounts, receiver }) - }) - - it("calls plasmaModule.getCallerAddress", () => { - sinon.assert.calledOnce(plasmaModuleStub.getCallerAddress) - }) - it("calls cardContract.batchTransferFrom", () => { - sinon.assert.calledOnce(batchTransferFromStub) - sinon.assert.calledWith(batchTransferFromStub, addressString, receiver, cardIds, amounts) - }) - it("calls TransactionObject.send", () => { - sinon.assert.calledOnce(sendStub) - sinon.assert.calledWith(sendStub, { from: addressString }) - }) - it("calls assetsModule.checkCardBalance", () => { - sinon.assert.calledOnce(checkCardBalanceStub) - }) - it("notifies feedback modules", () => { - sinon.assert.callOrder( - feedbackModuleStub.setTask, - feedbackModuleStub.setStep, - plasmaModuleStub.getCallerAddress, - batchTransferFromStub, - sendStub, - checkCardBalanceStub, - feedbackModuleStub.endTask, - feedbackModuleStub.showSuccess, - ) - }) - }) - - describe("checking pack balance", () => { - const balanceOfStubs = [] - const callStub = sinon.stub().returns({}) - const setPackBalanceStub = sinon.stub(assetsModule, "setPackBalance") - - before(async () => { - plasmaModuleStub.getCallerAddress.reset() - plasmaModuleStub.getCallerAddress.resolves(address) - PACKS_NAME.forEach((type) => { - balanceOfStubs[type] = sinon.stub(state.packsContract[type].methods, "balanceOf") - balanceOfStubs[type].returns({ - call: callStub, - }) - }) - // @ts-ignore - await checkPackBalance({ ...{state}, ...{rootState} }) - }) - - it("calls plasmaModule.getCallerAddress", () => { - sinon.assert.calledOnce(plasmaModuleStub.getCallerAddress) - }) - it("calls packsContract.balanceOf of each type", () => { - PACKS_NAME.forEach((type) => { - sinon.assert.calledOnce(balanceOfStubs[type]) - sinon.assert.calledWith(balanceOfStubs[type], rootState.plasma.address) - }) - }) - it("calls .call", () => { - PACKS_NAME.forEach((type) => { - sinon.assert.calledWith(callStub, { from: addressString }) - }) - expect(callStub.callCount).to.equal(PACKS_NAME.length) - }) - it("calls assetsModule.setCardBalanceStub", () => { - sinon.assert.calledOnce(setPackBalanceStub) - }) - }) - - describe("transfering packs success", () => { - const packType = "booster" - const amount = 1 - const receiver = addressString - - const transferStub = sinon.stub(state.packsContract[packType].methods, "transfer") - const sendStub = sinon.stub().returns({}) - const checkPackBalanceStub = sinon.stub(assetsModule, "checkPackBalance") - - before(async () => { - plasmaModuleStub.getCallerAddress.reset() - plasmaModuleStub.getCallerAddress.resolves(address) - // @ts-ignore - transferStub.returns({ - send: sendStub, - }) - checkPackBalanceStub.resolves() - // @ts-ignore - await transferPacks({ state }, { packType, amount, receiver }) - }) - - it("calls plasmaModule.getCallerAddress", () => { - sinon.assert.calledOnce(plasmaModuleStub.getCallerAddress) - }) - it("calls cardContract.batchTransferFrom", () => { - sinon.assert.calledOnce(transferStub) - sinon.assert.calledWith(transferStub, receiver, amount) - }) - it("calls TransactionObject.send", () => { - sinon.assert.calledOnce(sendStub) - sinon.assert.calledWith(sendStub, { from: addressString }) - }) - it("calls assetsModule.checkCardBalance", () => { - sinon.assert.calledOnce(checkPackBalanceStub) - }) - it("notifies feedback modules", () => { - sinon.assert.callOrder( - feedbackModuleStub.setTask, - feedbackModuleStub.setStep, - plasmaModuleStub.getCallerAddress, - transferStub, - sendStub, - checkPackBalanceStub, - feedbackModuleStub.endTask, - feedbackModuleStub.showSuccess, - ) - }) - }) -}) diff --git a/src/store/plasma/assets/__test__/getters.spec.ts b/src/store/plasma/assets/__test__/getters.spec.ts deleted file mode 100644 index ce94cc285..000000000 --- a/src/store/plasma/assets/__test__/getters.spec.ts +++ /dev/null @@ -1,80 +0,0 @@ -import "mocha" -import { Contract } from "web3-eth-contract" -import { MigratedZBGCard } from "@/contracts/types/web3-contracts/MigratedZBGCard" -import BoosterPackJSON from "@/contracts/BoosterPack.json" -import MigratedZBGCardJSON from "@/contracts/MigratedZBGCard.json" -import packAddresses from "@/data/ZBGPackAddresses.json" -import { AssetsState } from "../types" -import { PACKS_NAME } from "@/store/plasma/assets/reactions" -import { expect } from "chai" -import * as getters from "../getters" - -const initialState = (): AssetsState => { - return { - packsContract: {}, - cardContract: null, - cardBalance: [], - packBalance: [], - cardToTransferSelected: { - id: "0", - amount: 0, - display_name: "default", - image: "default", - title: "default", - variant: "default", - variation: "default", - mould_type: "default", - element: "default", - originalID: "default", - }, - packToTransferSelected: { - type: "Booster", - amount: 0, - }, - allCardsToTransferSelected: { - edition: "none", - cards: [], - amount: 0, - }, - } -} - -describe("Game Assets, Getters", () => { - let gameAssetState: AssetsState - let packType: string[] - let contract: Contract - const envName = ["local", "asia1", "plasma"] - - before(() => { - packType = PACKS_NAME - gameAssetState = initialState() - }) - - it("getPacksInstance", () => { - const randomPack = packType[Math.floor(Math.random() * packType.length)].toString() - const randomEnv = envName[Math.floor(Math.random() * envName.length)] - // Pack contract - contract = { - jsonInterface: BoosterPackJSON.abi, - address: packAddresses[randomEnv][randomPack], - } - gameAssetState.packsContract[randomPack] = contract - const packsInstance = getters.getPacksInstance(gameAssetState) - expect(gameAssetState.packsContract).to.eql(packsInstance) - // console.log(packsInstance) - }) - - it.skip("getCardInstance", () => { - // for environment on MigratedZBGCard, there is no 'local' env - envName.shift() - const randomEnv = envName[Math.floor(Math.random() * envName.length)] - // Card contract - contract = { - jsonInterface: MigratedZBGCardJSON.abi, - address: MigratedZBGCardJSON.networks[randomEnv].address, - } - gameAssetState.cardContract = (contract as MigratedZBGCard) - const cardInstance = getters.getCardInstance(gameAssetState) - expect(gameAssetState.cardContract).to.eql(cardInstance) - }) -}) diff --git a/src/store/plasma/assets/__test__/mutations.spec.ts b/src/store/plasma/assets/__test__/mutations.spec.ts deleted file mode 100644 index 1b85928e7..000000000 --- a/src/store/plasma/assets/__test__/mutations.spec.ts +++ /dev/null @@ -1,128 +0,0 @@ -// init asset state from index.ts -import "mocha" -import { CardDetail, PackDetail } from "../../types" -import { Contract } from "web3-eth-contract" -import { MigratedZBGCard } from "@/contracts/types/web3-contracts/MigratedZBGCard" -import BoosterPackJSON from "@/contracts/BoosterPack.json" -import MigratedZBGCardJSON from "@/contracts/MigratedZBGCard.json" -import packAddresses from "@/data/ZBGPackAddresses.json" -import { AssetsState } from "../types" -import { PACKS_NAME } from "@/store/plasma/assets/reactions" -import * as mutations from "../mutations" -import { expect } from "chai" - -const initialState = (): AssetsState => { - return { - packsContract: {}, - cardContract: null, - cardBalance: [], - packBalance: [], - cardToTransferSelected: { - id: "0", - amount: 0, - display_name: "default", - image: "default", - title: "default", - variant: "default", - variation: "default", - mould_type: "default", - element: "default", - originalID: "default", - }, - packToTransferSelected: { - type: "Booster", - amount: 0, - }, - allCardsToTransferSelected: { - edition: "none", - cards: [], - amount: 0, - }, - } -} - -describe("Game Assets, Mutations", () => { - let gameAssetState: AssetsState - let packType: string[] - let contract: Contract - const envName = ["local", "asia1", "plasma"] - const exCard: CardDetail = { - id: "1", - amount: 1, - display_name: "Example", - image: "Example", - title: "Example", - variant: "Example edition", - variation: "Example", - mould_type: "Example", - element: "Air", - originalID: "Example", - } - const exPack: PackDetail = { - type: "Booster", - amount: 1, - } - - before(() => { - packType = PACKS_NAME - gameAssetState = initialState() - }) - - it("setPackContract by a random pack type and environment", () => { - const randomPack = packType[Math.floor(Math.random() * packType.length)].toString() - const randomEnv = envName[Math.floor(Math.random() * envName.length)] - // Pack contract - contract = { - jsonInterface: BoosterPackJSON.abi, - address: packAddresses[randomEnv][randomPack], - } - mutations.setPacksContract(gameAssetState, { name: randomPack, contract }) - expect(gameAssetState.packsContract).to.eql({ [randomPack]: contract }) - }) - - it("setCardContract by random environment", () => { - const randomEnv = envName[Math.floor(Math.random() * (envName.length - 1)) + 1] - // Card contract - contract = { - jsonInterface: MigratedZBGCardJSON.abi, - address: MigratedZBGCardJSON.networks[randomEnv].address, - } - mutations.setCardContract(gameAssetState, contract as MigratedZBGCard) - expect(gameAssetState.cardContract).to.eql(contract) - }) - - it("setCardBalance", () => { - const exCardDetail: CardDetail[] = [] - exCardDetail.push(exCard) - mutations.setCardBalance(gameAssetState, exCardDetail) - expect(gameAssetState.cardBalance).to.eql(exCardDetail) - }) - - it("setPackBalance", () => { - const exPackDetail: PackDetail[] = [] - exPackDetail.push(exPack) - mutations.setPackBalance(gameAssetState, exPackDetail) - expect(gameAssetState.packBalance).to.eql(exPackDetail) - }) - - it("setCardToTransferSelected", () => { - mutations.setCardToTransferSelected(gameAssetState, exCard) - expect(gameAssetState.cardToTransferSelected).to.eql(exCard) - }) - - it("setPackToTransferSelected", () => { - mutations.setPackToTransferSelected(gameAssetState, exPack) - expect(gameAssetState.packToTransferSelected).to.eql(exPack) - }) - - it("setAllCardsToTransferSelected", () => { - const exCardDetail: CardDetail[] = [exCard] - const allCard = { - edition: "Standard Edition", - cards: exCardDetail, - amount: 1, - } - mutations.setAllCardsToTransferSelected(gameAssetState, allCard) - expect(gameAssetState.allCardsToTransferSelected).to.eql(allCard) - }) -}) diff --git a/src/store/plasma/assets/index.ts b/src/store/plasma/assets/index.ts index 51e3104d6..6507cdae9 100644 --- a/src/store/plasma/assets/index.ts +++ b/src/store/plasma/assets/index.ts @@ -145,12 +145,12 @@ export async function transferCards( ) } catch (error) { feedbackModule.endTask() - if (error.message.includes("denied")) { + if ((error as Error).message.includes("denied")) { feedbackModule.showError(i18n.t("messages.user_denied_tx").toString()) } else { feedbackModule.showError( i18n - .t("messages.transfer_card_err_tx", { msg: error.message }) + .t("messages.transfer_card_err_tx", { msg: (error as Error).message }) .toString(), ) throw error @@ -190,12 +190,12 @@ export async function transferPacks( ) } catch (error) { feedbackModule.endTask() - if (error.message.includes("denied")) { + if ((error as Error).message.includes("denied")) { feedbackModule.showError(i18n.t("messages.user_denied_tx").toString()) } else { feedbackModule.showError( i18n - .t("messages.transfer_pack_err_tx", { msg: error.message }) + .t("messages.transfer_pack_err_tx", { msg: (error as Error).message }) .toString(), ) throw error diff --git a/src/store/plasma/assets/mutations.ts b/src/store/plasma/assets/mutations.ts index 1210a8781..8ce546d43 100644 --- a/src/store/plasma/assets/mutations.ts +++ b/src/store/plasma/assets/mutations.ts @@ -1,7 +1,6 @@ -import { PlasmaState, CardDetail, PackDetail } from "../types" +import { CardDetail, PackDetail } from "../types" import { Contract } from "web3-eth-contract" import { MigratedZBGCard } from "@/contracts/types/web3-contracts/MigratedZBGCard" -import { BoosterPack } from "./web3-contracts/BoosterPack" import { AssetsState } from "./types" export function setPacksContract( diff --git a/src/store/plasma/assets/reactions.ts b/src/store/plasma/assets/reactions.ts index 679c335e6..c1cc54afc 100644 --- a/src/store/plasma/assets/reactions.ts +++ b/src/store/plasma/assets/reactions.ts @@ -1,10 +1,8 @@ -import { HasPlasmaState } from "../types" import { Store } from "vuex" import MigratedZBGCardJSON from "@/contracts/MigratedZBGCard.json" import BoosterPackJSON from "@/contracts/BoosterPack.json" import packAddresses from "@/data/ZBGPackAddresses.json" -import { plasmaModule } from ".." import { MigratedZBGCard } from "@/contracts/types/web3-contracts/MigratedZBGCard" import debug from "debug" diff --git a/src/store/plasma/helpers.ts b/src/store/plasma/helpers.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/store/plasma/index.ts b/src/store/plasma/index.ts index c612b527d..02d81ed5e 100644 --- a/src/store/plasma/index.ts +++ b/src/store/plasma/index.ts @@ -14,7 +14,7 @@ import { i18n } from "@/i18n" import { setupProtocolsFromEndpoint, createDefaultTxMiddleware, -} from "loom-js/dist/helpers" +} from "loom-js" // assets (make this a separate module) @@ -224,7 +224,7 @@ async function refreshHistory(context: PlasmaContext) { } }) } catch (e) { - console.error("Error loading plasma history. " + e.message) + console.error("Error loading plasma history. " + (e as Error).message) } // example entry diff --git a/src/store/plasma/mutations.ts b/src/store/plasma/mutations.ts index 7d98cad6a..d25c90429 100644 --- a/src/store/plasma/mutations.ts +++ b/src/store/plasma/mutations.ts @@ -1,8 +1,4 @@ -import { PlasmaState, CardDetail, PackDetail } from "./types" -import { Contract } from "web3-eth-contract" -import { MigratedZBGCard } from "@/contracts/types/web3-contracts/MigratedZBGCard" -import { UserDeployerWhitelist } from "loom-js/dist/contracts" -import { UserDeployerState } from "loom-js/dist/proto/user_deployer_whitelist_pb" +import { PlasmaState } from "./types" import BN from "bn.js" export function setBalance( diff --git a/src/store/plasma/reactions.ts b/src/store/plasma/reactions.ts index 25a746b85..06353b073 100644 --- a/src/store/plasma/reactions.ts +++ b/src/store/plasma/reactions.ts @@ -7,13 +7,11 @@ import BN from "bn.js" import Web3 from "web3" import * as Tokens from "./tokens" -import { Web3Provider } from "ethers/providers" import { ethers } from "ethers" import { publicKeyFromPrivateKey } from "loom-js/dist/crypto-utils" import { DashboardState } from "@/types" import debug from "debug" -import { tokenService } from "@/services/TokenService" const log = debug("dash.plasma") /** @@ -104,7 +102,7 @@ async function createPlasmaWeb3(store: Store) { : await createLoomProvider(client!, signer, genericKey) // @ts-ignore store.state.plasma.web3 = new Web3(loomProvider) - store.state.plasma.ethersProvider = new Web3Provider(loomProvider) + store.state.plasma.ethersProvider = new ethers.providers.Web3Provider(loomProvider) } async function createLoomProvider( diff --git a/src/store/plasma/tokens.ts b/src/store/plasma/tokens.ts index 502b437bc..2201a1440 100644 --- a/src/store/plasma/tokens.ts +++ b/src/store/plasma/tokens.ts @@ -9,7 +9,7 @@ import { } from "./types" import { plasmaModule } from "." import BN from "bn.js" -import { abi as ERC20ABI } from "loom-js/dist/mainnet-contracts/ERC20Factory" +import { abi as ERC20ABI } from "loom-js/dist/mainnet-contracts/factories/ERC20__factory" import debug from "debug" import { setNewTokenToLocalStorage, ZERO } from "@/utils" import { tokenService, TokenData } from "@/services/TokenService" @@ -109,7 +109,7 @@ export class CoinAdapter implements ContractAdapter { class ERC20Adapter implements ContractAdapter { constructor(readonly token: string, public contract: ERC20) { } get contractAddress() { - return this.contract.address.toLocaleLowerCase() + return this.contract.options.address.toLocaleLowerCase() } async balanceOf(account: string) { const caller = await plasmaModule.getCallerAddress() @@ -170,6 +170,7 @@ export async function addToken(context: PlasmaContext, payload: { token: TokenDa log("add token state ", state.coins) let contract try { + // @ts-ignore-next-line contract = new web3.eth.Contract(ERC20ABI, token.plasma) as ERC20 await addContract(token.symbol, PlasmaTokenKind.ERC20, contract) } catch (error) { @@ -263,13 +264,13 @@ export async function approve( await adapter.approve(to, approvalAmount) return true } catch (error) { - if (error.message.includes("User denied message")) { + if ((error as any).message.includes("User denied message")) { feedbackModule.showError(i18n.t("messages.user_denied_sign_tx").toString()) feedbackModule.endTask() } else { feedbackModule.showError( i18n - .t("messages.transaction_apprv_err_tx", { msg: error.message }) + .t("messages.transaction_apprv_err_tx", { msg: (error as any).message }) .toString(), ) feedbackModule.endTask() diff --git a/src/store/plasma/types.ts b/src/store/plasma/types.ts index a9a9b8b7e..e97128373 100644 --- a/src/store/plasma/types.ts +++ b/src/store/plasma/types.ts @@ -3,7 +3,7 @@ import BN from "bn.js" import { Client, LoomProvider } from "loom-js" import Web3 from "web3" import { BareActionContext } from "vuex-typex" -import { Provider } from "ethers/providers" +import { ethers } from "ethers" export interface PlasmaConfig { networkId: string @@ -24,7 +24,7 @@ export interface PlasmaState extends PlasmaConfig { provider: LoomProvider | null // for normal contracts web3: Web3 | null - ethersProvider: Provider | null + ethersProvider: ethers.providers.Provider | null address: string signer: PlasmaSigner | null history: any[] diff --git a/src/store/plasma/web3-contracts/ERC20.d.ts b/src/store/plasma/web3-contracts/ERC20.d.ts deleted file mode 100644 index 9265e1921..000000000 --- a/src/store/plasma/web3-contracts/ERC20.d.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* Generated by ts-generator ver. 0.0.8 */ -/* tslint:disable */ - -import { Contract, ContractOptions, Options } from "web3-eth-contract" -import { Block } from "web3-eth" -import { EventLog } from "web3-core" -import { EventEmitter } from "events" -import { Callback, TransactionObject } from "./types" - -export class ERC20 extends Contract { - constructor(jsonInterface: any[], address?: string, options?: ContractOptions) - methods: { - balanceOf(_who: string): TransactionObject - - allowance(_owner: string, _spender: string): TransactionObject - - transfer(_to: string, _value: number | string): TransactionObject - - transferFrom( - _from: string, - _to: string, - _value: number | string - ): TransactionObject - - approve( - _spender: string, - _value: number | string - ): TransactionObject - - totalSupply(): TransactionObject - } - events: { - Approval( - options?: { - filter?: object - fromBlock?: number | string - topics?: (null | string)[] - }, - cb?: Callback - ): EventEmitter - - Transfer( - options?: { - filter?: object - fromBlock?: number | string - topics?: (null | string)[] - }, - cb?: Callback - ): EventEmitter - - allEvents: ( - options?: { - filter?: object - fromBlock?: number | string - topics?: (null | string)[] - }, - cb?: Callback - ) => EventEmitter - } - address: string -} diff --git a/src/store/plasma/web3-contracts/ERC20.ts b/src/store/plasma/web3-contracts/ERC20.ts new file mode 100644 index 000000000..a44fae0b7 --- /dev/null +++ b/src/store/plasma/web3-contracts/ERC20.ts @@ -0,0 +1,89 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import type BN from "bn.js"; +import type { ContractOptions } from "web3-eth-contract"; +import type { EventLog } from "web3-core"; +import type { EventEmitter } from "events"; +import type { + Callback, + PayableTransactionObject, + NonPayableTransactionObject, + BlockType, + ContractEventLog, + BaseContract, +} from "./types"; + +export interface EventOptions { + filter?: object; + fromBlock?: BlockType; + topics?: string[]; +} + +export type Approval = ContractEventLog<{ + owner: string; + spender: string; + value: string; + 0: string; + 1: string; + 2: string; +}>; +export type Transfer = ContractEventLog<{ + from: string; + to: string; + value: string; + 0: string; + 1: string; + 2: string; +}>; + +export interface ERC20 extends BaseContract { + constructor( + jsonInterface: any[], + address?: string, + options?: ContractOptions + ): ERC20; + clone(): ERC20; + methods: { + totalSupply(): NonPayableTransactionObject; + + balanceOf(_who: string): NonPayableTransactionObject; + + transfer( + _to: string, + _value: number | string | BN + ): NonPayableTransactionObject; + + allowance( + _owner: string, + _spender: string + ): NonPayableTransactionObject; + + transferFrom( + _from: string, + _to: string, + _value: number | string | BN + ): NonPayableTransactionObject; + + approve( + _spender: string, + _value: number | string | BN + ): NonPayableTransactionObject; + }; + events: { + Approval(cb?: Callback): EventEmitter; + Approval(options?: EventOptions, cb?: Callback): EventEmitter; + + Transfer(cb?: Callback): EventEmitter; + Transfer(options?: EventOptions, cb?: Callback): EventEmitter; + + allEvents(options?: EventOptions, cb?: Callback): EventEmitter; + }; + + once(event: "Approval", cb: Callback): void; + once(event: "Approval", options: EventOptions, cb: Callback): void; + + once(event: "Transfer", cb: Callback): void; + once(event: "Transfer", options: EventOptions, cb: Callback): void; +} diff --git a/src/store/plasma/web3-contracts/index.ts b/src/store/plasma/web3-contracts/index.ts new file mode 100644 index 000000000..063d2fbc4 --- /dev/null +++ b/src/store/plasma/web3-contracts/index.ts @@ -0,0 +1,4 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +export type { ERC20 } from "./ERC20"; diff --git a/src/store/plasma/web3-contracts/types.d.ts b/src/store/plasma/web3-contracts/types.d.ts deleted file mode 100644 index 535ac0435..000000000 --- a/src/store/plasma/web3-contracts/types.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* Generated by ts-generator ver. 0.0.8 */ -/* tslint:disable */ - -import { Transaction } from "web3-core"; -// @ts-ignore -import PromiEvent from "web3-core-promievent"; -export type Callback = (error: Error, result: T) => void; -export interface TransactionObject { - arguments: any[]; - call(tx?: Transaction): Promise; - send(tx?: Transaction): PromiEvent; - estimateGas(tx?: Transaction): Promise; - encodeABI(): string; -} diff --git a/src/store/plasma/web3-contracts/types.ts b/src/store/plasma/web3-contracts/types.ts new file mode 100644 index 000000000..2431788c4 --- /dev/null +++ b/src/store/plasma/web3-contracts/types.ts @@ -0,0 +1,73 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type BN from "bn.js"; +import type { EventEmitter } from "events"; +import type { EventLog, PromiEvent, TransactionReceipt } from "web3-core/types"; +import type { Contract } from "web3-eth-contract"; + +export interface EstimateGasOptions { + from?: string; + gas?: number; + value?: number | string | BN; +} + +export interface EventOptions { + filter?: object; + fromBlock?: BlockType; + topics?: string[]; +} + +export type Callback = (error: Error, result: T) => void; +export interface ContractEventLog extends EventLog { + returnValues: T; +} +export interface ContractEventEmitter extends EventEmitter { + on(event: "connected", listener: (subscriptionId: string) => void): this; + on( + event: "data" | "changed", + listener: (event: ContractEventLog) => void + ): this; + on(event: "error", listener: (error: Error) => void): this; +} + +export interface NonPayableTx { + nonce?: string | number | BN; + chainId?: string | number | BN; + from?: string; + to?: string; + data?: string; + gas?: string | number | BN; + maxPriorityFeePerGas?: string | number | BN; + maxFeePerGas?: string | number | BN; + gasPrice?: string | number | BN; +} + +export interface PayableTx extends NonPayableTx { + value?: string | number | BN; +} + +export interface NonPayableTransactionObject { + arguments: any[]; + call(tx?: NonPayableTx, block?: BlockType): Promise; + send(tx?: NonPayableTx): PromiEvent; + estimateGas(tx?: NonPayableTx): Promise; + encodeABI(): string; +} + +export interface PayableTransactionObject { + arguments: any[]; + call(tx?: PayableTx, block?: BlockType): Promise; + send(tx?: PayableTx): PromiEvent; + estimateGas(tx?: PayableTx): Promise; + encodeABI(): string; +} + +export type BlockType = + | "latest" + | "pending" + | "genesis" + | "earliest" + | number + | BN; +export type BaseContract = Omit; diff --git a/src/types.ts b/src/types.ts index f6a8a7d63..ef54a3f4e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,14 +1,11 @@ import BN from "bn.js" -import { Client, DPOSUserV3, Address } from "loom-js" -import { AddressMapper, DPOS3 } from "loom-js/dist/contracts" -import { Contract } from "web3-eth-contract" +import { Address } from "loom-js" import { HasDPOSState, DPOSConfig } from "@/dpos/store/types" import { EthereumConfig } from "./store/ethereum/types" import { HasGatewayState, GatewayConfig } from "@/store/gateway/types" import { PlasmaConfig } from "@/store/plasma/types" import { HasWhiteListState } from "@/whitelist/store/types" import { HasAssetsState } from "./store/plasma/assets/types" -import { HasAirdropState } from "./store/plasma/airdrop/types" export interface DashboardConfig { name: string @@ -35,8 +32,7 @@ export interface DashboardState extends HasGatewayState, HasDPOSState, HasWhiteListState, - HasAssetsState, - HasAirdropState { + HasAssetsState { env: string envs: DashboardConfig[] disabled: string[] diff --git a/src/views/MobileAccount.vue b/src/views/MobileAccount.vue index 2634de89c..34b79e1ca 100644 --- a/src/views/MobileAccount.vue +++ b/src/views/MobileAccount.vue @@ -58,7 +58,6 @@ - @@ -95,7 +94,6 @@ import { plasmaModule } from "../store/plasma" import ElectionTimer from "@/dpos/components/ElectionTimer.vue" import Delegations from "@/dpos/components/Delegations.vue" import { Subscription, timer } from "rxjs" -import Airdrop from "@/dpos/components/Airdrop.vue" import OtherDelegations from "@/dpos/components/OtherDelegations.vue" const log = debug("mobileaccount") @@ -107,7 +105,6 @@ const log = debug("mobileaccount") Rewards, ElectionTimer, Delegations, - Airdrop, OtherDelegations, }, }) diff --git a/src/whitelist/store/__test__/actions.spec.ts b/src/whitelist/store/__test__/actions.spec.ts index 2489a5c61..a16a937f7 100644 --- a/src/whitelist/store/__test__/actions.spec.ts +++ b/src/whitelist/store/__test__/actions.spec.ts @@ -2,12 +2,10 @@ import "mocha" import { plasmaModuleStub, feedbackModuleStub } from "@/dpos/store/__test__/_helpers" import { Address, LocalAddress, CryptoUtils, Client } from "loom-js" import { TierID } from "loom-js/dist/proto/user_deployer_whitelist_pb" -import { generateMnemonic, mnemonicToSeedSync } from "bip39" import BN from "bn.js" import { UserDeployerWhitelist } from "loom-js/dist/contracts" -import { WhiteListState, DeployerAddress, DeployedContractAddress } from "../types" +import { WhiteListState } from "../types" import { ITier, IDeployer, IDeployedContract } from "loom-js/dist/contracts/user-deployer-whitelist" -import { sha256 } from "js-sha256" import sinon from "sinon" import { TransferRequest } from "@/store/plasma/types" import { diff --git a/src/whitelist/store/index.ts b/src/whitelist/store/index.ts index 7daa229ec..1280c3741 100644 --- a/src/whitelist/store/index.ts +++ b/src/whitelist/store/index.ts @@ -21,7 +21,6 @@ import { WhiteListContext, } from "@/whitelist/store/types" import * as mutations from "./mutations" -import { async } from "rxjs/internal/scheduler/async" const log = debug("whitelist") @@ -132,10 +131,10 @@ export async function addDeployer( ) } catch (error) { log("addDeployerAsync error", error) - let errorMessage = error.message - if (error.message.includes("User denied message")) { + let errorMessage = (error as Error).message + if (errorMessage.includes("User denied message")) { errorMessage = i18n.t("messages.user_denied_sign_tx").toString() - } else if (error.message.includes("deployer already exists")) { + } else if (errorMessage.includes("deployer already exists")) { errorMessage = i18n.t("messages.deployer_already_exists").toString() } feedbackModule.showError( diff --git a/src/whitelist/views/AddKey.vue b/src/whitelist/views/AddKey.vue index 6720565fd..db8c8d4ad 100644 --- a/src/whitelist/views/AddKey.vue +++ b/src/whitelist/views/AddKey.vue @@ -152,19 +152,17 @@