From d08e6bb237804616a8588915c2909f8e8a0af7fc Mon Sep 17 00:00:00 2001 From: liangping <18786721@qq.com> Date: Sun, 28 May 2023 11:15:29 +0800 Subject: [PATCH] improve account page --- src/modules/wallet/accounts.vue | 148 +++++++++++++++++++++++--------- src/modules/wallet/utils.ts | 60 +++++++------ 2 files changed, 141 insertions(+), 67 deletions(-) diff --git a/src/modules/wallet/accounts.vue b/src/modules/wallet/accounts.vue index 9b777372..92adad83 100644 --- a/src/modules/wallet/accounts.vue +++ b/src/modules/wallet/accounts.vue @@ -2,15 +2,18 @@ import { CosmosRestClient } from '@/libs/client'; import { useDashboard, useFormatter } from '@/stores'; import type { Coin, Delegation } from '@/types'; -import { fromBech32, toBase64, toBech32 } from '@cosmjs/encoding'; +import { fromBech32, toBase64, toBech32, toHex } from '@cosmjs/encoding'; import { Icon } from '@iconify/vue'; import { computed } from 'vue'; import { ref } from 'vue'; -import { scanLocalKeys, type AccountEntry, scanCompatibleAccounts } from './utils'; +import { scanLocalKeys, type AccountEntry, scanCompatibleAccounts, type LocalKey } from './utils'; const dashboard = useDashboard() const format = useFormatter() const editable = ref(false) // to edit addresses +const source = ref('wallet'); // values: wallet, imported, address +const sourceAddress = ref('') // +const selectedSource = ref({} as LocalKey) // function toggleEdit() { editable.value = !editable.value } @@ -19,10 +22,12 @@ const conf = ref(JSON.parse(localStorage.getItem("imported-addresses") || "{}") const balances = ref({} as Record) const delegations = ref({} as Record) +// auto import current connected wallet. scanLocalKeys().forEach(wallet => { const { data } = fromBech32(wallet.cosmosAddress) const walletKey = toBase64(data) let imported = conf.value[walletKey] + console.log('imported:', imported) // save the default address to local storage if (!imported) { imported = [] @@ -81,14 +86,52 @@ const addresses = computed(() => { return accounts.value.map(x => (x.address)) }) +const sourceOptions = computed(() => { + // scan all connected wallet + const keys = scanLocalKeys() + // all existed keys + Object.values(conf.value).forEach(x => { + const [first] = x + if (first) { + const { data } = fromBech32(first.address) + const hex = toHex(data) + if (keys.findIndex(k => toHex(fromBech32(k.cosmosAddress).data) === hex) === -1) { + keys.push({ + cosmosAddress: first.address, + hdPath: `m/44/${first.coinType}/0'/0/0` + }) + } + } + }) + // address + if (sourceAddress.value) { + const { prefix, data } = fromBech32(sourceAddress.value) + const chain = Object.values(dashboard.chains).find(x => x.bech32Prefix === prefix) + if (chain) { + keys.push({ + cosmosAddress: sourceAddress.value, + hdPath: `m/44/${chain.coinType}/0'/0/0` + }) + } + } + if (!selectedSource.value.cosmosAddress && keys.length > 0) { + selectedSource.value = keys[0] + } + return keys +}) + const availableAccount = computed(() => { - return scanCompatibleAccounts().filter(x => !addresses.value.includes(x.address)) + if (selectedSource.value.cosmosAddress) { + return scanCompatibleAccounts([selectedSource.value]).filter(x => !addresses.value.includes(x.address)) + } + return [] }) function removeAddress(addr: string) { const newConf = {} as Record Object.keys(conf.value).forEach(key => { - newConf[key] = conf.value[key].filter(x => x.address !== addr) + const acc = conf.value[key].filter(x => x.address !== addr) + if (acc.length > 0) newConf[key] = acc }) conf.value = newConf localStorage.setItem("imported-addresses", JSON.stringify(conf.value)) @@ -96,23 +139,36 @@ function removeAddress(addr: string) { async function addAddress(acc: AccountEntry) { console.log('add', acc) - const {data} = fromBech32(acc.address) + const { data } = fromBech32(acc.address) const key = toBase64(data) - if(conf.value[key]) { + if (conf.value[key]) { + // existed + if (conf.value[key].findIndex(x => x.address === acc.address) > -1) { + return + } conf.value[key].push(acc) } else { conf.value[key] = [acc] } - if(acc.endpoint) { + // also add chain to favorite + if(!dashboard?.favoriteMap?.[acc.chainName]) { + dashboard.favoriteMap[acc.chainName] = true + window.localStorage.setItem( + 'favoriteMap', + JSON.stringify(dashboard.favoriteMap) + ); + } + + if (acc.endpoint) { const client = CosmosRestClient.newDefault(acc.endpoint) client.getBankBalances(acc.address).then(res => { balances.value[acc.address] = res.balances.filter(x => x.denom.length < 10) }) client.getStakingDelegations(acc.address).then(res => { delegations.value[acc.address] = res.delegation_responses - }) + }) } localStorage.setItem("imported-addresses", JSON.stringify(conf.value)) @@ -169,9 +225,10 @@ async function addAddress(acc: AccountEntry) { - + +
- + @@ -186,11 +243,11 @@ async function addAddress(acc: AccountEntry) { -
Account +
-
+
@@ -232,45 +289,56 @@ async function addAddress(acc: AccountEntry) {
diff --git a/src/modules/wallet/utils.ts b/src/modules/wallet/utils.ts index f096d9c3..acdb5ae7 100644 --- a/src/modules/wallet/utils.ts +++ b/src/modules/wallet/utils.ts @@ -10,39 +10,45 @@ export interface AccountEntry { endpoint?: string, delegation?: Coin, balances?: Coin[], + compatiable?: boolean, +} + +export interface LocalKey { + cosmosAddress: string, hdPath: string } export function scanLocalKeys() { - const connected = [] as {cosmosAddress: string, hdPath: string}[] - for (let i = 0; i < localStorage.length; i++) { - const key = localStorage.key(i) - if (key?.startsWith("m/44")) { - const wallet = JSON.parse(localStorage.getItem(key) || "") - if (wallet) { - connected.push(wallet) - } + const connected = [] as LocalKey[] + for (let i = 0; i < localStorage.length; i++) { + const key = localStorage.key(i) + if (key?.startsWith("m/44")) { + const wallet = JSON.parse(localStorage.getItem(key) || "") + if (wallet) { + connected.push(wallet) } } - return connected } + return connected +} - -export function scanCompatibleAccounts() { - const dashboard = useDashboard() - const available = [] as AccountEntry[] - scanLocalKeys().forEach(wallet => { - Object.values(dashboard.chains).forEach(chain => { - if (wallet.hdPath.indexOf(chain.coinType) === 6) { - const { data } = fromBech32(wallet.cosmosAddress) - available.push({ - chainName: chain.chainName, - logo: chain.logo, - address: toBech32(chain.bech32Prefix, data), - coinType: chain.coinType, - endpoint: chain.endpoints.rest?.at(0)?.address - }) - } + +export function scanCompatibleAccounts(keys: LocalKey[]) { + const dashboard = useDashboard() + const available = [] as AccountEntry[] + console.log("from keys:", keys) + keys.forEach(wallet => { + Object.values(dashboard.chains).forEach(chain => { + const { data } = fromBech32(wallet.cosmosAddress) + available.push({ + chainName: chain.chainName, + logo: chain.logo, + address: toBech32(chain.bech32Prefix, data), + coinType: chain.coinType, + compatiable: wallet.hdPath.indexOf(chain.coinType) > 0, + endpoint: chain.endpoints.rest?.at(0)?.address }) }) - return available - } \ No newline at end of file + }) + console.log(available) + return available +} \ No newline at end of file