├── static ├── .gitkeep ├── Icon.icns ├── icon.ico ├── logo.ico ├── logo.png ├── icon_16x16.png ├── icon_32x32.png ├── iconMessage.ico ├── iconMessage.png ├── icon_128x128.png ├── icon_16x16@2x.png ├── icon_256x256.png ├── icon_32x32@2x.png ├── iconTransparent.ico ├── iconTransparent.png ├── icon_128x128@2x.png ├── icon_256x256@2x.png ├── iconMessageNotWin.png ├── iconMessageNotWin@2x.png ├── iconMessageNotWin@3x.png ├── iconTransparentNotWin.png ├── iconTransparentNotWin@2x.png └── iconTransparentNotWin@3x.png ├── connector.dll ├── connector.dylib ├── .env.example ├── .eslintignore ├── test ├── .eslintrc ├── e2e │ ├── specs │ │ ├── Launch.spec.js │ │ ├── deviceManager.spec.js │ │ └── api.spec.js │ ├── index.js │ └── utils.js └── unit │ ├── specs │ └── page.spec.js │ ├── index.js │ └── karma.conf.js ├── src ├── proto │ ├── substrate.proto │ ├── common.proto │ ├── tron.proto │ ├── cosmos.proto │ ├── eth.proto │ ├── filecoin.proto │ ├── btcfork.proto │ ├── eos.proto │ ├── btc.proto │ ├── device.proto │ ├── api.proto │ ├── substrate_pb.js │ └── common_pb.js ├── renderer │ ├── store │ │ ├── index.js │ │ └── dapps.js │ ├── App.vue │ ├── router │ │ └── index.js │ ├── main.js │ ├── views │ │ ├── appStart.vue │ │ └── welcomeHome.vue │ └── common │ │ └── lang │ │ └── zh.js ├── main │ └── index.dev.js ├── index.ejs ├── worker.ejs ├── common │ ├── path.js │ └── constants.js └── api │ ├── loadFail.html │ ├── crypto.js │ ├── callimkeycore.js │ ├── ethereumdapp_imkey_web3.js │ ├── polkadotdapp.js │ └── ethereumdapp.js ├── .gitignore ├── appveyor.yml ├── .eslintrc.js ├── protobuild.sh ├── .babelrc ├── README.md ├── .travis.yml ├── .electron-vue ├── dev-client.js ├── webpack.main.config.js ├── build.js ├── dev-runner.js ├── webpack.web.config.js └── webpack.renderer.config.js ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── package.json └── LICENSE /static/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /connector.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/connector.dll -------------------------------------------------------------------------------- /connector.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/connector.dylib -------------------------------------------------------------------------------- /static/Icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/Icon.icns -------------------------------------------------------------------------------- /static/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/icon.ico -------------------------------------------------------------------------------- /static/logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/logo.ico -------------------------------------------------------------------------------- /static/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/logo.png -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | bindCode_encryptionKey= 2 | TEAM_SHORT_NAME= 3 | APPLE_ID= 4 | APPLE_ID_PASSWORD= 5 | -------------------------------------------------------------------------------- /static/icon_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/icon_16x16.png -------------------------------------------------------------------------------- /static/icon_32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/icon_32x32.png -------------------------------------------------------------------------------- /static/iconMessage.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/iconMessage.ico -------------------------------------------------------------------------------- /static/iconMessage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/iconMessage.png -------------------------------------------------------------------------------- /static/icon_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/icon_128x128.png -------------------------------------------------------------------------------- /static/icon_16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/icon_16x16@2x.png -------------------------------------------------------------------------------- /static/icon_256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/icon_256x256.png -------------------------------------------------------------------------------- /static/icon_32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/icon_32x32@2x.png -------------------------------------------------------------------------------- /static/iconTransparent.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/iconTransparent.ico -------------------------------------------------------------------------------- /static/iconTransparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/iconTransparent.png -------------------------------------------------------------------------------- /static/icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/icon_128x128@2x.png -------------------------------------------------------------------------------- /static/icon_256x256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/icon_256x256@2x.png -------------------------------------------------------------------------------- /static/iconMessageNotWin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/iconMessageNotWin.png -------------------------------------------------------------------------------- /static/iconMessageNotWin@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/iconMessageNotWin@2x.png -------------------------------------------------------------------------------- /static/iconMessageNotWin@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/iconMessageNotWin@3x.png -------------------------------------------------------------------------------- /static/iconTransparentNotWin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/iconTransparentNotWin.png -------------------------------------------------------------------------------- /static/iconTransparentNotWin@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/iconTransparentNotWin@2x.png -------------------------------------------------------------------------------- /static/iconTransparentNotWin@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/consenlabs/imkey-manager/HEAD/static/iconTransparentNotWin@3x.png -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | test/unit/coverage/** 2 | test/unit/*.js 3 | test/e2e/*.js 4 | src/proto/** 5 | src/api/devicemanagerapi.js 6 | src/api/walletapi.js 7 | src/api/imkey_web3_provider.js -------------------------------------------------------------------------------- /test/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "mocha": true 4 | }, 5 | "globals": { 6 | "assert": true, 7 | "expect": true, 8 | "should": true, 9 | "__static": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/proto/substrate.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package substrateapi; 3 | 4 | message SubstrateRawTxIn { 5 | string rawData = 1; 6 | } 7 | 8 | message SubstrateTxOut { 9 | string signature = 1; 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | dist/electron/* 3 | dist/web/* 4 | build/* 5 | !build/icons 6 | node_modules/ 7 | npm-debug.log 8 | npm-debug.log.* 9 | thumbs.db 10 | imkey-desktop.iml 11 | !.gitkeep 12 | .idea/ 13 | yarn-error.log 14 | key.env 15 | key.env.prod 16 | 17 | .env 18 | -------------------------------------------------------------------------------- /src/proto/common.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package common; 3 | 4 | import "google/protobuf/any.proto"; 5 | message SignParam { 6 | string chainType = 1; 7 | string path = 2; 8 | string network = 3; 9 | google.protobuf.Any input = 4; 10 | string payment = 5; 11 | string receiver = 6; 12 | string sender = 7; 13 | string fee = 8; 14 | } -------------------------------------------------------------------------------- /src/proto/tron.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package tronapi; 3 | 4 | message TronTxInput { 5 | string raw_data = 2; 6 | } 7 | 8 | message TronTxOutput { 9 | string signature = 1; 10 | } 11 | 12 | message TronMessageInput { 13 | string message = 2; 14 | bool is_hex =4; 15 | bool is_tron_header=5; 16 | } 17 | 18 | message TronMessageOutput { 19 | string signature = 1; 20 | } -------------------------------------------------------------------------------- /test/e2e/specs/Launch.spec.js: -------------------------------------------------------------------------------- 1 | // import utils from '../utils' 2 | // 3 | // describe('Launch', function () { 4 | // beforeEach(utils.beforeEach) 5 | // afterEach(utils.afterEach) 6 | // 7 | // it('shows the proper application title', function () { 8 | // return this.app.client.getTitle() 9 | // .then(title => { 10 | // expect(title).to.equal('{{ name }}') 11 | // }) 12 | // }) 13 | // }) 14 | -------------------------------------------------------------------------------- /test/unit/specs/page.spec.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import stepPage from '../../../src/renderer/views/steps/step' 3 | 4 | describe('step.vue', () => { 5 | it('should render correct contents', () => { 6 | const vm = new Vue({ 7 | el: document.createElement('div'), 8 | render: h => h(stepPage) 9 | }).$mount() 10 | 11 | expect(vm.$el.querySelector('.title').textContent).to.contain('连接') 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /test/e2e/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | // Set BABEL_ENV to use proper .env config 4 | process.env.BABEL_ENV = 'test' 5 | 6 | // Enable use of ES6+ on required files 7 | require('@babel/register')({ 8 | ignore: [/node_modules/] 9 | }) 10 | 11 | // Attach Chai APIs to global scope 12 | let { expect,should,assert } = require('chai') 13 | global.expect = expect 14 | global.should = should 15 | global.assert = assert 16 | 17 | // Require all JS files in `./specs` for Mocha to consume 18 | require('require-dir')('./specs') 19 | -------------------------------------------------------------------------------- /src/proto/cosmos.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package cosmosapi; 3 | 4 | message Coin { 5 | string amount = 1; 6 | string denom = 2; 7 | } 8 | 9 | message StdFee { 10 | repeated Coin amount = 1; 11 | string gas = 2; 12 | } 13 | 14 | 15 | message CosmosTxInput { 16 | string account_number = 1; 17 | string chain_id = 2; 18 | StdFee fee = 3; 19 | string memo = 4; 20 | string msgs = 5; 21 | string sequence = 6; 22 | } 23 | 24 | message CosmosTxOutput { 25 | string signature = 1; 26 | string txHash = 2; 27 | } 28 | -------------------------------------------------------------------------------- /src/proto/eth.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package ethapi; 3 | 4 | message EthTxInput { 5 | string nonce = 1; 6 | string gas_price = 2; 7 | string gas_limit = 3; 8 | string to = 4; 9 | string value = 5; 10 | string data = 6; 11 | string chain_id = 7; 12 | } 13 | 14 | message EthTxOutput { 15 | string signature = 1; 16 | string txHash = 2; 17 | } 18 | 19 | message EthMessageInput { 20 | string message = 1; 21 | bool isPersonalSign = 2; 22 | } 23 | 24 | message EthMessageOutput { 25 | string signature = 1; 26 | } -------------------------------------------------------------------------------- /test/e2e/utils.js: -------------------------------------------------------------------------------- 1 | import electron from 'electron' 2 | import { Application } from 'spectron' 3 | 4 | export default { 5 | afterEach () { 6 | this.timeout(10000) 7 | 8 | if (this.app && this.app.isRunning()) { 9 | return this.app.stop() 10 | } 11 | }, 12 | beforeEach () { 13 | this.timeout(10000) 14 | this.app = new Application({ 15 | path: electron, 16 | args: ['dist/electron/main.js'], 17 | startTimeout: 10000, 18 | waitTimeout: 10000 19 | }) 20 | 21 | return this.app.start() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 0.1.{build} 2 | 3 | branches: 4 | only: 5 | - master 6 | 7 | image: Visual Studio 2019 8 | platform: 9 | - x64 10 | 11 | cache: 12 | - node_modules 13 | - '%APPDATA%\npm-cache' 14 | - '%USERPROFILE%\.electron' 15 | - '%USERPROFILE%\AppData\Local\Yarn\cache' 16 | 17 | init: 18 | - git config --global core.autocrlf input 19 | 20 | install: 21 | - ps: Install-Product node 12 x64 22 | - git reset --hard HEAD 23 | - yarn 24 | - node --version 25 | 26 | build_script: 27 | #- yarn build 28 | - npm run release 29 | 30 | test: off 31 | -------------------------------------------------------------------------------- /test/unit/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | Vue.config.devtools = false 3 | Vue.config.productionTip = false 4 | 5 | // require all test files (files that ends with .spec.js) 6 | const testsContext = require.context('./specs', true, /\.spec$/) 7 | testsContext.keys().forEach(testsContext) 8 | 9 | // require all src files except main.js for coverage. 10 | // you can also change this to match only the subset of files that 11 | // you want coverage for. 12 | const srcContext = require.context('../../src/renderer', true, /^\.\/(?!main(\.js)?$)/) 13 | srcContext.keys().forEach(srcContext) 14 | -------------------------------------------------------------------------------- /src/proto/filecoin.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package filecoinapi; 3 | 4 | message FilecoinTxInput { 5 | string to = 1; 6 | string from = 2; 7 | uint64 nonce = 3; 8 | string value = 4; 9 | int64 gasLimit = 5; 10 | string gasFeeCap = 6; 11 | string gasPremium = 7; 12 | uint64 method = 8; 13 | string params = 9; 14 | } 15 | 16 | message FilecoinTxOutput { 17 | string cid = 1; 18 | FilecoinTxInput message = 2; 19 | Signature signature = 3; 20 | } 21 | 22 | message Signature { 23 | uint32 type = 1; 24 | string data = 2; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: 'babel-eslint', 4 | parser: 'vue-eslint-parser', 5 | parserOptions: { 6 | sourceType: 'module' 7 | }, 8 | env: { 9 | browser: true, 10 | node: true 11 | }, 12 | extends: 'standard', 13 | globals: { 14 | __static: true 15 | }, 16 | plugins: [ 17 | 'html' 18 | ], 19 | 'rules': { 20 | // allow paren-less arrow functions 21 | 'arrow-parens': 0, 22 | // allow async-await 23 | 'generator-star-spacing': 0, 24 | // allow debugger during development 25 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/proto/btcfork.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package btcforkapi; 3 | 4 | message Utxo { 5 | string txHash = 1; 6 | int32 vout = 2; 7 | int64 amount = 3; 8 | string address = 4; 9 | string scriptPubKey = 5; 10 | string derivedPath = 6; 11 | int64 sequence = 7; 12 | } 13 | 14 | message BtcForkTxInput { 15 | string to = 1; 16 | int64 amount = 2; 17 | repeated Utxo unspents = 3; 18 | int64 fee = 4; 19 | uint32 changeAddressIndex = 5; 20 | string changeAddress = 6; 21 | string segWit = 7; 22 | } 23 | 24 | message BtcForkTxOutput { 25 | string signature = 1; 26 | string txHash = 2; 27 | string wtxHash = 3; 28 | } -------------------------------------------------------------------------------- /src/renderer/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | 4 | Vue.use(Vuex) 5 | 6 | export default new Vuex.Store({ 7 | state: { 8 | agree: true, 9 | message: '', 10 | activeStatus: '', 11 | apps: [], 12 | isCosUpdate: false, 13 | cosOldVersionData: '', 14 | cosNewVersionData: '', 15 | bleOldVersionData: '', 16 | bleNewVersionData: '', 17 | buttonTexts: '', 18 | userPath: '', 19 | isFirstGoToManagerPage: true, 20 | WalletAddress: [], 21 | installedBleVersion: '' 22 | }, 23 | mutations: {}, 24 | actions: {}, 25 | modules: {}, 26 | accounts: ['0xa6c82cf246f820f70d3c11b1b518b2d0eaca3258'] 27 | }) 28 | -------------------------------------------------------------------------------- /protobuild.sh: -------------------------------------------------------------------------------- 1 | cd src/proto 2 | protoc --js_out=import_style=commonjs,binary:. api.proto 3 | protoc --js_out=import_style=commonjs,binary:. btc.proto 4 | protoc --js_out=import_style=commonjs,binary:. btcfork.proto 5 | protoc --js_out=import_style=commonjs,binary:. cosmos.proto 6 | protoc --js_out=import_style=commonjs,binary:. device.proto 7 | protoc --js_out=import_style=commonjs,binary:. eos.proto 8 | protoc --js_out=import_style=commonjs,binary:. eth.proto 9 | protoc --js_out=import_style=commonjs,binary:. common.proto 10 | protoc --js_out=import_style=commonjs,binary:. filecoin.proto 11 | protoc --js_out=import_style=commonjs,binary:. substrate.proto 12 | protoc --js_out=import_style=commonjs,binary:. tron.proto 13 | cd ../../ 14 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "comments": false, 3 | "env": { 4 | "test": { 5 | "presets": [ 6 | ["@babel/env", { 7 | "targets": { "node": 12 } 8 | }], 9 | ], 10 | "plugins": ["istanbul"] 11 | }, 12 | "main": { 13 | "presets": [ 14 | ["@babel/env", { 15 | "targets": { "node": 12 } 16 | }], 17 | ] 18 | }, 19 | "renderer": { 20 | "presets": [ 21 | ["@babel/env", { 22 | "modules": false 23 | }], 24 | ] 25 | }, 26 | "web": { 27 | "presets": [ 28 | ["@babel/env", { 29 | "modules": false 30 | }], 31 | ] 32 | } 33 | }, 34 | "plugins": ["@babel/plugin-transform-runtime"] 35 | } 36 | -------------------------------------------------------------------------------- /src/proto/eos.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package eosapi; 3 | 4 | message EosTxInput { 5 | repeated EosSignData transactions = 1; 6 | } 7 | 8 | message EosSignData { 9 | string txHex = 1; 10 | repeated string publicKeys = 2; 11 | string chainId = 3; 12 | string receiver = 4; 13 | string payment = 5; 14 | string sender = 6; 15 | } 16 | 17 | message EosTxOutput { 18 | repeated EosSignResult trans_multi_signs = 1; 19 | } 20 | 21 | message EosSignResult { 22 | string hash = 1; 23 | repeated string signs = 2; 24 | } 25 | 26 | 27 | message EosMessageInput { 28 | string data = 1; 29 | string pubkey = 2; 30 | bool isHex = 3; 31 | } 32 | 33 | message EosMessageOutput { 34 | string signature = 1; 35 | } -------------------------------------------------------------------------------- /src/main/index.dev.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is used specifically and only for development. It installs 3 | * `electron-debug` & `vue-devtools`. There shouldn't be any need to 4 | * modify this file, but it can be used to extend your development 5 | * environment. 6 | */ 7 | 8 | /* eslint-disable */ 9 | 10 | // Install `electron-debug` with `devtron` 11 | require('electron-debug')({showDevTools: true}) 12 | 13 | // Install `vue-devtools` 14 | require('electron').app.on('ready', () => { 15 | let installExtension = require('electron-devtools-installer') 16 | installExtension.default(installExtension.VUEJS_DEVTOOLS) 17 | .then(() => { 18 | }) 19 | .catch(err => { 20 | console.log('Unable to install `vue-devtools`: \n', err) 21 | }) 22 | }) 23 | 24 | // Require `main` process to boot app 25 | require('./index') -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # imKey Manager Tool 2 | 3 | Desktop management tools for imKey wallet 4 | 5 | WARNING: not production ready yet. 6 | 7 | ## Goals 8 | * Unify interface for wallet common logic with multi blockchain support 9 | * Cross platform, on macos, linux, windows 10 | 11 | ## Layout 12 | * `.electron-vue` compile and package scripts 13 | * `build` build reference files 14 | * `dist` compilation output directory 15 | * `src ` project core code 16 | * `static` static file directory 17 | 18 | ## Code Styles 19 | This project is using pre-commit. Please install the git pre-commit hooks on you clone. 20 | 21 | Every time you will try to commit, pre-commit will run checks on your files to make sure they follow our style standards 22 | and they aren't affected by some simple issues. If the checks fail, pre-commit won't let you commit. 23 | 24 | ## License 25 | Apache Licence v2.0 26 | -------------------------------------------------------------------------------- /src/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |访问出错,请检查你的网络连接
7 | 8 | -------------------------------------------------------------------------------- /src/renderer/App.vue: -------------------------------------------------------------------------------- 1 | 2 |
13 |
14 | I expected to see this happen:
15 |
16 | Instead, this happened:
17 |
18 | ## Meta
19 |
20 | `rustc --version --verbose`:
21 |
22 | Backtrace:
23 | ```
24 |
25 | ## Submit Pull Request
26 |
27 | Pull requests are major way to contribute an opensource project. Github has a detailed explaination about [Pull Request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests).
28 |
29 | ## Code Style
30 |
31 | We expect run `cargo fmt` before code commit. Follow rust community [code style guide](https://github.com/rust-dev-tools/fmt-rfcs/blob/master/guide/guide.md).
32 |
33 | CI server already setup to check style on CI build. We recommand you turn on code auto format for you IDE or editor plugin, follow [this](https://github.com/rust-lang/rustfmt#running-rustfmt-from-your-editor) rustfmt document.
34 |
35 | ## CI
36 |
37 | Code submitted must pass all unit tests and static analysis ("lint") checks. We use Travis CI to test code on Linux, macOS.
38 |
39 | For failing CI builds, the issue may not be related to the PR itself. Such failures are usually related to flaky tests. These failures can be ignored (authors don't need to fix unrelated issues), but please file a GH issue so the test gets fixed eventually.
40 |
41 | ## Commit Message
42 |
43 | We follow a rough convention for commit message writing.
44 |
45 | First line is the subject line, in around 50 charactors or less to describe what changed. And the body of the commit should describe why changed.
46 |
47 | Template:
48 |
49 | ```
50 | Changes in around 50 charactors or less
51 |
52 | Longer explanation of the change in the commit. You can use
53 | multiple sentences here. It's usually best to include content
54 | from the PR description in the final commit message.
55 |
56 | issue notices, e.g. "Fixes #42, Resolve #123, See also #456".
57 | ```
58 |
59 |
--------------------------------------------------------------------------------
/src/proto/device.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package deviceapi;
3 |
4 | message AppDownloadReq {
5 | string app_name = 1;
6 | }
7 |
8 | message AppDownloadRes {
9 | repeated string address_register_list = 1;
10 | }
11 |
12 | message AppUpdateReq {
13 | string app_name = 1;
14 | }
15 |
16 | message AppUpdateRes {
17 | repeated string address_register_list = 1;
18 | }
19 |
20 | message AppDeleteReq {
21 | string app_name = 1;
22 | }
23 |
24 | // check_update api
25 | message CheckUpdateRes {
26 | string se_id = 1;
27 | string sn = 2;
28 | string status = 3;
29 | string sdk_mode = 4;
30 | repeated AvailableAppBean available_app_list = 5;
31 | }
32 |
33 | message AvailableAppBean {
34 | string app_name = 1;
35 | string app_logo = 2;
36 | string installed_version = 3;
37 | string last_updated = 4;
38 | string latest_version = 5;
39 | string install_mode = 6;
40 | }
41 |
42 | message BindCheckRes {
43 | string bind_status = 1;
44 | }
45 |
46 | message BindAcquireReq {
47 | string bind_code = 1;
48 | }
49 |
50 | message BindAcquireRes {
51 | string bind_result = 1;
52 | }
53 |
54 | message GetSeidRes {
55 | string seid = 1;
56 | }
57 |
58 | message GetSnRes {
59 | string sn = 1;
60 | }
61 |
62 | message GetRamSizeRes {
63 | string ram_size = 1;
64 | }
65 |
66 | message GetFirmwareVersionRes {
67 | string firmware_version = 1;
68 | }
69 |
70 | message GetBatteryPowerRes {
71 | string battery_power = 1;
72 | }
73 |
74 | message GetLifeTimeRes {
75 | string life_time = 1;
76 | }
77 |
78 | message GetBleNameRes {
79 | string ble_name = 1;
80 | }
81 |
82 | message SetBleNameReq {
83 | string ble_name = 1;
84 | }
85 |
86 | message GetBleVersionRes {
87 | string ble_version = 1;
88 | }
89 |
90 | message GetSdkInfoRes {
91 | string sdk_version = 1;
92 | }
93 |
94 | message DeviceConnectReq {
95 | string device_model_name = 1;
96 | }
97 |
98 | message CosCheckUpdateRes {
99 | string seid = 1;
100 | bool is_latest = 2;
101 | string latest_cos_version = 3;
102 | string latest_ble_version = 4;
103 | string update_type = 5;
104 | string description = 6;
105 | bool is_update_success = 7;
106 | }
107 |
108 | message IsBlStatusRes {
109 | bool check_result = 1;
110 | }
--------------------------------------------------------------------------------
/src/proto/api.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package api;
3 |
4 | import "google/protobuf/any.proto";
5 |
6 | // Action Wrapper
7 | // There is a `call_imkey_api` method in tcx which act as a endpoint like RPC. It accepts a `ImkeyAction` param which method field is
8 | // the real action and param field is the real param of that method.
9 | // When an error occurred, the `call_imkey_api` will return a `Response` which isSuccess field be false and error field is the reason
10 | // which cause the error.
11 | message ImkeyAction {
12 | string method = 1;
13 | google.protobuf.Any param = 2;
14 | }
15 |
16 | // A common response when error occurred.
17 | message ErrorResponse {
18 | bool isSuccess = 1;
19 | string error = 2;
20 | }
21 |
22 | //A commonresponse when successfully ended.
23 | message CommonResponse{
24 | string result = 1;
25 | }
26 |
27 | message AddressParam {
28 | string chainType = 1;
29 | string path = 2;
30 | string network = 3;
31 | bool isSegWit = 4;
32 | }
33 |
34 | message AddressResult {
35 | string path = 1;
36 | string chainType = 2;
37 | string address = 3;
38 | }
39 |
40 | message PubKeyParam {
41 | string chainType = 1;
42 | string path = 2;
43 | string network = 3;
44 | string isSegWit = 4;
45 | }
46 |
47 | message PubKeyResult {
48 | string path = 1;
49 | string chainType = 2;
50 | string pubKey = 3;
51 | string derivedMode = 4;
52 | }
53 |
54 | message ExternalAddress {
55 | string address = 1;
56 | string derivedPath = 2;
57 | string type = 3;
58 | }
59 |
60 |
61 | message BitcoinWallet {
62 | string path = 1;
63 | string chainType = 2;
64 | string address = 3;
65 | string encXPub = 4;
66 | ExternalAddress externalAddress = 5;
67 | }
68 |
69 |
70 | message EosWallet {
71 | string chainType = 1;
72 | string address = 2;
73 | message PubKeyInfo {
74 | string path = 1;
75 | string derivedMode = 2;
76 | string publicKey = 3;
77 | }
78 | repeated PubKeyInfo publicKeys = 3;
79 | }
80 |
81 |
82 | message ExternalAddressParam {
83 | string path = 1;
84 | string chainType = 2;
85 | string network = 3;
86 | string segWit = 4;
87 | int32 externalIdx = 5;
88 | }
89 |
90 | message InitImKeyCoreXParam {
91 | string fileDir = 1;
92 | string xpubCommonKey = 2;
93 | string xpubCommonIv = 3;
94 | bool isDebug = 4;
95 | string system = 5;
96 | string terminalType = 6;
97 | string sdkVersion = 7;
98 | string serverUrl = 8;
99 | }
100 |
101 | message BtcForkWallet {
102 | string path = 1;
103 | string chainType = 2;
104 | string address = 3;
105 | string encXPub = 4;
106 | }
--------------------------------------------------------------------------------
/src/renderer/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import router from './router'
4 | import store from './store'
5 | import ElementUI from 'element-ui'
6 | import 'element-ui/lib/theme-chalk/index.css'
7 | import VueI18n from 'vue-i18n'
8 | import '@fortawesome/fontawesome-free/css/all.css' // Ensure you are using css-loader
9 | const { ipcRenderer } = require('electron') // Renderer process modules
10 | // const { screen } = remote // Main process modules
11 | // const devInnerHeight = 1080.0 // 开发时的InnerHeight
12 | // const devDevicePixelRatio = 1.0// 开发时的devicepixelratio
13 | // const devScaleFactor = 1.3 // 开发时的ScaleFactor
14 | // const scaleFactor = screen.getPrimaryDisplay().scaleFactor
15 | // const zoomFactor = (window.innerHeight / devInnerHeight) * (window.devicePixelRatio / devDevicePixelRatio) * (devScaleFactor / scaleFactor)
16 | // ipcRenderer.send('zoomIn', zoomFactor)
17 | let callbackCache
18 | Vue.prototype.$ipcRenderer = {
19 | send: (msgType, msgData) => {
20 | ipcRenderer.send('message-from-renderer', {
21 | type: msgType,
22 | data: msgData
23 | })
24 | },
25 | on: (type, callback) => {
26 | callbackCache = {
27 | type,
28 | callback
29 | }
30 | }
31 | }
32 | ipcRenderer.on('message-to-renderer', (sender, msg) => {
33 | if (callbackCache.type === msg.type) {
34 | callbackCache.callback(msg.data)
35 | }
36 | }) // 监听主进程的消息
37 | Vue.config.productionTip = false
38 | Vue.prototype.$store = store
39 | Vue.prototype.router = router
40 | Vue.use(ElementUI)
41 | Vue.use(VueI18n)
42 | // 弹出框禁止滑动
43 | Vue.prototype.noScroll = function () {
44 | const mo = function (e) {
45 | e.preventDefault()
46 | }
47 | document.body.style.overflow = 'hidden'
48 | // 禁止页面滑动
49 | document.addEventListener('touchmove', mo, false)
50 | }
51 |
52 | // 弹出框可以滑动
53 | Vue.prototype.canScroll = function () {
54 | const mo = function (e) {
55 | e.preventDefault()
56 | }
57 | // 出现滚动条
58 | document.body.style.overflow = ''
59 | document.removeEventListener('touchmove', mo, false)
60 | }
61 | // 获取系统语言,根据系统语言来切换语言
62 | const app = require('electron').remote.app
63 | let sysLocale = app.getLocale()
64 | if (sysLocale !== 'zh-CN') {
65 | sysLocale = 'en-US'
66 | }
67 |
68 | // VueI18n
69 | const i18n = new VueI18n({
70 | // 默认中文
71 | // locale: 'zh-CN',
72 | // locale: 'en-US',
73 | // this.$i18n.locale // 通过切换locale的值来实现语言切换
74 | // 获取系统语言,根据系统语言来切换语言
75 | locale: sysLocale,
76 | messages: {
77 | // 语言包路径
78 | 'zh-CN': require('./common/lang/zh'),
79 | 'en-US': require('./common/lang/en')
80 | }
81 | })
82 |
83 | new Vue({
84 | i18n,
85 | router,
86 | store,
87 | render: h => h(App)
88 | }).$mount('#app')
89 | // vue 项目在路由切换的时候调用
90 | router.beforeEach(function (to, from, next) {
91 | next()
92 | let eventName = ''
93 | let toName = ''
94 | if (from.name === 'welcomeHome') {
95 | if (to.name === 'manager') {
96 | eventName = 'im_homepage$manage'
97 | toName = 'im_manage'
98 | }
99 | if (to.name === 'setting') {
100 | eventName = 'im_homepage$setting'
101 | toName = 'im_setting'
102 | }
103 | }
104 | if (from.name === 'manager') {
105 | if (to.name === 'welcomeHome') {
106 | eventName = 'im_manage$homepage'
107 | toName = 'im_homepage'
108 | }
109 | if (to.name === 'setting') {
110 | eventName = 'im_manage$setting'
111 | toName = 'im_setting'
112 | }
113 | }
114 | if (from.name === 'setting') {
115 | if (to.name === 'welcomeHome') {
116 | eventName = 'im_setting$homepage'
117 | toName = 'im_homepage'
118 | }
119 | if (to.name === 'manager') {
120 | eventName = 'im_setting$manage'
121 | toName = 'im_manage'
122 | }
123 | }
124 | })
125 |
--------------------------------------------------------------------------------
/.electron-vue/build.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | process.env.NODE_ENV = 'production'
4 |
5 | const {say} = require('cfonts')
6 | const chalk = require('chalk')
7 | const del = require('del')
8 | const {spawn} = require('child_process')
9 | const webpack = require('webpack')
10 | const Multispinner = require('multispinner')
11 |
12 |
13 | const mainConfig = require('./webpack.main.config')
14 | const rendererConfig = require('./webpack.renderer.config')
15 | const webConfig = require('./webpack.web.config')
16 |
17 | const doneLog = chalk.bgGreen.white(' DONE ') + ' '
18 | const errorLog = chalk.bgRed.white(' ERROR ') + ' '
19 | const okayLog = chalk.bgBlue.white(' OKAY ') + ' '
20 | const isCI = process.env.CI || false
21 |
22 | if (process.env.BUILD_TARGET === 'clean') clean()
23 | else if (process.env.BUILD_TARGET === 'web') web()
24 | else build()
25 |
26 | function clean() {
27 | del.sync(['build/*', '!build/icons', '!build/icons/icon.*'])
28 | console.log(`\n${doneLog}\n`)
29 | process.exit()
30 | }
31 |
32 | function build() {
33 | greeting()
34 |
35 | del.sync(['dist/electron/*', '!.gitkeep'])
36 |
37 | const tasks = ['main', 'renderer']
38 | const m = new Multispinner(tasks, {
39 | preText: 'building',
40 | postText: 'process'
41 | })
42 |
43 | let results = ''
44 |
45 | m.on('success', () => {
46 | process.stdout.write('\x1B[2J\x1B[0f')
47 | console.log(`\n\n${results}`)
48 | console.log(`${okayLog}take it away ${chalk.yellow('`electron-builder`')}\n`)
49 | process.exit()
50 | })
51 |
52 | pack(mainConfig).then(result => {
53 | results += result + '\n\n'
54 | m.success('main')
55 | }).catch(err => {
56 | m.error('main')
57 | console.log(`\n ${errorLog}failed to build main process`)
58 | console.error(`\n${err}\n`)
59 | process.exit(1)
60 | })
61 |
62 | pack(rendererConfig).then(result => {
63 | results += result + '\n\n'
64 | m.success('renderer')
65 | }).catch(err => {
66 | m.error('renderer')
67 | console.log(`\n ${errorLog}failed to build renderer process`)
68 | console.error(`\n${err}\n`)
69 | process.exit(1)
70 | })
71 | }
72 |
73 | function pack(config) {
74 | return new Promise((resolve, reject) => {
75 | config.mode = 'production'
76 | webpack(config, (err, stats) => {
77 | if (err) reject(err.stack || err)
78 | else if (stats.hasErrors()) {
79 | let err = ''
80 |
81 | stats.toString({
82 | chunks: false,
83 | colors: true
84 | })
85 | .split(/\r?\n/)
86 | .forEach(line => {
87 | err += ` ${line}\n`
88 | })
89 |
90 | reject(err)
91 | } else {
92 | resolve(stats.toString({
93 | chunks: false,
94 | colors: true
95 | }))
96 | }
97 | })
98 | })
99 | }
100 |
101 | function web() {
102 | del.sync(['dist/web/*', '!.gitkeep'])
103 | webConfig.mode = 'production'
104 | webpack(webConfig, (err, stats) => {
105 | if (err || stats.hasErrors()) console.log(err)
106 |
107 | console.log(stats.toString({
108 | chunks: false,
109 | colors: true
110 | }))
111 |
112 | process.exit()
113 | })
114 | }
115 |
116 | function greeting() {
117 | const cols = process.stdout.columns
118 | let text = ''
119 |
120 | if (cols > 85) text = 'lets-build'
121 | else if (cols > 60) text = 'lets-|build'
122 | else text = false
123 |
124 | if (text && !isCI) {
125 | say(text, {
126 | colors: ['yellow'],
127 | font: 'simple3d',
128 | space: false
129 | })
130 | } else console.log(chalk.yellow.bold('\n lets-build'))
131 | console.log()
132 | }
133 |
--------------------------------------------------------------------------------
/src/renderer/views/appStart.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
15 |
16 |
17 | {{$t('m.imKeyManager.imKey_manager')}}
18 | {{$t('m.imKeyManager.your_imKey_manager')}}
19 |
20 |
21 |
22 | {{$t('m.imKeyManager.no_have_imKey_pro')}}
23 |
24 |
25 |
26 |
54 |
104 |
--------------------------------------------------------------------------------
/.electron-vue/dev-runner.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | const chalk = require('chalk')
4 | const electron = require('electron')
5 | const path = require('path')
6 | const fs = require('fs')
7 | const {say} = require('cfonts')
8 | const {spawn} = require('child_process')
9 | const webpack = require('webpack')
10 | const WebpackDevServer = require('webpack-dev-server')
11 | const webpackHotMiddleware = require('webpack-hot-middleware')
12 |
13 | const mainConfig = require('./webpack.main.config')
14 | const rendererConfig = require('./webpack.renderer.config')
15 |
16 | let electronProcess = null
17 | let manualRestart = false
18 | let hotMiddleware
19 |
20 | function logStats(proc, data) {
21 | let log = ''
22 |
23 | log += chalk.yellow.bold(`┏ ${proc} Process ${new Array((19 - proc.length) + 1).join('-')}`)
24 | log += '\n\n'
25 |
26 | if (typeof data === 'object') {
27 | data.toString({
28 | colors: true,
29 | chunks: false
30 | }).split(/\r?\n/).forEach(line => {
31 | log += ' ' + line + '\n'
32 | })
33 | } else {
34 | log += ` ${data}\n`
35 | }
36 |
37 | log += '\n' + chalk.yellow.bold(`┗ ${new Array(28 + 1).join('-')}`) + '\n'
38 |
39 | console.log(log)
40 | }
41 |
42 | function startRenderer() {
43 | return new Promise((resolve, reject) => {
44 | rendererConfig.entry.renderer = [path.join(__dirname, 'dev-client')].concat(rendererConfig.entry.renderer)
45 | rendererConfig.mode = 'development'
46 | const compiler = webpack(rendererConfig)
47 | hotMiddleware = webpackHotMiddleware(compiler, {
48 | log: false,
49 | heartbeat: 2500
50 | })
51 |
52 | // compiler.hooks.compilation.tap('compilation', compilation => {
53 | // compilation.hooks.htmlWebpackPluginAfterEmit.tapAsync('html-webpack-plugin-after-emit', (data, cb) => {
54 | // hotMiddleware.publish({action: 'reload'})
55 | // cb()
56 | // })
57 | // })
58 | compiler.hooks.compilation.tap('html-webpack-plugin-after-emit', () => {
59 | hotMiddleware.publish({
60 | action: 'reload'
61 | });
62 | });
63 | compiler.hooks.done.tap('done', stats => {
64 | logStats('Renderer', stats)
65 | })
66 |
67 | const server = new WebpackDevServer(
68 | compiler,
69 | {
70 | contentBase: path.join(__dirname, '../'),
71 | quiet: true,
72 | before(app, ctx) {
73 | app.use(hotMiddleware)
74 | ctx.middleware.waitUntilValid(() => {
75 | resolve()
76 | })
77 | }
78 | }
79 | )
80 |
81 | server.listen(9080)
82 | })
83 | }
84 |
85 | function startMain() {
86 | return new Promise((resolve, reject) => {
87 | mainConfig.entry.main = [path.join(__dirname, '../src/main/index.dev.js')].concat(mainConfig.entry.main)
88 | mainConfig.mode = 'development'
89 | const compiler = webpack(mainConfig)
90 |
91 | compiler.hooks.watchRun.tapAsync('watch-run', (compilation, done) => {
92 | logStats('Main', chalk.white.bold('compiling...'))
93 | hotMiddleware.publish({action: 'compiling'})
94 | done()
95 | })
96 |
97 | compiler.watch({}, (err, stats) => {
98 | if (err) {
99 | console.log(err)
100 | return
101 | }
102 |
103 | logStats('Main', stats)
104 |
105 | if (electronProcess && electronProcess.kill) {
106 | manualRestart = true
107 | process.kill(electronProcess.pid)
108 | electronProcess = null
109 | startElectron()
110 |
111 | setTimeout(() => {
112 | manualRestart = false
113 | }, 5000)
114 | }
115 |
116 | resolve()
117 | })
118 | })
119 | }
120 |
121 | function startElectron() {
122 | var args = [
123 | // 为了方便调试chrome://inspect,本地调试用,此代码不能提交
124 | // '--inspect-brk=5858',
125 | path.join(__dirname, '../dist/electron/main.js')
126 | ]
127 |
128 | // detect yarn or npm and process commandline args accordingly
129 | if (process.env.npm_execpath.endsWith('yarn.js')) {
130 | args = args.concat(process.argv.slice(3))
131 | } else if (process.env.npm_execpath.endsWith('npm-cli.js')) {
132 | args = args.concat(process.argv.slice(2))
133 | }
134 |
135 | electronProcess = spawn(electron, args)
136 |
137 | electronProcess.stdout.on('data', data => {
138 | electronLog(data, 'blue')
139 | })
140 | electronProcess.stderr.on('data', data => {
141 | electronLog(data, 'red')
142 | })
143 |
144 | electronProcess.on('close', () => {
145 | if (!manualRestart) process.exit()
146 | })
147 | }
148 |
149 | function electronLog(data, color) {
150 | let log = ''
151 | data = data.toString().split(/\r?\n/)
152 | data.forEach(line => {
153 | log += ` ${line}\n`
154 | })
155 | if (/[0-9A-z]+/.test(log)) {
156 | console.log(
157 | chalk[color].bold('┏ Electron -------------------') +
158 | '\n\n' +
159 | log +
160 | chalk[color].bold('┗ ----------------------------') +
161 | '\n'
162 | )
163 | }
164 | }
165 |
166 |
167 | function greeting() {
168 | const cols = process.stdout.columns
169 | let text = ''
170 |
171 | if (cols > 104) text = 'electron-vue'
172 | else if (cols > 76) text = 'electron-|vue'
173 | else text = false
174 |
175 | if (text) {
176 | say(text, {
177 | colors: ['yellow'],
178 | font: 'simple3d',
179 | space: false
180 | })
181 | } else console.log(chalk.yellow.bold('\n electron-vue'))
182 | console.log(chalk.blue(' getting ready...') + '\n')
183 | }
184 |
185 | function init() {
186 | greeting()
187 | // example
188 | fs.createReadStream(path.join(__dirname,'../connector.dylib')).pipe(fs.createWriteStream(path.join(__dirname, '../dist/electron/connector.dylib')));
189 | fs.createReadStream(path.join(__dirname,'../connector.dll')).pipe(fs.createWriteStream(path.join(__dirname, '../dist/electron/connector.dll')));
190 | Promise.all([startRenderer(), startMain()])
191 | .then(() => {
192 | startElectron()
193 | })
194 | .catch(err => {
195 | console.error(err)
196 | })
197 | }
198 |
199 | init()
200 |
--------------------------------------------------------------------------------
/src/common/constants.js:
--------------------------------------------------------------------------------
1 | // sdk version
2 | const sdkVersion = '2.10.3'
3 | // serverurl
4 | // const serverUrl = 'https://imkeyserver.com:10444/imkey'
5 | const serverUrl = 'https://imkey.online:1000/imkey'
6 | // Terminaltype
7 | const terminalType = 'PC'
8 | // Battery is charging sign
9 | const BATTERY_CHARGING_SIGN = 'FF'
10 |
11 | // 设备初始化 80
12 | const LIFE_TIME_DEVICE_INITED = 'life_time_device_inited'
13 | // 已激活 89
14 | const LIFE_TIME_DEVICE_ACTIVATED = 'life_time_device_activated'
15 | // pin未设置 81
16 | const LIFE_TIME_UNSET_PIN = 'life_time_unset_pin'
17 | // 钱包unready 83
18 | const LIFE_TIME_WALLET_UNREADY = 'life_time_wallet_unready'
19 | // 钱包创建中 84
20 | const LIFE_TIME_WALLET_CREATTING = 'life_time_wallet_creatting'
21 | // 钱包恢复中 85
22 | const LIFE_TIME_WALLET_RECOVERING = 'life_time_wallet_recovering'
23 | // 钱包创建完成 86
24 | const LIFE_TIME_WALLET_READY = 'life_time_wallet_ready'
25 | // 未知
26 | const LIFE_TIME_UNKNOWN = 'life_time_unknown'
27 |
28 | // 设备绑定状态
29 | const BIND_STATUS_UNBOUND = '00'
30 | const BIND_STATUS_BOUND_THIS = '55'
31 | const BIND_STATUS_BOUND_OTHER = 'AA'
32 | const BIND_STATUS_STRING_UNBOUND = 'unbound'
33 | const BIND_STATUS_STRING_BOUND_THIS = 'bound_this'
34 | const BIND_STATUS_STRING_BOUND_OTHER = 'bound_other'
35 | // network
36 | const MAINNET = 'MAINNET'
37 | const TESTNET = 'TESTNET'
38 | // imKey device name
39 | const DEVICE_NAME_IMKEY_PRO = 'imKey Pro'
40 | // 成功状态
41 | const RESULT_STATUS_SUCCESS = 'success'
42 | // apiName
43 | const API_NAME_TRANSACTION_BTC = 'btc.signTransaction'
44 | const API_NAME_TRANSACTION_BTC_SEGWIT = 'btc.signSegWitTransaction'
45 | const API_NAME_TRANSACTION_BTC_USDT = 'btc.signUsdtTransaction'
46 | const API_NAME_TRANSACTION_BTC_USDT_SEGWIT = 'btc.signUsdtSegWitTransaction'
47 | const API_NAME_TRANSACTION_BCH = 'bch.signTransaction'
48 | const API_NAME_TRANSACTION_LTC = 'ltc.signTransaction'
49 | const API_NAME_TRANSACTION_SIGNTX_ETH = 'eth.signTransaction'
50 | const API_NAME_TRANSACTION_SIGNMSG_ETH = 'eth.signMessage'
51 | const API_NAME_TRANSACTION_SIGNTX_EOS = 'eos.signTransaction'
52 | const API_NAME_TRANSACTION_SIGNMSG_EOS = 'eos.signMessage'
53 | const API_NAME_TRANSACTION_SIGNTX_COSMOS = 'cosmos.signTransaction'
54 | const API_NAME_TRANSACTION_SIGNTX_FILECOIN = 'filecoin.signTransaction'
55 | const API_NAME_TRANSACTION_SIGNTX_POLKADOT = 'dot.signTransaction'
56 | const API_NAME_TRANSACTION_SIGNTX_KUSAMA = 'ksm.signTransaction'
57 | const API_NAME_TRANSACTION_SIGNTX_TRON = 'tron.signTransaction'
58 | const API_NAME_TRANSACTION_SIGNMSG_TRON = 'tron.signMessage'
59 | const API_NAME_TRANSACTION_SIGNTX_XTZ = 'xtz.signTransaction'
60 | const API_NAME_GET_BTC_XPUB = 'btc.getXpub'
61 | const API_NAME_GET_ADDRESS_BTC = 'btc.getAddress'
62 | const API_NAME_GET_ADDRESS_BTC_SEGWIT = 'btc.getSegWitAddress'
63 | const API_NAME_REGISTER_ADDRESS_BTC = 'btc.registerAddress'
64 | const API_NAME_REGISTER_ADDRESS_BTC_SEGWIT = 'btc.registerSegWitAddress'
65 | const API_NAME_GET_ADDRESS_BCH = 'bch.getAddress'
66 | const API_NAME_REGISTER_ADDRESS_BCH = 'bch.registerAddress'
67 | const API_NAME_GET_ADDRESS_LTC = 'ltc.getAddress'
68 | const API_NAME_REGISTER_ADDRESS_LTC = 'ltc.registerAddress'
69 | const API_NAME_GET_ADDRESS_LTC_SEGWIT = 'ltc.getSegWitAddress'
70 | const API_NAME_REGISTER_ADDRESS_LTC_SEGWIT = 'ltc.registerSegWitAddress'
71 | const API_NAME_GET_ADDRESS_ETH = 'eth.getAddress'
72 | const API_NAME_REGISTER_ADDRESS_ETH = 'eth.registerAddress'
73 | const API_NAME_GET_PUBKEY_EOS = 'eos.getPubKey'
74 | const API_NAME_REGISTER_PUBKEY_EOS = 'eos.registerPubKey'
75 | const API_NAME_GET_ADDRESS_COSMOS = 'cosmos.getAddress'
76 | const API_NAME_REGISTER_ADDRESS_COSMOS = 'cosmos.registerAddress'
77 | const API_NAME_GET_ADDRESS_FILECOIN = 'filecoin.getAddress'
78 | const API_NAME_REGISTER_ADDRESS_FILECOIN = 'filecoin.registerAddress'
79 | const API_NAME_GET_ADDRESS_POLKADOT = 'dot.getAddress'
80 | const API_NAME_REGISTER_ADDRESS_POLKADOT = 'dot.registerAddress'
81 | const API_NAME_GET_ADDRESS_KUSAMA = 'ksm.getAddress'
82 | const API_NAME_REGISTER_ADDRESS_KUSAMA = 'ksm.registerAddress'
83 | const API_NAME_GET_ADDRESS_TRON = 'tron.getAddress'
84 | const API_NAME_REGISTER_ADDRESS_TRON = 'tron.registerAddress'
85 | const API_NAME_GET_ADDRESS_XTZ = 'tezos.getAddress'
86 | const API_NAME_REGISTER_ADDRESS_XTZ = 'tezos.registerAddress'
87 | const XPubCommonKey128 = 'B888D25EC8C12BD5043777B1AC49F872'
88 | const XPubCommonIv = '9C0C30889CBCC5E01AB5B2BB88715799'
89 |
90 | module.exports = {
91 | sdkVersion,
92 | serverUrl,
93 | terminalType,
94 | BATTERY_CHARGING_SIGN,
95 | LIFE_TIME_DEVICE_INITED,
96 | LIFE_TIME_DEVICE_ACTIVATED,
97 | LIFE_TIME_UNSET_PIN,
98 | LIFE_TIME_WALLET_UNREADY,
99 | LIFE_TIME_WALLET_CREATTING,
100 | LIFE_TIME_WALLET_RECOVERING,
101 | LIFE_TIME_WALLET_READY,
102 | LIFE_TIME_UNKNOWN,
103 | BIND_STATUS_UNBOUND,
104 | BIND_STATUS_BOUND_THIS,
105 | BIND_STATUS_BOUND_OTHER,
106 | BIND_STATUS_STRING_UNBOUND,
107 | BIND_STATUS_STRING_BOUND_THIS,
108 | BIND_STATUS_STRING_BOUND_OTHER,
109 | MAINNET,
110 | TESTNET,
111 | DEVICE_NAME_IMKEY_PRO,
112 | RESULT_STATUS_SUCCESS,
113 | API_NAME_TRANSACTION_BTC,
114 | API_NAME_TRANSACTION_BTC_SEGWIT,
115 | API_NAME_TRANSACTION_BTC_USDT,
116 | API_NAME_TRANSACTION_BTC_USDT_SEGWIT,
117 | API_NAME_TRANSACTION_BCH,
118 | API_NAME_TRANSACTION_LTC,
119 | API_NAME_TRANSACTION_SIGNTX_ETH,
120 | API_NAME_TRANSACTION_SIGNMSG_ETH,
121 | API_NAME_TRANSACTION_SIGNTX_EOS,
122 | API_NAME_TRANSACTION_SIGNMSG_EOS,
123 | API_NAME_TRANSACTION_SIGNTX_COSMOS,
124 | API_NAME_TRANSACTION_SIGNTX_FILECOIN,
125 | API_NAME_TRANSACTION_SIGNTX_POLKADOT,
126 | API_NAME_TRANSACTION_SIGNTX_KUSAMA,
127 | API_NAME_TRANSACTION_SIGNTX_TRON,
128 | API_NAME_TRANSACTION_SIGNMSG_TRON,
129 | API_NAME_TRANSACTION_SIGNTX_XTZ,
130 | API_NAME_GET_BTC_XPUB,
131 | API_NAME_GET_ADDRESS_BTC,
132 | API_NAME_GET_ADDRESS_BTC_SEGWIT,
133 | API_NAME_REGISTER_ADDRESS_BTC,
134 | API_NAME_REGISTER_ADDRESS_BTC_SEGWIT,
135 | API_NAME_GET_ADDRESS_BCH,
136 | API_NAME_REGISTER_ADDRESS_BCH,
137 | API_NAME_GET_ADDRESS_LTC,
138 | API_NAME_REGISTER_ADDRESS_LTC,
139 | API_NAME_GET_ADDRESS_LTC_SEGWIT,
140 | API_NAME_REGISTER_ADDRESS_LTC_SEGWIT,
141 | API_NAME_GET_ADDRESS_ETH,
142 | API_NAME_REGISTER_ADDRESS_ETH,
143 | API_NAME_GET_PUBKEY_EOS,
144 | API_NAME_REGISTER_PUBKEY_EOS,
145 | API_NAME_GET_ADDRESS_COSMOS,
146 | API_NAME_REGISTER_ADDRESS_COSMOS,
147 | API_NAME_GET_ADDRESS_FILECOIN,
148 | API_NAME_REGISTER_ADDRESS_FILECOIN,
149 | API_NAME_GET_ADDRESS_POLKADOT,
150 | API_NAME_REGISTER_ADDRESS_POLKADOT,
151 | API_NAME_GET_ADDRESS_KUSAMA,
152 | API_NAME_REGISTER_ADDRESS_KUSAMA,
153 | API_NAME_GET_ADDRESS_TRON,
154 | API_NAME_REGISTER_ADDRESS_TRON,
155 | API_NAME_GET_ADDRESS_XTZ,
156 | API_NAME_REGISTER_ADDRESS_XTZ,
157 | XPubCommonKey128,
158 | XPubCommonIv
159 | }
160 |
--------------------------------------------------------------------------------
/src/api/polkadotdapp.js:
--------------------------------------------------------------------------------
1 | const {
2 | web3Enable
3 | } = require('@polkadot/extension-dapp')
4 |
5 | const { Decimal } = require('decimal.js')
6 | const { u8aToHex, hexToU8a } = require('@polkadot/util')
7 | const { TypeRegistry } = require('@polkadot/types/create')
8 | const { GenericAccountId, UInt } = require('@polkadot/types')
9 | const { encodeAddress } = require('@polkadot/util-crypto')
10 | const { ipcRenderer } = require('electron')
11 |
12 | const PolkadotGenesisHash = '0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3'
13 | const KusamaGenesisHash = '0xb0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe'
14 | const PolkadotPath = "m/44'/354'/0'/0'/0'"
15 | const KusamaPath = "m/44'/434'/0'/0'/0'"
16 |
17 | const REGISTRY = (() => {
18 | // kusama runtime is 28
19 | const ADDRESS_TYPES_KUSAMA = {
20 | Address: 'MultiAddress',
21 | LookupSource: 'MultiAddress'
22 | }
23 | const ADDRESS_TYPES_POLKADOT = ADDRESS_TYPES_KUSAMA
24 |
25 | const registryKSM = new TypeRegistry()
26 | const registryDOT = new TypeRegistry()
27 | registryKSM.register(ADDRESS_TYPES_KUSAMA)
28 | registryDOT.register(ADDRESS_TYPES_POLKADOT)
29 | return {
30 | KUSAMA: registryKSM,
31 | POLKADOT: registryDOT
32 | }
33 | })()
34 |
35 | let id = 0
36 |
37 | class Signer {
38 | constructor () {
39 | this.registry = REGISTRY.KUSAMA
40 | }
41 |
42 | async signPayload (payload) {
43 | // const registry = REGISTRY[params.chainType]
44 | // let extrinsicPayload = this.registry.createType('ExtrinsicPayload', payload, {version: payload.version});
45 | this.registry.setSignedExtensions(payload.signedExtensions)
46 | const extrinsicPayload = this.registry
47 | .createType('ExtrinsicPayload', payload, { version: payload.version })
48 | const rawdata = u8aToHex(extrinsicPayload.toU8a(true))
49 | console.log(rawdata)
50 | const encodedAddress = new GenericAccountId(this.registry, hexToU8a('0x' + payload.method.substring(6, 70))).toString()
51 | const toAddress = encodeAddress(encodedAddress, 0)
52 | let payment = '0'
53 |
54 | if (payload.method.length === 72) {
55 | console.log('none')
56 | } else {
57 | payment = new UInt(this.registry, hexToU8a('0x' + payload.method.substring(72, payload.method.length))).toString()
58 | payment = new Decimal(payment).dividedBy(10000000000)
59 | }
60 | let json = {
61 | jsonrpc: '2.0',
62 | method: 'ksm.signTransaction',
63 | params: {
64 | rawdata: rawdata.substring(2, rawdata.length),
65 | path: KusamaPath,
66 | preview: {
67 | payment: payment + ' KSM',
68 | receiver: toAddress,
69 | sender: payload.address
70 | // fee: '15.4000 milli DOT'
71 | }
72 | },
73 | id: 24
74 | }
75 | if (payload.address === addressDOT) {
76 | json = {
77 | jsonrpc: '2.0',
78 | method: 'dot.signTransaction',
79 | params: {
80 | rawdata: rawdata.substring(2, rawdata.length),
81 | path: PolkadotPath,
82 | preview: {
83 | payment: payment + ' DOT',
84 | receiver: toAddress,
85 | sender: payload.address
86 | // fee: '15.4000 milli DOT'
87 | }
88 | },
89 | id: 24
90 | }
91 | }
92 | const signature = sign(json)
93 | return {
94 | id: ++id,
95 | signature: signature
96 | }
97 | }
98 |
99 | async signRaw ({ address, data }) {
100 | console.log(address)
101 | console.log(data)
102 |
103 | let json = {
104 | jsonrpc: '2.0',
105 | method: 'ksm.signTransaction',
106 | params: {
107 | rawdata: data,
108 | path: KusamaPath
109 | },
110 | id: 24
111 | }
112 | if (address === addressDOT) {
113 | json = {
114 | jsonrpc: '2.0',
115 | method: 'dot.signTransaction',
116 | params: {
117 | rawdata: data,
118 | path: PolkadotPath
119 | },
120 | id: 24
121 | }
122 | }
123 | const signature = sign(json)
124 | return {
125 | id: ++id,
126 | signature
127 | }
128 | }
129 | }
130 |
131 | function sign (json) {
132 | // const ret = ipcRenderer.sendSync('showMessageBoxSync', JSON.stringify(json))
133 | const ret = ipcRenderer.sendSync('showMessageBoxSync', '')
134 | if (ret === 0) {
135 | const result = ipcRenderer.sendSync('message-from-get-api', json)
136 | return result.result.signature
137 | } else {
138 |
139 | }
140 | }
141 | let addressKSM
142 | let addressDOT
143 | function getAddress () {
144 | const res = ipcRenderer.sendSync('message-from-get-address')
145 | const walletAddressArray = res.result
146 | for (let i = 0; i < walletAddressArray.length; i++) {
147 | if (walletAddressArray[i].chain === 'Polkadot') {
148 | addressDOT = walletAddressArray[i].address
149 | }
150 | if (walletAddressArray[i].chain === 'Kusama') {
151 | addressKSM = walletAddressArray[i].address
152 | }
153 | }
154 | console.log(addressKSM)
155 | console.log(addressDOT)
156 | return transformAccounts([{
157 | address: addressKSM,
158 | name: 'imKey KSM',
159 | genesisHash: KusamaGenesisHash
160 | }, {
161 | address: addressDOT,
162 | name: 'imKey DOT',
163 | genesisHash: PolkadotGenesisHash
164 | }])
165 | }
166 | const accounts = getAddress()
167 |
168 | window.injectedWeb3 = {
169 | imkey: {
170 | version: '0.1.0',
171 | enable: async origin => ({
172 | accounts: {
173 | get: () => {
174 | console.log('accounts:' + accounts)
175 | return accounts
176 | }
177 | },
178 | signer: new Signer()
179 | })
180 | }
181 | }
182 |
183 | function transformAccounts (accounts) {
184 | return accounts.map(({
185 | address,
186 | name,
187 | genesisHash
188 | }) => ({
189 | address,
190 | name,
191 | genesisHash
192 | }))
193 | }
194 |
195 | // returns an array of all the injected sources
196 | // (this needs to be called first, before other requests)
197 | web3Enable('imkey')
198 |
199 | // returns an array of { address, meta: { name, source } }
200 | // meta.source contains the name of the extension that provides this account
201 | // const allAccounts = web3Accounts()
202 |
203 | // the address we use to use for signing, as injected
204 | // const SENDER = '5DgzZQE9FS7G5CJLrLgVq2YNa4LM3oYdPh4DFfpp4cMRcWeM'
205 |
206 | // finds an injector for an address
207 | // const injector = web3FromAddress(SENDER)
208 |
209 | // sign and send our transaction - notice here that the address of the account
210 | // (as retrieved injected) is passed through as the param to the `signAndSend`,
211 | // the API then calls the extension to present to the user and get it signed.
212 | // Once complete, the api sends the tx + signature via the normal process
213 | // api.tx.balances
214 | // .transfer('5EAKqFv3izjcjDdNuMLbrEk6Wzo1KEJsUAtWLyrB2zn4kMpT', 123456)
215 | // .signAndSend(SENDER, { SingleAccountSigner }, (status) => { });
216 |
--------------------------------------------------------------------------------
/.electron-vue/webpack.web.config.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | process.env.BABEL_ENV = 'web'
4 |
5 | const path = require('path')
6 | const webpack = require('webpack')
7 |
8 | // const BabiliWebpackPlugin = require('babili-webpack-plugin')
9 | const BabiliWebpackPlugin = require('babel-minify-webpack-plugin')
10 | const CopyWebpackPlugin = require('copy-webpack-plugin')
11 | const MiniCssExtractPlugin = require('mini-css-extract-plugin')
12 | const HtmlWebpackPlugin = require('html-webpack-plugin')
13 | const {VueLoaderPlugin} = require('vue-loader')
14 |
15 | let webConfig = {
16 | // devtool: '#cheap-module-eval-source-map',
17 | entry: {
18 | web: path.join(__dirname, '../src/renderer/main.js'),
19 | worker: path.join(__dirname, '../src/worker/worker.js'),
20 | polkadotdapp: path.join(__dirname, '../src/api/polkadotdapp.js'),
21 | ethereumdapp: path.join(__dirname, '../src/api/ethereumdapp.js'),
22 | // imkey_web3_provider: path.join(__dirname, '../src/api/imkey_web3_provider.js')
23 | },
24 | module: {
25 | rules: [
26 | {
27 | test: /\.vue$/,
28 | use: {
29 | loader: 'vue-loader',
30 | options: {
31 | extractCSS: true,
32 | loaders: {
33 | sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax=1',
34 | scss: 'vue-style-loader!css-loader!sass-loader',
35 | less: 'vue-style-loader!css-loader!less-loader'
36 | }
37 | }
38 | }
39 | },
40 | {
41 | test: /\.scss$/,
42 | use: ['vue-style-loader', 'css-loader', 'sass-loader']
43 | },
44 | {
45 | test: /\.sass$/,
46 | use: ['vue-style-loader', 'css-loader', 'sass-loader?indentedSyntax']
47 | },
48 | {
49 | test: /\.less$/,
50 | use: ['vue-style-loader', 'css-loader', 'less-loader']
51 | },
52 | {
53 | test: /\.css$/,
54 | use: ['vue-style-loader', 'css-loader']
55 | },
56 | {
57 | test: /\.html$/,
58 | use: 'vue-html-loader'
59 | },
60 | {
61 | test: /\.js$/,
62 | use: 'babel-loader',
63 | include: [path.resolve(__dirname, '../src/renderer')],
64 | exclude: /node_modules/
65 | },
66 |
67 | {
68 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
69 | use: {
70 | loader: 'url-loader',
71 | options: {
72 | limit: 10000,
73 | name: 'imgs/[name].[ext]'
74 | }
75 | }
76 | },
77 | {
78 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
79 | use: {
80 | loader: 'url-loader',
81 | options: {
82 | limit: 10000,
83 | name: 'fonts/[name].[ext]'
84 | }
85 | }
86 | }
87 | ]
88 | },
89 | plugins: [
90 | new VueLoaderPlugin(),
91 | new MiniCssExtractPlugin({filename: 'styles.css'}),
92 | new HtmlWebpackPlugin({
93 | filename: 'index.html',
94 | template: path.resolve(__dirname, '../src/index.ejs'),
95 | chunks: ['renderer', 'vendor'],
96 | templateParameters(compilation, assets, options) {
97 | return {
98 | compilation: compilation,
99 | webpack: compilation.getStats().toJson(),
100 | webpackConfig: compilation.options,
101 | htmlWebpackPlugin: {
102 | files: assets,
103 | options: options
104 | },
105 | process,
106 | };
107 | },
108 | minify: {
109 | collapseWhitespace: true,
110 | removeAttributeQuotes: true,
111 | removeComments: true
112 | },
113 | nodeModules: false
114 | }),
115 | new webpack.DefinePlugin({
116 | 'process.env.IS_WEB': 'true'
117 | }),
118 | new HtmlWebpackPlugin({
119 | filename: 'worker.html',
120 | template: path.resolve(__dirname, '../src/worker.ejs'),
121 | chunks: ['worker', 'vendor'],
122 | minify: {
123 | collapseWhitespace: true,
124 | removeAttributeQuotes: true,
125 | removeComments: true
126 | },
127 | templateParameters(compilation, assets, options) {
128 | return {
129 | compilation: compilation,
130 | webpack: compilation.getStats().toJson(),
131 | webpackConfig: compilation.options,
132 | htmlWebpackPlugin: {
133 | files: assets,
134 | options: options
135 | },
136 | process,
137 | };
138 | },
139 | nodeModules: process.env.NODE_ENV !== 'production'
140 | ? path.resolve(__dirname, '../node_modules')
141 | : false
142 | }),
143 | new webpack.HotModuleReplacementPlugin(),
144 | new webpack.NoEmitOnErrorsPlugin()
145 | ],
146 | output: {
147 | filename: '[name].js',
148 | path: path.join(__dirname, '../dist/web'),
149 | publicPath: './'
150 | },
151 | resolve: {
152 | alias: {
153 | '@': path.join(__dirname, '../src/renderer'),
154 | 'vue$': 'vue/dist/vue.esm.js'
155 | },
156 | extensions: ['.js', '.vue', '.json', '.css']
157 | },
158 | target: 'web'
159 | }
160 |
161 | /**
162 | * Adjust webConfig for production settings
163 | */
164 | if (process.env.NODE_ENV === 'production') {
165 | // webConfig.devtool = ''
166 |
167 | webConfig.plugins.push(
168 | new BabiliWebpackPlugin(),
169 | new CopyWebpackPlugin(
170 | {
171 | patterns: [
172 | { from: path.join(__dirname, '../static'),
173 | to: path.join(__dirname, '../dist/web/static')},
174 | { from: path.join(__dirname, '../src/api/imkey_web3_provider.js'),
175 | to: path.join(__dirname, '../dist/electron/imkey_web3_provider.js')},
176 | ]
177 | }),
178 | new webpack.DefinePlugin({
179 | 'process.env.NODE_ENV': '"production"'
180 | }),
181 | new webpack.LoaderOptionsPlugin({
182 | minimize: true
183 | })
184 | )
185 | }
186 |
187 | module.exports = webConfig
188 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "imKeyManager",
3 | "version": "2.1.6-beta",
4 | "author": "imkey ",
5 | "description": "imKey Manager @2020",
6 | "license": "MIT",
7 | "main": "./dist/electron/main.js",
8 | "scripts": {
9 | "build": "node .electron-vue/build.js && electron-builder",
10 | "build:dir": "node .electron-vue/build.js && electron-builder --dir",
11 | "build:clean": "cross-env BUILD_TARGET=clean node .electron-vue/build.js",
12 | "build:web": "cross-env BUILD_TARGET=web node .electron-vue/build.js",
13 | "lint": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter src test",
14 | "lint:fix": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter --fix src test",
15 | "dev": "node .electron-vue/dev-runner.js",
16 | "e2e": "mocha test/e2e",
17 | "pack": "npm run pack:main && npm run pack:renderer",
18 | "pack:main": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.main.config.js",
19 | "pack:renderer": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.renderer.config.js",
20 | "test": "npm run unit && npm run e2e",
21 | "unit": "karma start test/unit/karma.conf.js",
22 | "postinstall": "npm run lint:fix && electron-builder install-app-deps",
23 | "release": "node .electron-vue/build.js && electron-builder"
24 | },
25 | "build": {
26 | "afterSign": "build/notarize.js",
27 | "productName": "imKey Manager",
28 | "appId": "com.imkey.imkey-manager",
29 | "copyright": "Copyright © 2020 imkey",
30 | "directories": {
31 | "output": "build"
32 | },
33 | "publish": {
34 | "provider": "generic",
35 | "url": "https://files.imkey.im/downloads/imKeyManager"
36 | },
37 | "releaseInfo": {
38 | "releaseNotes": "[{id:1,info:\"新增蓝牙固件更新功能\"},{id:2,info:\"增加蓝牙固件版本显示\"},{id:3,info:\"删除DApp选项卡\"}]"
39 | },
40 | "files": [
41 | "dist/electron/**/*"
42 | ],
43 | "dmg": {
44 | "sign": false,
45 | "contents": [
46 | {
47 | "x": 410,
48 | "y": 150,
49 | "type": "link",
50 | "path": "/Applications"
51 | },
52 | {
53 | "x": 130,
54 | "y": 150,
55 | "type": "file"
56 | }
57 | ]
58 | },
59 | "mac": {
60 | "hardenedRuntime": true,
61 | "gatekeeperAssess": false,
62 | "entitlements": "build/entitlements.mac.plist",
63 | "entitlementsInherit": "build/entitlements.mac.plist",
64 | "icon": "build/icons/icon.icns",
65 | "extraResources": [
66 | {
67 | "from": "./connector.dylib",
68 | "to": "./"
69 | },
70 | {
71 | "from": "./key.env",
72 | "to": "./"
73 | }
74 | ]
75 | },
76 | "win": {
77 | "icon": "build/icons/icon.ico",
78 | "requestedExecutionLevel": "highestAvailable",
79 | "target": "nsis",
80 | "extraResources": [
81 | {
82 | "from": "./connector.dll",
83 | "to": "../"
84 | },
85 | {
86 | "from": "./key.env",
87 | "to": "../"
88 | }
89 | ]
90 | },
91 | "nsis": {
92 | "oneClick": false,
93 | "perMachine": true,
94 | "allowElevation": true,
95 | "allowToChangeInstallationDirectory": true,
96 | "createDesktopShortcut": true,
97 | "runAfterFinish": true
98 | },
99 | "linux": {
100 | "icon": "build/icons/icon.icns"
101 | }
102 | },
103 | "dependencies": {
104 | "@fortawesome/fontawesome-free": "^5.15.2",
105 | "@polkadot/api": "^4.2.1",
106 | "@polkadot/extension-dapp": "^0.37.2",
107 | "@polkadot/types": "^4.2.1",
108 | "@polkadot/util": "^6.0.5",
109 | "@polkadot/util-crypto": "^6.0.5",
110 | "body-parser": "^1.19.0",
111 | "copy-to-clipboard": "^3.3.1",
112 | "cors": "^2.8.5",
113 | "decimal.js": "^10.2.1",
114 | "dotenv": "^8.2.0",
115 | "electron-updater": "^4.3.8",
116 | "electron-localshortcut": "^3.2.1",
117 | "element-ui": "^2.15.1",
118 | "express": "^4.17.1",
119 | "ffi-napi": "^4.0.3",
120 | "fs-extra": "^9.1.0",
121 | "is-online": "^9.0.0",
122 | "lodash": "^4.17.21",
123 | "lodash-id": "^0.14.0",
124 | "ref-napi": "^3.0.2",
125 | "vue": "^2.6.12",
126 | "vue-cookies": "^1.7.4",
127 | "vue-electron": "^1.0.6",
128 | "vue-i18n": "^8.24.0",
129 | "vue-router": "^3.5.1",
130 | "vuex": "^3.6.2",
131 | "vuex-electron": "^1.0.3",
132 | "web3": "^1.3.4",
133 | "write-file-atomic": "^3.0.3"
134 | },
135 | "devDependencies": {
136 | "@babel/core": "^7.13.10",
137 | "@babel/plugin-transform-runtime": "^7.13.10",
138 | "@babel/preset-env": "^7.13.10",
139 | "@babel/register": "^7.13.8",
140 | "@babel/runtime": "^7.13.10",
141 | "@polkadot/api-cli": "^0.30.1",
142 | "@vue/devtools": "^6.0.0-beta.6",
143 | "ajv": "^7.2.1",
144 | "babel-eslint": "^10.1.0",
145 | "babel-loader": "^8.2.2",
146 | "babel-minify-webpack-plugin": "^0.3.1",
147 | "babel-plugin-istanbul": "^6.0.0",
148 | "bufferutil": "^4.0.3",
149 | "cfonts": "^2.9.1",
150 | "chai": "^4.3.3",
151 | "chai-http": "^4.3.0",
152 | "chalk": "^4.1.0",
153 | "copy-webpack-plugin": "^8.0.0",
154 | "cross-env": "^7.0.3",
155 | "css-loader": "^5.1.1",
156 | "del": "^6.0.0",
157 | "devtron": "^1.4.0",
158 | "electron": "^11.3.0",
159 | "electron-builder": "24.6.4",
160 | "electron-debug": "^3.2.0",
161 | "electron-devtools-installer": "^3.2.0",
162 | "electron-download": "^4.1.1",
163 | "electron-notarize": "^1.1.1",
164 | "eslint": "^7.21.0",
165 | "eslint-config-standard": "^16.0.2",
166 | "eslint-friendly-formatter": "^4.0.1",
167 | "eslint-loader": "^4.0.2",
168 | "eslint-plugin-html": "^6.1.2",
169 | "eslint-plugin-import": "^2.22.1",
170 | "eslint-plugin-node": "^11.1.0",
171 | "eslint-plugin-promise": "^4.3.1",
172 | "eslint-plugin-standard": "^5.0.0",
173 | "eslint-plugin-vue": "^7.7.0",
174 | "file-loader": "^6.2.0",
175 | "google-protobuf": "3.15.5",
176 | "html-webpack-plugin": "^5.3.0",
177 | "inject-loader": "^4.0.1",
178 | "karma": "^6.1.2",
179 | "karma-chai": "^0.1.0",
180 | "karma-coverage": "^2.0.3",
181 | "karma-electron": "^6.3.3",
182 | "karma-mocha": "^2.0.1",
183 | "karma-sourcemap-loader": "^0.3.8",
184 | "karma-spec-reporter": "^0.0.32",
185 | "karma-webpack": "^5.0.0",
186 | "less": "^4.1.1",
187 | "less-loader": "^8.0.0",
188 | "mini-css-extract-plugin": "^1.3.9",
189 | "mocha": "^8.3.1",
190 | "multispinner": "^0.2.1",
191 | "node-loader": "^1.0.2",
192 | "node-sass": "^5.0.0",
193 | "require-dir": "^1.2.0",
194 | "sass-loader": "^11.0.1",
195 | "should": "^13.2.3",
196 | "spectron": "^14.0.0",
197 | "style-loader": "^2.0.0",
198 | "url-loader": "^4.1.1",
199 | "utf-8-validate": "^5.0.4",
200 | "vue-html-loader": "^1.2.4",
201 | "vue-loader": "^15.9.6",
202 | "vue-style-loader": "^4.1.3",
203 | "vue-template-compiler": "^2.6.12",
204 | "webpack": "^5.24.4",
205 | "webpack-cli": "^4.5.0",
206 | "webpack-dev-server": "^3.11.2",
207 | "webpack-hot-middleware": "^2.25.0",
208 | "webpack-merge": "^5.7.3"
209 | },
210 | "repository": {
211 | "type": "git",
212 | "url": "git+https://github.com/consenlabs/imkey-manager.git"
213 | },
214 | "bugs": {
215 | "url": "https://github.com/consenlabs/imkey-manager/issues"
216 | },
217 | "homepage": "https://github.com/consenlabs/imkey-manager#readme"
218 | }
219 |
--------------------------------------------------------------------------------
/test/e2e/specs/deviceManager.spec.js:
--------------------------------------------------------------------------------
1 | // const chai = require('chai')
2 | const deviceManager = require('../../../src/api/devicemanagerapi')
3 | describe('Api', () => {
4 | describe('test initImKeyCore()', () => {
5 | it('it should show initImKeyCore() result', (done) => {
6 | const response = deviceManager.initImKeyCore()
7 | if (response.isSuccess) {
8 | expect(response.result).to.eq('success')
9 | done()
10 | } else {
11 | console.error(response.result)
12 | }
13 | }).timeout(500000)
14 | })
15 | describe('test connect()', () => {
16 | it('it should show connect() result', (done) => {
17 | const response = deviceManager.connect()
18 | if (response.isSuccess) {
19 | expect(response.result).to.eq('success')
20 | done()
21 | } else {
22 | console.error(response.result)
23 | }
24 | }).timeout(500000)
25 | })
26 |
27 | describe('test getSn()', () => {
28 | it('it should show getSn() result', (done) => {
29 | const response = deviceManager.getSn()
30 | if (response.isSuccess) {
31 | expect(response.result).to.eq('imKey01200100010')
32 | done()
33 | } else {
34 | console.error(response.result)
35 | }
36 | }).timeout(500000)
37 | })
38 | describe('test getSeid()', () => {
39 | it('it should show getSeid result', (done) => {
40 | const response = deviceManager.getSeid()
41 | if (response.isSuccess) {
42 | expect(response.result).to.eq('18080000000000860001010000000106')
43 | done()
44 | } else {
45 | console.error(response.result)
46 | }
47 | }).timeout(500000)
48 | })
49 |
50 | describe('test getRamSize()', () => {
51 | it('it should show getRamSize result', (done) => {
52 | const response = deviceManager.getRamSize()
53 | if (response.isSuccess) {
54 | expect(response.result).to.eq(3159)
55 | done()
56 | } else {
57 | console.error(response.result)
58 | }
59 | }).timeout(500000)
60 | })
61 |
62 | describe('test getFirmwareVersion()', () => {
63 | it('it should show getFirmwareVersion result', (done) => {
64 | const response = deviceManager.getFirmwareVersion()
65 | if (response.isSuccess) {
66 | expect(response.result).to.eq('1.5.08')
67 | done()
68 | } else {
69 | console.error(response.result)
70 | }
71 | }).timeout(500000)
72 | })
73 | describe('test isBLStatus()', () => {
74 | it('it should show isBLStatus result', (done) => {
75 | const response = deviceManager.isBLStatus()
76 | if (response.isSuccess) {
77 | expect(response.result).to.eq(false)
78 | done()
79 | } else {
80 | console.error(response.result)
81 | }
82 | }).timeout(500000)
83 | })
84 | describe('test getSdkInfo()', () => {
85 | it('it should show getSdkInfo result', (done) => {
86 | const response = deviceManager.getSdkInfo()
87 | if (response.isSuccess) {
88 | expect(response.result).to.eq('1.2.10')
89 | done()
90 | } else {
91 | console.error(response.result)
92 | }
93 | }).timeout(500000)
94 | })
95 | describe('test activeDevice()', () => {
96 | it('it should show activeDevice result', (done) => {
97 | const response = deviceManager.activeDevice()
98 | if (response.isSuccess) {
99 | expect(response.result).to.eq('success')
100 | done()
101 | } else {
102 | console.error(response.result)
103 | }
104 | }).timeout(500000)
105 | })
106 | describe('test checkDevice()', () => {
107 | it('it should show checkDevice result', (done) => {
108 | const response = deviceManager.checkDevice()
109 | if (response.isSuccess) {
110 | expect(response.result).to.eq('success')
111 | done()
112 | } else {
113 | console.error(response.result)
114 | }
115 | }).timeout(500000)
116 | })
117 | describe('test cosCheckUpdate()', () => {
118 | it('it should show cosCheckUpdate result', (done) => {
119 | const response = deviceManager.cosCheckUpdate()
120 | if (response.isSuccess) {
121 | expect(response.result).to.have.a.property('seid')
122 | done()
123 | } else {
124 | console.error(response.result)
125 | }
126 | }).timeout(500000)
127 | })
128 |
129 | describe('test checkUpdate()', () => {
130 | it('it should show checkUpdate result', (done) => {
131 | const response = deviceManager.checkUpdate()
132 | if (response.isSuccess) {
133 | expect(response.result).to.have.a.property('sn')
134 | done()
135 | } else {
136 | console.error(response.result)
137 | }
138 | }).timeout(500000)
139 | })
140 | describe('test checkUpdateAppList()', () => {
141 | it('it should show checkUpdateAppList result', (done) => {
142 | const response = deviceManager.checkUpdateAppList()
143 | if (response.isSuccess) {
144 | expect(response.result).to.have.a.property('list')
145 | done()
146 | } else {
147 | console.error(response.result)
148 | }
149 | }).timeout(500000)
150 | })
151 | const appletNmae = 'ETH'
152 | describe('test deleteApplet()', () => {
153 | it('it should show deleteApplet result', (done) => {
154 | const response = deviceManager.deleteApplet(appletNmae)
155 | if (response.isSuccess) {
156 | expect(response.result).to.eq('success')
157 | done()
158 | } else {
159 | console.error(response.result)
160 | }
161 | }).timeout(500000)
162 | })
163 |
164 | describe('test downloadApplet()', () => {
165 | it('it should show downloadApplet result', (done) => {
166 | const response = deviceManager.downloadApplet(appletNmae)
167 | if (response.isSuccess) {
168 | expect(response.result).to.eq('success')
169 | done()
170 | } else {
171 | console.error(response.result)
172 | }
173 | }).timeout(500000)
174 | })
175 |
176 | describe('test updateApplet()', () => {
177 | it('it should show updateApplet result', (done) => {
178 | const response = deviceManager.updateApplet(appletNmae)
179 | if (response.isSuccess) {
180 | expect(response.result).to.eq('success')
181 | done()
182 | } else {
183 | console.error(response.result)
184 | }
185 | }).timeout(500000)
186 | })
187 |
188 | describe('test deviceBindCheck()', () => {
189 | it('it should show deviceBindCheck result', (done) => {
190 | const filePath = require('path').resolve('./')
191 | const response = deviceManager.deviceBindCheck(filePath)
192 | if (response.isSuccess) {
193 | expect(response.result).to.contain('bound')
194 | done()
195 | } else {
196 | console.error(response.result)
197 | }
198 | }).timeout(500000)
199 | })
200 |
201 | describe('test deviceBindAcquire()', () => {
202 | it('it should show deviceBindAcquire result', (done) => {
203 | const bindCode = 'T52MKBA3'
204 | const response = deviceManager.deviceBindAcquire(bindCode)
205 | if (response.isSuccess) {
206 | expect(response.result).to.contain('success')
207 | done()
208 | } else {
209 | console.error(response.result)
210 | }
211 | }).timeout(500000)
212 | })
213 | describe('test deviceBindDisplay()', () => {
214 | it('it should show deviceBindDisplay result', (done) => {
215 | const response = deviceManager.deviceBindDisplay()
216 | if (response.isSuccess) {
217 | expect(response.result).to.contain('success')
218 | done()
219 | } else {
220 | console.error(response.result)
221 | }
222 | }).timeout(500000)
223 | })
224 |
225 | describe('test cosUpdate()', () => {
226 | it('it should show cosUpdate result', (done) => {
227 | const response = deviceManager.cosUpdate()
228 | if (response.isSuccess) {
229 | expect(response.result).to.contain('success')
230 | done()
231 | } else {
232 | console.error(response.result)
233 | }
234 | }).timeout(500000)
235 | })
236 | })
237 |
--------------------------------------------------------------------------------
/.electron-vue/webpack.renderer.config.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | process.env.BABEL_ENV = 'renderer'
4 |
5 | const path = require('path')
6 | const {dependencies} = require('../package.json')
7 | const webpack = require('webpack')
8 |
9 | // const BabiliWebpackPlugin = require('babili-webpack-plugin')
10 | const BabiliWebpackPlugin = require('babel-minify-webpack-plugin')
11 | const CopyWebpackPlugin = require('copy-webpack-plugin')
12 | const MiniCssExtractPlugin = require('mini-css-extract-plugin')
13 | const HtmlWebpackPlugin = require('html-webpack-plugin')
14 | const {VueLoaderPlugin} = require('vue-loader')
15 |
16 | /**
17 | * List of node_modules to include in webpack bundle
18 | *
19 | * Required for specific packages like Vue UI libraries
20 | * that provide pure *.vue files that need compiling
21 | * https://simulatedgreg.gitbooks.io/electron-vue/content/en/webpack-configurations.html#white-listing-externals
22 | */
23 | let whiteListedModules = ['vue', 'element-ui']
24 |
25 | let rendererConfig = {
26 | // devtool: '#cheap-module-eval-source-map',
27 | entry: {
28 | renderer: path.join(__dirname, '../src/renderer/main.js'),
29 | worker: path.join(__dirname, '../src/worker/worker.js'),
30 | polkadotdapp: path.join(__dirname, '../src/api/polkadotdapp.js'),
31 | ethereumdapp: path.join(__dirname, '../src/api/ethereumdapp.js'),
32 | ethereumdapp_imkey_web3: path.join(__dirname, '../src/api/ethereumdapp_imkey_web3.js'),
33 | // imkey_web3_provider: path.join(__dirname, '../src/api/imkey_web3_provider.js')
34 | },
35 | externals: [
36 | ...Object.keys(dependencies || {}).filter(d => !whiteListedModules.includes(d))
37 | ],
38 | module: {
39 | rules: [
40 | {
41 | test: /\.vue$/,
42 | use: {
43 | loader: 'vue-loader',
44 | options: {
45 | extractCSS: process.env.NODE_ENV === 'production',
46 | loaders: {
47 | sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax=1',
48 | scss: 'vue-style-loader!css-loader!sass-loader',
49 | less: 'vue-style-loader!css-loader!less-loader'
50 | }
51 | }
52 | }
53 | },
54 | {
55 | test: /\.scss$/,
56 | use: ['vue-style-loader', 'css-loader', 'sass-loader']
57 | },
58 | {
59 | test: /\.sass$/,
60 | use: ['vue-style-loader', 'css-loader', 'sass-loader?indentedSyntax']
61 | },
62 | {
63 | test: /\.less$/,
64 | use: ['vue-style-loader', 'css-loader', 'less-loader']
65 | },
66 | {
67 | test: /\.css$/,
68 | use: ['vue-style-loader', 'css-loader']
69 | },
70 | {
71 | test: /\.html$/,
72 | use: 'vue-html-loader'
73 | },
74 | {
75 | test: /\.js$/,
76 | use: 'babel-loader',
77 | exclude: /node_modules/
78 | },
79 | {
80 | test: /\.node$/,
81 | use: 'node-loader'
82 | },
83 |
84 | {
85 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
86 | use: {
87 | loader: 'url-loader',
88 | options: {
89 | limit: 10000,
90 | name: 'imgs/[name]--[folder].[ext]'
91 | }
92 | }
93 | },
94 | {
95 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
96 | loader: 'url-loader',
97 | options: {
98 | limit: 10000,
99 | name: 'media/[name]--[folder].[ext]'
100 | }
101 | },
102 | {
103 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
104 | use: {
105 | loader: 'url-loader',
106 | options: {
107 | limit: 10000,
108 | name: 'fonts/[name]--[folder].[ext]'
109 | }
110 | }
111 | }
112 | ]
113 | },
114 | node: {
115 | __dirname: process.env.NODE_ENV !== 'production',
116 | __filename: process.env.NODE_ENV !== 'production'
117 | },
118 | plugins: [
119 | new VueLoaderPlugin(),
120 | new MiniCssExtractPlugin({filename: 'styles.css'}),
121 | new HtmlWebpackPlugin({
122 | filename: 'index.html',
123 | template: path.resolve(__dirname, '../src/index.ejs'),
124 | chunks: ['renderer', 'vendor'],
125 | templateParameters(compilation, assets, options) {
126 | return {
127 | compilation: compilation,
128 | webpack: compilation.getStats().toJson(),
129 | webpackConfig: compilation.options,
130 | htmlWebpackPlugin: {
131 | files: assets,
132 | options: options
133 | },
134 | process,
135 | };
136 | },
137 | minify: {
138 | collapseWhitespace: true,
139 | removeAttributeQuotes: true,
140 | removeComments: true
141 | },
142 | nodeModules: process.env.NODE_ENV !== 'production'
143 | ? path.resolve(__dirname, '../node_modules')
144 | : false
145 | }),
146 | new HtmlWebpackPlugin({
147 | filename: 'worker.html',
148 | template: path.resolve(__dirname, '../src/worker.ejs'),
149 | chunks: ['worker', 'vendor'],
150 | minify: {
151 | collapseWhitespace: true,
152 | removeAttributeQuotes: true,
153 | removeComments: true
154 | },
155 | templateParameters(compilation, assets, options) {
156 | return {
157 | compilation: compilation,
158 | webpack: compilation.getStats().toJson(),
159 | webpackConfig: compilation.options,
160 | htmlWebpackPlugin: {
161 | files: assets,
162 | options: options
163 | },
164 | process,
165 | };
166 | },
167 | nodeModules: process.env.NODE_ENV !== 'production'
168 | ? path.resolve(__dirname, '../node_modules')
169 | : false
170 | }),
171 | new webpack.HotModuleReplacementPlugin(),
172 | new webpack.NoEmitOnErrorsPlugin()
173 | ],
174 | output: {
175 | filename: '[name].js',
176 | libraryTarget: 'commonjs2',
177 | path: path.join(__dirname, '../dist/electron'),
178 | publicPath: './'
179 | },
180 | resolve: {
181 | alias: {
182 | '@': path.join(__dirname, '../src/renderer'),
183 | 'vue$': 'vue/dist/vue.esm.js',
184 | '~': path.join(__dirname, '../src'),
185 | },
186 | extensions: ['.js', '.vue', '.json', '.css', '.node']
187 | },
188 | target: 'electron-renderer'
189 | }
190 |
191 | /**
192 | * Adjust rendererConfig for development settings
193 | */
194 | if (process.env.NODE_ENV !== 'production') {
195 | rendererConfig.plugins.push(
196 | new webpack.DefinePlugin({
197 | '__static': `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`
198 | })
199 | )
200 | }
201 |
202 | /**
203 | * Adjust rendererConfig for production settings
204 | */
205 | if (process.env.NODE_ENV === 'production') {
206 | // rendererConfig.devtool = ''
207 |
208 | rendererConfig.plugins.push(
209 | new BabiliWebpackPlugin(),
210 | new CopyWebpackPlugin(
211 | {
212 | patterns: [
213 | { from: path.join(__dirname, '../static'),
214 | to: path.join(__dirname, '../dist/electron/static')},
215 | { from: path.join(__dirname, '../src/api/imkey_web3_provider.js'),
216 | to: path.join(__dirname, '../dist/electron/imkey_web3_provider.js')},
217 | ]
218 | }),
219 | new webpack.DefinePlugin({
220 | 'process.env.NODE_ENV': '"production"'
221 | }),
222 | new webpack.LoaderOptionsPlugin({
223 | minimize: true
224 | })
225 | )
226 | }
227 |
228 | module.exports = rendererConfig
229 |
--------------------------------------------------------------------------------
/src/renderer/store/dapps.js:
--------------------------------------------------------------------------------
1 | export const DAPPS_ETH = [
2 | {
3 | id: 1,
4 | urlType: 'Tokenlon',
5 | url: 'https://tokenlon.im/instant',
6 | title: 'Tokenlon',
7 | iconUrl: 'https://aws-v2-cdn.token.im/app-production/dapps/app_icons/285/LON-Dashboard.png',
8 | desc: 'm.dapp.tokenlon_desc'
9 | },
10 | {
11 | id: 2,
12 | urlType: 'Sushiswap',
13 | url: 'https://app.sushi.com',
14 | title: 'Sushiswap',
15 | iconUrl: 'https://aws-v2-cdn.token.im/app-production/dapps/app_icons/277/WechatIMG3.png',
16 | desc: 'm.dapp.sushiswap_desc'
17 | },
18 | {
19 | id: 3,
20 | urlType: 'Uniswap',
21 | url: 'https://app.uniswap.org',
22 | title: 'Uniswap',
23 | iconUrl: 'https://aws-v2-cdn.token.im/app-production/dapps/app_icons/338/Uniswap-ipfs.png',
24 | desc: 'm.dapp.uniswap_desc'
25 | },
26 | {
27 | id: 4,
28 | urlType: 'Multisender',
29 | url: 'https://multisender.app',
30 | title: 'Multisender',
31 | iconUrl: 'https://multisender.app/favicon/favicon.ico',
32 | desc: 'm.dapp.multisender_desc'
33 | },
34 | {
35 | id: 5,
36 | urlType: 'Compound',
37 | url: 'https://app.compound.finance/',
38 | title: 'Compound',
39 | iconUrl: 'https://compound.finance/favicon.ico',
40 | desc: 'm.dapp.compound_desc'
41 | },
42 | {
43 | id: 6,
44 | urlType: 'AAVE',
45 | url: 'https://app.aave.com/',
46 | title: 'AAVE',
47 | iconUrl: 'https://defigogo.s3-ap-northeast-1.amazonaws.com/images/b7d8f173-de3f-4dc3-9316-00268fc402a9.jpg',
48 | desc: 'm.dapp.aave_desc'
49 | },
50 | {
51 | id: 7,
52 | urlType: 'Rarible',
53 | url: 'https://rarible.com',
54 | title: 'Rarible',
55 | iconUrl: 'https://rarible.com/favicon.png',
56 | desc: 'm.dapp.rarible_desc'
57 | },
58 | {
59 | id: 8,
60 | urlType: 'Murall',
61 | url: 'https://murall.art',
62 | title: 'Murall',
63 | iconUrl: 'https://murall.art/images/murall_top_logo_mobile.svg',
64 | desc: 'm.dapp.murall_desc'
65 | },
66 | // {
67 | // id: 9,
68 | // urlType: 'zkSync',
69 | // url: 'https://wallet.zksync.io/accounts',
70 | // title: 'zkSync',
71 | // iconUrl: 'https://zksync.io/favicon.ico',
72 | // desc: 'm.dapp.zksync_desc'
73 | // },
74 | {
75 | id: 9,
76 | urlType: 'ZKSwap',
77 | url: 'https://zks.app/zh/wallet',
78 | title: 'ZKSwap',
79 | iconUrl: 'https://zks.app/favicon.ico',
80 | desc: 'm.dapp.zkswap_desc'
81 | },
82 | {
83 | id: 10,
84 | urlType: 'Etherscan',
85 | url: 'https://cn.etherscan.com',
86 | title: 'Etherscan',
87 | iconUrl: 'https://aws-v2-cdn.token.im/app-production/dapps/app_icons/276/etherscanDapp_3x.png',
88 | desc: 'm.dapp.Etherscan_desc'
89 | },
90 | {
91 | id: 11,
92 | urlType: 'OpenSea',
93 | url: 'https://opensea.io/?ref=0xb9e29984fe50602e7a619662ebed4f90d93824c7"',
94 | title: 'OpenSea',
95 | iconUrl: 'https://aws-v2-cdn.token.im/app-production/dapps/app_icons/78/OpenSea_2_162-162.png',
96 | desc: 'm.dapp.OpenSea_desc'
97 | },
98 | {
99 | id: 12,
100 | urlType: 'Nifty Gateway',
101 | url: 'https://niftygateway.com/',
102 | title: 'Nifty Gateway',
103 | iconUrl: 'https://aws-v2-cdn.token.im/app-production/dapps/app_icons/382/nifty.jpg',
104 | desc: 'm.dapp.Nifty_Gateway_desc'
105 | },
106 | {
107 | id: 13,
108 | urlType: 'SuperRare',
109 | url: 'https://superrare.co/',
110 | title: 'SuperRare',
111 | iconUrl: 'https://aws-v2-cdn.token.im/app-production/dapps/app_icons/293/SuperRare126.jpg',
112 | desc: 'm.dapp.SuperRare_desc'
113 | }
114 |
115 | ]
116 | export const DAPPS_BSC = [
117 | // {
118 | // id: 1,
119 | // urlType: 'Venus',
120 | // url: 'https://app.venus.io/dashboard',
121 | // title: 'Venus',
122 | // iconUrl: 'https://www.defibox.com/media/20210308115849-566d86dd8aca.jpg',
123 | // desc: 'm.dapp.Venus_desc'
124 | // },
125 | {
126 | id: 1,
127 | urlType: 'pancake',
128 | url: 'https://pancakeswap.finance/',
129 | title: 'pancake',
130 | iconUrl: 'https://www.defibox.com/media/20210308122716-ce4f305bb61c.jpg',
131 | desc: 'm.dapp.pancake_desc'
132 | },
133 | {
134 | id: 2,
135 | urlType: 'Autofarm',
136 | url: 'https://autofarm.network/',
137 | title: 'Autofarm',
138 | iconUrl: 'https://www.defibox.com/media/20210308131736-b7b86d2e94d2.png',
139 | desc: 'm.dapp.Autofarm_desc'
140 | },
141 | {
142 | id: 3,
143 | urlType: 'PancakeBunny',
144 | url: 'https://pancakebunny.finance/',
145 | title: 'PancakeBunny',
146 | iconUrl: 'https://www.defibox.com/media/20210309172437-ffb7821a88a4.png',
147 | desc: 'm.dapp.PancakeBunny_desc'
148 | },
149 | {
150 | id: 4,
151 | urlType: 'Belt Finance',
152 | url: 'https://belt.fi/',
153 | title: 'Belt Finance',
154 | iconUrl: 'https://www.defibox.com/media/20210329113710-5d8c36afd079.png',
155 | desc: 'm.dapp.Belt_Finance_desc'
156 | },
157 | {
158 | id: 5,
159 | urlType: 'beefy.finance',
160 | url: 'https://app.beefy.finance/',
161 | title: 'beefy.finance',
162 | iconUrl: 'https://www.defibox.com/media/20210308130841-da93a82b0f97.png',
163 | desc: 'm.dapp.beefy_finance_desc'
164 | },
165 | {
166 | id: 6,
167 | urlType: 'Bscex LaunchpoolX',
168 | url: 'https://launchpoolx.bscex.org/',
169 | title: 'Bscex LaunchpoolX',
170 | iconUrl: 'https://www.defibox.com/media/20210309165630-9754c86ed206.png',
171 | desc: 'm.dapp.Bscex_LaunchpoolX_desc'
172 | },
173 | {
174 | id: 7,
175 | urlType: 'ACryptoS',
176 | url: 'https://app.acryptos.com/',
177 | title: 'ACryptoS',
178 | iconUrl: 'https://www.defibox.com/media/20210308131222-ab768b768a61.jpg',
179 | desc: 'm.dapp.ACryptoS_desc'
180 | },
181 | {
182 | id: 8,
183 | urlType: 'Alpaca Finance',
184 | url: 'https://app.alpacafinance.org/lend',
185 | title: 'Alpaca Finance',
186 | iconUrl: 'https://www.defibox.com/media/20210309162132-19d0ef32c55a.png',
187 | desc: 'm.dapp.Alpaca_Finance_desc'
188 | },
189 | {
190 | id: 9,
191 | urlType: 'Goose Finance',
192 | url: 'https://www.goosedefi.com/',
193 | title: 'Goose Finance',
194 | iconUrl: 'https://www.defibox.com/media/20210309164915-48abe3f2fc60.png',
195 | desc: 'm.dapp.Goose_Finance_desc'
196 | },
197 | {
198 | id: 10,
199 | urlType: 'JulSwap',
200 | url: 'https://julswap.com/#/swap',
201 | title: 'JulSwap',
202 | iconUrl: 'https://aws-v2-cdn.token.im/app-production/dapps/app_icons/416/julswap.jpg',
203 | desc: 'm.dapp.JulSwap_desc'
204 | }
205 | ]
206 | export const DAPPS_HECO = [
207 | {
208 | id: 1,
209 | urlType: 'MDEX',
210 | url: 'https://ht.mdex.com/#/swap',
211 | title: 'MDEX',
212 | iconUrl: 'https://www.defibox.com/media/3664bcb5-9e37-4602-b8e0-0d53cc3fa20d.png',
213 | desc: 'm.dapp.MDEX_desc'
214 | },
215 | {
216 | id: 2,
217 | urlType: 'BXH',
218 | url: 'https://bxh.com',
219 | title: 'BXH',
220 | iconUrl: 'https://www.defibox.com/media/20210330145517-0f974e8ebf4e.png',
221 | desc: 'm.dapp.BXH_desc'
222 | },
223 | {
224 | id: 3,
225 | urlType: 'CoinWind',
226 | url: 'https://www.coinwind.com/',
227 | title: 'CoinWind',
228 | iconUrl: 'https://www.defibox.com/media/20210222114531-d0dcdedc1f9c.png',
229 | desc: 'm.dapp.CoinWind_desc'
230 | },
231 | {
232 | id: 4,
233 | urlType: 'Lendhub',
234 | url: 'https://www.lendhub.org/',
235 | title: 'Lendhub',
236 | iconUrl: 'https://defigogo.s3-ap-northeast-1.amazonaws.com/media/960f016e-98ac-404a-8541-9f7989086b30.jpeg',
237 | desc: 'm.dapp.Lendhub_desc'
238 | }, // ,
239 | // {
240 | // id: 5,
241 | // urlType: 'Pilot Protocol',
242 | // url: 'https://p.td/',
243 | // title: 'Pilot Protocol',
244 | // iconUrl: 'https://www.defibox.com/media/20210311140656-af0715d5f927.png',
245 | // desc: 'm.dapp.sushiswap_desc'
246 | // }
247 |
248 | {
249 | id: 5,
250 | urlType: 'FilDA',
251 | url: 'https://filda.io/',
252 | title: 'FilDA',
253 | iconUrl: 'https://www.defibox.com/media/900edc7c-bea6-4051-a73b-02d71a1c84da.jpeg',
254 | desc: 'm.dapp.FilDA_desc'
255 | },
256 | {
257 | id: 6,
258 | urlType: 'EarnDefi',
259 | url: 'https://heco.earndefi.finance/',
260 | title: 'EarnDefi',
261 | iconUrl: 'https://www.defibox.com/media/3ed20046-0a5d-4a93-bcbe-8823d483147e.png',
262 | desc: 'm.dapp.EarnDefi_desc'
263 | },
264 | {
265 | id: 7,
266 | urlType: 'Channels',
267 | url: 'https://channels.finance/',
268 | title: 'Channels',
269 | iconUrl: 'https://defigogo.s3-ap-northeast-1.amazonaws.com/media/f7938d8a-df16-4936-9c0e-9d430512787a.png',
270 | desc: 'm.dapp.Channels_desc'
271 | },
272 | {
273 | id: 8,
274 | urlType: 'HFI.one',
275 | url: 'https://hfi.one',
276 | title: 'HFI.one',
277 | iconUrl: 'https://www.defibox.com/media/20210212183358-d5414d9f1240.jpg',
278 | desc: 'm.dapp.HFI_one_desc'
279 | },
280 | {
281 | id: 9,
282 | urlType: 'Pippi Shrimp Swap',
283 | url: 'https://app.pippi.finance/',
284 | title: 'Pippi Shrimp Swap',
285 | iconUrl: 'https://www.defibox.com/media/20210317165637-ae1c5eab7535.png',
286 | desc: 'm.dapp.Pippi_Shrimp_Swap_desc'
287 | },
288 | {
289 | id: 10,
290 | urlType: 'HashBridge',
291 | url: 'https://hboracle.org/#/',
292 | title: 'HashBridge',
293 | iconUrl: 'https://www.defibox.com/media/20210218175140-2346bca2ef51.png',
294 | desc: 'm.dapp.HashBridge_desc'
295 | }
296 |
297 | ]
298 | export const DAPPS_Polkadot = [
299 | {
300 | id: 1,
301 | urlType: 'Polkadot',
302 | url: 'https://polkadot.js.org/apps/#/accounts',
303 | title: 'Polkadot',
304 | iconUrl: 'https://polkadot.js.org/favicon.ico',
305 | desc: 'm.dapp.polkadotJS_desc'
306 | }
307 | ]
308 | export const DAPPS_Config = {
309 | ETH: {
310 | chainId: 1,
311 | rpcUrl: 'https://mainnet-eth.token.im',
312 | symbol: 'ETH'
313 | },
314 | BSC: {
315 | chainId: 56,
316 | rpcUrl: 'https://bsc-dataseed1.ninicoin.io',
317 | symbol: 'BNB'
318 | },
319 | HECO: {
320 | chainId: 128,
321 | rpcUrl: 'https://http-mainnet.Hecochain.com',
322 | symbol: 'HT'
323 | },
324 | Polkadot: {
325 | chainId: '',
326 | rpcUrl: '',
327 | symbol: ''
328 | }
329 | }
330 |
--------------------------------------------------------------------------------
/src/proto/substrate_pb.js:
--------------------------------------------------------------------------------
1 | // source: substrate.proto
2 | /**
3 | * @fileoverview
4 | * @enhanceable
5 | * @suppress {messageConventions} JS Compiler reports an error if a variable or
6 | * field starts with 'MSG_' and isn't a translatable message.
7 | * @public
8 | */
9 | // GENERATED CODE -- DO NOT EDIT!
10 |
11 | var jspb = require('google-protobuf');
12 | var goog = jspb;
13 | var global = Function('return this')();
14 |
15 | goog.exportSymbol('proto.substrateapi.SubstrateRawTxIn', null, global);
16 | goog.exportSymbol('proto.substrateapi.SubstrateTxOut', null, global);
17 | /**
18 | * Generated by JsPbCodeGenerator.
19 | * @param {Array=} opt_data Optional initial data array, typically from a
20 | * server response, or constructed directly in Javascript. The array is used
21 | * in place and becomes part of the constructed object. It is not cloned.
22 | * If no data is provided, the constructed object will be empty, but still
23 | * valid.
24 | * @extends {jspb.Message}
25 | * @constructor
26 | */
27 | proto.substrateapi.SubstrateRawTxIn = function(opt_data) {
28 | jspb.Message.initialize(this, opt_data, 0, -1, null, null);
29 | };
30 | goog.inherits(proto.substrateapi.SubstrateRawTxIn, jspb.Message);
31 | if (goog.DEBUG && !COMPILED) {
32 | /**
33 | * @public
34 | * @override
35 | */
36 | proto.substrateapi.SubstrateRawTxIn.displayName = 'proto.substrateapi.SubstrateRawTxIn';
37 | }
38 | /**
39 | * Generated by JsPbCodeGenerator.
40 | * @param {Array=} opt_data Optional initial data array, typically from a
41 | * server response, or constructed directly in Javascript. The array is used
42 | * in place and becomes part of the constructed object. It is not cloned.
43 | * If no data is provided, the constructed object will be empty, but still
44 | * valid.
45 | * @extends {jspb.Message}
46 | * @constructor
47 | */
48 | proto.substrateapi.SubstrateTxOut = function(opt_data) {
49 | jspb.Message.initialize(this, opt_data, 0, -1, null, null);
50 | };
51 | goog.inherits(proto.substrateapi.SubstrateTxOut, jspb.Message);
52 | if (goog.DEBUG && !COMPILED) {
53 | /**
54 | * @public
55 | * @override
56 | */
57 | proto.substrateapi.SubstrateTxOut.displayName = 'proto.substrateapi.SubstrateTxOut';
58 | }
59 |
60 |
61 |
62 | if (jspb.Message.GENERATE_TO_OBJECT) {
63 | /**
64 | * Creates an object representation of this proto.
65 | * Field names that are reserved in JavaScript and will be renamed to pb_name.
66 | * Optional fields that are not set will be set to undefined.
67 | * To access a reserved field use, foo.pb_, eg, foo.pb_default.
68 | * For the list of reserved names please see:
69 | * net/proto2/compiler/js/internal/generator.cc#kKeyword.
70 | * @param {boolean=} opt_includeInstance Deprecated. whether to include the
71 | * JSPB instance for transitional soy proto support:
72 | * http://goto/soy-param-migration
73 | * @return {!Object}
74 | */
75 | proto.substrateapi.SubstrateRawTxIn.prototype.toObject = function(opt_includeInstance) {
76 | return proto.substrateapi.SubstrateRawTxIn.toObject(opt_includeInstance, this);
77 | };
78 |
79 |
80 | /**
81 | * Static version of the {@see toObject} method.
82 | * @param {boolean|undefined} includeInstance Deprecated. Whether to include
83 | * the JSPB instance for transitional soy proto support:
84 | * http://goto/soy-param-migration
85 | * @param {!proto.substrateapi.SubstrateRawTxIn} msg The msg instance to transform.
86 | * @return {!Object}
87 | * @suppress {unusedLocalVariables} f is only used for nested messages
88 | */
89 | proto.substrateapi.SubstrateRawTxIn.toObject = function(includeInstance, msg) {
90 | var f, obj = {
91 | rawdata: jspb.Message.getFieldWithDefault(msg, 1, "")
92 | };
93 |
94 | if (includeInstance) {
95 | obj.$jspbMessageInstance = msg;
96 | }
97 | return obj;
98 | };
99 | }
100 |
101 |
102 | /**
103 | * Deserializes binary data (in protobuf wire format).
104 | * @param {jspb.ByteSource} bytes The bytes to deserialize.
105 | * @return {!proto.substrateapi.SubstrateRawTxIn}
106 | */
107 | proto.substrateapi.SubstrateRawTxIn.deserializeBinary = function(bytes) {
108 | var reader = new jspb.BinaryReader(bytes);
109 | var msg = new proto.substrateapi.SubstrateRawTxIn;
110 | return proto.substrateapi.SubstrateRawTxIn.deserializeBinaryFromReader(msg, reader);
111 | };
112 |
113 |
114 | /**
115 | * Deserializes binary data (in protobuf wire format) from the
116 | * given reader into the given message object.
117 | * @param {!proto.substrateapi.SubstrateRawTxIn} msg The message object to deserialize into.
118 | * @param {!jspb.BinaryReader} reader The BinaryReader to use.
119 | * @return {!proto.substrateapi.SubstrateRawTxIn}
120 | */
121 | proto.substrateapi.SubstrateRawTxIn.deserializeBinaryFromReader = function(msg, reader) {
122 | while (reader.nextField()) {
123 | if (reader.isEndGroup()) {
124 | break;
125 | }
126 | var field = reader.getFieldNumber();
127 | switch (field) {
128 | case 1:
129 | var value = /** @type {string} */ (reader.readString());
130 | msg.setRawdata(value);
131 | break;
132 | default:
133 | reader.skipField();
134 | break;
135 | }
136 | }
137 | return msg;
138 | };
139 |
140 |
141 | /**
142 | * Serializes the message to binary data (in protobuf wire format).
143 | * @return {!Uint8Array}
144 | */
145 | proto.substrateapi.SubstrateRawTxIn.prototype.serializeBinary = function() {
146 | var writer = new jspb.BinaryWriter();
147 | proto.substrateapi.SubstrateRawTxIn.serializeBinaryToWriter(this, writer);
148 | return writer.getResultBuffer();
149 | };
150 |
151 |
152 | /**
153 | * Serializes the given message to binary data (in protobuf wire
154 | * format), writing to the given BinaryWriter.
155 | * @param {!proto.substrateapi.SubstrateRawTxIn} message
156 | * @param {!jspb.BinaryWriter} writer
157 | * @suppress {unusedLocalVariables} f is only used for nested messages
158 | */
159 | proto.substrateapi.SubstrateRawTxIn.serializeBinaryToWriter = function(message, writer) {
160 | var f = undefined;
161 | f = message.getRawdata();
162 | if (f.length > 0) {
163 | writer.writeString(
164 | 1,
165 | f
166 | );
167 | }
168 | };
169 |
170 |
171 | /**
172 | * optional string rawData = 1;
173 | * @return {string}
174 | */
175 | proto.substrateapi.SubstrateRawTxIn.prototype.getRawdata = function() {
176 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
177 | };
178 |
179 |
180 | /**
181 | * @param {string} value
182 | * @return {!proto.substrateapi.SubstrateRawTxIn} returns this
183 | */
184 | proto.substrateapi.SubstrateRawTxIn.prototype.setRawdata = function(value) {
185 | return jspb.Message.setProto3StringField(this, 1, value);
186 | };
187 |
188 |
189 |
190 |
191 |
192 | if (jspb.Message.GENERATE_TO_OBJECT) {
193 | /**
194 | * Creates an object representation of this proto.
195 | * Field names that are reserved in JavaScript and will be renamed to pb_name.
196 | * Optional fields that are not set will be set to undefined.
197 | * To access a reserved field use, foo.pb_, eg, foo.pb_default.
198 | * For the list of reserved names please see:
199 | * net/proto2/compiler/js/internal/generator.cc#kKeyword.
200 | * @param {boolean=} opt_includeInstance Deprecated. whether to include the
201 | * JSPB instance for transitional soy proto support:
202 | * http://goto/soy-param-migration
203 | * @return {!Object}
204 | */
205 | proto.substrateapi.SubstrateTxOut.prototype.toObject = function(opt_includeInstance) {
206 | return proto.substrateapi.SubstrateTxOut.toObject(opt_includeInstance, this);
207 | };
208 |
209 |
210 | /**
211 | * Static version of the {@see toObject} method.
212 | * @param {boolean|undefined} includeInstance Deprecated. Whether to include
213 | * the JSPB instance for transitional soy proto support:
214 | * http://goto/soy-param-migration
215 | * @param {!proto.substrateapi.SubstrateTxOut} msg The msg instance to transform.
216 | * @return {!Object}
217 | * @suppress {unusedLocalVariables} f is only used for nested messages
218 | */
219 | proto.substrateapi.SubstrateTxOut.toObject = function(includeInstance, msg) {
220 | var f, obj = {
221 | signature: jspb.Message.getFieldWithDefault(msg, 1, "")
222 | };
223 |
224 | if (includeInstance) {
225 | obj.$jspbMessageInstance = msg;
226 | }
227 | return obj;
228 | };
229 | }
230 |
231 |
232 | /**
233 | * Deserializes binary data (in protobuf wire format).
234 | * @param {jspb.ByteSource} bytes The bytes to deserialize.
235 | * @return {!proto.substrateapi.SubstrateTxOut}
236 | */
237 | proto.substrateapi.SubstrateTxOut.deserializeBinary = function(bytes) {
238 | var reader = new jspb.BinaryReader(bytes);
239 | var msg = new proto.substrateapi.SubstrateTxOut;
240 | return proto.substrateapi.SubstrateTxOut.deserializeBinaryFromReader(msg, reader);
241 | };
242 |
243 |
244 | /**
245 | * Deserializes binary data (in protobuf wire format) from the
246 | * given reader into the given message object.
247 | * @param {!proto.substrateapi.SubstrateTxOut} msg The message object to deserialize into.
248 | * @param {!jspb.BinaryReader} reader The BinaryReader to use.
249 | * @return {!proto.substrateapi.SubstrateTxOut}
250 | */
251 | proto.substrateapi.SubstrateTxOut.deserializeBinaryFromReader = function(msg, reader) {
252 | while (reader.nextField()) {
253 | if (reader.isEndGroup()) {
254 | break;
255 | }
256 | var field = reader.getFieldNumber();
257 | switch (field) {
258 | case 1:
259 | var value = /** @type {string} */ (reader.readString());
260 | msg.setSignature(value);
261 | break;
262 | default:
263 | reader.skipField();
264 | break;
265 | }
266 | }
267 | return msg;
268 | };
269 |
270 |
271 | /**
272 | * Serializes the message to binary data (in protobuf wire format).
273 | * @return {!Uint8Array}
274 | */
275 | proto.substrateapi.SubstrateTxOut.prototype.serializeBinary = function() {
276 | var writer = new jspb.BinaryWriter();
277 | proto.substrateapi.SubstrateTxOut.serializeBinaryToWriter(this, writer);
278 | return writer.getResultBuffer();
279 | };
280 |
281 |
282 | /**
283 | * Serializes the given message to binary data (in protobuf wire
284 | * format), writing to the given BinaryWriter.
285 | * @param {!proto.substrateapi.SubstrateTxOut} message
286 | * @param {!jspb.BinaryWriter} writer
287 | * @suppress {unusedLocalVariables} f is only used for nested messages
288 | */
289 | proto.substrateapi.SubstrateTxOut.serializeBinaryToWriter = function(message, writer) {
290 | var f = undefined;
291 | f = message.getSignature();
292 | if (f.length > 0) {
293 | writer.writeString(
294 | 1,
295 | f
296 | );
297 | }
298 | };
299 |
300 |
301 | /**
302 | * optional string signature = 1;
303 | * @return {string}
304 | */
305 | proto.substrateapi.SubstrateTxOut.prototype.getSignature = function() {
306 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
307 | };
308 |
309 |
310 | /**
311 | * @param {string} value
312 | * @return {!proto.substrateapi.SubstrateTxOut} returns this
313 | */
314 | proto.substrateapi.SubstrateTxOut.prototype.setSignature = function(value) {
315 | return jspb.Message.setProto3StringField(this, 1, value);
316 | };
317 |
318 |
319 | goog.object.extend(exports, proto.substrateapi);
320 |
--------------------------------------------------------------------------------
/src/renderer/views/welcomeHome.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{$t('m.imKeyManager.welcome_used_imkKey_manager')}}
4 | {{$t('m.imKeyManager.imKey_manager_is_desktop_manager')}}
5 |
6 |
7 |
10 | {{$t('m.imKeyManager.imKey_wallet_version_manager')}}
11 |
12 |
13 |
16 | {{$t('m.imKeyManager.imKey_APP_version_manager')}}
17 |
18 |
19 |
22 | {{$t('m.imKeyManager.fast_connect_desktop_APP')}}
23 |
24 |
25 | {{$t('m.imKeyManager.used_this_desktop_APP')}}
26 |
62 |
63 |
64 |
65 |
87 |
88 |
209 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/src/proto/common_pb.js:
--------------------------------------------------------------------------------
1 | // source: common.proto
2 | /**
3 | * @fileoverview
4 | * @enhanceable
5 | * @suppress {messageConventions} JS Compiler reports an error if a variable or
6 | * field starts with 'MSG_' and isn't a translatable message.
7 | * @public
8 | */
9 | // GENERATED CODE -- DO NOT EDIT!
10 |
11 | var jspb = require('google-protobuf');
12 | var goog = jspb;
13 | var global = Function('return this')();
14 |
15 | var google_protobuf_any_pb = require('google-protobuf/google/protobuf/any_pb.js');
16 | goog.object.extend(proto, google_protobuf_any_pb);
17 | goog.exportSymbol('proto.common.SignParam', null, global);
18 | /**
19 | * Generated by JsPbCodeGenerator.
20 | * @param {Array=} opt_data Optional initial data array, typically from a
21 | * server response, or constructed directly in Javascript. The array is used
22 | * in place and becomes part of the constructed object. It is not cloned.
23 | * If no data is provided, the constructed object will be empty, but still
24 | * valid.
25 | * @extends {jspb.Message}
26 | * @constructor
27 | */
28 | proto.common.SignParam = function(opt_data) {
29 | jspb.Message.initialize(this, opt_data, 0, -1, null, null);
30 | };
31 | goog.inherits(proto.common.SignParam, jspb.Message);
32 | if (goog.DEBUG && !COMPILED) {
33 | /**
34 | * @public
35 | * @override
36 | */
37 | proto.common.SignParam.displayName = 'proto.common.SignParam';
38 | }
39 |
40 |
41 |
42 | if (jspb.Message.GENERATE_TO_OBJECT) {
43 | /**
44 | * Creates an object representation of this proto.
45 | * Field names that are reserved in JavaScript and will be renamed to pb_name.
46 | * Optional fields that are not set will be set to undefined.
47 | * To access a reserved field use, foo.pb_, eg, foo.pb_default.
48 | * For the list of reserved names please see:
49 | * net/proto2/compiler/js/internal/generator.cc#kKeyword.
50 | * @param {boolean=} opt_includeInstance Deprecated. whether to include the
51 | * JSPB instance for transitional soy proto support:
52 | * http://goto/soy-param-migration
53 | * @return {!Object}
54 | */
55 | proto.common.SignParam.prototype.toObject = function(opt_includeInstance) {
56 | return proto.common.SignParam.toObject(opt_includeInstance, this);
57 | };
58 |
59 |
60 | /**
61 | * Static version of the {@see toObject} method.
62 | * @param {boolean|undefined} includeInstance Deprecated. Whether to include
63 | * the JSPB instance for transitional soy proto support:
64 | * http://goto/soy-param-migration
65 | * @param {!proto.common.SignParam} msg The msg instance to transform.
66 | * @return {!Object}
67 | * @suppress {unusedLocalVariables} f is only used for nested messages
68 | */
69 | proto.common.SignParam.toObject = function(includeInstance, msg) {
70 | var f, obj = {
71 | chaintype: jspb.Message.getFieldWithDefault(msg, 1, ""),
72 | path: jspb.Message.getFieldWithDefault(msg, 2, ""),
73 | network: jspb.Message.getFieldWithDefault(msg, 3, ""),
74 | input: (f = msg.getInput()) && google_protobuf_any_pb.Any.toObject(includeInstance, f),
75 | payment: jspb.Message.getFieldWithDefault(msg, 5, ""),
76 | receiver: jspb.Message.getFieldWithDefault(msg, 6, ""),
77 | sender: jspb.Message.getFieldWithDefault(msg, 7, ""),
78 | fee: jspb.Message.getFieldWithDefault(msg, 8, "")
79 | };
80 |
81 | if (includeInstance) {
82 | obj.$jspbMessageInstance = msg;
83 | }
84 | return obj;
85 | };
86 | }
87 |
88 |
89 | /**
90 | * Deserializes binary data (in protobuf wire format).
91 | * @param {jspb.ByteSource} bytes The bytes to deserialize.
92 | * @return {!proto.common.SignParam}
93 | */
94 | proto.common.SignParam.deserializeBinary = function(bytes) {
95 | var reader = new jspb.BinaryReader(bytes);
96 | var msg = new proto.common.SignParam;
97 | return proto.common.SignParam.deserializeBinaryFromReader(msg, reader);
98 | };
99 |
100 |
101 | /**
102 | * Deserializes binary data (in protobuf wire format) from the
103 | * given reader into the given message object.
104 | * @param {!proto.common.SignParam} msg The message object to deserialize into.
105 | * @param {!jspb.BinaryReader} reader The BinaryReader to use.
106 | * @return {!proto.common.SignParam}
107 | */
108 | proto.common.SignParam.deserializeBinaryFromReader = function(msg, reader) {
109 | while (reader.nextField()) {
110 | if (reader.isEndGroup()) {
111 | break;
112 | }
113 | var field = reader.getFieldNumber();
114 | switch (field) {
115 | case 1:
116 | var value = /** @type {string} */ (reader.readString());
117 | msg.setChaintype(value);
118 | break;
119 | case 2:
120 | var value = /** @type {string} */ (reader.readString());
121 | msg.setPath(value);
122 | break;
123 | case 3:
124 | var value = /** @type {string} */ (reader.readString());
125 | msg.setNetwork(value);
126 | break;
127 | case 4:
128 | var value = new google_protobuf_any_pb.Any;
129 | reader.readMessage(value,google_protobuf_any_pb.Any.deserializeBinaryFromReader);
130 | msg.setInput(value);
131 | break;
132 | case 5:
133 | var value = /** @type {string} */ (reader.readString());
134 | msg.setPayment(value);
135 | break;
136 | case 6:
137 | var value = /** @type {string} */ (reader.readString());
138 | msg.setReceiver(value);
139 | break;
140 | case 7:
141 | var value = /** @type {string} */ (reader.readString());
142 | msg.setSender(value);
143 | break;
144 | case 8:
145 | var value = /** @type {string} */ (reader.readString());
146 | msg.setFee(value);
147 | break;
148 | default:
149 | reader.skipField();
150 | break;
151 | }
152 | }
153 | return msg;
154 | };
155 |
156 |
157 | /**
158 | * Serializes the message to binary data (in protobuf wire format).
159 | * @return {!Uint8Array}
160 | */
161 | proto.common.SignParam.prototype.serializeBinary = function() {
162 | var writer = new jspb.BinaryWriter();
163 | proto.common.SignParam.serializeBinaryToWriter(this, writer);
164 | return writer.getResultBuffer();
165 | };
166 |
167 |
168 | /**
169 | * Serializes the given message to binary data (in protobuf wire
170 | * format), writing to the given BinaryWriter.
171 | * @param {!proto.common.SignParam} message
172 | * @param {!jspb.BinaryWriter} writer
173 | * @suppress {unusedLocalVariables} f is only used for nested messages
174 | */
175 | proto.common.SignParam.serializeBinaryToWriter = function(message, writer) {
176 | var f = undefined;
177 | f = message.getChaintype();
178 | if (f.length > 0) {
179 | writer.writeString(
180 | 1,
181 | f
182 | );
183 | }
184 | f = message.getPath();
185 | if (f.length > 0) {
186 | writer.writeString(
187 | 2,
188 | f
189 | );
190 | }
191 | f = message.getNetwork();
192 | if (f.length > 0) {
193 | writer.writeString(
194 | 3,
195 | f
196 | );
197 | }
198 | f = message.getInput();
199 | if (f != null) {
200 | writer.writeMessage(
201 | 4,
202 | f,
203 | google_protobuf_any_pb.Any.serializeBinaryToWriter
204 | );
205 | }
206 | f = message.getPayment();
207 | if (f.length > 0) {
208 | writer.writeString(
209 | 5,
210 | f
211 | );
212 | }
213 | f = message.getReceiver();
214 | if (f.length > 0) {
215 | writer.writeString(
216 | 6,
217 | f
218 | );
219 | }
220 | f = message.getSender();
221 | if (f.length > 0) {
222 | writer.writeString(
223 | 7,
224 | f
225 | );
226 | }
227 | f = message.getFee();
228 | if (f.length > 0) {
229 | writer.writeString(
230 | 8,
231 | f
232 | );
233 | }
234 | };
235 |
236 |
237 | /**
238 | * optional string chainType = 1;
239 | * @return {string}
240 | */
241 | proto.common.SignParam.prototype.getChaintype = function() {
242 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
243 | };
244 |
245 |
246 | /**
247 | * @param {string} value
248 | * @return {!proto.common.SignParam} returns this
249 | */
250 | proto.common.SignParam.prototype.setChaintype = function(value) {
251 | return jspb.Message.setProto3StringField(this, 1, value);
252 | };
253 |
254 |
255 | /**
256 | * optional string path = 2;
257 | * @return {string}
258 | */
259 | proto.common.SignParam.prototype.getPath = function() {
260 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
261 | };
262 |
263 |
264 | /**
265 | * @param {string} value
266 | * @return {!proto.common.SignParam} returns this
267 | */
268 | proto.common.SignParam.prototype.setPath = function(value) {
269 | return jspb.Message.setProto3StringField(this, 2, value);
270 | };
271 |
272 |
273 | /**
274 | * optional string network = 3;
275 | * @return {string}
276 | */
277 | proto.common.SignParam.prototype.getNetwork = function() {
278 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
279 | };
280 |
281 |
282 | /**
283 | * @param {string} value
284 | * @return {!proto.common.SignParam} returns this
285 | */
286 | proto.common.SignParam.prototype.setNetwork = function(value) {
287 | return jspb.Message.setProto3StringField(this, 3, value);
288 | };
289 |
290 |
291 | /**
292 | * optional google.protobuf.Any input = 4;
293 | * @return {?proto.google.protobuf.Any}
294 | */
295 | proto.common.SignParam.prototype.getInput = function() {
296 | return /** @type{?proto.google.protobuf.Any} */ (
297 | jspb.Message.getWrapperField(this, google_protobuf_any_pb.Any, 4));
298 | };
299 |
300 |
301 | /**
302 | * @param {?proto.google.protobuf.Any|undefined} value
303 | * @return {!proto.common.SignParam} returns this
304 | */
305 | proto.common.SignParam.prototype.setInput = function(value) {
306 | return jspb.Message.setWrapperField(this, 4, value);
307 | };
308 |
309 |
310 | /**
311 | * Clears the message field making it undefined.
312 | * @return {!proto.common.SignParam} returns this
313 | */
314 | proto.common.SignParam.prototype.clearInput = function() {
315 | return this.setInput(undefined);
316 | };
317 |
318 |
319 | /**
320 | * Returns whether this field is set.
321 | * @return {boolean}
322 | */
323 | proto.common.SignParam.prototype.hasInput = function() {
324 | return jspb.Message.getField(this, 4) != null;
325 | };
326 |
327 |
328 | /**
329 | * optional string payment = 5;
330 | * @return {string}
331 | */
332 | proto.common.SignParam.prototype.getPayment = function() {
333 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
334 | };
335 |
336 |
337 | /**
338 | * @param {string} value
339 | * @return {!proto.common.SignParam} returns this
340 | */
341 | proto.common.SignParam.prototype.setPayment = function(value) {
342 | return jspb.Message.setProto3StringField(this, 5, value);
343 | };
344 |
345 |
346 | /**
347 | * optional string receiver = 6;
348 | * @return {string}
349 | */
350 | proto.common.SignParam.prototype.getReceiver = function() {
351 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
352 | };
353 |
354 |
355 | /**
356 | * @param {string} value
357 | * @return {!proto.common.SignParam} returns this
358 | */
359 | proto.common.SignParam.prototype.setReceiver = function(value) {
360 | return jspb.Message.setProto3StringField(this, 6, value);
361 | };
362 |
363 |
364 | /**
365 | * optional string sender = 7;
366 | * @return {string}
367 | */
368 | proto.common.SignParam.prototype.getSender = function() {
369 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
370 | };
371 |
372 |
373 | /**
374 | * @param {string} value
375 | * @return {!proto.common.SignParam} returns this
376 | */
377 | proto.common.SignParam.prototype.setSender = function(value) {
378 | return jspb.Message.setProto3StringField(this, 7, value);
379 | };
380 |
381 |
382 | /**
383 | * optional string fee = 8;
384 | * @return {string}
385 | */
386 | proto.common.SignParam.prototype.getFee = function() {
387 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
388 | };
389 |
390 |
391 | /**
392 | * @param {string} value
393 | * @return {!proto.common.SignParam} returns this
394 | */
395 | proto.common.SignParam.prototype.setFee = function(value) {
396 | return jspb.Message.setProto3StringField(this, 8, value);
397 | };
398 |
399 |
400 | goog.object.extend(exports, proto.common);
401 |
--------------------------------------------------------------------------------
/src/api/ethereumdapp.js:
--------------------------------------------------------------------------------
1 | // const KOVAN_RPC_URL = 'https://kovan.infura.io'
2 | // const ETHEREUM_MAIN_NET = 'https://kovan.infura.io'
3 |
4 | const { contextBridge, ipcRenderer } = require('electron')
5 |
6 | // Expose protected methods that allow the renderer process to use
7 | // the ipcRenderer without exposing the entire object
8 | contextBridge.exposeInMainWorld(
9 | 'imToken',
10 | {
11 | callPromisifyAPI: async (data) => {
12 | console.log('call Native Api before ipcRender')
13 | return await ipcRenderer.invoke('imkey-api', data)
14 | }
15 | }
16 | )
17 | /**
18 | * EIP 1102 and EIP 1193
19 | */
20 |
21 | const createEthereumProviderScript = function () {
22 | const imToken = window.top.imToken
23 |
24 | if (window.__inTokenSDKInjecked) return
25 |
26 | function createJsonrpcResponse (payload, result) {
27 | const response = payload
28 | response.result = result
29 | return response
30 | }
31 |
32 | // function createJsonrpcError (payload, error) {
33 | // const response = payload
34 | // response.error = error
35 | // response.result = null
36 | // return response
37 | // }
38 |
39 | function inherits (ctor, superCtor) {
40 | ctor.super_ = superCtor
41 | ctor.prototype = Object.create(superCtor.prototype, {
42 | constructor: {
43 | value: ctor,
44 | enumerable: false,
45 | writable: true,
46 | configurable: true
47 | }
48 | })
49 | }
50 |
51 | // only alert one time
52 | _alerted = false
53 |
54 | function _showEnableTip () {
55 | // !_alerted && imToken.callAPI('native.toastInfo', 'you should call ethereum.enable() first to access web3.eth.defaultAccount and web3.eth.accounts')
56 | // _alerted = true
57 | }
58 |
59 | let accounts = __accounts__
60 |
61 | function EthereumProvider () {
62 | EventEmitter.call(this)
63 | /**
64 | * https://metamask.github.io/metamask-docs/API_Reference/Ethereum_Provider#properties
65 | */
66 | this.networkVersion = __netVersion__
67 | this.chainId = __chainId__
68 | this.selectedAddress = accounts[0]
69 | this.isImToken = true
70 | this._isConnected = true
71 | this._nextJsonrpcId = 10000
72 |
73 | this._connect()
74 | }
75 |
76 | /**
77 | * https://github.com/ethereum/web3.js/blob/v1.0.0-beta.11/packages/web3-core-requestmanager/src/givenProvider.js#L38-L40
78 | * Note: We must use prototype inherit here, cannot use ES6 class extends, otherwise sendAsync method will be delete in web3.js 1.0 version
79 | */
80 | inherits(EthereumProvider, EventEmitter)
81 |
82 | // https://github.com/ensdomains/ens-app/pull/296
83 | EthereumProvider.prototype.supportsSubscriptions = () => false
84 |
85 | EthereumProvider.prototype.enable = function (payload) {
86 | if (imToken.addressAccessDenied) {
87 | return Promise.reject(new Error('user_canceled'))
88 | }
89 | return imToken.callPromisifyAPI('ethereum.enable', payload).then(_accounts => {
90 | accounts = _accounts
91 | window.ethereum.selectedAddress = accounts[0]
92 | return _accounts
93 | }).catch(err => {
94 | imToken.addressAccessDenied = true
95 | throw err
96 | })
97 | }
98 |
99 | EthereumProvider.prototype._connect = function () {
100 | this.emit('connect', {
101 | chainId: __chainId__
102 | })
103 | this.once('close', this._connect.bind(this))
104 | }
105 |
106 | EthereumProvider.prototype.isConnected = function () {
107 | return this._isConnected
108 | }
109 |
110 | /**
111 | * Events
112 | */
113 | EthereumProvider.prototype._emitNotification = function (result) {
114 | this.emit('notification', result)
115 | }
116 |
117 | EthereumProvider.prototype._emitConnect = function () {
118 | this._isConnected = true
119 | this.emit('connect')
120 | }
121 |
122 | EthereumProvider.prototype._emitClose = function (code, reason) {
123 | this._isConnected = false
124 | this.emit('close', code, reason)
125 | }
126 |
127 | EthereumProvider.prototype._emitNetworkChanged = function (networkId) {
128 | this.emit('networkChanged', networkId)
129 | }
130 |
131 | EthereumProvider.prototype._emitAccountsChanged = function (accounts) {
132 | this.emit('accountsChanged', accounts)
133 | }
134 |
135 | /**
136 | * EIP1103 send
137 | * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1193.md#send-1
138 | */
139 | EthereumProvider.prototype._eip1193Send = function (method, params) {
140 | const id = this._nextJsonrpcId++
141 |
142 | const payload = {
143 | jsonrpc: '2.0',
144 | id,
145 | method,
146 | params
147 | }
148 |
149 | if (payload.method === 'eth_requestAccounts') {
150 | return this.enable()
151 | }
152 |
153 | // https://tower.im/teams/349901/todos/16653/
154 | if (payload.method === 'eth_subscribe') {
155 | // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1193.md#error-object-and-codes
156 | // https://github.com/ethereum/web3.js/blob/a5a739b7d1834b53b7268c57f791db5d07b720da/packages/web3-core-method/src/index.js#L559-L560
157 | // https://github.com/ethereum/web3.js/issues/3669
158 | const error = new Error('eth_subscribe is not supported')
159 | error.code = 4200
160 | return Promise.reject(error)
161 | }
162 |
163 | return imToken.callPromisifyAPI('ethereum.sendAsync', payload)
164 | .then(response => {
165 | /**
166 | * return jsonrpc result.result
167 | */
168 | if (response.jsonrpc && response.hasOwnProperty('result')) {
169 | return response.result
170 | }
171 |
172 | if (!response.id) {
173 | if (response.method && response.method.indexOf('_subscription') > -1) {
174 | // Emit subscription notification
175 | this._emitNotification(message.params)
176 | }
177 | }
178 |
179 | return response
180 | })
181 | }
182 |
183 | /**
184 | * EIP1193 request
185 | */
186 | EthereumProvider.prototype.request = function (payload) {
187 | /**
188 | * because a web3.js bug https://github.com/ethereum/web3.js/pull/3649#issuecomment-695200876
189 | * we can't use `this._eip1193Send` here.
190 | * use `prototype` instead `this` can't solve this miss of `this` context.
191 | * it only fixed the problem that can't found `this._eip1193Send` method.
192 | * luckly we didn't use any `this` inside the `_eip1193Send` method.
193 | */
194 | return EthereumProvider.prototype._eip1193Send(payload.method, payload.params)
195 | }
196 |
197 | /**
198 | * case1: eip1193 send
199 | * case2: web3.js 0.1x send
200 | * case3 web3.js 1.x send
201 | */
202 | EthereumProvider.prototype.send = function (method, params) {
203 | return this._send(method, params)
204 | }
205 |
206 | EthereumProvider.prototype.sendAsync = function (payload, callback) {
207 | return this._sendAsync(payload, callback)
208 | }
209 |
210 | EthereumProvider.prototype._send = function (method, params) {
211 | if (!method) {
212 | return new Error('method is null')
213 | }
214 |
215 | /**
216 | * web3 httpProvider sync send, need return jsonrpc response
217 | */
218 | if (typeof method === 'object' && typeof method.method === 'string') {
219 | const payload = method
220 | cb = params
221 |
222 | /**
223 | * treat as web3 sendAsync, return by callback
224 | */
225 | if (typeof cb === 'function') {
226 | return this._sendAsync(payload, cb)
227 | } else {
228 | /**
229 | * return result
230 | */
231 | return this._sendSync(payload)
232 | }
233 | } else if (typeof method === 'string') {
234 | return this._eip1193Send(method, params)
235 | }
236 | }
237 |
238 | /**
239 | * web3.js Provider send Backwards Compatibility
240 | */
241 | EthereumProvider.prototype._sendSync = function (payload) {
242 | switch (payload.method) {
243 | case 'net_version':
244 | return createJsonrpcResponse(payload, __netVersion__)
245 | case 'eth_chainId':
246 | return createJsonrpcResponse(payload, __chainId__)
247 |
248 | case 'eth_accounts':
249 | if (!accounts[0]) {
250 | _showEnableTip()
251 | }
252 | return createJsonrpcResponse(payload, accounts)
253 |
254 | case 'eth_uninstallFilter':
255 | this._sendAsync(payload)
256 | return createJsonrpcResponse(payload, true)
257 |
258 | case 'eth_coinbase':
259 | return createJsonrpcResponse(payload, accounts[0])
260 | default:
261 | console.error('The imToken Web3 object does not support synchronous methods like ' + payload.method + ' without a callback parameter.')
262 | return this._eip1193Send(payload.method, payload.params)
263 | }
264 | }
265 |
266 | /**
267 | * web3.js Provider sendAsync Backwards Compatibility
268 | */
269 | EthereumProvider.prototype._sendAsync = function (payload, callback) {
270 | if (imToken.addressAccessDenied) {
271 | return Promise.reject(new Error('user_canceled'))
272 | }
273 | /**
274 | * https://github.com/ethereum/web3.js/blob/v1.0.0-beta.11/packages/web3-core-requestmanager/src/givenProvider.js#L38-L40
275 | * cause web3.js 1.0 delete sendAsync and set sendAsync to send, this is incompatible with EIP1193
276 | */
277 | if (typeof payload === 'string') {
278 | return this._eip1193Send(payload, callback)
279 | }
280 |
281 | // for batch payload
282 | if (Array.isArray(payload)) {
283 | return imToken.callPromisifyAPI('ethereum.sendAsync', payload)
284 | .then((response) => {
285 | return callback(null, response)
286 | }).catch((err) => {
287 | callback(err, null)
288 | console.error('Error from EthereumProvider sendAsync ' + JSON.stringify(payload) + ': ' + (err.message || err.toString()))
289 | })
290 | }
291 |
292 | /**
293 | * normal web3 sendAsync
294 | * payload: {method, params, id, jsonrpc}
295 | */
296 | return this._eip1193Send(payload.method, payload.params).then(r => {
297 | callback(null, createJsonrpcResponse(payload, r))
298 | }).catch(err => {
299 | const approveMethods = ['eth_requestAccounts', 'personal_listAccounts', 'eth_accounts']
300 | if (approveMethods.indexOf(payload.method) !== -1) {
301 | imToken.addressAccessDenied = true
302 | }
303 | callback(err, null)
304 | console.error('Error from EthereumProvider sendAsync ' + JSON.stringify(payload) + ': ' + (err.message || err.toString()))
305 | })
306 | }
307 |
308 | const web3EthProxyHandler = {
309 | get: function (obj, prop) {
310 | switch (prop) {
311 | case 'defaultAccount':
312 | if (accounts[0]) {
313 | return accounts[0]
314 | } else {
315 | _showEnableTip()
316 | return undefined
317 | }
318 | case 'accounts':
319 | // https://web3js.readthedocs.io/en/v1.2.0/web3-eth-accounts.html
320 | if (typeof obj[prop] === 'object' && obj[prop].create) {
321 | return obj[prop]
322 | // https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethaccounts
323 | } else {
324 | if (accounts[0]) {
325 | return accounts
326 | } else {
327 | _showEnableTip()
328 | return []
329 | }
330 | }
331 | default:
332 | return obj[prop]
333 | }
334 | }
335 | }
336 |
337 | // https://github.com/ethereum/web3.js/blob/v1.2.6/packages/web3-core-requestmanager/src/givenProvider.js#L36
338 | window.ethereum = window.ethereumProvider = new EthereumProvider()
339 |
340 | // inject web3 as default
341 | if (typeof Web3 !== 'undefined') {
342 | window.web3 = new Web3(window.ethereum)
343 |
344 | window.web3.eth.defaultAccount = accounts[0]
345 |
346 | // for web3.js 1.0 givenProvider
347 | window.web3.givenProvider = window.ethereum
348 | window.web3.eth.givenProvider = window.ethereum
349 |
350 | const _oldWe3Eth = window.web3.eth
351 | window.web3.eth = new Proxy(_oldWe3Eth, web3EthProxyHandler)
352 | }
353 |
354 | window.__inTokenSDKInjecked = true
355 | }
356 |
357 | export default (dappUrl, needInjectWeb3) => {
358 | const isApproved = needInjectWeb3 || selectIsApproved(dappUrl)
359 |
360 | const _accounts = isApproved ? getEthereumAccounts() : []
361 | // https://eips.ethereum.org/EIPS/eip-695 hex string
362 | const _chainId = `0x${parseInt(16)}`
363 | // number
364 | const _netVersion = parseInt(10)
365 |
366 | const template = `;(${createEthereumProviderScript.toString()}());`
367 | return template
368 | .replace(/__accounts__/g, JSON.stringify(_accounts))
369 | .replace(/__netVersion__/g, JSON.stringify(_netVersion))
370 | .replace(/__chainId__/g, JSON.stringify(_chainId))
371 | }
372 |
--------------------------------------------------------------------------------
/test/e2e/specs/api.spec.js:
--------------------------------------------------------------------------------
1 | // Require the dev-dependencies
2 | const chai = require('chai')
3 | const chaiHttp = require('chai-http')
4 | const fs = require('fs')
5 | const path = require('path')
6 | const testJsonPath = path.resolve('./test/e2e/specs/test.json')
7 | chai.use(chaiHttp)
8 |
9 | describe('Api', () => {
10 | const testObj = readFileToJsonObj(testJsonPath)
11 | const testJsonArr = []
12 | for (const json in testObj) {
13 | testJsonArr.push(json)
14 | console.log('json:' + json)
15 | }
16 | it('test ' + testJsonArr[0], (done) => {
17 | const reqJson = testObj[testJsonArr[0]]
18 | console.log('request:' + JSON.stringify(reqJson))
19 | chai.request('127.0.0.1:8081')
20 | .post('/api/imKey')
21 | .send(reqJson)
22 | .end((err, res) => {
23 | if (err) {
24 | console.log(err.stack)
25 | }
26 | console.log('response:' + JSON.stringify(res.body))
27 | expect(res.status).to.equal(200)
28 | expect(JSON.stringify(res.body.result)).to.equal(JSON.stringify(testObj[testJsonArr[1]].result))
29 | done()
30 | })
31 | }).timeout(30000)
32 |
33 | it('test ' + testJsonArr[2], (done) => {
34 | const reqJson = testObj[testJsonArr[2]]
35 | console.log('request:' + JSON.stringify(reqJson))
36 | chai.request('127.0.0.1:8081')
37 | .post('/api/imKey')
38 | .send(reqJson)
39 | .end((err, res) => {
40 | if (err) {
41 | console.log(err.stack)
42 | }
43 | console.log('response:' + JSON.stringify(res.body))
44 | expect(res.status).to.equal(200)
45 | expect(JSON.stringify(res.body.result)).to.equal(JSON.stringify(testObj[testJsonArr[3]].result))
46 | done()
47 | })
48 | }).timeout(30000)
49 | it('test ' + testJsonArr[4], (done) => {
50 | const reqJson = testObj[testJsonArr[4]]
51 | console.log('request:' + JSON.stringify(reqJson))
52 | chai.request('127.0.0.1:8081')
53 | .post('/api/imKey')
54 | .send(reqJson)
55 | .end((err, res) => {
56 | if (err) {
57 | console.log(err.stack)
58 | }
59 | console.log('response:' + JSON.stringify(res.body))
60 | expect(res.status).to.equal(200)
61 | expect(JSON.stringify(res.body.result)).to.equal(JSON.stringify(testObj[testJsonArr[5]].result))
62 | done()
63 | })
64 | }).timeout(30000)
65 | it('test ' + testJsonArr[6], (done) => {
66 | const reqJson = testObj[testJsonArr[6]]
67 | console.log('request:' + JSON.stringify(reqJson))
68 | chai.request('127.0.0.1:8081')
69 | .post('/api/imKey')
70 | .send(reqJson)
71 | .end((err, res) => {
72 | if (err) {
73 | console.log(err.stack)
74 | }
75 | console.log('response:' + JSON.stringify(res.body))
76 | expect(res.status).to.equal(200)
77 | expect(JSON.stringify(res.body.result)).to.equal(JSON.stringify(testObj[testJsonArr[7]].result))
78 | done()
79 | })
80 | }).timeout(30000)
81 | it('test ' + testJsonArr[8], (done) => {
82 | const reqJson = testObj[testJsonArr[8]]
83 | console.log('request:' + JSON.stringify(reqJson))
84 | chai.request('127.0.0.1:8081')
85 | .post('/api/imKey')
86 | .send(reqJson)
87 | .end((err, res) => {
88 | if (err) {
89 | console.log(err.stack)
90 | }
91 | console.log('response:' + JSON.stringify(res.body))
92 | expect(res.status).to.equal(200)
93 | expect(JSON.stringify(res.body.result)).to.equal(JSON.stringify(testObj[testJsonArr[9]].result))
94 | done()
95 | })
96 | }).timeout(30000)
97 | it('test ' + testJsonArr[10], (done) => {
98 | const reqJson = testObj[testJsonArr[10]]
99 | console.log('request:' + JSON.stringify(reqJson))
100 | chai.request('127.0.0.1:8081')
101 | .post('/api/imKey')
102 | .send(reqJson)
103 | .end((err, res) => {
104 | if (err) {
105 | console.log(err.stack)
106 | }
107 | console.log('response:' + JSON.stringify(res.body))
108 | expect(res.status).to.equal(200)
109 | expect(JSON.stringify(res.body.result)).to.equal(JSON.stringify(testObj[testJsonArr[11]].result))
110 | done()
111 | })
112 | }).timeout(30000)
113 | it('test ' + testJsonArr[12], (done) => {
114 | const reqJson = testObj[testJsonArr[12]]
115 | console.log('request:' + JSON.stringify(reqJson))
116 | chai.request('127.0.0.1:8081')
117 | .post('/api/imKey')
118 | .send(reqJson)
119 | .end((err, res) => {
120 | if (err) {
121 | console.log(err.stack)
122 | }
123 | console.log('response:' + JSON.stringify(res.body))
124 | expect(res.status).to.equal(200)
125 | expect(JSON.stringify(res.body.result)).to.equal(JSON.stringify(testObj[testJsonArr[13]].result))
126 | done()
127 | })
128 | }).timeout(30000)
129 | it('test ' + testJsonArr[14], (done) => {
130 | const reqJson = testObj[testJsonArr[14]]
131 | console.log('request:' + JSON.stringify(reqJson))
132 | chai.request('127.0.0.1:8081')
133 | .post('/api/imKey')
134 | .send(reqJson)
135 | .end((err, res) => {
136 | if (err) {
137 | console.log(err.stack)
138 | }
139 | console.log('response:' + JSON.stringify(res.body))
140 | expect(res.status).to.equal(200)
141 | expect(JSON.stringify(res.body.result)).to.equal(JSON.stringify(testObj[testJsonArr[15]].result))
142 | done()
143 | })
144 | }).timeout(30000)
145 | it('test ' + testJsonArr[16], (done) => {
146 | const reqJson = testObj[testJsonArr[16]]
147 | console.log('request:' + JSON.stringify(reqJson))
148 | chai.request('127.0.0.1:8081')
149 | .post('/api/imKey')
150 | .send(reqJson)
151 | .end((err, res) => {
152 | if (err) {
153 | console.log(err.stack)
154 | }
155 | console.log('response:' + JSON.stringify(res.body))
156 | expect(res.status).to.equal(200)
157 | expect(JSON.stringify(res.body.result)).to.equal(JSON.stringify(testObj[testJsonArr[17]].result))
158 | done()
159 | })
160 | }).timeout(30000)
161 | it('test ' + testJsonArr[18], (done) => {
162 | const reqJson = testObj[testJsonArr[18]]
163 | console.log('request:' + JSON.stringify(reqJson))
164 | chai.request('127.0.0.1:8081')
165 | .post('/api/imKey')
166 | .send(reqJson)
167 | .end((err, res) => {
168 | if (err) {
169 | console.log(err.stack)
170 | }
171 | console.log('response:' + JSON.stringify(res.body))
172 | expect(res.status).to.equal(200)
173 | expect(JSON.stringify(res.body.result)).to.equal(JSON.stringify(testObj[testJsonArr[19]].result))
174 | done()
175 | })
176 | }).timeout(30000)
177 | it('test ' + testJsonArr[20], (done) => {
178 | const reqJson = testObj[testJsonArr[20]]
179 | console.log('request:' + JSON.stringify(reqJson))
180 | chai.request('127.0.0.1:8081')
181 | .post('/api/imKey')
182 | .send(reqJson)
183 | .end((err, res) => {
184 | if (err) {
185 | console.log(err.stack)
186 | }
187 | console.log('response:' + JSON.stringify(res.body))
188 | expect(res.status).to.equal(200)
189 | expect(JSON.stringify(res.body.result)).to.equal(JSON.stringify(testObj[testJsonArr[21]].result))
190 | done()
191 | })
192 | }).timeout(30000)
193 | it('test ' + testJsonArr[22], (done) => {
194 | const reqJson = testObj[testJsonArr[22]]
195 | console.log('request:' + JSON.stringify(reqJson))
196 | chai.request('127.0.0.1:8081')
197 | .post('/api/imKey')
198 | .send(reqJson)
199 | .end((err, res) => {
200 | if (err) {
201 | console.log(err.stack)
202 | }
203 | console.log('response:' + JSON.stringify(res.body))
204 | expect(res.status).to.equal(200)
205 | expect(JSON.stringify(res.body.result)).to.equal(JSON.stringify(testObj[testJsonArr[23]].result))
206 | done()
207 | })
208 | }).timeout(30000)
209 | it('test ' + testJsonArr[24], (done) => {
210 | const reqJson = testObj[testJsonArr[24]]
211 | console.log('request:' + JSON.stringify(reqJson))
212 | chai.request('127.0.0.1:8081')
213 | .post('/api/imKey')
214 | .send(reqJson)
215 | .end((err, res) => {
216 | if (err) {
217 | console.log(err.stack)
218 | }
219 | console.log('response:' + JSON.stringify(res.body))
220 | expect(res.status).to.equal(200)
221 | expect(JSON.stringify(res.body.result)).to.equal(JSON.stringify(testObj[testJsonArr[25]].result))
222 | done()
223 | })
224 | }).timeout(30000)
225 |
226 | it('test ' + testJsonArr[26], (done) => {
227 | const reqJson = testObj[testJsonArr[26]]
228 | console.log('request:' + JSON.stringify(reqJson))
229 | chai.request('127.0.0.1:8081')
230 | .post('/api/imKey')
231 | .send(reqJson)
232 | .end((err, res) => {
233 | if (err) {
234 | console.log(err.stack)
235 | }
236 | console.log('response:' + JSON.stringify(res.body))
237 | expect(res.status).to.equal(200)
238 | expect(JSON.stringify(res.body.result)).to.equal(JSON.stringify(testObj[testJsonArr[27]].result))
239 | done()
240 | })
241 | }).timeout(30000)
242 | it('test ' + testJsonArr[28], (done) => {
243 | const reqJson = testObj[testJsonArr[28]]
244 | console.log('request:' + JSON.stringify(reqJson))
245 | chai.request('127.0.0.1:8081')
246 | .post('/api/imKey')
247 | .send(reqJson)
248 | .end((err, res) => {
249 | if (err) {
250 | console.log(err.stack)
251 | }
252 | console.log('response:' + JSON.stringify(res.body))
253 | expect(res.status).to.equal(200)
254 | expect(JSON.stringify(res.body.result)).to.equal(JSON.stringify(testObj[testJsonArr[29]].result))
255 | done()
256 | })
257 | }).timeout(30000)
258 |
259 | it('test ' + testJsonArr[30], (done) => {
260 | const reqJson = testObj[testJsonArr[30]]
261 | console.log('request:' + JSON.stringify(reqJson))
262 | chai.request('127.0.0.1:8081')
263 | .post('/api/imKey')
264 | .send(reqJson)
265 | .end((err, res) => {
266 | if (err) {
267 | console.log(err.stack)
268 | }
269 | console.log('response:' + JSON.stringify(res.body))
270 | expect(res.status).to.equal(200)
271 | expect(JSON.stringify(res.body.result)).to.equal(JSON.stringify(testObj[testJsonArr[31]].result))
272 | done()
273 | })
274 | }).timeout(30000)
275 | it('test ' + testJsonArr[32], (done) => {
276 | const reqJson = testObj[testJsonArr[32]]
277 | console.log('request:' + JSON.stringify(reqJson))
278 | chai.request('127.0.0.1:8081')
279 | .post('/api/imKey')
280 | .send(reqJson)
281 | .end((err, res) => {
282 | if (err) {
283 | console.log(err.stack)
284 | }
285 | console.log('response:' + JSON.stringify(res.body))
286 | expect(res.status).to.equal(200)
287 | expect(JSON.stringify(res.body.result)).to.equal(JSON.stringify(testObj[testJsonArr[33]].result))
288 | done()
289 | })
290 | }).timeout(30000)
291 | it('test ' + testJsonArr[34], (done) => {
292 | const reqJson = testObj[testJsonArr[34]]
293 | console.log('request:' + JSON.stringify(reqJson))
294 | chai.request('127.0.0.1:8081')
295 | .post('/api/imKey')
296 | .send(reqJson)
297 | .end((err, res) => {
298 | if (err) {
299 | console.log(err.stack)
300 | }
301 | console.log('response:' + JSON.stringify(res.body))
302 | expect(res.status).to.equal(200)
303 | expect(JSON.stringify(res.body.result)).to.equal(JSON.stringify(testObj[testJsonArr[35]].result))
304 | done()
305 | })
306 | }).timeout(30000)
307 | it('test ' + testJsonArr[36], (done) => {
308 | const reqJson = testObj[testJsonArr[36]]
309 | console.log('request:' + JSON.stringify(reqJson))
310 | chai.request('127.0.0.1:8081')
311 | .post('/api/imKey')
312 | .send(reqJson)
313 | .end((err, res) => {
314 | if (err) {
315 | console.log(err.stack)
316 | }
317 | console.log('response:' + JSON.stringify(res.body))
318 | expect(res.status).to.equal(200)
319 | expect(JSON.stringify(res.body.result)).to.equal(JSON.stringify(testObj[testJsonArr[37]].result))
320 | done()
321 | })
322 | }).timeout(30000)
323 | it('test ' + testJsonArr[38], (done) => {
324 | const reqJson = testObj[testJsonArr[38]]
325 | console.log('request:' + JSON.stringify(reqJson))
326 | chai.request('127.0.0.1:8081')
327 | .post('/api/imKey')
328 | .send(reqJson)
329 | .end((err, res) => {
330 | if (err) {
331 | console.log(err.stack)
332 | }
333 | console.log('response:' + JSON.stringify(res.body))
334 | expect(res.status).to.equal(200)
335 | expect(JSON.stringify(res.body.result)).to.equal(JSON.stringify(testObj[testJsonArr[39]].result))
336 | done()
337 | })
338 | }).timeout(30000)
339 |
340 | // describe('test btc.getXpub', () => {
341 | // it('it should show sign result', (done) => {
342 | // const reqJson = {
343 | // jsonrpc: '2.0',
344 | // method: 'btc.getXpub',
345 | // params: {
346 | // network: 'MAINNET',
347 | // path: "m/44'/0'/0'/0/0"
348 | // },
349 | // id: 5
350 | // }
351 | //
352 | // chai.request('127.0.0.1:8081')
353 | // .post('/api/imKey')
354 | // .send(reqJson
355 | // )
356 | // .end((err, res) => {
357 | // if (err) {
358 | // console.log(err.stack)
359 | // }
360 | // console.log(res.body)
361 | // expect(res.status).to.equal(200)
362 | // expect(res.body.result.xpub).to.equal('xpub6FuzpGNBc46EfvmcvECyqXjrzGcKErQgpQcpvhw1tiC5yXvi1jUkzudMpdg5AaguiFstdVR5ASDbSceBswKRy6cAhpTgozmgxMUayPDrLLX')
363 | // done()
364 | // })
365 | // }).timeout(30000)
366 | //
367 | //
368 | // it('test btc.getAddress', (done) => {
369 | // chai.request('127.0.0.1:8081')
370 | // .post('/api/imKey')
371 | // .send({
372 | // jsonrpc: '2.0',
373 | // method: 'btc.getAddress',
374 | // params: {
375 | // network: 'MAINNET',
376 | // path: "m/44'/0'/0'/0/0"
377 | // },
378 | // id: 6
379 | // }
380 | // )
381 | // .end((err, res) => {
382 | // if (err) {
383 | // console.log(err.stack)
384 | // }
385 | // console.log(res.body)
386 | // expect(res.status).to.equal(200)
387 | // expect(res.body.result.address).to.equal('12z6UzsA3tjpaeuvA2Zr9jwx19Azz74D6g')
388 | // done()
389 | // })
390 | // }).timeout(30000)
391 | // })
392 | })
393 |
394 | function readFileToJsonObj (filePath) {
395 | console.log(filePath)
396 | // 现将json文件读出来
397 | const data = fs.readFileSync(filePath, 'utf-8')
398 | const dataString = data.toString()// 将二进制的数据转换为字符串
399 | const jsonObj = JSON.parse(dataString)// 将字符串转换为json对象
400 | // console.log(jsonObj);
401 | return jsonObj
402 | // var str = JSON.stringify(jsonObj);//因为nodejs的写入文件只认识字符串或者二进制数,所以把json对象转换成字符串重新写入json文件中
403 | }
404 |
--------------------------------------------------------------------------------
/src/renderer/common/lang/zh.js:
--------------------------------------------------------------------------------
1 | // zh-CN
2 | export const m = {
3 | imKeyManager: {
4 | imKey_manager: 'imKey Manager',
5 | your_imKey_manager: '你的 imKey Pro 桌面管理工具',
6 | use_now: '立刻使用',
7 | no_have_imKey_pro: '还未拥有 imKey Pro ?',
8 | use_imKey_connected: '使用 imKey Pro 完成连接',
9 | use_imKey_connect_computer: '1. 使用 USB 将 imKey Pro 连接至电脑',
10 | click_connect_button: '2. 点击「连接」按钮',
11 | enter_pin_on_imKey: '3. 在 imKey Pro 中输入 PIN 码',
12 | if_no_set_pin_can_jump_step3: '* 如果你尚未在 imKey Pro 中设置 PIN 码,可以跳过第 3 步',
13 | if_bind_device_disconnect_bluetooth: '* 请确保当前处于imKey Pro首页,并断开蓝牙连接',
14 | connect: '连接',
15 | imKey_connecting_wait: 'imKey 连接中,请耐心等待',
16 | check_firmware_version_update: '检查固件版本升级',
17 | check_device_bind_code: '检查设备绑定码',
18 | check_pin_wallet: '检查 PIN 码及钱包',
19 | check_secure_test: '检查安全测试',
20 | usb_connect_error: 'USB 连接异常',
21 | check_usb_connect: '请拔出 USB 重试或检查 USB 接口是否松动,确认无误后再次点击「连接」',
22 | ok: '确定',
23 | firmware_update_fail: '固件升级未完成',
24 | find_firmware_update_fail_continue: '检测到因应用异常退出导致固件升级未完成,请继续升级,完成后可正常使用 imKey Manager',
25 | imKey_pro_firmware_update_wait: 'imKey Pro 固件版本升级中,请耐心等待',
26 | imKey_pro_firmware_update_no_disconnect: '注意:升级完成后 imKey Pro 将自动重启升级过程中请勿断开 USB 连接,同时中止 imKey 操作',
27 | notice: '升级提示',
28 | imKey_pro_ble_update_prompt_message: '升级成功后需删除蓝牙配对信息重新配对',
29 | enter_bind_code: '请输入设备绑定码',
30 | bind_code_error_please_check: ' 绑定码错误,请仔细核对,或通过导入助记词',
31 | reset_imKey: ' 重置 imKey ',
32 | retrieved: '找回',
33 | enter_pin_imKey_pro: '请在 imKey Pro 中输入 PIN 码',
34 | pin_code_error_please_check: 'PIN 码错误 / 遗忘可以通过',
35 | imKey_setting: 'imKey 设置',
36 | following_operations_on_imKey: '请在 imKey 上完成以下操作:',
37 | bin_code: '绑定码',
38 | create_restore_Wallet: '创建 / 恢复钱包',
39 | complete_setup: '完成设置',
40 |
41 | generate_bind_code: '生成设备绑定码',
42 | first_bind_device_see_to_imKey: '初次绑定将生成设备绑定码,请在 imKey Pro 中查看并妥善备份',
43 | operating_tutorial: '新手教程',
44 | precautions: '注意事项:',
45 | bind_code_used_check_device_please_save: '绑定码用于 imKey 与客户端一对一绑定,请仔细抄写并保管',
46 | bind_code_export_on_setting_or_rest_imKey: '绑定码在「设置」页面可导出,或通过导入助记词重置 imKey 找回',
47 | same_imKey_bind_different_PC_used_same_bind_code: '同一台 imKey Pro 若在不同 PC 端绑定,将使用相同的绑定码',
48 | next: '下一步',
49 | // enter_bind_code:'输入设备绑定码',
50 | enter_bind_code_for_use_on_the_current_device: '请输入设备绑定码,以便在当前设备上使用',
51 | // bind_code_error_please_check:'绑定码错误,请仔细核对,或通过导入助记词重置 imKey 找回',
52 |
53 | disconnect_usb: '断开USB连接',
54 | setting_pin: '设置 PIN 码',
55 | disconnect_usb_use_imKey_setting: '请断开 USB 连接,使用 imKey 进行设置,设置完成后重新连接并选择下一步',
56 | use_pin_unlock_imKey: 'PIN 码用于解锁 imKey',
57 | setting_6_8_bit_pin: '设置 6-8 位 PIN 码',
58 | do_not_enter_the_same_or_consecutive_pin: '请勿输入相同或连续数字的 PIN 码',
59 | // create_restore_Wallet:'创建 / 恢复钱包',
60 | Mnemonic_control_ownership_please_private: '助记词掌控资产所有权,请妥善私密保管',
61 | Replace_reset_device_use_mnemonic_restore_wallet: '更换或重置设备,可以使用助记词恢复钱包资产',
62 | Create_restore_wallet_2_minutes_wait: '创建 / 恢复钱包约 2 分钟,请耐心等待',
63 | choose_create_wallet_mnemonic_never_be_online: '建议选择创建钱包,保障助记词永不联网',
64 | // complete_setup:'完成设置',
65 | congratulations_complete_setup_final_security_check: '恭喜你已完成 imKey 设置,进行最后一步安全检查吧',
66 | confirm_pi_code_set_for_me_backup_completed: '确认为本人设置 PIN 码,并已完成备份',
67 | mnemonics_backup_offline_importance_of_mnemonics: '已离线备份助记词,并知晓助记词的重要性',
68 | binding_code_backup_known: '已备份设备绑定码,并知晓其作用',
69 | safety_your_assets_please_complete_all_security_checks: '为了你的资产安全,请完成所有安全检查项',
70 | previous: '上一步',
71 | done: '完成',
72 | home: '主页',
73 | manager: '管理',
74 | setting: '设置',
75 | welcome_used_imkKey_manager: '欢迎使用 imKey Manager :)',
76 | imKey_manager_is_desktop_manager: 'imKey Manager 是一款硬件钱包桌面管理程序,在这里你可以实现:',
77 | imKey_wallet_version_manager: 'imKey 硬件钱包版本管理',
78 | imKey_APP_version_manager: 'imKey App 版本管理',
79 | fast_connect_desktop_APP: '快速连接桌面端应用',
80 | used_this_desktop_APP: '尝试使用这些桌面端应用吧',
81 | view_imKey_Pro_support_coin_list_install_update_Apps: '查看 imKey Pro 币种支持列表,升级或安装新增币种',
82 | App_list: '币种列表',
83 | imKey_soft: 'imKey 软件',
84 | search: '搜索',
85 | install: '安装',
86 | upgrade: '升级',
87 | installed: '已安装',
88 | delete: '删除',
89 | APP_installing_do_not_disconnect_usb: '币种程序安装中,请勿断开 USB 连接,并中止 imKey 操作',
90 | APP_deleting_do_not_disconnect_usb: '币种程序删除中,请勿断开 USB 连接,并中止 imKey 操作',
91 | APP_upgrading_do_not_disconnect_usb: '币种程序升级中,请勿断开 USB 连接,并中止 imKey 操作',
92 | install_uninstall_upgrade_delete_Apps_fail: '币种安装/升级失败',
93 | check_usb_or_internet_connect: '请检查 USB 连接或网络连接情况,确认无误后重试',
94 | imKey_pro_setting_and_info: 'imKey Pro 基本设置及相关信息 ',
95 | device: '设备',
96 | current_least_cos_version: '已为最新固件版本',
97 | found_new_cos_version: '发现新固件版本',
98 | found_new_soft_version: 'imKey Manager 新版本提示',
99 | device_SN: '设备编号: ',
100 | device_bind_code: '设备绑定码:',
101 | export: '导出',
102 | understand_more: '了解更多',
103 | restart_automatically_after_upgrade: '注意:升级完成后 imKey Pro 将自动重启',
104 | upgrading_do_not_disconnect_usb_operating: '升级过程中请勿断开 USB 连接,同时中止 imKey 操作',
105 | upgrade_done: '升级完成',
106 | can_used_imKey_manager: '当前可以正常使用 imKey Manager',
107 | upgrade_fail: '升级失败',
108 | check_usb_internet_connect_click_upgrade_retry: '请检查 USB 连接或网络连接情况,确认无误后点击升级重试',
109 | bind_code_8_bit_world_uppercase: '8 位绑定码,英文字母均为大写',
110 | loading_fail: '加载失败',
111 | check_usb_internet_connect_retry: '请检查 USB 连接或网络连接情况,确认无误后点击重试',
112 | found_imKey_manager_new_version: 'imKey Manager 新版本提示',
113 | update: '更新',
114 | access_error_please_check_your_network_connection: '访问出错,请检查你的网络/USB连接',
115 | loading_please_wait: '加载中,请耐心等待',
116 | new_version_is: '新版本为 ',
117 | current_version_is: ',当前版本为 ',
118 | update_later: '稍后更新',
119 | update_now: '立刻更新',
120 | cancel: '取消',
121 | copy_success: '复制成功',
122 | verifying: ' 正在验证',
123 | verified_successfully: ' 验证成功',
124 | done_setting_select_next: ' 请完成上述设置再选择下一步',
125 |
126 | beginner_guide: '新手引导',
127 | learn_use_imKey: '学习如何配对和使用 imKey,或前往帮助中心浏览更多文章',
128 | buy: '快速购买',
129 | visit_Youzan_Mall_to_buy: '访问有赞商城购买 imKey 及其周边吧',
130 | user_support: '用户支持',
131 | email: '邮件:support@imkey.im',
132 | wechat: '微信:imKey_Official',
133 | tokenlon_info: '安全快速的去中心化交易所',
134 | compound_info: '存币生息,支持 USDT/USDC/Dai等 ',
135 | aave_info: '存/借贷生息,支持 17 个币种',
136 | operating_tutorial_url: 'https://imkey.im/get-started?locale=zh-cn',
137 | update_tip_wait: '更新完成后 App 将自动重启,请耐心等待',
138 | coming_soon: ' 敬请期待 ',
139 | found_dapp_access: 'imKey Manager 提示',
140 | installing_dot_ksm_coin: '请前往管理界面安装币种程序DOT和KSM'
141 | },
142 | appStart: {
143 | imKey_manager: 'imKey Manager',
144 | your_imKey_manager: '你的 imKey Pro 桌面管理工具',
145 | no_have_imKey_pro: '还未拥有 imKey Pro?',
146 | use_now: '立即使用'
147 | },
148 | connectDevice: {
149 | get_start_imKey: '开始使用你的imKey Pro',
150 | info_connect_imKey: '将imKey连接到你的电脑上',
151 | info_click_button: '点击连接按钮',
152 | info_enter_pin: '在imKey上输入PIN码 ',
153 | info_if_pin: '如果没有PIN就不用输入',
154 | connect: '连接',
155 | connect_success: '连接成功',
156 | connecting: '连接中',
157 | check_BL: '检查BL',
158 | upgrading_firmware: '升级固件中',
159 | check_active: '检查激活',
160 | active_success: '激活成功',
161 | check_bind: '检查绑定',
162 | check_create_wallet: '检查创建钱包'
163 | },
164 | step: {
165 | connect: '连接',
166 | active_bind: '激活&绑定',
167 | set_pin_create_wallet: '设置PIN&创建钱包'
168 | },
169 | stepOne: {
170 | connect_imKey: '连接你的imKey'
171 | },
172 | stepTwo: {
173 | active_bind: '激活&绑定',
174 | please_active_bind: '请激活并绑定你的imKey',
175 | active_imKey: '激活你的imKey',
176 | bind_imKey: '绑定你的imKey',
177 | start_active_bind_imKey: '开始激活并绑定你的imKey',
178 | start: '开始',
179 | activating_imKey: '正在激活你的imKey',
180 | binding_imKey: '正在绑定你的imKey',
181 | bind: '绑定',
182 | bind_code_is_null: '绑定码不能为空',
183 | bind_code_is_correct: '绑定码格式不正确',
184 | enter_bind_code: '输入绑定码'
185 | },
186 | stepThree: {
187 | set_pin_create_wallet: '设置PIN&创建钱包',
188 | please_disconnect: '请断开USB,设置PIN并创建钱包',
189 | set_modify_pin: '设置或修改PIN',
190 | create_wallet: '创建或恢复钱包',
191 | next: '下一步',
192 | operation_guide: '操作指南',
193 | how_to_set_pin: '设置方式:',
194 | set_pin_1: 'imKey 的 PIN 码设置要求为 6 - 8 位数字,不支持相同或连续的数字组合。',
195 | set_pin_2: 'imKey 上显示「设置 PIN 」进入设置流程。',
196 | set_pin_3: '设置每一位的数字,上下按钮切换,点击「OK」确认,点击「C」取消',
197 | set_pin_4: '重复此过程,直到选择了 PIN 码的所有数字。(如果你想设置 6 位 PIN 码,在第 7 位出现「✔️」符号时点击「OK」按钮即可完成设置。如果你想设置 7 位或者 8 位 PIN\n' +
198 | ' 码,在显示「✔️」符号时,通过切换按钮切换成数字并确认即可。)',
199 | set_pin_5: '再次输入 PIN 码进行确认',
200 | security_reminders: '安全提示:',
201 | security_info_1: 'PIN 码用于解锁 imKey,丢失无法找回,请妥善保管;',
202 | security_info_2: '不支持相同或连续的数字组合。',
203 | security_info_3: '切勿使用随机 PIN 码和第三方工具提供的 PIN 码。',
204 | how_to_change_PIN: '修改 PIN 码:',
205 | change_pin: '输入 PIN 开启 imKey,点击「OK」进入钱包设置界面,选择「设置」—「修改 PIN」,输入原 PIN 码进行身份确认,然后重新设置 PIN 码即可。',
206 | special_notes: '特别提示:为保证钱包资产安全,连续五次输入错误的 PIN 码,imKey 会被强制重置。请用户务必记牢设置的 PIN 码,PIN 码一旦遗失没有任何办法能够重置或者找回。',
207 | create_a_wallet: '创建钱包:',
208 | create_a_wallet_1: '根据 imKey 界面显示,使用上下按钮移动光标至「创建钱包」,点击 OK。',
209 | create_a_wallet_2: '阅读提醒后点击 OK 确认',
210 | create_a_wallet_3: '准确按顺序抄写单词',
211 | create_a_wallet_4: '重复此过程直到 12 个单词全部保存(助记词是恢复钱包的唯一方式,只能在创建钱包的时候备份备份,请务必离线妥善保管)',
212 | create_a_wallet_5: '备份助记词结束后 imKey 会显示「请确认助记词」',
213 | create_a_wallet_6: '上下按钮选择对应位置正确的单词,点击 OK 确认」',
214 | create_a_wallet_7: '重复此过程直到 12 个单词全部验证 ',
215 | create_a_wallet_8: '验证完成后提示「钱包创建中,预计 2 分钟完成」。创建完成后,即可开始使用。',
216 | recover_wallet: '恢复钱包:',
217 | recover_wallet_1: '根据 imKey 界面显示,使用上下按钮移动光标至「恢复钱包」,点击 OK。',
218 | recover_wallet_2: '选择要导入助记词的单词数量,imKey 目前支持导入 12、18、24 个单词的助记词。',
219 | recover_wallet_3: '选择助记词对应位置单词的字母,上下按钮切换,OK 确认,C 取消。',
220 | recover_wallet_4: '重复此操作,直到 imKey 显示可供选择的建议单词,上下按钮移动光标,点击 OK 选择正确的单词。(因为 BIP39 词库的 2048\n' +
221 | ' 个单词各不相同。每个单词只需要前几位字母即可确定,所以输入前几位字母后即可跳转到选择备选单词界面)',
222 | recover_wallet_5: '完成助记词导入后,点击 OK 。开始导入钱包后进入提示界面「钱包恢复中,预计 2 分钟完成」。',
223 | recover_wallet_6: '导入完成,即可开始使用。'
224 | },
225 | home: {
226 | buy_now: '现在购买',
227 | use_imToken_to_buy: '请使用 imToken 2.0 扫码购买',
228 | use_WeChat_AliPay_to_buy: '请使用微信/支付宝扫码购买',
229 | WeChat_AliPay: '微信/支付宝'
230 | },
231 | connect: {
232 | connect_imKey: '连接你的imKey',
233 | follow_steps: '执行下面步骤进入管理界面',
234 | connect_imKey_to_computer: '将你的imKey连接到电脑上',
235 | click_connect: '点击连接按钮',
236 | enter_pin_imKey: '在你的imKey上输入PIN码',
237 | connect: '连接'
238 | },
239 | manager: {
240 | manager: '管理',
241 | install_uninstall_apps: '给imKey安装或者下载应用',
242 | firmware_version: '固件版本',
243 | firmware_is: '有新的固件 ',
244 | available: '可用',
245 | update: '更新',
246 | app_catalog: '应用目录',
247 | search_app: '搜索应用',
248 | install: '安装'
249 | },
250 | setting: {
251 | info: '提示',
252 | is_update: '是否要更新?',
253 | cancel: '取消',
254 | ok: '确定',
255 | is_quit_update: '是否立刻退出更新?',
256 | setting: '设置',
257 | setting_imKey_manager: '设置imKey-manager',
258 | need_help: '帮助?',
259 | imKey_manager_version: 'imKey-manager版本',
260 | imKey_manager_version_is: 'imKey-manager有新的版本',
261 | available: '可用'
262 | },
263 | menu: {
264 | home: '主页',
265 | manager: '管理',
266 | setting: '设置'
267 | },
268 | noticeDialog: {
269 | info: '提示'
270 | },
271 | dapp: {
272 | newest_launched: '最新上架',
273 | tokenlon_desc: '安全快速的去中心化交易所',
274 | sushiswap_desc: '锁定 SushiSwap LP 代币,领取属于您的美味 SUSHI!',
275 | uniswap_desc: '保证数百万用户和数百个 Ethereum 应用的流动性',
276 | polkadotJS_desc: '加密货币交易所|简单的硬币兑换方式',
277 | multisender_desc: '将 ERC20 代币或 ETH 发送到成千上万的地址,只需一次交易......',
278 | rarible_desc: 'Create and sell digital collectibles',
279 | murall_desc: '在线创作加密艺术作品',
280 | zksync_desc: '安全、去信任化的以太坊二层网络',
281 | zkswap_desc: '基于 zkRollup Layer2 并采用 AMM 的去中心化交易所',
282 | compound_desc: '能够同时管理 MakerDAO 与 Compound 的理财神器',
283 | aave_desc: '去中心化理财, 抵押 DAI 获取稳定收益',
284 | Venus_desc: '去中心化的算法货币市场和稳定币协议,使借款人和供应商能够按需获得流动性和收益',
285 | pancake_desc: '允许在 Binance 智能链上交换两个代币。它速度快,价格便宜,并且任何人都可以参加',
286 | Autofarm_desc: 'AutoFarm 聚集了 BSC 上最好的保管库,并实施了最佳策略来最大化用户的收益',
287 | PancakeBunny_desc: '用于 PancakeSwap 的新型且快速增长的 DeFi 挖矿聚合器',
288 | Belt_Finance_desc: '具有低费用/滑点,还通过 vault 复合,借贷和收益率生成提供聚合',
289 | beefy_finance_desc: '收益更高,且不必担心不断地提高APY所必需的相互作用量',
290 | Bscex_LaunchpoolX_desc: '构建 Binance 交易所 Launchpool 的链上版本',
291 | ACryptoS_desc: '通过自动收益策略来增加您的资产',
292 | Alpaca_Finance_desc: '基于 Binance Smart Chain 的杠杆式收益挖矿协议',
293 | Goose_Finance_desc: 'Binance Smart Chain 上第一个删除迁移器代码的收益挖矿项目',
294 | MDEX_desc: '融合多种基础公链的差异化优势,打造高性能复合型 DEX 生态',
295 | BXH_desc: 'DEX 创新交易平台,是⼀个社区⾃治、⾃动做 市(AMM)的去中⼼化交易所',
296 | CoinWind_desc: 'DeFi 智能挖矿金融平台',
297 | Lendhub_desc: '基于火币生态链的去中心化借贷平台',
298 | FilDA_desc: '全球首个基于 HECO 的跨链借贷 DeFi 项目',
299 | EarnDefi_desc: '一站式 DEFI 协议,专挖头矿,具有聚合理财、交易、跨链等功能',
300 | Channels_desc: '专注于主流借贷币种 HUSD、USDT、ETH、HBTC 和 HT 等',
301 | HFI_one_desc: '基于 Heco 生态链的去中心化聚合挖矿平台',
302 | Pippi_Shrimp_Swap_desc: '基于火币智能链(Heco)的去中心化交易平台',
303 | HashBridge_desc: '提供一整套完善的数据服务方案',
304 | JulSwap_desc: '币安智能链上的 AMM',
305 | Etherscan_desc: '以太坊交易浏览器',
306 | OpenSea_desc: '全球知名加密收藏品交易平台',
307 | Nifty_Gateway_desc: '独一无二的 NFT 交易管理平台',
308 | SuperRare_desc: '收集超级珍稀(Super Rare)的数字艺术品'
309 | },
310 | imKeyCoreErrorInfo: {
311 | decoding_failed: '解析失败',
312 | imkey_publickey_mismatch_with_path: '公钥路径不匹配',
313 | imkey_illegal_param: '参数错误',
314 | get_seid_error: '获取seid失败',
315 | get_sn_error: '获取sn失败',
316 | get_ram_size_error: '获取内存空间失败',
317 | get_firmware_version_error: '获取固件版本失败',
318 | get_battery_power_error: '获取电量失败',
319 | get_life_time_error: '获取生命周期失败',
320 | get_ble_name_error: '获取蓝牙名称失败',
321 | get_ble_version_error: '获取蓝牙版本失败',
322 | parse_arguments_to_str: '解析api传入的字符失败',
323 | decode_imkey_api: 'api数据解析失败',
324 | encode_error: '编码错误',
325 | device_connect_interface_not_called: '没有调用api连接接口',
326 | device_data_read_time_out: '设备读取数据超时',
327 | imkey_device_not_connect: '没有连接imkey',
328 | Failed_opening_hid_device: '连接失败,如果已连接,请断开重连',
329 | hidapi_error_hid_error_is_not_implemented_yet: '连接失败,请断开重连',
330 | imkey_device_reconnect_fail: '重新连接失败,请断开重连',
331 | imkey_path_illegal: '路径错误',
332 | imkey_user_not_confirmed: '用户没有确认',
333 | imkey_conditions_not_satisfied: '安全条件不满足',
334 | imkey_command_format_error: '指令格式错误',
335 | imkey_command_data_error: '指令错误',
336 | imkey_applet_not_exist: '应用不存在',
337 | imkey_apdu_wrong_length: '指令长度错误',
338 | imkey_signature_verify_fail: '签名校验失败',
339 | imkey_bluetooth_channel_error: '蓝牙通道错误',
340 | imkey_applet_function_not_supported: '该应用不支持这个方法',
341 | imkey_exceeded_max_utxo_number: '超过了最大utxo数量',
342 | imkey_command_execute_fail: '指令执行失败',
343 | imkey_wallet_not_created: '钱包没有创建',
344 | imkey_in_menu_page: 'imkey在菜单页面',
345 | imkey_pin_not_verified: 'PIN码没有认证通过',
346 | imkey_address_mismatch_with_path: '地址不匹配',
347 | imkey_insufficient_funds: '资金不足',
348 | imkey_sdk_illegal_argument: 'sdk参数错误',
349 | imkey_amount_less_than_minimum: '金额少于最小值',
350 | get_xpub_error: '获取xpub错误',
351 | address_type_mismatch: '地址类型不匹配',
352 | imkey_tsm_device_authenticity_check_fail: '验证真伪失败',
353 | imkey_tsm_device_not_activated: '设备未激活',
354 | imkey_tsm_device_illegal: '非法设备',
355 | imkey_tsm_device_stop_using: '该设备已停用',
356 | imkey_tsm_server_error: '服务器错误',
357 | imkey_se_cert_invalid: 'imkey SE证书无效',
358 | imkey_tsm_device_update_check_fail: '设备更新检查失败l',
359 | imkey_tsm_device_active_fail: 'i设备激活失败',
360 | imkey_tsm_receipt_check_fail: 'receipt检查失败',
361 | imkey_tsm_app_download_fail: '应用下载失败',
362 | imkey_tsm_app_update_fail: '应用更新失败',
363 | imkey_tsm_app_delete_fail: '应用删除失败',
364 | imkey_tsm_oce_cert_check_fail: '公钥验证失败',
365 | imkey_tsm_cos_info_no_conf: 'COS 信息未配置',
366 | imkey_tsm_cos_upgrade_fail: 'COS升级失败',
367 | imkey_tsm_upload_cos_version_is_null: '上传的COS版本为空',
368 | imkey_tsm_switch_bl_status_fail: '切换BL状态失败',
369 | imkey_tsm_write_wallet_address_fail: '写wallet地址失败',
370 | imkey_tsm_check_update_fail: '检查更新失败',
371 | imkey_auth_code_ciphertext_storage_fail: '绑定码密文存储失败',
372 | imkey_keyfile_io_error: '创建key文件错误',
373 | imkey_encrypt_auth_code_fail: '加密绑定码失败',
374 | imkey_save_key_file_fail: '保存key文件失败'
375 | }
376 |
377 | }
378 |
--------------------------------------------------------------------------------