From b0ebf40312521d864b545cfe5d47464bf47776f0 Mon Sep 17 00:00:00 2001 From: liangping <18786721@qq.com> Date: Wed, 13 Sep 2023 17:09:31 +0800 Subject: [PATCH] add suggest chain --- package.json | 1 + src/layouts/components/DefaultLayout.vue | 14 ++ src/modules/wallet/suggest.vue | 166 +++++++++++++++++++++++ src/stores/useDashboard.ts | 11 ++ vite.config.ts | 3 + yarn.lock | 94 ++++++++++++- 6 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 src/modules/wallet/suggest.vue diff --git a/package.json b/package.json index 998f7a97..eab2ae9a 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@cosmjs/encoding": "^0.29.5", "@iconify/vue": "^4.1.0", "@intlify/unplugin-vue-i18n": "^0.8.2", + "@leapwallet/cosmos-snap-provider": "^0.1.20", "@leapwallet/name-matcha": "^1.1.0", "@osmonauts/lcd": "^0.8.0", "@ping-pub/chain-registry-client": "^0.0.25", diff --git a/src/layouts/components/DefaultLayout.vue b/src/layouts/components/DefaultLayout.vue index 6a1d9939..6920c4c4 100644 --- a/src/layouts/components/DefaultLayout.vue +++ b/src/layouts/components/DefaultLayout.vue @@ -239,6 +239,20 @@ function selected(route: any, nav: NavLink) { +
+ Tools +
+ + +
+ Wallet Helper +
+
+
{{ $t('module.links') }}
+import { computed, ref } from 'vue'; +import { suggestChain } from '@leapwallet/cosmos-snap-provider'; +import { useDashboard, type ChainConfig, useBlockchain, NetworkType } from '@/stores'; +import { CosmosRestClient } from '@/libs/client'; +import { onMounted } from 'vue'; + +const error = ref("") +const conf = ref("") +const dashboard = useDashboard() +const selected = ref({} as ChainConfig) +const wallet = ref("keplr") +const network = ref(NetworkType.Mainnet) +const mainnet = ref([] as ChainConfig[]) +const testnet = ref([] as ChainConfig[]) +const chains = computed(() => { + return network.value === NetworkType.Mainnet? mainnet.value : testnet.value +}) + +onMounted(() => { + const chainStore = useBlockchain() + selected.value = chainStore.current || Object.values(dashboard.chains)[0] + initParamsForKeplr() + + dashboard.loadLocalConfig(NetworkType.Mainnet).then((res) => { + mainnet.value = Object.values(res) + }) + dashboard.loadLocalConfig(NetworkType.Testnet).then((res) => { + testnet.value = Object.values(res) + }) +}) + +function onchange() { + wallet.value === "keplr" ? initParamsForKeplr() : initSnap() +} + +async function initParamsForKeplr() { + const chain = selected.value + if(!chain.endpoints?.rest?.at(0)) throw new Error("Endpoint does not set"); + const client = CosmosRestClient.newDefault(chain.endpoints.rest?.at(0)?.address || "") + const b = await client.getBaseBlockLatest() + const chainid = b.block.header.chain_id + + const gasPriceStep = chain.keplrPriceStep || { + low: 0.01, + average: 0.025, + high: 0.03, + } + const coinDecimals = chain.assets[0].denom_units.find(x => x.denom === chain.assets[0].symbol.toLowerCase())?.exponent || 6 + conf.value = JSON.stringify({ + chainId: chainid, + chainName: chain.chainName, + rpc: chain.endpoints?.rpc?.at(0)?.address, + rest: chain.endpoints?.rest?.at(0)?.address, + bip44: { + coinType: Number(chain.coinType), + }, + coinType: Number(chain.coinType), + bech32Config: { + bech32PrefixAccAddr: chain.bech32Prefix, + bech32PrefixAccPub: `${chain.bech32Prefix}pub`, + bech32PrefixValAddr: `${chain.bech32Prefix}valoper`, + bech32PrefixValPub: `${chain.bech32Prefix}valoperpub`, + bech32PrefixConsAddr: `${chain.bech32Prefix}valcons`, + bech32PrefixConsPub: `${chain.bech32Prefix}valconspub`, + }, + currencies: [ + { + coinDenom: chain.assets[0].symbol, + coinMinimalDenom: chain.assets[0].base, + coinDecimals, + coinGeckoId: chain.assets[0].coingecko_id || 'unknown', + }, + ], + feeCurrencies: [ + { + coinDenom: chain.assets[0].symbol, + coinMinimalDenom: chain.assets[0].base, + coinDecimals, + coinGeckoId: chain.assets[0].coingecko_id || 'unknown', + gasPriceStep, + }, + ], + gasPriceStep, + stakeCurrency: { + coinDenom: chain.assets[0].symbol, + coinMinimalDenom: chain.assets[0].base, + coinDecimals, + coinGeckoId: chain.assets[0].coingecko_id || 'unknown', + }, + features: chain.keplrFeatures || [], + }, null, '\t') +} + +async function initSnap() { + const chain = selected.value + const [token] = chain.assets + conf.value = JSON.stringify({ + chainId: chain.chainId, + chainName: chain.chainName, + bech32Config: { + bech32PrefixAccAddr: chain.bech32Prefix, + }, + bip44: { + coinType: Number(chain.coinType), + }, + feeCurrencies: [ + { + coinDenom: token.display, + coinMinimalDenom: token.base, + coinDecimals: token.denom_units.find(x => x.denom === token.display)?.exponent || 6, + coinGeckoId: token.coingecko_id, + gasPriceStep: { + low: 0.0625, + average: 0.5, + high: 62.5, + }, + }, + ], + }, null, '\t') +} + +function suggest() { + if(wallet.value === "keplr") { + // @ts-ignore + if (window.keplr) { + // @ts-ignore + window.keplr.experimentalSuggestChain(JSON.parse(conf.value)).catch(e => { + error.value = e + }) + } + } else { + suggestChain(JSON.parse(conf.value)); + } +} + + + + diff --git a/src/stores/useDashboard.ts b/src/stores/useDashboard.ts index 183a5741..2753c1c2 100644 --- a/src/stores/useDashboard.ts +++ b/src/stores/useDashboard.ts @@ -328,6 +328,17 @@ export const useDashboard = defineStore('dashboard', { this.setupDefault(); this.status = LoadingStatus.Loaded; }, + async loadLocalConfig(network: NetworkType) { + const config: Record = {} + const source: Record = + network === NetworkType.Mainnet + ? import.meta.glob('../../chains/mainnet/*.json', { eager: true }) + : import.meta.glob('../../chains/testnet/*.json', { eager: true }); + Object.values(source).forEach((x: LocalConfig) => { + config[x.chain_name] = fromLocal(x); + }); + return config + }, setupDefault() { if (this.length > 0) { const blockchain = useBlockchain(); diff --git a/vite.config.ts b/vite.config.ts index 9e7bc720..bf293936 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -12,6 +12,9 @@ import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'; // https://vitejs.dev/config/ export default defineConfig({ + define: { + 'process.env': {} + }, plugins: [ vue({ template: { diff --git a/yarn.lock b/yarn.lock index 81dbc48c..25e08104 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1257,6 +1257,16 @@ "@cosmjs/math" "^0.30.1" "@cosmjs/utils" "^0.30.1" +"@cosmjs/amino@^0.31.0", "@cosmjs/amino@^0.31.1": + version "0.31.1" + resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.31.1.tgz#e6b4adc3ebe19ddfd953c67ee04b1eae488238af" + integrity sha512-kkB9IAkNEUFtjp/uwHv95TgM8VGJ4VWfZwrTyLNqBDD1EpSX2dsNrmUe7k8OMPzKlZUFcKmD4iA0qGvIwzjbGA== + dependencies: + "@cosmjs/crypto" "^0.31.1" + "@cosmjs/encoding" "^0.31.1" + "@cosmjs/math" "^0.31.1" + "@cosmjs/utils" "^0.31.1" + "@cosmjs/cosmwasm-stargate@0.30.0": version "0.30.0" resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.30.0.tgz#b03c6c1383ef658695fcb02e6e1f4df2ddbd4710" @@ -1300,6 +1310,19 @@ elliptic "^6.5.4" libsodium-wrappers "^0.7.6" +"@cosmjs/crypto@^0.31.1": + version "0.31.1" + resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.31.1.tgz#ce4917df0f7b38f0909a32020907ccff04acefe6" + integrity sha512-4R/SqdzdVzd4E5dpyEh1IKm5GbTqwDogutyIyyb1bcOXiX/x3CrvPI9Tb4WSIMDLvlb5TVzu2YnUV51Q1+6mMA== + dependencies: + "@cosmjs/encoding" "^0.31.1" + "@cosmjs/math" "^0.31.1" + "@cosmjs/utils" "^0.31.1" + "@noble/hashes" "^1" + bn.js "^5.2.0" + elliptic "^6.5.4" + libsodium-wrappers-sumo "^0.7.11" + "@cosmjs/encoding@^0.29.3", "@cosmjs/encoding@^0.29.5": version "0.29.5" resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.29.5.tgz#009a4b1c596cdfd326f30ccfa79f5e56daa264f2" @@ -1318,6 +1341,15 @@ bech32 "^1.1.4" readonly-date "^1.0.0" +"@cosmjs/encoding@^0.31.1": + version "0.31.1" + resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.31.1.tgz#0041b2650c443d883e22f27c7d3cd7b844c6d0ec" + integrity sha512-IuxP6ewwX6vg9sUJ8ocJD92pkerI4lyG8J5ynAM3NaX3q+n+uMoPRSQXNeL9bnlrv01FF1kIm8if/f5F7ZPtkA== + dependencies: + base64-js "^1.3.0" + bech32 "^1.1.4" + readonly-date "^1.0.0" + "@cosmjs/json-rpc@^0.29.5": version "0.29.5" resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.29.5.tgz#5e483a9bd98a6270f935adf0dfd8a1e7eb777fe4" @@ -1348,6 +1380,13 @@ dependencies: bn.js "^5.2.0" +"@cosmjs/math@^0.31.1": + version "0.31.1" + resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.31.1.tgz#74c02cf237c2996b77661b636b014168b18d95e6" + integrity sha512-kiuHV6m6DSB8/4UV1qpFhlc4ul8SgLXTGRlYkYiIIP4l0YNeJ+OpPYaOlEgx4Unk2mW3/O2FWYj7Jc93+BWXng== + dependencies: + bn.js "^5.2.0" + "@cosmjs/proto-signing@0.29.3": version "0.29.3" resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.29.3.tgz#fa5ed609ed2a0007d8d5eacbeb1f5a89ba1b77ff" @@ -1387,6 +1426,19 @@ cosmjs-types "^0.7.1" long "^4.0.0" +"@cosmjs/proto-signing@^0.31.0": + version "0.31.1" + resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.31.1.tgz#3929d5bee3c88c42b3bc3c4b9db4ab3bddb684c4" + integrity sha512-hipbBVrssPu+jnmRzQRP5hhS/mbz2nU7RvxG/B1ZcdNhr1AtZC5DN09OTUoEpMSRgyQvScXmk/NTbyf+xmCgYg== + dependencies: + "@cosmjs/amino" "^0.31.1" + "@cosmjs/crypto" "^0.31.1" + "@cosmjs/encoding" "^0.31.1" + "@cosmjs/math" "^0.31.1" + "@cosmjs/utils" "^0.31.1" + cosmjs-types "^0.8.0" + long "^4.0.0" + "@cosmjs/socket@^0.29.5": version "0.29.5" resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.29.5.tgz#a48df6b4c45dc6a6ef8e47232725dd4aa556ac2d" @@ -1499,6 +1551,11 @@ resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.30.1.tgz#6d92582341be3c2ec8d82090253cfa4b7f959edb" integrity sha512-KvvX58MGMWh7xA+N+deCfunkA/ZNDvFLw4YbOmX3f/XBIkqrVY7qlotfy2aNb1kgp6h4B6Yc8YawJPDTfvWX7g== +"@cosmjs/utils@^0.31.1": + version "0.31.1" + resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.31.1.tgz#e6055cd7d722fa72df9cbd0d39cd1f7a9ac80483" + integrity sha512-n4Se1wu4GnKwztQHNFfJvUeWcpvx3o8cWhSbNs9JQShEuB3nv3R5lqFBtDCgHZF/emFQAP+ZjF8bTfCs9UBGhA== + "@cosmwasm/ts-codegen@0.21.1": version "0.21.1" resolved "https://registry.yarnpkg.com/@cosmwasm/ts-codegen/-/ts-codegen-0.21.1.tgz#abbb15fdb8f1c966079de49e0da0f847fa5045fe" @@ -1823,6 +1880,16 @@ resolved "https://registry.yarnpkg.com/@jsdevtools/ono/-/ono-7.1.3.tgz#9df03bbd7c696a5c58885c34aa06da41c8543796" integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg== +"@leapwallet/cosmos-snap-provider@^0.1.20": + version "0.1.20" + resolved "https://registry.yarnpkg.com/@leapwallet/cosmos-snap-provider/-/cosmos-snap-provider-0.1.20.tgz#b0c36f3b0e2cfa441769c6ed93bd4238f62a66d4" + integrity sha512-VUoxun5prJdLTjkCRU3EBLwx2CNnvYnP9deSiffwCx4lQQzcN38gSIHs3rfXpdyLdPv1jIi6nVVsqIVKFzvB1w== + dependencies: + "@cosmjs/amino" "^0.31.0" + "@cosmjs/proto-signing" "^0.31.0" + bignumber.js "^9.1.2" + long "^5.2.3" + "@leapwallet/name-matcha@^1.1.0": version "1.3.1" resolved "https://registry.yarnpkg.com/@leapwallet/name-matcha/-/name-matcha-1.3.1.tgz#2215b7f911ea0e1321bd28aded472a40c92932b2" @@ -2772,6 +2839,11 @@ bech32@1.1.4, bech32@^1.1.4: resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== +bignumber.js@^9.1.2: + version "9.1.2" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" + integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== + binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" @@ -3143,6 +3215,14 @@ cosmjs-types@^0.7.1: long "^4.0.0" protobufjs "~6.11.2" +cosmjs-types@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/cosmjs-types/-/cosmjs-types-0.8.0.tgz#2ed78f3e990f770229726f95f3ef5bf9e2b6859b" + integrity sha512-Q2Mj95Fl0PYMWEhA2LuGEIhipF7mQwd9gTQ85DdP9jjjopeoGaDxvmPa5nakNzsq7FnO1DMTatXTAx6bxMH7Lg== + dependencies: + long "^4.0.0" + protobufjs "~6.11.2" + cross-fetch@^3.1.5: version "3.1.8" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" @@ -4603,6 +4683,18 @@ lazy-load-vue3@^1.3.0: resolved "https://registry.yarnpkg.com/lazy-load-vue3/-/lazy-load-vue3-1.3.0.tgz#6aaf573d1d09626ac11fec6b2de9fd07c0130ac0" integrity sha512-IcyeMiDZrxzuIqqwkYkC+6RRQBdm0yTR0onIj6NITrWd6LaUlzzRmbvAmuzGB0g4H1HeVm/Oa0FokxD2lz9UAA== +libsodium-sumo@^0.7.11: + version "0.7.11" + resolved "https://registry.yarnpkg.com/libsodium-sumo/-/libsodium-sumo-0.7.11.tgz#ab0389e2424fca5c1dc8c4fd394906190da88a11" + integrity sha512-bY+7ph7xpk51Ez2GbE10lXAQ5sJma6NghcIDaSPbM/G9elfrjLa0COHl/7P6Wb/JizQzl5UQontOOP1z0VwbLA== + +libsodium-wrappers-sumo@^0.7.11: + version "0.7.11" + resolved "https://registry.yarnpkg.com/libsodium-wrappers-sumo/-/libsodium-wrappers-sumo-0.7.11.tgz#d96329ee3c0e7ec7f5fcf4cdde16cc3a1ae91d82" + integrity sha512-DGypHOmJbB1nZn89KIfGOAkDgfv5N6SBGC3Qvmy/On0P0WD1JQvNRS/e3UL3aFF+xC0m+MYz5M+MnRnK2HMrKQ== + dependencies: + libsodium-sumo "^0.7.11" + libsodium-wrappers@^0.7.6: version "0.7.11" resolved "https://registry.yarnpkg.com/libsodium-wrappers/-/libsodium-wrappers-0.7.11.tgz#53bd20606dffcc54ea2122133c7da38218f575f7" @@ -4684,7 +4776,7 @@ long@^4.0.0: resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== -long@^5.2.0, long@^5.2.1: +long@^5.2.0, long@^5.2.1, long@^5.2.3: version "5.2.3" resolved "https://registry.yarnpkg.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1" integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==