add custom cosmwasm enabled
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
"provider": "Oraichain"
|
||||
}
|
||||
],
|
||||
"cosmwasm_enabled": false,
|
||||
"sdk_version": "0.42.6",
|
||||
"coin_type": "118",
|
||||
"min_tx_fee": "800",
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
}
|
||||
],
|
||||
"rpc": [{ "provider": "Oraichain", "address": "https://rpc.orai.io" }],
|
||||
"cosmwasm_enabled": true,
|
||||
"sdk_version": "0.45.16",
|
||||
"coin_type": "118",
|
||||
"min_tx_fee": "800",
|
||||
|
||||
+76
-34
@@ -17,11 +17,12 @@ import {
|
||||
type IbcExtension,
|
||||
setupIbcExtension,
|
||||
setupSlashingExtension,
|
||||
setupDistributionExtension,
|
||||
} from '@cosmjs/stargate';
|
||||
import {
|
||||
HttpClient,
|
||||
Tendermint37Client,
|
||||
Tendermint34Client,
|
||||
// Tendermint34Client,
|
||||
WebsocketClient,
|
||||
type CometClient,
|
||||
} from '@cosmjs/tendermint-rpc';
|
||||
@@ -39,7 +40,11 @@ import {
|
||||
} from './registry';
|
||||
import { buildQuery } from '@cosmjs/tendermint-rpc/build/tendermint37/requests';
|
||||
import { PageRequest, type Coin } from '@/types';
|
||||
import type { SlashingExtension } from '@cosmjs/stargate/build/modules';
|
||||
import type {
|
||||
DistributionExtension,
|
||||
SlashingExtension,
|
||||
} from '@cosmjs/stargate/build/modules';
|
||||
import type { BondStatusString } from '@cosmjs/stargate/build/modules/staking/queries';
|
||||
|
||||
export class BaseRestClient<R extends AbstractRegistry> {
|
||||
endpoint: string;
|
||||
@@ -54,6 +59,7 @@ export class BaseRestClient<R extends AbstractRegistry> {
|
||||
GovExtension &
|
||||
IbcExtension &
|
||||
SlashingExtension &
|
||||
DistributionExtension &
|
||||
TxExtension;
|
||||
|
||||
constructor(endpoint: string, registry: R) {
|
||||
@@ -78,6 +84,7 @@ export class BaseRestClient<R extends AbstractRegistry> {
|
||||
setupGovExtension,
|
||||
setupIbcExtension,
|
||||
setupSlashingExtension,
|
||||
setupDistributionExtension,
|
||||
setupTxExtension
|
||||
);
|
||||
}
|
||||
@@ -188,31 +195,63 @@ export class CosmosRestClient extends BaseRestClient<RequestRegistry> {
|
||||
}
|
||||
// Distribution Module
|
||||
async getDistributionParams() {
|
||||
return this.request(this.registry.distribution_params, {});
|
||||
// return this.request(this.registry.distribution_params, {});
|
||||
const res = await this.queryClient.distribution.params();
|
||||
console.log(res);
|
||||
return res;
|
||||
}
|
||||
async getDistributionCommunityPool() {
|
||||
return this.request(this.registry.distribution_community_pool, {});
|
||||
// return this.request(this.registry.distribution_community_pool, {});
|
||||
const res = await this.queryClient.distribution.communityPool();
|
||||
console.log(res);
|
||||
return res;
|
||||
}
|
||||
async getDistributionDelegatorRewards(delegator_addr: string) {
|
||||
return this.request(this.registry.distribution_delegator_rewards, {
|
||||
delegator_addr,
|
||||
});
|
||||
// return this.request(this.registry.distribution_delegator_rewards, {
|
||||
// delegator_addr,
|
||||
// });
|
||||
const res = await this.queryClient.distribution.delegationTotalRewards(
|
||||
delegator_addr
|
||||
);
|
||||
console.log(res);
|
||||
return res;
|
||||
}
|
||||
async getDistributionValidatorCommission(validator_address: string) {
|
||||
return this.request(this.registry.distribution_validator_commission, {
|
||||
validator_address,
|
||||
});
|
||||
// return this.request(this.registry.distribution_validator_commission, {
|
||||
// validator_address,
|
||||
// });
|
||||
const res = await this.queryClient.distribution.validatorCommission(
|
||||
validator_address
|
||||
);
|
||||
console.log(res);
|
||||
return res;
|
||||
}
|
||||
async getDistributionValidatorOutstandingRewards(validator_address: string) {
|
||||
return this.request(
|
||||
this.registry.distribution_validator_outstanding_rewards,
|
||||
{ validator_address }
|
||||
// return this.request(
|
||||
// this.registry.distribution_validator_outstanding_rewards,
|
||||
// { validator_address }
|
||||
// );
|
||||
const res = await this.queryClient.distribution.validatorOutstandingRewards(
|
||||
validator_address
|
||||
);
|
||||
console.log(res);
|
||||
return res;
|
||||
}
|
||||
async getDistributionValidatorSlashes(validator_address: string) {
|
||||
return this.request(this.registry.distribution_validator_slashes, {
|
||||
async getDistributionValidatorSlashes(
|
||||
validator_address: string,
|
||||
starting_height: number,
|
||||
ending_height: number
|
||||
) {
|
||||
// return this.request(this.registry.distribution_validator_slashes, {
|
||||
// validator_address,
|
||||
// });
|
||||
const res = await this.queryClient.distribution.validatorSlashes(
|
||||
validator_address,
|
||||
});
|
||||
starting_height,
|
||||
ending_height
|
||||
);
|
||||
console.log(res);
|
||||
return res;
|
||||
}
|
||||
// Slashing
|
||||
async getSlashingParams() {
|
||||
@@ -273,22 +312,26 @@ export class CosmosRestClient extends BaseRestClient<RequestRegistry> {
|
||||
return this.request(this.registry.gov_proposals_deposits, { proposal_id });
|
||||
}
|
||||
async getGovProposalTally(proposal_id: string) {
|
||||
return this.request(
|
||||
this.registry.gov_proposals_tally,
|
||||
{ proposal_id },
|
||||
undefined,
|
||||
(source: any) => {
|
||||
return {
|
||||
tally: {
|
||||
yes: source.tally.yes || source.tally.yes_count,
|
||||
abstain: source.tally.abstain || source.tally.abstain_count,
|
||||
no: source.tally.no || source.tally.no_count,
|
||||
no_with_veto:
|
||||
source.tally.no_with_veto || source.tally.no_with_veto_count,
|
||||
},
|
||||
};
|
||||
}
|
||||
);
|
||||
const res = await this.queryClient.gov.tally(proposal_id);
|
||||
console.log(res);
|
||||
return res;
|
||||
|
||||
// return this.request(
|
||||
// this.registry.gov_proposals_tally,
|
||||
// { proposal_id },
|
||||
// undefined,
|
||||
// (source: any) => {
|
||||
// return {
|
||||
// tally: {
|
||||
// yes: source.tally.yes || source.tally.yes_count,
|
||||
// abstain: source.tally.abstain || source.tally.abstain_count,
|
||||
// no: source.tally.no || source.tally.no_count,
|
||||
// no_with_veto:
|
||||
// source.tally.no_with_veto || source.tally.no_with_veto_count,
|
||||
// },
|
||||
// };
|
||||
// }
|
||||
// );
|
||||
}
|
||||
async getGovProposalVotes(proposal_id: string, page?: PageRequest) {
|
||||
if (!page) page = new PageRequest();
|
||||
@@ -362,8 +405,7 @@ export class CosmosRestClient extends BaseRestClient<RequestRegistry> {
|
||||
return res;
|
||||
// return this.request(this.registry.staking_pool, {});
|
||||
}
|
||||
async getStakingValidators(status: string, limit = 200) {
|
||||
// @ts-ignore
|
||||
async getStakingValidators(status: BondStatusString, limit = 200) {
|
||||
const res = await this.queryClient.staking.validators(status);
|
||||
console.log(status, res);
|
||||
return res;
|
||||
|
||||
+23
-18
@@ -42,7 +42,7 @@ import type {
|
||||
Validator,
|
||||
} from '@/types/staking';
|
||||
import type { PaginatedTxs, Tx, TxResponse } from '@/types';
|
||||
import semver from 'semver'
|
||||
import semver from 'semver';
|
||||
export interface Request<T> {
|
||||
url: string;
|
||||
adapter: (source: any) => T;
|
||||
@@ -75,10 +75,10 @@ export interface RequestRegistry extends AbstractRegistry {
|
||||
distribution_community_pool: Request<{ pool: Coin[] }>;
|
||||
distribution_delegator_rewards: Request<{
|
||||
rewards: {
|
||||
validator_address: string,
|
||||
reward: Coin[]
|
||||
}[],
|
||||
total: Coin[]
|
||||
validator_address: string;
|
||||
reward: Coin[];
|
||||
}[];
|
||||
total: Coin[];
|
||||
}>;
|
||||
|
||||
mint_inflation: Request<{ inflation: string }>;
|
||||
@@ -90,7 +90,7 @@ export interface RequestRegistry extends AbstractRegistry {
|
||||
}>;
|
||||
mint_annual_provisions: Request<{ annual_provisions: string }>;
|
||||
|
||||
slashing_params: Request<{params: SlashingParam}>;
|
||||
slashing_params: Request<{ params: SlashingParam }>;
|
||||
slashing_signing_info: Request<PaginatedSigningInfo>;
|
||||
|
||||
gov_params_voting: Request<GovParams>;
|
||||
@@ -124,7 +124,7 @@ export interface RequestRegistry extends AbstractRegistry {
|
||||
base_tendermint_validatorsets_latest: Request<PaginatedTendermintValidator>;
|
||||
base_tendermint_validatorsets_height: Request<PaginatedTendermintValidator>;
|
||||
|
||||
params: Request<{param: any}>;
|
||||
params: Request<{ param: any }>;
|
||||
|
||||
tx_txs: Request<PaginatedTxs>;
|
||||
tx_txs_block: Request<Tx>;
|
||||
@@ -151,7 +151,9 @@ export interface RequestRegistry extends AbstractRegistry {
|
||||
ibc_core_connection_connections: Request<PaginatedIBCConnections>;
|
||||
ibc_core_connection_connections_connection_id: Request<ConnectionWithProof>;
|
||||
ibc_core_connection_connections_connection_id_client_state: Request<ClientStateWithProof>;
|
||||
interchain_security_ccv_provider_validator_consumer_addr: Request<{consumer_address: string}>
|
||||
interchain_security_ccv_provider_validator_consumer_addr: Request<{
|
||||
consumer_address: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
export function adapter<T>(source: any): T {
|
||||
@@ -174,16 +176,20 @@ export const VERSION_REGISTRY: ApiProfileRegistry = {};
|
||||
// ChainName Profile Registory
|
||||
export const NAME_REGISTRY: ApiProfileRegistry = {};
|
||||
|
||||
export function registryVersionProfile(version: string, requests: RequestRegistry) {
|
||||
VERSION_REGISTRY[version] = requests
|
||||
export function registryVersionProfile(
|
||||
version: string,
|
||||
requests: RequestRegistry
|
||||
) {
|
||||
VERSION_REGISTRY[version] = requests;
|
||||
}
|
||||
|
||||
export function registryChainProfile(version: string, requests: RequestRegistry) {
|
||||
NAME_REGISTRY[version] = requests
|
||||
export function registryChainProfile(
|
||||
version: string,
|
||||
requests: RequestRegistry
|
||||
) {
|
||||
NAME_REGISTRY[version] = requests;
|
||||
}
|
||||
export function findApiProfileByChain(
|
||||
name: string,
|
||||
): RequestRegistry {
|
||||
export function findApiProfileByChain(name: string): RequestRegistry {
|
||||
const url = NAME_REGISTRY[name];
|
||||
// if (!url) {
|
||||
// throw new Error(`Unsupported version or name: ${name}`);
|
||||
@@ -192,12 +198,11 @@ export function findApiProfileByChain(
|
||||
}
|
||||
|
||||
export function findApiProfileBySDKVersion(
|
||||
version: string,
|
||||
version: string
|
||||
): RequestRegistry | undefined {
|
||||
let closestVersion: string | null = null;
|
||||
|
||||
for (const k in VERSION_REGISTRY) {
|
||||
const key = k.replace('v', "")
|
||||
const key = k.replace('v', '');
|
||||
// console.log(semver.gt(key, version), semver.gte(version, key), key, version)
|
||||
if (semver.lte(key, version)) {
|
||||
if (!closestVersion || semver.gt(key, closestVersion)) {
|
||||
|
||||
@@ -81,13 +81,15 @@ const totalValue = computed(() => {
|
||||
});
|
||||
unbonding.value?.forEach((x) => {
|
||||
x.entries?.forEach((y) => {
|
||||
value += format.tokenValueNumber({amount: y.balance, denom: stakingStore.params.bond_denom});
|
||||
value += format.tokenValueNumber({
|
||||
amount: y.balance,
|
||||
denom: stakingStore.params.bond_denom,
|
||||
});
|
||||
});
|
||||
});
|
||||
return format.formatNumber(value, '0,0.00');
|
||||
});
|
||||
|
||||
|
||||
function loadAccount(address: string) {
|
||||
blockchain.rpc.getAuthAccount(address).then((x) => {
|
||||
account.value = x.account;
|
||||
@@ -113,7 +115,7 @@ function loadAccount(address: string) {
|
||||
});
|
||||
});
|
||||
|
||||
const receivedQuery = `?&pagination.reverse=true&events=coin_received.receiver='${address}'&pagination.limit=5`;
|
||||
const receivedQuery = `?&pagination.reverse=true&events=coin_received.receiver='${address}'&pagination.limit=5`;
|
||||
blockchain.rpc.getTxs(receivedQuery, {}).then((x) => {
|
||||
recentReceived.value = x.tx_responses;
|
||||
});
|
||||
@@ -123,11 +125,16 @@ function updateEvent() {
|
||||
loadAccount(props.address);
|
||||
}
|
||||
|
||||
function mapAmount(events:{type: string, attributes: {key: string, value: string}[]}[]) {
|
||||
if(!events) return []
|
||||
return events.find(x => x.type==='coin_received')?.attributes
|
||||
.filter(x => x.key === 'YW1vdW50'|| x.key === `amount`)
|
||||
.map(x => x.key==='amount'? x.value : String.fromCharCode(...fromBase64(x.value)))
|
||||
function mapAmount(
|
||||
events: { type: string; attributes: { key: string; value: string }[] }[]
|
||||
) {
|
||||
if (!events) return [];
|
||||
return events
|
||||
.find((x) => x.type === 'coin_received')
|
||||
?.attributes.filter((x) => x.key === 'YW1vdW50' || x.key === `amount`)
|
||||
.map((x) =>
|
||||
x.key === 'amount' ? x.value : String.fromCharCode(...fromBase64(x.value))
|
||||
);
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
@@ -164,33 +171,33 @@ function mapAmount(events:{type: string, attributes: {key: string, value: string
|
||||
<h2 class="card-title mb-4">{{ $t('account.assets') }}</h2>
|
||||
<!-- button -->
|
||||
<div class="flex justify-end mb-4 pr-5">
|
||||
<label
|
||||
for="send"
|
||||
class="btn btn-primary btn-sm mr-2"
|
||||
@click="dialog.open('send', {}, updateEvent)"
|
||||
>{{ $t('account.btn_send') }}</label
|
||||
>
|
||||
<label
|
||||
for="transfer"
|
||||
class="btn btn-primary btn-sm"
|
||||
@click="
|
||||
dialog.open(
|
||||
'transfer',
|
||||
{
|
||||
chain_name: blockchain.current?.prettyName,
|
||||
},
|
||||
updateEvent
|
||||
)
|
||||
"
|
||||
>{{ $t('account.btn_transfer') }}</label
|
||||
>
|
||||
</div>
|
||||
<label
|
||||
for="send"
|
||||
class="btn btn-primary btn-sm mr-2"
|
||||
@click="dialog.open('send', {}, updateEvent)"
|
||||
>{{ $t('account.btn_send') }}</label
|
||||
>
|
||||
<label
|
||||
for="transfer"
|
||||
class="btn btn-primary btn-sm"
|
||||
@click="
|
||||
dialog.open(
|
||||
'transfer',
|
||||
{
|
||||
chain_name: blockchain.current?.prettyName,
|
||||
},
|
||||
updateEvent
|
||||
)
|
||||
"
|
||||
>{{ $t('account.btn_transfer') }}</label
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid md:!grid-cols-3">
|
||||
<div class="md:!col-span-1">
|
||||
<DonutChart :series="totalAmountByCategory" :labels="labels" />
|
||||
</div>
|
||||
<div class="mt-4 md:!col-span-2 md:!mt-0 md:!ml-4">
|
||||
<div class="mt-4 md:!col-span-2 md:!mt-0 md:!ml-4">
|
||||
<!-- list-->
|
||||
<div class="">
|
||||
<!--balances -->
|
||||
@@ -221,7 +228,7 @@ function mapAmount(events:{type: string, attributes: {key: string, value: string
|
||||
<span
|
||||
class="inset-x-0 inset-y-0 opacity-10 absolute bg-primary dark:invert text-sm"
|
||||
></span>
|
||||
${{ format.tokenValue(balanceItem) }}
|
||||
${{ format.tokenValue(balanceItem) }}
|
||||
</div>
|
||||
</div>
|
||||
<!--delegations -->
|
||||
@@ -257,7 +264,7 @@ function mapAmount(events:{type: string, attributes: {key: string, value: string
|
||||
<span
|
||||
class="inset-x-0 inset-y-0 opacity-10 absolute bg-primary dark:invert text-sm"
|
||||
></span>
|
||||
${{ format.tokenValue(delegationItem?.balance) }}
|
||||
${{ format.tokenValue(delegationItem?.balance) }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- rewards.total -->
|
||||
@@ -282,15 +289,17 @@ function mapAmount(events:{type: string, attributes: {key: string, value: string
|
||||
<div class="text-sm font-semibold">
|
||||
{{ format.formatToken(rewardItem) }}
|
||||
</div>
|
||||
<div class="text-xs">{{ format.calculatePercent(rewardItem.amount, totalAmount) }}</div>
|
||||
<div class="text-xs">
|
||||
{{ format.calculatePercent(rewardItem.amount, totalAmount) }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="text-xs truncate relative py-1 px-3 rounded-full w-fit text-primary dark:invert mr-2"
|
||||
>
|
||||
<span
|
||||
class="inset-x-0 inset-y-0 opacity-10 absolute bg-primary dark:invert text-sm"
|
||||
></span>${{ format.tokenValue(rewardItem) }}
|
||||
|
||||
class="inset-x-0 inset-y-0 opacity-10 absolute bg-primary dark:invert text-sm"
|
||||
></span
|
||||
>${{ format.tokenValue(rewardItem) }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- mdi-account-arrow-right -->
|
||||
@@ -323,16 +332,21 @@ function mapAmount(events:{type: string, attributes: {key: string, value: string
|
||||
<div
|
||||
class="text-xs truncate relative py-1 px-3 rounded-full w-fit text-primary dark:invert mr-2"
|
||||
>
|
||||
<span class="inset-x-0 inset-y-0 opacity-10 absolute bg-primary dark:invert"></span>
|
||||
${{format.tokenValue({
|
||||
amount: String(unbondingTotal),
|
||||
denom: stakingStore.params.bond_denom,
|
||||
})
|
||||
}}
|
||||
<span
|
||||
class="inset-x-0 inset-y-0 opacity-10 absolute bg-primary dark:invert"
|
||||
></span>
|
||||
${{
|
||||
format.tokenValue({
|
||||
amount: String(unbondingTotal),
|
||||
denom: stakingStore.params.bond_denom,
|
||||
})
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 text-lg font-semibold mr-5 pl-5 border-t pt-4 text-right">
|
||||
<div
|
||||
class="mt-4 text-lg font-semibold mr-5 pl-5 border-t pt-4 text-right"
|
||||
>
|
||||
{{ $t('account.total_value') }}: ${{ totalValue }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -369,13 +383,21 @@ function mapAmount(events:{type: string, attributes: {key: string, value: string
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-sm">
|
||||
<tr v-if="delegations.length === 0"><td colspan="10"><div class="text-center">{{ $t('account.no_delegations') }}</div></td></tr>
|
||||
<tr v-if="delegations.length === 0">
|
||||
<td colspan="10">
|
||||
<div class="text-center">
|
||||
{{ $t('account.no_delegations') }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-for="(v, index) in delegations" :key="index">
|
||||
<td class="text-caption text-primary py-3">
|
||||
<RouterLink
|
||||
:to="`/${chain}/staking/${v.delegation.validator_address}`"
|
||||
>{{
|
||||
format.validatorFromBech32(v.delegation.validator_address) || v.delegation.validator_address
|
||||
format.validatorFromBech32(
|
||||
v.delegation.validator_address
|
||||
) || v.delegation.validator_address
|
||||
}}</RouterLink
|
||||
>
|
||||
</td>
|
||||
@@ -461,47 +483,52 @@ function mapAmount(events:{type: string, attributes: {key: string, value: string
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-sm" v-for="(v, index) in unbonding" :key="index">
|
||||
<tr>
|
||||
<td class="text-caption text-primary py-3 bg-slate-200" colspan="10">
|
||||
<RouterLink
|
||||
:to="`/${chain}/staking/${v.validator_address}`"
|
||||
>{{
|
||||
v.validator_address
|
||||
}}</RouterLink
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-for="entry in v.entries">
|
||||
<td class="py-3">{{ entry.creation_height }}</td>
|
||||
<td class="py-3">
|
||||
{{
|
||||
format.formatToken(
|
||||
{
|
||||
amount: entry.initial_balance,
|
||||
denom: stakingStore.params.bond_denom,
|
||||
},
|
||||
true,
|
||||
'0,0.[00]'
|
||||
)
|
||||
}}
|
||||
</td>
|
||||
<td class="py-3">
|
||||
{{
|
||||
format.formatToken(
|
||||
{
|
||||
amount: entry.balance,
|
||||
denom: stakingStore.params.bond_denom,
|
||||
},
|
||||
true,
|
||||
'0,0.[00]'
|
||||
)
|
||||
}}
|
||||
</td>
|
||||
<td class="py-3">
|
||||
<Countdown :time="new Date(entry.completion_time).getTime() - new Date().getTime()" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tr>
|
||||
<td
|
||||
class="text-caption text-primary py-3 bg-slate-200"
|
||||
colspan="10"
|
||||
>
|
||||
<RouterLink :to="`/${chain}/staking/${v.validator_address}`">{{
|
||||
v.validator_address
|
||||
}}</RouterLink>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-for="entry in v.entries">
|
||||
<td class="py-3">{{ entry.creation_height }}</td>
|
||||
<td class="py-3">
|
||||
{{
|
||||
format.formatToken(
|
||||
{
|
||||
amount: entry.initial_balance,
|
||||
denom: stakingStore.params.bond_denom,
|
||||
},
|
||||
true,
|
||||
'0,0.[00]'
|
||||
)
|
||||
}}
|
||||
</td>
|
||||
<td class="py-3">
|
||||
{{
|
||||
format.formatToken(
|
||||
{
|
||||
amount: entry.balance,
|
||||
denom: stakingStore.params.bond_denom,
|
||||
},
|
||||
true,
|
||||
'0,0.[00]'
|
||||
)
|
||||
}}
|
||||
</td>
|
||||
<td class="py-3">
|
||||
<Countdown
|
||||
:time="
|
||||
new Date(entry.completion_time).getTime() -
|
||||
new Date().getTime()
|
||||
"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -520,15 +547,26 @@ function mapAmount(events:{type: string, attributes: {key: string, value: string
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-sm">
|
||||
<tr v-if="txs.length === 0"><td colspan="10"><div class="text-center">{{ $t('account.no_transactions') }}</div></td></tr>
|
||||
<tr v-if="txs.length === 0">
|
||||
<td colspan="10">
|
||||
<div class="text-center">
|
||||
{{ $t('account.no_transactions') }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-for="(v, index) in txs" :key="index">
|
||||
<td class="text-sm py-3">
|
||||
<RouterLink :to="`/${chain}/block/${v.height}`" class="text-primary dark:invert">{{
|
||||
v.height
|
||||
}}</RouterLink>
|
||||
<RouterLink
|
||||
:to="`/${chain}/block/${v.height}`"
|
||||
class="text-primary dark:invert"
|
||||
>{{ v.height }}</RouterLink
|
||||
>
|
||||
</td>
|
||||
<td class="truncate py-3" style="max-width: 200px">
|
||||
<RouterLink :to="`/${chain}/tx/${v.txhash}`" class="text-primary dark:invert">
|
||||
<RouterLink
|
||||
:to="`/${chain}/tx/${v.txhash}`"
|
||||
class="text-primary dark:invert"
|
||||
>
|
||||
{{ v.txhash }}
|
||||
</RouterLink>
|
||||
</td>
|
||||
@@ -543,7 +581,12 @@ function mapAmount(events:{type: string, attributes: {key: string, value: string
|
||||
/>
|
||||
<Icon v-else icon="mdi-multiply" class="text-error text-lg" />
|
||||
</td>
|
||||
<td class="py-3">{{ format.toLocaleDate(v.timestamp) }} <span class=" text-xs">({{ format.toDay(v.timestamp, 'from') }})</span> </td>
|
||||
<td class="py-3">
|
||||
{{ format.toLocaleDate(v.timestamp) }}
|
||||
<span class="text-xs"
|
||||
>({{ format.toDay(v.timestamp, 'from') }})</span
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -564,21 +607,32 @@ function mapAmount(events:{type: string, attributes: {key: string, value: string
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="text-sm">
|
||||
<tr v-if="recentReceived.length === 0"><td colspan="10"><div class="text-center">{{ $t('account.no_transactions') }}</div></td></tr>
|
||||
<tr v-if="recentReceived.length === 0">
|
||||
<td colspan="10">
|
||||
<div class="text-center">
|
||||
{{ $t('account.no_transactions') }}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-for="(v, index) in recentReceived" :key="index">
|
||||
<td class="text-sm py-3">
|
||||
<RouterLink :to="`/${chain}/block/${v.height}`" class="text-primary dark:invert">{{
|
||||
v.height
|
||||
}}</RouterLink>
|
||||
<RouterLink
|
||||
:to="`/${chain}/block/${v.height}`"
|
||||
class="text-primary dark:invert"
|
||||
>{{ v.height }}</RouterLink
|
||||
>
|
||||
</td>
|
||||
<td class="truncate py-3" style="max-width: 200px">
|
||||
<RouterLink :to="`/${chain}/tx/${v.txhash}`" class="text-primary dark:invert">
|
||||
<RouterLink
|
||||
:to="`/${chain}/tx/${v.txhash}`"
|
||||
class="text-primary dark:invert"
|
||||
>
|
||||
{{ v.txhash }}
|
||||
</RouterLink>
|
||||
</td>
|
||||
<td class="flex items-center py-3">
|
||||
<div class="mr-2">
|
||||
{{ mapAmount(v.events)?.join(", ")}}
|
||||
{{ mapAmount(v.events)?.join(', ') }}
|
||||
</div>
|
||||
<Icon
|
||||
v-if="v.code === 0"
|
||||
@@ -587,7 +641,12 @@ function mapAmount(events:{type: string, attributes: {key: string, value: string
|
||||
/>
|
||||
<Icon v-else icon="mdi-multiply" class="text-error text-lg" />
|
||||
</td>
|
||||
<td class="py-3">{{ format.toLocaleDate(v.timestamp) }} <span class=" text-xs">({{ format.toDay(v.timestamp, 'from') }})</span> </td>
|
||||
<td class="py-3">
|
||||
{{ format.toLocaleDate(v.timestamp) }}
|
||||
<span class="text-xs"
|
||||
>({{ format.toDay(v.timestamp, 'from') }})</span
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
<script lang="ts" setup>
|
||||
import { formatSeconds } from '@/libs/utils';
|
||||
import { useBaseStore, useBlockchain, useFormatter } from '@/stores';
|
||||
import { type Connection, type ClientState, type Channel, PageRequest, type TxResponse, type PaginatedTxs } from '@/types';
|
||||
import {
|
||||
type Connection,
|
||||
type ClientState,
|
||||
type Channel,
|
||||
PageRequest,
|
||||
type TxResponse,
|
||||
type PaginatedTxs,
|
||||
} from '@/types';
|
||||
import { computed, onMounted } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
import { useIBCModule } from '../connStore';
|
||||
@@ -12,33 +19,31 @@ const props = defineProps(['chain', 'connection_id']);
|
||||
const chainStore = useBlockchain();
|
||||
const baseStore = useBaseStore();
|
||||
const format = useFormatter();
|
||||
const ibcStore = useIBCModule()
|
||||
const ibcStore = useIBCModule();
|
||||
const conn = ref({} as Connection);
|
||||
const clientState = ref({} as { client_id: string; client_state: ClientState });
|
||||
const channels = ref([] as Channel[]);
|
||||
|
||||
const connId = computed(() => {
|
||||
return props.connection_id || 0
|
||||
})
|
||||
return props.connection_id || 0;
|
||||
});
|
||||
|
||||
const loading = ref(false)
|
||||
const txs = ref({} as PaginatedTxs)
|
||||
const direction = ref('')
|
||||
const channel_id = ref('')
|
||||
const port_id = ref('')
|
||||
const page = ref(new PageRequest())
|
||||
page.value.limit = 5
|
||||
const loading = ref(false);
|
||||
const txs = ref({} as PaginatedTxs);
|
||||
const direction = ref('');
|
||||
const channel_id = ref('');
|
||||
const port_id = ref('');
|
||||
const page = ref(new PageRequest());
|
||||
page.value.limit = 5;
|
||||
|
||||
onMounted(() => {
|
||||
if (connId.value) {
|
||||
chainStore.rpc.getIBCConnectionsById(connId.value).then((x) => {
|
||||
conn.value = x.connection;
|
||||
});
|
||||
chainStore.rpc
|
||||
.getIBCConnectionsClientState(connId.value)
|
||||
.then((x) => {
|
||||
clientState.value = x.identified_client_state;
|
||||
});
|
||||
chainStore.rpc.getIBCConnectionsClientState(connId.value).then((x) => {
|
||||
clientState.value = x.identifiedClientState;
|
||||
});
|
||||
chainStore.rpc.getIBCConnectionsChannels(connId.value).then((x) => {
|
||||
channels.value = x.channels;
|
||||
});
|
||||
@@ -53,37 +58,47 @@ function loadChannel(channel: string, port: string) {
|
||||
|
||||
function pageload(pageNum: number) {
|
||||
if (direction.value === 'In') {
|
||||
fetchSendingTxs(channel_id.value, port_id.value, pageNum -1)
|
||||
fetchSendingTxs(channel_id.value, port_id.value, pageNum - 1);
|
||||
} else {
|
||||
fetchSendingTxs(channel_id.value, port_id.value, pageNum -1)
|
||||
fetchSendingTxs(channel_id.value, port_id.value, pageNum - 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function fetchSendingTxs(channel: string, port: string, pageNum = 0) {
|
||||
|
||||
page.value.setPage(pageNum)
|
||||
loading.value = true
|
||||
direction.value = 'Out'
|
||||
channel_id.value = channel
|
||||
port_id.value = port
|
||||
txs.value = {} as PaginatedTxs
|
||||
chainStore.rpc.getTxs("?order_by=2&events=send_packet.packet_src_channel='{channel}'&events=send_packet.packet_src_port='{port}'", { channel, port }, page.value).then(res => {
|
||||
txs.value = res
|
||||
})
|
||||
.finally(() => loading.value = false)
|
||||
page.value.setPage(pageNum);
|
||||
loading.value = true;
|
||||
direction.value = 'Out';
|
||||
channel_id.value = channel;
|
||||
port_id.value = port;
|
||||
txs.value = {} as PaginatedTxs;
|
||||
chainStore.rpc
|
||||
.getTxs(
|
||||
"?order_by=2&events=send_packet.packet_src_channel='{channel}'&events=send_packet.packet_src_port='{port}'",
|
||||
{ channel, port },
|
||||
page.value
|
||||
)
|
||||
.then((res) => {
|
||||
txs.value = res;
|
||||
})
|
||||
.finally(() => (loading.value = false));
|
||||
}
|
||||
function fetchRecevingTxs(channel: string, port: string, pageNum = 0) {
|
||||
page.value.setPage(pageNum)
|
||||
loading.value = true
|
||||
direction.value = 'In'
|
||||
channel_id.value = channel
|
||||
port_id.value = port
|
||||
txs.value = {} as PaginatedTxs
|
||||
chainStore.rpc.getTxs("?order_by=2&events=recv_packet.packet_dst_channel='{channel}'&events=recv_packet.packet_dst_port='{port}'", { channel, port }, page.value).then(res => {
|
||||
txs.value = res
|
||||
})
|
||||
.finally(() => loading.value = false)
|
||||
page.value.setPage(pageNum);
|
||||
loading.value = true;
|
||||
direction.value = 'In';
|
||||
channel_id.value = channel;
|
||||
port_id.value = port;
|
||||
txs.value = {} as PaginatedTxs;
|
||||
chainStore.rpc
|
||||
.getTxs(
|
||||
"?order_by=2&events=recv_packet.packet_dst_channel='{channel}'&events=recv_packet.packet_dst_port='{port}'",
|
||||
{ channel, port },
|
||||
page.value
|
||||
)
|
||||
.then((res) => {
|
||||
txs.value = res;
|
||||
})
|
||||
.finally(() => (loading.value = false));
|
||||
}
|
||||
|
||||
function color(v: string) {
|
||||
@@ -95,12 +110,14 @@ function color(v: string) {
|
||||
</script>
|
||||
<template>
|
||||
<div class="">
|
||||
<div class="px-4 pt-3 pb-4 bg-base-200 rounded mb-4 shadow ">
|
||||
<div class="px-4 pt-3 pb-4 bg-base-200 rounded mb-4 shadow">
|
||||
<div class="mx-auto max-w-7xl px-6 lg:!px-8">
|
||||
<dl class="grid grid-cols-1 gap-x-6 text-center lg:!grid-cols-3">
|
||||
<div class="mx-auto flex items-center">
|
||||
<div>
|
||||
<div class="order-first text-3xl font-semibold tracking-tight text-main mb-1">
|
||||
<div
|
||||
class="order-first text-3xl font-semibold tracking-tight text-main mb-1"
|
||||
>
|
||||
{{ baseStore.latest?.block?.header?.chain_id }}
|
||||
</div>
|
||||
<div class="text-sm text-gray-500 dark:text-gray-400">
|
||||
@@ -111,13 +128,15 @@ function color(v: string) {
|
||||
<div class="mx-auto flex items-center">
|
||||
<div :class="{ 'text-success': conn.state?.indexOf('_OPEN') > -1 }">
|
||||
<span class="text-lg rounded-full">⇌</span>
|
||||
<div class=" text-c">
|
||||
<div class="text-c">
|
||||
{{ conn.state }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mx-auto">
|
||||
<div class="order-first text-3xl font-semibold tracking-tight text-main mb-2">
|
||||
<div
|
||||
class="order-first text-3xl font-semibold tracking-tight text-main mb-2"
|
||||
>
|
||||
{{ clientState.client_state?.chain_id }}
|
||||
</div>
|
||||
<div class="text-sm text-gray-500 dark:text-gray-400">
|
||||
@@ -129,8 +148,12 @@ function color(v: string) {
|
||||
</div>
|
||||
|
||||
<div class="bg-base-100 px-4 pt-3 pb-4 rounded mb-4 shadow">
|
||||
<h2 class="card-title mb-4 overflow-hidden">{{ $t('ibc.title_2') }}<span class="ml-2 text-sm">{{
|
||||
clientState.client_state?.['@type'] }}</span></h2>
|
||||
<h2 class="card-title mb-4 overflow-hidden">
|
||||
{{ $t('ibc.title_2')
|
||||
}}<span class="ml-2 text-sm">{{
|
||||
clientState.client_state?.['@type']
|
||||
}}</span>
|
||||
</h2>
|
||||
<div class="overflow-x-auto grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<table class="table table-sm capitalize">
|
||||
<thead class="bg-base-200">
|
||||
@@ -149,15 +172,21 @@ function color(v: string) {
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="w-52">{{ $t('ibc.trusting_period') }}:</td>
|
||||
<td>{{ formatSeconds(clientState.client_state?.trusting_period) }}</td>
|
||||
<td>
|
||||
{{ formatSeconds(clientState.client_state?.trusting_period) }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="w-52">{{ $t('ibc.unbonding_period') }}:</td>
|
||||
<td>{{ formatSeconds(clientState.client_state?.unbonding_period) }}</td>
|
||||
<td>
|
||||
{{ formatSeconds(clientState.client_state?.unbonding_period) }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="w-52">{{ $t('ibc.max_clock_drift') }}:</td>
|
||||
<td>{{ formatSeconds(clientState.client_state?.max_clock_drift) }}</td>
|
||||
<td>
|
||||
{{ formatSeconds(clientState.client_state?.max_clock_drift) }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="w-52">{{ $t('ibc.frozen_height') }}:</td>
|
||||
@@ -178,23 +207,32 @@ function color(v: string) {
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="flex justify-between"><span>{{ $t('ibc.allow_update_after_expiry') }}:</span> <span>{{
|
||||
clientState.client_state?.allow_update_after_expiry }}</span></div>
|
||||
<div class="flex justify-between">
|
||||
<span>{{ $t('ibc.allow_update_after_expiry') }}:</span>
|
||||
<span>{{
|
||||
clientState.client_state?.allow_update_after_expiry
|
||||
}}</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="flex justify-between"><span>{{ $t('ibc.allow_update_after_misbehaviour') }}: </span> <span>{{
|
||||
clientState.client_state?.allow_update_after_misbehaviour }}</span></div>
|
||||
<div class="flex justify-between">
|
||||
<span>{{ $t('ibc.allow_update_after_misbehaviour') }}: </span>
|
||||
<span>{{
|
||||
clientState.client_state?.allow_update_after_misbehaviour
|
||||
}}</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="w-52">{{ $t('ibc.upgrade_path') }}:</td>
|
||||
<td class="text-right">{{ clientState.client_state?.upgrade_path.join(', ') }}</td>
|
||||
<td class="text-right">
|
||||
{{ clientState.client_state?.upgrade_path.join(', ') }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-base-100 px-4 pt-3 pb-4 rounded mb-4 shadow overflow-hidden">
|
||||
@@ -204,7 +242,9 @@ function color(v: string) {
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ $t('ibc.txs') }}</th>
|
||||
<th style="position: relative; z-index: 2">{{ $t('ibc.channel_id') }}</th>
|
||||
<th style="position: relative; z-index: 2">
|
||||
{{ $t('ibc.channel_id') }}
|
||||
</th>
|
||||
<th>{{ $t('ibc.port_id') }}</th>
|
||||
<th>{{ $t('ibc.state') }}</th>
|
||||
<th>{{ $t('ibc.counterparty') }}</th>
|
||||
@@ -217,36 +257,68 @@ function color(v: string) {
|
||||
<tr v-for="v in ibcStore.registryChannels">
|
||||
<td>
|
||||
<div class="flex gap-1">
|
||||
<button class="btn btn-xs"
|
||||
@click="fetchSendingTxs(v[ibcStore.sourceField].channel_id, v[ibcStore.sourceField].port_id)"
|
||||
:disabled="loading">
|
||||
<span v-if="loading" class="loading loading-spinner loading-sm"></span>
|
||||
<button
|
||||
class="btn btn-xs"
|
||||
@click="
|
||||
fetchSendingTxs(
|
||||
v[ibcStore.sourceField].channel_id,
|
||||
v[ibcStore.sourceField].port_id
|
||||
)
|
||||
"
|
||||
:disabled="loading"
|
||||
>
|
||||
<span
|
||||
v-if="loading"
|
||||
class="loading loading-spinner loading-sm"
|
||||
></span>
|
||||
{{ $t('ibc.btn_out') }}
|
||||
</button>
|
||||
<button class="btn btn-xs"
|
||||
@click="fetchRecevingTxs(v[ibcStore.sourceField].channel_id, v[ibcStore.sourceField].port_id)"
|
||||
:disabled="loading">
|
||||
<span v-if="loading" class="loading loading-spinner loading-sm"></span>
|
||||
<button
|
||||
class="btn btn-xs"
|
||||
@click="
|
||||
fetchRecevingTxs(
|
||||
v[ibcStore.sourceField].channel_id,
|
||||
v[ibcStore.sourceField].port_id
|
||||
)
|
||||
"
|
||||
:disabled="loading"
|
||||
>
|
||||
<span
|
||||
v-if="loading"
|
||||
class="loading loading-spinner loading-sm"
|
||||
></span>
|
||||
{{ $t('ibc.btn_in') }}
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<a href="#">{{
|
||||
v[ibcStore.sourceField].channel_id
|
||||
}}</a>
|
||||
<a href="#">{{ v[ibcStore.sourceField].channel_id }}</a>
|
||||
</td>
|
||||
<td>{{ v[ibcStore.sourceField].port_id }}</td>
|
||||
</tr>
|
||||
<tr v-for="v in channels">
|
||||
<td>
|
||||
<div class="flex gap-1">
|
||||
<button class="btn btn-xs" @click="fetchSendingTxs(v.channel_id, v.port_id)" :disabled="loading">
|
||||
<span v-if="loading" class="loading loading-spinner loading-sm"></span>
|
||||
<button
|
||||
class="btn btn-xs"
|
||||
@click="fetchSendingTxs(v.channel_id, v.port_id)"
|
||||
:disabled="loading"
|
||||
>
|
||||
<span
|
||||
v-if="loading"
|
||||
class="loading loading-spinner loading-sm"
|
||||
></span>
|
||||
{{ $t('ibc.btn_out') }}
|
||||
</button>
|
||||
<button class="btn btn-xs" @click="fetchRecevingTxs(v.channel_id, v.port_id)" :disabled="loading">
|
||||
<span v-if="loading" class="loading loading-spinner loading-sm"></span>
|
||||
<button
|
||||
class="btn btn-xs"
|
||||
@click="fetchRecevingTxs(v.channel_id, v.port_id)"
|
||||
:disabled="loading"
|
||||
>
|
||||
<span
|
||||
v-if="loading"
|
||||
class="loading loading-spinner loading-sm"
|
||||
></span>
|
||||
{{ $t('ibc.btn_in') }}
|
||||
</button>
|
||||
</div>
|
||||
@@ -258,8 +330,14 @@ function color(v: string) {
|
||||
</td>
|
||||
<td>{{ v.port_id }}</td>
|
||||
<td>
|
||||
<div class="text-xs truncate relative py-2 px-4 rounded-full w-fit" :class="`text-${color(v.state)}`">
|
||||
<span class="inset-x-0 inset-y-0 opacity-10 absolute" :class="`bg-${color(v.state)}`"></span>
|
||||
<div
|
||||
class="text-xs truncate relative py-2 px-4 rounded-full w-fit"
|
||||
:class="`text-${color(v.state)}`"
|
||||
>
|
||||
<span
|
||||
class="inset-x-0 inset-y-0 opacity-10 absolute"
|
||||
:class="`bg-${color(v.state)}`"
|
||||
></span>
|
||||
{{ v.state }}
|
||||
</div>
|
||||
</td>
|
||||
@@ -275,13 +353,15 @@ function color(v: string) {
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="channel_id">
|
||||
<h3 class=" card-title capitalize">Transactions ({{ channel_id }} {{ port_id }} {{ direction }}) </h3>
|
||||
<h3 class="card-title capitalize">
|
||||
Transactions ({{ channel_id }} {{ port_id }} {{ direction }})
|
||||
</h3>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<td> {{ $t('ibc.height') }}</td>
|
||||
<td>{{ $t('ibc.height') }}</td>
|
||||
<td>{{ $t('ibc.txhash') }}</td>
|
||||
<td> {{ $t('ibc.messages') }}</td>
|
||||
<td>{{ $t('ibc.messages') }}</td>
|
||||
<td>{{ $t('ibc.time') }}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -290,13 +370,20 @@ function color(v: string) {
|
||||
<td>{{ resp.height }}</td>
|
||||
<td>
|
||||
<div class="text-xs truncate text-primary dark:invert">
|
||||
<RouterLink :to="`/${chainStore.chainName}/tx/${resp.txhash}`">{{ resp.txhash }}</RouterLink>
|
||||
<RouterLink
|
||||
:to="`/${chainStore.chainName}/tx/${resp.txhash}`"
|
||||
>{{ resp.txhash }}</RouterLink
|
||||
>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="flex">
|
||||
{{ format.messages(resp.tx.body.messages) }}
|
||||
<Icon v-if="resp.code === 0" icon="mdi-check" class="text-success text-lg" />
|
||||
<Icon
|
||||
v-if="resp.code === 0"
|
||||
icon="mdi-check"
|
||||
class="text-success text-lg"
|
||||
/>
|
||||
<Icon v-else icon="mdi-multiply" class="text-error text-lg" />
|
||||
</div>
|
||||
</td>
|
||||
@@ -304,7 +391,11 @@ function color(v: string) {
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<PaginationBar :limit="page.limit" :total="txs.pagination?.total" :callback="pageload" />
|
||||
<PaginationBar
|
||||
:limit="page.limit"
|
||||
:total="txs.pagination?.total"
|
||||
:callback="pageload"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -195,12 +195,12 @@ async function loadBalances(
|
||||
const endpointObj = chainStore.randomEndpoint(chainName);
|
||||
const client = CosmosRestClient.newDefault(endpointObj?.address || endpoint);
|
||||
const paginatedBalances = await client.getBankBalances(address);
|
||||
balances.value[address] = paginatedBalances.balances.filter(
|
||||
balances.value[address] = paginatedBalances.filter(
|
||||
(x) => x.denom.length < 10
|
||||
);
|
||||
|
||||
const paginatedDelegations = await client.getStakingDelegations(address);
|
||||
delegations.value[address] = paginatedDelegations.delegation_responses;
|
||||
delegations.value[address] = paginatedDelegations.delegationResponses;
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
|
||||
@@ -21,7 +21,7 @@ async function initParamsForKeplr() {
|
||||
chain.endpoints.rpc?.at(0)?.address || ''
|
||||
);
|
||||
const b = await client.getBaseBlockLatest();
|
||||
const chainid = b.block.header.chain_id;
|
||||
const chainid = b.block.header.chainId;
|
||||
|
||||
const gasPriceStep = chain.keplrPriceStep || {
|
||||
low: 0.01,
|
||||
|
||||
@@ -70,31 +70,31 @@ watchEffect(() => {
|
||||
|
||||
Object.values(conf.value).forEach((imported) => {
|
||||
if (imported)
|
||||
imported.forEach((x) => {
|
||||
imported.forEach(async (x) => {
|
||||
if (x.endpoint && x.address) {
|
||||
loading.value += 1;
|
||||
const endpoint = chainStore.randomEndpoint(x.chainName);
|
||||
const client = CosmosRestClient.newDefault(
|
||||
endpoint?.address || x.endpoint
|
||||
);
|
||||
client
|
||||
.getBankBalances(x.address)
|
||||
.then((res) => {
|
||||
const bal = res.balances.filter((x) => x.denom.length < 10);
|
||||
if (bal) balances.value[x.address || ''] = bal;
|
||||
bal.forEach((b) => {
|
||||
tokenMeta.value[b.denom] = x;
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
loaded.value += 1;
|
||||
});
|
||||
client.getStakingDelegations(x.address).then((res) => {
|
||||
if (res && res.delegation_responses)
|
||||
delegations.value[x.address || ''] = res.delegation_responses;
|
||||
res.delegation_responses.forEach((del) => {
|
||||
tokenMeta.value[del.balance.denom] = x;
|
||||
});
|
||||
const coins = await client.getBankBalances(x.address);
|
||||
|
||||
const bal = coins.filter((x) => x.denom.length < 10);
|
||||
if (bal) balances.value[x.address || ''] = bal;
|
||||
bal.forEach((b) => {
|
||||
tokenMeta.value[b.denom] = x;
|
||||
});
|
||||
|
||||
loaded.value += 1;
|
||||
|
||||
const stakingDelegations = await client.getStakingDelegations(
|
||||
x.address
|
||||
);
|
||||
if (stakingDelegations.delegationResponses)
|
||||
delegations.value[x.address || ''] =
|
||||
stakingDelegations.delegationResponses;
|
||||
stakingDelegations.delegationResponses.forEach((del) => {
|
||||
tokenMeta.value[del.balance.denom] = x;
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -177,7 +177,7 @@ function loadPrice() {
|
||||
.map((x) => x.coinId)
|
||||
.join(',');
|
||||
get(
|
||||
`https://price.market.orai.io/coins/markets?vs_currency=${currency.value}&ids=${ids}&order=market_cap_desc&per_page=100&page=1&sparkline=true&price_change_percentage=14d&locale=en`
|
||||
`hhttps://api.coingecko.com/api/v3/coins/markets?vs_currency=${currency.value}&ids=${ids}&order=market_cap_desc&per_page=100&page=1&sparkline=true&price_change_percentage=14d&locale=en`
|
||||
).then((res) => {
|
||||
prices.value = res;
|
||||
});
|
||||
|
||||
@@ -46,7 +46,7 @@ async function initParamsForKeplr() {
|
||||
chain.endpoints.rpc?.at(0)?.address || ''
|
||||
);
|
||||
const b = await client.getBaseBlockLatest();
|
||||
const chainid = b.block.header.chain_id;
|
||||
const chainid = b.block.header.chainId;
|
||||
|
||||
const gasPriceStep = chain.keplrPriceStep || {
|
||||
low: 0.01,
|
||||
@@ -116,7 +116,7 @@ async function initSnap() {
|
||||
chain.endpoints.rpc?.at(0)?.address || ''
|
||||
);
|
||||
const b = await client.getBaseBlockLatest();
|
||||
const chainId = b.block.header.chain_id;
|
||||
const chainId = b.block.header.chainId;
|
||||
|
||||
conf.value = JSON.stringify(
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@ export const useBankStore = defineStore('bankstore', {
|
||||
supply: {} as Coin,
|
||||
balances: {} as Record<string, Coin[]>,
|
||||
totalSupply: { supply: [] as Coin[] },
|
||||
ibcDenoms: {} as Record<string, DenomTrace>
|
||||
ibcDenoms: {} as Record<string, DenomTrace>,
|
||||
};
|
||||
},
|
||||
getters: {
|
||||
@@ -42,7 +42,7 @@ export const useBankStore = defineStore('bankstore', {
|
||||
let trace = this.ibcDenoms[hash];
|
||||
if (!trace) {
|
||||
trace = (await this.blockchain.rpc.getIBCAppTransferDenom(hash))
|
||||
.denom_trace;
|
||||
.denomTrace;
|
||||
this.ibcDenoms[hash] = trace;
|
||||
}
|
||||
return trace;
|
||||
|
||||
@@ -86,11 +86,18 @@ export const useBlockchain = defineStore('blockchain', {
|
||||
badgeClass: 'bg-error',
|
||||
children: routes
|
||||
.filter((x) => x.meta.i18n) // defined menu name
|
||||
.filter(
|
||||
(x) =>
|
||||
.filter((x) => {
|
||||
// shortcut to ignore cosmwasm
|
||||
if (
|
||||
!this.current?.cosmwasmEnabled &&
|
||||
String(x.meta.i18n) === 'cosmwasm'
|
||||
)
|
||||
return false;
|
||||
return (
|
||||
!this.current?.features ||
|
||||
this.current.features.includes(String(x.meta.i18n))
|
||||
) // filter none-custom module
|
||||
);
|
||||
}) // filter none-custom module
|
||||
.map((x) => ({
|
||||
title: `module.${x.meta.i18n}`,
|
||||
to: { path: x.path.replace(':chain', this.chainName) },
|
||||
@@ -102,6 +109,7 @@ export const useBlockchain = defineStore('blockchain', {
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// compute favorite menu
|
||||
const favNavItems: VerticalNavItems = [];
|
||||
Object.keys(this.dashboard.favoriteMap).forEach((name) => {
|
||||
@@ -167,9 +175,9 @@ export const useBlockchain = defineStore('blockchain', {
|
||||
}
|
||||
},
|
||||
|
||||
async randomSetupEndpoint() {
|
||||
randomSetupEndpoint() {
|
||||
const endpoint = this.randomEndpoint(this.chainName);
|
||||
if (endpoint) await this.setRestEndpoint(endpoint);
|
||||
if (endpoint) this.setRestEndpoint(endpoint);
|
||||
},
|
||||
|
||||
setRestEndpoint(endpoint: Endpoint) {
|
||||
@@ -199,6 +207,7 @@ export const useBlockchain = defineStore('blockchain', {
|
||||
this.chainName = caseSensitiveName;
|
||||
}
|
||||
},
|
||||
|
||||
supportModule(mod: string) {
|
||||
return !this.current?.features || this.current.features.includes(mod);
|
||||
},
|
||||
|
||||
@@ -28,7 +28,7 @@ export const useCoingecko = defineStore('coingecko', {
|
||||
actions: {
|
||||
getMarketChart(days = 30, coinId = 'cosmos') {
|
||||
return get(
|
||||
`https://price.market.orai.io/coins/${coinId}/market_chart?vs_currency=usd&days=${days}`
|
||||
`https://api.coingecko.com/api/v3/coins/${coinId}/market_chart?vs_currency=usd&days=${days}`
|
||||
);
|
||||
},
|
||||
|
||||
@@ -42,7 +42,7 @@ export const useCoingecko = defineStore('coingecko', {
|
||||
});
|
||||
},
|
||||
getCoinInfo(coinId: string) {
|
||||
return get(`https://price.market.orai.io/coins/${coinId}`);
|
||||
return get(`https://api.coingecko.com/api/v3/coins/${coinId}`);
|
||||
},
|
||||
setSecondaryCurrency(currency: string) {
|
||||
if (currency !== 'usd') {
|
||||
|
||||
@@ -56,6 +56,7 @@ export interface DirectoryChain {
|
||||
export interface ChainConfig {
|
||||
chainName: string;
|
||||
prettyName: string;
|
||||
cosmwasmEnabled: boolean;
|
||||
bech32Prefix: string;
|
||||
chainId: string;
|
||||
coinType: string;
|
||||
@@ -105,6 +106,7 @@ export interface LocalConfig {
|
||||
logo: string;
|
||||
theme_color?: string;
|
||||
min_tx_fee: string;
|
||||
cosmwasm_enabled: boolean;
|
||||
rpc: string[] | Endpoint[];
|
||||
sdk_version: string;
|
||||
registry_name?: string;
|
||||
@@ -148,6 +150,7 @@ export function fromLocal(lc: LocalConfig): ChainConfig {
|
||||
{ denom: x.symbol.toLowerCase(), exponent: Number(x.exponent) },
|
||||
],
|
||||
}));
|
||||
conf.cosmwasmEnabled = lc.cosmwasm_enabled ?? false;
|
||||
conf.versions = {
|
||||
cosmosSdk: lc.sdk_version,
|
||||
};
|
||||
@@ -173,6 +176,8 @@ export function fromLocal(lc: LocalConfig): ChainConfig {
|
||||
|
||||
export function fromDirectory(source: DirectoryChain): ChainConfig {
|
||||
const conf = {} as ChainConfig;
|
||||
conf.cosmwasmEnabled = source.cosmwasm_enabled ?? false;
|
||||
|
||||
(conf.assets = source.assets),
|
||||
(conf.bech32Prefix = source.bech32_prefix),
|
||||
(conf.chainId = source.chain_id),
|
||||
@@ -330,6 +335,7 @@ export const useDashboard = defineStore('dashboard', {
|
||||
Object.values<LocalConfig>(source).forEach((x: LocalConfig) => {
|
||||
this.chains[x.chain_name] = fromLocal(x);
|
||||
});
|
||||
|
||||
this.setupDefault();
|
||||
this.status = LoadingStatus.Loaded;
|
||||
},
|
||||
|
||||
+11
-11
@@ -39,36 +39,36 @@ export const useGovStore = defineStore('govStore', {
|
||||
);
|
||||
|
||||
//filter spam proposals
|
||||
if(proposals?.proposals) {
|
||||
if (proposals?.proposals) {
|
||||
proposals.proposals = proposals.proposals.filter((item) => {
|
||||
const title = item.content?.title || item.title || ""
|
||||
return title.toLowerCase().indexOf("airdrop")===-1
|
||||
const title = item.content?.title || item.title || '';
|
||||
return title.toLowerCase().indexOf('airdrop') === -1;
|
||||
});
|
||||
}
|
||||
|
||||
if (status === '2') {
|
||||
proposals?.proposals?.forEach((item) => {
|
||||
this.fetchTally(item.proposal_id).then((res) => {
|
||||
item.final_tally_result = res?.tally;
|
||||
});
|
||||
// this.fetchTally(item.proposalId.toString()).then((res) => {
|
||||
// item.finalTallyResult = res?.tally;
|
||||
// });
|
||||
if (this.walletstore.currentAddress) {
|
||||
try {
|
||||
this.fetchProposalVotesVoter(
|
||||
item.proposal_id,
|
||||
item.proposalId.toString(),
|
||||
this.walletstore.currentAddress
|
||||
)
|
||||
.then((res) => {
|
||||
item.voterStatus = res?.vote?.option || 'VOTE_OPTION_NO_WITH_VETO'
|
||||
item.status = res?.vote?.option || 'VOTE_OPTION_NO_WITH_VETO';
|
||||
// 'No With Veto';
|
||||
})
|
||||
.catch((reject) => {
|
||||
item.voterStatus = 'VOTE_OPTION_NO_WITH_VETO'
|
||||
item.status = 'VOTE_OPTION_NO_WITH_VETO';
|
||||
});
|
||||
} catch (error) {
|
||||
item.voterStatus = 'VOTE_OPTION_NO_WITH_VETO'
|
||||
item.status = 'VOTE_OPTION_NO_WITH_VETO';
|
||||
}
|
||||
} else {
|
||||
item.voterStatus = 'VOTE_OPTION_NO_WITH_VETO'
|
||||
item.status = 'VOTE_OPTION_NO_WITH_VETO';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -94,8 +94,8 @@ export const useParamStore = defineStore('paramstore', {
|
||||
const height = this.chain.items.findIndex(
|
||||
(x) => x.subtitle === 'height'
|
||||
);
|
||||
this.chain.title = `Chain ID: ${res.block.header.chain_id}`;
|
||||
this.chain.items[height].value = res.block.header.height;
|
||||
this.chain.title = `Chain ID: ${res.block.header.chainId}`;
|
||||
this.chain.items[height].value = res.block.header.height.toString();
|
||||
// if (timeIn(res.block.header.time, 3, 'm')) {
|
||||
// this.syncing = true
|
||||
// } else {
|
||||
@@ -109,7 +109,7 @@ export const useParamStore = defineStore('paramstore', {
|
||||
},
|
||||
async handleStakingParams() {
|
||||
const res = await this.getStakingParams();
|
||||
const bond_denom = res?.params.bond_denom;
|
||||
const bond_denom = res?.params.bondDenom;
|
||||
this.staking.items = Object.entries(res.params)
|
||||
.map(([key, value]) => ({ subtitle: key, value: value }))
|
||||
.filter((item: any) => {
|
||||
@@ -123,13 +123,13 @@ export const useParamStore = defineStore('paramstore', {
|
||||
Promise.all([this.getStakingPool(), this.getBankTotal(bond_denom)]).then(
|
||||
(resArr) => {
|
||||
const pool = resArr[0]?.pool;
|
||||
const amount = resArr[1]?.amount?.amount;
|
||||
const amount = resArr[1]?.amount;
|
||||
const assets = this.blockchain.current?.assets;
|
||||
const bondedAndSupply = this.chain.items.findIndex(
|
||||
(x) => x.subtitle === 'bonded_and_supply'
|
||||
);
|
||||
this.chain.items[bondedAndSupply].value = `${formatNumber(
|
||||
formatTokenAmount(assets, pool.bonded_tokens, 2, bond_denom, false),
|
||||
formatTokenAmount(assets, pool.bondedTokens, 2, bond_denom, false),
|
||||
true,
|
||||
0
|
||||
)}/${formatNumber(
|
||||
@@ -141,7 +141,7 @@ export const useParamStore = defineStore('paramstore', {
|
||||
(x) => x.subtitle === 'bonded_ratio'
|
||||
);
|
||||
this.chain.items[bondedRatio].value = `${percent(
|
||||
Number(pool.bonded_tokens) / Number(amount)
|
||||
Number(pool.bondedTokens) / Number(amount)
|
||||
)}%`;
|
||||
}
|
||||
);
|
||||
@@ -181,9 +181,9 @@ export const useParamStore = defineStore('paramstore', {
|
||||
this.getGovParamsTally(),
|
||||
]).then((resArr) => {
|
||||
const govParams = {
|
||||
...resArr[0]?.voting_params,
|
||||
...resArr[1]?.deposit_params,
|
||||
...resArr[2]?.tally_params,
|
||||
...resArr[0]?.votingParams,
|
||||
...resArr[1]?.depositParams,
|
||||
...resArr[2]?.tallyParams,
|
||||
};
|
||||
this.gov.items = Object.entries(govParams).map(([key, value]) => ({
|
||||
subtitle: key,
|
||||
@@ -194,14 +194,19 @@ export const useParamStore = defineStore('paramstore', {
|
||||
async handleAbciInfo() {
|
||||
const res = await this.fetchAbciInfo();
|
||||
|
||||
localStorage.setItem(`sdk_version_${this.blockchain.chainName}`, res.application_version?.cosmos_sdk_version);
|
||||
|
||||
this.appVersion.items = Object.entries(res.application_version).map(
|
||||
([key, value]) => ({ subtitle: key, value: value })
|
||||
);
|
||||
this.nodeVersion.items = Object.entries(res.default_node_info).map(
|
||||
([key, value]) => ({ subtitle: key, value: value })
|
||||
localStorage.setItem(
|
||||
`sdk_version_${this.blockchain.chainName}`,
|
||||
res.version
|
||||
);
|
||||
|
||||
this.appVersion.items = [res.protocolVersion];
|
||||
// Object.entries(res.application_version).map(
|
||||
// ([key, value]) => ({ subtitle: key, value: value })
|
||||
// );
|
||||
this.nodeVersion.items = [res.version];
|
||||
// this.nodeVersion.items = Object.entries(res.default_node_info).map(
|
||||
// ([key, value]) => ({ subtitle: key, value: value })
|
||||
// );
|
||||
},
|
||||
async getBaseTendermintBlockLatest() {
|
||||
return await this.blockchain.rpc?.getBaseBlockLatest();
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
fromBech32,
|
||||
} from '@cosmjs/encoding';
|
||||
import { useBaseStore } from './useBaseStore';
|
||||
import type { BondStatusString } from '@cosmjs/stargate/build/modules/staking/queries';
|
||||
|
||||
export const useStakingStore = defineStore('stakingStore', {
|
||||
state: () => {
|
||||
@@ -156,7 +157,7 @@ export const useStakingStore = defineStore('stakingStore', {
|
||||
);
|
||||
}
|
||||
},
|
||||
async fetchValidators(status: string) {
|
||||
async fetchValidators(status: BondStatusString) {
|
||||
if (this.blockchain.isConsumerChain) {
|
||||
if (
|
||||
this.blockchain.current?.providerChain.api &&
|
||||
@@ -166,8 +167,8 @@ export const useStakingStore = defineStore('stakingStore', {
|
||||
this.blockchain.current.providerChain.api[0].address
|
||||
);
|
||||
// provider validators
|
||||
const res = await client.getStakingValidators(status);
|
||||
const proVals = res.validators.sort(
|
||||
const validatorsRes = await client.getStakingValidators(status);
|
||||
const proVals = validatorsRes.validators.sort(
|
||||
(a, b) => Number(b.delegatorShares) - Number(a.delegatorShares)
|
||||
);
|
||||
if (status === 'BOND_STATUS_BONDED') {
|
||||
@@ -177,15 +178,16 @@ export const useStakingStore = defineStore('stakingStore', {
|
||||
return proVals;
|
||||
}
|
||||
}
|
||||
return this.blockchain.rpc?.getStakingValidators(status).then((res) => {
|
||||
const vals = res.validators.sort(
|
||||
(a, b) => Number(b.delegatorShares) - Number(a.delegatorShares)
|
||||
);
|
||||
if (status === 'BOND_STATUS_BONDED') {
|
||||
this.validators = vals;
|
||||
}
|
||||
return vals;
|
||||
});
|
||||
const validatorsRes = await this.blockchain.rpc?.getStakingValidators(
|
||||
status
|
||||
);
|
||||
const vals = validatorsRes.validators.sort(
|
||||
(a, b) => Number(b.delegatorShares) - Number(a.delegatorShares)
|
||||
);
|
||||
if (status === 'BOND_STATUS_BONDED') {
|
||||
this.validators = vals;
|
||||
}
|
||||
return vals;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user